ding-react-admin 1.0.4 → 2.0.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/README.md +4 -10
- package/dist/index.js +1071 -803
- package/dist/src/crud/InlineFormSet.d.ts +2 -17
- package/dist/src/crud/InlineFormSet.d.ts.map +1 -1
- package/dist/src/crud/ResourceForm.d.ts +4 -9
- package/dist/src/crud/ResourceForm.d.ts.map +1 -1
- package/dist/src/crud/ResourceList.d.ts.map +1 -1
- package/dist/src/crud/columns/ImageColumn.d.ts +14 -0
- package/dist/src/crud/columns/ImageColumn.d.ts.map +1 -0
- package/dist/src/crud/context/InlineFieldsRegistry.d.ts +15 -0
- package/dist/src/crud/context/InlineFieldsRegistry.d.ts.map +1 -0
- package/dist/src/crud/context/PayloadFieldsContext.d.ts +18 -0
- package/dist/src/crud/context/PayloadFieldsContext.d.ts.map +1 -0
- package/dist/src/crud/fields/FileField.d.ts +12 -0
- package/dist/src/crud/fields/FileField.d.ts.map +1 -0
- package/dist/src/crud/fields/ImageField.d.ts +14 -0
- package/dist/src/crud/fields/ImageField.d.ts.map +1 -0
- package/dist/src/crud/fields/uploadFieldUtils.d.ts +5 -0
- package/dist/src/crud/fields/uploadFieldUtils.d.ts.map +1 -0
- package/dist/src/crud/fields/useUploadPreviewUrl.d.ts +4 -0
- package/dist/src/crud/fields/useUploadPreviewUrl.d.ts.map +1 -0
- package/dist/src/crud/index.d.ts +22 -9
- package/dist/src/crud/index.d.ts.map +1 -1
- package/dist/src/crud/types.d.ts +9 -7
- package/dist/src/crud/types.d.ts.map +1 -1
- package/dist/src/crud/utils/buildFormPayload.d.ts +6 -0
- package/dist/src/crud/utils/buildFormPayload.d.ts.map +1 -0
- package/dist/src/crud/utils/buildInlineRowsPayload.d.ts +6 -0
- package/dist/src/crud/utils/buildInlineRowsPayload.d.ts.map +1 -0
- package/dist/src/crud/utils/buildResourceFormSubmitBody.d.ts +5 -0
- package/dist/src/crud/utils/buildResourceFormSubmitBody.d.ts.map +1 -0
- package/dist/src/crud/utils/formErrors.d.ts +1 -1
- package/dist/src/crud/utils/formErrors.d.ts.map +1 -1
- package/dist/src/crud/utils/getFormValue.d.ts +3 -0
- package/dist/src/crud/utils/getFormValue.d.ts.map +1 -0
- package/dist/src/crud/utils/hasUploadValues.d.ts +3 -0
- package/dist/src/crud/utils/hasUploadValues.d.ts.map +1 -0
- package/dist/src/crud/utils/nestedFieldPath.d.ts +3 -0
- package/dist/src/crud/utils/nestedFieldPath.d.ts.map +1 -0
- package/dist/src/crud/utils/prepareFormSubmitBody.d.ts +7 -0
- package/dist/src/crud/utils/prepareFormSubmitBody.d.ts.map +1 -0
- package/dist/src/crud/utils/setFormValue.d.ts +3 -0
- package/dist/src/crud/utils/setFormValue.d.ts.map +1 -0
- package/dist/src/crud/utils/toFormData.d.ts +13 -0
- package/dist/src/crud/utils/toFormData.d.ts.map +1 -0
- package/dist/src/crud/utils/useFormRecord.d.ts +42 -0
- package/dist/src/crud/utils/useFormRecord.d.ts.map +1 -0
- package/dist/src/data/createRestResourceHandlers.d.ts +5 -5
- package/dist/src/data/createRestResourceHandlers.d.ts.map +1 -1
- package/dist/src/data/dataProviderTypes.d.ts +6 -5
- package/dist/src/data/dataProviderTypes.d.ts.map +1 -1
- package/dist/src/data/parseFormErrorHelpers.d.ts +44 -6
- package/dist/src/data/parseFormErrorHelpers.d.ts.map +1 -1
- package/dist/src/data/resourceHandlers.d.ts +1 -1
- package/dist/src/data/resourceHandlers.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/layouts/AdminLayout.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/crud/InlineFormSet.tsx +28 -85
- package/src/crud/ResourceForm.tsx +60 -66
- package/src/crud/ResourceFormModal.tsx +25 -25
- package/src/crud/ResourceList.tsx +1 -0
- package/src/crud/columns/ImageColumn.tsx +58 -0
- package/src/crud/columns/TextColumn.tsx +2 -2
- package/src/crud/context/InlineFieldsRegistry.tsx +61 -0
- package/src/crud/context/PayloadFieldsContext.tsx +62 -0
- package/src/crud/fields/FieldWrapper.tsx +87 -87
- package/src/crud/fields/FileField.tsx +123 -0
- package/src/crud/fields/ImageField.tsx +120 -0
- package/src/crud/fields/uploadFieldUtils.ts +21 -0
- package/src/crud/fields/useUploadPreviewUrl.ts +20 -0
- package/src/crud/index.ts +23 -19
- package/src/crud/types.ts +9 -7
- package/src/crud/utils/buildFormPayload.ts +24 -0
- package/src/crud/utils/buildInlineRowsPayload.ts +37 -0
- package/src/crud/utils/buildResourceFormSubmitBody.ts +29 -0
- package/src/crud/utils/formErrors.ts +42 -38
- package/src/crud/utils/{getByPath.ts → getFormValue.ts} +2 -2
- package/src/crud/utils/hasUploadValues.ts +9 -0
- package/src/crud/utils/nestedFieldPath.ts +8 -0
- package/src/crud/utils/prepareFormSubmitBody.ts +17 -0
- package/src/crud/utils/{setByPath.ts → setFormValue.ts} +2 -2
- package/src/crud/utils/toFormData.ts +81 -0
- package/src/crud/utils/useFormRecord.ts +156 -0
- package/src/data/createRestResourceHandlers.ts +19 -13
- package/src/data/dataProviderTypes.ts +7 -5
- package/src/data/dataUtils.test.ts +118 -6
- package/src/data/parseFormErrorHelpers.test.ts +138 -84
- package/src/data/parseFormErrorHelpers.ts +311 -224
- package/src/data/resourceHandlers.ts +1 -1
- package/src/index.ts +23 -11
- package/src/layouts/AdminLayout.tsx +2 -1
- package/dist/src/crud/context/SubmitFieldsContext.d.ts +0 -18
- package/dist/src/crud/context/SubmitFieldsContext.d.ts.map +0 -1
- package/dist/src/crud/utils/getByPath.d.ts +0 -3
- package/dist/src/crud/utils/getByPath.d.ts.map +0 -1
- package/dist/src/crud/utils/inlineArrayName.d.ts +0 -3
- package/dist/src/crud/utils/inlineArrayName.d.ts.map +0 -1
- package/dist/src/crud/utils/inlineFieldName.d.ts +0 -3
- package/dist/src/crud/utils/inlineFieldName.d.ts.map +0 -1
- package/dist/src/crud/utils/pickBySources.d.ts +0 -6
- package/dist/src/crud/utils/pickBySources.d.ts.map +0 -1
- package/dist/src/crud/utils/setByPath.d.ts +0 -3
- package/dist/src/crud/utils/setByPath.d.ts.map +0 -1
- package/dist/src/crud/utils/useResourceFormData.d.ts +0 -47
- package/dist/src/crud/utils/useResourceFormData.d.ts.map +0 -1
- package/src/crud/context/SubmitFieldsContext.tsx +0 -62
- package/src/crud/utils/inlineArrayName.ts +0 -4
- package/src/crud/utils/inlineFieldName.ts +0 -8
- package/src/crud/utils/pickBySources.ts +0 -24
- package/src/crud/utils/useResourceFormData.ts +0 -231
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataProviderTypes.d.ts","sourceRoot":"","sources":["../../../src/data/dataProviderTypes.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzC,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,mCAAmC;IACnC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAAC;IAC7B,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,4FAA4F;IAC5F,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACtE,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACrE,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACrE,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACrE,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"dataProviderTypes.d.ts","sourceRoot":"","sources":["../../../src/data/dataProviderTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,44 @@
|
|
|
1
1
|
import { FormValidationErrors, ParseFormErrorContext } from './dataProviderTypes';
|
|
2
2
|
export declare function asStringMessages(value: unknown): string[];
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
|
|
5
|
+
* Read a parsed JSON validation body when it is already available on the error.
|
|
6
|
+
|
|
7
|
+
*
|
|
8
|
+
|
|
9
|
+
* Supported transport shapes (sync only):
|
|
10
|
+
|
|
11
|
+
* - `{ body: { email: ["…"] } }` — explicit throw from a handler
|
|
12
|
+
|
|
13
|
+
* - `{ response: { data: { email: ["…"] } } }` — axios-style wrappers
|
|
14
|
+
|
|
15
|
+
* - `{ data: { email: ["…"] } }` — some HTTP clients attach parsed JSON here
|
|
16
|
+
|
|
17
|
+
*
|
|
18
|
+
|
|
19
|
+
* For fetch / OpenAPI clients that only expose a `Response`, use `resolveErrorBody`.
|
|
20
|
+
|
|
21
|
+
*/
|
|
4
22
|
export declare function getErrorBody(error: unknown): Record<string, unknown> | null;
|
|
5
|
-
export declare function applyInlineFieldPaths(fields: Record<string, string | string[]>, ctx: ParseFormErrorContext): Record<string, string | string[]>;
|
|
6
|
-
export declare function finalizeFormErrors(fields: Record<string, string | string[]>, global: string[], ctx: ParseFormErrorContext): FormValidationErrors;
|
|
7
23
|
/**
|
|
24
|
+
|
|
25
|
+
* Resolve a validation JSON body from any common HTTP client error shape.
|
|
26
|
+
|
|
27
|
+
* Falls back to reading `response.json()` for fetch / OpenAPI `ResponseError`.
|
|
28
|
+
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveErrorBody(error: unknown): Promise<Record<string, unknown> | null>;
|
|
31
|
+
/** Map `{ lines: [{ label: ["…"] }] }` → `{ "lines.0.label": "…" }`. */
|
|
32
|
+
export declare function flattenNestedArrayErrors(arrayKey: string, rows: unknown[], fields: Record<string, string | string[]>): void;
|
|
33
|
+
export declare function finalizeFormErrors(fields: Record<string, string | string[]>, global: string[]): FormValidationErrors;
|
|
34
|
+
/**
|
|
35
|
+
|
|
8
36
|
* Django REST framework validation body:
|
|
37
|
+
|
|
9
38
|
* `{ "email": ["Invalid"], "non_field_errors": ["…"] }`
|
|
39
|
+
|
|
10
40
|
*/
|
|
11
|
-
export declare function parseDjangoDRFFormErrors(error: unknown,
|
|
41
|
+
export declare function parseDjangoDRFFormErrors(error: unknown, _ctx: ParseFormErrorContext): FormValidationErrors | null;
|
|
12
42
|
export type DotNetFormErrorOptions = {
|
|
13
43
|
/** Map API property names to form `source` paths. */
|
|
14
44
|
fieldMap?: Record<string, string>;
|
|
@@ -18,18 +48,26 @@ export type DotNetFormErrorOptions = {
|
|
|
18
48
|
includeSummary?: boolean;
|
|
19
49
|
};
|
|
20
50
|
/**
|
|
51
|
+
|
|
21
52
|
* ASP.NET Core `ValidationProblemDetails`:
|
|
53
|
+
|
|
22
54
|
* `{ "errors": { "Email": ["The Email field is required."] } }`
|
|
55
|
+
|
|
23
56
|
*/
|
|
24
|
-
export declare function parseDotNetFormErrors(error: unknown,
|
|
57
|
+
export declare function parseDotNetFormErrors(error: unknown, _ctx: ParseFormErrorContext, options?: DotNetFormErrorOptions): FormValidationErrors | null;
|
|
25
58
|
export type NodeFormErrorOptions = {
|
|
26
59
|
fieldMap?: Record<string, string>;
|
|
27
60
|
};
|
|
28
61
|
/**
|
|
62
|
+
|
|
29
63
|
* Common Node / Express shapes:
|
|
64
|
+
|
|
30
65
|
* - `{ errors: { email: ["Invalid"] } }`
|
|
66
|
+
|
|
31
67
|
* - `{ errors: [{ path: "email", msg: "Invalid" }] }` (express-validator)
|
|
68
|
+
|
|
32
69
|
* - `{ details: [{ message: "…", path: ["email"] }] }` (Joi)
|
|
70
|
+
|
|
33
71
|
*/
|
|
34
|
-
export declare function parseNodeFormErrors(error: unknown,
|
|
72
|
+
export declare function parseNodeFormErrors(error: unknown, _ctx: ParseFormErrorContext, options?: NodeFormErrorOptions): FormValidationErrors | null;
|
|
35
73
|
//# sourceMappingURL=parseFormErrorHelpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseFormErrorHelpers.d.ts","sourceRoot":"","sources":["../../../src/data/parseFormErrorHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"parseFormErrorHelpers.d.ts","sourceRoot":"","sources":["../../../src/data/parseFormErrorHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,oBAAoB,EAEpB,qBAAqB,EAEtB,MAAM,qBAAqB,CAAC;AAI7B,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAczD;AA8CD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA0C3E;AAID;;;;;;GAMG;AAEH,wBAAsB,gBAAgB,CAEpC,KAAK,EAAE,OAAO,GAEb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAsCzC;AA8BD,wEAAwE;AAExE,wBAAgB,wBAAwB,CAEtC,QAAQ,EAAE,MAAM,EAEhB,IAAI,EAAE,OAAO,EAAE,EAEf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAExC,IAAI,CAwBN;AAID,wBAAgB,kBAAkB,CAEhC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAEzC,MAAM,EAAE,MAAM,EAAE,GAEf,oBAAoB,CAUtB;AAsDD;;;;;;GAMG;AAEH,wBAAgB,wBAAwB,CAEtC,KAAK,EAAE,OAAO,EAEd,IAAI,EAAE,qBAAqB,GAE1B,oBAAoB,GAAG,IAAI,CAQ7B;AAID,MAAM,MAAM,sBAAsB,GAAG;IAEnC,qDAAqD;IAErD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC,uCAAuC;IAEvC,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,mFAAmF;IAEnF,cAAc,CAAC,EAAE,OAAO,CAAC;CAE1B,CAAC;AAIF;;;;;;GAMG;AAEH,wBAAgB,qBAAqB,CAEnC,KAAK,EAAE,OAAO,EAEd,IAAI,EAAE,qBAAqB,EAE3B,OAAO,CAAC,EAAE,sBAAsB,GAE/B,oBAAoB,GAAG,IAAI,CAoD7B;AAID,MAAM,MAAM,oBAAoB,GAAG;IAEjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAEnC,CAAC;AAIF;;;;;;;;;;GAUG;AAEH,wBAAgB,mBAAmB,CAEjC,KAAK,EAAE,OAAO,EAEd,IAAI,EAAE,qBAAqB,EAE3B,OAAO,CAAC,EAAE,oBAAoB,GAE7B,oBAAoB,GAAG,IAAI,CAkH7B"}
|
|
@@ -8,7 +8,7 @@ export type ResourceGuard = (resource: string, action: ResourceAction) => void;
|
|
|
8
8
|
export type ResourceHandlers<RecordType extends Record<string, unknown> = Record<string, unknown>> = {
|
|
9
9
|
getList: (params: GetListParams) => Promise<GetListResult<RecordType>>;
|
|
10
10
|
getOne: (id: Identifier, params?: GetOneParams) => Promise<GetOneResult<RecordType>>;
|
|
11
|
-
create: (data: Partial<RecordType>) => Promise<CreateResult<RecordType>>;
|
|
11
|
+
create: (data: Partial<RecordType> | FormData) => Promise<CreateResult<RecordType>>;
|
|
12
12
|
update: (params: UpdateParams<RecordType>) => Promise<UpdateResult<RecordType>>;
|
|
13
13
|
delete: (id: Identifier) => Promise<DeleteResult<RecordType>>;
|
|
14
14
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceHandlers.d.ts","sourceRoot":"","sources":["../../../src/data/resourceHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAE9E,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3E,gGAAgG;AAChG,MAAM,MAAM,aAAa,GAAG,CAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,KACnB,IAAI,CAAC;AAEV,6EAA6E;AAC7E,MAAM,MAAM,gBAAgB,CAC1B,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAClE;IACF,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;IACvE,MAAM,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;IACrF,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"resourceHandlers.d.ts","sourceRoot":"","sources":["../../../src/data/resourceHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAE9E,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3E,gGAAgG;AAChG,MAAM,MAAM,aAAa,GAAG,CAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,KACnB,IAAI,CAAC;AAEV,6EAA6E;AAC7E,MAAM,MAAM,gBAAgB,CAC1B,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAClE;IACF,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;IACvE,MAAM,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;IACrF,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,QAAQ,KAAK,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;IACpF,MAAM,EAAE,CACN,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,KAC7B,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;IACvC,MAAM,EAAE,CAAC,EAAE,EAAE,UAAU,KAAK,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC5B,gBAAgB,GAChB;IACE,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC,CAAC;AAEN,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAEtE,MAAM,MAAM,8BAA8B,GAAG;IAC3C,0DAA0D;IAC1D,GAAG,CAAC,EAAE,kBAAkB,CAAC;IACzB,kEAAkE;IAClE,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,yEAAyE;IACzE,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAqBF;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,8BAA8B,GACvC,YAAY,CA0Cd"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ export { AuthProvider, createSessionStorageAuthAdapter, useAuth, type AuthProvid
|
|
|
4
4
|
export { DataProvider, useDataProvider, type DataProviderProps, } from './context/DataProvider';
|
|
5
5
|
export { PermissionsProvider, createPermissionsChecker, useCan, usePermissions, type PermissionsProviderProps, } from './context/PermissionsProvider';
|
|
6
6
|
export { AppThemeProvider, useThemeMode, } from './context/AppThemeProvider';
|
|
7
|
-
export type { CreateResult, DataProvider as DataProviderContract, DeleteResult, GetListParams, GetListResult, GetOneParams, GetOneResult, Identifier, PaginationParams, SortOrder, SortSpec, UpdateParams, UpdateResult, FormMutation, FormValidationErrors, ParseFormError, ParseFormErrorContext, } from './data/dataProviderTypes';
|
|
7
|
+
export type { CreateResult, DataProvider as DataProviderContract, DeleteResult, GetListParams, GetListResult, GetOneParams, GetOneResult, Identifier, PaginationParams, SortOrder, SortSpec, UpdateParams, UpdateResult, FormMutation, FormMutationBody, FormValidationErrors, ParseFormError, ParseFormErrorContext, } from './data/dataProviderTypes';
|
|
8
8
|
export { combineResourceHandlers } from './data/resourceHandlers';
|
|
9
9
|
export { isAbortError } from './data/abortError';
|
|
10
|
-
export { parseDjangoDRFFormErrors, parseDotNetFormErrors, parseNodeFormErrors, getErrorBody,
|
|
10
|
+
export { parseDjangoDRFFormErrors, parseDotNetFormErrors, parseNodeFormErrors, getErrorBody, resolveErrorBody, flattenNestedArrayErrors, asStringMessages, finalizeFormErrors, } from './data/parseFormErrorHelpers';
|
|
11
11
|
export type { DotNetFormErrorOptions, NodeFormErrorOptions, } from './data/parseFormErrorHelpers';
|
|
12
12
|
export { createMemoryResourceHandlers } from './data/createMemoryResourceHandlers';
|
|
13
13
|
export { createRestResourceHandlers } from './data/createRestResourceHandlers';
|
|
@@ -27,6 +27,6 @@ export { Guard, GuestOnly, Protected, RequirePermission } from './router/guards'
|
|
|
27
27
|
export { createAdminRouter } from './router/createAdminRouter';
|
|
28
28
|
export { deriveAuthPaths, getRouteAccess, partitionAdminRoutes, } from './router/routeAccess';
|
|
29
29
|
export type { AdminAppProps, AdminLayoutProps, AdminRouteChild, AppThemeProviderProps, AuthAdapter, LoginCredentials, AuthRedirects, CreateAdminRouterOptions, AuthAlternateLinkProps, AuthPageLayoutProps, LoginPageProps, NavItem, RouteAccess, ThemeDensity, ThemeMode, } from './types';
|
|
30
|
-
export { ResourceList, FilterBar, ResourceForm, ResourceFormModal, InlineFormSet, InlineFormSetStacked, FormTabs, FormTab, FormSteps, FormStep,
|
|
31
|
-
export type { ResourceFormProps,
|
|
30
|
+
export { ResourceList, FilterBar, ResourceForm, ResourceFormModal, InlineFormSet, InlineFormSetStacked, FormTabs, FormTab, FormSteps, FormStep, TextField, NumberField, BooleanField, DateField, SelectField, PasswordField, ReferenceField, ReferenceManyField, ImageField, FileField, FieldWrapper, TextColumn, NumberColumn, BooleanColumn, DateColumn, ReferenceColumn, ReferenceManyColumn, ImageColumn, CustomColumn, TextFilter, NumberFilter, BooleanFilter, DateFilter, SelectFilter, ReferenceFilter, ReferenceManyFilter, useListQueryState, useChoices, useAbortableEffect, getFormValue, setFormValue, buildFormPayload, buildInlineRowsPayload, buildResourceFormSubmitBody, prepareFormSubmitBody, toFormData, hasUploadValues, nestedFieldPath, useResourceListContext, useRegisterPayloadField, useRegisterSectionField, } from './crud';
|
|
31
|
+
export type { ResourceFormProps, ResourceFormModalProps, InlineFormSetProps, InlineFormSetStackedProps, FormTabsProps, FormTabProps, FormStepsProps, FormStepProps, InlineFormSetLayout, ResourceListProps, BaseSourceProps, ChoiceOption, ChoicesLoader, ReferenceProps, DisplayProps, EditMode, FieldRules, InlineCellContext, InlineColumnDef, InlineFormSetBaseProps, InlineRowContext, InlineFieldRegistration, FieldWrapperProps, ImageFieldProps, FileFieldProps, UploadFieldValue, ToFormDataOptions, PrepareFormSubmitBodyOptions, ResourceListBuiltInActions, ResourceListBulkAction, ResourceListBulkActionHelpers, ResourceListRowActionsHelpers, ListQueryState, ListQueryActions, } from './crud';
|
|
32
32
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EACL,YAAY,EACZ,+BAA+B,EAC/B,OAAO,EACP,KAAK,iBAAiB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,YAAY,EACZ,eAAe,EACf,KAAK,iBAAiB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,MAAM,EACN,cAAc,EACd,KAAK,wBAAwB,GAC9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,gBAAgB,EAChB,YAAY,GACb,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,YAAY,EACZ,YAAY,IAAI,oBAAoB,EACpC,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminLayout.d.ts","sourceRoot":"","sources":["../../../src/layouts/AdminLayout.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,gBAAgB,EAAW,MAAM,UAAU,CAAC;AAyG1D,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,KAAe,EACf,cAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,SAAoB,EACpB,wBAA4C,GAC7C,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"AdminLayout.d.ts","sourceRoot":"","sources":["../../../src/layouts/AdminLayout.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,gBAAgB,EAAW,MAAM,UAAU,CAAC;AAyG1D,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,KAAe,EACf,cAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,SAAoB,EACpB,wBAA4C,GAC7C,EAAE,gBAAgB,2CAkPlB"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { Button, Card, Space, Table, Typography } from "antd";
|
|
2
2
|
import { useFieldArray, useFormContext, type FieldValues } from "react-hook-form";
|
|
3
3
|
import { useMemo, type ReactNode } from "react";
|
|
4
|
-
import type { Identifier } from "../data/dataProviderTypes";
|
|
5
|
-
import type { DataProvider } from "../data/dataProviderTypes";
|
|
6
4
|
import type {
|
|
7
5
|
InlineColumnDef,
|
|
8
6
|
InlineFormSetBaseProps,
|
|
9
7
|
InlineRowContext,
|
|
10
8
|
} from "./types";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
9
|
+
import { nestedFieldPath } from "./utils/nestedFieldPath";
|
|
10
|
+
import { useRegisterInlineField } from "./context/InlineFieldsRegistry";
|
|
11
|
+
import { useRegisterPayloadField } from "./context/PayloadFieldsContext";
|
|
13
12
|
|
|
14
13
|
export type InlineFormSetLayout = "tabular" | "stacked";
|
|
15
14
|
|
|
@@ -29,11 +28,12 @@ function emptyRow(sources: string[]) {
|
|
|
29
28
|
return row;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
function useInlineRows(
|
|
31
|
+
function useInlineRows(field: string, sources: string[]) {
|
|
33
32
|
const { control } = useFormContext<FieldValues>();
|
|
34
33
|
const { fields, append, remove } = useFieldArray({
|
|
35
34
|
control,
|
|
36
|
-
name:
|
|
35
|
+
name: field,
|
|
36
|
+
keyName: "rowKey",
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
const appendEmpty = () => append(emptyRow(sources));
|
|
@@ -43,17 +43,20 @@ function useInlineRows(arrayName: string, sources: string[]) {
|
|
|
43
43
|
|
|
44
44
|
/** Tabular inline (Django TabularInline) — table with column headers. */
|
|
45
45
|
export function InlineFormSet({
|
|
46
|
-
|
|
46
|
+
field,
|
|
47
47
|
label,
|
|
48
|
-
|
|
48
|
+
payloadKey,
|
|
49
|
+
transformRows,
|
|
49
50
|
columns,
|
|
50
51
|
}: InlineFormSetProps) {
|
|
51
|
-
const arrayName = buildInlineArrayName(resource, name);
|
|
52
52
|
const sources = useMemo(
|
|
53
53
|
() => columns.map((col) => col.source),
|
|
54
54
|
[columns],
|
|
55
55
|
);
|
|
56
|
-
const { fields, remove, appendEmpty } = useInlineRows(
|
|
56
|
+
const { fields, remove, appendEmpty } = useInlineRows(field, sources);
|
|
57
|
+
|
|
58
|
+
useRegisterPayloadField(field);
|
|
59
|
+
useRegisterInlineField(field, sources, payloadKey, transformRows);
|
|
57
60
|
|
|
58
61
|
const tableColumns = useMemo(
|
|
59
62
|
() =>
|
|
@@ -67,12 +70,12 @@ export function InlineFormSet({
|
|
|
67
70
|
col.minWidth != null ? { style: { minWidth: col.minWidth } } : {},
|
|
68
71
|
render: (_: unknown, __: unknown, index: number) =>
|
|
69
72
|
col.cell({
|
|
70
|
-
name:
|
|
73
|
+
name: nestedFieldPath(field, index, col.source),
|
|
71
74
|
index,
|
|
72
|
-
|
|
75
|
+
field,
|
|
73
76
|
}),
|
|
74
77
|
})),
|
|
75
|
-
[columns,
|
|
78
|
+
[columns, field],
|
|
76
79
|
);
|
|
77
80
|
|
|
78
81
|
return (
|
|
@@ -82,7 +85,7 @@ export function InlineFormSet({
|
|
|
82
85
|
size="small"
|
|
83
86
|
pagination={false}
|
|
84
87
|
scroll={{ x: "max-content" }}
|
|
85
|
-
dataSource={fields.map((f) => ({ ...f, key: f.
|
|
88
|
+
dataSource={fields.map((f) => ({ ...f, key: f.rowKey }))}
|
|
86
89
|
columns={[
|
|
87
90
|
...tableColumns,
|
|
88
91
|
{
|
|
@@ -111,22 +114,25 @@ export function InlineFormSet({
|
|
|
111
114
|
|
|
112
115
|
/** Stacked inline (Django StackedInline) — each row in a card with field labels. */
|
|
113
116
|
export function InlineFormSetStacked({
|
|
114
|
-
|
|
117
|
+
field,
|
|
115
118
|
label,
|
|
116
|
-
|
|
119
|
+
payloadKey,
|
|
120
|
+
transformRows,
|
|
117
121
|
sources,
|
|
118
122
|
renderRow,
|
|
119
123
|
}: InlineFormSetStackedProps) {
|
|
120
|
-
const
|
|
121
|
-
|
|
124
|
+
const { fields, remove, appendEmpty } = useInlineRows(field, sources);
|
|
125
|
+
|
|
126
|
+
useRegisterPayloadField(field);
|
|
127
|
+
useRegisterInlineField(field, sources, payloadKey, transformRows);
|
|
122
128
|
|
|
123
129
|
return (
|
|
124
130
|
<div style={{ marginTop: 24 }}>
|
|
125
131
|
<Typography.Title level={5}>{label ?? "Related items"}</Typography.Title>
|
|
126
132
|
<Space orientation="vertical" size="middle" style={{ width: "100%" }}>
|
|
127
|
-
{fields.map((
|
|
133
|
+
{fields.map((rowField, index) => (
|
|
128
134
|
<Card
|
|
129
|
-
key={
|
|
135
|
+
key={rowField.rowKey}
|
|
130
136
|
size="small"
|
|
131
137
|
title={`Item ${index + 1}`}
|
|
132
138
|
extra={
|
|
@@ -141,9 +147,9 @@ export function InlineFormSetStacked({
|
|
|
141
147
|
}
|
|
142
148
|
>
|
|
143
149
|
{renderRow({
|
|
144
|
-
|
|
150
|
+
field,
|
|
145
151
|
index,
|
|
146
|
-
name: (source) =>
|
|
152
|
+
name: (source) => nestedFieldPath(field, index, source),
|
|
147
153
|
})}
|
|
148
154
|
</Card>
|
|
149
155
|
))}
|
|
@@ -154,66 +160,3 @@ export function InlineFormSetStacked({
|
|
|
154
160
|
</div>
|
|
155
161
|
);
|
|
156
162
|
}
|
|
157
|
-
|
|
158
|
-
export type SaveInlineOptions = {
|
|
159
|
-
resource: string;
|
|
160
|
-
foreignKey: string;
|
|
161
|
-
parentId: Identifier;
|
|
162
|
-
rows: Record<string, unknown>[];
|
|
163
|
-
existingIds?: Identifier[];
|
|
164
|
-
/** Return true when the error was handled (field errors applied). Stops saving further rows. */
|
|
165
|
-
onRowError?: (error: unknown, index: number) => boolean;
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
export async function saveInlineRows(
|
|
169
|
-
dp: DataProvider,
|
|
170
|
-
opts: SaveInlineOptions,
|
|
171
|
-
): Promise<boolean> {
|
|
172
|
-
const { resource, foreignKey, parentId, rows, existingIds = [], onRowError } =
|
|
173
|
-
opts;
|
|
174
|
-
const keptIds: Identifier[] = [];
|
|
175
|
-
|
|
176
|
-
for (let index = 0; index < rows.length; index++) {
|
|
177
|
-
const row = rows[index];
|
|
178
|
-
try {
|
|
179
|
-
const { id: _id, ...rest } = row;
|
|
180
|
-
const data = { ...rest, [foreignKey]: parentId };
|
|
181
|
-
const rowId = row.id as Identifier | undefined;
|
|
182
|
-
if (rowId != null && existingIds.some((e) => e === rowId)) {
|
|
183
|
-
await dp.update(resource, { id: rowId, data });
|
|
184
|
-
keptIds.push(rowId);
|
|
185
|
-
} else {
|
|
186
|
-
const res = await dp.create(resource, data);
|
|
187
|
-
const created = res.data as { id: Identifier };
|
|
188
|
-
keptIds.push(created.id);
|
|
189
|
-
}
|
|
190
|
-
} catch (e) {
|
|
191
|
-
if (onRowError?.(e, index)) return false;
|
|
192
|
-
throw e;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
for (const oldId of existingIds) {
|
|
197
|
-
if (!keptIds.some((k) => k === oldId)) {
|
|
198
|
-
await dp.delete(resource, oldId);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return true;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
export async function loadInlineRows(
|
|
206
|
-
dp: DataProvider,
|
|
207
|
-
resource: string,
|
|
208
|
-
foreignKey: string,
|
|
209
|
-
parentId: Identifier,
|
|
210
|
-
) {
|
|
211
|
-
const res = await dp.getList(resource, {
|
|
212
|
-
filter: { [foreignKey]: Number(parentId) || parentId },
|
|
213
|
-
pagination: { page: 1, perPage: 500 },
|
|
214
|
-
});
|
|
215
|
-
return {
|
|
216
|
-
rows: res.data as Record<string, unknown>[],
|
|
217
|
-
ids: (res.data as { id: Identifier }[]).map((r) => r.id),
|
|
218
|
-
};
|
|
219
|
-
}
|
|
@@ -8,14 +8,12 @@ import { usePermissions } from "../context/PermissionsProvider";
|
|
|
8
8
|
import type { ResourcePermissions } from "../permissions/resourcePermissions";
|
|
9
9
|
import { checkResourcePermission } from "../permissions/resourcePermissions";
|
|
10
10
|
import { FormMetaProvider } from "./context/FormContext";
|
|
11
|
-
import {
|
|
11
|
+
import { PayloadFieldsProvider } from "./context/PayloadFieldsContext";
|
|
12
12
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} from "./utils/
|
|
17
|
-
|
|
18
|
-
export type { ResourceFormInlineConfig };
|
|
13
|
+
InlineFieldsRegistryProvider,
|
|
14
|
+
type InlineFieldRegistration,
|
|
15
|
+
} from "./context/InlineFieldsRegistry";
|
|
16
|
+
import { useFormRecordLoad, useFormRecordSave } from "./utils/useFormRecord";
|
|
19
17
|
|
|
20
18
|
export type ResourceFormProps<T extends FieldValues> = {
|
|
21
19
|
resource: string;
|
|
@@ -25,18 +23,15 @@ export type ResourceFormProps<T extends FieldValues> = {
|
|
|
25
23
|
defaultValues?: Partial<T>;
|
|
26
24
|
onSaved?: (record: T) => void;
|
|
27
25
|
stayOnPage?: boolean;
|
|
28
|
-
inlines?: ResourceFormInlineConfig[];
|
|
29
26
|
/** Permission strings for create vs edit. Omit to allow all (demos only). */
|
|
30
27
|
permissions?: Pick<ResourcePermissions, "add" | "change">;
|
|
31
28
|
};
|
|
32
29
|
|
|
33
30
|
/**
|
|
34
|
-
* Create/edit page
|
|
31
|
+
* Create/edit page — standard react-hook-form under the hood.
|
|
35
32
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* 2. Edit — children render fields; useSubmitField tracks sources for the API payload
|
|
39
|
-
* 3. Save — pickBySources → create/update parent → saveInlineRows (see useResourceFormSubmit)
|
|
33
|
+
* Load: one `getOne` → `form.reset(record)` (nested inline arrays included).
|
|
34
|
+
* Save: one `create` or `update` with parent fields + nested inline rows.
|
|
40
35
|
*/
|
|
41
36
|
export function ResourceForm<T extends FieldValues & { id?: unknown }>({
|
|
42
37
|
resource,
|
|
@@ -46,7 +41,6 @@ export function ResourceForm<T extends FieldValues & { id?: unknown }>({
|
|
|
46
41
|
defaultValues,
|
|
47
42
|
onSaved,
|
|
48
43
|
stayOnPage,
|
|
49
|
-
inlines,
|
|
50
44
|
permissions,
|
|
51
45
|
}: ResourceFormProps<T>) {
|
|
52
46
|
const { id } = useParams();
|
|
@@ -56,13 +50,14 @@ export function ResourceForm<T extends FieldValues & { id?: unknown }>({
|
|
|
56
50
|
const navigate = useNavigate();
|
|
57
51
|
const { message } = App.useApp();
|
|
58
52
|
const { token } = theme.useToken();
|
|
59
|
-
const
|
|
53
|
+
const payloadFieldsRef = useRef(new Set<string>());
|
|
54
|
+
const inlineRegistryRef = useRef(new Map<string, InlineFieldRegistration>());
|
|
60
55
|
|
|
61
56
|
const form = useForm<T>({
|
|
62
57
|
defaultValues: defaultValues as DefaultValues<T>,
|
|
63
58
|
});
|
|
64
59
|
|
|
65
|
-
const { loading, formVersion
|
|
60
|
+
const { loading, formVersion } = useFormRecordLoad({
|
|
66
61
|
dp,
|
|
67
62
|
resource,
|
|
68
63
|
id,
|
|
@@ -70,10 +65,9 @@ export function ResourceForm<T extends FieldValues & { id?: unknown }>({
|
|
|
70
65
|
form,
|
|
71
66
|
message,
|
|
72
67
|
defaultValues,
|
|
73
|
-
inlines,
|
|
74
68
|
});
|
|
75
69
|
|
|
76
|
-
const onSubmit =
|
|
70
|
+
const onSubmit = useFormRecordSave({
|
|
77
71
|
dp,
|
|
78
72
|
resource,
|
|
79
73
|
id,
|
|
@@ -82,9 +76,8 @@ export function ResourceForm<T extends FieldValues & { id?: unknown }>({
|
|
|
82
76
|
message,
|
|
83
77
|
navigate,
|
|
84
78
|
listPath,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
existingInlineIds,
|
|
79
|
+
payloadFieldsRef,
|
|
80
|
+
inlineRegistryRef,
|
|
88
81
|
onSaved,
|
|
89
82
|
stayOnPage,
|
|
90
83
|
});
|
|
@@ -115,51 +108,52 @@ export function ResourceForm<T extends FieldValues & { id?: unknown }>({
|
|
|
115
108
|
}
|
|
116
109
|
>
|
|
117
110
|
<FormMetaProvider resource={resource} isNew={isNew}>
|
|
118
|
-
<
|
|
119
|
-
<
|
|
120
|
-
{
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
111
|
+
<PayloadFieldsProvider fieldsRef={payloadFieldsRef}>
|
|
112
|
+
<InlineFieldsRegistryProvider registryRef={inlineRegistryRef}>
|
|
113
|
+
<div style={{ position: "relative" }}>
|
|
114
|
+
{loading ? (
|
|
115
|
+
<div
|
|
116
|
+
style={{
|
|
117
|
+
position: "absolute",
|
|
118
|
+
inset: 0,
|
|
119
|
+
display: "flex",
|
|
120
|
+
alignItems: "center",
|
|
121
|
+
justifyContent: "center",
|
|
122
|
+
zIndex: 1,
|
|
123
|
+
}}
|
|
124
|
+
>
|
|
125
|
+
<Spin />
|
|
126
|
+
</div>
|
|
127
|
+
) : null}
|
|
128
|
+
<FormProvider {...form} key={formVersion}>
|
|
129
|
+
<Form
|
|
130
|
+
layout="vertical"
|
|
131
|
+
onFinish={() => void form.handleSubmit(onSubmit)()}
|
|
132
|
+
style={{
|
|
133
|
+
opacity: loading ? 0.4 : 1,
|
|
134
|
+
pointerEvents: loading ? "none" : undefined,
|
|
135
|
+
}}
|
|
136
|
+
>
|
|
137
|
+
{children}
|
|
138
|
+
<Form.Item style={{ marginTop: 16 }}>
|
|
139
|
+
<Space>
|
|
140
|
+
<Button
|
|
141
|
+
type="primary"
|
|
142
|
+
htmlType="submit"
|
|
143
|
+
disabled={loading || !canSave}
|
|
144
|
+
>
|
|
145
|
+
Save
|
|
146
|
+
</Button>
|
|
147
|
+
<Link to={listPath}>
|
|
148
|
+
<Button disabled={loading}>Cancel</Button>
|
|
149
|
+
</Link>
|
|
150
|
+
</Space>
|
|
151
|
+
</Form.Item>
|
|
152
|
+
</Form>
|
|
153
|
+
</FormProvider>
|
|
154
|
+
</div>
|
|
155
|
+
</InlineFieldsRegistryProvider>
|
|
156
|
+
</PayloadFieldsProvider>
|
|
163
157
|
</FormMetaProvider>
|
|
164
158
|
</Card>
|
|
165
159
|
);
|