@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.mjs CHANGED
@@ -125,13 +125,22 @@ var require_groups = __commonJS({
125
125
  const [a, b] = direction === "up" ? [ranges[to], ranges[at]] : [ranges[at], ranges[to]];
126
126
  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)];
127
127
  }
128
- function removeGroup2(rows, key, g) {
128
+ function removeGroup3(rows, key, g) {
129
129
  if (!g) return null;
130
130
  const start = rows.findIndex((row) => blockKey3(row) === String(key));
131
131
  if (start < 0 || !isOpener2(rows[start], g)) return null;
132
132
  const [, end] = groupRange3(rows, start, g);
133
+ if (end <= start || uidOf(rows[end]) !== g[uidOf(rows[start])]) return null;
133
134
  return [...rows.slice(0, start), ...rows.slice(end + 1)];
134
135
  }
136
+ function unwrapGroup3(rows, key, g) {
137
+ if (!g) return null;
138
+ const start = rows.findIndex((row) => blockKey3(row) === String(key));
139
+ if (start < 0 || !isOpener2(rows[start], g)) return null;
140
+ const [, end] = groupRange3(rows, start, g);
141
+ if (end <= start || uidOf(rows[end]) !== g[uidOf(rows[start])]) return null;
142
+ return [...rows.slice(0, start), ...rows.slice(start + 1, end), ...rows.slice(end + 1)];
143
+ }
135
144
  var MAX_COLUMNS = 12;
136
145
  var parseColumns = (value) => {
137
146
  const n = typeof value === "number" ? value : typeof value === "string" && /^\s*\d{1,3}\s*$/.test(value) ? Number(value) : NaN;
@@ -158,7 +167,8 @@ var require_groups = __commonJS({
158
167
  groupRows: groupRows2,
159
168
  topLevelRanges: topLevelRanges2,
160
169
  moveGroup: moveGroup2,
161
- removeGroup: removeGroup2,
170
+ removeGroup: removeGroup3,
171
+ unwrapGroup: unwrapGroup3,
162
172
  blockKey: blockKey3,
163
173
  isOpener: isOpener2,
164
174
  isClose: isClose2,
@@ -433,6 +443,12 @@ var pickable = (zone, config2) => {
433
443
  const closers = Object.values(config2.groups || {});
434
444
  return zone.components.filter((uid) => !closers.includes(uid));
435
445
  };
446
+ function showRowThumbnail(uid, config2 = {}) {
447
+ const configured = config2.components?.[uid]?.showRowThumbnail;
448
+ if (typeof configured === "boolean") return configured;
449
+ const groups = config2.groups || {};
450
+ return !Object.prototype.hasOwnProperty.call(groups, uid) && !Object.values(groups).includes(uid);
451
+ }
436
452
  function entryOf(uid, schema, config2) {
437
453
  const meta = config2.components?.[uid] || {};
438
454
  return {
@@ -579,13 +595,74 @@ var TEXT_TYPES = ["string", "text"];
579
595
  var RICH_TYPES = ["richtext", "blocks", "customField"];
580
596
  var EDITABLE_TYPES = [...TEXT_TYPES, ...RICH_TYPES];
581
597
  var SCALAR = ["string", "text", "richtext", "email", "enumeration", "integer", "biginteger", "float", "decimal", "boolean", "date", "datetime", "time", "json", "blocks", "uid", "customField"];
598
+ var ENTRY_SYSTEM = ["id", "documentId", "locale", "createdAt", "updatedAt", "publishedAt"];
599
+ var privateAttribute = (attr) => attr?.private === true || attr?.pluginOptions?.blockscene?.private === true;
600
+ var fieldReadable = (path, allowed, all = false) => {
601
+ if (all) return true;
602
+ const fields = Array.isArray(allowed) ? allowed : [];
603
+ const parts = String(path).split(".");
604
+ return parts.some((_, index) => fields.includes(parts.slice(0, index + 1).join("."))) || fields.some((field) => field.startsWith(`${path}.`));
605
+ };
582
606
  var blockKey = (row) => row && row.id != null ? `${row.__component}#${row.id}` : row && row.__temp_key__ != null ? String(row.__temp_key__) : null;
607
+ function plainValue(value, depth = 0) {
608
+ if (value == null || typeof value === "number" || typeof value === "boolean") return value;
609
+ if (typeof value === "string") return value.slice(0, 2e5);
610
+ if (typeof value !== "object" || depth > 8) return void 0;
611
+ if (Array.isArray(value)) return value.slice(0, 500).map((item) => plainValue(item, depth + 1)).filter((item) => item !== void 0);
612
+ const out = {};
613
+ for (const [name, child] of Object.entries(value).slice(0, 500)) {
614
+ const projected = plainValue(child, depth + 1);
615
+ if (projected !== void 0) out[name] = projected;
616
+ }
617
+ return out;
618
+ }
619
+ function projectEntryValue(value, attr, components, cmsOrigin, depth = 0, readable = () => true, path = "") {
620
+ if (privateAttribute(attr) || attr?.type === "password" || depth > 8) return void 0;
621
+ if (attr?.type === "media") {
622
+ const files = (attr.multiple ? Array.isArray(value) ? value : [] : value ? [value] : []).map((file) => projectMedia(file, cmsOrigin)).filter(Boolean);
623
+ return attr.multiple ? files : files[0] || null;
624
+ }
625
+ if (attr?.type === "component") {
626
+ const schema = components?.[attr.component];
627
+ const one = (item) => {
628
+ if (!item || !schema) return null;
629
+ const projected = projectEntryObject(item, schema, components, cmsOrigin, depth + 1, readable, path);
630
+ return item.id != null ? { id: item.id, ...projected } : projected;
631
+ };
632
+ return attr.repeatable ? (Array.isArray(value) ? value : []).slice(0, 500).map(one).filter(Boolean) : one(value);
633
+ }
634
+ if (attr?.type === "dynamiczone") {
635
+ return (Array.isArray(value) ? value : []).slice(0, 500).flatMap((item) => {
636
+ const uid = item?.__component;
637
+ const schema = components?.[uid];
638
+ if (!uid || !schema) return [];
639
+ const projected = projectEntryObject(item, schema, components, cmsOrigin, depth + 1, readable, path);
640
+ return [{ ...item.id != null && { id: item.id }, __component: uid, ...projected }];
641
+ });
642
+ }
643
+ return plainValue(value, depth);
644
+ }
645
+ function projectEntryObject(values, schema, components, cmsOrigin, depth = 0, readable = () => true, prefix2 = "") {
646
+ const out = {};
647
+ for (const [name, attr] of Object.entries(schema?.attributes || {})) {
648
+ const path = prefix2 ? `${prefix2}.${name}` : name;
649
+ if (!readable(path) || privateAttribute(attr) || attr.type === "password" || values?.[name] === void 0) continue;
650
+ const projected = projectEntryValue(values[name], attr, components, cmsOrigin, depth, readable, path);
651
+ if (projected !== void 0) out[name] = projected;
652
+ }
653
+ return out;
654
+ }
655
+ function projectEntry(values, schema, components, cmsOrigin, readable = () => true) {
656
+ const out = projectEntryObject(values, schema, components, cmsOrigin, 0, readable);
657
+ for (const name of ENTRY_SYSTEM) if (values?.[name] !== void 0) out[name] = plainValue(values[name]);
658
+ return out;
659
+ }
583
660
  function projectRow(row, schema, components, cmsOrigin, depth = 0) {
584
661
  if (!row || !schema || depth > 3) return null;
585
662
  const out = {};
586
663
  for (const [name, attr] of Object.entries(schema.attributes || {})) {
587
664
  const value = row[name];
588
- if (attr.type === "password" || attr.type === "relation" || attr.private) continue;
665
+ if (attr.type === "password" || attr.type === "relation" || privateAttribute(attr)) continue;
589
666
  if (SCALAR.includes(attr.type)) {
590
667
  if (value !== void 0) out[name] = typeof value === "string" ? value.slice(0, 2e5) : value;
591
668
  } else if (attr.type === "media") {
@@ -614,7 +691,7 @@ function resolveField(uid, field, components) {
614
691
  const parts = field.split(".");
615
692
  for (let i = 0; i < parts.length; i++) {
616
693
  const attr = schema?.attributes?.[parts[i]];
617
- if (!attr || attr.private === true) return null;
694
+ if (!attr || privateAttribute(attr)) return null;
618
695
  if (i === parts.length - 1) return attr;
619
696
  if (attr.type !== "component") return null;
620
697
  if (attr.repeatable) {
@@ -630,7 +707,7 @@ function editableFields(uid, row, components) {
630
707
  const out = [];
631
708
  const SYSTEM = ["id", "documentId", "locale", "createdAt", "updatedAt", "publishedAt", "createdBy", "updatedBy", "localizations", "__component", "__temp_key__"];
632
709
  const push = (name, attr, label) => {
633
- if (!SYSTEM.includes(name.split(".").pop()) && attr?.private !== true && EDITABLE_TYPES.includes(attr?.type)) out.push({ name, type: attr.type, label });
710
+ if (!SYSTEM.includes(name.split(".").pop()) && !privateAttribute(attr) && EDITABLE_TYPES.includes(attr?.type)) out.push({ name, type: attr.type, label });
634
711
  };
635
712
  for (const [name, attr] of Object.entries(schema?.attributes || {})) {
636
713
  if (attr.type === "component" && attr.repeatable) {
@@ -644,7 +721,7 @@ function editableFields(uid, row, components) {
644
721
  function mediaFields(uid, row, components) {
645
722
  const media = {};
646
723
  for (const [name, attr] of Object.entries(components?.[uid]?.attributes || {})) {
647
- 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]) };
724
+ 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]) };
648
725
  }
649
726
  return media;
650
727
  }
@@ -887,7 +964,7 @@ import { useIntl } from "react-intl";
887
964
  // admin/translations/en.json
888
965
  var en_default = {
889
966
  title: "Blockscene",
890
- settings: "Gallery",
967
+ settings: "General",
891
968
  gallery: "Block gallery",
892
969
  search: "Search blocks",
893
970
  clear: "Clear search",
@@ -903,6 +980,17 @@ var en_default = {
903
980
  moreActions: "More actions",
904
981
  settingsTitle: "Blockscene",
905
982
  settingsIntro: "Gallery thumbnails, wireframe palette and editor preferences. Changes apply the next time the gallery opens; no rebuild is needed.",
983
+ settingsGeneral: "General",
984
+ settingsGeneralIntro: "Choose how Blockscene behaves in the editor and which row actions are available.",
985
+ settingsPreview: "Page preview",
986
+ settingsPreviewIntro: "Connect the frontend preview and configure its modes, toolbar and responsive widths.",
987
+ settingsContentTypes: "Content types",
988
+ settingsContentTypesIntro: "Choose where Blockscene is enabled and tailor the visual editor for each content type.",
989
+ settingsGallery: "Block gallery",
990
+ settingsGalleryIntro: "Configure gallery thumbnails, wireframe colors, block types and filters.",
991
+ settingsHistory: "History & trash",
992
+ settingsHistoryIntro: "Control version snapshots, activity retention and recoverable deletions.",
993
+ historyUnavailable: "History and trash settings require Strapi 5.",
906
994
  palette: "Wireframe palette",
907
995
  background: "Background",
908
996
  surface: "Surfaces",
@@ -932,6 +1020,7 @@ var en_default = {
932
1020
  showCloseAll: 'Show "Collapse all"',
933
1021
  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.",
934
1022
  showRowThumbnails: "Show block thumbnails in the rows",
1023
+ componentRowThumbnail: "Show thumbnail in the editor row",
935
1024
  initialState: "Initial accordion state",
936
1025
  "states.closed": "All closed",
937
1026
  "states.open": "All open",
@@ -978,6 +1067,7 @@ var en_default = {
978
1067
  denied: "Access denied.",
979
1068
  loadFailed: "Could not load settings. Reload to try again.",
980
1069
  invalidColor: "Colors must use #RRGGBB.",
1070
+ invalidUrl: "Preview URLs must be complete HTTP or HTTPS URLs.",
981
1071
  previewLabel: "Palette preview",
982
1072
  removeGroup: "Remove group",
983
1073
  diagTitle: "Block groups need attention; publishing is refused until they are fixed:",
@@ -1012,6 +1102,7 @@ var en_default = {
1012
1102
  contentTypes: "Content types",
1013
1103
  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.',
1014
1104
  typeMode: "Opens in",
1105
+ typeAdvanced: "Visual editor options",
1015
1106
  modeDefault: "Default ({mode})",
1016
1107
  blockModalDone: "Done",
1017
1108
  crashed: "Blockscene stopped here after an error. The native editor is unaffected. If it happens again, turn Blockscene off in Settings, Blockscene.",
@@ -1103,6 +1194,11 @@ var en_default = {
1103
1194
  confirmDeleteTitle: "Delete block",
1104
1195
  confirmDelete: "Delete block {name}?",
1105
1196
  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.",
1197
+ confirmDeleteGroupTitle: "Delete group",
1198
+ confirmDeleteGroup: "Delete group {name}?",
1199
+ confirmDeleteGroupHint: "This group contains {count, plural, one {# block} other {# blocks}}. Choose whether to delete them or keep them on the page without the group.",
1200
+ keepGroupBlocks: "Remove group, keep blocks",
1201
+ deleteGroupAndBlocks: "{count, plural, =0 {Delete group} one {Delete group and # block} other {Delete group and # blocks}}",
1106
1202
  delete: "Delete",
1107
1203
  selectBlocks: "Select blocks",
1108
1204
  selectAll: "Select all",
@@ -1297,6 +1393,7 @@ var en_default = {
1297
1393
  gridCellMenu: "More actions for {label}",
1298
1394
  removeFromGroup: "Remove from group",
1299
1395
  gridAdd: "Add a block",
1396
+ groupAdd: "Add block inside {label}",
1300
1397
  gridShowList: "Show group {label} as a list",
1301
1398
  gridShowGrid: "Show group {label} as a grid",
1302
1399
  layoutColumnsField: "Layout grid: columns field",
@@ -1327,7 +1424,7 @@ var en_default = {
1327
1424
  // admin/translations/pt-BR.json
1328
1425
  var pt_BR_default = {
1329
1426
  title: "Blockscene",
1330
- settings: "Galeria",
1427
+ settings: "Geral",
1331
1428
  gallery: "Galeria de blocos",
1332
1429
  search: "Buscar blocos",
1333
1430
  clear: "Limpar busca",
@@ -1343,6 +1440,17 @@ var pt_BR_default = {
1343
1440
  moreActions: "Mais a\xE7\xF5es",
1344
1441
  settingsTitle: "Blockscene",
1345
1442
  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.",
1443
+ settingsGeneral: "Geral",
1444
+ settingsGeneralIntro: "Defina como o Blockscene funciona no editor e quais a\xE7\xF5es ficam dispon\xEDveis nas linhas.",
1445
+ settingsPreview: "Preview da p\xE1gina",
1446
+ settingsPreviewIntro: "Conecte a preview do frontend e configure modos, barra de ferramentas e larguras responsivas.",
1447
+ settingsContentTypes: "Tipos de conte\xFAdo",
1448
+ settingsContentTypesIntro: "Escolha onde o Blockscene fica ativo e personalize o editor visual de cada tipo de conte\xFAdo.",
1449
+ settingsGallery: "Galeria de blocos",
1450
+ settingsGalleryIntro: "Configure miniaturas, cores dos wireframes, tipos e filtros da galeria.",
1451
+ settingsHistory: "Hist\xF3rico e lixeira",
1452
+ settingsHistoryIntro: "Controle vers\xF5es, reten\xE7\xE3o de atividades e exclus\xF5es recuper\xE1veis.",
1453
+ historyUnavailable: "As configura\xE7\xF5es de hist\xF3rico e lixeira exigem o Strapi 5.",
1346
1454
  palette: "Paleta dos wireframes",
1347
1455
  background: "Fundo",
1348
1456
  surface: "Superf\xEDcies",
@@ -1372,6 +1480,7 @@ var pt_BR_default = {
1372
1480
  showCloseAll: 'Mostrar "Recolher tudo"',
1373
1481
  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.",
1374
1482
  showRowThumbnails: "Mostrar miniaturas dos blocos nas linhas",
1483
+ componentRowThumbnail: "Mostrar miniatura na linha do editor",
1375
1484
  initialState: "Estado inicial dos accordions",
1376
1485
  "states.closed": "Todos fechados",
1377
1486
  "states.open": "Todos abertos",
@@ -1418,6 +1527,7 @@ var pt_BR_default = {
1418
1527
  denied: "Acesso negado.",
1419
1528
  loadFailed: "N\xE3o foi poss\xEDvel carregar. Recarregue para tentar novamente.",
1420
1529
  invalidColor: "As cores devem usar #RRGGBB.",
1530
+ invalidUrl: "As URLs de preview devem ser URLs HTTP ou HTTPS completas.",
1421
1531
  previewLabel: "Pr\xE9via da paleta",
1422
1532
  removeGroup: "Remover grupo",
1423
1533
  diagTitle: "Os grupos de blocos precisam de aten\xE7\xE3o; a publica\xE7\xE3o \xE9 recusada at\xE9 a corre\xE7\xE3o:",
@@ -1452,6 +1562,7 @@ var pt_BR_default = {
1452
1562
  contentTypes: "Tipos de conte\xFAdo",
1453
1563
  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.',
1454
1564
  typeMode: "Abre em",
1565
+ typeAdvanced: "Op\xE7\xF5es do editor visual",
1455
1566
  modeDefault: "Padr\xE3o ({mode})",
1456
1567
  blockModalDone: "Concluir",
1457
1568
  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.",
@@ -1543,6 +1654,11 @@ var pt_BR_default = {
1543
1654
  confirmDeleteTitle: "Excluir bloco",
1544
1655
  confirmDelete: "Excluir o bloco {name}?",
1545
1656
  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.",
1657
+ confirmDeleteGroupTitle: "Excluir grupo",
1658
+ confirmDeleteGroup: "Excluir o grupo {name}?",
1659
+ 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.",
1660
+ keepGroupBlocks: "Remover grupo e manter blocos",
1661
+ deleteGroupAndBlocks: "{count, plural, =0 {Excluir grupo} one {Excluir grupo e # bloco} other {Excluir grupo e # blocos}}",
1546
1662
  delete: "Excluir",
1547
1663
  selectBlocks: "Selecionar blocos",
1548
1664
  selectAll: "Selecionar todos",
@@ -1737,6 +1853,7 @@ var pt_BR_default = {
1737
1853
  gridCellMenu: "Mais a\xE7\xF5es para {label}",
1738
1854
  removeFromGroup: "Remover do grupo",
1739
1855
  gridAdd: "Adicionar bloco",
1856
+ groupAdd: "Adicionar bloco dentro de {label}",
1740
1857
  gridShowList: "Mostrar o grupo {label} como lista",
1741
1858
  gridShowGrid: "Mostrar o grupo {label} como grade",
1742
1859
  layoutColumnsField: "Grade do layout: campo das colunas",
@@ -1767,7 +1884,7 @@ var pt_BR_default = {
1767
1884
  // admin/translations/pt.json
1768
1885
  var pt_default = {
1769
1886
  title: "Blockscene",
1770
- settings: "Galeria",
1887
+ settings: "Geral",
1771
1888
  gallery: "Galeria de blocos",
1772
1889
  search: "Pesquisar blocos",
1773
1890
  clear: "Limpar pesquisa",
@@ -1783,6 +1900,17 @@ var pt_default = {
1783
1900
  moreActions: "Mais a\xE7\xF5es",
1784
1901
  settingsTitle: "Blockscene",
1785
1902
  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.",
1903
+ settingsGeneral: "Geral",
1904
+ settingsGeneralIntro: "Defina como o Blockscene funciona no editor e quais a\xE7\xF5es ficam dispon\xEDveis nas linhas.",
1905
+ settingsPreview: "Pr\xE9-visualiza\xE7\xE3o da p\xE1gina",
1906
+ settingsPreviewIntro: "Ligue a pr\xE9-visualiza\xE7\xE3o do frontend e configure modos, barra de ferramentas e larguras responsivas.",
1907
+ settingsContentTypes: "Tipos de conte\xFAdo",
1908
+ settingsContentTypesIntro: "Escolha onde o Blockscene fica ativo e personalize o editor visual de cada tipo de conte\xFAdo.",
1909
+ settingsGallery: "Galeria de blocos",
1910
+ settingsGalleryIntro: "Configure miniaturas, cores dos wireframes, tipos e filtros da galeria.",
1911
+ settingsHistory: "Hist\xF3rico e lixo",
1912
+ settingsHistoryIntro: "Controle vers\xF5es, reten\xE7\xE3o de atividades e elimina\xE7\xF5es recuper\xE1veis.",
1913
+ historyUnavailable: "As configura\xE7\xF5es de hist\xF3rico e lixo exigem o Strapi 5.",
1786
1914
  palette: "Paleta dos wireframes",
1787
1915
  background: "Fundo",
1788
1916
  surface: "Superf\xEDcies",
@@ -1812,6 +1940,7 @@ var pt_default = {
1812
1940
  showCloseAll: 'Mostrar "Recolher tudo"',
1813
1941
  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.",
1814
1942
  showRowThumbnails: "Mostrar miniaturas dos blocos nas linhas",
1943
+ componentRowThumbnail: "Mostrar miniatura na linha do editor",
1815
1944
  initialState: "Estado inicial dos accordions",
1816
1945
  "states.closed": "Todos fechados",
1817
1946
  "states.open": "Todos abertos",
@@ -1858,6 +1987,7 @@ var pt_default = {
1858
1987
  denied: "Acesso negado.",
1859
1988
  loadFailed: "N\xE3o foi poss\xEDvel carregar. Recarregue para tentar novamente.",
1860
1989
  invalidColor: "As cores devem usar #RRGGBB.",
1990
+ invalidUrl: "Os URL de pr\xE9-visualiza\xE7\xE3o devem ser endere\xE7os HTTP ou HTTPS completos.",
1861
1991
  previewLabel: "Pr\xE9-visualiza\xE7\xE3o da paleta",
1862
1992
  removeGroup: "Remover grupo",
1863
1993
  diagTitle: "Os grupos de blocos precisam de aten\xE7\xE3o; a publica\xE7\xE3o \xE9 recusada at\xE9 \xE0 corre\xE7\xE3o:",
@@ -1892,6 +2022,7 @@ var pt_default = {
1892
2022
  contentTypes: "Tipos de conte\xFAdo",
1893
2023
  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.',
1894
2024
  typeMode: "Abre em",
2025
+ typeAdvanced: "Op\xE7\xF5es do editor visual",
1895
2026
  modeDefault: "Predefini\xE7\xE3o ({mode})",
1896
2027
  blockModalDone: "Concluir",
1897
2028
  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.",
@@ -1983,6 +2114,11 @@ var pt_default = {
1983
2114
  confirmDeleteTitle: "Eliminar bloco",
1984
2115
  confirmDelete: "Eliminar o bloco {name}?",
1985
2116
  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.",
2117
+ confirmDeleteGroupTitle: "Eliminar grupo",
2118
+ confirmDeleteGroup: "Eliminar o grupo {name}?",
2119
+ 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.",
2120
+ keepGroupBlocks: "Eliminar grupo e manter blocos",
2121
+ deleteGroupAndBlocks: "{count, plural, =0 {Eliminar grupo} one {Eliminar grupo e # bloco} other {Eliminar grupo e # blocos}}",
1986
2122
  delete: "Eliminar",
1987
2123
  selectBlocks: "Selecionar blocos",
1988
2124
  selectAll: "Selecionar todos",
@@ -2177,6 +2313,7 @@ var pt_default = {
2177
2313
  gridCellMenu: "Mais a\xE7\xF5es para {label}",
2178
2314
  removeFromGroup: "Remover do grupo",
2179
2315
  gridAdd: "Adicionar bloco",
2316
+ groupAdd: "Adicionar bloco dentro de {label}",
2180
2317
  gridShowList: "Mostrar o grupo {label} como lista",
2181
2318
  gridShowGrid: "Mostrar o grupo {label} como grelha",
2182
2319
  layoutColumnsField: "Grelha do layout: campo das colunas",
@@ -2207,7 +2344,7 @@ var pt_default = {
2207
2344
  // admin/translations/fr.json
2208
2345
  var fr_default = {
2209
2346
  title: "Blockscene",
2210
- settings: "Galerie",
2347
+ settings: "G\xE9n\xE9ral",
2211
2348
  gallery: "Galerie de blocs",
2212
2349
  search: "Rechercher des blocs",
2213
2350
  clear: "Effacer la recherche",
@@ -2223,6 +2360,17 @@ var fr_default = {
2223
2360
  moreActions: "Plus d'actions",
2224
2361
  settingsTitle: "Blockscene",
2225
2362
  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.",
2363
+ settingsGeneral: "G\xE9n\xE9ral",
2364
+ settingsGeneralIntro: "D\xE9finissez le comportement de Blockscene dans l'\xE9diteur et les actions disponibles sur les lignes.",
2365
+ settingsPreview: "Aper\xE7u de page",
2366
+ settingsPreviewIntro: "Connectez l'aper\xE7u du frontend et configurez ses modes, sa barre d'outils et ses largeurs responsives.",
2367
+ settingsContentTypes: "Types de contenu",
2368
+ settingsContentTypesIntro: "Choisissez o\xF9 Blockscene est actif et personnalisez l'\xE9diteur visuel pour chaque type de contenu.",
2369
+ settingsGallery: "Galerie de blocs",
2370
+ settingsGalleryIntro: "Configurez les vignettes, les couleurs des wireframes, les types et les filtres de la galerie.",
2371
+ settingsHistory: "Historique et corbeille",
2372
+ settingsHistoryIntro: "G\xE9rez les versions, la conservation des activit\xE9s et les suppressions r\xE9cup\xE9rables.",
2373
+ historyUnavailable: "Les r\xE9glages d'historique et de corbeille n\xE9cessitent Strapi 5.",
2226
2374
  palette: "Palette des wireframes",
2227
2375
  background: "Fond",
2228
2376
  surface: "Surfaces",
@@ -2252,6 +2400,7 @@ var fr_default = {
2252
2400
  showCloseAll: "Afficher \xAB Tout replier \xBB",
2253
2401
  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.",
2254
2402
  showRowThumbnails: "Afficher les miniatures des blocs dans les lignes",
2403
+ componentRowThumbnail: "Afficher la miniature dans la ligne de l'\xE9diteur",
2255
2404
  initialState: "\xC9tat initial des accord\xE9ons",
2256
2405
  "states.closed": "Tous ferm\xE9s",
2257
2406
  "states.open": "Tous ouverts",
@@ -2298,6 +2447,7 @@ var fr_default = {
2298
2447
  denied: "Acc\xE8s refus\xE9.",
2299
2448
  loadFailed: "Impossible de charger les param\xE8tres. Rechargez pour r\xE9essayer.",
2300
2449
  invalidColor: "Les couleurs doivent utiliser #RRGGBB.",
2450
+ invalidUrl: "Les URL d'aper\xE7u doivent \xEAtre des adresses HTTP ou HTTPS compl\xE8tes.",
2301
2451
  previewLabel: "Aper\xE7u de la palette",
2302
2452
  removeGroup: "Supprimer le groupe",
2303
2453
  diagTitle: "Les groupes de blocs demandent une correction ; la publication est refus\xE9e tant qu'ils ne sont pas corrig\xE9s :",
@@ -2332,6 +2482,7 @@ var fr_default = {
2332
2482
  contentTypes: "Types de contenu",
2333
2483
  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.",
2334
2484
  typeMode: "S'ouvre en",
2485
+ typeAdvanced: "Options de l'\xE9diteur visuel",
2335
2486
  modeDefault: "Par d\xE9faut ({mode})",
2336
2487
  blockModalDone: "Termin\xE9",
2337
2488
  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.",
@@ -2423,6 +2574,11 @@ var fr_default = {
2423
2574
  confirmDeleteTitle: "Supprimer le bloc",
2424
2575
  confirmDelete: "Supprimer le bloc {name} ?",
2425
2576
  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.",
2577
+ confirmDeleteGroupTitle: "Supprimer le groupe",
2578
+ confirmDeleteGroup: "Supprimer le groupe {name} ?",
2579
+ confirmDeleteGroupHint: "Ce groupe contient {count, plural, one {# bloc} other {# blocs}}. Choisissez de les supprimer ou de les conserver dans la page sans le groupe.",
2580
+ keepGroupBlocks: "Supprimer le groupe, conserver les blocs",
2581
+ deleteGroupAndBlocks: "{count, plural, =0 {Supprimer le groupe} one {Supprimer le groupe et # bloc} other {Supprimer le groupe et # blocs}}",
2426
2582
  delete: "Supprimer",
2427
2583
  selectBlocks: "S\xE9lectionner des blocs",
2428
2584
  selectAll: "Tout s\xE9lectionner",
@@ -2617,6 +2773,7 @@ var fr_default = {
2617
2773
  gridCellMenu: "Plus d'actions pour {label}",
2618
2774
  removeFromGroup: "Retirer du groupe",
2619
2775
  gridAdd: "Ajouter un bloc",
2776
+ groupAdd: "Ajouter un bloc dans {label}",
2620
2777
  gridShowList: "Afficher le groupe {label} en liste",
2621
2778
  gridShowGrid: "Afficher le groupe {label} en grille",
2622
2779
  layoutColumnsField: "Grille de mise en page : champ des colonnes",
@@ -2647,7 +2804,7 @@ var fr_default = {
2647
2804
  // admin/translations/es.json
2648
2805
  var es_default = {
2649
2806
  title: "Blockscene",
2650
- settings: "Galer\xEDa",
2807
+ settings: "General",
2651
2808
  gallery: "Galer\xEDa de bloques",
2652
2809
  search: "Buscar bloques",
2653
2810
  clear: "Borrar b\xFAsqueda",
@@ -2663,6 +2820,17 @@ var es_default = {
2663
2820
  moreActions: "M\xE1s acciones",
2664
2821
  settingsTitle: "Blockscene",
2665
2822
  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.",
2823
+ settingsGeneral: "General",
2824
+ settingsGeneralIntro: "Define c\xF3mo funciona Blockscene en el editor y qu\xE9 acciones est\xE1n disponibles en las filas.",
2825
+ settingsPreview: "Vista previa de p\xE1gina",
2826
+ settingsPreviewIntro: "Conecta la vista previa del frontend y configura sus modos, barra de herramientas y anchos adaptables.",
2827
+ settingsContentTypes: "Tipos de contenido",
2828
+ settingsContentTypesIntro: "Elige d\xF3nde se activa Blockscene y personaliza el editor visual de cada tipo de contenido.",
2829
+ settingsGallery: "Galer\xEDa de bloques",
2830
+ settingsGalleryIntro: "Configura miniaturas, colores de wireframes, tipos y filtros de la galer\xEDa.",
2831
+ settingsHistory: "Historial y papelera",
2832
+ settingsHistoryIntro: "Controla versiones, retenci\xF3n de actividad y eliminaciones recuperables.",
2833
+ historyUnavailable: "La configuraci\xF3n de historial y papelera requiere Strapi 5.",
2666
2834
  palette: "Paleta de wireframes",
2667
2835
  background: "Fondo",
2668
2836
  surface: "Superficies",
@@ -2692,6 +2860,7 @@ var es_default = {
2692
2860
  showCloseAll: "Mostrar \xABContraer todo\xBB",
2693
2861
  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.",
2694
2862
  showRowThumbnails: "Mostrar miniaturas de los bloques en las filas",
2863
+ componentRowThumbnail: "Mostrar miniatura en la fila del editor",
2695
2864
  initialState: "Estado inicial de los acordeones",
2696
2865
  "states.closed": "Todos cerrados",
2697
2866
  "states.open": "Todos abiertos",
@@ -2738,6 +2907,7 @@ var es_default = {
2738
2907
  denied: "Acceso denegado.",
2739
2908
  loadFailed: "No se pudieron cargar los ajustes. Recargue para reintentar.",
2740
2909
  invalidColor: "Los colores deben usar #RRGGBB.",
2910
+ invalidUrl: "Las URL de vista previa deben ser direcciones HTTP o HTTPS completas.",
2741
2911
  previewLabel: "Vista previa de la paleta",
2742
2912
  removeGroup: "Eliminar grupo",
2743
2913
  diagTitle: "Los grupos de bloques necesitan atenci\xF3n; la publicaci\xF3n se rechaza hasta corregirlos:",
@@ -2772,6 +2942,7 @@ var es_default = {
2772
2942
  contentTypes: "Tipos de contenido",
2773
2943
  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.',
2774
2944
  typeMode: "Se abre en",
2945
+ typeAdvanced: "Opciones del editor visual",
2775
2946
  modeDefault: "Predeterminado ({mode})",
2776
2947
  blockModalDone: "Listo",
2777
2948
  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.",
@@ -2863,6 +3034,11 @@ var es_default = {
2863
3034
  confirmDeleteTitle: "Eliminar bloque",
2864
3035
  confirmDelete: "\xBFEliminar el bloque {name}?",
2865
3036
  confirmDeleteMarker: "Es un marcador de grupo: solo se elimina el marcador, no los bloques del grupo, y el grupo queda desequilibrado hasta corregirlo.",
3037
+ confirmDeleteGroupTitle: "Eliminar grupo",
3038
+ confirmDeleteGroup: "\xBFEliminar el grupo {name}?",
3039
+ confirmDeleteGroupHint: "Este grupo contiene {count, plural, one {# bloque} other {# bloques}}. Elige si eliminarlos o conservarlos en la p\xE1gina sin el grupo.",
3040
+ keepGroupBlocks: "Eliminar grupo y conservar bloques",
3041
+ deleteGroupAndBlocks: "{count, plural, =0 {Eliminar grupo} one {Eliminar grupo y # bloque} other {Eliminar grupo y # bloques}}",
2866
3042
  delete: "Eliminar",
2867
3043
  selectBlocks: "Seleccionar bloques",
2868
3044
  selectAll: "Seleccionar todos",
@@ -3057,6 +3233,7 @@ var es_default = {
3057
3233
  gridCellMenu: "M\xE1s acciones para {label}",
3058
3234
  removeFromGroup: "Quitar del grupo",
3059
3235
  gridAdd: "A\xF1adir un bloque",
3236
+ groupAdd: "A\xF1adir un bloque dentro de {label}",
3060
3237
  gridShowList: "Mostrar el grupo {label} como lista",
3061
3238
  gridShowGrid: "Mostrar el grupo {label} como cuadr\xEDcula",
3062
3239
  layoutColumnsField: "Cuadr\xEDcula de dise\xF1o: campo de columnas",
@@ -3087,7 +3264,7 @@ var es_default = {
3087
3264
  // admin/translations/de.json
3088
3265
  var de_default = {
3089
3266
  title: "Blockscene",
3090
- settings: "Galerie",
3267
+ settings: "Allgemein",
3091
3268
  gallery: "Blockgalerie",
3092
3269
  search: "Bl\xF6cke suchen",
3093
3270
  clear: "Suche l\xF6schen",
@@ -3103,6 +3280,17 @@ var de_default = {
3103
3280
  moreActions: "Weitere Aktionen",
3104
3281
  settingsTitle: "Blockscene",
3105
3282
  settingsIntro: "Galerie-Vorschaubilder, Wireframe-Palette und Editor-Einstellungen. \xC4nderungen gelten beim n\xE4chsten \xD6ffnen der Galerie; kein Rebuild n\xF6tig.",
3283
+ settingsGeneral: "Allgemein",
3284
+ settingsGeneralIntro: "Lege fest, wie Blockscene im Editor arbeitet und welche Zeilenaktionen verf\xFCgbar sind.",
3285
+ settingsPreview: "Seitenvorschau",
3286
+ settingsPreviewIntro: "Verbinde die Frontend-Vorschau und konfiguriere Modi, Werkzeugleiste und responsive Breiten.",
3287
+ settingsContentTypes: "Inhaltstypen",
3288
+ settingsContentTypesIntro: "W\xE4hle, wo Blockscene aktiv ist, und passe den visuellen Editor je Inhaltstyp an.",
3289
+ settingsGallery: "Blockgalerie",
3290
+ settingsGalleryIntro: "Konfiguriere Vorschaubilder, Wireframe-Farben, Blocktypen und Filter.",
3291
+ settingsHistory: "Verlauf und Papierkorb",
3292
+ settingsHistoryIntro: "Steuere Versionen, Aufbewahrung von Aktivit\xE4ten und wiederherstellbare L\xF6schungen.",
3293
+ historyUnavailable: "Verlauf und Papierkorb erfordern Strapi 5.",
3106
3294
  palette: "Wireframe-Palette",
3107
3295
  background: "Hintergrund",
3108
3296
  surface: "Fl\xE4chen",
@@ -3132,6 +3320,7 @@ var de_default = {
3132
3320
  showCloseAll: "\u201EAlle zuklappen\u201C anzeigen",
3133
3321
  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.",
3134
3322
  showRowThumbnails: "Blockvorschaubilder in den Zeilen anzeigen",
3323
+ componentRowThumbnail: "Vorschaubild in der Editorzeile anzeigen",
3135
3324
  initialState: "Anfangszustand der Akkordeons",
3136
3325
  "states.closed": "Alle geschlossen",
3137
3326
  "states.open": "Alle ge\xF6ffnet",
@@ -3178,6 +3367,7 @@ var de_default = {
3178
3367
  denied: "Zugriff verweigert.",
3179
3368
  loadFailed: "Einstellungen konnten nicht geladen werden. Neu laden, um es erneut zu versuchen.",
3180
3369
  invalidColor: "Farben m\xFCssen #RRGGBB verwenden.",
3370
+ invalidUrl: "Vorschau-URLs m\xFCssen vollst\xE4ndige HTTP- oder HTTPS-Adressen sein.",
3181
3371
  previewLabel: "Palettenvorschau",
3182
3372
  removeGroup: "Gruppe entfernen",
3183
3373
  diagTitle: "Blockgruppen m\xFCssen korrigiert werden; das Ver\xF6ffentlichen wird bis dahin abgelehnt:",
@@ -3212,6 +3402,7 @@ var de_default = {
3212
3402
  contentTypes: "Inhaltstypen",
3213
3403
  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.",
3214
3404
  typeMode: "\xD6ffnet in",
3405
+ typeAdvanced: "Optionen des visuellen Editors",
3215
3406
  modeDefault: "Standard ({mode})",
3216
3407
  blockModalDone: "Fertig",
3217
3408
  crashed: "Blockscene wurde hier wegen eines Fehlers beendet. Der native Editor ist nicht betroffen. Passiert es erneut, schalte Blockscene unter Settings, Blockscene aus.",
@@ -3303,6 +3494,11 @@ var de_default = {
3303
3494
  confirmDeleteTitle: "Block l\xF6schen",
3304
3495
  confirmDelete: "Block {name} l\xF6schen?",
3305
3496
  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.",
3497
+ confirmDeleteGroupTitle: "Gruppe l\xF6schen",
3498
+ confirmDeleteGroup: "Gruppe {name} l\xF6schen?",
3499
+ 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.",
3500
+ keepGroupBlocks: "Gruppe entfernen, Bl\xF6cke behalten",
3501
+ deleteGroupAndBlocks: "{count, plural, =0 {Gruppe l\xF6schen} one {Gruppe und # Block l\xF6schen} other {Gruppe und # Bl\xF6cke l\xF6schen}}",
3306
3502
  delete: "L\xF6schen",
3307
3503
  selectBlocks: "Bl\xF6cke ausw\xE4hlen",
3308
3504
  selectAll: "Alle ausw\xE4hlen",
@@ -3497,6 +3693,7 @@ var de_default = {
3497
3693
  gridCellMenu: "Weitere Aktionen f\xFCr {label}",
3498
3694
  removeFromGroup: "Aus der Gruppe entfernen",
3499
3695
  gridAdd: "Block hinzuf\xFCgen",
3696
+ groupAdd: "Block in {label} hinzuf\xFCgen",
3500
3697
  gridShowList: "Gruppe {label} als Liste anzeigen",
3501
3698
  gridShowGrid: "Gruppe {label} als Raster anzeigen",
3502
3699
  layoutColumnsField: "Layout-Raster: Feld der Spalten",
@@ -3527,7 +3724,7 @@ var de_default = {
3527
3724
  // admin/translations/it.json
3528
3725
  var it_default = {
3529
3726
  title: "Blockscene",
3530
- settings: "Galleria",
3727
+ settings: "Generali",
3531
3728
  gallery: "Galleria dei blocchi",
3532
3729
  search: "Cerca blocchi",
3533
3730
  clear: "Cancella ricerca",
@@ -3543,6 +3740,17 @@ var it_default = {
3543
3740
  moreActions: "Altre azioni",
3544
3741
  settingsTitle: "Blockscene",
3545
3742
  settingsIntro: "Miniature della galleria, palette dei wireframe e preferenze dell'editor. Le modifiche valgono alla prossima apertura della galleria; non serve alcun rebuild.",
3743
+ settingsGeneral: "Generali",
3744
+ settingsGeneralIntro: "Configura il comportamento di Blockscene nell'editor e le azioni disponibili sulle righe.",
3745
+ settingsPreview: "Anteprima pagina",
3746
+ settingsPreviewIntro: "Collega l'anteprima del frontend e configura modalit\xE0, barra degli strumenti e larghezze responsive.",
3747
+ settingsContentTypes: "Tipi di contenuto",
3748
+ settingsContentTypesIntro: "Scegli dove attivare Blockscene e personalizza l'editor visivo per ogni tipo di contenuto.",
3749
+ settingsGallery: "Galleria dei blocchi",
3750
+ settingsGalleryIntro: "Configura miniature, colori dei wireframe, tipi e filtri della galleria.",
3751
+ settingsHistory: "Cronologia e cestino",
3752
+ settingsHistoryIntro: "Gestisci versioni, conservazione delle attivit\xE0 ed eliminazioni recuperabili.",
3753
+ historyUnavailable: "Le impostazioni di cronologia e cestino richiedono Strapi 5.",
3546
3754
  palette: "Palette dei wireframe",
3547
3755
  background: "Sfondo",
3548
3756
  surface: "Superfici",
@@ -3572,6 +3780,7 @@ var it_default = {
3572
3780
  showCloseAll: 'Mostra "Comprimi tutto"',
3573
3781
  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.",
3574
3782
  showRowThumbnails: "Mostra le miniature dei blocchi nelle righe",
3783
+ componentRowThumbnail: "Mostra la miniatura nella riga dell'editor",
3575
3784
  initialState: "Stato iniziale delle fisarmoniche",
3576
3785
  "states.closed": "Tutte chiuse",
3577
3786
  "states.open": "Tutte aperte",
@@ -3618,6 +3827,7 @@ var it_default = {
3618
3827
  denied: "Accesso negato.",
3619
3828
  loadFailed: "Impossibile caricare le impostazioni. Ricarica per riprovare.",
3620
3829
  invalidColor: "I colori devono usare #RRGGBB.",
3830
+ invalidUrl: "Gli URL di anteprima devono essere indirizzi HTTP o HTTPS completi.",
3621
3831
  previewLabel: "Anteprima della palette",
3622
3832
  removeGroup: "Rimuovi gruppo",
3623
3833
  diagTitle: "I gruppi di blocchi richiedono attenzione; la pubblicazione \xE8 rifiutata finch\xE9 non vengono corretti:",
@@ -3652,6 +3862,7 @@ var it_default = {
3652
3862
  contentTypes: "Tipi di contenuto",
3653
3863
  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.",
3654
3864
  typeMode: "Si apre in",
3865
+ typeAdvanced: "Opzioni dell'editor visivo",
3655
3866
  modeDefault: "Predefinito ({mode})",
3656
3867
  blockModalDone: "Fatto",
3657
3868
  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.",
@@ -3743,6 +3954,11 @@ var it_default = {
3743
3954
  confirmDeleteTitle: "Elimina blocco",
3744
3955
  confirmDelete: "Eliminare il blocco {name}?",
3745
3956
  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.",
3957
+ confirmDeleteGroupTitle: "Elimina gruppo",
3958
+ confirmDeleteGroup: "Eliminare il gruppo {name}?",
3959
+ confirmDeleteGroupHint: "Questo gruppo contiene {count, plural, one {# blocco} other {# blocchi}}. Scegli se eliminarli o mantenerli nella pagina senza il gruppo.",
3960
+ keepGroupBlocks: "Rimuovi il gruppo, mantieni i blocchi",
3961
+ deleteGroupAndBlocks: "{count, plural, =0 {Elimina gruppo} one {Elimina gruppo e # blocco} other {Elimina gruppo e # blocchi}}",
3746
3962
  delete: "Elimina",
3747
3963
  selectBlocks: "Seleziona blocchi",
3748
3964
  selectAll: "Seleziona tutti",
@@ -3937,6 +4153,7 @@ var it_default = {
3937
4153
  gridCellMenu: "Altre azioni per {label}",
3938
4154
  removeFromGroup: "Rimuovi dal gruppo",
3939
4155
  gridAdd: "Aggiungi un blocco",
4156
+ groupAdd: "Aggiungi un blocco dentro {label}",
3940
4157
  gridShowList: "Mostra il gruppo {label} come elenco",
3941
4158
  gridShowGrid: "Mostra il gruppo {label} come griglia",
3942
4159
  layoutColumnsField: "Griglia di layout: campo delle colonne",
@@ -3967,7 +4184,7 @@ var it_default = {
3967
4184
  // admin/translations/nl.json
3968
4185
  var nl_default = {
3969
4186
  title: "Blockscene",
3970
- settings: "Galerij",
4187
+ settings: "Algemeen",
3971
4188
  gallery: "Blokkengalerij",
3972
4189
  search: "Blokken zoeken",
3973
4190
  clear: "Zoekopdracht wissen",
@@ -3983,6 +4200,17 @@ var nl_default = {
3983
4200
  moreActions: "Meer acties",
3984
4201
  settingsTitle: "Blockscene",
3985
4202
  settingsIntro: "Galerijminiaturen, wireframe-palet en editorvoorkeuren. Wijzigingen gelden bij de volgende opening van de galerij; geen rebuild nodig.",
4203
+ settingsGeneral: "Algemeen",
4204
+ settingsGeneralIntro: "Bepaal hoe Blockscene in de editor werkt en welke rijacties beschikbaar zijn.",
4205
+ settingsPreview: "Paginavoorbeeld",
4206
+ settingsPreviewIntro: "Koppel het frontendvoorbeeld en configureer modi, werkbalk en responsieve breedtes.",
4207
+ settingsContentTypes: "Contenttypes",
4208
+ settingsContentTypesIntro: "Kies waar Blockscene actief is en pas de visuele editor per contenttype aan.",
4209
+ settingsGallery: "Blokkengalerij",
4210
+ settingsGalleryIntro: "Configureer miniaturen, wireframekleuren, bloktypen en filters.",
4211
+ settingsHistory: "Geschiedenis en prullenbak",
4212
+ settingsHistoryIntro: "Beheer versies, activiteitsbewaring en herstelbare verwijderingen.",
4213
+ historyUnavailable: "Instellingen voor geschiedenis en prullenbak vereisen Strapi 5.",
3986
4214
  palette: "Wireframe-palet",
3987
4215
  background: "Achtergrond",
3988
4216
  surface: "Vlakken",
@@ -4012,6 +4240,7 @@ var nl_default = {
4012
4240
  showCloseAll: '"Alles inklappen" tonen',
4013
4241
  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.",
4014
4242
  showRowThumbnails: "Blokminiaturen in de rijen tonen",
4243
+ componentRowThumbnail: "Miniatuur in de editorrij tonen",
4015
4244
  initialState: "Beginstand van de accordeons",
4016
4245
  "states.closed": "Alle gesloten",
4017
4246
  "states.open": "Alle open",
@@ -4058,6 +4287,7 @@ var nl_default = {
4058
4287
  denied: "Toegang geweigerd.",
4059
4288
  loadFailed: "Instellingen konden niet worden geladen. Herlaad om opnieuw te proberen.",
4060
4289
  invalidColor: "Kleuren moeten #RRGGBB gebruiken.",
4290
+ invalidUrl: "Voorbeeld-URL's moeten volledige HTTP- of HTTPS-adressen zijn.",
4061
4291
  previewLabel: "Paletvoorbeeld",
4062
4292
  removeGroup: "Groep verwijderen",
4063
4293
  diagTitle: "Blokgroepen vragen aandacht; publiceren wordt geweigerd tot ze hersteld zijn:",
@@ -4092,6 +4322,7 @@ var nl_default = {
4092
4322
  contentTypes: "Contenttypes",
4093
4323
  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.',
4094
4324
  typeMode: "Opent in",
4325
+ typeAdvanced: "Opties voor de visuele editor",
4095
4326
  modeDefault: "Standaard ({mode})",
4096
4327
  blockModalDone: "Klaar",
4097
4328
  crashed: "Blockscene is hier gestopt door een fout. De native editor blijft werken. Gebeurt het opnieuw, zet Blockscene uit in Settings, Blockscene.",
@@ -4183,6 +4414,11 @@ var nl_default = {
4183
4414
  confirmDeleteTitle: "Blok verwijderen",
4184
4415
  confirmDelete: "Blok {name} verwijderen?",
4185
4416
  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.",
4417
+ confirmDeleteGroupTitle: "Groep verwijderen",
4418
+ confirmDeleteGroup: "Groep {name} verwijderen?",
4419
+ confirmDeleteGroupHint: "Deze groep bevat {count, plural, one {# blok} other {# blokken}}. Verwijder ze of behoud ze op de pagina zonder de groep.",
4420
+ keepGroupBlocks: "Groep verwijderen, blokken behouden",
4421
+ deleteGroupAndBlocks: "{count, plural, =0 {Groep verwijderen} one {Groep en # blok verwijderen} other {Groep en # blokken verwijderen}}",
4186
4422
  delete: "Verwijderen",
4187
4423
  selectBlocks: "Blokken selecteren",
4188
4424
  selectAll: "Alles selecteren",
@@ -4377,6 +4613,7 @@ var nl_default = {
4377
4613
  gridCellMenu: "Meer acties voor {label}",
4378
4614
  removeFromGroup: "Uit de groep halen",
4379
4615
  gridAdd: "Blok toevoegen",
4616
+ groupAdd: "Blok toevoegen binnen {label}",
4380
4617
  gridShowList: "Groep {label} als lijst tonen",
4381
4618
  gridShowGrid: "Groep {label} als raster tonen",
4382
4619
  layoutColumnsField: "Layoutraster: veld met kolommen",
@@ -4505,8 +4742,15 @@ function RowPreviews({ zones, components, catalog, Modal: Modal3 }) {
4505
4742
  const candidates = (uid) => candidatesFor(uid, catalog?.components?.[uid] || {}, catalog || {});
4506
4743
  const label = (uid) => catalog?.components?.[uid]?.label || components?.[uid]?.info?.displayName || uid;
4507
4744
  const srcOf = (uid) => candidates(uid)[resolved[uid] ?? -1] || "";
4745
+ const visible = anchors.filter(({ uid }) => showRowThumbnail(uid, catalog));
4508
4746
  React2.useEffect(() => {
4509
4747
  for (const { el, uid } of anchors) {
4748
+ if (!showRowThumbnail(uid, catalog)) {
4749
+ el.style.removeProperty("cursor");
4750
+ for (const name of ["role", "tabindex", "aria-label"])
4751
+ el.removeAttribute(name);
4752
+ continue;
4753
+ }
4510
4754
  if (srcOf(uid)) {
4511
4755
  el.setAttribute("role", "button");
4512
4756
  el.setAttribute("tabindex", "0");
@@ -4518,7 +4762,7 @@ function RowPreviews({ zones, components, catalog, Modal: Modal3 }) {
4518
4762
  }
4519
4763
  });
4520
4764
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4521
- anchors.map(
4765
+ visible.map(
4522
4766
  (a) => createPortal(
4523
4767
  /* @__PURE__ */ jsx2(
4524
4768
  "span",
@@ -4741,7 +4985,15 @@ function movedRow(prev, next, actor) {
4741
4985
  }
4742
4986
  function keepGroupsTogether(prev, next, groups, actor) {
4743
4987
  if (!groups) return null;
4744
- const move = movedRow(prev, next, actor);
4988
+ let move = movedRow(prev, next, actor);
4989
+ if (!move && actor == null) {
4990
+ const candidates = prev.flatMap((row) => {
4991
+ if (!(0, import_groups2.isOpener)(row, groups)) return [];
4992
+ const candidate = movedRow(prev, next, (0, import_groups2.blockKey)(row));
4993
+ return candidate && (0, import_groups2.isOpener)(prev[candidate.from], groups) ? [candidate] : [];
4994
+ });
4995
+ if (candidates.length === 1) move = candidates[0];
4996
+ }
4745
4997
  if (!move || !(0, import_groups2.isOpener)(prev[move.from], groups)) return null;
4746
4998
  const start = move.from, end = groupOutline(prev, groups)[start].end;
4747
4999
  if (end == null) return null;
@@ -5094,6 +5346,7 @@ var DEPTH = "data-blockscene-depth";
5094
5346
  var KIND = "data-blockscene-group";
5095
5347
  var FOLD = "data-blockscene-fold";
5096
5348
  var COUNT = "data-blockscene-fold-count";
5349
+ var INSERT = "data-blockscene-group-insert";
5097
5350
  var GRID_BOX = "data-blockscene-grid";
5098
5351
  var STEP = "2.4rem";
5099
5352
  var folded = /* @__PURE__ */ new Set();
@@ -5115,6 +5368,14 @@ var Count = styled3.span`
5115
5368
  margin-right: 4px; padding: 1px 6px; border-radius: 3px; font-size: 11px; font-weight: 600; line-height: 16px; white-space: nowrap;
5116
5369
  color: ${({ theme }) => theme.colors.primary700}; background: ${({ theme }) => theme.colors.primary100};
5117
5370
  `;
5371
+ var GroupInsert = styled3.button`
5372
+ display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; min-height: 42px; padding: 8px 12px;
5373
+ border: 1px dashed ${({ theme }) => theme.colors.primary600}; border-radius: 4px; cursor: pointer; font: inherit; font-size: 12px; font-weight: 600;
5374
+ color: ${({ theme }) => theme.colors.primary600}; background: ${({ theme }) => theme.colors.neutral0};
5375
+ &:hover:not(:disabled) { background: ${({ theme }) => theme.colors.primary100}; }
5376
+ &:disabled { opacity: 0.5; cursor: default; }
5377
+ &:focus-visible { outline: 2px solid ${({ theme }) => theme.colors.primary600}; outline-offset: 1px; }
5378
+ `;
5118
5379
  function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, components, catalog, openBlock, openInsert }) {
5119
5380
  const t = useMessages();
5120
5381
  const theme = useTheme();
@@ -5210,18 +5471,34 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5210
5471
  for (const index of unfold) for (const p of outline[index]?.parents || []) folded.delete(idOf(p));
5211
5472
  const isFolded = (i) => outline[i].end != null && folded.has(idOf(i));
5212
5473
  const grid = [];
5474
+ const anchorByOpen = /* @__PURE__ */ new Map();
5213
5475
  lis.forEach((li, i) => {
5214
5476
  const o = outline[i];
5215
5477
  seen.add(li);
5216
5478
  set(li, DEPTH, o.depth ? String(o.depth) : null);
5217
5479
  if (o.depth) li.style.setProperty("--bs-depth", String(o.depth));
5218
5480
  set(li, KIND, o.kind === "block" ? null : o.kind);
5219
- const inGrid = (o.kind === "close" ? o.parents.slice(0, -1) : o.parents).some((p) => grid[p]);
5481
+ const inGrid = o.parents.some((p) => grid[p]);
5220
5482
  const hidden = o.parents.some(isFolded) || inGrid;
5221
5483
  set(li, FOLDED, hidden ? "" : null);
5222
5484
  const layout = o.kind === "open" && o.end != null ? layouts2?.[rows[i].__component] || null : null;
5223
5485
  const toggle = li.querySelector("button[aria-expanded]");
5224
5486
  grid[i] = Boolean(layout && toggle?.parentElement) && !hidden && !isFolded(i) && !listed.has(idOf(i));
5487
+ if (o.kind === "close") {
5488
+ const open = o.parents[o.parents.length - 1];
5489
+ const anchor2 = anchorByOpen.get(open);
5490
+ if (anchor2 && !grid[open] && !hidden) {
5491
+ let insertEl = li.querySelector(`:scope > [${INSERT}]`);
5492
+ if (!insertEl) {
5493
+ insertEl = document.createElement("div");
5494
+ insertEl.setAttribute(INSERT, "");
5495
+ li.appendChild(insertEl);
5496
+ }
5497
+ anchor2.insertEl = insertEl;
5498
+ anchor2.after = blockKey(rows[Math.max(open, i - 1)]);
5499
+ }
5500
+ return;
5501
+ }
5225
5502
  if (o.kind !== "open" || o.end == null || !toggle?.parentElement) return;
5226
5503
  let gridEl = li.querySelector(`:scope > [${GRID_BOX}]`);
5227
5504
  if (grid[i] && !gridEl) {
@@ -5244,15 +5521,32 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5244
5521
  countEl.style.cssText = "display:inline-flex;align-items:center";
5245
5522
  actions.insertBefore(countEl, actions.firstChild);
5246
5523
  }
5247
- 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 });
5524
+ const anchor = {
5525
+ el,
5526
+ countEl,
5527
+ insertEl: null,
5528
+ after: null,
5529
+ full: Boolean(zone.full),
5530
+ zone: zone.name,
5531
+ index: i,
5532
+ id: idOf(i),
5533
+ count: o.count || 0,
5534
+ open: !isFolded(i),
5535
+ label: labelOf2(rows[i]),
5536
+ layout,
5537
+ gridEl
5538
+ };
5539
+ next.push(anchor);
5540
+ anchorByOpen.set(i, anchor);
5248
5541
  });
5249
5542
  }
5250
5543
  landed.current = null;
5251
5544
  for (const li of document.querySelectorAll(`li[${DEPTH}], li[${KIND}], li[${FOLDED}]`))
5252
5545
  if (!seen.has(li)) for (const name of [DEPTH, KIND, FOLDED]) li.removeAttribute(name);
5253
- 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();
5546
+ for (const el of document.querySelectorAll(`[${FOLD}], [${COUNT}], [${GRID_BOX}], [${INSERT}]`))
5547
+ if (!next.some((a) => a.el === el || a.countEl === el || a.gridEl === el || a.insertEl === el)) el.remove();
5254
5548
  setAnchors(
5255
- (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
5549
+ (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
5256
5550
  );
5257
5551
  };
5258
5552
  React4.useEffect(() => {
@@ -5270,7 +5564,7 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5270
5564
  return () => {
5271
5565
  observer.disconnect();
5272
5566
  cancelAnimationFrame(frame2);
5273
- for (const el of document.querySelectorAll(`[${FOLD}], [${COUNT}], [${GRID_BOX}]`)) el.remove();
5567
+ for (const el of document.querySelectorAll(`[${FOLD}], [${COUNT}], [${GRID_BOX}], [${INSERT}]`)) el.remove();
5274
5568
  for (const li of document.querySelectorAll(`li[${DEPTH}], li[${KIND}], li[${FOLDED}]`)) for (const name of [DEPTH, KIND, FOLDED]) li.removeAttribute(name);
5275
5569
  };
5276
5570
  }, []);
@@ -5287,10 +5581,8 @@ function GroupRows({ zones, form, groups, docKey, labelOf, layouts = null, compo
5287
5581
  ${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; }
5288
5582
  ${list2}[${FOLDED}]:not([data-bp-block-modal]) { display: none !important; }
5289
5583
  ${list2}[data-bp-block-modal] { padding-left: 0 !important; background-image: none !important; }
5290
- ${list2}[${KIND}="close"] [data-handler-id] { display: none !important; }
5291
- ${list2}[${KIND}="close"] button[aria-expanded]:first-of-type { min-height: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important; opacity: 0.7; }
5292
- ${list2}[${KIND}="close"] button[aria-expanded]:first-of-type + * { padding-top: 0 !important; padding-bottom: 0 !important; }
5293
- ${list2}[${KIND}="close"] button[aria-expanded] [data-blockscene-row-thumb] { display: none; }` }),
5584
+ ${list2}[${KIND}="close"] > *:not([${INSERT}]) { display: none !important; }
5585
+ ${list2}[${KIND}="close"] [${INSERT}] { display: block; padding: 8px 12px; }` }),
5294
5586
  anchors.map(
5295
5587
  (a) => createPortal2(
5296
5588
  /* @__PURE__ */ jsx5(
@@ -5344,7 +5636,27 @@ ${list2}[${KIND}="close"] button[aria-expanded] [data-blockscene-row-thumb] { di
5344
5636
  a.gridEl,
5345
5637
  `grid:${a.zone}:${a.index}`
5346
5638
  ) : null;
5347
- })
5639
+ }),
5640
+ anchors.map(
5641
+ (a) => a.insertEl ? createPortal2(
5642
+ /* @__PURE__ */ jsxs3(
5643
+ GroupInsert,
5644
+ {
5645
+ type: "button",
5646
+ disabled: a.full,
5647
+ title: a.full ? t.zoneFull : void 0,
5648
+ "data-testid": `group-add-${a.zone}-${a.index}`,
5649
+ onClick: () => openInsert?.(a.zone, a.after),
5650
+ children: [
5651
+ /* @__PURE__ */ jsx5(Icon, { name: "plus", size: 14 }),
5652
+ t.f("groupAdd", { label: a.label })
5653
+ ]
5654
+ }
5655
+ ),
5656
+ a.insertEl,
5657
+ `insert:${a.zone}:${a.index}`
5658
+ ) : null
5659
+ )
5348
5660
  ] });
5349
5661
  }
5350
5662
  function ViewToggle({ grid, testid, label, onFlip }) {
@@ -5547,9 +5859,33 @@ function useRowActions({ zones, components, catalog, form }) {
5547
5859
  if (hiddenName) form.setRows(zoneName, setHidden(rows, index, groups, hiddenName, rows[index]?.[hiddenName] !== true));
5548
5860
  };
5549
5861
  const paste = (zoneName, at) => pasteInto(form, zoneOf(zoneName), clip, components, groups, t, at);
5862
+ const changeGroup = (zoneName, key, keepBlocks) => {
5863
+ const rows = form.rows(zoneName);
5864
+ const next = keepBlocks ? (0, import_groups2.unwrapGroup)(rows, key, groups) : (0, import_groups2.removeGroup)(rows, key, groups);
5865
+ if (next) form.setRows(zoneName, next);
5866
+ };
5550
5867
  const pastable = (zoneName) => !["empty", "notAllowed"].includes(pasteProblem(clip, zoneOf(zoneName), form.rows(zoneName), components, groups)?.code);
5551
5868
  const selectable = (zoneName) => form.rows(zoneName).filter((row) => canAct(row, groups)).map((row) => blockKey(row)).filter(Boolean);
5552
- return { t, editor, groups, hiddenName, clip, selection, setSelection, busy, form, labelOf, duplicate, copy: copy2, toggleHidden, paste, pastable, selectable, isMarker: (row) => isGroupMarker(row, groups) };
5869
+ return {
5870
+ t,
5871
+ editor,
5872
+ groups,
5873
+ hiddenName,
5874
+ clip,
5875
+ selection,
5876
+ setSelection,
5877
+ busy,
5878
+ form,
5879
+ labelOf,
5880
+ duplicate,
5881
+ copy: copy2,
5882
+ toggleHidden,
5883
+ paste,
5884
+ pastable,
5885
+ selectable,
5886
+ changeGroup,
5887
+ isMarker: (row) => isGroupMarker(row, groups)
5888
+ };
5553
5889
  }
5554
5890
  var RowButton = styled4.button`
5555
5891
  display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: 0;
@@ -5573,7 +5909,7 @@ function RowActions({ zones, actions, Modal: Modal3 }) {
5573
5909
  const latest = React5.useRef({ zones, a });
5574
5910
  latest.current = { zones, a };
5575
5911
  React5.useEffect(() => {
5576
- if (!a || e.confirmDelete === false) return;
5912
+ if (!a) return;
5577
5913
  const onClick = (event) => {
5578
5914
  const button = event.target?.closest?.("button");
5579
5915
  if (!button || bypass.current) return;
@@ -5583,10 +5919,23 @@ function RowActions({ zones, actions, Modal: Modal3 }) {
5583
5919
  const headers = toggles(list2);
5584
5920
  const index = headers.findIndex((toggle) => trashOf(toggle) === button);
5585
5921
  if (index < 0) return;
5922
+ const row = latest.current.a?.form.rows(zone.name)[index];
5923
+ const marker2 = Boolean(latest.current.a?.isMarker(row));
5924
+ if (!marker2 && e.confirmDelete === false) return;
5586
5925
  event.preventDefault();
5587
5926
  event.stopPropagation();
5588
- const row = latest.current.a?.form.rows(zone.name)[index];
5589
- setConfirm({ button, label: headers[index].textContent?.trim() || latest.current.a?.labelOf(row), marker: Boolean(latest.current.a?.isMarker(row)) });
5927
+ if (marker2 && !canAct(row, latest.current.a?.groups)) return;
5928
+ const key = blockKey(row) || "";
5929
+ const rows = latest.current.a.form.rows(zone.name);
5930
+ const range = marker2 ? actionRange(rows, index, latest.current.a.groups) : [index, index];
5931
+ setConfirm({
5932
+ button,
5933
+ label: latest.current.a?.labelOf(row) || headers[index].textContent?.trim(),
5934
+ kind: marker2 ? "group" : "block",
5935
+ zone: zone.name,
5936
+ key,
5937
+ count: marker2 ? rows.slice(range[0] + 1, range[1]).filter((item) => canAct(item, latest.current.a.groups)).length : 0
5938
+ });
5590
5939
  return;
5591
5940
  }
5592
5941
  };
@@ -5614,6 +5963,11 @@ function RowActions({ zones, actions, Modal: Modal3 }) {
5614
5963
  bypass.current = false;
5615
5964
  }
5616
5965
  };
5966
+ const confirmGroup = (keepBlocks) => {
5967
+ const target = confirm;
5968
+ setConfirm(null);
5969
+ if (target?.kind === "group") a.changeGroup(target.zone, target.key, keepBlocks);
5970
+ };
5617
5971
  return /* @__PURE__ */ jsxs4(Fragment3, { children: [
5618
5972
  /* @__PURE__ */ jsx6("style", { children: `li[${HIDDEN_ATTR}] button[aria-expanded] { opacity: 0.5; }
5619
5973
  ol[aria-describedby] > li button[data-strapi-accordion-toggle] { overflow: hidden; }
@@ -5693,14 +6047,25 @@ ol[aria-describedby] > li button[data-strapi-accordion-toggle] > span:last-child
5693
6047
  `${zone}:${index}`
5694
6048
  );
5695
6049
  }),
5696
- confirm && /* @__PURE__ */ jsx6(Modal3, { open: true, width: "48rem", onOpenChange: (open) => !open && setConfirm(null), trigger: null, title: t.confirmDeleteTitle, children: /* @__PURE__ */ jsxs4(Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "row-confirm-delete", children: [
5697
- /* @__PURE__ */ jsx6(Typography, { children: t.f("confirmDelete", { name: confirm.label }) }),
5698
- confirm.marker && /* @__PURE__ */ jsx6(Typography, { variant: "pi", textColor: "neutral600", children: t.confirmDeleteMarker }),
5699
- /* @__PURE__ */ jsxs4(Flex, { gap: 2, justifyContent: "flex-end", children: [
5700
- /* @__PURE__ */ jsx6(Button, { variant: "tertiary", onClick: () => setConfirm(null), "data-testid": "row-confirm-cancel", children: t.cancel }),
5701
- /* @__PURE__ */ jsx6(Button, { variant: "danger", onClick: confirmDelete, "data-testid": "row-confirm-ok", children: t.delete })
5702
- ] })
5703
- ] }) })
6050
+ confirm && /* @__PURE__ */ jsx6(
6051
+ Modal3,
6052
+ {
6053
+ open: true,
6054
+ width: "48rem",
6055
+ onOpenChange: (open) => !open && setConfirm(null),
6056
+ trigger: null,
6057
+ title: confirm.kind === "group" ? t.confirmDeleteGroupTitle : t.confirmDeleteTitle,
6058
+ children: /* @__PURE__ */ jsxs4(Flex, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "row-confirm-delete", children: [
6059
+ /* @__PURE__ */ jsx6(Typography, { children: t.f(confirm.kind === "group" ? "confirmDeleteGroup" : "confirmDelete", { name: confirm.label, count: confirm.count }) }),
6060
+ confirm.kind === "group" && confirm.count > 0 && /* @__PURE__ */ jsx6(Typography, { variant: "pi", textColor: "neutral600", children: t.f("confirmDeleteGroupHint", { count: confirm.count }) }),
6061
+ /* @__PURE__ */ jsxs4(Flex, { gap: 2, justifyContent: "flex-end", children: [
6062
+ /* @__PURE__ */ jsx6(Button, { variant: "tertiary", onClick: () => setConfirm(null), "data-testid": "row-confirm-cancel", children: t.cancel }),
6063
+ confirm.kind === "group" && confirm.count > 0 && /* @__PURE__ */ jsx6(Button, { variant: "secondary", onClick: () => confirmGroup(true), "data-testid": "row-confirm-unwrap", children: t.keepGroupBlocks }),
6064
+ /* @__PURE__ */ jsx6(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 })
6065
+ ] })
6066
+ ] })
6067
+ }
6068
+ )
5704
6069
  ] });
5705
6070
  }
5706
6071
  function zoneMenuItems(zone, a) {
@@ -7043,6 +7408,12 @@ import { Box as Box4, Button as Button3, Flex as Flex3, MenuItem, SimpleMenu, Ty
7043
7408
  // admin/pane.mjs
7044
7409
  var TOOLBAR = ["modes", "history", "versions", "devices", "status", "actions"];
7045
7410
  var RIGHT = ["status", "actions"];
7411
+ function topNavigationInset(navs, viewportWidth) {
7412
+ return Math.round(Math.max(0, ...(Array.isArray(navs) ? navs : []).flatMap((nav) => {
7413
+ const rect = nav?.rect || {};
7414
+ 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)] : [];
7415
+ })));
7416
+ }
7046
7417
  function toolbarLayout(list2) {
7047
7418
  const ids = Array.isArray(list2) ? list2.filter((id, i) => TOOLBAR.includes(id) && list2.indexOf(id) === i) : TOOLBAR;
7048
7419
  const at = ids.findIndex((id) => RIGHT.includes(id));
@@ -7177,6 +7548,25 @@ function useMainRect() {
7177
7548
  }, []);
7178
7549
  return rect;
7179
7550
  }
7551
+ function useAdminTopInset() {
7552
+ const [inset, setInset] = React8.useState(0);
7553
+ React8.useLayoutEffect(() => {
7554
+ const navs = () => [...document.querySelectorAll("nav")];
7555
+ const measure = () => setInset(topNavigationInset(navs().map((nav) => ({
7556
+ position: getComputedStyle(nav).position,
7557
+ rect: nav.getBoundingClientRect()
7558
+ })), window.innerWidth));
7559
+ measure();
7560
+ const observer = "ResizeObserver" in window ? new ResizeObserver(measure) : null;
7561
+ navs().forEach((nav) => observer?.observe(nav));
7562
+ window.addEventListener("resize", measure);
7563
+ return () => {
7564
+ observer?.disconnect();
7565
+ window.removeEventListener("resize", measure);
7566
+ };
7567
+ }, []);
7568
+ return inset;
7569
+ }
7180
7570
  var Handle = styled6.div`
7181
7571
  position: absolute;
7182
7572
  top: 0;
@@ -7265,6 +7655,7 @@ body.bp-block-modal [data-bp-block-modal] { position: fixed !important; top: ${B
7265
7655
  background: ${background}; border-radius: 0 0 8px 8px; box-shadow: 0 8px 32px rgba(33, 33, 52, 0.3); }
7266
7656
  body.bp-block-modal [data-bp-block-modal]::before, body.bp-block-modal [data-bp-block-modal]::after { display: none !important; }
7267
7657
  body.bp-block-modal [data-bp-block-modal] > div { margin: 0 !important; padding-top: 0 !important; }
7658
+ body.bp-block-modal > div:has(> [role="listbox"]) { z-index: 1002 !important; }
7268
7659
  body.bp-block-modal [data-bp-modal-hide] { display: none !important; }`;
7269
7660
  var DRAWER_WIDTH = 640;
7270
7661
  var fieldsStyle = (background, drawer) => `
@@ -7273,6 +7664,7 @@ body.bp-fields [data-bp-show] { grid-column: 1 / -1 !important; }
7273
7664
  body.bp-fields [data-bp-flat] { border: 0 !important; box-shadow: none !important; padding: 0 !important; background: transparent !important; }
7274
7665
  body.bp-fields [data-bp-fields] { position: fixed !important; z-index: 1001; overflow: auto; margin: 0 !important;
7275
7666
  padding: 1.6rem 2.4rem; background: ${background}; box-shadow: 0 8px 32px rgba(33, 33, 52, 0.3); }
7667
+ body.bp-fields > div:has(> [role="listbox"]) { z-index: 1002 !important; }
7276
7668
  body.bp-fields [data-bp-fields="modal"] { top: ${BLOCK_TOP}; left: 50%; transform: translateX(-50%); width: min(96rem, 92vw);
7277
7669
  max-height: calc(88vh - 5.6rem); border-radius: 0 0 8px 8px; }
7278
7670
  ${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; }` : ""}`;
@@ -7513,6 +7905,7 @@ function PagePreview({
7513
7905
  return v > 0 && v < 1 ? v : 0.5;
7514
7906
  });
7515
7907
  const main = useMainRect();
7908
+ const topInset = useAdminTopInset();
7516
7909
  const vw = main.width;
7517
7910
  const [dragging, setDragging] = React8.useState(false);
7518
7911
  const [ready, setReady] = React8.useState(false);
@@ -7520,6 +7913,7 @@ function PagePreview({
7520
7913
  const [failed, setFailed] = React8.useState(false);
7521
7914
  const [attempt, retry] = React8.useReducer((n) => n + 1, 0);
7522
7915
  const [picking, setPicking] = React8.useState(null);
7916
+ const [deletingGroup, setDeletingGroup] = React8.useState(null);
7523
7917
  const [hovered, setHovered] = React8.useState(null);
7524
7918
  const [edge, setEdge] = React8.useState(null);
7525
7919
  const hoverRow = React8.useRef(null);
@@ -7565,6 +7959,8 @@ function PagePreview({
7565
7959
  const readOnly = Boolean(version);
7566
7960
  const viewRows = React8.useRef([]);
7567
7961
  viewRows.current = version ? version.values?.[zone] || [] : latest.current;
7962
+ const viewValues = React8.useRef({});
7963
+ viewValues.current = version ? version.values : values;
7568
7964
  const channel = React8.useMemo(() => crypto.randomUUID(), [host.model, host.documentId, host.locale, version?.scope, version?.event.id]);
7569
7965
  const { base, source } = state.preview;
7570
7966
  const url = base ? new URL(base) : null;
@@ -7604,6 +8000,21 @@ function PagePreview({
7604
8000
  protocol: PROTOCOL,
7605
8001
  channel,
7606
8002
  type: "update-page",
8003
+ entry: projectEntry(
8004
+ viewValues.current,
8005
+ host.contentType,
8006
+ live.current.components,
8007
+ window.location.origin,
8008
+ host.readable
8009
+ ),
8010
+ contentType: {
8011
+ uid: host.model,
8012
+ kind: host.contentType?.kind,
8013
+ singularName: host.contentType?.info?.singularName,
8014
+ pluralName: host.contentType?.info?.pluralName,
8015
+ displayName: host.contentType?.info?.displayName
8016
+ },
8017
+ zone,
7607
8018
  blocks: projectPage(
7608
8019
  viewRows.current,
7609
8020
  live.current.components,
@@ -7618,7 +8029,7 @@ function PagePreview({
7618
8029
  },
7619
8030
  origin
7620
8031
  );
7621
- }, [channel, origin, hiddenAttribute, groups]);
8032
+ }, [channel, origin, hiddenAttribute, groups, host.contentType, host.model, host.readable, zone]);
7622
8033
  React8.useEffect(() => {
7623
8034
  if (readOnly) {
7624
8035
  setInserting(null);
@@ -7833,12 +8244,17 @@ function PagePreview({
7833
8244
  return;
7834
8245
  }
7835
8246
  if (is("delete-group") && canEdit2 && groups) {
7836
- const next = (0, import_groups.removeGroup)(
7837
- latest.current,
7838
- String(event.data.key),
7839
- groups
7840
- );
7841
- if (next) onChange2(zone, next);
8247
+ const key2 = String(event.data.key);
8248
+ const start = latest.current.findIndex((row) => blockKey(row) === key2);
8249
+ if (start < 0) return;
8250
+ const [, end] = (0, import_groups.groupRange)(latest.current, start, groups);
8251
+ if (end <= start || latest.current[end]?.__component !== groups[latest.current[start]?.__component]) return;
8252
+ const closes = new Set(Object.values(groups));
8253
+ setDeletingGroup({
8254
+ key: key2,
8255
+ label: components?.[latest.current[start]?.__component]?.info?.displayName || latest.current[start]?.__component || "",
8256
+ count: latest.current.slice(start + 1, end).filter((row) => !closes.has(row?.__component)).length
8257
+ });
7842
8258
  return;
7843
8259
  }
7844
8260
  if (is("insert-group") && canEdit2 && groups) {
@@ -8022,6 +8438,12 @@ function PagePreview({
8022
8438
  applyWidth(map[event.key], true);
8023
8439
  }
8024
8440
  };
8441
+ const confirmGroupDelete = (keepBlocks) => {
8442
+ if (!deletingGroup || !zone) return;
8443
+ const next = keepBlocks ? (0, import_groups.unwrapGroup)(latest.current, deletingGroup.key, groups) : (0, import_groups.removeGroup)(latest.current, deletingGroup.key, groups);
8444
+ setDeletingGroup(null);
8445
+ if (next) onChange(zone, next);
8446
+ };
8025
8447
  return (
8026
8448
  // Hidden anchor in the side panels column: split mode and the sidebar items find the edit view's grid from here.
8027
8449
  /* @__PURE__ */ jsxs6("div", { ref: anchor, children: [
@@ -8032,6 +8454,7 @@ function PagePreview({
8032
8454
  "data-testid": "page-preview-pane",
8033
8455
  "aria-label": t.previewPane,
8034
8456
  style: {
8457
+ top: topInset,
8035
8458
  left: mode === "preview" || narrow ? main.left : main.left + main.width - paneWidth,
8036
8459
  width: mode === "preview" || narrow ? main.width : paneWidth,
8037
8460
  userSelect: dragging ? "none" : void 0
@@ -8193,6 +8616,15 @@ ${/* Strapi 4's scrolled header is fixed to the viewport's right edge: beside th
8193
8616
  ),
8194
8617
  document.body
8195
8618
  ),
8619
+ deletingGroup && /* @__PURE__ */ jsx9(Modal3, { open: true, width: "48rem", onOpenChange: (open) => !open && setDeletingGroup(null), trigger: null, title: t.confirmDeleteGroupTitle, children: /* @__PURE__ */ jsxs6(Flex3, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "preview-confirm-delete-group", children: [
8620
+ /* @__PURE__ */ jsx9(Typography4, { children: t.f("confirmDeleteGroup", { name: deletingGroup.label, count: deletingGroup.count }) }),
8621
+ deletingGroup.count > 0 && /* @__PURE__ */ jsx9(Typography4, { variant: "pi", textColor: "neutral600", children: t.f("confirmDeleteGroupHint", { count: deletingGroup.count }) }),
8622
+ /* @__PURE__ */ jsxs6(Flex3, { gap: 2, justifyContent: "flex-end", children: [
8623
+ /* @__PURE__ */ jsx9(Button3, { variant: "tertiary", onClick: () => setDeletingGroup(null), children: t.cancel }),
8624
+ deletingGroup.count > 0 && /* @__PURE__ */ jsx9(Button3, { variant: "secondary", onClick: () => confirmGroupDelete(true), children: t.keepGroupBlocks }),
8625
+ /* @__PURE__ */ jsx9(Button3, { variant: "danger", onClick: () => confirmGroupDelete(false), children: t.f("deleteGroupAndBlocks", { count: deletingGroup.count }) })
8626
+ ] })
8627
+ ] }) }),
8196
8628
  inserting && insertAttr && /* @__PURE__ */ jsx9(
8197
8629
  PickerModal,
8198
8630
  {
@@ -8396,11 +8828,15 @@ function usePreviewHost5() {
8396
8828
  const { toggleNotification } = useNotification();
8397
8829
  const components = useStrapiApp("BlockscenePagePreview", (state) => state.components);
8398
8830
  const fields = c.layout?.edit?.layout?.flat(3) || [];
8831
+ const layoutFields = React9.useMemo(
8832
+ () => new Set(fields.map((field) => field?.name).filter(Boolean)),
8833
+ [c.layout?.edit?.layout]
8834
+ );
8399
8835
  const latest = React9.useRef(values);
8400
8836
  latest.current = values;
8401
8837
  const readable = React9.useCallback(
8402
- (name) => c.isCreatingEntry || (rbac.canReadFields || []).includes(name),
8403
- [c.isCreatingEntry, rbac.canReadFields]
8838
+ (name) => fieldReadable(name, rbac.canReadFields, c.isCreatingEntry) || layoutFields.has(name.split(".")[0]),
8839
+ [c.isCreatingEntry, layoutFields, rbac.canReadFields]
8404
8840
  );
8405
8841
  return {
8406
8842
  ds: 2,
@@ -9075,6 +9511,27 @@ var Card2 = styled8.div`
9075
9511
  display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: 4px;
9076
9512
  border: 1px solid ${({ theme }) => theme.colors.neutral200}; background: ${({ theme }) => theme.colors.neutral0};
9077
9513
  `;
9514
+ var ContentTypeGrid = styled8.div`
9515
+ display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr)); gap: 16px; align-items: start;
9516
+ `;
9517
+ var ContentTypeCard = styled8.div`
9518
+ display: flex; flex-direction: column; gap: 16px; padding: 20px; border-radius: 4px;
9519
+ border: 1px solid ${({ theme }) => theme.colors.neutral200}; background: ${({ theme }) => theme.colors.neutral0};
9520
+ `;
9521
+ var ContentTypeTop = styled8.div`
9522
+ display: grid; grid-template-columns: minmax(0, 1fr) minmax(190px, 240px); gap: 16px; align-items: end;
9523
+ @media (max-width: 520px) { grid-template-columns: 1fr; }
9524
+ `;
9525
+ var Advanced = styled8.details`
9526
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral200}; padding-top: 12px;
9527
+ summary { cursor: pointer; color: ${({ theme }) => theme.colors.neutral800}; font-size: 13px; font-weight: 600; }
9528
+ summary::marker { color: ${({ theme }) => theme.colors.neutral500}; }
9529
+ &[open] summary { margin-bottom: 16px; }
9530
+ `;
9531
+ var ToolbarSection = styled8.div`
9532
+ display: flex; flex-direction: column; gap: 12px; margin-top: 16px; padding-top: 16px;
9533
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral200};
9534
+ `;
9078
9535
  var Bar = styled8.div`
9079
9536
  position: fixed; top: 0; z-index: 4; padding: 12px 32px;
9080
9537
  background: ${({ theme }) => theme.colors.neutral100}; border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};
@@ -9119,13 +9576,33 @@ function ColorField({ name, label, value, onChange, disabled }) {
9119
9576
  ] });
9120
9577
  }
9121
9578
  function TagsField({ name, label, hint, value, onChange, disabled }) {
9122
- const [text, setText] = React12.useState(value.join(", "));
9579
+ const external = value.join(", ");
9580
+ const input = React12.useRef(null);
9581
+ const focused = React12.useRef(false);
9582
+ const parse = (next) => [...new Set(next.split(",").map((tag) => tag.replace(/[<>]/g, "").trim().slice(0, 24)).filter(Boolean))].slice(0, 10);
9583
+ React12.useEffect(() => {
9584
+ if (!focused.current && input.current && input.current.value !== external) input.current.value = external;
9585
+ }, [external]);
9123
9586
  return /* @__PURE__ */ jsxs10(Label, { children: [
9124
9587
  /* @__PURE__ */ jsx13(Typography8, { variant: "pi", fontWeight: "bold", textColor: "neutral800", children: label }),
9125
- /* @__PURE__ */ jsx13("input", { name, value: text, disabled, onChange: (e) => {
9126
- setText(e.target.value);
9127
- onChange([...new Set(e.target.value.split(",").map((tag) => tag.replace(/[<>]/g, "").trim().slice(0, 24)).filter(Boolean))].slice(0, 10));
9128
- }, style: { padding: "6px 8px", border: "1px solid #dcdce4", borderRadius: 4, fontSize: 13 } }),
9588
+ /* @__PURE__ */ jsx13(
9589
+ "input",
9590
+ {
9591
+ ref: input,
9592
+ name,
9593
+ defaultValue: external,
9594
+ disabled,
9595
+ spellCheck: false,
9596
+ onFocus: () => {
9597
+ focused.current = true;
9598
+ },
9599
+ onBlur: (e) => {
9600
+ focused.current = false;
9601
+ onChange(parse(e.currentTarget.value));
9602
+ },
9603
+ style: { padding: "6px 8px", border: "1px solid #dcdce4", borderRadius: 4, fontSize: 13 }
9604
+ }
9605
+ ),
9129
9606
  /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: hint })
9130
9607
  ] });
9131
9608
  }
@@ -9286,10 +9763,9 @@ function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: Selec
9286
9763
  };
9287
9764
  const fields = (type.attributes || []).filter((attr) => !SYSTEM_FIELDS2.includes(attr.name));
9288
9765
  const id = (name, index) => `sidebar-${name}-${type.uid}${index === void 0 ? "" : `-${index}`}`;
9289
- return /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 3, paddingLeft: 4, "data-testid": `sidebar-editor-${type.uid}`, children: [
9290
- /* @__PURE__ */ jsx13(Typography8, { variant: "delta", tag: "h3", children: t.f("sidebarTitle", { name: type.displayName }) }),
9766
+ return /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 3, "data-testid": `sidebar-editor-${type.uid}`, children: [
9291
9767
  /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: t.sidebarHelp }),
9292
- /* @__PURE__ */ jsx13(Box7, { style: { maxWidth: 240 }, children: /* @__PURE__ */ jsx13(
9768
+ /* @__PURE__ */ jsx13(Box7, { children: /* @__PURE__ */ jsx13(
9293
9769
  SelectField2,
9294
9770
  {
9295
9771
  name: id("position"),
@@ -9365,7 +9841,7 @@ function SidebarEditor({ type, entry, set: set2, t, disabled, SelectField: Selec
9365
9841
  ] });
9366
9842
  }
9367
9843
  var permissions = { read: [{ action: "plugin::blockscene.settings.read", subject: null }], update: [{ action: "plugin::blockscene.settings.update", subject: null }] };
9368
- function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: MediaPicker2, ToggleField: ToggleField2, SelectField: SelectField2, TextField: TextField2, lazyEditors = false }) {
9844
+ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: MediaPicker2, ToggleField: ToggleField2, SelectField: SelectField2, TextField: TextField2, lazyEditors = false, section = "general" }) {
9369
9845
  const t = useMessages();
9370
9846
  const { get, put, del } = useClient();
9371
9847
  const { canRead, canUpdate, isLoading } = usePermissions2();
@@ -9383,7 +9859,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9383
9859
  React12.useEffect(() => {
9384
9860
  if (!canRead || isLoading) return;
9385
9861
  let active = true;
9386
- Promise.all([get("/blockscene/settings"), get("/blockscene/catalog")]).then(([s, c]) => {
9862
+ Promise.all([get("/blockscene/settings"), section === "gallery" ? get("/blockscene/catalog") : Promise.resolve({ data: {} })]).then(([s, c]) => {
9387
9863
  if (!active) return;
9388
9864
  setData(s.data);
9389
9865
  setSettings(s.data.settings);
@@ -9395,18 +9871,20 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9395
9871
  return () => {
9396
9872
  active = false;
9397
9873
  };
9398
- }, [get, canRead, isLoading]);
9874
+ }, [get, canRead, isLoading, section]);
9399
9875
  const update = (patch) => {
9400
9876
  setSettings((current) => patch(structuredClone(current)));
9401
9877
  setDirty(true);
9402
9878
  setStatus("");
9403
9879
  };
9404
- 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)));
9880
+ const badPalette = settings && Object.values(settings.palette).some((value) => !COLOR2.test(value));
9881
+ const badPreviewUrl = settings && [settings.editor.previewUrl, settings.editor.blockPreviewUrl].some((url) => url && !/^https?:\/\/\S+$/.test(url));
9405
9882
  const badSidebar = settings && Object.values(settings.contentTypes || {}).some((entry) => (entry.sidebar || []).some(badItem));
9406
9883
  const badLazy = settings && badUids(settings.editor.lazyFields);
9407
9884
  const badHistory = settings && data?.historyTypes && badRetention(settings.history);
9408
- const badPane = settings && [settings.editor, ...Object.values(settings.contentTypes || {})].some((entry) => entry.previewDevices && badDevices(entry.previewDevices));
9409
- const invalid = badColor || badSidebar || badLazy || badHistory || badPane;
9885
+ const badEditorPane = settings && settings.editor.previewDevices && badDevices(settings.editor.previewDevices);
9886
+ const badTypePane = settings && Object.values(settings.contentTypes || {}).some((entry) => entry.previewDevices && badDevices(entry.previewDevices));
9887
+ const invalid = section === "general" ? badLazy : section === "preview" ? badPreviewUrl || badEditorPane : section === "content-types" ? badSidebar || badTypePane : section === "gallery" ? badPalette : badHistory;
9410
9888
  const save = async () => {
9411
9889
  if (!settings || invalid || !canUpdate) return;
9412
9890
  setSaving(true);
@@ -9458,6 +9936,8 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9458
9936
  return index === 0 && manual ? t.manual : t.automatic;
9459
9937
  };
9460
9938
  const ready = !isLoading && canRead && !failed && settings && catalog;
9939
+ const sectionTitle = t[`settings${section === "content-types" ? "ContentTypes" : section[0].toUpperCase() + section.slice(1)}`];
9940
+ const sectionIntro = t[`settings${section === "content-types" ? "ContentTypes" : section[0].toUpperCase() + section.slice(1)}Intro`];
9461
9941
  const header = React12.useRef(null);
9462
9942
  const [floating, setFloating] = React12.useState(false);
9463
9943
  const main = useMainRect2(header);
@@ -9470,22 +9950,22 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9470
9950
  }, [ready]);
9471
9951
  const controls = (suffix) => ready && /* @__PURE__ */ jsxs10(Flex7, { gap: 3, alignItems: "center", wrap: "wrap", children: [
9472
9952
  /* @__PURE__ */ jsx13(Typography8, { role: "status", "aria-live": "polite", textColor: dirty ? "warning700" : "neutral600", "data-testid": `${dirty ? "unsaved-indicator" : "save-status"}${suffix}`, children: dirty ? t.unsaved : status || t.noChanges }),
9473
- !suffix && /* @__PURE__ */ jsx13(Button7, { variant: "tertiary", onClick: restore, disabled: !canUpdate || saving, "data-testid": "restore-blockscene-settings", children: data.projectDefaults ? t.restoreProject : t.resetAll }),
9953
+ !suffix && section === "general" && /* @__PURE__ */ jsx13(Button7, { variant: "tertiary", onClick: restore, disabled: !canUpdate || saving, "data-testid": "restore-blockscene-settings", children: data.projectDefaults ? t.restoreProject : t.resetAll }),
9474
9954
  /* @__PURE__ */ jsx13(Button7, { onClick: save, disabled: !canUpdate || invalid || !dirty, loading: saving, "data-testid": `save-blockscene-settings${suffix}`, children: t.save })
9475
9955
  ] });
9476
9956
  return /* @__PURE__ */ jsx13(Box7, { padding: 8, background: "neutral100", children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 5, children: [
9477
9957
  /* @__PURE__ */ jsx13("div", { ref: header, children: /* @__PURE__ */ jsxs10(Flex7, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
9478
- /* @__PURE__ */ jsx13(Typography8, { variant: "alpha", tag: "h1", children: t.settingsTitle }),
9958
+ /* @__PURE__ */ jsx13(Typography8, { variant: "alpha", tag: "h1", children: sectionTitle }),
9479
9959
  controls("")
9480
9960
  ] }) }),
9481
9961
  floating && main.width > 0 && /* @__PURE__ */ jsx13(Bar, { style: { left: main.left, width: main.width }, "data-testid": "settings-floating-bar", children: /* @__PURE__ */ jsxs10(Flex7, { gap: 4, alignItems: "center", justifyContent: "space-between", wrap: "wrap", children: [
9482
- /* @__PURE__ */ jsx13(Typography8, { variant: "beta", tag: "p", children: t.settingsTitle }),
9962
+ /* @__PURE__ */ jsx13(Typography8, { variant: "beta", tag: "p", children: sectionTitle }),
9483
9963
  controls("-floating")
9484
9964
  ] }) }),
9485
- /* @__PURE__ */ jsx13(Typography8, { textColor: "neutral600", children: t.settingsIntro }),
9965
+ /* @__PURE__ */ jsx13(Typography8, { textColor: "neutral600", children: sectionIntro }),
9486
9966
  isLoading ? /* @__PURE__ */ jsx13(Typography8, { children: "\u2026" }) : !canRead ? /* @__PURE__ */ jsx13(Typography8, { role: "alert", children: t.denied }) : failed ? /* @__PURE__ */ jsx13(Typography8, { role: "alert", children: t.loadFailed }) : !settings || !catalog ? /* @__PURE__ */ jsx13(Typography8, { children: t.loading }) : /* @__PURE__ */ jsxs10(Fragment11, { children: [
9487
9967
  data.disabled && /* @__PURE__ */ jsx13(Box7, { padding: 4, background: "warning100", hasRadius: true, children: /* @__PURE__ */ jsx13(Typography8, { role: "alert", textColor: "warning700", children: t.disabledByServer }) }),
9488
- /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, children: [
9968
+ section === "gallery" && /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, children: [
9489
9969
  /* @__PURE__ */ jsx13(Typography8, { variant: "beta", tag: "h2", children: t.palette }),
9490
9970
  /* @__PURE__ */ jsx13(Swatches, { children: Object.keys(DEFAULT_PALETTE).map((key) => /* @__PURE__ */ jsx13(
9491
9971
  ColorField,
@@ -9501,7 +9981,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9501
9981
  },
9502
9982
  key
9503
9983
  )) }),
9504
- badColor && /* @__PURE__ */ jsx13(Typography8, { role: "alert", textColor: "danger600", children: t.invalidColor }),
9984
+ badPalette && /* @__PURE__ */ jsx13(Typography8, { role: "alert", textColor: "danger600", children: t.invalidColor }),
9505
9985
  /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: t.previewLabel }),
9506
9986
  /* @__PURE__ */ jsx13(Swatches, { "data-testid": "palette-preview", children: TEMPLATES.map((template) => /* @__PURE__ */ jsxs10(Flex7, { direction: "column", gap: 1, children: [
9507
9987
  /* @__PURE__ */ jsx13(Box7, { style: { aspectRatio: "16 / 9", overflow: "hidden" }, hasRadius: true, children: /* @__PURE__ */ jsx13(Wireframe, { template, palette: settings.palette }) }),
@@ -9512,7 +9992,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9512
9992
  return s;
9513
9993
  }), children: t.resetPalette }) })
9514
9994
  ] }) }),
9515
- /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, children: [
9995
+ section === "general" && /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, children: [
9516
9996
  /* @__PURE__ */ jsx13(Typography8, { variant: "beta", tag: "h2", children: t.editor }),
9517
9997
  /* @__PURE__ */ jsx13(ToggleField2, { name: "editor-enabled", label: t.enabled, value: editor.enabled, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9518
9998
  s.editor.enabled = v;
@@ -9552,6 +10032,30 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9552
10032
  }
9553
10033
  ),
9554
10034
  /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: t.rememberHelp }),
10035
+ lazyEditors && /* @__PURE__ */ jsxs10(Fragment11, { children: [
10036
+ /* @__PURE__ */ jsx13(ToggleField2, { name: "editor-lazyEditors", label: t.lazyEditors, value: editor.lazyEditors !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
10037
+ s.editor.lazyEditors = v;
10038
+ return s;
10039
+ }) }),
10040
+ /* @__PURE__ */ jsx13(
10041
+ UidListField,
10042
+ {
10043
+ TextField: TextField2,
10044
+ name: "editor-lazyFields",
10045
+ label: t.lazyFields,
10046
+ value: editor.lazyFields || [],
10047
+ disabled: !canUpdate || saving || editor.lazyEditors === false,
10048
+ placeholder: "plugin::ckeditor5.CKEditor",
10049
+ onChange: (uids) => update((s) => {
10050
+ s.editor.lazyFields = uids;
10051
+ return s;
10052
+ })
10053
+ }
10054
+ ),
10055
+ /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: badLazy ? "danger600" : "neutral600", role: badLazy ? "alert" : void 0, children: badLazy ? t.f("lazyFieldsInvalid", { max: LAZY_MAX }) : t.lazyEditorsHelp })
10056
+ ] })
10057
+ ] }) }),
10058
+ section === "preview" && /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, children: [
9555
10059
  /* @__PURE__ */ jsx13(
9556
10060
  TextField2,
9557
10061
  {
@@ -9615,37 +10119,16 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9615
10119
  })
9616
10120
  }
9617
10121
  ),
9618
- lazyEditors && /* @__PURE__ */ jsxs10(Fragment11, { children: [
9619
- /* @__PURE__ */ jsx13(ToggleField2, { name: "editor-lazyEditors", label: t.lazyEditors, value: editor.lazyEditors !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9620
- s.editor.lazyEditors = v;
10122
+ badPreviewUrl && /* @__PURE__ */ jsx13(Typography8, { role: "alert", textColor: "danger600", children: t.invalidUrl }),
10123
+ lazyEditors && data.blockPreviewAvailable && /* @__PURE__ */ jsxs10(Fragment11, { children: [
10124
+ /* @__PURE__ */ jsx13(ToggleField2, { name: "editor-blockPreviewInForm", label: t.blockPreviewInForm, value: editor.blockPreviewInForm, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
10125
+ s.editor.blockPreviewInForm = v;
9621
10126
  return s;
9622
10127
  }) }),
9623
- /* @__PURE__ */ jsx13(
9624
- UidListField,
9625
- {
9626
- TextField: TextField2,
9627
- name: "editor-lazyFields",
9628
- label: t.lazyFields,
9629
- value: editor.lazyFields || [],
9630
- disabled: !canUpdate || saving || editor.lazyEditors === false,
9631
- placeholder: "plugin::ckeditor5.CKEditor",
9632
- onChange: (uids) => update((s) => {
9633
- s.editor.lazyFields = uids;
9634
- return s;
9635
- })
9636
- }
9637
- ),
9638
- /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: badLazy ? "danger600" : "neutral600", role: badLazy ? "alert" : void 0, children: badLazy ? t.f("lazyFieldsInvalid", { max: LAZY_MAX }) : t.lazyEditorsHelp }),
9639
- data.blockPreviewAvailable && /* @__PURE__ */ jsxs10(Fragment11, { children: [
9640
- /* @__PURE__ */ jsx13(ToggleField2, { name: "editor-blockPreviewInForm", label: t.blockPreviewInForm, value: editor.blockPreviewInForm, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9641
- s.editor.blockPreviewInForm = v;
9642
- return s;
9643
- }) }),
9644
- /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
9645
- ] })
10128
+ /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: t.blockPreviewInFormHelp })
9646
10129
  ] })
9647
10130
  ] }) }),
9648
- /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "row-actions-settings", children: [
10131
+ section === "general" && /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "row-actions-settings", children: [
9649
10132
  /* @__PURE__ */ jsx13(Typography8, { variant: "beta", tag: "h2", children: t.rowActionsTitle }),
9650
10133
  /* @__PURE__ */ jsx13(ToggleField2, { name: "editor-confirmDelete", label: t.confirmDeleteOption, value: editor.confirmDelete !== false, disabled: !canUpdate || saving, onChange: (v) => update((s) => {
9651
10134
  s.editor.confirmDelete = v;
@@ -9675,7 +10158,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9675
10158
  ),
9676
10159
  /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: data.hiddenAttribute ? t.hiddenBlocksHelp : t.hiddenAttributeOff })
9677
10160
  ] }) }),
9678
- data.historyTypes && settings.history && /* @__PURE__ */ jsx13(
10161
+ section === "history" && data.historyTypes && settings.history && /* @__PURE__ */ jsx13(
9679
10162
  HistorySettings,
9680
10163
  {
9681
10164
  types: data.historyTypes,
@@ -9690,10 +10173,10 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9690
10173
  })
9691
10174
  }
9692
10175
  ),
9693
- (data.contentTypes || []).length > 0 && /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "content-types", children: [
9694
- /* @__PURE__ */ jsx13(Typography8, { variant: "beta", tag: "h2", children: t.contentTypes }),
9695
- /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: t.contentTypesHelp }),
9696
- data.contentTypes.map((type) => {
10176
+ section === "history" && !data.historyTypes && /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsx13(Typography8, { textColor: "neutral600", children: t.historyUnavailable }) }),
10177
+ section === "content-types" && (data.contentTypes || []).length > 0 && /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, "data-testid": "content-types", children: [
10178
+ /* @__PURE__ */ jsx13(Box7, { padding: 4, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: t.contentTypesHelp }) }),
10179
+ /* @__PURE__ */ jsx13(ContentTypeGrid, { children: data.contentTypes.map((type) => {
9697
10180
  const entry = settings.contentTypes?.[type.uid] || {};
9698
10181
  const set2 = (key, value, fallback) => update((s) => {
9699
10182
  const next = { ...s.contentTypes?.[type.uid] || {} };
@@ -9704,9 +10187,10 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9704
10187
  else delete s.contentTypes[type.uid];
9705
10188
  return s;
9706
10189
  });
9707
- return /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, children: [
9708
- /* @__PURE__ */ jsxs10(Flex7, { gap: 6, alignItems: "flex-end", wrap: "wrap", "data-testid": `content-type-${type.uid}`, children: [
9709
- /* @__PURE__ */ jsx13(Box7, { style: { minWidth: 220 }, children: /* @__PURE__ */ jsx13(
10190
+ const customized = Boolean(entry.sidebar?.length || entry.sidebarPosition || entry.previewToolbar || entry.previewDevices);
10191
+ return /* @__PURE__ */ jsxs10(ContentTypeCard, { "data-testid": `content-type-${type.uid}`, children: [
10192
+ /* @__PURE__ */ jsxs10(ContentTypeTop, { children: [
10193
+ /* @__PURE__ */ jsx13(Box7, { children: /* @__PURE__ */ jsx13(
9710
10194
  ToggleField2,
9711
10195
  {
9712
10196
  name: `type-enabled-${type.uid}`,
@@ -9716,7 +10200,7 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9716
10200
  onChange: (v) => set2("enabled", v, true)
9717
10201
  }
9718
10202
  ) }),
9719
- /* @__PURE__ */ jsx13(Box7, { style: { minWidth: 240 }, children: /* @__PURE__ */ jsx13(
10203
+ /* @__PURE__ */ jsx13(Box7, { children: /* @__PURE__ */ jsx13(
9720
10204
  SelectField2,
9721
10205
  {
9722
10206
  name: `type-mode-${type.uid}`,
@@ -9728,46 +10212,51 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9728
10212
  }
9729
10213
  ) })
9730
10214
  ] }),
9731
- entry.enabled !== false && /* @__PURE__ */ jsx13(SidebarEditor, { type, entry, set: set2, t, disabled: !canUpdate || saving, SelectField: SelectField2, TextField: TextField2 }),
9732
- entry.enabled !== false && /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 3, paddingLeft: 4, children: [
9733
- /* @__PURE__ */ jsx13(
9734
- ToggleField2,
9735
- {
9736
- name: `type-pane-${type.uid}`,
9737
- label: t.f("paneTypeOverride", { name: type.displayName }),
9738
- value: Boolean(entry.previewToolbar || entry.previewDevices),
9739
- disabled: !canUpdate || saving,
9740
- onChange: (v) => {
9741
- set2("previewToolbar", v ? [...editor.previewToolbar || TOOLBAR2] : void 0, void 0);
9742
- set2("previewDevices", v ? structuredClone(editor.previewDevices || DEVICE_NAMES) : void 0, void 0);
10215
+ entry.enabled !== false && /* @__PURE__ */ jsxs10(Advanced, { defaultOpen: customized, children: [
10216
+ /* @__PURE__ */ jsx13("summary", { children: t.typeAdvanced }),
10217
+ /* @__PURE__ */ jsx13(SidebarEditor, { type, entry, set: set2, t, disabled: !canUpdate || saving, SelectField: SelectField2, TextField: TextField2 }),
10218
+ /* @__PURE__ */ jsxs10(ToolbarSection, { children: [
10219
+ /* @__PURE__ */ jsx13(
10220
+ ToggleField2,
10221
+ {
10222
+ name: `type-pane-${type.uid}`,
10223
+ label: t.f("paneTypeOverride", { name: type.displayName }),
10224
+ value: Boolean(entry.previewToolbar || entry.previewDevices),
10225
+ disabled: !canUpdate || saving,
10226
+ onChange: (v) => {
10227
+ set2("previewToolbar", v ? [...editor.previewToolbar || TOOLBAR2] : void 0, void 0);
10228
+ set2("previewDevices", v ? structuredClone(editor.previewDevices || DEVICE_NAMES) : void 0, void 0);
10229
+ }
9743
10230
  }
9744
- }
9745
- ),
9746
- (entry.previewToolbar || entry.previewDevices) && /* @__PURE__ */ jsx13(
9747
- PaneEditor,
9748
- {
9749
- id: `type-${type.uid}`,
9750
- versions: Boolean(data.historyTypes),
9751
- toolbar: entry.previewToolbar || editor.previewToolbar || TOOLBAR2,
9752
- devices: entry.previewDevices || editor.previewDevices || DEVICE_NAMES,
9753
- t,
9754
- disabled: !canUpdate || saving,
9755
- TextField: TextField2,
9756
- set: (key, value) => set2(key, value, void 0)
9757
- }
9758
- )
10231
+ ),
10232
+ (entry.previewToolbar || entry.previewDevices) && /* @__PURE__ */ jsx13(
10233
+ PaneEditor,
10234
+ {
10235
+ id: `type-${type.uid}`,
10236
+ versions: Boolean(data.historyTypes),
10237
+ toolbar: entry.previewToolbar || editor.previewToolbar || TOOLBAR2,
10238
+ devices: entry.previewDevices || editor.previewDevices || DEVICE_NAMES,
10239
+ t,
10240
+ disabled: !canUpdate || saving,
10241
+ TextField: TextField2,
10242
+ set: (key, value) => set2(key, value, void 0)
10243
+ }
10244
+ )
10245
+ ] })
9759
10246
  ] })
9760
10247
  ] }, type.uid);
9761
- }),
10248
+ }) }),
9762
10249
  badSidebar && /* @__PURE__ */ jsx13(Typography8, { role: "alert", textColor: "danger600", children: t.sidebarInvalidSave })
9763
- ] }) }),
9764
- /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, children: [
10250
+ ] }),
10251
+ section === "gallery" && /* @__PURE__ */ jsx13(Box7, { padding: 6, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsxs10(Flex7, { direction: "column", alignItems: "stretch", gap: 4, children: [
9765
10252
  /* @__PURE__ */ jsx13(Typography8, { variant: "beta", tag: "h2", children: t.components }),
9766
10253
  /* @__PURE__ */ jsx13(Searchbar2, { name: "component-filter", value: filter, placeholder: t.filter, clearLabel: t.clear, onClear: () => setFilter(""), onChange: (e) => setFilter(e.target.value), children: t.filter }),
9767
10254
  /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", "data-testid": "components-count", children: t.f("countAll", { count: components.length }) }),
9768
10255
  /* @__PURE__ */ jsx13(Grid2, { "data-testid": "components-grid", children: components.map((component) => {
9769
10256
  const entry = settings.components[component.uid] || {};
9770
10257
  const meta = { ...catalog.components?.[component.uid] || {}, ...media[component.uid] || {} };
10258
+ const groupMarker = Boolean(catalog.groups?.[component.uid] || Object.values(catalog.groups || {}).includes(component.uid));
10259
+ const rowThumbnail = entry.showRowThumbnail ?? !groupMarker;
9771
10260
  const candidates = candidatesFor(component.uid, meta, catalog);
9772
10261
  return /* @__PURE__ */ jsxs10(Card2, { "data-testid": `settings-${component.uid}`, children: [
9773
10262
  /* @__PURE__ */ jsx13(
@@ -9846,6 +10335,16 @@ function Settings({ useClient, usePermissions: usePermissions2, MediaPicker: Med
9846
10335
  onChange: (tags) => setComponent(component.uid, "tags", tags.length ? tags : void 0)
9847
10336
  }
9848
10337
  ),
10338
+ /* @__PURE__ */ jsx13(
10339
+ ToggleField2,
10340
+ {
10341
+ name: `row-thumbnail-${component.uid}`,
10342
+ label: t.componentRowThumbnail,
10343
+ value: rowThumbnail,
10344
+ disabled: !canUpdate || saving,
10345
+ onChange: (v) => setComponent(component.uid, "showRowThumbnail", v)
10346
+ }
10347
+ ),
9849
10348
  meta.variants?.length > 0 && /* @__PURE__ */ jsxs10(Typography8, { variant: "pi", textColor: "neutral600", "data-testid": `variants-${component.uid}`, children: [
9850
10349
  t.variantsFromCode,
9851
10350
  ": ",
@@ -9921,18 +10420,29 @@ function LayoutFields({ component, layout, set: set2, t, disabled, SelectField:
9921
10420
  /* @__PURE__ */ jsx13(Typography8, { variant: "pi", textColor: "neutral600", children: fields.length ? t.layoutHelp : t.layoutNoFields })
9922
10421
  ] });
9923
10422
  }
10423
+ var SETTINGS_SECTIONS = [
10424
+ { id: "general", label: "General" },
10425
+ { id: "preview", label: "Page preview" },
10426
+ { id: "content-types", label: "Content types" },
10427
+ { id: "gallery", label: "Block gallery" },
10428
+ { id: "history", label: "History & trash" }
10429
+ ];
9924
10430
  function register(app, Component2, to) {
9925
10431
  app.createSettingSection(
9926
10432
  { id: "blockscene", intlLabel: { id: "blockscene.title", defaultMessage: "Blockscene" } },
9927
- [{
9928
- id: "blockscene-settings",
9929
- to,
9930
- intlLabel: { id: "blockscene.settings", defaultMessage: "Gallery" },
9931
- // Module shape: older Strapi 4 (e.g. 4.11) only reads `.default` from the loader result.
9932
- // Not an `async` function: Strapi 5 warns on AsyncFunction loaders.
9933
- Component: () => Promise.resolve({ default: Component2 }),
9934
- permissions: permissions.read
9935
- }]
10433
+ SETTINGS_SECTIONS.map(({ id, label }) => {
10434
+ const Page2 = () => React12.createElement(Component2, { section: id });
10435
+ const sectionPath = id === "general" ? to : to.startsWith("/") ? `${to}-${id}` : `${to}/${id}`;
10436
+ return {
10437
+ id: `blockscene-${id}`,
10438
+ to: sectionPath,
10439
+ intlLabel: { id: `blockscene.settings${id === "content-types" ? "ContentTypes" : id[0].toUpperCase() + id.slice(1)}`, defaultMessage: label },
10440
+ // Module shape: older Strapi 4 (e.g. 4.11) only reads `.default` from the loader result.
10441
+ // Not an `async` function: Strapi 5 warns on AsyncFunction loaders.
10442
+ Component: () => Promise.resolve({ default: Page2 }),
10443
+ permissions: permissions.read
10444
+ };
10445
+ })
9936
10446
  );
9937
10447
  }
9938
10448
 
@@ -10879,7 +11389,7 @@ function usePermissions() {
10879
11389
  isLoading
10880
11390
  };
10881
11391
  }
10882
- var SettingsPage = () => /* @__PURE__ */ jsx18(Guard, { children: /* @__PURE__ */ jsx18(
11392
+ var SettingsPage = ({ section }) => /* @__PURE__ */ jsx18(Guard, { children: /* @__PURE__ */ jsx18(
10883
11393
  Settings,
10884
11394
  {
10885
11395
  useClient: useFetchClient3,
@@ -10888,7 +11398,8 @@ var SettingsPage = () => /* @__PURE__ */ jsx18(Guard, { children: /* @__PURE__ *
10888
11398
  ToggleField,
10889
11399
  SelectField,
10890
11400
  TextField,
10891
- lazyEditors: true
11401
+ lazyEditors: true,
11402
+ section
10892
11403
  }
10893
11404
  ) });
10894
11405
  var strapiApp = null;