@cardinali-studio/adminkit 2.2.35 → 2.2.37
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/dist/app/app.css +2 -2
- package/dist/app/routes/PageEditor.js +4 -0
- package/dist/app/routes/PageSeoEditor.js +3 -0
- package/dist/app/site.d.ts +11 -0
- package/dist/form/Trash.js +25 -10
- package/package.json +1 -1
package/dist/app/app.css
CHANGED
|
@@ -2351,5 +2351,5 @@ body:has(.uk) .pane-body { padding-bottom: 190px; }
|
|
|
2351
2351
|
@media (prefers-reduced-motion: reduce) {
|
|
2352
2352
|
.ak-bug-trigger, .ak-bug-backdrop, .ak-bug-dialog { animation: none; transition: none; }
|
|
2353
2353
|
}
|
|
2354
|
-
:root[data-admin-interface="next"] .rail-foot > .ak-release-control{width:auto;height:auto;overflow:visible}
|
|
2355
|
-
:root[data-admin-interface="next"] .rail-foot > .ak-release-control > .ak-release-trigger{width:auto;min-width:104px;display:inline-flex;gap:9px;padding:0 14px;color:var(--ak-rail-ink-on);font:600 12px/1 var(--ak-font);overflow:visible}
|
|
2354
|
+
:root[data-admin-interface="next"] .rail-foot > .ak-release-control.ak-release-control{width:auto;height:auto;overflow:visible}
|
|
2355
|
+
:root[data-admin-interface="next"] .rail-foot > .ak-release-control.ak-release-control > .ak-release-trigger{width:auto;min-width:104px;display:inline-flex;gap:9px;padding:0 14px;color:var(--ak-rail-ink-on);font:600 12px/1 var(--ak-font);overflow:visible}
|
|
@@ -348,6 +348,10 @@ export function PageEditor({ page, onChange, onRefresh, pristine, pickMedia, pic
|
|
|
348
348
|
«Ritratto» e «Riconoscimenti» — campi di altri tipi di pagina, che compaiono perché il
|
|
349
349
|
form disegna tutto ciò che lo schema dichiara e non sa quale tipo si stia modificando.
|
|
350
350
|
Titolo, visibilità e SEO restano dove sono già: la barra in alto e la scheda SEO. */
|
|
351
|
+
if (definition?.editor && !translationActive) {
|
|
352
|
+
const Editor = definition.editor;
|
|
353
|
+
return _jsx("div", { className: "ed ed-site-page", children: _jsx(Editor, { page: page, onChange: onChange, pickMediaFiles: pickMediaFiles }, page._documentId || page.slug) });
|
|
354
|
+
}
|
|
351
355
|
if (isPortfolio && !translationActive) {
|
|
352
356
|
return (_jsxs("div", { className: "ed ed-portfolio", children: [bodyState === "error" && (_jsx("p", { className: "pe-load-error", children: "Non sono riuscito ad aggiornare i dati della pagina dal sito." })), _jsx(PortfolioWorksEditor, { value: page.works, onChange: (works) => onChange({ ...page, works }), pickMediaFiles: pickMediaFiles })] }));
|
|
353
357
|
}
|
|
@@ -94,6 +94,9 @@ export function PageSeoEditor({ page, onChange, onRefresh, pristine, pickMediaFi
|
|
|
94
94
|
const socialImage = explicitImage || automaticImage(page);
|
|
95
95
|
const pageUrl = `${site().publicBase}/${page.slug}/`;
|
|
96
96
|
const complete = !!seoTitle.trim() && !!seoDescription.trim() && !!socialImage;
|
|
97
|
+
const CustomEditor = pageType(page.type)?.seoEditor;
|
|
98
|
+
if (CustomEditor && !readOnly)
|
|
99
|
+
return _jsx(CustomEditor, { page: page, onChange: onChange, pickMediaFiles: pickMediaFiles }, page._documentId || page.slug);
|
|
97
100
|
const customShape = pageType(page.type)?.seoShape;
|
|
98
101
|
if (customShape)
|
|
99
102
|
return _jsxs("section", { className: "seo-editor", children: [_jsx("h2", { children: "SEO e GEO" }), loadError && _jsx("p", { className: "ak-error", children: "Non sono riuscito a rileggere la pagina." }), _jsx(SchemaForm, { shape: customShape, value: (page.seo ?? {}), onChange: (seo) => { if (!readOnly)
|
package/dist/app/site.d.ts
CHANGED
|
@@ -16,6 +16,17 @@ export interface PageTypeConfig {
|
|
|
16
16
|
creatable?: boolean;
|
|
17
17
|
create?: (title: string, slug: string) => Record<string, unknown>;
|
|
18
18
|
seoShape?: Shape;
|
|
19
|
+
seoEditor?: PageTypeConfig["editor"];
|
|
20
|
+
/** Content-specific visual editor inside the native page shell. */
|
|
21
|
+
editor?: ComponentType<{
|
|
22
|
+
page: Record<string, any> & {
|
|
23
|
+
slug: string;
|
|
24
|
+
};
|
|
25
|
+
onChange: (page: Record<string, any> & {
|
|
26
|
+
slug: string;
|
|
27
|
+
}) => void;
|
|
28
|
+
pickMediaFiles?: (options: import("../form/MediaPicker.js").PickerOptions) => Promise<import("../api.js").AssetFile[] | null>;
|
|
29
|
+
}>;
|
|
19
30
|
}
|
|
20
31
|
/** Lingue dei contenuti, assenti nei siti monolingui. I codici sono quelli dei sibling Hugo
|
|
21
32
|
* (`index.md`, `index.en.md`): la lingua predefinita non porta alcun suffisso. */
|
package/dist/form/Trash.js
CHANGED
|
@@ -23,20 +23,35 @@ export function Trash() {
|
|
|
23
23
|
return (_jsxs("div", { className: "tr", children: [_jsxs("header", { className: "mb-top", children: [_jsx("span", { className: "ak-spacer" }), !!items?.length && (_jsx("button", { className: "ak-btn", onClick: async () => {
|
|
24
24
|
if (!confirm(`Svuotare il cestino? ${items.length} file cancellati per sempre.`))
|
|
25
25
|
return;
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
try {
|
|
27
|
+
await api.trashEmpty();
|
|
28
|
+
await load();
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
32
|
+
}
|
|
28
33
|
}, children: "Svuota il cestino" }))] }), error && _jsx("p", { className: "ak-error", children: error }), !items && _jsx("p", { className: "ak-hint", children: "Carico\u2026" }), items?.length === 0 && _jsx("p", { className: "ak-hint", children: "Il cestino \u00E8 vuoto." }), _jsx("ul", { className: "tr-list", children: items?.map((it) => (_jsxs("li", { className: "tr-row", children: [_jsx("img", { src: it.previewUrl, alt: "", className: "tr-thumb", loading: "lazy" }), _jsx("span", { className: "tr-name", children: it.name }), _jsx("code", { className: "tr-orig", children: it.originalKey }), _jsx("span", { className: "ak-hint", children: fmtSize(it.size) }), _jsx("button", { className: "ak-btn ak-btn-quiet", onClick: async () => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
try {
|
|
35
|
+
const r = await api.trashRestore([it.trashKey]);
|
|
36
|
+
if (r.conflicts?.length) {
|
|
37
|
+
alert(`Esisteva già un file con quel nome: ripristinato come ${r.conflicts[0].restoredAs}.`);
|
|
38
|
+
}
|
|
39
|
+
// NB: il ripristino NON rimette i riferimenti nelle pagine — li aveva tolti la
|
|
40
|
+
// cancellazione. Va rifatto a mano, ed è documentato nell'endpoint.
|
|
41
|
+
await load();
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
32
45
|
}
|
|
33
|
-
// NB: il ripristino NON rimette i riferimenti nelle pagine — li aveva tolti la
|
|
34
|
-
// cancellazione. Va rifatto a mano, ed è documentato nell'endpoint.
|
|
35
|
-
await load();
|
|
36
46
|
}, children: "Ripristina" }), _jsx("button", { className: "ak-btn", onClick: async () => {
|
|
37
47
|
if (!confirm(`Cancellare ${it.name} per sempre? Non è più recuperabile.`))
|
|
38
48
|
return;
|
|
39
|
-
|
|
40
|
-
|
|
49
|
+
try {
|
|
50
|
+
await api.trashDelete([it.trashKey]);
|
|
51
|
+
await load();
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
55
|
+
}
|
|
41
56
|
}, children: "Elimina" })] }, it.trashKey))) })] }));
|
|
42
57
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardinali-studio/adminkit",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.37",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Motore riusabile di un pannello di amministrazione per siti Hugo su Cloudflare Pages: codec del front matter guidato dallo schema, form React, libreria media su R2. NIENTE di specifico di un sito qui dentro.",
|
|
6
6
|
"license": "0BSD",
|