@aduptive/strapi-blockscene 2.0.0-alpha.11 → 2.0.0-alpha.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/admin.cjs CHANGED
@@ -130,13 +130,22 @@ var require_groups = __commonJS({
130
130
  const [a, b] = direction === "up" ? [ranges[to], ranges[at]] : [ranges[at], ranges[to]];
131
131
  return [...rows.slice(0, a[0]), ...rows.slice(b[0], b[1] + 1), ...rows.slice(a[0], a[1] + 1), ...rows.slice(b[1] + 1)];
132
132
  }
133
- function removeGroup2(rows, key, g) {
133
+ function removeGroup3(rows, key, g) {
134
134
  if (!g) return null;
135
135
  const start = rows.findIndex((row) => blockKey3(row) === String(key));
136
136
  if (start < 0 || !isOpener2(rows[start], g)) return null;
137
137
  const [, end] = groupRange3(rows, start, g);
138
+ if (end <= start || uidOf(rows[end]) !== g[uidOf(rows[start])]) return null;
138
139
  return [...rows.slice(0, start), ...rows.slice(end + 1)];
139
140
  }
141
+ function unwrapGroup3(rows, key, g) {
142
+ if (!g) return null;
143
+ const start = rows.findIndex((row) => blockKey3(row) === String(key));
144
+ if (start < 0 || !isOpener2(rows[start], g)) return null;
145
+ const [, end] = groupRange3(rows, start, g);
146
+ if (end <= start || uidOf(rows[end]) !== g[uidOf(rows[start])]) return null;
147
+ return [...rows.slice(0, start), ...rows.slice(start + 1, end), ...rows.slice(end + 1)];
148
+ }
140
149
  var MAX_COLUMNS = 12;
141
150
  var parseColumns = (value) => {
142
151
  const n = typeof value === "number" ? value : typeof value === "string" && /^\s*\d{1,3}\s*$/.test(value) ? Number(value) : NaN;
@@ -163,7 +172,8 @@ var require_groups = __commonJS({
163
172
  groupRows: groupRows2,
164
173
  topLevelRanges: topLevelRanges2,
165
174
  moveGroup: moveGroup2,
166
- removeGroup: removeGroup2,
175
+ removeGroup: removeGroup3,
176
+ unwrapGroup: unwrapGroup3,
167
177
  blockKey: blockKey3,
168
178
  isOpener: isOpener2,
169
179
  isClose: isClose2,
@@ -260,8 +270,8 @@ var require_diff = __commonJS({
260
270
  }
261
271
  function summarize(before, after, schema) {
262
272
  const zones = Object.entries(schema?.attributes || {}).filter(([, attr]) => attr?.type === "dynamiczone").map(([name]) => name);
263
- const blocks = { added: 0, removed: 0, changed: 0 };
264
- if (!before) return { initial: true, fields: [], blocks };
273
+ const blocks = { total: zones.reduce((n, name) => n + (Array.isArray(after?.[name]) ? after[name].length : 0), 0), added: 0, removed: 0, changed: 0 };
274
+ if (!before) return { initial: true, fields: [], blocks: { ...blocks, added: blocks.total } };
265
275
  const names = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after || {})])];
266
276
  const fields = names.filter((name) => !zones.includes(name) && !same2(before[name], after?.[name])).sort();
267
277
  for (const name of zones) for (const { op } of diffRows2(before[name], after?.[name])) if (op !== "same") blocks[op]++;
@@ -277,9 +287,9 @@ __export(strapi5_exports, {
277
287
  default: () => strapi5_default
278
288
  });
279
289
  module.exports = __toCommonJS(strapi5_exports);
280
- var React16 = __toESM(require("react"));
281
- var import_design_system11 = require("@strapi/design-system");
282
- var import_admin4 = require("@strapi/strapi/admin");
290
+ var React18 = __toESM(require("react"));
291
+ var import_design_system13 = require("@strapi/design-system");
292
+ var import_admin5 = require("@strapi/strapi/admin");
283
293
  var import_strapi_admin2 = require("@strapi/content-manager/strapi-admin");
284
294
 
285
295
  // admin/Gallery.tsx
@@ -330,6 +340,26 @@ function variantRow(schema, components, values, keys = fractional) {
330
340
  }
331
341
  return row;
332
342
  }
343
+ function starterKitRows(kit, zones, components, form) {
344
+ const out = {};
345
+ for (const [name, items2] of Object.entries(kit?.zones || {})) {
346
+ const zone = zones.find((entry) => entry.name === name);
347
+ const current = form.rows(name);
348
+ if (!zone || current.length || current.length + items2.length > (zone.max ?? Infinity) || items2.some((item) => !zone.components.includes(item.__component) || !components[item.__component])) return null;
349
+ const keys = form.keys(current, current.length, items2.length);
350
+ out[name] = items2.map((item, index) => ({ ...variantRow(components[item.__component], components, item.values), __component: item.__component, __temp_key__: keys[index] }));
351
+ }
352
+ return out;
353
+ }
354
+ function starterKitsForLocale(kits, locale) {
355
+ if (!Array.isArray(kits)) return [];
356
+ const current = String(locale || "").toLowerCase();
357
+ const language = current.split("-")[0];
358
+ return kits.filter((kit) => !Array.isArray(kit.locales) || kit.locales.some((entry) => {
359
+ const wanted = String(entry).toLowerCase();
360
+ return wanted === current || !wanted.includes("-") && wanted === language;
361
+ }));
362
+ }
333
363
  function editableZones(schema, values, canEdit, disabled = false) {
334
364
  if (disabled) return [];
335
365
  return Object.entries(schema?.attributes || {}).filter(
@@ -394,6 +424,12 @@ var pickable = (zone, config2) => {
394
424
  const closers = Object.values(config2.groups || {});
395
425
  return zone.components.filter((uid) => !closers.includes(uid));
396
426
  };
427
+ function showRowThumbnail(uid, config2 = {}) {
428
+ const configured = config2.components?.[uid]?.showRowThumbnail;
429
+ if (typeof configured === "boolean") return configured;
430
+ const groups = config2.groups || {};
431
+ return !Object.prototype.hasOwnProperty.call(groups, uid) && !Object.values(groups).includes(uid);
432
+ }
397
433
  function entryOf(uid, schema, config2) {
398
434
  const meta = config2.components?.[uid] || {};
399
435
  return {
@@ -540,13 +576,74 @@ var TEXT_TYPES = ["string", "text"];
540
576
  var RICH_TYPES = ["richtext", "blocks", "customField"];
541
577
  var EDITABLE_TYPES = [...TEXT_TYPES, ...RICH_TYPES];
542
578
  var SCALAR = ["string", "text", "richtext", "email", "enumeration", "integer", "biginteger", "float", "decimal", "boolean", "date", "datetime", "time", "json", "blocks", "uid", "customField"];
579
+ var ENTRY_SYSTEM = ["id", "documentId", "locale", "createdAt", "updatedAt", "publishedAt"];
580
+ var privateAttribute = (attr) => attr?.private === true || attr?.pluginOptions?.blockscene?.private === true;
581
+ var fieldReadable = (path, allowed, all = false) => {
582
+ if (all) return true;
583
+ const fields = Array.isArray(allowed) ? allowed : [];
584
+ const parts = String(path).split(".");
585
+ return parts.some((_, index) => fields.includes(parts.slice(0, index + 1).join("."))) || fields.some((field) => field.startsWith(`${path}.`));
586
+ };
543
587
  var blockKey = (row) => row && row.id != null ? `${row.__component}#${row.id}` : row && row.__temp_key__ != null ? String(row.__temp_key__) : null;
588
+ function plainValue(value, depth = 0) {
589
+ if (value == null || typeof value === "number" || typeof value === "boolean") return value;
590
+ if (typeof value === "string") return value.slice(0, 2e5);
591
+ if (typeof value !== "object" || depth > 8) return void 0;
592
+ if (Array.isArray(value)) return value.slice(0, 500).map((item) => plainValue(item, depth + 1)).filter((item) => item !== void 0);
593
+ const out = {};
594
+ for (const [name, child] of Object.entries(value).slice(0, 500)) {
595
+ const projected = plainValue(child, depth + 1);
596
+ if (projected !== void 0) out[name] = projected;
597
+ }
598
+ return out;
599
+ }
600
+ function projectEntryValue(value, attr, components, cmsOrigin, depth = 0, readable = () => true, path = "") {
601
+ if (privateAttribute(attr) || attr?.type === "password" || depth > 8) return void 0;
602
+ if (attr?.type === "media") {
603
+ const files = (attr.multiple ? Array.isArray(value) ? value : [] : value ? [value] : []).map((file) => projectMedia(file, cmsOrigin)).filter(Boolean);
604
+ return attr.multiple ? files : files[0] || null;
605
+ }
606
+ if (attr?.type === "component") {
607
+ const schema = components?.[attr.component];
608
+ const one = (item) => {
609
+ if (!item || !schema) return null;
610
+ const projected = projectEntryObject(item, schema, components, cmsOrigin, depth + 1, readable, path);
611
+ return item.id != null ? { id: item.id, ...projected } : projected;
612
+ };
613
+ return attr.repeatable ? (Array.isArray(value) ? value : []).slice(0, 500).map(one).filter(Boolean) : one(value);
614
+ }
615
+ if (attr?.type === "dynamiczone") {
616
+ return (Array.isArray(value) ? value : []).slice(0, 500).flatMap((item) => {
617
+ const uid = item?.__component;
618
+ const schema = components?.[uid];
619
+ if (!uid || !schema) return [];
620
+ const projected = projectEntryObject(item, schema, components, cmsOrigin, depth + 1, readable, path);
621
+ return [{ ...item.id != null && { id: item.id }, __component: uid, ...projected }];
622
+ });
623
+ }
624
+ return plainValue(value, depth);
625
+ }
626
+ function projectEntryObject(values, schema, components, cmsOrigin, depth = 0, readable = () => true, prefix2 = "") {
627
+ const out = {};
628
+ for (const [name, attr] of Object.entries(schema?.attributes || {})) {
629
+ const path = prefix2 ? `${prefix2}.${name}` : name;
630
+ if (!readable(path) || privateAttribute(attr) || attr.type === "password" || values?.[name] === void 0) continue;
631
+ const projected = projectEntryValue(values[name], attr, components, cmsOrigin, depth, readable, path);
632
+ if (projected !== void 0) out[name] = projected;
633
+ }
634
+ return out;
635
+ }
636
+ function projectEntry(values, schema, components, cmsOrigin, readable = () => true) {
637
+ const out = projectEntryObject(values, schema, components, cmsOrigin, 0, readable);
638
+ for (const name of ENTRY_SYSTEM) if (values?.[name] !== void 0) out[name] = plainValue(values[name]);
639
+ return out;
640
+ }
544
641
  function projectRow(row, schema, components, cmsOrigin, depth = 0) {
545
642
  if (!row || !schema || depth > 3) return null;
546
643
  const out = {};
547
644
  for (const [name, attr] of Object.entries(schema.attributes || {})) {
548
645
  const value = row[name];
549
- if (attr.type === "password" || attr.type === "relation" || attr.private) continue;
646
+ if (attr.type === "password" || attr.type === "relation" || privateAttribute(attr)) continue;
550
647
  if (SCALAR.includes(attr.type)) {
551
648
  if (value !== void 0) out[name] = typeof value === "string" ? value.slice(0, 2e5) : value;
552
649
  } else if (attr.type === "media") {
@@ -575,7 +672,7 @@ function resolveField(uid, field, components) {
575
672
  const parts = field.split(".");
576
673
  for (let i = 0; i < parts.length; i++) {
577
674
  const attr = schema?.attributes?.[parts[i]];
578
- if (!attr || attr.private === true) return null;
675
+ if (!attr || privateAttribute(attr)) return null;
579
676
  if (i === parts.length - 1) return attr;
580
677
  if (attr.type !== "component") return null;
581
678
  if (attr.repeatable) {
@@ -591,7 +688,7 @@ function editableFields(uid, row, components) {
591
688
  const out = [];
592
689
  const SYSTEM = ["id", "documentId", "locale", "createdAt", "updatedAt", "publishedAt", "createdBy", "updatedBy", "localizations", "__component", "__temp_key__"];
593
690
  const push = (name, attr, label) => {
594
- if (!SYSTEM.includes(name.split(".").pop()) && attr?.private !== true && EDITABLE_TYPES.includes(attr?.type)) out.push({ name, type: attr.type, label });
691
+ if (!SYSTEM.includes(name.split(".").pop()) && !privateAttribute(attr) && EDITABLE_TYPES.includes(attr?.type)) out.push({ name, type: attr.type, label });
595
692
  };
596
693
  for (const [name, attr] of Object.entries(schema?.attributes || {})) {
597
694
  if (attr.type === "component" && attr.repeatable) {
@@ -605,7 +702,7 @@ function editableFields(uid, row, components) {
605
702
  function mediaFields(uid, row, components) {
606
703
  const media = {};
607
704
  for (const [name, attr] of Object.entries(components?.[uid]?.attributes || {})) {
608
- if (attr.type === "media" && attr.private !== true) media[name] = { required: attr.required === true, multiple: attr.multiple === true, present: attr.multiple ? Array.isArray(row?.[name]) && row[name].length > 0 : Boolean(row?.[name]) };
705
+ if (attr.type === "media" && !privateAttribute(attr)) media[name] = { required: attr.required === true, multiple: attr.multiple === true, present: attr.multiple ? Array.isArray(row?.[name]) && row[name].length > 0 : Boolean(row?.[name]) };
609
706
  }
610
707
  return media;
611
708
  }
@@ -645,6 +742,7 @@ var hoverKey = (key, rows) => key === null ? null : typeof key === "string" && k
645
742
  function isPreviewMessage(event, origin, source, channel, type) {
646
743
  return event.origin === origin && event.source === source && event.data?.protocol === PROTOCOL && event.data?.channel === channel && event.data?.type === type;
647
744
  }
745
+ var previewMessageAllowed = (event, origin, source, channel, readOnly) => isPreviewMessage(event, origin, source, channel, event.data?.type) && (!readOnly || event.data?.type === "ready");
648
746
  function insertIndex(rows, after) {
649
747
  if (after === null || after === void 0) return 0;
650
748
  const index = (Array.isArray(rows) ? rows : []).findIndex((row) => blockKey(row) === String(after));
@@ -847,7 +945,7 @@ var import_react_intl = require("react-intl");
847
945
  // admin/translations/en.json
848
946
  var en_default = {
849
947
  title: "Blockscene",
850
- settings: "Gallery",
948
+ settings: "General",
851
949
  gallery: "Block gallery",
852
950
  search: "Search blocks",
853
951
  clear: "Clear search",
@@ -863,6 +961,17 @@ var en_default = {
863
961
  moreActions: "More actions",
864
962
  settingsTitle: "Blockscene",
865
963
  settingsIntro: "Gallery thumbnails, wireframe palette and editor preferences. Changes apply the next time the gallery opens; no rebuild is needed.",
964
+ settingsGeneral: "General",
965
+ settingsGeneralIntro: "Choose how Blockscene behaves in the editor and which row actions are available.",
966
+ settingsPreview: "Page preview",
967
+ settingsPreviewIntro: "Connect the frontend preview and configure its modes, toolbar and responsive widths.",
968
+ settingsContentTypes: "Content types",
969
+ settingsContentTypesIntro: "Choose where Blockscene is enabled and tailor the visual editor for each content type.",
970
+ settingsGallery: "Block gallery",
971
+ settingsGalleryIntro: "Configure gallery thumbnails, wireframe colors, block types and filters.",
972
+ settingsHistory: "History & trash",
973
+ settingsHistoryIntro: "Control version snapshots, activity retention and recoverable deletions.",
974
+ historyUnavailable: "History and trash settings require Strapi 5.",
866
975
  palette: "Wireframe palette",
867
976
  background: "Background",
868
977
  surface: "Surfaces",
@@ -892,6 +1001,7 @@ var en_default = {
892
1001
  showCloseAll: 'Show "Collapse all"',
893
1002
  toggleHelp: "The zone bar shows one button: with both on it expands while any block is collapsed and collapses them all otherwise; with only one on, it offers that action alone.",
894
1003
  showRowThumbnails: "Show block thumbnails in the rows",
1004
+ componentRowThumbnail: "Show thumbnail in the editor row",
895
1005
  initialState: "Initial accordion state",
896
1006
  "states.closed": "All closed",
897
1007
  "states.open": "All open",
@@ -899,10 +1009,10 @@ var en_default = {
899
1009
  rememberHelp: "Only the explicit open all / close all buttons update the memory, per user and browser. Opening one block does not.",
900
1010
  previewUrl: "Preview route base URL",
901
1011
  previewUrlHelp: "Full URL of your frontend page-preview route, e.g. https://site.test/block-preview/page. Leave empty to reuse the origin of Strapi's native Preview (when configured for the content type) with /block-preview/page. The route must implement the bridge (see README).",
902
- previewUrlEmpty: "No preview URL is set: editors get the Fields + page and Visual editor modes only on content types where Strapi's native Preview is configured. Elsewhere the mode menu is not shown.",
1012
+ previewUrlEmpty: "No preview URL is set: editors get the Fields + preview and Visual editor modes only on content types where Strapi's native Preview is configured. Elsewhere the mode menu is not shown.",
903
1013
  previewMode: "Initial preview mode",
904
- "modes.form": "Fields",
905
- "modes.split": "Fields + page",
1014
+ "modes.form": "Fields only",
1015
+ "modes.split": "Fields + preview",
906
1016
  "modes.preview": "Visual editor",
907
1017
  previewModeHelp: "Every edit view opens in this mode, unless its content type sets its own below. Editors can switch while they edit; the switch is not remembered.",
908
1018
  lazyEdit: "Click to edit",
@@ -910,8 +1020,8 @@ var en_default = {
910
1020
  lazyFields: "Custom fields loaded on demand",
911
1021
  lazyEditorsHelp: "Listed custom fields show a read-only preview until clicked or focused, so opening large pages stays fast. Separate uids with commas.",
912
1022
  lazyFieldsInvalid: "Use up to {max} custom field uids such as plugin::ckeditor5.CKEditor or global::my-field.",
913
- modeForm: "Fields",
914
- modeSplit: "Fields + page",
1023
+ modeForm: "Fields only",
1024
+ modeSplit: "Fields + preview",
915
1025
  modePreview: "Visual editor",
916
1026
  previewPane: "Page preview",
917
1027
  resize: "Resize preview pane",
@@ -938,6 +1048,7 @@ var en_default = {
938
1048
  denied: "Access denied.",
939
1049
  loadFailed: "Could not load settings. Reload to try again.",
940
1050
  invalidColor: "Colors must use #RRGGBB.",
1051
+ invalidUrl: "Preview URLs must be complete HTTP or HTTPS URLs.",
941
1052
  previewLabel: "Palette preview",
942
1053
  removeGroup: "Remove group",
943
1054
  diagTitle: "Block groups need attention; publishing is refused until they are fixed:",
@@ -972,6 +1083,7 @@ var en_default = {
972
1083
  contentTypes: "Content types",
973
1084
  contentTypesHelp: 'The gallery, accordions and page preview work on these content types (the ones with a Dynamic Zone). Turn one off to leave its edit view native. "Opens in" is how every edit view of that type starts; editors can still switch while they edit.',
974
1085
  typeMode: "Opens in",
1086
+ typeAdvanced: "Visual editor options",
975
1087
  modeDefault: "Default ({mode})",
976
1088
  blockModalDone: "Done",
977
1089
  crashed: "Blockscene stopped here after an error. The native editor is unaffected. If it happens again, turn Blockscene off in Settings, Blockscene.",
@@ -1006,6 +1118,9 @@ var en_default = {
1006
1118
  unstar: "Remove star",
1007
1119
  quickInsert: "Insert {label}",
1008
1120
  insert: "Insert",
1121
+ starterKits: "Start with a kit",
1122
+ starterKitsHelp: "Choose a starting structure. Everything is inserted as an unsaved, editable draft.",
1123
+ startBlank: "Start blank",
1009
1124
  closeDetail: "Close details",
1010
1125
  typology: "Typology",
1011
1126
  typologyAuto: "Automatic ({name})",
@@ -1060,6 +1175,11 @@ var en_default = {
1060
1175
  confirmDeleteTitle: "Delete block",
1061
1176
  confirmDelete: "Delete block {name}?",
1062
1177
  confirmDeleteMarker: "This is a group marker: only the marker is removed, not the blocks inside the group, and the group stays unbalanced until it is fixed.",
1178
+ confirmDeleteGroupTitle: "Delete group",
1179
+ confirmDeleteGroup: "Delete group {name}?",
1180
+ confirmDeleteGroupHint: "This group contains {count, plural, one {# block} other {# blocks}}. Choose whether to delete them or keep them on the page without the group.",
1181
+ keepGroupBlocks: "Remove group, keep blocks",
1182
+ deleteGroupAndBlocks: "{count, plural, =0 {Delete group} one {Delete group and # block} other {Delete group and # blocks}}",
1063
1183
  delete: "Delete",
1064
1184
  selectBlocks: "Select blocks",
1065
1185
  selectAll: "Select all",
@@ -1254,6 +1374,7 @@ var en_default = {
1254
1374
  gridCellMenu: "More actions for {label}",
1255
1375
  removeFromGroup: "Remove from group",
1256
1376
  gridAdd: "Add a block",
1377
+ groupAdd: "Add block inside {label}",
1257
1378
  gridShowList: "Show group {label} as a list",
1258
1379
  gridShowGrid: "Show group {label} as a grid",
1259
1380
  layoutColumnsField: "Layout grid: columns field",
@@ -1262,13 +1383,29 @@ var en_default = {
1262
1383
  layoutOff: "No grid",
1263
1384
  layoutNoMobile: "None",
1264
1385
  layoutHelp: "The group's blocks show as a grid in the form, with the column count this block holds.",
1265
- layoutNoFields: "This block has no field that can hold a column count."
1386
+ layoutNoFields: "This block has no field that can hold a column count.",
1387
+ "toolbar.versions": "Version history",
1388
+ versionsDenied: "Ask an administrator to grant the Blockscene Read version history permission.",
1389
+ versionsDisabled: "History is not enabled for this content type. Ask an administrator to enable it in Settings > Blockscene (settings.history.enabled).",
1390
+ versionsNew: "Save this entry first to start its history.",
1391
+ versionsPerson: "Filter by person",
1392
+ versionsEveryone: "Everyone",
1393
+ versionsCounts: "{total} blocks",
1394
+ versionsCountsMissing: "Block counts unavailable (older or unrecorded event).",
1395
+ versionsPage: "Page {page} of {count}",
1396
+ versionsPrevious: "Previous",
1397
+ versionsNext: "Next",
1398
+ versionsViewing: "Viewing version of {date} by {person} (read-only).",
1399
+ versionsCurrent: "Back to current draft",
1400
+ versionsMissing: "Some blocks, fields, media or relations are no longer available in this preview.",
1401
+ versionsBridgeLegacy: "This preview bridge does not support read-only browsing. Interaction is disabled; update the bridge to support readOnly.",
1402
+ historyExpired: "Snapshot no longer available"
1266
1403
  };
1267
1404
 
1268
1405
  // admin/translations/pt-BR.json
1269
1406
  var pt_BR_default = {
1270
1407
  title: "Blockscene",
1271
- settings: "Galeria",
1408
+ settings: "Geral",
1272
1409
  gallery: "Galeria de blocos",
1273
1410
  search: "Buscar blocos",
1274
1411
  clear: "Limpar busca",
@@ -1284,6 +1421,17 @@ var pt_BR_default = {
1284
1421
  moreActions: "Mais a\xE7\xF5es",
1285
1422
  settingsTitle: "Blockscene",
1286
1423
  settingsIntro: "Miniaturas da galeria, paleta dos wireframes e prefer\xEAncias do editor. As mudan\xE7as valem na pr\xF3xima abertura da galeria; n\xE3o \xE9 preciso rebuild.",
1424
+ settingsGeneral: "Geral",
1425
+ settingsGeneralIntro: "Defina como o Blockscene funciona no editor e quais a\xE7\xF5es ficam dispon\xEDveis nas linhas.",
1426
+ settingsPreview: "Preview da p\xE1gina",
1427
+ settingsPreviewIntro: "Conecte a preview do frontend e configure modos, barra de ferramentas e larguras responsivas.",
1428
+ settingsContentTypes: "Tipos de conte\xFAdo",
1429
+ settingsContentTypesIntro: "Escolha onde o Blockscene fica ativo e personalize o editor visual de cada tipo de conte\xFAdo.",
1430
+ settingsGallery: "Galeria de blocos",
1431
+ settingsGalleryIntro: "Configure miniaturas, cores dos wireframes, tipos e filtros da galeria.",
1432
+ settingsHistory: "Hist\xF3rico e lixeira",
1433
+ settingsHistoryIntro: "Controle vers\xF5es, reten\xE7\xE3o de atividades e exclus\xF5es recuper\xE1veis.",
1434
+ historyUnavailable: "As configura\xE7\xF5es de hist\xF3rico e lixeira exigem o Strapi 5.",
1287
1435
  palette: "Paleta dos wireframes",
1288
1436
  background: "Fundo",
1289
1437
  surface: "Superf\xEDcies",
@@ -1313,6 +1461,7 @@ var pt_BR_default = {
1313
1461
  showCloseAll: 'Mostrar "Recolher tudo"',
1314
1462
  toggleHelp: "A barra da zona mostra um \xFAnico bot\xE3o: com as duas op\xE7\xF5es ligadas, ele expande enquanto houver algum bloco recolhido e, sen\xE3o, recolhe todos; com s\xF3 uma ligada, oferece apenas essa a\xE7\xE3o.",
1315
1463
  showRowThumbnails: "Mostrar miniaturas dos blocos nas linhas",
1464
+ componentRowThumbnail: "Mostrar miniatura na linha do editor",
1316
1465
  initialState: "Estado inicial dos accordions",
1317
1466
  "states.closed": "Todos fechados",
1318
1467
  "states.open": "Todos abertos",
@@ -1320,10 +1469,10 @@ var pt_BR_default = {
1320
1469
  rememberHelp: "Somente os bot\xF5es de abrir/fechar todos atualizam a mem\xF3ria, por usu\xE1rio e navegador. Abrir um bloco isolado n\xE3o muda.",
1321
1470
  previewUrl: "URL base da rota de preview",
1322
1471
  previewUrlHelp: "URL completa da rota de preview de p\xE1gina do seu frontend, por exemplo https://site.test/block-preview/page. Vazio reutiliza a origem da Preview nativa do Strapi (quando configurada para o tipo de conte\xFAdo) com /block-preview/page. A rota precisa implementar a bridge (ver README).",
1323
- previewUrlEmpty: "Nenhuma URL de preview definida: os editores s\xF3 t\xEAm os modos Campos + p\xE1gina e Editor visual nos tipos de conte\xFAdo com o Preview nativo do Strapi configurado. Nos demais, o menu de modos n\xE3o aparece.",
1472
+ previewUrlEmpty: "Nenhuma URL de preview definida: os editores s\xF3 t\xEAm os modos Campos + preview e Editor visual nos tipos de conte\xFAdo com o Preview nativo do Strapi configurado. Nos demais, o menu de modos n\xE3o aparece.",
1324
1473
  previewMode: "Modo inicial da preview",
1325
- "modes.form": "Campos",
1326
- "modes.split": "Campos + p\xE1gina",
1474
+ "modes.form": "Somente campos",
1475
+ "modes.split": "Campos + preview",
1327
1476
  "modes.preview": "Editor visual",
1328
1477
  previewModeHelp: "Toda tela de edi\xE7\xE3o abre neste modo, a menos que o tipo de conte\xFAdo defina o seu abaixo. Quem edita pode trocar durante a edi\xE7\xE3o; a troca n\xE3o fica gravada.",
1329
1478
  lazyEdit: "Clique para editar",
@@ -1331,8 +1480,8 @@ var pt_BR_default = {
1331
1480
  lazyFields: "Campos personalizados carregados sob demanda",
1332
1481
  lazyEditorsHelp: "Os campos personalizados listados mostram uma pr\xE9via somente leitura at\xE9 receberem clique ou foco, para que p\xE1ginas grandes abram r\xE1pido. Separe os uids com v\xEDrgulas.",
1333
1482
  lazyFieldsInvalid: "Use at\xE9 {max} uids de campos personalizados, como plugin::ckeditor5.CKEditor ou global::meu-campo.",
1334
- modeForm: "Campos",
1335
- modeSplit: "Campos + p\xE1gina",
1483
+ modeForm: "Somente campos",
1484
+ modeSplit: "Campos + preview",
1336
1485
  modePreview: "Editor visual",
1337
1486
  previewPane: "Preview da p\xE1gina",
1338
1487
  resize: "Redimensionar painel de preview",
@@ -1359,6 +1508,7 @@ var pt_BR_default = {
1359
1508
  denied: "Acesso negado.",
1360
1509
  loadFailed: "N\xE3o foi poss\xEDvel carregar. Recarregue para tentar novamente.",
1361
1510
  invalidColor: "As cores devem usar #RRGGBB.",
1511
+ invalidUrl: "As URLs de preview devem ser URLs HTTP ou HTTPS completas.",
1362
1512
  previewLabel: "Pr\xE9via da paleta",
1363
1513
  removeGroup: "Remover grupo",
1364
1514
  diagTitle: "Os grupos de blocos precisam de aten\xE7\xE3o; a publica\xE7\xE3o \xE9 recusada at\xE9 a corre\xE7\xE3o:",
@@ -1393,6 +1543,7 @@ var pt_BR_default = {
1393
1543
  contentTypes: "Tipos de conte\xFAdo",
1394
1544
  contentTypesHelp: 'A galeria, os accordions e o preview da p\xE1gina funcionam nestes tipos de conte\xFAdo (os que t\xEAm uma zona din\xE2mica). Desligue um para deixar a edi\xE7\xE3o dele nativa. "Abre em" \xE9 como toda tela de edi\xE7\xE3o desse tipo come\xE7a; quem edita ainda pode trocar durante a edi\xE7\xE3o.',
1395
1545
  typeMode: "Abre em",
1546
+ typeAdvanced: "Op\xE7\xF5es do editor visual",
1396
1547
  modeDefault: "Padr\xE3o ({mode})",
1397
1548
  blockModalDone: "Concluir",
1398
1549
  crashed: "O Blockscene parou aqui por causa de um erro. O editor nativo n\xE3o foi afetado. Se acontecer de novo, desligue o Blockscene em Settings, Blockscene.",
@@ -1427,6 +1578,9 @@ var pt_BR_default = {
1427
1578
  unstar: "Remover dos favoritos",
1428
1579
  quickInsert: "Inserir {label}",
1429
1580
  insert: "Inserir",
1581
+ starterKits: "Come\xE7ar com um kit",
1582
+ starterKitsHelp: "Escolha uma estrutura inicial. Tudo \xE9 inserido como rascunho edit\xE1vel e ainda n\xE3o salvo.",
1583
+ startBlank: "Come\xE7ar em branco",
1430
1584
  closeDetail: "Fechar detalhes",
1431
1585
  typology: "Tipologia",
1432
1586
  typologyAuto: "Autom\xE1tica ({name})",
@@ -1481,6 +1635,11 @@ var pt_BR_default = {
1481
1635
  confirmDeleteTitle: "Excluir bloco",
1482
1636
  confirmDelete: "Excluir o bloco {name}?",
1483
1637
  confirmDeleteMarker: "Este \xE9 um marcador de grupo: s\xF3 o marcador \xE9 removido, n\xE3o os blocos dentro do grupo, e o grupo fica desbalanceado at\xE9 ser corrigido.",
1638
+ confirmDeleteGroupTitle: "Excluir grupo",
1639
+ confirmDeleteGroup: "Excluir o grupo {name}?",
1640
+ confirmDeleteGroupHint: "Este grupo cont\xE9m {count, plural, one {# bloco} other {# blocos}}. Escolha entre exclu\xED-los ou mant\xEA-los na p\xE1gina sem o grupo.",
1641
+ keepGroupBlocks: "Remover grupo e manter blocos",
1642
+ deleteGroupAndBlocks: "{count, plural, =0 {Excluir grupo} one {Excluir grupo e # bloco} other {Excluir grupo e # blocos}}",
1484
1643
  delete: "Excluir",
1485
1644
  selectBlocks: "Selecionar blocos",
1486
1645
  selectAll: "Selecionar todos",
@@ -1675,6 +1834,7 @@ var pt_BR_default = {
1675
1834
  gridCellMenu: "Mais a\xE7\xF5es para {label}",
1676
1835
  removeFromGroup: "Remover do grupo",
1677
1836
  gridAdd: "Adicionar bloco",
1837
+ groupAdd: "Adicionar bloco dentro de {label}",
1678
1838
  gridShowList: "Mostrar o grupo {label} como lista",
1679
1839
  gridShowGrid: "Mostrar o grupo {label} como grade",
1680
1840
  layoutColumnsField: "Grade do layout: campo das colunas",
@@ -1683,13 +1843,29 @@ var pt_BR_default = {
1683
1843
  layoutOff: "Sem grade",
1684
1844
  layoutNoMobile: "Nenhum",
1685
1845
  layoutHelp: "Os blocos do grupo aparecem em grade no formul\xE1rio, com o n\xFAmero de colunas deste bloco.",
1686
- layoutNoFields: "Este bloco n\xE3o tem campo que guarde um n\xFAmero de colunas."
1846
+ layoutNoFields: "Este bloco n\xE3o tem campo que guarde um n\xFAmero de colunas.",
1847
+ "toolbar.versions": "Hist\xF3rico de vers\xF5es",
1848
+ versionsDenied: "Pe\xE7a a um administrador a permiss\xE3o Ler hist\xF3rico de vers\xF5es do Blockscene.",
1849
+ versionsDisabled: "O hist\xF3rico n\xE3o est\xE1 ativo para este tipo de conte\xFAdo. Pe\xE7a a um administrador para ativ\xE1-lo em Settings > Blockscene (settings.history.enabled).",
1850
+ versionsNew: "Salve este conte\xFAdo primeiro para iniciar seu hist\xF3rico.",
1851
+ versionsPerson: "Filtrar por pessoa",
1852
+ versionsEveryone: "Todas as pessoas",
1853
+ versionsCounts: "{total} blocos",
1854
+ versionsCountsMissing: "Contagem de blocos indispon\xEDvel (evento antigo ou n\xE3o registrado).",
1855
+ versionsPage: "P\xE1gina {page} de {count}",
1856
+ versionsPrevious: "Anterior",
1857
+ versionsNext: "Pr\xF3xima",
1858
+ versionsViewing: "Vendo vers\xE3o de {date} por {person} (somente leitura).",
1859
+ versionsCurrent: "Voltar ao rascunho atual",
1860
+ versionsMissing: "Alguns blocos, campos, m\xEDdias ou rela\xE7\xF5es n\xE3o est\xE3o mais dispon\xEDveis nesta preview.",
1861
+ versionsBridgeLegacy: "Esta bridge n\xE3o suporta navega\xE7\xE3o somente leitura. A intera\xE7\xE3o est\xE1 desativada; atualize a bridge para suportar readOnly.",
1862
+ historyExpired: "Snapshot n\xE3o est\xE1 mais dispon\xEDvel"
1687
1863
  };
1688
1864
 
1689
1865
  // admin/translations/pt.json
1690
1866
  var pt_default = {
1691
1867
  title: "Blockscene",
1692
- settings: "Galeria",
1868
+ settings: "Geral",
1693
1869
  gallery: "Galeria de blocos",
1694
1870
  search: "Pesquisar blocos",
1695
1871
  clear: "Limpar pesquisa",
@@ -1705,6 +1881,17 @@ var pt_default = {
1705
1881
  moreActions: "Mais a\xE7\xF5es",
1706
1882
  settingsTitle: "Blockscene",
1707
1883
  settingsIntro: "Miniaturas da galeria, paleta dos wireframes e prefer\xEAncias do editor. As mudan\xE7as valem na pr\xF3xima abertura da galeria; n\xE3o \xE9 preciso rebuild.",
1884
+ settingsGeneral: "Geral",
1885
+ settingsGeneralIntro: "Defina como o Blockscene funciona no editor e quais a\xE7\xF5es ficam dispon\xEDveis nas linhas.",
1886
+ settingsPreview: "Pr\xE9-visualiza\xE7\xE3o da p\xE1gina",
1887
+ settingsPreviewIntro: "Ligue a pr\xE9-visualiza\xE7\xE3o do frontend e configure modos, barra de ferramentas e larguras responsivas.",
1888
+ settingsContentTypes: "Tipos de conte\xFAdo",
1889
+ settingsContentTypesIntro: "Escolha onde o Blockscene fica ativo e personalize o editor visual de cada tipo de conte\xFAdo.",
1890
+ settingsGallery: "Galeria de blocos",
1891
+ settingsGalleryIntro: "Configure miniaturas, cores dos wireframes, tipos e filtros da galeria.",
1892
+ settingsHistory: "Hist\xF3rico e lixo",
1893
+ settingsHistoryIntro: "Controle vers\xF5es, reten\xE7\xE3o de atividades e elimina\xE7\xF5es recuper\xE1veis.",
1894
+ historyUnavailable: "As configura\xE7\xF5es de hist\xF3rico e lixo exigem o Strapi 5.",
1708
1895
  palette: "Paleta dos wireframes",
1709
1896
  background: "Fundo",
1710
1897
  surface: "Superf\xEDcies",
@@ -1734,6 +1921,7 @@ var pt_default = {
1734
1921
  showCloseAll: 'Mostrar "Recolher tudo"',
1735
1922
  toggleHelp: "A barra da zona mostra um \xFAnico bot\xE3o: com as duas op\xE7\xF5es ativas, expande enquanto houver algum bloco recolhido e, caso contr\xE1rio, recolhe todos; com apenas uma ativa, oferece s\xF3 essa a\xE7\xE3o.",
1736
1923
  showRowThumbnails: "Mostrar miniaturas dos blocos nas linhas",
1924
+ componentRowThumbnail: "Mostrar miniatura na linha do editor",
1737
1925
  initialState: "Estado inicial dos accordions",
1738
1926
  "states.closed": "Todos fechados",
1739
1927
  "states.open": "Todos abertos",
@@ -1741,10 +1929,10 @@ var pt_default = {
1741
1929
  rememberHelp: "Somente os bot\xF5es de abrir/fechar todos atualizam a mem\xF3ria, por usu\xE1rio e navegador. Abrir um bloco isolado n\xE3o muda.",
1742
1930
  previewUrl: "URL base da rota de pr\xE9-visualiza\xE7\xE3o",
1743
1931
  previewUrlHelp: "URL completa da rota de preview de p\xE1gina do seu frontend, por exemplo https://site.test/block-preview/page. Vazio reutiliza a origem da Preview nativa do Strapi (quando configurada para o tipo de conte\xFAdo) com /block-preview/page. A rota precisa implementar a bridge (ver README).",
1744
- previewUrlEmpty: "Nenhum URL de pr\xE9-visualiza\xE7\xE3o definido: os editores s\xF3 t\xEAm os modos Campos + p\xE1gina e Editor visual nos tipos de conte\xFAdo com a Preview nativa do Strapi configurada. Nos restantes, o menu de modos n\xE3o aparece.",
1932
+ previewUrlEmpty: "Nenhum URL de pr\xE9-visualiza\xE7\xE3o definido: os editores s\xF3 t\xEAm os modos Campos + pr\xE9-visualiza\xE7\xE3o e Editor visual nos tipos de conte\xFAdo com a Preview nativa do Strapi configurada. Nos restantes, o menu de modos n\xE3o aparece.",
1745
1933
  previewMode: "Modo inicial da pr\xE9-visualiza\xE7\xE3o",
1746
- "modes.form": "Campos",
1747
- "modes.split": "Campos + p\xE1gina",
1934
+ "modes.form": "Apenas campos",
1935
+ "modes.split": "Campos + pr\xE9-visualiza\xE7\xE3o",
1748
1936
  "modes.preview": "Editor visual",
1749
1937
  previewModeHelp: "Cada ecr\xE3 de edi\xE7\xE3o abre neste modo, salvo se o tipo de conte\xFAdo definir o seu abaixo. Quem edita pode mudar durante a edi\xE7\xE3o; a mudan\xE7a n\xE3o fica guardada.",
1750
1938
  lazyEdit: "Clique para editar",
@@ -1752,8 +1940,8 @@ var pt_default = {
1752
1940
  lazyFields: "Campos personalizados carregados a pedido",
1753
1941
  lazyEditorsHelp: "Os campos personalizados indicados mostram uma pr\xE9-visualiza\xE7\xE3o s\xF3 de leitura at\xE9 receberem clique ou foco, para que p\xE1ginas grandes abram depressa. Separe os uids com v\xEDrgulas.",
1754
1942
  lazyFieldsInvalid: "Use at\xE9 {max} uids de campos personalizados, como plugin::ckeditor5.CKEditor ou global::meu-campo.",
1755
- modeForm: "Campos",
1756
- modeSplit: "Campos + p\xE1gina",
1943
+ modeForm: "Apenas campos",
1944
+ modeSplit: "Campos + pr\xE9-visualiza\xE7\xE3o",
1757
1945
  modePreview: "Editor visual",
1758
1946
  previewPane: "Pr\xE9-visualiza\xE7\xE3o da p\xE1gina",
1759
1947
  resize: "Redimensionar painel de pr\xE9-visualiza\xE7\xE3o",
@@ -1780,6 +1968,7 @@ var pt_default = {
1780
1968
  denied: "Acesso negado.",
1781
1969
  loadFailed: "N\xE3o foi poss\xEDvel carregar. Recarregue para tentar novamente.",
1782
1970
  invalidColor: "As cores devem usar #RRGGBB.",
1971
+ invalidUrl: "Os URL de pr\xE9-visualiza\xE7\xE3o devem ser endere\xE7os HTTP ou HTTPS completos.",
1783
1972
  previewLabel: "Pr\xE9-visualiza\xE7\xE3o da paleta",
1784
1973
  removeGroup: "Remover grupo",
1785
1974
  diagTitle: "Os grupos de blocos precisam de aten\xE7\xE3o; a publica\xE7\xE3o \xE9 recusada at\xE9 \xE0 corre\xE7\xE3o:",
@@ -1814,6 +2003,7 @@ var pt_default = {
1814
2003
  contentTypes: "Tipos de conte\xFAdo",
1815
2004
  contentTypesHelp: 'A galeria, os acorde\xF5es e a pr\xE9-visualiza\xE7\xE3o da p\xE1gina funcionam nestes tipos de conte\xFAdo (os que t\xEAm uma zona din\xE2mica). Desligue um para manter a edi\xE7\xE3o nativa. "Abre em" \xE9 como come\xE7a cada ecr\xE3 de edi\xE7\xE3o desse tipo; quem edita pode sempre mudar durante a edi\xE7\xE3o.',
1816
2005
  typeMode: "Abre em",
2006
+ typeAdvanced: "Op\xE7\xF5es do editor visual",
1817
2007
  modeDefault: "Predefini\xE7\xE3o ({mode})",
1818
2008
  blockModalDone: "Concluir",
1819
2009
  crashed: "O Blockscene parou aqui devido a um erro. O editor nativo n\xE3o foi afetado. Se voltar a acontecer, desligue o Blockscene em Settings, Blockscene.",
@@ -1848,6 +2038,9 @@ var pt_default = {
1848
2038
  unstar: "Remover dos favoritos",
1849
2039
  quickInsert: "Inserir {label}",
1850
2040
  insert: "Inserir",
2041
+ starterKits: "Come\xE7ar com um kit",
2042
+ starterKitsHelp: "Escolha uma estrutura inicial. Tudo \xE9 inserido como um rascunho edit\xE1vel e ainda n\xE3o guardado.",
2043
+ startBlank: "Come\xE7ar em branco",
1851
2044
  closeDetail: "Fechar detalhes",
1852
2045
  typology: "Tipologia",
1853
2046
  typologyAuto: "Autom\xE1tica ({name})",
@@ -1902,6 +2095,11 @@ var pt_default = {
1902
2095
  confirmDeleteTitle: "Eliminar bloco",
1903
2096
  confirmDelete: "Eliminar o bloco {name}?",
1904
2097
  confirmDeleteMarker: "Este \xE9 um marcador de grupo: s\xF3 o marcador \xE9 removido, n\xE3o os blocos dentro do grupo, e o grupo fica desequilibrado at\xE9 ser corrigido.",
2098
+ confirmDeleteGroupTitle: "Eliminar grupo",
2099
+ confirmDeleteGroup: "Eliminar o grupo {name}?",
2100
+ confirmDeleteGroupHint: "Este grupo cont\xE9m {count, plural, one {# bloco} other {# blocos}}. Escolha entre elimin\xE1-los ou mant\xEA-los na p\xE1gina sem o grupo.",
2101
+ keepGroupBlocks: "Eliminar grupo e manter blocos",
2102
+ deleteGroupAndBlocks: "{count, plural, =0 {Eliminar grupo} one {Eliminar grupo e # bloco} other {Eliminar grupo e # blocos}}",
1905
2103
  delete: "Eliminar",
1906
2104
  selectBlocks: "Selecionar blocos",
1907
2105
  selectAll: "Selecionar todos",
@@ -2096,6 +2294,7 @@ var pt_default = {
2096
2294
  gridCellMenu: "Mais a\xE7\xF5es para {label}",
2097
2295
  removeFromGroup: "Remover do grupo",
2098
2296
  gridAdd: "Adicionar bloco",
2297
+ groupAdd: "Adicionar bloco dentro de {label}",
2099
2298
  gridShowList: "Mostrar o grupo {label} como lista",
2100
2299
  gridShowGrid: "Mostrar o grupo {label} como grelha",
2101
2300
  layoutColumnsField: "Grelha do layout: campo das colunas",
@@ -2104,13 +2303,29 @@ var pt_default = {
2104
2303
  layoutOff: "Sem grelha",
2105
2304
  layoutNoMobile: "Nenhum",
2106
2305
  layoutHelp: "Os blocos do grupo aparecem em grelha no formul\xE1rio, com o n\xFAmero de colunas deste bloco.",
2107
- layoutNoFields: "Este bloco n\xE3o tem campo que guarde um n\xFAmero de colunas."
2306
+ layoutNoFields: "Este bloco n\xE3o tem campo que guarde um n\xFAmero de colunas.",
2307
+ "toolbar.versions": "Hist\xF3rico de vers\xF5es",
2308
+ versionsDenied: "Pe\xE7a a um administrador a permiss\xE3o Ler hist\xF3rico de vers\xF5es do Blockscene.",
2309
+ versionsDisabled: "O hist\xF3rico n\xE3o est\xE1 ativo para este tipo de conte\xFAdo. Pe\xE7a a um administrador para o ativar em Settings > Blockscene (settings.history.enabled).",
2310
+ versionsNew: "Guarde este conte\xFAdo primeiro para iniciar o hist\xF3rico.",
2311
+ versionsPerson: "Filtrar por pessoa",
2312
+ versionsEveryone: "Todas as pessoas",
2313
+ versionsCounts: "{total} blocos",
2314
+ versionsCountsMissing: "Contagem de blocos indispon\xEDvel (evento antigo ou n\xE3o registado).",
2315
+ versionsPage: "P\xE1gina {page} de {count}",
2316
+ versionsPrevious: "Anterior",
2317
+ versionsNext: "Seguinte",
2318
+ versionsViewing: "A ver a vers\xE3o de {date} por {person} (s\xF3 de leitura).",
2319
+ versionsCurrent: "Voltar ao rascunho atual",
2320
+ versionsMissing: "Alguns blocos, campos, ficheiros ou rela\xE7\xF5es j\xE1 n\xE3o est\xE3o dispon\xEDveis nesta pr\xE9via.",
2321
+ versionsBridgeLegacy: "Esta bridge n\xE3o suporta navega\xE7\xE3o s\xF3 de leitura. A intera\xE7\xE3o est\xE1 desativada; atualize a bridge para suportar readOnly.",
2322
+ historyExpired: "Snapshot j\xE1 n\xE3o est\xE1 dispon\xEDvel"
2108
2323
  };
2109
2324
 
2110
2325
  // admin/translations/fr.json
2111
2326
  var fr_default = {
2112
2327
  title: "Blockscene",
2113
- settings: "Galerie",
2328
+ settings: "G\xE9n\xE9ral",
2114
2329
  gallery: "Galerie de blocs",
2115
2330
  search: "Rechercher des blocs",
2116
2331
  clear: "Effacer la recherche",
@@ -2126,6 +2341,17 @@ var fr_default = {
2126
2341
  moreActions: "Plus d'actions",
2127
2342
  settingsTitle: "Blockscene",
2128
2343
  settingsIntro: "Vignettes de la galerie, palette des wireframes et pr\xE9f\xE9rences de l'\xE9diteur. Les changements s'appliquent \xE0 la prochaine ouverture de la galerie ; aucun rebuild n'est n\xE9cessaire.",
2344
+ settingsGeneral: "G\xE9n\xE9ral",
2345
+ settingsGeneralIntro: "D\xE9finissez le comportement de Blockscene dans l'\xE9diteur et les actions disponibles sur les lignes.",
2346
+ settingsPreview: "Aper\xE7u de page",
2347
+ settingsPreviewIntro: "Connectez l'aper\xE7u du frontend et configurez ses modes, sa barre d'outils et ses largeurs responsives.",
2348
+ settingsContentTypes: "Types de contenu",
2349
+ settingsContentTypesIntro: "Choisissez o\xF9 Blockscene est actif et personnalisez l'\xE9diteur visuel pour chaque type de contenu.",
2350
+ settingsGallery: "Galerie de blocs",
2351
+ settingsGalleryIntro: "Configurez les vignettes, les couleurs des wireframes, les types et les filtres de la galerie.",
2352
+ settingsHistory: "Historique et corbeille",
2353
+ settingsHistoryIntro: "G\xE9rez les versions, la conservation des activit\xE9s et les suppressions r\xE9cup\xE9rables.",
2354
+ historyUnavailable: "Les r\xE9glages d'historique et de corbeille n\xE9cessitent Strapi 5.",
2129
2355
  palette: "Palette des wireframes",
2130
2356
  background: "Fond",
2131
2357
  surface: "Surfaces",
@@ -2155,6 +2381,7 @@ var fr_default = {
2155
2381
  showCloseAll: "Afficher \xAB Tout replier \xBB",
2156
2382
  toggleHelp: "La barre de la zone affiche un seul bouton : avec les deux options activ\xE9es, il d\xE9plie tant qu'un bloc est repli\xE9 et sinon les replie tous ; avec une seule, il ne propose que cette action.",
2157
2383
  showRowThumbnails: "Afficher les miniatures des blocs dans les lignes",
2384
+ componentRowThumbnail: "Afficher la miniature dans la ligne de l'\xE9diteur",
2158
2385
  initialState: "\xC9tat initial des accord\xE9ons",
2159
2386
  "states.closed": "Tous ferm\xE9s",
2160
2387
  "states.open": "Tous ouverts",
@@ -2162,10 +2389,10 @@ var fr_default = {
2162
2389
  rememberHelp: "Seuls les boutons explicites tout ouvrir / tout fermer mettent la m\xE9moire \xE0 jour, par utilisateur et navigateur. Ouvrir un seul bloc ne change rien.",
2163
2390
  previewUrl: "URL de base de la route d'aper\xE7u",
2164
2391
  previewUrlHelp: "URL compl\xE8te de la route d'aper\xE7u de page de votre frontend, par ex. https://site.test/block-preview/page. Laissez vide pour r\xE9utiliser l'origine de l'aper\xE7u natif de Strapi (s'il est configur\xE9 pour le type de contenu) avec /block-preview/page. La route doit impl\xE9menter le pont (voir README).",
2165
- previewUrlEmpty: "Aucune URL d'aper\xE7u : les \xE9diteurs n'ont les modes Champs + page et \xC9diteur visuel que sur les types de contenu o\xF9 l'aper\xE7u natif de Strapi est configur\xE9. Ailleurs, le menu des modes n'appara\xEEt pas.",
2392
+ previewUrlEmpty: "Aucune URL d'aper\xE7u : les \xE9diteurs n'ont les modes Champs + aper\xE7u et \xC9diteur visuel que sur les types de contenu o\xF9 l'aper\xE7u natif de Strapi est configur\xE9. Ailleurs, le menu des modes n'appara\xEEt pas.",
2166
2393
  previewMode: "Mode d'aper\xE7u initial",
2167
- "modes.form": "Champs",
2168
- "modes.split": "Champs + page",
2394
+ "modes.form": "Champs uniquement",
2395
+ "modes.split": "Champs + aper\xE7u",
2169
2396
  "modes.preview": "\xC9diteur visuel",
2170
2397
  previewModeHelp: "Chaque vue d'\xE9dition s'ouvre dans ce mode, sauf si son type de contenu d\xE9finit le sien ci-dessous. L'\xE9diteur peut changer pendant l'\xE9dition ; ce choix n'est pas m\xE9moris\xE9.",
2171
2398
  lazyEdit: "Cliquer pour modifier",
@@ -2173,8 +2400,8 @@ var fr_default = {
2173
2400
  lazyFields: "Champs personnalis\xE9s charg\xE9s \xE0 la demande",
2174
2401
  lazyEditorsHelp: "Les champs personnalis\xE9s list\xE9s affichent un aper\xE7u en lecture seule jusqu'au clic ou au focus, pour que les grandes pages s'ouvrent vite. S\xE9parez les uids par des virgules.",
2175
2402
  lazyFieldsInvalid: "Utilisez jusqu'\xE0 {max} uids de champs personnalis\xE9s, comme plugin::ckeditor5.CKEditor ou global::mon-champ.",
2176
- modeForm: "Champs",
2177
- modeSplit: "Champs + page",
2403
+ modeForm: "Champs uniquement",
2404
+ modeSplit: "Champs + aper\xE7u",
2178
2405
  modePreview: "\xC9diteur visuel",
2179
2406
  previewPane: "Aper\xE7u de la page",
2180
2407
  resize: "Redimensionner le panneau d'aper\xE7u",
@@ -2201,6 +2428,7 @@ var fr_default = {
2201
2428
  denied: "Acc\xE8s refus\xE9.",
2202
2429
  loadFailed: "Impossible de charger les param\xE8tres. Rechargez pour r\xE9essayer.",
2203
2430
  invalidColor: "Les couleurs doivent utiliser #RRGGBB.",
2431
+ invalidUrl: "Les URL d'aper\xE7u doivent \xEAtre des adresses HTTP ou HTTPS compl\xE8tes.",
2204
2432
  previewLabel: "Aper\xE7u de la palette",
2205
2433
  removeGroup: "Supprimer le groupe",
2206
2434
  diagTitle: "Les groupes de blocs demandent une correction ; la publication est refus\xE9e tant qu'ils ne sont pas corrig\xE9s :",
@@ -2235,6 +2463,7 @@ var fr_default = {
2235
2463
  contentTypes: "Types de contenu",
2236
2464
  contentTypesHelp: "La galerie, les accord\xE9ons et l'aper\xE7u de page fonctionnent sur ces types de contenu (ceux qui ont une Dynamic Zone). D\xE9sactivez-en un pour garder son \xE9dition native. \xAB S'ouvre en \xBB d\xE9finit le mode de d\xE9part de chaque vue d'\xE9dition de ce type ; l'\xE9diteur peut toujours changer pendant l'\xE9dition.",
2237
2465
  typeMode: "S'ouvre en",
2466
+ typeAdvanced: "Options de l'\xE9diteur visuel",
2238
2467
  modeDefault: "Par d\xE9faut ({mode})",
2239
2468
  blockModalDone: "Termin\xE9",
2240
2469
  crashed: "Blockscene s'est arr\xEAt\xE9 ici \xE0 cause d'une erreur. L'\xE9diteur natif n'est pas touch\xE9. Si cela se reproduit, d\xE9sactivez Blockscene dans Settings, Blockscene.",
@@ -2269,6 +2498,9 @@ var fr_default = {
2269
2498
  unstar: "Retirer des favoris",
2270
2499
  quickInsert: "Ins\xE9rer {label}",
2271
2500
  insert: "Ins\xE9rer",
2501
+ starterKits: "D\xE9marrer avec un kit",
2502
+ starterKitsHelp: "Choisissez une structure de d\xE9part. Tout est ins\xE9r\xE9 comme brouillon modifiable et non enregistr\xE9.",
2503
+ startBlank: "Commencer vide",
2272
2504
  closeDetail: "Fermer les d\xE9tails",
2273
2505
  typology: "Typologie",
2274
2506
  typologyAuto: "Automatique ({name})",
@@ -2323,6 +2555,11 @@ var fr_default = {
2323
2555
  confirmDeleteTitle: "Supprimer le bloc",
2324
2556
  confirmDelete: "Supprimer le bloc {name} ?",
2325
2557
  confirmDeleteMarker: "C'est un marqueur de groupe : seul le marqueur est supprim\xE9, pas les blocs du groupe, et le groupe reste d\xE9s\xE9quilibr\xE9 jusqu'\xE0 sa correction.",
2558
+ confirmDeleteGroupTitle: "Supprimer le groupe",
2559
+ confirmDeleteGroup: "Supprimer le groupe {name} ?",
2560
+ confirmDeleteGroupHint: "Ce groupe contient {count, plural, one {# bloc} other {# blocs}}. Choisissez de les supprimer ou de les conserver dans la page sans le groupe.",
2561
+ keepGroupBlocks: "Supprimer le groupe, conserver les blocs",
2562
+ deleteGroupAndBlocks: "{count, plural, =0 {Supprimer le groupe} one {Supprimer le groupe et # bloc} other {Supprimer le groupe et # blocs}}",
2326
2563
  delete: "Supprimer",
2327
2564
  selectBlocks: "S\xE9lectionner des blocs",
2328
2565
  selectAll: "Tout s\xE9lectionner",
@@ -2517,6 +2754,7 @@ var fr_default = {
2517
2754
  gridCellMenu: "Plus d'actions pour {label}",
2518
2755
  removeFromGroup: "Retirer du groupe",
2519
2756
  gridAdd: "Ajouter un bloc",
2757
+ groupAdd: "Ajouter un bloc dans {label}",
2520
2758
  gridShowList: "Afficher le groupe {label} en liste",
2521
2759
  gridShowGrid: "Afficher le groupe {label} en grille",
2522
2760
  layoutColumnsField: "Grille de mise en page : champ des colonnes",
@@ -2525,13 +2763,29 @@ var fr_default = {
2525
2763
  layoutOff: "Pas de grille",
2526
2764
  layoutNoMobile: "Aucun",
2527
2765
  layoutHelp: "Les blocs du groupe s'affichent en grille dans le formulaire, avec le nombre de colonnes de ce bloc.",
2528
- layoutNoFields: "Ce bloc n'a aucun champ pouvant contenir un nombre de colonnes."
2766
+ layoutNoFields: "Ce bloc n'a aucun champ pouvant contenir un nombre de colonnes.",
2767
+ "toolbar.versions": "Historique des versions",
2768
+ versionsDenied: "Demandez \xE0 un administrateur la permission Lire l\u2019historique des versions de Blockscene.",
2769
+ versionsDisabled: "L\u2019historique n\u2019est pas activ\xE9 pour ce type de contenu. Demandez \xE0 un administrateur de l\u2019activer dans Settings > Blockscene (settings.history.enabled).",
2770
+ versionsNew: "Enregistrez d\u2019abord ce contenu pour commencer son historique.",
2771
+ versionsPerson: "Filtrer par personne",
2772
+ versionsEveryone: "Tout le monde",
2773
+ versionsCounts: "{total} blocs",
2774
+ versionsCountsMissing: "Nombre de blocs indisponible (\xE9v\xE9nement ancien ou non enregistr\xE9).",
2775
+ versionsPage: "Page {page} sur {count}",
2776
+ versionsPrevious: "Pr\xE9c\xE9dente",
2777
+ versionsNext: "Suivante",
2778
+ versionsViewing: "Version du {date} par {person} (lecture seule).",
2779
+ versionsCurrent: "Revenir au brouillon actuel",
2780
+ versionsMissing: "Certains blocs, champs, m\xE9dias ou relations ne sont plus disponibles dans cet aper\xE7u.",
2781
+ versionsBridgeLegacy: "Cette bridge ne prend pas en charge la navigation en lecture seule. L\u2019interaction est d\xE9sactiv\xE9e ; mettez la bridge \xE0 jour pour prendre en charge readOnly.",
2782
+ historyExpired: "Snapshot indisponible"
2529
2783
  };
2530
2784
 
2531
2785
  // admin/translations/es.json
2532
2786
  var es_default = {
2533
2787
  title: "Blockscene",
2534
- settings: "Galer\xEDa",
2788
+ settings: "General",
2535
2789
  gallery: "Galer\xEDa de bloques",
2536
2790
  search: "Buscar bloques",
2537
2791
  clear: "Borrar b\xFAsqueda",
@@ -2547,6 +2801,17 @@ var es_default = {
2547
2801
  moreActions: "M\xE1s acciones",
2548
2802
  settingsTitle: "Blockscene",
2549
2803
  settingsIntro: "Miniaturas de la galer\xEDa, paleta de los wireframes y preferencias del editor. Los cambios se aplican la pr\xF3xima vez que se abra la galer\xEDa; no hace falta rebuild.",
2804
+ settingsGeneral: "General",
2805
+ settingsGeneralIntro: "Define c\xF3mo funciona Blockscene en el editor y qu\xE9 acciones est\xE1n disponibles en las filas.",
2806
+ settingsPreview: "Vista previa de p\xE1gina",
2807
+ settingsPreviewIntro: "Conecta la vista previa del frontend y configura sus modos, barra de herramientas y anchos adaptables.",
2808
+ settingsContentTypes: "Tipos de contenido",
2809
+ settingsContentTypesIntro: "Elige d\xF3nde se activa Blockscene y personaliza el editor visual de cada tipo de contenido.",
2810
+ settingsGallery: "Galer\xEDa de bloques",
2811
+ settingsGalleryIntro: "Configura miniaturas, colores de wireframes, tipos y filtros de la galer\xEDa.",
2812
+ settingsHistory: "Historial y papelera",
2813
+ settingsHistoryIntro: "Controla versiones, retenci\xF3n de actividad y eliminaciones recuperables.",
2814
+ historyUnavailable: "La configuraci\xF3n de historial y papelera requiere Strapi 5.",
2550
2815
  palette: "Paleta de wireframes",
2551
2816
  background: "Fondo",
2552
2817
  surface: "Superficies",
@@ -2576,6 +2841,7 @@ var es_default = {
2576
2841
  showCloseAll: "Mostrar \xABContraer todo\xBB",
2577
2842
  toggleHelp: "La barra de la zona muestra un solo bot\xF3n: con ambas opciones activadas expande mientras haya alg\xFAn bloque contra\xEDdo y, si no, los contrae todos; con solo una, ofrece \xFAnicamente esa acci\xF3n.",
2578
2843
  showRowThumbnails: "Mostrar miniaturas de los bloques en las filas",
2844
+ componentRowThumbnail: "Mostrar miniatura en la fila del editor",
2579
2845
  initialState: "Estado inicial de los acordeones",
2580
2846
  "states.closed": "Todos cerrados",
2581
2847
  "states.open": "Todos abiertos",
@@ -2583,10 +2849,10 @@ var es_default = {
2583
2849
  rememberHelp: "Solo los botones expl\xEDcitos de abrir/cerrar todos actualizan la memoria, por usuario y navegador. Abrir un solo bloque no la cambia.",
2584
2850
  previewUrl: "URL base de la ruta de vista previa",
2585
2851
  previewUrlHelp: "URL completa de la ruta de vista previa de p\xE1gina de su frontend, p. ej. https://site.test/block-preview/page. D\xE9jela vac\xEDa para reutilizar el origen de la Vista previa nativa de Strapi (si est\xE1 configurada para el tipo de contenido) con /block-preview/page. La ruta debe implementar el puente (ver README).",
2586
- previewUrlEmpty: "No hay URL de vista previa: los editores solo tienen los modos Campos + p\xE1gina y Editor visual en los tipos de contenido con la vista previa nativa de Strapi configurada. En los dem\xE1s no aparece el men\xFA de modos.",
2852
+ previewUrlEmpty: "No hay URL de vista previa: los editores solo tienen los modos Campos + vista previa y Editor visual en los tipos de contenido con la vista previa nativa de Strapi configurada. En los dem\xE1s no aparece el men\xFA de modos.",
2587
2853
  previewMode: "Modo inicial de la vista previa",
2588
- "modes.form": "Campos",
2589
- "modes.split": "Campos + p\xE1gina",
2854
+ "modes.form": "Solo campos",
2855
+ "modes.split": "Campos + vista previa",
2590
2856
  "modes.preview": "Editor visual",
2591
2857
  previewModeHelp: "Cada vista de edici\xF3n se abre en este modo, salvo que su tipo de contenido defina el suyo abajo. Quien edita puede cambiarlo mientras edita; el cambio no se recuerda.",
2592
2858
  lazyEdit: "Haz clic para editar",
@@ -2594,8 +2860,8 @@ var es_default = {
2594
2860
  lazyFields: "Campos personalizados cargados bajo demanda",
2595
2861
  lazyEditorsHelp: "Los campos personalizados de la lista muestran una vista previa de solo lectura hasta recibir un clic o el foco, para que las p\xE1ginas grandes abran r\xE1pido. Separa los uids con comas.",
2596
2862
  lazyFieldsInvalid: "Usa hasta {max} uids de campos personalizados, como plugin::ckeditor5.CKEditor o global::mi-campo.",
2597
- modeForm: "Campos",
2598
- modeSplit: "Campos + p\xE1gina",
2863
+ modeForm: "Solo campos",
2864
+ modeSplit: "Campos + vista previa",
2599
2865
  modePreview: "Editor visual",
2600
2866
  previewPane: "Vista previa de la p\xE1gina",
2601
2867
  resize: "Redimensionar el panel de vista previa",
@@ -2622,6 +2888,7 @@ var es_default = {
2622
2888
  denied: "Acceso denegado.",
2623
2889
  loadFailed: "No se pudieron cargar los ajustes. Recargue para reintentar.",
2624
2890
  invalidColor: "Los colores deben usar #RRGGBB.",
2891
+ invalidUrl: "Las URL de vista previa deben ser direcciones HTTP o HTTPS completas.",
2625
2892
  previewLabel: "Vista previa de la paleta",
2626
2893
  removeGroup: "Eliminar grupo",
2627
2894
  diagTitle: "Los grupos de bloques necesitan atenci\xF3n; la publicaci\xF3n se rechaza hasta corregirlos:",
@@ -2656,6 +2923,7 @@ var es_default = {
2656
2923
  contentTypes: "Tipos de contenido",
2657
2924
  contentTypesHelp: 'La galer\xEDa, los acordeones y la vista previa de p\xE1gina funcionan en estos tipos de contenido (los que tienen una Dynamic Zone). Desactiva uno para dejar su edici\xF3n nativa. "Se abre en" define c\xF3mo empieza cada vista de edici\xF3n de ese tipo; quien edita puede cambiarlo mientras edita.',
2658
2925
  typeMode: "Se abre en",
2926
+ typeAdvanced: "Opciones del editor visual",
2659
2927
  modeDefault: "Predeterminado ({mode})",
2660
2928
  blockModalDone: "Listo",
2661
2929
  crashed: "Blockscene se detuvo aqu\xED por un error. El editor nativo no se ve afectado. Si vuelve a pasar, desactiva Blockscene en Settings, Blockscene.",
@@ -2690,6 +2958,9 @@ var es_default = {
2690
2958
  unstar: "Quitar de favoritos",
2691
2959
  quickInsert: "Insertar {label}",
2692
2960
  insert: "Insertar",
2961
+ starterKits: "Comenzar con un kit",
2962
+ starterKitsHelp: "Elige una estructura inicial. Todo se inserta como un borrador editable y sin guardar.",
2963
+ startBlank: "Comenzar en blanco",
2693
2964
  closeDetail: "Cerrar detalles",
2694
2965
  typology: "Tipolog\xEDa",
2695
2966
  typologyAuto: "Autom\xE1tica ({name})",
@@ -2744,6 +3015,11 @@ var es_default = {
2744
3015
  confirmDeleteTitle: "Eliminar bloque",
2745
3016
  confirmDelete: "\xBFEliminar el bloque {name}?",
2746
3017
  confirmDeleteMarker: "Es un marcador de grupo: solo se elimina el marcador, no los bloques del grupo, y el grupo queda desequilibrado hasta corregirlo.",
3018
+ confirmDeleteGroupTitle: "Eliminar grupo",
3019
+ confirmDeleteGroup: "\xBFEliminar el grupo {name}?",
3020
+ confirmDeleteGroupHint: "Este grupo contiene {count, plural, one {# bloque} other {# bloques}}. Elige si eliminarlos o conservarlos en la p\xE1gina sin el grupo.",
3021
+ keepGroupBlocks: "Eliminar grupo y conservar bloques",
3022
+ deleteGroupAndBlocks: "{count, plural, =0 {Eliminar grupo} one {Eliminar grupo y # bloque} other {Eliminar grupo y # bloques}}",
2747
3023
  delete: "Eliminar",
2748
3024
  selectBlocks: "Seleccionar bloques",
2749
3025
  selectAll: "Seleccionar todos",
@@ -2938,6 +3214,7 @@ var es_default = {
2938
3214
  gridCellMenu: "M\xE1s acciones para {label}",
2939
3215
  removeFromGroup: "Quitar del grupo",
2940
3216
  gridAdd: "A\xF1adir un bloque",
3217
+ groupAdd: "A\xF1adir un bloque dentro de {label}",
2941
3218
  gridShowList: "Mostrar el grupo {label} como lista",
2942
3219
  gridShowGrid: "Mostrar el grupo {label} como cuadr\xEDcula",
2943
3220
  layoutColumnsField: "Cuadr\xEDcula de dise\xF1o: campo de columnas",
@@ -2946,13 +3223,29 @@ var es_default = {
2946
3223
  layoutOff: "Sin cuadr\xEDcula",
2947
3224
  layoutNoMobile: "Ninguno",
2948
3225
  layoutHelp: "Los bloques del grupo se muestran en cuadr\xEDcula en el formulario, con el n\xFAmero de columnas de este bloque.",
2949
- layoutNoFields: "Este bloque no tiene ning\xFAn campo que pueda guardar un n\xFAmero de columnas."
3226
+ layoutNoFields: "Este bloque no tiene ning\xFAn campo que pueda guardar un n\xFAmero de columnas.",
3227
+ "toolbar.versions": "Historial de versiones",
3228
+ versionsDenied: "Pide a un administrador el permiso Leer historial de versiones de Blockscene.",
3229
+ versionsDisabled: "El historial no est\xE1 activo para este tipo de contenido. Pide a un administrador que lo active en Settings > Blockscene (settings.history.enabled).",
3230
+ versionsNew: "Guarda primero este contenido para iniciar su historial.",
3231
+ versionsPerson: "Filtrar por persona",
3232
+ versionsEveryone: "Todas las personas",
3233
+ versionsCounts: "{total} bloques",
3234
+ versionsCountsMissing: "Recuento de bloques no disponible (evento antiguo o no registrado).",
3235
+ versionsPage: "P\xE1gina {page} de {count}",
3236
+ versionsPrevious: "Anterior",
3237
+ versionsNext: "Siguiente",
3238
+ versionsViewing: "Viendo la versi\xF3n del {date} por {person} (solo lectura).",
3239
+ versionsCurrent: "Volver al borrador actual",
3240
+ versionsMissing: "Algunos bloques, campos, archivos o relaciones ya no est\xE1n disponibles en esta vista previa.",
3241
+ versionsBridgeLegacy: "Esta bridge no admite navegaci\xF3n de solo lectura. La interacci\xF3n est\xE1 desactivada; actualiza la bridge para admitir readOnly.",
3242
+ historyExpired: "Snapshot ya no disponible"
2950
3243
  };
2951
3244
 
2952
3245
  // admin/translations/de.json
2953
3246
  var de_default = {
2954
3247
  title: "Blockscene",
2955
- settings: "Galerie",
3248
+ settings: "Allgemein",
2956
3249
  gallery: "Blockgalerie",
2957
3250
  search: "Bl\xF6cke suchen",
2958
3251
  clear: "Suche l\xF6schen",
@@ -2968,6 +3261,17 @@ var de_default = {
2968
3261
  moreActions: "Weitere Aktionen",
2969
3262
  settingsTitle: "Blockscene",
2970
3263
  settingsIntro: "Galerie-Vorschaubilder, Wireframe-Palette und Editor-Einstellungen. \xC4nderungen gelten beim n\xE4chsten \xD6ffnen der Galerie; kein Rebuild n\xF6tig.",
3264
+ settingsGeneral: "Allgemein",
3265
+ settingsGeneralIntro: "Lege fest, wie Blockscene im Editor arbeitet und welche Zeilenaktionen verf\xFCgbar sind.",
3266
+ settingsPreview: "Seitenvorschau",
3267
+ settingsPreviewIntro: "Verbinde die Frontend-Vorschau und konfiguriere Modi, Werkzeugleiste und responsive Breiten.",
3268
+ settingsContentTypes: "Inhaltstypen",
3269
+ settingsContentTypesIntro: "W\xE4hle, wo Blockscene aktiv ist, und passe den visuellen Editor je Inhaltstyp an.",
3270
+ settingsGallery: "Blockgalerie",
3271
+ settingsGalleryIntro: "Konfiguriere Vorschaubilder, Wireframe-Farben, Blocktypen und Filter.",
3272
+ settingsHistory: "Verlauf und Papierkorb",
3273
+ settingsHistoryIntro: "Steuere Versionen, Aufbewahrung von Aktivit\xE4ten und wiederherstellbare L\xF6schungen.",
3274
+ historyUnavailable: "Verlauf und Papierkorb erfordern Strapi 5.",
2971
3275
  palette: "Wireframe-Palette",
2972
3276
  background: "Hintergrund",
2973
3277
  surface: "Fl\xE4chen",
@@ -2997,6 +3301,7 @@ var de_default = {
2997
3301
  showCloseAll: "\u201EAlle zuklappen\u201C anzeigen",
2998
3302
  toggleHelp: "Die Zonenleiste zeigt einen einzigen Button: Sind beide Optionen an, klappt er auf, solange ein Block zugeklappt ist, sonst klappt er alle zu; ist nur eine an, bietet er nur diese Aktion.",
2999
3303
  showRowThumbnails: "Blockvorschaubilder in den Zeilen anzeigen",
3304
+ componentRowThumbnail: "Vorschaubild in der Editorzeile anzeigen",
3000
3305
  initialState: "Anfangszustand der Akkordeons",
3001
3306
  "states.closed": "Alle geschlossen",
3002
3307
  "states.open": "Alle ge\xF6ffnet",
@@ -3004,10 +3309,10 @@ var de_default = {
3004
3309
  rememberHelp: "Nur die expliziten Schaltfl\xE4chen \u201Ealle \xF6ffnen/schlie\xDFen\u201C aktualisieren die Erinnerung, pro Benutzer und Browser. Das \xD6ffnen eines einzelnen Blocks \xE4ndert nichts.",
3005
3310
  previewUrl: "Basis-URL der Vorschauroute",
3006
3311
  previewUrlHelp: "Vollst\xE4ndige URL der Seitenvorschau-Route Ihres Frontends, z. B. https://site.test/block-preview/page. Leer lassen, um den Ursprung der nativen Strapi-Vorschau (wenn f\xFCr den Inhaltstyp konfiguriert) mit /block-preview/page zu verwenden. Die Route muss die Bridge implementieren (siehe README).",
3007
- previewUrlEmpty: "Keine Vorschau-URL gesetzt: Redakteure erhalten die Modi Felder + Seite und Visueller Editor nur bei Inhaltstypen, f\xFCr die Strapis native Vorschau konfiguriert ist. Sonst wird das Modusmen\xFC nicht angezeigt.",
3312
+ previewUrlEmpty: "Keine Vorschau-URL gesetzt: Redakteure erhalten die Modi Felder + Vorschau und Visueller Editor nur bei Inhaltstypen, f\xFCr die Strapis native Vorschau konfiguriert ist. Sonst wird das Modusmen\xFC nicht angezeigt.",
3008
3313
  previewMode: "Anf\xE4nglicher Vorschaumodus",
3009
- "modes.form": "Felder",
3010
- "modes.split": "Felder + Seite",
3314
+ "modes.form": "Nur Felder",
3315
+ "modes.split": "Felder + Vorschau",
3011
3316
  "modes.preview": "Visueller Editor",
3012
3317
  previewModeHelp: "Jede Bearbeitungsansicht \xF6ffnet in diesem Modus, au\xDFer ihr Inhaltstyp legt unten einen eigenen fest. Beim Bearbeiten l\xE4sst sich wechseln; der Wechsel wird nicht gespeichert.",
3013
3318
  lazyEdit: "Zum Bearbeiten klicken",
@@ -3015,8 +3320,8 @@ var de_default = {
3015
3320
  lazyFields: "Bei Bedarf geladene benutzerdefinierte Felder",
3016
3321
  lazyEditorsHelp: "Die aufgef\xFChrten benutzerdefinierten Felder zeigen eine schreibgesch\xFCtzte Vorschau, bis sie angeklickt oder fokussiert werden, damit gro\xDFe Seiten schnell \xF6ffnen. Uids durch Kommas trennen.",
3017
3322
  lazyFieldsInvalid: "Bis zu {max} Uids benutzerdefinierter Felder verwenden, z. B. plugin::ckeditor5.CKEditor oder global::mein-feld.",
3018
- modeForm: "Felder",
3019
- modeSplit: "Felder + Seite",
3323
+ modeForm: "Nur Felder",
3324
+ modeSplit: "Felder + Vorschau",
3020
3325
  modePreview: "Visueller Editor",
3021
3326
  previewPane: "Seitenvorschau",
3022
3327
  resize: "Vorschaubereich anpassen",
@@ -3043,6 +3348,7 @@ var de_default = {
3043
3348
  denied: "Zugriff verweigert.",
3044
3349
  loadFailed: "Einstellungen konnten nicht geladen werden. Neu laden, um es erneut zu versuchen.",
3045
3350
  invalidColor: "Farben m\xFCssen #RRGGBB verwenden.",
3351
+ invalidUrl: "Vorschau-URLs m\xFCssen vollst\xE4ndige HTTP- oder HTTPS-Adressen sein.",
3046
3352
  previewLabel: "Palettenvorschau",
3047
3353
  removeGroup: "Gruppe entfernen",
3048
3354
  diagTitle: "Blockgruppen m\xFCssen korrigiert werden; das Ver\xF6ffentlichen wird bis dahin abgelehnt:",
@@ -3077,6 +3383,7 @@ var de_default = {
3077
3383
  contentTypes: "Inhaltstypen",
3078
3384
  contentTypesHelp: "Galerie, Akkordeons und Seitenvorschau arbeiten auf diesen Inhaltstypen (denen mit einer Dynamic Zone). Schalte einen aus, um seine Bearbeitung nativ zu lassen. \u201E\xD6ffnet in\u201C bestimmt, wie jede Bearbeitungsansicht dieses Typs startet; beim Bearbeiten l\xE4sst sich weiter wechseln.",
3079
3385
  typeMode: "\xD6ffnet in",
3386
+ typeAdvanced: "Optionen des visuellen Editors",
3080
3387
  modeDefault: "Standard ({mode})",
3081
3388
  blockModalDone: "Fertig",
3082
3389
  crashed: "Blockscene wurde hier wegen eines Fehlers beendet. Der native Editor ist nicht betroffen. Passiert es erneut, schalte Blockscene unter Settings, Blockscene aus.",
@@ -3111,6 +3418,9 @@ var de_default = {
3111
3418
  unstar: "Aus Favoriten entfernen",
3112
3419
  quickInsert: "{label} einf\xFCgen",
3113
3420
  insert: "Einf\xFCgen",
3421
+ starterKits: "Mit einem Kit starten",
3422
+ starterKitsHelp: "W\xE4hlen Sie eine Ausgangsstruktur. Alles wird als ungespeicherter, bearbeitbarer Entwurf eingef\xFCgt.",
3423
+ startBlank: "Leer beginnen",
3114
3424
  closeDetail: "Details schlie\xDFen",
3115
3425
  typology: "Typologie",
3116
3426
  typologyAuto: "Automatisch ({name})",
@@ -3165,6 +3475,11 @@ var de_default = {
3165
3475
  confirmDeleteTitle: "Block l\xF6schen",
3166
3476
  confirmDelete: "Block {name} l\xF6schen?",
3167
3477
  confirmDeleteMarker: "Dies ist eine Gruppenmarkierung: Nur die Markierung wird entfernt, nicht die Bl\xF6cke der Gruppe, und die Gruppe bleibt unausgeglichen, bis sie korrigiert ist.",
3478
+ confirmDeleteGroupTitle: "Gruppe l\xF6schen",
3479
+ confirmDeleteGroup: "Gruppe {name} l\xF6schen?",
3480
+ confirmDeleteGroupHint: "Diese Gruppe enth\xE4lt {count, plural, one {# Block} other {# Bl\xF6cke}}. L\xF6schen Sie sie oder behalten Sie sie ohne die Gruppe auf der Seite.",
3481
+ keepGroupBlocks: "Gruppe entfernen, Bl\xF6cke behalten",
3482
+ deleteGroupAndBlocks: "{count, plural, =0 {Gruppe l\xF6schen} one {Gruppe und # Block l\xF6schen} other {Gruppe und # Bl\xF6cke l\xF6schen}}",
3168
3483
  delete: "L\xF6schen",
3169
3484
  selectBlocks: "Bl\xF6cke ausw\xE4hlen",
3170
3485
  selectAll: "Alle ausw\xE4hlen",
@@ -3359,6 +3674,7 @@ var de_default = {
3359
3674
  gridCellMenu: "Weitere Aktionen f\xFCr {label}",
3360
3675
  removeFromGroup: "Aus der Gruppe entfernen",
3361
3676
  gridAdd: "Block hinzuf\xFCgen",
3677
+ groupAdd: "Block in {label} hinzuf\xFCgen",
3362
3678
  gridShowList: "Gruppe {label} als Liste anzeigen",
3363
3679
  gridShowGrid: "Gruppe {label} als Raster anzeigen",
3364
3680
  layoutColumnsField: "Layout-Raster: Feld der Spalten",
@@ -3367,13 +3683,29 @@ var de_default = {
3367
3683
  layoutOff: "Kein Raster",
3368
3684
  layoutNoMobile: "Keines",
3369
3685
  layoutHelp: "Die Bl\xF6cke der Gruppe erscheinen im Formular als Raster, mit der Spaltenzahl dieses Blocks.",
3370
- layoutNoFields: "Dieser Block hat kein Feld, das eine Spaltenzahl enthalten kann."
3686
+ layoutNoFields: "Dieser Block hat kein Feld, das eine Spaltenzahl enthalten kann.",
3687
+ "toolbar.versions": "Versionsverlauf",
3688
+ versionsDenied: "Bitte einen Administrator um die Blockscene-Berechtigung zum Lesen des Versionsverlaufs.",
3689
+ versionsDisabled: "Der Verlauf ist f\xFCr diesen Inhaltstyp nicht aktiviert. Bitte einen Administrator, ihn unter Settings > Blockscene zu aktivieren (settings.history.enabled).",
3690
+ versionsNew: "Speichere diesen Eintrag zuerst, um seinen Verlauf zu beginnen.",
3691
+ versionsPerson: "Nach Person filtern",
3692
+ versionsEveryone: "Alle Personen",
3693
+ versionsCounts: "{total} Bl\xF6cke",
3694
+ versionsCountsMissing: "Blockanzahl nicht verf\xFCgbar (\xE4lteres oder nicht aufgezeichnetes Ereignis).",
3695
+ versionsPage: "Seite {page} von {count}",
3696
+ versionsPrevious: "Zur\xFCck",
3697
+ versionsNext: "Weiter",
3698
+ versionsViewing: "Version vom {date} von {person} (schreibgesch\xFCtzt).",
3699
+ versionsCurrent: "Zur\xFCck zum aktuellen Entwurf",
3700
+ versionsMissing: "Einige Bl\xF6cke, Felder, Medien oder Beziehungen sind in dieser Vorschau nicht mehr verf\xFCgbar.",
3701
+ versionsBridgeLegacy: "Diese Bridge unterst\xFCtzt keine schreibgesch\xFCtzte Navigation. Interaktion ist deaktiviert; aktualisiere die Bridge f\xFCr readOnly.",
3702
+ historyExpired: "Snapshot nicht mehr verf\xFCgbar"
3371
3703
  };
3372
3704
 
3373
3705
  // admin/translations/it.json
3374
3706
  var it_default = {
3375
3707
  title: "Blockscene",
3376
- settings: "Galleria",
3708
+ settings: "Generali",
3377
3709
  gallery: "Galleria dei blocchi",
3378
3710
  search: "Cerca blocchi",
3379
3711
  clear: "Cancella ricerca",
@@ -3389,6 +3721,17 @@ var it_default = {
3389
3721
  moreActions: "Altre azioni",
3390
3722
  settingsTitle: "Blockscene",
3391
3723
  settingsIntro: "Miniature della galleria, palette dei wireframe e preferenze dell'editor. Le modifiche valgono alla prossima apertura della galleria; non serve alcun rebuild.",
3724
+ settingsGeneral: "Generali",
3725
+ settingsGeneralIntro: "Configura il comportamento di Blockscene nell'editor e le azioni disponibili sulle righe.",
3726
+ settingsPreview: "Anteprima pagina",
3727
+ settingsPreviewIntro: "Collega l'anteprima del frontend e configura modalit\xE0, barra degli strumenti e larghezze responsive.",
3728
+ settingsContentTypes: "Tipi di contenuto",
3729
+ settingsContentTypesIntro: "Scegli dove attivare Blockscene e personalizza l'editor visivo per ogni tipo di contenuto.",
3730
+ settingsGallery: "Galleria dei blocchi",
3731
+ settingsGalleryIntro: "Configura miniature, colori dei wireframe, tipi e filtri della galleria.",
3732
+ settingsHistory: "Cronologia e cestino",
3733
+ settingsHistoryIntro: "Gestisci versioni, conservazione delle attivit\xE0 ed eliminazioni recuperabili.",
3734
+ historyUnavailable: "Le impostazioni di cronologia e cestino richiedono Strapi 5.",
3392
3735
  palette: "Palette dei wireframe",
3393
3736
  background: "Sfondo",
3394
3737
  surface: "Superfici",
@@ -3418,6 +3761,7 @@ var it_default = {
3418
3761
  showCloseAll: 'Mostra "Comprimi tutto"',
3419
3762
  toggleHelp: "La barra della zona mostra un solo pulsante: con entrambe le opzioni attive espande finch\xE9 c'\xE8 un blocco compresso, altrimenti li comprime tutti; con una sola, offre solo quell'azione.",
3420
3763
  showRowThumbnails: "Mostra le miniature dei blocchi nelle righe",
3764
+ componentRowThumbnail: "Mostra la miniatura nella riga dell'editor",
3421
3765
  initialState: "Stato iniziale delle fisarmoniche",
3422
3766
  "states.closed": "Tutte chiuse",
3423
3767
  "states.open": "Tutte aperte",
@@ -3425,10 +3769,10 @@ var it_default = {
3425
3769
  rememberHelp: "Solo i pulsanti espliciti apri tutti / chiudi tutti aggiornano la memoria, per utente e browser. Aprire un singolo blocco non la cambia.",
3426
3770
  previewUrl: "URL di base della route di anteprima",
3427
3771
  previewUrlHelp: "URL completo della route di anteprima pagina del tuo frontend, ad es. https://site.test/block-preview/page. Lascia vuoto per riutilizzare l'origine dell'Anteprima nativa di Strapi (se configurata per il tipo di contenuto) con /block-preview/page. La route deve implementare il bridge (vedi README).",
3428
- previewUrlEmpty: "Nessun URL di anteprima impostato: gli editor hanno le modalit\xE0 Campi + pagina ed Editor visivo solo sui tipi di contenuto con l'anteprima nativa di Strapi configurata. Altrove il menu delle modalit\xE0 non compare.",
3772
+ previewUrlEmpty: "Nessun URL di anteprima impostato: gli editor hanno le modalit\xE0 Campi + anteprima ed Editor visivo solo sui tipi di contenuto con l'anteprima nativa di Strapi configurata. Altrove il menu delle modalit\xE0 non compare.",
3429
3773
  previewMode: "Modalit\xE0 iniziale dell'anteprima",
3430
- "modes.form": "Campi",
3431
- "modes.split": "Campi + pagina",
3774
+ "modes.form": "Solo campi",
3775
+ "modes.split": "Campi + anteprima",
3432
3776
  "modes.preview": "Editor visivo",
3433
3777
  previewModeHelp: "Ogni vista di modifica si apre in questo modo, a meno che il suo tipo di contenuto ne imposti uno proprio qui sotto. Durante la modifica si pu\xF2 cambiare; la scelta non viene ricordata.",
3434
3778
  lazyEdit: "Fai clic per modificare",
@@ -3436,8 +3780,8 @@ var it_default = {
3436
3780
  lazyFields: "Campi personalizzati caricati su richiesta",
3437
3781
  lazyEditorsHelp: "I campi personalizzati elencati mostrano un'anteprima di sola lettura finch\xE9 non ricevono un clic o il focus, cos\xEC le pagine grandi si aprono in fretta. Separa gli uid con virgole.",
3438
3782
  lazyFieldsInvalid: "Usa fino a {max} uid di campi personalizzati, come plugin::ckeditor5.CKEditor o global::mio-campo.",
3439
- modeForm: "Campi",
3440
- modeSplit: "Campi + pagina",
3783
+ modeForm: "Solo campi",
3784
+ modeSplit: "Campi + anteprima",
3441
3785
  modePreview: "Editor visivo",
3442
3786
  previewPane: "Anteprima della pagina",
3443
3787
  resize: "Ridimensiona il pannello di anteprima",
@@ -3464,6 +3808,7 @@ var it_default = {
3464
3808
  denied: "Accesso negato.",
3465
3809
  loadFailed: "Impossibile caricare le impostazioni. Ricarica per riprovare.",
3466
3810
  invalidColor: "I colori devono usare #RRGGBB.",
3811
+ invalidUrl: "Gli URL di anteprima devono essere indirizzi HTTP o HTTPS completi.",
3467
3812
  previewLabel: "Anteprima della palette",
3468
3813
  removeGroup: "Rimuovi gruppo",
3469
3814
  diagTitle: "I gruppi di blocchi richiedono attenzione; la pubblicazione \xE8 rifiutata finch\xE9 non vengono corretti:",
@@ -3498,6 +3843,7 @@ var it_default = {
3498
3843
  contentTypes: "Tipi di contenuto",
3499
3844
  contentTypesHelp: "La galleria, le fisarmoniche e l'anteprima di pagina funzionano su questi tipi di contenuto (quelli con una Dynamic Zone). Disattivane uno per lasciarne la modifica nativa. \xABSi apre in\xBB \xE8 il modo in cui parte ogni vista di modifica di quel tipo; durante la modifica si pu\xF2 sempre cambiare.",
3500
3845
  typeMode: "Si apre in",
3846
+ typeAdvanced: "Opzioni dell'editor visivo",
3501
3847
  modeDefault: "Predefinito ({mode})",
3502
3848
  blockModalDone: "Fatto",
3503
3849
  crashed: "Blockscene si \xE8 fermato qui a causa di un errore. L'editor nativo non \xE8 toccato. Se succede di nuovo, disattiva Blockscene in Settings, Blockscene.",
@@ -3532,6 +3878,9 @@ var it_default = {
3532
3878
  unstar: "Rimuovi dai preferiti",
3533
3879
  quickInsert: "Inserisci {label}",
3534
3880
  insert: "Inserisci",
3881
+ starterKits: "Inizia con un kit",
3882
+ starterKitsHelp: "Scegli una struttura iniziale. Tutto viene inserito come bozza modificabile e non salvata.",
3883
+ startBlank: "Inizia da zero",
3535
3884
  closeDetail: "Chiudi dettagli",
3536
3885
  typology: "Tipologia",
3537
3886
  typologyAuto: "Automatica ({name})",
@@ -3586,6 +3935,11 @@ var it_default = {
3586
3935
  confirmDeleteTitle: "Elimina blocco",
3587
3936
  confirmDelete: "Eliminare il blocco {name}?",
3588
3937
  confirmDeleteMarker: "\xC8 un marcatore di gruppo: viene rimosso solo il marcatore, non i blocchi del gruppo, e il gruppo resta sbilanciato finch\xE9 non viene corretto.",
3938
+ confirmDeleteGroupTitle: "Elimina gruppo",
3939
+ confirmDeleteGroup: "Eliminare il gruppo {name}?",
3940
+ confirmDeleteGroupHint: "Questo gruppo contiene {count, plural, one {# blocco} other {# blocchi}}. Scegli se eliminarli o mantenerli nella pagina senza il gruppo.",
3941
+ keepGroupBlocks: "Rimuovi il gruppo, mantieni i blocchi",
3942
+ deleteGroupAndBlocks: "{count, plural, =0 {Elimina gruppo} one {Elimina gruppo e # blocco} other {Elimina gruppo e # blocchi}}",
3589
3943
  delete: "Elimina",
3590
3944
  selectBlocks: "Seleziona blocchi",
3591
3945
  selectAll: "Seleziona tutti",
@@ -3780,6 +4134,7 @@ var it_default = {
3780
4134
  gridCellMenu: "Altre azioni per {label}",
3781
4135
  removeFromGroup: "Rimuovi dal gruppo",
3782
4136
  gridAdd: "Aggiungi un blocco",
4137
+ groupAdd: "Aggiungi un blocco dentro {label}",
3783
4138
  gridShowList: "Mostra il gruppo {label} come elenco",
3784
4139
  gridShowGrid: "Mostra il gruppo {label} come griglia",
3785
4140
  layoutColumnsField: "Griglia di layout: campo delle colonne",
@@ -3788,13 +4143,29 @@ var it_default = {
3788
4143
  layoutOff: "Nessuna griglia",
3789
4144
  layoutNoMobile: "Nessuno",
3790
4145
  layoutHelp: "I blocchi del gruppo appaiono in griglia nel modulo, con il numero di colonne di questo blocco.",
3791
- layoutNoFields: "Questo blocco non ha un campo che possa contenere un numero di colonne."
4146
+ layoutNoFields: "Questo blocco non ha un campo che possa contenere un numero di colonne.",
4147
+ "toolbar.versions": "Cronologia delle versioni",
4148
+ versionsDenied: "Chiedi a un amministratore il permesso Leggere la cronologia delle versioni di Blockscene.",
4149
+ versionsDisabled: "La cronologia non \xE8 attiva per questo tipo di contenuto. Chiedi a un amministratore di attivarla in Settings > Blockscene (settings.history.enabled).",
4150
+ versionsNew: "Salva prima questo contenuto per avviare la cronologia.",
4151
+ versionsPerson: "Filtra per persona",
4152
+ versionsEveryone: "Tutte le persone",
4153
+ versionsCounts: "{total} blocchi",
4154
+ versionsCountsMissing: "Conteggio dei blocchi non disponibile (evento vecchio o non registrato).",
4155
+ versionsPage: "Pagina {page} di {count}",
4156
+ versionsPrevious: "Precedente",
4157
+ versionsNext: "Successiva",
4158
+ versionsViewing: "Versione del {date} di {person} (sola lettura).",
4159
+ versionsCurrent: "Torna alla bozza attuale",
4160
+ versionsMissing: "Alcuni blocchi, campi, media o relazioni non sono pi\xF9 disponibili in questa anteprima.",
4161
+ versionsBridgeLegacy: "Questa bridge non supporta la navigazione in sola lettura. Interazione disattivata; aggiorna la bridge per supportare readOnly.",
4162
+ historyExpired: "Snapshot non pi\xF9 disponibile"
3792
4163
  };
3793
4164
 
3794
4165
  // admin/translations/nl.json
3795
4166
  var nl_default = {
3796
4167
  title: "Blockscene",
3797
- settings: "Galerij",
4168
+ settings: "Algemeen",
3798
4169
  gallery: "Blokkengalerij",
3799
4170
  search: "Blokken zoeken",
3800
4171
  clear: "Zoekopdracht wissen",
@@ -3810,6 +4181,17 @@ var nl_default = {
3810
4181
  moreActions: "Meer acties",
3811
4182
  settingsTitle: "Blockscene",
3812
4183
  settingsIntro: "Galerijminiaturen, wireframe-palet en editorvoorkeuren. Wijzigingen gelden bij de volgende opening van de galerij; geen rebuild nodig.",
4184
+ settingsGeneral: "Algemeen",
4185
+ settingsGeneralIntro: "Bepaal hoe Blockscene in de editor werkt en welke rijacties beschikbaar zijn.",
4186
+ settingsPreview: "Paginavoorbeeld",
4187
+ settingsPreviewIntro: "Koppel het frontendvoorbeeld en configureer modi, werkbalk en responsieve breedtes.",
4188
+ settingsContentTypes: "Contenttypes",
4189
+ settingsContentTypesIntro: "Kies waar Blockscene actief is en pas de visuele editor per contenttype aan.",
4190
+ settingsGallery: "Blokkengalerij",
4191
+ settingsGalleryIntro: "Configureer miniaturen, wireframekleuren, bloktypen en filters.",
4192
+ settingsHistory: "Geschiedenis en prullenbak",
4193
+ settingsHistoryIntro: "Beheer versies, activiteitsbewaring en herstelbare verwijderingen.",
4194
+ historyUnavailable: "Instellingen voor geschiedenis en prullenbak vereisen Strapi 5.",
3813
4195
  palette: "Wireframe-palet",
3814
4196
  background: "Achtergrond",
3815
4197
  surface: "Vlakken",
@@ -3839,6 +4221,7 @@ var nl_default = {
3839
4221
  showCloseAll: '"Alles inklappen" tonen',
3840
4222
  toggleHelp: "De zonebalk toont \xE9\xE9n knop: staan beide opties aan, dan klapt hij uit zolang er een blok ingeklapt is en klapt hij anders alles in; staat er maar \xE9\xE9n aan, dan biedt hij alleen die actie.",
3841
4223
  showRowThumbnails: "Blokminiaturen in de rijen tonen",
4224
+ componentRowThumbnail: "Miniatuur in de editorrij tonen",
3842
4225
  initialState: "Beginstand van de accordeons",
3843
4226
  "states.closed": "Alle gesloten",
3844
4227
  "states.open": "Alle open",
@@ -3846,10 +4229,10 @@ var nl_default = {
3846
4229
  rememberHelp: "Alleen de expliciete knoppen alles openen / alles sluiten werken het geheugen bij, per gebruiker en browser. E\xE9n blok openen verandert niets.",
3847
4230
  previewUrl: "Basis-URL van de voorbeeldroute",
3848
4231
  previewUrlHelp: "Volledige URL van de paginavoorbeeldroute van uw frontend, bijv. https://site.test/block-preview/page. Laat leeg om de oorsprong van Strapi's native Preview (indien geconfigureerd voor het contenttype) met /block-preview/page te hergebruiken. De route moet de bridge implementeren (zie README).",
3849
- previewUrlEmpty: "Geen preview-URL ingesteld: redacteuren krijgen de modi Velden + pagina en Visuele editor alleen bij inhoudstypes waarvoor de native Preview van Strapi is ingesteld. Elders verschijnt het modusmenu niet.",
4232
+ previewUrlEmpty: "Geen preview-URL ingesteld: redacteuren krijgen de modi Velden + voorbeeld en Visuele editor alleen bij inhoudstypes waarvoor de native Preview van Strapi is ingesteld. Elders verschijnt het modusmenu niet.",
3850
4233
  previewMode: "Beginmodus van het voorbeeld",
3851
- "modes.form": "Velden",
3852
- "modes.split": "Velden + pagina",
4234
+ "modes.form": "Alleen velden",
4235
+ "modes.split": "Velden + voorbeeld",
3853
4236
  "modes.preview": "Visuele editor",
3854
4237
  previewModeHelp: "Elke bewerkweergave opent in deze modus, tenzij het contenttype hieronder een eigen modus instelt. Tijdens het bewerken kan je wisselen; die keuze wordt niet onthouden.",
3855
4238
  lazyEdit: "Klik om te bewerken",
@@ -3857,8 +4240,8 @@ var nl_default = {
3857
4240
  lazyFields: "Aangepaste velden die op aanvraag laden",
3858
4241
  lazyEditorsHelp: "De vermelde aangepaste velden tonen een alleen-lezen voorbeeld tot ze worden aangeklikt of focus krijgen, zodat grote pagina's snel openen. Scheid uids met komma's.",
3859
4242
  lazyFieldsInvalid: "Gebruik maximaal {max} uids van aangepaste velden, zoals plugin::ckeditor5.CKEditor of global::mijn-veld.",
3860
- modeForm: "Velden",
3861
- modeSplit: "Velden + pagina",
4243
+ modeForm: "Alleen velden",
4244
+ modeSplit: "Velden + voorbeeld",
3862
4245
  modePreview: "Visuele editor",
3863
4246
  previewPane: "Paginavoorbeeld",
3864
4247
  resize: "Voorbeeldpaneel aanpassen",
@@ -3885,6 +4268,7 @@ var nl_default = {
3885
4268
  denied: "Toegang geweigerd.",
3886
4269
  loadFailed: "Instellingen konden niet worden geladen. Herlaad om opnieuw te proberen.",
3887
4270
  invalidColor: "Kleuren moeten #RRGGBB gebruiken.",
4271
+ invalidUrl: "Voorbeeld-URL's moeten volledige HTTP- of HTTPS-adressen zijn.",
3888
4272
  previewLabel: "Paletvoorbeeld",
3889
4273
  removeGroup: "Groep verwijderen",
3890
4274
  diagTitle: "Blokgroepen vragen aandacht; publiceren wordt geweigerd tot ze hersteld zijn:",
@@ -3919,6 +4303,7 @@ var nl_default = {
3919
4303
  contentTypes: "Contenttypes",
3920
4304
  contentTypesHelp: 'De galerij, accordeons en paginavoorbeeld werken op deze contenttypes (die met een Dynamic Zone). Zet er een uit om de bewerking native te laten. "Opent in" bepaalt hoe elke bewerkweergave van dat type start; tijdens het bewerken kan je nog wisselen.',
3921
4305
  typeMode: "Opent in",
4306
+ typeAdvanced: "Opties voor de visuele editor",
3922
4307
  modeDefault: "Standaard ({mode})",
3923
4308
  blockModalDone: "Klaar",
3924
4309
  crashed: "Blockscene is hier gestopt door een fout. De native editor blijft werken. Gebeurt het opnieuw, zet Blockscene uit in Settings, Blockscene.",
@@ -3953,6 +4338,9 @@ var nl_default = {
3953
4338
  unstar: "Uit favorieten verwijderen",
3954
4339
  quickInsert: "{label} invoegen",
3955
4340
  insert: "Invoegen",
4341
+ starterKits: "Start met een kit",
4342
+ starterKitsHelp: "Kies een beginstructuur. Alles wordt ingevoegd als een onopgeslagen, bewerkbaar concept.",
4343
+ startBlank: "Leeg beginnen",
3956
4344
  closeDetail: "Details sluiten",
3957
4345
  typology: "Typologie",
3958
4346
  typologyAuto: "Automatisch ({name})",
@@ -4007,6 +4395,11 @@ var nl_default = {
4007
4395
  confirmDeleteTitle: "Blok verwijderen",
4008
4396
  confirmDelete: "Blok {name} verwijderen?",
4009
4397
  confirmDeleteMarker: "Dit is een groepsmarkering: alleen de markering wordt verwijderd, niet de blokken in de groep, en de groep blijft onevenwichtig tot hij hersteld is.",
4398
+ confirmDeleteGroupTitle: "Groep verwijderen",
4399
+ confirmDeleteGroup: "Groep {name} verwijderen?",
4400
+ confirmDeleteGroupHint: "Deze groep bevat {count, plural, one {# blok} other {# blokken}}. Verwijder ze of behoud ze op de pagina zonder de groep.",
4401
+ keepGroupBlocks: "Groep verwijderen, blokken behouden",
4402
+ deleteGroupAndBlocks: "{count, plural, =0 {Groep verwijderen} one {Groep en # blok verwijderen} other {Groep en # blokken verwijderen}}",
4010
4403
  delete: "Verwijderen",
4011
4404
  selectBlocks: "Blokken selecteren",
4012
4405
  selectAll: "Alles selecteren",
@@ -4201,6 +4594,7 @@ var nl_default = {
4201
4594
  gridCellMenu: "Meer acties voor {label}",
4202
4595
  removeFromGroup: "Uit de groep halen",
4203
4596
  gridAdd: "Blok toevoegen",
4597
+ groupAdd: "Blok toevoegen binnen {label}",
4204
4598
  gridShowList: "Groep {label} als lijst tonen",
4205
4599
  gridShowGrid: "Groep {label} als raster tonen",
4206
4600
  layoutColumnsField: "Layoutraster: veld met kolommen",
@@ -4209,7 +4603,23 @@ var nl_default = {
4209
4603
  layoutOff: "Geen raster",
4210
4604
  layoutNoMobile: "Geen",
4211
4605
  layoutHelp: "De blokken van de groep verschijnen als raster in het formulier, met het aantal kolommen van dit blok.",
4212
- layoutNoFields: "Dit blok heeft geen veld dat een aantal kolommen kan bevatten."
4606
+ layoutNoFields: "Dit blok heeft geen veld dat een aantal kolommen kan bevatten.",
4607
+ "toolbar.versions": "Versiegeschiedenis",
4608
+ versionsDenied: "Vraag een beheerder om de Blockscene-machtiging Versiegeschiedenis lezen.",
4609
+ versionsDisabled: "Geschiedenis is niet ingeschakeld voor dit inhoudstype. Vraag een beheerder dit in Settings > Blockscene in te schakelen (settings.history.enabled).",
4610
+ versionsNew: "Sla dit item eerst op om de geschiedenis te starten.",
4611
+ versionsPerson: "Filter op persoon",
4612
+ versionsEveryone: "Iedereen",
4613
+ versionsCounts: "{total} blokken",
4614
+ versionsCountsMissing: "Aantal blokken niet beschikbaar (oudere of niet vastgelegde gebeurtenis).",
4615
+ versionsPage: "Pagina {page} van {count}",
4616
+ versionsPrevious: "Vorige",
4617
+ versionsNext: "Volgende",
4618
+ versionsViewing: "Versie van {date} door {person} bekijken (alleen-lezen).",
4619
+ versionsCurrent: "Terug naar huidig concept",
4620
+ versionsMissing: "Sommige blokken, velden, media of relaties zijn niet meer beschikbaar in dit voorbeeld.",
4621
+ versionsBridgeLegacy: "Deze bridge ondersteunt geen alleen-lezen navigatie. Interactie is uitgeschakeld; werk de bridge bij voor readOnly.",
4622
+ historyExpired: "Snapshot niet meer beschikbaar"
4213
4623
  };
4214
4624
 
4215
4625
  // admin/messages.ts
@@ -4313,8 +4723,15 @@ function RowPreviews({ zones, components, catalog, Modal: Modal3 }) {
4313
4723
  const candidates = (uid) => candidatesFor(uid, catalog?.components?.[uid] || {}, catalog || {});
4314
4724
  const label = (uid) => catalog?.components?.[uid]?.label || components?.[uid]?.info?.displayName || uid;
4315
4725
  const srcOf = (uid) => candidates(uid)[resolved[uid] ?? -1] || "";
4726
+ const visible = anchors.filter(({ uid }) => showRowThumbnail(uid, catalog));
4316
4727
  React2.useEffect(() => {
4317
4728
  for (const { el, uid } of anchors) {
4729
+ if (!showRowThumbnail(uid, catalog)) {
4730
+ el.style.removeProperty("cursor");
4731
+ for (const name of ["role", "tabindex", "aria-label"])
4732
+ el.removeAttribute(name);
4733
+ continue;
4734
+ }
4318
4735
  if (srcOf(uid)) {
4319
4736
  el.setAttribute("role", "button");
4320
4737
  el.setAttribute("tabindex", "0");
@@ -4326,7 +4743,7 @@ function RowPreviews({ zones, components, catalog, Modal: Modal3 }) {
4326
4743
  }
4327
4744
  });
4328
4745
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4329
- anchors.map(
4746
+ visible.map(
4330
4747
  (a) => (0, import_react_dom.createPortal)(
4331
4748
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4332
4749
  "span",
@@ -4549,7 +4966,15 @@ function movedRow(prev, next, actor) {
4549
4966
  }
4550
4967
  function keepGroupsTogether(prev, next, groups, actor) {
4551
4968
  if (!groups) return null;
4552
- const move = movedRow(prev, next, actor);
4969
+ let move = movedRow(prev, next, actor);
4970
+ if (!move && actor == null) {
4971
+ const candidates = prev.flatMap((row) => {
4972
+ if (!(0, import_groups2.isOpener)(row, groups)) return [];
4973
+ const candidate = movedRow(prev, next, (0, import_groups2.blockKey)(row));
4974
+ return candidate && (0, import_groups2.isOpener)(prev[candidate.from], groups) ? [candidate] : [];
4975
+ });
4976
+ if (candidates.length === 1) move = candidates[0];
4977
+ }
4553
4978
  if (!move || !(0, import_groups2.isOpener)(prev[move.from], groups)) return null;
4554
4979
  const start = move.from, end = groupOutline(prev, groups)[start].end;
4555
4980
  if (end == null) return null;
@@ -4902,6 +5327,7 @@ var DEPTH = "data-blockscene-depth";
4902
5327
  var KIND = "data-blockscene-group";
4903
5328
  var FOLD = "data-blockscene-fold";
4904
5329
  var COUNT = "data-blockscene-fold-count";
5330
+ var INSERT = "data-blockscene-group-insert";
4905
5331
  var GRID_BOX = "data-blockscene-grid";
4906
5332
  var STEP = "2.4rem";
4907
5333
  var folded = /* @__PURE__ */ new Set();
@@ -4923,6 +5349,14 @@ var Count = import_styled_components3.default.span`
4923
5349
  margin-right: 4px; padding: 1px 6px; border-radius: 3px; font-size: 11px; font-weight: 600; line-height: 16px; white-space: nowrap;
4924
5350
  color: ${({ theme }) => theme.colors.primary700}; background: ${({ theme }) => theme.colors.primary100};
4925
5351
  `;
5352
+ var GroupInsert = import_styled_components3.default.button`
5353
+ display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; min-height: 42px; padding: 8px 12px;
5354
+ border: 1px dashed ${({ theme }) => theme.colors.primary600}; border-radius: 4px; cursor: pointer; font: inherit; font-size: 12px; font-weight: 600;
5355
+ color: ${({ theme }) => theme.colors.primary600}; background: ${({ theme }) => theme.colors.neutral0};
5356
+ &:hover:not(:disabled) { background: ${({ theme }) => theme.colors.primary100}; }
5357
+ &:disabled { opacity: 0.5; cursor: default; }
5358
+ &:focus-visible { outline: 2px solid ${({ theme }) => theme.colors.primary600}; outline-offset: 1px; }
5359
+ `;
4926
5360
  function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, components, catalog, openBlock, openInsert }) {
4927
5361
  const t = useMessages();
4928
5362
  const theme = (0, import_styled_components3.useTheme)();
@@ -5018,18 +5452,34 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5018
5452
  for (const index of unfold) for (const p of outline[index]?.parents || []) folded.delete(idOf(p));
5019
5453
  const isFolded = (i) => outline[i].end != null && folded.has(idOf(i));
5020
5454
  const grid = [];
5455
+ const anchorByOpen = /* @__PURE__ */ new Map();
5021
5456
  lis.forEach((li, i) => {
5022
5457
  const o = outline[i];
5023
5458
  seen.add(li);
5024
5459
  set(li, DEPTH, o.depth ? String(o.depth) : null);
5025
5460
  if (o.depth) li.style.setProperty("--bs-depth", String(o.depth));
5026
5461
  set(li, KIND, o.kind === "block" ? null : o.kind);
5027
- const inGrid = (o.kind === "close" ? o.parents.slice(0, -1) : o.parents).some((p) => grid[p]);
5462
+ const inGrid = o.parents.some((p) => grid[p]);
5028
5463
  const hidden = o.parents.some(isFolded) || inGrid;
5029
5464
  set(li, FOLDED, hidden ? "" : null);
5030
5465
  const layout = o.kind === "open" && o.end != null ? layouts2?.[rows[i].__component] || null : null;
5031
5466
  const toggle = li.querySelector("button[aria-expanded]");
5032
5467
  grid[i] = Boolean(layout && toggle?.parentElement) && !hidden && !isFolded(i) && !listed.has(idOf(i));
5468
+ if (o.kind === "close") {
5469
+ const open = o.parents[o.parents.length - 1];
5470
+ const anchor2 = anchorByOpen.get(open);
5471
+ if (anchor2 && !grid[open] && !hidden) {
5472
+ let insertEl = li.querySelector(`:scope > [${INSERT}]`);
5473
+ if (!insertEl) {
5474
+ insertEl = document.createElement("div");
5475
+ insertEl.setAttribute(INSERT, "");
5476
+ li.appendChild(insertEl);
5477
+ }
5478
+ anchor2.insertEl = insertEl;
5479
+ anchor2.after = blockKey(rows[Math.max(open, i - 1)]);
5480
+ }
5481
+ return;
5482
+ }
5033
5483
  if (o.kind !== "open" || o.end == null || !toggle?.parentElement) return;
5034
5484
  let gridEl = li.querySelector(`:scope > [${GRID_BOX}]`);
5035
5485
  if (grid[i] && !gridEl) {
@@ -5052,15 +5502,32 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5052
5502
  countEl.style.cssText = "display:inline-flex;align-items:center";
5053
5503
  actions.insertBefore(countEl, actions.firstChild);
5054
5504
  }
5055
- next.push({ el, countEl, zone: zone.name, index: i, id: idOf(i), count: o.count || 0, open: !isFolded(i), label: labelOf2(rows[i]), layout, gridEl });
5505
+ const anchor = {
5506
+ el,
5507
+ countEl,
5508
+ insertEl: null,
5509
+ after: null,
5510
+ full: Boolean(zone.full),
5511
+ zone: zone.name,
5512
+ index: i,
5513
+ id: idOf(i),
5514
+ count: o.count || 0,
5515
+ open: !isFolded(i),
5516
+ label: labelOf2(rows[i]),
5517
+ layout,
5518
+ gridEl
5519
+ };
5520
+ next.push(anchor);
5521
+ anchorByOpen.set(i, anchor);
5056
5522
  });
5057
5523
  }
5058
5524
  landed.current = null;
5059
5525
  for (const li of document.querySelectorAll(`li[${DEPTH}], li[${KIND}], li[${FOLDED}]`))
5060
5526
  if (!seen.has(li)) for (const name of [DEPTH, KIND, FOLDED]) li.removeAttribute(name);
5061
- for (const el of document.querySelectorAll(`[${FOLD}], [${COUNT}], [${GRID_BOX}]`)) if (!next.some((a) => a.el === el || a.countEl === el || a.gridEl === el)) el.remove();
5527
+ for (const el of document.querySelectorAll(`[${FOLD}], [${COUNT}], [${GRID_BOX}], [${INSERT}]`))
5528
+ if (!next.some((a) => a.el === el || a.countEl === el || a.gridEl === el || a.insertEl === el)) el.remove();
5062
5529
  setAnchors(
5063
- (prev) => prev.length === next.length && prev.every((a, i) => ["el", "countEl", "id", "index", "count", "open", "label", "layout", "gridEl"].every((k) => a[k] === next[i][k])) ? prev : next
5530
+ (prev) => prev.length === next.length && prev.every((a, i) => ["el", "countEl", "insertEl", "after", "full", "id", "index", "count", "open", "label", "layout", "gridEl"].every((k) => a[k] === next[i][k])) ? prev : next
5064
5531
  );
5065
5532
  };
5066
5533
  React4.useEffect(() => {
@@ -5078,7 +5545,7 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5078
5545
  return () => {
5079
5546
  observer.disconnect();
5080
5547
  cancelAnimationFrame(frame2);
5081
- for (const el of document.querySelectorAll(`[${FOLD}], [${COUNT}], [${GRID_BOX}]`)) el.remove();
5548
+ for (const el of document.querySelectorAll(`[${FOLD}], [${COUNT}], [${GRID_BOX}], [${INSERT}]`)) el.remove();
5082
5549
  for (const li of document.querySelectorAll(`li[${DEPTH}], li[${KIND}], li[${FOLDED}]`)) for (const name of [DEPTH, KIND, FOLDED]) li.removeAttribute(name);
5083
5550
  };
5084
5551
  }, []);
@@ -5095,10 +5562,8 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5095
5562
  ${list2}[${DEPTH}] { padding-left: calc(var(--bs-depth) * ${STEP}); background: repeating-linear-gradient(to right, ${line} 0 2px, transparent 2px ${STEP}) 1.1rem 0 / calc(var(--bs-depth) * ${STEP}) 100% no-repeat; }
5096
5563
  ${list2}[${FOLDED}]:not([data-bp-block-modal]) { display: none !important; }
5097
5564
  ${list2}[data-bp-block-modal] { padding-left: 0 !important; background-image: none !important; }
5098
- ${list2}[${KIND}="close"] [data-handler-id] { display: none !important; }
5099
- ${list2}[${KIND}="close"] button[aria-expanded]:first-of-type { min-height: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important; opacity: 0.7; }
5100
- ${list2}[${KIND}="close"] button[aria-expanded]:first-of-type + * { padding-top: 0 !important; padding-bottom: 0 !important; }
5101
- ${list2}[${KIND}="close"] button[aria-expanded] [data-blockscene-row-thumb] { display: none; }` }),
5565
+ ${list2}[${KIND}="close"] > *:not([${INSERT}]) { display: none !important; }
5566
+ ${list2}[${KIND}="close"] [${INSERT}] { display: block; padding: 8px 12px; }` }),
5102
5567
  anchors.map(
5103
5568
  (a) => (0, import_react_dom2.createPortal)(
5104
5569
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
@@ -5152,7 +5617,27 @@ ${list2}[${KIND}="close"] button[aria-expanded] [data-blockscene-row-thumb] { di
5152
5617
  a.gridEl,
5153
5618
  `grid:${a.zone}:${a.index}`
5154
5619
  ) : null;
5155
- })
5620
+ }),
5621
+ anchors.map(
5622
+ (a) => a.insertEl ? (0, import_react_dom2.createPortal)(
5623
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
5624
+ GroupInsert,
5625
+ {
5626
+ type: "button",
5627
+ disabled: a.full,
5628
+ title: a.full ? t.zoneFull : void 0,
5629
+ "data-testid": `group-add-${a.zone}-${a.index}`,
5630
+ onClick: () => openInsert?.(a.zone, a.after),
5631
+ children: [
5632
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "plus", size: 14 }),
5633
+ t.f("groupAdd", { label: a.label })
5634
+ ]
5635
+ }
5636
+ ),
5637
+ a.insertEl,
5638
+ `insert:${a.zone}:${a.index}`
5639
+ ) : null
5640
+ )
5156
5641
  ] });
5157
5642
  }
5158
5643
  function ViewToggle({ grid, testid, label, onFlip }) {
@@ -5355,9 +5840,33 @@ function useRowActions({ zones, components, catalog, form }) {
5355
5840
  if (hiddenName) form.setRows(zoneName, setHidden(rows, index, groups, hiddenName, rows[index]?.[hiddenName] !== true));
5356
5841
  };
5357
5842
  const paste = (zoneName, at) => pasteInto(form, zoneOf(zoneName), clip, components, groups, t, at);
5843
+ const changeGroup = (zoneName, key, keepBlocks) => {
5844
+ const rows = form.rows(zoneName);
5845
+ const next = keepBlocks ? (0, import_groups2.unwrapGroup)(rows, key, groups) : (0, import_groups2.removeGroup)(rows, key, groups);
5846
+ if (next) form.setRows(zoneName, next);
5847
+ };
5358
5848
  const pastable = (zoneName) => !["empty", "notAllowed"].includes(pasteProblem(clip, zoneOf(zoneName), form.rows(zoneName), components, groups)?.code);
5359
5849
  const selectable = (zoneName) => form.rows(zoneName).filter((row) => canAct(row, groups)).map((row) => blockKey(row)).filter(Boolean);
5360
- return { t, editor, groups, hiddenName, clip, selection, setSelection, busy, form, labelOf, duplicate, copy: copy2, toggleHidden, paste, pastable, selectable, isMarker: (row) => isGroupMarker(row, groups) };
5850
+ return {
5851
+ t,
5852
+ editor,
5853
+ groups,
5854
+ hiddenName,
5855
+ clip,
5856
+ selection,
5857
+ setSelection,
5858
+ busy,
5859
+ form,
5860
+ labelOf,
5861
+ duplicate,
5862
+ copy: copy2,
5863
+ toggleHidden,
5864
+ paste,
5865
+ pastable,
5866
+ selectable,
5867
+ changeGroup,
5868
+ isMarker: (row) => isGroupMarker(row, groups)
5869
+ };
5361
5870
  }
5362
5871
  var RowButton = import_styled_components4.default.button`
5363
5872
  display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: 0;
@@ -5381,7 +5890,7 @@ function RowActions({ zones, actions, Modal: Modal3 }) {
5381
5890
  const latest = React5.useRef({ zones, a });
5382
5891
  latest.current = { zones, a };
5383
5892
  React5.useEffect(() => {
5384
- if (!a || e.confirmDelete === false) return;
5893
+ if (!a) return;
5385
5894
  const onClick = (event) => {
5386
5895
  const button = event.target?.closest?.("button");
5387
5896
  if (!button || bypass.current) return;
@@ -5391,10 +5900,23 @@ function RowActions({ zones, actions, Modal: Modal3 }) {
5391
5900
  const headers = toggles(list2);
5392
5901
  const index = headers.findIndex((toggle) => trashOf(toggle) === button);
5393
5902
  if (index < 0) return;
5903
+ const row = latest.current.a?.form.rows(zone.name)[index];
5904
+ const marker2 = Boolean(latest.current.a?.isMarker(row));
5905
+ if (!marker2 && e.confirmDelete === false) return;
5394
5906
  event.preventDefault();
5395
5907
  event.stopPropagation();
5396
- const row = latest.current.a?.form.rows(zone.name)[index];
5397
- setConfirm({ button, label: headers[index].textContent?.trim() || latest.current.a?.labelOf(row), marker: Boolean(latest.current.a?.isMarker(row)) });
5908
+ if (marker2 && !canAct(row, latest.current.a?.groups)) return;
5909
+ const key = blockKey(row) || "";
5910
+ const rows = latest.current.a.form.rows(zone.name);
5911
+ const range = marker2 ? actionRange(rows, index, latest.current.a.groups) : [index, index];
5912
+ setConfirm({
5913
+ button,
5914
+ label: latest.current.a?.labelOf(row) || headers[index].textContent?.trim(),
5915
+ kind: marker2 ? "group" : "block",
5916
+ zone: zone.name,
5917
+ key,
5918
+ count: marker2 ? rows.slice(range[0] + 1, range[1]).filter((item) => canAct(item, latest.current.a.groups)).length : 0
5919
+ });
5398
5920
  return;
5399
5921
  }
5400
5922
  };
@@ -5422,6 +5944,11 @@ function RowActions({ zones, actions, Modal: Modal3 }) {
5422
5944
  bypass.current = false;
5423
5945
  }
5424
5946
  };
5947
+ const confirmGroup = (keepBlocks) => {
5948
+ const target = confirm;
5949
+ setConfirm(null);
5950
+ if (target?.kind === "group") a.changeGroup(target.zone, target.key, keepBlocks);
5951
+ };
5425
5952
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
5426
5953
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `li[${HIDDEN_ATTR}] button[aria-expanded] { opacity: 0.5; }
5427
5954
  ol[aria-describedby] > li button[data-strapi-accordion-toggle] { overflow: hidden; }
@@ -5501,14 +6028,25 @@ ol[aria-describedby] > li button[data-strapi-accordion-toggle] > span:last-child
5501
6028
  `${zone}:${index}`
5502
6029
  );
5503
6030
  }),
5504
- confirm && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Modal3, { open: true, width: "48rem", onOpenChange: (open) => !open && setConfirm(null), trigger: null, title: t.confirmDeleteTitle, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "row-confirm-delete", children: [
5505
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Typography, { children: t.f("confirmDelete", { name: confirm.label }) }),
5506
- confirm.marker && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Typography, { variant: "pi", textColor: "neutral600", children: t.confirmDeleteMarker }),
5507
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system.Flex, { gap: 2, justifyContent: "flex-end", children: [
5508
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { variant: "tertiary", onClick: () => setConfirm(null), "data-testid": "row-confirm-cancel", children: t.cancel }),
5509
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { variant: "danger", onClick: confirmDelete, "data-testid": "row-confirm-ok", children: t.delete })
5510
- ] })
5511
- ] }) })
6031
+ confirm && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
6032
+ Modal3,
6033
+ {
6034
+ open: true,
6035
+ width: "48rem",
6036
+ onOpenChange: (open) => !open && setConfirm(null),
6037
+ trigger: null,
6038
+ title: confirm.kind === "group" ? t.confirmDeleteGroupTitle : t.confirmDeleteTitle,
6039
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "row-confirm-delete", children: [
6040
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Typography, { children: t.f(confirm.kind === "group" ? "confirmDeleteGroup" : "confirmDelete", { name: confirm.label, count: confirm.count }) }),
6041
+ confirm.kind === "group" && confirm.count > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Typography, { variant: "pi", textColor: "neutral600", children: t.f("confirmDeleteGroupHint", { count: confirm.count }) }),
6042
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system.Flex, { gap: 2, justifyContent: "flex-end", children: [
6043
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { variant: "tertiary", onClick: () => setConfirm(null), "data-testid": "row-confirm-cancel", children: t.cancel }),
6044
+ confirm.kind === "group" && confirm.count > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { variant: "secondary", onClick: () => confirmGroup(true), "data-testid": "row-confirm-unwrap", children: t.keepGroupBlocks }),
6045
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { variant: "danger", onClick: confirm.kind === "group" ? () => confirmGroup(false) : confirmDelete, "data-testid": "row-confirm-ok", children: confirm.kind === "group" ? t.f("deleteGroupAndBlocks", { count: confirm.count }) : t.delete })
6046
+ ] })
6047
+ ] })
6048
+ }
6049
+ )
5512
6050
  ] });
5513
6051
  }
5514
6052
  function zoneMenuItems(zone, a) {
@@ -5866,6 +6404,10 @@ var Round = import_styled_components5.default.button`
5866
6404
  border: 1px solid ${({ theme }) => theme.colors.neutral200};
5867
6405
  color: ${({ theme, $on }) => $on ? theme.colors.warning500 : theme.colors.neutral600};
5868
6406
  background: ${({ theme }) => theme.colors.neutral0};
6407
+ transition: transform 120ms ease-out;
6408
+ &:active {
6409
+ transform: scale(0.97);
6410
+ }
5869
6411
  &:focus-visible {
5870
6412
  outline: 2px solid ${({ theme }) => theme.colors.primary600};
5871
6413
  outline-offset: 1px;
@@ -6559,7 +7101,7 @@ function ZoneGallery({
6559
7101
  gap: 4,
6560
7102
  style: { overflowY: "auto", flex: 1, minHeight: 0, padding: "4px" },
6561
7103
  children: (view === "recent" ? [{ typology: "recent", entries }] : groupEntries(entries)).map(
6562
- ({ typology, entries: items2 }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system2.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
7104
+ ({ typology, entries: items2 }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_design_system2.Flex, { direction: "column", alignItems: "stretch", gap: 2, flex: "0 0 auto", children: [
6563
7105
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system2.Typography, { variant: "sigma", textColor: "neutral600", "data-testid": `block-group-${typology}`, children: `${typology === "recent" ? t.nav.recent : t.typologies[typology] || typology} (${items2.length})` }),
6564
7106
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Columns, { $columns: columns, children: items2.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6565
7107
  Card,
@@ -6845,8 +7387,14 @@ var import_styled_components6 = __toESM(require("styled-components"));
6845
7387
  var import_design_system4 = require("@strapi/design-system");
6846
7388
 
6847
7389
  // admin/pane.mjs
6848
- var TOOLBAR = ["modes", "history", "devices", "status", "actions"];
7390
+ var TOOLBAR = ["modes", "history", "versions", "devices", "status", "actions"];
6849
7391
  var RIGHT = ["status", "actions"];
7392
+ function topNavigationInset(navs, viewportWidth) {
7393
+ return Math.round(Math.max(0, ...(Array.isArray(navs) ? navs : []).flatMap((nav) => {
7394
+ const rect = nav?.rect || {};
7395
+ return ["fixed", "sticky"].includes(nav?.position) && Math.abs(Number(rect.top) || 0) <= 1 && (Number(rect.left) || 0) <= 1 && Number(rect.right) >= viewportWidth - 1 && Number(rect.height) > 0 && Number(rect.height) <= 128 ? [Number(rect.bottom) || Number(rect.height)] : [];
7396
+ })));
7397
+ }
6850
7398
  function toolbarLayout(list2) {
6851
7399
  const ids = Array.isArray(list2) ? list2.filter((id, i) => TOOLBAR.includes(id) && list2.indexOf(id) === i) : TOOLBAR;
6852
7400
  const at = ids.findIndex((id) => RIGHT.includes(id));
@@ -6981,6 +7529,25 @@ function useMainRect() {
6981
7529
  }, []);
6982
7530
  return rect;
6983
7531
  }
7532
+ function useAdminTopInset() {
7533
+ const [inset, setInset] = React8.useState(0);
7534
+ React8.useLayoutEffect(() => {
7535
+ const navs = () => [...document.querySelectorAll("nav")];
7536
+ const measure = () => setInset(topNavigationInset(navs().map((nav) => ({
7537
+ position: getComputedStyle(nav).position,
7538
+ rect: nav.getBoundingClientRect()
7539
+ })), window.innerWidth));
7540
+ measure();
7541
+ const observer = "ResizeObserver" in window ? new ResizeObserver(measure) : null;
7542
+ navs().forEach((nav) => observer?.observe(nav));
7543
+ window.addEventListener("resize", measure);
7544
+ return () => {
7545
+ observer?.disconnect();
7546
+ window.removeEventListener("resize", measure);
7547
+ };
7548
+ }, []);
7549
+ return inset;
7550
+ }
6984
7551
  var Handle = import_styled_components6.default.div`
6985
7552
  position: absolute;
6986
7553
  top: 0;
@@ -7069,6 +7636,7 @@ body.bp-block-modal [data-bp-block-modal] { position: fixed !important; top: ${B
7069
7636
  background: ${background}; border-radius: 0 0 8px 8px; box-shadow: 0 8px 32px rgba(33, 33, 52, 0.3); }
7070
7637
  body.bp-block-modal [data-bp-block-modal]::before, body.bp-block-modal [data-bp-block-modal]::after { display: none !important; }
7071
7638
  body.bp-block-modal [data-bp-block-modal] > div { margin: 0 !important; padding-top: 0 !important; }
7639
+ body.bp-block-modal > div:has(> [role="listbox"]) { z-index: 1002 !important; }
7072
7640
  body.bp-block-modal [data-bp-modal-hide] { display: none !important; }`;
7073
7641
  var DRAWER_WIDTH = 640;
7074
7642
  var fieldsStyle = (background, drawer) => `
@@ -7077,6 +7645,7 @@ body.bp-fields [data-bp-show] { grid-column: 1 / -1 !important; }
7077
7645
  body.bp-fields [data-bp-flat] { border: 0 !important; box-shadow: none !important; padding: 0 !important; background: transparent !important; }
7078
7646
  body.bp-fields [data-bp-fields] { position: fixed !important; z-index: 1001; overflow: auto; margin: 0 !important;
7079
7647
  padding: 1.6rem 2.4rem; background: ${background}; box-shadow: 0 8px 32px rgba(33, 33, 52, 0.3); }
7648
+ body.bp-fields > div:has(> [role="listbox"]) { z-index: 1002 !important; }
7080
7649
  body.bp-fields [data-bp-fields="modal"] { top: ${BLOCK_TOP}; left: 50%; transform: translateX(-50%); width: min(96rem, 92vw);
7081
7650
  max-height: calc(88vh - 5.6rem); border-radius: 0 0 8px 8px; }
7082
7651
  ${drawer ? `body.bp-fields [data-bp-fields="drawer"] { top: ${drawer.top + 56}px; left: ${drawer.left}px; width: ${drawer.width}px; height: ${drawer.height - 56}px; }` : ""}`;
@@ -7296,7 +7865,8 @@ function PagePreview({
7296
7865
  hiddenAttribute = null,
7297
7866
  form = null,
7298
7867
  Modal: Modal3,
7299
- Toggle
7868
+ Toggle,
7869
+ versions
7300
7870
  }) {
7301
7871
  const t = useMessages();
7302
7872
  const { values, zone, zoneLabel, canEdit, latest, insertRows: insertRows2 } = usePreviewZone(host);
@@ -7316,12 +7886,15 @@ function PagePreview({
7316
7886
  return v > 0 && v < 1 ? v : 0.5;
7317
7887
  });
7318
7888
  const main = useMainRect();
7889
+ const topInset = useAdminTopInset();
7319
7890
  const vw = main.width;
7320
7891
  const [dragging, setDragging] = React8.useState(false);
7321
7892
  const [ready, setReady] = React8.useState(false);
7893
+ const [readOnlyBridge, setReadOnlyBridge] = React8.useState(false);
7322
7894
  const [failed, setFailed] = React8.useState(false);
7323
7895
  const [attempt, retry] = React8.useReducer((n) => n + 1, 0);
7324
7896
  const [picking, setPicking] = React8.useState(null);
7897
+ const [deletingGroup, setDeletingGroup] = React8.useState(null);
7325
7898
  const [hovered, setHovered] = React8.useState(null);
7326
7899
  const [edge, setEdge] = React8.useState(null);
7327
7900
  const hoverRow = React8.useRef(null);
@@ -7363,7 +7936,13 @@ function PagePreview({
7363
7936
  const iframe = React8.useRef(null);
7364
7937
  const loaded = React8.useRef(false);
7365
7938
  const anchor = React8.useRef(null);
7366
- const channel = React8.useMemo(() => crypto.randomUUID(), []);
7939
+ const version = versions?.view;
7940
+ const readOnly = Boolean(version);
7941
+ const viewRows = React8.useRef([]);
7942
+ viewRows.current = version ? version.values?.[zone] || [] : latest.current;
7943
+ const viewValues = React8.useRef({});
7944
+ viewValues.current = version ? version.values : values;
7945
+ const channel = React8.useMemo(() => crypto.randomUUID(), [host.model, host.documentId, host.locale, version?.scope, version?.event.id]);
7367
7946
  const { base, source } = state.preview;
7368
7947
  const url = base ? new URL(base) : null;
7369
7948
  url?.searchParams.set("channel", channel);
@@ -7382,7 +7961,8 @@ function PagePreview({
7382
7961
  setMode,
7383
7962
  onChange,
7384
7963
  clip,
7385
- clipCount
7964
+ clipCount,
7965
+ readOnly
7386
7966
  });
7387
7967
  live.current = {
7388
7968
  mode,
@@ -7392,7 +7972,8 @@ function PagePreview({
7392
7972
  setMode,
7393
7973
  onChange,
7394
7974
  clip,
7395
- clipCount
7975
+ clipCount,
7976
+ readOnly
7396
7977
  };
7397
7978
  const send = React8.useCallback(() => {
7398
7979
  iframe.current?.contentWindow?.postMessage(
@@ -7400,20 +7981,45 @@ function PagePreview({
7400
7981
  protocol: PROTOCOL,
7401
7982
  channel,
7402
7983
  type: "update-page",
7984
+ entry: projectEntry(
7985
+ viewValues.current,
7986
+ host.contentType,
7987
+ live.current.components,
7988
+ window.location.origin,
7989
+ host.readable
7990
+ ),
7991
+ contentType: {
7992
+ uid: host.model,
7993
+ kind: host.contentType?.kind,
7994
+ singularName: host.contentType?.info?.singularName,
7995
+ pluralName: host.contentType?.info?.pluralName,
7996
+ displayName: host.contentType?.info?.displayName
7997
+ },
7998
+ zone,
7403
7999
  blocks: projectPage(
7404
- latest.current,
8000
+ viewRows.current,
7405
8001
  live.current.components,
7406
8002
  window.location.origin,
7407
8003
  hiddenAttribute
7408
- ),
8004
+ ).map((block) => live.current.readOnly ? { ...block, fields: [], media: {} } : block),
7409
8005
  groups,
7410
8006
  locale: t.locale,
7411
8007
  mode: live.current.mode,
7412
- clipboard: live.current.clipCount
8008
+ clipboard: live.current.readOnly ? 0 : live.current.clipCount,
8009
+ readOnly: live.current.readOnly
7413
8010
  },
7414
8011
  origin
7415
8012
  );
7416
- }, [channel, origin, hiddenAttribute]);
8013
+ }, [channel, origin, hiddenAttribute, groups, host.contentType, host.model, host.readable, zone]);
8014
+ React8.useEffect(() => {
8015
+ if (readOnly) {
8016
+ setInserting(null);
8017
+ setBlockModal(null);
8018
+ setPicking(null);
8019
+ setFieldsPanel(null);
8020
+ setHovered(null);
8021
+ }
8022
+ }, [readOnly]);
7417
8023
  const indexOf = (key) => latest.current.findIndex((row) => blockKey(row) === key);
7418
8024
  const path = (key, field) => `${zone}.${indexOf(key)}.${field}`;
7419
8025
  React8.useEffect(() => {
@@ -7570,9 +8176,11 @@ function PagePreview({
7570
8176
  React8.useEffect(() => {
7571
8177
  if (!active) return;
7572
8178
  setReady(false);
8179
+ setReadOnlyBridge(false);
7573
8180
  setFailed(false);
7574
8181
  const timeout = setTimeout(() => setFailed(true), 15e3);
7575
8182
  const receive = (event) => {
8183
+ if (!previewMessageAllowed(event, origin, iframe.current?.contentWindow, channel, live.current.readOnly)) return;
7576
8184
  const is = (type) => isPreviewMessage(
7577
8185
  event,
7578
8186
  origin,
@@ -7585,6 +8193,7 @@ function PagePreview({
7585
8193
  clearTimeout(timeout);
7586
8194
  setReady(true);
7587
8195
  setFailed(false);
8196
+ setReadOnlyBridge(Array.isArray(event.data.capabilities) && event.data.capabilities.includes("readOnly"));
7588
8197
  send();
7589
8198
  return;
7590
8199
  }
@@ -7616,12 +8225,17 @@ function PagePreview({
7616
8225
  return;
7617
8226
  }
7618
8227
  if (is("delete-group") && canEdit2 && groups) {
7619
- const next = (0, import_groups.removeGroup)(
7620
- latest.current,
7621
- String(event.data.key),
7622
- groups
7623
- );
7624
- if (next) onChange2(zone, next);
8228
+ const key2 = String(event.data.key);
8229
+ const start = latest.current.findIndex((row) => blockKey(row) === key2);
8230
+ if (start < 0) return;
8231
+ const [, end] = (0, import_groups.groupRange)(latest.current, start, groups);
8232
+ if (end <= start || latest.current[end]?.__component !== groups[latest.current[start]?.__component]) return;
8233
+ const closes = new Set(Object.values(groups));
8234
+ setDeletingGroup({
8235
+ key: key2,
8236
+ label: components?.[latest.current[start]?.__component]?.info?.displayName || latest.current[start]?.__component || "",
8237
+ count: latest.current.slice(start + 1, end).filter((row) => !closes.has(row?.__component)).length
8238
+ });
7625
8239
  return;
7626
8240
  }
7627
8241
  if (is("insert-group") && canEdit2 && groups) {
@@ -7712,9 +8326,9 @@ function PagePreview({
7712
8326
  if (!ready || !active) return;
7713
8327
  const timer = setTimeout(send, 120);
7714
8328
  return () => clearTimeout(timer);
7715
- }, [values, host.components, ready, active, send, mode, clipCount]);
8329
+ }, [values, version, host.components, ready, active, send, mode, clipCount]);
7716
8330
  React8.useEffect(() => {
7717
- if (!active || !ready) return;
8331
+ if (!active || !ready || readOnly) return;
7718
8332
  let last = null;
7719
8333
  const post = (key) => {
7720
8334
  if (key === last) return;
@@ -7737,7 +8351,7 @@ function PagePreview({
7737
8351
  document.removeEventListener("pointerout", onOut);
7738
8352
  post(null);
7739
8353
  };
7740
- }, [active, ready, channel, origin]);
8354
+ }, [active, ready, channel, origin, readOnly]);
7741
8355
  React8.useEffect(() => {
7742
8356
  const item = hovered && active ? findZoneList(live.current.zoneLabel)?.querySelectorAll(":scope > li")[indexOf(hovered)] : void 0;
7743
8357
  hoverRow.current = item || null;
@@ -7791,7 +8405,7 @@ function PagePreview({
7791
8405
  }
7792
8406
  ) });
7793
8407
  const layout = toolbarLayout(editor?.previewToolbar);
7794
- const tools = { modes: switcher, history: historyTools, devices };
8408
+ const tools = { modes: switcher, history: !readOnly && historyTools, versions: versions?.button, devices };
7795
8409
  const toolbarShown = !ready || layout.before.length + layout.right.length + layout.after.length > 0;
7796
8410
  const onKey = (event) => {
7797
8411
  const map = {
@@ -7805,6 +8419,12 @@ function PagePreview({
7805
8419
  applyWidth(map[event.key], true);
7806
8420
  }
7807
8421
  };
8422
+ const confirmGroupDelete = (keepBlocks) => {
8423
+ if (!deletingGroup || !zone) return;
8424
+ const next = keepBlocks ? (0, import_groups.unwrapGroup)(latest.current, deletingGroup.key, groups) : (0, import_groups.removeGroup)(latest.current, deletingGroup.key, groups);
8425
+ setDeletingGroup(null);
8426
+ if (next) onChange(zone, next);
8427
+ };
7808
8428
  return (
7809
8429
  // Hidden anchor in the side panels column: split mode and the sidebar items find the edit view's grid from here.
7810
8430
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { ref: anchor, children: [
@@ -7815,6 +8435,7 @@ function PagePreview({
7815
8435
  "data-testid": "page-preview-pane",
7816
8436
  "aria-label": t.previewPane,
7817
8437
  style: {
8438
+ top: topInset,
7818
8439
  left: mode === "preview" || narrow ? main.left : main.left + main.width - paneWidth,
7819
8440
  width: mode === "preview" || narrow ? main.width : paneWidth,
7820
8441
  userSelect: dragging ? "none" : void 0
@@ -7900,7 +8521,7 @@ ${/* Strapi 4's scrolled header is fixed to the viewport's right edge: beside th
7900
8521
  children: [
7901
8522
  !ready && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system4.Typography, { variant: "pi", role: "status", textColor: "neutral600", children: failed ? t.previewFailed : t.previewLoading }),
7902
8523
  failed && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system4.Button, { size: "S", variant: "secondary", onClick: retry, children: t.retry }),
7903
- layout.right.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Actions2, { parts: layout.right })
8524
+ !readOnly && layout.right.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Actions2, { parts: layout.right })
7904
8525
  ]
7905
8526
  }
7906
8527
  ),
@@ -7908,68 +8529,83 @@ ${/* Strapi 4's scrolled header is fixed to the viewport's right edge: beside th
7908
8529
  ]
7909
8530
  }
7910
8531
  ),
7911
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1, minHeight: 0, display: "flex", flexDirection: sidebarPosition === "bottom" ? "column-reverse" : sidebarPosition === "right" ? "row-reverse" : "row" }, children: [
7912
- mode === "preview" && sidebar.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: setRailEl, style: { display: "flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
7913
- import_design_system4.Flex,
7914
- {
7915
- "data-testid": "page-preview-sidebar",
7916
- "data-position": sidebarPosition,
7917
- role: "toolbar",
7918
- "aria-label": t.sidebarLabel,
7919
- direction: sidebarPosition === "bottom" ? "row" : "column",
7920
- gap: 1,
7921
- padding: 1,
7922
- background: "neutral100",
7923
- justifyContent: sidebarPosition === "bottom" ? "center" : "flex-start",
7924
- style: { [sidebarPosition === "bottom" ? "borderTop" : sidebarPosition === "right" ? "borderLeft" : "borderRight"]: `1px solid ${theme?.colors?.neutral200 || "#dcdce4"}`, overflow: "auto" },
7925
- children: sidebar.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
7926
- RailButton,
7927
- {
7928
- type: "button",
7929
- $active: fieldsPanel === item,
7930
- "aria-pressed": fieldsPanel === item,
7931
- title: item.label,
7932
- "data-testid": item.custom ? `sidebar-panel-${item.id}` : `sidebar-item-${i}`,
7933
- onClick: () => setFieldsPanel(fieldsPanel === item ? null : item),
7934
- children: [
7935
- typeof item.icon === "string" ? item.icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: item.icon }) : item.icon,
7936
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: item.label })
7937
- ]
7938
- },
7939
- `${item.label}-${i}`
7940
- ))
7941
- }
7942
- ) }),
7943
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
7944
- "div",
7945
- {
7946
- ref: setStage,
7947
- "data-testid": "page-preview-stage",
7948
- "data-device": device.id,
7949
- style: { position: "relative", flex: 1, overflow: "hidden", ...stageBackground(theme) },
7950
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
7951
- Frame2,
7952
- {
7953
- ref: iframe,
7954
- title: t.previewPane,
7955
- src: url.href,
7956
- sandbox: "allow-scripts allow-same-origin",
7957
- referrerPolicy: "no-referrer",
7958
- onLoad: () => {
7959
- loaded.current = true;
8532
+ versions?.banner,
8533
+ readOnly && ready && !readOnlyBridge && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system4.Box, { padding: 2, background: "neutral100", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system4.Typography, { variant: "pi", role: "status", children: t.versionsBridgeLegacy }) }),
8534
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1, minHeight: 0, display: "flex" }, children: [
8535
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1, minWidth: 0, minHeight: 0, display: "flex", flexDirection: sidebarPosition === "bottom" ? "column-reverse" : sidebarPosition === "right" ? "row-reverse" : "row" }, children: [
8536
+ !readOnly && mode === "preview" && sidebar.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: setRailEl, style: { display: "flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
8537
+ import_design_system4.Flex,
8538
+ {
8539
+ "data-testid": "page-preview-sidebar",
8540
+ "data-position": sidebarPosition,
8541
+ role: "toolbar",
8542
+ "aria-label": t.sidebarLabel,
8543
+ direction: sidebarPosition === "bottom" ? "row" : "column",
8544
+ gap: 1,
8545
+ padding: 1,
8546
+ background: "neutral100",
8547
+ justifyContent: sidebarPosition === "bottom" ? "center" : "flex-start",
8548
+ style: { [sidebarPosition === "bottom" ? "borderTop" : sidebarPosition === "right" ? "borderLeft" : "borderRight"]: `1px solid ${theme?.colors?.neutral200 || "#dcdce4"}`, overflow: "auto" },
8549
+ children: sidebar.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
8550
+ RailButton,
8551
+ {
8552
+ type: "button",
8553
+ $active: fieldsPanel === item,
8554
+ "aria-pressed": fieldsPanel === item,
8555
+ title: item.label,
8556
+ "data-testid": item.custom ? `sidebar-panel-${item.id}` : `sidebar-item-${i}`,
8557
+ onClick: () => setFieldsPanel(fieldsPanel === item ? null : item),
8558
+ children: [
8559
+ typeof item.icon === "string" ? item.icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: item.icon }) : item.icon,
8560
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: item.label })
8561
+ ]
7960
8562
  },
7961
- style: { ...frameStyle(device.width, stageSize), ...dragging ? { pointerEvents: "none" } : {} }
7962
- },
7963
- attempt
7964
- )
7965
- }
7966
- )
8563
+ `${item.label}-${i}`
8564
+ ))
8565
+ }
8566
+ ) }),
8567
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
8568
+ "div",
8569
+ {
8570
+ ref: setStage,
8571
+ "data-testid": "page-preview-stage",
8572
+ "data-device": device.id,
8573
+ style: { position: "relative", flex: 1, overflow: "hidden", ...stageBackground(theme) },
8574
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
8575
+ Frame2,
8576
+ {
8577
+ ref: iframe,
8578
+ title: t.previewPane,
8579
+ src: url.href,
8580
+ sandbox: "allow-scripts allow-same-origin",
8581
+ referrerPolicy: "no-referrer",
8582
+ ...readOnly && !readOnlyBridge ? { inert: "", tabIndex: -1 } : {},
8583
+ onLoad: () => {
8584
+ loaded.current = true;
8585
+ },
8586
+ style: { ...frameStyle(device.width, stageSize), ...dragging || readOnly && !readOnlyBridge ? { pointerEvents: "none" } : {} }
8587
+ },
8588
+ attempt
8589
+ )
8590
+ }
8591
+ )
8592
+ ] }),
8593
+ versions?.drawer
7967
8594
  ] })
7968
8595
  ]
7969
8596
  }
7970
8597
  ),
7971
8598
  document.body
7972
8599
  ),
8600
+ deletingGroup && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Modal3, { open: true, width: "48rem", onOpenChange: (open) => !open && setDeletingGroup(null), trigger: null, title: t.confirmDeleteGroupTitle, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_design_system4.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "preview-confirm-delete-group", children: [
8601
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system4.Typography, { children: t.f("confirmDeleteGroup", { name: deletingGroup.label, count: deletingGroup.count }) }),
8602
+ deletingGroup.count > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system4.Typography, { variant: "pi", textColor: "neutral600", children: t.f("confirmDeleteGroupHint", { count: deletingGroup.count }) }),
8603
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_design_system4.Flex, { gap: 2, justifyContent: "flex-end", children: [
8604
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system4.Button, { variant: "tertiary", onClick: () => setDeletingGroup(null), children: t.cancel }),
8605
+ deletingGroup.count > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system4.Button, { variant: "secondary", onClick: () => confirmGroupDelete(true), children: t.keepGroupBlocks }),
8606
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system4.Button, { variant: "danger", onClick: () => confirmGroupDelete(false), children: t.f("deleteGroupAndBlocks", { count: deletingGroup.count }) })
8607
+ ] })
8608
+ ] }) }),
7973
8609
  inserting && insertAttr && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
7974
8610
  PickerModal,
7975
8611
  {
@@ -7990,6 +8626,7 @@ ${/* Strapi 4's scrolled header is fixed to the viewport's right edge: beside th
7990
8626
  if (!open) setInserting(null);
7991
8627
  },
7992
8628
  onSelect: (uid, values2) => {
8629
+ if (live.current.readOnly) return;
7993
8630
  const rows = inserting.zone === zone ? latest.current : Array.isArray(host.values?.[inserting.zone]) ? host.values[inserting.zone] : [];
7994
8631
  const index = insertIndex(rows, inserting.after);
7995
8632
  setInserting(null);
@@ -8114,6 +8751,7 @@ ${/* Strapi 4's scrolled header is fixed to the viewport's right edge: beside th
8114
8751
  multiple: picking.attr.multiple === true,
8115
8752
  onClose: () => setPicking(null),
8116
8753
  onSelectAssets: (assets) => {
8754
+ if (live.current.readOnly) return;
8117
8755
  const index = indexOf(picking.key);
8118
8756
  setPicking(null);
8119
8757
  if (index < 0 || !assets?.length) return;
@@ -8160,11 +8798,15 @@ function usePreviewHost5() {
8160
8798
  const { toggleNotification } = (0, import_admin.useNotification)();
8161
8799
  const components = (0, import_admin.useStrapiApp)("BlockscenePagePreview", (state) => state.components);
8162
8800
  const fields = c.layout?.edit?.layout?.flat(3) || [];
8801
+ const layoutFields = React9.useMemo(
8802
+ () => new Set(fields.map((field) => field?.name).filter(Boolean)),
8803
+ [c.layout?.edit?.layout]
8804
+ );
8163
8805
  const latest = React9.useRef(values);
8164
8806
  latest.current = values;
8165
8807
  const readable = React9.useCallback(
8166
- (name) => c.isCreatingEntry || (rbac.canReadFields || []).includes(name),
8167
- [c.isCreatingEntry, rbac.canReadFields]
8808
+ (name) => fieldReadable(name, rbac.canReadFields, c.isCreatingEntry) || layoutFields.has(name.split(".")[0]),
8809
+ [c.isCreatingEntry, layoutFields, rbac.canReadFields]
8168
8810
  );
8169
8811
  return {
8170
8812
  ds: 2,
@@ -8438,6 +9080,8 @@ function History({ model, documentId, schema, components, editable, disabled, ge
8438
9080
  const initialValues = (0, import_admin2.useForm)("BlocksceneVersions", (state) => state.initialValues);
8439
9081
  const setValues = (0, import_admin2.useForm)("BlocksceneVersions", (state) => state.setValues);
8440
9082
  const [events, setEvents] = React10.useState(null);
9083
+ const [pagination, setPagination] = React10.useState(null);
9084
+ const [moreLoading, setMoreLoading] = React10.useState(false);
8441
9085
  const [failed, setFailed] = React10.useState(false);
8442
9086
  const [shown, setShown] = React10.useState(PAGE);
8443
9087
  const [open, setOpen] = React10.useState(null);
@@ -8445,11 +9089,19 @@ function History({ model, documentId, schema, components, editable, disabled, ge
8445
9089
  const [loading, setLoading] = React10.useState(false);
8446
9090
  const [refresh, reload] = React10.useReducer((n) => n + 1, 0);
8447
9091
  const allowed = Boolean(allowedActions?.canRead);
9092
+ const scope = `${model}:${documentId}:${locale}:${allowed}`;
9093
+ const latestScope = React10.useRef(scope);
9094
+ latestScope.current = scope;
8448
9095
  React10.useEffect(() => {
8449
9096
  if (!allowed || !documentId) return;
8450
9097
  let active = true;
8451
9098
  setFailed(false);
8452
- get(`/blockscene/history/${encodeURIComponent(model)}/${encodeURIComponent(documentId)}${locale ? `?locale=${encodeURIComponent(locale)}` : ""}`).then(({ data }) => active && setEvents(Array.isArray(data?.results) ? data.results : [])).catch(() => active && setFailed(true));
9099
+ get(`/blockscene/history/${encodeURIComponent(model)}/${encodeURIComponent(documentId)}${locale ? `?locale=${encodeURIComponent(locale)}` : ""}`).then(({ data }) => {
9100
+ if (active) {
9101
+ setEvents(Array.isArray(data?.results) ? data.results : []);
9102
+ setPagination(data?.pagination);
9103
+ }
9104
+ }).catch(() => active && setFailed(true));
8453
9105
  return () => {
8454
9106
  active = false;
8455
9107
  };
@@ -8458,7 +9110,26 @@ function History({ model, documentId, schema, components, editable, disabled, ge
8458
9110
  setOpen(null);
8459
9111
  setReport(null);
8460
9112
  setShown(PAGE);
9113
+ setEvents(null);
9114
+ setPagination(null);
9115
+ setMoreLoading(false);
8461
9116
  }, [model, documentId, locale]);
9117
+ const more = async () => {
9118
+ if (shown < (events?.length || 0)) return setShown(shown + PAGE);
9119
+ setMoreLoading(true);
9120
+ try {
9121
+ const params = new URLSearchParams({ page: String((pagination?.page || 1) + 1), ...locale && { locale } });
9122
+ const { data } = await get(`/blockscene/history/${encodeURIComponent(model)}/${encodeURIComponent(documentId)}?${params}`);
9123
+ if (latestScope.current !== scope) return;
9124
+ setEvents((previous) => [...previous || [], ...data?.results || []]);
9125
+ setPagination(data?.pagination);
9126
+ setShown(shown + PAGE);
9127
+ } catch {
9128
+ if (latestScope.current === scope) setFailed(true);
9129
+ } finally {
9130
+ if (latestScope.current === scope) setMoreLoading(false);
9131
+ }
9132
+ };
8462
9133
  if (isLoading || !allowed || !documentId) return null;
8463
9134
  const name = (uid) => components?.[uid]?.info?.displayName || uid;
8464
9135
  const when2 = (at) => {
@@ -8554,30 +9225,291 @@ function History({ model, documentId, schema, components, editable, disabled, ge
8554
9225
  ] }) })
8555
9226
  ] }, event.id);
8556
9227
  }),
8557
- events.length > shown && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_design_system6.Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_design_system6.Button, { variant: "tertiary", size: "S", onClick: () => setShown(shown + PAGE), children: t.historyShowMore }) })
9228
+ (events.length > shown || pagination?.page < pagination?.pageCount) && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_design_system6.Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_design_system6.Button, { variant: "tertiary", size: "S", onClick: more, loading: moreLoading, disabled: moreLoading, children: t.historyShowMore }) })
8558
9229
  ] })
8559
9230
  ] });
8560
9231
  }
8561
9232
 
8562
- // admin/Settings.tsx
9233
+ // admin/Versions.tsx
8563
9234
  var React11 = __toESM(require("react"));
8564
- var import_design_system7 = require("@strapi/design-system");
8565
9235
  var import_styled_components7 = __toESM(require("styled-components"));
9236
+ var import_design_system7 = require("@strapi/design-system");
9237
+ var import_admin3 = require("@strapi/strapi/admin");
8566
9238
  var import_jsx_runtime12 = require("react/jsx-runtime");
9239
+ var Drawer = import_styled_components7.default.aside`
9240
+ width: min(36rem, 55%); flex: 0 0 auto; overflow: auto;
9241
+ border-left: 1px solid ${({ theme }) => theme.colors.neutral200};
9242
+ background: ${({ theme }) => theme.colors.neutral0};
9243
+ `;
9244
+ var Entry = import_styled_components7.default.button`
9245
+ display: block; width: 100%; text-align: left; padding: 12px; margin: 4px 0;
9246
+ border: 1px solid ${({ theme }) => theme.colors.neutral200}; border-radius: 4px;
9247
+ background: ${({ theme }) => theme.colors.neutral0}; cursor: pointer;
9248
+ &[aria-pressed="true"] { background: ${({ theme }) => theme.colors.primary100}; border-color: ${({ theme }) => theme.colors.primary600}; }
9249
+ &:focus-visible { outline: 2px solid ${({ theme }) => theme.colors.primary600}; outline-offset: 2px; }
9250
+ &:disabled { cursor: default; opacity: .65; }
9251
+ overflow-wrap: anywhere;
9252
+ `;
9253
+ var PAGE_SIZE = 25;
9254
+ function useVersions(host, config2) {
9255
+ const t = useMessages();
9256
+ const [{ query: query2 }] = (0, import_admin3.useQueryParams)();
9257
+ const locale = typeof query2?.plugins?.i18n?.locale === "string" ? query2.plugins.i18n.locale : host.locale || "";
9258
+ const rbac = (0, import_admin3.useRBAC)(HISTORY_READ);
9259
+ const allowed = !rbac.isLoading && Boolean(rbac.allowedActions?.canRead);
9260
+ const enabled = Boolean(config2?.contentTypes?.includes(host.model));
9261
+ const scope = `${host.model}:${host.documentId || ""}:${locale}:${allowed}:${enabled}`;
9262
+ const currentScope = React11.useRef(scope);
9263
+ currentScope.current = scope;
9264
+ const requests = React11.useRef(0);
9265
+ const [open, setOpen] = React11.useState(false);
9266
+ const [actor, setActor] = React11.useState("");
9267
+ const [page, setPage] = React11.useState(1);
9268
+ const [list2, setList] = React11.useState(null);
9269
+ const [people, setPeople] = React11.useState(null);
9270
+ const [selection, setSelection] = React11.useState(null);
9271
+ const [failed, setFailed] = React11.useState(false);
9272
+ const [refresh, retry] = React11.useReducer((n) => n + 1, 0);
9273
+ const trigger = React11.useRef(null);
9274
+ const closeButton = React11.useRef(null);
9275
+ const titleId = React11.useId(), drawerId = React11.useId();
9276
+ const available = allowed && enabled && Boolean(host.documentId) && !host.creating;
9277
+ const reason = rbac.isLoading ? t.historyLoading : !allowed ? t.versionsDenied : !enabled ? t.versionsDisabled : !host.documentId || host.creating ? t.versionsNew : "";
9278
+ const view = selection?.scope === scope ? selection : null;
9279
+ const close = () => {
9280
+ setOpen(false);
9281
+ trigger.current?.focus();
9282
+ };
9283
+ const back = () => {
9284
+ requests.current++;
9285
+ setSelection(null);
9286
+ setFailed(false);
9287
+ trigger.current?.focus();
9288
+ };
9289
+ React11.useEffect(() => {
9290
+ requests.current++;
9291
+ setSelection(null);
9292
+ setList(null);
9293
+ setPeople(null);
9294
+ setActor("");
9295
+ setPage(1);
9296
+ setFailed(false);
9297
+ return () => {
9298
+ requests.current++;
9299
+ };
9300
+ }, [scope]);
9301
+ React11.useEffect(() => {
9302
+ if (open) closeButton.current?.focus();
9303
+ }, [open]);
9304
+ React11.useEffect(() => {
9305
+ if (!open || !available) return;
9306
+ let active = true;
9307
+ setList(null);
9308
+ setFailed(false);
9309
+ const params = new URLSearchParams({ page: String(page), pageSize: String(PAGE_SIZE), ...locale && { locale }, ...actor && { actor } });
9310
+ host.get(`/blockscene/history/${encodeURIComponent(host.model)}/${encodeURIComponent(String(host.documentId))}?${params}`).then(({ data }) => {
9311
+ if (active && currentScope.current === scope) {
9312
+ setList({ ...data, scope });
9313
+ setPeople({ scope, actors: data.actors || [] });
9314
+ }
9315
+ }).catch(() => {
9316
+ if (active && currentScope.current === scope) setFailed(true);
9317
+ });
9318
+ return () => {
9319
+ active = false;
9320
+ };
9321
+ }, [scope, open, page, actor, refresh, host.get, host.history?.epoch]);
9322
+ const select = async (event) => {
9323
+ if (!available || !event.stored) return;
9324
+ const request = ++requests.current;
9325
+ setSelection({ scope, event, pending: true, values: view?.values });
9326
+ setFailed(false);
9327
+ try {
9328
+ const { data } = await host.get(`/blockscene/history-events/${event.id}`);
9329
+ if (requests.current !== request || currentScope.current !== scope) return;
9330
+ const localized2 = host.contentType?.pluginOptions?.i18n?.localized;
9331
+ if (!data?.snapshot || data.event?.contentType !== host.model || data.event?.relatedDocumentId !== String(host.documentId) || localized2 && (data.event?.locale || "") !== (locale || list2?.locale || "")) throw new Error("Unavailable version");
9332
+ const loaded = loadVersion(data.snapshot, {
9333
+ schema: host.contentType,
9334
+ components: host.components,
9335
+ media: data.media,
9336
+ relations: data.relations,
9337
+ editable: host.readable
9338
+ });
9339
+ for (const [name, attr] of Object.entries(host.contentType?.attributes || {}))
9340
+ if (attr.type === "dynamiczone") loaded.values[name]?.forEach((row, i) => {
9341
+ row.__temp_key__ = `version:${event.id}:${i}`;
9342
+ });
9343
+ setSelection({ scope, event, values: loaded.values, report: loaded.report, pending: false });
9344
+ } catch {
9345
+ if (requests.current === request && currentScope.current === scope) {
9346
+ setFailed(true);
9347
+ setSelection(null);
9348
+ }
9349
+ }
9350
+ };
9351
+ const when2 = (at, day = false) => new Date(at).toLocaleString(t.locale, { dateStyle: "medium", ...!day && { timeStyle: "short" } });
9352
+ const events = list2?.scope === scope ? list2.results || [] : [];
9353
+ let previousDay = "";
9354
+ const drawer = open && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9355
+ Drawer,
9356
+ {
9357
+ id: drawerId,
9358
+ role: "region",
9359
+ "aria-labelledby": titleId,
9360
+ "data-testid": "versions-drawer",
9361
+ onKeyDown: (event) => {
9362
+ if (event.key === "Escape") {
9363
+ event.preventDefault();
9364
+ event.stopPropagation();
9365
+ close();
9366
+ }
9367
+ },
9368
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Box, { padding: 4, children: [
9369
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 2, justifyContent: "space-between", children: [
9370
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { id: titleId, tag: "h2", variant: "delta", children: t.historyTitle }),
9371
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { ref: closeButton, size: "S", variant: "tertiary", "aria-label": t.close, onClick: close, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "close" }) })
9372
+ ] }),
9373
+ reason ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { tag: "p", textColor: "neutral600", children: reason }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
9374
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { paddingTop: 3, paddingBottom: 3, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.SingleSelect, { "aria-label": t.versionsPerson, value: actor, onChange: (value) => {
9375
+ setActor(value);
9376
+ setPage(1);
9377
+ }, children: [
9378
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.SingleSelectOption, { value: "", children: t.versionsEveryone }),
9379
+ (people?.scope === scope ? people.actors : []).map((person) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.SingleSelectOption, { value: person.actor, children: person.actorName || person.actor }, person.actor))
9380
+ ] }) }),
9381
+ !list2 && !failed && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "status", children: t.historyLoading }),
9382
+ list2 && !events.length && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { children: t.historyEmpty }),
9383
+ events.map((event) => {
9384
+ const day = when2(event.at, true), heading = day !== previousDay;
9385
+ previousDay = day;
9386
+ const blocks = event.summary?.blocks;
9387
+ const counted = ["total", "added", "removed", "changed"].every((key) => Number.isInteger(blocks?.[key]));
9388
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(React11.Fragment, { children: [
9389
+ heading && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { tag: "h3", variant: "omega", fontWeight: "bold", style: { marginTop: 12 }, children: day }),
9390
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
9391
+ Entry,
9392
+ {
9393
+ "aria-pressed": view?.event.id === event.id,
9394
+ disabled: !event.stored,
9395
+ title: !event.stored ? t.historyExpired : void 0,
9396
+ "data-testid": `version-${event.id}`,
9397
+ onClick: () => select(event),
9398
+ children: [
9399
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { tag: "span", fontWeight: "bold", children: event.actorName || event.actor }),
9400
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Typography, { tag: "p", variant: "pi", children: [
9401
+ when2(event.at),
9402
+ " \xB7 ",
9403
+ t.historyActions[event.action] || event.action
9404
+ ] }),
9405
+ counted ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
9406
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { tag: "p", variant: "pi", textColor: "neutral600", children: t.f("versionsCounts", blocks) }),
9407
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 2, wrap: "wrap", children: [
9408
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Typography, { variant: "pi", textColor: "success700", children: [
9409
+ "+",
9410
+ blocks.added,
9411
+ " ",
9412
+ t.diffOps.added
9413
+ ] }),
9414
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Typography, { variant: "pi", textColor: "danger700", children: [
9415
+ "\u2212",
9416
+ blocks.removed,
9417
+ " ",
9418
+ t.diffOps.removed
9419
+ ] }),
9420
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Typography, { variant: "pi", textColor: "warning700", children: [
9421
+ "~",
9422
+ blocks.changed,
9423
+ " ",
9424
+ t.diffOps.changed
9425
+ ] })
9426
+ ] })
9427
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { tag: "p", variant: "pi", textColor: "neutral600", children: t.versionsCountsMissing }),
9428
+ !event.stored && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { tag: "p", variant: "pi", children: t.historyExpired })
9429
+ ]
9430
+ }
9431
+ )
9432
+ ] }, event.id);
9433
+ }),
9434
+ list2 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 2, paddingTop: 3, justifyContent: "space-between", children: [
9435
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { size: "S", variant: "tertiary", disabled: page <= 1, onClick: () => setPage(page - 1), children: t.versionsPrevious }),
9436
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", children: t.f("versionsPage", { page, count: Math.max(1, list2.pagination?.pageCount || 0) }) }),
9437
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { size: "S", variant: "tertiary", disabled: page >= (list2.pagination?.pageCount || 0), onClick: () => setPage(page + 1), children: t.versionsNext })
9438
+ ] })
9439
+ ] }),
9440
+ failed && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Box, { paddingTop: 3, children: [
9441
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "alert", textColor: "danger600", children: t.historyFailed }),
9442
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { size: "S", variant: "tertiary", onClick: retry, children: t.retry })
9443
+ ] })
9444
+ ] })
9445
+ }
9446
+ );
9447
+ return {
9448
+ view,
9449
+ drawer,
9450
+ button: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9451
+ import_design_system7.Button,
9452
+ {
9453
+ ref: trigger,
9454
+ size: "S",
9455
+ variant: "tertiary",
9456
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "clock" }),
9457
+ "data-testid": "versions-toggle",
9458
+ "aria-expanded": open,
9459
+ "aria-controls": open ? drawerId : void 0,
9460
+ title: reason || t.historyTitle,
9461
+ onClick: () => setOpen(!open),
9462
+ children: t.historyTitle
9463
+ }
9464
+ ),
9465
+ banner: view && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { padding: 3, gap: 3, wrap: "wrap", background: "primary100", "data-testid": "versions-banner", children: [
9466
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "status", children: view.pending ? t.historyLoading : t.f("versionsViewing", { date: when2(view.event.at), person: view.event.actorName || view.event.actor }) }),
9467
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { size: "S", variant: "secondary", onClick: back, children: t.versionsCurrent }),
9468
+ !view.pending && (view.report?.blocks || view.report?.media || view.report?.relations || view.report?.removed.length) > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", children: t.versionsMissing })
9469
+ ] })
9470
+ };
9471
+ }
9472
+
9473
+ // admin/Settings.tsx
9474
+ var React12 = __toESM(require("react"));
9475
+ var import_design_system8 = require("@strapi/design-system");
9476
+ var import_styled_components8 = __toESM(require("styled-components"));
9477
+ var import_jsx_runtime13 = require("react/jsx-runtime");
8567
9478
  var COLOR2 = /^#[0-9A-Fa-f]{6}$/;
8568
- var Grid2 = import_styled_components7.default.div` display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 16px; `;
8569
- var Card2 = import_styled_components7.default.div`
9479
+ var Grid2 = import_styled_components8.default.div` display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 16px; `;
9480
+ var Card2 = import_styled_components8.default.div`
8570
9481
  display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: 4px;
8571
9482
  border: 1px solid ${({ theme }) => theme.colors.neutral200}; background: ${({ theme }) => theme.colors.neutral0};
8572
9483
  `;
8573
- var Bar = import_styled_components7.default.div`
9484
+ var ContentTypeGrid = import_styled_components8.default.div`
9485
+ display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr)); gap: 16px; align-items: start;
9486
+ `;
9487
+ var ContentTypeCard = import_styled_components8.default.div`
9488
+ display: flex; flex-direction: column; gap: 16px; padding: 20px; border-radius: 4px;
9489
+ border: 1px solid ${({ theme }) => theme.colors.neutral200}; background: ${({ theme }) => theme.colors.neutral0};
9490
+ `;
9491
+ var ContentTypeTop = import_styled_components8.default.div`
9492
+ display: grid; grid-template-columns: minmax(0, 1fr) minmax(190px, 240px); gap: 16px; align-items: end;
9493
+ @media (max-width: 520px) { grid-template-columns: 1fr; }
9494
+ `;
9495
+ var Advanced = import_styled_components8.default.details`
9496
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral200}; padding-top: 12px;
9497
+ summary { cursor: pointer; color: ${({ theme }) => theme.colors.neutral800}; font-size: 13px; font-weight: 600; }
9498
+ summary::marker { color: ${({ theme }) => theme.colors.neutral500}; }
9499
+ &[open] summary { margin-bottom: 16px; }
9500
+ `;
9501
+ var ToolbarSection = import_styled_components8.default.div`
9502
+ display: flex; flex-direction: column; gap: 12px; margin-top: 16px; padding-top: 16px;
9503
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
9504
+ `;
9505
+ var Bar = import_styled_components8.default.div`
8574
9506
  position: fixed; top: 0; z-index: 4; padding: 12px 32px;
8575
9507
  background: ${({ theme }) => theme.colors.neutral100}; border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};
8576
9508
  box-shadow: 0 1px 4px rgba(33, 33, 52, 0.1);
8577
9509
  `;
8578
9510
  function useMainRect2(anchor) {
8579
- const [rect, setRect] = React11.useState({ left: 0, width: 0 });
8580
- React11.useEffect(() => {
9511
+ const [rect, setRect] = React12.useState({ left: 0, width: 0 });
9512
+ React12.useEffect(() => {
8581
9513
  const read3 = () => {
8582
9514
  let host = document.getElementById("main-content");
8583
9515
  for (let el = anchor.current?.parentElement; !host && el; el = el.parentElement) if (["auto", "scroll"].includes(getComputedStyle(el).overflowY) && el.scrollHeight > el.clientHeight) host = el;
@@ -8590,15 +9522,15 @@ function useMainRect2(anchor) {
8590
9522
  });
8591
9523
  return rect;
8592
9524
  }
8593
- var Swatches = import_styled_components7.default.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; `;
8594
- var Label = import_styled_components7.default.label` display: flex; flex-direction: column; gap: 4px; font-size: 12px; `;
9525
+ var Swatches = import_styled_components8.default.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; `;
9526
+ var Label = import_styled_components8.default.label` display: flex; flex-direction: column; gap: 4px; font-size: 12px; `;
8595
9527
  function ColorField({ name, label, value, onChange, disabled }) {
8596
9528
  const valid = COLOR2.test(value);
8597
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Label, { children: [
8598
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
8599
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 2, children: [
8600
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "color", "aria-label": label, value: valid ? value : "#000000", disabled, onChange: (e) => onChange(e.target.value.toUpperCase()), style: { width: 40, height: 32, padding: 0, border: 0, background: "none" } }),
8601
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9529
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Label, { children: [
9530
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
9531
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 2, children: [
9532
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "color", "aria-label": label, value: valid ? value : "#000000", disabled, onChange: (e) => onChange(e.target.value.toUpperCase()), style: { width: 40, height: 32, padding: 0, border: 0, background: "none" } }),
9533
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8602
9534
  "input",
8603
9535
  {
8604
9536
  name,
@@ -8614,14 +9546,34 @@ function ColorField({ name, label, value, onChange, disabled }) {
8614
9546
  ] });
8615
9547
  }
8616
9548
  function TagsField({ name, label, hint, value, onChange, disabled }) {
8617
- const [text, setText] = React11.useState(value.join(", "));
8618
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Label, { children: [
8619
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
8620
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { name, value: text, disabled, onChange: (e) => {
8621
- setText(e.target.value);
8622
- onChange([...new Set(e.target.value.split(",").map((tag) => tag.replace(/[<>]/g, "").trim().slice(0, 24)).filter(Boolean))].slice(0, 10));
8623
- }, style: { padding: "6px 8px", border: "1px solid #dcdce4", borderRadius: 4, fontSize: 13 } }),
8624
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: hint })
9549
+ const external = value.join(", ");
9550
+ const input = React12.useRef(null);
9551
+ const focused = React12.useRef(false);
9552
+ const parse = (next) => [...new Set(next.split(",").map((tag) => tag.replace(/[<>]/g, "").trim().slice(0, 24)).filter(Boolean))].slice(0, 10);
9553
+ React12.useEffect(() => {
9554
+ if (!focused.current && input.current && input.current.value !== external) input.current.value = external;
9555
+ }, [external]);
9556
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Label, { children: [
9557
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
9558
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9559
+ "input",
9560
+ {
9561
+ ref: input,
9562
+ name,
9563
+ defaultValue: external,
9564
+ disabled,
9565
+ spellCheck: false,
9566
+ onFocus: () => {
9567
+ focused.current = true;
9568
+ },
9569
+ onBlur: (e) => {
9570
+ focused.current = false;
9571
+ onChange(parse(e.currentTarget.value));
9572
+ },
9573
+ style: { padding: "6px 8px", border: "1px solid #dcdce4", borderRadius: 4, fontSize: 13 }
9574
+ }
9575
+ ),
9576
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: hint })
8625
9577
  ] });
8626
9578
  }
8627
9579
  var FIELD_UID = /^(plugin|global)::[\w.-]+$/;
@@ -8629,11 +9581,11 @@ var LAZY_MAX = 20;
8629
9581
  var parseUids = (text) => [...new Set(text.split(/[\s,]+/).filter(Boolean))];
8630
9582
  var badUids = (uids = []) => uids.length > LAZY_MAX || uids.some((uid) => !FIELD_UID.test(uid));
8631
9583
  function UidListField({ TextField: TextField2, value, onChange, ...props }) {
8632
- const [text, setText] = React11.useState(value.join(", "));
8633
- React11.useEffect(() => {
9584
+ const [text, setText] = React12.useState(value.join(", "));
9585
+ React12.useEffect(() => {
8634
9586
  if (parseUids(text).join() !== value.join()) setText(value.join(", "));
8635
9587
  }, [value.join()]);
8636
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TextField2, { ...props, value: text, onChange: (v) => {
9588
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TextField2, { ...props, value: text, onChange: (v) => {
8637
9589
  setText(v);
8638
9590
  onChange(parseUids(v));
8639
9591
  } });
@@ -8643,31 +9595,31 @@ var SIDEBAR_MAX = 12;
8643
9595
  var ITEM_LABEL = /^[^<>]{1,40}$/;
8644
9596
  var badItem = (item) => !ITEM_LABEL.test(String(item.label || "").trim()) || !item.fields?.length;
8645
9597
  var SYSTEM_FIELDS2 = ["createdAt", "updatedAt", "publishedAt", "createdBy", "updatedBy", "locale", "localizations"];
8646
- var Item = import_styled_components7.default.div`
9598
+ var Item = import_styled_components8.default.div`
8647
9599
  display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: 4px;
8648
9600
  border: 1px solid ${({ theme }) => theme.colors.neutral200}; background: ${({ theme }) => theme.colors.neutral100};
8649
9601
  `;
8650
- var Checks = import_styled_components7.default.fieldset`
9602
+ var Checks = import_styled_components8.default.fieldset`
8651
9603
  display: flex; flex-wrap: wrap; gap: 4px 16px; border: 0; padding: 0; margin: 0; font-size: 13px; color: ${({ theme }) => theme.colors.neutral800};
8652
9604
  legend { font-size: 12px; font-weight: 600; margin-bottom: 4px; }
8653
9605
  label { display: inline-flex; align-items: center; gap: 6px; }
8654
9606
  `;
8655
- var TOOLBAR2 = ["modes", "history", "devices", "status", "actions"];
9607
+ var TOOLBAR2 = ["modes", "history", "versions", "devices", "status", "actions"];
8656
9608
  var DEVICE_NAMES = ["fit", "mobile", "tablet", "desktop"];
8657
9609
  var DEVICE_LABEL = /^[^<>]{1,24}$/;
8658
9610
  var badDevices = (list2 = []) => list2.length < 1 || list2.length > 8 || list2.some((item) => typeof item !== "string" && (!DEVICE_LABEL.test(String(item.label || "").trim()) || !(Number.isInteger(item.width) && item.width >= 240 && item.width <= 3840))) || new Set(list2.map((item) => typeof item === "string" ? item : item.width)).size !== list2.length;
8659
- var Row = import_styled_components7.default.div` display: flex; align-items: center; gap: 8px; min-height: 36px; font-size: 13px; color: ${({ theme }) => theme.colors.neutral800}; `;
8660
- function PaneEditor({ id, toolbar, devices, set: set2, t, disabled, TextField: TextField2 }) {
9611
+ var Row = import_styled_components8.default.div` display: flex; align-items: center; gap: 8px; min-height: 36px; font-size: 13px; color: ${({ theme }) => theme.colors.neutral800}; `;
9612
+ function PaneEditor({ id, toolbar, devices, set: set2, t, disabled, TextField: TextField2, versions }) {
8661
9613
  const move = (list2, index, by) => {
8662
9614
  const next = [...list2];
8663
9615
  [next[index], next[index + by]] = [next[index + by], next[index]];
8664
9616
  return next;
8665
9617
  };
8666
- const arrows = (list2, index, key) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
8667
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tool, { icon: "up", label: t.moveUp, disabled: disabled || index < 0 || index === 0, onClick: () => set2(key, move(list2, index, -1)) }),
8668
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tool, { icon: "down", label: t.moveDown, disabled: disabled || index < 0 || index === list2.length - 1, onClick: () => set2(key, move(list2, index, 1)) })
9618
+ const arrows = (list2, index, key) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
9619
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tool, { icon: "up", label: t.moveUp, disabled: disabled || index < 0 || index === 0, onClick: () => set2(key, move(list2, index, -1)) }),
9620
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tool, { icon: "down", label: t.moveDown, disabled: disabled || index < 0 || index === list2.length - 1, onClick: () => set2(key, move(list2, index, 1)) })
8669
9621
  ] });
8670
- const check = (list2, item, key) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9622
+ const check = (list2, item, key) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8671
9623
  "input",
8672
9624
  {
8673
9625
  type: "checkbox",
@@ -8678,27 +9630,27 @@ function PaneEditor({ id, toolbar, devices, set: set2, t, disabled, TextField: T
8678
9630
  }
8679
9631
  );
8680
9632
  const width = (index, patch) => set2("previewDevices", devices.map((item, i) => i === index ? { ...item, ...patch } : item));
8681
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 3, "data-testid": `pane-editor-${id}`, children: [
8682
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.paneHelp }),
8683
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { children: [...toolbar, ...TOOLBAR2.filter((item) => !toolbar.includes(item))].map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Row, { "data-testid": `${id}-toolbar-${item}`, children: [
9633
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 3, "data-testid": `pane-editor-${id}`, children: [
9634
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.paneHelp }),
9635
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { children: [...toolbar, ...TOOLBAR2.filter((item) => !toolbar.includes(item))].filter((item) => item !== "versions" || versions).map((item) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Row, { "data-testid": `${id}-toolbar-${item}`, children: [
8684
9636
  arrows(toolbar, toolbar.indexOf(item), "previewToolbar"),
8685
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { style: { display: "inline-flex", gap: 6, alignItems: "center" }, children: [
9637
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { style: { display: "inline-flex", gap: 6, alignItems: "center" }, children: [
8686
9638
  check(toolbar, item, "previewToolbar"),
8687
9639
  t.toolbar[item]
8688
9640
  ] })
8689
9641
  ] }, item)) }),
8690
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "delta", tag: "h3", children: t.paneDevices }),
8691
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.paneDevicesHelp }),
8692
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { children: [...devices, ...DEVICE_NAMES.filter((item) => !devices.includes(item))].map((item) => {
9642
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "delta", tag: "h3", children: t.paneDevices }),
9643
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.paneDevicesHelp }),
9644
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { children: [...devices, ...DEVICE_NAMES.filter((item) => !devices.includes(item))].map((item) => {
8693
9645
  const index = devices.indexOf(item);
8694
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Row, { "data-testid": `${id}-device-${typeof item === "string" ? item : index}`, children: [
9646
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Row, { "data-testid": `${id}-device-${typeof item === "string" ? item : index}`, children: [
8695
9647
  arrows(devices, index, "previewDevices"),
8696
- typeof item === "string" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { style: { display: "inline-flex", gap: 6, alignItems: "center" }, children: [
9648
+ typeof item === "string" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { style: { display: "inline-flex", gap: 6, alignItems: "center" }, children: [
8697
9649
  check(devices, item, "previewDevices"),
8698
9650
  t.device[item]
8699
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
8700
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { flex: "1 1 160px" }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TextField2, { name: `${id}-device-label-${index}`, label: t.paneWidthLabel, value: item.label, disabled, onChange: (v) => width(index, { label: v }) }) }),
8701
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { width: 140 }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9651
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
9652
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { flex: "1 1 160px" }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TextField2, { name: `${id}-device-label-${index}`, label: t.paneWidthLabel, value: item.label, disabled, onChange: (v) => width(index, { label: v }) }) }),
9653
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { width: 140 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8702
9654
  TextField2,
8703
9655
  {
8704
9656
  name: `${id}-device-width-${index}`,
@@ -8708,12 +9660,12 @@ function PaneEditor({ id, toolbar, devices, set: set2, t, disabled, TextField: T
8708
9660
  onChange: (v) => width(index, { width: /^\d{1,4}$/.test(v.trim()) ? Number(v.trim()) : NaN })
8709
9661
  }
8710
9662
  ) }),
8711
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tool, { icon: "close", label: t.paneRemoveWidth, disabled, onClick: () => set2("previewDevices", devices.filter((_, i) => i !== index)) })
9663
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tool, { icon: "close", label: t.paneRemoveWidth, disabled, onClick: () => set2("previewDevices", devices.filter((_, i) => i !== index)) })
8712
9664
  ] })
8713
9665
  ] }, typeof item === "string" ? item : `px-${index}`);
8714
9666
  }) }),
8715
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
8716
- import_design_system7.Button,
9667
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9668
+ import_design_system8.Button,
8717
9669
  {
8718
9670
  variant: "secondary",
8719
9671
  size: "S",
@@ -8723,7 +9675,7 @@ function PaneEditor({ id, toolbar, devices, set: set2, t, disabled, TextField: T
8723
9675
  children: t.paneAddWidth
8724
9676
  }
8725
9677
  ) }),
8726
- badDevices(devices) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "alert", variant: "pi", textColor: "danger600", children: t.paneInvalid })
9678
+ badDevices(devices) && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", variant: "pi", textColor: "danger600", children: t.paneInvalid })
8727
9679
  ] });
8728
9680
  }
8729
9681
  var DAYS = (n) => Number.isInteger(n) && n >= 1 && n <= 3650;
@@ -8731,7 +9683,7 @@ var badRetention = (h) => !h || !DAYS(h.retentionDays) || !DAYS(h.eventDays) ||
8731
9683
  function HistorySettings({ types, history, set: set2, t, disabled, ToggleField: ToggleField2, TextField: TextField2 }) {
8732
9684
  const all = history.contentTypes === "all";
8733
9685
  const list2 = all ? [] : history.contentTypes;
8734
- const number = (key) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { minWidth: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9686
+ const number = (key) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { minWidth: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8735
9687
  TextField2,
8736
9688
  {
8737
9689
  name: `history-${key}`,
@@ -8741,15 +9693,15 @@ function HistorySettings({ types, history, set: set2, t, disabled, ToggleField:
8741
9693
  onChange: (v) => set2(key, /^\d{1,5}$/.test(v.trim()) ? Number(v.trim()) : NaN)
8742
9694
  }
8743
9695
  ) });
8744
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "history-settings", children: [
8745
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "beta", tag: "h2", children: t.historySettings }),
8746
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.historySettingsHelp }),
8747
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "history-enabled", label: t.historyEnabled, value: history.enabled, disabled, onChange: (v) => set2("enabled", v) }),
8748
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "history-all", label: t.historyAll, value: all, disabled: disabled || !history.enabled, onChange: (v) => set2("contentTypes", v ? "all" : types.map((type) => type.uid)) }),
8749
- !all && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Checks, { disabled: disabled || !history.enabled, children: [
8750
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("legend", { children: t.historyTypes }),
8751
- types.map((type) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
8752
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9696
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "history-settings", children: [
9697
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.historySettings }),
9698
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.historySettingsHelp }),
9699
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "history-enabled", label: t.historyEnabled, value: history.enabled, disabled, onChange: (v) => set2("enabled", v) }),
9700
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "history-all", label: t.historyAll, value: all, disabled: disabled || !history.enabled, onChange: (v) => set2("contentTypes", v ? "all" : types.map((type) => type.uid)) }),
9701
+ !all && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Checks, { disabled: disabled || !history.enabled, children: [
9702
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("legend", { children: t.historyTypes }),
9703
+ types.map((type) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
9704
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8753
9705
  "input",
8754
9706
  {
8755
9707
  type: "checkbox",
@@ -8761,13 +9713,13 @@ function HistorySettings({ types, history, set: set2, t, disabled, ToggleField:
8761
9713
  type.displayName
8762
9714
  ] }, type.uid))
8763
9715
  ] }),
8764
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 4, wrap: "wrap", alignItems: "flex-end", children: [
9716
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 4, wrap: "wrap", alignItems: "flex-end", children: [
8765
9717
  number("retentionDays"),
8766
9718
  number("maxSnapshots"),
8767
9719
  number("eventDays"),
8768
9720
  number("trashDays")
8769
9721
  ] }),
8770
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: badRetention(history) ? "danger600" : "neutral600", role: badRetention(history) ? "alert" : void 0, children: badRetention(history) ? t.historyInvalid : `${t.historyRetentionHelp} ${t.trashDaysHelp}` })
9722
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: badRetention(history) ? "danger600" : "neutral600", role: badRetention(history) ? "alert" : void 0, children: badRetention(history) ? t.historyInvalid : `${t.historyRetentionHelp} ${t.trashDaysHelp}` })
8771
9723
  ] }) });
8772
9724
  }
8773
9725
  function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: SelectField2, TextField: TextField2 }) {
@@ -8781,10 +9733,9 @@ function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: Selec
8781
9733
  };
8782
9734
  const fields = (type.attributes || []).filter((attr) => !SYSTEM_FIELDS2.includes(attr.name));
8783
9735
  const id = (name, index) => `sidebar-${name}-${type.uid}${index === void 0 ? "" : `-${index}`}`;
8784
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 3, paddingLeft: 4, "data-testid": `sidebar-editor-${type.uid}`, children: [
8785
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "delta", tag: "h3", children: t.f("sidebarTitle", { name: type.displayName }) }),
8786
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.sidebarHelp }),
8787
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { maxWidth: 240 }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9736
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 3, "data-testid": `sidebar-editor-${type.uid}`, children: [
9737
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.sidebarHelp }),
9738
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8788
9739
  SelectField2,
8789
9740
  {
8790
9741
  name: id("position"),
@@ -8795,21 +9746,21 @@ function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: Selec
8795
9746
  onChange: (v) => set2("sidebarPosition", v, "left")
8796
9747
  }
8797
9748
  ) }),
8798
- items2.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Item, { "data-testid": id("item", index), children: [
8799
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 4, alignItems: "flex-end", wrap: "wrap", children: [
8800
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { flex: "1 1 200px" }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TextField2, { name: id("label", index), label: t.sidebarItemLabel, value: item.label, disabled, onChange: (v) => edit(index, { label: v }) }) }),
8801
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { minWidth: 180 }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9749
+ items2.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Item, { "data-testid": id("item", index), children: [
9750
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 4, alignItems: "flex-end", wrap: "wrap", children: [
9751
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { flex: "1 1 200px" }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TextField2, { name: id("label", index), label: t.sidebarItemLabel, value: item.label, disabled, onChange: (v) => edit(index, { label: v }) }) }),
9752
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { minWidth: 180 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8802
9753
  SelectField2,
8803
9754
  {
8804
9755
  name: id("icon", index),
8805
9756
  label: t.sidebarIcon,
8806
9757
  value: item.icon || "none",
8807
9758
  disabled,
8808
- options: [{ value: "none", label: t.noIcon }, ...SIDEBAR_ICONS.map((value) => ({ value, label: t.icons[value], icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: value, size: 16 }) }))],
9759
+ options: [{ value: "none", label: t.noIcon }, ...SIDEBAR_ICONS.map((value) => ({ value, label: t.icons[value], icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: value, size: 16 }) }))],
8809
9760
  onChange: (v) => edit(index, { icon: v === "none" ? void 0 : v })
8810
9761
  }
8811
9762
  ) }),
8812
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { minWidth: 160 }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9763
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { minWidth: 160 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8813
9764
  SelectField2,
8814
9765
  {
8815
9766
  name: id("open", index),
@@ -8820,16 +9771,16 @@ function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: Selec
8820
9771
  onChange: (v) => edit(index, { open: v })
8821
9772
  }
8822
9773
  ) }),
8823
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 1, paddingBottom: 1, children: [
8824
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tool, { icon: "up", label: t.moveUp, disabled: disabled || index === 0, onClick: () => move(index, -1) }),
8825
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tool, { icon: "down", label: t.moveDown, disabled: disabled || index === items2.length - 1, onClick: () => move(index, 1) }),
8826
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tool, { icon: "close", label: t.sidebarRemove, disabled, onClick: () => save(items2.filter((_, i) => i !== index)) })
9774
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 1, paddingBottom: 1, children: [
9775
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tool, { icon: "up", label: t.moveUp, disabled: disabled || index === 0, onClick: () => move(index, -1) }),
9776
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tool, { icon: "down", label: t.moveDown, disabled: disabled || index === items2.length - 1, onClick: () => move(index, 1) }),
9777
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tool, { icon: "close", label: t.sidebarRemove, disabled, onClick: () => save(items2.filter((_, i) => i !== index)) })
8827
9778
  ] })
8828
9779
  ] }),
8829
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Checks, { disabled, children: [
8830
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("legend", { children: t.sidebarFields }),
8831
- fields.map((attr) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
8832
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9780
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Checks, { disabled, children: [
9781
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("legend", { children: t.sidebarFields }),
9782
+ fields.map((attr) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
9783
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8833
9784
  "input",
8834
9785
  {
8835
9786
  type: "checkbox",
@@ -8841,11 +9792,11 @@ function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: Selec
8841
9792
  attr.name
8842
9793
  ] }, attr.name))
8843
9794
  ] }),
8844
- badItem(item) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "alert", variant: "pi", textColor: "danger600", children: t.sidebarInvalid })
9795
+ badItem(item) && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", variant: "pi", textColor: "danger600", children: t.sidebarInvalid })
8845
9796
  ] }, index)),
8846
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 2, alignItems: "center", children: [
8847
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
8848
- import_design_system7.Button,
9797
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 2, alignItems: "center", children: [
9798
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9799
+ import_design_system8.Button,
8849
9800
  {
8850
9801
  variant: "secondary",
8851
9802
  size: "S",
@@ -8855,30 +9806,30 @@ function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: Selec
8855
9806
  children: t.sidebarAdd
8856
9807
  }
8857
9808
  ),
8858
- items2.length >= SIDEBAR_MAX && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.f("sidebarLimit", { max: SIDEBAR_MAX }) })
9809
+ items2.length >= SIDEBAR_MAX && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.f("sidebarLimit", { max: SIDEBAR_MAX }) })
8859
9810
  ] })
8860
9811
  ] });
8861
9812
  }
8862
9813
  var permissions = { read: [{ action: "plugin::blockscene.settings.read", subject: null }], update: [{ action: "plugin::blockscene.settings.update", subject: null }] };
8863
- function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: MediaPicker2, ToggleField: ToggleField2, SelectField: SelectField2, TextField: TextField2, lazyEditors = false }) {
9814
+ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: MediaPicker2, ToggleField: ToggleField2, SelectField: SelectField2, TextField: TextField2, lazyEditors = false, section = "general" }) {
8864
9815
  const t = useMessages();
8865
9816
  const { get, put, del } = useClient();
8866
9817
  const { canRead, canUpdate, isLoading } = usePermissions2();
8867
- const [data, setData] = React11.useState(null);
8868
- const [catalog, setCatalog] = React11.useState(null);
8869
- const [settings, setSettings] = React11.useState(null);
8870
- const [media, setMedia] = React11.useState({});
8871
- const [sources, setSources] = React11.useState({});
8872
- const [dirty, setDirty] = React11.useState(false);
8873
- const [saving, setSaving] = React11.useState(false);
8874
- const [status, setStatus] = React11.useState("");
8875
- const [failed, setFailed] = React11.useState(false);
8876
- const [filter, setFilter] = React11.useState("");
8877
- const [picking, setPicking] = React11.useState(null);
8878
- React11.useEffect(() => {
9818
+ const [data, setData] = React12.useState(null);
9819
+ const [catalog, setCatalog] = React12.useState(null);
9820
+ const [settings, setSettings] = React12.useState(null);
9821
+ const [media, setMedia] = React12.useState({});
9822
+ const [sources, setSources] = React12.useState({});
9823
+ const [dirty, setDirty] = React12.useState(false);
9824
+ const [saving, setSaving] = React12.useState(false);
9825
+ const [status, setStatus] = React12.useState("");
9826
+ const [failed, setFailed] = React12.useState(false);
9827
+ const [filter, setFilter] = React12.useState("");
9828
+ const [picking, setPicking] = React12.useState(null);
9829
+ React12.useEffect(() => {
8879
9830
  if (!canRead || isLoading) return;
8880
9831
  let active = true;
8881
- Promise.all([get("/blockscene/settings"), get("/blockscene/catalog")]).then(([s, c]) => {
9832
+ Promise.all([get("/blockscene/settings"), section === "gallery" ? get("/blockscene/catalog") : Promise.resolve({ data: {} })]).then(([s, c]) => {
8882
9833
  if (!active) return;
8883
9834
  setData(s.data);
8884
9835
  setSettings(s.data.settings);
@@ -8890,18 +9841,20 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
8890
9841
  return () => {
8891
9842
  active = false;
8892
9843
  };
8893
- }, [get, canRead, isLoading]);
9844
+ }, [get, canRead, isLoading, section]);
8894
9845
  const update = (patch) => {
8895
9846
  setSettings((current) => patch(structuredClone(current)));
8896
9847
  setDirty(true);
8897
9848
  setStatus("");
8898
9849
  };
8899
- const badColor = settings && (Object.values(settings.palette).some((value) => !COLOR2.test(value)) || [settings.editor.previewUrl, settings.editor.blockPreviewUrl].some((url) => url && !/^https?:\/\/\S+$/.test(url)));
9850
+ const badPalette = settings && Object.values(settings.palette).some((value) => !COLOR2.test(value));
9851
+ const badPreviewUrl = settings && [settings.editor.previewUrl, settings.editor.blockPreviewUrl].some((url) => url && !/^https?:\/\/\S+$/.test(url));
8900
9852
  const badSidebar = settings && Object.values(settings.contentTypes || {}).some((entry) => (entry.sidebar || []).some(badItem));
8901
9853
  const badLazy = settings && badUids(settings.editor.lazyFields);
8902
9854
  const badHistory = settings && data?.historyTypes && badRetention(settings.history);
8903
- const badPane = settings && [settings.editor, ...Object.values(settings.contentTypes || {})].some((entry) => entry.previewDevices && badDevices(entry.previewDevices));
8904
- const invalid = badColor || badSidebar || badLazy || badHistory || badPane;
9855
+ const badEditorPane = settings && settings.editor.previewDevices && badDevices(settings.editor.previewDevices);
9856
+ const badTypePane = settings && Object.values(settings.contentTypes || {}).some((entry) => entry.previewDevices && badDevices(entry.previewDevices));
9857
+ const invalid = section === "general" ? badLazy : section === "preview" ? badPreviewUrl || badEditorPane : section === "content-types" ? badSidebar || badTypePane : section === "gallery" ? badPalette : badHistory;
8905
9858
  const save = async () => {
8906
9859
  if (!settings || invalid || !canUpdate) return;
8907
9860
  setSaving(true);
@@ -8953,36 +9906,38 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
8953
9906
  return index === 0 && manual ? t.manual : t.automatic;
8954
9907
  };
8955
9908
  const ready = !isLoading && canRead && !failed && settings && catalog;
8956
- const header = React11.useRef(null);
8957
- const [floating, setFloating] = React11.useState(false);
9909
+ const sectionTitle = t[`settings${section === "content-types" ? "ContentTypes" : section[0].toUpperCase() + section.slice(1)}`];
9910
+ const sectionIntro = t[`settings${section === "content-types" ? "ContentTypes" : section[0].toUpperCase() + section.slice(1)}Intro`];
9911
+ const header = React12.useRef(null);
9912
+ const [floating, setFloating] = React12.useState(false);
8958
9913
  const main = useMainRect2(header);
8959
- React11.useEffect(() => {
9914
+ React12.useEffect(() => {
8960
9915
  const el = header.current;
8961
9916
  if (!el || typeof IntersectionObserver === "undefined") return;
8962
9917
  const observer = new IntersectionObserver(([entry]) => setFloating(!entry.isIntersecting && entry.boundingClientRect.top < 0));
8963
9918
  observer.observe(el);
8964
9919
  return () => observer.disconnect();
8965
9920
  }, [ready]);
8966
- const controls = (suffix) => ready && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
8967
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "status", "aria-live": "polite", textColor: dirty ? "warning700" : "neutral600", "data-testid": `${dirty ? "unsaved-indicator" : "save-status"}${suffix}`, children: dirty ? t.unsaved : status || t.noChanges }),
8968
- !suffix && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { variant: "tertiary", onClick: restore, disabled: !canUpdate || saving, "data-testid": "restore-blockscene-settings", children: data.projectDefaults ? t.restoreProject : t.resetAll }),
8969
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { onClick: save, disabled: !canUpdate || invalid || !dirty, loading: saving, "data-testid": `save-blockscene-settings${suffix}`, children: t.save })
9921
+ const controls = (suffix) => ready && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
9922
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "status", "aria-live": "polite", textColor: dirty ? "warning700" : "neutral600", "data-testid": `${dirty ? "unsaved-indicator" : "save-status"}${suffix}`, children: dirty ? t.unsaved : status || t.noChanges }),
9923
+ !suffix && section === "general" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Button, { variant: "tertiary", onClick: restore, disabled: !canUpdate || saving, "data-testid": "restore-blockscene-settings", children: data.projectDefaults ? t.restoreProject : t.resetAll }),
9924
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Button, { onClick: save, disabled: !canUpdate || invalid || !dirty, loading: saving, "data-testid": `save-blockscene-settings${suffix}`, children: t.save })
8970
9925
  ] });
8971
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { padding: 8, background: "neutral100", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 5, children: [
8972
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: header, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
8973
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "alpha", tag: "h1", children: t.settingsTitle }),
9926
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 8, background: "neutral100", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 5, children: [
9927
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: header, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
9928
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "alpha", tag: "h1", children: sectionTitle }),
8974
9929
  controls("")
8975
9930
  ] }) }),
8976
- floating && main.width > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Bar, { style: { left: main.left, width: main.width }, "data-testid": "settings-floating-bar", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
8977
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "beta", tag: "p", children: t.settingsTitle }),
9931
+ floating && main.width > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Bar, { style: { left: main.left, width: main.width }, "data-testid": "settings-floating-bar", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
9932
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "p", children: sectionTitle }),
8978
9933
  controls("-floating")
8979
9934
  ] }) }),
8980
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { textColor: "neutral600", children: t.settingsIntro }),
8981
- isLoading ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { children: "\u2026" }) : !canRead ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "alert", children: t.denied }) : failed ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "alert", children: t.loadFailed }) : !settings || !catalog ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { children: t.loading }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
8982
- data.disabled && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { padding: 4, background: "warning100", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "alert", textColor: "warning700", children: t.disabledByServer }) }),
8983
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
8984
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "beta", tag: "h2", children: t.palette }),
8985
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Swatches, { children: Object.keys(DEFAULT_PALETTE).map((key) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9935
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { textColor: "neutral600", children: sectionIntro }),
9936
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { children: "\u2026" }) : !canRead ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", children: t.denied }) : failed ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", children: t.loadFailed }) : !settings || !catalog ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { children: t.loading }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
9937
+ data.disabled && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 4, background: "warning100", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", textColor: "warning700", children: t.disabledByServer }) }),
9938
+ section === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
9939
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.palette }),
9940
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Swatches, { children: Object.keys(DEFAULT_PALETTE).map((key) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
8986
9941
  ColorField,
8987
9942
  {
8988
9943
  name: `palette-${key}`,
@@ -8996,43 +9951,43 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
8996
9951
  },
8997
9952
  key
8998
9953
  )) }),
8999
- badColor && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "alert", textColor: "danger600", children: t.invalidColor }),
9000
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.previewLabel }),
9001
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Swatches, { "data-testid": "palette-preview", children: TEMPLATES.map((template) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", gap: 1, children: [
9002
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { aspectRatio: "16 / 9", overflow: "hidden" }, hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Wireframe, { template, palette: settings.palette }) }),
9003
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.templates[template] })
9954
+ badPalette && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", textColor: "danger600", children: t.invalidColor }),
9955
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.previewLabel }),
9956
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Swatches, { "data-testid": "palette-preview", children: TEMPLATES.map((template) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", gap: 1, children: [
9957
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { aspectRatio: "16 / 9", overflow: "hidden" }, hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Wireframe, { template, palette: settings.palette }) }),
9958
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.templates[template] })
9004
9959
  ] }, template)) }),
9005
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { variant: "tertiary", size: "S", disabled: !canUpdate, onClick: () => update((s) => {
9960
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Button, { variant: "tertiary", size: "S", disabled: !canUpdate, onClick: () => update((s) => {
9006
9961
  s.palette = { ...DEFAULT_PALETTE };
9007
9962
  return s;
9008
9963
  }), children: t.resetPalette }) })
9009
9964
  ] }) }),
9010
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
9011
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "beta", tag: "h2", children: t.editor }),
9012
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-enabled", label: t.enabled, value: editor.enabled, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9965
+ section === "general" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
9966
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.editor }),
9967
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-enabled", label: t.enabled, value: editor.enabled, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9013
9968
  s.editor.enabled = v;
9014
9969
  return s;
9015
9970
  }) }),
9016
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.enabledHelp }),
9017
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-showOpenAll", label: t.showOpenAll, value: editor.showOpenAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9971
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.enabledHelp }),
9972
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-showOpenAll", label: t.showOpenAll, value: editor.showOpenAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9018
9973
  s.editor.showOpenAll = v;
9019
9974
  return s;
9020
9975
  }) }),
9021
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-showCloseAll", label: t.showCloseAll, value: editor.showCloseAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9976
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-showCloseAll", label: t.showCloseAll, value: editor.showCloseAll, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9022
9977
  s.editor.showCloseAll = v;
9023
9978
  return s;
9024
9979
  }) }),
9025
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.toggleHelp }),
9026
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-showRowThumbnails", label: t.showRowThumbnails, value: editor.showRowThumbnails !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9980
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.toggleHelp }),
9981
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-showRowThumbnails", label: t.showRowThumbnails, value: editor.showRowThumbnails !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9027
9982
  s.editor.showRowThumbnails = v;
9028
9983
  return s;
9029
9984
  }) }),
9030
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-friendlyLabels", label: t.friendlyLabels, value: editor.friendlyLabels !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9985
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-friendlyLabels", label: t.friendlyLabels, value: editor.friendlyLabels !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9031
9986
  s.editor.friendlyLabels = v;
9032
9987
  return s;
9033
9988
  }) }),
9034
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.friendlyLabelsHelp }),
9035
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9989
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.friendlyLabelsHelp }),
9990
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9036
9991
  SelectField2,
9037
9992
  {
9038
9993
  name: "editor-initialState",
@@ -9046,8 +10001,32 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9046
10001
  })
9047
10002
  }
9048
10003
  ),
9049
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.rememberHelp }),
9050
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10004
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.rememberHelp }),
10005
+ lazyEditors && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
10006
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-lazyEditors", label: t.lazyEditors, value: editor.lazyEditors !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
10007
+ s.editor.lazyEditors = v;
10008
+ return s;
10009
+ }) }),
10010
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
10011
+ UidListField,
10012
+ {
10013
+ TextField: TextField2,
10014
+ name: "editor-lazyFields",
10015
+ label: t.lazyFields,
10016
+ value: editor.lazyFields || [],
10017
+ disabled: !canUpdate || saving || editor.lazyEditors === false,
10018
+ placeholder: "plugin::ckeditor5.CKEditor",
10019
+ onChange: (uids) => update((s) => {
10020
+ s.editor.lazyFields = uids;
10021
+ return s;
10022
+ })
10023
+ }
10024
+ ),
10025
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: badLazy ? "danger600" : "neutral600", role: badLazy ? "alert" : void 0, children: badLazy ? t.f("lazyFieldsInvalid", { max: LAZY_MAX }) : t.lazyEditorsHelp })
10026
+ ] })
10027
+ ] }) }),
10028
+ section === "preview" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
10029
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9051
10030
  TextField2,
9052
10031
  {
9053
10032
  name: "editor-blockPreviewUrl",
@@ -9061,8 +10040,8 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9061
10040
  })
9062
10041
  }
9063
10042
  ),
9064
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.blockPreviewUrlHelp }),
9065
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10043
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.blockPreviewUrlHelp }),
10044
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9066
10045
  TextField2,
9067
10046
  {
9068
10047
  name: "editor-previewUrl",
@@ -9076,9 +10055,9 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9076
10055
  })
9077
10056
  }
9078
10057
  ),
9079
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.previewUrlHelp }),
9080
- !editor.previewUrl && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "warning700", "data-testid": "preview-url-empty", children: t.previewUrlEmpty }),
9081
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10058
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.previewUrlHelp }),
10059
+ !editor.previewUrl && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "warning700", "data-testid": "preview-url-empty", children: t.previewUrlEmpty }),
10060
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9082
10061
  SelectField2,
9083
10062
  {
9084
10063
  name: "editor-previewMode",
@@ -9092,12 +10071,13 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9092
10071
  })
9093
10072
  }
9094
10073
  ),
9095
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.previewModeHelp }),
9096
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "delta", tag: "h3", children: t.paneTitle }),
9097
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10074
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.previewModeHelp }),
10075
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "delta", tag: "h3", children: t.paneTitle }),
10076
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9098
10077
  PaneEditor,
9099
10078
  {
9100
10079
  id: "editor",
10080
+ versions: Boolean(data.historyTypes),
9101
10081
  toolbar: editor.previewToolbar || TOOLBAR2,
9102
10082
  devices: editor.previewDevices || DEVICE_NAMES,
9103
10083
  t,
@@ -9109,51 +10089,30 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9109
10089
  })
9110
10090
  }
9111
10091
  ),
9112
- lazyEditors && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
9113
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-lazyEditors", label: t.lazyEditors, value: editor.lazyEditors !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9114
- s.editor.lazyEditors = v;
10092
+ badPreviewUrl && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", textColor: "danger600", children: t.invalidUrl }),
10093
+ lazyEditors && data.blockPreviewAvailable && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
10094
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-blockPreviewInForm", label: t.blockPreviewInForm, value: editor.blockPreviewInForm, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
10095
+ s.editor.blockPreviewInForm = v;
9115
10096
  return s;
9116
10097
  }) }),
9117
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9118
- UidListField,
9119
- {
9120
- TextField: TextField2,
9121
- name: "editor-lazyFields",
9122
- label: t.lazyFields,
9123
- value: editor.lazyFields || [],
9124
- disabled: !canUpdate || saving || editor.lazyEditors === false,
9125
- placeholder: "plugin::ckeditor5.CKEditor",
9126
- onChange: (uids) => update((s) => {
9127
- s.editor.lazyFields = uids;
9128
- return s;
9129
- })
9130
- }
9131
- ),
9132
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: badLazy ? "danger600" : "neutral600", role: badLazy ? "alert" : void 0, children: badLazy ? t.f("lazyFieldsInvalid", { max: LAZY_MAX }) : t.lazyEditorsHelp }),
9133
- data.blockPreviewAvailable && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
9134
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-blockPreviewInForm", label: t.blockPreviewInForm, value: editor.blockPreviewInForm, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9135
- s.editor.blockPreviewInForm = v;
9136
- return s;
9137
- }) }),
9138
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
9139
- ] })
10098
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
9140
10099
  ] })
9141
10100
  ] }) }),
9142
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "row-actions-settings", children: [
9143
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "beta", tag: "h2", children: t.rowActionsTitle }),
9144
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-confirmDelete", label: t.confirmDeleteOption, value: editor.confirmDelete !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
10101
+ section === "general" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "row-actions-settings", children: [
10102
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.rowActionsTitle }),
10103
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-confirmDelete", label: t.confirmDeleteOption, value: editor.confirmDelete !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9145
10104
  s.editor.confirmDelete = v;
9146
10105
  return s;
9147
10106
  }) }),
9148
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-duplicate", label: t.duplicateOption, value: editor.duplicate !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
10107
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-duplicate", label: t.duplicateOption, value: editor.duplicate !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9149
10108
  s.editor.duplicate = v;
9150
10109
  return s;
9151
10110
  }) }),
9152
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToggleField2, { name: "editor-clipboard", label: t.clipboardOption, value: editor.clipboard !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
10111
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-clipboard", label: t.clipboardOption, value: editor.clipboard !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9153
10112
  s.editor.clipboard = v;
9154
10113
  return s;
9155
10114
  }) }),
9156
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10115
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9157
10116
  SelectField2,
9158
10117
  {
9159
10118
  name: "editor-hiddenBlocks",
@@ -9167,9 +10126,9 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9167
10126
  })
9168
10127
  }
9169
10128
  ),
9170
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: data.hiddenAttribute ? t.hiddenBlocksHelp : t.hiddenAttributeOff })
10129
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: data.hiddenAttribute ? t.hiddenBlocksHelp : t.hiddenAttributeOff })
9171
10130
  ] }) }),
9172
- data.historyTypes && settings.history && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10131
+ section === "history" && data.historyTypes && settings.history && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9173
10132
  HistorySettings,
9174
10133
  {
9175
10134
  types: data.historyTypes,
@@ -9184,10 +10143,10 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9184
10143
  })
9185
10144
  }
9186
10145
  ),
9187
- (data.contentTypes || []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "content-types", children: [
9188
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "beta", tag: "h2", children: t.contentTypes }),
9189
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: t.contentTypesHelp }),
9190
- data.contentTypes.map((type) => {
10146
+ section === "history" && !data.historyTypes && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { textColor: "neutral600", children: t.historyUnavailable }) }),
10147
+ section === "content-types" && (data.contentTypes || []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "content-types", children: [
10148
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 4, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.contentTypesHelp }) }),
10149
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ContentTypeGrid, { children: data.contentTypes.map((type) => {
9191
10150
  const entry = settings.contentTypes?.[type.uid] || {};
9192
10151
  const set2 = (key, value, fallback) => update((s) => {
9193
10152
  const next = { ...s.contentTypes?.[type.uid] || {} };
@@ -9198,9 +10157,10 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9198
10157
  else delete s.contentTypes[type.uid];
9199
10158
  return s;
9200
10159
  });
9201
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
9202
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 6, alignItems: "flex-end", wrap: "wrap", "data-testid": `content-type-${type.uid}`, children: [
9203
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { minWidth: 220 }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10160
+ const customized = Boolean(entry.sidebar?.length || entry.sidebarPosition || entry.previewToolbar || entry.previewDevices);
10161
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ContentTypeCard, { "data-testid": `content-type-${type.uid}`, children: [
10162
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ContentTypeTop, { children: [
10163
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9204
10164
  ToggleField2,
9205
10165
  {
9206
10166
  name: `type-enabled-${type.uid}`,
@@ -9210,7 +10170,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9210
10170
  onChange: (v) => set2("enabled", v, true)
9211
10171
  }
9212
10172
  ) }),
9213
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { style: { minWidth: 240 }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10173
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9214
10174
  SelectField2,
9215
10175
  {
9216
10176
  name: `type-mode-${type.uid}`,
@@ -9222,48 +10182,54 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9222
10182
  }
9223
10183
  ) })
9224
10184
  ] }),
9225
- entry.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SidebarEditor, { type, entry, set: set2, t, disabled: !canUpdate || saving, SelectField: SelectField2, TextField: TextField2 }),
9226
- entry.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 3, paddingLeft: 4, children: [
9227
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9228
- ToggleField2,
9229
- {
9230
- name: `type-pane-${type.uid}`,
9231
- label: t.f("paneTypeOverride", { name: type.displayName }),
9232
- value: Boolean(entry.previewToolbar || entry.previewDevices),
9233
- disabled: !canUpdate || saving,
9234
- onChange: (v) => {
9235
- set2("previewToolbar", v ? [...editor.previewToolbar || TOOLBAR2] : void 0, void 0);
9236
- set2("previewDevices", v ? structuredClone(editor.previewDevices || DEVICE_NAMES) : void 0, void 0);
10185
+ entry.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Advanced, { defaultOpen: customized, children: [
10186
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("summary", { children: t.typeAdvanced }),
10187
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SidebarEditor, { type, entry, set: set2, t, disabled: !canUpdate || saving, SelectField: SelectField2, TextField: TextField2 }),
10188
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ToolbarSection, { children: [
10189
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
10190
+ ToggleField2,
10191
+ {
10192
+ name: `type-pane-${type.uid}`,
10193
+ label: t.f("paneTypeOverride", { name: type.displayName }),
10194
+ value: Boolean(entry.previewToolbar || entry.previewDevices),
10195
+ disabled: !canUpdate || saving,
10196
+ onChange: (v) => {
10197
+ set2("previewToolbar", v ? [...editor.previewToolbar || TOOLBAR2] : void 0, void 0);
10198
+ set2("previewDevices", v ? structuredClone(editor.previewDevices || DEVICE_NAMES) : void 0, void 0);
10199
+ }
9237
10200
  }
9238
- }
9239
- ),
9240
- (entry.previewToolbar || entry.previewDevices) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
9241
- PaneEditor,
9242
- {
9243
- id: `type-${type.uid}`,
9244
- toolbar: entry.previewToolbar || editor.previewToolbar || TOOLBAR2,
9245
- devices: entry.previewDevices || editor.previewDevices || DEVICE_NAMES,
9246
- t,
9247
- disabled: !canUpdate || saving,
9248
- TextField: TextField2,
9249
- set: (key, value) => set2(key, value, void 0)
9250
- }
9251
- )
10201
+ ),
10202
+ (entry.previewToolbar || entry.previewDevices) && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
10203
+ PaneEditor,
10204
+ {
10205
+ id: `type-${type.uid}`,
10206
+ versions: Boolean(data.historyTypes),
10207
+ toolbar: entry.previewToolbar || editor.previewToolbar || TOOLBAR2,
10208
+ devices: entry.previewDevices || editor.previewDevices || DEVICE_NAMES,
10209
+ t,
10210
+ disabled: !canUpdate || saving,
10211
+ TextField: TextField2,
10212
+ set: (key, value) => set2(key, value, void 0)
10213
+ }
10214
+ )
10215
+ ] })
9252
10216
  ] })
9253
10217
  ] }, type.uid);
9254
- }),
9255
- badSidebar && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { role: "alert", textColor: "danger600", children: t.sidebarInvalidSave })
9256
- ] }) }),
9257
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
9258
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "beta", tag: "h2", children: t.components }),
9259
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Searchbar, { name: "component-filter", value: filter, placeholder: t.filter, clearLabel: t.clear, onClear: () => setFilter(""), onChange: (e) => setFilter(e.target.value), children: t.filter }),
9260
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", "data-testid": "components-count", children: t.f("countAll", { count: components.length }) }),
9261
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Grid2, { "data-testid": "components-grid", children: components.map((component) => {
10218
+ }) }),
10219
+ badSidebar && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", textColor: "danger600", children: t.sidebarInvalidSave })
10220
+ ] }),
10221
+ section === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
10222
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.components }),
10223
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Searchbar, { name: "component-filter", value: filter, placeholder: t.filter, clearLabel: t.clear, onClear: () => setFilter(""), onChange: (e) => setFilter(e.target.value), children: t.filter }),
10224
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", "data-testid": "components-count", children: t.f("countAll", { count: components.length }) }),
10225
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Grid2, { "data-testid": "components-grid", children: components.map((component) => {
9262
10226
  const entry = settings.components[component.uid] || {};
9263
10227
  const meta = { ...catalog.components?.[component.uid] || {}, ...media[component.uid] || {} };
10228
+ const groupMarker = Boolean(catalog.groups?.[component.uid] || Object.values(catalog.groups || {}).includes(component.uid));
10229
+ const rowThumbnail = entry.showRowThumbnail ?? !groupMarker;
9264
10230
  const candidates = candidatesFor(component.uid, meta, catalog);
9265
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Card2, { "data-testid": `settings-${component.uid}`, children: [
9266
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10231
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Card2, { "data-testid": `settings-${component.uid}`, children: [
10232
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9267
10233
  Thumb,
9268
10234
  {
9269
10235
  candidates,
@@ -9274,23 +10240,23 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9274
10240
  onResolved: (index) => setSources((current) => current[component.uid] === index ? current : { ...current, [component.uid]: index })
9275
10241
  }
9276
10242
  ),
9277
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [
9278
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { fontWeight: "bold", textColor: "neutral800", children: component.displayName }),
9279
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: [
10243
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [
10244
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { fontWeight: "bold", textColor: "neutral800", children: component.displayName }),
10245
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: [
9280
10246
  component.uid,
9281
10247
  " \xB7 ",
9282
10248
  component.category
9283
10249
  ] }),
9284
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Typography, { variant: "pi", "data-testid": `source-${component.uid}`, children: [
10250
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Typography, { variant: "pi", "data-testid": `source-${component.uid}`, children: [
9285
10251
  t.source,
9286
10252
  ": ",
9287
10253
  sourceOf(component.uid, Boolean(meta.manualImage)),
9288
10254
  meta.manualName ? ` (${meta.manualName})` : ""
9289
10255
  ] }),
9290
- meta.manualMissing && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", role: "alert", textColor: "danger600", children: t.brokenMedia }),
9291
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { gap: 2, wrap: "wrap", children: [
9292
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { variant: "secondary", size: "S", disabled: !canUpdate || saving, onClick: () => setPicking(component.uid), children: entry.mediaId ? t.replace : t.choose }),
9293
- entry.mediaId && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Button, { variant: "tertiary", size: "S", disabled: !canUpdate || saving, onClick: () => {
10256
+ meta.manualMissing && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", role: "alert", textColor: "danger600", children: t.brokenMedia }),
10257
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 2, wrap: "wrap", children: [
10258
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Button, { variant: "secondary", size: "S", disabled: !canUpdate || saving, onClick: () => setPicking(component.uid), children: entry.mediaId ? t.replace : t.choose }),
10259
+ entry.mediaId && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Button, { variant: "tertiary", size: "S", disabled: !canUpdate || saving, onClick: () => {
9294
10260
  update((s) => {
9295
10261
  delete s.components[component.uid]?.mediaId;
9296
10262
  if (!Object.keys(s.components[component.uid] || {}).length) delete s.components[component.uid];
@@ -9303,7 +10269,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9303
10269
  });
9304
10270
  }, children: t.useAutomatic })
9305
10271
  ] }),
9306
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10272
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9307
10273
  SelectField2,
9308
10274
  {
9309
10275
  name: `template-${component.uid}`,
@@ -9317,7 +10283,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9317
10283
  })
9318
10284
  }
9319
10285
  ),
9320
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10286
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9321
10287
  SelectField2,
9322
10288
  {
9323
10289
  name: `typology-${component.uid}`,
@@ -9328,7 +10294,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9328
10294
  onChange: (v) => setComponent(component.uid, "typology", v === "auto" ? void 0 : v)
9329
10295
  }
9330
10296
  ),
9331
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10297
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9332
10298
  TagsField,
9333
10299
  {
9334
10300
  name: `tags-${component.uid}`,
@@ -9339,12 +10305,22 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9339
10305
  onChange: (tags) => setComponent(component.uid, "tags", tags.length ? tags : void 0)
9340
10306
  }
9341
10307
  ),
9342
- meta.variants?.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", "data-testid": `variants-${component.uid}`, children: [
10308
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
10309
+ ToggleField2,
10310
+ {
10311
+ name: `row-thumbnail-${component.uid}`,
10312
+ label: t.componentRowThumbnail,
10313
+ value: rowThumbnail,
10314
+ disabled: !canUpdate || saving,
10315
+ onChange: (v) => setComponent(component.uid, "showRowThumbnail", v)
10316
+ }
10317
+ ),
10318
+ meta.variants?.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", "data-testid": `variants-${component.uid}`, children: [
9343
10319
  t.variantsFromCode,
9344
10320
  ": ",
9345
10321
  meta.variants.map((item) => localized(item.label, t.locale) || item.id).join(", ")
9346
10322
  ] }),
9347
- catalog.groups?.[component.uid] && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10323
+ catalog.groups?.[component.uid] && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9348
10324
  LayoutFields,
9349
10325
  {
9350
10326
  component,
@@ -9359,7 +10335,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9359
10335
  ] }, component.uid);
9360
10336
  }) })
9361
10337
  ] }) }),
9362
- picking && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MediaPicker2, { onClose: () => setPicking(null), onSelect: (asset) => {
10338
+ picking && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MediaPicker2, { onClose: () => setPicking(null), onSelect: (asset) => {
9363
10339
  const uid = picking;
9364
10340
  setPicking(null);
9365
10341
  if (!asset?.id) return;
@@ -9375,8 +10351,8 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9375
10351
  function LayoutFields({ component, layout, set: set2, t, disabled, SelectField: SelectField2 }) {
9376
10352
  const fields = (component.layoutFields || []).map((name) => ({ value: name, label: name }));
9377
10353
  const change = (key, value) => set2(key === "columnsField" && value === "none" ? void 0 : Object.fromEntries(Object.entries({ ...layout, [key]: value }).filter(([, v]) => v !== "none" && v !== void 0)));
9378
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system7.Flex, { direction: "column", alignItems: "stretch", gap: 2, "data-testid": `layout-${component.uid}`, style: { width: "100%" }, children: [
9379
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10354
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 2, "data-testid": `layout-${component.uid}`, style: { width: "100%" }, children: [
10355
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9380
10356
  SelectField2,
9381
10357
  {
9382
10358
  name: `layout-columns-${component.uid}`,
@@ -9387,8 +10363,8 @@ function LayoutFields({ component, layout, set: set2, t, disabled, SelectField:
9387
10363
  onChange: (v) => change("columnsField", v)
9388
10364
  }
9389
10365
  ),
9390
- layout?.columnsField && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
9391
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10366
+ layout?.columnsField && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
10367
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9392
10368
  SelectField2,
9393
10369
  {
9394
10370
  name: `layout-mobile-${component.uid}`,
@@ -9399,7 +10375,7 @@ function LayoutFields({ component, layout, set: set2, t, disabled, SelectField:
9399
10375
  onChange: (v) => change("mobileColumnsField", v)
9400
10376
  }
9401
10377
  ),
9402
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
10378
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9403
10379
  SelectField2,
9404
10380
  {
9405
10381
  name: `layout-max-${component.uid}`,
@@ -9411,46 +10387,57 @@ function LayoutFields({ component, layout, set: set2, t, disabled, SelectField:
9411
10387
  }
9412
10388
  )
9413
10389
  ] }),
9414
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system7.Typography, { variant: "pi", textColor: "neutral600", children: fields.length ? t.layoutHelp : t.layoutNoFields })
10390
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: fields.length ? t.layoutHelp : t.layoutNoFields })
9415
10391
  ] });
9416
10392
  }
10393
+ var SETTINGS_SECTIONS = [
10394
+ { id: "general", label: "General" },
10395
+ { id: "preview", label: "Page preview" },
10396
+ { id: "content-types", label: "Content types" },
10397
+ { id: "gallery", label: "Block gallery" },
10398
+ { id: "history", label: "History & trash" }
10399
+ ];
9417
10400
  function register(app, Component2, to) {
9418
10401
  app.createSettingSection(
9419
10402
  { id: "blockscene", intlLabel: { id: "blockscene.title", defaultMessage: "Blockscene" } },
9420
- [{
9421
- id: "blockscene-settings",
9422
- to,
9423
- intlLabel: { id: "blockscene.settings", defaultMessage: "Gallery" },
9424
- // Module shape: older Strapi 4 (e.g. 4.11) only reads `.default` from the loader result.
9425
- // Not an `async` function: Strapi 5 warns on AsyncFunction loaders.
9426
- Component: () => Promise.resolve({ default: Component2 }),
9427
- permissions: permissions.read
9428
- }]
10403
+ SETTINGS_SECTIONS.map(({ id, label }) => {
10404
+ const Page2 = () => React12.createElement(Component2, { section: id });
10405
+ const sectionPath = id === "general" ? to : to.startsWith("/") ? `${to}-${id}` : `${to}/${id}`;
10406
+ return {
10407
+ id: `blockscene-${id}`,
10408
+ to: sectionPath,
10409
+ intlLabel: { id: `blockscene.settings${id === "content-types" ? "ContentTypes" : id[0].toUpperCase() + id.slice(1)}`, defaultMessage: label },
10410
+ // Module shape: older Strapi 4 (e.g. 4.11) only reads `.default` from the loader result.
10411
+ // Not an `async` function: Strapi 5 warns on AsyncFunction loaders.
10412
+ Component: () => Promise.resolve({ default: Page2 }),
10413
+ permissions: permissions.read
10414
+ };
10415
+ })
9429
10416
  );
9430
10417
  }
9431
10418
 
9432
10419
  // admin/catalog.ts
9433
- var React13 = __toESM(require("react"));
10420
+ var React14 = __toESM(require("react"));
9434
10421
 
9435
10422
  // admin/FieldHelp.tsx
9436
- var React12 = __toESM(require("react"));
9437
- var import_styled_components8 = __toESM(require("styled-components"));
9438
- var import_design_system8 = require("@strapi/design-system");
9439
- var import_jsx_runtime13 = require("react/jsx-runtime");
9440
- var HelpButton = import_styled_components8.default.button`
10423
+ var React13 = __toESM(require("react"));
10424
+ var import_styled_components9 = __toESM(require("styled-components"));
10425
+ var import_design_system9 = require("@strapi/design-system");
10426
+ var import_jsx_runtime14 = require("react/jsx-runtime");
10427
+ var HelpButton = import_styled_components9.default.button`
9441
10428
  display: inline-flex; padding: 0; border: 0; border-radius: 50%; background: none; cursor: help; color: inherit;
9442
10429
  &:hover, &:focus-visible { color: ${({ theme }) => theme.colors.primary600}; }
9443
10430
  &:focus-visible { outline: 2px solid ${({ theme }) => theme.colors.primary600}; outline-offset: 2px; }
9444
10431
  `;
9445
10432
  function FieldHelp({ text, previous, title }) {
9446
10433
  const m = useMessages();
9447
- const kept2 = React12.isValidElement(previous) && previous.props.title ? React12.cloneElement(previous, { title }) : previous;
9448
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 1, alignItems: "center", children: [
10434
+ const kept2 = React13.isValidElement(previous) && previous.props.title ? React13.cloneElement(previous, { title }) : previous;
10435
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_design_system9.Flex, { gap: 1, alignItems: "center", children: [
9449
10436
  kept2,
9450
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Tooltip, { label: text, style: { maxWidth: 320 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(HelpButton, { type: "button", "aria-label": m.fieldHelp, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "info", size: 14 }) }) })
10437
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system9.Tooltip, { label: text, style: { maxWidth: 320 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(HelpButton, { type: "button", "aria-label": m.fieldHelp, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "info", size: 14 }) }) })
9451
10438
  ] });
9452
10439
  }
9453
- var helpAction = (text, previous) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FieldHelp, { text, previous, title: React12.isValidElement(previous) && previous.props.title || { id: "blockscene.fieldHelp" } });
10440
+ var helpAction = (text, previous) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(FieldHelp, { text, previous, title: React13.isValidElement(previous) && previous.props.title || { id: "blockscene.fieldHelp" } });
9454
10441
 
9455
10442
  // admin/catalog.ts
9456
10443
  var cached = null;
@@ -9463,8 +10450,8 @@ var load = (get) => flight || (flight = get("/blockscene/catalog").then(({ data
9463
10450
  flight = null;
9464
10451
  }));
9465
10452
  function useCatalog(get) {
9466
- const [catalog, setCatalog] = React13.useState(null);
9467
- React13.useEffect(() => {
10453
+ const [catalog, setCatalog] = React14.useState(null);
10454
+ React14.useEffect(() => {
9468
10455
  let active = true;
9469
10456
  load(get).then((data) => {
9470
10457
  if (active) setCatalog(data);
@@ -9500,9 +10487,9 @@ var labelsHook = (get, relabel, drop) => (args) => {
9500
10487
  };
9501
10488
 
9502
10489
  // admin/LazyInput.tsx
9503
- var React14 = __toESM(require("react"));
9504
- var import_design_system9 = require("@strapi/design-system");
9505
- var import_styled_components9 = __toESM(require("styled-components"));
10490
+ var React15 = __toESM(require("react"));
10491
+ var import_design_system10 = require("@strapi/design-system");
10492
+ var import_styled_components10 = __toESM(require("styled-components"));
9506
10493
 
9507
10494
  // admin/sanitize.mjs
9508
10495
  var DROP = /* @__PURE__ */ new Set(["SCRIPT", "STYLE", "IFRAME", "FRAME", "OBJECT", "EMBED", "LINK", "META", "BASE", "FORM", "TEMPLATE", "NOSCRIPT"]);
@@ -9556,7 +10543,7 @@ function sanitizeHtml(html) {
9556
10543
  }
9557
10544
 
9558
10545
  // admin/LazyInput.tsx
9559
- var import_jsx_runtime14 = require("react/jsx-runtime");
10546
+ var import_jsx_runtime15 = require("react/jsx-runtime");
9560
10547
  var config = { on: false, fields: [] };
9561
10548
  var listeners = /* @__PURE__ */ new Set();
9562
10549
  function setLazyConfig(next) {
@@ -9572,7 +10559,7 @@ var subscribe = (run) => {
9572
10559
  };
9573
10560
  var read2 = () => config;
9574
10561
  var lazyFor = (uid) => config.on && config.fields.includes(uid);
9575
- var Preview = import_styled_components9.default.div`
10562
+ var Preview = import_styled_components10.default.div`
9576
10563
  min-height: 240px; border: 1px solid ${({ theme }) => theme.colors.neutral200}; border-radius: 4px; overflow: hidden;
9577
10564
  background: ${({ theme, $disabled }) => $disabled ? theme.colors.neutral150 : theme.colors.neutral0};
9578
10565
  color: ${({ theme }) => theme.colors.neutral800}; font-size: 1.4rem; line-height: 1.5;
@@ -9591,14 +10578,14 @@ var Preview = import_styled_components9.default.div`
9591
10578
  `;
9592
10579
  function Placeholder({ name, label, hint, error, required, labelAction, placeholder, value, disabled, onActivate }) {
9593
10580
  const t = useMessages();
9594
- const html = React14.useMemo(() => typeof value === "string" ? sanitizeHtml(value) : value == null ? "" : null, [value]);
10581
+ const html = React15.useMemo(() => typeof value === "string" ? sanitizeHtml(value) : value == null ? "" : null, [value]);
9595
10582
  const activate = disabled ? void 0 : (event) => {
9596
10583
  event.preventDefault();
9597
10584
  onActivate();
9598
10585
  };
9599
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system9.Field.Root, { id: name, name, error, hint, required, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_design_system9.Flex, { direction: "column", alignItems: "stretch", gap: 1, children: [
9600
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system9.Field.Label, { action: labelAction, children: label }),
9601
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
10586
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Field.Root, { id: name, name, error, hint, required, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "stretch", gap: 1, children: [
10587
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Field.Label, { action: labelAction, children: label }),
10588
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9602
10589
  Preview,
9603
10590
  {
9604
10591
  id: name,
@@ -9614,22 +10601,22 @@ function Placeholder({ name, label, hint, error, required, labelAction, placehol
9614
10601
  if (e.key === "Enter" || e.key === " ") activate?.(e);
9615
10602
  },
9616
10603
  children: [
9617
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "data-bar": true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system9.Typography, { variant: "pi", textColor: "neutral500", children: disabled ? "" : t.lazyEdit }) }),
9618
- html === null ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "data-body": true, children: JSON.stringify(value) }) : html ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "data-body": true, dangerouslySetInnerHTML: { __html: html } }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "data-body": true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system9.Typography, { textColor: "neutral500", children: placeholder || "" }) })
10604
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { "data-bar": true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", textColor: "neutral500", children: disabled ? "" : t.lazyEdit }) }),
10605
+ html === null ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { "data-body": true, children: JSON.stringify(value) }) : html ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { "data-body": true, dangerouslySetInnerHTML: { __html: html } }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { "data-body": true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { textColor: "neutral500", children: placeholder || "" }) })
9619
10606
  ]
9620
10607
  }
9621
10608
  ),
9622
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system9.Field.Hint, {}),
9623
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system9.Field.Error, {})
10609
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Field.Hint, {}),
10610
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Field.Error, {})
9624
10611
  ] }) });
9625
10612
  }
9626
10613
  function lazyInput(uid, Real) {
9627
- const Lazy = React14.forwardRef((props, ref) => {
9628
- React14.useSyncExternalStore(subscribe, read2);
9629
- const [active, setActive] = React14.useState(() => !lazyFor(uid));
9630
- const box = React14.useRef(null);
9631
- const focus = React14.useRef(false);
9632
- React14.useEffect(() => {
10614
+ const Lazy = React15.forwardRef((props, ref) => {
10615
+ React15.useSyncExternalStore(subscribe, read2);
10616
+ const [active, setActive] = React15.useState(() => !lazyFor(uid));
10617
+ const box = React15.useRef(null);
10618
+ const focus = React15.useRef(false);
10619
+ React15.useEffect(() => {
9633
10620
  if (!active || !focus.current) return;
9634
10621
  focus.current = false;
9635
10622
  let frame2 = 0;
@@ -9642,7 +10629,7 @@ function lazyInput(uid, Real) {
9642
10629
  poll();
9643
10630
  return () => cancelAnimationFrame(frame2);
9644
10631
  }, [active]);
9645
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref: box, style: { display: "contents" }, children: active || !lazyFor(uid) ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Real, { ...props, ref }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Placeholder, { ...props, onActivate: () => {
10632
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: box, style: { display: "contents" }, children: active || !lazyFor(uid) ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Real, { ...props, ref }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Placeholder, { ...props, onActivate: () => {
9646
10633
  focus.current = true;
9647
10634
  setActive(true);
9648
10635
  } }) });
@@ -9662,17 +10649,17 @@ function wrapCustomFields(app) {
9662
10649
  }
9663
10650
 
9664
10651
  // admin/Activity.tsx
9665
- var React15 = __toESM(require("react"));
9666
- var import_design_system10 = require("@strapi/design-system");
9667
- var import_admin3 = require("@strapi/strapi/admin");
9668
- var import_jsx_runtime15 = require("react/jsx-runtime");
10652
+ var React16 = __toESM(require("react"));
10653
+ var import_design_system11 = require("@strapi/design-system");
10654
+ var import_admin4 = require("@strapi/strapi/admin");
10655
+ var import_jsx_runtime16 = require("react/jsx-runtime");
9669
10656
  var ACTIVITY = [{ action: "plugin::blockscene.activity.read", subject: null }];
9670
10657
  var TRASH = ["read", "restore", "purge"].map((name) => ({ action: `plugin::blockscene.trash.${name}`, subject: null }));
9671
10658
  var ACTIONS = ["create", "update", "publish", "unpublish", "discard", "delete", "restore", "purge"];
9672
10659
  var DAY = 24 * 60 * 60 * 1e3;
9673
10660
  var contentMenuLink = (Component2) => ({
9674
10661
  to: "plugins/blockscene",
9675
- icon: () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "clock", size: 20 }),
10662
+ icon: () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Icon, { name: "clock", size: 20 }),
9676
10663
  intlLabel: { id: "blockscene.contentMenu", defaultMessage: "Activity and trash" },
9677
10664
  permissions: [...ACTIVITY, TRASH[0]],
9678
10665
  // Not an `async` function: Strapi 5 warns on AsyncFunction loaders.
@@ -9691,29 +10678,29 @@ var editUrl = (type, documentId, locale) => {
9691
10678
  return `${base}/content-manager/${kind}/${type.uid}${kind === "single-types" ? "" : `/${encodeURIComponent(documentId)}`}${locale ? `?plugins[i18n][locale]=${encodeURIComponent(locale)}` : ""}`;
9692
10679
  };
9693
10680
  var query = (params) => new URLSearchParams(Object.entries(params).filter(([, v]) => v !== "" && v != null).map(([k, v]) => [k, String(v)])).toString();
9694
- var Select = ({ label, value, onChange, options, name }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Box, { style: { minWidth: 180 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Field.Root, { name, children: [
9695
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Field.Label, { children: label }),
9696
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.SingleSelect, { value, onChange: (v) => onChange(String(v)), children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.SingleSelectOption, { value: o.value, children: o.label }, o.value)) })
10681
+ var Select = ({ label, value, onChange, options, name }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Box, { style: { minWidth: 180 }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Field.Root, { name, children: [
10682
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Field.Label, { children: label }),
10683
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.SingleSelect, { value, onChange: (v) => onChange(String(v)), children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.SingleSelectOption, { value: o.value, children: o.label }, o.value)) })
9697
10684
  ] }) });
9698
- var Input = ({ label, value, onChange, name, type = "text" }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Box, { style: { minWidth: 160 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Field.Root, { name, children: [
9699
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Field.Label, { children: label }),
9700
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.TextInput, { name, type, value, onChange: (e) => onChange(e.target.value) })
10685
+ var Input = ({ label, value, onChange, name, type = "text" }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Box, { style: { minWidth: 160 }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Field.Root, { name, children: [
10686
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Field.Label, { children: label }),
10687
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.TextInput, { name, type, value, onChange: (e) => onChange(e.target.value) })
9701
10688
  ] }) });
9702
10689
  function Pager({ t, pagination, setPage }) {
9703
10690
  if (!pagination?.total) return null;
9704
10691
  const { page, pageCount, total } = pagination;
9705
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { justifyContent: "space-between", alignItems: "center", paddingTop: 4, children: [
9706
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", textColor: "neutral600", children: t.f("contentPage", { page, pages: Math.max(pageCount, 1), total }) }),
9707
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { gap: 2, children: [
9708
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { variant: "tertiary", size: "S", disabled: page <= 1, onClick: () => setPage(page - 1), children: t.contentPrevious }),
9709
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { variant: "tertiary", size: "S", disabled: page >= pageCount, onClick: () => setPage(page + 1), children: t.contentNext })
10692
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { justifyContent: "space-between", alignItems: "center", paddingTop: 4, children: [
10693
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", textColor: "neutral600", children: t.f("contentPage", { page, pages: Math.max(pageCount, 1), total }) }),
10694
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { gap: 2, children: [
10695
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { variant: "tertiary", size: "S", disabled: page <= 1, onClick: () => setPage(page - 1), children: t.contentPrevious }),
10696
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { variant: "tertiary", size: "S", disabled: page >= pageCount, onClick: () => setPage(page + 1), children: t.contentNext })
9710
10697
  ] })
9711
10698
  ] });
9712
10699
  }
9713
10700
  function useList(get, path, params, refresh = 0) {
9714
- const [state, setState] = React15.useState({ data: null, failed: false });
10701
+ const [state, setState] = React16.useState({ data: null, failed: false });
9715
10702
  const key = `${path}?${query(params)}`;
9716
- React15.useEffect(() => {
10703
+ React16.useEffect(() => {
9717
10704
  let active = true;
9718
10705
  setState((s) => ({ data: s.data, failed: false, loading: true }));
9719
10706
  get(`/blockscene${key}`).then(({ data }) => active && setState({ data, failed: false })).catch(() => active && setState({ data: null, failed: true }));
@@ -9725,9 +10712,9 @@ function useList(get, path, params, refresh = 0) {
9725
10712
  }
9726
10713
  var Doc = ({ t, type, row, documentId, locale }) => {
9727
10714
  const title = row.title || t.contentUntitled;
9728
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "flex-start", gap: 1, children: [
9729
- row.exists && type ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Link, { href: editUrl(type, documentId, locale), children: title }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { fontWeight: "bold", children: title }),
9730
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Typography, { variant: "pi", textColor: "neutral600", children: [
10715
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "flex-start", gap: 1, children: [
10716
+ row.exists && type ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Link, { href: editUrl(type, documentId, locale), children: title }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { fontWeight: "bold", children: title }),
10717
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Typography, { variant: "pi", textColor: "neutral600", children: [
9731
10718
  type?.displayName || row.contentType,
9732
10719
  locale ? ` \xB7 ${locale}` : "",
9733
10720
  row.exists === false ? ` \xB7 ${t.contentGone}` : ""
@@ -9735,9 +10722,9 @@ var Doc = ({ t, type, row, documentId, locale }) => {
9735
10722
  ] });
9736
10723
  };
9737
10724
  function ActivityTab({ t, get }) {
9738
- const [filters, setFilters] = React15.useState({ actor: "", contentType: "", action: "", from: "", to: "", q: "" });
9739
- const [search, setSearch] = React15.useState("");
9740
- const [page, setPage] = React15.useState(1);
10725
+ const [filters, setFilters] = React16.useState({ actor: "", contentType: "", action: "", from: "", to: "", q: "" });
10726
+ const [search, setSearch] = React16.useState("");
10727
+ const [page, setPage] = React16.useState(1);
9741
10728
  const set2 = (key, value) => {
9742
10729
  setFilters((f) => ({ ...f, [key]: value }));
9743
10730
  setPage(1);
@@ -9749,13 +10736,13 @@ function ActivityTab({ t, get }) {
9749
10736
  };
9750
10737
  const { data, failed } = useList(get, "/activity", { ...filters, from: day(filters.from, false), to: day(filters.to, true), page, pageSize: 25 });
9751
10738
  const types = new Map((data?.types || []).map((type) => [type.uid, type]));
9752
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
9753
- data && !data.enabled && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Box, { padding: 3, background: "warning100", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", textColor: "warning700", children: t.contentOff }) }),
9754
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { tag: "form", gap: 3, wrap: "wrap", alignItems: "flex-end", onSubmit: (e) => {
10739
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
10740
+ data && !data.enabled && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Box, { padding: 3, background: "warning100", hasRadius: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", textColor: "warning700", children: t.contentOff }) }),
10741
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { tag: "form", gap: 3, wrap: "wrap", alignItems: "flex-end", onSubmit: (e) => {
9755
10742
  e.preventDefault();
9756
10743
  set2("q", search.trim());
9757
10744
  }, children: [
9758
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
10745
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9759
10746
  Select,
9760
10747
  {
9761
10748
  name: "actor",
@@ -9765,7 +10752,7 @@ function ActivityTab({ t, get }) {
9765
10752
  options: [{ value: "", label: t.activityAnyone }, ...(data?.actors || []).map((a) => ({ value: a.actor, label: a.actorName || (a.actor === "system" ? t.historySystem : a.actor) }))]
9766
10753
  }
9767
10754
  ),
9768
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
10755
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9769
10756
  Select,
9770
10757
  {
9771
10758
  name: "contentType",
@@ -9775,7 +10762,7 @@ function ActivityTab({ t, get }) {
9775
10762
  options: [{ value: "", label: t.activityAnyType }, ...(data?.types || []).map((type) => ({ value: type.uid, label: type.displayName }))]
9776
10763
  }
9777
10764
  ),
9778
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
10765
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9779
10766
  Select,
9780
10767
  {
9781
10768
  name: "action",
@@ -9785,35 +10772,35 @@ function ActivityTab({ t, get }) {
9785
10772
  options: [{ value: "", label: t.activityAnyAction }, ...ACTIONS.map((a) => ({ value: a, label: t.historyActions[a] || a }))]
9786
10773
  }
9787
10774
  ),
9788
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Input, { name: "from", type: "date", label: t.activityFrom, value: filters.from, onChange: (v) => set2("from", v) }),
9789
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Input, { name: "to", type: "date", label: t.activityTo, value: filters.to, onChange: (v) => set2("to", v) }),
9790
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Input, { name: "q", label: t.activitySearch, value: search, onChange: setSearch }),
9791
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { type: "submit", variant: "secondary", children: t.activitySearchButton }),
9792
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { type: "button", variant: "tertiary", onClick: () => {
10775
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Input, { name: "from", type: "date", label: t.activityFrom, value: filters.from, onChange: (v) => set2("from", v) }),
10776
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Input, { name: "to", type: "date", label: t.activityTo, value: filters.to, onChange: (v) => set2("to", v) }),
10777
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Input, { name: "q", label: t.activitySearch, value: search, onChange: setSearch }),
10778
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { type: "submit", variant: "secondary", children: t.activitySearchButton }),
10779
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { type: "button", variant: "tertiary", onClick: () => {
9793
10780
  setSearch("");
9794
10781
  setFilters({ actor: "", contentType: "", action: "", from: "", to: "", q: "" });
9795
10782
  setPage(1);
9796
10783
  }, children: t.contentClear })
9797
10784
  ] }),
9798
- failed ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { role: "alert", textColor: "danger600", children: t.activityFailed }) : !data ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { textColor: "neutral600", children: t.contentLoading }) : !data.results.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { textColor: "neutral600", children: t.activityEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Box, { children: [
9799
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Table, { colCount: 4, rowCount: data.results.length + 1, "data-testid": "blockscene-activity", children: [
9800
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Tr, { children: [
9801
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", children: t.activityWhen }) }),
9802
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", children: t.activityDocument }) }),
9803
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", children: t.activityWho }) }),
9804
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", children: t.activityWhat }) })
10785
+ failed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { role: "alert", textColor: "danger600", children: t.activityFailed }) : !data ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { textColor: "neutral600", children: t.contentLoading }) : !data.results.length ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { textColor: "neutral600", children: t.activityEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Box, { children: [
10786
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Table, { colCount: 4, rowCount: data.results.length + 1, "data-testid": "blockscene-activity", children: [
10787
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Tr, { children: [
10788
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", children: t.activityWhen }) }),
10789
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", children: t.activityDocument }) }),
10790
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", children: t.activityWho }) }),
10791
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", children: t.activityWhat }) })
9805
10792
  ] }) }),
9806
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Tbody, { children: data.results.map((event) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Tr, { "data-testid": `activity-${event.id}`, children: [
9807
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", children: when(t, event.at) }) }),
9808
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Doc, { t, type: types.get(event.contentType), row: event, documentId: event.relatedDocumentId, locale: event.locale }) }),
9809
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", children: event.actorName || (event.actor === "system" ? t.historySystem : event.actor) }) }),
9810
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "flex-start", gap: 1, children: [
9811
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "omega", fontWeight: "bold", children: t.historyActions[event.action] || event.action }),
9812
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", textColor: event.summary?.missing ? "warning700" : "neutral700", children: ["delete", "purge"].includes(event.action) ? "" : [event.summary?.restoredFrom ? t.activityRestoredFrom : "", summaryText(t, event.summary)].filter(Boolean).join(" \xB7 ") })
10793
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Tbody, { children: data.results.map((event) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Tr, { "data-testid": `activity-${event.id}`, children: [
10794
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", children: when(t, event.at) }) }),
10795
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Doc, { t, type: types.get(event.contentType), row: event, documentId: event.relatedDocumentId, locale: event.locale }) }),
10796
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", children: event.actorName || (event.actor === "system" ? t.historySystem : event.actor) }) }),
10797
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "flex-start", gap: 1, children: [
10798
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "omega", fontWeight: "bold", children: t.historyActions[event.action] || event.action }),
10799
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", textColor: event.summary?.missing ? "warning700" : "neutral700", children: ["delete", "purge"].includes(event.action) ? "" : [event.summary?.restoredFrom ? t.activityRestoredFrom : "", summaryText(t, event.summary)].filter(Boolean).join(" \xB7 ") })
9813
10800
  ] }) })
9814
10801
  ] }, event.id)) })
9815
10802
  ] }),
9816
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Pager, { t, pagination: data.pagination, setPage })
10803
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Pager, { t, pagination: data.pagination, setPage })
9817
10804
  ] })
9818
10805
  ] });
9819
10806
  }
@@ -9822,57 +10809,57 @@ function Report({ t, report }) {
9822
10809
  const line = (item) => item.code === "incoming" ? t.f("report.incoming", item) : t.f(`report.${item.code}`, { ...item, locale: locale(item.locale), locales: (item.locales || []).map(locale).join(", "), fields: (item.fields || []).join(", ") });
9823
10810
  const incoming = report.incoming && (report.incoming.reconnect || report.incoming.gone || report.incoming.replaced || report.incoming.published) ? [{ code: "incoming", ...report.incoming }] : [];
9824
10811
  const warnings = [...report.warnings || [], ...incoming];
9825
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "stretch", gap: 2, "data-testid": "restore-report", children: [
9826
- report.blocking?.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Box, { padding: 3, background: "danger100", hasRadius: true, children: [
9827
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", fontWeight: "bold", textColor: "danger700", children: t.restoreBlocked }),
9828
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { style: { margin: "4px 0 0", paddingLeft: 16 }, children: report.blocking.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", textColor: "danger700", children: line(item) }) }, i)) })
10812
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "stretch", gap: 2, "data-testid": "restore-report", children: [
10813
+ report.blocking?.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Box, { padding: 3, background: "danger100", hasRadius: true, children: [
10814
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", fontWeight: "bold", textColor: "danger700", children: t.restoreBlocked }),
10815
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { style: { margin: "4px 0 0", paddingLeft: 16 }, children: report.blocking.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", textColor: "danger700", children: line(item) }) }, i)) })
9829
10816
  ] }),
9830
- warnings.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Box, { padding: 3, background: "warning100", hasRadius: true, children: [
9831
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", fontWeight: "bold", textColor: "warning700", children: t.restoreWarnings }),
9832
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { style: { margin: "4px 0 0", paddingLeft: 16 }, children: warnings.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", textColor: "warning700", children: line(item) }) }, i)) })
10817
+ warnings.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Box, { padding: 3, background: "warning100", hasRadius: true, children: [
10818
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", fontWeight: "bold", textColor: "warning700", children: t.restoreWarnings }),
10819
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { style: { margin: "4px 0 0", paddingLeft: 16 }, children: warnings.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", textColor: "warning700", children: line(item) }) }, i)) })
9833
10820
  ] })
9834
10821
  ] });
9835
10822
  }
9836
10823
  function Preview2({ t, id, get, onClose }) {
9837
- const [row, setRow] = React15.useState(null);
9838
- const [failed, setFailed] = React15.useState(false);
9839
- React15.useEffect(() => {
10824
+ const [row, setRow] = React16.useState(null);
10825
+ const [failed, setFailed] = React16.useState(false);
10826
+ React16.useEffect(() => {
9840
10827
  get(`/blockscene/trash/${id}`).then(({ data }) => setRow(data)).catch(() => setFailed(true));
9841
10828
  }, [get, id]);
9842
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Modal.Root, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Modal.Content, { style: { width: "min(900px, 92vw)" }, children: [
9843
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Modal.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Modal.Title, { children: row?.title || t.trashPreview }) }),
9844
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Modal.Body, { children: failed ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { role: "alert", textColor: "danger600", children: t.trashFailed }) : !row ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { children: t.contentLoading }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "stretch", gap: 5, "data-testid": "trash-preview", children: [
9845
- row.incoming > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", textColor: "neutral600", children: t.f("trashIncoming", { count: row.incoming }) }),
9846
- row.entries.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
9847
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Typography, { variant: "delta", tag: "h3", children: [
10829
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Root, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Modal.Content, { style: { width: "min(900px, 92vw)" }, children: [
10830
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Title, { children: row?.title || t.trashPreview }) }),
10831
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Body, { children: failed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { role: "alert", textColor: "danger600", children: t.trashFailed }) : !row ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { children: t.contentLoading }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "stretch", gap: 5, "data-testid": "trash-preview", children: [
10832
+ row.incoming > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", textColor: "neutral600", children: t.f("trashIncoming", { count: row.incoming }) }),
10833
+ row.entries.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
10834
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Typography, { variant: "delta", tag: "h3", children: [
9848
10835
  entry.locale || t.contentNone,
9849
10836
  entry.status ? ` \xB7 ${entry.status === "published" ? t.trashPublished : t.trashDraft}` : ""
9850
10837
  ] }),
9851
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", textColor: "neutral600", children: t.trashFields }),
9852
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dl", { style: { display: "grid", gridTemplateColumns: "minmax(120px, max-content) 1fr", gap: "4px 16px", margin: 0 }, children: entry.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(React15.Fragment, { children: [
9853
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dt", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", fontWeight: "bold", children: field.name }) }),
9854
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dd", { style: { margin: 0, wordBreak: "break-word" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", children: field.count !== void 0 ? t.f("trashItems", { count: field.count }) : field.value }) })
10838
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", textColor: "neutral600", children: t.trashFields }),
10839
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dl", { style: { display: "grid", gridTemplateColumns: "minmax(120px, max-content) 1fr", gap: "4px 16px", margin: 0 }, children: entry.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React16.Fragment, { children: [
10840
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dt", { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", fontWeight: "bold", children: field.name }) }),
10841
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dd", { style: { margin: 0, wordBreak: "break-word" }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", children: field.count !== void 0 ? t.f("trashItems", { count: field.count }) : field.value }) })
9855
10842
  ] }, field.name)) }),
9856
- entry.blocks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
9857
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", textColor: "neutral600", children: t.trashBlocks }),
9858
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ol", { style: { margin: 0, paddingLeft: 20 }, children: entry.blocks.map((block, j) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", children: block.name }) }, j)) })
10843
+ entry.blocks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
10844
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", textColor: "neutral600", children: t.trashBlocks }),
10845
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ol", { style: { margin: 0, paddingLeft: 20 }, children: entry.blocks.map((block, j) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", children: block.name }) }, j)) })
9859
10846
  ] })
9860
10847
  ] }, i))
9861
10848
  ] }) }),
9862
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Modal.Footer, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Modal.Close, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { variant: "tertiary", children: t.trashClose }) }) })
10849
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Footer, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Close, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { variant: "tertiary", children: t.trashClose }) }) })
9863
10850
  ] }) });
9864
10851
  }
9865
10852
  function TrashTab({ t, get, post, del, can }) {
9866
- const { toggleNotification } = (0, import_admin3.useNotification)();
9867
- const [contentType, setType] = React15.useState("");
9868
- const [restored, setRestored] = React15.useState(false);
9869
- const [page, setPage] = React15.useState(1);
9870
- const [refresh, reload] = React15.useReducer((n) => n + 1, 0);
10853
+ const { toggleNotification } = (0, import_admin4.useNotification)();
10854
+ const [contentType, setType] = React16.useState("");
10855
+ const [restored, setRestored] = React16.useState(false);
10856
+ const [page, setPage] = React16.useState(1);
10857
+ const [refresh, reload] = React16.useReducer((n) => n + 1, 0);
9871
10858
  const { data, failed } = useList(get, "/trash", { contentType, status: restored ? "restored" : "trashed", page, pageSize: 20 }, refresh);
9872
- const [preview, setPreview] = React15.useState(null);
9873
- const [restore, setRestore] = React15.useState(null);
9874
- const [remove, setRemove] = React15.useState(null);
9875
- const [busy, setBusy] = React15.useState(false);
10859
+ const [preview, setPreview] = React16.useState(null);
10860
+ const [restore, setRestore] = React16.useState(null);
10861
+ const [remove, setRemove] = React16.useState(null);
10862
+ const [busy, setBusy] = React16.useState(false);
9876
10863
  const types = new Map((data?.types || []).map((type) => [type.uid, type]));
9877
10864
  const title = (row) => row.title || t.contentUntitled;
9878
10865
  const check = async (row) => {
@@ -9918,9 +10905,9 @@ function TrashTab({ t, get, post, del, can }) {
9918
10905
  const days = Math.floor((new Date(at).getTime() - Date.now()) / DAY);
9919
10906
  return days < 1 ? t.trashExpiresToday : t.f("trashExpiresIn", { days });
9920
10907
  };
9921
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
9922
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { gap: 4, wrap: "wrap", alignItems: "flex-end", children: [
9923
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
10908
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
10909
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { gap: 4, wrap: "wrap", alignItems: "flex-end", children: [
10910
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9924
10911
  Select,
9925
10912
  {
9926
10913
  name: "trash-type",
@@ -9933,108 +10920,163 @@ function TrashTab({ t, get, post, del, can }) {
9933
10920
  options: [{ value: "", label: t.activityAnyType }, ...(data?.types || []).map((type) => ({ value: type.uid, label: type.displayName }))]
9934
10921
  }
9935
10922
  ),
9936
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { gap: 2, paddingBottom: 2, children: [
9937
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Switch, { "aria-label": t.trashShowRestored, checked: restored, onCheckedChange: (v) => {
10923
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { gap: 2, paddingBottom: 2, children: [
10924
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Switch, { "aria-label": t.trashShowRestored, checked: restored, onCheckedChange: (v) => {
9938
10925
  setRestored(v);
9939
10926
  setPage(1);
9940
10927
  } }),
9941
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", children: t.trashShowRestored })
10928
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", children: t.trashShowRestored })
9942
10929
  ] })
9943
10930
  ] }),
9944
- failed ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { role: "alert", textColor: "danger600", children: t.trashFailed }) : !data ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { textColor: "neutral600", children: t.contentLoading }) : !data.results.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { textColor: "neutral600", children: t.trashEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Box, { children: [
9945
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Table, { colCount: 5, rowCount: data.results.length + 1, "data-testid": "blockscene-trash", children: [
9946
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Tr, { children: [
9947
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", children: t.activityDocument }) }),
9948
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", children: t.trashLocales }) }),
9949
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", children: t.trashDeletedBy }) }),
9950
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", children: restored ? t.trashRestoredAs : t.trashExpires }) }),
9951
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "sigma", children: " " }) })
10931
+ failed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { role: "alert", textColor: "danger600", children: t.trashFailed }) : !data ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { textColor: "neutral600", children: t.contentLoading }) : !data.results.length ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { textColor: "neutral600", children: t.trashEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Box, { children: [
10932
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Table, { colCount: 5, rowCount: data.results.length + 1, "data-testid": "blockscene-trash", children: [
10933
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Tr, { children: [
10934
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", children: t.activityDocument }) }),
10935
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", children: t.trashLocales }) }),
10936
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", children: t.trashDeletedBy }) }),
10937
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", children: restored ? t.trashRestoredAs : t.trashExpires }) }),
10938
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Th, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "sigma", children: " " }) })
9952
10939
  ] }) }),
9953
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Tbody, { children: data.results.map((row) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Tr, { "data-testid": `trash-${row.id}`, children: [
9954
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Doc, { t, type: types.get(row.contentType), row: { ...row, exists: void 0 }, documentId: row.relatedDocumentId, locale: null }) }),
9955
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", children: (row.locales || []).map((l) => l ?? t.contentNone).join(", ") }) }),
9956
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "flex-start", children: [
9957
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", children: row.actorName || (row.actor === "system" ? t.historySystem : row.actor) }),
9958
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", textColor: "neutral600", children: when(t, row.deletedAt) })
10940
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Tbody, { children: data.results.map((row) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Tr, { "data-testid": `trash-${row.id}`, children: [
10941
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Doc, { t, type: types.get(row.contentType), row: { ...row, exists: void 0 }, documentId: row.relatedDocumentId, locale: null }) }),
10942
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", children: (row.locales || []).map((l) => l ?? t.contentNone).join(", ") }) }),
10943
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "flex-start", children: [
10944
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", children: row.actorName || (row.actor === "system" ? t.historySystem : row.actor) }),
10945
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", textColor: "neutral600", children: when(t, row.deletedAt) })
9959
10946
  ] }) }),
9960
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Td, { children: [
9961
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", children: restored ? row.restoredAt ? when(t, row.restoredAt) : "" : expires(row.expiresAt) }),
9962
- restored && row.restoredAs && types.get(row.contentType) && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Link, { href: editUrl(types.get(row.contentType), row.restoredAs, null), children: t.contentOpen }) })
10947
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Td, { children: [
10948
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", children: restored ? row.restoredAt ? when(t, row.restoredAt) : "" : expires(row.expiresAt) }),
10949
+ restored && row.restoredAs && types.get(row.contentType) && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Link, { href: editUrl(types.get(row.contentType), row.restoredAs, null), children: t.contentOpen }) })
9963
10950
  ] }),
9964
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { gap: 2, justifyContent: "flex-end", children: [
9965
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { variant: "tertiary", size: "S", onClick: () => setPreview(row.id), children: t.trashPreview }),
9966
- !restored && can.canRestore && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { variant: "secondary", size: "S", onClick: () => check(row), "data-testid": `trash-restore-${row.id}`, children: t.trashRestore }),
9967
- can.canPurge && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { variant: "danger-light", size: "S", onClick: () => setRemove(row), "data-testid": `trash-delete-${row.id}`, children: t.trashDelete })
10951
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { gap: 2, justifyContent: "flex-end", children: [
10952
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { variant: "tertiary", size: "S", onClick: () => setPreview(row.id), children: t.trashPreview }),
10953
+ !restored && can.canRestore && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { variant: "secondary", size: "S", onClick: () => check(row), "data-testid": `trash-restore-${row.id}`, children: t.trashRestore }),
10954
+ can.canPurge && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { variant: "danger-light", size: "S", onClick: () => setRemove(row), "data-testid": `trash-delete-${row.id}`, children: t.trashDelete })
9968
10955
  ] }) })
9969
10956
  ] }, row.id)) })
9970
10957
  ] }),
9971
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Pager, { t, pagination: data.pagination, setPage })
10958
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Pager, { t, pagination: data.pagination, setPage })
9972
10959
  ] }),
9973
- preview !== null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Preview2, { t, id: preview, get, onClose: () => setPreview(null) }),
9974
- restore && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Dialog.Root, { open: true, onOpenChange: (open) => !open && !busy && setRestore(null), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Dialog.Content, { children: [
9975
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Dialog.Header, { children: t.f("restoreTitle", { title: title(restore.row) }) }),
9976
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Flex, { direction: "column", alignItems: "stretch", gap: 3, width: "100%", children: restore.done ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Flex, { direction: "column", alignItems: "flex-start", gap: 2, role: "status", "data-testid": "restore-done", children: [
9977
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { textColor: "success700", children: restore.done.already ? t.restoreAlready : t.restoreDone }),
9978
- restore.done.documentId && types.get(restore.row.contentType) && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Link, { href: editUrl(types.get(restore.row.contentType), restore.done.documentId, restore.done.locales?.[0] ?? null), children: t.restoreOpen }),
9979
- !restore.done.already && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Report, { t, report: { warnings: restore.done.warnings, incoming: restore.done.incoming && { ...restore.done.incoming, reconnect: restore.done.incoming.reconnected } } })
9980
- ] }) : !restore.report ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { children: t.restoreChecking }) : restore.failed ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { role: "alert", textColor: "danger600", children: t.restoreFailed }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
9981
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Typography, { variant: "pi", children: [
10960
+ preview !== null && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Preview2, { t, id: preview, get, onClose: () => setPreview(null) }),
10961
+ restore && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Dialog.Root, { open: true, onOpenChange: (open) => !open && !busy && setRestore(null), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Dialog.Content, { children: [
10962
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Dialog.Header, { children: t.f("restoreTitle", { title: title(restore.row) }) }),
10963
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Flex, { direction: "column", alignItems: "stretch", gap: 3, width: "100%", children: restore.done ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "flex-start", gap: 2, role: "status", "data-testid": "restore-done", children: [
10964
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { textColor: "success700", children: restore.done.already ? t.restoreAlready : t.restoreDone }),
10965
+ restore.done.documentId && types.get(restore.row.contentType) && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Link, { href: editUrl(types.get(restore.row.contentType), restore.done.documentId, restore.done.locales?.[0] ?? null), children: t.restoreOpen }),
10966
+ !restore.done.already && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Report, { t, report: { warnings: restore.done.warnings, incoming: restore.done.incoming && { ...restore.done.incoming, reconnect: restore.done.incoming.reconnected } } })
10967
+ ] }) : !restore.report ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { children: t.restoreChecking }) : restore.failed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { role: "alert", textColor: "danger600", children: t.restoreFailed }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
10968
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Typography, { variant: "pi", children: [
9982
10969
  t.restoreIntro,
9983
10970
  " ",
9984
10971
  restore.report.documentId ? t.restoreInto : t.restoreNew
9985
10972
  ] }),
9986
- restore.report.locales?.length > 0 && restore.report.locales[0] !== null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { variant: "pi", children: t.f("restoreLocales", { locales: restore.report.locales.join(", ") }) }),
9987
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Report, { t, report: restore.report })
10973
+ restore.report.locales?.length > 0 && restore.report.locales[0] !== null && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { variant: "pi", children: t.f("restoreLocales", { locales: restore.report.locales.join(", ") }) }),
10974
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Report, { t, report: restore.report })
9988
10975
  ] }) }) }),
9989
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Dialog.Footer, { children: [
9990
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Dialog.Cancel, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { variant: "tertiary", disabled: busy, children: restore.done ? t.trashClose : t.restoreCancel }) }),
9991
- !restore.done && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { onClick: confirmRestore, loading: busy, disabled: busy || !restore.report || restore.failed || restore.report.blocking?.length > 0, "data-testid": "restore-confirm", children: t.restoreConfirm })
10976
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Dialog.Footer, { children: [
10977
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Dialog.Cancel, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { variant: "tertiary", disabled: busy, children: restore.done ? t.trashClose : t.restoreCancel }) }),
10978
+ !restore.done && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { onClick: confirmRestore, loading: busy, disabled: busy || !restore.report || restore.failed || restore.report.blocking?.length > 0, "data-testid": "restore-confirm", children: t.restoreConfirm })
9992
10979
  ] })
9993
10980
  ] }) }),
9994
- remove && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Dialog.Root, { open: true, onOpenChange: (open) => !open && !busy && setRemove(null), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Dialog.Content, { children: [
9995
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Dialog.Header, { children: t.trashDeleteTitle }),
9996
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Typography, { children: t.f("trashDeleteConfirm", { title: title(remove) }) }) }),
9997
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Dialog.Footer, { children: [
9998
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Dialog.Cancel, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { variant: "tertiary", disabled: busy, children: t.restoreCancel }) }),
9999
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Button, { variant: "danger", onClick: confirmRemove, loading: busy, disabled: busy, "data-testid": "delete-confirm", children: t.trashDelete })
10981
+ remove && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Dialog.Root, { open: true, onOpenChange: (open) => !open && !busy && setRemove(null), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Dialog.Content, { children: [
10982
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Dialog.Header, { children: t.trashDeleteTitle }),
10983
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { children: t.f("trashDeleteConfirm", { title: title(remove) }) }) }),
10984
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Dialog.Footer, { children: [
10985
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Dialog.Cancel, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { variant: "tertiary", disabled: busy, children: t.restoreCancel }) }),
10986
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Button, { variant: "danger", onClick: confirmRemove, loading: busy, disabled: busy, "data-testid": "delete-confirm", children: t.trashDelete })
10000
10987
  ] })
10001
10988
  ] }) })
10002
10989
  ] });
10003
10990
  }
10004
10991
  function ContentPage() {
10005
10992
  const t = useMessages();
10006
- const { get, post, del } = (0, import_admin3.useFetchClient)();
10007
- const activity = (0, import_admin3.useRBAC)(ACTIVITY);
10008
- const trash = (0, import_admin3.useRBAC)(TRASH);
10009
- const [tab, setTab] = React15.useState(null);
10010
- if (activity.isLoading || trash.isLoading) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_admin3.Page.Loading, {});
10993
+ const { get, post, del } = (0, import_admin4.useFetchClient)();
10994
+ const activity = (0, import_admin4.useRBAC)(ACTIVITY);
10995
+ const trash = (0, import_admin4.useRBAC)(TRASH);
10996
+ const [tab, setTab] = React16.useState(null);
10997
+ if (activity.isLoading || trash.isLoading) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_admin4.Page.Loading, {});
10011
10998
  const canActivity = Boolean(activity.allowedActions?.canRead), canTrash = Boolean(trash.allowedActions?.canRead);
10012
- if (!canActivity && !canTrash) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_admin3.Page.NoPermissions, {});
10999
+ if (!canActivity && !canTrash) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_admin4.Page.NoPermissions, {});
10013
11000
  const current = tab || (canActivity ? "activity" : "trash");
10014
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_admin3.Page.Main, { children: [
10015
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_admin3.Page.Title, { children: t.contentTitle }),
10016
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_admin3.Layouts.Header, { title: t.contentTitle, subtitle: t.contentSubtitle }),
10017
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_admin3.Layouts.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Tabs.Root, { value: current, onValueChange: setTab, children: [
10018
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Tabs.List, { "aria-label": t.contentTitle, children: [
10019
- canActivity && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Tabs.Trigger, { value: "activity", children: t.activityTab }),
10020
- canTrash && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Tabs.Trigger, { value: "trash", children: t.trashTab })
11001
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_admin4.Page.Main, { children: [
11002
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_admin4.Page.Title, { children: t.contentTitle }),
11003
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_admin4.Layouts.Header, { title: t.contentTitle, subtitle: t.contentSubtitle }),
11004
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_admin4.Layouts.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Tabs.Root, { value: current, onValueChange: setTab, children: [
11005
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Tabs.List, { "aria-label": t.contentTitle, children: [
11006
+ canActivity && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Tabs.Trigger, { value: "activity", children: t.activityTab }),
11007
+ canTrash && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Tabs.Trigger, { value: "trash", children: t.trashTab })
10021
11008
  ] }),
10022
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system10.Box, { paddingTop: 6, paddingBottom: 6, background: "neutral0", hasRadius: true, paddingLeft: 6, paddingRight: 6, marginTop: 4, children: [
10023
- canActivity && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Tabs.Content, { value: "activity", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ActivityTab, { t, get }) }),
10024
- canTrash && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system10.Tabs.Content, { value: "trash", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TrashTab, { t, get, post, del, can: trash.allowedActions }) })
11009
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Box, { paddingTop: 6, paddingBottom: 6, background: "neutral0", hasRadius: true, paddingLeft: 6, paddingRight: 6, marginTop: 4, children: [
11010
+ canActivity && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Tabs.Content, { value: "activity", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ActivityTab, { t, get }) }),
11011
+ canTrash && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Tabs.Content, { value: "trash", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TrashTab, { t, get, post, del, can: trash.allowedActions }) })
10025
11012
  ] })
10026
11013
  ] }) })
10027
11014
  ] });
10028
11015
  }
10029
11016
 
11017
+ // admin/StarterKits.tsx
11018
+ var React17 = __toESM(require("react"));
11019
+ var import_design_system12 = require("@strapi/design-system");
11020
+ var import_jsx_runtime17 = require("react/jsx-runtime");
11021
+ var marker = (docKey) => {
11022
+ try {
11023
+ const entry = window.history.state?.key ?? window.history.state?.idx ?? "route";
11024
+ return `blockscene:starter-kit:${entry}:${docKey}`;
11025
+ } catch {
11026
+ return `blockscene:starter-kit:${docKey}`;
11027
+ }
11028
+ };
11029
+ var wasHandled = (key) => {
11030
+ try {
11031
+ return window.sessionStorage.getItem(key) === "handled";
11032
+ } catch {
11033
+ return false;
11034
+ }
11035
+ };
11036
+ var remember2 = (key) => {
11037
+ try {
11038
+ window.sessionStorage.setItem(key, "handled");
11039
+ } catch {
11040
+ }
11041
+ };
11042
+ function StarterKits({ creating, kits, zones, components, form, Modal: Modal3, docKey }) {
11043
+ const t = useMessages();
11044
+ const key = marker(docKey);
11045
+ const handled = React17.useRef({ key, value: wasHandled(key) });
11046
+ if (handled.current.key !== key) handled.current = { key, value: wasHandled(key) };
11047
+ const usable = starterKitsForLocale(kits, form?.locale).filter((kit) => Object.keys(kit.zones || {}).every((name) => zones.some((zone) => zone.name === name)));
11048
+ const available = creating && form && !handled.current.value && usable.length > 0 && zones.length > 0 && zones.every((zone) => form.rows(zone.name).length === 0);
11049
+ const [open, setOpen] = React17.useState(available);
11050
+ React17.useEffect(() => {
11051
+ if (available) setOpen(true);
11052
+ }, [available, key]);
11053
+ if (!available) return null;
11054
+ const finish = () => {
11055
+ handled.current.value = true;
11056
+ remember2(key);
11057
+ setOpen(false);
11058
+ };
11059
+ const apply = (kit) => {
11060
+ const rows = starterKitRows(kit, zones, components, form);
11061
+ if (!rows) return;
11062
+ for (const [zone, value] of Object.entries(rows)) form.setRows(zone, value);
11063
+ finish();
11064
+ };
11065
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Modal3, { open, onOpenChange: (next) => next ? setOpen(true) : finish(), title: t.starterKits, width: "560px", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_design_system12.Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
11066
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_design_system12.Typography, { textColor: "neutral600", children: t.starterKitsHelp }),
11067
+ usable.map((kit) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_design_system12.Button, { variant: "secondary", fullWidth: true, onClick: () => apply(kit), "data-testid": `starter-kit-${kit.id}`, children: localized(kit.label, t.locale) }, kit.id)),
11068
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_design_system12.Box, { paddingTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_design_system12.Button, { variant: "tertiary", onClick: finish, children: t.startBlank }) })
11069
+ ] }) });
11070
+ }
11071
+
10030
11072
  // admin/strapi5.tsx
10031
- var import_jsx_runtime16 = require("react/jsx-runtime");
11073
+ var import_jsx_runtime18 = require("react/jsx-runtime");
10032
11074
  function Modal2({ open, onOpenChange, trigger, title, children, width = "80vw" }) {
10033
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Modal.Root, { open, onOpenChange, children: [
10034
- trigger && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Trigger, { children: trigger }),
10035
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Modal.Content, { style: { width, maxWidth: "92vw" }, children: [
10036
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Title, { children: title }) }),
10037
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Modal.Body, { children })
11075
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_design_system13.Modal.Root, { open, onOpenChange, children: [
11076
+ trigger && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.Modal.Trigger, { children: trigger }),
11077
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_design_system13.Modal.Content, { style: { width, maxWidth: "92vw" }, children: [
11078
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.Modal.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.Modal.Title, { children: title }) }),
11079
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.Modal.Body, { children })
10038
11080
  ] })
10039
11081
  ] });
10040
11082
  }
@@ -10049,10 +11091,10 @@ async function relationsOf(get, { uid, id, field }, locale) {
10049
11091
  return out.reverse();
10050
11092
  }
10051
11093
  function useRowForm(c, values, get) {
10052
- const onChange = (0, import_admin4.useForm)("Blockscene", (state) => state.onChange);
10053
- const errors = (0, import_admin4.useForm)("Blockscene", (state) => state.errors);
10054
- const { toggleNotification } = (0, import_admin4.useNotification)();
10055
- const latest = React16.useRef(values);
11094
+ const onChange = (0, import_admin5.useForm)("Blockscene", (state) => state.onChange);
11095
+ const errors = (0, import_admin5.useForm)("Blockscene", (state) => state.errors);
11096
+ const { toggleNotification } = (0, import_admin5.useNotification)();
11097
+ const latest = React18.useRef(values);
10056
11098
  latest.current = values;
10057
11099
  const locale = c.form?.initialValues?.locale || void 0;
10058
11100
  if (typeof onChange !== "function") return null;
@@ -10076,8 +11118,8 @@ function useRowForm(c, values, get) {
10076
11118
  function useScope() {
10077
11119
  const c = (0, import_strapi_admin2.unstable_useContentManagerContext)();
10078
11120
  const rbac = (0, import_strapi_admin2.useDocumentRBAC)("Blockscene", (state) => state);
10079
- const { get, put } = (0, import_admin4.useFetchClient)();
10080
- const formValues = (0, import_admin4.useForm)("Blockscene", (state) => state.values);
11121
+ const { get, put } = (0, import_admin5.useFetchClient)();
11122
+ const formValues = (0, import_admin5.useForm)("Blockscene", (state) => state.values);
10081
11123
  const catalog = useCatalog(get);
10082
11124
  const creating = !c.id && !c.form?.initialValues?.id && !c.form?.initialValues?.documentId;
10083
11125
  const allowed = (creating ? rbac.canCreateFields : rbac.canUpdateFields) || [];
@@ -10096,8 +11138,8 @@ function useScope() {
10096
11138
  const history = !creating && Boolean(c.id) && Boolean(catalog?.history?.contentTypes?.includes(c.model));
10097
11139
  return { c, rbac, get, put, formValues, catalog, creating, zones, typeSettings, gallery, history };
10098
11140
  }
10099
- var Menu2 = ({ label, testid, items: items2 }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Box, { "data-testid": testid, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.SimpleMenu, { variant: "tertiary", size: "S", "aria-label": label, title: label, endIcon: null, label: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Icon, { name: "more", size: 16 }), children: items2.map((item) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.MenuItem, { onSelect: item.onSelect, "data-testid": item.testid, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { gap: 2, alignItems: "center", children: [
10100
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Icon, { name: item.icon, size: 16 }),
11141
+ var Menu2 = ({ label, testid, items: items2 }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.Box, { "data-testid": testid, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.SimpleMenu, { variant: "tertiary", size: "S", "aria-label": label, title: label, endIcon: null, label: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "more", size: 16 }), children: items2.map((item) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.MenuItem, { onSelect: item.onSelect, "data-testid": item.testid, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_design_system13.Flex, { gap: 2, alignItems: "center", children: [
11142
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: item.icon, size: 16 }),
10101
11143
  item.label
10102
11144
  ] }) }, item.testid)) }) });
10103
11145
  function Editor() {
@@ -10105,17 +11147,17 @@ function Editor() {
10105
11147
  const { catalog, typeSettings, gallery } = scope;
10106
11148
  const lazy = Boolean(catalog?.editor?.enabled && catalog.editor.lazyEditors !== false && typeSettings.enabled !== false);
10107
11149
  const lazyFields = (catalog?.editor?.lazyFields || []).join(",");
10108
- React16.useEffect(() => {
11150
+ React18.useEffect(() => {
10109
11151
  if (catalog) setLazyConfig({ on: lazy, fields: lazyFields ? lazyFields.split(",") : [] });
10110
11152
  }, [catalog, lazy, lazyFields]);
10111
- const kept2 = React16.useRef(false);
11153
+ const kept2 = React18.useRef(false);
10112
11154
  if (!scope.c.isLoading) kept2.current = gallery;
10113
11155
  if (!kept2.current) return null;
10114
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { hidden: true, "data-blockscene-editor": "", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Workspace, { scope }) }) });
11156
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { hidden: true, "data-blockscene-editor": "", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Workspace, { scope }) }) });
10115
11157
  }
10116
11158
  function Workspace({ scope }) {
10117
11159
  const { c, get, put, formValues, catalog, creating, zones, typeSettings } = scope;
10118
- const user = (0, import_admin4.useAuth)("Blockscene", (state2) => state2.user);
11160
+ const user = (0, import_admin5.useAuth)("Blockscene", (state2) => state2.user);
10119
11161
  const form = useRowForm(c, formValues ?? c.form?.values, get);
10120
11162
  const editor = {
10121
11163
  ...catalog.editor,
@@ -10127,6 +11169,8 @@ function Workspace({ scope }) {
10127
11169
  };
10128
11170
  const host = usePreviewHost5();
10129
11171
  const state = useEditorState(editor, host);
11172
+ const versions = useVersions(host, catalog?.history);
11173
+ const docKey = `${c.model}:${creating ? "new" : c.id}:${c.form?.initialValues?.locale || ""}`;
10130
11174
  const add = (zone, uid, preset) => {
10131
11175
  const values = formValues ?? c.form.values;
10132
11176
  const close = catalog?.groups?.[uid];
@@ -10144,8 +11188,9 @@ function Workspace({ scope }) {
10144
11188
  if (close) c.form.addFieldRow(zone.name, { __component: close }, at + 1);
10145
11189
  return true;
10146
11190
  };
10147
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
10148
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
11191
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
11192
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(StarterKits, { creating, kits: catalog.kits?.[c.model], zones, components: c.components, form, Modal: Modal2, docKey }),
11193
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10149
11194
  Gallery,
10150
11195
  {
10151
11196
  zones,
@@ -10158,18 +11203,19 @@ function Workspace({ scope }) {
10158
11203
  put,
10159
11204
  editor: catalog.editor,
10160
11205
  catalog,
10161
- docKey: `${c.model}:${creating ? "new" : c.id}:${c.form?.initialValues?.locale || ""}`,
11206
+ docKey,
10162
11207
  contentType: c.model,
10163
11208
  userId: user?.id,
10164
11209
  form,
10165
- zoneTools: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ZoneBarTools, { state }),
11210
+ zoneTools: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ZoneBarTools, { state }),
10166
11211
  openBlock: state.openBlock,
10167
11212
  openInsert: state.openInsert
10168
11213
  }
10169
11214
  ),
10170
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
11215
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10171
11216
  PagePreview,
10172
11217
  {
11218
+ versions,
10173
11219
  editor,
10174
11220
  state,
10175
11221
  host,
@@ -10184,7 +11230,7 @@ function Workspace({ scope }) {
10184
11230
  }
10185
11231
  function Panel2() {
10186
11232
  const { c, rbac, get, catalog, gallery, history } = useScope();
10187
- const canReadHistory = Boolean((0, import_admin4.useRBAC)(HISTORY_READ).allowedActions?.canRead);
11233
+ const canReadHistory = Boolean((0, import_admin5.useRBAC)(HISTORY_READ).allowedActions?.canRead);
10188
11234
  const preview = usePreviewZone(usePreviewHost5());
10189
11235
  const groups = gallery ? catalog?.groups : null;
10190
11236
  const problems = groups && preview.zone ? (0, import_groups.validateGroups)(preview.rows, groups) : [];
@@ -10192,9 +11238,9 @@ function Panel2() {
10192
11238
  if (!versions && !problems.length) return null;
10193
11239
  return {
10194
11240
  title: "Blockscene",
10195
- content: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
10196
- problems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(GroupDiagnostics, { scope: preview, groups, problems }),
10197
- versions && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
11241
+ content: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_design_system13.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
11242
+ problems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(GroupDiagnostics, { scope: preview, groups, problems }),
11243
+ versions && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10198
11244
  History,
10199
11245
  {
10200
11246
  model: c.model,
@@ -10210,9 +11256,9 @@ function Panel2() {
10210
11256
  ] }) })
10211
11257
  };
10212
11258
  }
10213
- var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Flex, { gap: 3, children: [
10214
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10215
- import_design_system11.Switch,
11259
+ var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_design_system13.Flex, { gap: 3, children: [
11260
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
11261
+ import_design_system13.Switch,
10216
11262
  {
10217
11263
  name,
10218
11264
  "aria-label": label,
@@ -10221,7 +11267,7 @@ var ToggleField = ({ name, label, value, onChange, disabled }) => /* @__PURE__ *
10221
11267
  onCheckedChange: onChange
10222
11268
  }
10223
11269
  ),
10224
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Typography, { children: label })
11270
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.Typography, { children: label })
10225
11271
  ] });
10226
11272
  var TextField = ({
10227
11273
  name,
@@ -10230,10 +11276,10 @@ var TextField = ({
10230
11276
  onChange,
10231
11277
  disabled,
10232
11278
  placeholder
10233
- }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Field.Root, { name, children: [
10234
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Field.Label, { children: label }),
10235
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10236
- import_design_system11.TextInput,
11279
+ }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_design_system13.Field.Root, { name, children: [
11280
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.Field.Label, { children: label }),
11281
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
11282
+ import_design_system13.TextInput,
10237
11283
  {
10238
11284
  name,
10239
11285
  value,
@@ -10250,30 +11296,30 @@ var SelectField = ({
10250
11296
  onChange,
10251
11297
  disabled,
10252
11298
  options
10253
- }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system11.Field.Root, { name, children: [
10254
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.Field.Label, { children: label }),
10255
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10256
- import_design_system11.SingleSelect,
11299
+ }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_design_system13.Field.Root, { name, children: [
11300
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.Field.Label, { children: label }),
11301
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
11302
+ import_design_system13.SingleSelect,
10257
11303
  {
10258
11304
  value,
10259
11305
  disabled,
10260
11306
  startIcon: options.find((o) => o.value === value)?.icon,
10261
11307
  onChange: (v) => onChange(String(v)),
10262
- children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system11.SingleSelectOption, { value: o.value, startIcon: o.icon, children: o.label }, o.value))
11308
+ children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system13.SingleSelectOption, { value: o.value, startIcon: o.icon, children: o.label }, o.value))
10263
11309
  }
10264
11310
  )
10265
11311
  ] });
10266
11312
  function MediaPicker({ onClose, onSelect }) {
10267
- const components = (0, import_admin4.useStrapiApp)(
11313
+ const components = (0, import_admin5.useStrapiApp)(
10268
11314
  "Blockscene",
10269
11315
  (state) => state.components
10270
11316
  );
10271
11317
  const Dialog3 = components?.["media-library"];
10272
- React16.useEffect(() => {
11318
+ React18.useEffect(() => {
10273
11319
  if (!Dialog3) onClose();
10274
11320
  }, [Dialog3, onClose]);
10275
11321
  if (!Dialog3) return null;
10276
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
11322
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10277
11323
  Dialog3,
10278
11324
  {
10279
11325
  onClose,
@@ -10284,7 +11330,7 @@ function MediaPicker({ onClose, onSelect }) {
10284
11330
  );
10285
11331
  }
10286
11332
  function usePermissions() {
10287
- const { allowedActions, isLoading } = (0, import_admin4.useRBAC)(
11333
+ const { allowedActions, isLoading } = (0, import_admin5.useRBAC)(
10288
11334
  Object.values(permissions).flat()
10289
11335
  );
10290
11336
  return {
@@ -10293,16 +11339,17 @@ function usePermissions() {
10293
11339
  isLoading
10294
11340
  };
10295
11341
  }
10296
- var SettingsPage = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
11342
+ var SettingsPage = ({ section }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10297
11343
  Settings,
10298
11344
  {
10299
- useClient: import_admin4.useFetchClient,
11345
+ useClient: import_admin5.useFetchClient,
10300
11346
  usePermissions,
10301
11347
  MediaPicker,
10302
11348
  ToggleField,
10303
11349
  SelectField,
10304
11350
  TextField,
10305
- lazyEditors: true
11351
+ lazyEditors: true,
11352
+ section
10306
11353
  }
10307
11354
  ) });
10308
11355
  var strapiApp = null;
@@ -10311,13 +11358,13 @@ var strapi5_default = {
10311
11358
  strapiApp = app;
10312
11359
  register(app, SettingsPage, "blockscene");
10313
11360
  app.registerPlugin({ id: "blockscene", name: "Blockscene", apis: { registerPanel: (panel) => registerPanel(panel, ICON_NAMES) } });
10314
- app.addMenuLink(contentMenuLink(() => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ContentPage, {}) })));
11361
+ app.addMenuLink(contentMenuLink(() => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ContentPage, {}) })));
10315
11362
  },
10316
11363
  registerTrads,
10317
11364
  bootstrap(app) {
10318
11365
  app.getPlugin("content-manager").apis.addEditViewSidePanel([Panel2]);
10319
11366
  app.getPlugin("content-manager").injectComponent("editView", "right-links", { name: "blockscene", Component: Editor });
10320
- app.registerHook("Admin/CM/pages/EditView/mutate-edit-view-layout", labelsHook(() => (0, import_admin4.getFetchClient)().get, labelEditLayout, dropField));
11367
+ app.registerHook("Admin/CM/pages/EditView/mutate-edit-view-layout", labelsHook(() => (0, import_admin5.getFetchClient)().get, labelEditLayout, dropField));
10321
11368
  wrapCustomFields(strapiApp);
10322
11369
  }
10323
11370
  };