@refinedev/core 4.36.2 → 4.37.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@refinedev/core",
3
- "version": "4.36.2",
3
+ "version": "4.37.0",
4
4
  "description": "refine is a React-based framework for building internal tools, rapidly. It ships with Ant Design System, an enterprise-level UI toolkit.",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -1,8 +1,21 @@
1
- import React from "react";
1
+ import React, { useEffect } from "react";
2
2
 
3
3
  import { useCan, useResource } from "@hooks";
4
4
  import { BaseKey, IResourceItem, ITreeMenu } from "../../interfaces";
5
5
 
6
+ type CanParams = {
7
+ resource?: IResourceItem & { children?: ITreeMenu[] };
8
+ id?: BaseKey;
9
+ [key: string]: any;
10
+ };
11
+
12
+ type OnUnauthorizedProps = {
13
+ resource?: string;
14
+ reason?: string;
15
+ action: string;
16
+ params: CanParams;
17
+ };
18
+
6
19
  type CanAccessBaseProps = {
7
20
  /**
8
21
  * Resource name for API data interactions
@@ -16,15 +29,15 @@ type CanAccessBaseProps = {
16
29
  * Parameters associated with the resource
17
30
  * @type { resource?: [IResourceItem](https://refine.dev/docs/api-reference/core/interfaceReferences/#canparams), id?: [BaseKey](https://refine.dev/docs/api-reference/core/interfaceReferences/#basekey), [key: string]: any }
18
31
  */
19
- params?: {
20
- resource?: IResourceItem & { children?: ITreeMenu[] };
21
- id?: BaseKey;
22
- [key: string]: any;
23
- };
32
+ params?: CanParams;
24
33
  /**
25
34
  * Content to show if access control returns `false`
26
35
  */
27
36
  fallback?: React.ReactNode;
37
+ /**
38
+ * Callback function to be called if access control returns `can: false`
39
+ */
40
+ onUnauthorized?: (props: OnUnauthorizedProps) => void;
28
41
  children: React.ReactNode;
29
42
  };
30
43
 
@@ -42,8 +55,9 @@ export type CanAccessProps = CanAccessBaseProps | CanAccessWithoutParamsProps;
42
55
  export const CanAccess: React.FC<CanAccessProps> = ({
43
56
  resource: resourceFromProp,
44
57
  action: actionFromProp,
45
- params,
58
+ params: paramsFromProp,
46
59
  fallback,
60
+ onUnauthorized,
47
61
  children,
48
62
  ...rest
49
63
  }) => {
@@ -55,25 +69,40 @@ export const CanAccess: React.FC<CanAccessProps> = ({
55
69
  const { identifier } = useResource();
56
70
 
57
71
  const getDefaultId = () => {
58
- const idFromPropsOrRoute = params?.id ?? idFromRoute;
72
+ const idFromPropsOrRoute = paramsFromProp?.id ?? idFromRoute;
59
73
 
60
74
  if (resourceFromProp && resourceFromProp !== identifier) {
61
- return params?.id;
75
+ return paramsFromProp?.id;
62
76
  }
63
77
 
64
78
  return idFromPropsOrRoute;
65
79
  };
66
80
  const defaultId = getDefaultId();
67
81
 
82
+ const resourceName = resourceFromProp ?? resource?.name;
83
+ const action = actionFromProp ?? actionFromRoute ?? "";
84
+ const params = paramsFromProp ?? {
85
+ id: defaultId,
86
+ resource: resource,
87
+ };
88
+
68
89
  const { data } = useCan({
69
- resource: resourceFromProp ?? resource?.name,
70
- action: actionFromProp ?? actionFromRoute ?? "",
71
- params: params ?? {
72
- id: defaultId,
73
- resource: resource,
74
- },
90
+ resource: resourceName,
91
+ action,
92
+ params,
75
93
  });
76
94
 
95
+ useEffect(() => {
96
+ if (onUnauthorized && data?.can === false) {
97
+ onUnauthorized({
98
+ resource: resourceName,
99
+ action,
100
+ reason: data?.reason,
101
+ params,
102
+ });
103
+ }
104
+ }, [data?.can]);
105
+
77
106
  if (data?.can) {
78
107
  if (React.isValidElement(children)) {
79
108
  const Children = React.cloneElement(children, rest);
@@ -332,7 +332,8 @@ export const useForm = <
332
332
  warnOnce(
333
333
  (isClone || isEdit) &&
334
334
  Boolean(resourceFromProps) &&
335
- !Boolean(idFromProps),
335
+ !Boolean(idFromProps) &&
336
+ queryOptions?.enabled !== false,
336
337
  `[useForm]: action: "${action}", resource: "${identifier}", id: ${id} \n\n` +
337
338
  `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` +
338
339
  `See https://refine.dev/docs/api-reference/core/hooks/useForm/#resource`,