@asteby/metacore-runtime-react 23.11.1 → 23.11.2
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 +6 -0
- package/dist/dynamic-form.d.ts.map +1 -1
- package/dist/dynamic-form.js +12 -6
- package/package.json +1 -1
- package/src/dynamic-form.tsx +16 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @asteby/metacore-runtime-react
|
|
2
2
|
|
|
3
|
+
## 23.11.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 990bb63: DynamicForm oculta los campos readonly (estado de conexión, valores escritos por sync): el servidor los posee, el form no los captura ni los envía en el submit.
|
|
8
|
+
|
|
3
9
|
## 23.11.1
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-form.d.ts","sourceRoot":"","sources":["../src/dynamic-form.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,EACH,cAAc,EACd,aAAa,EAKhB,MAAM,uBAAuB,CAAA;AAO9B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE5C,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,WAAW,CAAC,EACxB,MAAM,EACN,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,WAAuB,EACvB,WAAwB,EACxB,QAAgB,GACnB,EAAE,gBAAgB,+
|
|
1
|
+
{"version":3,"file":"dynamic-form.d.ts","sourceRoot":"","sources":["../src/dynamic-form.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,EACH,cAAc,EACd,aAAa,EAKhB,MAAM,uBAAuB,CAAA;AAO9B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE5C,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,WAAW,CAAC,EACxB,MAAM,EACN,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,WAAuB,EACvB,WAAwB,EACxB,QAAgB,GACnB,EAAE,gBAAgB,+BA8FlB"}
|
package/dist/dynamic-form.js
CHANGED
|
@@ -19,22 +19,28 @@ export function DynamicForm({ fields, initialValues, onSubmit, onCancel, submitL
|
|
|
19
19
|
const [values, setValues] = useState({});
|
|
20
20
|
const [errors, setErrors] = useState({});
|
|
21
21
|
const [submitting, setSubmitting] = useState(false);
|
|
22
|
-
|
|
22
|
+
// Readonly fields are system-owned (connection state, sync-written values):
|
|
23
|
+
// the server writes them, so the form never captures them — hidden outright
|
|
24
|
+
// instead of rendered disabled, matching the metadata contract
|
|
25
|
+
// (ColumnDef.Readonly). They are also excluded from defaults/submit so a
|
|
26
|
+
// create never posts e.g. `status: ""` over the column default.
|
|
27
|
+
const editableFields = useMemo(() => fields.filter((f) => !f.readonly), [fields]);
|
|
28
|
+
const schema = useMemo(() => buildZodSchema(editableFields), [editableFields]);
|
|
23
29
|
// Line-items fields carrying a balance rule gate submit: an unbalanced entry
|
|
24
30
|
// (Σdebit ≠ Σcredit, or all-zero when require_nonzero) can't be saved. This
|
|
25
31
|
// is fully declarative — `evaluateBalance` returns undefined for fields with
|
|
26
32
|
// no rule, so non-balanced forms are unaffected.
|
|
27
33
|
const balanceBlocked = useMemo(() => {
|
|
28
|
-
for (const f of
|
|
34
|
+
for (const f of editableFields) {
|
|
29
35
|
const state = evaluateBalance(f, values[f.key]);
|
|
30
36
|
if (state && !state.balanced)
|
|
31
37
|
return true;
|
|
32
38
|
}
|
|
33
39
|
return false;
|
|
34
|
-
}, [
|
|
40
|
+
}, [editableFields, values]);
|
|
35
41
|
useEffect(() => {
|
|
36
42
|
const defaults = {};
|
|
37
|
-
for (const f of
|
|
43
|
+
for (const f of editableFields) {
|
|
38
44
|
if (isLineItemsField(f)) {
|
|
39
45
|
defaults[f.key] = initialValues?.[f.key] ?? f.defaultValue ?? [];
|
|
40
46
|
continue;
|
|
@@ -43,7 +49,7 @@ export function DynamicForm({ fields, initialValues, onSubmit, onCancel, submitL
|
|
|
43
49
|
}
|
|
44
50
|
setValues(defaults);
|
|
45
51
|
setErrors({});
|
|
46
|
-
}, [
|
|
52
|
+
}, [editableFields, initialValues]);
|
|
47
53
|
const update = (k, v) => setValues((prev) => ({ ...prev, [k]: v }));
|
|
48
54
|
const handleSubmit = async (e) => {
|
|
49
55
|
e.preventDefault();
|
|
@@ -73,7 +79,7 @@ export function DynamicForm({ fields, initialValues, onSubmit, onCancel, submitL
|
|
|
73
79
|
// line-items grids (and textareas) span the full width so the row table /
|
|
74
80
|
// memo gets room. Mirrors the pro look of the federated journal modal but
|
|
75
81
|
// stays fully declarative — driven only by field shape.
|
|
76
|
-
return (_jsxs("form", { onSubmit: handleSubmit, className: "grid gap-4", children: [_jsx("div", { className: "grid gap-4 sm:grid-cols-2", children:
|
|
82
|
+
return (_jsxs("form", { onSubmit: handleSubmit, className: "grid gap-4", children: [_jsx("div", { className: "grid gap-4 sm:grid-cols-2", children: editableFields.map((field) => (_jsx(FieldRow, { field: field, value: values[field.key], onChange: (v) => update(field.key, v), values: values, error: errors[field.key], initialValues: initialValues }, field.key))) }), _jsxs("div", { className: "flex justify-end gap-2 pt-2", children: [onCancel && (_jsx(Button, { type: "button", variant: "outline", onClick: onCancel, disabled: submitting || disabled, children: cancelLabel })), _jsx(Button, { type: "submit", disabled: submitting || disabled || balanceBlocked, children: submitLabel })] })] }));
|
|
77
83
|
}
|
|
78
84
|
// One form field row: label + renderer + inline error. Encapsulated as its own
|
|
79
85
|
// component so a STATIC enum select whose options are all gated out by a sibling
|
package/package.json
CHANGED
package/src/dynamic-form.tsx
CHANGED
|
@@ -58,23 +58,33 @@ export function DynamicForm({
|
|
|
58
58
|
const [errors, setErrors] = useState<Record<string, string>>({})
|
|
59
59
|
const [submitting, setSubmitting] = useState(false)
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
// Readonly fields are system-owned (connection state, sync-written values):
|
|
62
|
+
// the server writes them, so the form never captures them — hidden outright
|
|
63
|
+
// instead of rendered disabled, matching the metadata contract
|
|
64
|
+
// (ColumnDef.Readonly). They are also excluded from defaults/submit so a
|
|
65
|
+
// create never posts e.g. `status: ""` over the column default.
|
|
66
|
+
const editableFields = useMemo(
|
|
67
|
+
() => fields.filter((f) => !(f as { readonly?: boolean }).readonly),
|
|
68
|
+
[fields],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
const schema = useMemo(() => buildZodSchema(editableFields), [editableFields])
|
|
62
72
|
|
|
63
73
|
// Line-items fields carrying a balance rule gate submit: an unbalanced entry
|
|
64
74
|
// (Σdebit ≠ Σcredit, or all-zero when require_nonzero) can't be saved. This
|
|
65
75
|
// is fully declarative — `evaluateBalance` returns undefined for fields with
|
|
66
76
|
// no rule, so non-balanced forms are unaffected.
|
|
67
77
|
const balanceBlocked = useMemo(() => {
|
|
68
|
-
for (const f of
|
|
78
|
+
for (const f of editableFields) {
|
|
69
79
|
const state = evaluateBalance(f, values[f.key])
|
|
70
80
|
if (state && !state.balanced) return true
|
|
71
81
|
}
|
|
72
82
|
return false
|
|
73
|
-
}, [
|
|
83
|
+
}, [editableFields, values])
|
|
74
84
|
|
|
75
85
|
useEffect(() => {
|
|
76
86
|
const defaults: Record<string, any> = {}
|
|
77
|
-
for (const f of
|
|
87
|
+
for (const f of editableFields) {
|
|
78
88
|
if (isLineItemsField(f)) {
|
|
79
89
|
defaults[f.key] = initialValues?.[f.key] ?? f.defaultValue ?? []
|
|
80
90
|
continue
|
|
@@ -83,7 +93,7 @@ export function DynamicForm({
|
|
|
83
93
|
}
|
|
84
94
|
setValues(defaults)
|
|
85
95
|
setErrors({})
|
|
86
|
-
}, [
|
|
96
|
+
}, [editableFields, initialValues])
|
|
87
97
|
|
|
88
98
|
const update = (k: string, v: any) =>
|
|
89
99
|
setValues((prev: Record<string, any>) => ({ ...prev, [k]: v }))
|
|
@@ -113,7 +123,7 @@ export function DynamicForm({
|
|
|
113
123
|
return (
|
|
114
124
|
<form onSubmit={handleSubmit} className="grid gap-4">
|
|
115
125
|
<div className="grid gap-4 sm:grid-cols-2">
|
|
116
|
-
{
|
|
126
|
+
{editableFields.map((field) => (
|
|
117
127
|
<FieldRow
|
|
118
128
|
key={field.key}
|
|
119
129
|
field={field}
|