@asteby/metacore-runtime-react 48.0.0 → 49.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/action-modal-dispatcher.d.ts +17 -3
  3. package/dist/action-modal-dispatcher.d.ts.map +1 -1
  4. package/dist/action-modal-dispatcher.js +57 -10
  5. package/dist/action-priority.d.ts +34 -0
  6. package/dist/action-priority.d.ts.map +1 -0
  7. package/dist/action-priority.js +60 -0
  8. package/dist/business/catalog-product-search.d.ts +7 -0
  9. package/dist/business/catalog-product-search.d.ts.map +1 -1
  10. package/dist/business/catalog-product-search.js +14 -0
  11. package/dist/business/document-editor-model.d.ts +14 -2
  12. package/dist/business/document-editor-model.d.ts.map +1 -1
  13. package/dist/business/document-editor-model.js +42 -4
  14. package/dist/business/document-editor.d.ts.map +1 -1
  15. package/dist/business/document-editor.js +65 -17
  16. package/dist/business/line-items.d.ts +9 -1
  17. package/dist/business/line-items.d.ts.map +1 -1
  18. package/dist/business/line-items.js +8 -1
  19. package/dist/document/document-page.d.ts.map +1 -1
  20. package/dist/document/document-page.js +8 -1
  21. package/dist/document/evaluate.d.ts.map +1 -1
  22. package/dist/document/evaluate.js +17 -1
  23. package/dist/document/index.d.ts +1 -0
  24. package/dist/document/index.d.ts.map +1 -1
  25. package/dist/document/index.js +1 -0
  26. package/dist/document/secondary-bar.d.ts +20 -0
  27. package/dist/document/secondary-bar.d.ts.map +1 -0
  28. package/dist/document/secondary-bar.js +44 -0
  29. package/dist/document/types.d.ts +8 -0
  30. package/dist/document/types.d.ts.map +1 -1
  31. package/dist/document-form-dialog.d.ts.map +1 -1
  32. package/dist/document-form-dialog.js +7 -4
  33. package/dist/dynamic-columns.d.ts +1 -11
  34. package/dist/dynamic-columns.d.ts.map +1 -1
  35. package/dist/dynamic-columns.js +7 -17
  36. package/dist/dynamic-crud-page.d.ts +12 -0
  37. package/dist/dynamic-crud-page.d.ts.map +1 -1
  38. package/dist/dynamic-crud-page.js +3 -3
  39. package/dist/dynamic-row-actions.d.ts +8 -0
  40. package/dist/dynamic-row-actions.d.ts.map +1 -1
  41. package/dist/dynamic-row-actions.js +12 -2
  42. package/dist/dynamic-table.d.ts.map +1 -1
  43. package/dist/dynamic-table.js +64 -63
  44. package/dist/index.d.ts +2 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +6 -0
  47. package/dist/primitives/contributions.d.ts +14 -3
  48. package/dist/primitives/contributions.d.ts.map +1 -1
  49. package/dist/primitives/contributions.js +50 -13
  50. package/dist/record-actions.d.ts +21 -0
  51. package/dist/record-actions.d.ts.map +1 -0
  52. package/dist/record-actions.js +76 -0
  53. package/dist/row-actions-menu.d.ts +32 -0
  54. package/dist/row-actions-menu.d.ts.map +1 -0
  55. package/dist/row-actions-menu.js +59 -0
  56. package/dist/slot.d.ts +4 -21
  57. package/dist/slot.d.ts.map +1 -1
  58. package/dist/slot.js +14 -36
  59. package/dist/types.d.ts +32 -0
  60. package/dist/types.d.ts.map +1 -1
  61. package/package.json +3 -3
  62. package/src/__tests__/document-editor-model.test.ts +55 -1
  63. package/src/__tests__/document-editor.test.tsx +80 -1
  64. package/src/__tests__/document-form-dialog.test.tsx +40 -0
  65. package/src/__tests__/prefill-scalar-from-record.test.ts +52 -1
  66. package/src/__tests__/row-action-link-navigation.test.ts +17 -0
  67. package/src/__tests__/secondary-actions.test.tsx +261 -0
  68. package/src/action-modal-dispatcher.tsx +58 -16
  69. package/src/action-priority.ts +82 -0
  70. package/src/business/business.test.ts +1 -1
  71. package/src/business/catalog-product-search.ts +18 -0
  72. package/src/business/document-editor-model.ts +48 -6
  73. package/src/business/document-editor.tsx +72 -18
  74. package/src/business/line-items.ts +16 -1
  75. package/src/document/document-page.tsx +15 -0
  76. package/src/document/evaluate.ts +17 -1
  77. package/src/document/index.ts +1 -0
  78. package/src/document/secondary-bar.tsx +92 -0
  79. package/src/document/types.ts +8 -0
  80. package/src/document-form-dialog.tsx +8 -4
  81. package/src/dynamic-columns.tsx +13 -57
  82. package/src/dynamic-crud-page.tsx +11 -2
  83. package/src/dynamic-row-actions.tsx +12 -2
  84. package/src/dynamic-table.tsx +3 -0
  85. package/src/index.ts +25 -0
  86. package/src/primitives/contributions.ts +59 -12
  87. package/src/record-actions.ts +101 -0
  88. package/src/row-actions-menu.tsx +159 -0
  89. package/src/slot.tsx +18 -53
  90. package/src/types.ts +28 -0
@@ -31,7 +31,7 @@ import { DocumentLinesGrid } from './line-items-editor';
31
31
  import { computeTotals, serializeLineItems, taxBreakdown } from './line-items';
32
32
  import { roundMoney, toAmount, useFormatter } from './format';
33
33
  import { createCatalogProductSearch } from './catalog-product-search';
34
- import { allocationAmountField, allocationIssueMessages, allocationPayload, creditStatus, editorLinesConfig, linesFromSource, localIssues, partyDefaults, partySummaryRows, splitEditorFields, toOpenDocuments, withFriendlyOptions, } from './document-editor-model';
34
+ import { allocationAmountField, allocationIssueMessages, allocationPayload, creditStatus, editorLinesConfig, linesFromSource, localIssues, sourceLoadSummary, sourceTracksRemaining, partyDefaults, partySummaryRows, splitEditorFields, toOpenDocuments, withFriendlyOptions, } from './document-editor-model';
35
35
  import { CollapsibleSection, EditorSection, PartyCard, PreviewPanel, TotalsPanel, ValidationChecklist, } from './document-editor-panels';
36
36
  import { PaymentAllocator } from './payment-allocator';
37
37
  import { actionErrorBannerMessage, buildFieldDefaults, prefillFromFieldRelationRequest, renderField } from '../action-modal-dispatcher';
@@ -78,6 +78,10 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
78
78
  const [attempted, setAttempted] = useState(false);
79
79
  const [sourceKey, setSourceKey] = useState(initialSource?.key ?? '');
80
80
  const [sourceId, setSourceId] = useState(initialSource?.id ?? '');
81
+ // Fuente de la que salieron los renglones: su `line_link_field` viaja en cada
82
+ // renglón para que el servidor descuente lo ya facturado/devuelto y valide.
83
+ const [loadedSource, setLoadedSource] = useState(null);
84
+ const [sourceNote, setSourceNote] = useState();
81
85
  const relCache = useRef(new Map());
82
86
  const taxRate = defaultTaxRate ?? orgTaxRate;
83
87
  const search = useMemo(() => searchProducts ?? createCatalogProductSearch(api, { model: productModel, defaultTaxRate: taxRate }), [searchProducts, api, productModel, taxRate]);
@@ -188,10 +192,13 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
188
192
  if (forms.type_field && !type.submit_action)
189
193
  p[forms.type_field] = type.value ?? type.key;
190
194
  if (lineCfg) {
191
- p[lineCfg.field] = isAllocation && openCfg ? allocationPayload(allocation.allocations, openCfg) : serializeLineItems(lines);
195
+ p[lineCfg.field] =
196
+ isAllocation && openCfg
197
+ ? allocationPayload(allocation.allocations, openCfg)
198
+ : serializeLineItems(lines, { sourceLineField: loadedSource?.line_link_field });
192
199
  }
193
200
  return p;
194
- }, [type, header, forms.type_field, lineCfg, isAllocation, openCfg, allocation, lines]);
201
+ }, [type, header, forms.type_field, lineCfg, isAllocation, openCfg, allocation, lines, loadedSource]);
195
202
  const baseUrl = type.endpoint ?? endpoint ?? `/dynamic/${model}`;
196
203
  /** Crea o actualiza el BORRADOR (idempotente por draftId). La vista previa lo necesita. */
197
204
  const saveDraft = useCallback(async () => {
@@ -219,25 +226,66 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
219
226
  }
220
227
  };
221
228
  // ---- Cargar desde… --------------------------------------------------------
229
+ /**
230
+ * Renglones del origen. Con lo pendiente declarado (`line_link_field`,
231
+ * `remaining_qty_field` o `remaining_endpoint`) los sirve el host ya con
232
+ * `remaining_quantity` (cantidad − lo ya facturado/devuelto, calculado en el
233
+ * servidor); si el host aún no tiene `source-lines` (404) o la fuente no lo
234
+ * declara, se leen de la relación como antes.
235
+ */
236
+ const fetchSourceRows = useCallback(async (src, id) => {
237
+ if (src.remaining_endpoint) {
238
+ const res = await api.get(src.remaining_endpoint, { params: { id } });
239
+ return res?.data?.data ?? [];
240
+ }
241
+ if (sourceTracksRemaining(src)) {
242
+ try {
243
+ const res = await api.get(`${baseUrl}/source-lines`, {
244
+ params: { source: src.key, id, ...(draftId ? { exclude: draftId } : {}) },
245
+ });
246
+ return res?.data?.data ?? [];
247
+ }
248
+ catch (err) {
249
+ if (err?.response?.status !== 404)
250
+ throw err;
251
+ }
252
+ }
253
+ let rels = relCache.current.get(src.model);
254
+ if (!rels) {
255
+ rels = api
256
+ .get(`/metadata/table/${src.model}`)
257
+ .then((r) => r?.data?.data?.relations ?? r?.data?.relations ?? []);
258
+ relCache.current.set(src.model, rels);
259
+ }
260
+ const call = prefillFromFieldRelationRequest({ fieldKey: lineCfg?.field ?? 'lines', refModel: src.model, refId: id, spec: { $prefillFromRecord: src.lines } }, await rels);
261
+ if (!call)
262
+ throw new Error(`${src.model}: falta la relación «${src.lines}»`);
263
+ const res = await api.get(call.endpoint, { params: call.params });
264
+ return res?.data?.data ?? [];
265
+ }, [api, baseUrl, draftId, lineCfg?.field]);
222
266
  const loadFromSource = useCallback(async (src, id) => {
223
267
  if (!lineCfg || !id)
224
268
  return;
225
269
  setBusy('source');
226
270
  try {
227
271
  if (!isAllocation) {
228
- let rels = relCache.current.get(src.model);
229
- if (!rels) {
230
- rels = api
231
- .get(`/metadata/table/${src.model}`)
232
- .then((r) => r?.data?.data?.relations ?? r?.data?.relations ?? []);
233
- relCache.current.set(src.model, rels);
234
- }
235
- const call = prefillFromFieldRelationRequest({ fieldKey: lineCfg.field, refModel: src.model, refId: id, spec: { $prefillFromRecord: src.lines } }, await rels);
236
- if (!call)
237
- throw new Error(`${src.model}: falta la relación «${src.lines}»`);
238
- const res = await api.get(call.endpoint, { params: call.params });
239
- setLines(linesFromSource(res?.data?.data ?? [], src.map, { kind }));
272
+ const rows = await fetchSourceRows(src, id);
273
+ const loaded = linesFromSource(rows, src.map, { kind, discountMode: lineCfg.discount_mode });
274
+ const { covered } = sourceLoadSummary(rows);
275
+ setLines(loaded);
276
+ setLoadedSource(src);
240
277
  setLinesFromSourceDoc(kind === 'credit');
278
+ setSourceNote(loaded.length === 0 && covered > 0
279
+ ? t('documentEditor.source_all_covered', {
280
+ defaultValue: 'Todo el documento ya está registrado en otros documentos; no queda nada pendiente.',
281
+ })
282
+ : covered > 0
283
+ ? t('documentEditor.source_loaded_partial', {
284
+ defaultValue: '{{count}} renglones con lo pendiente · {{covered}} ya cubiertos se omitieron',
285
+ count: loaded.length,
286
+ covered,
287
+ })
288
+ : t('documentEditor.source_loaded', { defaultValue: '{{count}} renglones cargados', count: loaded.length }));
241
289
  }
242
290
  if (src.header || src.link_field) {
243
291
  const h = await api.get(`/data/${src.model}`, { params: { f_id: `eq:${id}`, per_page: 1 } });
@@ -262,7 +310,7 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
262
310
  finally {
263
311
  setBusy(null);
264
312
  }
265
- }, [api, lineCfg, isAllocation, kind, t]);
313
+ }, [api, lineCfg, isAllocation, kind, t, fetchSourceRows]);
266
314
  // Prefill al abrir desde un documento origen (acción de fila «Crear NC», «Facturar venta»…).
267
315
  const autoLoaded = useRef(false);
268
316
  useEffect(() => {
@@ -417,7 +465,7 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
417
465
  : isAllocation
418
466
  ? t('documentEditor.allocation_title', { defaultValue: 'Documentos a pagar' })
419
467
  : t('documentEditor.lines_title', { defaultValue: 'Conceptos' });
420
- return (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col", "data-slot": "document-editor", "data-kind": kind, children: [_jsxs("div", { className: "-mx-1 min-h-0 flex-1 space-y-8 overflow-y-auto px-1 py-2", children: [_jsx(FormErrorBanner, { message: formError }), _jsxs(EditorSection, { slot: "editor-essentials", children: [_jsxs(FieldGrid, { children: [groups.party && fieldCell(groups.party), groups.essential.map((f) => fieldCell(f))] }), party && (_jsx(PartyCard, { name: party.name ?? party.legal_name, rows: summaryRows, credit: credit, fmt: fmt, children: partyContribs.map(({ id, component: C }) => (_jsx(C, { ...contribProps }, id))) }))] }), sources.length > 0 && !isAllocation && (_jsx(EditorSection, { slot: "load-from-source", title: t('documentEditor.load_from', { defaultValue: 'Cargar desde…' }), hint: busy === 'source' ? t('documentEditor.loading_source', { defaultValue: 'Cargando…' }) : undefined, children: _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [sources.length > 1 && (_jsxs("select", { "aria-label": t('documentEditor.source_kind', { defaultValue: 'Tipo de documento origen' }), className: "h-9 rounded-md border bg-background px-2 text-sm", value: sourceKey, onChange: (e) => {
468
+ return (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col", "data-slot": "document-editor", "data-kind": kind, children: [_jsxs("div", { className: "-mx-1 min-h-0 flex-1 space-y-8 overflow-y-auto px-1 py-2", children: [_jsx(FormErrorBanner, { message: formError }), _jsxs(EditorSection, { slot: "editor-essentials", children: [_jsxs(FieldGrid, { children: [groups.party && fieldCell(groups.party), groups.essential.map((f) => fieldCell(f))] }), party && (_jsx(PartyCard, { name: party.name ?? party.legal_name, rows: summaryRows, credit: credit, fmt: fmt, children: partyContribs.map(({ id, component: C }) => (_jsx(C, { ...contribProps }, id))) }))] }), sources.length > 0 && !isAllocation && (_jsx(EditorSection, { slot: "load-from-source", title: t('documentEditor.load_from', { defaultValue: 'Cargar desde…' }), hint: busy === 'source' ? t('documentEditor.loading_source', { defaultValue: 'Cargando…' }) : sourceNote, children: _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [sources.length > 1 && (_jsxs("select", { "aria-label": t('documentEditor.source_kind', { defaultValue: 'Tipo de documento origen' }), className: "h-9 rounded-md border bg-background px-2 text-sm", value: sourceKey, onChange: (e) => {
421
469
  setSourceKey(e.target.value);
422
470
  setSourceId('');
423
471
  }, children: [_jsx("option", { value: "", children: t('documentEditor.choose_source', { defaultValue: 'Elige…' }) }), sources.map((s) => (_jsx("option", { value: s.key, children: tl(s.label) }, s.key)))] })), (activeSource ?? (sources.length === 1 ? sources[0] : undefined)) && (_jsx(SourcePicker, { source: (activeSource ?? sources[0]), value: sourceId, header: header, label: tl((activeSource ?? sources[0]).label), onPick: (id) => {
@@ -25,6 +25,12 @@ export interface LineItem {
25
25
  cost?: number;
26
26
  /** Tope de cantidad (NC: facturado − acreditado; devolución: vendido − devuelto). */
27
27
  max_quantity?: number;
28
+ /**
29
+ * Id del renglón del documento origen («crear desde»). Viaja en la columna
30
+ * `line_link_field` de la fuente para que el servidor descuente y valide lo
31
+ * pendiente; un renglón libre no lo lleva.
32
+ */
33
+ source_line_id?: string;
28
34
  technician_id?: string;
29
35
  lot?: string;
30
36
  dot?: string;
@@ -92,7 +98,9 @@ export declare function validateLineItems(lines: LineItem[], policy?: LineItemsP
92
98
  * Forma que se manda al backend: números reales (nunca `""`), sin claves de UI,
93
99
  * opcionales vacíos omitidos y `position` 1-based conservando el orden.
94
100
  */
95
- export declare function serializeLineItems(lines: LineItem[]): Array<Record<string, unknown>>;
101
+ export declare function serializeLineItems(lines: LineItem[], opts?: {
102
+ sourceLineField?: string;
103
+ }): Array<Record<string, unknown>>;
96
104
  /** Inversa de `serializeLineItems`: filas del API → líneas editables (defaults seguros). */
97
105
  export declare function parseLineItems(rows: unknown): LineItem[];
98
106
  //# sourceMappingURL=line-items.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"line-items.d.ts","sourceRoot":"","sources":["../../src/business/line-items.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"line-items.d.ts","sourceRoot":"","sources":["../../src/business/line-items.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAA;AAEtD,MAAM,WAAW,QAAQ;IACrB,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,YAAY,CAAA;IAClB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;IACpC,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAA;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACtC;AAED,2CAA2C;AAC3C,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;AAEpD,MAAM,WAAW,eAAe;IAC5B,sBAAsB;IACtB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,yFAAyF;IACzF,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC9B;AAGD,uCAAuC;AACvC,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED,wBAAgB,QAAQ,CAAC,OAAO,GAAE,OAAO,CAAC,QAAQ,CAAM,GAAG,QAAQ,CAWlE;AAED,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,WAAW,CACvB,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,CAAC,GAAG;IAAE,aAAa,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;CAAE,GAChI,WAAW,CAWb;AAED,MAAM,WAAW,eAAe;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,eAAe,CAehE;AAED,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBlG;AAED,MAAM,WAAW,mBAAmB;IAChC,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;CACjB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,GAAE,eAAoB,GAAG,mBAAmB,CAuCtG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAC9B,KAAK,EAAE,QAAQ,EAAE,EACjB,IAAI,GAAE;IAAkF,eAAe,CAAC,EAAE,MAAM,CAAA;CAAO,GACxH,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA4BhC;AAED,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,CA+BxD"}
@@ -123,7 +123,7 @@ export function validateLineItems(lines, policy = {}) {
123
123
  * Forma que se manda al backend: números reales (nunca `""`), sin claves de UI,
124
124
  * opcionales vacíos omitidos y `position` 1-based conservando el orden.
125
125
  */
126
- export function serializeLineItems(lines) {
126
+ export function serializeLineItems(lines, opts = {}) {
127
127
  return lines.map((l, i) => {
128
128
  const out = {
129
129
  position: i + 1,
@@ -146,6 +146,13 @@ export function serializeLineItems(lines) {
146
146
  }
147
147
  if (l.extensions && Object.keys(l.extensions).length > 0)
148
148
  out.fiscal_data = { ...l.extensions };
149
+ if (opts.sourceLineField && l.source_line_id)
150
+ out[opts.sourceLineField] = l.source_line_id;
151
+ // Importes ya calculados: un modelo de renglón sin tasa (solo
152
+ // `tax_amount`/`subtotal`) los guarda tal cual en vez de perder el IVA.
153
+ const a = computeLine(l);
154
+ out.subtotal = a.net;
155
+ out.tax_amount = a.tax;
149
156
  }
150
157
  return out;
151
158
  });
@@ -1 +1 @@
1
- {"version":3,"file":"document-page.d.ts","sourceRoot":"","sources":["../../src/document/document-page.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AASzD,OAAO,EAAoB,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,EAAqB,KAAK,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAE7E,OAAO,KAAK,EAER,eAAe,EAEf,oBAAoB,EAGpB,cAAc,EACjB,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IACzD,YAAY,EAAE,wBAAwB,CAAA;IACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B;;;;OAIG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACnF,yFAAyF;IACzF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IAC5C,2DAA2D;IAC3D,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,SAAS,CAAA;IAC5F,wDAAwD;IACxD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2FAA2F;IAC3F,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BA4HpD"}
1
+ {"version":3,"file":"document-page.d.ts","sourceRoot":"","sources":["../../src/document/document-page.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAUzD,OAAO,EAAoB,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,EAAqB,KAAK,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAE7E,OAAO,KAAK,EAER,eAAe,EAEf,oBAAoB,EAGpB,cAAc,EACjB,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IACzD,YAAY,EAAE,wBAAwB,CAAA;IACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B;;;;OAIG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACnF,yFAAyF;IACzF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IAC5C,2DAA2D;IAC3D,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,SAAS,CAAA;IAC5F,wDAAwD;IACxD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2FAA2F;IAC3F,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BA0IpD"}
@@ -9,6 +9,7 @@ import { useTranslation } from 'react-i18next';
9
9
  import { Tabs, TabsContent, TabsList, TabsTrigger } from '@asteby/metacore-ui/primitives';
10
10
  import { cn } from '@asteby/metacore-ui/lib';
11
11
  import { ActionBar } from './action-bar';
12
+ import { DocumentSecondaryBar } from './secondary-bar';
12
13
  import { DocumentHeader } from './document-header';
13
14
  import { SmartButtons } from './smart-buttons';
14
15
  import { StatusBadge } from './status-badge';
@@ -97,7 +98,13 @@ export function DocumentPage(props) {
97
98
  .filter((b) => !!b);
98
99
  return (_jsxs("div", { className: cn('flex flex-col gap-4', className), "data-document-page": spec.model, children: [_jsx(DocumentHeader, { title: resolveTitle(spec.title, ctx) || t('document.untitled', { defaultValue: 'Documento' }), subtitle: subtitle, subtitleHref: subtitleHref, badges: badges, metrics: metrics, copyable: spec.copyable && copyValue
99
100
  ? { label: t(spec.copyable.label, { defaultValue: spec.copyable.label }), value: String(copyValue) }
100
- : undefined, leading: leading, renderLink: renderLink, actions: _jsx(ActionBar, { layout: layout, onAction: (a) => handleAction(a) }) }), _jsx(SmartButtons, { items: smart }), _jsxs(Tabs, { value: tab, onValueChange: setTab, className: 'flex flex-col gap-4', children: [_jsx(TabsList, { className: 'w-fit', children: spec.tabs.map((tb) => (_jsxs(TabsTrigger, { value: tb.key, children: [t(tb.label, { defaultValue: tb.label }), tabCount(tb, ctx) !== undefined ? (_jsx("span", { className: 'ml-1.5 rounded-full bg-muted px-1.5 text-xs tabular-nums', children: tabCount(tb, ctx) })) : null] }, tb.key))) }), spec.tabs.map((tb) => (_jsx(TabsContent, { value: tb.key, className: 'mt-0', children: renderTab(tb, spec, ctx, fmt, slots) }, tb.key)))] })] }));
101
+ : undefined, leading: leading, renderLink: renderLink, actions: _jsx(ActionBar, { layout: layout, onAction: (a) => handleAction(a) }) }), _jsx(SmartButtons, { items: smart }), _jsxs(Tabs, { value: tab, onValueChange: setTab, className: 'flex flex-col gap-4', children: [_jsx(TabsList, { className: 'w-fit', children: spec.tabs.map((tb) => (_jsxs(TabsTrigger, { value: tb.key, children: [t(tb.label, { defaultValue: tb.label }), tabCount(tb, ctx) !== undefined ? (_jsx("span", { className: 'ml-1.5 rounded-full bg-muted px-1.5 text-xs tabular-nums', children: tabCount(tb, ctx) })) : null] }, tb.key))) }), spec.tabs.map((tb) => (_jsx(TabsContent, { value: tb.key, className: 'mt-0', children: renderTab(tb, spec, ctx, fmt, slots) }, tb.key)))] }), _jsx(DocumentSecondaryBar, { items: layout.footer.map((a) => ({
102
+ key: a.def.key,
103
+ label: a.def.label,
104
+ icon: a.def.icon,
105
+ blockedReason: a.blockedReason,
106
+ run: () => handleAction(a),
107
+ })), model: spec.model, record: record })] }));
101
108
  }
102
109
  /** Total de una fuente: el del servidor si lo dio (`meta.total`), si no las filas traídas. */
103
110
  function sourceCount(ctx, key) {
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/document/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGR,eAAe,EACf,YAAY,EACZ,SAAS,EAET,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,IAAI,EACP,MAAM,SAAS,CAAA;AAEhB,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAuBpE;AAkBD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CA0B7E;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAIlF;AAED,uGAAuG;AACvG,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,CAQjG;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,eAAe,GAAG,oBAAoB,CAoC7F;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM,CAK1E;AAED,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM,CAM3E;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,YAAY,EAAE,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,YAAY,CAMjH"}
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/document/evaluate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGR,eAAe,EACf,YAAY,EACZ,SAAS,EAET,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,IAAI,EACP,MAAM,SAAS,CAAA;AAEhB,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAuBpE;AAkBD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CA0B7E;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAIlF;AAED,uGAAuG;AACvG,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,CAQjG;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,eAAe,GAAG,oBAAoB,CAuC7F;AAcD,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM,CAK1E;AAED,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM,CAM3E;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,YAAY,EAAE,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,YAAY,CAMjH"}
@@ -1,3 +1,4 @@
1
+ import { classifyActionPriority } from '../action-priority';
1
2
  /** Máximo de secundarias visibles; el resto pasa a «Más…» (§5.2 / §6.2). */
2
3
  export const MAX_VISIBLE_SECONDARY = 3;
3
4
  /**
@@ -119,15 +120,20 @@ export function resolveActions(spec, ctx) {
119
120
  const destructive = many(layout.destructive);
120
121
  const secondary = [];
121
122
  const more = [];
123
+ const footer = [];
122
124
  for (const a of [...many(layout.secondary)]) {
123
125
  if (a.def.destructive)
124
126
  destructive.push(a);
127
+ else if (isFooterAction(a.def))
128
+ footer.push(a);
125
129
  else
126
130
  secondary.push(a);
127
131
  }
128
132
  for (const a of many(layout.more)) {
129
133
  if (a.def.destructive)
130
134
  destructive.push(a);
135
+ else if (isFooterAction(a.def))
136
+ footer.push(a);
131
137
  else
132
138
  more.push(a);
133
139
  }
@@ -138,7 +144,17 @@ export function resolveActions(spec, ctx) {
138
144
  destructive.unshift(primary);
139
145
  primary = undefined;
140
146
  }
141
- return { primary, secondary, more, destructive };
147
+ return { primary, secondary, more, destructive, footer };
148
+ }
149
+ /**
150
+ * ¿Va al pie? `priority: secondary`, o la convención por clave sobre la acción
151
+ * del modelo (`modelAction ?? key`): compartir, imprimir, correo, chat, PDF/XML.
152
+ */
153
+ function isFooterAction(def) {
154
+ if (def.priority)
155
+ return def.priority === 'secondary';
156
+ return (classifyActionPriority({ key: def.key }) === 'secondary' ||
157
+ (!!def.modelAction && classifyActionPriority({ key: def.modelAction }) === 'secondary'));
142
158
  }
143
159
  /** Interpola `{{campo}}` con valores del registro (sin evaluar código). */
144
160
  export function interpolate(template, ctx) {
@@ -3,6 +3,7 @@ export { MAX_VISIBLE_SECONDARY, evaluatePredicate, evaluateWhen, interpolate, pr
3
3
  export { formatFieldValue, type FieldFormatOptions } from './format';
4
4
  export { StatusBadge, STATUS_TONE_STYLE, type StatusBadgeProps } from './status-badge';
5
5
  export { ActionBar, type ActionBarProps } from './action-bar';
6
+ export { DocumentSecondaryBar, type DocumentSecondaryBarProps, type SecondaryBarItem } from './secondary-bar';
6
7
  export { DocumentHeader, type DocumentHeaderProps, type HeaderBadge, type HeaderMetric } from './document-header';
7
8
  export { SmartButtons, type SmartButtonItem, type SmartButtonsProps } from './smart-buttons';
8
9
  export { DocumentTimeline, type DocumentTimelineProps, type TimelineEntry } from './document-timeline';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/document/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,uBAAuB,EACvB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,YAAY,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtF,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACjH,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAC5F,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACtG,OAAO,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC1H,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AACtF,OAAO,EACH,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,KAAK,wBAAwB,GAChC,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/document/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,uBAAuB,EACvB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,YAAY,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtF,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAC7G,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACjH,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAC5F,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACtG,OAAO,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC1H,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AACtF,OAAO,EACH,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,KAAK,wBAAwB,GAChC,MAAM,YAAY,CAAA"}
@@ -3,6 +3,7 @@ export { MAX_VISIBLE_SECONDARY, evaluatePredicate, evaluateWhen, interpolate, pr
3
3
  export { formatFieldValue } from './format';
4
4
  export { StatusBadge, STATUS_TONE_STYLE } from './status-badge';
5
5
  export { ActionBar } from './action-bar';
6
+ export { DocumentSecondaryBar } from './secondary-bar';
6
7
  export { DocumentHeader } from './document-header';
7
8
  export { SmartButtons } from './smart-buttons';
8
9
  export { DocumentTimeline } from './document-timeline';
@@ -0,0 +1,20 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface SecondaryBarItem {
3
+ key: string;
4
+ label: string;
5
+ icon?: string;
6
+ /** Deshabilitada con su motivo (no desaparece). */
7
+ blockedReason?: string;
8
+ run: () => unknown;
9
+ }
10
+ export interface DocumentSecondaryBarProps {
11
+ items?: SecondaryBarItem[];
12
+ /** Modelo + registro: resuelven las acciones aportadas por addons. */
13
+ model?: string;
14
+ record?: Record<string, unknown> | null;
15
+ /** Controles extra del host (al final). */
16
+ children?: ReactNode;
17
+ className?: string;
18
+ }
19
+ export declare function DocumentSecondaryBar({ items, model, record, children, className }: DocumentSecondaryBarProps): import("react").JSX.Element | null;
20
+ //# sourceMappingURL=secondary-bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secondary-bar.d.ts","sourceRoot":"","sources":["../../src/document/secondary-bar.tsx"],"names":[],"mappings":"AASA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAQhD,MAAM,WAAW,gBAAgB;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,GAAG,EAAE,MAAM,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,yBAAyB;IACtC,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC1B,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACvC,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,oBAAoB,CAAC,EAAE,KAAU,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,yBAAyB,sCAuDjH"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // DocumentSecondaryBar — pie del documento con las acciones secundarias:
3
+ // compartir, imprimir/descargar PDF o XML, enviar por correo, enviar al chat…
4
+ // La cabecera se queda con UNA primaria (y sus principales); esto va abajo,
5
+ // discreto. Junta dos fuentes:
6
+ // - `items`: acciones del propio documento/modelo ya clasificadas como
7
+ // secundarias (resolveActions → `footer`, o splitActionsByPriority);
8
+ // - las aportadas por addons/host con registerRecordAction, sólo si su
9
+ // proveedor está instalado y activo (useRecordActions).
10
+ // Sin nada que mostrar no pinta nada.
11
+ import { useState } from 'react';
12
+ import { useTranslation } from 'react-i18next';
13
+ import { Loader2 } from 'lucide-react';
14
+ import { Button } from '@asteby/metacore-ui/primitives';
15
+ import { cn } from '@asteby/metacore-ui/lib';
16
+ import { DynamicIcon } from '../dynamic-icon';
17
+ import { useRecordActions } from '../record-actions';
18
+ export function DocumentSecondaryBar({ items = [], model, record, children, className }) {
19
+ const { t } = useTranslation();
20
+ const contributed = useRecordActions(model ?? '', model ? record : null);
21
+ const [busy, setBusy] = useState(null);
22
+ const run = async (key, fn) => {
23
+ if (!fn || busy)
24
+ return;
25
+ setBusy(key);
26
+ try {
27
+ await fn();
28
+ }
29
+ finally {
30
+ setBusy(null);
31
+ }
32
+ };
33
+ const all = [
34
+ ...items,
35
+ ...contributed.filter((c) => c.run).map((c) => ({ key: c.key, label: c.label, icon: c.icon, run: c.run })),
36
+ ];
37
+ const rendered = contributed.filter((c) => c.render && !c.run);
38
+ if (all.length === 0 && rendered.length === 0 && !children)
39
+ return null;
40
+ return (_jsxs("footer", { className: cn('flex flex-wrap items-center gap-1.5 border-t pt-3', className), "data-document-secondary": '', "aria-label": t('datatable.secondary_actions', { defaultValue: 'Compartir y documentos' }), children: [all.map((a) => (_jsxs(Button, { type: 'button', size: 'sm', variant: 'ghost', className: 'text-muted-foreground', "data-action": a.key, disabled: !!a.blockedReason || (!!busy && busy !== a.key), title: a.blockedReason ? t(a.blockedReason, { defaultValue: a.blockedReason }) : undefined, onClick: () => void run(a.key, a.run), children: [busy === a.key ? (_jsx(Loader2, { className: 'mr-1.5 h-4 w-4 animate-spin' })) : a.icon ? (_jsx(DynamicIcon, { name: a.icon, className: 'mr-1.5 h-4 w-4' })) : null, t(a.label, { defaultValue: a.label })] }, a.key))), rendered.map((c) => {
41
+ const C = c.render;
42
+ return _jsx(C, { model: model, record: record }, c.key);
43
+ }), children] }));
44
+ }
@@ -52,6 +52,12 @@ export interface DocumentActionDef {
52
52
  href?: string;
53
53
  openUrl?: string;
54
54
  tab?: string;
55
+ /**
56
+ * "secondary" (o, sin valor, una clave de compartir/imprimir/correo/chat/
57
+ * PDF/XML por convención) saca la acción de la cabecera y la pone en la
58
+ * barra secundaria del pie — salvo que el layout la haga primaria.
59
+ */
60
+ priority?: 'primary' | 'secondary';
55
61
  /** Estilo crítico: siempre va en la zona destructiva. */
56
62
  destructive?: boolean;
57
63
  /** Se muestra deshabilitada con el motivo en lugar de desaparecer. */
@@ -193,6 +199,8 @@ export interface ResolvedActionLayout {
193
199
  secondary: ResolvedAction[];
194
200
  more: ResolvedAction[];
195
201
  destructive: ResolvedAction[];
202
+ /** Secundarias (compartir, imprimir, correo…) → DocumentSecondaryBar, no la cabecera. */
203
+ footer: ResolvedAction[];
196
204
  }
197
205
  export type DocumentSlotRenderer = (ctx: DocumentContext) => ReactNode;
198
206
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/document/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/document/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"document-form-dialog.d.ts","sourceRoot":"","sources":["../src/document-form-dialog.tsx"],"names":[],"mappings":"AA6BA,OAAO,EAEH,KAAK,sBAAsB,EAE9B,MAAM,8BAA8B,CAAA;AAerC,OAAO,KAAK,EAER,qBAAqB,EACrB,aAAa,EAChB,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,uBAAuB;IACpC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,qBAAqB,CAAA;IAC5B,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uCAAuC;IACvC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACpC;;;OAGG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAA;IACjD,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0GAA0G;IAC1G,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,gFAAgF;IAChF,aAAa,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9C;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAChC,QAAQ,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,IAAI,EACvD,QAAQ,CAAC,EAAE,qBAAqB,GAAG,IAAI,GACxC,qBAAqB,GAAG,SAAS,CAGnC;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACtC,KAAK,EAAE,qBAAqB,GAAG,SAAS,EACxC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACxC;IAAE,KAAK,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAQnE;AAID,wBAAgB,kBAAkB,CAAC,EAC/B,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,KAAK,EACL,WAAW,EACX,OAAO,EACP,cAAc,EACd,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,MAAM,EACN,aAAa,GAChB,EAAE,uBAAuB,+BAgTzB"}
1
+ {"version":3,"file":"document-form-dialog.d.ts","sourceRoot":"","sources":["../src/document-form-dialog.tsx"],"names":[],"mappings":"AA6BA,OAAO,EAEH,KAAK,sBAAsB,EAE9B,MAAM,8BAA8B,CAAA;AAerC,OAAO,KAAK,EAER,qBAAqB,EACrB,aAAa,EAChB,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,uBAAuB;IACpC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,qBAAqB,CAAA;IAC5B,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uCAAuC;IACvC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACpC;;;OAGG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAA;IACjD,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0GAA0G;IAC1G,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,gFAAgF;IAChF,aAAa,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9C;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAChC,QAAQ,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,IAAI,EACvD,QAAQ,CAAC,EAAE,qBAAqB,GAAG,IAAI,GACxC,qBAAqB,GAAG,SAAS,CAGnC;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACtC,KAAK,EAAE,qBAAqB,GAAG,SAAS,EACxC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACxC;IAAE,KAAK,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAQnE;AAID,wBAAgB,kBAAkB,CAAC,EAC/B,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,KAAK,EACL,WAAW,EACX,OAAO,EACP,cAAc,EACd,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,MAAM,EACN,aAAa,GAChB,EAAE,uBAAuB,+BAoTzB"}
@@ -28,7 +28,7 @@ import { validateValues, bagHasErrors } from './validator';
28
28
  import { clearFieldErrorTree } from './field-validation-ui';
29
29
  import { emitRecordMutation } from './record-mutation-events';
30
30
  import { isLineItemsField, resolveWidget, scopeValueFromFilterToken } from './dynamic-form-schema';
31
- import { createCatalogProductSearch } from './business/catalog-product-search';
31
+ import { createCatalogProductSearch, withDefaultTaxRate } from './business/catalog-product-search';
32
32
  import { DocumentEditor } from './business/document-editor';
33
33
  import { editorLinesConfig, isEditorLayout } from './business/document-editor-model';
34
34
  /** Manifest efectivo: la prop gana sobre el metadata; sin tipos devuelve undefined. */
@@ -73,9 +73,12 @@ export function DocumentFormDialog({ open, onOpenChange, model, endpoint, forms,
73
73
  const type = useMemo(() => types.find((x) => x.key === typeKey) ?? null, [types, typeKey]);
74
74
  // Sin buscador inyectado, el paso de renglones solo ofrecía «Renglón libre»
75
75
  // y la línea entraba sin precio (DynamicCRUDPage no pasa searchProducts).
76
- // Default: el catálogo de productos de la org.
76
+ // Default: el catálogo de productos de la org. El buscador del host también
77
+ // recibe el IVA de la org para los productos que no traen su tasa.
77
78
  const taxRate = defaultTaxRate ?? orgTaxRate;
78
- const lineSearch = useMemo(() => searchProducts ?? createCatalogProductSearch(api, { model: productModel, defaultTaxRate: taxRate }), [searchProducts, api, productModel, taxRate]);
79
+ const lineSearch = useMemo(() => searchProducts
80
+ ? withDefaultTaxRate(searchProducts, taxRate)
81
+ : createCatalogProductSearch(api, { model: productModel, defaultTaxRate: taxRate }), [searchProducts, api, productModel, taxRate]);
79
82
  const lineCfg = type ? editorLinesConfig(type, forms) : undefined;
80
83
  // Reset every time the dialog (re)opens.
81
84
  useEffect(() => {
@@ -201,7 +204,7 @@ export function DocumentFormDialog({ open, onOpenChange, model, endpoint, forms,
201
204
  : tl(lineCfg?.title ?? 'Renglones');
202
205
  // layout "editor": una sola pantalla por secciones (DocumentEditor). Sin él
203
206
  // sigue el wizard de siempre (retrocompatible).
204
- if (open && type && step !== 'type' && isEditorLayout(type)) {
207
+ if (open && type && step !== 'type' && (isEditorLayout(type) || !!initialSource)) {
205
208
  return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "flex max-h-[92dvh] flex-col overflow-hidden", style: { maxHeight: '92dvh', maxWidth: '960px', width: '95vw' }, "data-slot": "document-editor-dialog", children: [_jsxs(DialogHeader, { className: "shrink-0", children: [_jsx(DialogTitle, { children: tl(type.label) }), type.description && _jsx(DialogDescription, { children: tl(type.description) })] }), _jsx(DocumentEditor, { model: model, endpoint: endpoint, forms: forms, type: type, record: record, initialSource: initialSource, searchProducts: lineSearch, currency: currency, onCancel: () => (canGoBackToTypes ? setStep('type') : onOpenChange(false)), onSaved: (rec) => {
206
209
  onSaved?.(rec);
207
210
  onOpenChange(false);
@@ -38,17 +38,7 @@ export declare const aggregateOf: (col: ColumnDefinition) => string | undefined;
38
38
  * empty filtered set reads cleanly.
39
39
  */
40
40
  export declare const formatAggregateTotal: (col: ColumnDefinition, value: unknown, currency?: string, locale?: string) => string;
41
- /**
42
- * One entry of the row "…" menu. An action gated by a missing optional addon
43
- * (`requiresAddon`) stays listed with a lock + tooltip; the click still goes to
44
- * `onAction`, whose shared handler (useDynamicRowActions) opens the
45
- * requires-addon dialog instead of executing.
46
- */
47
- export declare function RowActionMenuItem({ action, label, onSelect, }: {
48
- action: any;
49
- label: React.ReactNode;
50
- onSelect: (e: React.MouseEvent) => void;
51
- }): React.JSX.Element;
41
+ export { RowActionMenuItem } from './row-actions-menu';
52
42
  /**
53
43
  * State-machine gate for per-row actions.
54
44
  *
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-columns.d.ts","sourceRoot":"","sources":["../src/dynamic-columns.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dynamic-columns.d.ts","sourceRoot":"","sources":["../src/dynamic-columns.tsx"],"names":[],"mappings":"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"}
@@ -16,8 +16,8 @@ import * as React from 'react';
16
16
  import { format } from 'date-fns';
17
17
  import { isCalendarDayValue, parseCalendarDate } from './calendar-date';
18
18
  import { es, enUS } from 'date-fns/locale';
19
- import { Calendar, Check, Copy, Mail, Minus, MoreHorizontal } from 'lucide-react';
20
- import { Avatar, AvatarFallback, AvatarImage, Badge, Button, Checkbox, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, InitialsAvatar, } from '@asteby/metacore-ui';
19
+ import { Calendar, Check, Copy, Mail, Minus } from 'lucide-react';
20
+ import { Avatar, AvatarFallback, AvatarImage, Badge, Checkbox, InitialsAvatar, } from '@asteby/metacore-ui';
21
21
  import { DataTableColumnHeader, FilterableColumnHeader, } from '@asteby/metacore-ui/data-table';
22
22
  import { generateBadgeStyles, getInitials, relationChipStyles, } from '@asteby/metacore-ui/lib';
23
23
  import { Progress } from './dialogs/_primitives';
@@ -30,7 +30,7 @@ import { DynamicIcon, isLucideIconName } from './dynamic-icon';
30
30
  import { CollectionCell } from './collection-cell';
31
31
  import { isNilUuid, normalizeNilUuid } from './nil-uuid';
32
32
  import { useOptionsResolver } from './use-options-resolver';
33
- import { RequiresAddonLock, resolveRequiresAddon, useRequiresAddonLabel } from './requires-addon';
33
+ import { RowActionsMenu } from './row-actions-menu';
34
34
  import { isColumnVisibleInTable } from './column-visibility';
35
35
  const defaultGetImageUrl = (path) => path;
36
36
  const getNestedValue = (obj, path) => path.split('.').reduce((acc, part) => acc && acc[part], obj);
@@ -109,17 +109,9 @@ const CodeCell = ({ text, maxLength }) => {
109
109
  };
110
110
  return (_jsxs("div", { className: "group flex items-center gap-1.5", children: [_jsx("code", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-xs text-foreground/80", title: text, children: display }), _jsx("button", { type: "button", onClick: onCopy, className: "opacity-0 transition-opacity group-hover:opacity-100 text-muted-foreground hover:text-foreground", "aria-label": "Copiar", title: "Copiar", children: copied ? (_jsx(Check, { className: "h-3.5 w-3.5 text-green-500" })) : (_jsx(Copy, { className: "h-3.5 w-3.5" })) })] }));
111
111
  };
112
- /**
113
- * One entry of the row "…" menu. An action gated by a missing optional addon
114
- * (`requiresAddon`) stays listed with a lock + tooltip; the click still goes to
115
- * `onAction`, whose shared handler (useDynamicRowActions) opens the
116
- * requires-addon dialog instead of executing.
117
- */
118
- export function RowActionMenuItem({ action, label, onSelect, }) {
119
- const requirement = resolveRequiresAddon(action);
120
- const requiresAddonLabel = useRequiresAddonLabel();
121
- return (_jsxs(DropdownMenuItem, { onClick: onSelect, title: requirement ? requiresAddonLabel(requirement) : undefined, "data-requires-addon": requirement?.key, children: [_jsx(DynamicIcon, { name: action.icon || 'Zap', className: "mr-2 h-4 w-4" }), label, requirement && _jsx(RequiresAddonLock, { requirement: requirement })] }));
122
- }
112
+ // RowActionMenuItem vive en row-actions-menu.tsx (junto al menú que lo usa);
113
+ // se re-exporta aquí por compatibilidad (dynamic-kanban, hosts).
114
+ export { RowActionMenuItem } from './row-actions-menu';
123
115
  /**
124
116
  * Lifecycle column used by `requiresState`: prefer `status` (workshop, vehicles,
125
117
  * …) and fall back to `state` (purchases, inventory transfers, …). Empty string
@@ -1049,9 +1041,7 @@ export function makeDefaultGetDynamicColumns(helpers = {}) {
1049
1041
  size: 80,
1050
1042
  maxSize: 80,
1051
1043
  meta: {},
1052
- cell: ({ row }) => (_jsx("div", { className: "flex items-center justify-end", children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", className: "h-8 w-8 p-0", children: [_jsx("span", { className: "sr-only", children: "Abrir men\u00FA" }), _jsx(MoreHorizontal, { className: "h-4 w-4" })] }) }), _jsx(DropdownMenuContent, { align: "end", children: resolvedActions
1053
- .filter((action) => isRowActionVisible(action, row.original, lifecycleStageField(metadata)))
1054
- .map((action) => (_jsx(RowActionMenuItem, { action: action, label: translateMetadataLabel(action.label, t), onSelect: () => onAction && onAction(action.key, row.original) }, action.key))) })] }) })),
1044
+ cell: ({ row }) => (_jsx(RowActionsMenu, { actions: resolvedActions.filter((action) => isRowActionVisible(action, row.original, lifecycleStageField(metadata))), row: row.original, onAction: onAction })),
1055
1045
  });
1056
1046
  }
1057
1047
  return columns;
@@ -51,6 +51,18 @@ export interface DynamicCRUDPageProps {
51
51
  * formulario para él.
52
52
  */
53
53
  filter?: Record<string, string>;
54
+ /**
55
+ * Abre el alta guiada al montar («crear desde»): tipo de documento y origen
56
+ * a precargar (`sources[].key` + id), p. ej. leídos de la URL
57
+ * `?create=<tipo>&from=<fuente>&from_id=<id>`. Solo con document_forms.
58
+ */
59
+ initialCreate?: {
60
+ type?: string;
61
+ source?: {
62
+ key: string;
63
+ id: string;
64
+ };
65
+ };
54
66
  }
55
67
  /**
56
68
  * Page-level CRUD shell wired around <DynamicTable>. Hosts mount a single
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-crud-page.d.ts","sourceRoot":"","sources":["../src/dynamic-crud-page.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAKN,MAAM,OAAO,CAAA;AAad,OAAO,KAAK,EAAE,qBAAqB,EAAiB,MAAM,SAAS,CAAA;AAEnE,MAAM,WAAW,sBAAsB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;mDAC+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AASD,MAAM,WAAW,sBAAsB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,oBAAoB;IACjC,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,sBAAsB,CAAA;IAC7B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC9B,8DAA8D;IAC9D,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC/B,sDAAsD;IACtD,OAAO,CAAC,EAAE,sBAAsB,CAAA;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,qBAAqB,CAAA;IACrC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,qBA0O1D"}
1
+ {"version":3,"file":"dynamic-crud-page.d.ts","sourceRoot":"","sources":["../src/dynamic-crud-page.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAKN,MAAM,OAAO,CAAA;AAad,OAAO,KAAK,EAAE,qBAAqB,EAAiB,MAAM,SAAS,CAAA;AAEnE,MAAM,WAAW,sBAAsB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;mDAC+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AASD,MAAM,WAAW,sBAAsB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,oBAAoB;IACjC,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,sBAAsB,CAAA;IAC7B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC9B,8DAA8D;IAC9D,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC/B,sDAAsD;IACtD,OAAO,CAAC,EAAE,sBAAsB,CAAA;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,qBAAqB,CAAA;IACrC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B;;;;OAIG;IACH,aAAa,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAC1E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,qBA6O1D"}