@aduptive/strapi-blockscene 2.0.0-alpha.3 → 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 +12 -1
- package/dist/admin.cjs +1295 -366
- package/dist/admin.mjs +1334 -368
- package/package.json +1 -1
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,56 +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)(
|
|
1860
|
-
|
|
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
|
+
);
|
|
1861
2464
|
const fields = c.layout?.edit?.layout?.flat(3) || [];
|
|
1862
2465
|
const readable = (name) => c.isCreatingEntry || (rbac.canReadFields || []).includes(name);
|
|
1863
|
-
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
|
+
);
|
|
1864
2470
|
const zoneLabel = fields.find((field) => field.name === zone)?.label || zone || "";
|
|
1865
|
-
const canEdit = Boolean(
|
|
1866
|
-
|
|
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(() => {
|
|
1867
2475
|
const v = read(MODE_KEY);
|
|
1868
2476
|
return v === "split" || v === "preview" ? v : editor?.previewMode || "form";
|
|
1869
2477
|
});
|
|
@@ -1871,32 +2479,37 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1871
2479
|
setModeState(next);
|
|
1872
2480
|
write(MODE_KEY, next);
|
|
1873
2481
|
};
|
|
1874
|
-
const [ratio, setRatio] =
|
|
2482
|
+
const [ratio, setRatio] = React4.useState(() => {
|
|
1875
2483
|
const v = Number(read(RATIO_KEY));
|
|
1876
2484
|
return v > 0 && v < 1 ? v : 0.5;
|
|
1877
2485
|
});
|
|
1878
2486
|
const main = useMainRect();
|
|
1879
2487
|
const vw = main.width;
|
|
1880
|
-
const [dragging, setDragging] =
|
|
1881
|
-
const [ready, setReady] =
|
|
1882
|
-
const [failed, setFailed] =
|
|
1883
|
-
const [attempt, retry] =
|
|
1884
|
-
const [picking, setPicking] =
|
|
1885
|
-
|
|
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(() => {
|
|
1886
2494
|
setEditing(null);
|
|
1887
2495
|
setPicking(null);
|
|
1888
2496
|
setInserting(null);
|
|
1889
2497
|
}, [c.id, c.form?.initialValues?.locale]);
|
|
1890
|
-
const [editing, setEditing] =
|
|
1891
|
-
const [inserting, setInserting] =
|
|
2498
|
+
const [editing, setEditing] = React4.useState(null);
|
|
2499
|
+
const [inserting, setInserting] = React4.useState(null);
|
|
1892
2500
|
const { get } = (0, import_admin2.useFetchClient)();
|
|
1893
2501
|
const { toggleNotification } = (0, import_admin2.useNotification)();
|
|
1894
2502
|
const zoneAttr = zone ? c.contentType?.attributes?.[zone] : null;
|
|
1895
|
-
const iframe =
|
|
1896
|
-
const loaded =
|
|
1897
|
-
const anchor =
|
|
1898
|
-
const channel =
|
|
1899
|
-
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
|
+
);
|
|
1900
2513
|
const url = base ? new URL(base) : null;
|
|
1901
2514
|
url?.searchParams.set("channel", channel);
|
|
1902
2515
|
const origin = url?.origin || "";
|
|
@@ -1905,21 +2518,50 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1905
2518
|
const resizable = mode === "split" && !narrow;
|
|
1906
2519
|
const active = mode !== "form" && Boolean(url) && Boolean(zone);
|
|
1907
2520
|
const rows = zone && Array.isArray(values?.[zone]) ? values[zone] : [];
|
|
1908
|
-
const latest =
|
|
2521
|
+
const latest = React4.useRef(rows);
|
|
1909
2522
|
latest.current = rows;
|
|
1910
2523
|
const insertRows = (at, ...items) => items.forEach((item, i) => {
|
|
1911
2524
|
const from = latest.current.length + i;
|
|
1912
2525
|
addFieldRow(zone, item);
|
|
1913
2526
|
if (at + i < from) moveFieldRow(zone, from, at + i);
|
|
1914
2527
|
});
|
|
1915
|
-
const live =
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
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
|
+
);
|
|
1919
2561
|
}, [channel, origin]);
|
|
1920
2562
|
const indexOf = (key) => latest.current.findIndex((row) => blockKey(row) === key);
|
|
1921
2563
|
const path = (key, field) => `${zone}.${indexOf(key)}.${field}`;
|
|
1922
|
-
|
|
2564
|
+
React4.useEffect(() => {
|
|
1923
2565
|
if (resizable) markLayout(anchor.current);
|
|
1924
2566
|
document.body.classList.toggle("bp-split", resizable);
|
|
1925
2567
|
document.documentElement.style.setProperty("--bp-pane", `${paneWidth}px`);
|
|
@@ -1931,7 +2573,9 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1931
2573
|
if (persist) write(RATIO_KEY, String(next));
|
|
1932
2574
|
};
|
|
1933
2575
|
const focusField = (index, field) => {
|
|
1934
|
-
const item = findZoneList(live.current.zoneLabel)?.querySelectorAll(
|
|
2576
|
+
const item = findZoneList(live.current.zoneLabel)?.querySelectorAll(
|
|
2577
|
+
":scope > li"
|
|
2578
|
+
)[index];
|
|
1935
2579
|
if (!item) return;
|
|
1936
2580
|
const header = toggles(item.parentElement)[index];
|
|
1937
2581
|
if (header?.getAttribute("aria-expanded") === "false") header.click();
|
|
@@ -1942,33 +2586,47 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1942
2586
|
if (++tries > 40) return clearInterval(timer);
|
|
1943
2587
|
let scope = item;
|
|
1944
2588
|
for (let i = 0; i + 1 < parts.length; i += 2) {
|
|
1945
|
-
const nested = [
|
|
2589
|
+
const nested = [
|
|
2590
|
+
...scope.querySelectorAll(
|
|
2591
|
+
"button[aria-expanded][data-radix-collection-item]"
|
|
2592
|
+
)
|
|
2593
|
+
].filter((b) => b !== header);
|
|
1946
2594
|
const row = nested[Number(parts[i + 1])];
|
|
1947
2595
|
if (!row) return;
|
|
1948
2596
|
if (row.getAttribute("aria-expanded") === "false") row.click();
|
|
1949
2597
|
scope = row.closest("li, div") || scope;
|
|
1950
2598
|
}
|
|
1951
|
-
const target = document.querySelector(
|
|
2599
|
+
const target = document.querySelector(
|
|
2600
|
+
`[name="${escaped}"], label[for="${escaped}"]`
|
|
2601
|
+
);
|
|
1952
2602
|
if (!target) return;
|
|
1953
2603
|
const INPUT = '.ck-editor__editable, textarea, input:not([type="hidden"]), select';
|
|
1954
2604
|
let container = target.matches(INPUT) ? target : target.parentElement;
|
|
1955
|
-
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;
|
|
1956
2607
|
const editable = container?.matches(INPUT) ? container : container?.querySelector(INPUT);
|
|
1957
2608
|
if (!editable) return;
|
|
1958
|
-
if (editable.classList.contains("ck-editor__editable") && !editable.isContentEditable)
|
|
2609
|
+
if (editable.classList.contains("ck-editor__editable") && !editable.isContentEditable)
|
|
2610
|
+
return;
|
|
1959
2611
|
editable.focus();
|
|
1960
2612
|
if (document.activeElement !== editable) return;
|
|
1961
2613
|
clearInterval(timer);
|
|
1962
2614
|
editable.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
1963
2615
|
}, 150);
|
|
1964
2616
|
};
|
|
1965
|
-
|
|
2617
|
+
React4.useEffect(() => {
|
|
1966
2618
|
if (!active) return;
|
|
1967
2619
|
setReady(false);
|
|
1968
2620
|
setFailed(false);
|
|
1969
2621
|
const timeout = setTimeout(() => setFailed(true), 15e3);
|
|
1970
2622
|
const receive = (event) => {
|
|
1971
|
-
const is = (type) => isPreviewMessage(
|
|
2623
|
+
const is = (type) => isPreviewMessage(
|
|
2624
|
+
event,
|
|
2625
|
+
origin,
|
|
2626
|
+
iframe.current?.contentWindow,
|
|
2627
|
+
channel,
|
|
2628
|
+
type
|
|
2629
|
+
);
|
|
1972
2630
|
const { mode: mode2, canEdit: canEdit2, zoneLabel: zoneLabel2, components: components2, setMode: setMode2, onChange: onChange2 } = live.current;
|
|
1973
2631
|
if (is("ready")) {
|
|
1974
2632
|
clearTimeout(timeout);
|
|
@@ -1988,12 +2646,21 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1988
2646
|
return;
|
|
1989
2647
|
}
|
|
1990
2648
|
if (is("move-group") && canEdit2 && groups) {
|
|
1991
|
-
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
|
+
);
|
|
1992
2655
|
if (next) onChange2(zone, next);
|
|
1993
2656
|
return;
|
|
1994
2657
|
}
|
|
1995
2658
|
if (is("delete-group") && canEdit2 && groups) {
|
|
1996
|
-
const next = (0, import_groups.removeGroup)(
|
|
2659
|
+
const next = (0, import_groups.removeGroup)(
|
|
2660
|
+
latest.current,
|
|
2661
|
+
String(event.data.key),
|
|
2662
|
+
groups
|
|
2663
|
+
);
|
|
1997
2664
|
if (next) onChange2(zone, next);
|
|
1998
2665
|
return;
|
|
1999
2666
|
}
|
|
@@ -2003,12 +2670,20 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2003
2670
|
const uid2 = String(event.data.uid || "");
|
|
2004
2671
|
const close = groups[uid2];
|
|
2005
2672
|
const allowed = zoneAttr?.components || [];
|
|
2006
|
-
if (index2 < 0 || !close || !allowed.includes(uid2) || !allowed.includes(close))
|
|
2673
|
+
if (index2 < 0 || !close || !allowed.includes(uid2) || !allowed.includes(close))
|
|
2674
|
+
return;
|
|
2007
2675
|
if (latest.current.length + 2 > (zoneAttr?.max ?? Infinity)) {
|
|
2008
2676
|
toggleNotification({ type: "info", message: t.zoneFull });
|
|
2009
2677
|
return;
|
|
2010
2678
|
}
|
|
2011
|
-
insertRows(
|
|
2679
|
+
insertRows(
|
|
2680
|
+
index2,
|
|
2681
|
+
{
|
|
2682
|
+
...componentDefaults(components2[uid2], components2),
|
|
2683
|
+
__component: uid2
|
|
2684
|
+
},
|
|
2685
|
+
{ __component: close }
|
|
2686
|
+
);
|
|
2012
2687
|
return;
|
|
2013
2688
|
}
|
|
2014
2689
|
const key = typeof event.data?.key === "string" ? event.data.key : "";
|
|
@@ -2028,11 +2703,21 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2028
2703
|
}, 1500);
|
|
2029
2704
|
}
|
|
2030
2705
|
if (mode2 === "preview") setMode2("split");
|
|
2031
|
-
iframe.current?.contentWindow?.postMessage(
|
|
2706
|
+
iframe.current?.contentWindow?.postMessage(
|
|
2707
|
+
{ protocol: PROTOCOL, channel, type: "highlight", key },
|
|
2708
|
+
origin
|
|
2709
|
+
);
|
|
2032
2710
|
} else if (is("focus")) {
|
|
2033
2711
|
const attr = validateFocus(uid, event.data.field, components2);
|
|
2034
2712
|
if (!attr) return;
|
|
2035
|
-
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
|
+
});
|
|
2036
2721
|
else focusField(index, event.data.field);
|
|
2037
2722
|
} else if (is("media") && canEdit2) {
|
|
2038
2723
|
const attr = mediaAttribute(uid, event.data.field, components2);
|
|
@@ -2041,27 +2726,67 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2041
2726
|
const attr = mediaAttribute(uid, event.data.field, components2);
|
|
2042
2727
|
if (attr && !attr.required) onChange2(path(key, event.data.field), null);
|
|
2043
2728
|
} else if (is("edit") && canEdit2) {
|
|
2044
|
-
const value = validateEdit(
|
|
2729
|
+
const value = validateEdit(
|
|
2730
|
+
uid,
|
|
2731
|
+
event.data.field,
|
|
2732
|
+
event.data.value,
|
|
2733
|
+
components2
|
|
2734
|
+
);
|
|
2045
2735
|
if (value !== null) onChange2(path(key, event.data.field), value);
|
|
2046
2736
|
}
|
|
2047
2737
|
};
|
|
2048
2738
|
window.addEventListener("message", receive);
|
|
2049
|
-
if (loaded.current)
|
|
2739
|
+
if (loaded.current)
|
|
2740
|
+
iframe.current?.contentWindow?.postMessage(
|
|
2741
|
+
{ protocol: PROTOCOL, channel, type: "ping" },
|
|
2742
|
+
origin
|
|
2743
|
+
);
|
|
2050
2744
|
return () => {
|
|
2051
2745
|
clearTimeout(timeout);
|
|
2052
2746
|
window.removeEventListener("message", receive);
|
|
2053
2747
|
};
|
|
2054
2748
|
}, [active, attempt, channel, origin, groups]);
|
|
2055
|
-
|
|
2749
|
+
React4.useEffect(() => {
|
|
2056
2750
|
if (!ready || !active) return;
|
|
2057
2751
|
const timer = setTimeout(send, 120);
|
|
2058
2752
|
return () => clearTimeout(timer);
|
|
2059
2753
|
}, [values, c.components, ready, active, send, mode]);
|
|
2060
2754
|
if (!zone) return null;
|
|
2061
|
-
const modes = [
|
|
2062
|
-
|
|
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
|
+
);
|
|
2063
2783
|
const onKey = (event) => {
|
|
2064
|
-
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
|
+
};
|
|
2065
2790
|
if (event.key in map) {
|
|
2066
2791
|
event.preventDefault();
|
|
2067
2792
|
applyWidth(map[event.key], true);
|
|
@@ -2072,28 +2797,69 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2072
2797
|
const end = (0, import_groups.groupRange)(latest.current, error.index, groups)[1];
|
|
2073
2798
|
insertRows(end + 1, { __component: error.expected });
|
|
2074
2799
|
};
|
|
2075
|
-
const diagnostics = problems.length > 0 && /* @__PURE__ */ (0,
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
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: [
|
|
2084
2846
|
switcher,
|
|
2085
2847
|
diagnostics,
|
|
2086
|
-
/* @__PURE__ */ (0,
|
|
2087
|
-
active && (0,
|
|
2088
|
-
/* @__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)(
|
|
2089
2851
|
Pane,
|
|
2090
2852
|
{
|
|
2091
2853
|
"data-testid": "page-preview-pane",
|
|
2092
2854
|
"aria-label": t.previewPane,
|
|
2093
|
-
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
|
+
},
|
|
2094
2860
|
children: [
|
|
2095
|
-
/* @__PURE__ */ (0,
|
|
2096
|
-
resizable && /* @__PURE__ */ (0,
|
|
2861
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: SPLIT_STYLE }),
|
|
2862
|
+
resizable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2097
2863
|
Handle,
|
|
2098
2864
|
{
|
|
2099
2865
|
role: "separator",
|
|
@@ -2111,7 +2877,8 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2111
2877
|
setDragging(true);
|
|
2112
2878
|
},
|
|
2113
2879
|
onPointerMove: (e) => {
|
|
2114
|
-
if (dragging)
|
|
2880
|
+
if (dragging)
|
|
2881
|
+
applyWidth(main.left + main.width - e.clientX, false);
|
|
2115
2882
|
},
|
|
2116
2883
|
onPointerUp: (e) => {
|
|
2117
2884
|
if (!dragging) return;
|
|
@@ -2123,15 +2890,44 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2123
2890
|
onKeyDown: onKey
|
|
2124
2891
|
}
|
|
2125
2892
|
),
|
|
2126
|
-
/* @__PURE__ */ (0,
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
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)(
|
|
2135
2931
|
Frame2,
|
|
2136
2932
|
{
|
|
2137
2933
|
ref: iframe,
|
|
@@ -2151,12 +2947,16 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2151
2947
|
),
|
|
2152
2948
|
document.body
|
|
2153
2949
|
),
|
|
2154
|
-
inserting && zoneAttr && /* @__PURE__ */ (0,
|
|
2950
|
+
inserting && zoneAttr && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2155
2951
|
PickerModal,
|
|
2156
2952
|
{
|
|
2157
|
-
zone: {
|
|
2953
|
+
zone: {
|
|
2954
|
+
name: zone,
|
|
2955
|
+
components: zoneAttr.components || [],
|
|
2956
|
+
max: zoneAttr.max
|
|
2957
|
+
},
|
|
2158
2958
|
components: c.components,
|
|
2159
|
-
Modal:
|
|
2959
|
+
Modal: Modal3,
|
|
2160
2960
|
Toggle,
|
|
2161
2961
|
get,
|
|
2162
2962
|
open: true,
|
|
@@ -2168,14 +2968,24 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2168
2968
|
setInserting(null);
|
|
2169
2969
|
const close = groups?.[uid];
|
|
2170
2970
|
if (index < 0 || !(zoneAttr.components || []).includes(uid) || close && !(zoneAttr.components || []).includes(close) || latest.current.length + (close ? 2 : 1) > (zoneAttr.max ?? Infinity)) {
|
|
2171
|
-
toggleNotification({
|
|
2971
|
+
toggleNotification({
|
|
2972
|
+
type: "warning",
|
|
2973
|
+
message: close ? t.zoneFull : t.insertMoved
|
|
2974
|
+
});
|
|
2172
2975
|
return;
|
|
2173
2976
|
}
|
|
2174
|
-
insertRows(
|
|
2977
|
+
insertRows(
|
|
2978
|
+
index,
|
|
2979
|
+
{
|
|
2980
|
+
...componentDefaults(c.components[uid], c.components),
|
|
2981
|
+
__component: uid
|
|
2982
|
+
},
|
|
2983
|
+
...close ? [{ __component: close }] : []
|
|
2984
|
+
);
|
|
2175
2985
|
}
|
|
2176
2986
|
}
|
|
2177
2987
|
),
|
|
2178
|
-
editing && /* @__PURE__ */ (0,
|
|
2988
|
+
editing && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2179
2989
|
FieldEditorModal,
|
|
2180
2990
|
{
|
|
2181
2991
|
label: editing.label,
|
|
@@ -2185,11 +2995,12 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2185
2995
|
onApply: (value) => {
|
|
2186
2996
|
const index = indexOf(editing.key);
|
|
2187
2997
|
setEditing(null);
|
|
2188
|
-
if (index >= 0)
|
|
2998
|
+
if (index >= 0)
|
|
2999
|
+
onChange(`${zone}.${index}.${editing.field}`, value);
|
|
2189
3000
|
}
|
|
2190
3001
|
}
|
|
2191
3002
|
),
|
|
2192
|
-
picking && MediaLibraryDialog && /* @__PURE__ */ (0,
|
|
3003
|
+
picking && MediaLibraryDialog && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2193
3004
|
MediaLibraryDialog,
|
|
2194
3005
|
{
|
|
2195
3006
|
allowedTypes: picking.attr.allowedTypes || ["images"],
|
|
@@ -2200,19 +3011,32 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2200
3011
|
setPicking(null);
|
|
2201
3012
|
if (index < 0 || !assets?.length) return;
|
|
2202
3013
|
const current = getIn(latest.current[index], picking.field);
|
|
2203
|
-
onChange(
|
|
3014
|
+
onChange(
|
|
3015
|
+
`${zone}.${index}.${picking.field}`,
|
|
3016
|
+
picking.attr.multiple ? [...Array.isArray(current) ? current : [], ...assets] : assets[0]
|
|
3017
|
+
);
|
|
2204
3018
|
}
|
|
2205
3019
|
}
|
|
2206
3020
|
),
|
|
2207
|
-
/* @__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
|
+
)
|
|
2208
3032
|
] });
|
|
2209
3033
|
}
|
|
2210
3034
|
|
|
2211
3035
|
// admin/Settings.tsx
|
|
2212
|
-
var
|
|
2213
|
-
var
|
|
3036
|
+
var React5 = __toESM(require("react"));
|
|
3037
|
+
var import_design_system4 = require("@strapi/design-system");
|
|
2214
3038
|
var import_styled_components3 = __toESM(require("styled-components"));
|
|
2215
|
-
var
|
|
3039
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2216
3040
|
var COLOR2 = /^#[0-9A-Fa-f]{6}$/;
|
|
2217
3041
|
var Grid = import_styled_components3.default.div` display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 16px; `;
|
|
2218
3042
|
var Card2 = import_styled_components3.default.div`
|
|
@@ -2225,8 +3049,8 @@ var Bar = import_styled_components3.default.div`
|
|
|
2225
3049
|
box-shadow: 0 1px 4px rgba(33, 33, 52, 0.1);
|
|
2226
3050
|
`;
|
|
2227
3051
|
function useMainRect2(anchor) {
|
|
2228
|
-
const [rect, setRect] =
|
|
2229
|
-
|
|
3052
|
+
const [rect, setRect] = React5.useState({ left: 0, width: 0 });
|
|
3053
|
+
React5.useEffect(() => {
|
|
2230
3054
|
const read2 = () => {
|
|
2231
3055
|
let host = document.getElementById("main-content");
|
|
2232
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;
|
|
@@ -2243,11 +3067,11 @@ var Swatches = import_styled_components3.default.div` display: grid; grid-templa
|
|
|
2243
3067
|
var Label = import_styled_components3.default.label` display: flex; flex-direction: column; gap: 4px; font-size: 12px; `;
|
|
2244
3068
|
function ColorField({ name, label, value, onChange, disabled }) {
|
|
2245
3069
|
const valid = COLOR2.test(value);
|
|
2246
|
-
return /* @__PURE__ */ (0,
|
|
2247
|
-
/* @__PURE__ */ (0,
|
|
2248
|
-
/* @__PURE__ */ (0,
|
|
2249
|
-
/* @__PURE__ */ (0,
|
|
2250
|
-
/* @__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)(
|
|
2251
3075
|
"input",
|
|
2252
3076
|
{
|
|
2253
3077
|
name,
|
|
@@ -2267,18 +3091,18 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2267
3091
|
const t = useMessages();
|
|
2268
3092
|
const { get, put } = useClient();
|
|
2269
3093
|
const { canRead, canUpdate, isLoading } = usePermissions2();
|
|
2270
|
-
const [data, setData] =
|
|
2271
|
-
const [catalog, setCatalog] =
|
|
2272
|
-
const [settings, setSettings] =
|
|
2273
|
-
const [media, setMedia] =
|
|
2274
|
-
const [sources, setSources] =
|
|
2275
|
-
const [dirty, setDirty] =
|
|
2276
|
-
const [saving, setSaving] =
|
|
2277
|
-
const [status, setStatus] =
|
|
2278
|
-
const [failed, setFailed] =
|
|
2279
|
-
const [filter, setFilter] =
|
|
2280
|
-
const [picking, setPicking] =
|
|
2281
|
-
|
|
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(() => {
|
|
2282
3106
|
if (!canRead || isLoading) return;
|
|
2283
3107
|
let active = true;
|
|
2284
3108
|
Promise.all([get("/blockscene/settings"), get("/blockscene/catalog")]).then(([s, c]) => {
|
|
@@ -2326,35 +3150,35 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2326
3150
|
return index === 0 && manual ? t.manual : t.automatic;
|
|
2327
3151
|
};
|
|
2328
3152
|
const ready = !isLoading && canRead && !failed && settings && catalog;
|
|
2329
|
-
const header =
|
|
2330
|
-
const [floating, setFloating] =
|
|
3153
|
+
const header = React5.useRef(null);
|
|
3154
|
+
const [floating, setFloating] = React5.useState(false);
|
|
2331
3155
|
const main = useMainRect2(header);
|
|
2332
|
-
|
|
3156
|
+
React5.useEffect(() => {
|
|
2333
3157
|
const el = header.current;
|
|
2334
3158
|
if (!el || typeof IntersectionObserver === "undefined") return;
|
|
2335
3159
|
const observer = new IntersectionObserver(([entry]) => setFloating(!entry.isIntersecting && entry.boundingClientRect.top < 0));
|
|
2336
3160
|
observer.observe(el);
|
|
2337
3161
|
return () => observer.disconnect();
|
|
2338
3162
|
}, [ready]);
|
|
2339
|
-
const controls = (suffix) => ready && /* @__PURE__ */ (0,
|
|
2340
|
-
/* @__PURE__ */ (0,
|
|
2341
|
-
/* @__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 })
|
|
2342
3166
|
] });
|
|
2343
|
-
return /* @__PURE__ */ (0,
|
|
2344
|
-
/* @__PURE__ */ (0,
|
|
2345
|
-
/* @__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 }),
|
|
2346
3170
|
controls("")
|
|
2347
3171
|
] }) }),
|
|
2348
|
-
floating && main.width > 0 && /* @__PURE__ */ (0,
|
|
2349
|
-
/* @__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 }),
|
|
2350
3174
|
controls("-floating")
|
|
2351
3175
|
] }) }),
|
|
2352
|
-
/* @__PURE__ */ (0,
|
|
2353
|
-
isLoading ? /* @__PURE__ */ (0,
|
|
2354
|
-
data.disabled && /* @__PURE__ */ (0,
|
|
2355
|
-
/* @__PURE__ */ (0,
|
|
2356
|
-
/* @__PURE__ */ (0,
|
|
2357
|
-
/* @__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)(
|
|
2358
3182
|
ColorField,
|
|
2359
3183
|
{
|
|
2360
3184
|
name: `palette-${key}`,
|
|
@@ -2368,33 +3192,33 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2368
3192
|
},
|
|
2369
3193
|
key
|
|
2370
3194
|
)) }),
|
|
2371
|
-
invalid && /* @__PURE__ */ (0,
|
|
2372
|
-
/* @__PURE__ */ (0,
|
|
2373
|
-
/* @__PURE__ */ (0,
|
|
2374
|
-
/* @__PURE__ */ (0,
|
|
2375
|
-
/* @__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] })
|
|
2376
3200
|
] }, template)) }),
|
|
2377
|
-
/* @__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) => {
|
|
2378
3202
|
s.palette = { ...DEFAULT_PALETTE };
|
|
2379
3203
|
return s;
|
|
2380
3204
|
}), children: t.resetPalette }) })
|
|
2381
3205
|
] }) }),
|
|
2382
|
-
/* @__PURE__ */ (0,
|
|
2383
|
-
/* @__PURE__ */ (0,
|
|
2384
|
-
/* @__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) => {
|
|
2385
3209
|
s.editor.enabled = v;
|
|
2386
3210
|
return s;
|
|
2387
3211
|
}) }),
|
|
2388
|
-
/* @__PURE__ */ (0,
|
|
2389
|
-
/* @__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) => {
|
|
2390
3214
|
s.editor.showOpenAll = v;
|
|
2391
3215
|
return s;
|
|
2392
3216
|
}) }),
|
|
2393
|
-
/* @__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) => {
|
|
2394
3218
|
s.editor.showCloseAll = v;
|
|
2395
3219
|
return s;
|
|
2396
3220
|
}) }),
|
|
2397
|
-
/* @__PURE__ */ (0,
|
|
3221
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2398
3222
|
SelectField2,
|
|
2399
3223
|
{
|
|
2400
3224
|
name: "editor-initialState",
|
|
@@ -2408,9 +3232,9 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2408
3232
|
})
|
|
2409
3233
|
}
|
|
2410
3234
|
),
|
|
2411
|
-
/* @__PURE__ */ (0,
|
|
2412
|
-
previewSupported ? /* @__PURE__ */ (0,
|
|
2413
|
-
/* @__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)(
|
|
2414
3238
|
TextField2,
|
|
2415
3239
|
{
|
|
2416
3240
|
name: "editor-previewUrl",
|
|
@@ -2424,8 +3248,8 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2424
3248
|
})
|
|
2425
3249
|
}
|
|
2426
3250
|
),
|
|
2427
|
-
/* @__PURE__ */ (0,
|
|
2428
|
-
/* @__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)(
|
|
2429
3253
|
SelectField2,
|
|
2430
3254
|
{
|
|
2431
3255
|
name: "editor-previewMode",
|
|
@@ -2439,26 +3263,26 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2439
3263
|
})
|
|
2440
3264
|
}
|
|
2441
3265
|
),
|
|
2442
|
-
/* @__PURE__ */ (0,
|
|
2443
|
-
data.blockPreviewAvailable && /* @__PURE__ */ (0,
|
|
2444
|
-
/* @__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) => {
|
|
2445
3269
|
s.editor.blockPreviewInForm = v;
|
|
2446
3270
|
return s;
|
|
2447
3271
|
}) }),
|
|
2448
|
-
/* @__PURE__ */ (0,
|
|
3272
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
|
|
2449
3273
|
] })
|
|
2450
|
-
] }) : /* @__PURE__ */ (0,
|
|
3274
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.previewV4 })
|
|
2451
3275
|
] }) }),
|
|
2452
|
-
/* @__PURE__ */ (0,
|
|
2453
|
-
/* @__PURE__ */ (0,
|
|
2454
|
-
/* @__PURE__ */ (0,
|
|
2455
|
-
/* @__PURE__ */ (0,
|
|
2456
|
-
/* @__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) => {
|
|
2457
3281
|
const entry = settings.components[component.uid] || {};
|
|
2458
3282
|
const meta = { ...catalog.components?.[component.uid] || {}, ...media[component.uid] || {} };
|
|
2459
3283
|
const candidates = candidatesFor(component.uid, meta, catalog);
|
|
2460
|
-
return /* @__PURE__ */ (0,
|
|
2461
|
-
/* @__PURE__ */ (0,
|
|
3284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Card2, { "data-testid": `settings-${component.uid}`, children: [
|
|
3285
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2462
3286
|
Thumb,
|
|
2463
3287
|
{
|
|
2464
3288
|
candidates,
|
|
@@ -2469,23 +3293,23 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2469
3293
|
onResolved: (index) => setSources((current) => current[component.uid] === index ? current : { ...current, [component.uid]: index })
|
|
2470
3294
|
}
|
|
2471
3295
|
),
|
|
2472
|
-
/* @__PURE__ */ (0,
|
|
2473
|
-
/* @__PURE__ */ (0,
|
|
2474
|
-
/* @__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: [
|
|
2475
3299
|
component.uid,
|
|
2476
3300
|
" \xB7 ",
|
|
2477
3301
|
component.category
|
|
2478
3302
|
] }),
|
|
2479
|
-
/* @__PURE__ */ (0,
|
|
3303
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system4.Typography, { variant: "pi", "data-testid": `source-${component.uid}`, children: [
|
|
2480
3304
|
t.source,
|
|
2481
3305
|
": ",
|
|
2482
3306
|
sourceOf(component.uid, Boolean(meta.manualImage)),
|
|
2483
3307
|
meta.manualName ? ` (${meta.manualName})` : ""
|
|
2484
3308
|
] }),
|
|
2485
|
-
meta.manualMissing && /* @__PURE__ */ (0,
|
|
2486
|
-
/* @__PURE__ */ (0,
|
|
2487
|
-
/* @__PURE__ */ (0,
|
|
2488
|
-
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: () => {
|
|
2489
3313
|
update((s) => {
|
|
2490
3314
|
delete s.components[component.uid]?.mediaId;
|
|
2491
3315
|
if (!Object.keys(s.components[component.uid] || {}).length) delete s.components[component.uid];
|
|
@@ -2498,7 +3322,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2498
3322
|
});
|
|
2499
3323
|
}, children: t.useAutomatic })
|
|
2500
3324
|
] }),
|
|
2501
|
-
/* @__PURE__ */ (0,
|
|
3325
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2502
3326
|
SelectField2,
|
|
2503
3327
|
{
|
|
2504
3328
|
name: `template-${component.uid}`,
|
|
@@ -2516,7 +3340,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2516
3340
|
] }, component.uid);
|
|
2517
3341
|
}) })
|
|
2518
3342
|
] }) }),
|
|
2519
|
-
picking && /* @__PURE__ */ (0,
|
|
3343
|
+
picking && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MediaPicker2, { onClose: () => setPicking(null), onSelect: (asset) => {
|
|
2520
3344
|
const uid = picking;
|
|
2521
3345
|
setPicking(null);
|
|
2522
3346
|
if (!asset?.id) return;
|
|
@@ -2545,10 +3369,10 @@ function register(app, Component, to) {
|
|
|
2545
3369
|
}
|
|
2546
3370
|
|
|
2547
3371
|
// admin/catalog.ts
|
|
2548
|
-
var
|
|
3372
|
+
var React6 = __toESM(require("react"));
|
|
2549
3373
|
function useCatalog(get) {
|
|
2550
|
-
const [catalog, setCatalog] =
|
|
2551
|
-
|
|
3374
|
+
const [catalog, setCatalog] = React6.useState(null);
|
|
3375
|
+
React6.useEffect(() => {
|
|
2552
3376
|
let active = true;
|
|
2553
3377
|
get("/blockscene/catalog").then(({ data }) => {
|
|
2554
3378
|
if (active) setCatalog(data);
|
|
@@ -2563,13 +3387,13 @@ function useCatalog(get) {
|
|
|
2563
3387
|
}
|
|
2564
3388
|
|
|
2565
3389
|
// admin/strapi5.tsx
|
|
2566
|
-
var
|
|
3390
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2567
3391
|
function Modal2({ open, onOpenChange, trigger, title, children }) {
|
|
2568
|
-
return /* @__PURE__ */ (0,
|
|
2569
|
-
/* @__PURE__ */ (0,
|
|
2570
|
-
/* @__PURE__ */ (0,
|
|
2571
|
-
/* @__PURE__ */ (0,
|
|
2572
|
-
/* @__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 })
|
|
2573
3397
|
] })
|
|
2574
3398
|
] });
|
|
2575
3399
|
}
|
|
@@ -2589,49 +3413,154 @@ function Panel() {
|
|
|
2589
3413
|
formValues ?? c.form?.values,
|
|
2590
3414
|
(name) => allowed.includes(name) && (creating || (rbac.canReadFields || []).includes(name)) && fields.find((field) => field.name === name)?.disabled !== true,
|
|
2591
3415
|
c.isLoading || c.form?.disabled || !c.form?.addFieldRow
|
|
2592
|
-
).map((zone) => ({
|
|
3416
|
+
).map((zone) => ({
|
|
3417
|
+
...zone,
|
|
3418
|
+
label: fields.find((field) => field.name === zone.name)?.label || zone.name
|
|
3419
|
+
}));
|
|
2593
3420
|
const add = (zone, uid) => {
|
|
2594
3421
|
const values = formValues ?? c.form.values;
|
|
2595
3422
|
const close = catalog?.groups?.[uid];
|
|
2596
|
-
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;
|
|
2597
3425
|
const at = Array.isArray(values?.[zone.name]) ? values[zone.name].length : 0;
|
|
2598
|
-
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
|
+
);
|
|
2599
3434
|
if (close) c.form.addFieldRow(zone.name, { __component: close }, at + 1);
|
|
2600
3435
|
return true;
|
|
2601
3436
|
};
|
|
2602
3437
|
if (!zones.length || !catalog?.editor?.enabled) return null;
|
|
2603
3438
|
const docKey = `${c.model}:${creating ? "new" : c.id}:${c.form?.initialValues?.locale || ""}`;
|
|
2604
|
-
return {
|
|
2605
|
-
|
|
2606
|
-
/* @__PURE__ */ (0,
|
|
2607
|
-
|
|
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
|
+
};
|
|
2608
3469
|
}
|
|
2609
|
-
var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ */ (0,
|
|
2610
|
-
/* @__PURE__ */ (0,
|
|
2611
|
-
|
|
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 })
|
|
2612
3482
|
] });
|
|
2613
|
-
var TextField = ({
|
|
2614
|
-
|
|
2615
|
-
|
|
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
|
+
)
|
|
2616
3502
|
] });
|
|
2617
|
-
var SelectField = ({
|
|
2618
|
-
|
|
2619
|
-
|
|
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
|
+
)
|
|
2620
3521
|
] });
|
|
2621
3522
|
function MediaPicker({ onClose, onSelect }) {
|
|
2622
|
-
const components = (0, import_admin3.useStrapiApp)(
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
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
|
+
);
|
|
2629
3541
|
}
|
|
2630
3542
|
function usePermissions() {
|
|
2631
|
-
const { allowedActions, isLoading } = (0, import_admin3.useRBAC)(
|
|
2632
|
-
|
|
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
|
+
};
|
|
2633
3551
|
}
|
|
2634
|
-
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
|
+
);
|
|
2635
3564
|
var strapi5_default = {
|
|
2636
3565
|
register(app) {
|
|
2637
3566
|
register(app, SettingsPage, "blockscene");
|