@aduptive/strapi-blockscene 2.0.0-alpha.1 → 2.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -5
- package/dist/admin.cjs +1307 -372
- package/dist/admin.mjs +1346 -374
- package/package.json +3 -5
package/dist/admin.mjs
CHANGED
|
@@ -131,30 +131,61 @@ var require_groups = __commonJS({
|
|
|
131
131
|
});
|
|
132
132
|
|
|
133
133
|
// admin/strapi5.tsx
|
|
134
|
-
import * as
|
|
135
|
-
import {
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
import * as React7 from "react";
|
|
135
|
+
import {
|
|
136
|
+
Modal as Dialog,
|
|
137
|
+
Switch,
|
|
138
|
+
Flex as Flex5,
|
|
139
|
+
Typography as Typography5,
|
|
140
|
+
Field,
|
|
141
|
+
SingleSelect as SingleSelect2,
|
|
142
|
+
SingleSelectOption as SingleSelectOption2,
|
|
143
|
+
TextInput
|
|
144
|
+
} from "@strapi/design-system";
|
|
145
|
+
import {
|
|
146
|
+
useFetchClient as useFetchClient2,
|
|
147
|
+
useRBAC,
|
|
148
|
+
useStrapiApp as useStrapiApp3,
|
|
149
|
+
useAuth,
|
|
150
|
+
useForm as useForm3
|
|
151
|
+
} from "@strapi/strapi/admin";
|
|
152
|
+
import {
|
|
153
|
+
unstable_useContentManagerContext as useContext2,
|
|
154
|
+
useDocumentRBAC as useDocumentRBAC2
|
|
155
|
+
} from "@strapi/content-manager/strapi-admin";
|
|
138
156
|
|
|
139
157
|
// admin/Gallery.tsx
|
|
140
|
-
import * as
|
|
158
|
+
import * as React2 from "react";
|
|
141
159
|
import { unstable_batchedUpdates } from "react-dom";
|
|
142
|
-
import {
|
|
160
|
+
import {
|
|
161
|
+
Box,
|
|
162
|
+
Button,
|
|
163
|
+
Flex,
|
|
164
|
+
Searchbar,
|
|
165
|
+
SingleSelect,
|
|
166
|
+
SingleSelectOption,
|
|
167
|
+
Typography
|
|
168
|
+
} from "@strapi/design-system";
|
|
143
169
|
import styled from "styled-components";
|
|
144
170
|
|
|
145
171
|
// admin/model.mjs
|
|
146
172
|
import { generateNKeysBetween } from "fractional-indexing";
|
|
147
173
|
function componentDefaults(schema, components, stack = []) {
|
|
148
|
-
if (!schema || stack.includes(schema))
|
|
174
|
+
if (!schema || stack.includes(schema))
|
|
175
|
+
throw new Error("Invalid recursive component defaults");
|
|
149
176
|
const row = {};
|
|
150
177
|
for (const [name, attr] of Object.entries(schema.attributes || {})) {
|
|
151
178
|
if (Object.hasOwn(attr, "default")) {
|
|
152
179
|
const value = structuredClone(attr.default);
|
|
153
180
|
if (attr.type === "password") row[name] = "";
|
|
154
|
-
else if (attr.type === "relation")
|
|
181
|
+
else if (attr.type === "relation")
|
|
182
|
+
row[name] = { connect: [], disconnect: [] };
|
|
155
183
|
else if (value !== null || attr.type === "boolean") row[name] = value;
|
|
156
184
|
} else if (attr.type === "component" && attr.required) {
|
|
157
|
-
const create = () => componentDefaults(components[attr.component], components, [
|
|
185
|
+
const create = () => componentDefaults(components[attr.component], components, [
|
|
186
|
+
...stack,
|
|
187
|
+
schema
|
|
188
|
+
]);
|
|
158
189
|
if (attr.repeatable) {
|
|
159
190
|
const keys = generateNKeysBetween(null, null, attr.min || 0);
|
|
160
191
|
row[name] = keys.map((key) => ({ ...create(), __temp_key__: key }));
|
|
@@ -165,27 +196,58 @@ function componentDefaults(schema, components, stack = []) {
|
|
|
165
196
|
}
|
|
166
197
|
function editableZones(schema, values, canEdit, disabled = false) {
|
|
167
198
|
if (disabled) return [];
|
|
168
|
-
return Object.entries(schema?.attributes || {}).filter(
|
|
169
|
-
|
|
170
|
-
|
|
199
|
+
return Object.entries(schema?.attributes || {}).filter(
|
|
200
|
+
([name, attr]) => attr.type === "dynamiczone" && !attr.conditions && canEdit(name)
|
|
201
|
+
).map(([name, attr]) => {
|
|
202
|
+
const rows = Array.isArray(values?.[name]) ? values[name] : [];
|
|
203
|
+
return {
|
|
204
|
+
name,
|
|
205
|
+
components: attr.components || [],
|
|
206
|
+
max: attr.max,
|
|
207
|
+
count: rows.length,
|
|
208
|
+
uids: rows.map(
|
|
209
|
+
(row) => row && typeof row.__component === "string" ? row.__component : ""
|
|
210
|
+
),
|
|
211
|
+
full: rows.length >= (attr.max ?? Infinity)
|
|
212
|
+
};
|
|
171
213
|
});
|
|
172
214
|
}
|
|
173
215
|
function canInsert(zone, uid, values, components, count = 1) {
|
|
174
|
-
return Boolean(
|
|
216
|
+
return Boolean(
|
|
217
|
+
zone?.components.includes(uid) && components[uid] && (Array.isArray(values?.[zone.name]) ? values[zone.name].length : 0) + count <= (zone.max ?? Infinity)
|
|
218
|
+
);
|
|
175
219
|
}
|
|
176
220
|
function candidatesFor(uid, meta = {}, config = {}) {
|
|
177
221
|
const version = config.previewVersion ? `?v=${encodeURIComponent(config.previewVersion)}` : "";
|
|
178
222
|
const base = (config.previewBaseUrl || "/block-previews").replace(/\/$/, "");
|
|
179
|
-
return [
|
|
223
|
+
return [
|
|
224
|
+
meta.manualImage,
|
|
225
|
+
meta.image,
|
|
226
|
+
`${base}/${encodeURIComponent(uid)}.webp${version}`
|
|
227
|
+
].filter(Boolean);
|
|
180
228
|
}
|
|
181
|
-
var SYSTEM_FIELDS = [
|
|
229
|
+
var SYSTEM_FIELDS = [
|
|
230
|
+
"id",
|
|
231
|
+
"documentId",
|
|
232
|
+
"createdAt",
|
|
233
|
+
"updatedAt",
|
|
234
|
+
"publishedAt",
|
|
235
|
+
"createdBy",
|
|
236
|
+
"updatedBy",
|
|
237
|
+
"locale",
|
|
238
|
+
"localizations"
|
|
239
|
+
];
|
|
182
240
|
var fieldType = (attr) => attr?.type === "customField" ? String(attr.customField || "").includes("CKEditor") ? "richtext" : "customField" : attr?.type || "unknown";
|
|
183
241
|
var fieldsOf = (schema) => Object.entries(schema?.attributes || {}).filter(([name]) => !SYSTEM_FIELDS.includes(name)).map(([name, attr]) => ({ name, type: fieldType(attr) }));
|
|
184
242
|
var categoryOf = (uid, schema, meta = {}) => meta.category || schema?.category || uid.split(".")[0];
|
|
185
243
|
var byCategory = (a, b) => (a === "admin" ? 1 : 0) - (b === "admin" ? 1 : 0) || a.localeCompare(b);
|
|
244
|
+
var pickable = (zone, config) => {
|
|
245
|
+
const closers = Object.values(config.groups || {});
|
|
246
|
+
return zone.components.filter((uid) => !closers.includes(uid));
|
|
247
|
+
};
|
|
186
248
|
function entriesFor(zone, components, config, query, category = "all") {
|
|
187
249
|
const needle = query.trim().toLocaleLowerCase();
|
|
188
|
-
return zone.
|
|
250
|
+
return pickable(zone, config).flatMap((uid) => {
|
|
189
251
|
const schema = components[uid];
|
|
190
252
|
if (!schema) return [];
|
|
191
253
|
const meta = config.components?.[uid] || {};
|
|
@@ -200,11 +262,13 @@ function entriesFor(zone, components, config, query, category = "all") {
|
|
|
200
262
|
};
|
|
201
263
|
if (category !== "all" && entry.category !== category) return [];
|
|
202
264
|
return `${entry.label} ${entry.description} ${entry.category} ${uid} ${meta.keywords || ""}`.toLocaleLowerCase().includes(needle) ? [entry] : [];
|
|
203
|
-
}).sort(
|
|
265
|
+
}).sort(
|
|
266
|
+
(a, b) => byCategory(a.category, b.category) || a.label.localeCompare(b.label)
|
|
267
|
+
);
|
|
204
268
|
}
|
|
205
269
|
function categoriesFor(zone, components, config) {
|
|
206
270
|
const counts = /* @__PURE__ */ new Map();
|
|
207
|
-
for (const uid of zone
|
|
271
|
+
for (const uid of pickable(zone, config)) {
|
|
208
272
|
const schema = components[uid];
|
|
209
273
|
if (!schema) continue;
|
|
210
274
|
const c = categoryOf(uid, schema, config.components?.[uid] || {});
|
|
@@ -214,8 +278,12 @@ function categoriesFor(zone, components, config) {
|
|
|
214
278
|
}
|
|
215
279
|
function groupEntries(entries) {
|
|
216
280
|
const map = /* @__PURE__ */ new Map();
|
|
217
|
-
for (const entry of entries)
|
|
218
|
-
|
|
281
|
+
for (const entry of entries)
|
|
282
|
+
map.set(entry.category, [...map.get(entry.category) || [], entry]);
|
|
283
|
+
return [...map.entries()].map(([category, items]) => ({
|
|
284
|
+
category,
|
|
285
|
+
entries: items
|
|
286
|
+
}));
|
|
219
287
|
}
|
|
220
288
|
function memoryKey({ base = "", userId, contentType, zone }) {
|
|
221
289
|
if (!userId || !contentType || !zone) return null;
|
|
@@ -231,7 +299,8 @@ function readMemory(storage2, key) {
|
|
|
231
299
|
}
|
|
232
300
|
function writeMemory(storage2, key, value) {
|
|
233
301
|
try {
|
|
234
|
-
if (key && (value === "open" || value === "closed"))
|
|
302
|
+
if (key && (value === "open" || value === "closed"))
|
|
303
|
+
storage2?.setItem(key, value);
|
|
235
304
|
} catch {
|
|
236
305
|
}
|
|
237
306
|
}
|
|
@@ -317,6 +386,10 @@ function Wireframe({ template, palette, className, noPreview }) {
|
|
|
317
386
|
);
|
|
318
387
|
}
|
|
319
388
|
|
|
389
|
+
// admin/RowPreviews.tsx
|
|
390
|
+
import * as React from "react";
|
|
391
|
+
import { createPortal } from "react-dom";
|
|
392
|
+
|
|
320
393
|
// admin/messages.ts
|
|
321
394
|
import { useIntl } from "react-intl";
|
|
322
395
|
|
|
@@ -431,7 +504,8 @@ var en_default = {
|
|
|
431
504
|
columns: "Columns",
|
|
432
505
|
noPreview: "no preview",
|
|
433
506
|
"templates.none": "No preview",
|
|
434
|
-
noChanges: "No unsaved changes"
|
|
507
|
+
noChanges: "No unsaved changes",
|
|
508
|
+
rowPreview: "Open the {label} preview"
|
|
435
509
|
};
|
|
436
510
|
|
|
437
511
|
// admin/translations/pt-BR.json
|
|
@@ -545,7 +619,8 @@ var pt_BR_default = {
|
|
|
545
619
|
columns: "Colunas",
|
|
546
620
|
noPreview: "sem preview",
|
|
547
621
|
"templates.none": "Sem preview",
|
|
548
|
-
noChanges: "Sem altera\xE7\xF5es pendentes"
|
|
622
|
+
noChanges: "Sem altera\xE7\xF5es pendentes",
|
|
623
|
+
rowPreview: "Abrir a pr\xE9via de {label}"
|
|
549
624
|
};
|
|
550
625
|
|
|
551
626
|
// admin/translations/pt.json
|
|
@@ -659,7 +734,8 @@ var pt_default = {
|
|
|
659
734
|
columns: "Colunas",
|
|
660
735
|
noPreview: "sem pr\xE9-visualiza\xE7\xE3o",
|
|
661
736
|
"templates.none": "Sem pr\xE9-visualiza\xE7\xE3o",
|
|
662
|
-
noChanges: "Sem altera\xE7\xF5es pendentes"
|
|
737
|
+
noChanges: "Sem altera\xE7\xF5es pendentes",
|
|
738
|
+
rowPreview: "Abrir a pr\xE9-visualiza\xE7\xE3o de {label}"
|
|
663
739
|
};
|
|
664
740
|
|
|
665
741
|
// admin/translations/fr.json
|
|
@@ -773,7 +849,8 @@ var fr_default = {
|
|
|
773
849
|
columns: "Colonnes",
|
|
774
850
|
noPreview: "pas d\u2019aper\xE7u",
|
|
775
851
|
"templates.none": "Pas d\u2019aper\xE7u",
|
|
776
|
-
noChanges: "Aucune modification en attente"
|
|
852
|
+
noChanges: "Aucune modification en attente",
|
|
853
|
+
rowPreview: "Ouvrir l\u2019aper\xE7u de {label}"
|
|
777
854
|
};
|
|
778
855
|
|
|
779
856
|
// admin/translations/es.json
|
|
@@ -887,7 +964,8 @@ var es_default = {
|
|
|
887
964
|
columns: "Columnas",
|
|
888
965
|
noPreview: "sin vista previa",
|
|
889
966
|
"templates.none": "Sin vista previa",
|
|
890
|
-
noChanges: "Sin cambios pendientes"
|
|
967
|
+
noChanges: "Sin cambios pendientes",
|
|
968
|
+
rowPreview: "Abrir la vista previa de {label}"
|
|
891
969
|
};
|
|
892
970
|
|
|
893
971
|
// admin/translations/de.json
|
|
@@ -1001,7 +1079,8 @@ var de_default = {
|
|
|
1001
1079
|
columns: "Spalten",
|
|
1002
1080
|
noPreview: "keine Vorschau",
|
|
1003
1081
|
"templates.none": "Keine Vorschau",
|
|
1004
|
-
noChanges: "Keine ungespeicherten \xC4nderungen"
|
|
1082
|
+
noChanges: "Keine ungespeicherten \xC4nderungen",
|
|
1083
|
+
rowPreview: "Vorschau von {label} \xF6ffnen"
|
|
1005
1084
|
};
|
|
1006
1085
|
|
|
1007
1086
|
// admin/translations/it.json
|
|
@@ -1115,7 +1194,8 @@ var it_default = {
|
|
|
1115
1194
|
columns: "Colonne",
|
|
1116
1195
|
noPreview: "nessuna anteprima",
|
|
1117
1196
|
"templates.none": "Nessuna anteprima",
|
|
1118
|
-
noChanges: "Nessuna modifica in sospeso"
|
|
1197
|
+
noChanges: "Nessuna modifica in sospeso",
|
|
1198
|
+
rowPreview: "Apri l\u2019anteprima di {label}"
|
|
1119
1199
|
};
|
|
1120
1200
|
|
|
1121
1201
|
// admin/translations/nl.json
|
|
@@ -1229,7 +1309,8 @@ var nl_default = {
|
|
|
1229
1309
|
columns: "Kolommen",
|
|
1230
1310
|
noPreview: "geen voorbeeld",
|
|
1231
1311
|
"templates.none": "Geen voorbeeld",
|
|
1232
|
-
noChanges: "Geen niet-opgeslagen wijzigingen"
|
|
1312
|
+
noChanges: "Geen niet-opgeslagen wijzigingen",
|
|
1313
|
+
rowPreview: "Voorbeeld van {label} openen"
|
|
1233
1314
|
};
|
|
1234
1315
|
|
|
1235
1316
|
// admin/messages.ts
|
|
@@ -1249,26 +1330,224 @@ function useMessages() {
|
|
|
1249
1330
|
return out;
|
|
1250
1331
|
}
|
|
1251
1332
|
|
|
1333
|
+
// admin/RowPreviews.tsx
|
|
1334
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
1335
|
+
var ATTR = "data-blockscene-row-thumb";
|
|
1336
|
+
function useAnchors(zones, onOpen) {
|
|
1337
|
+
const [anchors, setAnchors] = React.useState([]);
|
|
1338
|
+
const open = React.useRef(onOpen);
|
|
1339
|
+
open.current = onOpen;
|
|
1340
|
+
const latest = React.useRef(zones);
|
|
1341
|
+
latest.current = zones;
|
|
1342
|
+
const sync = React.useRef(() => {
|
|
1343
|
+
});
|
|
1344
|
+
sync.current = () => {
|
|
1345
|
+
const next = [];
|
|
1346
|
+
for (const zone of latest.current) {
|
|
1347
|
+
const list = zone.uids?.length ? findZoneList(zone.label) : null;
|
|
1348
|
+
if (!list) continue;
|
|
1349
|
+
toggles(list).forEach((button, index) => {
|
|
1350
|
+
const uid = zone.uids[index];
|
|
1351
|
+
if (!uid) return;
|
|
1352
|
+
let el = button.querySelector(
|
|
1353
|
+
`:scope > [${ATTR}]`
|
|
1354
|
+
);
|
|
1355
|
+
if (!el) {
|
|
1356
|
+
el = document.createElement("span");
|
|
1357
|
+
el.setAttribute(ATTR, "");
|
|
1358
|
+
el.style.cssText = "display:inline-flex;align-items:center";
|
|
1359
|
+
const activate = (event) => {
|
|
1360
|
+
if (!event.currentTarget.getAttribute("role"))
|
|
1361
|
+
return;
|
|
1362
|
+
event.preventDefault();
|
|
1363
|
+
event.stopPropagation();
|
|
1364
|
+
open.current(
|
|
1365
|
+
String(event.currentTarget.dataset.uid || "")
|
|
1366
|
+
);
|
|
1367
|
+
};
|
|
1368
|
+
el.addEventListener("click", activate, true);
|
|
1369
|
+
el.addEventListener(
|
|
1370
|
+
"keydown",
|
|
1371
|
+
(event) => {
|
|
1372
|
+
if (event.key === "Enter" || event.key === " ") activate(event);
|
|
1373
|
+
},
|
|
1374
|
+
true
|
|
1375
|
+
);
|
|
1376
|
+
button.insertBefore(el, button.firstChild);
|
|
1377
|
+
}
|
|
1378
|
+
el.dataset.uid = uid;
|
|
1379
|
+
next.push({ el, uid, zone: zone.name, index });
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
for (const el of document.querySelectorAll(`[${ATTR}]`))
|
|
1383
|
+
if (!next.some((a) => a.el === el)) el.remove();
|
|
1384
|
+
setAnchors(
|
|
1385
|
+
(prev) => prev.length === next.length && prev.every((a, i) => a.el === next[i].el && a.uid === next[i].uid) ? prev : next
|
|
1386
|
+
);
|
|
1387
|
+
};
|
|
1388
|
+
React.useEffect(() => {
|
|
1389
|
+
sync.current();
|
|
1390
|
+
});
|
|
1391
|
+
React.useEffect(() => {
|
|
1392
|
+
let frame = 0;
|
|
1393
|
+
const observer = new MutationObserver(() => {
|
|
1394
|
+
if (frame) return;
|
|
1395
|
+
frame = requestAnimationFrame(() => {
|
|
1396
|
+
frame = 0;
|
|
1397
|
+
sync.current();
|
|
1398
|
+
});
|
|
1399
|
+
});
|
|
1400
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
1401
|
+
return () => {
|
|
1402
|
+
observer.disconnect();
|
|
1403
|
+
cancelAnimationFrame(frame);
|
|
1404
|
+
for (const el of document.querySelectorAll(`[${ATTR}]`)) el.remove();
|
|
1405
|
+
};
|
|
1406
|
+
}, []);
|
|
1407
|
+
return anchors;
|
|
1408
|
+
}
|
|
1409
|
+
function RowPreviews({ zones, components, catalog, Modal: Modal3 }) {
|
|
1410
|
+
const t = useMessages();
|
|
1411
|
+
const [resolved, setResolved] = React.useState({});
|
|
1412
|
+
const [open, setOpen] = React.useState(null);
|
|
1413
|
+
const anchors = useAnchors(zones, (uid) => setOpen(uid));
|
|
1414
|
+
const candidates = (uid) => candidatesFor(uid, catalog?.components?.[uid] || {}, catalog || {});
|
|
1415
|
+
const label = (uid) => catalog?.components?.[uid]?.label || components?.[uid]?.info?.displayName || uid;
|
|
1416
|
+
const srcOf = (uid) => candidates(uid)[resolved[uid] ?? -1] || "";
|
|
1417
|
+
React.useEffect(() => {
|
|
1418
|
+
for (const { el, uid } of anchors) {
|
|
1419
|
+
if (srcOf(uid)) {
|
|
1420
|
+
el.setAttribute("role", "button");
|
|
1421
|
+
el.setAttribute("tabindex", "0");
|
|
1422
|
+
el.setAttribute("aria-label", t.f("rowPreview", { label: label(uid) }));
|
|
1423
|
+
el.style.cursor = "zoom-in";
|
|
1424
|
+
} else
|
|
1425
|
+
for (const name of ["role", "tabindex", "aria-label"])
|
|
1426
|
+
el.removeAttribute(name);
|
|
1427
|
+
}
|
|
1428
|
+
});
|
|
1429
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1430
|
+
anchors.map(
|
|
1431
|
+
(a) => createPortal(
|
|
1432
|
+
/* @__PURE__ */ jsx2(
|
|
1433
|
+
"span",
|
|
1434
|
+
{
|
|
1435
|
+
style: {
|
|
1436
|
+
display: "block",
|
|
1437
|
+
width: "6.4rem",
|
|
1438
|
+
marginRight: "8px",
|
|
1439
|
+
flex: "0 0 auto"
|
|
1440
|
+
},
|
|
1441
|
+
children: /* @__PURE__ */ jsx2(
|
|
1442
|
+
Thumb,
|
|
1443
|
+
{
|
|
1444
|
+
candidates: candidates(a.uid),
|
|
1445
|
+
blank: true,
|
|
1446
|
+
onResolved: (index) => setResolved(
|
|
1447
|
+
(prev) => prev[a.uid] === index ? prev : { ...prev, [a.uid]: index }
|
|
1448
|
+
)
|
|
1449
|
+
}
|
|
1450
|
+
)
|
|
1451
|
+
}
|
|
1452
|
+
),
|
|
1453
|
+
a.el,
|
|
1454
|
+
`${a.zone}:${a.index}`
|
|
1455
|
+
)
|
|
1456
|
+
),
|
|
1457
|
+
open && srcOf(open) && /* @__PURE__ */ jsx2(
|
|
1458
|
+
Modal3,
|
|
1459
|
+
{
|
|
1460
|
+
open: true,
|
|
1461
|
+
onOpenChange: (value) => {
|
|
1462
|
+
if (!value) setOpen(null);
|
|
1463
|
+
},
|
|
1464
|
+
trigger: null,
|
|
1465
|
+
title: label(open),
|
|
1466
|
+
children: /* @__PURE__ */ jsx2(
|
|
1467
|
+
"img",
|
|
1468
|
+
{
|
|
1469
|
+
src: srcOf(open),
|
|
1470
|
+
alt: "",
|
|
1471
|
+
style: {
|
|
1472
|
+
display: "block",
|
|
1473
|
+
margin: "0 auto",
|
|
1474
|
+
maxWidth: "100%",
|
|
1475
|
+
maxHeight: "75vh",
|
|
1476
|
+
objectFit: "contain"
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
)
|
|
1480
|
+
}
|
|
1481
|
+
)
|
|
1482
|
+
] });
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1252
1485
|
// admin/Gallery.tsx
|
|
1253
|
-
import { jsx as
|
|
1486
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1254
1487
|
var Columns = styled.div`
|
|
1255
|
-
column-count: ${({ $columns }) => $columns};
|
|
1256
|
-
|
|
1488
|
+
column-count: ${({ $columns }) => $columns};
|
|
1489
|
+
column-gap: 12px;
|
|
1490
|
+
> * {
|
|
1491
|
+
break-inside: avoid;
|
|
1492
|
+
-webkit-column-break-inside: avoid;
|
|
1493
|
+
margin-bottom: 12px;
|
|
1494
|
+
}
|
|
1257
1495
|
`;
|
|
1258
1496
|
var Tile = styled.button`
|
|
1259
|
-
display: flex;
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1497
|
+
display: flex;
|
|
1498
|
+
flex-direction: column;
|
|
1499
|
+
gap: 8px;
|
|
1500
|
+
text-align: left;
|
|
1501
|
+
width: 100%;
|
|
1502
|
+
padding: 8px;
|
|
1503
|
+
border: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
1504
|
+
border-radius: 4px;
|
|
1505
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
1506
|
+
cursor: pointer;
|
|
1507
|
+
&:hover {
|
|
1508
|
+
border-color: ${({ theme }) => theme.colors.primary600};
|
|
1509
|
+
}
|
|
1510
|
+
&:focus-visible {
|
|
1511
|
+
outline: 2px solid ${({ theme }) => theme.colors.primary600};
|
|
1512
|
+
outline-offset: 2px;
|
|
1513
|
+
}
|
|
1514
|
+
`;
|
|
1515
|
+
var Clamp = styled(Typography)`
|
|
1516
|
+
display: -webkit-box;
|
|
1517
|
+
-webkit-line-clamp: 2;
|
|
1518
|
+
-webkit-box-orient: vertical;
|
|
1519
|
+
overflow: hidden;
|
|
1264
1520
|
`;
|
|
1265
|
-
var Clamp = styled(Typography)` display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; `;
|
|
1266
1521
|
var Slider = styled.input`
|
|
1267
|
-
appearance: none;
|
|
1522
|
+
appearance: none;
|
|
1523
|
+
-webkit-appearance: none;
|
|
1524
|
+
width: 8rem;
|
|
1525
|
+
height: 0.4rem;
|
|
1526
|
+
border-radius: 0.4rem;
|
|
1527
|
+
cursor: pointer;
|
|
1268
1528
|
background: ${({ theme, $percent }) => `linear-gradient(to right, ${theme.colors.primary600} ${$percent}%, ${theme.colors.neutral200} ${$percent}%)`};
|
|
1269
|
-
&::-webkit-slider-thumb {
|
|
1270
|
-
|
|
1271
|
-
|
|
1529
|
+
&::-webkit-slider-thumb {
|
|
1530
|
+
appearance: none;
|
|
1531
|
+
-webkit-appearance: none;
|
|
1532
|
+
width: 1.6rem;
|
|
1533
|
+
height: 1.6rem;
|
|
1534
|
+
border-radius: 50%;
|
|
1535
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
1536
|
+
border: 0.2rem solid ${({ theme }) => theme.colors.primary600};
|
|
1537
|
+
cursor: pointer;
|
|
1538
|
+
}
|
|
1539
|
+
&::-moz-range-thumb {
|
|
1540
|
+
width: 1.6rem;
|
|
1541
|
+
height: 1.6rem;
|
|
1542
|
+
border-radius: 50%;
|
|
1543
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
1544
|
+
border: 0.2rem solid ${({ theme }) => theme.colors.primary600};
|
|
1545
|
+
cursor: pointer;
|
|
1546
|
+
}
|
|
1547
|
+
&:focus-visible {
|
|
1548
|
+
outline: 0.2rem solid ${({ theme }) => theme.colors.primary600};
|
|
1549
|
+
outline-offset: 0.2rem;
|
|
1550
|
+
}
|
|
1272
1551
|
`;
|
|
1273
1552
|
var COLUMNS = { key: "blockscene:columns", min: 1, max: 5, initial: 3 };
|
|
1274
1553
|
var SHOW_FIELDS_KEY = "blockscene:show-fields";
|
|
@@ -1294,16 +1573,31 @@ var remember = (key, value) => {
|
|
|
1294
1573
|
}
|
|
1295
1574
|
};
|
|
1296
1575
|
var Frame = styled.div`
|
|
1297
|
-
width: 100%;
|
|
1576
|
+
width: 100%;
|
|
1577
|
+
overflow: hidden;
|
|
1578
|
+
border-radius: 4px;
|
|
1579
|
+
line-height: 0;
|
|
1298
1580
|
aspect-ratio: ${({ $fixed }) => $fixed ? "16 / 9" : "auto"};
|
|
1299
1581
|
background: ${({ theme }) => theme.colors.neutral100};
|
|
1300
|
-
img {
|
|
1582
|
+
img {
|
|
1583
|
+
width: 100%;
|
|
1584
|
+
height: auto;
|
|
1585
|
+
display: block;
|
|
1586
|
+
}
|
|
1301
1587
|
`;
|
|
1302
|
-
function Thumb({
|
|
1588
|
+
function Thumb({
|
|
1589
|
+
candidates,
|
|
1590
|
+
template,
|
|
1591
|
+
palette,
|
|
1592
|
+
onResolved,
|
|
1593
|
+
noPreview,
|
|
1594
|
+
eager,
|
|
1595
|
+
blank
|
|
1596
|
+
}) {
|
|
1303
1597
|
const key = candidates.join("|");
|
|
1304
|
-
const [state, setState] =
|
|
1598
|
+
const [state, setState] = React2.useState({ key, index: 0 });
|
|
1305
1599
|
const index = state.key === key ? state.index : 0;
|
|
1306
|
-
const resolved =
|
|
1600
|
+
const resolved = React2.useRef("");
|
|
1307
1601
|
const report = (value) => {
|
|
1308
1602
|
const tag = `${key}:${value}`;
|
|
1309
1603
|
if (resolved.current !== tag) {
|
|
@@ -1311,11 +1605,19 @@ function Thumb({ candidates, template, palette, onResolved, noPreview, eager })
|
|
|
1311
1605
|
onResolved?.(value);
|
|
1312
1606
|
}
|
|
1313
1607
|
};
|
|
1314
|
-
|
|
1608
|
+
React2.useEffect(() => {
|
|
1315
1609
|
if (index >= candidates.length) report(-1);
|
|
1316
1610
|
});
|
|
1317
|
-
if (index >= candidates.length)
|
|
1318
|
-
|
|
1611
|
+
if (index >= candidates.length)
|
|
1612
|
+
return blank ? null : /* @__PURE__ */ jsx3(Frame, { $fixed: true, "data-thumb": "wireframe", children: /* @__PURE__ */ jsx3(
|
|
1613
|
+
Wireframe,
|
|
1614
|
+
{
|
|
1615
|
+
template,
|
|
1616
|
+
palette,
|
|
1617
|
+
noPreview
|
|
1618
|
+
}
|
|
1619
|
+
) });
|
|
1620
|
+
return /* @__PURE__ */ jsx3(Frame, { "data-thumb": String(index), children: /* @__PURE__ */ jsx3(
|
|
1319
1621
|
"img",
|
|
1320
1622
|
{
|
|
1321
1623
|
src: candidates[index],
|
|
@@ -1329,28 +1631,90 @@ function Thumb({ candidates, template, palette, onResolved, noPreview, eager })
|
|
|
1329
1631
|
}
|
|
1330
1632
|
function Card({ entry, palette, showFields, onSelect }) {
|
|
1331
1633
|
const t = useMessages();
|
|
1332
|
-
return /* @__PURE__ */
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1634
|
+
return /* @__PURE__ */ jsxs2(
|
|
1635
|
+
Tile,
|
|
1636
|
+
{
|
|
1637
|
+
type: "button",
|
|
1638
|
+
onClick: onSelect,
|
|
1639
|
+
title: entry.uid,
|
|
1640
|
+
"data-testid": `blockscene-${entry.uid}`,
|
|
1641
|
+
children: [
|
|
1642
|
+
/* @__PURE__ */ jsx3(
|
|
1643
|
+
Thumb,
|
|
1644
|
+
{
|
|
1645
|
+
candidates: entry.candidates,
|
|
1646
|
+
template: entry.template,
|
|
1647
|
+
palette,
|
|
1648
|
+
noPreview: t.noPreview
|
|
1649
|
+
}
|
|
1650
|
+
),
|
|
1651
|
+
/* @__PURE__ */ jsx3(
|
|
1652
|
+
Typography,
|
|
1653
|
+
{
|
|
1654
|
+
variant: "pi",
|
|
1655
|
+
fontWeight: "bold",
|
|
1656
|
+
textColor: "neutral800",
|
|
1657
|
+
ellipsis: true,
|
|
1658
|
+
children: entry.label
|
|
1659
|
+
}
|
|
1660
|
+
),
|
|
1661
|
+
entry.description && /* @__PURE__ */ jsx3(Clamp, { variant: "pi", textColor: "neutral600", children: entry.description }),
|
|
1662
|
+
showFields && entry.fields.length > 0 && /* @__PURE__ */ jsx3(
|
|
1663
|
+
Typography,
|
|
1664
|
+
{
|
|
1665
|
+
variant: "pi",
|
|
1666
|
+
textColor: "neutral500",
|
|
1667
|
+
style: { fontStyle: "italic" },
|
|
1668
|
+
"data-testid": "block-fields",
|
|
1669
|
+
children: entry.fields.map((f) => `${f.name} (${f.type})`).join(", ")
|
|
1670
|
+
}
|
|
1671
|
+
)
|
|
1672
|
+
]
|
|
1673
|
+
}
|
|
1674
|
+
);
|
|
1338
1675
|
}
|
|
1339
|
-
function PickerModal({
|
|
1340
|
-
|
|
1676
|
+
function PickerModal({
|
|
1677
|
+
zone,
|
|
1678
|
+
components,
|
|
1679
|
+
open,
|
|
1680
|
+
onOpenChange,
|
|
1681
|
+
onSelect,
|
|
1682
|
+
Modal: Modal3,
|
|
1683
|
+
Toggle,
|
|
1684
|
+
get
|
|
1685
|
+
}) {
|
|
1686
|
+
return /* @__PURE__ */ jsx3(
|
|
1687
|
+
ZoneGallery,
|
|
1688
|
+
{
|
|
1689
|
+
zone,
|
|
1690
|
+
components,
|
|
1691
|
+
Modal: Modal3,
|
|
1692
|
+
Toggle,
|
|
1693
|
+
get,
|
|
1694
|
+
controlled: { open, onOpenChange, onSelect }
|
|
1695
|
+
}
|
|
1696
|
+
);
|
|
1341
1697
|
}
|
|
1342
|
-
function ZoneGallery({
|
|
1698
|
+
function ZoneGallery({
|
|
1699
|
+
zone,
|
|
1700
|
+
components,
|
|
1701
|
+
add,
|
|
1702
|
+
Modal: Modal3,
|
|
1703
|
+
Toggle,
|
|
1704
|
+
get,
|
|
1705
|
+
controlled
|
|
1706
|
+
}) {
|
|
1343
1707
|
const t = useMessages();
|
|
1344
|
-
const [ownOpen, setOwnOpen] =
|
|
1708
|
+
const [ownOpen, setOwnOpen] = React2.useState(false);
|
|
1345
1709
|
const open = controlled ? controlled.open : ownOpen;
|
|
1346
1710
|
const setOpen = controlled ? controlled.onOpenChange : setOwnOpen;
|
|
1347
|
-
const [query, setQuery] =
|
|
1348
|
-
const [category, setCategory] =
|
|
1349
|
-
const [showFields, setShowFields] =
|
|
1350
|
-
const [columns, setColumns] =
|
|
1351
|
-
const [config, setConfig] =
|
|
1352
|
-
const [error, setError] =
|
|
1353
|
-
|
|
1711
|
+
const [query, setQuery] = React2.useState("");
|
|
1712
|
+
const [category, setCategory] = React2.useState("all");
|
|
1713
|
+
const [showFields, setShowFields] = React2.useState(readShowFields);
|
|
1714
|
+
const [columns, setColumns] = React2.useState(readColumns);
|
|
1715
|
+
const [config, setConfig] = React2.useState(null);
|
|
1716
|
+
const [error, setError] = React2.useState("");
|
|
1717
|
+
React2.useEffect(() => {
|
|
1354
1718
|
if (controlled) return;
|
|
1355
1719
|
const onClick = (event) => {
|
|
1356
1720
|
const button = event.target?.closest?.("button");
|
|
@@ -1362,7 +1726,7 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1362
1726
|
document.addEventListener("click", onClick, true);
|
|
1363
1727
|
return () => document.removeEventListener("click", onClick, true);
|
|
1364
1728
|
}, [controlled, zone.name, zone.label]);
|
|
1365
|
-
|
|
1729
|
+
React2.useEffect(() => {
|
|
1366
1730
|
if (!open) return;
|
|
1367
1731
|
let active = true;
|
|
1368
1732
|
setError("");
|
|
@@ -1378,7 +1742,10 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1378
1742
|
}, [open, get, t.failed]);
|
|
1379
1743
|
const entries = config ? entriesFor(zone, components, config, query, category) : [];
|
|
1380
1744
|
const categories = config ? categoriesFor(zone, components, config) : [];
|
|
1381
|
-
const total = categories.reduce(
|
|
1745
|
+
const total = categories.reduce(
|
|
1746
|
+
(sum, [, count]) => sum + count,
|
|
1747
|
+
0
|
|
1748
|
+
);
|
|
1382
1749
|
const filtering = query.trim() !== "" || category !== "all";
|
|
1383
1750
|
const reset = () => {
|
|
1384
1751
|
setQuery("");
|
|
@@ -1402,21 +1769,41 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1402
1769
|
setShowFields(value);
|
|
1403
1770
|
remember(SHOW_FIELDS_KEY, String(value));
|
|
1404
1771
|
};
|
|
1405
|
-
return /* @__PURE__ */
|
|
1772
|
+
return /* @__PURE__ */ jsx3(
|
|
1406
1773
|
Modal3,
|
|
1407
1774
|
{
|
|
1408
1775
|
open,
|
|
1409
1776
|
onOpenChange: setOpen,
|
|
1410
1777
|
title: t.gallery,
|
|
1411
|
-
trigger: controlled ? null : /* @__PURE__ */
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1778
|
+
trigger: controlled ? null : /* @__PURE__ */ jsxs2(
|
|
1779
|
+
Button,
|
|
1780
|
+
{
|
|
1781
|
+
variant: "secondary",
|
|
1782
|
+
fullWidth: true,
|
|
1783
|
+
onClick: () => setOpen(true),
|
|
1784
|
+
"data-testid": `open-gallery-${zone.name}`,
|
|
1785
|
+
children: [
|
|
1786
|
+
t.add,
|
|
1787
|
+
": ",
|
|
1788
|
+
zone.name
|
|
1789
|
+
]
|
|
1790
|
+
}
|
|
1791
|
+
),
|
|
1792
|
+
children: /* @__PURE__ */ jsxs2(Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
|
|
1793
|
+
/* @__PURE__ */ jsxs2(Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
|
|
1794
|
+
/* @__PURE__ */ jsx3(
|
|
1795
|
+
Typography,
|
|
1796
|
+
{
|
|
1797
|
+
variant: "omega",
|
|
1798
|
+
fontWeight: "bold",
|
|
1799
|
+
textColor: "neutral800",
|
|
1800
|
+
style: { whiteSpace: "nowrap" },
|
|
1801
|
+
"data-testid": `block-count-${zone.name}`,
|
|
1802
|
+
"aria-live": "polite",
|
|
1803
|
+
children: filtering ? t.f("countFiltered", { shown: entries.length, total }) : t.f("countAll", { count: total })
|
|
1804
|
+
}
|
|
1805
|
+
),
|
|
1806
|
+
/* @__PURE__ */ jsx3(Box, { style: { flex: 1, minWidth: "12rem" }, children: /* @__PURE__ */ jsx3(
|
|
1420
1807
|
Searchbar,
|
|
1421
1808
|
{
|
|
1422
1809
|
name: `block-search-${zone.name}`,
|
|
@@ -1428,14 +1815,54 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1428
1815
|
children: t.search
|
|
1429
1816
|
}
|
|
1430
1817
|
) }),
|
|
1431
|
-
categories.length > 1 && /* @__PURE__ */
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1818
|
+
categories.length > 1 && /* @__PURE__ */ jsx3(
|
|
1819
|
+
Box,
|
|
1820
|
+
{
|
|
1821
|
+
style: { width: "14rem" },
|
|
1822
|
+
"data-testid": `block-category-${zone.name}`,
|
|
1823
|
+
children: /* @__PURE__ */ jsxs2(
|
|
1824
|
+
SingleSelect,
|
|
1825
|
+
{
|
|
1826
|
+
"aria-label": t.filterCategory,
|
|
1827
|
+
size: "S",
|
|
1828
|
+
value: category,
|
|
1829
|
+
onChange: (value) => setCategory(String(value)),
|
|
1830
|
+
children: [
|
|
1831
|
+
/* @__PURE__ */ jsx3(SingleSelectOption, { value: "all", children: t.allCategories }),
|
|
1832
|
+
categories.map(([name, count]) => /* @__PURE__ */ jsx3(
|
|
1833
|
+
SingleSelectOption,
|
|
1834
|
+
{
|
|
1835
|
+
value: name,
|
|
1836
|
+
children: `${name} (${count})`
|
|
1837
|
+
},
|
|
1838
|
+
name
|
|
1839
|
+
))
|
|
1840
|
+
]
|
|
1841
|
+
}
|
|
1842
|
+
)
|
|
1843
|
+
}
|
|
1844
|
+
),
|
|
1845
|
+
Toggle && /* @__PURE__ */ jsx3(
|
|
1846
|
+
Toggle,
|
|
1847
|
+
{
|
|
1848
|
+
name: `block-fields-${zone.name}`,
|
|
1849
|
+
label: t.showFields,
|
|
1850
|
+
hint: t.showFieldsHint,
|
|
1851
|
+
value: showFields,
|
|
1852
|
+
onChange: changeShowFields
|
|
1853
|
+
}
|
|
1854
|
+
),
|
|
1855
|
+
/* @__PURE__ */ jsxs2(Flex, { gap: 2, alignItems: "center", children: [
|
|
1856
|
+
/* @__PURE__ */ jsx3(
|
|
1857
|
+
Typography,
|
|
1858
|
+
{
|
|
1859
|
+
variant: "pi",
|
|
1860
|
+
textColor: "neutral600",
|
|
1861
|
+
id: `block-columns-${zone.name}`,
|
|
1862
|
+
children: t.columns
|
|
1863
|
+
}
|
|
1864
|
+
),
|
|
1865
|
+
/* @__PURE__ */ jsx3(
|
|
1439
1866
|
Slider,
|
|
1440
1867
|
{
|
|
1441
1868
|
type: "range",
|
|
@@ -1448,16 +1875,52 @@ function ZoneGallery({ zone, components, add, Modal: Modal3, Toggle, get, contro
|
|
|
1448
1875
|
onChange: (e) => changeColumns(Number(e.target.value))
|
|
1449
1876
|
}
|
|
1450
1877
|
),
|
|
1451
|
-
/* @__PURE__ */
|
|
1878
|
+
/* @__PURE__ */ jsx3(Typography, { variant: "pi", fontWeight: "bold", children: columns })
|
|
1452
1879
|
] })
|
|
1453
1880
|
] }),
|
|
1454
|
-
/* @__PURE__ */
|
|
1455
|
-
error ? /* @__PURE__ */
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1881
|
+
/* @__PURE__ */ jsx3(Typography, { variant: "pi", textColor: "neutral600", children: t.example }),
|
|
1882
|
+
error ? /* @__PURE__ */ jsx3(Typography, { role: "alert", textColor: "danger600", children: error }) : !config ? /* @__PURE__ */ jsx3(Typography, { children: t.loading }) : entries.length ? /* @__PURE__ */ jsx3(
|
|
1883
|
+
Flex,
|
|
1884
|
+
{
|
|
1885
|
+
direction: "column",
|
|
1886
|
+
alignItems: "stretch",
|
|
1887
|
+
gap: 4,
|
|
1888
|
+
style: { overflowY: "auto", maxHeight: "60vh", padding: "4px" },
|
|
1889
|
+
children: groupEntries(entries).map(
|
|
1890
|
+
({ category: name, entries: items }) => /* @__PURE__ */ jsxs2(
|
|
1891
|
+
Flex,
|
|
1892
|
+
{
|
|
1893
|
+
direction: "column",
|
|
1894
|
+
alignItems: "stretch",
|
|
1895
|
+
gap: 2,
|
|
1896
|
+
children: [
|
|
1897
|
+
/* @__PURE__ */ jsx3(
|
|
1898
|
+
Typography,
|
|
1899
|
+
{
|
|
1900
|
+
variant: "sigma",
|
|
1901
|
+
textColor: "neutral600",
|
|
1902
|
+
"data-testid": `block-group-${name}`,
|
|
1903
|
+
children: `${name} (${items.length})`
|
|
1904
|
+
}
|
|
1905
|
+
),
|
|
1906
|
+
/* @__PURE__ */ jsx3(Columns, { $columns: columns, children: items.map((entry) => /* @__PURE__ */ jsx3("div", { children: /* @__PURE__ */ jsx3(
|
|
1907
|
+
Card,
|
|
1908
|
+
{
|
|
1909
|
+
entry,
|
|
1910
|
+
palette: config.palette,
|
|
1911
|
+
showFields,
|
|
1912
|
+
onSelect: () => select(entry.uid)
|
|
1913
|
+
}
|
|
1914
|
+
) }, entry.uid)) })
|
|
1915
|
+
]
|
|
1916
|
+
},
|
|
1917
|
+
name
|
|
1918
|
+
)
|
|
1919
|
+
)
|
|
1920
|
+
}
|
|
1921
|
+
) : /* @__PURE__ */ jsxs2(Flex, { gap: 3, alignItems: "center", children: [
|
|
1922
|
+
/* @__PURE__ */ jsx3(Typography, { children: t.empty }),
|
|
1923
|
+
filtering && /* @__PURE__ */ jsx3(Button, { variant: "tertiary", size: "S", onClick: reset, children: t.clear })
|
|
1461
1924
|
] })
|
|
1462
1925
|
] })
|
|
1463
1926
|
}
|
|
@@ -1471,13 +1934,19 @@ var storage = () => {
|
|
|
1471
1934
|
}
|
|
1472
1935
|
};
|
|
1473
1936
|
var memoryBase = () => `${window.location.origin}${window.location.pathname.split("/content-manager")[0]}`;
|
|
1474
|
-
function useInitialAccordions({
|
|
1475
|
-
|
|
1476
|
-
|
|
1937
|
+
function useInitialAccordions({
|
|
1938
|
+
zones,
|
|
1939
|
+
editor,
|
|
1940
|
+
docKey,
|
|
1941
|
+
contentType,
|
|
1942
|
+
userId
|
|
1943
|
+
}) {
|
|
1944
|
+
const applied = React2.useRef("");
|
|
1945
|
+
const user = React2.useRef(userId);
|
|
1477
1946
|
user.current = userId;
|
|
1478
|
-
const latest =
|
|
1947
|
+
const latest = React2.useRef(zones);
|
|
1479
1948
|
latest.current = zones;
|
|
1480
|
-
|
|
1949
|
+
React2.useEffect(() => {
|
|
1481
1950
|
if (!editor?.enabled || !docKey || applied.current === docKey) return;
|
|
1482
1951
|
if (applied.current.startsWith(`${contentType}:new`) && docKey.startsWith(`${contentType}:`)) {
|
|
1483
1952
|
applied.current = docKey;
|
|
@@ -1486,7 +1955,10 @@ function useInitialAccordions({ zones, editor, docKey, contentType, userId }) {
|
|
|
1486
1955
|
applied.current = docKey;
|
|
1487
1956
|
let tries = 0;
|
|
1488
1957
|
const cancel = (event) => {
|
|
1489
|
-
if (event.target?.closest?.(
|
|
1958
|
+
if (event.target?.closest?.(
|
|
1959
|
+
'button[aria-expanded], [data-testid^="block-accordion-controls-"]'
|
|
1960
|
+
))
|
|
1961
|
+
stop();
|
|
1490
1962
|
};
|
|
1491
1963
|
const stop = () => {
|
|
1492
1964
|
clearInterval(timer);
|
|
@@ -1504,8 +1976,17 @@ function useInitialAccordions({ zones, editor, docKey, contentType, userId }) {
|
|
|
1504
1976
|
for (const zone of pending) {
|
|
1505
1977
|
const list = findZoneList(zone.label);
|
|
1506
1978
|
if (!list) continue;
|
|
1507
|
-
const key = memoryKey({
|
|
1508
|
-
|
|
1979
|
+
const key = memoryKey({
|
|
1980
|
+
base: memoryBase(),
|
|
1981
|
+
userId: user.current,
|
|
1982
|
+
contentType,
|
|
1983
|
+
zone: zone.name
|
|
1984
|
+
});
|
|
1985
|
+
setAll(
|
|
1986
|
+
list,
|
|
1987
|
+
initialState(editor, readMemory(storage(), key)) === "open",
|
|
1988
|
+
unstable_batchedUpdates
|
|
1989
|
+
);
|
|
1509
1990
|
}
|
|
1510
1991
|
}, 200);
|
|
1511
1992
|
return stop;
|
|
@@ -1517,50 +1998,117 @@ function ZoneControls({ zone, editor, contentType, userId }) {
|
|
|
1517
1998
|
const apply = (open) => {
|
|
1518
1999
|
const list = findZoneList(zone.label);
|
|
1519
2000
|
if (list) setAll(list, open, unstable_batchedUpdates);
|
|
1520
|
-
writeMemory(
|
|
2001
|
+
writeMemory(
|
|
2002
|
+
storage(),
|
|
2003
|
+
memoryKey({ base: memoryBase(), userId, contentType, zone: zone.name }),
|
|
2004
|
+
open ? "open" : "closed"
|
|
2005
|
+
);
|
|
1521
2006
|
};
|
|
1522
|
-
return /* @__PURE__ */
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
2007
|
+
return /* @__PURE__ */ jsxs2(
|
|
2008
|
+
Flex,
|
|
2009
|
+
{
|
|
2010
|
+
gap: 2,
|
|
2011
|
+
wrap: "wrap",
|
|
2012
|
+
"data-testid": `block-accordion-controls-${zone.name}`,
|
|
2013
|
+
children: [
|
|
2014
|
+
editor.showOpenAll && /* @__PURE__ */ jsx3(
|
|
2015
|
+
Button,
|
|
2016
|
+
{
|
|
2017
|
+
type: "button",
|
|
2018
|
+
variant: "tertiary",
|
|
2019
|
+
size: "S",
|
|
2020
|
+
onClick: () => apply(true),
|
|
2021
|
+
children: t.openAll
|
|
2022
|
+
}
|
|
2023
|
+
),
|
|
2024
|
+
editor.showCloseAll && /* @__PURE__ */ jsx3(
|
|
2025
|
+
Button,
|
|
2026
|
+
{
|
|
2027
|
+
type: "button",
|
|
2028
|
+
variant: "tertiary",
|
|
2029
|
+
size: "S",
|
|
2030
|
+
onClick: () => apply(false),
|
|
2031
|
+
children: t.closeAll
|
|
2032
|
+
}
|
|
2033
|
+
)
|
|
2034
|
+
]
|
|
2035
|
+
}
|
|
2036
|
+
);
|
|
1526
2037
|
}
|
|
1527
|
-
function Gallery({
|
|
2038
|
+
function Gallery({
|
|
2039
|
+
zones,
|
|
2040
|
+
editor,
|
|
2041
|
+
docKey,
|
|
2042
|
+
contentType,
|
|
2043
|
+
userId,
|
|
2044
|
+
catalog,
|
|
2045
|
+
...props
|
|
2046
|
+
}) {
|
|
1528
2047
|
useInitialAccordions({ zones, editor, docKey, contentType, userId });
|
|
1529
|
-
return /* @__PURE__ */
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
2048
|
+
return /* @__PURE__ */ jsxs2(Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
|
|
2049
|
+
/* @__PURE__ */ jsx3(
|
|
2050
|
+
RowPreviews,
|
|
2051
|
+
{
|
|
2052
|
+
zones,
|
|
2053
|
+
components: props.components,
|
|
2054
|
+
catalog,
|
|
2055
|
+
Modal: props.Modal
|
|
2056
|
+
}
|
|
2057
|
+
),
|
|
2058
|
+
zones.map((zone) => /* @__PURE__ */ jsxs2(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
|
|
2059
|
+
!zone.full && /* @__PURE__ */ jsx3(ZoneGallery, { zone, ...props }),
|
|
2060
|
+
/* @__PURE__ */ jsx3(
|
|
2061
|
+
ZoneControls,
|
|
2062
|
+
{
|
|
2063
|
+
zone,
|
|
2064
|
+
editor,
|
|
2065
|
+
contentType,
|
|
2066
|
+
userId
|
|
2067
|
+
}
|
|
2068
|
+
)
|
|
2069
|
+
] }, zone.name))
|
|
2070
|
+
] });
|
|
1533
2071
|
}
|
|
1534
2072
|
|
|
1535
2073
|
// admin/PagePreview.tsx
|
|
1536
|
-
import * as
|
|
1537
|
-
import { createPortal } from "react-dom";
|
|
2074
|
+
import * as React4 from "react";
|
|
2075
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
1538
2076
|
import styled2 from "styled-components";
|
|
1539
2077
|
import { Box as Box2, Button as Button3, Flex as Flex3, Typography as Typography3 } from "@strapi/design-system";
|
|
1540
|
-
import {
|
|
1541
|
-
|
|
1542
|
-
|
|
2078
|
+
import {
|
|
2079
|
+
DescriptionComponentRenderer,
|
|
2080
|
+
useFetchClient,
|
|
2081
|
+
useForm as useForm2,
|
|
2082
|
+
useNotification,
|
|
2083
|
+
useQueryParams,
|
|
2084
|
+
useStrapiApp as useStrapiApp2
|
|
2085
|
+
} from "@strapi/strapi/admin";
|
|
2086
|
+
import {
|
|
2087
|
+
unstable_useContentManagerContext as useContext,
|
|
2088
|
+
unstable_useDocument as useDocument,
|
|
2089
|
+
useDocumentRBAC
|
|
2090
|
+
} from "@strapi/content-manager/strapi-admin";
|
|
1543
2091
|
|
|
1544
2092
|
// admin/FieldEditorModal.tsx
|
|
1545
|
-
import * as
|
|
2093
|
+
import * as React3 from "react";
|
|
1546
2094
|
import { Form, InputRenderer, useForm, useStrapiApp } from "@strapi/strapi/admin";
|
|
1547
2095
|
import { Button as Button2, Flex as Flex2, Modal, Typography as Typography2 } from "@strapi/design-system";
|
|
1548
|
-
import { jsx as
|
|
2096
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1549
2097
|
var Actions = ({ onApply, onCancel }) => {
|
|
1550
2098
|
const t = useMessages();
|
|
1551
2099
|
const value = useForm("BlocksceneFieldEditor", (state) => state.values.value);
|
|
1552
|
-
return /* @__PURE__ */
|
|
1553
|
-
/* @__PURE__ */
|
|
1554
|
-
/* @__PURE__ */
|
|
2100
|
+
return /* @__PURE__ */ jsxs3(Flex2, { gap: 2, justifyContent: "flex-end", children: [
|
|
2101
|
+
/* @__PURE__ */ jsx4(Button2, { variant: "tertiary", onClick: onCancel, children: t.cancel }),
|
|
2102
|
+
/* @__PURE__ */ jsx4(Button2, { onClick: () => onApply(value ?? null), "data-testid": "field-editor-apply", children: t.apply })
|
|
1555
2103
|
] });
|
|
1556
2104
|
};
|
|
1557
2105
|
function FieldEditorModal({ label, attribute, value, onApply, onCancel }) {
|
|
1558
2106
|
const t = useMessages();
|
|
1559
2107
|
const customFields = useStrapiApp("BlocksceneFieldEditor", (state) => state.customFields);
|
|
1560
|
-
const [Input, setInput] =
|
|
2108
|
+
const [Input, setInput] = React3.useState(void 0);
|
|
1561
2109
|
const isCustom = Boolean(attribute?.customField);
|
|
1562
2110
|
const isText = attribute?.type === "string" || attribute?.type === "text";
|
|
1563
|
-
|
|
2111
|
+
React3.useEffect(() => {
|
|
1564
2112
|
let active = true;
|
|
1565
2113
|
if (!isCustom) {
|
|
1566
2114
|
setInput(null);
|
|
@@ -1581,24 +2129,24 @@ function FieldEditorModal({ label, attribute, value, onApply, onCancel }) {
|
|
|
1581
2129
|
};
|
|
1582
2130
|
}, [attribute, customFields, isCustom]);
|
|
1583
2131
|
const supported = isText || isCustom && Input;
|
|
1584
|
-
return /* @__PURE__ */
|
|
2132
|
+
return /* @__PURE__ */ jsx4(Modal.Root, { open: true, onOpenChange: (open) => {
|
|
1585
2133
|
if (!open) onCancel();
|
|
1586
|
-
}, children: /* @__PURE__ */
|
|
1587
|
-
/* @__PURE__ */
|
|
2134
|
+
}, children: /* @__PURE__ */ jsxs3(Modal.Content, { "aria-label": `${t.editText} ${label}`, children: [
|
|
2135
|
+
/* @__PURE__ */ jsx4(Modal.Header, { children: /* @__PURE__ */ jsxs3(Modal.Title, { children: [
|
|
1588
2136
|
t.editText,
|
|
1589
2137
|
" \xB7 ",
|
|
1590
2138
|
label
|
|
1591
2139
|
] }) }),
|
|
1592
|
-
/* @__PURE__ */
|
|
2140
|
+
/* @__PURE__ */ jsxs3(Form, { initialValues: { value: value ?? (isText ? "" : null) }, method: "PUT", onSubmit: () => {
|
|
1593
2141
|
}, children: [
|
|
1594
|
-
/* @__PURE__ */
|
|
1595
|
-
/* @__PURE__ */
|
|
1596
|
-
isCustom && Input === void 0 && /* @__PURE__ */
|
|
1597
|
-
isCustom && Input && /* @__PURE__ */
|
|
1598
|
-
isText && /* @__PURE__ */
|
|
1599
|
-
(isCustom && Input === null || !isCustom && !isText) && /* @__PURE__ */
|
|
2142
|
+
/* @__PURE__ */ jsx4(Modal.Body, { children: /* @__PURE__ */ jsxs3(Flex2, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "field-editor-modal", children: [
|
|
2143
|
+
/* @__PURE__ */ jsx4(Typography2, { variant: "pi", textColor: "neutral600", children: t.editHelp }),
|
|
2144
|
+
isCustom && Input === void 0 && /* @__PURE__ */ jsx4(Typography2, { children: t.loading }),
|
|
2145
|
+
isCustom && Input && /* @__PURE__ */ jsx4(Input, { name: "value", attribute, label, type: attribute.type }),
|
|
2146
|
+
isText && /* @__PURE__ */ jsx4(InputRenderer, { type: attribute.type === "text" ? "text" : "string", name: "value", label }),
|
|
2147
|
+
(isCustom && Input === null || !isCustom && !isText) && /* @__PURE__ */ jsx4(Typography2, { role: "alert", textColor: "danger600", children: t.editUnsupported })
|
|
1600
2148
|
] }) }),
|
|
1601
|
-
/* @__PURE__ */
|
|
2149
|
+
/* @__PURE__ */ jsx4(Modal.Footer, { children: supported ? /* @__PURE__ */ jsx4(Actions, { onApply, onCancel }) : /* @__PURE__ */ jsx4(Button2, { variant: "tertiary", onClick: onCancel, children: t.close }) })
|
|
1602
2150
|
] })
|
|
1603
2151
|
] }) });
|
|
1604
2152
|
}
|
|
@@ -1709,6 +2257,7 @@ var mediaAttribute = (uid, field, components) => {
|
|
|
1709
2257
|
const attr = resolveField(uid, field, components);
|
|
1710
2258
|
return attr?.type === "media" ? attr : null;
|
|
1711
2259
|
};
|
|
2260
|
+
var getIn = (row, path) => String(path).split(".").reduce((value, key) => value == null ? void 0 : value[key], row);
|
|
1712
2261
|
function isPreviewMessage(event, origin, source, channel, type) {
|
|
1713
2262
|
return event.origin === origin && event.source === source && event.data?.protocol === PROTOCOL && event.data?.channel === channel && event.data?.type === type;
|
|
1714
2263
|
}
|
|
@@ -1719,7 +2268,7 @@ function insertIndex(rows, after) {
|
|
|
1719
2268
|
}
|
|
1720
2269
|
|
|
1721
2270
|
// admin/PagePreview.tsx
|
|
1722
|
-
import { jsx as
|
|
2271
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1723
2272
|
var MODE_KEY = "blockscene:page-mode";
|
|
1724
2273
|
var RATIO_KEY = "blockscene:page-split-ratio";
|
|
1725
2274
|
var MIN_PANE = 360;
|
|
@@ -1740,20 +2289,32 @@ var write = (key, value) => {
|
|
|
1740
2289
|
} catch {
|
|
1741
2290
|
}
|
|
1742
2291
|
};
|
|
1743
|
-
var clampWidth = (width, vw) => Math.round(
|
|
1744
|
-
|
|
2292
|
+
var clampWidth = (width, vw) => Math.round(
|
|
2293
|
+
Math.min(Math.max(width, MIN_PANE), Math.max(MIN_PANE, vw - MIN_FORM))
|
|
2294
|
+
);
|
|
1745
2295
|
var Pane = styled2.aside`
|
|
1746
|
-
position: fixed;
|
|
1747
|
-
|
|
2296
|
+
position: fixed;
|
|
2297
|
+
top: 0;
|
|
2298
|
+
bottom: 0;
|
|
2299
|
+
z-index: 2;
|
|
2300
|
+
display: flex;
|
|
2301
|
+
flex-direction: column;
|
|
2302
|
+
background: ${({ theme }) => theme.colors.neutral0};
|
|
2303
|
+
border-left: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
1748
2304
|
box-shadow: ${({ theme }) => theme.shadows.popupShadow};
|
|
1749
2305
|
`;
|
|
1750
2306
|
function useMainRect() {
|
|
1751
|
-
const [rect, setRect] =
|
|
1752
|
-
|
|
2307
|
+
const [rect, setRect] = React4.useState(() => ({
|
|
2308
|
+
left: 0,
|
|
2309
|
+
width: window.innerWidth
|
|
2310
|
+
}));
|
|
2311
|
+
React4.useEffect(() => {
|
|
1753
2312
|
const main = document.getElementById("main-content");
|
|
1754
2313
|
const measure = () => {
|
|
1755
2314
|
const r = main?.getBoundingClientRect();
|
|
1756
|
-
setRect(
|
|
2315
|
+
setRect(
|
|
2316
|
+
r && r.width > 0 ? { left: Math.round(r.left), width: Math.round(r.width) } : { left: 0, width: window.innerWidth }
|
|
2317
|
+
);
|
|
1757
2318
|
};
|
|
1758
2319
|
measure();
|
|
1759
2320
|
const observer = main && "ResizeObserver" in window ? new ResizeObserver(measure) : null;
|
|
@@ -1767,12 +2328,37 @@ function useMainRect() {
|
|
|
1767
2328
|
return rect;
|
|
1768
2329
|
}
|
|
1769
2330
|
var Handle = styled2.div`
|
|
1770
|
-
position: absolute;
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
2331
|
+
position: absolute;
|
|
2332
|
+
top: 0;
|
|
2333
|
+
bottom: 0;
|
|
2334
|
+
left: -5px;
|
|
2335
|
+
width: 10px;
|
|
2336
|
+
cursor: col-resize;
|
|
2337
|
+
z-index: 3;
|
|
2338
|
+
touch-action: none;
|
|
2339
|
+
&::after {
|
|
2340
|
+
content: "";
|
|
2341
|
+
position: absolute;
|
|
2342
|
+
top: 0;
|
|
2343
|
+
bottom: 0;
|
|
2344
|
+
left: 4px;
|
|
2345
|
+
width: 2px;
|
|
2346
|
+
}
|
|
2347
|
+
&:hover::after,
|
|
2348
|
+
&[data-dragging="true"]::after,
|
|
2349
|
+
&:focus-visible::after {
|
|
2350
|
+
background: ${({ theme }) => theme.colors.primary600};
|
|
2351
|
+
}
|
|
2352
|
+
&:focus-visible {
|
|
2353
|
+
outline: none;
|
|
2354
|
+
}
|
|
2355
|
+
`;
|
|
2356
|
+
var Frame2 = styled2.iframe`
|
|
2357
|
+
flex: 1;
|
|
2358
|
+
width: 100%;
|
|
2359
|
+
border: 0;
|
|
2360
|
+
background: white;
|
|
1774
2361
|
`;
|
|
1775
|
-
var Frame2 = styled2.iframe` flex: 1; width: 100%; border: 0; background: white; `;
|
|
1776
2362
|
var SPLIT_STYLE = `
|
|
1777
2363
|
body.bp-split #main-content { padding-right: calc(var(--bp-pane, 50vw) + 1.6rem) !important; }
|
|
1778
2364
|
body.bp-split [data-bp-grid] { display: flex !important; flex-direction: column-reverse; gap: 1.6rem; }
|
|
@@ -1781,20 +2367,26 @@ body.bp-split [data-bp-panels] > div { flex-direction: row; flex-wrap: wrap; ali
|
|
|
1781
2367
|
body.bp-split [data-bp-panels] > div > * { flex: 1 1 24rem; }`;
|
|
1782
2368
|
var markLayout = (anchor) => {
|
|
1783
2369
|
let item = anchor;
|
|
1784
|
-
while (item?.parentElement && getComputedStyle(item.parentElement).display !== "grid")
|
|
2370
|
+
while (item?.parentElement && getComputedStyle(item.parentElement).display !== "grid")
|
|
2371
|
+
item = item.parentElement;
|
|
1785
2372
|
if (!item?.parentElement) return;
|
|
1786
2373
|
item.dataset.bpPanels = "";
|
|
1787
2374
|
item.parentElement.dataset.bpGrid = "";
|
|
1788
2375
|
};
|
|
1789
2376
|
function usePreviewBase(override, model, documentId, locale) {
|
|
1790
2377
|
const { get } = useFetchClient();
|
|
1791
|
-
const [native, setNative] =
|
|
1792
|
-
|
|
2378
|
+
const [native, setNative] = React4.useState(null);
|
|
2379
|
+
React4.useEffect(() => {
|
|
1793
2380
|
if (override || !model) return;
|
|
1794
2381
|
let active = true;
|
|
1795
|
-
const query = new URLSearchParams({
|
|
2382
|
+
const query = new URLSearchParams({
|
|
2383
|
+
status: "draft",
|
|
2384
|
+
...documentId ? { documentId } : {},
|
|
2385
|
+
...locale ? { locale } : {}
|
|
2386
|
+
});
|
|
1796
2387
|
get(`/content-manager/preview/url/${model}?${query}`).then(({ data }) => {
|
|
1797
|
-
if (active && typeof data?.data?.url === "string")
|
|
2388
|
+
if (active && typeof data?.data?.url === "string")
|
|
2389
|
+
setNative(`${new URL(data.data.url).origin}/block-preview/page`);
|
|
1798
2390
|
}).catch(() => {
|
|
1799
2391
|
if (active) setNative(null);
|
|
1800
2392
|
});
|
|
@@ -1804,55 +2396,109 @@ function usePreviewBase(override, model, documentId, locale) {
|
|
|
1804
2396
|
}, [get, model, documentId, locale, override]);
|
|
1805
2397
|
return override ? { base: override, source: "custom" } : native ? { base: native, source: "native" } : { base: null, source: "none" };
|
|
1806
2398
|
}
|
|
1807
|
-
function PickerDialog({ open, onOpenChange, trigger, title, children }) {
|
|
1808
|
-
return /* @__PURE__ */ jsxs3(Dialog.Root, { open, onOpenChange, children: [
|
|
1809
|
-
trigger && /* @__PURE__ */ jsx4(Dialog.Trigger, { children: trigger }),
|
|
1810
|
-
/* @__PURE__ */ jsxs3(Dialog.Content, { children: [
|
|
1811
|
-
/* @__PURE__ */ jsx4(Dialog.Header, { children: /* @__PURE__ */ jsx4(Dialog.Title, { children: title }) }),
|
|
1812
|
-
/* @__PURE__ */ jsx4(Dialog.Body, { children })
|
|
1813
|
-
] })
|
|
1814
|
-
] });
|
|
1815
|
-
}
|
|
1816
2399
|
var ACTION_TYPES = ["update", "publish"];
|
|
1817
|
-
var nativeButtons = () => document.querySelectorAll(
|
|
2400
|
+
var nativeButtons = () => document.querySelectorAll(
|
|
2401
|
+
'#main-content button:not([data-testid="page-preview-pane"] button)'
|
|
2402
|
+
);
|
|
1818
2403
|
function ToolbarActions({ model, collectionType, documentId, locale }) {
|
|
1819
|
-
const plugins = useStrapiApp2(
|
|
2404
|
+
const plugins = useStrapiApp2(
|
|
2405
|
+
"BlocksceneToolbar",
|
|
2406
|
+
(state) => state.plugins
|
|
2407
|
+
);
|
|
1820
2408
|
const [{ query }] = useQueryParams();
|
|
1821
|
-
const { document: doc, meta } = useDocument(
|
|
2409
|
+
const { document: doc, meta } = useDocument(
|
|
2410
|
+
{ model, collectionType, documentId, params: { locale } },
|
|
2411
|
+
{ skip: !documentId }
|
|
2412
|
+
);
|
|
1822
2413
|
const { toggleNotification } = useNotification();
|
|
1823
2414
|
const t = useMessages();
|
|
1824
2415
|
const descriptions = (plugins["content-manager"]?.apis?.getDocumentActions?.("panel") || []).filter((d) => ACTION_TYPES.includes(d.type));
|
|
1825
|
-
const props = {
|
|
2416
|
+
const props = {
|
|
2417
|
+
activeTab: query.status || "draft",
|
|
2418
|
+
model,
|
|
2419
|
+
documentId,
|
|
2420
|
+
document: doc,
|
|
2421
|
+
meta,
|
|
2422
|
+
collectionType
|
|
2423
|
+
};
|
|
1826
2424
|
const run = async (action, event) => {
|
|
1827
|
-
const native = [...nativeButtons()].find(
|
|
2425
|
+
const native = [...nativeButtons()].find(
|
|
2426
|
+
(b) => b.textContent?.trim() === action.label
|
|
2427
|
+
);
|
|
1828
2428
|
if (native) {
|
|
1829
2429
|
native.click();
|
|
1830
2430
|
return;
|
|
1831
2431
|
}
|
|
1832
2432
|
const mute = await action.onClick?.(event);
|
|
1833
|
-
if (action.dialog && !mute && action.dialog.type === "notification")
|
|
2433
|
+
if (action.dialog && !mute && action.dialog.type === "notification")
|
|
2434
|
+
toggleNotification({
|
|
2435
|
+
title: action.dialog.title,
|
|
2436
|
+
message: action.dialog.content,
|
|
2437
|
+
type: action.dialog.status
|
|
2438
|
+
});
|
|
1834
2439
|
};
|
|
1835
|
-
const typeOf = (action) => action.type || descriptions.find(
|
|
1836
|
-
|
|
2440
|
+
const typeOf = (action) => action.type || descriptions.find(
|
|
2441
|
+
(d) => typeof action.id === "string" && action.id.startsWith(`${d.name || d.displayName}-`)
|
|
2442
|
+
)?.type;
|
|
2443
|
+
return /* @__PURE__ */ jsx5(DescriptionComponentRenderer, { props, descriptions, children: (actions) => /* @__PURE__ */ jsx5(Flex3, { gap: 1, "data-testid": "page-preview-actions", children: [...actions].sort(
|
|
2444
|
+
(a, b) => ACTION_TYPES.indexOf(typeOf(a)) - ACTION_TYPES.indexOf(typeOf(b))
|
|
2445
|
+
).map((action) => {
|
|
1837
2446
|
const reason = action.disabled ? typeOf(action) === "publish" ? t.publishDisabledHint : t.saveDisabledHint : void 0;
|
|
1838
|
-
return /* @__PURE__ */
|
|
2447
|
+
return /* @__PURE__ */ jsx5("span", { title: reason, children: /* @__PURE__ */ jsx5(
|
|
2448
|
+
Button3,
|
|
2449
|
+
{
|
|
2450
|
+
size: "S",
|
|
2451
|
+
variant: action.variant || "default",
|
|
2452
|
+
disabled: action.disabled,
|
|
2453
|
+
loading: action.loading,
|
|
2454
|
+
"aria-description": reason,
|
|
2455
|
+
onClick: (e) => run(action, e),
|
|
2456
|
+
children: action.label
|
|
2457
|
+
}
|
|
2458
|
+
) }, action.id);
|
|
1839
2459
|
}) }) });
|
|
1840
2460
|
}
|
|
1841
|
-
function PagePreview({
|
|
2461
|
+
function PagePreview({
|
|
2462
|
+
editor,
|
|
2463
|
+
groups = null,
|
|
2464
|
+
Modal: Modal3,
|
|
2465
|
+
Toggle
|
|
2466
|
+
}) {
|
|
1842
2467
|
const t = useMessages();
|
|
1843
2468
|
const c = useContext();
|
|
1844
|
-
const rbac = useDocumentRBAC(
|
|
2469
|
+
const rbac = useDocumentRBAC(
|
|
2470
|
+
"BlockscenePagePreview",
|
|
2471
|
+
(state) => state
|
|
2472
|
+
);
|
|
1845
2473
|
const values = useForm2("BlockscenePagePreview", (state) => state.values);
|
|
1846
|
-
const onChange = useForm2(
|
|
1847
|
-
|
|
2474
|
+
const onChange = useForm2(
|
|
2475
|
+
"BlockscenePagePreview",
|
|
2476
|
+
(state) => state.onChange
|
|
2477
|
+
);
|
|
2478
|
+
const components = useStrapiApp2(
|
|
2479
|
+
"BlockscenePagePreview",
|
|
2480
|
+
(state) => state.components
|
|
2481
|
+
);
|
|
1848
2482
|
const MediaLibraryDialog = components?.["media-library"];
|
|
1849
|
-
const addFieldRow = useForm2(
|
|
2483
|
+
const addFieldRow = useForm2(
|
|
2484
|
+
"BlockscenePagePreview",
|
|
2485
|
+
(state) => state.addFieldRow
|
|
2486
|
+
);
|
|
2487
|
+
const moveFieldRow = useForm2(
|
|
2488
|
+
"BlockscenePagePreview",
|
|
2489
|
+
(state) => state.moveFieldRow
|
|
2490
|
+
);
|
|
1850
2491
|
const fields = c.layout?.edit?.layout?.flat(3) || [];
|
|
1851
2492
|
const readable = (name) => c.isCreatingEntry || (rbac.canReadFields || []).includes(name);
|
|
1852
|
-
const zone =
|
|
2493
|
+
const zone = React4.useMemo(
|
|
2494
|
+
() => editableZones(c.contentType, values, readable, c.isLoading)[0]?.name,
|
|
2495
|
+
[c.contentType, values, c.isLoading, rbac.canReadFields, c.isCreatingEntry]
|
|
2496
|
+
);
|
|
1853
2497
|
const zoneLabel = fields.find((field) => field.name === zone)?.label || zone || "";
|
|
1854
|
-
const canEdit = Boolean(
|
|
1855
|
-
|
|
2498
|
+
const canEdit = Boolean(
|
|
2499
|
+
zone && ((c.isCreatingEntry ? rbac.canCreateFields : rbac.canUpdateFields) || []).includes(zone) && fields.find((field) => field.name === zone)?.disabled !== true && !c.form?.disabled && typeof addFieldRow === "function"
|
|
2500
|
+
);
|
|
2501
|
+
const [mode, setModeState] = React4.useState(() => {
|
|
1856
2502
|
const v = read(MODE_KEY);
|
|
1857
2503
|
return v === "split" || v === "preview" ? v : editor?.previewMode || "form";
|
|
1858
2504
|
});
|
|
@@ -1860,32 +2506,37 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1860
2506
|
setModeState(next);
|
|
1861
2507
|
write(MODE_KEY, next);
|
|
1862
2508
|
};
|
|
1863
|
-
const [ratio, setRatio] =
|
|
2509
|
+
const [ratio, setRatio] = React4.useState(() => {
|
|
1864
2510
|
const v = Number(read(RATIO_KEY));
|
|
1865
2511
|
return v > 0 && v < 1 ? v : 0.5;
|
|
1866
2512
|
});
|
|
1867
2513
|
const main = useMainRect();
|
|
1868
2514
|
const vw = main.width;
|
|
1869
|
-
const [dragging, setDragging] =
|
|
1870
|
-
const [ready, setReady] =
|
|
1871
|
-
const [failed, setFailed] =
|
|
1872
|
-
const [attempt, retry] =
|
|
1873
|
-
const [picking, setPicking] =
|
|
1874
|
-
|
|
2515
|
+
const [dragging, setDragging] = React4.useState(false);
|
|
2516
|
+
const [ready, setReady] = React4.useState(false);
|
|
2517
|
+
const [failed, setFailed] = React4.useState(false);
|
|
2518
|
+
const [attempt, retry] = React4.useReducer((n) => n + 1, 0);
|
|
2519
|
+
const [picking, setPicking] = React4.useState(null);
|
|
2520
|
+
React4.useEffect(() => {
|
|
1875
2521
|
setEditing(null);
|
|
1876
2522
|
setPicking(null);
|
|
1877
2523
|
setInserting(null);
|
|
1878
2524
|
}, [c.id, c.form?.initialValues?.locale]);
|
|
1879
|
-
const [editing, setEditing] =
|
|
1880
|
-
const [inserting, setInserting] =
|
|
2525
|
+
const [editing, setEditing] = React4.useState(null);
|
|
2526
|
+
const [inserting, setInserting] = React4.useState(null);
|
|
1881
2527
|
const { get } = useFetchClient();
|
|
1882
2528
|
const { toggleNotification } = useNotification();
|
|
1883
2529
|
const zoneAttr = zone ? c.contentType?.attributes?.[zone] : null;
|
|
1884
|
-
const iframe =
|
|
1885
|
-
const loaded =
|
|
1886
|
-
const anchor =
|
|
1887
|
-
const channel =
|
|
1888
|
-
const { base, source } = usePreviewBase(
|
|
2530
|
+
const iframe = React4.useRef(null);
|
|
2531
|
+
const loaded = React4.useRef(false);
|
|
2532
|
+
const anchor = React4.useRef(null);
|
|
2533
|
+
const channel = React4.useMemo(() => crypto.randomUUID(), []);
|
|
2534
|
+
const { base, source } = usePreviewBase(
|
|
2535
|
+
editor?.previewUrl || "",
|
|
2536
|
+
c.model,
|
|
2537
|
+
c.isCreatingEntry ? void 0 : c.id,
|
|
2538
|
+
c.form?.initialValues?.locale
|
|
2539
|
+
);
|
|
1889
2540
|
const url = base ? new URL(base) : null;
|
|
1890
2541
|
url?.searchParams.set("channel", channel);
|
|
1891
2542
|
const origin = url?.origin || "";
|
|
@@ -1894,16 +2545,50 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1894
2545
|
const resizable = mode === "split" && !narrow;
|
|
1895
2546
|
const active = mode !== "form" && Boolean(url) && Boolean(zone);
|
|
1896
2547
|
const rows = zone && Array.isArray(values?.[zone]) ? values[zone] : [];
|
|
1897
|
-
const latest =
|
|
2548
|
+
const latest = React4.useRef(rows);
|
|
1898
2549
|
latest.current = rows;
|
|
1899
|
-
const
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
2550
|
+
const insertRows = (at, ...items) => items.forEach((item, i) => {
|
|
2551
|
+
const from = latest.current.length + i;
|
|
2552
|
+
addFieldRow(zone, item);
|
|
2553
|
+
if (at + i < from) moveFieldRow(zone, from, at + i);
|
|
2554
|
+
});
|
|
2555
|
+
const live = React4.useRef({
|
|
2556
|
+
mode,
|
|
2557
|
+
canEdit,
|
|
2558
|
+
zoneLabel,
|
|
2559
|
+
components: c.components,
|
|
2560
|
+
setMode,
|
|
2561
|
+
onChange
|
|
2562
|
+
});
|
|
2563
|
+
live.current = {
|
|
2564
|
+
mode,
|
|
2565
|
+
canEdit,
|
|
2566
|
+
zoneLabel,
|
|
2567
|
+
components: c.components,
|
|
2568
|
+
setMode,
|
|
2569
|
+
onChange
|
|
2570
|
+
};
|
|
2571
|
+
const send = React4.useCallback(() => {
|
|
2572
|
+
iframe.current?.contentWindow?.postMessage(
|
|
2573
|
+
{
|
|
2574
|
+
protocol: PROTOCOL,
|
|
2575
|
+
channel,
|
|
2576
|
+
type: "update-page",
|
|
2577
|
+
blocks: projectPage(
|
|
2578
|
+
latest.current,
|
|
2579
|
+
live.current.components,
|
|
2580
|
+
window.location.origin
|
|
2581
|
+
),
|
|
2582
|
+
groups,
|
|
2583
|
+
locale: t.locale,
|
|
2584
|
+
mode: live.current.mode
|
|
2585
|
+
},
|
|
2586
|
+
origin
|
|
2587
|
+
);
|
|
1903
2588
|
}, [channel, origin]);
|
|
1904
2589
|
const indexOf = (key) => latest.current.findIndex((row) => blockKey(row) === key);
|
|
1905
2590
|
const path = (key, field) => `${zone}.${indexOf(key)}.${field}`;
|
|
1906
|
-
|
|
2591
|
+
React4.useEffect(() => {
|
|
1907
2592
|
if (resizable) markLayout(anchor.current);
|
|
1908
2593
|
document.body.classList.toggle("bp-split", resizable);
|
|
1909
2594
|
document.documentElement.style.setProperty("--bp-pane", `${paneWidth}px`);
|
|
@@ -1915,7 +2600,9 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1915
2600
|
if (persist) write(RATIO_KEY, String(next));
|
|
1916
2601
|
};
|
|
1917
2602
|
const focusField = (index, field) => {
|
|
1918
|
-
const item = findZoneList(live.current.zoneLabel)?.querySelectorAll(
|
|
2603
|
+
const item = findZoneList(live.current.zoneLabel)?.querySelectorAll(
|
|
2604
|
+
":scope > li"
|
|
2605
|
+
)[index];
|
|
1919
2606
|
if (!item) return;
|
|
1920
2607
|
const header = toggles(item.parentElement)[index];
|
|
1921
2608
|
if (header?.getAttribute("aria-expanded") === "false") header.click();
|
|
@@ -1926,33 +2613,47 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1926
2613
|
if (++tries > 40) return clearInterval(timer);
|
|
1927
2614
|
let scope = item;
|
|
1928
2615
|
for (let i = 0; i + 1 < parts.length; i += 2) {
|
|
1929
|
-
const nested = [
|
|
2616
|
+
const nested = [
|
|
2617
|
+
...scope.querySelectorAll(
|
|
2618
|
+
"button[aria-expanded][data-radix-collection-item]"
|
|
2619
|
+
)
|
|
2620
|
+
].filter((b) => b !== header);
|
|
1930
2621
|
const row = nested[Number(parts[i + 1])];
|
|
1931
2622
|
if (!row) return;
|
|
1932
2623
|
if (row.getAttribute("aria-expanded") === "false") row.click();
|
|
1933
2624
|
scope = row.closest("li, div") || scope;
|
|
1934
2625
|
}
|
|
1935
|
-
const target = document.querySelector(
|
|
2626
|
+
const target = document.querySelector(
|
|
2627
|
+
`[name="${escaped}"], label[for="${escaped}"]`
|
|
2628
|
+
);
|
|
1936
2629
|
if (!target) return;
|
|
1937
2630
|
const INPUT = '.ck-editor__editable, textarea, input:not([type="hidden"]), select';
|
|
1938
2631
|
let container = target.matches(INPUT) ? target : target.parentElement;
|
|
1939
|
-
for (let depth = 0; container && depth < 4 && !container.matches(INPUT) && !container.querySelector(INPUT); depth++)
|
|
2632
|
+
for (let depth = 0; container && depth < 4 && !container.matches(INPUT) && !container.querySelector(INPUT); depth++)
|
|
2633
|
+
container = container.parentElement;
|
|
1940
2634
|
const editable = container?.matches(INPUT) ? container : container?.querySelector(INPUT);
|
|
1941
2635
|
if (!editable) return;
|
|
1942
|
-
if (editable.classList.contains("ck-editor__editable") && !editable.isContentEditable)
|
|
2636
|
+
if (editable.classList.contains("ck-editor__editable") && !editable.isContentEditable)
|
|
2637
|
+
return;
|
|
1943
2638
|
editable.focus();
|
|
1944
2639
|
if (document.activeElement !== editable) return;
|
|
1945
2640
|
clearInterval(timer);
|
|
1946
2641
|
editable.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
1947
2642
|
}, 150);
|
|
1948
2643
|
};
|
|
1949
|
-
|
|
2644
|
+
React4.useEffect(() => {
|
|
1950
2645
|
if (!active) return;
|
|
1951
2646
|
setReady(false);
|
|
1952
2647
|
setFailed(false);
|
|
1953
2648
|
const timeout = setTimeout(() => setFailed(true), 15e3);
|
|
1954
2649
|
const receive = (event) => {
|
|
1955
|
-
const is = (type) => isPreviewMessage(
|
|
2650
|
+
const is = (type) => isPreviewMessage(
|
|
2651
|
+
event,
|
|
2652
|
+
origin,
|
|
2653
|
+
iframe.current?.contentWindow,
|
|
2654
|
+
channel,
|
|
2655
|
+
type
|
|
2656
|
+
);
|
|
1956
2657
|
const { mode: mode2, canEdit: canEdit2, zoneLabel: zoneLabel2, components: components2, setMode: setMode2, onChange: onChange2 } = live.current;
|
|
1957
2658
|
if (is("ready")) {
|
|
1958
2659
|
clearTimeout(timeout);
|
|
@@ -1972,12 +2673,21 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1972
2673
|
return;
|
|
1973
2674
|
}
|
|
1974
2675
|
if (is("move-group") && canEdit2 && groups) {
|
|
1975
|
-
const next = (0, import_groups.moveGroup)(
|
|
2676
|
+
const next = (0, import_groups.moveGroup)(
|
|
2677
|
+
latest.current,
|
|
2678
|
+
String(event.data.key),
|
|
2679
|
+
event.data.direction === "up" ? "up" : "down",
|
|
2680
|
+
groups
|
|
2681
|
+
);
|
|
1976
2682
|
if (next) onChange2(zone, next);
|
|
1977
2683
|
return;
|
|
1978
2684
|
}
|
|
1979
2685
|
if (is("delete-group") && canEdit2 && groups) {
|
|
1980
|
-
const next = (0, import_groups.removeGroup)(
|
|
2686
|
+
const next = (0, import_groups.removeGroup)(
|
|
2687
|
+
latest.current,
|
|
2688
|
+
String(event.data.key),
|
|
2689
|
+
groups
|
|
2690
|
+
);
|
|
1981
2691
|
if (next) onChange2(zone, next);
|
|
1982
2692
|
return;
|
|
1983
2693
|
}
|
|
@@ -1987,13 +2697,20 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
1987
2697
|
const uid2 = String(event.data.uid || "");
|
|
1988
2698
|
const close = groups[uid2];
|
|
1989
2699
|
const allowed = zoneAttr?.components || [];
|
|
1990
|
-
if (index2 < 0 || !close || !allowed.includes(uid2) || !allowed.includes(close))
|
|
2700
|
+
if (index2 < 0 || !close || !allowed.includes(uid2) || !allowed.includes(close))
|
|
2701
|
+
return;
|
|
1991
2702
|
if (latest.current.length + 2 > (zoneAttr?.max ?? Infinity)) {
|
|
1992
2703
|
toggleNotification({ type: "info", message: t.zoneFull });
|
|
1993
2704
|
return;
|
|
1994
2705
|
}
|
|
1995
|
-
|
|
1996
|
-
|
|
2706
|
+
insertRows(
|
|
2707
|
+
index2,
|
|
2708
|
+
{
|
|
2709
|
+
...componentDefaults(components2[uid2], components2),
|
|
2710
|
+
__component: uid2
|
|
2711
|
+
},
|
|
2712
|
+
{ __component: close }
|
|
2713
|
+
);
|
|
1997
2714
|
return;
|
|
1998
2715
|
}
|
|
1999
2716
|
const key = typeof event.data?.key === "string" ? event.data.key : "";
|
|
@@ -2013,11 +2730,21 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2013
2730
|
}, 1500);
|
|
2014
2731
|
}
|
|
2015
2732
|
if (mode2 === "preview") setMode2("split");
|
|
2016
|
-
iframe.current?.contentWindow?.postMessage(
|
|
2733
|
+
iframe.current?.contentWindow?.postMessage(
|
|
2734
|
+
{ protocol: PROTOCOL, channel, type: "highlight", key },
|
|
2735
|
+
origin
|
|
2736
|
+
);
|
|
2017
2737
|
} else if (is("focus")) {
|
|
2018
2738
|
const attr = validateFocus(uid, event.data.field, components2);
|
|
2019
2739
|
if (!attr) return;
|
|
2020
|
-
if (mode2 === "preview" && canEdit2 && (attr.customField || MODAL_TYPES.includes(attr.type)))
|
|
2740
|
+
if (mode2 === "preview" && canEdit2 && (attr.customField || MODAL_TYPES.includes(attr.type)))
|
|
2741
|
+
setEditing({
|
|
2742
|
+
key,
|
|
2743
|
+
field: event.data.field,
|
|
2744
|
+
attr,
|
|
2745
|
+
label: `${components2[uid]?.info?.displayName || uid} \xB7 ${event.data.field}`,
|
|
2746
|
+
value: getIn(latest.current[index], event.data.field)
|
|
2747
|
+
});
|
|
2021
2748
|
else focusField(index, event.data.field);
|
|
2022
2749
|
} else if (is("media") && canEdit2) {
|
|
2023
2750
|
const attr = mediaAttribute(uid, event.data.field, components2);
|
|
@@ -2026,27 +2753,67 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2026
2753
|
const attr = mediaAttribute(uid, event.data.field, components2);
|
|
2027
2754
|
if (attr && !attr.required) onChange2(path(key, event.data.field), null);
|
|
2028
2755
|
} else if (is("edit") && canEdit2) {
|
|
2029
|
-
const value = validateEdit(
|
|
2756
|
+
const value = validateEdit(
|
|
2757
|
+
uid,
|
|
2758
|
+
event.data.field,
|
|
2759
|
+
event.data.value,
|
|
2760
|
+
components2
|
|
2761
|
+
);
|
|
2030
2762
|
if (value !== null) onChange2(path(key, event.data.field), value);
|
|
2031
2763
|
}
|
|
2032
2764
|
};
|
|
2033
2765
|
window.addEventListener("message", receive);
|
|
2034
|
-
if (loaded.current)
|
|
2766
|
+
if (loaded.current)
|
|
2767
|
+
iframe.current?.contentWindow?.postMessage(
|
|
2768
|
+
{ protocol: PROTOCOL, channel, type: "ping" },
|
|
2769
|
+
origin
|
|
2770
|
+
);
|
|
2035
2771
|
return () => {
|
|
2036
2772
|
clearTimeout(timeout);
|
|
2037
2773
|
window.removeEventListener("message", receive);
|
|
2038
2774
|
};
|
|
2039
2775
|
}, [active, attempt, channel, origin, groups]);
|
|
2040
|
-
|
|
2776
|
+
React4.useEffect(() => {
|
|
2041
2777
|
if (!ready || !active) return;
|
|
2042
2778
|
const timer = setTimeout(send, 120);
|
|
2043
2779
|
return () => clearTimeout(timer);
|
|
2044
2780
|
}, [values, c.components, ready, active, send, mode]);
|
|
2045
2781
|
if (!zone) return null;
|
|
2046
|
-
const modes = [
|
|
2047
|
-
|
|
2782
|
+
const modes = [
|
|
2783
|
+
["form", t.modeForm],
|
|
2784
|
+
["split", t.modeSplit],
|
|
2785
|
+
["preview", t.modePreview]
|
|
2786
|
+
];
|
|
2787
|
+
const switcher = /* @__PURE__ */ jsx5(
|
|
2788
|
+
Flex3,
|
|
2789
|
+
{
|
|
2790
|
+
gap: 1,
|
|
2791
|
+
wrap: "wrap",
|
|
2792
|
+
"data-testid": "page-preview-modes",
|
|
2793
|
+
role: "group",
|
|
2794
|
+
"aria-label": t.modeGroup,
|
|
2795
|
+
children: modes.map(([value, label]) => /* @__PURE__ */ jsx5(
|
|
2796
|
+
Button3,
|
|
2797
|
+
{
|
|
2798
|
+
type: "button",
|
|
2799
|
+
size: "S",
|
|
2800
|
+
variant: mode === value ? "default" : "tertiary",
|
|
2801
|
+
"aria-pressed": mode === value,
|
|
2802
|
+
onClick: () => setMode(value),
|
|
2803
|
+
disabled: !url && value !== "form",
|
|
2804
|
+
children: label
|
|
2805
|
+
},
|
|
2806
|
+
value
|
|
2807
|
+
))
|
|
2808
|
+
}
|
|
2809
|
+
);
|
|
2048
2810
|
const onKey = (event) => {
|
|
2049
|
-
const map = {
|
|
2811
|
+
const map = {
|
|
2812
|
+
ArrowLeft: paneWidth + KEY_STEP,
|
|
2813
|
+
ArrowRight: paneWidth - KEY_STEP,
|
|
2814
|
+
Home: MIN_PANE,
|
|
2815
|
+
End: vw - MIN_FORM
|
|
2816
|
+
};
|
|
2050
2817
|
if (event.key in map) {
|
|
2051
2818
|
event.preventDefault();
|
|
2052
2819
|
applyWidth(map[event.key], true);
|
|
@@ -2055,30 +2822,71 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2055
2822
|
const problems = groups ? (0, import_groups.validateGroups)(rows, groups) : [];
|
|
2056
2823
|
const insertClose = (error) => {
|
|
2057
2824
|
const end = (0, import_groups.groupRange)(latest.current, error.index, groups)[1];
|
|
2058
|
-
|
|
2825
|
+
insertRows(end + 1, { __component: error.expected });
|
|
2059
2826
|
};
|
|
2060
|
-
const diagnostics = problems.length > 0 && /* @__PURE__ */
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2827
|
+
const diagnostics = problems.length > 0 && /* @__PURE__ */ jsx5(
|
|
2828
|
+
Box2,
|
|
2829
|
+
{
|
|
2830
|
+
role: "alert",
|
|
2831
|
+
"data-testid": "page-preview-diagnostics",
|
|
2832
|
+
padding: 2,
|
|
2833
|
+
background: "danger100",
|
|
2834
|
+
hasRadius: true,
|
|
2835
|
+
children: /* @__PURE__ */ jsxs4("details", { children: [
|
|
2836
|
+
/* @__PURE__ */ jsx5("summary", { style: { cursor: "pointer" }, children: /* @__PURE__ */ jsx5(Typography3, { variant: "pi", fontWeight: "bold", textColor: "danger700", children: t.f("diagSummary", { count: problems.length }) }) }),
|
|
2837
|
+
/* @__PURE__ */ jsx5("ul", { style: { margin: "6px 0 0 16px", padding: 0 }, children: problems.map((error) => /* @__PURE__ */ jsxs4(
|
|
2838
|
+
"li",
|
|
2839
|
+
{
|
|
2840
|
+
style: { marginBottom: 6 },
|
|
2841
|
+
children: [
|
|
2842
|
+
/* @__PURE__ */ jsx5(Typography3, { variant: "pi", textColor: "danger700", children: t.f(
|
|
2843
|
+
error.code === "closeBeforeOpen" ? "diagCloseBeforeOpen" : error.code === "mismatch" ? "diagMismatch" : "diagUnclosed",
|
|
2844
|
+
{
|
|
2845
|
+
n: error.index + 1,
|
|
2846
|
+
uid: error.uid,
|
|
2847
|
+
open: error.open || "",
|
|
2848
|
+
expected: error.expected || ""
|
|
2849
|
+
}
|
|
2850
|
+
) }),
|
|
2851
|
+
error.code === "unclosed" && canEdit && /* @__PURE__ */ jsx5(Box2, { paddingTop: 1, children: /* @__PURE__ */ jsx5(
|
|
2852
|
+
Button3,
|
|
2853
|
+
{
|
|
2854
|
+
size: "S",
|
|
2855
|
+
variant: "danger-light",
|
|
2856
|
+
"data-testid": `diag-insert-close-${error.index}`,
|
|
2857
|
+
onClick: () => insertClose(error),
|
|
2858
|
+
children: t.f("diagInsertClose", {
|
|
2859
|
+
n: error.index + 1,
|
|
2860
|
+
expected: error.expected
|
|
2861
|
+
})
|
|
2862
|
+
}
|
|
2863
|
+
) }),
|
|
2864
|
+
error.code === "closeBeforeOpen" && /* @__PURE__ */ jsx5(Typography3, { variant: "pi", textColor: "neutral600", children: t.diagStrayHint })
|
|
2865
|
+
]
|
|
2866
|
+
},
|
|
2867
|
+
`${error.code}-${error.index}`
|
|
2868
|
+
)) })
|
|
2869
|
+
] })
|
|
2870
|
+
}
|
|
2871
|
+
);
|
|
2872
|
+
return /* @__PURE__ */ jsxs4(Flex3, { direction: "column", alignItems: "stretch", gap: 2, ref: anchor, children: [
|
|
2069
2873
|
switcher,
|
|
2070
2874
|
diagnostics,
|
|
2071
|
-
/* @__PURE__ */
|
|
2072
|
-
active &&
|
|
2073
|
-
/* @__PURE__ */
|
|
2875
|
+
/* @__PURE__ */ jsx5(Typography3, { variant: "pi", textColor: "neutral600", children: url ? t.previewHelp : t.previewNoUrl }),
|
|
2876
|
+
active && createPortal2(
|
|
2877
|
+
/* @__PURE__ */ jsxs4(
|
|
2074
2878
|
Pane,
|
|
2075
2879
|
{
|
|
2076
2880
|
"data-testid": "page-preview-pane",
|
|
2077
2881
|
"aria-label": t.previewPane,
|
|
2078
|
-
style: {
|
|
2882
|
+
style: {
|
|
2883
|
+
left: mode === "preview" || narrow ? main.left : main.left + main.width - paneWidth,
|
|
2884
|
+
width: mode === "preview" || narrow ? main.width : paneWidth,
|
|
2885
|
+
userSelect: dragging ? "none" : void 0
|
|
2886
|
+
},
|
|
2079
2887
|
children: [
|
|
2080
|
-
/* @__PURE__ */
|
|
2081
|
-
resizable && /* @__PURE__ */
|
|
2888
|
+
/* @__PURE__ */ jsx5("style", { children: SPLIT_STYLE }),
|
|
2889
|
+
resizable && /* @__PURE__ */ jsx5(
|
|
2082
2890
|
Handle,
|
|
2083
2891
|
{
|
|
2084
2892
|
role: "separator",
|
|
@@ -2096,7 +2904,8 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2096
2904
|
setDragging(true);
|
|
2097
2905
|
},
|
|
2098
2906
|
onPointerMove: (e) => {
|
|
2099
|
-
if (dragging)
|
|
2907
|
+
if (dragging)
|
|
2908
|
+
applyWidth(main.left + main.width - e.clientX, false);
|
|
2100
2909
|
},
|
|
2101
2910
|
onPointerUp: (e) => {
|
|
2102
2911
|
if (!dragging) return;
|
|
@@ -2108,15 +2917,44 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2108
2917
|
onKeyDown: onKey
|
|
2109
2918
|
}
|
|
2110
2919
|
),
|
|
2111
|
-
/* @__PURE__ */
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2920
|
+
/* @__PURE__ */ jsxs4(
|
|
2921
|
+
Flex3,
|
|
2922
|
+
{
|
|
2923
|
+
padding: 2,
|
|
2924
|
+
gap: 2,
|
|
2925
|
+
justifyContent: "space-between",
|
|
2926
|
+
alignItems: "center",
|
|
2927
|
+
background: "neutral100",
|
|
2928
|
+
wrap: "wrap",
|
|
2929
|
+
style: { position: "sticky", top: 0, zIndex: 2 },
|
|
2930
|
+
children: [
|
|
2931
|
+
switcher,
|
|
2932
|
+
/* @__PURE__ */ jsxs4(
|
|
2933
|
+
Flex3,
|
|
2934
|
+
{
|
|
2935
|
+
gap: 2,
|
|
2936
|
+
alignItems: "center",
|
|
2937
|
+
wrap: "wrap",
|
|
2938
|
+
style: { marginLeft: "auto" },
|
|
2939
|
+
children: [
|
|
2940
|
+
/* @__PURE__ */ jsx5(Typography3, { variant: "pi", role: "status", textColor: "neutral600", children: failed ? t.previewFailed : ready ? t.previewReady : t.previewLoading }),
|
|
2941
|
+
failed && /* @__PURE__ */ jsx5(Button3, { size: "S", variant: "secondary", onClick: retry, children: t.retry }),
|
|
2942
|
+
/* @__PURE__ */ jsx5(
|
|
2943
|
+
ToolbarActions,
|
|
2944
|
+
{
|
|
2945
|
+
model: c.model,
|
|
2946
|
+
collectionType: c.collectionType,
|
|
2947
|
+
documentId: c.isCreatingEntry ? void 0 : c.id,
|
|
2948
|
+
locale: c.form?.initialValues?.locale
|
|
2949
|
+
}
|
|
2950
|
+
)
|
|
2951
|
+
]
|
|
2952
|
+
}
|
|
2953
|
+
)
|
|
2954
|
+
]
|
|
2955
|
+
}
|
|
2956
|
+
),
|
|
2957
|
+
/* @__PURE__ */ jsx5(
|
|
2120
2958
|
Frame2,
|
|
2121
2959
|
{
|
|
2122
2960
|
ref: iframe,
|
|
@@ -2136,12 +2974,16 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2136
2974
|
),
|
|
2137
2975
|
document.body
|
|
2138
2976
|
),
|
|
2139
|
-
inserting && zoneAttr && /* @__PURE__ */
|
|
2977
|
+
inserting && zoneAttr && /* @__PURE__ */ jsx5(
|
|
2140
2978
|
PickerModal,
|
|
2141
2979
|
{
|
|
2142
|
-
zone: {
|
|
2980
|
+
zone: {
|
|
2981
|
+
name: zone,
|
|
2982
|
+
components: zoneAttr.components || [],
|
|
2983
|
+
max: zoneAttr.max
|
|
2984
|
+
},
|
|
2143
2985
|
components: c.components,
|
|
2144
|
-
Modal:
|
|
2986
|
+
Modal: Modal3,
|
|
2145
2987
|
Toggle,
|
|
2146
2988
|
get,
|
|
2147
2989
|
open: true,
|
|
@@ -2153,15 +2995,24 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2153
2995
|
setInserting(null);
|
|
2154
2996
|
const close = groups?.[uid];
|
|
2155
2997
|
if (index < 0 || !(zoneAttr.components || []).includes(uid) || close && !(zoneAttr.components || []).includes(close) || latest.current.length + (close ? 2 : 1) > (zoneAttr.max ?? Infinity)) {
|
|
2156
|
-
toggleNotification({
|
|
2998
|
+
toggleNotification({
|
|
2999
|
+
type: "warning",
|
|
3000
|
+
message: close ? t.zoneFull : t.insertMoved
|
|
3001
|
+
});
|
|
2157
3002
|
return;
|
|
2158
3003
|
}
|
|
2159
|
-
|
|
2160
|
-
|
|
3004
|
+
insertRows(
|
|
3005
|
+
index,
|
|
3006
|
+
{
|
|
3007
|
+
...componentDefaults(c.components[uid], c.components),
|
|
3008
|
+
__component: uid
|
|
3009
|
+
},
|
|
3010
|
+
...close ? [{ __component: close }] : []
|
|
3011
|
+
);
|
|
2161
3012
|
}
|
|
2162
3013
|
}
|
|
2163
3014
|
),
|
|
2164
|
-
editing && /* @__PURE__ */
|
|
3015
|
+
editing && /* @__PURE__ */ jsx5(
|
|
2165
3016
|
FieldEditorModal,
|
|
2166
3017
|
{
|
|
2167
3018
|
label: editing.label,
|
|
@@ -2171,11 +3022,12 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2171
3022
|
onApply: (value) => {
|
|
2172
3023
|
const index = indexOf(editing.key);
|
|
2173
3024
|
setEditing(null);
|
|
2174
|
-
if (index >= 0)
|
|
3025
|
+
if (index >= 0)
|
|
3026
|
+
onChange(`${zone}.${index}.${editing.field}`, value);
|
|
2175
3027
|
}
|
|
2176
3028
|
}
|
|
2177
3029
|
),
|
|
2178
|
-
picking && MediaLibraryDialog && /* @__PURE__ */
|
|
3030
|
+
picking && MediaLibraryDialog && /* @__PURE__ */ jsx5(
|
|
2179
3031
|
MediaLibraryDialog,
|
|
2180
3032
|
{
|
|
2181
3033
|
allowedTypes: picking.attr.allowedTypes || ["images"],
|
|
@@ -2186,19 +3038,32 @@ function PagePreview({ editor, groups = null, Toggle }) {
|
|
|
2186
3038
|
setPicking(null);
|
|
2187
3039
|
if (index < 0 || !assets?.length) return;
|
|
2188
3040
|
const current = getIn(latest.current[index], picking.field);
|
|
2189
|
-
onChange(
|
|
3041
|
+
onChange(
|
|
3042
|
+
`${zone}.${index}.${picking.field}`,
|
|
3043
|
+
picking.attr.multiple ? [...Array.isArray(current) ? current : [], ...assets] : assets[0]
|
|
3044
|
+
);
|
|
2190
3045
|
}
|
|
2191
3046
|
}
|
|
2192
3047
|
),
|
|
2193
|
-
/* @__PURE__ */
|
|
3048
|
+
/* @__PURE__ */ jsx5(
|
|
3049
|
+
Box2,
|
|
3050
|
+
{
|
|
3051
|
+
hidden: true,
|
|
3052
|
+
"data-testid": "page-preview-state",
|
|
3053
|
+
"data-mode": mode,
|
|
3054
|
+
"data-ready": ready,
|
|
3055
|
+
"data-failed": failed,
|
|
3056
|
+
"data-preview-source": source
|
|
3057
|
+
}
|
|
3058
|
+
)
|
|
2194
3059
|
] });
|
|
2195
3060
|
}
|
|
2196
3061
|
|
|
2197
3062
|
// admin/Settings.tsx
|
|
2198
|
-
import * as
|
|
3063
|
+
import * as React5 from "react";
|
|
2199
3064
|
import { Box as Box3, Button as Button4, Flex as Flex4, Searchbar as Searchbar2, Typography as Typography4 } from "@strapi/design-system";
|
|
2200
3065
|
import styled3 from "styled-components";
|
|
2201
|
-
import { Fragment, jsx as
|
|
3066
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2202
3067
|
var COLOR2 = /^#[0-9A-Fa-f]{6}$/;
|
|
2203
3068
|
var Grid = styled3.div` display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 16px; `;
|
|
2204
3069
|
var Card2 = styled3.div`
|
|
@@ -2211,8 +3076,8 @@ var Bar = styled3.div`
|
|
|
2211
3076
|
box-shadow: 0 1px 4px rgba(33, 33, 52, 0.1);
|
|
2212
3077
|
`;
|
|
2213
3078
|
function useMainRect2(anchor) {
|
|
2214
|
-
const [rect, setRect] =
|
|
2215
|
-
|
|
3079
|
+
const [rect, setRect] = React5.useState({ left: 0, width: 0 });
|
|
3080
|
+
React5.useEffect(() => {
|
|
2216
3081
|
const read2 = () => {
|
|
2217
3082
|
let host = document.getElementById("main-content");
|
|
2218
3083
|
for (let el = anchor.current?.parentElement; !host && el; el = el.parentElement) if (["auto", "scroll"].includes(getComputedStyle(el).overflowY) && el.scrollHeight > el.clientHeight) host = el;
|
|
@@ -2229,11 +3094,11 @@ var Swatches = styled3.div` display: grid; grid-template-columns: repeat(auto-fi
|
|
|
2229
3094
|
var Label = styled3.label` display: flex; flex-direction: column; gap: 4px; font-size: 12px; `;
|
|
2230
3095
|
function ColorField({ name, label, value, onChange, disabled }) {
|
|
2231
3096
|
const valid = COLOR2.test(value);
|
|
2232
|
-
return /* @__PURE__ */
|
|
2233
|
-
/* @__PURE__ */
|
|
2234
|
-
/* @__PURE__ */
|
|
2235
|
-
/* @__PURE__ */
|
|
2236
|
-
/* @__PURE__ */
|
|
3097
|
+
return /* @__PURE__ */ jsxs5(Label, { children: [
|
|
3098
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
|
|
3099
|
+
/* @__PURE__ */ jsxs5(Flex4, { gap: 2, children: [
|
|
3100
|
+
/* @__PURE__ */ jsx6("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" } }),
|
|
3101
|
+
/* @__PURE__ */ jsx6(
|
|
2237
3102
|
"input",
|
|
2238
3103
|
{
|
|
2239
3104
|
name,
|
|
@@ -2253,18 +3118,18 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2253
3118
|
const t = useMessages();
|
|
2254
3119
|
const { get, put } = useClient();
|
|
2255
3120
|
const { canRead, canUpdate, isLoading } = usePermissions2();
|
|
2256
|
-
const [data, setData] =
|
|
2257
|
-
const [catalog, setCatalog] =
|
|
2258
|
-
const [settings, setSettings] =
|
|
2259
|
-
const [media, setMedia] =
|
|
2260
|
-
const [sources, setSources] =
|
|
2261
|
-
const [dirty, setDirty] =
|
|
2262
|
-
const [saving, setSaving] =
|
|
2263
|
-
const [status, setStatus] =
|
|
2264
|
-
const [failed, setFailed] =
|
|
2265
|
-
const [filter, setFilter] =
|
|
2266
|
-
const [picking, setPicking] =
|
|
2267
|
-
|
|
3121
|
+
const [data, setData] = React5.useState(null);
|
|
3122
|
+
const [catalog, setCatalog] = React5.useState(null);
|
|
3123
|
+
const [settings, setSettings] = React5.useState(null);
|
|
3124
|
+
const [media, setMedia] = React5.useState({});
|
|
3125
|
+
const [sources, setSources] = React5.useState({});
|
|
3126
|
+
const [dirty, setDirty] = React5.useState(false);
|
|
3127
|
+
const [saving, setSaving] = React5.useState(false);
|
|
3128
|
+
const [status, setStatus] = React5.useState("");
|
|
3129
|
+
const [failed, setFailed] = React5.useState(false);
|
|
3130
|
+
const [filter, setFilter] = React5.useState("");
|
|
3131
|
+
const [picking, setPicking] = React5.useState(null);
|
|
3132
|
+
React5.useEffect(() => {
|
|
2268
3133
|
if (!canRead || isLoading) return;
|
|
2269
3134
|
let active = true;
|
|
2270
3135
|
Promise.all([get("/blockscene/settings"), get("/blockscene/catalog")]).then(([s, c]) => {
|
|
@@ -2312,35 +3177,35 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2312
3177
|
return index === 0 && manual ? t.manual : t.automatic;
|
|
2313
3178
|
};
|
|
2314
3179
|
const ready = !isLoading && canRead && !failed && settings && catalog;
|
|
2315
|
-
const header =
|
|
2316
|
-
const [floating, setFloating] =
|
|
3180
|
+
const header = React5.useRef(null);
|
|
3181
|
+
const [floating, setFloating] = React5.useState(false);
|
|
2317
3182
|
const main = useMainRect2(header);
|
|
2318
|
-
|
|
3183
|
+
React5.useEffect(() => {
|
|
2319
3184
|
const el = header.current;
|
|
2320
3185
|
if (!el || typeof IntersectionObserver === "undefined") return;
|
|
2321
3186
|
const observer = new IntersectionObserver(([entry]) => setFloating(!entry.isIntersecting && entry.boundingClientRect.top < 0));
|
|
2322
3187
|
observer.observe(el);
|
|
2323
3188
|
return () => observer.disconnect();
|
|
2324
3189
|
}, [ready]);
|
|
2325
|
-
const controls = (suffix) => ready && /* @__PURE__ */
|
|
2326
|
-
/* @__PURE__ */
|
|
2327
|
-
/* @__PURE__ */
|
|
3190
|
+
const controls = (suffix) => ready && /* @__PURE__ */ jsxs5(Flex4, { gap: 3, alignItems: "center", wrap: "wrap", children: [
|
|
3191
|
+
/* @__PURE__ */ jsx6(Typography4, { role: "status", "aria-live": "polite", textColor: dirty ? "warning700" : "neutral600", "data-testid": `${dirty ? "unsaved-indicator" : "save-status"}${suffix}`, children: dirty ? t.unsaved : status || t.noChanges }),
|
|
3192
|
+
/* @__PURE__ */ jsx6(Button4, { onClick: save, disabled: !canUpdate || invalid || !dirty, loading: saving, "data-testid": `save-blockscene-settings${suffix}`, children: t.save })
|
|
2328
3193
|
] });
|
|
2329
|
-
return /* @__PURE__ */
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
/* @__PURE__ */
|
|
3194
|
+
return /* @__PURE__ */ jsx6(Box3, { padding: 8, background: "neutral100", children: /* @__PURE__ */ jsxs5(Flex4, { direction: "column", alignItems: "stretch", gap: 5, children: [
|
|
3195
|
+
/* @__PURE__ */ jsx6("div", { ref: header, children: /* @__PURE__ */ jsxs5(Flex4, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
|
|
3196
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "alpha", tag: "h1", children: t.settingsTitle }),
|
|
2332
3197
|
controls("")
|
|
2333
3198
|
] }) }),
|
|
2334
|
-
floating && main.width > 0 && /* @__PURE__ */
|
|
2335
|
-
/* @__PURE__ */
|
|
3199
|
+
floating && main.width > 0 && /* @__PURE__ */ jsx6(Bar, { style: { left: main.left, width: main.width }, "data-testid": "settings-floating-bar", children: /* @__PURE__ */ jsxs5(Flex4, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
|
|
3200
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "beta", tag: "p", children: t.settingsTitle }),
|
|
2336
3201
|
controls("-floating")
|
|
2337
3202
|
] }) }),
|
|
2338
|
-
/* @__PURE__ */
|
|
2339
|
-
isLoading ? /* @__PURE__ */
|
|
2340
|
-
data.disabled && /* @__PURE__ */
|
|
2341
|
-
/* @__PURE__ */
|
|
2342
|
-
/* @__PURE__ */
|
|
2343
|
-
/* @__PURE__ */
|
|
3203
|
+
/* @__PURE__ */ jsx6(Typography4, { textColor: "neutral600", children: t.settingsIntro }),
|
|
3204
|
+
isLoading ? /* @__PURE__ */ jsx6(Typography4, { children: "\u2026" }) : !canRead ? /* @__PURE__ */ jsx6(Typography4, { role: "alert", children: t.denied }) : failed ? /* @__PURE__ */ jsx6(Typography4, { role: "alert", children: t.loadFailed }) : !settings || !catalog ? /* @__PURE__ */ jsx6(Typography4, { children: t.loading }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
3205
|
+
data.disabled && /* @__PURE__ */ jsx6(Box3, { padding: 4, background: "warning100", hasRadius: true, children: /* @__PURE__ */ jsx6(Typography4, { role: "alert", textColor: "warning700", children: t.disabledByServer }) }),
|
|
3206
|
+
/* @__PURE__ */ jsx6(Box3, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs5(Flex4, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
3207
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "beta", tag: "h2", children: t.palette }),
|
|
3208
|
+
/* @__PURE__ */ jsx6(Swatches, { children: Object.keys(DEFAULT_PALETTE).map((key) => /* @__PURE__ */ jsx6(
|
|
2344
3209
|
ColorField,
|
|
2345
3210
|
{
|
|
2346
3211
|
name: `palette-${key}`,
|
|
@@ -2354,33 +3219,33 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2354
3219
|
},
|
|
2355
3220
|
key
|
|
2356
3221
|
)) }),
|
|
2357
|
-
invalid && /* @__PURE__ */
|
|
2358
|
-
/* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2360
|
-
/* @__PURE__ */
|
|
2361
|
-
/* @__PURE__ */
|
|
3222
|
+
invalid && /* @__PURE__ */ jsx6(Typography4, { role: "alert", textColor: "danger600", children: t.invalidColor }),
|
|
3223
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "pi", textColor: "neutral600", children: t.previewLabel }),
|
|
3224
|
+
/* @__PURE__ */ jsx6(Swatches, { "data-testid": "palette-preview", children: TEMPLATES.map((template) => /* @__PURE__ */ jsxs5(Flex4, { direction: "column", gap: 1, children: [
|
|
3225
|
+
/* @__PURE__ */ jsx6(Box3, { style: { aspectRatio: "16 / 9", overflow: "hidden" }, hasRadius: true, children: /* @__PURE__ */ jsx6(Wireframe, { template, palette: settings.palette }) }),
|
|
3226
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "pi", textColor: "neutral600", children: t.templates[template] })
|
|
2362
3227
|
] }, template)) }),
|
|
2363
|
-
/* @__PURE__ */
|
|
3228
|
+
/* @__PURE__ */ jsx6(Flex4, { children: /* @__PURE__ */ jsx6(Button4, { variant: "tertiary", size: "S", disabled: !canUpdate, onClick: () => update((s) => {
|
|
2364
3229
|
s.palette = { ...DEFAULT_PALETTE };
|
|
2365
3230
|
return s;
|
|
2366
3231
|
}), children: t.resetPalette }) })
|
|
2367
3232
|
] }) }),
|
|
2368
|
-
/* @__PURE__ */
|
|
2369
|
-
/* @__PURE__ */
|
|
2370
|
-
/* @__PURE__ */
|
|
3233
|
+
/* @__PURE__ */ jsx6(Box3, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs5(Flex4, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
3234
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "beta", tag: "h2", children: t.editor }),
|
|
3235
|
+
/* @__PURE__ */ jsx6(ToggleField2, { name: "editor-enabled", label: t.enabled, value: editor.enabled, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
2371
3236
|
s.editor.enabled = v;
|
|
2372
3237
|
return s;
|
|
2373
3238
|
}) }),
|
|
2374
|
-
/* @__PURE__ */
|
|
2375
|
-
/* @__PURE__ */
|
|
3239
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "pi", textColor: "neutral600", children: t.enabledHelp }),
|
|
3240
|
+
/* @__PURE__ */ jsx6(ToggleField2, { name: "editor-showOpenAll", label: t.showOpenAll, value: editor.showOpenAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
2376
3241
|
s.editor.showOpenAll = v;
|
|
2377
3242
|
return s;
|
|
2378
3243
|
}) }),
|
|
2379
|
-
/* @__PURE__ */
|
|
3244
|
+
/* @__PURE__ */ jsx6(ToggleField2, { name: "editor-showCloseAll", label: t.showCloseAll, value: editor.showCloseAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
2380
3245
|
s.editor.showCloseAll = v;
|
|
2381
3246
|
return s;
|
|
2382
3247
|
}) }),
|
|
2383
|
-
/* @__PURE__ */
|
|
3248
|
+
/* @__PURE__ */ jsx6(
|
|
2384
3249
|
SelectField2,
|
|
2385
3250
|
{
|
|
2386
3251
|
name: "editor-initialState",
|
|
@@ -2394,9 +3259,9 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2394
3259
|
})
|
|
2395
3260
|
}
|
|
2396
3261
|
),
|
|
2397
|
-
/* @__PURE__ */
|
|
2398
|
-
previewSupported ? /* @__PURE__ */
|
|
2399
|
-
/* @__PURE__ */
|
|
3262
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "pi", textColor: "neutral600", children: t.rememberHelp }),
|
|
3263
|
+
previewSupported ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
3264
|
+
/* @__PURE__ */ jsx6(
|
|
2400
3265
|
TextField2,
|
|
2401
3266
|
{
|
|
2402
3267
|
name: "editor-previewUrl",
|
|
@@ -2410,8 +3275,8 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2410
3275
|
})
|
|
2411
3276
|
}
|
|
2412
3277
|
),
|
|
2413
|
-
/* @__PURE__ */
|
|
2414
|
-
/* @__PURE__ */
|
|
3278
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "pi", textColor: "neutral600", children: t.previewUrlHelp }),
|
|
3279
|
+
/* @__PURE__ */ jsx6(
|
|
2415
3280
|
SelectField2,
|
|
2416
3281
|
{
|
|
2417
3282
|
name: "editor-previewMode",
|
|
@@ -2425,26 +3290,26 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2425
3290
|
})
|
|
2426
3291
|
}
|
|
2427
3292
|
),
|
|
2428
|
-
/* @__PURE__ */
|
|
2429
|
-
data.blockPreviewAvailable && /* @__PURE__ */
|
|
2430
|
-
/* @__PURE__ */
|
|
3293
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "pi", textColor: "neutral600", children: t.previewModeHelp }),
|
|
3294
|
+
data.blockPreviewAvailable && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
3295
|
+
/* @__PURE__ */ jsx6(ToggleField2, { name: "editor-blockPreviewInForm", label: t.blockPreviewInForm, value: editor.blockPreviewInForm, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
|
|
2431
3296
|
s.editor.blockPreviewInForm = v;
|
|
2432
3297
|
return s;
|
|
2433
3298
|
}) }),
|
|
2434
|
-
/* @__PURE__ */
|
|
3299
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
|
|
2435
3300
|
] })
|
|
2436
|
-
] }) : /* @__PURE__ */
|
|
3301
|
+
] }) : /* @__PURE__ */ jsx6(Typography4, { variant: "pi", textColor: "neutral600", children: t.previewV4 })
|
|
2437
3302
|
] }) }),
|
|
2438
|
-
/* @__PURE__ */
|
|
2439
|
-
/* @__PURE__ */
|
|
2440
|
-
/* @__PURE__ */
|
|
2441
|
-
/* @__PURE__ */
|
|
2442
|
-
/* @__PURE__ */
|
|
3303
|
+
/* @__PURE__ */ jsx6(Box3, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs5(Flex4, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
3304
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "beta", tag: "h2", children: t.components }),
|
|
3305
|
+
/* @__PURE__ */ jsx6(Searchbar2, { name: "component-filter", value: filter, placeholder: t.filter, clearLabel: t.clear, onClear: () => setFilter(""), onChange: (e) => setFilter(e.target.value), children: t.filter }),
|
|
3306
|
+
/* @__PURE__ */ jsx6(Typography4, { variant: "pi", textColor: "neutral600", "data-testid": "components-count", children: t.f("countAll", { count: components.length }) }),
|
|
3307
|
+
/* @__PURE__ */ jsx6(Grid, { "data-testid": "components-grid", children: components.map((component) => {
|
|
2443
3308
|
const entry = settings.components[component.uid] || {};
|
|
2444
3309
|
const meta = { ...catalog.components?.[component.uid] || {}, ...media[component.uid] || {} };
|
|
2445
3310
|
const candidates = candidatesFor(component.uid, meta, catalog);
|
|
2446
|
-
return /* @__PURE__ */
|
|
2447
|
-
/* @__PURE__ */
|
|
3311
|
+
return /* @__PURE__ */ jsxs5(Card2, { "data-testid": `settings-${component.uid}`, children: [
|
|
3312
|
+
/* @__PURE__ */ jsx6(
|
|
2448
3313
|
Thumb,
|
|
2449
3314
|
{
|
|
2450
3315
|
candidates,
|
|
@@ -2455,23 +3320,23 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2455
3320
|
onResolved: (index) => setSources((current) => current[component.uid] === index ? current : { ...current, [component.uid]: index })
|
|
2456
3321
|
}
|
|
2457
3322
|
),
|
|
2458
|
-
/* @__PURE__ */
|
|
2459
|
-
/* @__PURE__ */
|
|
2460
|
-
/* @__PURE__ */
|
|
3323
|
+
/* @__PURE__ */ jsxs5(Flex4, { direction: "column", alignItems: "flex-start", gap: 2, children: [
|
|
3324
|
+
/* @__PURE__ */ jsx6(Typography4, { fontWeight: "bold", textColor: "neutral800", children: component.displayName }),
|
|
3325
|
+
/* @__PURE__ */ jsxs5(Typography4, { variant: "pi", textColor: "neutral600", children: [
|
|
2461
3326
|
component.uid,
|
|
2462
3327
|
" \xB7 ",
|
|
2463
3328
|
component.category
|
|
2464
3329
|
] }),
|
|
2465
|
-
/* @__PURE__ */
|
|
3330
|
+
/* @__PURE__ */ jsxs5(Typography4, { variant: "pi", "data-testid": `source-${component.uid}`, children: [
|
|
2466
3331
|
t.source,
|
|
2467
3332
|
": ",
|
|
2468
3333
|
sourceOf(component.uid, Boolean(meta.manualImage)),
|
|
2469
3334
|
meta.manualName ? ` (${meta.manualName})` : ""
|
|
2470
3335
|
] }),
|
|
2471
|
-
meta.manualMissing && /* @__PURE__ */
|
|
2472
|
-
/* @__PURE__ */
|
|
2473
|
-
/* @__PURE__ */
|
|
2474
|
-
entry.mediaId && /* @__PURE__ */
|
|
3336
|
+
meta.manualMissing && /* @__PURE__ */ jsx6(Typography4, { variant: "pi", role: "alert", textColor: "danger600", children: t.brokenMedia }),
|
|
3337
|
+
/* @__PURE__ */ jsxs5(Flex4, { gap: 2, wrap: "wrap", children: [
|
|
3338
|
+
/* @__PURE__ */ jsx6(Button4, { variant: "secondary", size: "S", disabled: !canUpdate || saving, onClick: () => setPicking(component.uid), children: entry.mediaId ? t.replace : t.choose }),
|
|
3339
|
+
entry.mediaId && /* @__PURE__ */ jsx6(Button4, { variant: "tertiary", size: "S", disabled: !canUpdate || saving, onClick: () => {
|
|
2475
3340
|
update((s) => {
|
|
2476
3341
|
delete s.components[component.uid]?.mediaId;
|
|
2477
3342
|
if (!Object.keys(s.components[component.uid] || {}).length) delete s.components[component.uid];
|
|
@@ -2484,7 +3349,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2484
3349
|
});
|
|
2485
3350
|
}, children: t.useAutomatic })
|
|
2486
3351
|
] }),
|
|
2487
|
-
/* @__PURE__ */
|
|
3352
|
+
/* @__PURE__ */ jsx6(
|
|
2488
3353
|
SelectField2,
|
|
2489
3354
|
{
|
|
2490
3355
|
name: `template-${component.uid}`,
|
|
@@ -2502,7 +3367,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2502
3367
|
] }, component.uid);
|
|
2503
3368
|
}) })
|
|
2504
3369
|
] }) }),
|
|
2505
|
-
picking && /* @__PURE__ */
|
|
3370
|
+
picking && /* @__PURE__ */ jsx6(MediaPicker2, { onClose: () => setPicking(null), onSelect: (asset) => {
|
|
2506
3371
|
const uid = picking;
|
|
2507
3372
|
setPicking(null);
|
|
2508
3373
|
if (!asset?.id) return;
|
|
@@ -2515,24 +3380,26 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
|
|
|
2515
3380
|
] })
|
|
2516
3381
|
] }) });
|
|
2517
3382
|
}
|
|
2518
|
-
function register(app, Component) {
|
|
3383
|
+
function register(app, Component, to) {
|
|
2519
3384
|
app.createSettingSection(
|
|
2520
3385
|
{ id: "blockscene", intlLabel: { id: "blockscene.title", defaultMessage: "Blockscene" } },
|
|
2521
3386
|
[{
|
|
2522
3387
|
id: "blockscene-settings",
|
|
2523
|
-
to
|
|
3388
|
+
to,
|
|
2524
3389
|
intlLabel: { id: "blockscene.settings", defaultMessage: "Gallery" },
|
|
2525
|
-
|
|
3390
|
+
// Module shape: older Strapi 4 (e.g. 4.11) only reads `.default` from the loader result.
|
|
3391
|
+
// Not an `async` function: Strapi 5 warns on AsyncFunction loaders.
|
|
3392
|
+
Component: () => Promise.resolve({ default: Component }),
|
|
2526
3393
|
permissions: permissions.read
|
|
2527
3394
|
}]
|
|
2528
3395
|
);
|
|
2529
3396
|
}
|
|
2530
3397
|
|
|
2531
3398
|
// admin/catalog.ts
|
|
2532
|
-
import * as
|
|
3399
|
+
import * as React6 from "react";
|
|
2533
3400
|
function useCatalog(get) {
|
|
2534
|
-
const [catalog, setCatalog] =
|
|
2535
|
-
|
|
3401
|
+
const [catalog, setCatalog] = React6.useState(null);
|
|
3402
|
+
React6.useEffect(() => {
|
|
2536
3403
|
let active = true;
|
|
2537
3404
|
get("/blockscene/catalog").then(({ data }) => {
|
|
2538
3405
|
if (active) setCatalog(data);
|
|
@@ -2547,13 +3414,13 @@ function useCatalog(get) {
|
|
|
2547
3414
|
}
|
|
2548
3415
|
|
|
2549
3416
|
// admin/strapi5.tsx
|
|
2550
|
-
import { jsx as
|
|
3417
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2551
3418
|
function Modal2({ open, onOpenChange, trigger, title, children }) {
|
|
2552
|
-
return /* @__PURE__ */
|
|
2553
|
-
/* @__PURE__ */
|
|
2554
|
-
/* @__PURE__ */
|
|
2555
|
-
/* @__PURE__ */
|
|
2556
|
-
/* @__PURE__ */
|
|
3419
|
+
return /* @__PURE__ */ jsxs6(Dialog.Root, { open, onOpenChange, children: [
|
|
3420
|
+
trigger && /* @__PURE__ */ jsx7(Dialog.Trigger, { children: trigger }),
|
|
3421
|
+
/* @__PURE__ */ jsxs6(Dialog.Content, { style: { width: "80vw", maxWidth: "80vw" }, children: [
|
|
3422
|
+
/* @__PURE__ */ jsx7(Dialog.Header, { children: /* @__PURE__ */ jsx7(Dialog.Title, { children: title }) }),
|
|
3423
|
+
/* @__PURE__ */ jsx7(Dialog.Body, { children })
|
|
2557
3424
|
] })
|
|
2558
3425
|
] });
|
|
2559
3426
|
}
|
|
@@ -2573,52 +3440,157 @@ function Panel() {
|
|
|
2573
3440
|
formValues ?? c.form?.values,
|
|
2574
3441
|
(name) => allowed.includes(name) && (creating || (rbac.canReadFields || []).includes(name)) && fields.find((field) => field.name === name)?.disabled !== true,
|
|
2575
3442
|
c.isLoading || c.form?.disabled || !c.form?.addFieldRow
|
|
2576
|
-
).map((zone) => ({
|
|
3443
|
+
).map((zone) => ({
|
|
3444
|
+
...zone,
|
|
3445
|
+
label: fields.find((field) => field.name === zone.name)?.label || zone.name
|
|
3446
|
+
}));
|
|
2577
3447
|
const add = (zone, uid) => {
|
|
2578
3448
|
const values = formValues ?? c.form.values;
|
|
2579
3449
|
const close = catalog?.groups?.[uid];
|
|
2580
|
-
if (c.form.disabled || !canInsert(zone, uid, values, c.components, close ? 2 : 1) || close && !zone.components.includes(close))
|
|
3450
|
+
if (c.form.disabled || !canInsert(zone, uid, values, c.components, close ? 2 : 1) || close && !zone.components.includes(close))
|
|
3451
|
+
return false;
|
|
2581
3452
|
const at = Array.isArray(values?.[zone.name]) ? values[zone.name].length : 0;
|
|
2582
|
-
c.form.addFieldRow(
|
|
3453
|
+
c.form.addFieldRow(
|
|
3454
|
+
zone.name,
|
|
3455
|
+
{
|
|
3456
|
+
...componentDefaults(c.components[uid], c.components),
|
|
3457
|
+
__component: uid
|
|
3458
|
+
},
|
|
3459
|
+
at
|
|
3460
|
+
);
|
|
2583
3461
|
if (close) c.form.addFieldRow(zone.name, { __component: close }, at + 1);
|
|
2584
3462
|
return true;
|
|
2585
3463
|
};
|
|
2586
3464
|
if (!zones.length || !catalog?.editor?.enabled) return null;
|
|
2587
3465
|
const docKey = `${c.model}:${creating ? "new" : c.id}:${c.form?.initialValues?.locale || ""}`;
|
|
2588
|
-
return {
|
|
2589
|
-
|
|
2590
|
-
/* @__PURE__ */
|
|
2591
|
-
|
|
3466
|
+
return {
|
|
3467
|
+
title: t.gallery,
|
|
3468
|
+
content: /* @__PURE__ */ jsxs6(Flex5, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
3469
|
+
/* @__PURE__ */ jsx7(
|
|
3470
|
+
Gallery,
|
|
3471
|
+
{
|
|
3472
|
+
zones,
|
|
3473
|
+
components: c.components,
|
|
3474
|
+
add,
|
|
3475
|
+
Modal: Modal2,
|
|
3476
|
+
Toggle: ToggleField,
|
|
3477
|
+
get,
|
|
3478
|
+
editor: catalog.editor,
|
|
3479
|
+
catalog,
|
|
3480
|
+
docKey,
|
|
3481
|
+
contentType: c.model,
|
|
3482
|
+
userId: user?.id
|
|
3483
|
+
}
|
|
3484
|
+
),
|
|
3485
|
+
/* @__PURE__ */ jsx7(
|
|
3486
|
+
PagePreview,
|
|
3487
|
+
{
|
|
3488
|
+
editor: catalog.editor,
|
|
3489
|
+
groups: catalog.groups || null,
|
|
3490
|
+
Modal: Modal2,
|
|
3491
|
+
Toggle: ToggleField
|
|
3492
|
+
}
|
|
3493
|
+
)
|
|
3494
|
+
] })
|
|
3495
|
+
};
|
|
2592
3496
|
}
|
|
2593
|
-
var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ */
|
|
2594
|
-
/* @__PURE__ */
|
|
2595
|
-
|
|
3497
|
+
var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ */ jsxs6(Flex5, { gap: 3, children: [
|
|
3498
|
+
/* @__PURE__ */ jsx7(
|
|
3499
|
+
Switch,
|
|
3500
|
+
{
|
|
3501
|
+
name,
|
|
3502
|
+
"aria-label": label,
|
|
3503
|
+
checked: Boolean(value),
|
|
3504
|
+
disabled,
|
|
3505
|
+
onCheckedChange: onChange
|
|
3506
|
+
}
|
|
3507
|
+
),
|
|
3508
|
+
/* @__PURE__ */ jsx7(Typography5, { children: label })
|
|
2596
3509
|
] });
|
|
2597
|
-
var TextField = ({
|
|
2598
|
-
|
|
2599
|
-
|
|
3510
|
+
var TextField = ({
|
|
3511
|
+
name,
|
|
3512
|
+
label,
|
|
3513
|
+
value,
|
|
3514
|
+
onChange,
|
|
3515
|
+
disabled,
|
|
3516
|
+
placeholder
|
|
3517
|
+
}) => /* @__PURE__ */ jsxs6(Field.Root, { name, children: [
|
|
3518
|
+
/* @__PURE__ */ jsx7(Field.Label, { children: label }),
|
|
3519
|
+
/* @__PURE__ */ jsx7(
|
|
3520
|
+
TextInput,
|
|
3521
|
+
{
|
|
3522
|
+
name,
|
|
3523
|
+
value,
|
|
3524
|
+
disabled,
|
|
3525
|
+
placeholder,
|
|
3526
|
+
onChange: (e) => onChange(e.target.value)
|
|
3527
|
+
}
|
|
3528
|
+
)
|
|
2600
3529
|
] });
|
|
2601
|
-
var SelectField = ({
|
|
2602
|
-
|
|
2603
|
-
|
|
3530
|
+
var SelectField = ({
|
|
3531
|
+
name,
|
|
3532
|
+
label,
|
|
3533
|
+
value,
|
|
3534
|
+
onChange,
|
|
3535
|
+
disabled,
|
|
3536
|
+
options
|
|
3537
|
+
}) => /* @__PURE__ */ jsxs6(Field.Root, { name, children: [
|
|
3538
|
+
/* @__PURE__ */ jsx7(Field.Label, { children: label }),
|
|
3539
|
+
/* @__PURE__ */ jsx7(
|
|
3540
|
+
SingleSelect2,
|
|
3541
|
+
{
|
|
3542
|
+
value,
|
|
3543
|
+
disabled,
|
|
3544
|
+
onChange: (v) => onChange(String(v)),
|
|
3545
|
+
children: options.map((o) => /* @__PURE__ */ jsx7(SingleSelectOption2, { value: o.value, children: o.label }, o.value))
|
|
3546
|
+
}
|
|
3547
|
+
)
|
|
2604
3548
|
] });
|
|
2605
3549
|
function MediaPicker({ onClose, onSelect }) {
|
|
2606
|
-
const components = useStrapiApp3(
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
3550
|
+
const components = useStrapiApp3(
|
|
3551
|
+
"Blockscene",
|
|
3552
|
+
(state) => state.components
|
|
3553
|
+
);
|
|
3554
|
+
const Dialog2 = components?.["media-library"];
|
|
3555
|
+
React7.useEffect(() => {
|
|
3556
|
+
if (!Dialog2) onClose();
|
|
3557
|
+
}, [Dialog2, onClose]);
|
|
3558
|
+
if (!Dialog2) return null;
|
|
3559
|
+
return /* @__PURE__ */ jsx7(
|
|
3560
|
+
Dialog2,
|
|
3561
|
+
{
|
|
3562
|
+
onClose,
|
|
3563
|
+
allowedTypes: ["images"],
|
|
3564
|
+
multiple: false,
|
|
3565
|
+
onSelectAssets: (assets) => onSelect(assets?.[0])
|
|
3566
|
+
}
|
|
3567
|
+
);
|
|
2613
3568
|
}
|
|
2614
3569
|
function usePermissions() {
|
|
2615
|
-
const { allowedActions, isLoading } = useRBAC(
|
|
2616
|
-
|
|
3570
|
+
const { allowedActions, isLoading } = useRBAC(
|
|
3571
|
+
Object.values(permissions).flat()
|
|
3572
|
+
);
|
|
3573
|
+
return {
|
|
3574
|
+
canRead: allowedActions.canRead,
|
|
3575
|
+
canUpdate: allowedActions.canUpdate,
|
|
3576
|
+
isLoading
|
|
3577
|
+
};
|
|
2617
3578
|
}
|
|
2618
|
-
var SettingsPage = () => /* @__PURE__ */
|
|
3579
|
+
var SettingsPage = () => /* @__PURE__ */ jsx7(
|
|
3580
|
+
Settings,
|
|
3581
|
+
{
|
|
3582
|
+
useClient: useFetchClient2,
|
|
3583
|
+
usePermissions,
|
|
3584
|
+
MediaPicker,
|
|
3585
|
+
ToggleField,
|
|
3586
|
+
SelectField,
|
|
3587
|
+
TextField,
|
|
3588
|
+
previewSupported: true
|
|
3589
|
+
}
|
|
3590
|
+
);
|
|
2619
3591
|
var strapi5_default = {
|
|
2620
3592
|
register(app) {
|
|
2621
|
-
register(app, SettingsPage);
|
|
3593
|
+
register(app, SettingsPage, "blockscene");
|
|
2622
3594
|
app.registerPlugin({ id: "blockscene", name: "Blockscene" });
|
|
2623
3595
|
},
|
|
2624
3596
|
registerTrads,
|