@nomos-ui/uanela-redux-next 0.0.4 → 0.1.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/dist/components/data-manipulation/create-data-wrapper.d.ts +65 -37
- package/dist/components/data-manipulation/create-data-wrapper.d.ts.map +1 -1
- package/dist/components/data-manipulation/create-data-wrapper.js +36 -36
- package/dist/components/data-manipulation/create-data-wrapper.js.map +1 -1
- package/dist/components/data-manipulation/update-data-wrapper.d.ts +68 -57
- package/dist/components/data-manipulation/update-data-wrapper.d.ts.map +1 -1
- package/dist/components/data-manipulation/update-data-wrapper.js +46 -41
- package/dist/components/data-manipulation/update-data-wrapper.js.map +1 -1
- package/dist/components/modals/create.modal.d.ts +40 -32
- package/dist/components/modals/create.modal.d.ts.map +1 -1
- package/dist/components/modals/create.modal.js +23 -21
- package/dist/components/modals/create.modal.js.map +1 -1
- package/dist/components/modals/update.modal.d.ts +58 -33
- package/dist/components/modals/update.modal.d.ts.map +1 -1
- package/dist/components/modals/update.modal.js +20 -16
- package/dist/components/modals/update.modal.js.map +1 -1
- package/dist/components/pages/create-data-page/index.d.ts +72 -11
- package/dist/components/pages/create-data-page/index.d.ts.map +1 -1
- package/dist/components/pages/create-data-page/index.js +27 -7
- package/dist/components/pages/create-data-page/index.js.map +1 -1
- package/dist/components/pages/list-page/header-action-buttons.d.ts +11 -0
- package/dist/components/pages/list-page/header-action-buttons.d.ts.map +1 -1
- package/dist/components/pages/list-page/header-action-buttons.js +12 -7
- package/dist/components/pages/list-page/header-action-buttons.js.map +1 -1
- package/dist/components/pages/list-page/list-page.d.ts +29 -4
- package/dist/components/pages/list-page/list-page.d.ts.map +1 -1
- package/dist/components/pages/list-page/list-page.js +22 -5
- package/dist/components/pages/list-page/list-page.js.map +1 -1
- package/dist/components/pages/list-page/table/table.d.ts +3 -8
- package/dist/components/pages/list-page/table/table.d.ts.map +1 -1
- package/dist/components/pages/list-page/table/table.js +15 -16
- package/dist/components/pages/list-page/table/table.js.map +1 -1
- package/dist/components/pages/list-page/template.d.ts +59 -3
- package/dist/components/pages/list-page/template.d.ts.map +1 -1
- package/dist/components/pages/list-page/template.js +31 -24
- package/dist/components/pages/list-page/template.js.map +1 -1
- package/dist/components/pages/update-data-page/index.d.ts +84 -11
- package/dist/components/pages/update-data-page/index.d.ts.map +1 -1
- package/dist/components/pages/update-data-page/index.js +30 -11
- package/dist/components/pages/update-data-page/index.js.map +1 -1
- package/dist/components/query-boundary.d.ts +29 -20
- package/dist/components/query-boundary.d.ts.map +1 -1
- package/dist/components/query-boundary.js +30 -37
- package/dist/components/query-boundary.js.map +1 -1
- package/package.json +10 -5
- package/dist/hooks/use-update-search-params.d.ts +0 -5
- package/dist/hooks/use-update-search-params.d.ts.map +0 -1
- package/dist/hooks/use-update-search-params.js +0 -13
- package/dist/hooks/use-update-search-params.js.map +0 -1
|
@@ -2,68 +2,96 @@ import React from "react";
|
|
|
2
2
|
import { UseFormReturn } from "react-hook-form";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
/**
|
|
5
|
-
* Props for the CreateDataWrapper
|
|
5
|
+
* Props for the CreateDataWrapper component
|
|
6
|
+
*
|
|
7
|
+
* @template Input - The shape of the form values / data being submitted
|
|
8
|
+
* @template Response - The shape of the API response returned after successful creation
|
|
9
|
+
* @template FormProps - Additional props accepted by the Form component
|
|
6
10
|
*/
|
|
7
|
-
type CreateDataWrapperProps = {
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Form: (props:
|
|
11
|
+
type CreateDataWrapperProps<Input, Response, FormProps extends Record<string, any> = Record<string, any>> = {
|
|
12
|
+
/**
|
|
13
|
+
* The form component to render.
|
|
14
|
+
* Receives all mutation state from the library (e.g. isLoading, isPending, error),
|
|
15
|
+
* formProps, and the onSubmit handler.
|
|
16
|
+
*/
|
|
17
|
+
Form: (props: FormProps & {
|
|
18
|
+
onSubmit: any;
|
|
19
|
+
} & Record<string, any>) => React.JSX.Element;
|
|
14
20
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
21
|
+
* The mutation hook to call for data creation.
|
|
22
|
+
* Pass the hook itself (e.g. useCreateProductMutation), not its result.
|
|
23
|
+
* The component will call it internally following React's rules of hooks.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* useMutation={useCreateProductMutation}
|
|
27
|
+
*/
|
|
28
|
+
useMutation: () => any;
|
|
29
|
+
/**
|
|
30
|
+
* Callback executed after a successful creation.
|
|
31
|
+
* Receives the API response, the cleaned submitted data, and the form instance.
|
|
32
|
+
*
|
|
33
|
+
* @param x.response - The raw API response
|
|
34
|
+
* @param x.data - The cleaned data that was submitted
|
|
35
|
+
* @param x.form - The react-hook-form instance typed to Input
|
|
17
36
|
*/
|
|
18
|
-
createMutation?: string;
|
|
19
|
-
/** Flag to show alert after successful creation */
|
|
20
|
-
showAlertAfterSuccessCreate?: boolean;
|
|
21
|
-
/** Callback function executed after successful data creation */
|
|
22
37
|
doAfterSuccessCreate?: (x: {
|
|
23
|
-
response:
|
|
24
|
-
data:
|
|
25
|
-
form: UseFormReturn
|
|
38
|
+
response: Response;
|
|
39
|
+
data: Input;
|
|
40
|
+
form: UseFormReturn<Input extends Record<string, any> ? Input : any>;
|
|
26
41
|
}) => Promise<any> | void;
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Optional function to transform or clean the form data before submission.
|
|
44
|
+
* Defaults to an identity function (returns data as-is).
|
|
45
|
+
*
|
|
46
|
+
* @param data - Raw form data
|
|
47
|
+
* @returns Cleaned data to be submitted
|
|
48
|
+
*/
|
|
49
|
+
cleanDataBeforeCreate?: (data: Input) => Promise<Input>;
|
|
50
|
+
/**
|
|
51
|
+
* Props passed directly to the Form component.
|
|
52
|
+
*/
|
|
53
|
+
formProps: FormProps & {
|
|
35
54
|
/** Label for the form's submit button */
|
|
36
55
|
buttonLabel: string;
|
|
37
56
|
/** Optional CSS class name for the form */
|
|
38
57
|
className?: string;
|
|
39
|
-
/**
|
|
58
|
+
/** If true, keeps the loading state active after submission */
|
|
40
59
|
keepIsLoading?: boolean;
|
|
41
|
-
/** Additional data
|
|
60
|
+
/** Additional data required by the form (e.g. select options, related records) */
|
|
42
61
|
requiredData?: Record<string, any>;
|
|
43
|
-
/** Zod schema for form validation */
|
|
62
|
+
/** Zod schema used for form validation */
|
|
44
63
|
schema: z.ZodObject<any>;
|
|
45
64
|
};
|
|
46
65
|
};
|
|
47
66
|
/**
|
|
48
|
-
* A generic
|
|
49
|
-
*
|
|
50
|
-
*
|
|
67
|
+
* A generic wrapper that handles data creation logic independently of the query library.
|
|
68
|
+
* Supports both RTK Query and TanStack Query via the provider config.
|
|
69
|
+
*
|
|
70
|
+
* Responsibilities:
|
|
71
|
+
* - Calls the provided mutation hook
|
|
72
|
+
* - Extracts and normalizes the trigger function based on the query library
|
|
73
|
+
* - Passes all raw mutation state directly to the Form (no normalization)
|
|
74
|
+
* - Handles submit orchestration: cleaning data, triggering mutation, running callbacks, resetting form
|
|
75
|
+
*
|
|
76
|
+
* The Form component receives everything the mutation hook provides plus `onSubmit`.
|
|
51
77
|
*
|
|
52
|
-
* @
|
|
53
|
-
* @
|
|
78
|
+
* @template Input - The shape of the form values / data being submitted
|
|
79
|
+
* @template Response - The shape of the API response returned after successful creation
|
|
80
|
+
* @template FormProps - Additional props accepted by the Form component
|
|
54
81
|
*
|
|
55
82
|
* @example
|
|
56
83
|
* ```tsx
|
|
57
|
-
* <CreateDataWrapper
|
|
58
|
-
* name="product"
|
|
84
|
+
* <CreateDataWrapper<CreateProductInput, Product, ProductFormProps>
|
|
59
85
|
* Form={ProductForm}
|
|
86
|
+
* useMutation={useCreateProductMutation}
|
|
87
|
+
* doAfterSuccessCreate={({ response }) => router.push(`/products/${response.id}`)}
|
|
60
88
|
* formProps={{
|
|
61
89
|
* buttonLabel: "Create Product",
|
|
62
|
-
* schema: productSchema
|
|
90
|
+
* schema: productSchema,
|
|
63
91
|
* }}
|
|
64
92
|
* />
|
|
65
93
|
* ```
|
|
66
94
|
*/
|
|
67
|
-
export default function CreateDataWrapper({
|
|
95
|
+
export default function CreateDataWrapper<Input, Response, FormProps extends Record<string, any> = Record<string, any>>({ Form, useMutation, doAfterSuccessCreate, cleanDataBeforeCreate, formProps, }: CreateDataWrapperProps<Input, Response, FormProps>): import("react/jsx-runtime").JSX.Element;
|
|
68
96
|
export {};
|
|
69
97
|
//# sourceMappingURL=create-data-wrapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-data-wrapper.d.ts","sourceRoot":"","sources":["../../../src/components/data-manipulation/create-data-wrapper.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create-data-wrapper.d.ts","sourceRoot":"","sources":["../../../src/components/data-manipulation/create-data-wrapper.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;GAMG;AACH,KAAK,sBAAsB,CACzB,KAAK,EACL,QAAQ,EACR,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IACzD;IACF;;;;OAIG;IACH,IAAI,EAAE,CACJ,KAAK,EAAE,SAAS,GAAG;QAAE,QAAQ,EAAE,GAAG,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KACvD,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;IACvB;;;;;;;OAOG;IACH,WAAW,EAAE,MAAM,GAAG,CAAC;IACvB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,CAAC,CAAC,EAAE;QACzB,QAAQ,EAAE,QAAQ,CAAC;QACnB,IAAI,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,aAAa,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;KACtE,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAC1B;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IACxD;;OAEG;IACH,SAAS,EAAE,SAAS,GAAG;QACrB,yCAAyC;QACzC,WAAW,EAAE,MAAM,CAAC;QACpB,2CAA2C;QAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,+DAA+D;QAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,kFAAkF;QAClF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnC,0CAA0C;QAC1C,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;KAC1B,CAAC;CACH,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,KAAK,EACL,QAAQ,EACR,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,EACA,IAAI,EACJ,WAAW,EACX,oBAAoB,EACpB,qBAA4C,EAC5C,SAAS,GACV,EAAE,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,2CAuCpD"}
|
|
@@ -2,47 +2,56 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = CreateDataWrapper;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const
|
|
5
|
+
const core_1 = require("@nomos-ui/core");
|
|
6
|
+
const utils_1 = require("@nomos-ui/core/utils");
|
|
6
7
|
const react_1 = require("react");
|
|
7
|
-
const navigation_1 = require("next/navigation");
|
|
8
|
-
const react_redux_1 = require("react-redux");
|
|
9
|
-
const api_provider_1 = require("../api-provider");
|
|
10
8
|
/**
|
|
11
|
-
* A generic
|
|
12
|
-
*
|
|
13
|
-
* Also supports template-based default values from Redux state
|
|
9
|
+
* A generic wrapper that handles data creation logic independently of the query library.
|
|
10
|
+
* Supports both RTK Query and TanStack Query via the provider config.
|
|
14
11
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* Responsibilities:
|
|
13
|
+
* - Calls the provided mutation hook
|
|
14
|
+
* - Extracts and normalizes the trigger function based on the query library
|
|
15
|
+
* - Passes all raw mutation state directly to the Form (no normalization)
|
|
16
|
+
* - Handles submit orchestration: cleaning data, triggering mutation, running callbacks, resetting form
|
|
17
|
+
*
|
|
18
|
+
* The Form component receives everything the mutation hook provides plus `onSubmit`.
|
|
19
|
+
*
|
|
20
|
+
* @template Input - The shape of the form values / data being submitted
|
|
21
|
+
* @template Response - The shape of the API response returned after successful creation
|
|
22
|
+
* @template FormProps - Additional props accepted by the Form component
|
|
17
23
|
*
|
|
18
24
|
* @example
|
|
19
25
|
* ```tsx
|
|
20
|
-
* <CreateDataWrapper
|
|
21
|
-
* name="product"
|
|
26
|
+
* <CreateDataWrapper<CreateProductInput, Product, ProductFormProps>
|
|
22
27
|
* Form={ProductForm}
|
|
28
|
+
* useMutation={useCreateProductMutation}
|
|
29
|
+
* doAfterSuccessCreate={({ response }) => router.push(`/products/${response.id}`)}
|
|
23
30
|
* formProps={{
|
|
24
31
|
* buttonLabel: "Create Product",
|
|
25
|
-
* schema: productSchema
|
|
32
|
+
* schema: productSchema,
|
|
26
33
|
* }}
|
|
27
34
|
* />
|
|
28
35
|
* ```
|
|
29
36
|
*/
|
|
30
|
-
function CreateDataWrapper({
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const
|
|
37
|
+
function CreateDataWrapper({ Form, useMutation, doAfterSuccessCreate, cleanDataBeforeCreate = async (data) => data, formProps, }) {
|
|
38
|
+
const { config } = (0, core_1.useProvider)();
|
|
39
|
+
const mutationResult = useMutation();
|
|
40
|
+
const { trigger, state } = (0, utils_1.extractMutation)(mutationResult, config.queryLibrary);
|
|
34
41
|
/**
|
|
35
|
-
* Handles form submission
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
42
|
+
* Handles form submission.
|
|
43
|
+
* Cleans the data, triggers the mutation, runs the success callback, and resets the form.
|
|
44
|
+
* Calls onError if provided and the mutation fails.
|
|
45
|
+
*
|
|
46
|
+
* @param data - The validated form data
|
|
47
|
+
* @param form - The react-hook-form instance typed to Input
|
|
48
|
+
* @param onError - Optional callback invoked with the original data and error on failure
|
|
39
49
|
*/
|
|
40
|
-
const handleCreateData = (0, react_1.useCallback)(async function
|
|
41
|
-
const cleanedData = cleanDataBeforeCreate(data);
|
|
50
|
+
const handleCreateData = (0, react_1.useCallback)(async function (data, form, onError) {
|
|
51
|
+
const cleanedData = await cleanDataBeforeCreate(data);
|
|
42
52
|
try {
|
|
43
|
-
const response = await
|
|
44
|
-
doAfterSuccessCreate
|
|
45
|
-
(await doAfterSuccessCreate({ response, data: cleanedData, form }));
|
|
53
|
+
const response = await trigger(cleanedData);
|
|
54
|
+
await doAfterSuccessCreate?.({ response, data: cleanedData, form });
|
|
46
55
|
form.reset();
|
|
47
56
|
return response;
|
|
48
57
|
}
|
|
@@ -50,16 +59,7 @@ function CreateDataWrapper({ name, Form, createMutation, doAfterSuccessCreate, c
|
|
|
50
59
|
onError?.(data, err);
|
|
51
60
|
return err;
|
|
52
61
|
}
|
|
53
|
-
}, [
|
|
54
|
-
(0,
|
|
55
|
-
const listHref = pathname.split("/");
|
|
56
|
-
listHref.pop();
|
|
57
|
-
}, [pathname]);
|
|
58
|
-
// Get template data from Redux store if available
|
|
59
|
-
const template = (0, react_redux_1.useSelector)((state) => state.app.template);
|
|
60
|
-
return ((0, jsx_runtime_1.jsx)(Form, { ...state, ...formProps, ...(template &&
|
|
61
|
-
template.name === name && {
|
|
62
|
-
defaultValues: template.data,
|
|
63
|
-
}), onSubmit: handleCreateData }));
|
|
62
|
+
}, [trigger]);
|
|
63
|
+
return (0, jsx_runtime_1.jsx)(Form, { ...state, ...formProps, onSubmit: handleCreateData });
|
|
64
64
|
}
|
|
65
65
|
//# sourceMappingURL=create-data-wrapper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-data-wrapper.js","sourceRoot":"","sources":["../../../src/components/data-manipulation/create-data-wrapper.tsx"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"create-data-wrapper.js","sourceRoot":"","sources":["../../../src/components/data-manipulation/create-data-wrapper.tsx"],"names":[],"mappings":";;AAsGA,oCAiDC;;AAvJD,yCAA6C;AAC7C,gDAAuD;AACvD,iCAA2C;AAuE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,SAAwB,iBAAiB,CAIvC,EACA,IAAI,EACJ,WAAW,EACX,oBAAoB,EACpB,qBAAqB,GAAG,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAC5C,SAAS,GAC0C;IACnD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAW,GAAE,CAAC;IACjC,MAAM,cAAc,GAAG,WAAW,EAAE,CAAC;IAErC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAA,uBAAe,EACxC,cAAc,EACd,MAAM,CAAC,YAAY,CACpB,CAAC;IAEF;;;;;;;;OAQG;IACH,MAAM,gBAAgB,GAAG,IAAA,mBAAW,EAClC,KAAK,WACH,IAAW,EACX,IAAoE,EACpE,OAA2C;QAE3C,MAAM,WAAW,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;YAC5C,MAAM,oBAAoB,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACrB,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,OAAO,uBAAC,IAAI,OAAK,KAAK,KAAM,SAAS,EAAE,QAAQ,EAAE,gBAAgB,GAAI,CAAC;AACxE,CAAC"}
|
|
@@ -1,91 +1,102 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { UseFormReturn } from "react-hook-form";
|
|
2
|
+
import { FieldValues, UseFormReturn } from "react-hook-form";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
/**
|
|
5
|
-
* Props for the
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/** Form submission handler */
|
|
11
|
-
onSubmit: (data: any, form: UseFormReturn) => void;
|
|
12
|
-
/** Label for the submit button */
|
|
13
|
-
buttonLabel: string;
|
|
14
|
-
/** Optional CSS class name */
|
|
15
|
-
className?: string;
|
|
16
|
-
/** Loading state for the form */
|
|
17
|
-
isLoading?: boolean;
|
|
18
|
-
/** Zod schema for form validation */
|
|
19
|
-
schema: z.ZodObject<any>;
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Props for the UpdateDataWrapper
|
|
5
|
+
* Props for the UpdateDataWrapper component
|
|
6
|
+
*
|
|
7
|
+
* @template Input - The shape of the form values / data being submitted
|
|
8
|
+
* @template Response - The shape of the API response returned after successful update
|
|
9
|
+
* @template FormProps - Additional props accepted by the Form component
|
|
23
10
|
*/
|
|
24
|
-
type UpdateDataWrapperProps = {
|
|
11
|
+
type UpdateDataWrapperProps<Input extends FieldValues, Response, FormProps extends Record<string, any> = Record<string, any>> = {
|
|
25
12
|
/** ID of the record to update */
|
|
26
13
|
id?: string | number;
|
|
27
|
-
/** Name identifier used to generate API mutation name if not provided */
|
|
28
|
-
name: string;
|
|
29
14
|
/** Form component to render for data updating */
|
|
30
|
-
Form: (props:
|
|
15
|
+
Form: (props: any) => React.JSX.Element;
|
|
31
16
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
17
|
+
* The mutation hook to call for data update.
|
|
18
|
+
* Pass the hook itself (e.g. useUpdateProductMutation), not its result.
|
|
19
|
+
* The component will call it internally following React's rules of hooks.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* useMutation={useUpdateProductMutation}
|
|
23
|
+
*/
|
|
24
|
+
useMutation: () => any;
|
|
25
|
+
/**
|
|
26
|
+
* The query hook to fetch the existing record.
|
|
27
|
+
* Pass the hook itself (e.g. useGetProductQuery), not its result.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* useQuery={useGetProductQuery}
|
|
31
|
+
*/
|
|
32
|
+
useQuery: (params: any) => any;
|
|
33
|
+
/**
|
|
34
|
+
* Callback executed after successful data update.
|
|
35
|
+
* Receives the API response, the cleaned submitted data, and the form instance.
|
|
36
|
+
*
|
|
37
|
+
* @param x.response - The raw API response
|
|
38
|
+
* @param x.data - The cleaned data that was submitted
|
|
39
|
+
* @param x.form - The react-hook-form instance typed to Input
|
|
34
40
|
*/
|
|
35
|
-
updateMutation?: string;
|
|
36
|
-
/** Flag to show alert after successful update */
|
|
37
|
-
showAlertAfterSuccessUpdate?: boolean;
|
|
38
|
-
/** Callback function executed after successful data update */
|
|
39
41
|
doAfterSuccessUpdate?: (x: {
|
|
40
|
-
response:
|
|
41
|
-
data:
|
|
42
|
-
form: UseFormReturn
|
|
42
|
+
response: Response;
|
|
43
|
+
data: Input;
|
|
44
|
+
form: UseFormReturn<Input>;
|
|
43
45
|
}) => Promise<any> | void;
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Optional function to transform or clean the form data before submission.
|
|
48
|
+
* Defaults to an identity function (returns data as-is).
|
|
49
|
+
*
|
|
50
|
+
* @param data - Raw form data
|
|
51
|
+
* @returns Cleaned data to be submitted
|
|
52
|
+
*/
|
|
53
|
+
cleanDataBeforeUpdate?: (data: Input) => Input;
|
|
54
|
+
/** Additional parameters passed to the query hook for data fetching */
|
|
55
|
+
params?: Record<string, any>;
|
|
56
|
+
/** Props passed directly to the Form component */
|
|
57
|
+
formProps: FormProps & {
|
|
52
58
|
/** Label for the form's submit button */
|
|
53
59
|
buttonLabel: string;
|
|
54
60
|
/** Optional CSS class name for the form */
|
|
55
61
|
className?: string;
|
|
56
|
-
/**
|
|
62
|
+
/** If true, keeps the loading state active after submission */
|
|
57
63
|
keepIsLoading?: boolean;
|
|
58
|
-
/** Additional data
|
|
64
|
+
/** Additional data required by the form (e.g. select options, related records) */
|
|
59
65
|
requiredData?: Record<string, any>;
|
|
60
|
-
/** Zod schema for form validation */
|
|
66
|
+
/** Zod schema used for form validation */
|
|
61
67
|
schema: z.ZodObject<any>;
|
|
62
68
|
};
|
|
63
|
-
/** Additional parameters passed to QueryBaseComponent for data fetching */
|
|
64
|
-
params?: Record<string, any>;
|
|
65
69
|
};
|
|
66
70
|
/**
|
|
67
|
-
* A generic
|
|
71
|
+
* A generic wrapper that handles data update logic independently of the query library.
|
|
72
|
+
* Supports both RTK Query and TanStack Query via the provider config.
|
|
73
|
+
*
|
|
74
|
+
* Responsibilities:
|
|
75
|
+
* - Fetches existing record via useQuery and populates form default values
|
|
76
|
+
* - Calls the provided mutation hook
|
|
77
|
+
* - Extracts and normalizes the trigger function based on the query library
|
|
78
|
+
* - Passes all raw mutation state directly to the Form (no normalization)
|
|
79
|
+
* - Handles submit orchestration: cleaning data, triggering mutation, running callbacks, resetting form
|
|
68
80
|
*
|
|
69
|
-
*
|
|
70
|
-
* -
|
|
71
|
-
*
|
|
72
|
-
* - Supports custom mutation names and callbacks
|
|
73
|
-
* - Handles form validation with Zod
|
|
74
|
-
* - Ignores timestamp fields (createdAt, updatedAt, deletedAt) in change detection
|
|
81
|
+
* @template Input - The shape of the form values / data being submitted
|
|
82
|
+
* @template Response - The shape of the API response returned after successful update
|
|
83
|
+
* @template FormProps - Additional props accepted by the Form component
|
|
75
84
|
*
|
|
76
85
|
* @example
|
|
77
86
|
* ```tsx
|
|
78
|
-
* <UpdateDataWrapper
|
|
79
|
-
* id=
|
|
80
|
-
* name="product"
|
|
87
|
+
* <UpdateDataWrapper<UpdateProductInput, Product, ProductFormProps>
|
|
88
|
+
* id={productId}
|
|
81
89
|
* Form={ProductForm}
|
|
90
|
+
* useMutation={useUpdateProductMutation}
|
|
91
|
+
* useQuery={useGetProductQuery}
|
|
92
|
+
* doAfterSuccessUpdate={({ response }) => router.push(`/products`)}
|
|
82
93
|
* formProps={{
|
|
83
94
|
* buttonLabel: "Update Product",
|
|
84
|
-
* schema: productSchema
|
|
95
|
+
* schema: productSchema,
|
|
85
96
|
* }}
|
|
86
97
|
* />
|
|
87
98
|
* ```
|
|
88
99
|
*/
|
|
89
|
-
export default function UpdateDataWrapper({ id,
|
|
100
|
+
export default function UpdateDataWrapper<Input extends FieldValues, Response, FormProps extends Record<string, any> = Record<string, any>>({ id, Form, useMutation, useQuery, doAfterSuccessUpdate, cleanDataBeforeUpdate, formProps, params, }: UpdateDataWrapperProps<Input, Response, FormProps>): import("react/jsx-runtime").JSX.Element;
|
|
90
101
|
export {};
|
|
91
102
|
//# sourceMappingURL=update-data-wrapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-data-wrapper.d.ts","sourceRoot":"","sources":["../../../src/components/data-manipulation/update-data-wrapper.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update-data-wrapper.d.ts","sourceRoot":"","sources":["../../../src/components/data-manipulation/update-data-wrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;;;;;GAMG;AACH,KAAK,sBAAsB,CACzB,KAAK,SAAS,WAAW,EACzB,QAAQ,EACR,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IACzD;IACF,iCAAiC;IACjC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,iDAAiD;IACjD,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;IACxC;;;;;;;OAOG;IACH,WAAW,EAAE,MAAM,GAAG,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAC/B;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,CAAC,CAAC,EAAE;QACzB,QAAQ,EAAE,QAAQ,CAAC;QACnB,IAAI,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;KAC5B,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAC1B;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,KAAK,CAAC;IAC/C,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,kDAAkD;IAClD,SAAS,EAAE,SAAS,GAAG;QACrB,yCAAyC;QACzC,WAAW,EAAE,MAAM,CAAC;QACpB,2CAA2C;QAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,+DAA+D;QAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,kFAAkF;QAClF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnC,0CAA0C;QAC1C,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;KAC1B,CAAC;CACH,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,KAAK,SAAS,WAAW,EACzB,QAAQ,EACR,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,EACA,EAAE,EACF,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,oBAAoB,EACpB,qBAAsC,EACtC,SAAS,EACT,MAAM,GACP,EAAE,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,2CA0DpD"}
|
|
@@ -5,76 +5,81 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.default = UpdateDataWrapper;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
-
const change_case_all_1 = require("change-case-all");
|
|
9
8
|
const react_1 = require("react");
|
|
10
|
-
const
|
|
9
|
+
const core_1 = require("@nomos-ui/core");
|
|
10
|
+
const utils_1 = require("@nomos-ui/core/utils");
|
|
11
11
|
const query_boundary_1 = __importDefault(require("../query-boundary"));
|
|
12
12
|
/**
|
|
13
|
-
* A generic
|
|
13
|
+
* A generic wrapper that handles data update logic independently of the query library.
|
|
14
|
+
* Supports both RTK Query and TanStack Query via the provider config.
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
* -
|
|
17
|
-
* -
|
|
18
|
-
* -
|
|
19
|
-
* -
|
|
20
|
-
* -
|
|
16
|
+
* Responsibilities:
|
|
17
|
+
* - Fetches existing record via useQuery and populates form default values
|
|
18
|
+
* - Calls the provided mutation hook
|
|
19
|
+
* - Extracts and normalizes the trigger function based on the query library
|
|
20
|
+
* - Passes all raw mutation state directly to the Form (no normalization)
|
|
21
|
+
* - Handles submit orchestration: cleaning data, triggering mutation, running callbacks, resetting form
|
|
22
|
+
*
|
|
23
|
+
* @template Input - The shape of the form values / data being submitted
|
|
24
|
+
* @template Response - The shape of the API response returned after successful update
|
|
25
|
+
* @template FormProps - Additional props accepted by the Form component
|
|
21
26
|
*
|
|
22
27
|
* @example
|
|
23
28
|
* ```tsx
|
|
24
|
-
* <UpdateDataWrapper
|
|
25
|
-
* id=
|
|
26
|
-
* name="product"
|
|
29
|
+
* <UpdateDataWrapper<UpdateProductInput, Product, ProductFormProps>
|
|
30
|
+
* id={productId}
|
|
27
31
|
* Form={ProductForm}
|
|
32
|
+
* useMutation={useUpdateProductMutation}
|
|
33
|
+
* useQuery={useGetProductQuery}
|
|
34
|
+
* doAfterSuccessUpdate={({ response }) => router.push(`/products`)}
|
|
28
35
|
* formProps={{
|
|
29
36
|
* buttonLabel: "Update Product",
|
|
30
|
-
* schema: productSchema
|
|
37
|
+
* schema: productSchema,
|
|
31
38
|
* }}
|
|
32
39
|
* />
|
|
33
40
|
* ```
|
|
34
41
|
*/
|
|
35
|
-
function UpdateDataWrapper({ id,
|
|
36
|
-
const
|
|
37
|
-
const
|
|
42
|
+
function UpdateDataWrapper({ id, Form, useMutation, useQuery, doAfterSuccessUpdate, cleanDataBeforeUpdate = (data) => data, formProps, params, }) {
|
|
43
|
+
const { config } = (0, core_1.useProvider)();
|
|
44
|
+
const mutationResult = useMutation();
|
|
45
|
+
const { trigger, state } = (0, utils_1.extractMutation)(mutationResult, config.queryLibrary);
|
|
38
46
|
const [fetchedData, setFetchedData] = (0, react_1.useState)();
|
|
39
47
|
const [dataForm, setDataForm] = (0, react_1.useState)();
|
|
40
48
|
(0, react_1.useEffect)(() => {
|
|
41
49
|
dataForm?.reset(fetchedData);
|
|
42
50
|
}, [fetchedData]);
|
|
43
51
|
/**
|
|
44
|
-
* Handles form submission and data update
|
|
45
|
-
*
|
|
52
|
+
* Handles form submission and data update.
|
|
53
|
+
* Cleans the data, triggers the mutation with id + body, runs the success callback, and resets the form.
|
|
46
54
|
*
|
|
47
|
-
* @param data
|
|
48
|
-
* @param form
|
|
55
|
+
* @param data - The validated form data
|
|
56
|
+
* @param form - The react-hook-form instance
|
|
57
|
+
* @param onError - Optional callback invoked with the original data and error on failure
|
|
49
58
|
*/
|
|
50
|
-
|
|
51
|
-
const cleanedData = cleanDataBeforeUpdate(data
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// data
|
|
56
|
-
// )
|
|
57
|
-
);
|
|
58
|
-
// Submit update with ID in path and changed data in body
|
|
59
|
-
updateData({ id, body: cleanedData })
|
|
60
|
-
.unwrap()
|
|
61
|
-
.then(async (response) => {
|
|
62
|
-
doAfterSuccessUpdate &&
|
|
63
|
-
(await doAfterSuccessUpdate({ response, data: cleanedData, form }));
|
|
59
|
+
const handleUpdateData = (0, react_1.useCallback)(async function (data, form, onError) {
|
|
60
|
+
const cleanedData = cleanDataBeforeUpdate(data);
|
|
61
|
+
try {
|
|
62
|
+
const response = await trigger({ id, body: cleanedData });
|
|
63
|
+
await doAfterSuccessUpdate?.({ response, data: cleanedData, form });
|
|
64
64
|
form.reset({ ...data, ...fetchedData });
|
|
65
65
|
setDataForm(form);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
return response;
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
onError?.(data, err);
|
|
70
|
+
return err;
|
|
71
|
+
}
|
|
72
|
+
}, [trigger, id, fetchedData]);
|
|
73
|
+
return ((0, jsx_runtime_1.jsx)(query_boundary_1.default, { useQuery: useQuery, successComponentProps: {
|
|
70
74
|
formProps: { ...state, ...formProps, onSubmit: handleUpdateData },
|
|
71
|
-
Form
|
|
75
|
+
Form,
|
|
72
76
|
fetchedData,
|
|
73
77
|
setFetchedData,
|
|
74
|
-
}, SuccessComponent: SuccessComponent,
|
|
78
|
+
}, SuccessComponent: SuccessComponent, params: { id, ...params }, showReloadAgainButton: false }));
|
|
75
79
|
}
|
|
76
80
|
/**
|
|
77
|
-
*
|
|
81
|
+
* Internal component that renders the form with fetched data.
|
|
82
|
+
* Sets the fetched data on mount so the form can populate default values.
|
|
78
83
|
*/
|
|
79
84
|
function SuccessComponent({ data, Form, formProps, setFetchedData, }) {
|
|
80
85
|
(0, react_1.useEffect)(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-data-wrapper.js","sourceRoot":"","sources":["../../../src/components/data-manipulation/update-data-wrapper.tsx"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"update-data-wrapper.js","sourceRoot":"","sources":["../../../src/components/data-manipulation/update-data-wrapper.tsx"],"names":[],"mappings":";;;;;AA4GA,oCAuEC;;AAnLD,iCAAgE;AAGhE,yCAA6C;AAC7C,gDAAuD;AACvD,uEAA8C;AAyE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,SAAwB,iBAAiB,CAIvC,EACA,EAAE,EACF,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,oBAAoB,EACpB,qBAAqB,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EACtC,SAAS,EACT,MAAM,GAC6C;IACnD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAW,GAAE,CAAC;IACjC,MAAM,cAAc,GAAG,WAAW,EAAE,CAAC;IACrC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAA,uBAAe,EACxC,cAAc,EACd,MAAM,CAAC,YAAY,CACpB,CAAC;IAEF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,GAAuB,CAAC;IACtE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,gBAAQ,GAAiB,CAAC;IAE1D,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB;;;;;;;OAOG;IACH,MAAM,gBAAgB,GAAG,IAAA,mBAAW,EAClC,KAAK,WACH,IAAW,EACX,IAA0B,EAC1B,OAA2C;QAE3C,MAAM,WAAW,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAS,CAAC,CAAC;YACjE,MAAM,oBAAoB,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,WAAW,EAAE,CAAC,CAAC;YACxC,WAAW,CAAC,IAAW,CAAC,CAAC;YACzB,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACrB,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC,EACD,CAAC,OAAO,EAAE,EAAE,EAAE,WAAW,CAAC,CAC3B,CAAC;IAEF,OAAO,CACL,uBAAC,wBAAa,IACZ,QAAQ,EAAE,QAAQ,EAClB,qBAAqB,EAAE;YACrB,SAAS,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE;YACjE,IAAI;YACJ,WAAW;YACX,cAAc;SACf,EACD,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,EACzB,qBAAqB,EAAE,KAAK,GAC5B,CACH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,EACxB,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,cAAc,GASf;IACC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,uBAAC,IAAI,OAAK,SAAS,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,GAAI,CAAC;AAC9E,CAAC"}
|