@refinedev/core 4.26.4 → 4.28.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 (44) hide show
  1. package/CHANGELOG.md +256 -0
  2. package/dist/contexts/refine/IRefineContext.d.ts +7 -0
  3. package/dist/contexts/refine/IRefineContext.d.ts.map +1 -1
  4. package/dist/contexts/refine/index.d.ts.map +1 -1
  5. package/dist/definitions/helpers/handleRefineOptions/index.d.ts.map +1 -1
  6. package/dist/esm/index.js +7 -7
  7. package/dist/esm/index.js.map +1 -1
  8. package/dist/hooks/data/useDelete.d.ts +28 -0
  9. package/dist/hooks/data/useDelete.d.ts.map +1 -1
  10. package/dist/hooks/data/useDeleteMany.d.ts +28 -0
  11. package/dist/hooks/data/useDeleteMany.d.ts.map +1 -1
  12. package/dist/hooks/data/useUpdate.d.ts +1 -1
  13. package/dist/hooks/data/useUpdateMany.d.ts +25 -0
  14. package/dist/hooks/data/useUpdateMany.d.ts.map +1 -1
  15. package/dist/hooks/form/useForm.d.ts +6 -6
  16. package/dist/hooks/form/useForm.d.ts.map +1 -1
  17. package/dist/iife/index.js +7 -7
  18. package/dist/iife/index.js.map +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +7 -7
  22. package/dist/index.js.map +1 -1
  23. package/dist/interfaces/autoSave.d.ts +28 -0
  24. package/dist/interfaces/autoSave.d.ts.map +1 -0
  25. package/dist/interfaces/errors/HttpError.d.ts +7 -0
  26. package/dist/interfaces/errors/HttpError.d.ts.map +1 -1
  27. package/dist/interfaces/index.d.ts +1 -0
  28. package/dist/interfaces/index.d.ts.map +1 -1
  29. package/dist/interfaces/successErrorNotification.d.ts +2 -2
  30. package/dist/interfaces/successErrorNotification.d.ts.map +1 -1
  31. package/package.json +1 -1
  32. package/src/contexts/refine/IRefineContext.ts +7 -0
  33. package/src/contexts/refine/index.tsx +1 -0
  34. package/src/definitions/helpers/handleRefineOptions/index.ts +3 -0
  35. package/src/hooks/data/useDelete.ts +28 -0
  36. package/src/hooks/data/useDeleteMany.ts +28 -0
  37. package/src/hooks/data/useUpdate.ts +1 -1
  38. package/src/hooks/data/useUpdateMany.ts +25 -0
  39. package/src/hooks/form/useForm.ts +59 -2
  40. package/src/index.tsx +2 -0
  41. package/src/interfaces/autoSave.ts +43 -0
  42. package/src/interfaces/errors/HttpError.ts +9 -0
  43. package/src/interfaces/index.ts +2 -0
  44. package/src/interfaces/successErrorNotification.ts +2 -2
@@ -0,0 +1,28 @@
1
+ import { BaseRecord, HttpError, UpdateResponse } from ".";
2
+ import { UseUpdateReturnType } from "../hooks/data/useUpdate";
3
+ export declare type AutoSaveProps<TVariables> = {
4
+ autoSave?: {
5
+ enabled: boolean;
6
+ debounce?: number;
7
+ onFinish?: (values: TVariables) => TVariables;
8
+ };
9
+ };
10
+ export declare type AutoSaveReturnType<TData extends BaseRecord = BaseRecord, TError extends HttpError = HttpError, TVariables = {}> = {
11
+ autoSaveProps: Pick<UseUpdateReturnType<TData, TError, TVariables>, "data" | "error" | "status">;
12
+ onFinishAutoSave: (values: TVariables) => Promise<UpdateResponse<TData> | void> | void;
13
+ };
14
+ export declare type AutoSaveIndicatorProps<TData extends BaseRecord = BaseRecord, TError extends HttpError = HttpError, TVariables = {}> = {
15
+ /**
16
+ * The data returned by the update request.
17
+ */
18
+ data?: UseUpdateReturnType<TData, TError, TVariables>["data"];
19
+ /**
20
+ * The error returned by the update request.
21
+ */
22
+ error?: UseUpdateReturnType<TData, TError, TVariables>["error"];
23
+ /**
24
+ * The status of the update request.
25
+ */
26
+ status: UseUpdateReturnType<TData, TError, TVariables>["status"];
27
+ };
28
+ //# sourceMappingURL=autoSave.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoSave.d.ts","sourceRoot":"","sources":["../../src/interfaces/autoSave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,GAAG,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,oBAAY,aAAa,CAAC,UAAU,IAAI;IACpC,QAAQ,CAAC,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,UAAU,CAAC;KACjD,CAAC;CACL,CAAC;AAEF,oBAAY,kBAAkB,CAC1B,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,MAAM,SAAS,SAAS,GAAG,SAAS,EACpC,UAAU,GAAG,EAAE,IACf;IACA,aAAa,EAAE,IAAI,CACf,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAC9C,MAAM,GAAG,OAAO,GAAG,QAAQ,CAC9B,CAAC;IACF,gBAAgB,EAAE,CACd,MAAM,EAAE,UAAU,KACjB,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;CACrD,CAAC;AAEF,oBAAY,sBAAsB,CAC9B,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,MAAM,SAAS,SAAS,GAAG,SAAS,EACpC,UAAU,GAAG,EAAE,IACf;IACA;;OAEG;IACH,IAAI,CAAC,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9D;;OAEG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC;IAChE;;OAEG;IACH,MAAM,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;CACpE,CAAC"}
@@ -1,5 +1,12 @@
1
+ export interface ValidationErrors {
2
+ [field: string]: string | string[] | boolean | {
3
+ key: string;
4
+ message: string;
5
+ };
6
+ }
1
7
  export interface HttpError extends Record<string, any> {
2
8
  message: string;
3
9
  statusCode: number;
10
+ errors?: ValidationErrors;
4
11
  }
5
12
  //# sourceMappingURL=HttpError.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"HttpError.d.ts","sourceRoot":"","sources":["../../../src/interfaces/errors/HttpError.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAU,SAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"HttpError.d.ts","sourceRoot":"","sources":["../../../src/interfaces/errors/HttpError.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC7B,CAAC,KAAK,EAAE,MAAM,GACR,MAAM,GACN,MAAM,EAAE,GACR,OAAO,GACP;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C;AAED,MAAM,WAAW,SAAU,SAAQ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC7B"}
@@ -46,5 +46,6 @@ export * from "./form-url-params";
46
46
  export * from "./auth";
47
47
  export * from "./bindings";
48
48
  export * from "./prettify";
49
+ export * from "./autoSave";
49
50
  export * from "./textTransformers";
50
51
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,iDAAiD,CAAC;AAChE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,uCAAuC,CAAC;AAEtD,cAAc,2BAA2B,CAAC;AAG1C,cAAc,WAAW,CAAC;AAG1B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,UAAU,CAAC;AAGzB,cAAc,oBAAoB,CAAC;AAGnC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,6BAA6B,CAAC;AAG5C,cAAc,aAAa,CAAC;AAG5B,cAAc,4BAA4B,CAAC;AAG3C,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;AAG3B,cAAc,QAAQ,CAAC;AAGvB,cAAc,YAAY,CAAC;AAE3B,oBAAY,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AACtC,oBAAY,UAAU,GAAG;IACrB,EAAE,CAAC,EAAE,OAAO,CAAC;IAEb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB,CAAC;AACF,MAAM,WAAW,MAAM;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB;AAGD,oBAAY,SAAS,GAAG,aAAa,GAAG;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAEF,oBAAY,SAAS,GAAG,aAAa,GAAG;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,cAAc,mBAAmB,CAAC;AAElC,cAAc,QAAQ,CAAC;AAEvB,cAAc,YAAY,CAAC;AAE3B,cAAc,YAAY,CAAC;AAE3B,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,iDAAiD,CAAC;AAChE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,uCAAuC,CAAC;AAEtD,cAAc,2BAA2B,CAAC;AAG1C,cAAc,WAAW,CAAC;AAG1B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,UAAU,CAAC;AAGzB,cAAc,oBAAoB,CAAC;AAGnC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,6BAA6B,CAAC;AAG5C,cAAc,aAAa,CAAC;AAG5B,cAAc,4BAA4B,CAAC;AAG3C,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;AAG3B,cAAc,QAAQ,CAAC;AAGvB,cAAc,YAAY,CAAC;AAE3B,oBAAY,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AACtC,oBAAY,UAAU,GAAG;IACrB,EAAE,CAAC,EAAE,OAAO,CAAC;IAEb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB,CAAC;AACF,MAAM,WAAW,MAAM;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB;AAGD,oBAAY,SAAS,GAAG,aAAa,GAAG;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAEF,oBAAY,SAAS,GAAG,aAAa,GAAG;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,cAAc,mBAAmB,CAAC;AAElC,cAAc,QAAQ,CAAC;AAEvB,cAAc,YAAY,CAAC;AAE3B,cAAc,YAAY,CAAC;AAE3B,cAAc,YAAY,CAAC;AAE3B,cAAc,oBAAoB,CAAC"}
@@ -5,11 +5,11 @@ export declare type SuccessErrorNotification<TData = unknown, TError = unknown,
5
5
  * @default '"There was an error creating resource (status code: `statusCode`)" or "Error when updating resource (status code: statusCode)"'
6
6
 
7
7
  */
8
- successNotification?: OpenNotificationParams | false | ((data?: TData, values?: TVariables, resource?: string) => OpenNotificationParams);
8
+ successNotification?: OpenNotificationParams | false | ((data?: TData, values?: TVariables, resource?: string) => OpenNotificationParams | false);
9
9
  /**
10
10
  * Error notification configuration to be displayed when the mutation fails.
11
11
  * @default '"There was an error creating resource (status code: `statusCode`)" or "Error when updating resource (status code: statusCode)"'
12
12
  */
13
- errorNotification?: OpenNotificationParams | false | ((error?: TError, values?: TVariables, resource?: string) => OpenNotificationParams);
13
+ errorNotification?: OpenNotificationParams | false | ((error?: TError, values?: TVariables, resource?: string) => OpenNotificationParams | false);
14
14
  };
15
15
  //# sourceMappingURL=successErrorNotification.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"successErrorNotification.d.ts","sourceRoot":"","sources":["../../src/interfaces/successErrorNotification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,GAAG,CAAC;AAE3C,oBAAY,wBAAwB,CAChC,KAAK,GAAG,OAAO,EACf,MAAM,GAAG,OAAO,EAChB,UAAU,GAAG,OAAO,IACpB;IACA;;;;OAIG;IACH,mBAAmB,CAAC,EACd,sBAAsB,GACtB,KAAK,GACL,CAAC,CACG,IAAI,CAAC,EAAE,KAAK,EACZ,MAAM,CAAC,EAAE,UAAU,EACnB,QAAQ,CAAC,EAAE,MAAM,KAChB,sBAAsB,CAAC,CAAC;IACnC;;;OAGG;IACH,iBAAiB,CAAC,EACZ,sBAAsB,GACtB,KAAK,GACL,CAAC,CACG,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,UAAU,EACnB,QAAQ,CAAC,EAAE,MAAM,KAChB,sBAAsB,CAAC,CAAC;CACtC,CAAC"}
1
+ {"version":3,"file":"successErrorNotification.d.ts","sourceRoot":"","sources":["../../src/interfaces/successErrorNotification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,GAAG,CAAC;AAE3C,oBAAY,wBAAwB,CAChC,KAAK,GAAG,OAAO,EACf,MAAM,GAAG,OAAO,EAChB,UAAU,GAAG,OAAO,IACpB;IACA;;;;OAIG;IACH,mBAAmB,CAAC,EACd,sBAAsB,GACtB,KAAK,GACL,CAAC,CACG,IAAI,CAAC,EAAE,KAAK,EACZ,MAAM,CAAC,EAAE,UAAU,EACnB,QAAQ,CAAC,EAAE,MAAM,KAChB,sBAAsB,GAAG,KAAK,CAAC,CAAC;IAC3C;;;OAGG;IACH,iBAAiB,CAAC,EACZ,sBAAsB,GACtB,KAAK,GACL,CAAC,CACG,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,UAAU,EACnB,QAAQ,CAAC,EAAE,MAAM,KAChB,sBAAsB,GAAG,KAAK,CAAC,CAAC;CAC9C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@refinedev/core",
3
- "version": "4.26.4",
3
+ "version": "4.28.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
  "main": "dist/index.js",
@@ -32,6 +32,12 @@ export interface IRefineOptions {
32
32
  };
33
33
  overtime?: UseLoadingOvertimeRefineContext;
34
34
  textTransformers?: TextTransformers;
35
+ /**
36
+ * Disables server-side validation globally for the useForm hook
37
+ * @default false
38
+ * @see {@link https://refine.dev/docs/advanced-tutorials/forms/server-side-form-validation/}
39
+ */
40
+ disableServerSideValidation?: boolean;
35
41
  }
36
42
 
37
43
  export interface IRefineContextOptions {
@@ -48,6 +54,7 @@ export interface IRefineContextOptions {
48
54
  };
49
55
  overtime: UseLoadingOvertimeRefineContext;
50
56
  textTransformers: Required<TextTransformers>;
57
+ disableServerSideValidation: boolean;
51
58
  }
52
59
 
53
60
  export interface IRefineContext {
@@ -30,6 +30,7 @@ export const defaultRefineOptions: IRefineContextOptions = {
30
30
  plural: pluralize.plural,
31
31
  singular: pluralize.singular,
32
32
  },
33
+ disableServerSideValidation: false,
33
34
  };
34
35
 
35
36
  export const RefineContext = React.createContext<IRefineContext>({
@@ -86,6 +86,9 @@ export const handleRefineOptions = ({
86
86
  options?.textTransformers?.singular ??
87
87
  defaultRefineOptions.textTransformers.singular,
88
88
  },
89
+ disableServerSideValidation:
90
+ options?.disableServerSideValidation ??
91
+ defaultRefineOptions.disableServerSideValidation,
89
92
  };
90
93
 
91
94
  const disableTelemetryWithDefault =
@@ -46,18 +46,46 @@ import {
46
46
  } from "../useLoadingOvertime";
47
47
 
48
48
  export type DeleteParams<TData, TError, TVariables> = {
49
+ /**
50
+ * id for mutation function
51
+ */
49
52
  id: BaseKey;
53
+ /**
54
+ * Resource name for API data interactions
55
+ */
50
56
  resource: string;
57
+ /**
58
+ * [Determines when mutations are executed](/advanced-tutorials/mutation-mode.md)
59
+ */
51
60
  mutationMode?: MutationMode;
61
+ /**
62
+ * Duration in ms to wait before executing the mutation when `mutationMode = "undoable"`
63
+ */
52
64
  undoableTimeout?: number;
65
+ /**
66
+ * Provides a function to cancel the mutation when `mutationMode = "undoable"`
67
+ */
53
68
  onCancel?: (cancelMutation: () => void) => void;
69
+ /**
70
+ * Metadata query for dataProvider
71
+ */
54
72
  meta?: MetaQuery;
55
73
  /**
56
74
  * @deprecated `metaData` is deprecated with refine@4, refine will pass `meta` instead, however, we still support `metaData` for backward compatibility.
57
75
  */
58
76
  metaData?: MetaQuery;
77
+ /**
78
+ * If there is more than one `dataProvider`, you should use the `dataProviderName` that you will use.
79
+ * @default "default"
80
+ */
59
81
  dataProviderName?: string;
82
+ /**
83
+ * You can use it to manage the invalidations that will occur at the end of the mutation.
84
+ */
60
85
  invalidates?: Array<keyof IQueryKeys>;
86
+ /**
87
+ * Values for mutation function
88
+ */
61
89
  values?: TVariables;
62
90
  } & SuccessErrorNotification<DeleteOneResponse<TData>, TError, BaseKey>;
63
91
 
@@ -47,18 +47,46 @@ import {
47
47
  } from "../useLoadingOvertime";
48
48
 
49
49
  export type DeleteManyParams<TData, TError, TVariables> = {
50
+ /**
51
+ * ids for mutation function
52
+ */
50
53
  ids: BaseKey[];
54
+ /**
55
+ * Resource name for API data interactions
56
+ */
51
57
  resource: string;
58
+ /**
59
+ * [Determines when mutations are executed](/advanced-tutorials/mutation-mode.md)
60
+ */
52
61
  mutationMode?: MutationMode;
62
+ /**
63
+ * Duration in ms to wait before executing the mutation when `mutationMode = "undoable"`
64
+ */
53
65
  undoableTimeout?: number;
66
+ /**
67
+ * Provides a function to cancel the mutation when `mutationMode = "undoable"`
68
+ */
54
69
  onCancel?: (cancelMutation: () => void) => void;
70
+ /**
71
+ * Metadata query for dataProvider
72
+ */
55
73
  meta?: MetaQuery;
56
74
  /**
57
75
  * @deprecated `metaData` is deprecated with refine@4, refine will pass `meta` instead, however, we still support `metaData` for backward compatibility.
58
76
  */
59
77
  metaData?: MetaQuery;
78
+ /**
79
+ * If there is more than one `dataProvider`, you should use the `dataProviderName` that you will use.
80
+ * @default "default"
81
+ */
60
82
  dataProviderName?: string;
83
+ /**
84
+ * You can use it to manage the invalidations that will occur at the end of the mutation.
85
+ */
61
86
  invalidates?: Array<keyof IQueryKeys>;
87
+ /**
88
+ * Values for mutation function
89
+ */
62
90
  values?: TVariables;
63
91
  } & SuccessErrorNotification<DeleteManyResponse<TData>, TError, BaseKey[]>;
64
92
 
@@ -63,7 +63,7 @@ export type UpdateParams<TData, TError, TVariables> = {
63
63
  */
64
64
  undoableTimeout?: number;
65
65
  /**
66
- * Callback that runs when undo button is clicked on `mutationMode = "undoable"`
66
+ * Provides a function to cancel the mutation when `mutationMode = "undoable"`
67
67
  */
68
68
  onCancel?: (cancelMutation: () => void) => void;
69
69
  /**
@@ -47,11 +47,29 @@ import {
47
47
  } from "../useLoadingOvertime";
48
48
 
49
49
  type UpdateManyParams<TData, TError, TVariables> = {
50
+ /**
51
+ * ids for mutation function
52
+ */
50
53
  ids: BaseKey[];
54
+ /**
55
+ * Resource name for API data interactions
56
+ */
51
57
  resource: string;
58
+ /**
59
+ * [Determines when mutations are executed](/advanced-tutorials/mutation-mode.md)
60
+ */
52
61
  mutationMode?: MutationMode;
62
+ /**
63
+ * Duration in ms to wait before executing the mutation when `mutationMode = "undoable"`
64
+ */
53
65
  undoableTimeout?: number;
66
+ /**
67
+ * Provides a function to cancel the mutation when `mutationMode = "undoable"`
68
+ */
54
69
  onCancel?: (cancelMutation: () => void) => void;
70
+ /**
71
+ * Values for mutation function
72
+ */
55
73
  values: TVariables;
56
74
  /**
57
75
  * meta data for `dataProvider`
@@ -62,7 +80,14 @@ type UpdateManyParams<TData, TError, TVariables> = {
62
80
  * @deprecated `metaData` is deprecated with refine@4, refine will pass `meta` instead, however, we still support `metaData` for backward compatibility.
63
81
  */
64
82
  metaData?: MetaQuery;
83
+ /**
84
+ * If there is more than one `dataProvider`, you should use the `dataProviderName` that you will use.
85
+ * @default "default"
86
+ */
65
87
  dataProviderName?: string;
88
+ /**
89
+ * You can use it to manage the invalidations that will occur at the end of the mutation.
90
+ */
66
91
  invalidates?: Array<keyof IQueryKeys>;
67
92
  } & SuccessErrorNotification<
68
93
  UpdateManyResponse<TData>,
@@ -1,6 +1,7 @@
1
1
  import React, { Dispatch, SetStateAction } from "react";
2
2
  import { QueryObserverResult, UseQueryOptions } from "@tanstack/react-query";
3
3
  import warnOnce from "warn-once";
4
+ import debounce from "lodash/debounce";
4
5
 
5
6
  import {
6
7
  useWarnAboutChange,
@@ -27,6 +28,8 @@ import {
27
28
  IQueryKeys,
28
29
  FormAction,
29
30
  MetaQuery,
31
+ AutoSaveProps,
32
+ AutoSaveReturnType,
30
33
  } from "../../interfaces";
31
34
  import {
32
35
  UpdateParams,
@@ -104,6 +107,7 @@ type ActionFormProps<
104
107
  data: CreateResponse<TResponse> | UpdateResponse<TResponse>,
105
108
  variables: TVariables,
106
109
  context: any,
110
+ isAutoSave?: boolean,
107
111
  ) => void;
108
112
  /**
109
113
  * Called when a mutation encounters an error
@@ -112,6 +116,7 @@ type ActionFormProps<
112
116
  error: TResponseError,
113
117
  variables: TVariables,
114
118
  context: any,
119
+ isAutoSave?: boolean,
115
120
  ) => void;
116
121
  /**
117
122
  * Duration to wait before executing mutations when `mutationMode = "undoable"`
@@ -177,7 +182,8 @@ export type UseFormProps<
177
182
  > &
178
183
  ActionParams &
179
184
  LiveModeProps &
180
- UseLoadingOvertimeOptionsProps;
185
+ UseLoadingOvertimeOptionsProps &
186
+ AutoSaveProps<TVariables>;
181
187
 
182
188
  export type UseFormReturnType<
183
189
  TQueryFnData extends BaseRecord = BaseRecord,
@@ -202,7 +208,8 @@ export type UseFormReturnType<
202
208
  idFromFunction?: BaseKey | undefined,
203
209
  routeParams?: Record<string, string | number>,
204
210
  ) => void;
205
- } & UseLoadingOvertimeReturnType;
211
+ } & UseLoadingOvertimeReturnType &
212
+ AutoSaveReturnType<TResponse, TResponseError, TVariables>;
206
213
 
207
214
  /**
208
215
  * `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 +255,7 @@ export const useForm = <
248
255
  createMutationOptions,
249
256
  updateMutationOptions,
250
257
  overtimeOptions,
258
+ autoSave,
251
259
  }: UseFormProps<
252
260
  TQueryFnData,
253
261
  TError,
@@ -378,6 +386,10 @@ export const useForm = <
378
386
  const { mutate: mutateUpdate, isLoading: isLoadingUpdate } =
379
387
  mutationResultUpdate;
380
388
 
389
+ const autoSaveMutation = useUpdate<TResponse, TResponseError, TVariables>(
390
+ {},
391
+ );
392
+
381
393
  const { setWarnWhen } = useWarnAboutChange();
382
394
 
383
395
  const handleSubmitWithRedirect = useRedirectionAfterSubmission();
@@ -443,6 +455,45 @@ export const useForm = <
443
455
  );
444
456
  };
445
457
 
458
+ const onFinishAutoSaveMutation = (
459
+ values: TVariables,
460
+ ): Promise<UpdateResponse<TResponse> | void> | void => {
461
+ if (!resource || !isEdit) return;
462
+
463
+ const variables: UpdateParams<TResponse, TResponseError, TVariables> = {
464
+ id: id ?? "",
465
+ values,
466
+ resource: identifier ?? resource.name,
467
+ successNotification: false,
468
+ errorNotification: false,
469
+ meta: { ...combinedMeta, ...mutationMeta },
470
+ metaData: { ...combinedMeta, ...mutationMeta },
471
+ dataProviderName,
472
+ invalidates: [],
473
+ };
474
+
475
+ return autoSaveMutation.mutate(variables, {
476
+ onSuccess: (data, _, context) => {
477
+ if (onMutationSuccess) {
478
+ onMutationSuccess(data, values, context, true);
479
+ }
480
+ },
481
+ onError: (error: TResponseError, _, context) => {
482
+ if (onMutationError) {
483
+ return onMutationError(error, values, context, true);
484
+ }
485
+ },
486
+ });
487
+ };
488
+
489
+ const onFinishAutoSave = React.useMemo(
490
+ () =>
491
+ debounce((allValues) => {
492
+ return onFinishAutoSaveMutation(allValues);
493
+ }, autoSave?.debounce || 1000),
494
+ [],
495
+ );
496
+
446
497
  const onFinishUpdate = async (values: TVariables) => {
447
498
  setWarnWhen(false);
448
499
 
@@ -532,6 +583,12 @@ export const useForm = <
532
583
  return {
533
584
  ...result,
534
585
  queryResult,
586
+ onFinishAutoSave,
587
+ autoSaveProps: {
588
+ status: autoSaveMutation.status,
589
+ data: autoSaveMutation.data,
590
+ error: autoSaveMutation.error,
591
+ },
535
592
  id,
536
593
  setId,
537
594
  redirect: (redirect, idFromFunction?: BaseKey | undefined) => {
package/src/index.tsx CHANGED
@@ -86,6 +86,8 @@ export {
86
86
  ParseFunction,
87
87
  Prettify,
88
88
  FormWithSyncWithLocationParams,
89
+ AutoSaveIndicatorProps,
90
+ AutoSaveProps,
89
91
  } from "./interfaces";
90
92
 
91
93
  // all auth types
@@ -0,0 +1,43 @@
1
+ import { BaseRecord, HttpError, UpdateResponse } from ".";
2
+ import { UseUpdateReturnType } from "../hooks/data/useUpdate";
3
+
4
+ export type AutoSaveProps<TVariables> = {
5
+ autoSave?: {
6
+ enabled: boolean;
7
+ debounce?: number;
8
+ onFinish?: (values: TVariables) => TVariables;
9
+ };
10
+ };
11
+
12
+ export type AutoSaveReturnType<
13
+ TData extends BaseRecord = BaseRecord,
14
+ TError extends HttpError = HttpError,
15
+ TVariables = {},
16
+ > = {
17
+ autoSaveProps: Pick<
18
+ UseUpdateReturnType<TData, TError, TVariables>,
19
+ "data" | "error" | "status"
20
+ >;
21
+ onFinishAutoSave: (
22
+ values: TVariables,
23
+ ) => Promise<UpdateResponse<TData> | void> | void;
24
+ };
25
+
26
+ export type AutoSaveIndicatorProps<
27
+ TData extends BaseRecord = BaseRecord,
28
+ TError extends HttpError = HttpError,
29
+ TVariables = {},
30
+ > = {
31
+ /**
32
+ * The data returned by the update request.
33
+ */
34
+ data?: UseUpdateReturnType<TData, TError, TVariables>["data"];
35
+ /**
36
+ * The error returned by the update request.
37
+ */
38
+ error?: UseUpdateReturnType<TData, TError, TVariables>["error"];
39
+ /**
40
+ * The status of the update request.
41
+ */
42
+ status: UseUpdateReturnType<TData, TError, TVariables>["status"];
43
+ };
@@ -1,4 +1,13 @@
1
+ export interface ValidationErrors {
2
+ [field: string]:
3
+ | string
4
+ | string[]
5
+ | boolean
6
+ | { key: string; message: string };
7
+ }
8
+
1
9
  export interface HttpError extends Record<string, any> {
2
10
  message: string;
3
11
  statusCode: number;
12
+ errors?: ValidationErrors;
4
13
  }
@@ -85,4 +85,6 @@ export * from "./bindings";
85
85
 
86
86
  export * from "./prettify";
87
87
 
88
+ export * from "./autoSave";
89
+
88
90
  export * from "./textTransformers";
@@ -17,7 +17,7 @@ export type SuccessErrorNotification<
17
17
  data?: TData,
18
18
  values?: TVariables,
19
19
  resource?: string,
20
- ) => OpenNotificationParams);
20
+ ) => OpenNotificationParams | false);
21
21
  /**
22
22
  * Error notification configuration to be displayed when the mutation fails.
23
23
  * @default '"There was an error creating resource (status code: `statusCode`)" or "Error when updating resource (status code: statusCode)"'
@@ -29,5 +29,5 @@ export type SuccessErrorNotification<
29
29
  error?: TError,
30
30
  values?: TVariables,
31
31
  resource?: string,
32
- ) => OpenNotificationParams);
32
+ ) => OpenNotificationParams | false);
33
33
  };