@asteby/metacore-runtime-react 39.2.3 → 39.2.5
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 +12 -0
- package/dist/action-modal-dispatcher.d.ts +13 -0
- package/dist/action-modal-dispatcher.d.ts.map +1 -1
- package/dist/action-modal-dispatcher.js +57 -0
- package/dist/dialogs/dynamic-record.d.ts.map +1 -1
- package/dist/dialogs/dynamic-record.js +15 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/validator.d.ts +9 -0
- package/dist/validator.d.ts.map +1 -1
- package/dist/validator.js +32 -0
- package/package.json +1 -1
- package/src/__tests__/prefill-from-relation.test.ts +42 -0
- package/src/__tests__/validator.test.ts +28 -1
- package/src/action-modal-dispatcher.tsx +72 -0
- package/src/dialogs/dynamic-record.tsx +20 -3
- package/src/index.ts +1 -0
- package/src/validator.ts +36 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @asteby/metacore-runtime-react
|
|
2
2
|
|
|
3
|
+
## 39.2.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 92f150c: Al editar un registro, un valor que ya estaba guardado y no se modificó deja de re-validarse contra `validation` (regex, min, max, custom). Así un dato viejo que no cumple una regla agregada después (un RFC con guiones, un precio negativo) no bloquea el guardado de otros campos. Es el mismo criterio que aplica el kernel en `update`. Nuevo helper `exemptUnchangedRuleIssues` (LIVE-19).
|
|
8
|
+
|
|
9
|
+
## 39.2.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- c759e48: Los modales de acción que precargan renglones desde el registro (`$prefillFromRecord`, p. ej. "Recibir" de una orden de compra) ahora cargan las líneas desde la relación declarada del modelo cuando la fila de la lista no las trae. Antes el modal abría con "Sin renglones".
|
|
14
|
+
|
|
3
15
|
## 39.2.3
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -20,6 +20,19 @@ export interface PrefillSpec {
|
|
|
20
20
|
export declare function isPrefillSpec(v: unknown): v is PrefillSpec;
|
|
21
21
|
export declare function applyPrefillLock(field: ActionFieldDef): ActionFieldDef;
|
|
22
22
|
export declare function buildPrefillRows(spec: PrefillSpec, record: any): Array<Record<string, any>>;
|
|
23
|
+
export interface PrefillRelationRequest {
|
|
24
|
+
fieldKey: string;
|
|
25
|
+
spec: PrefillSpec;
|
|
26
|
+
endpoint: string;
|
|
27
|
+
params: Record<string, string | number>;
|
|
28
|
+
}
|
|
29
|
+
export declare function prefillRelationRequests(fields: ActionFieldDef[] | undefined, record: any, relations: Array<{
|
|
30
|
+
name?: string;
|
|
31
|
+
kind?: string;
|
|
32
|
+
through?: string;
|
|
33
|
+
foreign_key?: string;
|
|
34
|
+
scope?: Record<string, unknown>;
|
|
35
|
+
}>): PrefillRelationRequest[];
|
|
23
36
|
export declare function unwrapRecordScalar(value: unknown): unknown;
|
|
24
37
|
export declare function readRecordPath(record: any, path: string): unknown;
|
|
25
38
|
/** Scalar seed for one action field from the row being acted on. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-modal-dispatcher.d.ts","sourceRoot":"","sources":["../src/action-modal-dispatcher.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"action-modal-dispatcher.d.ts","sourceRoot":"","sources":["../src/action-modal-dispatcher.tsx"],"names":[],"mappings":"AAwEA,OAAO,KAAK,EAAE,cAAc,EAAmC,MAAM,SAAS,CAAA;AAE9E,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAExB,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAA;AAiBhD,MAAM,WAAW,WAAW;IACxB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1D;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAM1D;AAsBD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,CAStE;AAGD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAkB3F;AAYD,MAAM,WAAW,sBAAsB;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;CAC1C;AAED,wBAAgB,uBAAuB,CACnC,MAAM,EAAE,cAAc,EAAE,GAAG,SAAS,EACpC,MAAM,EAAE,GAAG,EACX,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,GAC5H,sBAAsB,EAAE,CAyB1B;AASD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAY1D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CASjE;AAUD,oEAAoE;AACpE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,CAgBnF;AAED,wBAAgB,qBAAqB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,GACZ,EAAE,gBAAgB,sCAkFlB"}
|
|
@@ -23,6 +23,7 @@ import { validateValues, bagHasErrors } from './validator';
|
|
|
23
23
|
import { clearFieldErrorTree, formatFieldErrorsDescription, labelsForValidationFields, labelForValidationPath, lineItemErrorsFor, } from './field-validation-ui';
|
|
24
24
|
import { validationCatalog } from './validation-catalog';
|
|
25
25
|
import { useApi } from './api-context';
|
|
26
|
+
import { buildRelationFilterParams } from './dynamic-relation-helpers';
|
|
26
27
|
import { DynamicIcon } from './dynamic-icon';
|
|
27
28
|
import { DynamicLineItems } from './dynamic-line-items';
|
|
28
29
|
import { DynamicRelations } from './dynamic-relations';
|
|
@@ -94,6 +95,36 @@ export function buildPrefillRows(spec, record) {
|
|
|
94
95
|
}
|
|
95
96
|
return rows;
|
|
96
97
|
}
|
|
98
|
+
export function prefillRelationRequests(fields, record, relations) {
|
|
99
|
+
const out = [];
|
|
100
|
+
const recordId = record?.id;
|
|
101
|
+
if (!fields || recordId === undefined || recordId === null || recordId === '')
|
|
102
|
+
return out;
|
|
103
|
+
for (const field of fields) {
|
|
104
|
+
if (!isLineItemsField(field))
|
|
105
|
+
continue;
|
|
106
|
+
const spec = lineItemsDefault(field);
|
|
107
|
+
if (!isPrefillSpec(spec))
|
|
108
|
+
continue;
|
|
109
|
+
if (Array.isArray(record?.[spec.$prefillFromRecord]))
|
|
110
|
+
continue; // already embedded
|
|
111
|
+
const rel = (relations || []).find((r) => r?.name === spec.$prefillFromRecord && (r.kind ?? 'one_to_many') === 'one_to_many');
|
|
112
|
+
if (!rel?.through || !rel.foreign_key)
|
|
113
|
+
continue;
|
|
114
|
+
const scope = {};
|
|
115
|
+
for (const [k, v] of Object.entries(rel.scope ?? {})) {
|
|
116
|
+
if (v !== undefined && v !== null)
|
|
117
|
+
scope[k] = String(v);
|
|
118
|
+
}
|
|
119
|
+
out.push({
|
|
120
|
+
fieldKey: field.key,
|
|
121
|
+
spec,
|
|
122
|
+
endpoint: `/data/${rel.through}`,
|
|
123
|
+
params: { ...buildRelationFilterParams(rel.foreign_key, recordId, scope), per_page: 200 },
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
97
128
|
// ---- scalar prefill from the acted-on record --------------------------------
|
|
98
129
|
//
|
|
99
130
|
// Row actions (stamp / refactura / cancel-with-reason) should open with the
|
|
@@ -457,6 +488,32 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
457
488
|
setFieldErrors({});
|
|
458
489
|
}
|
|
459
490
|
}, [open, action.fields, record]);
|
|
491
|
+
// Lines the list row does not carry: load them from the declared relation
|
|
492
|
+
// (see prefillRelationRequests) and seed the line-items grid.
|
|
493
|
+
useEffect(() => {
|
|
494
|
+
if (!open || relations.length === 0)
|
|
495
|
+
return;
|
|
496
|
+
const reqs = prefillRelationRequests(action.fields, record, relations);
|
|
497
|
+
if (reqs.length === 0)
|
|
498
|
+
return;
|
|
499
|
+
let cancelled = false;
|
|
500
|
+
for (const req of reqs) {
|
|
501
|
+
api.get(req.endpoint, { params: req.params })
|
|
502
|
+
.then((res) => {
|
|
503
|
+
if (cancelled)
|
|
504
|
+
return;
|
|
505
|
+
const rows = res?.data?.data ?? res?.data ?? [];
|
|
506
|
+
if (!Array.isArray(rows))
|
|
507
|
+
return;
|
|
508
|
+
const built = buildPrefillRows(req.spec, { [req.spec.$prefillFromRecord]: rows });
|
|
509
|
+
setFormData((prev) => ({ ...prev, [req.fieldKey]: built }));
|
|
510
|
+
})
|
|
511
|
+
.catch(() => { });
|
|
512
|
+
}
|
|
513
|
+
return () => {
|
|
514
|
+
cancelled = true;
|
|
515
|
+
};
|
|
516
|
+
}, [open, action.fields, record, relations, api]);
|
|
460
517
|
const updateField = (key, value) => {
|
|
461
518
|
setFormData((prev) => ({ ...prev, [key]: value }));
|
|
462
519
|
setFieldErrors((prev) => clearFieldErrorTree(prev, key));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-record.d.ts","sourceRoot":"","sources":["../../src/dialogs/dynamic-record.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"dynamic-record.d.ts","sourceRoot":"","sources":["../../src/dialogs/dynamic-record.tsx"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,7 @@ import { AssistInterview } from '../assist-interview';
|
|
|
36
36
|
import { FieldCell } from '../field-grid';
|
|
37
37
|
import { isNilUuid, normalizeNilUuid } from '../nil-uuid';
|
|
38
38
|
import { normalizeRefFieldsForSubmit } from './normalize-submit';
|
|
39
|
-
import { validateValues, bagHasErrors } from '../validator';
|
|
39
|
+
import { validateValues, bagHasErrors, exemptUnchangedRuleIssues } from '../validator';
|
|
40
40
|
import { DynamicIcon, isLucideIconName } from '../dynamic-icon';
|
|
41
41
|
import { IconPickerField } from '../icon-picker-field';
|
|
42
42
|
import { humanizeToken } from '../dynamic-columns-helpers';
|
|
@@ -560,7 +560,18 @@ export function DynamicRecordDialog({ open, onOpenChange, nestedInlineCreateSelf
|
|
|
560
560
|
// Laravel-style: collect every issue from the shared validator
|
|
561
561
|
// (required + rule strings / min/max / email…) on visible fields only.
|
|
562
562
|
const visible = filterVisibleFields(modalMeta.fields, mode, formValues);
|
|
563
|
-
|
|
563
|
+
let bag = validateValues(visible, formValues);
|
|
564
|
+
// Edit: a legacy value re-sent unchanged is not re-judged by a rule
|
|
565
|
+
// added after it was written (same grandfathering as the kernel).
|
|
566
|
+
if (mode === 'edit' && record) {
|
|
567
|
+
const persisted = {};
|
|
568
|
+
for (const f of visible) {
|
|
569
|
+
const v = resolvePath(record, f.key);
|
|
570
|
+
if (v !== undefined)
|
|
571
|
+
persisted[f.key] = v;
|
|
572
|
+
}
|
|
573
|
+
bag = exemptUnchangedRuleIssues(bag, formValues, persisted);
|
|
574
|
+
}
|
|
564
575
|
if (bagHasErrors(bag)) {
|
|
565
576
|
const labels = {};
|
|
566
577
|
for (const f of visible)
|
|
@@ -719,7 +730,7 @@ export function DynamicRecordDialog({ open, onOpenChange, nestedInlineCreateSelf
|
|
|
719
730
|
setStepIndex(Math.min(clampedStep + 1, groups.length - 1));
|
|
720
731
|
};
|
|
721
732
|
const goBackStep = () => setStepIndex(Math.max(clampedStep - 1, 0));
|
|
722
|
-
return (_jsx(RecordDialogModelContext.Provider, { value: model, children: _jsx(Dialog, { open: open, onOpenChange: onOpenChange, nestedInlineCreateSelf: nestedInlineCreateSelf, children: _jsxs(DialogContent, { className: "sm:max-w-2xl max-h-[90dvh] flex flex-col p-0 gap-0 overflow-hidden", style: { maxHeight: '90dvh' }, children: [_jsxs(DialogHeader, { className: "p-6 pb-4 border-b shrink-0", children: [_jsx(DialogTitle, { children: title }), _jsx(DialogDescription, { children: config.description })] }), _jsx("div", { className: "flex-1 overflow-y-auto p-6", children: loading ? (_jsx(LoadingSkeleton, {})) : modalMeta ? (_jsx(ModelContext.Provider, { value: model, children: _jsx(ImageUrlContext.Provider, { value: getImageUrl, children: _jsx(TimeZoneContext.Provider, { value: timeZone, children: _jsxs(CurrencyContext.Provider, { value: currency, children: [_jsxs("form", { id: formId, onSubmit: handleSubmit, className: "grid gap-y-4", children: [isSteps && (_jsx(WizardProgress, { groups: groups, stepIndex: clampedStep, onStepClick: i => setStepIndex(i) })), (isSteps ? [groups[clampedStep]] : groups).map(group =>
|
|
733
|
+
return (_jsx(RecordDialogModelContext.Provider, { value: model, children: _jsx(Dialog, { open: open, onOpenChange: onOpenChange, nestedInlineCreateSelf: nestedInlineCreateSelf, children: _jsxs(DialogContent, { className: "sm:max-w-2xl max-h-[90dvh] flex flex-col p-0 gap-0 overflow-hidden", style: { maxHeight: '90dvh' }, children: [_jsxs(DialogHeader, { className: "p-6 pb-4 border-b shrink-0", children: [_jsx(DialogTitle, { children: title }), _jsx(DialogDescription, { children: config.description })] }), _jsx("div", { className: "flex-1 overflow-y-auto p-6", children: loading ? (_jsx(LoadingSkeleton, {})) : modalMeta ? (_jsx(ModelContext.Provider, { value: model, children: _jsx(ImageUrlContext.Provider, { value: getImageUrl, children: _jsx(TimeZoneContext.Provider, { value: timeZone, children: _jsxs(CurrencyContext.Provider, { value: currency, children: [_jsxs("form", { id: formId, "data-aby-record-form": "", "data-aby-model": model, "data-aby-mode": mode, onSubmit: handleSubmit, className: "grid gap-y-4", children: [isSteps && (_jsx(WizardProgress, { groups: groups, stepIndex: clampedStep, onStepClick: i => setStepIndex(i) })), (isSteps ? [groups[clampedStep]] : groups).map(group =>
|
|
723
734
|
// An assisted step IS the interview: no form inputs, the
|
|
724
735
|
// provider asks what it needs and fills the fields.
|
|
725
736
|
isSteps && isEditable && group.assist ? (_jsx(AssistInterview, { assist: group.assist, values: formValues, eyebrow: group.title, autoStart: group.assist.trigger !== 'button', onApply: fields => setFormValues(prev => ({ ...prev, ...fields })) }, group.key)) : (_jsxs(FieldSection, { group: group, children: [_jsx("div", { className: "grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: renderFields(group.fields) }), isEditable && group.assist && (_jsx(AssistInterview, { assist: group.assist, values: formValues, eyebrow: group.title, autoStart: group.assist.trigger === 'auto', onApply: fields => setFormValues(prev => ({ ...prev, ...fields })) }))] }, group.key))), record?.external_url && (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2", children: _jsx("div", { className: "sm:col-span-2 min-w-0", children: _jsxs("a", { href: record.external_url, target: "_blank", rel: "noreferrer", className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline mt-1", children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5" }), "Ver en ", record.external_provider ?? 'proveedor externo'] }) }) }))] }), !isCreate && record && relations.length > 0 && (_jsx("div", { className: "mt-6", children: _jsx(DynamicRelations, { record: record, relations: relations, lineSubtable: true, embedOnly: true, canCreate: mode === 'edit', canEdit: mode === 'edit', canDelete: mode === 'edit', onChange: handleChildChange }) }))] }) }) }) })) : null }), _jsxs(DialogFooter, { className: "p-4 border-t shrink-0 sm:justify-between", children: [isView && onOpenFullPage ? (_jsxs(Button, { variant: "ghost", size: "sm", className: "text-muted-foreground", onClick: () => { onOpenChange(false); onOpenFullPage(); }, children: [_jsx(ExternalLink, { className: "mr-1.5 h-3.5 w-3.5" }), "Ver p\u00E1gina completa"] })) : _jsx("span", {}), _jsxs("div", { className: "flex items-center gap-2", children: [isSteps && clampedStep > 0 ? (_jsx(Button, { variant: "outline", onClick: goBackStep, disabled: saving || deleting, children: "Anterior" })) : (_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: saving || deleting, children: config.cancelLabel })), isView && onDelete && (_jsxs(Button, { variant: "destructive", onClick: handleDelete, disabled: deleting || loading, children: [deleting && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), deleting ? 'Eliminando...' : 'Eliminar'] })), isView && onEdit && (_jsx(Button, { onClick: onEdit, disabled: deleting || loading, children: "Editar" })), isEditable && isSteps && !isLastStep && (_jsx(Button, { type: "button", onClick: goNextStep, disabled: saving || loading, children: "Siguiente" })), isEditable && (!isSteps || isLastStep) && (_jsxs(Button, { type: "submit", form: formId, disabled: saving || loading, children: [saving && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), saving ? config.submittingLabel : config.submitLabel] }))] })] })] }) }) }));
|
|
@@ -736,7 +747,7 @@ function FieldRow({ field, record, value, mode, onChange, error, locked }) {
|
|
|
736
747
|
// the rich read-only renderer. `locked` forces the same disabled rendering on
|
|
737
748
|
// CREATE for a caller-specified field (see `lockedFields`).
|
|
738
749
|
const isEditReadonly = (mode === 'edit' && !!field.readonly) || !!locked;
|
|
739
|
-
return (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsxs(Label, { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: [field.label, field.required && mode !== 'view' && !isEditReadonly && (_jsx("span", { className: "text-destructive ml-0.5", children: "*" }))] }), mode === 'view' ? (_jsx(ViewValue, { field: field, value: value, record: record })) : isEditReadonly ? (_jsx(ReadonlyEditField, { field: field, value: value })) : (_jsx(EditField, { field: field, value: value, onChange: onChange, record: record, invalid: !!error })), error && mode !== 'view' && (_jsx("p", { className: "text-destructive text-xs mt-1", children: error }))] }));
|
|
750
|
+
return (_jsxs("div", { className: "flex flex-col gap-1.5", "data-aby-field": field.key, children: [_jsxs(Label, { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: [field.label, field.required && mode !== 'view' && !isEditReadonly && (_jsx("span", { className: "text-destructive ml-0.5", children: "*" }))] }), mode === 'view' ? (_jsx(ViewValue, { field: field, value: value, record: record })) : isEditReadonly ? (_jsx(ReadonlyEditField, { field: field, value: value })) : (_jsx(EditField, { field: field, value: value, onChange: onChange, record: record, invalid: !!error })), error && mode !== 'view' && (_jsx("p", { className: "text-destructive text-xs mt-1", children: error }))] }));
|
|
740
751
|
}
|
|
741
752
|
// ReadonlyEditField — the edit-mode rendering of a `readonly` (system-generated)
|
|
742
753
|
// field: a disabled, muted input that shows the current value without allowing
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from './table-virtualization';
|
|
|
3
3
|
export { LicenseGate, LicenseExpiryBanner, LicenseStatusBadge, isLicenseOperable, isLicenseBlocking, isPresetEntitled, isTrialExpired, type LicenseGateProps, type LicenseExpiryBannerProps, type LicenseStatusBadgeProps, type LicenseState, type LicenseStatus, type LicenseBranding, } from './license';
|
|
4
4
|
export * from './options-context';
|
|
5
5
|
export { extractServerError, extractFieldErrors, localizeFieldIssue, localizeFieldErrorMap, toastServerError, toastServerSuccess, type ExtractedError, type Translate, type FieldIssue, } from './server-error';
|
|
6
|
-
export { parseRuleString, fieldValidationOf, checkValue, validateValues, bagHasErrors, type ValidationSpec, } from './validator';
|
|
6
|
+
export { parseRuleString, fieldValidationOf, checkValue, validateValues, bagHasErrors, exemptUnchangedRuleIssues, type ValidationSpec, } from './validator';
|
|
7
7
|
export { VALIDATION_CATALOGS, validationCatalog, validationMessageKey } from './validation-catalog';
|
|
8
8
|
export { labelForValidationPath, labelsForValidationFields, formatFieldErrorsDescription, clearFieldErrorTree, lineItemErrorsFor, } from './field-validation-ui';
|
|
9
9
|
export * from './dynamic-table';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ export * from './table-virtualization';
|
|
|
8
8
|
export { LicenseGate, LicenseExpiryBanner, LicenseStatusBadge, isLicenseOperable, isLicenseBlocking, isPresetEntitled, isTrialExpired, } from './license';
|
|
9
9
|
export * from './options-context';
|
|
10
10
|
export { extractServerError, extractFieldErrors, localizeFieldIssue, localizeFieldErrorMap, toastServerError, toastServerSuccess, } from './server-error';
|
|
11
|
-
export { parseRuleString, fieldValidationOf, checkValue, validateValues, bagHasErrors, } from './validator';
|
|
11
|
+
export { parseRuleString, fieldValidationOf, checkValue, validateValues, bagHasErrors, exemptUnchangedRuleIssues, } from './validator';
|
|
12
12
|
export { VALIDATION_CATALOGS, validationCatalog, validationMessageKey } from './validation-catalog';
|
|
13
13
|
export { labelForValidationPath, labelsForValidationFields, formatFieldErrorsDescription, clearFieldErrorTree, lineItemErrorsFor, } from './field-validation-ui';
|
|
14
14
|
export * from './dynamic-table';
|
package/dist/validator.d.ts
CHANGED
|
@@ -19,4 +19,13 @@ export declare function checkValue(value: unknown, spec: ValidationSpec): FieldI
|
|
|
19
19
|
* field issue, dotted keys for line-items (`items.0.qty`). */
|
|
20
20
|
export declare function validateValues(fields: readonly ActionFieldDef[], values: Record<string, unknown>): Record<string, FieldIssue[]>;
|
|
21
21
|
export declare function bagHasErrors(bag: Record<string, FieldIssue[]>): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Edit mode: drop the rule issues (regex/min/max/custom) of a top-level field
|
|
24
|
+
* whose value is the one already persisted. The edit form posts every field
|
|
25
|
+
* back, so a rule added after the row was written (an RFC pattern over legacy
|
|
26
|
+
* data) would otherwise block saving a record over a field nobody touched.
|
|
27
|
+
* Mirrors the kernel (dynamic.validateWrite grandfathers unchanged values on
|
|
28
|
+
* update). required / invalid_option / invalid_type are kept.
|
|
29
|
+
*/
|
|
30
|
+
export declare function exemptUnchangedRuleIssues(bag: Record<string, FieldIssue[]>, values: Record<string, unknown>, persisted: Record<string, unknown> | null | undefined): Record<string, FieldIssue[]>;
|
|
22
31
|
//# sourceMappingURL=validator.d.ts.map
|
package/dist/validator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAKhD,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAQD,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAyCzD;AAqCD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAUlG;AAiCD,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,UAAU,EAAE,CAmC7E;AAgDD;+DAC+D;AAC/D,wBAAgB,cAAc,CAC1B,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAI9B;AA8BD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,GAAG,OAAO,CAEvE"}
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAKhD,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAQD,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAyCzD;AAqCD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAUlG;AAiCD,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,UAAU,EAAE,CAmC7E;AAgDD;+DAC+D;AAC/D,wBAAgB,cAAc,CAC1B,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAI9B;AA8BD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,GAAG,OAAO,CAEvE;AAYD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACrC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,EACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GACtD,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAY9B"}
|
package/dist/validator.js
CHANGED
|
@@ -259,3 +259,35 @@ function walk(fields, values, prefix, bag) {
|
|
|
259
259
|
export function bagHasErrors(bag) {
|
|
260
260
|
return Object.keys(bag).length > 0;
|
|
261
261
|
}
|
|
262
|
+
/** Issue codes produced by a field's declarative rule (regex / min / max /
|
|
263
|
+
* custom builtins) — the ones the kernel grandfathers on update. */
|
|
264
|
+
const RULE_CODES = new Set(['regex', 'min', 'max', 'email', 'uuid', 'url', 'numeric', 'integer', 'custom']);
|
|
265
|
+
function sameValue(a, b) {
|
|
266
|
+
if (isEmpty(a) && isEmpty(b))
|
|
267
|
+
return true;
|
|
268
|
+
if (isNumeric(a) && isNumeric(b))
|
|
269
|
+
return numericValue(a) === numericValue(b);
|
|
270
|
+
return asString(a) === asString(b);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Edit mode: drop the rule issues (regex/min/max/custom) of a top-level field
|
|
274
|
+
* whose value is the one already persisted. The edit form posts every field
|
|
275
|
+
* back, so a rule added after the row was written (an RFC pattern over legacy
|
|
276
|
+
* data) would otherwise block saving a record over a field nobody touched.
|
|
277
|
+
* Mirrors the kernel (dynamic.validateWrite grandfathers unchanged values on
|
|
278
|
+
* update). required / invalid_option / invalid_type are kept.
|
|
279
|
+
*/
|
|
280
|
+
export function exemptUnchangedRuleIssues(bag, values, persisted) {
|
|
281
|
+
if (!persisted)
|
|
282
|
+
return bag;
|
|
283
|
+
const out = {};
|
|
284
|
+
for (const [path, issues] of Object.entries(bag)) {
|
|
285
|
+
const unchanged = !path.includes('.') &&
|
|
286
|
+
Object.prototype.hasOwnProperty.call(persisted, path) &&
|
|
287
|
+
sameValue(values?.[path], persisted[path]);
|
|
288
|
+
const kept = unchanged ? issues.filter(i => !RULE_CODES.has(String(i.code))) : issues;
|
|
289
|
+
if (kept.length)
|
|
290
|
+
out[path] = kept;
|
|
291
|
+
}
|
|
292
|
+
return out;
|
|
293
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { prefillRelationRequests } from '../action-modal-dispatcher'
|
|
3
|
+
import type { ActionFieldDef } from '../types'
|
|
4
|
+
|
|
5
|
+
// QA 7Leguas: the purchase-order receive modal opened from the LIST showed
|
|
6
|
+
// "Sin renglones" — the list row carries no `items`, so the
|
|
7
|
+
// $prefillFromRecord grid had nothing to project. The modal must load the
|
|
8
|
+
// lines from the model's declared one_to_many relation.
|
|
9
|
+
const itemsField: ActionFieldDef = {
|
|
10
|
+
key: 'items',
|
|
11
|
+
label: 'Renglones',
|
|
12
|
+
type: 'array',
|
|
13
|
+
itemFields: [
|
|
14
|
+
{ key: 'product_id', label: 'Producto', type: 'dynamic_select', ref: 'Product' },
|
|
15
|
+
{ key: 'qty_received', label: 'Recibido', type: 'number' },
|
|
16
|
+
],
|
|
17
|
+
default: { $prefillFromRecord: 'items', map: { product_id: 'product_variant_id' } },
|
|
18
|
+
} as unknown as ActionFieldDef
|
|
19
|
+
|
|
20
|
+
const relations = [
|
|
21
|
+
{ name: 'items', kind: 'one_to_many', through: 'PurchaseOrderItem', foreign_key: 'purchase_order_id' },
|
|
22
|
+
{ name: 'goods_receipts', kind: 'one_to_many', through: 'GoodsReceipt', foreign_key: 'purchase_order_id' },
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
describe('prefillRelationRequests', () => {
|
|
26
|
+
it('pide las líneas por la relación declarada cuando el registro no las trae', () => {
|
|
27
|
+
const reqs = prefillRelationRequests([itemsField], { id: 'po-1' }, relations)
|
|
28
|
+
expect(reqs).toHaveLength(1)
|
|
29
|
+
expect(reqs[0].fieldKey).toBe('items')
|
|
30
|
+
expect(reqs[0].endpoint).toBe('/data/PurchaseOrderItem')
|
|
31
|
+
expect(reqs[0].params).toMatchObject({ f_purchase_order_id: 'eq:po-1' })
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('no pide nada si el registro ya trae las líneas embebidas', () => {
|
|
35
|
+
expect(prefillRelationRequests([itemsField], { id: 'po-1', items: [] }, relations)).toHaveLength(0)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('no pide nada sin id (acción de creación) o sin relación con ese nombre', () => {
|
|
39
|
+
expect(prefillRelationRequests([itemsField], {}, relations)).toHaveLength(0)
|
|
40
|
+
expect(prefillRelationRequests([itemsField], { id: 'po-1' }, [relations[1]])).toHaveLength(0)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import { parseRuleString, checkValue, validateValues, bagHasErrors } from '../validator'
|
|
2
|
+
import { parseRuleString, checkValue, validateValues, bagHasErrors, exemptUnchangedRuleIssues } from '../validator'
|
|
3
3
|
import type { ActionFieldDef } from '../types'
|
|
4
4
|
|
|
5
5
|
describe('parseRuleString', () => {
|
|
@@ -68,3 +68,30 @@ describe('validateValues', () => {
|
|
|
68
68
|
expect(bag.email?.[0]?.code).toBe('email')
|
|
69
69
|
})
|
|
70
70
|
})
|
|
71
|
+
|
|
72
|
+
describe('exemptUnchangedRuleIssues (QA LIVE-19)', () => {
|
|
73
|
+
const fields: ActionFieldDef[] = [
|
|
74
|
+
{ key: 'name', label: 'Nombre', type: 'text', required: true } as ActionFieldDef,
|
|
75
|
+
{ key: 'tax_id', label: 'RFC', type: 'text', validation: { regex: '^[A-Z]{3,4}[0-9]{6}[A-Z0-9]{3}$' } } as ActionFieldDef,
|
|
76
|
+
{ key: 'price', label: 'Precio', type: 'number', validation: { min: 0 } } as ActionFieldDef,
|
|
77
|
+
]
|
|
78
|
+
it('keeps an untouched legacy value from blocking the edit', () => {
|
|
79
|
+
const values = { name: 'Renombrado', tax_id: 'abc-010101', price: '-5' }
|
|
80
|
+
const bag = validateValues(fields, values)
|
|
81
|
+
expect(bagHasErrors(bag)).toBe(true)
|
|
82
|
+
const out = exemptUnchangedRuleIssues(bag, values, { name: 'Viejo', tax_id: 'abc-010101', price: -5 })
|
|
83
|
+
expect(bagHasErrors(out)).toBe(false)
|
|
84
|
+
})
|
|
85
|
+
it('still reports a changed invalid value and required', () => {
|
|
86
|
+
const values = { name: '', tax_id: 'xyz', price: -6 }
|
|
87
|
+
const out = exemptUnchangedRuleIssues(validateValues(fields, values), values, { name: 'Viejo', tax_id: 'abc-010101', price: -5 })
|
|
88
|
+
expect(out.tax_id?.[0]?.code).toBe('regex')
|
|
89
|
+
expect(out.price?.[0]?.code).toBe('min')
|
|
90
|
+
expect(out.name?.[0]?.code).toBe('required')
|
|
91
|
+
})
|
|
92
|
+
it('is a no-op without a persisted record (create)', () => {
|
|
93
|
+
const values = { name: 'x', tax_id: 'abc' }
|
|
94
|
+
const bag = validateValues(fields, values)
|
|
95
|
+
expect(exemptUnchangedRuleIssues(bag, values, null)).toEqual(bag)
|
|
96
|
+
})
|
|
97
|
+
})
|
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
} from './field-validation-ui'
|
|
54
54
|
import { validationCatalog } from './validation-catalog'
|
|
55
55
|
import { useApi } from './api-context'
|
|
56
|
+
import { buildRelationFilterParams } from './dynamic-relation-helpers'
|
|
56
57
|
import { DynamicIcon } from './dynamic-icon'
|
|
57
58
|
import { DynamicLineItems } from './dynamic-line-items'
|
|
58
59
|
import { DynamicRelations } from './dynamic-relations'
|
|
@@ -167,6 +168,54 @@ export function buildPrefillRows(spec: PrefillSpec, record: any): Array<Record<s
|
|
|
167
168
|
return rows
|
|
168
169
|
}
|
|
169
170
|
|
|
171
|
+
// ---- prefill lines from the record's declared relation ----------------------
|
|
172
|
+
//
|
|
173
|
+
// A row action opened from a LIST gets the list row, which does not carry the
|
|
174
|
+
// document's lines: `record.items` is undefined and a receive modal opened
|
|
175
|
+
// with "Sin renglones" (QA 7Leguas: OC receive modal empty, the user could not
|
|
176
|
+
// see what was being received). When the prefill source key is missing from
|
|
177
|
+
// the record but the model declares a one_to_many relation with that name, the
|
|
178
|
+
// modal fetches the child rows the same way the relation panel does
|
|
179
|
+
// (`/data/<through>?f_<fk>=eq:<id>`) and builds the rows from them.
|
|
180
|
+
|
|
181
|
+
export interface PrefillRelationRequest {
|
|
182
|
+
fieldKey: string
|
|
183
|
+
spec: PrefillSpec
|
|
184
|
+
endpoint: string
|
|
185
|
+
params: Record<string, string | number>
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function prefillRelationRequests(
|
|
189
|
+
fields: ActionFieldDef[] | undefined,
|
|
190
|
+
record: any,
|
|
191
|
+
relations: Array<{ name?: string; kind?: string; through?: string; foreign_key?: string; scope?: Record<string, unknown> }>,
|
|
192
|
+
): PrefillRelationRequest[] {
|
|
193
|
+
const out: PrefillRelationRequest[] = []
|
|
194
|
+
const recordId = record?.id
|
|
195
|
+
if (!fields || recordId === undefined || recordId === null || recordId === '') return out
|
|
196
|
+
for (const field of fields) {
|
|
197
|
+
if (!isLineItemsField(field)) continue
|
|
198
|
+
const spec = lineItemsDefault(field)
|
|
199
|
+
if (!isPrefillSpec(spec)) continue
|
|
200
|
+
if (Array.isArray(record?.[spec.$prefillFromRecord])) continue // already embedded
|
|
201
|
+
const rel = (relations || []).find(
|
|
202
|
+
(r) => r?.name === spec.$prefillFromRecord && (r.kind ?? 'one_to_many') === 'one_to_many',
|
|
203
|
+
)
|
|
204
|
+
if (!rel?.through || !rel.foreign_key) continue
|
|
205
|
+
const scope: Record<string, string> = {}
|
|
206
|
+
for (const [k, v] of Object.entries(rel.scope ?? {})) {
|
|
207
|
+
if (v !== undefined && v !== null) scope[k] = String(v)
|
|
208
|
+
}
|
|
209
|
+
out.push({
|
|
210
|
+
fieldKey: field.key,
|
|
211
|
+
spec,
|
|
212
|
+
endpoint: `/data/${rel.through}`,
|
|
213
|
+
params: { ...buildRelationFilterParams(rel.foreign_key, recordId, scope), per_page: 200 },
|
|
214
|
+
})
|
|
215
|
+
}
|
|
216
|
+
return out
|
|
217
|
+
}
|
|
218
|
+
|
|
170
219
|
// ---- scalar prefill from the acted-on record --------------------------------
|
|
171
220
|
//
|
|
172
221
|
// Row actions (stamp / refactura / cancel-with-reason) should open with the
|
|
@@ -686,6 +735,29 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
686
735
|
}
|
|
687
736
|
}, [open, action.fields, record])
|
|
688
737
|
|
|
738
|
+
// Lines the list row does not carry: load them from the declared relation
|
|
739
|
+
// (see prefillRelationRequests) and seed the line-items grid.
|
|
740
|
+
useEffect(() => {
|
|
741
|
+
if (!open || relations.length === 0) return
|
|
742
|
+
const reqs = prefillRelationRequests(action.fields, record, relations)
|
|
743
|
+
if (reqs.length === 0) return
|
|
744
|
+
let cancelled = false
|
|
745
|
+
for (const req of reqs) {
|
|
746
|
+
api.get(req.endpoint, { params: req.params })
|
|
747
|
+
.then((res: any) => {
|
|
748
|
+
if (cancelled) return
|
|
749
|
+
const rows = res?.data?.data ?? res?.data ?? []
|
|
750
|
+
if (!Array.isArray(rows)) return
|
|
751
|
+
const built = buildPrefillRows(req.spec, { [req.spec.$prefillFromRecord]: rows })
|
|
752
|
+
setFormData((prev: Record<string, any>) => ({ ...prev, [req.fieldKey]: built }))
|
|
753
|
+
})
|
|
754
|
+
.catch(() => {})
|
|
755
|
+
}
|
|
756
|
+
return () => {
|
|
757
|
+
cancelled = true
|
|
758
|
+
}
|
|
759
|
+
}, [open, action.fields, record, relations, api])
|
|
760
|
+
|
|
689
761
|
const updateField = (key: string, value: any) => {
|
|
690
762
|
setFormData((prev: Record<string, any>) => ({ ...prev, [key]: value }))
|
|
691
763
|
setFieldErrors((prev) => clearFieldErrorTree(prev, key))
|
|
@@ -67,7 +67,7 @@ import { AssistInterview } from '../assist-interview'
|
|
|
67
67
|
import { FieldCell } from '../field-grid'
|
|
68
68
|
import { isNilUuid, normalizeNilUuid } from '../nil-uuid'
|
|
69
69
|
import { normalizeRefFieldsForSubmit } from './normalize-submit'
|
|
70
|
-
import { validateValues, bagHasErrors } from '../validator'
|
|
70
|
+
import { validateValues, bagHasErrors, exemptUnchangedRuleIssues } from '../validator'
|
|
71
71
|
import { DynamicIcon, isLucideIconName } from '../dynamic-icon'
|
|
72
72
|
import { IconPickerField } from '../icon-picker-field'
|
|
73
73
|
import { humanizeToken } from '../dynamic-columns-helpers'
|
|
@@ -868,7 +868,17 @@ export function DynamicRecordDialog({
|
|
|
868
868
|
// Laravel-style: collect every issue from the shared validator
|
|
869
869
|
// (required + rule strings / min/max / email…) on visible fields only.
|
|
870
870
|
const visible = filterVisibleFields(modalMeta.fields, mode, formValues)
|
|
871
|
-
|
|
871
|
+
let bag = validateValues(visible as ActionFieldDef[], formValues)
|
|
872
|
+
// Edit: a legacy value re-sent unchanged is not re-judged by a rule
|
|
873
|
+
// added after it was written (same grandfathering as the kernel).
|
|
874
|
+
if (mode === 'edit' && record) {
|
|
875
|
+
const persisted: Record<string, unknown> = {}
|
|
876
|
+
for (const f of visible) {
|
|
877
|
+
const v = resolvePath(record, f.key)
|
|
878
|
+
if (v !== undefined) persisted[f.key] = v
|
|
879
|
+
}
|
|
880
|
+
bag = exemptUnchangedRuleIssues(bag, formValues, persisted)
|
|
881
|
+
}
|
|
872
882
|
if (bagHasErrors(bag)) {
|
|
873
883
|
const labels: Record<string, string> = {}
|
|
874
884
|
for (const f of visible) labels[f.key] = f.label
|
|
@@ -1077,6 +1087,13 @@ export function DynamicRecordDialog({
|
|
|
1077
1087
|
blow the two columns past the dialog width. */}
|
|
1078
1088
|
<form
|
|
1079
1089
|
id={formId}
|
|
1090
|
+
// Stable Aby / guidance contract: unique id={formId}
|
|
1091
|
+
// keeps nested create footers from submitting the
|
|
1092
|
+
// parent, while data-aby-* lets tours find the
|
|
1093
|
+
// open form without a hardcoded id.
|
|
1094
|
+
data-aby-record-form=""
|
|
1095
|
+
data-aby-model={model}
|
|
1096
|
+
data-aby-mode={mode}
|
|
1080
1097
|
onSubmit={handleSubmit}
|
|
1081
1098
|
className="grid gap-y-4"
|
|
1082
1099
|
>
|
|
@@ -1264,7 +1281,7 @@ function FieldRow({ field, record, value, mode, onChange, error, locked }: Field
|
|
|
1264
1281
|
const isEditReadonly = (mode === 'edit' && !!field.readonly) || !!locked
|
|
1265
1282
|
|
|
1266
1283
|
return (
|
|
1267
|
-
<div className="flex flex-col gap-1.5">
|
|
1284
|
+
<div className="flex flex-col gap-1.5" data-aby-field={field.key}>
|
|
1268
1285
|
<Label className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
|
1269
1286
|
{field.label}
|
|
1270
1287
|
{field.required && mode !== 'view' && !isEditReadonly && (
|
package/src/index.ts
CHANGED
package/src/validator.ts
CHANGED
|
@@ -273,3 +273,39 @@ function walk(
|
|
|
273
273
|
export function bagHasErrors(bag: Record<string, FieldIssue[]>): boolean {
|
|
274
274
|
return Object.keys(bag).length > 0
|
|
275
275
|
}
|
|
276
|
+
|
|
277
|
+
/** Issue codes produced by a field's declarative rule (regex / min / max /
|
|
278
|
+
* custom builtins) — the ones the kernel grandfathers on update. */
|
|
279
|
+
const RULE_CODES = new Set(['regex', 'min', 'max', 'email', 'uuid', 'url', 'numeric', 'integer', 'custom'])
|
|
280
|
+
|
|
281
|
+
function sameValue(a: unknown, b: unknown): boolean {
|
|
282
|
+
if (isEmpty(a) && isEmpty(b)) return true
|
|
283
|
+
if (isNumeric(a) && isNumeric(b)) return numericValue(a) === numericValue(b)
|
|
284
|
+
return asString(a) === asString(b)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Edit mode: drop the rule issues (regex/min/max/custom) of a top-level field
|
|
289
|
+
* whose value is the one already persisted. The edit form posts every field
|
|
290
|
+
* back, so a rule added after the row was written (an RFC pattern over legacy
|
|
291
|
+
* data) would otherwise block saving a record over a field nobody touched.
|
|
292
|
+
* Mirrors the kernel (dynamic.validateWrite grandfathers unchanged values on
|
|
293
|
+
* update). required / invalid_option / invalid_type are kept.
|
|
294
|
+
*/
|
|
295
|
+
export function exemptUnchangedRuleIssues(
|
|
296
|
+
bag: Record<string, FieldIssue[]>,
|
|
297
|
+
values: Record<string, unknown>,
|
|
298
|
+
persisted: Record<string, unknown> | null | undefined,
|
|
299
|
+
): Record<string, FieldIssue[]> {
|
|
300
|
+
if (!persisted) return bag
|
|
301
|
+
const out: Record<string, FieldIssue[]> = {}
|
|
302
|
+
for (const [path, issues] of Object.entries(bag)) {
|
|
303
|
+
const unchanged =
|
|
304
|
+
!path.includes('.') &&
|
|
305
|
+
Object.prototype.hasOwnProperty.call(persisted, path) &&
|
|
306
|
+
sameValue(values?.[path], persisted[path])
|
|
307
|
+
const kept = unchanged ? issues.filter(i => !RULE_CODES.has(String(i.code))) : issues
|
|
308
|
+
if (kept.length) out[path] = kept
|
|
309
|
+
}
|
|
310
|
+
return out
|
|
311
|
+
}
|