@asteby/metacore-runtime-react 48.0.0 → 49.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 +41 -0
- package/dist/action-modal-dispatcher.d.ts +33 -3
- package/dist/action-modal-dispatcher.d.ts.map +1 -1
- package/dist/action-modal-dispatcher.js +84 -11
- package/dist/action-priority.d.ts +34 -0
- package/dist/action-priority.d.ts.map +1 -0
- package/dist/action-priority.js +60 -0
- package/dist/business/catalog-product-search.d.ts +7 -0
- package/dist/business/catalog-product-search.d.ts.map +1 -1
- package/dist/business/catalog-product-search.js +14 -0
- package/dist/business/document-editor-model.d.ts +14 -2
- package/dist/business/document-editor-model.d.ts.map +1 -1
- package/dist/business/document-editor-model.js +42 -4
- package/dist/business/document-editor.d.ts.map +1 -1
- package/dist/business/document-editor.js +68 -19
- package/dist/business/line-items.d.ts +9 -1
- package/dist/business/line-items.d.ts.map +1 -1
- package/dist/business/line-items.js +8 -1
- package/dist/calendar-date.d.ts +12 -0
- package/dist/calendar-date.d.ts.map +1 -1
- package/dist/calendar-date.js +36 -0
- package/dist/document/document-page.d.ts.map +1 -1
- package/dist/document/document-page.js +8 -1
- package/dist/document/evaluate.d.ts.map +1 -1
- package/dist/document/evaluate.js +17 -1
- package/dist/document/index.d.ts +1 -0
- package/dist/document/index.d.ts.map +1 -1
- package/dist/document/index.js +1 -0
- package/dist/document/secondary-bar.d.ts +20 -0
- package/dist/document/secondary-bar.d.ts.map +1 -0
- package/dist/document/secondary-bar.js +44 -0
- package/dist/document/types.d.ts +8 -0
- package/dist/document/types.d.ts.map +1 -1
- package/dist/document-form-dialog.d.ts +23 -2
- package/dist/document-form-dialog.d.ts.map +1 -1
- package/dist/document-form-dialog.js +48 -9
- package/dist/dynamic-columns.d.ts +1 -11
- package/dist/dynamic-columns.d.ts.map +1 -1
- package/dist/dynamic-columns.js +7 -17
- package/dist/dynamic-crud-page.d.ts +19 -0
- package/dist/dynamic-crud-page.d.ts.map +1 -1
- package/dist/dynamic-crud-page.js +6 -5
- package/dist/dynamic-row-actions.d.ts +8 -0
- package/dist/dynamic-row-actions.d.ts.map +1 -1
- package/dist/dynamic-row-actions.js +12 -2
- package/dist/dynamic-table.d.ts.map +1 -1
- package/dist/dynamic-table.js +64 -63
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/primitives/contributions.d.ts +14 -3
- package/dist/primitives/contributions.d.ts.map +1 -1
- package/dist/primitives/contributions.js +50 -13
- package/dist/record-actions.d.ts +21 -0
- package/dist/record-actions.d.ts.map +1 -0
- package/dist/record-actions.js +76 -0
- package/dist/row-actions-menu.d.ts +32 -0
- package/dist/row-actions-menu.d.ts.map +1 -0
- package/dist/row-actions-menu.js +59 -0
- package/dist/slot.d.ts +4 -21
- package/dist/slot.d.ts.map +1 -1
- package/dist/slot.js +14 -36
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/document-editor-model.test.ts +55 -1
- package/src/__tests__/document-editor.test.tsx +80 -1
- package/src/__tests__/document-form-create-model.test.tsx +143 -0
- package/src/__tests__/document-form-dialog.test.tsx +40 -0
- package/src/__tests__/field-default-today.test.tsx +116 -0
- package/src/__tests__/prefill-scalar-from-record.test.ts +52 -1
- package/src/__tests__/row-action-link-navigation.test.ts +17 -0
- package/src/__tests__/secondary-actions.test.tsx +261 -0
- package/src/action-modal-dispatcher.tsx +97 -17
- package/src/action-priority.ts +82 -0
- package/src/business/business.test.ts +1 -1
- package/src/business/catalog-product-search.ts +18 -0
- package/src/business/document-editor-model.ts +48 -6
- package/src/business/document-editor.tsx +75 -20
- package/src/business/line-items.ts +16 -1
- package/src/calendar-date.ts +36 -0
- package/src/document/document-page.tsx +15 -0
- package/src/document/evaluate.ts +17 -1
- package/src/document/index.ts +1 -0
- package/src/document/secondary-bar.tsx +92 -0
- package/src/document/types.ts +8 -0
- package/src/document-form-dialog.tsx +67 -8
- package/src/dynamic-columns.tsx +13 -57
- package/src/dynamic-crud-page.tsx +31 -4
- package/src/dynamic-row-actions.tsx +12 -2
- package/src/dynamic-table.tsx +3 -0
- package/src/index.ts +31 -0
- package/src/primitives/contributions.ts +59 -12
- package/src/record-actions.ts +101 -0
- package/src/row-actions-menu.tsx +159 -0
- package/src/slot.tsx +18 -53
- package/src/types.ts +35 -0
|
@@ -24,14 +24,14 @@ import { Button } from '@asteby/metacore-ui/primitives';
|
|
|
24
24
|
import { Loader2 } from 'lucide-react';
|
|
25
25
|
import { toast } from 'sonner';
|
|
26
26
|
import { useApi } from '../api-context';
|
|
27
|
-
import { useOrgTaxRate } from '../org-runtime-context';
|
|
27
|
+
import { useOrgTaxRate, useTimeZone } from '../org-runtime-context';
|
|
28
28
|
import { FieldCell, FieldGrid, FieldLabel } from '../field-grid';
|
|
29
29
|
import { FormErrorBanner } from './feedback';
|
|
30
30
|
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';
|
|
@@ -50,13 +50,14 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
|
|
|
50
50
|
const fmt = useFormatter({ currency });
|
|
51
51
|
const installed = useInstalledAddons();
|
|
52
52
|
const orgTaxRate = useOrgTaxRate();
|
|
53
|
+
const orgTimeZone = useTimeZone();
|
|
53
54
|
const tl = useCallback((s) => t(s, { defaultValue: s }), [t]);
|
|
54
55
|
const lineCfg = useMemo(() => editorLinesConfig(type, forms), [type, forms]);
|
|
55
56
|
const kind = lineCfg?.kind ?? 'sale';
|
|
56
57
|
const isAllocation = kind === 'allocation' && !!lineCfg?.open_documents;
|
|
57
58
|
const amountKey = isAllocation ? allocationAmountField(type.fields) : undefined;
|
|
58
59
|
const [header, setHeader] = useState(() => ({
|
|
59
|
-
...buildFieldDefaults(type.fields, record),
|
|
60
|
+
...buildFieldDefaults(type.fields, record, undefined, { timeZone: orgTimeZone, now: today }),
|
|
60
61
|
...(type.defaults ?? {}),
|
|
61
62
|
}));
|
|
62
63
|
const [lines, setLines] = useState([]);
|
|
@@ -78,6 +79,10 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
|
|
|
78
79
|
const [attempted, setAttempted] = useState(false);
|
|
79
80
|
const [sourceKey, setSourceKey] = useState(initialSource?.key ?? '');
|
|
80
81
|
const [sourceId, setSourceId] = useState(initialSource?.id ?? '');
|
|
82
|
+
// Fuente de la que salieron los renglones: su `line_link_field` viaja en cada
|
|
83
|
+
// renglón para que el servidor descuente lo ya facturado/devuelto y valide.
|
|
84
|
+
const [loadedSource, setLoadedSource] = useState(null);
|
|
85
|
+
const [sourceNote, setSourceNote] = useState();
|
|
81
86
|
const relCache = useRef(new Map());
|
|
82
87
|
const taxRate = defaultTaxRate ?? orgTaxRate;
|
|
83
88
|
const search = useMemo(() => searchProducts ?? createCatalogProductSearch(api, { model: productModel, defaultTaxRate: taxRate }), [searchProducts, api, productModel, taxRate]);
|
|
@@ -188,10 +193,13 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
|
|
|
188
193
|
if (forms.type_field && !type.submit_action)
|
|
189
194
|
p[forms.type_field] = type.value ?? type.key;
|
|
190
195
|
if (lineCfg) {
|
|
191
|
-
p[lineCfg.field] =
|
|
196
|
+
p[lineCfg.field] =
|
|
197
|
+
isAllocation && openCfg
|
|
198
|
+
? allocationPayload(allocation.allocations, openCfg)
|
|
199
|
+
: serializeLineItems(lines, { sourceLineField: loadedSource?.line_link_field });
|
|
192
200
|
}
|
|
193
201
|
return p;
|
|
194
|
-
}, [type, header, forms.type_field, lineCfg, isAllocation, openCfg, allocation, lines]);
|
|
202
|
+
}, [type, header, forms.type_field, lineCfg, isAllocation, openCfg, allocation, lines, loadedSource]);
|
|
195
203
|
const baseUrl = type.endpoint ?? endpoint ?? `/dynamic/${model}`;
|
|
196
204
|
/** Crea o actualiza el BORRADOR (idempotente por draftId). La vista previa lo necesita. */
|
|
197
205
|
const saveDraft = useCallback(async () => {
|
|
@@ -219,25 +227,66 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
|
|
|
219
227
|
}
|
|
220
228
|
};
|
|
221
229
|
// ---- Cargar desde… --------------------------------------------------------
|
|
230
|
+
/**
|
|
231
|
+
* Renglones del origen. Con lo pendiente declarado (`line_link_field`,
|
|
232
|
+
* `remaining_qty_field` o `remaining_endpoint`) los sirve el host ya con
|
|
233
|
+
* `remaining_quantity` (cantidad − lo ya facturado/devuelto, calculado en el
|
|
234
|
+
* servidor); si el host aún no tiene `source-lines` (404) o la fuente no lo
|
|
235
|
+
* declara, se leen de la relación como antes.
|
|
236
|
+
*/
|
|
237
|
+
const fetchSourceRows = useCallback(async (src, id) => {
|
|
238
|
+
if (src.remaining_endpoint) {
|
|
239
|
+
const res = await api.get(src.remaining_endpoint, { params: { id } });
|
|
240
|
+
return res?.data?.data ?? [];
|
|
241
|
+
}
|
|
242
|
+
if (sourceTracksRemaining(src)) {
|
|
243
|
+
try {
|
|
244
|
+
const res = await api.get(`${baseUrl}/source-lines`, {
|
|
245
|
+
params: { source: src.key, id, ...(draftId ? { exclude: draftId } : {}) },
|
|
246
|
+
});
|
|
247
|
+
return res?.data?.data ?? [];
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
if (err?.response?.status !== 404)
|
|
251
|
+
throw err;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
let rels = relCache.current.get(src.model);
|
|
255
|
+
if (!rels) {
|
|
256
|
+
rels = api
|
|
257
|
+
.get(`/metadata/table/${src.model}`)
|
|
258
|
+
.then((r) => r?.data?.data?.relations ?? r?.data?.relations ?? []);
|
|
259
|
+
relCache.current.set(src.model, rels);
|
|
260
|
+
}
|
|
261
|
+
const call = prefillFromFieldRelationRequest({ fieldKey: lineCfg?.field ?? 'lines', refModel: src.model, refId: id, spec: { $prefillFromRecord: src.lines } }, await rels);
|
|
262
|
+
if (!call)
|
|
263
|
+
throw new Error(`${src.model}: falta la relación «${src.lines}»`);
|
|
264
|
+
const res = await api.get(call.endpoint, { params: call.params });
|
|
265
|
+
return res?.data?.data ?? [];
|
|
266
|
+
}, [api, baseUrl, draftId, lineCfg?.field]);
|
|
222
267
|
const loadFromSource = useCallback(async (src, id) => {
|
|
223
268
|
if (!lineCfg || !id)
|
|
224
269
|
return;
|
|
225
270
|
setBusy('source');
|
|
226
271
|
try {
|
|
227
272
|
if (!isAllocation) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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 }));
|
|
273
|
+
const rows = await fetchSourceRows(src, id);
|
|
274
|
+
const loaded = linesFromSource(rows, src.map, { kind, discountMode: lineCfg.discount_mode });
|
|
275
|
+
const { covered } = sourceLoadSummary(rows);
|
|
276
|
+
setLines(loaded);
|
|
277
|
+
setLoadedSource(src);
|
|
240
278
|
setLinesFromSourceDoc(kind === 'credit');
|
|
279
|
+
setSourceNote(loaded.length === 0 && covered > 0
|
|
280
|
+
? t('documentEditor.source_all_covered', {
|
|
281
|
+
defaultValue: 'Todo el documento ya está registrado en otros documentos; no queda nada pendiente.',
|
|
282
|
+
})
|
|
283
|
+
: covered > 0
|
|
284
|
+
? t('documentEditor.source_loaded_partial', {
|
|
285
|
+
defaultValue: '{{count}} renglones con lo pendiente · {{covered}} ya cubiertos se omitieron',
|
|
286
|
+
count: loaded.length,
|
|
287
|
+
covered,
|
|
288
|
+
})
|
|
289
|
+
: t('documentEditor.source_loaded', { defaultValue: '{{count}} renglones cargados', count: loaded.length }));
|
|
241
290
|
}
|
|
242
291
|
if (src.header || src.link_field) {
|
|
243
292
|
const h = await api.get(`/data/${src.model}`, { params: { f_id: `eq:${id}`, per_page: 1 } });
|
|
@@ -262,7 +311,7 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
|
|
|
262
311
|
finally {
|
|
263
312
|
setBusy(null);
|
|
264
313
|
}
|
|
265
|
-
}, [api, lineCfg, isAllocation, kind, t]);
|
|
314
|
+
}, [api, lineCfg, isAllocation, kind, t, fetchSourceRows]);
|
|
266
315
|
// Prefill al abrir desde un documento origen (acción de fila «Crear NC», «Facturar venta»…).
|
|
267
316
|
const autoLoaded = useRef(false);
|
|
268
317
|
useEffect(() => {
|
|
@@ -417,7 +466,7 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
|
|
|
417
466
|
: isAllocation
|
|
418
467
|
? t('documentEditor.allocation_title', { defaultValue: 'Documentos a pagar' })
|
|
419
468
|
: 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…' }) :
|
|
469
|
+
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
470
|
setSourceKey(e.target.value);
|
|
422
471
|
setSourceId('');
|
|
423
472
|
}, 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[]
|
|
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":"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"}
|
|
@@ -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
|
});
|
package/dist/calendar-date.d.ts
CHANGED
|
@@ -9,4 +9,16 @@ export declare function parseCalendarDate(v: unknown): Date | undefined;
|
|
|
9
9
|
* Mexico City = 30 Sep 00:41Z) shows as the 30th (PIT-025).
|
|
10
10
|
*/
|
|
11
11
|
export declare function isCalendarDayValue(v: unknown): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Today's calendar day ("YYYY-MM-DD") in `timeZone` (IANA, e.g. the org's
|
|
14
|
+
* `America/Mexico_City`), or in the browser zone when absent/invalid. A form
|
|
15
|
+
* that seeds «hoy» must use the org's day, not UTC's: at 19:00 in Mexico City
|
|
16
|
+
* UTC is already tomorrow.
|
|
17
|
+
*/
|
|
18
|
+
export declare function todayInZone(timeZone?: string, now?: Date): string;
|
|
19
|
+
/**
|
|
20
|
+
* A field default that names «today» instead of a fixed day: `$today` (the
|
|
21
|
+
* token flows already use) or `today`. Case-insensitive.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isTodayToken(v: unknown): boolean;
|
|
12
24
|
//# sourceMappingURL=calendar-date.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar-date.d.ts","sourceRoot":"","sources":["../src/calendar-date.ts"],"names":[],"mappings":"AAKA;2DAC2D;AAC3D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAQ9D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAGtD"}
|
|
1
|
+
{"version":3,"file":"calendar-date.d.ts","sourceRoot":"","sources":["../src/calendar-date.ts"],"names":[],"mappings":"AAKA;2DAC2D;AAC3D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAQ9D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAGtD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,IAAiB,GAAG,MAAM,CAkB7E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAIhD"}
|
package/dist/calendar-date.js
CHANGED
|
@@ -28,3 +28,39 @@ export function isCalendarDayValue(v) {
|
|
|
28
28
|
return false;
|
|
29
29
|
return /^\d{4}-\d{2}-\d{2}(?:[T ]00:00:00(?:\.0+)?(?:Z|\+00:00)?)?$/.test(v.trim());
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Today's calendar day ("YYYY-MM-DD") in `timeZone` (IANA, e.g. the org's
|
|
33
|
+
* `America/Mexico_City`), or in the browser zone when absent/invalid. A form
|
|
34
|
+
* that seeds «hoy» must use the org's day, not UTC's: at 19:00 in Mexico City
|
|
35
|
+
* UTC is already tomorrow.
|
|
36
|
+
*/
|
|
37
|
+
export function todayInZone(timeZone, now = new Date()) {
|
|
38
|
+
if (timeZone) {
|
|
39
|
+
try {
|
|
40
|
+
// en-CA formats as YYYY-MM-DD.
|
|
41
|
+
return new Intl.DateTimeFormat('en-CA', {
|
|
42
|
+
timeZone,
|
|
43
|
+
year: 'numeric',
|
|
44
|
+
month: '2-digit',
|
|
45
|
+
day: '2-digit',
|
|
46
|
+
}).format(now);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
/* unknown zone → browser day */
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const y = now.getFullYear();
|
|
53
|
+
const m = String(now.getMonth() + 1).padStart(2, '0');
|
|
54
|
+
const d = String(now.getDate()).padStart(2, '0');
|
|
55
|
+
return `${y}-${m}-${d}`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A field default that names «today» instead of a fixed day: `$today` (the
|
|
59
|
+
* token flows already use) or `today`. Case-insensitive.
|
|
60
|
+
*/
|
|
61
|
+
export function isTodayToken(v) {
|
|
62
|
+
if (typeof v !== 'string')
|
|
63
|
+
return false;
|
|
64
|
+
const s = v.trim().toLowerCase();
|
|
65
|
+
return s === '$today' || s === 'today';
|
|
66
|
+
}
|
|
@@ -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;
|
|
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":"
|
|
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) {
|
package/dist/document/index.d.ts
CHANGED
|
@@ -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"}
|
package/dist/document/index.js
CHANGED
|
@@ -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
|
+
}
|
package/dist/document/types.d.ts
CHANGED
|
@@ -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,5 +1,5 @@
|
|
|
1
1
|
import { type DocumentLinesGridProps } from './business/line-items-editor';
|
|
2
|
-
import type { DocumentFormsManifest, TableMetadata } from './types';
|
|
2
|
+
import type { DocumentFormType, DocumentFormsManifest, TableMetadata } from './types';
|
|
3
3
|
export interface DocumentFormDialogProps {
|
|
4
4
|
open: boolean;
|
|
5
5
|
onOpenChange: (open: boolean) => void;
|
|
@@ -33,7 +33,28 @@ export interface DocumentFormDialogProps {
|
|
|
33
33
|
key: string;
|
|
34
34
|
id: string;
|
|
35
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Tipo con `create_model`: el alta vive en otro modelo. El host navega a la
|
|
38
|
+
* página de ese modelo con su alta abierta; el diálogo se cierra sin pintar
|
|
39
|
+
* formulario. Sin este callback un tipo delegado no se ofrece.
|
|
40
|
+
*/
|
|
41
|
+
onDelegateCreate?: (target: DelegatedCreate) => void;
|
|
42
|
+
}
|
|
43
|
+
/** Alta delegada a otro modelo (`document_forms.types[].create_model`). */
|
|
44
|
+
export interface DelegatedCreate {
|
|
45
|
+
/** Clave del modelo destino tal como la declara el manifest (`customers.Invoice`). */
|
|
46
|
+
model: string;
|
|
47
|
+
/** Tipo que la declaró. */
|
|
48
|
+
type: DocumentFormType;
|
|
36
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Si «Crear» de estos formularios es un alta delegada: un único tipo (p. ej.
|
|
52
|
+
* ya acotado por el filtro de la vista) con `create_model`. Con varios tipos el
|
|
53
|
+
* selector la ofrece como una tarjeta más.
|
|
54
|
+
*/
|
|
55
|
+
export declare function delegatedCreate(forms: DocumentFormsManifest | undefined): DelegatedCreate | undefined;
|
|
56
|
+
/** Quita los tipos delegados cuando el host no sabe navegar a otro modelo. */
|
|
57
|
+
export declare function withoutDelegatedTypes(forms: DocumentFormsManifest | undefined): DocumentFormsManifest | undefined;
|
|
37
58
|
/** Manifest efectivo: la prop gana sobre el metadata; sin tipos devuelve undefined. */
|
|
38
59
|
export declare function resolveDocumentForms(metadata?: Pick<TableMetadata, 'document_forms'> | null, override?: DocumentFormsManifest | null): DocumentFormsManifest | undefined;
|
|
39
60
|
/**
|
|
@@ -48,5 +69,5 @@ export declare function scopeDocumentFormsToFilter(forms: DocumentFormsManifest
|
|
|
48
69
|
forms: DocumentFormsManifest | undefined;
|
|
49
70
|
hideCreate: boolean;
|
|
50
71
|
};
|
|
51
|
-
export declare function DocumentFormDialog({ open, onOpenChange, model, endpoint, forms, initialType, onSaved, searchProducts, productModel, defaultTaxRate, currency, record, initialSource, }: DocumentFormDialogProps): import("react").JSX.Element;
|
|
72
|
+
export declare function DocumentFormDialog({ open, onOpenChange, model, endpoint, forms, initialType, onSaved, searchProducts, productModel, defaultTaxRate, currency, record, initialSource, onDelegateCreate, }: DocumentFormDialogProps): import("react").JSX.Element | null;
|
|
52
73
|
//# sourceMappingURL=document-form-dialog.d.ts.map
|
|
@@ -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;
|
|
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,gBAAgB,EAChB,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;IAC3C;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAA;CACvD;AAED,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC5B,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,IAAI,EAAE,gBAAgB,CAAA;CACzB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GAAG,eAAe,GAAG,SAAS,CAIrG;AAED,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GAAG,qBAAqB,GAAG,SAAS,CAKjH;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,EACb,gBAAgB,GACnB,EAAE,uBAAuB,sCAwUzB"}
|