@asteby/metacore-runtime-react 46.3.0 → 47.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.
- package/CHANGELOG.md +31 -0
- package/dist/action-modal-dispatcher.d.ts +10 -1
- package/dist/action-modal-dispatcher.d.ts.map +1 -1
- package/dist/action-modal-dispatcher.js +107 -19
- package/dist/business/catalog.d.ts.map +1 -1
- package/dist/business/catalog.js +24 -0
- package/dist/business/index.d.ts +3 -0
- package/dist/business/index.d.ts.map +1 -1
- package/dist/business/index.js +3 -0
- package/dist/business/print-send-dialog.d.ts +27 -0
- package/dist/business/print-send-dialog.d.ts.map +1 -0
- package/dist/business/print-send-dialog.js +55 -0
- package/dist/business/relate-documents.d.ts +41 -0
- package/dist/business/relate-documents.d.ts.map +1 -0
- package/dist/business/relate-documents.js +42 -0
- package/dist/business/vehicle-picker.d.ts +36 -0
- package/dist/business/vehicle-picker.d.ts.map +1 -0
- package/dist/business/vehicle-picker.js +61 -0
- package/dist/cfdi-stamp-panel.d.ts +29 -0
- package/dist/cfdi-stamp-panel.d.ts.map +1 -0
- package/dist/cfdi-stamp-panel.js +53 -0
- package/dist/dialogs/dynamic-record.d.ts.map +1 -1
- package/dist/dialogs/dynamic-record.js +5 -0
- package/dist/document-form-dialog.d.ts +23 -0
- package/dist/document-form-dialog.d.ts.map +1 -0
- package/dist/document-form-dialog.js +196 -0
- package/dist/dynamic-crud-page.d.ts +6 -0
- package/dist/dynamic-crud-page.d.ts.map +1 -1
- package/dist/dynamic-crud-page.js +17 -7
- package/dist/dynamic-kanban.d.ts.map +1 -1
- package/dist/dynamic-kanban.js +3 -1
- package/dist/dynamic-table.d.ts.map +1 -1
- package/dist/dynamic-table.js +6 -2
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/list-primary-action.d.ts +31 -0
- package/dist/list-primary-action.d.ts.map +1 -0
- package/dist/list-primary-action.js +35 -0
- package/dist/model-action-toolbar.d.ts +7 -1
- package/dist/model-action-toolbar.d.ts.map +1 -1
- package/dist/model-action-toolbar.js +10 -3
- package/dist/model-extension-registry.d.ts +7 -0
- package/dist/model-extension-registry.d.ts.map +1 -1
- package/dist/nav-permissions.d.ts +19 -0
- package/dist/nav-permissions.d.ts.map +1 -0
- package/dist/nav-permissions.js +51 -0
- package/dist/navigation-builder.d.ts +6 -0
- package/dist/navigation-builder.d.ts.map +1 -1
- package/dist/navigation-builder.js +26 -1
- package/dist/permissions-manager.d.ts +9 -0
- package/dist/permissions-manager.d.ts.map +1 -1
- package/dist/permissions-manager.js +50 -17
- package/dist/print-document-button.d.ts.map +1 -1
- package/dist/print-document-button.js +9 -1
- package/dist/record-mutation-events.d.ts +14 -0
- package/dist/record-mutation-events.d.ts.map +1 -0
- package/dist/record-mutation-events.js +37 -0
- package/dist/types.d.ts +60 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/use-print-document.d.ts +15 -1
- package/dist/use-print-document.d.ts.map +1 -1
- package/dist/use-print-document.js +52 -1
- package/dist/use-record-mutation-tick.d.ts +6 -0
- package/dist/use-record-mutation-tick.d.ts.map +1 -0
- package/dist/use-record-mutation-tick.js +11 -0
- package/package.json +3 -3
- package/src/__tests__/action-modal-feedback.test.tsx +116 -0
- package/src/__tests__/business-pickers.test.tsx +157 -0
- package/src/__tests__/document-form-dialog.test.tsx +190 -0
- package/src/__tests__/dynamic-table-mutation-refresh.test.tsx +116 -0
- package/src/__tests__/list-primary-action.test.tsx +157 -0
- package/src/__tests__/nav-permissions.test.tsx +76 -0
- package/src/__tests__/permissions-manager.test.tsx +21 -4
- package/src/__tests__/use-print-document-feedback.test.tsx +58 -0
- package/src/action-modal-dispatcher.tsx +124 -6
- package/src/business/catalog.ts +24 -0
- package/src/business/index.ts +3 -0
- package/src/business/print-send-dialog.tsx +175 -0
- package/src/business/relate-documents.tsx +182 -0
- package/src/business/vehicle-picker.tsx +188 -0
- package/src/cfdi-stamp-panel.tsx +146 -0
- package/src/dialogs/dynamic-record.tsx +5 -0
- package/src/document-form-dialog.tsx +357 -0
- package/src/dynamic-crud-page.tsx +36 -7
- package/src/dynamic-kanban.tsx +3 -1
- package/src/dynamic-table.tsx +6 -2
- package/src/index.ts +36 -0
- package/src/list-primary-action.ts +71 -0
- package/src/model-action-toolbar.tsx +18 -3
- package/src/model-extension-registry.tsx +7 -0
- package/src/nav-permissions.ts +58 -0
- package/src/navigation-builder.tsx +27 -1
- package/src/permissions-manager.tsx +39 -26
- package/src/print-document-button.tsx +9 -1
- package/src/record-mutation-events.ts +50 -0
- package/src/types.ts +63 -0
- package/src/use-print-document.ts +66 -3
- package/src/use-record-mutation-tick.ts +12 -0
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
// The ApiClient is a PEER via <ApiProvider> (same one useAddonSettings uses), so
|
|
18
18
|
// this hook constructs no client of its own.
|
|
19
19
|
import { useCallback } from 'react'
|
|
20
|
+
import { toast } from 'sonner'
|
|
20
21
|
import { useApi } from './api-context'
|
|
21
22
|
|
|
22
23
|
export interface PrintDocumentArgs {
|
|
@@ -40,6 +41,42 @@ export interface PrintDocumentArgs {
|
|
|
40
41
|
* that is how downloads end up literally named with mustache braces.
|
|
41
42
|
*/
|
|
42
43
|
filename?: string
|
|
44
|
+
/**
|
|
45
|
+
* User feedback. Default: a toast while the file is prepared, a success toast
|
|
46
|
+
* when it is ready and an error toast with the server's reason when it fails
|
|
47
|
+
* (a download used to give NO sign of life — PIT «Descargar Factura CFDI»).
|
|
48
|
+
* `false` silences all of it; `{ error: false }` leaves errors to the caller
|
|
49
|
+
* (the promise still rejects either way).
|
|
50
|
+
*/
|
|
51
|
+
feedback?: boolean | { progress?: boolean; success?: boolean; error?: boolean }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const noun = (mode: 'print' | 'download' | 'open') =>
|
|
55
|
+
mode === 'download' ? 'Descargando documento…' : mode === 'open' ? 'Abriendo documento…' : 'Preparando impresión…'
|
|
56
|
+
|
|
57
|
+
const readyMessage = (mode: 'print' | 'download' | 'open') =>
|
|
58
|
+
mode === 'download' ? 'Documento descargado' : mode === 'open' ? 'Documento abierto' : 'Documento listo para imprimir'
|
|
59
|
+
|
|
60
|
+
/** Best-effort message from an error whose body is a Blob (responseType: 'blob'). */
|
|
61
|
+
export async function documentErrorMessage(err: unknown): Promise<string> {
|
|
62
|
+
const fallback = 'No se pudo generar el documento. Inténtalo de nuevo.'
|
|
63
|
+
const e = err as { response?: { data?: unknown; status?: number }; message?: unknown } | undefined
|
|
64
|
+
let data = e?.response?.data
|
|
65
|
+
try {
|
|
66
|
+
if (typeof Blob !== 'undefined' && data instanceof Blob) {
|
|
67
|
+
data = JSON.parse(await data.text())
|
|
68
|
+
}
|
|
69
|
+
} catch {
|
|
70
|
+
data = undefined
|
|
71
|
+
}
|
|
72
|
+
const d = data as { message?: unknown; details?: unknown; error?: unknown } | string | undefined
|
|
73
|
+
if (typeof d === 'string' && d.trim()) return d.trim().slice(0, 200)
|
|
74
|
+
if (d && typeof d === 'object') {
|
|
75
|
+
const msg = [d.message, d.details, d.error].find((x) => typeof x === 'string' && x.trim()) as string | undefined
|
|
76
|
+
if (msg) return msg.trim()
|
|
77
|
+
}
|
|
78
|
+
if (e?.response?.status === 404) return 'El documento no está disponible todavía.'
|
|
79
|
+
return fallback
|
|
43
80
|
}
|
|
44
81
|
|
|
45
82
|
/** Parse filename from Content-Disposition (RFC 5987 / quoted). */
|
|
@@ -71,14 +108,14 @@ export function looksLikeFilenameTemplate(name: string | undefined): boolean {
|
|
|
71
108
|
*/
|
|
72
109
|
export function usePrintDocument() {
|
|
73
110
|
const api = useApi()
|
|
74
|
-
|
|
111
|
+
const run = useCallback(
|
|
75
112
|
async ({
|
|
76
113
|
model,
|
|
77
114
|
id,
|
|
78
115
|
key,
|
|
79
|
-
mode
|
|
116
|
+
mode,
|
|
80
117
|
filename,
|
|
81
|
-
}: PrintDocumentArgs): Promise<string> => {
|
|
118
|
+
}: Required<Pick<PrintDocumentArgs, 'model' | 'id' | 'key' | 'mode'>> & Pick<PrintDocumentArgs, 'filename'>): Promise<string> => {
|
|
82
119
|
const url = `/data/${encodeURIComponent(model)}/${encodeURIComponent(
|
|
83
120
|
id,
|
|
84
121
|
)}/documents/${encodeURIComponent(key)}.pdf`
|
|
@@ -145,4 +182,30 @@ export function usePrintDocument() {
|
|
|
145
182
|
},
|
|
146
183
|
[api],
|
|
147
184
|
)
|
|
185
|
+
return useCallback(
|
|
186
|
+
async ({
|
|
187
|
+
model,
|
|
188
|
+
id,
|
|
189
|
+
key,
|
|
190
|
+
mode = 'print',
|
|
191
|
+
filename,
|
|
192
|
+
feedback = true,
|
|
193
|
+
}: PrintDocumentArgs): Promise<string> => {
|
|
194
|
+
const fb = feedback === false ? {} : feedback === true ? { progress: true, success: true, error: true } : feedback
|
|
195
|
+
const toastId = fb.progress ? toast.loading(noun(mode)) : undefined
|
|
196
|
+
try {
|
|
197
|
+
const blobUrl = await run({ model, id, key, mode, filename })
|
|
198
|
+
if (toastId !== undefined) toast.dismiss(toastId)
|
|
199
|
+
if (fb.success) toast.success(readyMessage(mode))
|
|
200
|
+
return blobUrl
|
|
201
|
+
} catch (err) {
|
|
202
|
+
if (toastId !== undefined) toast.dismiss(toastId)
|
|
203
|
+
if (fb.error) toast.error(await documentErrorMessage(err))
|
|
204
|
+
throw err
|
|
205
|
+
} finally {
|
|
206
|
+
if (toastId !== undefined) toast.dismiss(toastId)
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
[run],
|
|
210
|
+
)
|
|
148
211
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
import { subscribeRecordMutations } from './record-mutation-events'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A counter that increments whenever a record of `model` is created, updated
|
|
6
|
+
* or deleted anywhere in the app. Fold it into a list's refetch deps.
|
|
7
|
+
*/
|
|
8
|
+
export function useRecordMutationTick(model: string | undefined | null): number {
|
|
9
|
+
const [tick, setTick] = useState(0)
|
|
10
|
+
useEffect(() => subscribeRecordMutations(model, () => setTick((n) => n + 1)), [model])
|
|
11
|
+
return tick
|
|
12
|
+
}
|