@aduptive/strapi-blockscene 1.0.0-alpha.3 → 1.0.0-alpha.4
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/README.md +12 -1
- package/dist/admin.cjs +765 -206
- package/dist/admin.mjs +789 -207
- package/package.json +1 -1
package/dist/admin.cjs
CHANGED
|
@@ -32,13 +32,13 @@ __export(strapi4_exports, {
|
|
|
32
32
|
default: () => strapi4_default
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(strapi4_exports);
|
|
35
|
-
var
|
|
35
|
+
var React5 = __toESM(require("react"));
|
|
36
36
|
var import_design_system3 = require("@strapi/design-system");
|
|
37
37
|
var import_helper_plugin = require("@strapi/helper-plugin");
|
|
38
38
|
|
|
39
39
|
// admin/Gallery.tsx
|
|
40
|
-
var
|
|
41
|
-
var
|
|
40
|
+
var React2 = __toESM(require("react"));
|
|
41
|
+
var import_react_dom2 = require("react-dom");
|
|
42
42
|
var import_design_system = require("@strapi/design-system");
|
|
43
43
|
var import_styled_components = __toESM(require("styled-components"));
|
|
44
44
|
|
|
@@ -46,27 +46,58 @@ var import_styled_components = __toESM(require("styled-components"));
|
|
|
46
46
|
var import_fractional_indexing = require("fractional-indexing");
|
|
47
47
|
function editableZones(schema, values, canEdit, disabled = false) {
|
|
48
48
|
if (disabled) return [];
|
|
49
|
-
return Object.entries(schema?.attributes || {}).filter(
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
return Object.entries(schema?.attributes || {}).filter(
|
|
50
|
+
([name, attr]) => attr.type === "dynamiczone" && !attr.conditions && canEdit(name)
|
|
51
|
+
).map(([name, attr]) => {
|
|
52
|
+
const rows = Array.isArray(values?.[name]) ? values[name] : [];
|
|
53
|
+
return {
|
|
54
|
+
name,
|
|
55
|
+
components: attr.components || [],
|
|
56
|
+
max: attr.max,
|
|
57
|
+
count: rows.length,
|
|
58
|
+
uids: rows.map(
|
|
59
|
+
(row) => row && typeof row.__component === "string" ? row.__component : ""
|
|
60
|
+
),
|
|
61
|
+
full: rows.length >= (attr.max ?? Infinity)
|
|
62
|
+
};
|
|
52
63
|
});
|
|
53
64
|
}
|
|
54
65
|
function canInsert(zone, uid, values, components, count = 1) {
|
|
55
|
-
return Boolean(
|
|
66
|
+
return Boolean(
|
|
67
|
+
zone?.components.includes(uid) && components[uid] && (Array.isArray(values?.[zone.name]) ? values[zone.name].length : 0) + count <= (zone.max ?? Infinity)
|
|
68
|
+
);
|
|
56
69
|
}
|
|
57
70
|
function candidatesFor(uid, meta = {}, config = {}) {
|
|
58
71
|
const version = config.previewVersion ? `?v=${encodeURIComponent(config.previewVersion)}` : "";
|
|
59
72
|
const base = (config.previewBaseUrl || "/block-previews").replace(/\/$/, "");
|
|
60
|
-
return [
|
|
73
|
+
return [
|
|
74
|
+
meta.manualImage,
|
|
75
|
+
meta.image,
|
|
76
|
+
`${base}/${encodeURIComponent(uid)}.webp${version}`
|
|
77
|
+
].filter(Boolean);
|
|
61
78
|
}
|
|
62
|
-
var SYSTEM_FIELDS = [
|
|
79
|
+
var SYSTEM_FIELDS = [
|
|
80
|
+
"id",
|
|
81
|
+
"documentId",
|
|
82
|
+
"createdAt",
|
|
83
|
+
"updatedAt",
|
|
84
|
+
"publishedAt",
|
|
85
|
+
"createdBy",
|
|
86
|
+
"updatedBy",
|
|
87
|
+
"locale",
|
|
88
|
+
"localizations"
|
|
89
|
+
];
|
|
63
90
|
var fieldType = (attr) => attr?.type === "customField" ? String(attr.customField || "").includes("CKEditor") ? "richtext" : "customField" : attr?.type || "unknown";
|
|
64
91
|
var fieldsOf = (schema) => Object.entries(schema?.attributes || {}).filter(([name]) => !SYSTEM_FIELDS.includes(name)).map(([name, attr]) => ({ name, type: fieldType(attr) }));
|
|
65
92
|
var categoryOf = (uid, schema, meta = {}) => meta.category || schema?.category || uid.split(".")[0];
|
|
66
93
|
var byCategory = (a, b) => (a === "admin" ? 1 : 0) - (b === "admin" ? 1 : 0) || a.localeCompare(b);
|
|
94
|
+
var pickable = (zone, config) => {
|
|
95
|
+
const closers = Object.values(config.groups || {});
|
|
96
|
+
return zone.components.filter((uid) => !closers.includes(uid));
|
|
97
|
+
};
|
|
67
98
|
function entriesFor(zone, components, config, query, category = "all") {
|
|
68
99
|
const needle = query.trim().toLocaleLowerCase();
|
|
69
|
-
return zone.
|
|
100
|
+
return pickable(zone, config).flatMap((uid) => {
|
|
70
101
|
const schema = components[uid];
|
|
71
102
|
if (!schema) return [];
|
|
72
103
|
const meta = config.components?.[uid] || {};
|
|
@@ -81,11 +112,13 @@ function entriesFor(zone, components, config, query, category = "all") {
|
|
|
81
112
|
};
|
|
82
113
|
if (category !== "all" && entry.category !== category) return [];
|
|
83
114
|
return `${entry.label} ${entry.description} ${entry.category} ${uid} ${meta.keywords || ""}`.toLocaleLowerCase().includes(needle) ? [entry] : [];
|
|
84
|
-
}).sort(
|
|
115
|
+
}).sort(
|
|
116
|
+
(a, b) => byCategory(a.category, b.category) || a.label.localeCompare(b.label)
|
|
117
|
+
);
|
|
85
118
|
}
|
|
86
119
|
function categoriesFor(zone, components, config) {
|
|
87
120
|
const counts = /* @__PURE__ */ new Map();
|
|
88
|
-
for (const uid of zone
|
|
121
|
+
for (const uid of pickable(zone, config)) {
|
|
89
122
|
const schema = components[uid];
|
|
90
123
|
if (!schema) continue;
|
|
91
124
|
const c = categoryOf(uid, schema, config.components?.[uid] || {});
|
|
@@ -95,8 +128,12 @@ function categoriesFor(zone, components, config) {
|
|
|
95
128
|
}
|
|
96
129
|
function groupEntries(entries) {
|
|
97
130
|
const map = /* @__PURE__ */ new Map();
|
|
98
|
-
for (const entry of entries)
|
|
99
|
-
|
|
131
|
+
for (const entry of entries)
|
|
132
|
+
map.set(entry.category, [...map.get(entry.category) || [], entry]);
|
|
133
|
+
return [...map.entries()].map(([category, items]) => ({
|
|
134
|
+
category,
|
|
135
|
+
entries: items
|
|
136
|
+
}));
|
|
100
137
|
}
|
|
101
138
|
function memoryKey({ base = "", userId, contentType, zone }) {
|
|
102
139
|
if (!userId || !contentType || !zone) return null;
|
|
@@ -112,7 +149,8 @@ function readMemory(storage2, key) {
|
|
|
112
149
|
}
|
|
113
150
|
function writeMemory(storage2, key, value) {
|
|
114
151
|
try {
|
|
115
|
-
if (key && (value === "open" || value === "closed"))
|
|
152
|
+
if (key && (value === "open" || value === "closed"))
|
|
153
|
+
storage2?.setItem(key, value);
|
|
116
154
|
} catch {
|
|
117
155
|
}
|
|
118
156
|
}
|
|
@@ -198,6 +236,10 @@ function Wireframe({ template, palette, className, noPreview }) {
|
|
|
198
236
|
);
|
|
199
237
|
}
|
|
200
238
|
|
|
239
|
+
// admin/RowPreviews.tsx
|
|
240
|
+
var React = __toESM(require("react"));
|
|
241
|
+
var import_react_dom = require("react-dom");
|
|
242
|
+
|
|
201
243
|
// admin/messages.ts
|
|
202
244
|
var import_react_intl = require("react-intl");
|
|
203
245
|
|
|
@@ -312,7 +354,8 @@ var en_default = {
|
|
|
312
354
|
columns: "Columns",
|
|
313
355
|
noPreview: "no preview",
|
|
314
356
|
"templates.none": "No preview",
|
|
315
|
-
noChanges: "No unsaved changes"
|
|
357
|
+
noChanges: "No unsaved changes",
|
|
358
|
+
rowPreview: "Open the {label} preview"
|
|
316
359
|
};
|
|
317
360
|
|
|
318
361
|
// admin/translations/pt-BR.json
|
|
@@ -426,7 +469,8 @@ var pt_BR_default = {
|
|
|
426
469
|
columns: "Colunas",
|
|
427
470
|
noPreview: "sem preview",
|
|
428
471
|
"templates.none": "Sem preview",
|
|
429
|
-
noChanges: "Sem altera\xE7\xF5es pendentes"
|
|
472
|
+
noChanges: "Sem altera\xE7\xF5es pendentes",
|
|
473
|
+
rowPreview: "Abrir a pr\xE9via de {label}"
|
|
430
474
|
};
|
|
431
475
|
|
|
432
476
|
// admin/translations/pt.json
|
|
@@ -540,7 +584,8 @@ var pt_default = {
|
|
|
540
584
|
columns: "Colunas",
|
|
541
585
|
noPreview: "sem pr\xE9-visualiza\xE7\xE3o",
|
|
542
586
|
"templates.none": "Sem pr\xE9-visualiza\xE7\xE3o",
|
|
543
|
-
noChanges: "Sem altera\xE7\xF5es pendentes"
|
|
587
|
+
noChanges: "Sem altera\xE7\xF5es pendentes",
|
|
588
|
+
rowPreview: "Abrir a pr\xE9-visualiza\xE7\xE3o de {label}"
|
|
544
589
|
};
|
|
545
590
|
|
|
546
591
|
// admin/translations/fr.json
|
|
@@ -654,7 +699,8 @@ var fr_default = {
|
|
|
654
699
|
columns: "Colonnes",
|
|
655
700
|
noPreview: "pas d\u2019aper\xE7u",
|
|
656
701
|
"templates.none": "Pas d\u2019aper\xE7u",
|
|
657
|
-
noChanges: "Aucune modification en attente"
|
|
702
|
+
noChanges: "Aucune modification en attente",
|
|
703
|
+
rowPreview: "Ouvrir l\u2019aper\xE7u de {label}"
|
|
658
704
|
};
|
|
659
705
|
|
|
660
706
|
// admin/translations/es.json
|
|
@@ -768,7 +814,8 @@ var es_default = {
|
|
|
768
814
|
columns: "Columnas",
|
|
769
815
|
noPreview: "sin vista previa",
|
|
770
816
|
"templates.none": "Sin vista previa",
|
|
771
|
-
noChanges: "Sin cambios pendientes"
|
|
817
|
+
noChanges: "Sin cambios pendientes",
|
|
818
|
+
rowPreview: "Abrir la vista previa de {label}"
|
|
772
819
|
};
|
|
773
820
|
|
|
774
821
|
// admin/translations/de.json
|
|
@@ -882,7 +929,8 @@ var de_default = {
|
|
|
882
929
|
columns: "Spalten",
|
|
883
930
|
noPreview: "keine Vorschau",
|
|
884
931
|
"templates.none": "Keine Vorschau",
|
|
885
|
-
noChanges: "Keine ungespeicherten \xC4nderungen"
|
|
932
|
+
noChanges: "Keine ungespeicherten \xC4nderungen",
|
|
933
|
+
rowPreview: "Vorschau von {label} \xF6ffnen"
|
|
886
934
|
};
|
|
887
935
|
|
|
888
936
|
// admin/translations/it.json
|
|
@@ -996,7 +1044,8 @@ var it_default = {
|
|
|
996
1044
|
columns: "Colonne",
|
|
997
1045
|
noPreview: "nessuna anteprima",
|
|
998
1046
|
"templates.none": "Nessuna anteprima",
|
|
999
|
-
noChanges: "Nessuna modifica in sospeso"
|
|
1047
|
+
noChanges: "Nessuna modifica in sospeso",
|
|
1048
|
+
rowPreview: "Apri l\u2019anteprima di {label}"
|
|
1000
1049
|
};
|
|
1001
1050
|
|
|
1002
1051
|
// admin/translations/nl.json
|
|
@@ -1110,7 +1159,8 @@ var nl_default = {
|
|
|
1110
1159
|
columns: "Kolommen",
|
|
1111
1160
|
noPreview: "geen voorbeeld",
|
|
1112
1161
|
"templates.none": "Geen voorbeeld",
|
|
1113
|
-
noChanges: "Geen niet-opgeslagen wijzigingen"
|
|
1162
|
+
noChanges: "Geen niet-opgeslagen wijzigingen",
|
|
1163
|
+
rowPreview: "Voorbeeld van {label} openen"
|
|
1114
1164
|
};
|
|
1115
1165
|
|
|
1116
1166
|
// admin/messages.ts
|
|
@@ -1130,26 +1180,224 @@ function useMessages() {
|
|
|
1130
1180
|
return out;
|
|
1131
1181
|
}
|
|
1132
1182
|
|
|
1133
|
-
// admin/
|
|
1183
|
+
// admin/RowPreviews.tsx
|
|
1134
1184
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1185
|
+
var ATTR = "data-blockscene-row-thumb";
|
|
1186
|
+
function useAnchors(zones, onOpen) {
|
|
1187
|
+
const [anchors, setAnchors] = React.useState([]);
|
|
1188
|
+
const open = React.useRef(onOpen);
|
|
1189
|
+
open.current = onOpen;
|
|
1190
|
+
const latest = React.useRef(zones);
|
|
1191
|
+
latest.current = zones;
|
|
1192
|
+
const sync = React.useRef(() => {
|
|
1193
|
+
});
|
|
1194
|
+
sync.current = () => {
|
|
1195
|
+
const next = [];
|
|
1196
|
+
for (const zone of latest.current) {
|
|
1197
|
+
const list = zone.uids?.length ? findZoneList(zone.label) : null;
|
|
1198
|
+
if (!list) continue;
|
|
1199
|
+
toggles(list).forEach((button, index) => {
|
|
1200
|
+
const uid = zone.uids[index];
|
|
1201
|
+
if (!uid) return;
|
|
1202
|
+
let el = button.querySelector(
|
|
1203
|
+
`:scope > [${ATTR}]`
|
|
1204
|
+
);
|
|
1205
|
+
if (!el) {
|
|
1206
|
+
el = document.createElement("span");
|
|
1207
|
+
el.setAttribute(ATTR, "");
|
|
1208
|
+
el.style.cssText = "display:inline-flex;align-items:center";
|
|
1209
|
+
const activate = (event) => {
|
|
1210
|
+
if (!event.currentTarget.getAttribute("role"))
|
|
1211
|
+
return;
|
|
1212
|
+
event.preventDefault();
|
|
1213
|
+
event.stopPropagation();
|
|
1214
|
+
open.current(
|
|
1215
|
+
String(event.currentTarget.dataset.uid || "")
|
|
1216
|
+
);
|
|
1217
|
+
};
|
|
1218
|
+
el.addEventListener("click", activate, true);
|
|
1219
|
+
el.addEventListener(
|
|
1220
|
+
"keydown",
|
|
1221
|
+
(event) => {
|
|
1222
|
+
if (event.key === "Enter" || event.key === " ") activate(event);
|
|
1223
|
+
},
|
|
1224
|
+
true
|
|
1225
|
+
);
|
|
1226
|
+
button.insertBefore(el, button.firstChild);
|
|
1227
|
+
}
|
|
1228
|
+
el.dataset.uid = uid;
|
|
1229
|
+
next.push({ el, uid, zone: zone.name, index });
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
for (const el of document.querySelectorAll(`[${ATTR}]`))
|
|
1233
|
+
if (!next.some((a) => a.el === el)) el.remove();
|
|
1234
|
+
setAnchors(
|
|
1235
|
+
(prev) => prev.length === next.length && prev.every((a, i) => a.el === next[i].el && a.uid === next[i].uid) ? prev : next
|
|
1236
|
+
);
|
|
1237
|
+
};
|
|
1238
|
+
React.useEffect(() => {
|
|
1239
|
+
sync.current();
|
|
1240
|
+
});
|
|
1241
|
+
React.useEffect(() => {
|
|
1242
|
+
let frame = 0;
|
|
1243
|
+
const observer = new MutationObserver(() => {
|
|
1244
|
+
if (frame) return;
|
|
1245
|
+
frame = requestAnimationFrame(() => {
|
|
1246
|
+
frame = 0;
|
|
1247
|
+
sync.current();
|
|
1248
|
+
});
|
|
1249
|
+
});
|
|
1250
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
1251
|
+
return () => {
|
|
1252
|
+
observer.disconnect();
|
|
1253
|
+
cancelAnimationFrame(frame);
|
|
1254
|
+
for (const el of document.querySelectorAll(`[${ATTR}]`)) el.remove();
|
|
1255
|
+
};
|
|
1256
|
+
}, []);
|
|
1257
|
+
return anchors;
|
|
1258
|
+
}
|
|
1259
|
+
function RowPreviews({ zones, components, catalog, Modal: Modal2 }) {
|
|
1260
|
+
const t = useMessages();
|
|
1261
|
+
const [resolved, setResolved] = React.useState({});
|
|
1262
|
+
const [open, setOpen] = React.useState(null);
|
|
1263
|
+
const anchors = useAnchors(zones, (uid) => setOpen(uid));
|
|
1264
|
+
const candidates = (uid) => candidatesFor(uid, catalog?.components?.[uid] || {}, catalog || {});
|
|
1265
|
+
const label = (uid) => catalog?.components?.[uid]?.label || components?.[uid]?.info?.displayName || uid;
|
|
1266
|
+
const srcOf = (uid) => candidates(uid)[resolved[uid] ?? -1] || "";
|
|
1267
|
+
React.useEffect(() => {
|
|
1268
|
+
for (const { el, uid } of anchors) {
|
|
1269
|
+
if (srcOf(uid)) {
|
|
1270
|
+
el.setAttribute("role", "button");
|
|
1271
|
+
el.setAttribute("tabindex", "0");
|
|
1272
|
+
el.setAttribute("aria-label", t.f("rowPreview", { label: label(uid) }));
|
|
1273
|
+
el.style.cursor = "zoom-in";
|
|
1274
|
+
} else
|
|
1275
|
+
for (const name of ["role", "tabindex", "aria-label"])
|
|
1276
|
+
el.removeAttribute(name);
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
1280
|
+
anchors.map(
|
|
1281
|
+
(a) => (0, import_react_dom.createPortal)(
|
|
1282
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1283
|
+
"span",
|
|
1284
|
+
{
|
|
1285
|
+
style: {
|
|
1286
|
+
display: "block",
|
|
1287
|
+
width: "6.4rem",
|
|
1288
|
+
marginRight: "8px",
|
|
1289
|
+
flex: "0 0 auto"
|
|
1290
|
+
},
|
|
1291
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1292
|
+
Thumb,
|
|
1293
|
+
{
|
|
1294
|
+
candidates: candidates(a.uid),
|
|
1295
|
+
blank: true,
|
|
1296
|
+
onResolved: (index) => setResolved(
|
|
1297
|
+
(prev) => prev[a.uid] === index ? prev : { ...prev, [a.uid]: index }
|
|
1298
|
+
)
|
|
1299
|
+
}
|
|
1300
|
+
)
|
|
1301
|
+
}
|
|
1302
|
+
),
|
|
1303
|
+
a.el,
|
|
1304
|
+
`${a.zone}:${a.index}`
|
|
1305
|
+
)
|
|
1306
|
+
),
|
|
1307
|
+
open && srcOf(open) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1308
|
+
Modal2,
|
|
1309
|
+
{
|
|
1310
|
+
open: true,
|
|
1311
|
+
onOpenChange: (value) => {
|
|
1312
|
+
if (!value) setOpen(null);
|
|
1313
|
+
},
|
|
1314
|
+
trigger: null,
|
|
1315
|
+
title: label(open),
|
|
1316
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1317
|
+
"img",
|
|
1318
|
+
{
|
|
1319
|
+
src: srcOf(open),
|
|
1320
|
+
alt: "",
|
|
1321
|
+
style: {
|
|
1322
|
+
display: "block",
|
|
1323
|
+
margin: "0 auto",
|
|
1324
|
+
maxWidth: "100%",
|
|
1325
|
+
maxHeight: "75vh",
|
|
1326
|
+
objectFit: "contain"
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
)
|
|
1330
|
+
}
|
|
1331
|
+
)
|
|
1332
|
+
] });
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
// admin/Gallery.tsx
|
|
1336
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1135
1337
|
var Columns = import_styled_components.default.div`
|
|
1136
|
-
column-count: ${({ $columns }) => $columns};
|
|
1137
|
-
|
|
1338
|
+
column-count: ${({ $columns }) => $columns};
|
|
1339
|
+
column-gap: 12px;
|
|
1340
|
+
> * {
|
|
1341
|
+
break-inside: avoid;
|
|
1342
|
+
-webkit-column-break-inside: avoid;
|
|
1343
|
+
margin-bottom: 12px;
|
|
1344
|
+
}
|
|
1138
1345
|
`;
|
|
1139
1346
|
var Tile = import_styled_components.default.button`
|
|
1140
|
-
display: flex;
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1347
|
+
display: flex;
|
|
1348
|
+
flex-direction: column;
|
|
1349
|
+
gap: 8px;
|
|
1350
|
+
text-align: left;
|
|
1351
|
+
width: 100%;
|
|
1352
|
+
padding: 8px;
|
|
1353
|
+
border: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
1354
|
+
border-radius: 4px;
|
|
1355
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
1356
|
+
cursor: pointer;
|
|
1357
|
+
&:hover {
|
|
1358
|
+
border-color: ${({ theme }) => theme.colors.primary600};
|
|
1359
|
+
}
|
|
1360
|
+
&:focus-visible {
|
|
1361
|
+
outline: 2px solid ${({ theme }) => theme.colors.primary600};
|
|
1362
|
+
outline-offset: 2px;
|
|
1363
|
+
}
|
|
1364
|
+
`;
|
|
1365
|
+
var Clamp = (0, import_styled_components.default)(import_design_system.Typography)`
|
|
1366
|
+
display: -webkit-box;
|
|
1367
|
+
-webkit-line-clamp: 2;
|
|
1368
|
+
-webkit-box-orient: vertical;
|
|
1369
|
+
overflow: hidden;
|
|
1145
1370
|
`;
|
|
1146
|
-
var Clamp = (0, import_styled_components.default)(import_design_system.Typography)` display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; `;
|
|
1147
1371
|
var Slider = import_styled_components.default.input`
|
|
1148
|
-
appearance: none;
|
|
1372
|
+
appearance: none;
|
|
1373
|
+
-webkit-appearance: none;
|
|
1374
|
+
width: 8rem;
|
|
1375
|
+
height: 0.4rem;
|
|
1376
|
+
border-radius: 0.4rem;
|
|
1377
|
+
cursor: pointer;
|
|
1149
1378
|
background: ${({ theme, $percent }) => `linear-gradient(to right, ${theme.colors.primary600} ${$percent}%, ${theme.colors.neutral200} ${$percent}%)`};
|
|
1150
|
-
&::-webkit-slider-thumb {
|
|
1151
|
-
|
|
1152
|
-
|
|
1379
|
+
&::-webkit-slider-thumb {
|
|
1380
|
+
appearance: none;
|
|
1381
|
+
-webkit-appearance: none;
|
|
1382
|
+
width: 1.6rem;
|
|
1383
|
+
height: 1.6rem;
|
|
1384
|
+
border-radius: 50%;
|
|
1385
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
1386
|
+
border: 0.2rem solid ${({ theme }) => theme.colors.primary600};
|
|
1387
|
+
cursor: pointer;
|
|
1388
|
+
}
|
|
1389
|
+
&::-moz-range-thumb {
|
|
1390
|
+
width: 1.6rem;
|
|
1391
|
+
height: 1.6rem;
|
|
1392
|
+
border-radius: 50%;
|
|
1393
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
1394
|
+
border: 0.2rem solid ${({ theme }) => theme.colors.primary600};
|
|
1395
|
+
cursor: pointer;
|
|
1396
|
+
}
|
|
1397
|
+
&:focus-visible {
|
|
1398
|
+
outline: 0.2rem solid ${({ theme }) => theme.colors.primary600};
|
|
1399
|
+
outline-offset: 0.2rem;
|
|
1400
|
+
}
|
|
1153
1401
|
`;
|
|
1154
1402
|
var COLUMNS = { key: "blockscene:columns", min: 1, max: 5, initial: 3 };
|
|
1155
1403
|
var SHOW_FIELDS_KEY = "blockscene:show-fields";
|
|
@@ -1175,16 +1423,31 @@ var remember = (key, value) => {
|
|
|
1175
1423
|
}
|
|
1176
1424
|
};
|
|
1177
1425
|
var Frame = import_styled_components.default.div`
|
|
1178
|
-
width: 100%;
|
|
1426
|
+
width: 100%;
|
|
1427
|
+
overflow: hidden;
|
|
1428
|
+
border-radius: 4px;
|
|
1429
|
+
line-height: 0;
|
|
1179
1430
|
aspect-ratio: ${({ $fixed }) => $fixed ? "16 / 9" : "auto"};
|
|
1180
1431
|
background: ${({ theme }) => theme.colors.neutral100};
|
|
1181
|
-
img {
|
|
1432
|
+
img {
|
|
1433
|
+
width: 100%;
|
|
1434
|
+
height: auto;
|
|
1435
|
+
display: block;
|
|
1436
|
+
}
|
|
1182
1437
|
`;
|
|
1183
|
-
function Thumb({
|
|
1438
|
+
function Thumb({
|
|
1439
|
+
candidates,
|
|
1440
|
+
template,
|
|
1441
|
+
palette,
|
|
1442
|
+
onResolved,
|
|
1443
|
+
noPreview,
|
|
1444
|
+
eager,
|
|
1445
|
+
blank
|
|
1446
|
+
}) {
|
|
1184
1447
|
const key = candidates.join("|");
|
|
1185
|
-
const [state, setState] =
|
|
1448
|
+
const [state, setState] = React2.useState({ key, index: 0 });
|
|
1186
1449
|
const index = state.key === key ? state.index : 0;
|
|
1187
|
-
const resolved =
|
|
1450
|
+
const resolved = React2.useRef("");
|
|
1188
1451
|
const report = (value) => {
|
|
1189
1452
|
const tag = `${key}:${value}`;
|
|
1190
1453
|
if (resolved.current !== tag) {
|
|
@@ -1192,11 +1455,19 @@ function Thumb({ candidates, template, palette, onResolved, noPreview, eager })
|
|
|
1192
1455
|
onResolved?.(value);
|
|
1193
1456
|
}
|
|
1194
1457
|
};
|
|
1195
|
-
|
|
1458
|
+
React2.useEffect(() => {
|
|
1196
1459
|
if (index >= candidates.length) report(-1);
|
|
1197
1460
|
});
|
|
1198
|
-
if (index >= candidates.length)
|
|
1199
|
-
|
|
1461
|
+
if (index >= candidates.length)
|
|
1462
|
+
return blank ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Frame, { $fixed: true, "data-thumb": "wireframe", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1463
|
+
Wireframe,
|
|
1464
|
+
{
|
|
1465
|
+
template,
|
|
1466
|
+
palette,
|
|
1467
|
+
noPreview
|
|
1468
|
+
}
|
|
1469
|
+
) });
|
|
1470
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Frame, { "data-thumb": String(index), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1200
1471
|
"img",
|
|
1201
1472
|
{
|
|
1202
1473
|
src: candidates[index],
|
|
@@ -1210,25 +1481,68 @@ function Thumb({ candidates, template, palette, onResolved, noPreview, eager })
|
|
|
1210
1481
|
}
|
|
1211
1482
|
function Card({ entry, palette, showFields, onSelect }) {
|
|
1212
1483
|
const t = useMessages();
|
|
1213
|
-
return /* @__PURE__ */ (0,
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1485
|
+
Tile,
|
|
1486
|
+
{
|
|
1487
|
+
type: "button",
|
|
1488
|
+
onClick: onSelect,
|
|
1489
|
+
title: entry.uid,
|
|
1490
|
+
"data-testid": `blockscene-${entry.uid}`,
|
|
1491
|
+
children: [
|
|
1492
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1493
|
+
Thumb,
|
|
1494
|
+
{
|
|
1495
|
+
candidates: entry.candidates,
|
|
1496
|
+
template: entry.template,
|
|
1497
|
+
palette,
|
|
1498
|
+
noPreview: t.noPreview
|
|
1499
|
+
}
|
|
1500
|
+
),
|
|
1501
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1502
|
+
import_design_system.Typography,
|
|
1503
|
+
{
|
|
1504
|
+
variant: "pi",
|
|
1505
|
+
fontWeight: "bold",
|
|
1506
|
+
textColor: "neutral800",
|
|
1507
|
+
ellipsis: true,
|
|
1508
|
+
children: entry.label
|
|
1509
|
+
}
|
|
1510
|
+
),
|
|
1511
|
+
entry.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Clamp, { variant: "pi", textColor: "neutral600", children: entry.description }),
|
|
1512
|
+
showFields && entry.fields.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1513
|
+
import_design_system.Typography,
|
|
1514
|
+
{
|
|
1515
|
+
variant: "pi",
|
|
1516
|
+
textColor: "neutral500",
|
|
1517
|
+
style: { fontStyle: "italic" },
|
|
1518
|
+
"data-testid": "block-fields",
|
|
1519
|
+
children: entry.fields.map((f) => `${f.name} (${f.type})`).join(", ")
|
|
1520
|
+
}
|
|
1521
|
+
)
|
|
1522
|
+
]
|
|
1523
|
+
}
|
|
1524
|
+
);
|
|
1219
1525
|
}
|
|
1220
|
-
function ZoneGallery({
|
|
1526
|
+
function ZoneGallery({
|
|
1527
|
+
zone,
|
|
1528
|
+
components,
|
|
1529
|
+
add,
|
|
1530
|
+
Modal: Modal2,
|
|
1531
|
+
Toggle,
|
|
1532
|
+
get,
|
|
1533
|
+
controlled
|
|
1534
|
+
}) {
|
|
1221
1535
|
const t = useMessages();
|
|
1222
|
-
const [ownOpen, setOwnOpen] =
|
|
1536
|
+
const [ownOpen, setOwnOpen] = React2.useState(false);
|
|
1223
1537
|
const open = controlled ? controlled.open : ownOpen;
|
|
1224
1538
|
const setOpen = controlled ? controlled.onOpenChange : setOwnOpen;
|
|
1225
|
-
const [query, setQuery] =
|
|
1226
|
-
const [category, setCategory] =
|
|
1227
|
-
const [showFields, setShowFields] =
|
|
1228
|
-
const [columns, setColumns] =
|
|
1229
|
-
const [config, setConfig] =
|
|
1230
|
-
const [error, setError] =
|
|
1231
|
-
|
|
1539
|
+
const [query, setQuery] = React2.useState("");
|
|
1540
|
+
const [category, setCategory] = React2.useState("all");
|
|
1541
|
+
const [showFields, setShowFields] = React2.useState(readShowFields);
|
|
1542
|
+
const [columns, setColumns] = React2.useState(readColumns);
|
|
1543
|
+
const [config, setConfig] = React2.useState(null);
|
|
1544
|
+
const [error, setError] = React2.useState("");
|
|
1545
|
+
React2.useEffect(() => {
|
|
1232
1546
|
if (controlled) return;
|
|
1233
1547
|
const onClick = (event) => {
|
|
1234
1548
|
const button = event.target?.closest?.("button");
|
|
@@ -1240,7 +1554,7 @@ function ZoneGallery({ zone, components, add, Modal: Modal2, Toggle, get, contro
|
|
|
1240
1554
|
document.addEventListener("click", onClick, true);
|
|
1241
1555
|
return () => document.removeEventListener("click", onClick, true);
|
|
1242
1556
|
}, [controlled, zone.name, zone.label]);
|
|
1243
|
-
|
|
1557
|
+
React2.useEffect(() => {
|
|
1244
1558
|
if (!open) return;
|
|
1245
1559
|
let active = true;
|
|
1246
1560
|
setError("");
|
|
@@ -1256,7 +1570,10 @@ function ZoneGallery({ zone, components, add, Modal: Modal2, Toggle, get, contro
|
|
|
1256
1570
|
}, [open, get, t.failed]);
|
|
1257
1571
|
const entries = config ? entriesFor(zone, components, config, query, category) : [];
|
|
1258
1572
|
const categories = config ? categoriesFor(zone, components, config) : [];
|
|
1259
|
-
const total = categories.reduce(
|
|
1573
|
+
const total = categories.reduce(
|
|
1574
|
+
(sum, [, count]) => sum + count,
|
|
1575
|
+
0
|
|
1576
|
+
);
|
|
1260
1577
|
const filtering = query.trim() !== "" || category !== "all";
|
|
1261
1578
|
const reset = () => {
|
|
1262
1579
|
setQuery("");
|
|
@@ -1280,21 +1597,41 @@ function ZoneGallery({ zone, components, add, Modal: Modal2, Toggle, get, contro
|
|
|
1280
1597
|
setShowFields(value);
|
|
1281
1598
|
remember(SHOW_FIELDS_KEY, String(value));
|
|
1282
1599
|
};
|
|
1283
|
-
return /* @__PURE__ */ (0,
|
|
1600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1284
1601
|
Modal2,
|
|
1285
1602
|
{
|
|
1286
1603
|
open,
|
|
1287
1604
|
onOpenChange: setOpen,
|
|
1288
1605
|
title: t.gallery,
|
|
1289
|
-
trigger: controlled ? null : /* @__PURE__ */ (0,
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1606
|
+
trigger: controlled ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1607
|
+
import_design_system.Button,
|
|
1608
|
+
{
|
|
1609
|
+
variant: "secondary",
|
|
1610
|
+
fullWidth: true,
|
|
1611
|
+
onClick: () => setOpen(true),
|
|
1612
|
+
"data-testid": `open-gallery-${zone.name}`,
|
|
1613
|
+
children: [
|
|
1614
|
+
t.add,
|
|
1615
|
+
": ",
|
|
1616
|
+
zone.name
|
|
1617
|
+
]
|
|
1618
|
+
}
|
|
1619
|
+
),
|
|
1620
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
|
|
1621
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
|
|
1622
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1623
|
+
import_design_system.Typography,
|
|
1624
|
+
{
|
|
1625
|
+
variant: "omega",
|
|
1626
|
+
fontWeight: "bold",
|
|
1627
|
+
textColor: "neutral800",
|
|
1628
|
+
style: { whiteSpace: "nowrap" },
|
|
1629
|
+
"data-testid": `block-count-${zone.name}`,
|
|
1630
|
+
"aria-live": "polite",
|
|
1631
|
+
children: filtering ? t.f("countFiltered", { shown: entries.length, total }) : t.f("countAll", { count: total })
|
|
1632
|
+
}
|
|
1633
|
+
),
|
|
1634
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Box, { style: { flex: 1, minWidth: "12rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1298
1635
|
import_design_system.Searchbar,
|
|
1299
1636
|
{
|
|
1300
1637
|
name: `block-search-${zone.name}`,
|
|
@@ -1306,14 +1643,54 @@ function ZoneGallery({ zone, components, add, Modal: Modal2, Toggle, get, contro
|
|
|
1306
1643
|
children: t.search
|
|
1307
1644
|
}
|
|
1308
1645
|
) }),
|
|
1309
|
-
categories.length > 1 && /* @__PURE__ */ (0,
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1646
|
+
categories.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1647
|
+
import_design_system.Box,
|
|
1648
|
+
{
|
|
1649
|
+
style: { width: "14rem" },
|
|
1650
|
+
"data-testid": `block-category-${zone.name}`,
|
|
1651
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1652
|
+
import_design_system.SingleSelect,
|
|
1653
|
+
{
|
|
1654
|
+
"aria-label": t.filterCategory,
|
|
1655
|
+
size: "S",
|
|
1656
|
+
value: category,
|
|
1657
|
+
onChange: (value) => setCategory(String(value)),
|
|
1658
|
+
children: [
|
|
1659
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.SingleSelectOption, { value: "all", children: t.allCategories }),
|
|
1660
|
+
categories.map(([name, count]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1661
|
+
import_design_system.SingleSelectOption,
|
|
1662
|
+
{
|
|
1663
|
+
value: name,
|
|
1664
|
+
children: `${name} (${count})`
|
|
1665
|
+
},
|
|
1666
|
+
name
|
|
1667
|
+
))
|
|
1668
|
+
]
|
|
1669
|
+
}
|
|
1670
|
+
)
|
|
1671
|
+
}
|
|
1672
|
+
),
|
|
1673
|
+
Toggle && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1674
|
+
Toggle,
|
|
1675
|
+
{
|
|
1676
|
+
name: `block-fields-${zone.name}`,
|
|
1677
|
+
label: t.showFields,
|
|
1678
|
+
hint: t.showFieldsHint,
|
|
1679
|
+
value: showFields,
|
|
1680
|
+
onChange: changeShowFields
|
|
1681
|
+
}
|
|
1682
|
+
),
|
|
1683
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { gap: 2, alignItems: "center", children: [
|
|
1684
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1685
|
+
import_design_system.Typography,
|
|
1686
|
+
{
|
|
1687
|
+
variant: "pi",
|
|
1688
|
+
textColor: "neutral600",
|
|
1689
|
+
id: `block-columns-${zone.name}`,
|
|
1690
|
+
children: t.columns
|
|
1691
|
+
}
|
|
1692
|
+
),
|
|
1693
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1317
1694
|
Slider,
|
|
1318
1695
|
{
|
|
1319
1696
|
type: "range",
|
|
@@ -1326,16 +1703,52 @@ function ZoneGallery({ zone, components, add, Modal: Modal2, Toggle, get, contro
|
|
|
1326
1703
|
onChange: (e) => changeColumns(Number(e.target.value))
|
|
1327
1704
|
}
|
|
1328
1705
|
),
|
|
1329
|
-
/* @__PURE__ */ (0,
|
|
1706
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Typography, { variant: "pi", fontWeight: "bold", children: columns })
|
|
1330
1707
|
] })
|
|
1331
1708
|
] }),
|
|
1332
|
-
/* @__PURE__ */ (0,
|
|
1333
|
-
error ? /* @__PURE__ */ (0,
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1709
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Typography, { variant: "pi", textColor: "neutral600", children: t.example }),
|
|
1710
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Typography, { role: "alert", textColor: "danger600", children: error }) : !config ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Typography, { children: t.loading }) : entries.length ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1711
|
+
import_design_system.Flex,
|
|
1712
|
+
{
|
|
1713
|
+
direction: "column",
|
|
1714
|
+
alignItems: "stretch",
|
|
1715
|
+
gap: 4,
|
|
1716
|
+
style: { overflowY: "auto", maxHeight: "60vh", padding: "4px" },
|
|
1717
|
+
children: groupEntries(entries).map(
|
|
1718
|
+
({ category: name, entries: items }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1719
|
+
import_design_system.Flex,
|
|
1720
|
+
{
|
|
1721
|
+
direction: "column",
|
|
1722
|
+
alignItems: "stretch",
|
|
1723
|
+
gap: 2,
|
|
1724
|
+
children: [
|
|
1725
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1726
|
+
import_design_system.Typography,
|
|
1727
|
+
{
|
|
1728
|
+
variant: "sigma",
|
|
1729
|
+
textColor: "neutral600",
|
|
1730
|
+
"data-testid": `block-group-${name}`,
|
|
1731
|
+
children: `${name} (${items.length})`
|
|
1732
|
+
}
|
|
1733
|
+
),
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Columns, { $columns: columns, children: items.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1735
|
+
Card,
|
|
1736
|
+
{
|
|
1737
|
+
entry,
|
|
1738
|
+
palette: config.palette,
|
|
1739
|
+
showFields,
|
|
1740
|
+
onSelect: () => select(entry.uid)
|
|
1741
|
+
}
|
|
1742
|
+
) }, entry.uid)) })
|
|
1743
|
+
]
|
|
1744
|
+
},
|
|
1745
|
+
name
|
|
1746
|
+
)
|
|
1747
|
+
)
|
|
1748
|
+
}
|
|
1749
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { gap: 3, alignItems: "center", children: [
|
|
1750
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Typography, { children: t.empty }),
|
|
1751
|
+
filtering && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Button, { variant: "tertiary", size: "S", onClick: reset, children: t.clear })
|
|
1339
1752
|
] })
|
|
1340
1753
|
] })
|
|
1341
1754
|
}
|
|
@@ -1349,13 +1762,19 @@ var storage = () => {
|
|
|
1349
1762
|
}
|
|
1350
1763
|
};
|
|
1351
1764
|
var memoryBase = () => `${window.location.origin}${window.location.pathname.split("/content-manager")[0]}`;
|
|
1352
|
-
function useInitialAccordions({
|
|
1353
|
-
|
|
1354
|
-
|
|
1765
|
+
function useInitialAccordions({
|
|
1766
|
+
zones,
|
|
1767
|
+
editor,
|
|
1768
|
+
docKey,
|
|
1769
|
+
contentType,
|
|
1770
|
+
userId
|
|
1771
|
+
}) {
|
|
1772
|
+
const applied = React2.useRef("");
|
|
1773
|
+
const user = React2.useRef(userId);
|
|
1355
1774
|
user.current = userId;
|
|
1356
|
-
const latest =
|
|
1775
|
+
const latest = React2.useRef(zones);
|
|
1357
1776
|
latest.current = zones;
|
|
1358
|
-
|
|
1777
|
+
React2.useEffect(() => {
|
|
1359
1778
|
if (!editor?.enabled || !docKey || applied.current === docKey) return;
|
|
1360
1779
|
if (applied.current.startsWith(`${contentType}:new`) && docKey.startsWith(`${contentType}:`)) {
|
|
1361
1780
|
applied.current = docKey;
|
|
@@ -1364,7 +1783,10 @@ function useInitialAccordions({ zones, editor, docKey, contentType, userId }) {
|
|
|
1364
1783
|
applied.current = docKey;
|
|
1365
1784
|
let tries = 0;
|
|
1366
1785
|
const cancel = (event) => {
|
|
1367
|
-
if (event.target?.closest?.(
|
|
1786
|
+
if (event.target?.closest?.(
|
|
1787
|
+
'button[aria-expanded], [data-testid^="block-accordion-controls-"]'
|
|
1788
|
+
))
|
|
1789
|
+
stop();
|
|
1368
1790
|
};
|
|
1369
1791
|
const stop = () => {
|
|
1370
1792
|
clearInterval(timer);
|
|
@@ -1382,8 +1804,17 @@ function useInitialAccordions({ zones, editor, docKey, contentType, userId }) {
|
|
|
1382
1804
|
for (const zone of pending) {
|
|
1383
1805
|
const list = findZoneList(zone.label);
|
|
1384
1806
|
if (!list) continue;
|
|
1385
|
-
const key = memoryKey({
|
|
1386
|
-
|
|
1807
|
+
const key = memoryKey({
|
|
1808
|
+
base: memoryBase(),
|
|
1809
|
+
userId: user.current,
|
|
1810
|
+
contentType,
|
|
1811
|
+
zone: zone.name
|
|
1812
|
+
});
|
|
1813
|
+
setAll(
|
|
1814
|
+
list,
|
|
1815
|
+
initialState(editor, readMemory(storage(), key)) === "open",
|
|
1816
|
+
import_react_dom2.unstable_batchedUpdates
|
|
1817
|
+
);
|
|
1387
1818
|
}
|
|
1388
1819
|
}, 200);
|
|
1389
1820
|
return stop;
|
|
@@ -1394,27 +1825,84 @@ function ZoneControls({ zone, editor, contentType, userId }) {
|
|
|
1394
1825
|
if (!zone.count || !(editor.showOpenAll || editor.showCloseAll)) return null;
|
|
1395
1826
|
const apply = (open) => {
|
|
1396
1827
|
const list = findZoneList(zone.label);
|
|
1397
|
-
if (list) setAll(list, open,
|
|
1398
|
-
writeMemory(
|
|
1828
|
+
if (list) setAll(list, open, import_react_dom2.unstable_batchedUpdates);
|
|
1829
|
+
writeMemory(
|
|
1830
|
+
storage(),
|
|
1831
|
+
memoryKey({ base: memoryBase(), userId, contentType, zone: zone.name }),
|
|
1832
|
+
open ? "open" : "closed"
|
|
1833
|
+
);
|
|
1399
1834
|
};
|
|
1400
|
-
return /* @__PURE__ */ (0,
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1836
|
+
import_design_system.Flex,
|
|
1837
|
+
{
|
|
1838
|
+
gap: 2,
|
|
1839
|
+
wrap: "wrap",
|
|
1840
|
+
"data-testid": `block-accordion-controls-${zone.name}`,
|
|
1841
|
+
children: [
|
|
1842
|
+
editor.showOpenAll && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1843
|
+
import_design_system.Button,
|
|
1844
|
+
{
|
|
1845
|
+
type: "button",
|
|
1846
|
+
variant: "tertiary",
|
|
1847
|
+
size: "S",
|
|
1848
|
+
onClick: () => apply(true),
|
|
1849
|
+
children: t.openAll
|
|
1850
|
+
}
|
|
1851
|
+
),
|
|
1852
|
+
editor.showCloseAll && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1853
|
+
import_design_system.Button,
|
|
1854
|
+
{
|
|
1855
|
+
type: "button",
|
|
1856
|
+
variant: "tertiary",
|
|
1857
|
+
size: "S",
|
|
1858
|
+
onClick: () => apply(false),
|
|
1859
|
+
children: t.closeAll
|
|
1860
|
+
}
|
|
1861
|
+
)
|
|
1862
|
+
]
|
|
1863
|
+
}
|
|
1864
|
+
);
|
|
1404
1865
|
}
|
|
1405
|
-
function Gallery({
|
|
1866
|
+
function Gallery({
|
|
1867
|
+
zones,
|
|
1868
|
+
editor,
|
|
1869
|
+
docKey,
|
|
1870
|
+
contentType,
|
|
1871
|
+
userId,
|
|
1872
|
+
catalog,
|
|
1873
|
+
...props
|
|
1874
|
+
}) {
|
|
1406
1875
|
useInitialAccordions({ zones, editor, docKey, contentType, userId });
|
|
1407
|
-
return /* @__PURE__ */ (0,
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
|
|
1877
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1878
|
+
RowPreviews,
|
|
1879
|
+
{
|
|
1880
|
+
zones,
|
|
1881
|
+
components: props.components,
|
|
1882
|
+
catalog,
|
|
1883
|
+
Modal: props.Modal
|
|
1884
|
+
}
|
|
1885
|
+
),
|
|
1886
|
+
zones.map((zone) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
|
1887
|
+
!zone.full && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ZoneGallery, { zone, ...props }),
|
|
1888
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1889
|
+
ZoneControls,
|
|
1890
|
+
{
|
|
1891
|
+
zone,
|
|
1892
|
+
editor,
|
|
1893
|
+
contentType,
|
|
1894
|
+
userId
|
|
1895
|
+
}
|
|
1896
|
+
)
|
|
1897
|
+
] }, zone.name))
|
|
1898
|
+
] });
|
|
1411
1899
|
}
|
|
1412
1900
|
|
|
1413
1901
|
// admin/Settings.tsx
|
|
1414
|
-
var
|
|
1902
|
+
var React3 = __toESM(require("react"));
|
|
1415
1903
|
var import_design_system2 = require("@strapi/design-system");
|
|
1416
1904
|
var import_styled_components2 = __toESM(require("styled-components"));
|
|
1417
|
-
var
|
|
1905
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1418
1906
|
var COLOR2 = /^#[0-9A-Fa-f]{6}$/;
|
|
1419
1907
|
var Grid = import_styled_components2.default.div` display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 16px; `;
|
|
1420
1908
|
var Card2 = import_styled_components2.default.div`
|
|
@@ -1427,8 +1915,8 @@ var Bar = import_styled_components2.default.div`
|
|
|
1427
1915
|
box-shadow: 0 1px 4px rgba(33, 33, 52, 0.1);
|
|
1428
1916
|
`;
|
|
1429
1917
|
function useMainRect(anchor) {
|
|
1430
|
-
const [rect, setRect] =
|
|
1431
|
-
|
|
1918
|
+
const [rect, setRect] = React3.useState({ left: 0, width: 0 });
|
|
1919
|
+
React3.useEffect(() => {
|
|
1432
1920
|
const read = () => {
|
|
1433
1921
|
let host = document.getElementById("main-content");
|
|
1434
1922
|
for (let el = anchor.current?.parentElement; !host && el; el = el.parentElement) if (["auto", "scroll"].includes(getComputedStyle(el).overflowY) && el.scrollHeight > el.clientHeight) host = el;
|
|
@@ -1445,11 +1933,11 @@ var Swatches = import_styled_components2.default.div` display: grid; grid-templa
|
|
|
1445
1933
|
var Label = import_styled_components2.default.label` display: flex; flex-direction: column; gap: 4px; font-size: 12px; `;
|
|
1446
1934
|
function ColorField({ name, label, value, onChange, disabled }) {
|
|
1447
1935
|
const valid = COLOR2.test(value);
|
|
1448
|
-
return /* @__PURE__ */ (0,
|
|
1449
|
-
/* @__PURE__ */ (0,
|
|
1450
|
-
/* @__PURE__ */ (0,
|
|
1451
|
-
/* @__PURE__ */ (0,
|
|
1452
|
-
/* @__PURE__ */ (0,
|
|
1936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Label, { children: [
|
|
1937
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
|
|
1938
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { gap: 2, children: [
|
|
1939
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("input", { type: "color", "aria-label": label, value: valid ? value : "#000000", disabled, onChange: (e) => onChange(e.target.value.toUpperCase()), style: { width: 40, height: 32, padding: 0, border: 0, background: "none" } }),
|
|
1940
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1453
1941
|
"input",
|
|
1454
1942
|
{
|
|
1455
1943
|
name,
|
|
@@ -1469,18 +1957,18 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
1469
1957
|
const t = useMessages();
|
|
1470
1958
|
const { get, put } = useClient();
|
|
1471
1959
|
const { canRead, canUpdate, isLoading } = usePermissions2();
|
|
1472
|
-
const [data, setData] =
|
|
1473
|
-
const [catalog, setCatalog] =
|
|
1474
|
-
const [settings, setSettings] =
|
|
1475
|
-
const [media, setMedia] =
|
|
1476
|
-
const [sources, setSources] =
|
|
1477
|
-
const [dirty, setDirty] =
|
|
1478
|
-
const [saving, setSaving] =
|
|
1479
|
-
const [status, setStatus] =
|
|
1480
|
-
const [failed, setFailed] =
|
|
1481
|
-
const [filter, setFilter] =
|
|
1482
|
-
const [picking, setPicking] =
|
|
1483
|
-
|
|
1960
|
+
const [data, setData] = React3.useState(null);
|
|
1961
|
+
const [catalog, setCatalog] = React3.useState(null);
|
|
1962
|
+
const [settings, setSettings] = React3.useState(null);
|
|
1963
|
+
const [media, setMedia] = React3.useState({});
|
|
1964
|
+
const [sources, setSources] = React3.useState({});
|
|
1965
|
+
const [dirty, setDirty] = React3.useState(false);
|
|
1966
|
+
const [saving, setSaving] = React3.useState(false);
|
|
1967
|
+
const [status, setStatus] = React3.useState("");
|
|
1968
|
+
const [failed, setFailed] = React3.useState(false);
|
|
1969
|
+
const [filter, setFilter] = React3.useState("");
|
|
1970
|
+
const [picking, setPicking] = React3.useState(null);
|
|
1971
|
+
React3.useEffect(() => {
|
|
1484
1972
|
if (!canRead || isLoading) return;
|
|
1485
1973
|
let active = true;
|
|
1486
1974
|
Promise.all([get("/blockscene/settings"), get("/blockscene/catalog")]).then(([s, c]) => {
|
|
@@ -1528,35 +2016,35 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
1528
2016
|
return index === 0 && manual ? t.manual : t.automatic;
|
|
1529
2017
|
};
|
|
1530
2018
|
const ready = !isLoading && canRead && !failed && settings && catalog;
|
|
1531
|
-
const header =
|
|
1532
|
-
const [floating, setFloating] =
|
|
2019
|
+
const header = React3.useRef(null);
|
|
2020
|
+
const [floating, setFloating] = React3.useState(false);
|
|
1533
2021
|
const main = useMainRect(header);
|
|
1534
|
-
|
|
2022
|
+
React3.useEffect(() => {
|
|
1535
2023
|
const el = header.current;
|
|
1536
2024
|
if (!el || typeof IntersectionObserver === "undefined") return;
|
|
1537
2025
|
const observer = new IntersectionObserver(([entry]) => setFloating(!entry.isIntersecting && entry.boundingClientRect.top < 0));
|
|
1538
2026
|
observer.observe(el);
|
|
1539
2027
|
return () => observer.disconnect();
|
|
1540
2028
|
}, [ready]);
|
|
1541
|
-
const controls = (suffix) => ready && /* @__PURE__ */ (0,
|
|
1542
|
-
/* @__PURE__ */ (0,
|
|
1543
|
-
/* @__PURE__ */ (0,
|
|
2029
|
+
const controls = (suffix) => ready && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
|
|
2030
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { role: "status", "aria-live": "polite", textColor: dirty ? "warning700" : "neutral600", "data-testid": `${dirty ? "unsaved-indicator" : "save-status"}${suffix}`, children: dirty ? t.unsaved : status || t.noChanges }),
|
|
2031
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Button, { onClick: save, disabled: !canUpdate || invalid || !dirty, loading: saving, "data-testid": `save-blockscene-settings${suffix}`, children: t.save })
|
|
1544
2032
|
] });
|
|
1545
|
-
return /* @__PURE__ */ (0,
|
|
1546
|
-
/* @__PURE__ */ (0,
|
|
1547
|
-
/* @__PURE__ */ (0,
|
|
2033
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Box, { padding: 8, background: "neutral100", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { direction: "column", alignItems: "stretch", gap: 5, children: [
|
|
2034
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref: header, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
|
|
2035
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "alpha", tag: "h1", children: t.settingsTitle }),
|
|
1548
2036
|
controls("")
|
|
1549
2037
|
] }) }),
|
|
1550
|
-
floating && main.width > 0 && /* @__PURE__ */ (0,
|
|
1551
|
-
/* @__PURE__ */ (0,
|
|
2038
|
+
floating && main.width > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Bar, { style: { left: main.left, width: main.width }, "data-testid": "settings-floating-bar", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
|
|
2039
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "beta", tag: "p", children: t.settingsTitle }),
|
|
1552
2040
|
controls("-floating")
|
|
1553
2041
|
] }) }),
|
|
1554
|
-
/* @__PURE__ */ (0,
|
|
1555
|
-
isLoading ? /* @__PURE__ */ (0,
|
|
1556
|
-
data.disabled && /* @__PURE__ */ (0,
|
|
1557
|
-
/* @__PURE__ */ (0,
|
|
1558
|
-
/* @__PURE__ */ (0,
|
|
1559
|
-
/* @__PURE__ */ (0,
|
|
2042
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { textColor: "neutral600", children: t.settingsIntro }),
|
|
2043
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { children: "\u2026" }) : !canRead ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { role: "alert", children: t.denied }) : failed ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { role: "alert", children: t.loadFailed }) : !settings || !catalog ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { children: t.loading }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
2044
|
+
data.disabled && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Box, { padding: 4, background: "warning100", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { role: "alert", textColor: "warning700", children: t.disabledByServer }) }),
|
|
2045
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
2046
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "beta", tag: "h2", children: t.palette }),
|
|
2047
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Swatches, { children: Object.keys(DEFAULT_PALETTE).map((key) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1560
2048
|
ColorField,
|
|
1561
2049
|
{
|
|
1562
2050
|
name: `palette-${key}`,
|
|
@@ -1570,33 +2058,33 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
1570
2058
|
},
|
|
1571
2059
|
key
|
|
1572
2060
|
)) }),
|
|
1573
|
-
invalid && /* @__PURE__ */ (0,
|
|
1574
|
-
/* @__PURE__ */ (0,
|
|
1575
|
-
/* @__PURE__ */ (0,
|
|
1576
|
-
/* @__PURE__ */ (0,
|
|
1577
|
-
/* @__PURE__ */ (0,
|
|
2061
|
+
invalid && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { role: "alert", textColor: "danger600", children: t.invalidColor }),
|
|
2062
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: t.previewLabel }),
|
|
2063
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Swatches, { "data-testid": "palette-preview", children: TEMPLATES.map((template) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { direction: "column", gap: 1, children: [
|
|
2064
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Box, { style: { aspectRatio: "16 / 9", overflow: "hidden" }, hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Wireframe, { template, palette: settings.palette }) }),
|
|
2065
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: t.templates[template] })
|
|
1578
2066
|
] }, template)) }),
|
|
1579
|
-
/* @__PURE__ */ (0,
|
|
2067
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Button, { variant: "tertiary", size: "S", disabled: !canUpdate, onClick: () => update((s) => {
|
|
1580
2068
|
s.palette = { ...DEFAULT_PALETTE };
|
|
1581
2069
|
return s;
|
|
1582
2070
|
}), children: t.resetPalette }) })
|
|
1583
2071
|
] }) }),
|
|
1584
|
-
/* @__PURE__ */ (0,
|
|
1585
|
-
/* @__PURE__ */ (0,
|
|
1586
|
-
/* @__PURE__ */ (0,
|
|
2072
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
2073
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "beta", tag: "h2", children: t.editor }),
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ToggleField2, { name: "editor-enabled", label: t.enabled, value: editor.enabled, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
1587
2075
|
s.editor.enabled = v;
|
|
1588
2076
|
return s;
|
|
1589
2077
|
}) }),
|
|
1590
|
-
/* @__PURE__ */ (0,
|
|
1591
|
-
/* @__PURE__ */ (0,
|
|
2078
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: t.enabledHelp }),
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ToggleField2, { name: "editor-showOpenAll", label: t.showOpenAll, value: editor.showOpenAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
1592
2080
|
s.editor.showOpenAll = v;
|
|
1593
2081
|
return s;
|
|
1594
2082
|
}) }),
|
|
1595
|
-
/* @__PURE__ */ (0,
|
|
2083
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ToggleField2, { name: "editor-showCloseAll", label: t.showCloseAll, value: editor.showCloseAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
1596
2084
|
s.editor.showCloseAll = v;
|
|
1597
2085
|
return s;
|
|
1598
2086
|
}) }),
|
|
1599
|
-
/* @__PURE__ */ (0,
|
|
2087
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1600
2088
|
SelectField2,
|
|
1601
2089
|
{
|
|
1602
2090
|
name: "editor-initialState",
|
|
@@ -1610,9 +2098,9 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
1610
2098
|
})
|
|
1611
2099
|
}
|
|
1612
2100
|
),
|
|
1613
|
-
/* @__PURE__ */ (0,
|
|
1614
|
-
previewSupported ? /* @__PURE__ */ (0,
|
|
1615
|
-
/* @__PURE__ */ (0,
|
|
2101
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: t.rememberHelp }),
|
|
2102
|
+
previewSupported ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
2103
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1616
2104
|
TextField,
|
|
1617
2105
|
{
|
|
1618
2106
|
name: "editor-previewUrl",
|
|
@@ -1626,8 +2114,8 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
1626
2114
|
})
|
|
1627
2115
|
}
|
|
1628
2116
|
),
|
|
1629
|
-
/* @__PURE__ */ (0,
|
|
1630
|
-
/* @__PURE__ */ (0,
|
|
2117
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: t.previewUrlHelp }),
|
|
2118
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1631
2119
|
SelectField2,
|
|
1632
2120
|
{
|
|
1633
2121
|
name: "editor-previewMode",
|
|
@@ -1641,26 +2129,26 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
1641
2129
|
})
|
|
1642
2130
|
}
|
|
1643
2131
|
),
|
|
1644
|
-
/* @__PURE__ */ (0,
|
|
1645
|
-
data.blockPreviewAvailable && /* @__PURE__ */ (0,
|
|
1646
|
-
/* @__PURE__ */ (0,
|
|
2132
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: t.previewModeHelp }),
|
|
2133
|
+
data.blockPreviewAvailable && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
2134
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ToggleField2, { name: "editor-blockPreviewInForm", label: t.blockPreviewInForm, value: editor.blockPreviewInForm, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
1647
2135
|
s.editor.blockPreviewInForm = v;
|
|
1648
2136
|
return s;
|
|
1649
2137
|
}) }),
|
|
1650
|
-
/* @__PURE__ */ (0,
|
|
2138
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
|
|
1651
2139
|
] })
|
|
1652
|
-
] }) : /* @__PURE__ */ (0,
|
|
2140
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: t.previewV4 })
|
|
1653
2141
|
] }) }),
|
|
1654
|
-
/* @__PURE__ */ (0,
|
|
1655
|
-
/* @__PURE__ */ (0,
|
|
1656
|
-
/* @__PURE__ */ (0,
|
|
1657
|
-
/* @__PURE__ */ (0,
|
|
1658
|
-
/* @__PURE__ */ (0,
|
|
2142
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
2143
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "beta", tag: "h2", children: t.components }),
|
|
2144
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Searchbar, { name: "component-filter", value: filter, placeholder: t.filter, clearLabel: t.clear, onClear: () => setFilter(""), onChange: (e) => setFilter(e.target.value), children: t.filter }),
|
|
2145
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", "data-testid": "components-count", children: t.f("countAll", { count: components.length }) }),
|
|
2146
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Grid, { "data-testid": "components-grid", children: components.map((component) => {
|
|
1659
2147
|
const entry = settings.components[component.uid] || {};
|
|
1660
2148
|
const meta = { ...catalog.components?.[component.uid] || {}, ...media[component.uid] || {} };
|
|
1661
2149
|
const candidates = candidatesFor(component.uid, meta, catalog);
|
|
1662
|
-
return /* @__PURE__ */ (0,
|
|
1663
|
-
/* @__PURE__ */ (0,
|
|
2150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Card2, { "data-testid": `settings-${component.uid}`, children: [
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1664
2152
|
Thumb,
|
|
1665
2153
|
{
|
|
1666
2154
|
candidates,
|
|
@@ -1671,23 +2159,23 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
1671
2159
|
onResolved: (index) => setSources((current) => current[component.uid] === index ? current : { ...current, [component.uid]: index })
|
|
1672
2160
|
}
|
|
1673
2161
|
),
|
|
1674
|
-
/* @__PURE__ */ (0,
|
|
1675
|
-
/* @__PURE__ */ (0,
|
|
1676
|
-
/* @__PURE__ */ (0,
|
|
2162
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { fontWeight: "bold", textColor: "neutral800", children: component.displayName }),
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
1677
2165
|
component.uid,
|
|
1678
2166
|
" \xB7 ",
|
|
1679
2167
|
component.category
|
|
1680
2168
|
] }),
|
|
1681
|
-
/* @__PURE__ */ (0,
|
|
2169
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Typography, { variant: "pi", "data-testid": `source-${component.uid}`, children: [
|
|
1682
2170
|
t.source,
|
|
1683
2171
|
": ",
|
|
1684
2172
|
sourceOf(component.uid, Boolean(meta.manualImage)),
|
|
1685
2173
|
meta.manualName ? ` (${meta.manualName})` : ""
|
|
1686
2174
|
] }),
|
|
1687
|
-
meta.manualMissing && /* @__PURE__ */ (0,
|
|
1688
|
-
/* @__PURE__ */ (0,
|
|
1689
|
-
/* @__PURE__ */ (0,
|
|
1690
|
-
entry.mediaId && /* @__PURE__ */ (0,
|
|
2175
|
+
meta.manualMissing && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", role: "alert", textColor: "danger600", children: t.brokenMedia }),
|
|
2176
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { gap: 2, wrap: "wrap", children: [
|
|
2177
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Button, { variant: "secondary", size: "S", disabled: !canUpdate || saving, onClick: () => setPicking(component.uid), children: entry.mediaId ? t.replace : t.choose }),
|
|
2178
|
+
entry.mediaId && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Button, { variant: "tertiary", size: "S", disabled: !canUpdate || saving, onClick: () => {
|
|
1691
2179
|
update((s) => {
|
|
1692
2180
|
delete s.components[component.uid]?.mediaId;
|
|
1693
2181
|
if (!Object.keys(s.components[component.uid] || {}).length) delete s.components[component.uid];
|
|
@@ -1700,7 +2188,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
1700
2188
|
});
|
|
1701
2189
|
}, children: t.useAutomatic })
|
|
1702
2190
|
] }),
|
|
1703
|
-
/* @__PURE__ */ (0,
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1704
2192
|
SelectField2,
|
|
1705
2193
|
{
|
|
1706
2194
|
name: `template-${component.uid}`,
|
|
@@ -1718,7 +2206,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
1718
2206
|
] }, component.uid);
|
|
1719
2207
|
}) })
|
|
1720
2208
|
] }) }),
|
|
1721
|
-
picking && /* @__PURE__ */ (0,
|
|
2209
|
+
picking && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MediaPicker2, { onClose: () => setPicking(null), onSelect: (asset) => {
|
|
1722
2210
|
const uid = picking;
|
|
1723
2211
|
setPicking(null);
|
|
1724
2212
|
if (!asset?.id) return;
|
|
@@ -1747,10 +2235,10 @@ function register(app, Component, to) {
|
|
|
1747
2235
|
}
|
|
1748
2236
|
|
|
1749
2237
|
// admin/catalog.ts
|
|
1750
|
-
var
|
|
2238
|
+
var React4 = __toESM(require("react"));
|
|
1751
2239
|
function useCatalog(get) {
|
|
1752
|
-
const [catalog, setCatalog] =
|
|
1753
|
-
|
|
2240
|
+
const [catalog, setCatalog] = React4.useState(null);
|
|
2241
|
+
React4.useEffect(() => {
|
|
1754
2242
|
let active = true;
|
|
1755
2243
|
get("/blockscene/catalog").then(({ data }) => {
|
|
1756
2244
|
if (active) setCatalog(data);
|
|
@@ -1765,14 +2253,14 @@ function useCatalog(get) {
|
|
|
1765
2253
|
}
|
|
1766
2254
|
|
|
1767
2255
|
// admin/strapi4.tsx
|
|
1768
|
-
var
|
|
2256
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1769
2257
|
function Modal({ open, onOpenChange, trigger, title, children }) {
|
|
1770
|
-
const id =
|
|
1771
|
-
return /* @__PURE__ */ (0,
|
|
2258
|
+
const id = React5.useId();
|
|
2259
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1772
2260
|
trigger,
|
|
1773
|
-
open && /* @__PURE__ */ (0,
|
|
1774
|
-
/* @__PURE__ */ (0,
|
|
1775
|
-
/* @__PURE__ */ (0,
|
|
2261
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_design_system3.ModalLayout, { onClose: () => onOpenChange(false), labelledBy: id, children: [
|
|
2262
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.ModalHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Typography, { id, variant: "beta", children: title }) }),
|
|
2263
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.ModalBody, { children })
|
|
1776
2264
|
] })
|
|
1777
2265
|
] });
|
|
1778
2266
|
}
|
|
@@ -1783,17 +2271,37 @@ function Picker() {
|
|
|
1783
2271
|
const components = c.allLayoutData?.components || {};
|
|
1784
2272
|
const schema = c.layout || c.allLayoutData?.contentType;
|
|
1785
2273
|
const allowed = (c.isCreatingEntry ? c.createActionAllowedFields : c.updateActionAllowedFields) || [];
|
|
1786
|
-
const zones = editableZones(
|
|
2274
|
+
const zones = editableZones(
|
|
2275
|
+
schema,
|
|
2276
|
+
c.modifiedData,
|
|
2277
|
+
(name) => allowed.includes(name) && schema?.metadatas?.[name]?.edit?.editable !== false,
|
|
2278
|
+
!c.addComponentToDynamicZone
|
|
2279
|
+
).map((zone) => ({
|
|
2280
|
+
...zone,
|
|
2281
|
+
label: schema?.metadatas?.[zone.name]?.edit?.label || zone.name
|
|
2282
|
+
}));
|
|
1787
2283
|
const add = (zone, uid) => {
|
|
1788
2284
|
const close = catalog?.groups?.[uid];
|
|
1789
|
-
if (!canInsert(zone, uid, c.modifiedData, components, close ? 2 : 1) || close && !zone.components.includes(close))
|
|
1790
|
-
|
|
1791
|
-
|
|
2285
|
+
if (!canInsert(zone, uid, c.modifiedData, components, close ? 2 : 1) || close && !zone.components.includes(close))
|
|
2286
|
+
return false;
|
|
2287
|
+
c.addComponentToDynamicZone(
|
|
2288
|
+
zone.name,
|
|
2289
|
+
components[uid],
|
|
2290
|
+
components,
|
|
2291
|
+
Boolean(c.formErrors?.[zone.name])
|
|
2292
|
+
);
|
|
2293
|
+
if (close)
|
|
2294
|
+
c.addComponentToDynamicZone(
|
|
2295
|
+
zone.name,
|
|
2296
|
+
components[close],
|
|
2297
|
+
components,
|
|
2298
|
+
Boolean(c.formErrors?.[zone.name])
|
|
2299
|
+
);
|
|
1792
2300
|
return true;
|
|
1793
2301
|
};
|
|
1794
2302
|
if (!catalog?.editor?.enabled) return null;
|
|
1795
2303
|
const docKey = `${c.slug}:${c.isCreatingEntry ? "new" : c.initialData?.id}:${c.initialData?.locale || ""}`;
|
|
1796
|
-
return /* @__PURE__ */ (0,
|
|
2304
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1797
2305
|
Gallery,
|
|
1798
2306
|
{
|
|
1799
2307
|
zones,
|
|
@@ -1803,17 +2311,44 @@ function Picker() {
|
|
|
1803
2311
|
Toggle: ToggleField,
|
|
1804
2312
|
get,
|
|
1805
2313
|
editor: catalog.editor,
|
|
2314
|
+
catalog,
|
|
1806
2315
|
docKey,
|
|
1807
2316
|
contentType: c.slug,
|
|
1808
2317
|
userId: import_helper_plugin.auth.getUserInfo?.()?.id
|
|
1809
2318
|
}
|
|
1810
2319
|
);
|
|
1811
2320
|
}
|
|
1812
|
-
var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ */ (0,
|
|
1813
|
-
/* @__PURE__ */ (0,
|
|
1814
|
-
|
|
2321
|
+
var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_design_system3.Flex, { gap: 3, children: [
|
|
2322
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2323
|
+
import_design_system3.Switch,
|
|
2324
|
+
{
|
|
2325
|
+
name,
|
|
2326
|
+
"aria-label": label,
|
|
2327
|
+
selected: Boolean(value),
|
|
2328
|
+
disabled,
|
|
2329
|
+
onChange: () => onChange(!value)
|
|
2330
|
+
}
|
|
2331
|
+
),
|
|
2332
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Typography, { children: label })
|
|
1815
2333
|
] });
|
|
1816
|
-
var SelectField = ({
|
|
2334
|
+
var SelectField = ({
|
|
2335
|
+
name,
|
|
2336
|
+
label,
|
|
2337
|
+
value,
|
|
2338
|
+
onChange,
|
|
2339
|
+
disabled,
|
|
2340
|
+
options
|
|
2341
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2342
|
+
import_design_system3.SingleSelect,
|
|
2343
|
+
{
|
|
2344
|
+
name,
|
|
2345
|
+
label,
|
|
2346
|
+
value,
|
|
2347
|
+
disabled,
|
|
2348
|
+
onChange: (v) => onChange(String(v)),
|
|
2349
|
+
children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.SingleSelectOption, { value: o.value, children: o.label }, o.value))
|
|
2350
|
+
}
|
|
2351
|
+
);
|
|
1817
2352
|
function MediaPicker({ onClose, onSelect }) {
|
|
1818
2353
|
const { components } = (0, import_helper_plugin.useLibrary)();
|
|
1819
2354
|
const Dialog = components?.["media-library"];
|
|
@@ -1821,13 +2356,34 @@ function MediaPicker({ onClose, onSelect }) {
|
|
|
1821
2356
|
onClose();
|
|
1822
2357
|
return null;
|
|
1823
2358
|
}
|
|
1824
|
-
return /* @__PURE__ */ (0,
|
|
2359
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2360
|
+
Dialog,
|
|
2361
|
+
{
|
|
2362
|
+
onClose,
|
|
2363
|
+
allowedTypes: ["images"],
|
|
2364
|
+
onSelectAssets: (assets) => onSelect(assets?.[0])
|
|
2365
|
+
}
|
|
2366
|
+
);
|
|
1825
2367
|
}
|
|
1826
2368
|
function usePermissions() {
|
|
1827
2369
|
const { allowedActions, isLoading } = (0, import_helper_plugin.useRBAC)(permissions);
|
|
1828
|
-
return {
|
|
2370
|
+
return {
|
|
2371
|
+
canRead: allowedActions.canRead,
|
|
2372
|
+
canUpdate: allowedActions.canUpdate,
|
|
2373
|
+
isLoading
|
|
2374
|
+
};
|
|
1829
2375
|
}
|
|
1830
|
-
var SettingsPage = () => /* @__PURE__ */ (0,
|
|
2376
|
+
var SettingsPage = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2377
|
+
Settings,
|
|
2378
|
+
{
|
|
2379
|
+
useClient: import_helper_plugin.useFetchClient,
|
|
2380
|
+
usePermissions,
|
|
2381
|
+
MediaPicker,
|
|
2382
|
+
ToggleField,
|
|
2383
|
+
SelectField,
|
|
2384
|
+
previewSupported: false
|
|
2385
|
+
}
|
|
2386
|
+
);
|
|
1831
2387
|
var strapi4_default = {
|
|
1832
2388
|
register(app) {
|
|
1833
2389
|
register(app, SettingsPage, "/settings/blockscene");
|
|
@@ -1835,6 +2391,9 @@ var strapi4_default = {
|
|
|
1835
2391
|
},
|
|
1836
2392
|
registerTrads,
|
|
1837
2393
|
bootstrap(app) {
|
|
1838
|
-
app.injectContentManagerComponent("editView", "right-links", {
|
|
2394
|
+
app.injectContentManagerComponent("editView", "right-links", {
|
|
2395
|
+
name: "blockscene",
|
|
2396
|
+
Component: Picker
|
|
2397
|
+
});
|
|
1839
2398
|
}
|
|
1840
2399
|
};
|