@asteby/metacore-runtime-react 25.1.2 → 25.1.4
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 +23 -0
- package/dist/action-modal-dispatcher.d.ts.map +1 -1
- package/dist/action-modal-dispatcher.js +76 -13
- package/dist/dialogs/dynamic-record.d.ts.map +1 -1
- package/dist/dialogs/dynamic-record.js +70 -12
- package/dist/dialogs/normalize-submit.d.ts +17 -0
- package/dist/dialogs/normalize-submit.d.ts.map +1 -0
- package/dist/dialogs/normalize-submit.js +36 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/server-error.d.ts +26 -1
- package/dist/server-error.d.ts.map +1 -1
- package/dist/server-error.js +66 -0
- package/package.json +1 -1
- package/src/__tests__/extract-field-errors.test.ts +102 -0
- package/src/__tests__/normalize-ref-fields.test.ts +63 -0
- package/src/action-modal-dispatcher.tsx +84 -12
- package/src/dialogs/dynamic-record.tsx +78 -12
- package/src/dialogs/normalize-submit.ts +49 -0
- package/src/index.ts +1 -0
- package/src/server-error.ts +87 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @asteby/metacore-runtime-react
|
|
2
2
|
|
|
3
|
+
## 25.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- bdbc542: Per-field validation error rendering + Spanish localization. On a 422 with a
|
|
8
|
+
`{ errors: { <field>: [{ code, params }] } }` map, create/edit dialogs and action
|
|
9
|
+
modals now show each field's first error inline (in red under the input) plus a
|
|
10
|
+
summary toast, instead of one flattened toast. Errors localize to Spanish from
|
|
11
|
+
locale-agnostic codes (`required`, `invalid_option`, `not_found`, `duplicate`,
|
|
12
|
+
`invalid_type`, generic fallback) using the field label via i18next `{{label}}`
|
|
13
|
+
interpolation, so hosts can override the copy under `validation.<code>`.
|
|
14
|
+
Pre-localized string entries pass through verbatim. Adds exported helpers
|
|
15
|
+
`extractFieldErrors` and `localizeFieldIssue` (with the `FieldIssue` type) in
|
|
16
|
+
`server-error`. The client-side required check now marks all missing fields
|
|
17
|
+
inline rather than toasting only the first.
|
|
18
|
+
|
|
19
|
+
## 25.1.3
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 2f117ad: Fix FK violation (SQLSTATE 23503) when creating/updating a record with an empty optional relation. DynamicRecordDialog now normalizes the submit payload so empty reference pickers (and any nil-UUID value) are sent as `null` instead of `""`/"00000000-…", which a nullable FK column (e.g. products.category_id) would otherwise reject. Generic across all addons — keyed off field metadata (ref / dynamic_select / search). Exposed as `normalizeRefFieldsForSubmit`.
|
|
24
|
+
- 579ab21: DynamicRecordDialog now surfaces the server's real error cause (`details`) in the create/update/delete error toast via `toastServerError`, instead of showing only the generic headline ("Error creating record"). This is the modal the generic model CRUD page uses, so a failed create now shows the underlying Postgres/validation reason as the toast description.
|
|
25
|
+
|
|
3
26
|
## 25.1.2
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -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":"AA0DA,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAExB,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAA;AA0FhD,wBAAgB,qBAAqB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,GACZ,EAAE,gBAAgB,sCA+DlB"}
|
|
@@ -12,7 +12,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
12
12
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Button, Input, Textarea, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Switch, } from '@asteby/metacore-ui/primitives';
|
|
13
13
|
import { Loader2 } from 'lucide-react';
|
|
14
14
|
import { toast } from 'sonner';
|
|
15
|
-
import { toastServerError, toastServerSuccess } from './server-error';
|
|
15
|
+
import { toastServerError, toastServerSuccess, extractFieldErrors, localizeFieldIssue } from './server-error';
|
|
16
16
|
import { useApi } from './api-context';
|
|
17
17
|
import { DynamicIcon } from './dynamic-icon';
|
|
18
18
|
import { DynamicLineItems } from './dynamic-line-items';
|
|
@@ -250,6 +250,39 @@ function RecordPreview({ model, record }) {
|
|
|
250
250
|
return (_jsxs("div", { className: "flex items-baseline gap-3 border-t px-3 py-1.5 first:border-t-0", children: [_jsx("span", { className: "w-1/3 shrink-0 truncate text-muted-foreground", children: label }), _jsx("div", { className: "min-w-0 flex-1 [&_p]:py-0", children: _jsx(ViewValue, { field: col, value: value, record: record }) })] }, col.key));
|
|
251
251
|
}) }));
|
|
252
252
|
}
|
|
253
|
+
/** Humanize a field key for a label fallback ("unit_price" → "Unit Price"). */
|
|
254
|
+
function humanizeKey(k) {
|
|
255
|
+
return k.replace(/[._-]+/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
|
|
256
|
+
}
|
|
257
|
+
/** Localize a failed action submit's per-field `errors` (422 map or `{errors}`
|
|
258
|
+
* body) into `{ [fieldKey]: localizedMessage }`, using each field's label.
|
|
259
|
+
* Returns undefined when there is no usable per-field map. */
|
|
260
|
+
function localizeActionFieldErrors(err, fields, t) {
|
|
261
|
+
const map = extractFieldErrors(err);
|
|
262
|
+
if (!map)
|
|
263
|
+
return undefined;
|
|
264
|
+
const labelFor = (k) => {
|
|
265
|
+
const f = (fields ?? []).find(x => x.key === k);
|
|
266
|
+
return f?.label ? t(f.label, { defaultValue: f.label }) : humanizeKey(k);
|
|
267
|
+
};
|
|
268
|
+
const out = {};
|
|
269
|
+
for (const [k, issues] of Object.entries(map))
|
|
270
|
+
out[k] = localizeFieldIssue(issues[0], labelFor(k), t);
|
|
271
|
+
return out;
|
|
272
|
+
}
|
|
273
|
+
/** Toast a failed action: a summary + localized per-field lines when the server
|
|
274
|
+
* returned a per-field `errors` map, else the standard cause-carrying toast.
|
|
275
|
+
* Used where inline rendering isn't wired (confirm / multi-step wizard). */
|
|
276
|
+
function toastActionError(err, fields, t) {
|
|
277
|
+
const localized = localizeActionFieldErrors(err, fields, t);
|
|
278
|
+
if (localized) {
|
|
279
|
+
toast.error(t('dynamic.validation_failed', { defaultValue: 'Revisa los campos marcados' }), {
|
|
280
|
+
description: Object.values(localized).join('\n'),
|
|
281
|
+
});
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
toastServerError(err, { t });
|
|
285
|
+
}
|
|
253
286
|
function ConfirmActionDialog({ open, onOpenChange, action, model, record, endpoint, onSuccess }) {
|
|
254
287
|
const { t } = useTranslation();
|
|
255
288
|
const api = useApi();
|
|
@@ -269,11 +302,11 @@ function ConfirmActionDialog({ open, onOpenChange, action, model, record, endpoi
|
|
|
269
302
|
onSuccess();
|
|
270
303
|
}
|
|
271
304
|
else {
|
|
272
|
-
|
|
305
|
+
toastActionError({ response: { data: res.data } }, action.fields, t);
|
|
273
306
|
}
|
|
274
307
|
}
|
|
275
308
|
catch (err) {
|
|
276
|
-
|
|
309
|
+
toastActionError(err, action.fields, t);
|
|
277
310
|
}
|
|
278
311
|
finally {
|
|
279
312
|
setExecuting(false);
|
|
@@ -290,6 +323,8 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
290
323
|
const api = useApi();
|
|
291
324
|
const [formData, setFormData] = useState({});
|
|
292
325
|
const [executing, setExecuting] = useState(false);
|
|
326
|
+
// Per-field validation errors (localized), shown inline under each input.
|
|
327
|
+
const [fieldErrors, setFieldErrors] = useState({});
|
|
293
328
|
// Related records to surface BELOW the form, as read-only context for the
|
|
294
329
|
// record being acted on — e.g. the reception history of a transfer while
|
|
295
330
|
// receiving against it. Sourced from the model's metadata.relations (the
|
|
@@ -334,28 +369,56 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
334
369
|
defaults[field.key] = field.defaultValue ?? (field.type === 'boolean' ? false : '');
|
|
335
370
|
}
|
|
336
371
|
setFormData(defaults);
|
|
372
|
+
setFieldErrors({});
|
|
337
373
|
}
|
|
338
374
|
}, [open, action.fields, record]);
|
|
339
|
-
const updateField = (key, value) =>
|
|
375
|
+
const updateField = (key, value) => {
|
|
376
|
+
setFormData((prev) => ({ ...prev, [key]: value }));
|
|
377
|
+
setFieldErrors(prev => {
|
|
378
|
+
if (!prev[key])
|
|
379
|
+
return prev;
|
|
380
|
+
const next = { ...prev };
|
|
381
|
+
delete next[key];
|
|
382
|
+
return next;
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
const handleActionError = (err) => {
|
|
386
|
+
const localized = localizeActionFieldErrors(err, action.fields, t);
|
|
387
|
+
if (localized) {
|
|
388
|
+
setFieldErrors(localized);
|
|
389
|
+
toast.error(t('dynamic.validation_failed', { defaultValue: 'Revisa los campos marcados' }));
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
toastServerError(err, { t });
|
|
393
|
+
};
|
|
340
394
|
const execute = async () => {
|
|
341
395
|
if (action.fields) {
|
|
396
|
+
// Client-side required check → mark ALL missing fields inline.
|
|
397
|
+
const missing = {};
|
|
342
398
|
for (const field of action.fields) {
|
|
343
399
|
if (!field.required)
|
|
344
400
|
continue;
|
|
345
401
|
if (isLineItemsField(field)) {
|
|
346
402
|
const rows = formData[field.key];
|
|
347
403
|
if (!Array.isArray(rows) || rows.length === 0) {
|
|
348
|
-
|
|
349
|
-
|
|
404
|
+
missing[field.key] = t('validation.line_items_required', {
|
|
405
|
+
defaultValue: '{{label}} requiere al menos un renglón',
|
|
406
|
+
label: tl(field.label),
|
|
407
|
+
});
|
|
350
408
|
}
|
|
351
409
|
continue;
|
|
352
410
|
}
|
|
353
411
|
if (!formData[field.key] && formData[field.key] !== false) {
|
|
354
|
-
|
|
355
|
-
return;
|
|
412
|
+
missing[field.key] = localizeFieldIssue({ code: 'required' }, tl(field.label), t);
|
|
356
413
|
}
|
|
357
414
|
}
|
|
415
|
+
if (Object.keys(missing).length) {
|
|
416
|
+
setFieldErrors(missing);
|
|
417
|
+
toast.error(t('dynamic.validation_failed', { defaultValue: 'Revisa los campos marcados' }));
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
358
420
|
}
|
|
421
|
+
setFieldErrors({});
|
|
359
422
|
setExecuting(true);
|
|
360
423
|
try {
|
|
361
424
|
const url = buildActionUrl(endpoint, model, record.id, action.key);
|
|
@@ -366,11 +429,11 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
366
429
|
onSuccess();
|
|
367
430
|
}
|
|
368
431
|
else {
|
|
369
|
-
|
|
432
|
+
handleActionError({ response: { data: res.data } });
|
|
370
433
|
}
|
|
371
434
|
}
|
|
372
435
|
catch (err) {
|
|
373
|
-
|
|
436
|
+
handleActionError(err);
|
|
374
437
|
}
|
|
375
438
|
finally {
|
|
376
439
|
setExecuting(false);
|
|
@@ -394,7 +457,7 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
394
457
|
const fullWidth = isLineItemsField(field) ||
|
|
395
458
|
resolveWidget(field) === 'textarea' ||
|
|
396
459
|
resolveWidget(field) === 'richtext';
|
|
397
|
-
return (_jsxs(FieldCell, { fullWidth: fullWidth, children: [_jsx(FieldLabel, { htmlFor: field.key, required: field.required, children: tl(field.label) }), renderField(field, formData[field.key], (v) => updateField(field.key, v), formData)] }, field.key));
|
|
460
|
+
return (_jsxs(FieldCell, { fullWidth: fullWidth, children: [_jsx(FieldLabel, { htmlFor: field.key, required: field.required, children: tl(field.label) }), renderField(field, formData[field.key], (v) => updateField(field.key, v), formData), fieldErrors[field.key] && (_jsx("p", { className: "text-destructive text-xs mt-1", children: fieldErrors[field.key] }))] }, field.key));
|
|
398
461
|
}), relations.length > 0 && (_jsx(FieldCell, { fullWidth: true, children: _jsx(DynamicRelations, { record: record, relations: relations }) }))] }) }), _jsxs(DialogFooter, { className: "shrink-0", children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: executing, children: t('common.cancel') }), _jsxs(Button, { onClick: execute, disabled: executing, style: action.color ? { backgroundColor: action.color, color: 'white' } : undefined, children: [executing ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : _jsx(DynamicIcon, { name: action.icon, className: "mr-2 h-4 w-4" }), tl(action.label)] })] })] }) }));
|
|
399
462
|
}
|
|
400
463
|
// buildFieldDefaults seeds formData for a set of action fields, honoring the
|
|
@@ -495,11 +558,11 @@ function WizardActionModal({ open, onOpenChange, action, model, record, endpoint
|
|
|
495
558
|
onSuccess();
|
|
496
559
|
}
|
|
497
560
|
else {
|
|
498
|
-
|
|
561
|
+
toastActionError({ response: { data: res.data } }, steps.flatMap(s => s.fields ?? []), t);
|
|
499
562
|
}
|
|
500
563
|
}
|
|
501
564
|
catch (err) {
|
|
502
|
-
|
|
565
|
+
toastActionError(err, steps.flatMap(s => s.fields ?? []), t);
|
|
503
566
|
}
|
|
504
567
|
finally {
|
|
505
568
|
setExecuting(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-record.d.ts","sourceRoot":"","sources":["../../src/dialogs/dynamic-record.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"dynamic-record.d.ts","sourceRoot":"","sources":["../../src/dialogs/dynamic-record.tsx"],"names":[],"mappings":"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"}
|
|
@@ -19,12 +19,14 @@ import { format, parseISO } from 'date-fns';
|
|
|
19
19
|
import { es } from 'date-fns/locale';
|
|
20
20
|
import { ExternalLink, Loader2, CalendarIcon, ChevronDown, Check, Upload, X as XIcon } from 'lucide-react';
|
|
21
21
|
import { useApi } from '../api-context';
|
|
22
|
+
import { toastServerError, extractFieldErrors, localizeFieldIssue } from '../server-error';
|
|
22
23
|
import { DynamicSelectField, OptionLead, OptionThumb } from '../dynamic-select-field';
|
|
23
24
|
import { DynamicRelations } from '../dynamic-relations';
|
|
24
25
|
import { useOptionsResolver } from '../use-options-resolver';
|
|
25
26
|
import { getFieldRef } from '../dynamic-form-schema';
|
|
26
27
|
import { FieldCell } from '../field-grid';
|
|
27
28
|
import { isNilUuid, normalizeNilUuid } from '../nil-uuid';
|
|
29
|
+
import { normalizeRefFieldsForSubmit } from './normalize-submit';
|
|
28
30
|
import { DynamicIcon, isLucideIconName } from '../dynamic-icon';
|
|
29
31
|
import { humanizeToken } from '../dynamic-columns-helpers';
|
|
30
32
|
import { formatDateCell } from '../dynamic-columns';
|
|
@@ -252,6 +254,10 @@ export function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId,
|
|
|
252
254
|
const [relations, setRelations] = useState([]);
|
|
253
255
|
const [record, setRecord] = useState(null);
|
|
254
256
|
const [formValues, setFormValues] = useState({});
|
|
257
|
+
// Per-field validation errors (localized strings), keyed by field.key. Shown
|
|
258
|
+
// inline under each input; populated from a 422 `errors` map or the client
|
|
259
|
+
// required-field check, cleared per-field on change and wholesale on reopen.
|
|
260
|
+
const [fieldErrors, setFieldErrors] = useState({});
|
|
255
261
|
const [loading, setLoading] = useState(false);
|
|
256
262
|
const [saving, setSaving] = useState(false);
|
|
257
263
|
const [deleting, setDeleting] = useState(false);
|
|
@@ -265,6 +271,8 @@ export function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId,
|
|
|
265
271
|
return;
|
|
266
272
|
if (!isCreate && !recordId)
|
|
267
273
|
return;
|
|
274
|
+
// Fresh open → drop any validation errors from a prior submit.
|
|
275
|
+
setFieldErrors({});
|
|
268
276
|
let cancelled = false;
|
|
269
277
|
// Seed instantly from the row the table already has so view/edit render
|
|
270
278
|
// without a spinner. The list row carries the pro siblings (resolved
|
|
@@ -422,29 +430,66 @@ export function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId,
|
|
|
422
430
|
}
|
|
423
431
|
onChange?.();
|
|
424
432
|
}, [api, endpoint, model, recordId, isCreate, modalMeta, onChange]);
|
|
433
|
+
// The human label for a field key, for localizing validation errors. Falls
|
|
434
|
+
// back to a humanized key when the field is unknown (e.g. a server-side key
|
|
435
|
+
// with no matching form field).
|
|
436
|
+
const labelForKey = (key) => {
|
|
437
|
+
const f = (modalMeta?.fields ?? []).find(x => x.key === key);
|
|
438
|
+
if (f?.label)
|
|
439
|
+
return f.label;
|
|
440
|
+
return key.replace(/[._-]+/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
|
|
441
|
+
};
|
|
442
|
+
// Turn a failed submit (422 `errors` map, or a bare `{errors}` body) into
|
|
443
|
+
// inline field errors + a summary toast. When there is no field map, fall
|
|
444
|
+
// back to the existing single cause-carrying toast.
|
|
445
|
+
const handleSubmitError = (err) => {
|
|
446
|
+
const map = extractFieldErrors(err);
|
|
447
|
+
if (map) {
|
|
448
|
+
const next = {};
|
|
449
|
+
for (const [key, issues] of Object.entries(map)) {
|
|
450
|
+
next[key] = localizeFieldIssue(issues[0], labelForKey(key), t);
|
|
451
|
+
}
|
|
452
|
+
setFieldErrors(next);
|
|
453
|
+
toast.error(t('dynamic.validation_failed', { defaultValue: 'Revisa los campos marcados' }));
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
toastServerError(err, { t, fallback: t('dynamic.save_error', { defaultValue: 'No se pudo guardar' }) });
|
|
457
|
+
};
|
|
425
458
|
const handleSubmit = async (e) => {
|
|
426
459
|
e?.preventDefault();
|
|
427
460
|
if (!modalMeta)
|
|
428
461
|
return;
|
|
429
462
|
if (isEditable) {
|
|
463
|
+
// Collect ALL missing required fields (not just the first) and mark
|
|
464
|
+
// each inline instead of a single toast.
|
|
465
|
+
const missing = {};
|
|
430
466
|
for (const field of modalMeta.fields ?? []) {
|
|
431
467
|
if (field.required && !formValues[field.key] && formValues[field.key] !== 0 && formValues[field.key] !== false) {
|
|
432
|
-
|
|
433
|
-
return;
|
|
468
|
+
missing[field.key] = localizeFieldIssue({ code: 'required' }, field.label, t);
|
|
434
469
|
}
|
|
435
470
|
}
|
|
471
|
+
if (Object.keys(missing).length) {
|
|
472
|
+
setFieldErrors(missing);
|
|
473
|
+
toast.error(t('dynamic.validation_failed', { defaultValue: 'Revisa los campos marcados' }));
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
436
476
|
}
|
|
477
|
+
// Required check passed → clear any prior validation errors.
|
|
478
|
+
setFieldErrors({});
|
|
479
|
+
// Empty reference pickers → null (not "" / nil-UUID) so nullable FK
|
|
480
|
+
// columns accept them instead of raising a 23503 FK violation.
|
|
481
|
+
const payload = normalizeRefFieldsForSubmit(formValues, modalMeta.fields);
|
|
437
482
|
setSaving(true);
|
|
438
483
|
try {
|
|
439
484
|
if (isCreate && onCreate) {
|
|
440
|
-
const created = await onCreate(
|
|
485
|
+
const created = await onCreate(payload);
|
|
441
486
|
toast.success(modalMeta?.messages?.created || t('dynamic.create_success', { defaultValue: 'Registro creado correctamente' }));
|
|
442
487
|
onSaved?.(created ?? undefined);
|
|
443
488
|
onOpenChange(false);
|
|
444
489
|
return;
|
|
445
490
|
}
|
|
446
491
|
if (!isCreate && recordId && onUpdate) {
|
|
447
|
-
const updated = await onUpdate(String(recordId),
|
|
492
|
+
const updated = await onUpdate(String(recordId), payload);
|
|
448
493
|
toast.success(modalMeta?.messages?.updated || t('dynamic.update_success', { defaultValue: 'Guardado correctamente' }));
|
|
449
494
|
onSaved?.(updated ?? undefined);
|
|
450
495
|
onOpenChange(false);
|
|
@@ -453,13 +498,13 @@ export function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId,
|
|
|
453
498
|
let res;
|
|
454
499
|
if (isCreate) {
|
|
455
500
|
const createEndpoint = endpoint || `/dynamic/${model}`;
|
|
456
|
-
res = await api.post(createEndpoint,
|
|
501
|
+
res = await api.post(createEndpoint, payload);
|
|
457
502
|
}
|
|
458
503
|
else {
|
|
459
504
|
const updateEndpoint = endpoint
|
|
460
505
|
? `${endpoint}/${recordId}`
|
|
461
506
|
: `/dynamic/${model}/${recordId}`;
|
|
462
|
-
res = await api.put(updateEndpoint,
|
|
507
|
+
res = await api.put(updateEndpoint, payload);
|
|
463
508
|
}
|
|
464
509
|
if (res.data?.success !== false) {
|
|
465
510
|
// Prefer the addon's localized message (modal metadata), then a
|
|
@@ -474,11 +519,14 @@ export function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId,
|
|
|
474
519
|
onOpenChange(false);
|
|
475
520
|
}
|
|
476
521
|
else {
|
|
477
|
-
|
|
522
|
+
// Surface the server's real cause (`details`) as the toast
|
|
523
|
+
// description, not just the generic headline. `res.data` is the
|
|
524
|
+
// `{ success:false, message, details }` envelope.
|
|
525
|
+
handleSubmitError(res.data);
|
|
478
526
|
}
|
|
479
527
|
}
|
|
480
528
|
catch (err) {
|
|
481
|
-
|
|
529
|
+
handleSubmitError(err);
|
|
482
530
|
}
|
|
483
531
|
finally {
|
|
484
532
|
setSaving(false);
|
|
@@ -494,7 +542,7 @@ export function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId,
|
|
|
494
542
|
}
|
|
495
543
|
catch (err) {
|
|
496
544
|
console.error('[DynamicRecordDialog] delete error:', err);
|
|
497
|
-
|
|
545
|
+
toastServerError(err, { t, fallback: t('dynamic.delete_error', { defaultValue: 'No se pudo eliminar el registro' }) });
|
|
498
546
|
}
|
|
499
547
|
finally {
|
|
500
548
|
setDeleting(false);
|
|
@@ -506,13 +554,23 @@ export function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId,
|
|
|
506
554
|
const isFullWidth = field.type === 'textarea' ||
|
|
507
555
|
field.widget === 'textarea' ||
|
|
508
556
|
field.widget === 'richtext';
|
|
509
|
-
return (_jsx(FieldCell, { fullWidth: isFullWidth, children: _jsx(FieldRow, { field: field, record: record, value: formValues[field.key] ?? '', mode: mode,
|
|
557
|
+
return (_jsx(FieldCell, { fullWidth: isFullWidth, children: _jsx(FieldRow, { field: field, record: record, value: formValues[field.key] ?? '', mode: mode, error: fieldErrors[field.key], onChange: val => {
|
|
558
|
+
setFormValues((prev) => ({ ...prev, [field.key]: val }));
|
|
559
|
+
// Clear this field's error as soon as the user edits it.
|
|
560
|
+
setFieldErrors(prev => {
|
|
561
|
+
if (!prev[field.key])
|
|
562
|
+
return prev;
|
|
563
|
+
const next = { ...prev };
|
|
564
|
+
delete next[field.key];
|
|
565
|
+
return next;
|
|
566
|
+
});
|
|
567
|
+
} }) }, field.key));
|
|
510
568
|
}), record?.external_url && (_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, 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: [_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 && (_jsxs(Button, { type: "submit", form: "dynamic-record-form", disabled: saving || loading, children: [saving && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), saving ? config.submittingLabel : config.submitLabel] }))] })] })] }) }));
|
|
511
569
|
}
|
|
512
570
|
function LoadingSkeleton() {
|
|
513
571
|
return (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-4", children: Array.from({ length: 6 }).map((_, i) => (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Skeleton, { className: "h-3.5 w-24" }), _jsx(Skeleton, { className: "h-9 w-full" })] }, i))) }));
|
|
514
572
|
}
|
|
515
|
-
function FieldRow({ field, record, value, mode, onChange }) {
|
|
573
|
+
function FieldRow({ field, record, value, mode, onChange, error }) {
|
|
516
574
|
// A `readonly` field is server/system-generated (e.g. the GitHub addon's
|
|
517
575
|
// `number`/`github_url`, filled by the API after the outbound create). On
|
|
518
576
|
// CREATE it is excluded from the form entirely (see `visibleFields`); on EDIT
|
|
@@ -520,7 +578,7 @@ function FieldRow({ field, record, value, mode, onChange }) {
|
|
|
520
578
|
// so the user sees its value without being able to change it. View mode keeps
|
|
521
579
|
// the rich read-only renderer.
|
|
522
580
|
const isEditReadonly = mode === 'edit' && !!field.readonly;
|
|
523
|
-
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 }))] }));
|
|
581
|
+
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 })), error && mode !== 'view' && (_jsx("p", { className: "text-destructive text-xs mt-1", children: error }))] }));
|
|
524
582
|
}
|
|
525
583
|
// ReadonlyEditField — the edit-mode rendering of a `readonly` (system-generated)
|
|
526
584
|
// field: a disabled, muted input that shows the current value without allowing
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Minimal field-metadata shape the normalizer reads. Kept permissive so any
|
|
2
|
+
* caller's field type (e.g. the dialog's `FieldDef[]`) is accepted. */
|
|
3
|
+
type RefFieldMeta = Record<string, any>;
|
|
4
|
+
/**
|
|
5
|
+
* Normalize a submit payload so that EMPTY reference fields go to the server as
|
|
6
|
+
* `null` rather than as `""` or the nil UUID ("00000000-…"). A dynamic FK column
|
|
7
|
+
* (e.g. products.category_id, a nullable `ref`) rejects a non-null value that
|
|
8
|
+
* points at no row: sending `""`/nil-UUID triggers
|
|
9
|
+
* insert ... violates foreign key constraint "fk_products_category" (23503)
|
|
10
|
+
* even though the user left the picker empty. This is generic — it keys off the
|
|
11
|
+
* field metadata (`getFieldRef` / dynamic_select / search), so every addon's
|
|
12
|
+
* optional relations benefit, not just products. Non-reference fields are left
|
|
13
|
+
* untouched (an empty text field is a legitimate `""`). Does not mutate `values`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function normalizeRefFieldsForSubmit(values: Record<string, any>, fields: RefFieldMeta[] | undefined): Record<string, any>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=normalize-submit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-submit.d.ts","sourceRoot":"","sources":["../../src/dialogs/normalize-submit.ts"],"names":[],"mappings":"AAOA;wEACwE;AACxE,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAEvC;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,MAAM,EAAE,YAAY,EAAE,GAAG,SAAS,GACnC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAuBrB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Pure submit-payload normalization for dynamic record forms. Kept in its own
|
|
2
|
+
// module (no React / UI imports) so it is unit-testable in isolation and
|
|
3
|
+
// reusable by any caller that builds a create/update payload.
|
|
4
|
+
import { isNilUuid } from '../nil-uuid';
|
|
5
|
+
import { getFieldRef } from '../dynamic-form-schema';
|
|
6
|
+
/**
|
|
7
|
+
* Normalize a submit payload so that EMPTY reference fields go to the server as
|
|
8
|
+
* `null` rather than as `""` or the nil UUID ("00000000-…"). A dynamic FK column
|
|
9
|
+
* (e.g. products.category_id, a nullable `ref`) rejects a non-null value that
|
|
10
|
+
* points at no row: sending `""`/nil-UUID triggers
|
|
11
|
+
* insert ... violates foreign key constraint "fk_products_category" (23503)
|
|
12
|
+
* even though the user left the picker empty. This is generic — it keys off the
|
|
13
|
+
* field metadata (`getFieldRef` / dynamic_select / search), so every addon's
|
|
14
|
+
* optional relations benefit, not just products. Non-reference fields are left
|
|
15
|
+
* untouched (an empty text field is a legitimate `""`). Does not mutate `values`.
|
|
16
|
+
*/
|
|
17
|
+
export function normalizeRefFieldsForSubmit(values, fields) {
|
|
18
|
+
const refKeys = new Set((fields ?? [])
|
|
19
|
+
.filter((f) => !!getFieldRef(f) ||
|
|
20
|
+
f.type === 'dynamic_select' ||
|
|
21
|
+
f.widget === 'dynamic_select' ||
|
|
22
|
+
f.type === 'search')
|
|
23
|
+
.map((f) => f.key));
|
|
24
|
+
const out = { ...values };
|
|
25
|
+
for (const [k, v] of Object.entries(out)) {
|
|
26
|
+
// A nil UUID is never a real target row — null it out on any field.
|
|
27
|
+
if (isNilUuid(v)) {
|
|
28
|
+
out[k] = null;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
// An empty reference picker means "no relation" → null (not "").
|
|
32
|
+
if (refKeys.has(k) && (v === '' || v == null))
|
|
33
|
+
out[k] = null;
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export { UrlChip, FileChip, ImageThumbnail, MediaValue, RichText, linkifyText, c
|
|
|
38
38
|
export { CollectionCell, formatScalar, prettifyKey, countLabel, type CollectionCellProps, type Translate as CollectionCellTranslate, } from './collection-cell';
|
|
39
39
|
export { NIL_UUID, isNilUuid, normalizeNilUuid } from './nil-uuid';
|
|
40
40
|
export { DynamicRecordDialog, ViewValue } from './dialogs/dynamic-record';
|
|
41
|
+
export { normalizeRefFieldsForSubmit } from './dialogs/normalize-submit';
|
|
41
42
|
export type { DynamicRecordDialogProps, FieldDef, FieldOption, GetImageUrl } from './dialogs/dynamic-record';
|
|
42
43
|
export { CreateRecordDialog } from './dialogs/create-record-dialog';
|
|
43
44
|
export { ViewRecordDialog } from './dialogs/view-record-dialog';
|
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
|
@@ -42,6 +42,7 @@ export { UrlChip, FileChip, ImageThumbnail, MediaValue, RichText, linkifyText, c
|
|
|
42
42
|
export { CollectionCell, formatScalar, prettifyKey, countLabel, } from './collection-cell';
|
|
43
43
|
export { NIL_UUID, isNilUuid, normalizeNilUuid } from './nil-uuid';
|
|
44
44
|
export { DynamicRecordDialog, ViewValue } from './dialogs/dynamic-record';
|
|
45
|
+
export { normalizeRefFieldsForSubmit } from './dialogs/normalize-submit';
|
|
45
46
|
export { CreateRecordDialog } from './dialogs/create-record-dialog';
|
|
46
47
|
export { ViewRecordDialog } from './dialogs/view-record-dialog';
|
|
47
48
|
export { ExportDialog } from './dialogs/export';
|
package/dist/server-error.d.ts
CHANGED
|
@@ -18,10 +18,35 @@ export interface ExtractedError {
|
|
|
18
18
|
* description ← data.details → data.error → joined data.errors → raw err.message
|
|
19
19
|
*/
|
|
20
20
|
export declare function extractServerError(err: unknown, fallbackTitle: string): ExtractedError;
|
|
21
|
-
/** i18n translator, tolerant of non-keys (returns `defaultValue`/the input).
|
|
21
|
+
/** i18n translator, tolerant of non-keys (returns `defaultValue`/the input).
|
|
22
|
+
* Accepts arbitrary interpolation values (e.g. `label`, plus a code's `params`)
|
|
23
|
+
* so `localizeFieldIssue` can pass `{{label}}` and friends through i18next. */
|
|
22
24
|
export type Translate = (key: string, opts?: {
|
|
23
25
|
defaultValue?: string;
|
|
26
|
+
[k: string]: unknown;
|
|
24
27
|
}) => string;
|
|
28
|
+
/** A single normalized validation issue for one field: either a machine `code`
|
|
29
|
+
* (+ optional `params`) to localize, or a ready-to-show `message` string. */
|
|
30
|
+
export interface FieldIssue {
|
|
31
|
+
code?: string;
|
|
32
|
+
params?: Record<string, any>;
|
|
33
|
+
message?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Pull the per-field `errors` map out of an axios error (`err.response.data.errors`)
|
|
37
|
+
* or a bare response body (`{ errors }`), normalizing each field's value to a
|
|
38
|
+
* `FieldIssue[]`. A value may be a single entry or an array; string entries become
|
|
39
|
+
* `{message}`, object entries `{code,params}`. Returns `undefined` when there is no
|
|
40
|
+
* usable map (no `errors`, or nothing normalized). Pure — no i18n, no toast.
|
|
41
|
+
*/
|
|
42
|
+
export declare function extractFieldErrors(err: unknown): Record<string, FieldIssue[]> | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Localize a single `FieldIssue` to a human, Spanish-by-default string using the
|
|
45
|
+
* field `label`. A pre-localized `message` passes through verbatim. Otherwise the
|
|
46
|
+
* `code` is translated via `t('validation.'+code, { defaultValue, label, ...params })`
|
|
47
|
+
* so hosts can override the copy and `{{label}}`/param interpolation still works.
|
|
48
|
+
*/
|
|
49
|
+
export declare function localizeFieldIssue(issue: FieldIssue, label: string, t: Translate): string;
|
|
25
50
|
/**
|
|
26
51
|
* Toast a successful mutation/action response, LOCALIZED. The kernel/host often
|
|
27
52
|
* returns a hardcoded English `message` ("Record created successfully"); echoing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-error.d.ts","sourceRoot":"","sources":["../src/server-error.ts"],"names":[],"mappings":"AAaA,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC3B,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;IACb;;gDAE4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,cAAc,CAuBtF;AAED
|
|
1
|
+
{"version":3,"file":"server-error.d.ts","sourceRoot":"","sources":["../src/server-error.ts"],"names":[],"mappings":"AAaA,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC3B,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;IACb;;gDAE4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,cAAc,CAuBtF;AAED;;gFAEgF;AAChF,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,KAAK,MAAM,CAAA;AAUvG;8EAC8E;AAC9E,MAAM,WAAW,UAAU;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAkCD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,GAAG,SAAS,CAazF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAKzF;AAUD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAC9B,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;IAAE,CAAC,CAAC,EAAE,SAAS,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,IAAI,CAUN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;IAAE,CAAC,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAOhG"}
|