@aduptive/strapi-blockscene 2.0.0-alpha.12 → 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,
@@ -414,6 +424,12 @@ var pickable = (zone, config2) => {
414
424
  const closers = Object.values(config2.groups || {});
415
425
  return zone.components.filter((uid) => !closers.includes(uid));
416
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
+ }
417
433
  function entryOf(uid, schema, config2) {
418
434
  const meta = config2.components?.[uid] || {};
419
435
  return {
@@ -560,13 +576,74 @@ var TEXT_TYPES = ["string", "text"];
560
576
  var RICH_TYPES = ["richtext", "blocks", "customField"];
561
577
  var EDITABLE_TYPES = [...TEXT_TYPES, ...RICH_TYPES];
562
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
+ };
563
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
+ }
564
641
  function projectRow(row, schema, components, cmsOrigin, depth = 0) {
565
642
  if (!row || !schema || depth > 3) return null;
566
643
  const out = {};
567
644
  for (const [name, attr] of Object.entries(schema.attributes || {})) {
568
645
  const value = row[name];
569
- if (attr.type === "password" || attr.type === "relation" || attr.private) continue;
646
+ if (attr.type === "password" || attr.type === "relation" || privateAttribute(attr)) continue;
570
647
  if (SCALAR.includes(attr.type)) {
571
648
  if (value !== void 0) out[name] = typeof value === "string" ? value.slice(0, 2e5) : value;
572
649
  } else if (attr.type === "media") {
@@ -595,7 +672,7 @@ function resolveField(uid, field, components) {
595
672
  const parts = field.split(".");
596
673
  for (let i = 0; i < parts.length; i++) {
597
674
  const attr = schema?.attributes?.[parts[i]];
598
- if (!attr || attr.private === true) return null;
675
+ if (!attr || privateAttribute(attr)) return null;
599
676
  if (i === parts.length - 1) return attr;
600
677
  if (attr.type !== "component") return null;
601
678
  if (attr.repeatable) {
@@ -611,7 +688,7 @@ function editableFields(uid, row, components) {
611
688
  const out = [];
612
689
  const SYSTEM = ["id", "documentId", "locale", "createdAt", "updatedAt", "publishedAt", "createdBy", "updatedBy", "localizations", "__component", "__temp_key__"];
613
690
  const push = (name, attr, label) => {
614
- 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 });
615
692
  };
616
693
  for (const [name, attr] of Object.entries(schema?.attributes || {})) {
617
694
  if (attr.type === "component" && attr.repeatable) {
@@ -625,7 +702,7 @@ function editableFields(uid, row, components) {
625
702
  function mediaFields(uid, row, components) {
626
703
  const media = {};
627
704
  for (const [name, attr] of Object.entries(components?.[uid]?.attributes || {})) {
628
- 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]) };
629
706
  }
630
707
  return media;
631
708
  }
@@ -868,7 +945,7 @@ var import_react_intl = require("react-intl");
868
945
  // admin/translations/en.json
869
946
  var en_default = {
870
947
  title: "Blockscene",
871
- settings: "Gallery",
948
+ settings: "General",
872
949
  gallery: "Block gallery",
873
950
  search: "Search blocks",
874
951
  clear: "Clear search",
@@ -884,6 +961,17 @@ var en_default = {
884
961
  moreActions: "More actions",
885
962
  settingsTitle: "Blockscene",
886
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.",
887
975
  palette: "Wireframe palette",
888
976
  background: "Background",
889
977
  surface: "Surfaces",
@@ -913,6 +1001,7 @@ var en_default = {
913
1001
  showCloseAll: 'Show "Collapse all"',
914
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.",
915
1003
  showRowThumbnails: "Show block thumbnails in the rows",
1004
+ componentRowThumbnail: "Show thumbnail in the editor row",
916
1005
  initialState: "Initial accordion state",
917
1006
  "states.closed": "All closed",
918
1007
  "states.open": "All open",
@@ -959,6 +1048,7 @@ var en_default = {
959
1048
  denied: "Access denied.",
960
1049
  loadFailed: "Could not load settings. Reload to try again.",
961
1050
  invalidColor: "Colors must use #RRGGBB.",
1051
+ invalidUrl: "Preview URLs must be complete HTTP or HTTPS URLs.",
962
1052
  previewLabel: "Palette preview",
963
1053
  removeGroup: "Remove group",
964
1054
  diagTitle: "Block groups need attention; publishing is refused until they are fixed:",
@@ -993,6 +1083,7 @@ var en_default = {
993
1083
  contentTypes: "Content types",
994
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.',
995
1085
  typeMode: "Opens in",
1086
+ typeAdvanced: "Visual editor options",
996
1087
  modeDefault: "Default ({mode})",
997
1088
  blockModalDone: "Done",
998
1089
  crashed: "Blockscene stopped here after an error. The native editor is unaffected. If it happens again, turn Blockscene off in Settings, Blockscene.",
@@ -1084,6 +1175,11 @@ var en_default = {
1084
1175
  confirmDeleteTitle: "Delete block",
1085
1176
  confirmDelete: "Delete block {name}?",
1086
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}}",
1087
1183
  delete: "Delete",
1088
1184
  selectBlocks: "Select blocks",
1089
1185
  selectAll: "Select all",
@@ -1278,6 +1374,7 @@ var en_default = {
1278
1374
  gridCellMenu: "More actions for {label}",
1279
1375
  removeFromGroup: "Remove from group",
1280
1376
  gridAdd: "Add a block",
1377
+ groupAdd: "Add block inside {label}",
1281
1378
  gridShowList: "Show group {label} as a list",
1282
1379
  gridShowGrid: "Show group {label} as a grid",
1283
1380
  layoutColumnsField: "Layout grid: columns field",
@@ -1308,7 +1405,7 @@ var en_default = {
1308
1405
  // admin/translations/pt-BR.json
1309
1406
  var pt_BR_default = {
1310
1407
  title: "Blockscene",
1311
- settings: "Galeria",
1408
+ settings: "Geral",
1312
1409
  gallery: "Galeria de blocos",
1313
1410
  search: "Buscar blocos",
1314
1411
  clear: "Limpar busca",
@@ -1324,6 +1421,17 @@ var pt_BR_default = {
1324
1421
  moreActions: "Mais a\xE7\xF5es",
1325
1422
  settingsTitle: "Blockscene",
1326
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.",
1327
1435
  palette: "Paleta dos wireframes",
1328
1436
  background: "Fundo",
1329
1437
  surface: "Superf\xEDcies",
@@ -1353,6 +1461,7 @@ var pt_BR_default = {
1353
1461
  showCloseAll: 'Mostrar "Recolher tudo"',
1354
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.",
1355
1463
  showRowThumbnails: "Mostrar miniaturas dos blocos nas linhas",
1464
+ componentRowThumbnail: "Mostrar miniatura na linha do editor",
1356
1465
  initialState: "Estado inicial dos accordions",
1357
1466
  "states.closed": "Todos fechados",
1358
1467
  "states.open": "Todos abertos",
@@ -1399,6 +1508,7 @@ var pt_BR_default = {
1399
1508
  denied: "Acesso negado.",
1400
1509
  loadFailed: "N\xE3o foi poss\xEDvel carregar. Recarregue para tentar novamente.",
1401
1510
  invalidColor: "As cores devem usar #RRGGBB.",
1511
+ invalidUrl: "As URLs de preview devem ser URLs HTTP ou HTTPS completas.",
1402
1512
  previewLabel: "Pr\xE9via da paleta",
1403
1513
  removeGroup: "Remover grupo",
1404
1514
  diagTitle: "Os grupos de blocos precisam de aten\xE7\xE3o; a publica\xE7\xE3o \xE9 recusada at\xE9 a corre\xE7\xE3o:",
@@ -1433,6 +1543,7 @@ var pt_BR_default = {
1433
1543
  contentTypes: "Tipos de conte\xFAdo",
1434
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.',
1435
1545
  typeMode: "Abre em",
1546
+ typeAdvanced: "Op\xE7\xF5es do editor visual",
1436
1547
  modeDefault: "Padr\xE3o ({mode})",
1437
1548
  blockModalDone: "Concluir",
1438
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.",
@@ -1524,6 +1635,11 @@ var pt_BR_default = {
1524
1635
  confirmDeleteTitle: "Excluir bloco",
1525
1636
  confirmDelete: "Excluir o bloco {name}?",
1526
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}}",
1527
1643
  delete: "Excluir",
1528
1644
  selectBlocks: "Selecionar blocos",
1529
1645
  selectAll: "Selecionar todos",
@@ -1718,6 +1834,7 @@ var pt_BR_default = {
1718
1834
  gridCellMenu: "Mais a\xE7\xF5es para {label}",
1719
1835
  removeFromGroup: "Remover do grupo",
1720
1836
  gridAdd: "Adicionar bloco",
1837
+ groupAdd: "Adicionar bloco dentro de {label}",
1721
1838
  gridShowList: "Mostrar o grupo {label} como lista",
1722
1839
  gridShowGrid: "Mostrar o grupo {label} como grade",
1723
1840
  layoutColumnsField: "Grade do layout: campo das colunas",
@@ -1748,7 +1865,7 @@ var pt_BR_default = {
1748
1865
  // admin/translations/pt.json
1749
1866
  var pt_default = {
1750
1867
  title: "Blockscene",
1751
- settings: "Galeria",
1868
+ settings: "Geral",
1752
1869
  gallery: "Galeria de blocos",
1753
1870
  search: "Pesquisar blocos",
1754
1871
  clear: "Limpar pesquisa",
@@ -1764,6 +1881,17 @@ var pt_default = {
1764
1881
  moreActions: "Mais a\xE7\xF5es",
1765
1882
  settingsTitle: "Blockscene",
1766
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.",
1767
1895
  palette: "Paleta dos wireframes",
1768
1896
  background: "Fundo",
1769
1897
  surface: "Superf\xEDcies",
@@ -1793,6 +1921,7 @@ var pt_default = {
1793
1921
  showCloseAll: 'Mostrar "Recolher tudo"',
1794
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.",
1795
1923
  showRowThumbnails: "Mostrar miniaturas dos blocos nas linhas",
1924
+ componentRowThumbnail: "Mostrar miniatura na linha do editor",
1796
1925
  initialState: "Estado inicial dos accordions",
1797
1926
  "states.closed": "Todos fechados",
1798
1927
  "states.open": "Todos abertos",
@@ -1839,6 +1968,7 @@ var pt_default = {
1839
1968
  denied: "Acesso negado.",
1840
1969
  loadFailed: "N\xE3o foi poss\xEDvel carregar. Recarregue para tentar novamente.",
1841
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.",
1842
1972
  previewLabel: "Pr\xE9-visualiza\xE7\xE3o da paleta",
1843
1973
  removeGroup: "Remover grupo",
1844
1974
  diagTitle: "Os grupos de blocos precisam de aten\xE7\xE3o; a publica\xE7\xE3o \xE9 recusada at\xE9 \xE0 corre\xE7\xE3o:",
@@ -1873,6 +2003,7 @@ var pt_default = {
1873
2003
  contentTypes: "Tipos de conte\xFAdo",
1874
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.',
1875
2005
  typeMode: "Abre em",
2006
+ typeAdvanced: "Op\xE7\xF5es do editor visual",
1876
2007
  modeDefault: "Predefini\xE7\xE3o ({mode})",
1877
2008
  blockModalDone: "Concluir",
1878
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.",
@@ -1964,6 +2095,11 @@ var pt_default = {
1964
2095
  confirmDeleteTitle: "Eliminar bloco",
1965
2096
  confirmDelete: "Eliminar o bloco {name}?",
1966
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}}",
1967
2103
  delete: "Eliminar",
1968
2104
  selectBlocks: "Selecionar blocos",
1969
2105
  selectAll: "Selecionar todos",
@@ -2158,6 +2294,7 @@ var pt_default = {
2158
2294
  gridCellMenu: "Mais a\xE7\xF5es para {label}",
2159
2295
  removeFromGroup: "Remover do grupo",
2160
2296
  gridAdd: "Adicionar bloco",
2297
+ groupAdd: "Adicionar bloco dentro de {label}",
2161
2298
  gridShowList: "Mostrar o grupo {label} como lista",
2162
2299
  gridShowGrid: "Mostrar o grupo {label} como grelha",
2163
2300
  layoutColumnsField: "Grelha do layout: campo das colunas",
@@ -2188,7 +2325,7 @@ var pt_default = {
2188
2325
  // admin/translations/fr.json
2189
2326
  var fr_default = {
2190
2327
  title: "Blockscene",
2191
- settings: "Galerie",
2328
+ settings: "G\xE9n\xE9ral",
2192
2329
  gallery: "Galerie de blocs",
2193
2330
  search: "Rechercher des blocs",
2194
2331
  clear: "Effacer la recherche",
@@ -2204,6 +2341,17 @@ var fr_default = {
2204
2341
  moreActions: "Plus d'actions",
2205
2342
  settingsTitle: "Blockscene",
2206
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.",
2207
2355
  palette: "Palette des wireframes",
2208
2356
  background: "Fond",
2209
2357
  surface: "Surfaces",
@@ -2233,6 +2381,7 @@ var fr_default = {
2233
2381
  showCloseAll: "Afficher \xAB Tout replier \xBB",
2234
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.",
2235
2383
  showRowThumbnails: "Afficher les miniatures des blocs dans les lignes",
2384
+ componentRowThumbnail: "Afficher la miniature dans la ligne de l'\xE9diteur",
2236
2385
  initialState: "\xC9tat initial des accord\xE9ons",
2237
2386
  "states.closed": "Tous ferm\xE9s",
2238
2387
  "states.open": "Tous ouverts",
@@ -2279,6 +2428,7 @@ var fr_default = {
2279
2428
  denied: "Acc\xE8s refus\xE9.",
2280
2429
  loadFailed: "Impossible de charger les param\xE8tres. Rechargez pour r\xE9essayer.",
2281
2430
  invalidColor: "Les couleurs doivent utiliser #RRGGBB.",
2431
+ invalidUrl: "Les URL d'aper\xE7u doivent \xEAtre des adresses HTTP ou HTTPS compl\xE8tes.",
2282
2432
  previewLabel: "Aper\xE7u de la palette",
2283
2433
  removeGroup: "Supprimer le groupe",
2284
2434
  diagTitle: "Les groupes de blocs demandent une correction ; la publication est refus\xE9e tant qu'ils ne sont pas corrig\xE9s :",
@@ -2313,6 +2463,7 @@ var fr_default = {
2313
2463
  contentTypes: "Types de contenu",
2314
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.",
2315
2465
  typeMode: "S'ouvre en",
2466
+ typeAdvanced: "Options de l'\xE9diteur visuel",
2316
2467
  modeDefault: "Par d\xE9faut ({mode})",
2317
2468
  blockModalDone: "Termin\xE9",
2318
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.",
@@ -2404,6 +2555,11 @@ var fr_default = {
2404
2555
  confirmDeleteTitle: "Supprimer le bloc",
2405
2556
  confirmDelete: "Supprimer le bloc {name} ?",
2406
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}}",
2407
2563
  delete: "Supprimer",
2408
2564
  selectBlocks: "S\xE9lectionner des blocs",
2409
2565
  selectAll: "Tout s\xE9lectionner",
@@ -2598,6 +2754,7 @@ var fr_default = {
2598
2754
  gridCellMenu: "Plus d'actions pour {label}",
2599
2755
  removeFromGroup: "Retirer du groupe",
2600
2756
  gridAdd: "Ajouter un bloc",
2757
+ groupAdd: "Ajouter un bloc dans {label}",
2601
2758
  gridShowList: "Afficher le groupe {label} en liste",
2602
2759
  gridShowGrid: "Afficher le groupe {label} en grille",
2603
2760
  layoutColumnsField: "Grille de mise en page : champ des colonnes",
@@ -2628,7 +2785,7 @@ var fr_default = {
2628
2785
  // admin/translations/es.json
2629
2786
  var es_default = {
2630
2787
  title: "Blockscene",
2631
- settings: "Galer\xEDa",
2788
+ settings: "General",
2632
2789
  gallery: "Galer\xEDa de bloques",
2633
2790
  search: "Buscar bloques",
2634
2791
  clear: "Borrar b\xFAsqueda",
@@ -2644,6 +2801,17 @@ var es_default = {
2644
2801
  moreActions: "M\xE1s acciones",
2645
2802
  settingsTitle: "Blockscene",
2646
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.",
2647
2815
  palette: "Paleta de wireframes",
2648
2816
  background: "Fondo",
2649
2817
  surface: "Superficies",
@@ -2673,6 +2841,7 @@ var es_default = {
2673
2841
  showCloseAll: "Mostrar \xABContraer todo\xBB",
2674
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.",
2675
2843
  showRowThumbnails: "Mostrar miniaturas de los bloques en las filas",
2844
+ componentRowThumbnail: "Mostrar miniatura en la fila del editor",
2676
2845
  initialState: "Estado inicial de los acordeones",
2677
2846
  "states.closed": "Todos cerrados",
2678
2847
  "states.open": "Todos abiertos",
@@ -2719,6 +2888,7 @@ var es_default = {
2719
2888
  denied: "Acceso denegado.",
2720
2889
  loadFailed: "No se pudieron cargar los ajustes. Recargue para reintentar.",
2721
2890
  invalidColor: "Los colores deben usar #RRGGBB.",
2891
+ invalidUrl: "Las URL de vista previa deben ser direcciones HTTP o HTTPS completas.",
2722
2892
  previewLabel: "Vista previa de la paleta",
2723
2893
  removeGroup: "Eliminar grupo",
2724
2894
  diagTitle: "Los grupos de bloques necesitan atenci\xF3n; la publicaci\xF3n se rechaza hasta corregirlos:",
@@ -2753,6 +2923,7 @@ var es_default = {
2753
2923
  contentTypes: "Tipos de contenido",
2754
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.',
2755
2925
  typeMode: "Se abre en",
2926
+ typeAdvanced: "Opciones del editor visual",
2756
2927
  modeDefault: "Predeterminado ({mode})",
2757
2928
  blockModalDone: "Listo",
2758
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.",
@@ -2844,6 +3015,11 @@ var es_default = {
2844
3015
  confirmDeleteTitle: "Eliminar bloque",
2845
3016
  confirmDelete: "\xBFEliminar el bloque {name}?",
2846
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}}",
2847
3023
  delete: "Eliminar",
2848
3024
  selectBlocks: "Seleccionar bloques",
2849
3025
  selectAll: "Seleccionar todos",
@@ -3038,6 +3214,7 @@ var es_default = {
3038
3214
  gridCellMenu: "M\xE1s acciones para {label}",
3039
3215
  removeFromGroup: "Quitar del grupo",
3040
3216
  gridAdd: "A\xF1adir un bloque",
3217
+ groupAdd: "A\xF1adir un bloque dentro de {label}",
3041
3218
  gridShowList: "Mostrar el grupo {label} como lista",
3042
3219
  gridShowGrid: "Mostrar el grupo {label} como cuadr\xEDcula",
3043
3220
  layoutColumnsField: "Cuadr\xEDcula de dise\xF1o: campo de columnas",
@@ -3068,7 +3245,7 @@ var es_default = {
3068
3245
  // admin/translations/de.json
3069
3246
  var de_default = {
3070
3247
  title: "Blockscene",
3071
- settings: "Galerie",
3248
+ settings: "Allgemein",
3072
3249
  gallery: "Blockgalerie",
3073
3250
  search: "Bl\xF6cke suchen",
3074
3251
  clear: "Suche l\xF6schen",
@@ -3084,6 +3261,17 @@ var de_default = {
3084
3261
  moreActions: "Weitere Aktionen",
3085
3262
  settingsTitle: "Blockscene",
3086
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.",
3087
3275
  palette: "Wireframe-Palette",
3088
3276
  background: "Hintergrund",
3089
3277
  surface: "Fl\xE4chen",
@@ -3113,6 +3301,7 @@ var de_default = {
3113
3301
  showCloseAll: "\u201EAlle zuklappen\u201C anzeigen",
3114
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.",
3115
3303
  showRowThumbnails: "Blockvorschaubilder in den Zeilen anzeigen",
3304
+ componentRowThumbnail: "Vorschaubild in der Editorzeile anzeigen",
3116
3305
  initialState: "Anfangszustand der Akkordeons",
3117
3306
  "states.closed": "Alle geschlossen",
3118
3307
  "states.open": "Alle ge\xF6ffnet",
@@ -3159,6 +3348,7 @@ var de_default = {
3159
3348
  denied: "Zugriff verweigert.",
3160
3349
  loadFailed: "Einstellungen konnten nicht geladen werden. Neu laden, um es erneut zu versuchen.",
3161
3350
  invalidColor: "Farben m\xFCssen #RRGGBB verwenden.",
3351
+ invalidUrl: "Vorschau-URLs m\xFCssen vollst\xE4ndige HTTP- oder HTTPS-Adressen sein.",
3162
3352
  previewLabel: "Palettenvorschau",
3163
3353
  removeGroup: "Gruppe entfernen",
3164
3354
  diagTitle: "Blockgruppen m\xFCssen korrigiert werden; das Ver\xF6ffentlichen wird bis dahin abgelehnt:",
@@ -3193,6 +3383,7 @@ var de_default = {
3193
3383
  contentTypes: "Inhaltstypen",
3194
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.",
3195
3385
  typeMode: "\xD6ffnet in",
3386
+ typeAdvanced: "Optionen des visuellen Editors",
3196
3387
  modeDefault: "Standard ({mode})",
3197
3388
  blockModalDone: "Fertig",
3198
3389
  crashed: "Blockscene wurde hier wegen eines Fehlers beendet. Der native Editor ist nicht betroffen. Passiert es erneut, schalte Blockscene unter Settings, Blockscene aus.",
@@ -3284,6 +3475,11 @@ var de_default = {
3284
3475
  confirmDeleteTitle: "Block l\xF6schen",
3285
3476
  confirmDelete: "Block {name} l\xF6schen?",
3286
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}}",
3287
3483
  delete: "L\xF6schen",
3288
3484
  selectBlocks: "Bl\xF6cke ausw\xE4hlen",
3289
3485
  selectAll: "Alle ausw\xE4hlen",
@@ -3478,6 +3674,7 @@ var de_default = {
3478
3674
  gridCellMenu: "Weitere Aktionen f\xFCr {label}",
3479
3675
  removeFromGroup: "Aus der Gruppe entfernen",
3480
3676
  gridAdd: "Block hinzuf\xFCgen",
3677
+ groupAdd: "Block in {label} hinzuf\xFCgen",
3481
3678
  gridShowList: "Gruppe {label} als Liste anzeigen",
3482
3679
  gridShowGrid: "Gruppe {label} als Raster anzeigen",
3483
3680
  layoutColumnsField: "Layout-Raster: Feld der Spalten",
@@ -3508,7 +3705,7 @@ var de_default = {
3508
3705
  // admin/translations/it.json
3509
3706
  var it_default = {
3510
3707
  title: "Blockscene",
3511
- settings: "Galleria",
3708
+ settings: "Generali",
3512
3709
  gallery: "Galleria dei blocchi",
3513
3710
  search: "Cerca blocchi",
3514
3711
  clear: "Cancella ricerca",
@@ -3524,6 +3721,17 @@ var it_default = {
3524
3721
  moreActions: "Altre azioni",
3525
3722
  settingsTitle: "Blockscene",
3526
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.",
3527
3735
  palette: "Palette dei wireframe",
3528
3736
  background: "Sfondo",
3529
3737
  surface: "Superfici",
@@ -3553,6 +3761,7 @@ var it_default = {
3553
3761
  showCloseAll: 'Mostra "Comprimi tutto"',
3554
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.",
3555
3763
  showRowThumbnails: "Mostra le miniature dei blocchi nelle righe",
3764
+ componentRowThumbnail: "Mostra la miniatura nella riga dell'editor",
3556
3765
  initialState: "Stato iniziale delle fisarmoniche",
3557
3766
  "states.closed": "Tutte chiuse",
3558
3767
  "states.open": "Tutte aperte",
@@ -3599,6 +3808,7 @@ var it_default = {
3599
3808
  denied: "Accesso negato.",
3600
3809
  loadFailed: "Impossibile caricare le impostazioni. Ricarica per riprovare.",
3601
3810
  invalidColor: "I colori devono usare #RRGGBB.",
3811
+ invalidUrl: "Gli URL di anteprima devono essere indirizzi HTTP o HTTPS completi.",
3602
3812
  previewLabel: "Anteprima della palette",
3603
3813
  removeGroup: "Rimuovi gruppo",
3604
3814
  diagTitle: "I gruppi di blocchi richiedono attenzione; la pubblicazione \xE8 rifiutata finch\xE9 non vengono corretti:",
@@ -3633,6 +3843,7 @@ var it_default = {
3633
3843
  contentTypes: "Tipi di contenuto",
3634
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.",
3635
3845
  typeMode: "Si apre in",
3846
+ typeAdvanced: "Opzioni dell'editor visivo",
3636
3847
  modeDefault: "Predefinito ({mode})",
3637
3848
  blockModalDone: "Fatto",
3638
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.",
@@ -3724,6 +3935,11 @@ var it_default = {
3724
3935
  confirmDeleteTitle: "Elimina blocco",
3725
3936
  confirmDelete: "Eliminare il blocco {name}?",
3726
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}}",
3727
3943
  delete: "Elimina",
3728
3944
  selectBlocks: "Seleziona blocchi",
3729
3945
  selectAll: "Seleziona tutti",
@@ -3918,6 +4134,7 @@ var it_default = {
3918
4134
  gridCellMenu: "Altre azioni per {label}",
3919
4135
  removeFromGroup: "Rimuovi dal gruppo",
3920
4136
  gridAdd: "Aggiungi un blocco",
4137
+ groupAdd: "Aggiungi un blocco dentro {label}",
3921
4138
  gridShowList: "Mostra il gruppo {label} come elenco",
3922
4139
  gridShowGrid: "Mostra il gruppo {label} come griglia",
3923
4140
  layoutColumnsField: "Griglia di layout: campo delle colonne",
@@ -3948,7 +4165,7 @@ var it_default = {
3948
4165
  // admin/translations/nl.json
3949
4166
  var nl_default = {
3950
4167
  title: "Blockscene",
3951
- settings: "Galerij",
4168
+ settings: "Algemeen",
3952
4169
  gallery: "Blokkengalerij",
3953
4170
  search: "Blokken zoeken",
3954
4171
  clear: "Zoekopdracht wissen",
@@ -3964,6 +4181,17 @@ var nl_default = {
3964
4181
  moreActions: "Meer acties",
3965
4182
  settingsTitle: "Blockscene",
3966
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.",
3967
4195
  palette: "Wireframe-palet",
3968
4196
  background: "Achtergrond",
3969
4197
  surface: "Vlakken",
@@ -3993,6 +4221,7 @@ var nl_default = {
3993
4221
  showCloseAll: '"Alles inklappen" tonen',
3994
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.",
3995
4223
  showRowThumbnails: "Blokminiaturen in de rijen tonen",
4224
+ componentRowThumbnail: "Miniatuur in de editorrij tonen",
3996
4225
  initialState: "Beginstand van de accordeons",
3997
4226
  "states.closed": "Alle gesloten",
3998
4227
  "states.open": "Alle open",
@@ -4039,6 +4268,7 @@ var nl_default = {
4039
4268
  denied: "Toegang geweigerd.",
4040
4269
  loadFailed: "Instellingen konden niet worden geladen. Herlaad om opnieuw te proberen.",
4041
4270
  invalidColor: "Kleuren moeten #RRGGBB gebruiken.",
4271
+ invalidUrl: "Voorbeeld-URL's moeten volledige HTTP- of HTTPS-adressen zijn.",
4042
4272
  previewLabel: "Paletvoorbeeld",
4043
4273
  removeGroup: "Groep verwijderen",
4044
4274
  diagTitle: "Blokgroepen vragen aandacht; publiceren wordt geweigerd tot ze hersteld zijn:",
@@ -4073,6 +4303,7 @@ var nl_default = {
4073
4303
  contentTypes: "Contenttypes",
4074
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.',
4075
4305
  typeMode: "Opent in",
4306
+ typeAdvanced: "Opties voor de visuele editor",
4076
4307
  modeDefault: "Standaard ({mode})",
4077
4308
  blockModalDone: "Klaar",
4078
4309
  crashed: "Blockscene is hier gestopt door een fout. De native editor blijft werken. Gebeurt het opnieuw, zet Blockscene uit in Settings, Blockscene.",
@@ -4164,6 +4395,11 @@ var nl_default = {
4164
4395
  confirmDeleteTitle: "Blok verwijderen",
4165
4396
  confirmDelete: "Blok {name} verwijderen?",
4166
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}}",
4167
4403
  delete: "Verwijderen",
4168
4404
  selectBlocks: "Blokken selecteren",
4169
4405
  selectAll: "Alles selecteren",
@@ -4358,6 +4594,7 @@ var nl_default = {
4358
4594
  gridCellMenu: "Meer acties voor {label}",
4359
4595
  removeFromGroup: "Uit de groep halen",
4360
4596
  gridAdd: "Blok toevoegen",
4597
+ groupAdd: "Blok toevoegen binnen {label}",
4361
4598
  gridShowList: "Groep {label} als lijst tonen",
4362
4599
  gridShowGrid: "Groep {label} als raster tonen",
4363
4600
  layoutColumnsField: "Layoutraster: veld met kolommen",
@@ -4486,8 +4723,15 @@ function RowPreviews({ zones, components, catalog, Modal: Modal3 }) {
4486
4723
  const candidates = (uid) => candidatesFor(uid, catalog?.components?.[uid] || {}, catalog || {});
4487
4724
  const label = (uid) => catalog?.components?.[uid]?.label || components?.[uid]?.info?.displayName || uid;
4488
4725
  const srcOf = (uid) => candidates(uid)[resolved[uid] ?? -1] || "";
4726
+ const visible = anchors.filter(({ uid }) => showRowThumbnail(uid, catalog));
4489
4727
  React2.useEffect(() => {
4490
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
+ }
4491
4735
  if (srcOf(uid)) {
4492
4736
  el.setAttribute("role", "button");
4493
4737
  el.setAttribute("tabindex", "0");
@@ -4499,7 +4743,7 @@ function RowPreviews({ zones, components, catalog, Modal: Modal3 }) {
4499
4743
  }
4500
4744
  });
4501
4745
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4502
- anchors.map(
4746
+ visible.map(
4503
4747
  (a) => (0, import_react_dom.createPortal)(
4504
4748
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4505
4749
  "span",
@@ -4722,7 +4966,15 @@ function movedRow(prev, next, actor) {
4722
4966
  }
4723
4967
  function keepGroupsTogether(prev, next, groups, actor) {
4724
4968
  if (!groups) return null;
4725
- 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
+ }
4726
4978
  if (!move || !(0, import_groups2.isOpener)(prev[move.from], groups)) return null;
4727
4979
  const start = move.from, end = groupOutline(prev, groups)[start].end;
4728
4980
  if (end == null) return null;
@@ -5075,6 +5327,7 @@ var DEPTH = "data-blockscene-depth";
5075
5327
  var KIND = "data-blockscene-group";
5076
5328
  var FOLD = "data-blockscene-fold";
5077
5329
  var COUNT = "data-blockscene-fold-count";
5330
+ var INSERT = "data-blockscene-group-insert";
5078
5331
  var GRID_BOX = "data-blockscene-grid";
5079
5332
  var STEP = "2.4rem";
5080
5333
  var folded = /* @__PURE__ */ new Set();
@@ -5096,6 +5349,14 @@ var Count = import_styled_components3.default.span`
5096
5349
  margin-right: 4px; padding: 1px 6px; border-radius: 3px; font-size: 11px; font-weight: 600; line-height: 16px; white-space: nowrap;
5097
5350
  color: ${({ theme }) => theme.colors.primary700}; background: ${({ theme }) => theme.colors.primary100};
5098
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
+ `;
5099
5360
  function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, components, catalog, openBlock, openInsert }) {
5100
5361
  const t = useMessages();
5101
5362
  const theme = (0, import_styled_components3.useTheme)();
@@ -5191,18 +5452,34 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5191
5452
  for (const index of unfold) for (const p of outline[index]?.parents || []) folded.delete(idOf(p));
5192
5453
  const isFolded = (i) => outline[i].end != null && folded.has(idOf(i));
5193
5454
  const grid = [];
5455
+ const anchorByOpen = /* @__PURE__ */ new Map();
5194
5456
  lis.forEach((li, i) => {
5195
5457
  const o = outline[i];
5196
5458
  seen.add(li);
5197
5459
  set(li, DEPTH, o.depth ? String(o.depth) : null);
5198
5460
  if (o.depth) li.style.setProperty("--bs-depth", String(o.depth));
5199
5461
  set(li, KIND, o.kind === "block" ? null : o.kind);
5200
- 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]);
5201
5463
  const hidden = o.parents.some(isFolded) || inGrid;
5202
5464
  set(li, FOLDED, hidden ? "" : null);
5203
5465
  const layout = o.kind === "open" && o.end != null ? layouts2?.[rows[i].__component] || null : null;
5204
5466
  const toggle = li.querySelector("button[aria-expanded]");
5205
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
+ }
5206
5483
  if (o.kind !== "open" || o.end == null || !toggle?.parentElement) return;
5207
5484
  let gridEl = li.querySelector(`:scope > [${GRID_BOX}]`);
5208
5485
  if (grid[i] && !gridEl) {
@@ -5225,15 +5502,32 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5225
5502
  countEl.style.cssText = "display:inline-flex;align-items:center";
5226
5503
  actions.insertBefore(countEl, actions.firstChild);
5227
5504
  }
5228
- 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);
5229
5522
  });
5230
5523
  }
5231
5524
  landed.current = null;
5232
5525
  for (const li of document.querySelectorAll(`li[${DEPTH}], li[${KIND}], li[${FOLDED}]`))
5233
5526
  if (!seen.has(li)) for (const name of [DEPTH, KIND, FOLDED]) li.removeAttribute(name);
5234
- 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();
5235
5529
  setAnchors(
5236
- (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
5237
5531
  );
5238
5532
  };
5239
5533
  React4.useEffect(() => {
@@ -5251,7 +5545,7 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5251
5545
  return () => {
5252
5546
  observer.disconnect();
5253
5547
  cancelAnimationFrame(frame2);
5254
- 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();
5255
5549
  for (const li of document.querySelectorAll(`li[${DEPTH}], li[${KIND}], li[${FOLDED}]`)) for (const name of [DEPTH, KIND, FOLDED]) li.removeAttribute(name);
5256
5550
  };
5257
5551
  }, []);
@@ -5268,10 +5562,8 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5268
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; }
5269
5563
  ${list2}[${FOLDED}]:not([data-bp-block-modal]) { display: none !important; }
5270
5564
  ${list2}[data-bp-block-modal] { padding-left: 0 !important; background-image: none !important; }
5271
- ${list2}[${KIND}="close"] [data-handler-id] { display: none !important; }
5272
- ${list2}[${KIND}="close"] button[aria-expanded]:first-of-type { min-height: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important; opacity: 0.7; }
5273
- ${list2}[${KIND}="close"] button[aria-expanded]:first-of-type + * { padding-top: 0 !important; padding-bottom: 0 !important; }
5274
- ${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; }` }),
5275
5567
  anchors.map(
5276
5568
  (a) => (0, import_react_dom2.createPortal)(
5277
5569
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
@@ -5325,7 +5617,27 @@ ${list2}[${KIND}="close"] button[aria-expanded] [data-blockscene-row-thumb] { di
5325
5617
  a.gridEl,
5326
5618
  `grid:${a.zone}:${a.index}`
5327
5619
  ) : null;
5328
- })
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
+ )
5329
5641
  ] });
5330
5642
  }
5331
5643
  function ViewToggle({ grid, testid, label, onFlip }) {
@@ -5528,9 +5840,33 @@ function useRowActions({ zones, components, catalog, form }) {
5528
5840
  if (hiddenName) form.setRows(zoneName, setHidden(rows, index, groups, hiddenName, rows[index]?.[hiddenName] !== true));
5529
5841
  };
5530
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
+ };
5531
5848
  const pastable = (zoneName) => !["empty", "notAllowed"].includes(pasteProblem(clip, zoneOf(zoneName), form.rows(zoneName), components, groups)?.code);
5532
5849
  const selectable = (zoneName) => form.rows(zoneName).filter((row) => canAct(row, groups)).map((row) => blockKey(row)).filter(Boolean);
5533
- 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
+ };
5534
5870
  }
5535
5871
  var RowButton = import_styled_components4.default.button`
5536
5872
  display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: 0;
@@ -5554,7 +5890,7 @@ function RowActions({ zones, actions, Modal: Modal3 }) {
5554
5890
  const latest = React5.useRef({ zones, a });
5555
5891
  latest.current = { zones, a };
5556
5892
  React5.useEffect(() => {
5557
- if (!a || e.confirmDelete === false) return;
5893
+ if (!a) return;
5558
5894
  const onClick = (event) => {
5559
5895
  const button = event.target?.closest?.("button");
5560
5896
  if (!button || bypass.current) return;
@@ -5564,10 +5900,23 @@ function RowActions({ zones, actions, Modal: Modal3 }) {
5564
5900
  const headers = toggles(list2);
5565
5901
  const index = headers.findIndex((toggle) => trashOf(toggle) === button);
5566
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;
5567
5906
  event.preventDefault();
5568
5907
  event.stopPropagation();
5569
- const row = latest.current.a?.form.rows(zone.name)[index];
5570
- 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
+ });
5571
5920
  return;
5572
5921
  }
5573
5922
  };
@@ -5595,6 +5944,11 @@ function RowActions({ zones, actions, Modal: Modal3 }) {
5595
5944
  bypass.current = false;
5596
5945
  }
5597
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
+ };
5598
5952
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
5599
5953
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `li[${HIDDEN_ATTR}] button[aria-expanded] { opacity: 0.5; }
5600
5954
  ol[aria-describedby] > li button[data-strapi-accordion-toggle] { overflow: hidden; }
@@ -5674,14 +6028,25 @@ ol[aria-describedby] > li button[data-strapi-accordion-toggle] > span:last-child
5674
6028
  `${zone}:${index}`
5675
6029
  );
5676
6030
  }),
5677
- 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: [
5678
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Typography, { children: t.f("confirmDelete", { name: confirm.label }) }),
5679
- confirm.marker && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Typography, { variant: "pi", textColor: "neutral600", children: t.confirmDeleteMarker }),
5680
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_design_system.Flex, { gap: 2, justifyContent: "flex-end", children: [
5681
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { variant: "tertiary", onClick: () => setConfirm(null), "data-testid": "row-confirm-cancel", children: t.cancel }),
5682
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { variant: "danger", onClick: confirmDelete, "data-testid": "row-confirm-ok", children: t.delete })
5683
- ] })
5684
- ] }) })
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
+ )
5685
6050
  ] });
5686
6051
  }
5687
6052
  function zoneMenuItems(zone, a) {
@@ -7024,6 +7389,12 @@ var import_design_system4 = require("@strapi/design-system");
7024
7389
  // admin/pane.mjs
7025
7390
  var TOOLBAR = ["modes", "history", "versions", "devices", "status", "actions"];
7026
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
+ }
7027
7398
  function toolbarLayout(list2) {
7028
7399
  const ids = Array.isArray(list2) ? list2.filter((id, i) => TOOLBAR.includes(id) && list2.indexOf(id) === i) : TOOLBAR;
7029
7400
  const at = ids.findIndex((id) => RIGHT.includes(id));
@@ -7158,6 +7529,25 @@ function useMainRect() {
7158
7529
  }, []);
7159
7530
  return rect;
7160
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
+ }
7161
7551
  var Handle = import_styled_components6.default.div`
7162
7552
  position: absolute;
7163
7553
  top: 0;
@@ -7246,6 +7636,7 @@ body.bp-block-modal [data-bp-block-modal] { position: fixed !important; top: ${B
7246
7636
  background: ${background}; border-radius: 0 0 8px 8px; box-shadow: 0 8px 32px rgba(33, 33, 52, 0.3); }
7247
7637
  body.bp-block-modal [data-bp-block-modal]::before, body.bp-block-modal [data-bp-block-modal]::after { display: none !important; }
7248
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; }
7249
7640
  body.bp-block-modal [data-bp-modal-hide] { display: none !important; }`;
7250
7641
  var DRAWER_WIDTH = 640;
7251
7642
  var fieldsStyle = (background, drawer) => `
@@ -7254,6 +7645,7 @@ body.bp-fields [data-bp-show] { grid-column: 1 / -1 !important; }
7254
7645
  body.bp-fields [data-bp-flat] { border: 0 !important; box-shadow: none !important; padding: 0 !important; background: transparent !important; }
7255
7646
  body.bp-fields [data-bp-fields] { position: fixed !important; z-index: 1001; overflow: auto; margin: 0 !important;
7256
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; }
7257
7649
  body.bp-fields [data-bp-fields="modal"] { top: ${BLOCK_TOP}; left: 50%; transform: translateX(-50%); width: min(96rem, 92vw);
7258
7650
  max-height: calc(88vh - 5.6rem); border-radius: 0 0 8px 8px; }
7259
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; }` : ""}`;
@@ -7494,6 +7886,7 @@ function PagePreview({
7494
7886
  return v > 0 && v < 1 ? v : 0.5;
7495
7887
  });
7496
7888
  const main = useMainRect();
7889
+ const topInset = useAdminTopInset();
7497
7890
  const vw = main.width;
7498
7891
  const [dragging, setDragging] = React8.useState(false);
7499
7892
  const [ready, setReady] = React8.useState(false);
@@ -7501,6 +7894,7 @@ function PagePreview({
7501
7894
  const [failed, setFailed] = React8.useState(false);
7502
7895
  const [attempt, retry] = React8.useReducer((n) => n + 1, 0);
7503
7896
  const [picking, setPicking] = React8.useState(null);
7897
+ const [deletingGroup, setDeletingGroup] = React8.useState(null);
7504
7898
  const [hovered, setHovered] = React8.useState(null);
7505
7899
  const [edge, setEdge] = React8.useState(null);
7506
7900
  const hoverRow = React8.useRef(null);
@@ -7546,6 +7940,8 @@ function PagePreview({
7546
7940
  const readOnly = Boolean(version);
7547
7941
  const viewRows = React8.useRef([]);
7548
7942
  viewRows.current = version ? version.values?.[zone] || [] : latest.current;
7943
+ const viewValues = React8.useRef({});
7944
+ viewValues.current = version ? version.values : values;
7549
7945
  const channel = React8.useMemo(() => crypto.randomUUID(), [host.model, host.documentId, host.locale, version?.scope, version?.event.id]);
7550
7946
  const { base, source } = state.preview;
7551
7947
  const url = base ? new URL(base) : null;
@@ -7585,6 +7981,21 @@ function PagePreview({
7585
7981
  protocol: PROTOCOL,
7586
7982
  channel,
7587
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,
7588
7999
  blocks: projectPage(
7589
8000
  viewRows.current,
7590
8001
  live.current.components,
@@ -7599,7 +8010,7 @@ function PagePreview({
7599
8010
  },
7600
8011
  origin
7601
8012
  );
7602
- }, [channel, origin, hiddenAttribute, groups]);
8013
+ }, [channel, origin, hiddenAttribute, groups, host.contentType, host.model, host.readable, zone]);
7603
8014
  React8.useEffect(() => {
7604
8015
  if (readOnly) {
7605
8016
  setInserting(null);
@@ -7814,12 +8225,17 @@ function PagePreview({
7814
8225
  return;
7815
8226
  }
7816
8227
  if (is("delete-group") && canEdit2 && groups) {
7817
- const next = (0, import_groups.removeGroup)(
7818
- latest.current,
7819
- String(event.data.key),
7820
- groups
7821
- );
7822
- 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
+ });
7823
8239
  return;
7824
8240
  }
7825
8241
  if (is("insert-group") && canEdit2 && groups) {
@@ -8003,6 +8419,12 @@ function PagePreview({
8003
8419
  applyWidth(map[event.key], true);
8004
8420
  }
8005
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
+ };
8006
8428
  return (
8007
8429
  // Hidden anchor in the side panels column: split mode and the sidebar items find the edit view's grid from here.
8008
8430
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { ref: anchor, children: [
@@ -8013,6 +8435,7 @@ function PagePreview({
8013
8435
  "data-testid": "page-preview-pane",
8014
8436
  "aria-label": t.previewPane,
8015
8437
  style: {
8438
+ top: topInset,
8016
8439
  left: mode === "preview" || narrow ? main.left : main.left + main.width - paneWidth,
8017
8440
  width: mode === "preview" || narrow ? main.width : paneWidth,
8018
8441
  userSelect: dragging ? "none" : void 0
@@ -8174,6 +8597,15 @@ ${/* Strapi 4's scrolled header is fixed to the viewport's right edge: beside th
8174
8597
  ),
8175
8598
  document.body
8176
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
+ ] }) }),
8177
8609
  inserting && insertAttr && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
8178
8610
  PickerModal,
8179
8611
  {
@@ -8366,11 +8798,15 @@ function usePreviewHost5() {
8366
8798
  const { toggleNotification } = (0, import_admin.useNotification)();
8367
8799
  const components = (0, import_admin.useStrapiApp)("BlockscenePagePreview", (state) => state.components);
8368
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
+ );
8369
8805
  const latest = React9.useRef(values);
8370
8806
  latest.current = values;
8371
8807
  const readable = React9.useCallback(
8372
- (name) => c.isCreatingEntry || (rbac.canReadFields || []).includes(name),
8373
- [c.isCreatingEntry, rbac.canReadFields]
8808
+ (name) => fieldReadable(name, rbac.canReadFields, c.isCreatingEntry) || layoutFields.has(name.split(".")[0]),
8809
+ [c.isCreatingEntry, layoutFields, rbac.canReadFields]
8374
8810
  );
8375
8811
  return {
8376
8812
  ds: 2,
@@ -9045,6 +9481,27 @@ var Card2 = import_styled_components8.default.div`
9045
9481
  display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: 4px;
9046
9482
  border: 1px solid ${({ theme }) => theme.colors.neutral200}; background: ${({ theme }) => theme.colors.neutral0};
9047
9483
  `;
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
+ `;
9048
9505
  var Bar = import_styled_components8.default.div`
9049
9506
  position: fixed; top: 0; z-index: 4; padding: 12px 32px;
9050
9507
  background: ${({ theme }) => theme.colors.neutral100}; border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};
@@ -9089,13 +9546,33 @@ function ColorField({ name, label, value, onChange, disabled }) {
9089
9546
  ] });
9090
9547
  }
9091
9548
  function TagsField({ name, label, hint, value, onChange, disabled }) {
9092
- const [text, setText] = React12.useState(value.join(", "));
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]);
9093
9556
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Label, { children: [
9094
9557
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
9095
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { name, value: text, disabled, onChange: (e) => {
9096
- setText(e.target.value);
9097
- onChange([...new Set(e.target.value.split(",").map((tag) => tag.replace(/[<>]/g, "").trim().slice(0, 24)).filter(Boolean))].slice(0, 10));
9098
- }, style: { padding: "6px 8px", border: "1px solid #dcdce4", borderRadius: 4, fontSize: 13 } }),
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
+ ),
9099
9576
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: hint })
9100
9577
  ] });
9101
9578
  }
@@ -9256,10 +9733,9 @@ function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: Selec
9256
9733
  };
9257
9734
  const fields = (type.attributes || []).filter((attr) => !SYSTEM_FIELDS2.includes(attr.name));
9258
9735
  const id = (name, index) => `sidebar-${name}-${type.uid}${index === void 0 ? "" : `-${index}`}`;
9259
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 3, paddingLeft: 4, "data-testid": `sidebar-editor-${type.uid}`, children: [
9260
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "delta", tag: "h3", children: t.f("sidebarTitle", { name: type.displayName }) }),
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: [
9261
9737
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.sidebarHelp }),
9262
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { maxWidth: 240 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9738
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9263
9739
  SelectField2,
9264
9740
  {
9265
9741
  name: id("position"),
@@ -9335,7 +9811,7 @@ function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: Selec
9335
9811
  ] });
9336
9812
  }
9337
9813
  var permissions = { read: [{ action: "plugin::blockscene.settings.read", subject: null }], update: [{ action: "plugin::blockscene.settings.update", subject: null }] };
9338
- 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" }) {
9339
9815
  const t = useMessages();
9340
9816
  const { get, put, del } = useClient();
9341
9817
  const { canRead, canUpdate, isLoading } = usePermissions2();
@@ -9353,7 +9829,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9353
9829
  React12.useEffect(() => {
9354
9830
  if (!canRead || isLoading) return;
9355
9831
  let active = true;
9356
- 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]) => {
9357
9833
  if (!active) return;
9358
9834
  setData(s.data);
9359
9835
  setSettings(s.data.settings);
@@ -9365,18 +9841,20 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9365
9841
  return () => {
9366
9842
  active = false;
9367
9843
  };
9368
- }, [get, canRead, isLoading]);
9844
+ }, [get, canRead, isLoading, section]);
9369
9845
  const update = (patch) => {
9370
9846
  setSettings((current) => patch(structuredClone(current)));
9371
9847
  setDirty(true);
9372
9848
  setStatus("");
9373
9849
  };
9374
- 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));
9375
9852
  const badSidebar = settings && Object.values(settings.contentTypes || {}).some((entry) => (entry.sidebar || []).some(badItem));
9376
9853
  const badLazy = settings && badUids(settings.editor.lazyFields);
9377
9854
  const badHistory = settings && data?.historyTypes && badRetention(settings.history);
9378
- const badPane = settings && [settings.editor, ...Object.values(settings.contentTypes || {})].some((entry) => entry.previewDevices && badDevices(entry.previewDevices));
9379
- 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;
9380
9858
  const save = async () => {
9381
9859
  if (!settings || invalid || !canUpdate) return;
9382
9860
  setSaving(true);
@@ -9428,6 +9906,8 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9428
9906
  return index === 0 && manual ? t.manual : t.automatic;
9429
9907
  };
9430
9908
  const ready = !isLoading && canRead && !failed && settings && catalog;
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`];
9431
9911
  const header = React12.useRef(null);
9432
9912
  const [floating, setFloating] = React12.useState(false);
9433
9913
  const main = useMainRect2(header);
@@ -9440,22 +9920,22 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9440
9920
  }, [ready]);
9441
9921
  const controls = (suffix) => ready && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
9442
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 }),
9443
- !suffix && /* @__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 }),
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 }),
9444
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 })
9445
9925
  ] });
9446
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: [
9447
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: [
9448
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "alpha", tag: "h1", children: t.settingsTitle }),
9928
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "alpha", tag: "h1", children: sectionTitle }),
9449
9929
  controls("")
9450
9930
  ] }) }),
9451
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: [
9452
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "p", children: t.settingsTitle }),
9932
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "p", children: sectionTitle }),
9453
9933
  controls("-floating")
9454
9934
  ] }) }),
9455
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { textColor: "neutral600", children: t.settingsIntro }),
9935
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { textColor: "neutral600", children: sectionIntro }),
9456
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: [
9457
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 }) }),
9458
- /* @__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: [
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: [
9459
9939
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.palette }),
9460
9940
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Swatches, { children: Object.keys(DEFAULT_PALETTE).map((key) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9461
9941
  ColorField,
@@ -9471,7 +9951,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9471
9951
  },
9472
9952
  key
9473
9953
  )) }),
9474
- badColor && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", textColor: "danger600", children: t.invalidColor }),
9954
+ badPalette && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", textColor: "danger600", children: t.invalidColor }),
9475
9955
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.previewLabel }),
9476
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: [
9477
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 }) }),
@@ -9482,7 +9962,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9482
9962
  return s;
9483
9963
  }), children: t.resetPalette }) })
9484
9964
  ] }) }),
9485
- /* @__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: [
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: [
9486
9966
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.editor }),
9487
9967
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-enabled", label: t.enabled, value: editor.enabled, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9488
9968
  s.editor.enabled = v;
@@ -9522,6 +10002,30 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9522
10002
  }
9523
10003
  ),
9524
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: [
9525
10029
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9526
10030
  TextField2,
9527
10031
  {
@@ -9585,37 +10089,16 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9585
10089
  })
9586
10090
  }
9587
10091
  ),
9588
- lazyEditors && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
9589
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-lazyEditors", label: t.lazyEditors, value: editor.lazyEditors !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9590
- 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;
9591
10096
  return s;
9592
10097
  }) }),
9593
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9594
- UidListField,
9595
- {
9596
- TextField: TextField2,
9597
- name: "editor-lazyFields",
9598
- label: t.lazyFields,
9599
- value: editor.lazyFields || [],
9600
- disabled: !canUpdate || saving || editor.lazyEditors === false,
9601
- placeholder: "plugin::ckeditor5.CKEditor",
9602
- onChange: (uids) => update((s) => {
9603
- s.editor.lazyFields = uids;
9604
- return s;
9605
- })
9606
- }
9607
- ),
9608
- /* @__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 }),
9609
- data.blockPreviewAvailable && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
9610
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToggleField2, { name: "editor-blockPreviewInForm", label: t.blockPreviewInForm, value: editor.blockPreviewInForm, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9611
- s.editor.blockPreviewInForm = v;
9612
- return s;
9613
- }) }),
9614
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
9615
- ] })
10098
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
9616
10099
  ] })
9617
10100
  ] }) }),
9618
- /* @__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: [
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: [
9619
10102
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.rowActionsTitle }),
9620
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) => {
9621
10104
  s.editor.confirmDelete = v;
@@ -9645,7 +10128,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9645
10128
  ),
9646
10129
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: data.hiddenAttribute ? t.hiddenBlocksHelp : t.hiddenAttributeOff })
9647
10130
  ] }) }),
9648
- data.historyTypes && settings.history && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
10131
+ section === "history" && data.historyTypes && settings.history && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9649
10132
  HistorySettings,
9650
10133
  {
9651
10134
  types: data.historyTypes,
@@ -9660,10 +10143,10 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9660
10143
  })
9661
10144
  }
9662
10145
  ),
9663
- (data.contentTypes || []).length > 0 && /* @__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": "content-types", children: [
9664
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.contentTypes }),
9665
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: t.contentTypesHelp }),
9666
- 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) => {
9667
10150
  const entry = settings.contentTypes?.[type.uid] || {};
9668
10151
  const set2 = (key, value, fallback) => update((s) => {
9669
10152
  const next = { ...s.contentTypes?.[type.uid] || {} };
@@ -9674,9 +10157,10 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9674
10157
  else delete s.contentTypes[type.uid];
9675
10158
  return s;
9676
10159
  });
9677
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
9678
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { gap: 6, alignItems: "flex-end", wrap: "wrap", "data-testid": `content-type-${type.uid}`, children: [
9679
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { minWidth: 220 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.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)(
9680
10164
  ToggleField2,
9681
10165
  {
9682
10166
  name: `type-enabled-${type.uid}`,
@@ -9686,7 +10170,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9686
10170
  onChange: (v) => set2("enabled", v, true)
9687
10171
  }
9688
10172
  ) }),
9689
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { style: { minWidth: 240 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
10173
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9690
10174
  SelectField2,
9691
10175
  {
9692
10176
  name: `type-mode-${type.uid}`,
@@ -9698,46 +10182,51 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9698
10182
  }
9699
10183
  ) })
9700
10184
  ] }),
9701
- entry.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SidebarEditor, { type, entry, set: set2, t, disabled: !canUpdate || saving, SelectField: SelectField2, TextField: TextField2 }),
9702
- entry.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_design_system8.Flex, { direction: "column", alignItems: "stretch", gap: 3, paddingLeft: 4, children: [
9703
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9704
- ToggleField2,
9705
- {
9706
- name: `type-pane-${type.uid}`,
9707
- label: t.f("paneTypeOverride", { name: type.displayName }),
9708
- value: Boolean(entry.previewToolbar || entry.previewDevices),
9709
- disabled: !canUpdate || saving,
9710
- onChange: (v) => {
9711
- set2("previewToolbar", v ? [...editor.previewToolbar || TOOLBAR2] : void 0, void 0);
9712
- 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
+ }
9713
10200
  }
9714
- }
9715
- ),
9716
- (entry.previewToolbar || entry.previewDevices) && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
9717
- PaneEditor,
9718
- {
9719
- id: `type-${type.uid}`,
9720
- versions: Boolean(data.historyTypes),
9721
- toolbar: entry.previewToolbar || editor.previewToolbar || TOOLBAR2,
9722
- devices: entry.previewDevices || editor.previewDevices || DEVICE_NAMES,
9723
- t,
9724
- disabled: !canUpdate || saving,
9725
- TextField: TextField2,
9726
- set: (key, value) => set2(key, value, void 0)
9727
- }
9728
- )
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
+ ] })
9729
10216
  ] })
9730
10217
  ] }, type.uid);
9731
- }),
10218
+ }) }),
9732
10219
  badSidebar && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { role: "alert", textColor: "danger600", children: t.sidebarInvalidSave })
9733
- ] }) }),
9734
- /* @__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: [
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: [
9735
10222
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "beta", tag: "h2", children: t.components }),
9736
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 }),
9737
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 }) }),
9738
10225
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Grid2, { "data-testid": "components-grid", children: components.map((component) => {
9739
10226
  const entry = settings.components[component.uid] || {};
9740
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;
9741
10230
  const candidates = candidatesFor(component.uid, meta, catalog);
9742
10231
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Card2, { "data-testid": `settings-${component.uid}`, children: [
9743
10232
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
@@ -9816,6 +10305,16 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9816
10305
  onChange: (tags) => setComponent(component.uid, "tags", tags.length ? tags : void 0)
9817
10306
  }
9818
10307
  ),
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
+ ),
9819
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: [
9820
10319
  t.variantsFromCode,
9821
10320
  ": ",
@@ -9891,18 +10390,29 @@ function LayoutFields({ component, layout, set: set2, t, disabled, SelectField:
9891
10390
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system8.Typography, { variant: "pi", textColor: "neutral600", children: fields.length ? t.layoutHelp : t.layoutNoFields })
9892
10391
  ] });
9893
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
+ ];
9894
10400
  function register(app, Component2, to) {
9895
10401
  app.createSettingSection(
9896
10402
  { id: "blockscene", intlLabel: { id: "blockscene.title", defaultMessage: "Blockscene" } },
9897
- [{
9898
- id: "blockscene-settings",
9899
- to,
9900
- intlLabel: { id: "blockscene.settings", defaultMessage: "Gallery" },
9901
- // Module shape: older Strapi 4 (e.g. 4.11) only reads `.default` from the loader result.
9902
- // Not an `async` function: Strapi 5 warns on AsyncFunction loaders.
9903
- Component: () => Promise.resolve({ default: Component2 }),
9904
- permissions: permissions.read
9905
- }]
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
+ })
9906
10416
  );
9907
10417
  }
9908
10418
 
@@ -10829,7 +11339,7 @@ function usePermissions() {
10829
11339
  isLoading
10830
11340
  };
10831
11341
  }
10832
- var SettingsPage = () => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
11342
+ var SettingsPage = ({ section }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Guard, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10833
11343
  Settings,
10834
11344
  {
10835
11345
  useClient: import_admin5.useFetchClient,
@@ -10838,7 +11348,8 @@ var SettingsPage = () => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Guard, {
10838
11348
  ToggleField,
10839
11349
  SelectField,
10840
11350
  TextField,
10841
- lazyEditors: true
11351
+ lazyEditors: true,
11352
+ section
10842
11353
  }
10843
11354
  ) });
10844
11355
  var strapiApp = null;