@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.
- package/CHANGELOG.md +180 -0
- package/dist/components/canAccess/index.d.ts.map +1 -1
- package/dist/contexts/refine/IRefineContext.d.ts +3 -0
- package/dist/contexts/refine/IRefineContext.d.ts.map +1 -1
- package/dist/contexts/refine/index.d.ts.map +1 -1
- package/dist/definitions/helpers/generateDocumentTitle/index.d.ts.map +1 -1
- package/dist/definitions/helpers/handleRefineOptions/index.d.ts.map +1 -1
- package/dist/definitions/helpers/pick-resource/index.d.ts.map +1 -1
- package/dist/esm/index.js +6 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/hooks/data/useCreate.d.ts +3 -2
- package/dist/hooks/data/useCreate.d.ts.map +1 -1
- package/dist/hooks/data/useCreateMany.d.ts +3 -2
- package/dist/hooks/data/useCreateMany.d.ts.map +1 -1
- package/dist/hooks/data/useCustom.d.ts +3 -2
- package/dist/hooks/data/useCustom.d.ts.map +1 -1
- package/dist/hooks/data/useCustomMutation.d.ts +3 -2
- package/dist/hooks/data/useCustomMutation.d.ts.map +1 -1
- package/dist/hooks/data/useDelete.d.ts +4 -3
- package/dist/hooks/data/useDelete.d.ts.map +1 -1
- package/dist/hooks/data/useDeleteMany.d.ts +4 -3
- package/dist/hooks/data/useDeleteMany.d.ts.map +1 -1
- package/dist/hooks/data/useInfiniteList.d.ts +3 -2
- package/dist/hooks/data/useInfiniteList.d.ts.map +1 -1
- package/dist/hooks/data/useList.d.ts +3 -2
- package/dist/hooks/data/useList.d.ts.map +1 -1
- package/dist/hooks/data/useMany.d.ts +3 -2
- package/dist/hooks/data/useMany.d.ts.map +1 -1
- package/dist/hooks/data/useOne.d.ts +3 -2
- package/dist/hooks/data/useOne.d.ts.map +1 -1
- package/dist/hooks/data/useUpdate.d.ts +4 -3
- package/dist/hooks/data/useUpdate.d.ts.map +1 -1
- package/dist/hooks/data/useUpdateMany.d.ts +4 -3
- package/dist/hooks/data/useUpdateMany.d.ts.map +1 -1
- package/dist/hooks/export/index.d.ts.map +1 -1
- package/dist/hooks/form/useForm.d.ts +4 -3
- package/dist/hooks/form/useForm.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/live/useResourceSubscription/index.d.ts +1 -1
- package/dist/hooks/live/useResourceSubscription/index.d.ts.map +1 -1
- package/dist/hooks/resource/useResource/index.d.ts +11 -1
- package/dist/hooks/resource/useResource/index.d.ts.map +1 -1
- package/dist/hooks/show/useShow.d.ts +4 -3
- package/dist/hooks/show/useShow.d.ts.map +1 -1
- package/dist/hooks/useLoadingOvertime/index.d.ts +49 -0
- package/dist/hooks/useLoadingOvertime/index.d.ts.map +1 -0
- package/dist/hooks/useSelect/index.d.ts +3 -2
- package/dist/hooks/useSelect/index.d.ts.map +1 -1
- package/dist/hooks/useTable/index.d.ts +4 -3
- package/dist/hooks/useTable/index.d.ts.map +1 -1
- package/dist/iife/index.js +6 -6
- package/dist/iife/index.js.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/canAccess/index.tsx +17 -92
- package/src/contexts/refine/IRefineContext.ts +3 -0
- package/src/contexts/refine/index.tsx +3 -0
- package/src/definitions/helpers/generateDocumentTitle/index.ts +5 -3
- package/src/definitions/helpers/handleRefineOptions/index.ts +1 -0
- package/src/definitions/helpers/pick-resource/index.ts +4 -3
- package/src/hooks/data/useCreate.ts +49 -23
- package/src/hooks/data/useCreateMany.ts +54 -26
- package/src/hooks/data/useCustom.ts +17 -3
- package/src/hooks/data/useCustomMutation.ts +16 -3
- package/src/hooks/data/useDelete.ts +60 -31
- package/src/hooks/data/useDeleteMany.ts +64 -31
- package/src/hooks/data/useInfiniteList.ts +30 -14
- package/src/hooks/data/useList.ts +30 -20
- package/src/hooks/data/useMany.ts +34 -23
- package/src/hooks/data/useOne.ts +36 -22
- package/src/hooks/data/useUpdate.ts +55 -32
- package/src/hooks/data/useUpdateMany.ts +69 -33
- package/src/hooks/export/index.ts +12 -11
- package/src/hooks/form/useForm.ts +46 -98
- package/src/hooks/import/index.tsx +17 -17
- package/src/hooks/index.ts +1 -0
- package/src/hooks/live/useResourceSubscription/index.ts +6 -3
- package/src/hooks/resource/useResource/index.ts +48 -1
- package/src/hooks/show/useShow.ts +34 -80
- package/src/hooks/useLoadingOvertime/index.ts +114 -0
- package/src/hooks/useSelect/index.ts +21 -14
- 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
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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: "${
|
|
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:
|
|
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(
|
|
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:
|
|
220
|
+
resource: identifier ?? "",
|
|
212
221
|
values: value,
|
|
213
222
|
successNotification: false,
|
|
214
223
|
errorNotification: false,
|
|
215
224
|
dataProviderName,
|
|
216
|
-
meta:
|
|
217
|
-
metaData:
|
|
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:
|
|
265
|
+
resource: identifier ?? "",
|
|
260
266
|
values: chunkedValues,
|
|
261
267
|
successNotification: false,
|
|
262
268
|
errorNotification: false,
|
|
263
269
|
dataProviderName,
|
|
264
|
-
meta:
|
|
265
|
-
|
|
266
|
-
metaData,
|
|
267
|
-
),
|
|
268
|
-
metaData: pickNotDeprecated(
|
|
269
|
-
meta,
|
|
270
|
-
metaData,
|
|
271
|
-
),
|
|
270
|
+
meta: combinedMeta,
|
|
271
|
+
metaData: combinedMeta,
|
|
272
272
|
});
|
|
273
273
|
|
|
274
274
|
return {
|
package/src/hooks/index.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const {
|
|
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
|
|
118
|
+
const getDefaultId = () => {
|
|
119
|
+
const idFromPropsOrRoute = id ?? idFromRoute;
|
|
120
|
+
|
|
121
|
+
if (resourceFromProp && resourceFromProp !== inferredIdentifier) {
|
|
122
|
+
return id;
|
|
123
|
+
}
|
|
123
124
|
|
|
124
|
-
|
|
125
|
-
|
|
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: "${
|
|
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:
|
|
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
|
};
|