@aduptive/strapi-blockscene 2.0.0-alpha.1 → 2.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 +17 -5
- package/dist/admin.cjs +1307 -372
- package/dist/admin.mjs +1346 -374
- package/package.json +3 -5
package/dist/admin.cjs
CHANGED
|
@@ -141,30 +141,35 @@ __export(strapi5_exports, {
|
|
|
141
141
|
default: () => strapi5_default
|
|
142
142
|
});
|
|
143
143
|
module.exports = __toCommonJS(strapi5_exports);
|
|
144
|
-
var
|
|
145
|
-
var
|
|
144
|
+
var React7 = __toESM(require("react"));
|
|
145
|
+
var import_design_system5 = require("@strapi/design-system");
|
|
146
146
|
var import_admin3 = require("@strapi/strapi/admin");
|
|
147
147
|
var import_strapi_admin2 = require("@strapi/content-manager/strapi-admin");
|
|
148
148
|
|
|
149
149
|
// admin/Gallery.tsx
|
|
150
|
-
var
|
|
151
|
-
var
|
|
150
|
+
var React2 = __toESM(require("react"));
|
|
151
|
+
var import_react_dom2 = require("react-dom");
|
|
152
152
|
var import_design_system = require("@strapi/design-system");
|
|
153
153
|
var import_styled_components = __toESM(require("styled-components"));
|
|
154
154
|
|
|
155
155
|
// admin/model.mjs
|
|
156
156
|
var import_fractional_indexing = require("fractional-indexing");
|
|
157
157
|
function componentDefaults(schema, components, stack = []) {
|
|
158
|
-
if (!schema || stack.includes(schema))
|
|
158
|
+
if (!schema || stack.includes(schema))
|
|
159
|
+
throw new Error("Invalid recursive component defaults");
|
|
159
160
|
const row = {};
|
|
160
161
|
for (const [name, attr] of Object.entries(schema.attributes || {})) {
|
|
161
162
|
if (Object.hasOwn(attr, "default")) {
|
|
162
163
|
const value = structuredClone(attr.default);
|
|
163
164
|
if (attr.type === "password") row[name] = "";
|
|
164
|
-
else if (attr.type === "relation")
|
|
165
|
+
else if (attr.type === "relation")
|
|
166
|
+
row[name] = { connect: [], disconnect: [] };
|
|
165
167
|
else if (value !== null || attr.type === "boolean") row[name] = value;
|
|
166
168
|
} else if (attr.type === "component" && attr.required) {
|
|
167
|
-
const create = () => componentDefaults(components[attr.component], components, [
|
|
169
|
+
const create = () => componentDefaults(components[attr.component], components, [
|
|
170
|
+
...stack,
|
|
171
|
+
schema
|
|
172
|
+
]);
|
|
168
173
|
if (attr.repeatable) {
|
|
169
174
|
const keys = (0, import_fractional_indexing.generateNKeysBetween)(null, null, attr.min || 0);
|
|
170
175
|
row[name] = keys.map((key) => ({ ...create(), __temp_key__: key }));
|
|
@@ -175,27 +180,58 @@ function componentDefaults(schema, components, stack = []) {
|
|
|
175
180
|
}
|
|
176
181
|
function editableZones(schema, values, canEdit, disabled = false) {
|
|
177
182
|
if (disabled) return [];
|
|
178
|
-
return Object.entries(schema?.attributes || {}).filter(
|
|
179
|
-
|
|
180
|
-
|
|
183
|
+
return Object.entries(schema?.attributes || {}).filter(
|
|
184
|
+
([name, attr]) => attr.type === "dynamiczone" && !attr.conditions && canEdit(name)
|
|
185
|
+
).map(([name, attr]) => {
|
|
186
|
+
const rows = Array.isArray(values?.[name]) ? values[name] : [];
|
|
187
|
+
return {
|
|
188
|
+
name,
|
|
189
|
+
components: attr.components || [],
|
|
190
|
+
max: attr.max,
|
|
191
|
+
count: rows.length,
|
|
192
|
+
uids: rows.map(
|
|
193
|
+
(row) => row && typeof row.__component === "string" ? row.__component : ""
|
|
194
|
+
),
|
|
195
|
+
full: rows.length >= (attr.max ?? Infinity)
|
|
196
|
+
};
|
|
181
197
|
});
|
|
182
198
|
}
|
|
183
199
|
function canInsert(zone, uid, values, components, count = 1) {
|
|
184
|
-
return Boolean(
|
|
200
|
+
return Boolean(
|
|
201
|
+
zone?.components.includes(uid) && components[uid] && (Array.isArray(values?.[zone.name]) ? values[zone.name].length : 0) + count <= (zone.max ?? Infinity)
|
|
202
|
+
);
|
|
185
203
|
}
|
|
186
204
|
function candidatesFor(uid, meta = {}, config = {}) {
|
|
187
205
|
const version = config.previewVersion ? `?v=${encodeURIComponent(config.previewVersion)}` : "";
|
|
188
206
|
const base = (config.previewBaseUrl || "/block-previews").replace(/\/$/, "");
|
|
189
|
-
return [
|
|
207
|
+
return [
|
|
208
|
+
meta.manualImage,
|
|
209
|
+
meta.image,
|
|
210
|
+
`${base}/${encodeURIComponent(uid)}.webp${version}`
|
|
211
|
+
].filter(Boolean);
|
|
190
212
|
}
|
|
191
|
-
var SYSTEM_FIELDS = [
|
|
213
|
+
var SYSTEM_FIELDS = [
|
|
214
|
+
"id",
|
|
215
|
+
"documentId",
|
|
216
|
+
"createdAt",
|
|
217
|
+
"updatedAt",
|
|
218
|
+
"publishedAt",
|
|
219
|
+
"createdBy",
|
|
220
|
+
"updatedBy",
|
|
221
|
+
"locale",
|
|
222
|
+
"localizations"
|
|
223
|
+
];
|
|
192
224
|
var fieldType = (attr) => attr?.type === "customField" ? String(attr.customField || "").includes("CKEditor") ? "richtext" : "customField" : attr?.type || "unknown";
|
|
193
225
|
var fieldsOf = (schema) => Object.entries(schema?.attributes || {}).filter(([name]) => !SYSTEM_FIELDS.includes(name)).map(([name, attr]) => ({ name, type: fieldType(attr) }));
|
|
194
226
|
var categoryOf = (uid, schema, meta = {}) => meta.category || schema?.category || uid.split(".")[0];
|
|
195
227
|
var byCategory = (a, b) => (a === "admin" ? 1 : 0) - (b === "admin" ? 1 : 0) || a.localeCompare(b);
|
|
228
|
+
var pickable = (zone, config) => {
|
|
229
|
+
const closers = Object.values(config.groups || {});
|
|
230
|
+
return zone.components.filter((uid) => !closers.includes(uid));
|
|
231
|
+
};
|
|
196
232
|
function entriesFor(zone, components, config, query, category = "all") {
|
|
197
233
|
const needle = query.trim().toLocaleLowerCase();
|
|
198
|
-
return zone.
|
|
234
|
+
return pickable(zone, config).flatMap((uid) => {
|
|
199
235
|
const schema = components[uid];
|
|
200
236
|
if (!schema) return [];
|
|
201
237
|
const meta = config.components?.[uid] || {};
|
|
@@ -210,11 +246,13 @@ function entriesFor(zone, components, config, query, category = "all") {
|
|
|
210
246
|
};
|
|
211
247
|
if (category !== "all" && entry.category !== category) return [];
|
|
212
248
|
return `${entry.label} ${entry.description} ${entry.category} ${uid} ${meta.keywords || ""}`.toLocaleLowerCase().includes(needle) ? [entry] : [];
|
|
213
|
-
}).sort(
|
|
249
|
+
}).sort(
|
|
250
|
+
(a, b) => byCategory(a.category, b.category) || a.label.localeCompare(b.label)
|
|
251
|
+
);
|
|
214
252
|
}
|
|
215
253
|
function categoriesFor(zone, components, config) {
|
|
216
254
|
const counts = /* @__PURE__ */ new Map();
|
|
217
|
-
for (const uid of zone
|
|
255
|
+
for (const uid of pickable(zone, config)) {
|
|
218
256
|
const schema = components[uid];
|
|
219
257
|
if (!schema) continue;
|
|
220
258
|
const c = categoryOf(uid, schema, config.components?.[uid] || {});
|
|
@@ -224,8 +262,12 @@ function categoriesFor(zone, components, config) {
|
|
|
224
262
|
}
|
|
225
263
|
function groupEntries(entries) {
|
|
226
264
|
const map = /* @__PURE__ */ new Map();
|
|
227
|
-
for (const entry of entries)
|
|
228
|
-
|
|
265
|
+
for (const entry of entries)
|
|
266
|
+
map.set(entry.category, [...map.get(entry.category) || [], entry]);
|
|
267
|
+
return [...map.entries()].map(([category, items]) => ({
|
|
268
|
+
category,
|
|
269
|
+
entries: items
|
|
270
|
+
}));
|
|
229
271
|
}
|
|
230
272
|
function memoryKey({ base = "", userId, contentType, zone }) {
|
|
231
273
|
if (!userId || !contentType || !zone) return null;
|
|
@@ -241,7 +283,8 @@ function readMemory(storage2, key) {
|
|
|
241
283
|
}
|
|
242
284
|
function writeMemory(storage2, key, value) {
|
|
243
285
|
try {
|
|
244
|
-
if (key && (value === "open" || value === "closed"))
|
|
286
|
+
if (key && (value === "open" || value === "closed"))
|
|
287
|
+
storage2?.setItem(key, value);
|
|
245
288
|
} catch {
|
|
246
289
|
}
|
|
247
290
|
}
|
|
@@ -327,6 +370,10 @@ function Wireframe({ template, palette, className, noPreview }) {
|
|
|
327
370
|
);
|
|
328
371
|
}
|
|
329
372
|
|
|
373
|
+
// admin/RowPreviews.tsx
|
|
374
|
+
var React = __toESM(require("react"));
|
|
375
|
+
var import_react_dom = require("react-dom");
|
|
376
|
+
|
|
330
377
|
// admin/messages.ts
|
|
331
378
|
var import_react_intl = require("react-intl");
|
|
332
379
|
|
|
@@ -441,7 +488,8 @@ var en_default = {
|
|
|
441
488
|
columns: "Columns",
|
|
442
489
|
noPreview: "no preview",
|
|
443
490
|
"templates.none": "No preview",
|
|
444
|
-
noChanges: "No unsaved changes"
|
|
491
|
+
noChanges: "No unsaved changes",
|
|
492
|
+
rowPreview: "Open the {label} preview"
|
|
445
493
|
};
|
|
446
494
|
|
|
447
495
|
// admin/translations/pt-BR.json
|
|
@@ -555,7 +603,8 @@ var pt_BR_default = {
|
|
|
555
603
|
columns: "Colunas",
|
|
556
604
|
noPreview: "sem preview",
|
|
557
605
|
"templates.none": "Sem preview",
|
|
558
|
-
noChanges: "Sem altera\xE7\xF5es pendentes"
|
|
606
|
+
noChanges: "Sem altera\xE7\xF5es pendentes",
|
|
607
|
+
rowPreview: "Abrir a pr\xE9via de {label}"
|
|
559
608
|
};
|
|
560
609
|
|
|
561
610
|
// admin/translations/pt.json
|
|
@@ -669,7 +718,8 @@ var pt_default = {
|
|
|
669
718
|
columns: "Colunas",
|
|
670
719
|
noPreview: "sem pr\xE9-visualiza\xE7\xE3o",
|
|
671
720
|
"templates.none": "Sem pr\xE9-visualiza\xE7\xE3o",
|
|
672
|
-
noChanges: "Sem altera\xE7\xF5es pendentes"
|
|
721
|
+
noChanges: "Sem altera\xE7\xF5es pendentes",
|
|
722
|
+
rowPreview: "Abrir a pr\xE9-visualiza\xE7\xE3o de {label}"
|
|
673
723
|
};
|
|
674
724
|
|
|
675
725
|
// admin/translations/fr.json
|
|
@@ -783,7 +833,8 @@ var fr_default = {
|
|
|
783
833
|
columns: "Colonnes",
|
|
784
834
|
noPreview: "pas d\u2019aper\xE7u",
|
|
785
835
|
"templates.none": "Pas d\u2019aper\xE7u",
|
|
786
|
-
noChanges: "Aucune modification en attente"
|
|
836
|
+
noChanges: "Aucune modification en attente",
|
|
837
|
+
rowPreview: "Ouvrir l\u2019aper\xE7u de {label}"
|
|
787
838
|
};
|
|
788
839
|
|
|
789
840
|
// admin/translations/es.json
|
|
@@ -897,7 +948,8 @@ var es_default = {
|
|
|
897
948
|
columns: "Columnas",
|
|
898
949
|
noPreview: "sin vista previa",
|
|
899
950
|
"templates.none": "Sin vista previa",
|
|
900
|
-
noChanges: "Sin cambios pendientes"
|
|
951
|
+
noChanges: "Sin cambios pendientes",
|
|
952
|
+
rowPreview: "Abrir la vista previa de {label}"
|
|
901
953
|
};
|
|
902
954
|
|
|
903
955
|
// admin/translations/de.json
|
|
@@ -1011,7 +1063,8 @@ var de_default = {
|
|
|
1011
1063
|
columns: "Spalten",
|
|
1012
1064
|
noPreview: "keine Vorschau",
|
|
1013
1065
|
"templates.none": "Keine Vorschau",
|
|
1014
|
-
noChanges: "Keine ungespeicherten \xC4nderungen"
|
|
1066
|
+
noChanges: "Keine ungespeicherten \xC4nderungen",
|
|
1067
|
+
rowPreview: "Vorschau von {label} \xF6ffnen"
|
|
1015
1068
|
};
|
|
1016
1069
|
|
|
1017
1070
|
// admin/translations/it.json
|
|
@@ -1125,7 +1178,8 @@ var it_default = {
|
|
|
1125
1178
|
columns: "Colonne",
|
|
1126
1179
|
noPreview: "nessuna anteprima",
|
|
1127
1180
|
"templates.none": "Nessuna anteprima",
|
|
1128
|
-
noChanges: "Nessuna modifica in sospeso"
|
|
1181
|
+
noChanges: "Nessuna modifica in sospeso",
|
|
1182
|
+
rowPreview: "Apri l\u2019anteprima di {label}"
|
|
1129
1183
|
};
|
|
1130
1184
|
|
|
1131
1185
|
// admin/translations/nl.json
|
|
@@ -1239,7 +1293,8 @@ var nl_default = {
|
|
|
1239
1293
|
columns: "Kolommen",
|
|
1240
1294
|
noPreview: "geen voorbeeld",
|
|
1241
1295
|
"templates.none": "Geen voorbeeld",
|
|
1242
|
-
noChanges: "Geen niet-opgeslagen wijzigingen"
|
|
1296
|
+
noChanges: "Geen niet-opgeslagen wijzigingen",
|
|
1297
|
+
rowPreview: "Voorbeeld van {label} openen"
|
|
1243
1298
|
};
|
|
1244
1299
|
|
|
1245
1300
|
// admin/messages.ts
|
|
@@ -1259,26 +1314,224 @@ function useMessages() {
|
|
|
1259
1314
|
return out;
|
|
1260
1315
|
}
|
|
1261
1316
|
|
|
1262
|
-
// admin/
|
|
1317
|
+
// admin/RowPreviews.tsx
|
|
1263
1318
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1319
|
+
var ATTR = "data-blockscene-row-thumb";
|
|
1320
|
+
function useAnchors(zones, onOpen) {
|
|
1321
|
+
const [anchors, setAnchors] = React.useState([]);
|
|
1322
|
+
const open = React.useRef(onOpen);
|
|
1323
|
+
open.current = onOpen;
|
|
1324
|
+
const latest = React.useRef(zones);
|
|
1325
|
+
latest.current = zones;
|
|
1326
|
+
const sync = React.useRef(() => {
|
|
1327
|
+
});
|
|
1328
|
+
sync.current = () => {
|
|
1329
|
+
const next = [];
|
|
1330
|
+
for (const zone of latest.current) {
|
|
1331
|
+
const list = zone.uids?.length ? findZoneList(zone.label) : null;
|
|
1332
|
+
if (!list) continue;
|
|
1333
|
+
toggles(list).forEach((button, index) => {
|
|
1334
|
+
const uid = zone.uids[index];
|
|
1335
|
+
if (!uid) return;
|
|
1336
|
+
let el = button.querySelector(
|
|
1337
|
+
`:scope > [${ATTR}]`
|
|
1338
|
+
);
|
|
1339
|
+
if (!el) {
|
|
1340
|
+
el = document.createElement("span");
|
|
1341
|
+
el.setAttribute(ATTR, "");
|
|
1342
|
+
el.style.cssText = "display:inline-flex;align-items:center";
|
|
1343
|
+
const activate = (event) => {
|
|
1344
|
+
if (!event.currentTarget.getAttribute("role"))
|
|
1345
|
+
return;
|
|
1346
|
+
event.preventDefault();
|
|
1347
|
+
event.stopPropagation();
|
|
1348
|
+
open.current(
|
|
1349
|
+
String(event.currentTarget.dataset.uid || "")
|
|
1350
|
+
);
|
|
1351
|
+
};
|
|
1352
|
+
el.addEventListener("click", activate, true);
|
|
1353
|
+
el.addEventListener(
|
|
1354
|
+
"keydown",
|
|
1355
|
+
(event) => {
|
|
1356
|
+
if (event.key === "Enter" || event.key === " ") activate(event);
|
|
1357
|
+
},
|
|
1358
|
+
true
|
|
1359
|
+
);
|
|
1360
|
+
button.insertBefore(el, button.firstChild);
|
|
1361
|
+
}
|
|
1362
|
+
el.dataset.uid = uid;
|
|
1363
|
+
next.push({ el, uid, zone: zone.name, index });
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
for (const el of document.querySelectorAll(`[${ATTR}]`))
|
|
1367
|
+
if (!next.some((a) => a.el === el)) el.remove();
|
|
1368
|
+
setAnchors(
|
|
1369
|
+
(prev) => prev.length === next.length && prev.every((a, i) => a.el === next[i].el && a.uid === next[i].uid) ? prev : next
|
|
1370
|
+
);
|
|
1371
|
+
};
|
|
1372
|
+
React.useEffect(() => {
|
|
1373
|
+
sync.current();
|
|
1374
|
+
});
|
|
1375
|
+
React.useEffect(() => {
|
|
1376
|
+
let frame = 0;
|
|
1377
|
+
const observer = new MutationObserver(() => {
|
|
1378
|
+
if (frame) return;
|
|
1379
|
+
frame = requestAnimationFrame(() => {
|
|
1380
|
+
frame = 0;
|
|
1381
|
+
sync.current();
|
|
1382
|
+
});
|
|
1383
|
+
});
|
|
1384
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
1385
|
+
return () => {
|
|
1386
|
+
observer.disconnect();
|
|
1387
|
+
cancelAnimationFrame(frame);
|
|
1388
|
+
for (const el of document.querySelectorAll(`[${ATTR}]`)) el.remove();
|
|
1389
|
+
};
|
|
1390
|
+
}, []);
|
|
1391
|
+
return anchors;
|
|
1392
|
+
}
|
|
1393
|
+
function RowPreviews({ zones, components, catalog, Modal: Modal3 }) {
|
|
1394
|
+
const t = useMessages();
|
|
1395
|
+
const [resolved, setResolved] = React.useState({});
|
|
1396
|
+
const [open, setOpen] = React.useState(null);
|
|
1397
|
+
const anchors = useAnchors(zones, (uid) => setOpen(uid));
|
|
1398
|
+
const candidates = (uid) => candidatesFor(uid, catalog?.components?.[uid] || {}, catalog || {});
|
|
1399
|
+
const label = (uid) => catalog?.components?.[uid]?.label || components?.[uid]?.info?.displayName || uid;
|
|
1400
|
+
const srcOf = (uid) => candidates(uid)[resolved[uid] ?? -1] || "";
|
|
1401
|
+
React.useEffect(() => {
|
|
1402
|
+
for (const { el, uid } of anchors) {
|
|
1403
|
+
if (srcOf(uid)) {
|
|
1404
|
+
el.setAttribute("role", "button");
|
|
1405
|
+
el.setAttribute("tabindex", "0");
|
|
1406
|
+
el.setAttribute("aria-label", t.f("rowPreview", { label: label(uid) }));
|
|
1407
|
+
el.style.cursor = "zoom-in";
|
|
1408
|
+
} else
|
|
1409
|
+
for (const name of ["role", "tabindex", "aria-label"])
|
|
1410
|
+
el.removeAttribute(name);
|
|
1411
|
+
}
|
|
1412
|
+
});
|
|
1413
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
1414
|
+
anchors.map(
|
|
1415
|
+
(a) => (0, import_react_dom.createPortal)(
|
|
1416
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1417
|
+
"span",
|
|
1418
|
+
{
|
|
1419
|
+
style: {
|
|
1420
|
+
display: "block",
|
|
1421
|
+
width: "6.4rem",
|
|
1422
|
+
marginRight: "8px",
|
|
1423
|
+
flex: "0 0 auto"
|
|
1424
|
+
},
|
|
1425
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1426
|
+
Thumb,
|
|
1427
|
+
{
|
|
1428
|
+
candidates: candidates(a.uid),
|
|
1429
|
+
blank: true,
|
|
1430
|
+
onResolved: (index) => setResolved(
|
|
1431
|
+
(prev) => prev[a.uid] === index ? prev : { ...prev, [a.uid]: index }
|
|
1432
|
+
)
|
|
1433
|
+
}
|
|
1434
|
+
)
|
|
1435
|
+
}
|
|
1436
|
+
),
|
|
1437
|
+
a.el,
|
|
1438
|
+
`${a.zone}:${a.index}`
|
|
1439
|
+
)
|
|
1440
|
+
),
|
|
1441
|
+
open && srcOf(open) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1442
|
+
Modal3,
|
|
1443
|
+
{
|
|
1444
|
+
open: true,
|
|
1445
|
+
onOpenChange: (value) => {
|
|
1446
|
+
if (!value) setOpen(null);
|
|
1447
|
+
},
|
|
1448
|
+
trigger: null,
|
|
1449
|
+
title: label(open),
|
|
1450
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1451
|
+
"img",
|
|
1452
|
+
{
|
|
1453
|
+
src: srcOf(open),
|
|
1454
|
+
alt: "",
|
|
1455
|
+
style: {
|
|
1456
|
+
display: "block",
|
|
1457
|
+
margin: "0 auto",
|
|
1458
|
+
maxWidth: "100%",
|
|
1459
|
+
maxHeight: "75vh",
|
|
1460
|
+
objectFit: "contain"
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
)
|
|
1464
|
+
}
|
|
1465
|
+
)
|
|
1466
|
+
] });
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
// admin/Gallery.tsx
|
|
1470
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1264
1471
|
var Columns = import_styled_components.default.div`
|
|
1265
|
-
column-count: ${({ $columns }) => $columns};
|
|
1266
|
-
|
|
1472
|
+
column-count: ${({ $columns }) => $columns};
|
|
1473
|
+
column-gap: 12px;
|
|
1474
|
+
> * {
|
|
1475
|
+
break-inside: avoid;
|
|
1476
|
+
-webkit-column-break-inside: avoid;
|
|
1477
|
+
margin-bottom: 12px;
|
|
1478
|
+
}
|
|
1267
1479
|
`;
|
|
1268
1480
|
var Tile = import_styled_components.default.button`
|
|
1269
|
-
display: flex;
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1481
|
+
display: flex;
|
|
1482
|
+
flex-direction: column;
|
|
1483
|
+
gap: 8px;
|
|
1484
|
+
text-align: left;
|
|
1485
|
+
width: 100%;
|
|
1486
|
+
padding: 8px;
|
|
1487
|
+
border: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
1488
|
+
border-radius: 4px;
|
|
1489
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
1490
|
+
cursor: pointer;
|
|
1491
|
+
&:hover {
|
|
1492
|
+
border-color: ${({ theme }) => theme.colors.primary600};
|
|
1493
|
+
}
|
|
1494
|
+
&:focus-visible {
|
|
1495
|
+
outline: 2px solid ${({ theme }) => theme.colors.primary600};
|
|
1496
|
+
outline-offset: 2px;
|
|
1497
|
+
}
|
|
1498
|
+
`;
|
|
1499
|
+
var Clamp = (0, import_styled_components.default)(import_design_system.Typography)`
|
|
1500
|
+
display: -webkit-box;
|
|
1501
|
+
-webkit-line-clamp: 2;
|
|
1502
|
+
-webkit-box-orient: vertical;
|
|
1503
|
+
overflow: hidden;
|
|
1274
1504
|
`;
|
|
1275
|
-
var Clamp = (0, import_styled_components.default)(import_design_system.Typography)` display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; `;
|
|
1276
1505
|
var Slider = import_styled_components.default.input`
|
|
1277
|
-
appearance: none;
|
|
1506
|
+
appearance: none;
|
|
1507
|
+
-webkit-appearance: none;
|
|
1508
|
+
width: 8rem;
|
|
1509
|
+
height: 0.4rem;
|
|
1510
|
+
border-radius: 0.4rem;
|
|
1511
|
+
cursor: pointer;
|
|
1278
1512
|
background: ${({ theme, $percent }) => `linear-gradient(to right, ${theme.colors.primary600} ${$percent}%, ${theme.colors.neutral200} ${$percent}%)`};
|
|
1279
|
-
&::-webkit-slider-thumb {
|
|
1280
|
-
|
|
1281
|
-
|
|
1513
|
+
&::-webkit-slider-thumb {
|
|
1514
|
+
appearance: none;
|
|
1515
|
+
-webkit-appearance: none;
|
|
1516
|
+
width: 1.6rem;
|
|
1517
|
+
height: 1.6rem;
|
|
1518
|
+
border-radius: 50%;
|
|
1519
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
1520
|
+
border: 0.2rem solid ${({ theme }) => theme.colors.primary600};
|
|
1521
|
+
cursor: pointer;
|
|
1522
|
+
}
|
|
1523
|
+
&::-moz-range-thumb {
|
|
1524
|
+
width: 1.6rem;
|
|
1525
|
+
height: 1.6rem;
|
|
1526
|
+
border-radius: 50%;
|
|
1527
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
1528
|
+
border: 0.2rem solid ${({ theme }) => theme.colors.primary600};
|
|
1529
|
+
cursor: pointer;
|
|
1530
|
+
}
|
|
1531
|
+
&:focus-visible {
|
|
1532
|
+
outline: 0.2rem solid ${({ theme }) => theme.colors.primary600};
|
|
1533
|
+
outline-offset: 0.2rem;
|
|
1534
|
+
}
|
|
1282
1535
|
`;
|
|
1283
1536
|
var COLUMNS = { key: "blockscene:columns", min: 1, max: 5, initial: 3 };
|
|
1284
1537
|
var SHOW_FIELDS_KEY = "blockscene:show-fields";
|
|
@@ -1304,16 +1557,31 @@ var remember = (key, value) => {
|
|
|
1304
1557
|
}
|
|
1305
1558
|
};
|
|
1306
1559
|
var Frame = import_styled_components.default.div`
|
|
1307
|
-
width: 100%;
|
|
1560
|
+
width: 100%;
|
|
1561
|
+
overflow: hidden;
|
|
1562
|
+
border-radius: 4px;
|
|
1563
|
+
line-height: 0;
|
|
1308
1564
|
aspect-ratio: ${({ $fixed }) => $fixed ? "16 / 9" : "auto"};
|
|
1309
1565
|
background: ${({ theme }) => theme.colors.neutral100};
|
|
1310
|
-
img {
|
|
1566
|
+
img {
|
|
1567
|
+
width: 100%;
|
|
1568
|
+
height: auto;
|
|
1569
|
+
display: block;
|
|
1570
|
+
}
|
|
1311
1571
|
`;
|
|
1312
|
-
function Thumb({
|
|
1572
|
+
function Thumb({
|
|
1573
|
+
candidates,
|
|
1574
|
+
template,
|
|
1575
|
+
palette,
|
|
1576
|
+
onResolved,
|
|
1577
|
+
noPreview,
|
|
1578
|
+
eager,
|
|
1579
|
+
blank
|
|
1580
|
+
}) {
|
|
1313
1581
|
const key = candidates.join("|");
|
|
1314
|
-
const [state, setState] =
|
|
1582
|
+
const [state, setState] = React2.useState({ key, index: 0 });
|
|
1315
1583
|
const index = state.key === key ? state.index : 0;
|
|
1316
|
-
const resolved =
|
|
1584
|
+
const resolved = React2.useRef("");
|
|
1317
1585
|
const report = (value) => {
|
|
1318
1586
|
const tag = `${key}:${value}`;
|
|
1319
1587
|
if (resolved.current !== tag) {
|
|
@@ -1321,11 +1589,19 @@ function Thumb({ candidates, template, palette, onResolved, noPreview, eager })
|
|
|
1321
1589
|
onResolved?.(value);
|
|
1322
1590
|
}
|
|
1323
1591
|
};
|
|
1324
|
-
|
|
1592
|
+
React2.useEffect(() => {
|
|
1325
1593
|
if (index >= candidates.length) report(-1);
|
|
1326
1594
|
});
|
|
1327
|
-
if (index >= candidates.length)
|
|
1328
|
-
|
|
1595
|
+
if (index >= candidates.length)
|
|
1596
|
+
return blank ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Frame, { $fixed: true, "data-thumb": "wireframe", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1597
|
+
Wireframe,
|
|
1598
|
+
{
|
|
1599
|
+
template,
|
|
1600
|
+
palette,
|
|
1601
|
+
noPreview
|
|
1602
|
+
}
|
|
1603
|
+
) });
|
|
1604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Frame, { "data-thumb": String(index), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1329
1605
|
"img",
|
|
1330
1606
|
{
|
|
1331
1607
|
src: candidates[index],
|
|
@@ -1339,28 +1615,90 @@ function Thumb({ candidates, template, palette, onResolved, noPreview, eager })
|
|
|
1339
1615
|
}
|
|
1340
1616
|
function Card({ entry, palette, showFields, onSelect }) {
|
|
1341
1617
|
const t = useMessages();
|
|
1342
|
-
return /* @__PURE__ */ (0,
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1619
|
+
Tile,
|
|
1620
|
+
{
|
|
1621
|
+
type: "button",
|
|
1622
|
+
onClick: onSelect,
|
|
1623
|
+
title: entry.uid,
|
|
1624
|
+
"data-testid": `blockscene-${entry.uid}`,
|
|
1625
|
+
children: [
|
|
1626
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1627
|
+
Thumb,
|
|
1628
|
+
{
|
|
1629
|
+
candidates: entry.candidates,
|
|
1630
|
+
template: entry.template,
|
|
1631
|
+
palette,
|
|
1632
|
+
noPreview: t.noPreview
|
|
1633
|
+
}
|
|
1634
|
+
),
|
|
1635
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1636
|
+
import_design_system.Typography,
|
|
1637
|
+
{
|
|
1638
|
+
variant: "pi",
|
|
1639
|
+
fontWeight: "bold",
|
|
1640
|
+
textColor: "neutral800",
|
|
1641
|
+
ellipsis: true,
|
|
1642
|
+
children: entry.label
|
|
1643
|
+
}
|
|
1644
|
+
),
|
|
1645
|
+
entry.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Clamp, { variant: "pi", textColor: "neutral600", children: entry.description }),
|
|
1646
|
+
showFields && entry.fields.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1647
|
+
import_design_system.Typography,
|
|
1648
|
+
{
|
|
1649
|
+
variant: "pi",
|
|
1650
|
+
textColor: "neutral500",
|
|
1651
|
+
style: { fontStyle: "italic" },
|
|
1652
|
+
"data-testid": "block-fields",
|
|
1653
|
+
children: entry.fields.map((f) => `${f.name} (${f.type})`).join(", ")
|
|
1654
|
+
}
|
|
1655
|
+
)
|
|
1656
|
+
]
|
|
1657
|
+
}
|
|
1658
|
+
);
|
|
1348
1659
|
}
|
|
1349
|
-
function PickerModal({
|
|
1350
|
-
|
|
1660
|
+
function PickerModal({
|
|
1661
|
+
zone,
|
|
1662
|
+
components,
|
|
1663
|
+
open,
|
|
1664
|
+
onOpenChange,
|
|
1665
|
+
onSelect,
|
|
1666
|
+
Modal: Modal3,
|
|
1667
|
+
Toggle,
|
|
1668
|
+
get
|
|
1669
|
+
}) {
|
|
1670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1671
|
+
ZoneGallery,
|
|
1672
|
+
{
|
|
1673
|
+
zone,
|
|
1674
|
+
components,
|
|
1675
|
+
Modal: Modal3,
|
|
1676
|
+
Toggle,
|
|
1677
|
+
get,
|
|
1678
|
+
controlled: { open, onOpenChange, onSelect }
|
|
1679
|
+
}
|
|
1680
|
+
);
|
|
1351
1681
|
}
|
|
1352
|
-
function ZoneGallery({
|
|
1682
|
+
function ZoneGallery({
|
|
1683
|
+
zone,
|
|
1684
|
+
components,
|
|
1685
|
+
add,
|
|
1686
|
+
Modal: Modal3,
|
|
1687
|
+
Toggle,
|
|
1688
|
+
get,
|
|
1689
|
+
controlled
|
|
1690
|
+
}) {
|
|
1353
1691
|
const t = useMessages();
|
|
1354
|
-
const [ownOpen, setOwnOpen] =
|
|
1692
|
+
const [ownOpen, setOwnOpen] = React2.useState(false);
|
|
1355
1693
|
const open = controlled ? controlled.open : ownOpen;
|
|
1356
1694
|
const setOpen = controlled ? controlled.onOpenChange : setOwnOpen;
|
|
1357
|
-
const [query, setQuery] =
|
|
1358
|
-
const [category, setCategory] =
|
|
1359
|
-
const [showFields, setShowFields] =
|
|
1360
|
-
const [columns, setColumns] =
|
|
1361
|
-
const [config, setConfig] =
|
|
1362
|
-
const [error, setError] =
|
|
1363
|
-
|
|
1695
|
+
const [query, setQuery] = React2.useState("");
|
|
1696
|
+
const [category, setCategory] = React2.useState("all");
|
|
1697
|
+
const [showFields, setShowFields] = React2.useState(readShowFields);
|
|
1698
|
+
const [columns, setColumns] = React2.useState(readColumns);
|
|
1699
|
+
const [config, setConfig] = React2.useState(null);
|
|
1700
|
+
const [error, setError] = React2.useState("");
|
|
1701
|
+
React2.useEffect(() => {
|
|
1364
1702
|
if (controlled) return;
|
|
1365
1703
|
const onClick = (event) => {
|
|
1366
1704
|
const button = event.target?.closest?.("button");
|
|
@@ -1372,7 +1710,7 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1372
1710
|
document.addEventListener("click", onClick, true);
|
|
1373
1711
|
return () => document.removeEventListener("click", onClick, true);
|
|
1374
1712
|
}, [controlled, zone.name, zone.label]);
|
|
1375
|
-
|
|
1713
|
+
React2.useEffect(() => {
|
|
1376
1714
|
if (!open) return;
|
|
1377
1715
|
let active = true;
|
|
1378
1716
|
setError("");
|
|
@@ -1388,7 +1726,10 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1388
1726
|
}, [open, get, t.failed]);
|
|
1389
1727
|
const entries = config ? entriesFor(zone, components, config, query, category) : [];
|
|
1390
1728
|
const categories = config ? categoriesFor(zone, components, config) : [];
|
|
1391
|
-
const total = categories.reduce(
|
|
1729
|
+
const total = categories.reduce(
|
|
1730
|
+
(sum, [, count]) => sum + count,
|
|
1731
|
+
0
|
|
1732
|
+
);
|
|
1392
1733
|
const filtering = query.trim() !== "" || category !== "all";
|
|
1393
1734
|
const reset = () => {
|
|
1394
1735
|
setQuery("");
|
|
@@ -1412,21 +1753,41 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1412
1753
|
setShowFields(value);
|
|
1413
1754
|
remember(SHOW_FIELDS_KEY, String(value));
|
|
1414
1755
|
};
|
|
1415
|
-
return /* @__PURE__ */ (0,
|
|
1756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1416
1757
|
Modal3,
|
|
1417
1758
|
{
|
|
1418
1759
|
open,
|
|
1419
1760
|
onOpenChange: setOpen,
|
|
1420
1761
|
title: t.gallery,
|
|
1421
|
-
trigger: controlled ? null : /* @__PURE__ */ (0,
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1762
|
+
trigger: controlled ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1763
|
+
import_design_system.Button,
|
|
1764
|
+
{
|
|
1765
|
+
variant: "secondary",
|
|
1766
|
+
fullWidth: true,
|
|
1767
|
+
onClick: () => setOpen(true),
|
|
1768
|
+
"data-testid": `open-gallery-${zone.name}`,
|
|
1769
|
+
children: [
|
|
1770
|
+
t.add,
|
|
1771
|
+
": ",
|
|
1772
|
+
zone.name
|
|
1773
|
+
]
|
|
1774
|
+
}
|
|
1775
|
+
),
|
|
1776
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
|
|
1777
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
|
|
1778
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1779
|
+
import_design_system.Typography,
|
|
1780
|
+
{
|
|
1781
|
+
variant: "omega",
|
|
1782
|
+
fontWeight: "bold",
|
|
1783
|
+
textColor: "neutral800",
|
|
1784
|
+
style: { whiteSpace: "nowrap" },
|
|
1785
|
+
"data-testid": `block-count-${zone.name}`,
|
|
1786
|
+
"aria-live": "polite",
|
|
1787
|
+
children: filtering ? t.f("countFiltered", { shown: entries.length, total }) : t.f("countAll", { count: total })
|
|
1788
|
+
}
|
|
1789
|
+
),
|
|
1790
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Box, { style: { flex: 1, minWidth: "12rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1430
1791
|
import_design_system.Searchbar,
|
|
1431
1792
|
{
|
|
1432
1793
|
name: `block-search-${zone.name}`,
|
|
@@ -1438,14 +1799,54 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1438
1799
|
children: t.search
|
|
1439
1800
|
}
|
|
1440
1801
|
) }),
|
|
1441
|
-
categories.length > 1 && /* @__PURE__ */ (0,
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1802
|
+
categories.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1803
|
+
import_design_system.Box,
|
|
1804
|
+
{
|
|
1805
|
+
style: { width: "14rem" },
|
|
1806
|
+
"data-testid": `block-category-${zone.name}`,
|
|
1807
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1808
|
+
import_design_system.SingleSelect,
|
|
1809
|
+
{
|
|
1810
|
+
"aria-label": t.filterCategory,
|
|
1811
|
+
size: "S",
|
|
1812
|
+
value: category,
|
|
1813
|
+
onChange: (value) => setCategory(String(value)),
|
|
1814
|
+
children: [
|
|
1815
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.SingleSelectOption, { value: "all", children: t.allCategories }),
|
|
1816
|
+
categories.map(([name, count]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1817
|
+
import_design_system.SingleSelectOption,
|
|
1818
|
+
{
|
|
1819
|
+
value: name,
|
|
1820
|
+
children: `${name} (${count})`
|
|
1821
|
+
},
|
|
1822
|
+
name
|
|
1823
|
+
))
|
|
1824
|
+
]
|
|
1825
|
+
}
|
|
1826
|
+
)
|
|
1827
|
+
}
|
|
1828
|
+
),
|
|
1829
|
+
Toggle && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1830
|
+
Toggle,
|
|
1831
|
+
{
|
|
1832
|
+
name: `block-fields-${zone.name}`,
|
|
1833
|
+
label: t.showFields,
|
|
1834
|
+
hint: t.showFieldsHint,
|
|
1835
|
+
value: showFields,
|
|
1836
|
+
onChange: changeShowFields
|
|
1837
|
+
}
|
|
1838
|
+
),
|
|
1839
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { gap: 2, alignItems: "center", children: [
|
|
1840
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1841
|
+
import_design_system.Typography,
|
|
1842
|
+
{
|
|
1843
|
+
variant: "pi",
|
|
1844
|
+
textColor: "neutral600",
|
|
1845
|
+
id: `block-columns-${zone.name}`,
|
|
1846
|
+
children: t.columns
|
|
1847
|
+
}
|
|
1848
|
+
),
|
|
1849
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1449
1850
|
Slider,
|
|
1450
1851
|
{
|
|
1451
1852
|
type: "range",
|
|
@@ -1458,16 +1859,52 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1458
1859
|
onChange: (e) => changeColumns(Number(e.target.value))
|
|
1459
1860
|
}
|
|
1460
1861
|
),
|
|
1461
|
-
/* @__PURE__ */ (0,
|
|
1862
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Typography, { variant: "pi", fontWeight: "bold", children: columns })
|
|
1462
1863
|
] })
|
|
1463
1864
|
] }),
|
|
1464
|
-
/* @__PURE__ */ (0,
|
|
1465
|
-
error ? /* @__PURE__ */ (0,
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1865
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Typography, { variant: "pi", textColor: "neutral600", children: t.example }),
|
|
1866
|
+
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)(
|
|
1867
|
+
import_design_system.Flex,
|
|
1868
|
+
{
|
|
1869
|
+
direction: "column",
|
|
1870
|
+
alignItems: "stretch",
|
|
1871
|
+
gap: 4,
|
|
1872
|
+
style: { overflowY: "auto", maxHeight: "60vh", padding: "4px" },
|
|
1873
|
+
children: groupEntries(entries).map(
|
|
1874
|
+
({ category: name, entries: items }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1875
|
+
import_design_system.Flex,
|
|
1876
|
+
{
|
|
1877
|
+
direction: "column",
|
|
1878
|
+
alignItems: "stretch",
|
|
1879
|
+
gap: 2,
|
|
1880
|
+
children: [
|
|
1881
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1882
|
+
import_design_system.Typography,
|
|
1883
|
+
{
|
|
1884
|
+
variant: "sigma",
|
|
1885
|
+
textColor: "neutral600",
|
|
1886
|
+
"data-testid": `block-group-${name}`,
|
|
1887
|
+
children: `${name} (${items.length})`
|
|
1888
|
+
}
|
|
1889
|
+
),
|
|
1890
|
+
/* @__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)(
|
|
1891
|
+
Card,
|
|
1892
|
+
{
|
|
1893
|
+
entry,
|
|
1894
|
+
palette: config.palette,
|
|
1895
|
+
showFields,
|
|
1896
|
+
onSelect: () => select(entry.uid)
|
|
1897
|
+
}
|
|
1898
|
+
) }, entry.uid)) })
|
|
1899
|
+
]
|
|
1900
|
+
},
|
|
1901
|
+
name
|
|
1902
|
+
)
|
|
1903
|
+
)
|
|
1904
|
+
}
|
|
1905
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { gap: 3, alignItems: "center", children: [
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Typography, { children: t.empty }),
|
|
1907
|
+
filtering && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.Button, { variant: "tertiary", size: "S", onClick: reset, children: t.clear })
|
|
1471
1908
|
] })
|
|
1472
1909
|
] })
|
|
1473
1910
|
}
|
|
@@ -1481,13 +1918,19 @@ var storage = () => {
|
|
|
1481
1918
|
}
|
|
1482
1919
|
};
|
|
1483
1920
|
var memoryBase = () => `${window.location.origin}${window.location.pathname.split("/content-manager")[0]}`;
|
|
1484
|
-
function useInitialAccordions({
|
|
1485
|
-
|
|
1486
|
-
|
|
1921
|
+
function useInitialAccordions({
|
|
1922
|
+
zones,
|
|
1923
|
+
editor,
|
|
1924
|
+
docKey,
|
|
1925
|
+
contentType,
|
|
1926
|
+
userId
|
|
1927
|
+
}) {
|
|
1928
|
+
const applied = React2.useRef("");
|
|
1929
|
+
const user = React2.useRef(userId);
|
|
1487
1930
|
user.current = userId;
|
|
1488
|
-
const latest =
|
|
1931
|
+
const latest = React2.useRef(zones);
|
|
1489
1932
|
latest.current = zones;
|
|
1490
|
-
|
|
1933
|
+
React2.useEffect(() => {
|
|
1491
1934
|
if (!editor?.enabled || !docKey || applied.current === docKey) return;
|
|
1492
1935
|
if (applied.current.startsWith(`${contentType}:new`) && docKey.startsWith(`${contentType}:`)) {
|
|
1493
1936
|
applied.current = docKey;
|
|
@@ -1496,7 +1939,10 @@ function useInitialAccordions({ zones, editor, docKey, contentType, userId }) {
|
|
|
1496
1939
|
applied.current = docKey;
|
|
1497
1940
|
let tries = 0;
|
|
1498
1941
|
const cancel = (event) => {
|
|
1499
|
-
if (event.target?.closest?.(
|
|
1942
|
+
if (event.target?.closest?.(
|
|
1943
|
+
'button[aria-expanded], [data-testid^="block-accordion-controls-"]'
|
|
1944
|
+
))
|
|
1945
|
+
stop();
|
|
1500
1946
|
};
|
|
1501
1947
|
const stop = () => {
|
|
1502
1948
|
clearInterval(timer);
|
|
@@ -1514,8 +1960,17 @@ function useInitialAccordions({ zones, editor, docKey, contentType, userId }) {
|
|
|
1514
1960
|
for (const zone of pending) {
|
|
1515
1961
|
const list = findZoneList(zone.label);
|
|
1516
1962
|
if (!list) continue;
|
|
1517
|
-
const key = memoryKey({
|
|
1518
|
-
|
|
1963
|
+
const key = memoryKey({
|
|
1964
|
+
base: memoryBase(),
|
|
1965
|
+
userId: user.current,
|
|
1966
|
+
contentType,
|
|
1967
|
+
zone: zone.name
|
|
1968
|
+
});
|
|
1969
|
+
setAll(
|
|
1970
|
+
list,
|
|
1971
|
+
initialState(editor, readMemory(storage(), key)) === "open",
|
|
1972
|
+
import_react_dom2.unstable_batchedUpdates
|
|
1973
|
+
);
|
|
1519
1974
|
}
|
|
1520
1975
|
}, 200);
|
|
1521
1976
|
return stop;
|
|
@@ -1526,51 +1981,107 @@ function ZoneControls({ zone, editor, contentType, userId }) {
|
|
|
1526
1981
|
if (!zone.count || !(editor.showOpenAll || editor.showCloseAll)) return null;
|
|
1527
1982
|
const apply = (open) => {
|
|
1528
1983
|
const list = findZoneList(zone.label);
|
|
1529
|
-
if (list) setAll(list, open,
|
|
1530
|
-
writeMemory(
|
|
1984
|
+
if (list) setAll(list, open, import_react_dom2.unstable_batchedUpdates);
|
|
1985
|
+
writeMemory(
|
|
1986
|
+
storage(),
|
|
1987
|
+
memoryKey({ base: memoryBase(), userId, contentType, zone: zone.name }),
|
|
1988
|
+
open ? "open" : "closed"
|
|
1989
|
+
);
|
|
1531
1990
|
};
|
|
1532
|
-
return /* @__PURE__ */ (0,
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1991
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1992
|
+
import_design_system.Flex,
|
|
1993
|
+
{
|
|
1994
|
+
gap: 2,
|
|
1995
|
+
wrap: "wrap",
|
|
1996
|
+
"data-testid": `block-accordion-controls-${zone.name}`,
|
|
1997
|
+
children: [
|
|
1998
|
+
editor.showOpenAll && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1999
|
+
import_design_system.Button,
|
|
2000
|
+
{
|
|
2001
|
+
type: "button",
|
|
2002
|
+
variant: "tertiary",
|
|
2003
|
+
size: "S",
|
|
2004
|
+
onClick: () => apply(true),
|
|
2005
|
+
children: t.openAll
|
|
2006
|
+
}
|
|
2007
|
+
),
|
|
2008
|
+
editor.showCloseAll && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
2009
|
+
import_design_system.Button,
|
|
2010
|
+
{
|
|
2011
|
+
type: "button",
|
|
2012
|
+
variant: "tertiary",
|
|
2013
|
+
size: "S",
|
|
2014
|
+
onClick: () => apply(false),
|
|
2015
|
+
children: t.closeAll
|
|
2016
|
+
}
|
|
2017
|
+
)
|
|
2018
|
+
]
|
|
2019
|
+
}
|
|
2020
|
+
);
|
|
1536
2021
|
}
|
|
1537
|
-
function Gallery({
|
|
2022
|
+
function Gallery({
|
|
2023
|
+
zones,
|
|
2024
|
+
editor,
|
|
2025
|
+
docKey,
|
|
2026
|
+
contentType,
|
|
2027
|
+
userId,
|
|
2028
|
+
catalog,
|
|
2029
|
+
...props
|
|
2030
|
+
}) {
|
|
1538
2031
|
useInitialAccordions({ zones, editor, docKey, contentType, userId });
|
|
1539
|
-
return /* @__PURE__ */ (0,
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
2032
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
|
|
2033
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
2034
|
+
RowPreviews,
|
|
2035
|
+
{
|
|
2036
|
+
zones,
|
|
2037
|
+
components: props.components,
|
|
2038
|
+
catalog,
|
|
2039
|
+
Modal: props.Modal
|
|
2040
|
+
}
|
|
2041
|
+
),
|
|
2042
|
+
zones.map((zone) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
|
2043
|
+
!zone.full && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ZoneGallery, { zone, ...props }),
|
|
2044
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
2045
|
+
ZoneControls,
|
|
2046
|
+
{
|
|
2047
|
+
zone,
|
|
2048
|
+
editor,
|
|
2049
|
+
contentType,
|
|
2050
|
+
userId
|
|
2051
|
+
}
|
|
2052
|
+
)
|
|
2053
|
+
] }, zone.name))
|
|
2054
|
+
] });
|
|
1543
2055
|
}
|
|
1544
2056
|
|
|
1545
2057
|
// admin/PagePreview.tsx
|
|
1546
|
-
var
|
|
1547
|
-
var
|
|
2058
|
+
var React4 = __toESM(require("react"));
|
|
2059
|
+
var import_react_dom3 = require("react-dom");
|
|
1548
2060
|
var import_styled_components2 = __toESM(require("styled-components"));
|
|
1549
2061
|
var import_design_system3 = require("@strapi/design-system");
|
|
1550
2062
|
var import_admin2 = require("@strapi/strapi/admin");
|
|
1551
|
-
var import_design_system4 = require("@strapi/design-system");
|
|
1552
2063
|
var import_strapi_admin = require("@strapi/content-manager/strapi-admin");
|
|
1553
2064
|
|
|
1554
2065
|
// admin/FieldEditorModal.tsx
|
|
1555
|
-
var
|
|
2066
|
+
var React3 = __toESM(require("react"));
|
|
1556
2067
|
var import_admin = require("@strapi/strapi/admin");
|
|
1557
2068
|
var import_design_system2 = require("@strapi/design-system");
|
|
1558
|
-
var
|
|
2069
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1559
2070
|
var Actions = ({ onApply, onCancel }) => {
|
|
1560
2071
|
const t = useMessages();
|
|
1561
2072
|
const value = (0, import_admin.useForm)("BlocksceneFieldEditor", (state) => state.values.value);
|
|
1562
|
-
return /* @__PURE__ */ (0,
|
|
1563
|
-
/* @__PURE__ */ (0,
|
|
1564
|
-
/* @__PURE__ */ (0,
|
|
2073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { gap: 2, justifyContent: "flex-end", children: [
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Button, { variant: "tertiary", onClick: onCancel, children: t.cancel }),
|
|
2075
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Button, { onClick: () => onApply(value ?? null), "data-testid": "field-editor-apply", children: t.apply })
|
|
1565
2076
|
] });
|
|
1566
2077
|
};
|
|
1567
2078
|
function FieldEditorModal({ label, attribute, value, onApply, onCancel }) {
|
|
1568
2079
|
const t = useMessages();
|
|
1569
2080
|
const customFields = (0, import_admin.useStrapiApp)("BlocksceneFieldEditor", (state) => state.customFields);
|
|
1570
|
-
const [Input, setInput] =
|
|
2081
|
+
const [Input, setInput] = React3.useState(void 0);
|
|
1571
2082
|
const isCustom = Boolean(attribute?.customField);
|
|
1572
2083
|
const isText = attribute?.type === "string" || attribute?.type === "text";
|
|
1573
|
-
|
|
2084
|
+
React3.useEffect(() => {
|
|
1574
2085
|
let active = true;
|
|
1575
2086
|
if (!isCustom) {
|
|
1576
2087
|
setInput(null);
|
|
@@ -1591,24 +2102,24 @@ function FieldEditorModal({ label, attribute, value, onApply, onCancel }) {
|
|
|
1591
2102
|
};
|
|
1592
2103
|
}, [attribute, customFields, isCustom]);
|
|
1593
2104
|
const supported = isText || isCustom && Input;
|
|
1594
|
-
return /* @__PURE__ */ (0,
|
|
2105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Modal.Root, { open: true, onOpenChange: (open) => {
|
|
1595
2106
|
if (!open) onCancel();
|
|
1596
|
-
}, children: /* @__PURE__ */ (0,
|
|
1597
|
-
/* @__PURE__ */ (0,
|
|
2107
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Modal.Content, { "aria-label": `${t.editText} ${label}`, children: [
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Modal.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Modal.Title, { children: [
|
|
1598
2109
|
t.editText,
|
|
1599
2110
|
" \xB7 ",
|
|
1600
2111
|
label
|
|
1601
2112
|
] }) }),
|
|
1602
|
-
/* @__PURE__ */ (0,
|
|
2113
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_admin.Form, { initialValues: { value: value ?? (isText ? "" : null) }, method: "PUT", onSubmit: () => {
|
|
1603
2114
|
}, children: [
|
|
1604
|
-
/* @__PURE__ */ (0,
|
|
1605
|
-
/* @__PURE__ */ (0,
|
|
1606
|
-
isCustom && Input === void 0 && /* @__PURE__ */ (0,
|
|
1607
|
-
isCustom && Input && /* @__PURE__ */ (0,
|
|
1608
|
-
isText && /* @__PURE__ */ (0,
|
|
1609
|
-
(isCustom && Input === null || !isCustom && !isText) && /* @__PURE__ */ (0,
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Modal.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system2.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "field-editor-modal", children: [
|
|
2116
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { variant: "pi", textColor: "neutral600", children: t.editHelp }),
|
|
2117
|
+
isCustom && Input === void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { children: t.loading }),
|
|
2118
|
+
isCustom && Input && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Input, { name: "value", attribute, label, type: attribute.type }),
|
|
2119
|
+
isText && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_admin.InputRenderer, { type: attribute.type === "text" ? "text" : "string", name: "value", label }),
|
|
2120
|
+
(isCustom && Input === null || !isCustom && !isText) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Typography, { role: "alert", textColor: "danger600", children: t.editUnsupported })
|
|
1610
2121
|
] }) }),
|
|
1611
|
-
/* @__PURE__ */ (0,
|
|
2122
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Modal.Footer, { children: supported ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Actions, { onApply, onCancel }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system2.Button, { variant: "tertiary", onClick: onCancel, children: t.close }) })
|
|
1612
2123
|
] })
|
|
1613
2124
|
] }) });
|
|
1614
2125
|
}
|
|
@@ -1719,6 +2230,7 @@ var mediaAttribute = (uid, field, components) => {
|
|
|
1719
2230
|
const attr = resolveField(uid, field, components);
|
|
1720
2231
|
return attr?.type === "media" ? attr : null;
|
|
1721
2232
|
};
|
|
2233
|
+
var getIn = (row, path) => String(path).split(".").reduce((value, key) => value == null ? void 0 : value[key], row);
|
|
1722
2234
|
function isPreviewMessage(event, origin, source, channel, type) {
|
|
1723
2235
|
return event.origin === origin && event.source === source && event.data?.protocol === PROTOCOL && event.data?.channel === channel && event.data?.type === type;
|
|
1724
2236
|
}
|
|
@@ -1729,7 +2241,7 @@ function insertIndex(rows, after) {
|
|
|
1729
2241
|
}
|
|
1730
2242
|
|
|
1731
2243
|
// admin/PagePreview.tsx
|
|
1732
|
-
var
|
|
2244
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1733
2245
|
var MODE_KEY = "blockscene:page-mode";
|
|
1734
2246
|
var RATIO_KEY = "blockscene:page-split-ratio";
|
|
1735
2247
|
var MIN_PANE = 360;
|
|
@@ -1750,20 +2262,32 @@ var write = (key, value) => {
|
|
|
1750
2262
|
} catch {
|
|
1751
2263
|
}
|
|
1752
2264
|
};
|
|
1753
|
-
var clampWidth = (width, vw) => Math.round(
|
|
1754
|
-
|
|
2265
|
+
var clampWidth = (width, vw) => Math.round(
|
|
2266
|
+
Math.min(Math.max(width, MIN_PANE), Math.max(MIN_PANE, vw - MIN_FORM))
|
|
2267
|
+
);
|
|
1755
2268
|
var Pane = import_styled_components2.default.aside`
|
|
1756
|
-
position: fixed;
|
|
1757
|
-
|
|
2269
|
+
position: fixed;
|
|
2270
|
+
top: 0;
|
|
2271
|
+
bottom: 0;
|
|
2272
|
+
z-index: 2;
|
|
2273
|
+
display: flex;
|
|
2274
|
+
flex-direction: column;
|
|
2275
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
2276
|
+
border-left: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
1758
2277
|
box-shadow: ${({ theme }) => theme.shadows.popupShadow};
|
|
1759
2278
|
`;
|
|
1760
2279
|
function useMainRect() {
|
|
1761
|
-
const [rect, setRect] =
|
|
1762
|
-
|
|
2280
|
+
const [rect, setRect] = React4.useState(() => ({
|
|
2281
|
+
left: 0,
|
|
2282
|
+
width: window.innerWidth
|
|
2283
|
+
}));
|
|
2284
|
+
React4.useEffect(() => {
|
|
1763
2285
|
const main = document.getElementById("main-content");
|
|
1764
2286
|
const measure = () => {
|
|
1765
2287
|
const r = main?.getBoundingClientRect();
|
|
1766
|
-
setRect(
|
|
2288
|
+
setRect(
|
|
2289
|
+
r && r.width > 0 ? { left: Math.round(r.left), width: Math.round(r.width) } : { left: 0, width: window.innerWidth }
|
|
2290
|
+
);
|
|
1767
2291
|
};
|
|
1768
2292
|
measure();
|
|
1769
2293
|
const observer = main && "ResizeObserver" in window ? new ResizeObserver(measure) : null;
|
|
@@ -1777,12 +2301,37 @@ function useMainRect() {
|
|
|
1777
2301
|
return rect;
|
|
1778
2302
|
}
|
|
1779
2303
|
var Handle = import_styled_components2.default.div`
|
|
1780
|
-
position: absolute;
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
2304
|
+
position: absolute;
|
|
2305
|
+
top: 0;
|
|
2306
|
+
bottom: 0;
|
|
2307
|
+
left: -5px;
|
|
2308
|
+
width: 10px;
|
|
2309
|
+
cursor: col-resize;
|
|
2310
|
+
z-index: 3;
|
|
2311
|
+
touch-action: none;
|
|
2312
|
+
&::after {
|
|
2313
|
+
content: "";
|
|
2314
|
+
position: absolute;
|
|
2315
|
+
top: 0;
|
|
2316
|
+
bottom: 0;
|
|
2317
|
+
left: 4px;
|
|
2318
|
+
width: 2px;
|
|
2319
|
+
}
|
|
2320
|
+
&:hover::after,
|
|
2321
|
+
&[data-dragging="true"]::after,
|
|
2322
|
+
&:focus-visible::after {
|
|
2323
|
+
background: ${({ theme }) => theme.colors.primary600};
|
|
2324
|
+
}
|
|
2325
|
+
&:focus-visible {
|
|
2326
|
+
outline: none;
|
|
2327
|
+
}
|
|
2328
|
+
`;
|
|
2329
|
+
var Frame2 = import_styled_components2.default.iframe`
|
|
2330
|
+
flex: 1;
|
|
2331
|
+
width: 100%;
|
|
2332
|
+
border: 0;
|
|
2333
|
+
background: white;
|
|
1784
2334
|
`;
|
|
1785
|
-
var Frame2 = import_styled_components2.default.iframe` flex: 1; width: 100%; border: 0; background: white; `;
|
|
1786
2335
|
var SPLIT_STYLE = `
|
|
1787
2336
|
body.bp-split #main-content { padding-right: calc(var(--bp-pane, 50vw) + 1.6rem) !important; }
|
|
1788
2337
|
body.bp-split [data-bp-grid] { display: flex !important; flex-direction: column-reverse; gap: 1.6rem; }
|
|
@@ -1791,20 +2340,26 @@ body.bp-split [data-bp-panels] > div { flex-direction: row; flex-wrap: wrap; ali
|
|
|
1791
2340
|
body.bp-split [data-bp-panels] > div > * { flex: 1 1 24rem; }`;
|
|
1792
2341
|
var markLayout = (anchor) => {
|
|
1793
2342
|
let item = anchor;
|
|
1794
|
-
while (item?.parentElement && getComputedStyle(item.parentElement).display !== "grid")
|
|
2343
|
+
while (item?.parentElement && getComputedStyle(item.parentElement).display !== "grid")
|
|
2344
|
+
item = item.parentElement;
|
|
1795
2345
|
if (!item?.parentElement) return;
|
|
1796
2346
|
item.dataset.bpPanels = "";
|
|
1797
2347
|
item.parentElement.dataset.bpGrid = "";
|
|
1798
2348
|
};
|
|
1799
2349
|
function usePreviewBase(override, model, documentId, locale) {
|
|
1800
2350
|
const { get } = (0, import_admin2.useFetchClient)();
|
|
1801
|
-
const [native, setNative] =
|
|
1802
|
-
|
|
2351
|
+
const [native, setNative] = React4.useState(null);
|
|
2352
|
+
React4.useEffect(() => {
|
|
1803
2353
|
if (override || !model) return;
|
|
1804
2354
|
let active = true;
|
|
1805
|
-
const query = new URLSearchParams({
|
|
2355
|
+
const query = new URLSearchParams({
|
|
2356
|
+
status: "draft",
|
|
2357
|
+
...documentId ? { documentId } : {},
|
|
2358
|
+
...locale ? { locale } : {}
|
|
2359
|
+
});
|
|
1806
2360
|
get(`/content-manager/preview/url/${model}?${query}`).then(({ data }) => {
|
|
1807
|
-
if (active && typeof data?.data?.url === "string")
|
|
2361
|
+
if (active && typeof data?.data?.url === "string")
|
|
2362
|
+
setNative(`${new URL(data.data.url).origin}/block-preview/page`);
|
|
1808
2363
|
}).catch(() => {
|
|
1809
2364
|
if (active) setNative(null);
|
|
1810
2365
|
});
|
|
@@ -1814,55 +2369,109 @@ function usePreviewBase(override, model, documentId, locale) {
|
|
|
1814
2369
|
}, [get, model, documentId, locale, override]);
|
|
1815
2370
|
return override ? { base: override, source: "custom" } : native ? { base: native, source: "native" } : { base: null, source: "none" };
|
|
1816
2371
|
}
|
|
1817
|
-
function PickerDialog({ open, onOpenChange, trigger, title, children }) {
|
|
1818
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system4.Modal.Root, { open, onOpenChange, children: [
|
|
1819
|
-
trigger && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system4.Modal.Trigger, { children: trigger }),
|
|
1820
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system4.Modal.Content, { children: [
|
|
1821
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system4.Modal.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system4.Modal.Title, { children: title }) }),
|
|
1822
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system4.Modal.Body, { children })
|
|
1823
|
-
] })
|
|
1824
|
-
] });
|
|
1825
|
-
}
|
|
1826
2372
|
var ACTION_TYPES = ["update", "publish"];
|
|
1827
|
-
var nativeButtons = () => document.querySelectorAll(
|
|
2373
|
+
var nativeButtons = () => document.querySelectorAll(
|
|
2374
|
+
'#main-content button:not([data-testid="page-preview-pane"] button)'
|
|
2375
|
+
);
|
|
1828
2376
|
function ToolbarActions({ model, collectionType, documentId, locale }) {
|
|
1829
|
-
const plugins = (0, import_admin2.useStrapiApp)(
|
|
2377
|
+
const plugins = (0, import_admin2.useStrapiApp)(
|
|
2378
|
+
"BlocksceneToolbar",
|
|
2379
|
+
(state) => state.plugins
|
|
2380
|
+
);
|
|
1830
2381
|
const [{ query }] = (0, import_admin2.useQueryParams)();
|
|
1831
|
-
const { document: doc, meta } = (0, import_strapi_admin.unstable_useDocument)(
|
|
2382
|
+
const { document: doc, meta } = (0, import_strapi_admin.unstable_useDocument)(
|
|
2383
|
+
{ model, collectionType, documentId, params: { locale } },
|
|
2384
|
+
{ skip: !documentId }
|
|
2385
|
+
);
|
|
1832
2386
|
const { toggleNotification } = (0, import_admin2.useNotification)();
|
|
1833
2387
|
const t = useMessages();
|
|
1834
2388
|
const descriptions = (plugins["content-manager"]?.apis?.getDocumentActions?.("panel") || []).filter((d) => ACTION_TYPES.includes(d.type));
|
|
1835
|
-
const props = {
|
|
2389
|
+
const props = {
|
|
2390
|
+
activeTab: query.status || "draft",
|
|
2391
|
+
model,
|
|
2392
|
+
documentId,
|
|
2393
|
+
document: doc,
|
|
2394
|
+
meta,
|
|
2395
|
+
collectionType
|
|
2396
|
+
};
|
|
1836
2397
|
const run = async (action, event) => {
|
|
1837
|
-
const native = [...nativeButtons()].find(
|
|
2398
|
+
const native = [...nativeButtons()].find(
|
|
2399
|
+
(b) => b.textContent?.trim() === action.label
|
|
2400
|
+
);
|
|
1838
2401
|
if (native) {
|
|
1839
2402
|
native.click();
|
|
1840
2403
|
return;
|
|
1841
2404
|
}
|
|
1842
2405
|
const mute = await action.onClick?.(event);
|
|
1843
|
-
if (action.dialog && !mute && action.dialog.type === "notification")
|
|
2406
|
+
if (action.dialog && !mute && action.dialog.type === "notification")
|
|
2407
|
+
toggleNotification({
|
|
2408
|
+
title: action.dialog.title,
|
|
2409
|
+
message: action.dialog.content,
|
|
2410
|
+
type: action.dialog.status
|
|
2411
|
+
});
|
|
1844
2412
|
};
|
|
1845
|
-
const typeOf = (action) => action.type || descriptions.find(
|
|
1846
|
-
|
|
2413
|
+
const typeOf = (action) => action.type || descriptions.find(
|
|
2414
|
+
(d) => typeof action.id === "string" && action.id.startsWith(`${d.name || d.displayName}-`)
|
|
2415
|
+
)?.type;
|
|
2416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_admin2.DescriptionComponentRenderer, { props, descriptions, children: (actions) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Flex, { gap: 1, "data-testid": "page-preview-actions", children: [...actions].sort(
|
|
2417
|
+
(a, b) => ACTION_TYPES.indexOf(typeOf(a)) - ACTION_TYPES.indexOf(typeOf(b))
|
|
2418
|
+
).map((action) => {
|
|
1847
2419
|
const reason = action.disabled ? typeOf(action) === "publish" ? t.publishDisabledHint : t.saveDisabledHint : void 0;
|
|
1848
|
-
return /* @__PURE__ */ (0,
|
|
2420
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { title: reason, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2421
|
+
import_design_system3.Button,
|
|
2422
|
+
{
|
|
2423
|
+
size: "S",
|
|
2424
|
+
variant: action.variant || "default",
|
|
2425
|
+
disabled: action.disabled,
|
|
2426
|
+
loading: action.loading,
|
|
2427
|
+
"aria-description": reason,
|
|
2428
|
+
onClick: (e) => run(action, e),
|
|
2429
|
+
children: action.label
|
|
2430
|
+
}
|
|
2431
|
+
) }, action.id);
|
|
1849
2432
|
}) }) });
|
|
1850
2433
|
}
|
|
1851
|
-
function PagePreview({
|
|
2434
|
+
function PagePreview({
|
|
2435
|
+
editor,
|
|
2436
|
+
groups = null,
|
|
2437
|
+
Modal: Modal3,
|
|
2438
|
+
Toggle
|
|
2439
|
+
}) {
|
|
1852
2440
|
const t = useMessages();
|
|
1853
2441
|
const c = (0, import_strapi_admin.unstable_useContentManagerContext)();
|
|
1854
|
-
const rbac = (0, import_strapi_admin.useDocumentRBAC)(
|
|
2442
|
+
const rbac = (0, import_strapi_admin.useDocumentRBAC)(
|
|
2443
|
+
"BlockscenePagePreview",
|
|
2444
|
+
(state) => state
|
|
2445
|
+
);
|
|
1855
2446
|
const values = (0, import_admin2.useForm)("BlockscenePagePreview", (state) => state.values);
|
|
1856
|
-
const onChange = (0, import_admin2.useForm)(
|
|
1857
|
-
|
|
2447
|
+
const onChange = (0, import_admin2.useForm)(
|
|
2448
|
+
"BlockscenePagePreview",
|
|
2449
|
+
(state) => state.onChange
|
|
2450
|
+
);
|
|
2451
|
+
const components = (0, import_admin2.useStrapiApp)(
|
|
2452
|
+
"BlockscenePagePreview",
|
|
2453
|
+
(state) => state.components
|
|
2454
|
+
);
|
|
1858
2455
|
const MediaLibraryDialog = components?.["media-library"];
|
|
1859
|
-
const addFieldRow = (0, import_admin2.useForm)(
|
|
2456
|
+
const addFieldRow = (0, import_admin2.useForm)(
|
|
2457
|
+
"BlockscenePagePreview",
|
|
2458
|
+
(state) => state.addFieldRow
|
|
2459
|
+
);
|
|
2460
|
+
const moveFieldRow = (0, import_admin2.useForm)(
|
|
2461
|
+
"BlockscenePagePreview",
|
|
2462
|
+
(state) => state.moveFieldRow
|
|
2463
|
+
);
|
|
1860
2464
|
const fields = c.layout?.edit?.layout?.flat(3) || [];
|
|
1861
2465
|
const readable = (name) => c.isCreatingEntry || (rbac.canReadFields || []).includes(name);
|
|
1862
|
-
const zone =
|
|
2466
|
+
const zone = React4.useMemo(
|
|
2467
|
+
() => editableZones(c.contentType, values, readable, c.isLoading)[0]?.name,
|
|
2468
|
+
[c.contentType, values, c.isLoading, rbac.canReadFields, c.isCreatingEntry]
|
|
2469
|
+
);
|
|
1863
2470
|
const zoneLabel = fields.find((field) => field.name === zone)?.label || zone || "";
|
|
1864
|
-
const canEdit = Boolean(
|
|
1865
|
-
|
|
2471
|
+
const canEdit = Boolean(
|
|
2472
|
+
zone && ((c.isCreatingEntry ? rbac.canCreateFields : rbac.canUpdateFields) || []).includes(zone) && fields.find((field) => field.name === zone)?.disabled !== true && !c.form?.disabled && typeof addFieldRow === "function"
|
|
2473
|
+
);
|
|
2474
|
+
const [mode, setModeState] = React4.useState(() => {
|
|
1866
2475
|
const v = read(MODE_KEY);
|
|
1867
2476
|
return v === "split" || v === "preview" ? v : editor?.previewMode || "form";
|
|
1868
2477
|
});
|
|
@@ -1870,32 +2479,37 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1870
2479
|
setModeState(next);
|
|
1871
2480
|
write(MODE_KEY, next);
|
|
1872
2481
|
};
|
|
1873
|
-
const [ratio, setRatio] =
|
|
2482
|
+
const [ratio, setRatio] = React4.useState(() => {
|
|
1874
2483
|
const v = Number(read(RATIO_KEY));
|
|
1875
2484
|
return v > 0 && v < 1 ? v : 0.5;
|
|
1876
2485
|
});
|
|
1877
2486
|
const main = useMainRect();
|
|
1878
2487
|
const vw = main.width;
|
|
1879
|
-
const [dragging, setDragging] =
|
|
1880
|
-
const [ready, setReady] =
|
|
1881
|
-
const [failed, setFailed] =
|
|
1882
|
-
const [attempt, retry] =
|
|
1883
|
-
const [picking, setPicking] =
|
|
1884
|
-
|
|
2488
|
+
const [dragging, setDragging] = React4.useState(false);
|
|
2489
|
+
const [ready, setReady] = React4.useState(false);
|
|
2490
|
+
const [failed, setFailed] = React4.useState(false);
|
|
2491
|
+
const [attempt, retry] = React4.useReducer((n) => n + 1, 0);
|
|
2492
|
+
const [picking, setPicking] = React4.useState(null);
|
|
2493
|
+
React4.useEffect(() => {
|
|
1885
2494
|
setEditing(null);
|
|
1886
2495
|
setPicking(null);
|
|
1887
2496
|
setInserting(null);
|
|
1888
2497
|
}, [c.id, c.form?.initialValues?.locale]);
|
|
1889
|
-
const [editing, setEditing] =
|
|
1890
|
-
const [inserting, setInserting] =
|
|
2498
|
+
const [editing, setEditing] = React4.useState(null);
|
|
2499
|
+
const [inserting, setInserting] = React4.useState(null);
|
|
1891
2500
|
const { get } = (0, import_admin2.useFetchClient)();
|
|
1892
2501
|
const { toggleNotification } = (0, import_admin2.useNotification)();
|
|
1893
2502
|
const zoneAttr = zone ? c.contentType?.attributes?.[zone] : null;
|
|
1894
|
-
const iframe =
|
|
1895
|
-
const loaded =
|
|
1896
|
-
const anchor =
|
|
1897
|
-
const channel =
|
|
1898
|
-
const { base, source } = usePreviewBase(
|
|
2503
|
+
const iframe = React4.useRef(null);
|
|
2504
|
+
const loaded = React4.useRef(false);
|
|
2505
|
+
const anchor = React4.useRef(null);
|
|
2506
|
+
const channel = React4.useMemo(() => crypto.randomUUID(), []);
|
|
2507
|
+
const { base, source } = usePreviewBase(
|
|
2508
|
+
editor?.previewUrl || "",
|
|
2509
|
+
c.model,
|
|
2510
|
+
c.isCreatingEntry ? void 0 : c.id,
|
|
2511
|
+
c.form?.initialValues?.locale
|
|
2512
|
+
);
|
|
1899
2513
|
const url = base ? new URL(base) : null;
|
|
1900
2514
|
url?.searchParams.set("channel", channel);
|
|
1901
2515
|
const origin = url?.origin || "";
|
|
@@ -1904,16 +2518,50 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1904
2518
|
const resizable = mode === "split" && !narrow;
|
|
1905
2519
|
const active = mode !== "form" && Boolean(url) && Boolean(zone);
|
|
1906
2520
|
const rows = zone && Array.isArray(values?.[zone]) ? values[zone] : [];
|
|
1907
|
-
const latest =
|
|
2521
|
+
const latest = React4.useRef(rows);
|
|
1908
2522
|
latest.current = rows;
|
|
1909
|
-
const
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
2523
|
+
const insertRows = (at, ...items) => items.forEach((item, i) => {
|
|
2524
|
+
const from = latest.current.length + i;
|
|
2525
|
+
addFieldRow(zone, item);
|
|
2526
|
+
if (at + i < from) moveFieldRow(zone, from, at + i);
|
|
2527
|
+
});
|
|
2528
|
+
const live = React4.useRef({
|
|
2529
|
+
mode,
|
|
2530
|
+
canEdit,
|
|
2531
|
+
zoneLabel,
|
|
2532
|
+
components: c.components,
|
|
2533
|
+
setMode,
|
|
2534
|
+
onChange
|
|
2535
|
+
});
|
|
2536
|
+
live.current = {
|
|
2537
|
+
mode,
|
|
2538
|
+
canEdit,
|
|
2539
|
+
zoneLabel,
|
|
2540
|
+
components: c.components,
|
|
2541
|
+
setMode,
|
|
2542
|
+
onChange
|
|
2543
|
+
};
|
|
2544
|
+
const send = React4.useCallback(() => {
|
|
2545
|
+
iframe.current?.contentWindow?.postMessage(
|
|
2546
|
+
{
|
|
2547
|
+
protocol: PROTOCOL,
|
|
2548
|
+
channel,
|
|
2549
|
+
type: "update-page",
|
|
2550
|
+
blocks: projectPage(
|
|
2551
|
+
latest.current,
|
|
2552
|
+
live.current.components,
|
|
2553
|
+
window.location.origin
|
|
2554
|
+
),
|
|
2555
|
+
groups,
|
|
2556
|
+
locale: t.locale,
|
|
2557
|
+
mode: live.current.mode
|
|
2558
|
+
},
|
|
2559
|
+
origin
|
|
2560
|
+
);
|
|
1913
2561
|
}, [channel, origin]);
|
|
1914
2562
|
const indexOf = (key) => latest.current.findIndex((row) => blockKey(row) === key);
|
|
1915
2563
|
const path = (key, field) => `${zone}.${indexOf(key)}.${field}`;
|
|
1916
|
-
|
|
2564
|
+
React4.useEffect(() => {
|
|
1917
2565
|
if (resizable) markLayout(anchor.current);
|
|
1918
2566
|
document.body.classList.toggle("bp-split", resizable);
|
|
1919
2567
|
document.documentElement.style.setProperty("--bp-pane", `${paneWidth}px`);
|
|
@@ -1925,7 +2573,9 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1925
2573
|
if (persist) write(RATIO_KEY, String(next));
|
|
1926
2574
|
};
|
|
1927
2575
|
const focusField = (index, field) => {
|
|
1928
|
-
const item = findZoneList(live.current.zoneLabel)?.querySelectorAll(
|
|
2576
|
+
const item = findZoneList(live.current.zoneLabel)?.querySelectorAll(
|
|
2577
|
+
":scope > li"
|
|
2578
|
+
)[index];
|
|
1929
2579
|
if (!item) return;
|
|
1930
2580
|
const header = toggles(item.parentElement)[index];
|
|
1931
2581
|
if (header?.getAttribute("aria-expanded") === "false") header.click();
|
|
@@ -1936,33 +2586,47 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1936
2586
|
if (++tries > 40) return clearInterval(timer);
|
|
1937
2587
|
let scope = item;
|
|
1938
2588
|
for (let i = 0; i + 1 < parts.length; i += 2) {
|
|
1939
|
-
const nested = [
|
|
2589
|
+
const nested = [
|
|
2590
|
+
...scope.querySelectorAll(
|
|
2591
|
+
"button[aria-expanded][data-radix-collection-item]"
|
|
2592
|
+
)
|
|
2593
|
+
].filter((b) => b !== header);
|
|
1940
2594
|
const row = nested[Number(parts[i + 1])];
|
|
1941
2595
|
if (!row) return;
|
|
1942
2596
|
if (row.getAttribute("aria-expanded") === "false") row.click();
|
|
1943
2597
|
scope = row.closest("li, div") || scope;
|
|
1944
2598
|
}
|
|
1945
|
-
const target = document.querySelector(
|
|
2599
|
+
const target = document.querySelector(
|
|
2600
|
+
`[name="${escaped}"], label[for="${escaped}"]`
|
|
2601
|
+
);
|
|
1946
2602
|
if (!target) return;
|
|
1947
2603
|
const INPUT = '.ck-editor__editable, textarea, input:not([type="hidden"]), select';
|
|
1948
2604
|
let container = target.matches(INPUT) ? target : target.parentElement;
|
|
1949
|
-
for (let depth = 0; container && depth < 4 && !container.matches(INPUT) && !container.querySelector(INPUT); depth++)
|
|
2605
|
+
for (let depth = 0; container && depth < 4 && !container.matches(INPUT) && !container.querySelector(INPUT); depth++)
|
|
2606
|
+
container = container.parentElement;
|
|
1950
2607
|
const editable = container?.matches(INPUT) ? container : container?.querySelector(INPUT);
|
|
1951
2608
|
if (!editable) return;
|
|
1952
|
-
if (editable.classList.contains("ck-editor__editable") && !editable.isContentEditable)
|
|
2609
|
+
if (editable.classList.contains("ck-editor__editable") && !editable.isContentEditable)
|
|
2610
|
+
return;
|
|
1953
2611
|
editable.focus();
|
|
1954
2612
|
if (document.activeElement !== editable) return;
|
|
1955
2613
|
clearInterval(timer);
|
|
1956
2614
|
editable.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
1957
2615
|
}, 150);
|
|
1958
2616
|
};
|
|
1959
|
-
|
|
2617
|
+
React4.useEffect(() => {
|
|
1960
2618
|
if (!active) return;
|
|
1961
2619
|
setReady(false);
|
|
1962
2620
|
setFailed(false);
|
|
1963
2621
|
const timeout = setTimeout(() => setFailed(true), 15e3);
|
|
1964
2622
|
const receive = (event) => {
|
|
1965
|
-
const is = (type) => isPreviewMessage(
|
|
2623
|
+
const is = (type) => isPreviewMessage(
|
|
2624
|
+
event,
|
|
2625
|
+
origin,
|
|
2626
|
+
iframe.current?.contentWindow,
|
|
2627
|
+
channel,
|
|
2628
|
+
type
|
|
2629
|
+
);
|
|
1966
2630
|
const { mode: mode2, canEdit: canEdit2, zoneLabel: zoneLabel2, components: components2, setMode: setMode2, onChange: onChange2 } = live.current;
|
|
1967
2631
|
if (is("ready")) {
|
|
1968
2632
|
clearTimeout(timeout);
|
|
@@ -1982,12 +2646,21 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1982
2646
|
return;
|
|
1983
2647
|
}
|
|
1984
2648
|
if (is("move-group") && canEdit2 && groups) {
|
|
1985
|
-
const next = (0, import_groups.moveGroup)(
|
|
2649
|
+
const next = (0, import_groups.moveGroup)(
|
|
2650
|
+
latest.current,
|
|
2651
|
+
String(event.data.key),
|
|
2652
|
+
event.data.direction === "up" ? "up" : "down",
|
|
2653
|
+
groups
|
|
2654
|
+
);
|
|
1986
2655
|
if (next) onChange2(zone, next);
|
|
1987
2656
|
return;
|
|
1988
2657
|
}
|
|
1989
2658
|
if (is("delete-group") && canEdit2 && groups) {
|
|
1990
|
-
const next = (0, import_groups.removeGroup)(
|
|
2659
|
+
const next = (0, import_groups.removeGroup)(
|
|
2660
|
+
latest.current,
|
|
2661
|
+
String(event.data.key),
|
|
2662
|
+
groups
|
|
2663
|
+
);
|
|
1991
2664
|
if (next) onChange2(zone, next);
|
|
1992
2665
|
return;
|
|
1993
2666
|
}
|
|
@@ -1997,13 +2670,20 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1997
2670
|
const uid2 = String(event.data.uid || "");
|
|
1998
2671
|
const close = groups[uid2];
|
|
1999
2672
|
const allowed = zoneAttr?.components || [];
|
|
2000
|
-
if (index2 < 0 || !close || !allowed.includes(uid2) || !allowed.includes(close))
|
|
2673
|
+
if (index2 < 0 || !close || !allowed.includes(uid2) || !allowed.includes(close))
|
|
2674
|
+
return;
|
|
2001
2675
|
if (latest.current.length + 2 > (zoneAttr?.max ?? Infinity)) {
|
|
2002
2676
|
toggleNotification({ type: "info", message: t.zoneFull });
|
|
2003
2677
|
return;
|
|
2004
2678
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2679
|
+
insertRows(
|
|
2680
|
+
index2,
|
|
2681
|
+
{
|
|
2682
|
+
...componentDefaults(components2[uid2], components2),
|
|
2683
|
+
__component: uid2
|
|
2684
|
+
},
|
|
2685
|
+
{ __component: close }
|
|
2686
|
+
);
|
|
2007
2687
|
return;
|
|
2008
2688
|
}
|
|
2009
2689
|
const key = typeof event.data?.key === "string" ? event.data.key : "";
|
|
@@ -2023,11 +2703,21 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2023
2703
|
}, 1500);
|
|
2024
2704
|
}
|
|
2025
2705
|
if (mode2 === "preview") setMode2("split");
|
|
2026
|
-
iframe.current?.contentWindow?.postMessage(
|
|
2706
|
+
iframe.current?.contentWindow?.postMessage(
|
|
2707
|
+
{ protocol: PROTOCOL, channel, type: "highlight", key },
|
|
2708
|
+
origin
|
|
2709
|
+
);
|
|
2027
2710
|
} else if (is("focus")) {
|
|
2028
2711
|
const attr = validateFocus(uid, event.data.field, components2);
|
|
2029
2712
|
if (!attr) return;
|
|
2030
|
-
if (mode2 === "preview" && canEdit2 && (attr.customField || MODAL_TYPES.includes(attr.type)))
|
|
2713
|
+
if (mode2 === "preview" && canEdit2 && (attr.customField || MODAL_TYPES.includes(attr.type)))
|
|
2714
|
+
setEditing({
|
|
2715
|
+
key,
|
|
2716
|
+
field: event.data.field,
|
|
2717
|
+
attr,
|
|
2718
|
+
label: `${components2[uid]?.info?.displayName || uid} \xB7 ${event.data.field}`,
|
|
2719
|
+
value: getIn(latest.current[index], event.data.field)
|
|
2720
|
+
});
|
|
2031
2721
|
else focusField(index, event.data.field);
|
|
2032
2722
|
} else if (is("media") && canEdit2) {
|
|
2033
2723
|
const attr = mediaAttribute(uid, event.data.field, components2);
|
|
@@ -2036,27 +2726,67 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2036
2726
|
const attr = mediaAttribute(uid, event.data.field, components2);
|
|
2037
2727
|
if (attr && !attr.required) onChange2(path(key, event.data.field), null);
|
|
2038
2728
|
} else if (is("edit") && canEdit2) {
|
|
2039
|
-
const value = validateEdit(
|
|
2729
|
+
const value = validateEdit(
|
|
2730
|
+
uid,
|
|
2731
|
+
event.data.field,
|
|
2732
|
+
event.data.value,
|
|
2733
|
+
components2
|
|
2734
|
+
);
|
|
2040
2735
|
if (value !== null) onChange2(path(key, event.data.field), value);
|
|
2041
2736
|
}
|
|
2042
2737
|
};
|
|
2043
2738
|
window.addEventListener("message", receive);
|
|
2044
|
-
if (loaded.current)
|
|
2739
|
+
if (loaded.current)
|
|
2740
|
+
iframe.current?.contentWindow?.postMessage(
|
|
2741
|
+
{ protocol: PROTOCOL, channel, type: "ping" },
|
|
2742
|
+
origin
|
|
2743
|
+
);
|
|
2045
2744
|
return () => {
|
|
2046
2745
|
clearTimeout(timeout);
|
|
2047
2746
|
window.removeEventListener("message", receive);
|
|
2048
2747
|
};
|
|
2049
2748
|
}, [active, attempt, channel, origin, groups]);
|
|
2050
|
-
|
|
2749
|
+
React4.useEffect(() => {
|
|
2051
2750
|
if (!ready || !active) return;
|
|
2052
2751
|
const timer = setTimeout(send, 120);
|
|
2053
2752
|
return () => clearTimeout(timer);
|
|
2054
2753
|
}, [values, c.components, ready, active, send, mode]);
|
|
2055
2754
|
if (!zone) return null;
|
|
2056
|
-
const modes = [
|
|
2057
|
-
|
|
2755
|
+
const modes = [
|
|
2756
|
+
["form", t.modeForm],
|
|
2757
|
+
["split", t.modeSplit],
|
|
2758
|
+
["preview", t.modePreview]
|
|
2759
|
+
];
|
|
2760
|
+
const switcher = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2761
|
+
import_design_system3.Flex,
|
|
2762
|
+
{
|
|
2763
|
+
gap: 1,
|
|
2764
|
+
wrap: "wrap",
|
|
2765
|
+
"data-testid": "page-preview-modes",
|
|
2766
|
+
role: "group",
|
|
2767
|
+
"aria-label": t.modeGroup,
|
|
2768
|
+
children: modes.map(([value, label]) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2769
|
+
import_design_system3.Button,
|
|
2770
|
+
{
|
|
2771
|
+
type: "button",
|
|
2772
|
+
size: "S",
|
|
2773
|
+
variant: mode === value ? "default" : "tertiary",
|
|
2774
|
+
"aria-pressed": mode === value,
|
|
2775
|
+
onClick: () => setMode(value),
|
|
2776
|
+
disabled: !url && value !== "form",
|
|
2777
|
+
children: label
|
|
2778
|
+
},
|
|
2779
|
+
value
|
|
2780
|
+
))
|
|
2781
|
+
}
|
|
2782
|
+
);
|
|
2058
2783
|
const onKey = (event) => {
|
|
2059
|
-
const map = {
|
|
2784
|
+
const map = {
|
|
2785
|
+
ArrowLeft: paneWidth + KEY_STEP,
|
|
2786
|
+
ArrowRight: paneWidth - KEY_STEP,
|
|
2787
|
+
Home: MIN_PANE,
|
|
2788
|
+
End: vw - MIN_FORM
|
|
2789
|
+
};
|
|
2060
2790
|
if (event.key in map) {
|
|
2061
2791
|
event.preventDefault();
|
|
2062
2792
|
applyWidth(map[event.key], true);
|
|
@@ -2065,30 +2795,71 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2065
2795
|
const problems = groups ? (0, import_groups.validateGroups)(rows, groups) : [];
|
|
2066
2796
|
const insertClose = (error) => {
|
|
2067
2797
|
const end = (0, import_groups.groupRange)(latest.current, error.index, groups)[1];
|
|
2068
|
-
|
|
2798
|
+
insertRows(end + 1, { __component: error.expected });
|
|
2069
2799
|
};
|
|
2070
|
-
const diagnostics = problems.length > 0 && /* @__PURE__ */ (0,
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2800
|
+
const diagnostics = problems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2801
|
+
import_design_system3.Box,
|
|
2802
|
+
{
|
|
2803
|
+
role: "alert",
|
|
2804
|
+
"data-testid": "page-preview-diagnostics",
|
|
2805
|
+
padding: 2,
|
|
2806
|
+
background: "danger100",
|
|
2807
|
+
hasRadius: true,
|
|
2808
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("details", { children: [
|
|
2809
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("summary", { style: { cursor: "pointer" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Typography, { variant: "pi", fontWeight: "bold", textColor: "danger700", children: t.f("diagSummary", { count: problems.length }) }) }),
|
|
2810
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { style: { margin: "6px 0 0 16px", padding: 0 }, children: problems.map((error) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2811
|
+
"li",
|
|
2812
|
+
{
|
|
2813
|
+
style: { marginBottom: 6 },
|
|
2814
|
+
children: [
|
|
2815
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Typography, { variant: "pi", textColor: "danger700", children: t.f(
|
|
2816
|
+
error.code === "closeBeforeOpen" ? "diagCloseBeforeOpen" : error.code === "mismatch" ? "diagMismatch" : "diagUnclosed",
|
|
2817
|
+
{
|
|
2818
|
+
n: error.index + 1,
|
|
2819
|
+
uid: error.uid,
|
|
2820
|
+
open: error.open || "",
|
|
2821
|
+
expected: error.expected || ""
|
|
2822
|
+
}
|
|
2823
|
+
) }),
|
|
2824
|
+
error.code === "unclosed" && canEdit && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Box, { paddingTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2825
|
+
import_design_system3.Button,
|
|
2826
|
+
{
|
|
2827
|
+
size: "S",
|
|
2828
|
+
variant: "danger-light",
|
|
2829
|
+
"data-testid": `diag-insert-close-${error.index}`,
|
|
2830
|
+
onClick: () => insertClose(error),
|
|
2831
|
+
children: t.f("diagInsertClose", {
|
|
2832
|
+
n: error.index + 1,
|
|
2833
|
+
expected: error.expected
|
|
2834
|
+
})
|
|
2835
|
+
}
|
|
2836
|
+
) }),
|
|
2837
|
+
error.code === "closeBeforeOpen" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Typography, { variant: "pi", textColor: "neutral600", children: t.diagStrayHint })
|
|
2838
|
+
]
|
|
2839
|
+
},
|
|
2840
|
+
`${error.code}-${error.index}`
|
|
2841
|
+
)) })
|
|
2842
|
+
] })
|
|
2843
|
+
}
|
|
2844
|
+
);
|
|
2845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_design_system3.Flex, { direction: "column", alignItems: "stretch", gap: 2, ref: anchor, children: [
|
|
2079
2846
|
switcher,
|
|
2080
2847
|
diagnostics,
|
|
2081
|
-
/* @__PURE__ */ (0,
|
|
2082
|
-
active && (0,
|
|
2083
|
-
/* @__PURE__ */ (0,
|
|
2848
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Typography, { variant: "pi", textColor: "neutral600", children: url ? t.previewHelp : t.previewNoUrl }),
|
|
2849
|
+
active && (0, import_react_dom3.createPortal)(
|
|
2850
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2084
2851
|
Pane,
|
|
2085
2852
|
{
|
|
2086
2853
|
"data-testid": "page-preview-pane",
|
|
2087
2854
|
"aria-label": t.previewPane,
|
|
2088
|
-
style: {
|
|
2855
|
+
style: {
|
|
2856
|
+
left: mode === "preview" || narrow ? main.left : main.left + main.width - paneWidth,
|
|
2857
|
+
width: mode === "preview" || narrow ? main.width : paneWidth,
|
|
2858
|
+
userSelect: dragging ? "none" : void 0
|
|
2859
|
+
},
|
|
2089
2860
|
children: [
|
|
2090
|
-
/* @__PURE__ */ (0,
|
|
2091
|
-
resizable && /* @__PURE__ */ (0,
|
|
2861
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: SPLIT_STYLE }),
|
|
2862
|
+
resizable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2092
2863
|
Handle,
|
|
2093
2864
|
{
|
|
2094
2865
|
role: "separator",
|
|
@@ -2106,7 +2877,8 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2106
2877
|
setDragging(true);
|
|
2107
2878
|
},
|
|
2108
2879
|
onPointerMove: (e) => {
|
|
2109
|
-
if (dragging)
|
|
2880
|
+
if (dragging)
|
|
2881
|
+
applyWidth(main.left + main.width - e.clientX, false);
|
|
2110
2882
|
},
|
|
2111
2883
|
onPointerUp: (e) => {
|
|
2112
2884
|
if (!dragging) return;
|
|
@@ -2118,15 +2890,44 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2118
2890
|
onKeyDown: onKey
|
|
2119
2891
|
}
|
|
2120
2892
|
),
|
|
2121
|
-
/* @__PURE__ */ (0,
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2893
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2894
|
+
import_design_system3.Flex,
|
|
2895
|
+
{
|
|
2896
|
+
padding: 2,
|
|
2897
|
+
gap: 2,
|
|
2898
|
+
justifyContent: "space-between",
|
|
2899
|
+
alignItems: "center",
|
|
2900
|
+
background: "neutral100",
|
|
2901
|
+
wrap: "wrap",
|
|
2902
|
+
style: { position: "sticky", top: 0, zIndex: 2 },
|
|
2903
|
+
children: [
|
|
2904
|
+
switcher,
|
|
2905
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2906
|
+
import_design_system3.Flex,
|
|
2907
|
+
{
|
|
2908
|
+
gap: 2,
|
|
2909
|
+
alignItems: "center",
|
|
2910
|
+
wrap: "wrap",
|
|
2911
|
+
style: { marginLeft: "auto" },
|
|
2912
|
+
children: [
|
|
2913
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Typography, { variant: "pi", role: "status", textColor: "neutral600", children: failed ? t.previewFailed : ready ? t.previewReady : t.previewLoading }),
|
|
2914
|
+
failed && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system3.Button, { size: "S", variant: "secondary", onClick: retry, children: t.retry }),
|
|
2915
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2916
|
+
ToolbarActions,
|
|
2917
|
+
{
|
|
2918
|
+
model: c.model,
|
|
2919
|
+
collectionType: c.collectionType,
|
|
2920
|
+
documentId: c.isCreatingEntry ? void 0 : c.id,
|
|
2921
|
+
locale: c.form?.initialValues?.locale
|
|
2922
|
+
}
|
|
2923
|
+
)
|
|
2924
|
+
]
|
|
2925
|
+
}
|
|
2926
|
+
)
|
|
2927
|
+
]
|
|
2928
|
+
}
|
|
2929
|
+
),
|
|
2930
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2130
2931
|
Frame2,
|
|
2131
2932
|
{
|
|
2132
2933
|
ref: iframe,
|
|
@@ -2146,12 +2947,16 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2146
2947
|
),
|
|
2147
2948
|
document.body
|
|
2148
2949
|
),
|
|
2149
|
-
inserting && zoneAttr && /* @__PURE__ */ (0,
|
|
2950
|
+
inserting && zoneAttr && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2150
2951
|
PickerModal,
|
|
2151
2952
|
{
|
|
2152
|
-
zone: {
|
|
2953
|
+
zone: {
|
|
2954
|
+
name: zone,
|
|
2955
|
+
components: zoneAttr.components || [],
|
|
2956
|
+
max: zoneAttr.max
|
|
2957
|
+
},
|
|
2153
2958
|
components: c.components,
|
|
2154
|
-
Modal:
|
|
2959
|
+
Modal: Modal3,
|
|
2155
2960
|
Toggle,
|
|
2156
2961
|
get,
|
|
2157
2962
|
open: true,
|
|
@@ -2163,15 +2968,24 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2163
2968
|
setInserting(null);
|
|
2164
2969
|
const close = groups?.[uid];
|
|
2165
2970
|
if (index < 0 || !(zoneAttr.components || []).includes(uid) || close && !(zoneAttr.components || []).includes(close) || latest.current.length + (close ? 2 : 1) > (zoneAttr.max ?? Infinity)) {
|
|
2166
|
-
toggleNotification({
|
|
2971
|
+
toggleNotification({
|
|
2972
|
+
type: "warning",
|
|
2973
|
+
message: close ? t.zoneFull : t.insertMoved
|
|
2974
|
+
});
|
|
2167
2975
|
return;
|
|
2168
2976
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2977
|
+
insertRows(
|
|
2978
|
+
index,
|
|
2979
|
+
{
|
|
2980
|
+
...componentDefaults(c.components[uid], c.components),
|
|
2981
|
+
__component: uid
|
|
2982
|
+
},
|
|
2983
|
+
...close ? [{ __component: close }] : []
|
|
2984
|
+
);
|
|
2171
2985
|
}
|
|
2172
2986
|
}
|
|
2173
2987
|
),
|
|
2174
|
-
editing && /* @__PURE__ */ (0,
|
|
2988
|
+
editing && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2175
2989
|
FieldEditorModal,
|
|
2176
2990
|
{
|
|
2177
2991
|
label: editing.label,
|
|
@@ -2181,11 +2995,12 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2181
2995
|
onApply: (value) => {
|
|
2182
2996
|
const index = indexOf(editing.key);
|
|
2183
2997
|
setEditing(null);
|
|
2184
|
-
if (index >= 0)
|
|
2998
|
+
if (index >= 0)
|
|
2999
|
+
onChange(`${zone}.${index}.${editing.field}`, value);
|
|
2185
3000
|
}
|
|
2186
3001
|
}
|
|
2187
3002
|
),
|
|
2188
|
-
picking && MediaLibraryDialog && /* @__PURE__ */ (0,
|
|
3003
|
+
picking && MediaLibraryDialog && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2189
3004
|
MediaLibraryDialog,
|
|
2190
3005
|
{
|
|
2191
3006
|
allowedTypes: picking.attr.allowedTypes || ["images"],
|
|
@@ -2196,19 +3011,32 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2196
3011
|
setPicking(null);
|
|
2197
3012
|
if (index < 0 || !assets?.length) return;
|
|
2198
3013
|
const current = getIn(latest.current[index], picking.field);
|
|
2199
|
-
onChange(
|
|
3014
|
+
onChange(
|
|
3015
|
+
`${zone}.${index}.${picking.field}`,
|
|
3016
|
+
picking.attr.multiple ? [...Array.isArray(current) ? current : [], ...assets] : assets[0]
|
|
3017
|
+
);
|
|
2200
3018
|
}
|
|
2201
3019
|
}
|
|
2202
3020
|
),
|
|
2203
|
-
/* @__PURE__ */ (0,
|
|
3021
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3022
|
+
import_design_system3.Box,
|
|
3023
|
+
{
|
|
3024
|
+
hidden: true,
|
|
3025
|
+
"data-testid": "page-preview-state",
|
|
3026
|
+
"data-mode": mode,
|
|
3027
|
+
"data-ready": ready,
|
|
3028
|
+
"data-failed": failed,
|
|
3029
|
+
"data-preview-source": source
|
|
3030
|
+
}
|
|
3031
|
+
)
|
|
2204
3032
|
] });
|
|
2205
3033
|
}
|
|
2206
3034
|
|
|
2207
3035
|
// admin/Settings.tsx
|
|
2208
|
-
var
|
|
2209
|
-
var
|
|
3036
|
+
var React5 = __toESM(require("react"));
|
|
3037
|
+
var import_design_system4 = require("@strapi/design-system");
|
|
2210
3038
|
var import_styled_components3 = __toESM(require("styled-components"));
|
|
2211
|
-
var
|
|
3039
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2212
3040
|
var COLOR2 = /^#[0-9A-Fa-f]{6}$/;
|
|
2213
3041
|
var Grid = import_styled_components3.default.div` display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 16px; `;
|
|
2214
3042
|
var Card2 = import_styled_components3.default.div`
|
|
@@ -2221,8 +3049,8 @@ var Bar = import_styled_components3.default.div`
|
|
|
2221
3049
|
box-shadow: 0 1px 4px rgba(33, 33, 52, 0.1);
|
|
2222
3050
|
`;
|
|
2223
3051
|
function useMainRect2(anchor) {
|
|
2224
|
-
const [rect, setRect] =
|
|
2225
|
-
|
|
3052
|
+
const [rect, setRect] = React5.useState({ left: 0, width: 0 });
|
|
3053
|
+
React5.useEffect(() => {
|
|
2226
3054
|
const read2 = () => {
|
|
2227
3055
|
let host = document.getElementById("main-content");
|
|
2228
3056
|
for (let el = anchor.current?.parentElement; !host && el; el = el.parentElement) if (["auto", "scroll"].includes(getComputedStyle(el).overflowY) && el.scrollHeight > el.clientHeight) host = el;
|
|
@@ -2239,11 +3067,11 @@ var Swatches = import_styled_components3.default.div` display: grid; grid-templa
|
|
|
2239
3067
|
var Label = import_styled_components3.default.label` display: flex; flex-direction: column; gap: 4px; font-size: 12px; `;
|
|
2240
3068
|
function ColorField({ name, label, value, onChange, disabled }) {
|
|
2241
3069
|
const valid = COLOR2.test(value);
|
|
2242
|
-
return /* @__PURE__ */ (0,
|
|
2243
|
-
/* @__PURE__ */ (0,
|
|
2244
|
-
/* @__PURE__ */ (0,
|
|
2245
|
-
/* @__PURE__ */ (0,
|
|
2246
|
-
/* @__PURE__ */ (0,
|
|
3070
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Label, { children: [
|
|
3071
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
|
|
3072
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { gap: 2, children: [
|
|
3073
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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" } }),
|
|
3074
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2247
3075
|
"input",
|
|
2248
3076
|
{
|
|
2249
3077
|
name,
|
|
@@ -2263,18 +3091,18 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2263
3091
|
const t = useMessages();
|
|
2264
3092
|
const { get, put } = useClient();
|
|
2265
3093
|
const { canRead, canUpdate, isLoading } = usePermissions2();
|
|
2266
|
-
const [data, setData] =
|
|
2267
|
-
const [catalog, setCatalog] =
|
|
2268
|
-
const [settings, setSettings] =
|
|
2269
|
-
const [media, setMedia] =
|
|
2270
|
-
const [sources, setSources] =
|
|
2271
|
-
const [dirty, setDirty] =
|
|
2272
|
-
const [saving, setSaving] =
|
|
2273
|
-
const [status, setStatus] =
|
|
2274
|
-
const [failed, setFailed] =
|
|
2275
|
-
const [filter, setFilter] =
|
|
2276
|
-
const [picking, setPicking] =
|
|
2277
|
-
|
|
3094
|
+
const [data, setData] = React5.useState(null);
|
|
3095
|
+
const [catalog, setCatalog] = React5.useState(null);
|
|
3096
|
+
const [settings, setSettings] = React5.useState(null);
|
|
3097
|
+
const [media, setMedia] = React5.useState({});
|
|
3098
|
+
const [sources, setSources] = React5.useState({});
|
|
3099
|
+
const [dirty, setDirty] = React5.useState(false);
|
|
3100
|
+
const [saving, setSaving] = React5.useState(false);
|
|
3101
|
+
const [status, setStatus] = React5.useState("");
|
|
3102
|
+
const [failed, setFailed] = React5.useState(false);
|
|
3103
|
+
const [filter, setFilter] = React5.useState("");
|
|
3104
|
+
const [picking, setPicking] = React5.useState(null);
|
|
3105
|
+
React5.useEffect(() => {
|
|
2278
3106
|
if (!canRead || isLoading) return;
|
|
2279
3107
|
let active = true;
|
|
2280
3108
|
Promise.all([get("/blockscene/settings"), get("/blockscene/catalog")]).then(([s, c]) => {
|
|
@@ -2322,35 +3150,35 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2322
3150
|
return index === 0 && manual ? t.manual : t.automatic;
|
|
2323
3151
|
};
|
|
2324
3152
|
const ready = !isLoading && canRead && !failed && settings && catalog;
|
|
2325
|
-
const header =
|
|
2326
|
-
const [floating, setFloating] =
|
|
3153
|
+
const header = React5.useRef(null);
|
|
3154
|
+
const [floating, setFloating] = React5.useState(false);
|
|
2327
3155
|
const main = useMainRect2(header);
|
|
2328
|
-
|
|
3156
|
+
React5.useEffect(() => {
|
|
2329
3157
|
const el = header.current;
|
|
2330
3158
|
if (!el || typeof IntersectionObserver === "undefined") return;
|
|
2331
3159
|
const observer = new IntersectionObserver(([entry]) => setFloating(!entry.isIntersecting && entry.boundingClientRect.top < 0));
|
|
2332
3160
|
observer.observe(el);
|
|
2333
3161
|
return () => observer.disconnect();
|
|
2334
3162
|
}, [ready]);
|
|
2335
|
-
const controls = (suffix) => ready && /* @__PURE__ */ (0,
|
|
2336
|
-
/* @__PURE__ */ (0,
|
|
2337
|
-
/* @__PURE__ */ (0,
|
|
3163
|
+
const controls = (suffix) => ready && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
|
|
3164
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.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 }),
|
|
3165
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Button, { onClick: save, disabled: !canUpdate || invalid || !dirty, loading: saving, "data-testid": `save-blockscene-settings${suffix}`, children: t.save })
|
|
2338
3166
|
] });
|
|
2339
|
-
return /* @__PURE__ */ (0,
|
|
2340
|
-
/* @__PURE__ */ (0,
|
|
2341
|
-
/* @__PURE__ */ (0,
|
|
3167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Box, { padding: 8, background: "neutral100", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { direction: "column", alignItems: "stretch", gap: 5, children: [
|
|
3168
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: header, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
|
|
3169
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "alpha", tag: "h1", children: t.settingsTitle }),
|
|
2342
3170
|
controls("")
|
|
2343
3171
|
] }) }),
|
|
2344
|
-
floating && main.width > 0 && /* @__PURE__ */ (0,
|
|
2345
|
-
/* @__PURE__ */ (0,
|
|
3172
|
+
floating && main.width > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Bar, { style: { left: main.left, width: main.width }, "data-testid": "settings-floating-bar", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
|
|
3173
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "beta", tag: "p", children: t.settingsTitle }),
|
|
2346
3174
|
controls("-floating")
|
|
2347
3175
|
] }) }),
|
|
2348
|
-
/* @__PURE__ */ (0,
|
|
2349
|
-
isLoading ? /* @__PURE__ */ (0,
|
|
2350
|
-
data.disabled && /* @__PURE__ */ (0,
|
|
2351
|
-
/* @__PURE__ */ (0,
|
|
2352
|
-
/* @__PURE__ */ (0,
|
|
2353
|
-
/* @__PURE__ */ (0,
|
|
3176
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { textColor: "neutral600", children: t.settingsIntro }),
|
|
3177
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { children: "\u2026" }) : !canRead ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { role: "alert", children: t.denied }) : failed ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { role: "alert", children: t.loadFailed }) : !settings || !catalog ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { children: t.loading }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
3178
|
+
data.disabled && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Box, { padding: 4, background: "warning100", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { role: "alert", textColor: "warning700", children: t.disabledByServer }) }),
|
|
3179
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
3180
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "beta", tag: "h2", children: t.palette }),
|
|
3181
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Swatches, { children: Object.keys(DEFAULT_PALETTE).map((key) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2354
3182
|
ColorField,
|
|
2355
3183
|
{
|
|
2356
3184
|
name: `palette-${key}`,
|
|
@@ -2364,33 +3192,33 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2364
3192
|
},
|
|
2365
3193
|
key
|
|
2366
3194
|
)) }),
|
|
2367
|
-
invalid && /* @__PURE__ */ (0,
|
|
2368
|
-
/* @__PURE__ */ (0,
|
|
2369
|
-
/* @__PURE__ */ (0,
|
|
2370
|
-
/* @__PURE__ */ (0,
|
|
2371
|
-
/* @__PURE__ */ (0,
|
|
3195
|
+
invalid && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { role: "alert", textColor: "danger600", children: t.invalidColor }),
|
|
3196
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.previewLabel }),
|
|
3197
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Swatches, { "data-testid": "palette-preview", children: TEMPLATES.map((template) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { direction: "column", gap: 1, children: [
|
|
3198
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Box, { style: { aspectRatio: "16 / 9", overflow: "hidden" }, hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Wireframe, { template, palette: settings.palette }) }),
|
|
3199
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.templates[template] })
|
|
2372
3200
|
] }, template)) }),
|
|
2373
|
-
/* @__PURE__ */ (0,
|
|
3201
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Button, { variant: "tertiary", size: "S", disabled: !canUpdate, onClick: () => update((s) => {
|
|
2374
3202
|
s.palette = { ...DEFAULT_PALETTE };
|
|
2375
3203
|
return s;
|
|
2376
3204
|
}), children: t.resetPalette }) })
|
|
2377
3205
|
] }) }),
|
|
2378
|
-
/* @__PURE__ */ (0,
|
|
2379
|
-
/* @__PURE__ */ (0,
|
|
2380
|
-
/* @__PURE__ */ (0,
|
|
3206
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
3207
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "beta", tag: "h2", children: t.editor }),
|
|
3208
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ToggleField2, { name: "editor-enabled", label: t.enabled, value: editor.enabled, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
2381
3209
|
s.editor.enabled = v;
|
|
2382
3210
|
return s;
|
|
2383
3211
|
}) }),
|
|
2384
|
-
/* @__PURE__ */ (0,
|
|
2385
|
-
/* @__PURE__ */ (0,
|
|
3212
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.enabledHelp }),
|
|
3213
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ToggleField2, { name: "editor-showOpenAll", label: t.showOpenAll, value: editor.showOpenAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
2386
3214
|
s.editor.showOpenAll = v;
|
|
2387
3215
|
return s;
|
|
2388
3216
|
}) }),
|
|
2389
|
-
/* @__PURE__ */ (0,
|
|
3217
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ToggleField2, { name: "editor-showCloseAll", label: t.showCloseAll, value: editor.showCloseAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
2390
3218
|
s.editor.showCloseAll = v;
|
|
2391
3219
|
return s;
|
|
2392
3220
|
}) }),
|
|
2393
|
-
/* @__PURE__ */ (0,
|
|
3221
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2394
3222
|
SelectField2,
|
|
2395
3223
|
{
|
|
2396
3224
|
name: "editor-initialState",
|
|
@@ -2404,9 +3232,9 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2404
3232
|
})
|
|
2405
3233
|
}
|
|
2406
3234
|
),
|
|
2407
|
-
/* @__PURE__ */ (0,
|
|
2408
|
-
previewSupported ? /* @__PURE__ */ (0,
|
|
2409
|
-
/* @__PURE__ */ (0,
|
|
3235
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.rememberHelp }),
|
|
3236
|
+
previewSupported ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
3237
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2410
3238
|
TextField2,
|
|
2411
3239
|
{
|
|
2412
3240
|
name: "editor-previewUrl",
|
|
@@ -2420,8 +3248,8 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2420
3248
|
})
|
|
2421
3249
|
}
|
|
2422
3250
|
),
|
|
2423
|
-
/* @__PURE__ */ (0,
|
|
2424
|
-
/* @__PURE__ */ (0,
|
|
3251
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.previewUrlHelp }),
|
|
3252
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2425
3253
|
SelectField2,
|
|
2426
3254
|
{
|
|
2427
3255
|
name: "editor-previewMode",
|
|
@@ -2435,26 +3263,26 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2435
3263
|
})
|
|
2436
3264
|
}
|
|
2437
3265
|
),
|
|
2438
|
-
/* @__PURE__ */ (0,
|
|
2439
|
-
data.blockPreviewAvailable && /* @__PURE__ */ (0,
|
|
2440
|
-
/* @__PURE__ */ (0,
|
|
3266
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.previewModeHelp }),
|
|
3267
|
+
data.blockPreviewAvailable && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
3268
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ToggleField2, { name: "editor-blockPreviewInForm", label: t.blockPreviewInForm, value: editor.blockPreviewInForm, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
2441
3269
|
s.editor.blockPreviewInForm = v;
|
|
2442
3270
|
return s;
|
|
2443
3271
|
}) }),
|
|
2444
|
-
/* @__PURE__ */ (0,
|
|
3272
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
|
|
2445
3273
|
] })
|
|
2446
|
-
] }) : /* @__PURE__ */ (0,
|
|
3274
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.previewV4 })
|
|
2447
3275
|
] }) }),
|
|
2448
|
-
/* @__PURE__ */ (0,
|
|
2449
|
-
/* @__PURE__ */ (0,
|
|
2450
|
-
/* @__PURE__ */ (0,
|
|
2451
|
-
/* @__PURE__ */ (0,
|
|
2452
|
-
/* @__PURE__ */ (0,
|
|
3276
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
3277
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "beta", tag: "h2", children: t.components }),
|
|
3278
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Searchbar, { name: "component-filter", value: filter, placeholder: t.filter, clearLabel: t.clear, onClear: () => setFilter(""), onChange: (e) => setFilter(e.target.value), children: t.filter }),
|
|
3279
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", "data-testid": "components-count", children: t.f("countAll", { count: components.length }) }),
|
|
3280
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Grid, { "data-testid": "components-grid", children: components.map((component) => {
|
|
2453
3281
|
const entry = settings.components[component.uid] || {};
|
|
2454
3282
|
const meta = { ...catalog.components?.[component.uid] || {}, ...media[component.uid] || {} };
|
|
2455
3283
|
const candidates = candidatesFor(component.uid, meta, catalog);
|
|
2456
|
-
return /* @__PURE__ */ (0,
|
|
2457
|
-
/* @__PURE__ */ (0,
|
|
3284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Card2, { "data-testid": `settings-${component.uid}`, children: [
|
|
3285
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2458
3286
|
Thumb,
|
|
2459
3287
|
{
|
|
2460
3288
|
candidates,
|
|
@@ -2465,23 +3293,23 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2465
3293
|
onResolved: (index) => setSources((current) => current[component.uid] === index ? current : { ...current, [component.uid]: index })
|
|
2466
3294
|
}
|
|
2467
3295
|
),
|
|
2468
|
-
/* @__PURE__ */ (0,
|
|
2469
|
-
/* @__PURE__ */ (0,
|
|
2470
|
-
/* @__PURE__ */ (0,
|
|
3296
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [
|
|
3297
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { fontWeight: "bold", textColor: "neutral800", children: component.displayName }),
|
|
3298
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
2471
3299
|
component.uid,
|
|
2472
3300
|
" \xB7 ",
|
|
2473
3301
|
component.category
|
|
2474
3302
|
] }),
|
|
2475
|
-
/* @__PURE__ */ (0,
|
|
3303
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Typography, { variant: "pi", "data-testid": `source-${component.uid}`, children: [
|
|
2476
3304
|
t.source,
|
|
2477
3305
|
": ",
|
|
2478
3306
|
sourceOf(component.uid, Boolean(meta.manualImage)),
|
|
2479
3307
|
meta.manualName ? ` (${meta.manualName})` : ""
|
|
2480
3308
|
] }),
|
|
2481
|
-
meta.manualMissing && /* @__PURE__ */ (0,
|
|
2482
|
-
/* @__PURE__ */ (0,
|
|
2483
|
-
/* @__PURE__ */ (0,
|
|
2484
|
-
entry.mediaId && /* @__PURE__ */ (0,
|
|
3309
|
+
meta.manualMissing && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", role: "alert", textColor: "danger600", children: t.brokenMedia }),
|
|
3310
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Flex, { gap: 2, wrap: "wrap", children: [
|
|
3311
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Button, { variant: "secondary", size: "S", disabled: !canUpdate || saving, onClick: () => setPicking(component.uid), children: entry.mediaId ? t.replace : t.choose }),
|
|
3312
|
+
entry.mediaId && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Button, { variant: "tertiary", size: "S", disabled: !canUpdate || saving, onClick: () => {
|
|
2485
3313
|
update((s) => {
|
|
2486
3314
|
delete s.components[component.uid]?.mediaId;
|
|
2487
3315
|
if (!Object.keys(s.components[component.uid] || {}).length) delete s.components[component.uid];
|
|
@@ -2494,7 +3322,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2494
3322
|
});
|
|
2495
3323
|
}, children: t.useAutomatic })
|
|
2496
3324
|
] }),
|
|
2497
|
-
/* @__PURE__ */ (0,
|
|
3325
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2498
3326
|
SelectField2,
|
|
2499
3327
|
{
|
|
2500
3328
|
name: `template-${component.uid}`,
|
|
@@ -2512,7 +3340,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2512
3340
|
] }, component.uid);
|
|
2513
3341
|
}) })
|
|
2514
3342
|
] }) }),
|
|
2515
|
-
picking && /* @__PURE__ */ (0,
|
|
3343
|
+
picking && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MediaPicker2, { onClose: () => setPicking(null), onSelect: (asset) => {
|
|
2516
3344
|
const uid = picking;
|
|
2517
3345
|
setPicking(null);
|
|
2518
3346
|
if (!asset?.id) return;
|
|
@@ -2525,24 +3353,26 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2525
3353
|
] })
|
|
2526
3354
|
] }) });
|
|
2527
3355
|
}
|
|
2528
|
-
function register(app, Component) {
|
|
3356
|
+
function register(app, Component, to) {
|
|
2529
3357
|
app.createSettingSection(
|
|
2530
3358
|
{ id: "blockscene", intlLabel: { id: "blockscene.title", defaultMessage: "Blockscene" } },
|
|
2531
3359
|
[{
|
|
2532
3360
|
id: "blockscene-settings",
|
|
2533
|
-
to
|
|
3361
|
+
to,
|
|
2534
3362
|
intlLabel: { id: "blockscene.settings", defaultMessage: "Gallery" },
|
|
2535
|
-
|
|
3363
|
+
// Module shape: older Strapi 4 (e.g. 4.11) only reads `.default` from the loader result.
|
|
3364
|
+
// Not an `async` function: Strapi 5 warns on AsyncFunction loaders.
|
|
3365
|
+
Component: () => Promise.resolve({ default: Component }),
|
|
2536
3366
|
permissions: permissions.read
|
|
2537
3367
|
}]
|
|
2538
3368
|
);
|
|
2539
3369
|
}
|
|
2540
3370
|
|
|
2541
3371
|
// admin/catalog.ts
|
|
2542
|
-
var
|
|
3372
|
+
var React6 = __toESM(require("react"));
|
|
2543
3373
|
function useCatalog(get) {
|
|
2544
|
-
const [catalog, setCatalog] =
|
|
2545
|
-
|
|
3374
|
+
const [catalog, setCatalog] = React6.useState(null);
|
|
3375
|
+
React6.useEffect(() => {
|
|
2546
3376
|
let active = true;
|
|
2547
3377
|
get("/blockscene/catalog").then(({ data }) => {
|
|
2548
3378
|
if (active) setCatalog(data);
|
|
@@ -2557,13 +3387,13 @@ function useCatalog(get) {
|
|
|
2557
3387
|
}
|
|
2558
3388
|
|
|
2559
3389
|
// admin/strapi5.tsx
|
|
2560
|
-
var
|
|
3390
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2561
3391
|
function Modal2({ open, onOpenChange, trigger, title, children }) {
|
|
2562
|
-
return /* @__PURE__ */ (0,
|
|
2563
|
-
/* @__PURE__ */ (0,
|
|
2564
|
-
/* @__PURE__ */ (0,
|
|
2565
|
-
/* @__PURE__ */ (0,
|
|
2566
|
-
/* @__PURE__ */ (0,
|
|
3392
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system5.Modal.Root, { open, onOpenChange, children: [
|
|
3393
|
+
trigger && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system5.Modal.Trigger, { children: trigger }),
|
|
3394
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system5.Modal.Content, { style: { width: "80vw", maxWidth: "80vw" }, children: [
|
|
3395
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system5.Modal.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system5.Modal.Title, { children: title }) }),
|
|
3396
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system5.Modal.Body, { children })
|
|
2567
3397
|
] })
|
|
2568
3398
|
] });
|
|
2569
3399
|
}
|
|
@@ -2583,52 +3413,157 @@ function Panel() {
|
|
|
2583
3413
|
formValues ?? c.form?.values,
|
|
2584
3414
|
(name) => allowed.includes(name) && (creating || (rbac.canReadFields || []).includes(name)) && fields.find((field) => field.name === name)?.disabled !== true,
|
|
2585
3415
|
c.isLoading || c.form?.disabled || !c.form?.addFieldRow
|
|
2586
|
-
).map((zone) => ({
|
|
3416
|
+
).map((zone) => ({
|
|
3417
|
+
...zone,
|
|
3418
|
+
label: fields.find((field) => field.name === zone.name)?.label || zone.name
|
|
3419
|
+
}));
|
|
2587
3420
|
const add = (zone, uid) => {
|
|
2588
3421
|
const values = formValues ?? c.form.values;
|
|
2589
3422
|
const close = catalog?.groups?.[uid];
|
|
2590
|
-
if (c.form.disabled || !canInsert(zone, uid, values, c.components, close ? 2 : 1) || close && !zone.components.includes(close))
|
|
3423
|
+
if (c.form.disabled || !canInsert(zone, uid, values, c.components, close ? 2 : 1) || close && !zone.components.includes(close))
|
|
3424
|
+
return false;
|
|
2591
3425
|
const at = Array.isArray(values?.[zone.name]) ? values[zone.name].length : 0;
|
|
2592
|
-
c.form.addFieldRow(
|
|
3426
|
+
c.form.addFieldRow(
|
|
3427
|
+
zone.name,
|
|
3428
|
+
{
|
|
3429
|
+
...componentDefaults(c.components[uid], c.components),
|
|
3430
|
+
__component: uid
|
|
3431
|
+
},
|
|
3432
|
+
at
|
|
3433
|
+
);
|
|
2593
3434
|
if (close) c.form.addFieldRow(zone.name, { __component: close }, at + 1);
|
|
2594
3435
|
return true;
|
|
2595
3436
|
};
|
|
2596
3437
|
if (!zones.length || !catalog?.editor?.enabled) return null;
|
|
2597
3438
|
const docKey = `${c.model}:${creating ? "new" : c.id}:${c.form?.initialValues?.locale || ""}`;
|
|
2598
|
-
return {
|
|
2599
|
-
|
|
2600
|
-
/* @__PURE__ */ (0,
|
|
2601
|
-
|
|
3439
|
+
return {
|
|
3440
|
+
title: t.gallery,
|
|
3441
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system5.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
3442
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3443
|
+
Gallery,
|
|
3444
|
+
{
|
|
3445
|
+
zones,
|
|
3446
|
+
components: c.components,
|
|
3447
|
+
add,
|
|
3448
|
+
Modal: Modal2,
|
|
3449
|
+
Toggle: ToggleField,
|
|
3450
|
+
get,
|
|
3451
|
+
editor: catalog.editor,
|
|
3452
|
+
catalog,
|
|
3453
|
+
docKey,
|
|
3454
|
+
contentType: c.model,
|
|
3455
|
+
userId: user?.id
|
|
3456
|
+
}
|
|
3457
|
+
),
|
|
3458
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3459
|
+
PagePreview,
|
|
3460
|
+
{
|
|
3461
|
+
editor: catalog.editor,
|
|
3462
|
+
groups: catalog.groups || null,
|
|
3463
|
+
Modal: Modal2,
|
|
3464
|
+
Toggle: ToggleField
|
|
3465
|
+
}
|
|
3466
|
+
)
|
|
3467
|
+
] })
|
|
3468
|
+
};
|
|
2602
3469
|
}
|
|
2603
|
-
var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ */ (0,
|
|
2604
|
-
/* @__PURE__ */ (0,
|
|
2605
|
-
|
|
3470
|
+
var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system5.Flex, { gap: 3, children: [
|
|
3471
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3472
|
+
import_design_system5.Switch,
|
|
3473
|
+
{
|
|
3474
|
+
name,
|
|
3475
|
+
"aria-label": label,
|
|
3476
|
+
checked: Boolean(value),
|
|
3477
|
+
disabled,
|
|
3478
|
+
onCheckedChange: onChange
|
|
3479
|
+
}
|
|
3480
|
+
),
|
|
3481
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system5.Typography, { children: label })
|
|
2606
3482
|
] });
|
|
2607
|
-
var TextField = ({
|
|
2608
|
-
|
|
2609
|
-
|
|
3483
|
+
var TextField = ({
|
|
3484
|
+
name,
|
|
3485
|
+
label,
|
|
3486
|
+
value,
|
|
3487
|
+
onChange,
|
|
3488
|
+
disabled,
|
|
3489
|
+
placeholder
|
|
3490
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system5.Field.Root, { name, children: [
|
|
3491
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system5.Field.Label, { children: label }),
|
|
3492
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3493
|
+
import_design_system5.TextInput,
|
|
3494
|
+
{
|
|
3495
|
+
name,
|
|
3496
|
+
value,
|
|
3497
|
+
disabled,
|
|
3498
|
+
placeholder,
|
|
3499
|
+
onChange: (e) => onChange(e.target.value)
|
|
3500
|
+
}
|
|
3501
|
+
)
|
|
2610
3502
|
] });
|
|
2611
|
-
var SelectField = ({
|
|
2612
|
-
|
|
2613
|
-
|
|
3503
|
+
var SelectField = ({
|
|
3504
|
+
name,
|
|
3505
|
+
label,
|
|
3506
|
+
value,
|
|
3507
|
+
onChange,
|
|
3508
|
+
disabled,
|
|
3509
|
+
options
|
|
3510
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system5.Field.Root, { name, children: [
|
|
3511
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system5.Field.Label, { children: label }),
|
|
3512
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3513
|
+
import_design_system5.SingleSelect,
|
|
3514
|
+
{
|
|
3515
|
+
value,
|
|
3516
|
+
disabled,
|
|
3517
|
+
onChange: (v) => onChange(String(v)),
|
|
3518
|
+
children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system5.SingleSelectOption, { value: o.value, children: o.label }, o.value))
|
|
3519
|
+
}
|
|
3520
|
+
)
|
|
2614
3521
|
] });
|
|
2615
3522
|
function MediaPicker({ onClose, onSelect }) {
|
|
2616
|
-
const components = (0, import_admin3.useStrapiApp)(
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
3523
|
+
const components = (0, import_admin3.useStrapiApp)(
|
|
3524
|
+
"Blockscene",
|
|
3525
|
+
(state) => state.components
|
|
3526
|
+
);
|
|
3527
|
+
const Dialog2 = components?.["media-library"];
|
|
3528
|
+
React7.useEffect(() => {
|
|
3529
|
+
if (!Dialog2) onClose();
|
|
3530
|
+
}, [Dialog2, onClose]);
|
|
3531
|
+
if (!Dialog2) return null;
|
|
3532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3533
|
+
Dialog2,
|
|
3534
|
+
{
|
|
3535
|
+
onClose,
|
|
3536
|
+
allowedTypes: ["images"],
|
|
3537
|
+
multiple: false,
|
|
3538
|
+
onSelectAssets: (assets) => onSelect(assets?.[0])
|
|
3539
|
+
}
|
|
3540
|
+
);
|
|
2623
3541
|
}
|
|
2624
3542
|
function usePermissions() {
|
|
2625
|
-
const { allowedActions, isLoading } = (0, import_admin3.useRBAC)(
|
|
2626
|
-
|
|
3543
|
+
const { allowedActions, isLoading } = (0, import_admin3.useRBAC)(
|
|
3544
|
+
Object.values(permissions).flat()
|
|
3545
|
+
);
|
|
3546
|
+
return {
|
|
3547
|
+
canRead: allowedActions.canRead,
|
|
3548
|
+
canUpdate: allowedActions.canUpdate,
|
|
3549
|
+
isLoading
|
|
3550
|
+
};
|
|
2627
3551
|
}
|
|
2628
|
-
var SettingsPage = () => /* @__PURE__ */ (0,
|
|
3552
|
+
var SettingsPage = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3553
|
+
Settings,
|
|
3554
|
+
{
|
|
3555
|
+
useClient: import_admin3.useFetchClient,
|
|
3556
|
+
usePermissions,
|
|
3557
|
+
MediaPicker,
|
|
3558
|
+
ToggleField,
|
|
3559
|
+
SelectField,
|
|
3560
|
+
TextField,
|
|
3561
|
+
previewSupported: true
|
|
3562
|
+
}
|
|
3563
|
+
);
|
|
2629
3564
|
var strapi5_default = {
|
|
2630
3565
|
register(app) {
|
|
2631
|
-
register(app, SettingsPage);
|
|
3566
|
+
register(app, SettingsPage, "blockscene");
|
|
2632
3567
|
app.registerPlugin({ id: "blockscene", name: "Blockscene" });
|
|
2633
3568
|
},
|
|
2634
3569
|
registerTrads,
|