@asteby/metacore-runtime-react 30.0.6 → 31.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 +13 -0
- package/dist/document-template-editor.d.ts +11 -0
- package/dist/document-template-editor.d.ts.map +1 -0
- package/dist/document-template-editor.js +87 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/use-org-document-templates.d.ts +71 -0
- package/dist/use-org-document-templates.d.ts.map +1 -0
- package/dist/use-org-document-templates.js +147 -0
- package/package.json +3 -3
- package/src/document-template-editor.tsx +143 -0
- package/src/index.ts +2 -0
- package/src/use-org-document-templates.ts +214 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @asteby/metacore-runtime-react
|
|
2
2
|
|
|
3
|
+
## 31.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 50c832f: Plantillas: hooks y editor para el overlay HTML por organización de documents[] del addon.
|
|
8
|
+
|
|
9
|
+
## 31.0.0
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [d122ae0]
|
|
14
|
+
- @asteby/metacore-ui@2.15.0
|
|
15
|
+
|
|
3
16
|
## 30.0.6
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface DocumentTemplateEditorProps {
|
|
2
|
+
addonKey: string;
|
|
3
|
+
documentKey: string;
|
|
4
|
+
/** Called after a successful save or reset. */
|
|
5
|
+
onSaved?: () => void;
|
|
6
|
+
onError?: (err: unknown) => void;
|
|
7
|
+
className?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function DocumentTemplateEditor({ addonKey, documentKey, onSaved, onError, className, disabled, }: DocumentTemplateEditorProps): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=document-template-editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-template-editor.d.ts","sourceRoot":"","sources":["../src/document-template-editor.tsx"],"names":[],"mappings":"AAYA,MAAM,WAAW,2BAA2B;IACxC,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,sBAAsB,CAAC,EACnC,QAAQ,EACR,WAAW,EACX,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,GACX,EAAE,2BAA2B,+BAiH7B"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// DocumentTemplateEditor — textarea + preview/save/reset for one org overlay
|
|
3
|
+
// of an addon document. Headless-friendly: plain buttons + textarea, styled via
|
|
4
|
+
// className. Host surfaces (ops Plantillas) can wrap this or roll their own
|
|
5
|
+
// using the hooks in use-org-document-templates.
|
|
6
|
+
import { useEffect, useState } from 'react';
|
|
7
|
+
import { useOrgDocumentTemplate, usePreviewOrgDocumentTemplate, useResetOrgDocumentTemplate, useSaveOrgDocumentTemplate, } from './use-org-document-templates';
|
|
8
|
+
export function DocumentTemplateEditor({ addonKey, documentKey, onSaved, onError, className, disabled, }) {
|
|
9
|
+
const { template, isLoading } = useOrgDocumentTemplate(addonKey, documentKey);
|
|
10
|
+
const save = useSaveOrgDocumentTemplate();
|
|
11
|
+
const reset = useResetOrgDocumentTemplate();
|
|
12
|
+
const preview = usePreviewOrgDocumentTemplate();
|
|
13
|
+
const [html, setHtml] = useState('');
|
|
14
|
+
const [previewUrl, setPreviewUrl] = useState(null);
|
|
15
|
+
const [previewing, setPreviewing] = useState(false);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (template?.html != null)
|
|
18
|
+
setHtml(template.html);
|
|
19
|
+
}, [template?.html]);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
return () => {
|
|
22
|
+
if (previewUrl)
|
|
23
|
+
URL.revokeObjectURL(previewUrl);
|
|
24
|
+
};
|
|
25
|
+
}, [previewUrl]);
|
|
26
|
+
const busy = save.isPending || reset.isPending || previewing || disabled;
|
|
27
|
+
async function onPreview() {
|
|
28
|
+
setPreviewing(true);
|
|
29
|
+
try {
|
|
30
|
+
const url = await preview({
|
|
31
|
+
addonKey,
|
|
32
|
+
documentKey,
|
|
33
|
+
html,
|
|
34
|
+
paper: template?.paper,
|
|
35
|
+
});
|
|
36
|
+
setPreviewUrl((prev) => {
|
|
37
|
+
if (prev)
|
|
38
|
+
URL.revokeObjectURL(prev);
|
|
39
|
+
return url;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
onError?.(err);
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
setPreviewing(false);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function onSave() {
|
|
50
|
+
try {
|
|
51
|
+
await save.mutateAsync({
|
|
52
|
+
addonKey,
|
|
53
|
+
documentKey,
|
|
54
|
+
html,
|
|
55
|
+
paper: template?.paper,
|
|
56
|
+
});
|
|
57
|
+
onSaved?.();
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
onError?.(err);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function onReset() {
|
|
64
|
+
try {
|
|
65
|
+
const detail = await reset.mutateAsync({ addonKey, documentKey });
|
|
66
|
+
setHtml(detail.html);
|
|
67
|
+
onSaved?.();
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
onError?.(err);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (isLoading && !template) {
|
|
74
|
+
return _jsx("p", { className: className, children: "\u2026" });
|
|
75
|
+
}
|
|
76
|
+
return (_jsxs("div", { className: className, children: [_jsx("textarea", { value: html, onChange: (e) => setHtml(e.target.value), disabled: busy, spellCheck: false, rows: 22, style: {
|
|
77
|
+
width: '100%',
|
|
78
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
|
|
79
|
+
fontSize: 12,
|
|
80
|
+
lineHeight: 1.45,
|
|
81
|
+
} }), _jsxs("div", { style: { display: 'flex', gap: 8, marginTop: 12, flexWrap: 'wrap' }, children: [_jsx("button", { type: "button", disabled: busy, onClick: () => void onPreview(), children: previewing ? '…' : 'Vista previa' }), _jsx("button", { type: "button", disabled: busy, onClick: () => void onSave(), children: "Guardar" }), _jsx("button", { type: "button", disabled: busy || !template?.customized, onClick: () => void onReset(), children: "Restaurar default" })] }), previewUrl ? (_jsx("iframe", { title: "Vista previa", src: previewUrl, style: {
|
|
82
|
+
width: '100%',
|
|
83
|
+
height: 480,
|
|
84
|
+
marginTop: 12,
|
|
85
|
+
border: '1px solid #e5e7eb',
|
|
86
|
+
} })) : null] }));
|
|
87
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export * from './api-context';
|
|
|
32
32
|
export * from './use-addon-settings';
|
|
33
33
|
export * from './use-print-document';
|
|
34
34
|
export * from './print-document-button';
|
|
35
|
+
export * from './use-org-document-templates';
|
|
36
|
+
export * from './document-template-editor';
|
|
35
37
|
export * from './metadata-cache';
|
|
36
38
|
export { ADDON_MANIFEST_CHANGED_TYPE, wireHotSwapInvalidation, useManifestHotSwapSubscriber, type AddonManifestChangedMessage, type ManifestHotSwapClient, type WireHotSwapInvalidationOptions, } from './manifest-hotswap-subscriber';
|
|
37
39
|
export { useHotSwapReload, applyHotSwapReload, withVersionParam, clearFederationContainer, shortenHash, type HotSwapReloadStrategy, type HotSwapReloadConfig, type HotSwapReloadAction, type HotSwapReloadDeps, type UseHotSwapReloadResult, } from './hotswap-reload-policy';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,8 @@ export * from './api-context';
|
|
|
37
37
|
export * from './use-addon-settings';
|
|
38
38
|
export * from './use-print-document';
|
|
39
39
|
export * from './print-document-button';
|
|
40
|
+
export * from './use-org-document-templates';
|
|
41
|
+
export * from './document-template-editor';
|
|
40
42
|
export * from './metadata-cache';
|
|
41
43
|
export { ADDON_MANIFEST_CHANGED_TYPE, wireHotSwapInvalidation, useManifestHotSwapSubscriber, } from './manifest-hotswap-subscriber';
|
|
42
44
|
export { useHotSwapReload, applyHotSwapReload, withVersionParam, clearFederationContainer, shortenHash, } from './hotswap-reload-policy';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export interface OrgDocumentCatalogItem {
|
|
2
|
+
addon_key: string;
|
|
3
|
+
addon_name: string;
|
|
4
|
+
document_key: string;
|
|
5
|
+
label: string;
|
|
6
|
+
model: string;
|
|
7
|
+
paper: string;
|
|
8
|
+
filename?: string;
|
|
9
|
+
customized: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface OrgDocumentTemplateDetail extends OrgDocumentCatalogItem {
|
|
12
|
+
html: string;
|
|
13
|
+
default_html: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function orgDocumentCatalogKey(): readonly ["org-document-templates"];
|
|
16
|
+
export declare function orgDocumentTemplateKey(addonKey: string, documentKey: string): readonly ["org-document-templates", string, string];
|
|
17
|
+
export declare function useOrgDocumentCatalog(opts?: {
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
}): {
|
|
20
|
+
items: NoInfer<OrgDocumentCatalogItem[]>;
|
|
21
|
+
isLoading: boolean;
|
|
22
|
+
error: Error | null;
|
|
23
|
+
refetch: () => void;
|
|
24
|
+
};
|
|
25
|
+
export declare function useOrgDocumentTemplate(addonKey: string, documentKey: string, opts?: {
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
}): {
|
|
28
|
+
template: NoInfer<OrgDocumentTemplateDetail> | undefined;
|
|
29
|
+
isLoading: boolean;
|
|
30
|
+
error: Error | null;
|
|
31
|
+
refetch: () => void;
|
|
32
|
+
};
|
|
33
|
+
export declare function useSaveOrgDocumentTemplate(): import("@tanstack/react-query").UseMutationResult<OrgDocumentTemplateDetail, Error, {
|
|
34
|
+
addonKey: string;
|
|
35
|
+
documentKey: string;
|
|
36
|
+
html: string;
|
|
37
|
+
paper?: string;
|
|
38
|
+
}, unknown>;
|
|
39
|
+
export declare function useResetOrgDocumentTemplate(): import("@tanstack/react-query").UseMutationResult<OrgDocumentTemplateDetail, Error, {
|
|
40
|
+
addonKey: string;
|
|
41
|
+
documentKey: string;
|
|
42
|
+
}, unknown>;
|
|
43
|
+
/**
|
|
44
|
+
* Renders a PDF preview of unsaved HTML against dummy record + org branding.
|
|
45
|
+
* Returns a blob URL the caller should revoke.
|
|
46
|
+
*/
|
|
47
|
+
export declare function usePreviewOrgDocumentTemplate(): (args: {
|
|
48
|
+
addonKey: string;
|
|
49
|
+
documentKey: string;
|
|
50
|
+
html: string;
|
|
51
|
+
paper?: string;
|
|
52
|
+
}) => Promise<string>;
|
|
53
|
+
export declare function groupDocumentCatalog(items: OrgDocumentCatalogItem[]): {
|
|
54
|
+
addonKey: string;
|
|
55
|
+
addonName: string;
|
|
56
|
+
documents: OrgDocumentCatalogItem[];
|
|
57
|
+
}[];
|
|
58
|
+
export declare function useGroupedOrgDocumentCatalog(opts?: {
|
|
59
|
+
enabled?: boolean;
|
|
60
|
+
}): {
|
|
61
|
+
groups: {
|
|
62
|
+
addonKey: string;
|
|
63
|
+
addonName: string;
|
|
64
|
+
documents: OrgDocumentCatalogItem[];
|
|
65
|
+
}[];
|
|
66
|
+
items: NoInfer<OrgDocumentCatalogItem[]>;
|
|
67
|
+
isLoading: boolean;
|
|
68
|
+
error: Error | null;
|
|
69
|
+
refetch: () => void;
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=use-org-document-templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-org-document-templates.d.ts","sourceRoot":"","sources":["../src/use-org-document-templates.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,sBAAsB;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,yBAA0B,SAAQ,sBAAsB;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,qBAAqB,wCAEpC;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,uDAE3E;AAQD,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;;;;;EAoBjE;AAED,wBAAgB,sBAAsB,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;;;;;EAsB/B;AAED,wBAAgB,0BAA0B;cAMtB,MAAM;iBAAe,MAAM;UAAQ,MAAM;YAAU,MAAM;YAgB5E;AAED,wBAAgB,2BAA2B;cAMvB,MAAM;iBAAe,MAAM;YAe9C;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,WAGxB;IACT,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,KAAG,OAAO,CAAC,MAAM,CAAC,CAmB1B;AAED,wBAAgB,oBAAoB,CAChC,KAAK,EAAE,sBAAsB,EAAE,GAChC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,sBAAsB,EAAE,CAAA;CAAE,EAAE,CAoBhF;AAED,wBAAgB,4BAA4B,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;;kBAtB1D,MAAM;mBAAa,MAAM;mBAAa,sBAAsB,EAAE;;;;;;EA6B5E"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// useOrgDocumentTemplates — host primitive for the per-org overlay of addon
|
|
2
|
+
// printable documents (Ajustes → Organización → Plantillas).
|
|
3
|
+
//
|
|
4
|
+
// The addon still owns the default HTML in its bundle. The host persists an
|
|
5
|
+
// optional override per (org, addon, document key) and resolves
|
|
6
|
+
// `org overlay → addon default` at PDF render time, so a business can change
|
|
7
|
+
// tickets/PDFs without a new addon version.
|
|
8
|
+
//
|
|
9
|
+
// GET /api/settings/templates
|
|
10
|
+
// GET /api/settings/templates/:addon/:key
|
|
11
|
+
// PUT /api/settings/templates/:addon/:key { html, paper? }
|
|
12
|
+
// DELETE /api/settings/templates/:addon/:key
|
|
13
|
+
// POST /api/settings/templates/preview → application/pdf
|
|
14
|
+
//
|
|
15
|
+
// ApiClient is a PEER via <ApiProvider> (same one usePrintDocument uses).
|
|
16
|
+
import { useCallback, useMemo } from 'react';
|
|
17
|
+
import { useMutation, useQuery, useQueryClient, } from '@tanstack/react-query';
|
|
18
|
+
import { useApi } from './api-context';
|
|
19
|
+
export function orgDocumentCatalogKey() {
|
|
20
|
+
return ['org-document-templates'];
|
|
21
|
+
}
|
|
22
|
+
export function orgDocumentTemplateKey(addonKey, documentKey) {
|
|
23
|
+
return ['org-document-templates', addonKey, documentKey];
|
|
24
|
+
}
|
|
25
|
+
function unwrapData(res) {
|
|
26
|
+
const body = res.data;
|
|
27
|
+
const values = body?.success ? body.data : body;
|
|
28
|
+
return values;
|
|
29
|
+
}
|
|
30
|
+
export function useOrgDocumentCatalog(opts) {
|
|
31
|
+
const api = useApi();
|
|
32
|
+
const query = useQuery({
|
|
33
|
+
queryKey: orgDocumentCatalogKey(),
|
|
34
|
+
queryFn: async () => {
|
|
35
|
+
const res = await api.get('/settings/templates');
|
|
36
|
+
const data = unwrapData(res);
|
|
37
|
+
return Array.isArray(data) ? data : [];
|
|
38
|
+
},
|
|
39
|
+
staleTime: 30_000,
|
|
40
|
+
enabled: opts?.enabled ?? true,
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
items: query.data ?? [],
|
|
44
|
+
isLoading: query.isLoading,
|
|
45
|
+
error: query.error,
|
|
46
|
+
refetch: () => {
|
|
47
|
+
void query.refetch();
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function useOrgDocumentTemplate(addonKey, documentKey, opts) {
|
|
52
|
+
const api = useApi();
|
|
53
|
+
const query = useQuery({
|
|
54
|
+
queryKey: orgDocumentTemplateKey(addonKey, documentKey),
|
|
55
|
+
queryFn: async () => {
|
|
56
|
+
const res = await api.get(`/settings/templates/${encodeURIComponent(addonKey)}/${encodeURIComponent(documentKey)}`);
|
|
57
|
+
return unwrapData(res);
|
|
58
|
+
},
|
|
59
|
+
enabled: (opts?.enabled ?? true) && !!addonKey && !!documentKey,
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
template: query.data,
|
|
63
|
+
isLoading: query.isLoading,
|
|
64
|
+
error: query.error,
|
|
65
|
+
refetch: () => {
|
|
66
|
+
void query.refetch();
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export function useSaveOrgDocumentTemplate() {
|
|
71
|
+
const api = useApi();
|
|
72
|
+
const qc = useQueryClient();
|
|
73
|
+
return useMutation({
|
|
74
|
+
mutationFn: async ({ addonKey, documentKey, html, paper }) => {
|
|
75
|
+
const res = await api.put(`/settings/templates/${encodeURIComponent(addonKey)}/${encodeURIComponent(documentKey)}`, { html, paper });
|
|
76
|
+
return unwrapData(res);
|
|
77
|
+
},
|
|
78
|
+
onSuccess: (_data, vars) => {
|
|
79
|
+
void qc.invalidateQueries({ queryKey: orgDocumentCatalogKey() });
|
|
80
|
+
void qc.invalidateQueries({
|
|
81
|
+
queryKey: orgDocumentTemplateKey(vars.addonKey, vars.documentKey),
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
export function useResetOrgDocumentTemplate() {
|
|
87
|
+
const api = useApi();
|
|
88
|
+
const qc = useQueryClient();
|
|
89
|
+
return useMutation({
|
|
90
|
+
mutationFn: async ({ addonKey, documentKey }) => {
|
|
91
|
+
const res = await api.delete(`/settings/templates/${encodeURIComponent(addonKey)}/${encodeURIComponent(documentKey)}`);
|
|
92
|
+
return unwrapData(res);
|
|
93
|
+
},
|
|
94
|
+
onSuccess: (_data, vars) => {
|
|
95
|
+
void qc.invalidateQueries({ queryKey: orgDocumentCatalogKey() });
|
|
96
|
+
void qc.invalidateQueries({
|
|
97
|
+
queryKey: orgDocumentTemplateKey(vars.addonKey, vars.documentKey),
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Renders a PDF preview of unsaved HTML against dummy record + org branding.
|
|
104
|
+
* Returns a blob URL the caller should revoke.
|
|
105
|
+
*/
|
|
106
|
+
export function usePreviewOrgDocumentTemplate() {
|
|
107
|
+
const api = useApi();
|
|
108
|
+
return useCallback(async (args) => {
|
|
109
|
+
const res = await api.post('/settings/templates/preview', {
|
|
110
|
+
addon_key: args.addonKey,
|
|
111
|
+
document_key: args.documentKey,
|
|
112
|
+
html: args.html,
|
|
113
|
+
paper: args.paper,
|
|
114
|
+
}, { responseType: 'blob' });
|
|
115
|
+
const blob = res.data instanceof Blob
|
|
116
|
+
? res.data
|
|
117
|
+
: new Blob([res.data], { type: 'application/pdf' });
|
|
118
|
+
return URL.createObjectURL(blob);
|
|
119
|
+
}, [api]);
|
|
120
|
+
}
|
|
121
|
+
export function groupDocumentCatalog(items) {
|
|
122
|
+
const order = [];
|
|
123
|
+
const byAddon = new Map();
|
|
124
|
+
for (const item of items) {
|
|
125
|
+
const list = byAddon.get(item.addon_key);
|
|
126
|
+
if (list) {
|
|
127
|
+
list.push(item);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
order.push(item.addon_key);
|
|
131
|
+
byAddon.set(item.addon_key, [item]);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return order.map((addonKey) => {
|
|
135
|
+
const documents = byAddon.get(addonKey) ?? [];
|
|
136
|
+
return {
|
|
137
|
+
addonKey,
|
|
138
|
+
addonName: documents[0]?.addon_name || addonKey,
|
|
139
|
+
documents,
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
export function useGroupedOrgDocumentCatalog(opts) {
|
|
144
|
+
const catalog = useOrgDocumentCatalog(opts);
|
|
145
|
+
const groups = useMemo(() => groupDocumentCatalog(catalog.items), [catalog.items]);
|
|
146
|
+
return { ...catalog, groups };
|
|
147
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asteby/metacore-runtime-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "31.1.0",
|
|
4
4
|
"description": "React runtime for metacore hosts — renders addon contributions dynamically",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"sonner": ">=1.7",
|
|
39
39
|
"zustand": ">=5",
|
|
40
40
|
"@asteby/metacore-sdk": "^3.4.0",
|
|
41
|
-
"@asteby/metacore-ui": "^2.
|
|
41
|
+
"@asteby/metacore-ui": "^2.15.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependenciesMeta": {
|
|
44
44
|
"@tanstack/react-router": {
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"vitest": "^4.0.0",
|
|
69
69
|
"zustand": "^5.0.0",
|
|
70
70
|
"@asteby/metacore-sdk": "3.4.0",
|
|
71
|
-
"@asteby/metacore-ui": "2.
|
|
71
|
+
"@asteby/metacore-ui": "2.15.0"
|
|
72
72
|
},
|
|
73
73
|
"scripts": {
|
|
74
74
|
"build": "tsc -p tsconfig.json",
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// DocumentTemplateEditor — textarea + preview/save/reset for one org overlay
|
|
2
|
+
// of an addon document. Headless-friendly: plain buttons + textarea, styled via
|
|
3
|
+
// className. Host surfaces (ops Plantillas) can wrap this or roll their own
|
|
4
|
+
// using the hooks in use-org-document-templates.
|
|
5
|
+
import { useEffect, useState } from 'react'
|
|
6
|
+
import {
|
|
7
|
+
useOrgDocumentTemplate,
|
|
8
|
+
usePreviewOrgDocumentTemplate,
|
|
9
|
+
useResetOrgDocumentTemplate,
|
|
10
|
+
useSaveOrgDocumentTemplate,
|
|
11
|
+
} from './use-org-document-templates'
|
|
12
|
+
|
|
13
|
+
export interface DocumentTemplateEditorProps {
|
|
14
|
+
addonKey: string
|
|
15
|
+
documentKey: string
|
|
16
|
+
/** Called after a successful save or reset. */
|
|
17
|
+
onSaved?: () => void
|
|
18
|
+
onError?: (err: unknown) => void
|
|
19
|
+
className?: string
|
|
20
|
+
disabled?: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function DocumentTemplateEditor({
|
|
24
|
+
addonKey,
|
|
25
|
+
documentKey,
|
|
26
|
+
onSaved,
|
|
27
|
+
onError,
|
|
28
|
+
className,
|
|
29
|
+
disabled,
|
|
30
|
+
}: DocumentTemplateEditorProps) {
|
|
31
|
+
const { template, isLoading } = useOrgDocumentTemplate(addonKey, documentKey)
|
|
32
|
+
const save = useSaveOrgDocumentTemplate()
|
|
33
|
+
const reset = useResetOrgDocumentTemplate()
|
|
34
|
+
const preview = usePreviewOrgDocumentTemplate()
|
|
35
|
+
const [html, setHtml] = useState('')
|
|
36
|
+
const [previewUrl, setPreviewUrl] = useState<string | null>(null)
|
|
37
|
+
const [previewing, setPreviewing] = useState(false)
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (template?.html != null) setHtml(template.html)
|
|
41
|
+
}, [template?.html])
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
return () => {
|
|
45
|
+
if (previewUrl) URL.revokeObjectURL(previewUrl)
|
|
46
|
+
}
|
|
47
|
+
}, [previewUrl])
|
|
48
|
+
|
|
49
|
+
const busy = save.isPending || reset.isPending || previewing || disabled
|
|
50
|
+
|
|
51
|
+
async function onPreview() {
|
|
52
|
+
setPreviewing(true)
|
|
53
|
+
try {
|
|
54
|
+
const url = await preview({
|
|
55
|
+
addonKey,
|
|
56
|
+
documentKey,
|
|
57
|
+
html,
|
|
58
|
+
paper: template?.paper,
|
|
59
|
+
})
|
|
60
|
+
setPreviewUrl((prev) => {
|
|
61
|
+
if (prev) URL.revokeObjectURL(prev)
|
|
62
|
+
return url
|
|
63
|
+
})
|
|
64
|
+
} catch (err) {
|
|
65
|
+
onError?.(err)
|
|
66
|
+
} finally {
|
|
67
|
+
setPreviewing(false)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function onSave() {
|
|
72
|
+
try {
|
|
73
|
+
await save.mutateAsync({
|
|
74
|
+
addonKey,
|
|
75
|
+
documentKey,
|
|
76
|
+
html,
|
|
77
|
+
paper: template?.paper,
|
|
78
|
+
})
|
|
79
|
+
onSaved?.()
|
|
80
|
+
} catch (err) {
|
|
81
|
+
onError?.(err)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function onReset() {
|
|
86
|
+
try {
|
|
87
|
+
const detail = await reset.mutateAsync({ addonKey, documentKey })
|
|
88
|
+
setHtml(detail.html)
|
|
89
|
+
onSaved?.()
|
|
90
|
+
} catch (err) {
|
|
91
|
+
onError?.(err)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (isLoading && !template) {
|
|
96
|
+
return <p className={className}>…</p>
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<div className={className}>
|
|
101
|
+
<textarea
|
|
102
|
+
value={html}
|
|
103
|
+
onChange={(e) => setHtml(e.target.value)}
|
|
104
|
+
disabled={busy}
|
|
105
|
+
spellCheck={false}
|
|
106
|
+
rows={22}
|
|
107
|
+
style={{
|
|
108
|
+
width: '100%',
|
|
109
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
|
|
110
|
+
fontSize: 12,
|
|
111
|
+
lineHeight: 1.45,
|
|
112
|
+
}}
|
|
113
|
+
/>
|
|
114
|
+
<div style={{ display: 'flex', gap: 8, marginTop: 12, flexWrap: 'wrap' }}>
|
|
115
|
+
<button type="button" disabled={busy} onClick={() => void onPreview()}>
|
|
116
|
+
{previewing ? '…' : 'Vista previa'}
|
|
117
|
+
</button>
|
|
118
|
+
<button type="button" disabled={busy} onClick={() => void onSave()}>
|
|
119
|
+
Guardar
|
|
120
|
+
</button>
|
|
121
|
+
<button
|
|
122
|
+
type="button"
|
|
123
|
+
disabled={busy || !template?.customized}
|
|
124
|
+
onClick={() => void onReset()}
|
|
125
|
+
>
|
|
126
|
+
Restaurar default
|
|
127
|
+
</button>
|
|
128
|
+
</div>
|
|
129
|
+
{previewUrl ? (
|
|
130
|
+
<iframe
|
|
131
|
+
title="Vista previa"
|
|
132
|
+
src={previewUrl}
|
|
133
|
+
style={{
|
|
134
|
+
width: '100%',
|
|
135
|
+
height: 480,
|
|
136
|
+
marginTop: 12,
|
|
137
|
+
border: '1px solid #e5e7eb',
|
|
138
|
+
}}
|
|
139
|
+
/>
|
|
140
|
+
) : null}
|
|
141
|
+
</div>
|
|
142
|
+
)
|
|
143
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -179,6 +179,8 @@ export * from './api-context'
|
|
|
179
179
|
export * from './use-addon-settings'
|
|
180
180
|
export * from './use-print-document'
|
|
181
181
|
export * from './print-document-button'
|
|
182
|
+
export * from './use-org-document-templates'
|
|
183
|
+
export * from './document-template-editor'
|
|
182
184
|
export * from './metadata-cache'
|
|
183
185
|
export {
|
|
184
186
|
ADDON_MANIFEST_CHANGED_TYPE,
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// useOrgDocumentTemplates — host primitive for the per-org overlay of addon
|
|
2
|
+
// printable documents (Ajustes → Organización → Plantillas).
|
|
3
|
+
//
|
|
4
|
+
// The addon still owns the default HTML in its bundle. The host persists an
|
|
5
|
+
// optional override per (org, addon, document key) and resolves
|
|
6
|
+
// `org overlay → addon default` at PDF render time, so a business can change
|
|
7
|
+
// tickets/PDFs without a new addon version.
|
|
8
|
+
//
|
|
9
|
+
// GET /api/settings/templates
|
|
10
|
+
// GET /api/settings/templates/:addon/:key
|
|
11
|
+
// PUT /api/settings/templates/:addon/:key { html, paper? }
|
|
12
|
+
// DELETE /api/settings/templates/:addon/:key
|
|
13
|
+
// POST /api/settings/templates/preview → application/pdf
|
|
14
|
+
//
|
|
15
|
+
// ApiClient is a PEER via <ApiProvider> (same one usePrintDocument uses).
|
|
16
|
+
import { useCallback, useMemo } from 'react'
|
|
17
|
+
import {
|
|
18
|
+
useMutation,
|
|
19
|
+
useQuery,
|
|
20
|
+
useQueryClient,
|
|
21
|
+
} from '@tanstack/react-query'
|
|
22
|
+
import { useApi } from './api-context'
|
|
23
|
+
|
|
24
|
+
export interface OrgDocumentCatalogItem {
|
|
25
|
+
addon_key: string
|
|
26
|
+
addon_name: string
|
|
27
|
+
document_key: string
|
|
28
|
+
label: string
|
|
29
|
+
model: string
|
|
30
|
+
paper: string
|
|
31
|
+
filename?: string
|
|
32
|
+
customized: boolean
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface OrgDocumentTemplateDetail extends OrgDocumentCatalogItem {
|
|
36
|
+
html: string
|
|
37
|
+
default_html: string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function orgDocumentCatalogKey() {
|
|
41
|
+
return ['org-document-templates'] as const
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function orgDocumentTemplateKey(addonKey: string, documentKey: string) {
|
|
45
|
+
return ['org-document-templates', addonKey, documentKey] as const
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function unwrapData<T>(res: { data?: unknown }): T {
|
|
49
|
+
const body = (res as { data: any }).data
|
|
50
|
+
const values = body?.success ? body.data : body
|
|
51
|
+
return values as T
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function useOrgDocumentCatalog(opts?: { enabled?: boolean }) {
|
|
55
|
+
const api = useApi()
|
|
56
|
+
const query = useQuery<OrgDocumentCatalogItem[]>({
|
|
57
|
+
queryKey: orgDocumentCatalogKey(),
|
|
58
|
+
queryFn: async () => {
|
|
59
|
+
const res = await api.get('/settings/templates')
|
|
60
|
+
const data = unwrapData<OrgDocumentCatalogItem[] | null>(res)
|
|
61
|
+
return Array.isArray(data) ? data : []
|
|
62
|
+
},
|
|
63
|
+
staleTime: 30_000,
|
|
64
|
+
enabled: opts?.enabled ?? true,
|
|
65
|
+
})
|
|
66
|
+
return {
|
|
67
|
+
items: query.data ?? [],
|
|
68
|
+
isLoading: query.isLoading,
|
|
69
|
+
error: query.error,
|
|
70
|
+
refetch: () => {
|
|
71
|
+
void query.refetch()
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function useOrgDocumentTemplate(
|
|
77
|
+
addonKey: string,
|
|
78
|
+
documentKey: string,
|
|
79
|
+
opts?: { enabled?: boolean },
|
|
80
|
+
) {
|
|
81
|
+
const api = useApi()
|
|
82
|
+
const query = useQuery<OrgDocumentTemplateDetail>({
|
|
83
|
+
queryKey: orgDocumentTemplateKey(addonKey, documentKey),
|
|
84
|
+
queryFn: async () => {
|
|
85
|
+
const res = await api.get(
|
|
86
|
+
`/settings/templates/${encodeURIComponent(addonKey)}/${encodeURIComponent(documentKey)}`,
|
|
87
|
+
)
|
|
88
|
+
return unwrapData<OrgDocumentTemplateDetail>(res)
|
|
89
|
+
},
|
|
90
|
+
enabled:
|
|
91
|
+
(opts?.enabled ?? true) && !!addonKey && !!documentKey,
|
|
92
|
+
})
|
|
93
|
+
return {
|
|
94
|
+
template: query.data,
|
|
95
|
+
isLoading: query.isLoading,
|
|
96
|
+
error: query.error,
|
|
97
|
+
refetch: () => {
|
|
98
|
+
void query.refetch()
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function useSaveOrgDocumentTemplate() {
|
|
104
|
+
const api = useApi()
|
|
105
|
+
const qc = useQueryClient()
|
|
106
|
+
return useMutation<
|
|
107
|
+
OrgDocumentTemplateDetail,
|
|
108
|
+
Error,
|
|
109
|
+
{ addonKey: string; documentKey: string; html: string; paper?: string }
|
|
110
|
+
>({
|
|
111
|
+
mutationFn: async ({ addonKey, documentKey, html, paper }) => {
|
|
112
|
+
const res = await api.put(
|
|
113
|
+
`/settings/templates/${encodeURIComponent(addonKey)}/${encodeURIComponent(documentKey)}`,
|
|
114
|
+
{ html, paper },
|
|
115
|
+
)
|
|
116
|
+
return unwrapData<OrgDocumentTemplateDetail>(res)
|
|
117
|
+
},
|
|
118
|
+
onSuccess: (_data, vars) => {
|
|
119
|
+
void qc.invalidateQueries({ queryKey: orgDocumentCatalogKey() })
|
|
120
|
+
void qc.invalidateQueries({
|
|
121
|
+
queryKey: orgDocumentTemplateKey(vars.addonKey, vars.documentKey),
|
|
122
|
+
})
|
|
123
|
+
},
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function useResetOrgDocumentTemplate() {
|
|
128
|
+
const api = useApi()
|
|
129
|
+
const qc = useQueryClient()
|
|
130
|
+
return useMutation<
|
|
131
|
+
OrgDocumentTemplateDetail,
|
|
132
|
+
Error,
|
|
133
|
+
{ addonKey: string; documentKey: string }
|
|
134
|
+
>({
|
|
135
|
+
mutationFn: async ({ addonKey, documentKey }) => {
|
|
136
|
+
const res = await api.delete(
|
|
137
|
+
`/settings/templates/${encodeURIComponent(addonKey)}/${encodeURIComponent(documentKey)}`,
|
|
138
|
+
)
|
|
139
|
+
return unwrapData<OrgDocumentTemplateDetail>(res)
|
|
140
|
+
},
|
|
141
|
+
onSuccess: (_data, vars) => {
|
|
142
|
+
void qc.invalidateQueries({ queryKey: orgDocumentCatalogKey() })
|
|
143
|
+
void qc.invalidateQueries({
|
|
144
|
+
queryKey: orgDocumentTemplateKey(vars.addonKey, vars.documentKey),
|
|
145
|
+
})
|
|
146
|
+
},
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Renders a PDF preview of unsaved HTML against dummy record + org branding.
|
|
152
|
+
* Returns a blob URL the caller should revoke.
|
|
153
|
+
*/
|
|
154
|
+
export function usePreviewOrgDocumentTemplate() {
|
|
155
|
+
const api = useApi()
|
|
156
|
+
return useCallback(
|
|
157
|
+
async (args: {
|
|
158
|
+
addonKey: string
|
|
159
|
+
documentKey: string
|
|
160
|
+
html: string
|
|
161
|
+
paper?: string
|
|
162
|
+
}): Promise<string> => {
|
|
163
|
+
const res = await api.post(
|
|
164
|
+
'/settings/templates/preview',
|
|
165
|
+
{
|
|
166
|
+
addon_key: args.addonKey,
|
|
167
|
+
document_key: args.documentKey,
|
|
168
|
+
html: args.html,
|
|
169
|
+
paper: args.paper,
|
|
170
|
+
},
|
|
171
|
+
{ responseType: 'blob' },
|
|
172
|
+
)
|
|
173
|
+
const blob =
|
|
174
|
+
res.data instanceof Blob
|
|
175
|
+
? res.data
|
|
176
|
+
: new Blob([res.data], { type: 'application/pdf' })
|
|
177
|
+
return URL.createObjectURL(blob)
|
|
178
|
+
},
|
|
179
|
+
[api],
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function groupDocumentCatalog(
|
|
184
|
+
items: OrgDocumentCatalogItem[],
|
|
185
|
+
): { addonKey: string; addonName: string; documents: OrgDocumentCatalogItem[] }[] {
|
|
186
|
+
const order: string[] = []
|
|
187
|
+
const byAddon = new Map<string, OrgDocumentCatalogItem[]>()
|
|
188
|
+
for (const item of items) {
|
|
189
|
+
const list = byAddon.get(item.addon_key)
|
|
190
|
+
if (list) {
|
|
191
|
+
list.push(item)
|
|
192
|
+
} else {
|
|
193
|
+
order.push(item.addon_key)
|
|
194
|
+
byAddon.set(item.addon_key, [item])
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return order.map((addonKey) => {
|
|
198
|
+
const documents = byAddon.get(addonKey) ?? []
|
|
199
|
+
return {
|
|
200
|
+
addonKey,
|
|
201
|
+
addonName: documents[0]?.addon_name || addonKey,
|
|
202
|
+
documents,
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function useGroupedOrgDocumentCatalog(opts?: { enabled?: boolean }) {
|
|
208
|
+
const catalog = useOrgDocumentCatalog(opts)
|
|
209
|
+
const groups = useMemo(
|
|
210
|
+
() => groupDocumentCatalog(catalog.items),
|
|
211
|
+
[catalog.items],
|
|
212
|
+
)
|
|
213
|
+
return { ...catalog, groups }
|
|
214
|
+
}
|