@asteby/metacore-runtime-react 24.0.2 → 25.1.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 +19 -0
- package/dist/action-modal-dispatcher.d.ts.map +1 -1
- package/dist/action-modal-dispatcher.js +10 -9
- package/dist/dynamic-line-items.d.ts.map +1 -1
- package/dist/dynamic-line-items.js +6 -2
- 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 +47 -0
- package/dist/server-error.d.ts.map +1 -0
- package/dist/server-error.js +100 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/line-items-lock-rows.test.tsx +70 -0
- package/src/__tests__/server-error.test.ts +43 -0
- package/src/action-modal-dispatcher.tsx +10 -9
- package/src/dynamic-line-items.tsx +30 -19
- package/src/index.ts +7 -0
- package/src/server-error.ts +121 -0
- package/src/types.ts +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @asteby/metacore-runtime-react
|
|
2
2
|
|
|
3
|
+
## 25.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a7da67d: feat(errors): los toasts de mutación/acción muestran la causa real del servidor
|
|
8
|
+
|
|
9
|
+
Nuevo helper compartido `toastServerError` / `extractServerError` (`server-error.ts`): en vez de tragarse el `details` y mostrar solo el `message` genérico ("Error creating record"), el toast muestra el `message` como título y el `details`/`errors` de validación como descripción. Cableado en `action-modal-dispatcher` (create/edit/acciones declarativas). Cualquier consumidor puede reusarlo. Así un 500 del kernel (p. ej. un error de Postgres o un guard declarativo) llega legible al usuario/operador.
|
|
10
|
+
|
|
11
|
+
## 25.0.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 711bdfc: Nuevo flag declarativo `lock_rows` en campos de line-items (`type: "array"`): cuando está activo, el renderer fija las filas — oculta el botón "Agregar renglón" y los botones de borrar por fila, dejando solo editables las celdas de las filas ya presentes. Primitivo genérico del framework (se lee snake_case `lock_rows` con alias camelCase `lockRows`).
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [711bdfc]
|
|
20
|
+
- @asteby/metacore-sdk@3.3.0
|
|
21
|
+
|
|
3
22
|
## 24.0.2
|
|
4
23
|
|
|
5
24
|
### 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":"AAyDA,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,6 +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
16
|
import { useApi } from './api-context';
|
|
16
17
|
import { DynamicIcon } from './dynamic-icon';
|
|
17
18
|
import { DynamicLineItems } from './dynamic-line-items';
|
|
@@ -263,16 +264,16 @@ function ConfirmActionDialog({ open, onOpenChange, action, model, record, endpoi
|
|
|
263
264
|
const url = buildActionUrl(endpoint, model, record.id, action.key);
|
|
264
265
|
const res = await api.post(url, {});
|
|
265
266
|
if (res.data.success) {
|
|
266
|
-
|
|
267
|
+
toastServerSuccess(res.data, { t });
|
|
267
268
|
onOpenChange(false);
|
|
268
269
|
onSuccess();
|
|
269
270
|
}
|
|
270
271
|
else {
|
|
271
|
-
|
|
272
|
+
toastServerError({ response: { data: res.data } }, { t });
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
275
|
catch (err) {
|
|
275
|
-
|
|
276
|
+
toastServerError(err, { t });
|
|
276
277
|
}
|
|
277
278
|
finally {
|
|
278
279
|
setExecuting(false);
|
|
@@ -360,16 +361,16 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
360
361
|
const url = buildActionUrl(endpoint, model, record.id, action.key);
|
|
361
362
|
const res = await api.post(url, formData);
|
|
362
363
|
if (res.data.success) {
|
|
363
|
-
|
|
364
|
+
toastServerSuccess(res.data, { t });
|
|
364
365
|
onOpenChange(false);
|
|
365
366
|
onSuccess();
|
|
366
367
|
}
|
|
367
368
|
else {
|
|
368
|
-
|
|
369
|
+
toastServerError({ response: { data: res.data } }, { t });
|
|
369
370
|
}
|
|
370
371
|
}
|
|
371
372
|
catch (err) {
|
|
372
|
-
|
|
373
|
+
toastServerError(err, { t });
|
|
373
374
|
}
|
|
374
375
|
finally {
|
|
375
376
|
setExecuting(false);
|
|
@@ -489,16 +490,16 @@ function WizardActionModal({ open, onOpenChange, action, model, record, endpoint
|
|
|
489
490
|
const url = buildActionUrl(endpoint, model, record?.id, action.key);
|
|
490
491
|
const res = await api.post(url, formData);
|
|
491
492
|
if (res.data.success) {
|
|
492
|
-
|
|
493
|
+
toastServerSuccess(res.data, { t });
|
|
493
494
|
onOpenChange(false);
|
|
494
495
|
onSuccess();
|
|
495
496
|
}
|
|
496
497
|
else {
|
|
497
|
-
|
|
498
|
+
toastServerError({ response: { data: res.data } }, { t });
|
|
498
499
|
}
|
|
499
500
|
}
|
|
500
501
|
catch (err) {
|
|
501
|
-
|
|
502
|
+
toastServerError(err, { t });
|
|
502
503
|
}
|
|
503
504
|
finally {
|
|
504
505
|
setExecuting(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-line-items.d.ts","sourceRoot":"","sources":["../src/dynamic-line-items.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAgB7C,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,cAAc,CAAA;IACrB,KAAK,EAAE,GAAG,EAAE,GAAG,SAAS,CAAA;IACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CACnC;AAkBD,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAgB,EAAE,UAAU,EAAE,EAAE,qBAAqB,+
|
|
1
|
+
{"version":3,"file":"dynamic-line-items.d.ts","sourceRoot":"","sources":["../src/dynamic-line-items.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAgB7C,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,cAAc,CAAA;IACrB,KAAK,EAAE,GAAG,EAAE,GAAG,SAAS,CAAA;IACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CACnC;AAkBD,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAgB,EAAE,UAAU,EAAE,EAAE,qBAAqB,+BA8J/G"}
|
|
@@ -29,6 +29,10 @@ function emptyRow(itemFields) {
|
|
|
29
29
|
export function DynamicLineItems({ field, value, onChange, disabled = false, formValues }) {
|
|
30
30
|
const itemFields = getItemFields(field);
|
|
31
31
|
const rows = Array.isArray(value) ? value : [];
|
|
32
|
+
// `lock_rows` fixes the row set: no add-row button, no per-row delete. Rows
|
|
33
|
+
// stay editable cell-by-cell. Snake_case is what the kernel serves; tolerate
|
|
34
|
+
// the camelCase alias too. Derived once.
|
|
35
|
+
const lockRows = field.lock_rows ?? field.lockRows ?? false;
|
|
32
36
|
// Columns flagged `total` get a per-column sum in the footer; the balance
|
|
33
37
|
// rule (if any) reconciles two of them. Both are declarative & generic.
|
|
34
38
|
const totals = computeLineItemTotals(field, rows);
|
|
@@ -60,7 +64,7 @@ export function DynamicLineItems({ field, value, onChange, disabled = false, for
|
|
|
60
64
|
updateCell(idx, key, cellValue);
|
|
61
65
|
};
|
|
62
66
|
return (_jsxs("div", { className: "grid gap-2", "data-widget": "line_items", children: [_jsx("div", { className: "overflow-x-auto rounded-md border", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-muted/50", children: _jsxs("tr", { children: [itemFields.map((col) => (_jsxs("th", { className: 'px-3 py-2 font-medium ' +
|
|
63
|
-
(isNumericCol(col) ? 'text-right' : 'text-left'), children: [col.label, col.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }, col.key))), _jsx("th", { className: "w-12 px-3 py-2", "aria-label": "acciones" })] }) }), _jsxs("tbody", { children: [rows.length === 0 && (_jsx("tr", { children: _jsx("td", { colSpan: itemFields.length + 1, className: "px-3 py-4 text-center text-muted-foreground", children: "Sin renglones" }) })), rows.map((row, idx) => (_jsxs("tr", { className: "border-t align-top", children: [itemFields.map((col) => (_jsx("td", { className: "px-2 py-1.5", children: _jsx(CellRenderer, { field: col, value: row?.[col.key], onChange: (v) => handleCell(idx, col.key, v), disabled: disabled, formValues: formValues, rowValues: row }) }, col.key))), _jsx("td", { className: "px-2 py-1.5 text-center", children: _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => removeRow(idx), disabled: disabled, "aria-label": "Eliminar rengl\u00F3n", children: _jsx(Trash2, { className: "h-4 w-4 text-red-500" }) }) })] }, idx)))] }), hasTotals && rows.length > 0 && (_jsx("tfoot", { className: "border-t bg-muted/30", children: _jsxs("tr", { children: [itemFields.map((col, ci) => {
|
|
67
|
+
(isNumericCol(col) ? 'text-right' : 'text-left'), children: [col.label, col.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }, col.key))), !lockRows && _jsx("th", { className: "w-12 px-3 py-2", "aria-label": "acciones" })] }) }), _jsxs("tbody", { children: [rows.length === 0 && (_jsx("tr", { children: _jsx("td", { colSpan: itemFields.length + (lockRows ? 0 : 1), className: "px-3 py-4 text-center text-muted-foreground", children: "Sin renglones" }) })), rows.map((row, idx) => (_jsxs("tr", { className: "border-t align-top", children: [itemFields.map((col) => (_jsx("td", { className: "px-2 py-1.5", children: _jsx(CellRenderer, { field: col, value: row?.[col.key], onChange: (v) => handleCell(idx, col.key, v), disabled: disabled, formValues: formValues, rowValues: row }) }, col.key))), !lockRows && (_jsx("td", { className: "px-2 py-1.5 text-center", children: _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => removeRow(idx), disabled: disabled, "aria-label": "Eliminar rengl\u00F3n", children: _jsx(Trash2, { className: "h-4 w-4 text-red-500" }) }) }))] }, idx)))] }), hasTotals && rows.length > 0 && (_jsx("tfoot", { className: "border-t bg-muted/30", children: _jsxs("tr", { children: [itemFields.map((col, ci) => {
|
|
64
68
|
if (ci === 0) {
|
|
65
69
|
return (_jsx("td", { className: "px-3 py-2 text-left font-medium text-muted-foreground", children: "Totales" }, col.key));
|
|
66
70
|
}
|
|
@@ -68,7 +72,7 @@ export function DynamicLineItems({ field, value, onChange, disabled = false, for
|
|
|
68
72
|
(col.total
|
|
69
73
|
? 'text-right font-semibold tabular-nums'
|
|
70
74
|
: ''), children: col.total ? fmtNumber(totals[col.key] ?? 0) : null }, col.key));
|
|
71
|
-
}), _jsx("td", {})] }) }))] }) }), _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: addRow, disabled: disabled, children: [_jsx(Plus, { className: "mr-1 h-4 w-4" }), "Agregar rengl\u00F3n"] }), balance && _jsx(BalanceBadge, { state: balance })] })] }));
|
|
75
|
+
}), !lockRows && _jsx("td", {})] }) }))] }) }), _jsxs("div", { className: "flex items-center justify-between gap-2", children: [lockRows ? (_jsx("span", {})) : (_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: addRow, disabled: disabled, children: [_jsx(Plus, { className: "mr-1 h-4 w-4" }), "Agregar rengl\u00F3n"] })), balance && _jsx(BalanceBadge, { state: balance })] })] }));
|
|
72
76
|
}
|
|
73
77
|
function BalanceBadge({ state, }) {
|
|
74
78
|
if (state.balanced) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './types';
|
|
2
2
|
export { LicenseGate, LicenseExpiryBanner, LicenseStatusBadge, isLicenseOperable, isLicenseBlocking, isPresetEntitled, isTrialExpired, type LicenseGateProps, type LicenseExpiryBannerProps, type LicenseStatusBadgeProps, type LicenseState, type LicenseStatus, type LicenseBranding, } from './license';
|
|
3
3
|
export * from './options-context';
|
|
4
|
+
export { extractServerError, toastServerError, toastServerSuccess, type ExtractedError, type Translate, } from './server-error';
|
|
4
5
|
export * from './dynamic-table';
|
|
5
6
|
export { DynamicKanban, type DynamicKanbanProps, deriveStages, groupByStage, isTransitionAllowed, applyOptimisticMove, selectCardColumns, UNASSIGNED_LANE, } from './dynamic-kanban';
|
|
6
7
|
export { useStageAutomations, StageAutomationsButton, isTagColumn, automationFieldOptions, groupAutomationsByStage, activeAutomationCount, type StageAutomation, type StageAutomationAction, type StageAutomationActionType, type NewStageAutomation, type UseStageAutomationsResult, type StageAutomationsButtonProps, } from './stage-automations';
|
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
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
export * from './types';
|
|
7
7
|
export { LicenseGate, LicenseExpiryBanner, LicenseStatusBadge, isLicenseOperable, isLicenseBlocking, isPresetEntitled, isTrialExpired, } from './license';
|
|
8
8
|
export * from './options-context';
|
|
9
|
+
export { extractServerError, toastServerError, toastServerSuccess, } from './server-error';
|
|
9
10
|
export * from './dynamic-table';
|
|
10
11
|
export { DynamicKanban, deriveStages, groupByStage, isTransitionAllowed, applyOptimisticMove, selectCardColumns, UNASSIGNED_LANE, } from './dynamic-kanban';
|
|
11
12
|
export { useStageAutomations, StageAutomationsButton, isTagColumn, automationFieldOptions, groupAutomationsByStage, activeAutomationCount, } from './stage-automations';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Structured, display-ready view of an error: a headline + an optional cause. */
|
|
2
|
+
export interface ExtractedError {
|
|
3
|
+
/** Primary line — the server's `message` (may be an i18n key) or a fallback. */
|
|
4
|
+
title: string;
|
|
5
|
+
/** Secondary line — the specific cause: `details`, `error`, joined validation
|
|
6
|
+
* `errors`, or a raw network/thrown message. Undefined when nothing more
|
|
7
|
+
* specific than the title is available. */
|
|
8
|
+
description?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Pull the best available headline + cause out of an axios error, a raw
|
|
12
|
+
* `{ success:false, ... }` response body, or a thrown Error/string. Pure — no
|
|
13
|
+
* i18n, no toast — so it is unit-testable and reusable (dialogs, inline errors).
|
|
14
|
+
*
|
|
15
|
+
* Resolution:
|
|
16
|
+
* title ← data.message (else the specific cause, so the toast is never
|
|
17
|
+
* empty; else `fallbackTitle`)
|
|
18
|
+
* description ← data.details → data.error → joined data.errors → raw err.message
|
|
19
|
+
*/
|
|
20
|
+
export declare function extractServerError(err: unknown, fallbackTitle: string): ExtractedError;
|
|
21
|
+
/** i18n translator, tolerant of non-keys (returns `defaultValue`/the input). */
|
|
22
|
+
export type Translate = (key: string, opts?: {
|
|
23
|
+
defaultValue?: string;
|
|
24
|
+
}) => string;
|
|
25
|
+
/**
|
|
26
|
+
* Toast a successful mutation/action response, LOCALIZED. The kernel/host often
|
|
27
|
+
* returns a hardcoded English `message` ("Record created successfully"); echoing
|
|
28
|
+
* it verbatim leaks English into a Spanish UI. So we only translate the server
|
|
29
|
+
* message when it is an i18n KEY (dotted, e.g. "pos.rate.created"); a prose
|
|
30
|
+
* message is dropped in favour of the localized `fallbackKey` (default
|
|
31
|
+
* "common.success"). Pass the app's `t`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function toastServerSuccess(data: unknown, opts?: {
|
|
34
|
+
t?: Translate;
|
|
35
|
+
fallbackKey?: string;
|
|
36
|
+
}): void;
|
|
37
|
+
/**
|
|
38
|
+
* Toast a server/network error, surfacing the REAL cause as the description
|
|
39
|
+
* instead of a bare generic line. Pass the app's `t` so an i18n-key `message`
|
|
40
|
+
* (e.g. "pos.error.no_rate") is localized; a plain-text message passes through
|
|
41
|
+
* unchanged. Use everywhere a mutation/action can fail.
|
|
42
|
+
*/
|
|
43
|
+
export declare function toastServerError(err: unknown, opts?: {
|
|
44
|
+
t?: Translate;
|
|
45
|
+
fallback?: string;
|
|
46
|
+
}): void;
|
|
47
|
+
//# sourceMappingURL=server-error.d.ts.map
|
|
@@ -0,0 +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,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,CAAA;AAUjF;;;;;;;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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Shared server/network error surfacing for declarative mutations & actions.
|
|
2
|
+
//
|
|
3
|
+
// Kernel/host handlers answer a failed write with a consistent envelope:
|
|
4
|
+
// { success: false, message: "<headline / i18n key>", details: "<real cause>" }
|
|
5
|
+
// where `details` carries what actually went wrong (a Postgres error, a
|
|
6
|
+
// declarative guard failure, a validation reason). The historical toast pattern
|
|
7
|
+
// toast.error(err?.response?.data?.message || t('common.error'))
|
|
8
|
+
// threw `details` away and showed only the generic headline ("Error creating
|
|
9
|
+
// record") — so a user/operator saw "something failed" with no way to know WHY
|
|
10
|
+
// or report it. This module keeps the headline but ALSO surfaces the cause as
|
|
11
|
+
// the toast description, in ONE place so every call site behaves identically.
|
|
12
|
+
import { toast } from 'sonner';
|
|
13
|
+
/** Flattens a validation `errors` payload (string | string[] | field→msgs map)
|
|
14
|
+
* into a single newline-joined string, or undefined when empty. */
|
|
15
|
+
function joinErrors(errors) {
|
|
16
|
+
if (!errors)
|
|
17
|
+
return undefined;
|
|
18
|
+
if (typeof errors === 'string')
|
|
19
|
+
return errors || undefined;
|
|
20
|
+
if (Array.isArray(errors))
|
|
21
|
+
return errors.filter(Boolean).map(String).join('\n') || undefined;
|
|
22
|
+
if (typeof errors === 'object') {
|
|
23
|
+
const parts = Object.entries(errors).map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : String(v)}`);
|
|
24
|
+
return parts.join('\n') || undefined;
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Pull the best available headline + cause out of an axios error, a raw
|
|
30
|
+
* `{ success:false, ... }` response body, or a thrown Error/string. Pure — no
|
|
31
|
+
* i18n, no toast — so it is unit-testable and reusable (dialogs, inline errors).
|
|
32
|
+
*
|
|
33
|
+
* Resolution:
|
|
34
|
+
* title ← data.message (else the specific cause, so the toast is never
|
|
35
|
+
* empty; else `fallbackTitle`)
|
|
36
|
+
* description ← data.details → data.error → joined data.errors → raw err.message
|
|
37
|
+
*/
|
|
38
|
+
export function extractServerError(err, fallbackTitle) {
|
|
39
|
+
// Accept either an axios error (`err.response.data`) or a bare response body
|
|
40
|
+
// (`{ success, message, details }`) passed straight in.
|
|
41
|
+
const maybeAxios = err?.response?.data;
|
|
42
|
+
const data = maybeAxios ?? err;
|
|
43
|
+
if (data && typeof data === 'object' && ('message' in data || 'details' in data || 'errors' in data || 'error' in data)) {
|
|
44
|
+
const d = data;
|
|
45
|
+
const message = typeof d.message === 'string' ? d.message.trim() : '';
|
|
46
|
+
const details = (typeof d.details === 'string' && d.details.trim()) ||
|
|
47
|
+
(typeof d.error === 'string' && d.error.trim()) ||
|
|
48
|
+
joinErrors(d.errors) ||
|
|
49
|
+
'';
|
|
50
|
+
if (message && details && message !== details)
|
|
51
|
+
return { title: message, description: details };
|
|
52
|
+
if (message || details)
|
|
53
|
+
return { title: message || details };
|
|
54
|
+
}
|
|
55
|
+
// Non-HTTP failure (network down, CORS, a thrown string/Error): show it as
|
|
56
|
+
// the cause under the generic fallback headline.
|
|
57
|
+
const raw = typeof err === 'string' ? err : err?.message;
|
|
58
|
+
if (typeof raw === 'string' && raw.trim())
|
|
59
|
+
return { title: fallbackTitle, description: raw.trim() };
|
|
60
|
+
return { title: fallbackTitle };
|
|
61
|
+
}
|
|
62
|
+
/** A dotted, space-free token (e.g. "pos.rate.created") — the shape of an i18n
|
|
63
|
+
* key, as opposed to human prose ("Record created successfully"). Used to
|
|
64
|
+
* decide whether a server-sent message is safe to translate or should be
|
|
65
|
+
* replaced by a localized fallback. */
|
|
66
|
+
function looksLikeI18nKey(s) {
|
|
67
|
+
return /^[a-z0-9_-]+(\.[a-z0-9_-]+)+$/i.test(s);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Toast a successful mutation/action response, LOCALIZED. The kernel/host often
|
|
71
|
+
* returns a hardcoded English `message` ("Record created successfully"); echoing
|
|
72
|
+
* it verbatim leaks English into a Spanish UI. So we only translate the server
|
|
73
|
+
* message when it is an i18n KEY (dotted, e.g. "pos.rate.created"); a prose
|
|
74
|
+
* message is dropped in favour of the localized `fallbackKey` (default
|
|
75
|
+
* "common.success"). Pass the app's `t`.
|
|
76
|
+
*/
|
|
77
|
+
export function toastServerSuccess(data, opts) {
|
|
78
|
+
const t = opts?.t;
|
|
79
|
+
const fallbackKey = opts?.fallbackKey ?? 'common.success';
|
|
80
|
+
const fallback = t ? t(fallbackKey, { defaultValue: 'Success' }) : 'Success';
|
|
81
|
+
const msg = data?.message;
|
|
82
|
+
if (t && typeof msg === 'string' && msg && looksLikeI18nKey(msg)) {
|
|
83
|
+
toast.success(t(msg, { defaultValue: fallback }));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
toast.success(fallback);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Toast a server/network error, surfacing the REAL cause as the description
|
|
90
|
+
* instead of a bare generic line. Pass the app's `t` so an i18n-key `message`
|
|
91
|
+
* (e.g. "pos.error.no_rate") is localized; a plain-text message passes through
|
|
92
|
+
* unchanged. Use everywhere a mutation/action can fail.
|
|
93
|
+
*/
|
|
94
|
+
export function toastServerError(err, opts) {
|
|
95
|
+
const t = opts?.t;
|
|
96
|
+
const fallback = opts?.fallback ?? (t ? t('common.error', { defaultValue: 'Something went wrong' }) : 'Something went wrong');
|
|
97
|
+
const { title, description } = extractServerError(err, fallback);
|
|
98
|
+
const shownTitle = t ? t(title, { defaultValue: title }) : title;
|
|
99
|
+
toast.error(shownTitle, description ? { description } : undefined);
|
|
100
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -393,6 +393,16 @@ export interface ActionFieldDef {
|
|
|
393
393
|
* reconcile. Mirrors kernel v3 `ActionField.balance`.
|
|
394
394
|
*/
|
|
395
395
|
balance?: FieldBalanceRule;
|
|
396
|
+
/**
|
|
397
|
+
* On a line-items (`type: "array"`) field: fixes the set of rows. When true
|
|
398
|
+
* the SDK hides the "Agregar renglón" button and the per-row delete control,
|
|
399
|
+
* so the rows served (e.g. a prefilled set of allocations) can only have
|
|
400
|
+
* their cells edited — never added to or removed. Generic & domain-agnostic.
|
|
401
|
+
* Mirrors kernel v3 `ActionField.lock_rows`. Tolerates the camelCase alias.
|
|
402
|
+
*/
|
|
403
|
+
lock_rows?: boolean;
|
|
404
|
+
/** camelCase alias for `lock_rows`. */
|
|
405
|
+
lockRows?: boolean;
|
|
396
406
|
/**
|
|
397
407
|
* `upload` widget: comma-separated accept list forwarded to the file input
|
|
398
408
|
* `accept` attribute (e.g. `"image/*,.pdf"`). Tolerates the snake_case the
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asteby/metacore-runtime-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "25.1.0",
|
|
4
4
|
"description": "React runtime for metacore hosts — renders addon contributions dynamically",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"react-i18next": ">=13",
|
|
38
38
|
"sonner": ">=1.7",
|
|
39
39
|
"zustand": ">=5",
|
|
40
|
-
"@asteby/metacore-sdk": "^3.
|
|
40
|
+
"@asteby/metacore-sdk": "^3.3.0",
|
|
41
41
|
"@asteby/metacore-ui": "^2.10.1"
|
|
42
42
|
},
|
|
43
43
|
"peerDependenciesMeta": {
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"typescript": "^6.0.0",
|
|
68
68
|
"vitest": "^4.0.0",
|
|
69
69
|
"zustand": "^5.0.0",
|
|
70
|
-
"@asteby/metacore-sdk": "3.
|
|
70
|
+
"@asteby/metacore-sdk": "3.3.0",
|
|
71
71
|
"@asteby/metacore-ui": "2.10.1"
|
|
72
72
|
},
|
|
73
73
|
"scripts": {
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
//
|
|
3
|
+
// `lock_rows` on a line-items (type "array") field fixes the row set: the SDK
|
|
4
|
+
// hides the "Agregar renglón" button and every per-row delete control, so the
|
|
5
|
+
// served rows can only have their cells edited — never added to or removed.
|
|
6
|
+
// Generic framework primitive (mirrors kernel v3 `ActionField.lock_rows`).
|
|
7
|
+
//
|
|
8
|
+
// Cells here are plain text/number inputs on purpose: no Radix Select, so the
|
|
9
|
+
// happy-dom BubbleSelect value-reset gotcha does not apply.
|
|
10
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
11
|
+
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
|
|
12
|
+
import { DynamicLineItems } from '../dynamic-line-items'
|
|
13
|
+
import type { ActionFieldDef } from '../types'
|
|
14
|
+
|
|
15
|
+
afterEach(cleanup)
|
|
16
|
+
|
|
17
|
+
const lineField = (overrides: Partial<ActionFieldDef> = {}): ActionFieldDef => ({
|
|
18
|
+
key: 'allocations',
|
|
19
|
+
label: 'Renglones',
|
|
20
|
+
type: 'array',
|
|
21
|
+
itemFields: [
|
|
22
|
+
{ key: 'sku', label: 'SKU', type: 'text' },
|
|
23
|
+
{ key: 'qty', label: 'Cantidad', type: 'number' },
|
|
24
|
+
],
|
|
25
|
+
...overrides,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const rows = [
|
|
29
|
+
{ sku: 'A-1', qty: 2 },
|
|
30
|
+
{ sku: 'B-2', qty: 5 },
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
describe('DynamicLineItems — lock_rows', () => {
|
|
34
|
+
it('con lock_rows=true oculta "Agregar renglón" y los botones de borrar, pero deja editar celdas', () => {
|
|
35
|
+
const onChange = vi.fn()
|
|
36
|
+
render(
|
|
37
|
+
<DynamicLineItems field={lineField({ lock_rows: true })} value={rows} onChange={onChange} />,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
// No add-row control, no per-row delete controls.
|
|
41
|
+
expect(screen.queryByText('Agregar renglón')).toBeNull()
|
|
42
|
+
expect(screen.queryByLabelText('Eliminar renglón')).toBeNull()
|
|
43
|
+
|
|
44
|
+
// Cells stay editable: typing into a cell fires onChange with the row updated.
|
|
45
|
+
const skuInputs = screen.getAllByDisplayValue('A-1')
|
|
46
|
+
fireEvent.change(skuInputs[0], { target: { value: 'A-9' } })
|
|
47
|
+
expect(onChange).toHaveBeenCalledWith([
|
|
48
|
+
{ sku: 'A-9', qty: 2 },
|
|
49
|
+
{ sku: 'B-2', qty: 5 },
|
|
50
|
+
])
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('acepta el alias camelCase lockRows', () => {
|
|
54
|
+
render(
|
|
55
|
+
<DynamicLineItems
|
|
56
|
+
field={lineField({ lockRows: true })}
|
|
57
|
+
value={rows}
|
|
58
|
+
onChange={vi.fn()}
|
|
59
|
+
/>,
|
|
60
|
+
)
|
|
61
|
+
expect(screen.queryByText('Agregar renglón')).toBeNull()
|
|
62
|
+
expect(screen.queryByLabelText('Eliminar renglón')).toBeNull()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('control: sin lock_rows muestra "Agregar renglón" y un botón de borrar por fila', () => {
|
|
66
|
+
render(<DynamicLineItems field={lineField()} value={rows} onChange={vi.fn()} />)
|
|
67
|
+
expect(screen.getByText('Agregar renglón')).toBeTruthy()
|
|
68
|
+
expect(screen.getAllByLabelText('Eliminar renglón')).toHaveLength(2)
|
|
69
|
+
})
|
|
70
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { extractServerError } from '../server-error'
|
|
3
|
+
|
|
4
|
+
describe('extractServerError', () => {
|
|
5
|
+
it('surfaces details as description under message headline', () => {
|
|
6
|
+
const err = { response: { data: { success: false, message: 'Error creating record', details: 'ERROR: column "x" does not exist (SQLSTATE 42703)' } } }
|
|
7
|
+
expect(extractServerError(err, 'fallback')).toEqual({ title: 'Error creating record', description: 'ERROR: column "x" does not exist (SQLSTATE 42703)' })
|
|
8
|
+
})
|
|
9
|
+
it('accepts a bare response body', () => {
|
|
10
|
+
expect(extractServerError({ success: false, message: 'm', details: 'd' }, 'fb')).toEqual({ title: 'm', description: 'd' })
|
|
11
|
+
})
|
|
12
|
+
it('uses details as title when no message', () => {
|
|
13
|
+
expect(extractServerError({ response: { data: { details: 'boom' } } }, 'fb')).toEqual({ title: 'boom' })
|
|
14
|
+
})
|
|
15
|
+
it('joins validation errors object', () => {
|
|
16
|
+
const r = extractServerError({ response: { data: { message: 'Validation error', errors: { name: ['required'], sku: 'dup' } } } }, 'fb')
|
|
17
|
+
expect(r.title).toBe('Validation error'); expect(r.description).toContain('name: required'); expect(r.description).toContain('sku: dup')
|
|
18
|
+
})
|
|
19
|
+
it('falls back for a thrown string / network error', () => {
|
|
20
|
+
expect(extractServerError('Network Error', 'fb')).toEqual({ title: 'fb', description: 'Network Error' })
|
|
21
|
+
expect(extractServerError({}, 'fb')).toEqual({ title: 'fb' })
|
|
22
|
+
})
|
|
23
|
+
it('does not duplicate when message equals details', () => {
|
|
24
|
+
expect(extractServerError({ response: { data: { message: 'same', details: 'same' } } }, 'fb')).toEqual({ title: 'same' })
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
import { vi } from 'vitest'
|
|
29
|
+
import { toastServerSuccess } from '../server-error'
|
|
30
|
+
vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }))
|
|
31
|
+
import { toast } from 'sonner'
|
|
32
|
+
describe('toastServerSuccess', () => {
|
|
33
|
+
const t = (k: string, o?: { defaultValue?: string }) => (k === 'common.success' ? 'Registro creado' : (o?.defaultValue ?? k))
|
|
34
|
+
it('drops English prose in favour of localized fallback', () => {
|
|
35
|
+
toastServerSuccess({ message: 'Record created successfully' }, { t })
|
|
36
|
+
expect((toast.success as any).mock.calls.at(-1)[0]).toBe('Registro creado')
|
|
37
|
+
})
|
|
38
|
+
it('translates a dotted i18n key', () => {
|
|
39
|
+
const t2 = (k: string, o?: { defaultValue?: string }) => (k === 'pos.rate.created' ? 'Tasa creada' : (k === 'common.success' ? 'Registro creado' : (o?.defaultValue ?? k)))
|
|
40
|
+
toastServerSuccess({ message: 'pos.rate.created' }, { t: t2 })
|
|
41
|
+
expect((toast.success as any).mock.calls.at(-1)[0]).toBe('Tasa creada')
|
|
42
|
+
})
|
|
43
|
+
})
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
} from '@asteby/metacore-ui/primitives'
|
|
36
36
|
import { Loader2 } from 'lucide-react'
|
|
37
37
|
import { toast } from 'sonner'
|
|
38
|
+
import { toastServerError, toastServerSuccess } from './server-error'
|
|
38
39
|
import { useApi } from './api-context'
|
|
39
40
|
import { DynamicIcon } from './dynamic-icon'
|
|
40
41
|
import { DynamicLineItems } from './dynamic-line-items'
|
|
@@ -417,14 +418,14 @@ function ConfirmActionDialog({ open, onOpenChange, action, model, record, endpoi
|
|
|
417
418
|
const url = buildActionUrl(endpoint, model, record.id, action.key)
|
|
418
419
|
const res = await api.post(url, {})
|
|
419
420
|
if (res.data.success) {
|
|
420
|
-
|
|
421
|
+
toastServerSuccess(res.data, { t })
|
|
421
422
|
onOpenChange(false)
|
|
422
423
|
onSuccess()
|
|
423
424
|
} else {
|
|
424
|
-
|
|
425
|
+
toastServerError({ response: { data: res.data } }, { t })
|
|
425
426
|
}
|
|
426
427
|
} catch (err: any) {
|
|
427
|
-
|
|
428
|
+
toastServerError(err, { t })
|
|
428
429
|
} finally {
|
|
429
430
|
setExecuting(false)
|
|
430
431
|
}
|
|
@@ -539,14 +540,14 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
539
540
|
const url = buildActionUrl(endpoint, model, record.id, action.key)
|
|
540
541
|
const res = await api.post(url, formData)
|
|
541
542
|
if (res.data.success) {
|
|
542
|
-
|
|
543
|
+
toastServerSuccess(res.data, { t })
|
|
543
544
|
onOpenChange(false)
|
|
544
545
|
onSuccess()
|
|
545
546
|
} else {
|
|
546
|
-
|
|
547
|
+
toastServerError({ response: { data: res.data } }, { t })
|
|
547
548
|
}
|
|
548
549
|
} catch (err: any) {
|
|
549
|
-
|
|
550
|
+
toastServerError(err, { t })
|
|
550
551
|
} finally {
|
|
551
552
|
setExecuting(false)
|
|
552
553
|
}
|
|
@@ -744,14 +745,14 @@ function WizardActionModal({ open, onOpenChange, action, model, record, endpoint
|
|
|
744
745
|
const url = buildActionUrl(endpoint, model, record?.id, action.key)
|
|
745
746
|
const res = await api.post(url, formData)
|
|
746
747
|
if (res.data.success) {
|
|
747
|
-
|
|
748
|
+
toastServerSuccess(res.data, { t })
|
|
748
749
|
onOpenChange(false)
|
|
749
750
|
onSuccess()
|
|
750
751
|
} else {
|
|
751
|
-
|
|
752
|
+
toastServerError({ response: { data: res.data } }, { t })
|
|
752
753
|
}
|
|
753
754
|
} catch (err: any) {
|
|
754
|
-
|
|
755
|
+
toastServerError(err, { t })
|
|
755
756
|
} finally {
|
|
756
757
|
setExecuting(false)
|
|
757
758
|
}
|
|
@@ -69,6 +69,11 @@ export function DynamicLineItems({ field, value, onChange, disabled = false, for
|
|
|
69
69
|
const itemFields = getItemFields(field)
|
|
70
70
|
const rows: any[] = Array.isArray(value) ? value : []
|
|
71
71
|
|
|
72
|
+
// `lock_rows` fixes the row set: no add-row button, no per-row delete. Rows
|
|
73
|
+
// stay editable cell-by-cell. Snake_case is what the kernel serves; tolerate
|
|
74
|
+
// the camelCase alias too. Derived once.
|
|
75
|
+
const lockRows = field.lock_rows ?? (field as any).lockRows ?? false
|
|
76
|
+
|
|
72
77
|
// Columns flagged `total` get a per-column sum in the footer; the balance
|
|
73
78
|
// rule (if any) reconciles two of them. Both are declarative & generic.
|
|
74
79
|
const totals = computeLineItemTotals(field, rows)
|
|
@@ -126,14 +131,14 @@ export function DynamicLineItems({ field, value, onChange, disabled = false, for
|
|
|
126
131
|
{col.required && <span className="text-red-500 ml-1">*</span>}
|
|
127
132
|
</th>
|
|
128
133
|
))}
|
|
129
|
-
<th className="w-12 px-3 py-2" aria-label="acciones" />
|
|
134
|
+
{!lockRows && <th className="w-12 px-3 py-2" aria-label="acciones" />}
|
|
130
135
|
</tr>
|
|
131
136
|
</thead>
|
|
132
137
|
<tbody>
|
|
133
138
|
{rows.length === 0 && (
|
|
134
139
|
<tr>
|
|
135
140
|
<td
|
|
136
|
-
colSpan={itemFields.length + 1}
|
|
141
|
+
colSpan={itemFields.length + (lockRows ? 0 : 1)}
|
|
137
142
|
className="px-3 py-4 text-center text-muted-foreground"
|
|
138
143
|
>
|
|
139
144
|
Sin renglones
|
|
@@ -154,18 +159,20 @@ export function DynamicLineItems({ field, value, onChange, disabled = false, for
|
|
|
154
159
|
/>
|
|
155
160
|
</td>
|
|
156
161
|
))}
|
|
157
|
-
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
162
|
+
{!lockRows && (
|
|
163
|
+
<td className="px-2 py-1.5 text-center">
|
|
164
|
+
<Button
|
|
165
|
+
type="button"
|
|
166
|
+
variant="ghost"
|
|
167
|
+
size="icon"
|
|
168
|
+
onClick={() => removeRow(idx)}
|
|
169
|
+
disabled={disabled}
|
|
170
|
+
aria-label="Eliminar renglón"
|
|
171
|
+
>
|
|
172
|
+
<Trash2 className="h-4 w-4 text-red-500" />
|
|
173
|
+
</Button>
|
|
174
|
+
</td>
|
|
175
|
+
)}
|
|
169
176
|
</tr>
|
|
170
177
|
))}
|
|
171
178
|
</tbody>
|
|
@@ -197,17 +204,21 @@ export function DynamicLineItems({ field, value, onChange, disabled = false, for
|
|
|
197
204
|
</td>
|
|
198
205
|
)
|
|
199
206
|
})}
|
|
200
|
-
<td />
|
|
207
|
+
{!lockRows && <td />}
|
|
201
208
|
</tr>
|
|
202
209
|
</tfoot>
|
|
203
210
|
)}
|
|
204
211
|
</table>
|
|
205
212
|
</div>
|
|
206
213
|
<div className="flex items-center justify-between gap-2">
|
|
207
|
-
|
|
208
|
-
<
|
|
209
|
-
|
|
210
|
-
|
|
214
|
+
{lockRows ? (
|
|
215
|
+
<span />
|
|
216
|
+
) : (
|
|
217
|
+
<Button type="button" variant="outline" size="sm" onClick={addRow} disabled={disabled}>
|
|
218
|
+
<Plus className="mr-1 h-4 w-4" />
|
|
219
|
+
Agregar renglón
|
|
220
|
+
</Button>
|
|
221
|
+
)}
|
|
211
222
|
{balance && <BalanceBadge state={balance} />}
|
|
212
223
|
</div>
|
|
213
224
|
</div>
|
package/src/index.ts
CHANGED
|
@@ -20,6 +20,13 @@ export {
|
|
|
20
20
|
type LicenseBranding,
|
|
21
21
|
} from './license'
|
|
22
22
|
export * from './options-context'
|
|
23
|
+
export {
|
|
24
|
+
extractServerError,
|
|
25
|
+
toastServerError,
|
|
26
|
+
toastServerSuccess,
|
|
27
|
+
type ExtractedError,
|
|
28
|
+
type Translate,
|
|
29
|
+
} from './server-error'
|
|
23
30
|
export * from './dynamic-table'
|
|
24
31
|
export {
|
|
25
32
|
DynamicKanban,
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Shared server/network error surfacing for declarative mutations & actions.
|
|
2
|
+
//
|
|
3
|
+
// Kernel/host handlers answer a failed write with a consistent envelope:
|
|
4
|
+
// { success: false, message: "<headline / i18n key>", details: "<real cause>" }
|
|
5
|
+
// where `details` carries what actually went wrong (a Postgres error, a
|
|
6
|
+
// declarative guard failure, a validation reason). The historical toast pattern
|
|
7
|
+
// toast.error(err?.response?.data?.message || t('common.error'))
|
|
8
|
+
// threw `details` away and showed only the generic headline ("Error creating
|
|
9
|
+
// record") — so a user/operator saw "something failed" with no way to know WHY
|
|
10
|
+
// or report it. This module keeps the headline but ALSO surfaces the cause as
|
|
11
|
+
// the toast description, in ONE place so every call site behaves identically.
|
|
12
|
+
import { toast } from 'sonner'
|
|
13
|
+
|
|
14
|
+
/** Structured, display-ready view of an error: a headline + an optional cause. */
|
|
15
|
+
export interface ExtractedError {
|
|
16
|
+
/** Primary line — the server's `message` (may be an i18n key) or a fallback. */
|
|
17
|
+
title: string
|
|
18
|
+
/** Secondary line — the specific cause: `details`, `error`, joined validation
|
|
19
|
+
* `errors`, or a raw network/thrown message. Undefined when nothing more
|
|
20
|
+
* specific than the title is available. */
|
|
21
|
+
description?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Flattens a validation `errors` payload (string | string[] | field→msgs map)
|
|
25
|
+
* into a single newline-joined string, or undefined when empty. */
|
|
26
|
+
function joinErrors(errors: unknown): string | undefined {
|
|
27
|
+
if (!errors) return undefined
|
|
28
|
+
if (typeof errors === 'string') return errors || undefined
|
|
29
|
+
if (Array.isArray(errors)) return errors.filter(Boolean).map(String).join('\n') || undefined
|
|
30
|
+
if (typeof errors === 'object') {
|
|
31
|
+
const parts = Object.entries(errors as Record<string, unknown>).map(
|
|
32
|
+
([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : String(v)}`,
|
|
33
|
+
)
|
|
34
|
+
return parts.join('\n') || undefined
|
|
35
|
+
}
|
|
36
|
+
return undefined
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Pull the best available headline + cause out of an axios error, a raw
|
|
41
|
+
* `{ success:false, ... }` response body, or a thrown Error/string. Pure — no
|
|
42
|
+
* i18n, no toast — so it is unit-testable and reusable (dialogs, inline errors).
|
|
43
|
+
*
|
|
44
|
+
* Resolution:
|
|
45
|
+
* title ← data.message (else the specific cause, so the toast is never
|
|
46
|
+
* empty; else `fallbackTitle`)
|
|
47
|
+
* description ← data.details → data.error → joined data.errors → raw err.message
|
|
48
|
+
*/
|
|
49
|
+
export function extractServerError(err: unknown, fallbackTitle: string): ExtractedError {
|
|
50
|
+
// Accept either an axios error (`err.response.data`) or a bare response body
|
|
51
|
+
// (`{ success, message, details }`) passed straight in.
|
|
52
|
+
const maybeAxios = (err as { response?: { data?: unknown } } | undefined)?.response?.data
|
|
53
|
+
const data = maybeAxios ?? err
|
|
54
|
+
|
|
55
|
+
if (data && typeof data === 'object' && ('message' in data || 'details' in data || 'errors' in data || 'error' in data)) {
|
|
56
|
+
const d = data as { message?: unknown; details?: unknown; error?: unknown; errors?: unknown }
|
|
57
|
+
const message = typeof d.message === 'string' ? d.message.trim() : ''
|
|
58
|
+
const details =
|
|
59
|
+
(typeof d.details === 'string' && d.details.trim()) ||
|
|
60
|
+
(typeof d.error === 'string' && d.error.trim()) ||
|
|
61
|
+
joinErrors(d.errors) ||
|
|
62
|
+
''
|
|
63
|
+
if (message && details && message !== details) return { title: message, description: details }
|
|
64
|
+
if (message || details) return { title: message || details }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Non-HTTP failure (network down, CORS, a thrown string/Error): show it as
|
|
68
|
+
// the cause under the generic fallback headline.
|
|
69
|
+
const raw = typeof err === 'string' ? err : (err as { message?: unknown } | undefined)?.message
|
|
70
|
+
if (typeof raw === 'string' && raw.trim()) return { title: fallbackTitle, description: raw.trim() }
|
|
71
|
+
return { title: fallbackTitle }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** i18n translator, tolerant of non-keys (returns `defaultValue`/the input). */
|
|
75
|
+
export type Translate = (key: string, opts?: { defaultValue?: string }) => string
|
|
76
|
+
|
|
77
|
+
/** A dotted, space-free token (e.g. "pos.rate.created") — the shape of an i18n
|
|
78
|
+
* key, as opposed to human prose ("Record created successfully"). Used to
|
|
79
|
+
* decide whether a server-sent message is safe to translate or should be
|
|
80
|
+
* replaced by a localized fallback. */
|
|
81
|
+
function looksLikeI18nKey(s: string): boolean {
|
|
82
|
+
return /^[a-z0-9_-]+(\.[a-z0-9_-]+)+$/i.test(s)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Toast a successful mutation/action response, LOCALIZED. The kernel/host often
|
|
87
|
+
* returns a hardcoded English `message` ("Record created successfully"); echoing
|
|
88
|
+
* it verbatim leaks English into a Spanish UI. So we only translate the server
|
|
89
|
+
* message when it is an i18n KEY (dotted, e.g. "pos.rate.created"); a prose
|
|
90
|
+
* message is dropped in favour of the localized `fallbackKey` (default
|
|
91
|
+
* "common.success"). Pass the app's `t`.
|
|
92
|
+
*/
|
|
93
|
+
export function toastServerSuccess(
|
|
94
|
+
data: unknown,
|
|
95
|
+
opts?: { t?: Translate; fallbackKey?: string },
|
|
96
|
+
): void {
|
|
97
|
+
const t = opts?.t
|
|
98
|
+
const fallbackKey = opts?.fallbackKey ?? 'common.success'
|
|
99
|
+
const fallback = t ? t(fallbackKey, { defaultValue: 'Success' }) : 'Success'
|
|
100
|
+
const msg = (data as { message?: unknown } | undefined)?.message
|
|
101
|
+
if (t && typeof msg === 'string' && msg && looksLikeI18nKey(msg)) {
|
|
102
|
+
toast.success(t(msg, { defaultValue: fallback }))
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
toast.success(fallback)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Toast a server/network error, surfacing the REAL cause as the description
|
|
110
|
+
* instead of a bare generic line. Pass the app's `t` so an i18n-key `message`
|
|
111
|
+
* (e.g. "pos.error.no_rate") is localized; a plain-text message passes through
|
|
112
|
+
* unchanged. Use everywhere a mutation/action can fail.
|
|
113
|
+
*/
|
|
114
|
+
export function toastServerError(err: unknown, opts?: { t?: Translate; fallback?: string }): void {
|
|
115
|
+
const t = opts?.t
|
|
116
|
+
const fallback =
|
|
117
|
+
opts?.fallback ?? (t ? t('common.error', { defaultValue: 'Something went wrong' }) : 'Something went wrong')
|
|
118
|
+
const { title, description } = extractServerError(err, fallback)
|
|
119
|
+
const shownTitle = t ? t(title, { defaultValue: title }) : title
|
|
120
|
+
toast.error(shownTitle, description ? { description } : undefined)
|
|
121
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -443,6 +443,16 @@ export interface ActionFieldDef {
|
|
|
443
443
|
* reconcile. Mirrors kernel v3 `ActionField.balance`.
|
|
444
444
|
*/
|
|
445
445
|
balance?: FieldBalanceRule
|
|
446
|
+
/**
|
|
447
|
+
* On a line-items (`type: "array"`) field: fixes the set of rows. When true
|
|
448
|
+
* the SDK hides the "Agregar renglón" button and the per-row delete control,
|
|
449
|
+
* so the rows served (e.g. a prefilled set of allocations) can only have
|
|
450
|
+
* their cells edited — never added to or removed. Generic & domain-agnostic.
|
|
451
|
+
* Mirrors kernel v3 `ActionField.lock_rows`. Tolerates the camelCase alias.
|
|
452
|
+
*/
|
|
453
|
+
lock_rows?: boolean
|
|
454
|
+
/** camelCase alias for `lock_rows`. */
|
|
455
|
+
lockRows?: boolean
|
|
446
456
|
/**
|
|
447
457
|
* `upload` widget: comma-separated accept list forwarded to the file input
|
|
448
458
|
* `accept` attribute (e.g. `"image/*,.pdf"`). Tolerates the snake_case the
|