@object-ui/plugin-form 17.6.0 → 18.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/CHANGELOG.md +4991 -0
- package/README.md +522 -80
- package/dist/DrawerForm.d.ts +42 -3
- package/dist/DrawerForm.d.ts.map +1 -1
- package/dist/EmbeddableForm.d.ts.map +1 -1
- package/dist/FormAnalytics.d.ts.map +1 -1
- package/dist/LineItemsPanel.d.ts +6 -3
- package/dist/LineItemsPanel.d.ts.map +1 -1
- package/dist/MasterDetailForm.d.ts +79 -38
- package/dist/MasterDetailForm.d.ts.map +1 -1
- package/dist/ModalForm.d.ts +60 -5
- package/dist/ModalForm.d.ts.map +1 -1
- package/dist/ObjectForm.d.ts.map +1 -1
- package/dist/SplitForm.d.ts +49 -3
- package/dist/SplitForm.d.ts.map +1 -1
- package/dist/TabbedForm.d.ts +75 -5
- package/dist/TabbedForm.d.ts.map +1 -1
- package/dist/WizardForm.d.ts +145 -38
- package/dist/WizardForm.d.ts.map +1 -1
- package/dist/autoLayout.d.ts +113 -8
- package/dist/autoLayout.d.ts.map +1 -1
- package/dist/closedAffordanceNotice.d.ts +14 -0
- package/dist/closedAffordanceNotice.d.ts.map +1 -0
- package/dist/customFieldsMerge.d.ts +29 -0
- package/dist/customFieldsMerge.d.ts.map +1 -0
- package/dist/deriveMasterDetail.d.ts +82 -29
- package/dist/deriveMasterDetail.d.ts.map +1 -1
- package/dist/fieldGroups.d.ts +189 -0
- package/dist/fieldGroups.d.ts.map +1 -1
- package/dist/fieldWriteGate.d.ts +136 -0
- package/dist/fieldWriteGate.d.ts.map +1 -0
- package/dist/flatFields.d.ts +11 -2
- package/dist/flatFields.d.ts.map +1 -1
- package/dist/formChrome.d.ts +55 -0
- package/dist/formChrome.d.ts.map +1 -0
- package/dist/index.d.ts +149 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3984 -2332
- package/dist/index.umd.cjs +1 -1
- package/dist/initialFieldFocus.d.ts +23 -0
- package/dist/initialFieldFocus.d.ts.map +1 -0
- package/dist/initialRecord.d.ts +72 -0
- package/dist/initialRecord.d.ts.map +1 -0
- package/dist/loadFailure.d.ts +28 -0
- package/dist/loadFailure.d.ts.map +1 -0
- package/dist/masterDetailTx.d.ts.map +1 -1
- package/dist/occSave.d.ts +6 -1
- package/dist/occSave.d.ts.map +1 -1
- package/dist/recordInvalidation.d.ts +33 -0
- package/dist/recordInvalidation.d.ts.map +1 -0
- package/dist/recordReadGate.d.ts +34 -0
- package/dist/recordReadGate.d.ts.map +1 -0
- package/dist/sanitize.d.ts +272 -5
- package/dist/sanitize.d.ts.map +1 -1
- package/dist/schemaDefaults.d.ts +104 -9
- package/dist/schemaDefaults.d.ts.map +1 -1
- package/dist/sectionFields.d.ts +67 -2
- package/dist/sectionFields.d.ts.map +1 -1
- package/dist/sectionGroups.d.ts +62 -0
- package/dist/sectionGroups.d.ts.map +1 -0
- package/dist/sectionPredicateDiagnostic.d.ts +38 -0
- package/dist/sectionPredicateDiagnostic.d.ts.map +1 -0
- package/dist/submitTarget.d.ts +136 -0
- package/dist/submitTarget.d.ts.map +1 -0
- package/dist/successBehavior.d.ts +44 -25
- package/dist/successBehavior.d.ts.map +1 -1
- package/dist/thankYouRedirectCountdown.d.ts +1 -1
- package/dist/uploadGate.d.ts +35 -0
- package/dist/uploadGate.d.ts.map +1 -0
- package/dist/writePayload.d.ts +87 -0
- package/dist/writePayload.d.ts.map +1 -0
- package/package.json +13 -12
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { useUploadingScope } from '@object-ui/fields';
|
|
3
|
+
export interface UploadGate {
|
|
4
|
+
/** True while at least one upload inside this form is still in flight. */
|
|
5
|
+
uploading: boolean;
|
|
6
|
+
/** Mount around the form body so its upload widgets report in. */
|
|
7
|
+
scope: ReturnType<typeof useUploadingScope>;
|
|
8
|
+
/** The Save button's label while `uploading`. */
|
|
9
|
+
busyLabel: string;
|
|
10
|
+
/** Why Save is unavailable — shown, and used as the refusal message. */
|
|
11
|
+
reason: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Own the gate for one record form. The host renders its form body inside
|
|
15
|
+
* {@link UploadGateProvider} with the returned `scope`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useUploadGate(): UploadGate;
|
|
18
|
+
/** Re-exported under this package's own name so hosts import one module. */
|
|
19
|
+
export declare function UploadGateProvider({ gate, children, }: {
|
|
20
|
+
gate: UploadGate;
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
}): React.ReactElement;
|
|
23
|
+
/**
|
|
24
|
+
* The visible reason. Rendered beside the action row, not as a toast: the
|
|
25
|
+
* explanation has to be readable at the moment the user looks at the control
|
|
26
|
+
* that will not respond, and a toast is gone by then.
|
|
27
|
+
*
|
|
28
|
+
* `role="status"` (polite) rather than `alert`: nothing has gone wrong, an
|
|
29
|
+
* upload is simply still running, and an assertive live region would interrupt
|
|
30
|
+
* a screen-reader user mid-sentence every time a file is picked.
|
|
31
|
+
*/
|
|
32
|
+
export declare function UploadInFlightNotice({ gate }: {
|
|
33
|
+
gate: UploadGate;
|
|
34
|
+
}): React.ReactElement | null;
|
|
35
|
+
//# sourceMappingURL=uploadGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadGate.d.ts","sourceRoot":"","sources":["../src/uploadGate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAA0B,MAAM,mBAAmB,CAAC;AAgD9E,MAAM,WAAW,UAAU;IACzB,0EAA0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,KAAK,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;IAC5C,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAS1C;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,GAAG,KAAK,CAAC,YAAY,CAErB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CAO9F"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { LoadedRecordSnapshot } from './sanitize.js';
|
|
2
|
+
import { FieldWriteGate } from './fieldWriteGate.js';
|
|
3
|
+
/** The facts of a form schema the outbound sequence reads. */
|
|
4
|
+
export interface FormWriteTarget {
|
|
5
|
+
mode?: string;
|
|
6
|
+
objectName: string;
|
|
7
|
+
recordId?: string | number | null;
|
|
8
|
+
/** Inline field definitions (`object-form.customFields`). */
|
|
9
|
+
customFields?: readonly unknown[] | null;
|
|
10
|
+
}
|
|
11
|
+
/** Where the outbound sequence gets its answers from. */
|
|
12
|
+
export interface FormWriteSources {
|
|
13
|
+
/** The object definition the form loaded, or `null` when it has none. */
|
|
14
|
+
objectSchema: {
|
|
15
|
+
fields?: Record<string, Record<string, unknown> | undefined>;
|
|
16
|
+
} | null | undefined;
|
|
17
|
+
/** The caller's field-level write verdict — {@link FieldWriteGate}. */
|
|
18
|
+
canEdit: FieldWriteGate | undefined;
|
|
19
|
+
/** The record this form read for the record it edits (objectui#10156). */
|
|
20
|
+
snapshot: LoadedRecordSnapshot | null | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* On a create, the values the form OPENED with — its `seedCreateValues`
|
|
23
|
+
* result (objectui#12359). An owner the user picked against it is written,
|
|
24
|
+
* and one the form was seeded with and the user left alone is not. Ignored
|
|
25
|
+
* on an edit.
|
|
26
|
+
*
|
|
27
|
+
* Required, so a layout cannot forget it and silently drop a pick again —
|
|
28
|
+
* which is how every create writer behaved before. `null` says there is no
|
|
29
|
+
* opening value to judge against: no pick can then be told from a seed, so
|
|
30
|
+
* the owner stays off the wire.
|
|
31
|
+
*/
|
|
32
|
+
createBaseline: Record<string, unknown> | null;
|
|
33
|
+
}
|
|
34
|
+
export interface FormWritePayloads {
|
|
35
|
+
/**
|
|
36
|
+
* Every value the form may write, as the form now holds it: stripped of what
|
|
37
|
+
* a form never writes and, on a create, of the fields the producer owns. On
|
|
38
|
+
* a create it also carries an owner the user picked (objectui#12359), since
|
|
39
|
+
* a create writes `payload` itself.
|
|
40
|
+
*/
|
|
41
|
+
payload: Record<string, unknown>;
|
|
42
|
+
/**
|
|
43
|
+
* What the save sends — on BOTH routes, the host `submitHandler` and the
|
|
44
|
+
* form's own create / OCC-guarded update. On an edit, the fields of
|
|
45
|
+
* {@link FormWritePayloads.payload} that differ from the record the form
|
|
46
|
+
* read; otherwise `payload` itself.
|
|
47
|
+
*/
|
|
48
|
+
writePayload: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The ONE outbound sequence of a record form: what a save writes, built from
|
|
52
|
+
* the values the form collected (objectui#10563).
|
|
53
|
+
*
|
|
54
|
+
* 1. `sanitizeFormData` drops what a form never writes — server-owned columns
|
|
55
|
+
* (objectui#10108), computed / formula / read-only columns, keys the object
|
|
56
|
+
* does not declare, and every field the caller's field-level security
|
|
57
|
+
* refuses (`canEdit`, `80c54122e`).
|
|
58
|
+
* 2. On a create, `createOwnerPayload` adds back an owner the user picked
|
|
59
|
+
* against {@link FormWriteSources.createBaseline} (objectui#12359), and then
|
|
60
|
+
* `omitServerResolvedDefaults` drops an empty field whose runtime default
|
|
61
|
+
* the producer resolves (#4069).
|
|
62
|
+
* 3. On an edit, `dirtyEditPayload` keeps only the fields that differ from the
|
|
63
|
+
* record the form read (objectui#10156), and sends the whole of step 1's
|
|
64
|
+
* result when it cannot settle that. It is handed the values too, so an
|
|
65
|
+
* owner the user changed is written while an untouched one is not
|
|
66
|
+
* (objectui#12205): on an edit only `writePayload` can carry it, never
|
|
67
|
+
* `payload`.
|
|
68
|
+
*
|
|
69
|
+
* ## Why it is one function
|
|
70
|
+
*
|
|
71
|
+
* `ObjectForm` routes a record save through several layouts, and each layout
|
|
72
|
+
* owns its save handler. When the sequence was spelled inline in each handler,
|
|
73
|
+
* three of them — `TabbedForm`, `SplitForm` and `WizardForm` (which also renders
|
|
74
|
+
* a simple form's mobile `stepper`) — carried none of it and wrote every value
|
|
75
|
+
* they held, `id`, `owner_id`, the formula columns and the field-level-refused
|
|
76
|
+
* ones included. ⛔ Do not spell any step of it beside a call to this function.
|
|
77
|
+
*
|
|
78
|
+
* ## The inline-members rule
|
|
79
|
+
*
|
|
80
|
+
* With a non-empty `customFields` the object definition is NOT handed to steps
|
|
81
|
+
* 1 and 2: an inline member may name a field the object never declares (it is
|
|
82
|
+
* appended after the generated set, objectui#9778), and the unknown-key strip
|
|
83
|
+
* would drop the value the author asked for. The server-owned roster and the
|
|
84
|
+
* field-level verdict still apply, because neither needs a definition.
|
|
85
|
+
*/
|
|
86
|
+
export declare function formWritePayload(values: Record<string, unknown>, form: FormWriteTarget, { objectSchema, canEdit, snapshot, createBaseline }: FormWriteSources): FormWritePayloads;
|
|
87
|
+
//# sourceMappingURL=writePayload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writePayload.d.ts","sourceRoot":"","sources":["../src/writePayload.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAAC;CAC1C;AAED,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,YAAY,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IAClG,uEAAuE;IACvE,OAAO,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC,0EAA0E;IAC1E,QAAQ,EAAE,oBAAoB,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD;;;;;;;;;;OAUG;IACH,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,eAAe,EACrB,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,gBAAgB,GACpE,iBAAiB,CAmBnB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/plugin-form",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "18.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Form plugin for Object UI",
|
|
@@ -15,15 +15,15 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@objectstack/spec": "^
|
|
19
|
-
"lucide-react": "^1.
|
|
20
|
-
"@object-ui/components": "
|
|
21
|
-
"@object-ui/core": "
|
|
22
|
-
"@object-ui/fields": "
|
|
23
|
-
"@object-ui/i18n": "
|
|
24
|
-
"@object-ui/permissions": "
|
|
25
|
-
"@object-ui/react": "
|
|
26
|
-
"@object-ui/types": "
|
|
18
|
+
"@objectstack/spec": "^18.0.0",
|
|
19
|
+
"lucide-react": "^1.43.0",
|
|
20
|
+
"@object-ui/components": "18.0.0",
|
|
21
|
+
"@object-ui/core": "18.0.0",
|
|
22
|
+
"@object-ui/fields": "18.0.0",
|
|
23
|
+
"@object-ui/i18n": "18.0.0",
|
|
24
|
+
"@object-ui/permissions": "18.0.0",
|
|
25
|
+
"@object-ui/react": "18.0.0",
|
|
26
|
+
"@object-ui/types": "18.0.0"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"typescript": "^6.0.3",
|
|
36
36
|
"vite": "^8.2.1",
|
|
37
37
|
"vite-plugin-dts": "^5.0.3",
|
|
38
|
-
"@object-ui/data-objectstack": "
|
|
38
|
+
"@object-ui/data-objectstack": "18.0.0",
|
|
39
|
+
"@object-ui/test-support": "17.4.0"
|
|
39
40
|
},
|
|
40
41
|
"keywords": [
|
|
41
42
|
"objectui",
|
|
@@ -71,7 +72,7 @@
|
|
|
71
72
|
],
|
|
72
73
|
"scripts": {
|
|
73
74
|
"build": "vite build",
|
|
74
|
-
"test": "vitest run",
|
|
75
|
+
"test": "vitest run --root ../.. packages/plugin-form/",
|
|
75
76
|
"type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
|
|
76
77
|
"lint": "eslint ."
|
|
77
78
|
}
|