@refinedev/core 4.22.0 → 4.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +180 -0
  2. package/dist/components/canAccess/index.d.ts.map +1 -1
  3. package/dist/contexts/refine/IRefineContext.d.ts +3 -0
  4. package/dist/contexts/refine/IRefineContext.d.ts.map +1 -1
  5. package/dist/contexts/refine/index.d.ts.map +1 -1
  6. package/dist/definitions/helpers/generateDocumentTitle/index.d.ts.map +1 -1
  7. package/dist/definitions/helpers/handleRefineOptions/index.d.ts.map +1 -1
  8. package/dist/definitions/helpers/pick-resource/index.d.ts.map +1 -1
  9. package/dist/esm/index.js +6 -6
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/hooks/data/useCreate.d.ts +3 -2
  12. package/dist/hooks/data/useCreate.d.ts.map +1 -1
  13. package/dist/hooks/data/useCreateMany.d.ts +3 -2
  14. package/dist/hooks/data/useCreateMany.d.ts.map +1 -1
  15. package/dist/hooks/data/useCustom.d.ts +3 -2
  16. package/dist/hooks/data/useCustom.d.ts.map +1 -1
  17. package/dist/hooks/data/useCustomMutation.d.ts +3 -2
  18. package/dist/hooks/data/useCustomMutation.d.ts.map +1 -1
  19. package/dist/hooks/data/useDelete.d.ts +4 -3
  20. package/dist/hooks/data/useDelete.d.ts.map +1 -1
  21. package/dist/hooks/data/useDeleteMany.d.ts +4 -3
  22. package/dist/hooks/data/useDeleteMany.d.ts.map +1 -1
  23. package/dist/hooks/data/useInfiniteList.d.ts +3 -2
  24. package/dist/hooks/data/useInfiniteList.d.ts.map +1 -1
  25. package/dist/hooks/data/useList.d.ts +3 -2
  26. package/dist/hooks/data/useList.d.ts.map +1 -1
  27. package/dist/hooks/data/useMany.d.ts +3 -2
  28. package/dist/hooks/data/useMany.d.ts.map +1 -1
  29. package/dist/hooks/data/useOne.d.ts +3 -2
  30. package/dist/hooks/data/useOne.d.ts.map +1 -1
  31. package/dist/hooks/data/useUpdate.d.ts +4 -3
  32. package/dist/hooks/data/useUpdate.d.ts.map +1 -1
  33. package/dist/hooks/data/useUpdateMany.d.ts +4 -3
  34. package/dist/hooks/data/useUpdateMany.d.ts.map +1 -1
  35. package/dist/hooks/export/index.d.ts.map +1 -1
  36. package/dist/hooks/form/useForm.d.ts +4 -3
  37. package/dist/hooks/form/useForm.d.ts.map +1 -1
  38. package/dist/hooks/index.d.ts +1 -0
  39. package/dist/hooks/index.d.ts.map +1 -1
  40. package/dist/hooks/live/useResourceSubscription/index.d.ts +1 -1
  41. package/dist/hooks/live/useResourceSubscription/index.d.ts.map +1 -1
  42. package/dist/hooks/resource/useResource/index.d.ts +11 -1
  43. package/dist/hooks/resource/useResource/index.d.ts.map +1 -1
  44. package/dist/hooks/show/useShow.d.ts +4 -3
  45. package/dist/hooks/show/useShow.d.ts.map +1 -1
  46. package/dist/hooks/useLoadingOvertime/index.d.ts +49 -0
  47. package/dist/hooks/useLoadingOvertime/index.d.ts.map +1 -0
  48. package/dist/hooks/useSelect/index.d.ts +3 -2
  49. package/dist/hooks/useSelect/index.d.ts.map +1 -1
  50. package/dist/hooks/useTable/index.d.ts +4 -3
  51. package/dist/hooks/useTable/index.d.ts.map +1 -1
  52. package/dist/iife/index.js +6 -6
  53. package/dist/iife/index.js.map +1 -1
  54. package/dist/index.js +6 -6
  55. package/dist/index.js.map +1 -1
  56. package/package.json +1 -1
  57. package/src/components/canAccess/index.tsx +17 -92
  58. package/src/contexts/refine/IRefineContext.ts +3 -0
  59. package/src/contexts/refine/index.tsx +3 -0
  60. package/src/definitions/helpers/generateDocumentTitle/index.ts +5 -3
  61. package/src/definitions/helpers/handleRefineOptions/index.ts +1 -0
  62. package/src/definitions/helpers/pick-resource/index.ts +4 -3
  63. package/src/hooks/data/useCreate.ts +49 -23
  64. package/src/hooks/data/useCreateMany.ts +54 -26
  65. package/src/hooks/data/useCustom.ts +17 -3
  66. package/src/hooks/data/useCustomMutation.ts +16 -3
  67. package/src/hooks/data/useDelete.ts +60 -31
  68. package/src/hooks/data/useDeleteMany.ts +64 -31
  69. package/src/hooks/data/useInfiniteList.ts +30 -14
  70. package/src/hooks/data/useList.ts +30 -20
  71. package/src/hooks/data/useMany.ts +34 -23
  72. package/src/hooks/data/useOne.ts +36 -22
  73. package/src/hooks/data/useUpdate.ts +55 -32
  74. package/src/hooks/data/useUpdateMany.ts +69 -33
  75. package/src/hooks/export/index.ts +12 -11
  76. package/src/hooks/form/useForm.ts +46 -98
  77. package/src/hooks/import/index.tsx +17 -17
  78. package/src/hooks/index.ts +1 -0
  79. package/src/hooks/live/useResourceSubscription/index.ts +6 -3
  80. package/src/hooks/resource/useResource/index.ts +48 -1
  81. package/src/hooks/show/useShow.ts +34 -80
  82. package/src/hooks/useLoadingOvertime/index.ts +114 -0
  83. package/src/hooks/useSelect/index.ts +21 -14
  84. package/src/hooks/useTable/index.ts +22 -8
@@ -3,8 +3,6 @@ import { QueryObserverResult, UseQueryOptions } from "@tanstack/react-query";
3
3
  import warnOnce from "warn-once";
4
4
 
5
5
  import {
6
- useResourceWithRoute,
7
- useRouterContext,
8
6
  useWarnAboutChange,
9
7
  useCreate,
10
8
  useUpdate,
@@ -21,7 +19,6 @@ import {
21
19
  GetOneResponse,
22
20
  HttpError,
23
21
  LiveModeProps,
24
- ResourceRouterParams,
25
22
  RedirectAction,
26
23
  SuccessErrorNotification,
27
24
  UpdateResponse,
@@ -29,7 +26,6 @@ import {
29
26
  BaseKey,
30
27
  IQueryKeys,
31
28
  FormAction,
32
- IResourceItem,
33
29
  MetaQuery,
34
30
  } from "../../interfaces";
35
31
  import {
@@ -39,11 +35,13 @@ import {
39
35
  } from "../data/useUpdate";
40
36
  import { UseCreateProps, UseCreateReturnType } from "../data/useCreate";
41
37
  import { redirectPage } from "@definitions/helpers";
42
- import { useRouterType } from "@contexts/router-picker";
43
- import { useParsed } from "@hooks/router/use-parsed";
44
- import { pickResource } from "@definitions/helpers/pick-resource";
45
38
  import { useResource } from "../resource/useResource";
46
39
  import { pickNotDeprecated } from "@definitions/helpers";
40
+ import {
41
+ useLoadingOvertime,
42
+ UseLoadingOvertimeOptionsProps,
43
+ UseLoadingOvertimeReturnType,
44
+ } from "../useLoadingOvertime";
47
45
 
48
46
  export type ActionParams = {
49
47
  /**
@@ -178,7 +176,8 @@ export type UseFormProps<
178
176
  TResponseError
179
177
  > &
180
178
  ActionParams &
181
- LiveModeProps;
179
+ LiveModeProps &
180
+ UseLoadingOvertimeOptionsProps;
182
181
 
183
182
  export type UseFormReturnType<
184
183
  TQueryFnData extends BaseRecord = BaseRecord,
@@ -203,7 +202,7 @@ export type UseFormReturnType<
203
202
  idFromFunction?: BaseKey | undefined,
204
203
  routeParams?: Record<string, string | number>,
205
204
  ) => void;
206
- };
205
+ } & UseLoadingOvertimeReturnType;
207
206
 
208
207
  /**
209
208
  * `useForm` is used to manage forms. It uses Ant Design {@link https://ant.design/components/form/ Form} data scope management under the hood and returns the required props for managing the form actions.
@@ -248,6 +247,7 @@ export const useForm = <
248
247
  queryOptions,
249
248
  createMutationOptions,
250
249
  updateMutationOptions,
250
+ overtimeOptions,
251
251
  }: UseFormProps<
252
252
  TQueryFnData,
253
253
  TError,
@@ -264,37 +264,28 @@ export const useForm = <
264
264
  TResponseError
265
265
  > => {
266
266
  const { options } = useRefineContext();
267
- const { resources } = useResource();
268
- const routerType = useRouterType();
269
- const {
270
- resource: resourceFromRouter,
271
- id: idFromRouter,
272
- action: actionFromRouter,
273
- } = useParsed();
274
- const { useParams } = useRouterContext();
275
- const {
276
- resource: legacyResourceFromRoute,
277
- action: legacyActionFromRoute,
278
- id: legacyIdFromParams,
279
- } = useParams<ResourceRouterParams>();
280
267
  const getMeta = useMeta();
281
268
 
282
- const newResourceNameFromRouter =
283
- typeof resourceFromRouter === "string"
284
- ? resourceFromRouter
285
- : resourceFromRouter?.name;
269
+ const {
270
+ resource,
271
+ id: idFromRoute,
272
+ action: actionFromRoute,
273
+ identifier,
274
+ } = useResource(resourceFromProps);
275
+ const { identifier: inferredIdentifier } = useResource();
286
276
 
287
277
  /** We only accept `id` from URL params if `resource` is not explicitly passed. */
288
278
  /** This is done to avoid sending wrong requests for custom `resource` and an async `id` */
289
- const defaultId =
290
- !resourceFromProps ||
291
- resourceFromProps ===
292
- (routerType === "legacy"
293
- ? legacyResourceFromRoute
294
- : newResourceNameFromRouter)
295
- ? idFromProps ??
296
- (routerType === "legacy" ? legacyIdFromParams : idFromRouter)
297
- : idFromProps;
279
+ const getDefaultId = () => {
280
+ const idFromPropsOrRoute = idFromProps ?? idFromRoute;
281
+
282
+ if (resourceFromProps && resourceFromProps !== inferredIdentifier) {
283
+ return idFromProps;
284
+ }
285
+
286
+ return idFromPropsOrRoute;
287
+ };
288
+ const defaultId = getDefaultId();
298
289
 
299
290
  // id state is needed to determine selected record in a context for example useModal
300
291
  const [id, setId] = React.useState<BaseKey | undefined>(defaultId);
@@ -310,65 +301,13 @@ export const useForm = <
310
301
  setId(defaultId);
311
302
  }, [defaultId]);
312
303
 
313
- /** `resourceName` fallback value depends on the router type */
314
- const resourceName =
315
- resourceFromProps ??
316
- (routerType === "legacy"
317
- ? legacyResourceFromRoute
318
- : newResourceNameFromRouter);
319
- /** `action` fallback value depends on the router type */
320
- /**
321
- * In earlier versions, we've trivially inferred the action type as `create` in `show` types.
322
- * This is probably done to cover cases with modals and drawers.
323
- *
324
- * This is not right, as we should not do trivial inference of the action type.
325
- * Users should explicitly pass the action type when needed.
326
- */
327
- const fallbackAction =
328
- routerType === "legacy" ? legacyActionFromRoute : actionFromRouter;
329
- const action =
330
- actionFromProps ??
331
- (fallbackAction === "edit" || fallbackAction === "clone"
332
- ? fallbackAction
333
- : "create");
334
-
335
- const resourceWithRoute = useResourceWithRoute();
336
- let resource: IResourceItem | undefined;
337
-
338
- if (routerType === "legacy") {
339
- if (resourceName) {
340
- resource = resourceWithRoute(resourceName);
341
- }
342
- } else {
343
- /** If `resource` is provided by the user, then try to pick the resource of create a dummy one */
344
- if (resourceFromProps) {
345
- const picked = pickResource(resourceFromProps, resources);
346
- if (picked) {
347
- resource = picked;
348
- } else {
349
- resource = {
350
- name: resourceFromProps,
351
- route: resourceFromProps,
352
- };
353
- }
354
- } else {
355
- /** If `resource` is not provided, check the resource from the router params */
356
- if (typeof resourceFromRouter === "string") {
357
- const picked = pickResource(resourceFromRouter, resources);
358
- if (picked) {
359
- resource = picked;
360
- } else {
361
- resource = {
362
- name: resourceFromRouter,
363
- route: resourceFromRouter,
364
- };
365
- }
366
- } else {
367
- /** If `resource` is passed as an IResourceItem, use it or `resource` is undefined and cannot be inferred. */
368
- resource = resourceFromRouter;
369
- }
370
- }
371
- }
304
+ const getAction = () => {
305
+ if (actionFromProps) return actionFromProps;
306
+ else if (actionFromRoute === "edit" || actionFromRoute === "clone")
307
+ return actionFromRoute;
308
+ else return "create";
309
+ };
310
+ const action = getAction();
372
311
 
373
312
  const combinedMeta = getMeta({
374
313
  resource,
@@ -386,7 +325,7 @@ export const useForm = <
386
325
  (isClone || isEdit) &&
387
326
  Boolean(resourceFromProps) &&
388
327
  !Boolean(idFromProps),
389
- `[useForm]: action: "${action}", resource: "${resourceName}", id: ${id} \n\n` +
328
+ `[useForm]: action: "${action}", resource: "${identifier}", id: ${id} \n\n` +
390
329
  `If you don't use the \`setId\` method to set the \`id\`, you should pass the \`id\` prop to \`useForm\`. Otherwise, \`useForm\` will not be able to infer the \`id\` from the current URL. \n\n` +
391
330
  `See https://refine.dev/docs/api-reference/core/hooks/useForm/#resource`,
392
331
  );
@@ -403,7 +342,7 @@ export const useForm = <
403
342
  const enableQuery = id !== undefined && (isEdit || isClone);
404
343
 
405
344
  const queryResult = useOne<TQueryFnData, TError, TData>({
406
- resource: resource?.name,
345
+ resource: identifier,
407
346
  id: id ?? "",
408
347
  queryOptions: {
409
348
  enabled: enableQuery,
@@ -472,7 +411,7 @@ export const useForm = <
472
411
  return mutateCreate(
473
412
  {
474
413
  values,
475
- resource: resource.name,
414
+ resource: identifier ?? resource.name,
476
415
  successNotification,
477
416
  errorNotification,
478
417
  meta: { ...combinedMeta, ...mutationMeta },
@@ -512,7 +451,7 @@ export const useForm = <
512
451
  const variables: UpdateParams<TResponse, TResponseError, TVariables> = {
513
452
  id: id ?? "",
514
453
  values,
515
- resource: resource.name,
454
+ resource: identifier ?? resource.name,
516
455
  mutationMode,
517
456
  undoableTimeout,
518
457
  successNotification,
@@ -584,6 +523,12 @@ export const useForm = <
584
523
 
585
524
  const result = isCreate || isClone ? createResult : editResult;
586
525
 
526
+ const { elapsedTime } = useLoadingOvertime({
527
+ isLoading: result.mutationResult.isLoading || queryResult.isFetching,
528
+ interval: overtimeOptions?.interval,
529
+ onInterval: overtimeOptions?.onInterval,
530
+ });
531
+
587
532
  return {
588
533
  ...result,
589
534
  queryResult,
@@ -602,5 +547,8 @@ export const useForm = <
602
547
  meta: pickNotDeprecated(meta, metaData),
603
548
  });
604
549
  },
550
+ overtime: {
551
+ elapsedTime,
552
+ },
605
553
  };
606
554
  };
@@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
2
2
  import { parse, ParseConfig } from "papaparse";
3
3
  import chunk from "lodash/chunk";
4
4
 
5
- import { useCreate, useCreateMany, useResource } from "@hooks";
5
+ import { useCreate, useCreateMany, useMeta, useResource } from "@hooks";
6
6
  import { MapDataFn, BaseRecord, HttpError, MetaQuery } from "../../interfaces";
7
7
  import {
8
8
  importCSVMapper,
@@ -151,11 +151,20 @@ export const useImport = <
151
151
  const [totalAmount, setTotalAmount] = useState<number>(0);
152
152
  const [isLoading, setIsLoading] = useState(false);
153
153
 
154
- const { resource } = useResource(resourceFromProps ?? resourceName);
154
+ const { resource, identifier } = useResource(
155
+ resourceFromProps ?? resourceName,
156
+ );
157
+
158
+ const getMeta = useMeta();
155
159
 
156
160
  const createMany = useCreateMany<TData, TError, TVariables>();
157
161
  const create = useCreate<TData, TError, TVariables>();
158
162
 
163
+ const combinedMeta = getMeta({
164
+ resource,
165
+ meta: pickNotDeprecated(meta, metaData),
166
+ });
167
+
159
168
  let mutationResult:
160
169
  | UseCreateReturnType<TData, TError, TVariables>
161
170
  | UseCreateManyReturnType<TData, TError, TVariables>;
@@ -208,16 +217,13 @@ export const useImport = <
208
217
  const valueFns = values.map((value) => {
209
218
  const fn = async () => {
210
219
  const response = await create.mutateAsync({
211
- resource: resource?.name ?? "",
220
+ resource: identifier ?? "",
212
221
  values: value,
213
222
  successNotification: false,
214
223
  errorNotification: false,
215
224
  dataProviderName,
216
- meta: pickNotDeprecated(meta, metaData),
217
- metaData: pickNotDeprecated(
218
- meta,
219
- metaData,
220
- ),
225
+ meta: combinedMeta,
226
+ metaData: combinedMeta,
221
227
  });
222
228
 
223
229
  return { response, value };
@@ -256,19 +262,13 @@ export const useImport = <
256
262
  const fn = async () => {
257
263
  const response =
258
264
  await createMany.mutateAsync({
259
- resource: resource?.name ?? "",
265
+ resource: identifier ?? "",
260
266
  values: chunkedValues,
261
267
  successNotification: false,
262
268
  errorNotification: false,
263
269
  dataProviderName,
264
- meta: pickNotDeprecated(
265
- meta,
266
- metaData,
267
- ),
268
- metaData: pickNotDeprecated(
269
- meta,
270
- metaData,
271
- ),
270
+ meta: combinedMeta,
271
+ metaData: combinedMeta,
272
272
  });
273
273
 
274
274
  return {
@@ -23,3 +23,4 @@ export * from "./invalidate";
23
23
  export * from "./breadcrumb";
24
24
  export * from "./menu";
25
25
  export * from "./useMeta";
26
+ export * from "./useLoadingOvertime";
@@ -14,6 +14,7 @@ import {
14
14
  import { LiveContext } from "@contexts/live";
15
15
  import { RefineContext } from "@contexts/refine";
16
16
  import { queryKeys } from "@definitions";
17
+ import { useResource } from "@hooks/resource";
17
18
 
18
19
  export type UseResourceSubscriptionProps = {
19
20
  channel: string;
@@ -49,7 +50,7 @@ export type PublishType = {
49
50
  };
50
51
 
51
52
  export const useResourceSubscription = ({
52
- resource,
53
+ resource: resourceFromProp,
53
54
  params,
54
55
  channel,
55
56
  types,
@@ -58,7 +59,9 @@ export const useResourceSubscription = ({
58
59
  onLiveEvent,
59
60
  }: UseResourceSubscriptionProps): void => {
60
61
  const queryClient = useQueryClient();
61
- const queryKey = queryKeys(resource);
62
+
63
+ const { resource, identifier } = useResource(resourceFromProp);
64
+ const queryKey = queryKeys(identifier);
62
65
 
63
66
  const liveDataContext = useContext<ILiveContext>(LiveContext);
64
67
  const {
@@ -75,7 +78,7 @@ export const useResourceSubscription = ({
75
78
  subscription = liveDataContext?.subscribe({
76
79
  channel,
77
80
  params: {
78
- resource,
81
+ resource: resource?.name,
79
82
  ...params,
80
83
  },
81
84
  types,
@@ -37,7 +37,11 @@ export type UseResourceLegacyProps = {
37
37
  */
38
38
  export type UseResourceParam = string | undefined;
39
39
 
40
- type UseResourceReturnType = {
40
+ type SelectReturnType<T extends boolean> = T extends true
41
+ ? { resource: IResourceItem; identifier: string }
42
+ : { resource: IResourceItem; identifier: string } | undefined;
43
+
44
+ export type UseResourceReturnType = {
41
45
  resources: IResourceItem[];
42
46
  resource?: IResourceItem;
43
47
  /**
@@ -46,10 +50,16 @@ type UseResourceReturnType = {
46
50
  resourceName?: string;
47
51
  id?: BaseKey;
48
52
  action?: Action;
53
+ select: <T extends boolean = true>(
54
+ resourceName: string,
55
+ force?: T,
56
+ ) => SelectReturnType<T>;
57
+ identifier?: string;
49
58
  };
50
59
 
51
60
  type UseResourceReturnTypeWithResource = UseResourceReturnType & {
52
61
  resource: IResourceItem;
62
+ identifier: string;
53
63
  };
54
64
 
55
65
  /**
@@ -89,6 +99,37 @@ export function useResource(
89
99
  args && typeof args !== "string" ? args.recordItemId : undefined,
90
100
  };
91
101
 
102
+ const select = <T extends boolean = true>(
103
+ resourceName: string,
104
+ force = true,
105
+ ): SelectReturnType<T> => {
106
+ const isLegacy = routerType === "legacy";
107
+ const pickedResource = pickResource(resourceName, resources, isLegacy);
108
+
109
+ if (pickedResource) {
110
+ return {
111
+ resource: pickedResource,
112
+ identifier: pickedResource.identifier ?? pickedResource.name,
113
+ } as SelectReturnType<T>;
114
+ }
115
+
116
+ if (force) {
117
+ const resource: IResourceItem = {
118
+ name: resourceName,
119
+ identifier: resourceName,
120
+ };
121
+
122
+ const identifier = resource.identifier ?? resource.name;
123
+
124
+ return {
125
+ resource,
126
+ identifier,
127
+ } as SelectReturnType<T>;
128
+ }
129
+
130
+ return undefined as SelectReturnType<T>;
131
+ };
132
+
92
133
  /**
93
134
  * Legacy Router - Start
94
135
  *
@@ -112,6 +153,8 @@ export function useResource(
112
153
  const legacyAction = legacyParams.action;
113
154
  const legacyResourceName =
114
155
  oldProps?.resourceName ?? legacyResource?.name;
156
+ const legacyIdentifier =
157
+ legacyResource?.identifier ?? legacyResource?.name;
115
158
 
116
159
  return {
117
160
  resources,
@@ -119,6 +162,8 @@ export function useResource(
119
162
  resourceName: legacyResourceName,
120
163
  id: legacyId,
121
164
  action: legacyAction,
165
+ select,
166
+ identifier: legacyIdentifier,
122
167
  };
123
168
  }
124
169
  /** Legacy Router - End */
@@ -147,5 +192,7 @@ export function useResource(
147
192
  resourceName: resource?.name,
148
193
  id: params.id,
149
194
  action: params.action,
195
+ select,
196
+ identifier: resource?.identifier ?? resource?.name,
150
197
  };
151
198
  }
@@ -2,15 +2,9 @@ import React, { useState } from "react";
2
2
  import { QueryObserverResult, UseQueryOptions } from "@tanstack/react-query";
3
3
  import warnOnce from "warn-once";
4
4
 
5
- import {
6
- useMeta,
7
- useOne,
8
- useResourceWithRoute,
9
- useRouterContext,
10
- } from "@hooks";
5
+ import { useMeta, useOne } from "@hooks";
11
6
 
12
7
  import {
13
- ResourceRouterParams,
14
8
  BaseRecord,
15
9
  GetOneResponse,
16
10
  SuccessErrorNotification,
@@ -18,20 +12,21 @@ import {
18
12
  LiveModeProps,
19
13
  BaseKey,
20
14
  HttpError,
21
- IResourceItem,
22
15
  Prettify,
23
16
  } from "../../interfaces";
24
- import { useRouterType } from "@contexts/router-picker";
25
- import { useParsed } from "@hooks/router/use-parsed";
26
- import { pickResource } from "@definitions/helpers/pick-resource";
27
17
  import { useResource } from "../resource/useResource";
28
18
  import { pickNotDeprecated } from "@definitions/helpers";
19
+ import {
20
+ useLoadingOvertime,
21
+ UseLoadingOvertimeOptionsProps,
22
+ UseLoadingOvertimeReturnType,
23
+ } from "../useLoadingOvertime";
29
24
 
30
25
  export type useShowReturnType<TData extends BaseRecord = BaseRecord> = {
31
26
  queryResult: QueryObserverResult<GetOneResponse<TData>>;
32
27
  showId?: BaseKey;
33
28
  setShowId: React.Dispatch<React.SetStateAction<BaseKey | undefined>>;
34
- };
29
+ } & UseLoadingOvertimeReturnType;
35
30
 
36
31
  export type useShowProps<
37
32
  TQueryFnData extends BaseRecord = BaseRecord,
@@ -75,7 +70,8 @@ export type useShowProps<
75
70
  GetOneResponse<TData>,
76
71
  TError,
77
72
  Prettify<{ id?: BaseKey } & MetaQuery>
78
- >;
73
+ > &
74
+ UseLoadingOvertimeOptionsProps;
79
75
 
80
76
  /**
81
77
  * `useShow` hook allows you to fetch the desired record.
@@ -105,33 +101,30 @@ export const useShow = <
105
101
  onLiveEvent,
106
102
  dataProviderName,
107
103
  queryOptions,
104
+ overtimeOptions,
108
105
  }: useShowProps<
109
106
  TQueryFnData,
110
107
  TError,
111
108
  TData
112
109
  > = {}): useShowReturnType<TData> => {
113
- const routerType = useRouterType();
114
- const { resources } = useResource();
115
- const { useParams } = useRouterContext();
116
- const { resource: resourceFromRouter, id: idFromRouter } = useParsed();
117
-
118
- const { resource: legacyResourceFromRoute, id: legacyIdFromParams } =
119
- useParams<ResourceRouterParams>();
110
+ const {
111
+ resource,
112
+ id: idFromRoute,
113
+ identifier,
114
+ } = useResource(resourceFromProp);
115
+ const { identifier: inferredIdentifier } = useResource();
120
116
  const getMeta = useMeta();
121
117
 
122
- const newResourceNameFromRouter = resourceFromRouter?.name;
118
+ const getDefaultId = () => {
119
+ const idFromPropsOrRoute = id ?? idFromRoute;
120
+
121
+ if (resourceFromProp && resourceFromProp !== inferredIdentifier) {
122
+ return id;
123
+ }
123
124
 
124
- /** We only accept `id` from URL params if `resource` is not explicitly passed. */
125
- /** This is done to avoid sending wrong requests for custom `resource` and an async `id` */
126
- const defaultId =
127
- !resourceFromProp ||
128
- resourceFromProp ===
129
- (routerType === "legacy"
130
- ? legacyResourceFromRoute
131
- : newResourceNameFromRouter)
132
- ? id ??
133
- (routerType === "legacy" ? legacyIdFromParams : idFromRouter)
134
- : id;
125
+ return idFromPropsOrRoute;
126
+ };
127
+ const defaultId = getDefaultId();
135
128
 
136
129
  const [showId, setShowId] = useState<BaseKey | undefined>(defaultId);
137
130
 
@@ -139,52 +132,6 @@ export const useShow = <
139
132
  setShowId(defaultId);
140
133
  }, [defaultId]);
141
134
 
142
- /** `resourceName` fallback value depends on the router type */
143
- const resourceName =
144
- resourceFromProp ??
145
- (routerType === "legacy"
146
- ? legacyResourceFromRoute
147
- : newResourceNameFromRouter);
148
-
149
- let resource: IResourceItem | undefined;
150
-
151
- const resourceWithRoute = useResourceWithRoute();
152
-
153
- if (routerType === "legacy") {
154
- if (resourceName) {
155
- resource = resourceWithRoute(resourceName);
156
- }
157
- } else {
158
- /** If `resource` is provided by the user, then try to pick the resource of create a dummy one */
159
- if (resourceFromProp) {
160
- const picked = pickResource(resourceFromProp, resources);
161
- if (picked) {
162
- resource = picked;
163
- } else {
164
- resource = {
165
- name: resourceFromProp,
166
- route: resourceFromProp,
167
- };
168
- }
169
- } else {
170
- /** If `resource` is not provided, check the resource from the router params */
171
- if (typeof resourceFromRouter === "string") {
172
- const picked = pickResource(resourceFromRouter, resources);
173
- if (picked) {
174
- resource = picked;
175
- } else {
176
- resource = {
177
- name: resourceFromRouter,
178
- route: resourceFromRouter,
179
- };
180
- }
181
- } else {
182
- /** If `resource` is passed as an IResourceItem, use it or `resource` is undefined and cannot be inferred. */
183
- resource = resourceFromRouter;
184
- }
185
- }
186
- }
187
-
188
135
  const combinedMeta = getMeta({
189
136
  resource,
190
137
  meta: pickNotDeprecated(meta, metaData),
@@ -192,13 +139,13 @@ export const useShow = <
192
139
 
193
140
  warnOnce(
194
141
  Boolean(resourceFromProp) && !Boolean(id),
195
- `[useShow]: resource: "${resourceName}", id: ${id} \n\n` +
142
+ `[useShow]: resource: "${identifier}", id: ${id} \n\n` +
196
143
  `If you don't use the \`setShowId\` method to set the \`showId\`, you should pass the \`id\` prop to \`useShow\`. Otherwise, \`useShow\` will not be able to infer the \`id\` from the current URL. \n\n` +
197
144
  `See https://refine.dev/docs/api-reference/core/hooks/show/useShow/#resource`,
198
145
  );
199
146
 
200
147
  const queryResult = useOne<TQueryFnData, TError, TData>({
201
- resource: resource?.name,
148
+ resource: identifier,
202
149
  id: showId ?? "",
203
150
  queryOptions: {
204
151
  enabled: showId !== undefined,
@@ -213,9 +160,16 @@ export const useShow = <
213
160
  dataProviderName,
214
161
  });
215
162
 
163
+ const { elapsedTime } = useLoadingOvertime({
164
+ isLoading: queryResult.isFetching,
165
+ interval: overtimeOptions?.interval,
166
+ onInterval: overtimeOptions?.onInterval,
167
+ });
168
+
216
169
  return {
217
170
  queryResult,
218
171
  showId,
219
172
  setShowId,
173
+ overtime: { elapsedTime },
220
174
  };
221
175
  };