@blokkli/editor 2.0.0-alpha.48 → 2.0.0-alpha.49

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.
Files changed (35) hide show
  1. package/dist/chunks/tailwindConfig.mjs +222 -0
  2. package/dist/global/types/definitions.d.ts +1 -1
  3. package/dist/module.d.mts +2 -2
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +143 -11
  6. package/dist/modules/agent/index.d.mts +1 -1
  7. package/dist/modules/agent/index.mjs +6 -29
  8. package/dist/modules/charts/index.d.mts +1 -1
  9. package/dist/modules/charts/index.mjs +3 -3
  10. package/dist/modules/charts/runtime/features/charts/Editor/index.d.vue.ts +1 -0
  11. package/dist/modules/charts/runtime/features/charts/Editor/index.vue +50 -53
  12. package/dist/modules/charts/runtime/features/charts/Editor/index.vue.d.ts +1 -0
  13. package/dist/modules/drupal/index.d.mts +1 -1
  14. package/dist/modules/drupal/index.mjs +1 -1
  15. package/dist/modules/index.d.mts +7 -0
  16. package/dist/{shared/editor.CGf7C_0M.mjs → modules/index.mjs} +1 -1
  17. package/dist/modules/table-of-contents/index.d.mts +1 -1
  18. package/dist/modules/table-of-contents/index.mjs +1 -1
  19. package/dist/modules/tailwind/index.d.mts +5 -0
  20. package/dist/modules/tailwind/index.mjs +2 -0
  21. package/dist/runtime/editor/components/NestedEditorOverlay/index.vue +4 -4
  22. package/dist/runtime/editor/features/add-list/index.vue +1 -1
  23. package/dist/runtime/editor/features/anchors/Overlay/index.vue +25 -7
  24. package/dist/runtime/editor/features/complex-options/index.vue +98 -0
  25. package/dist/runtime/editor/features/dragging-overlay/index.vue +29 -13
  26. package/dist/runtime/editor/translations/de.json +15 -15
  27. package/dist/runtime/editor/translations/fr.json +14 -14
  28. package/dist/runtime/editor/translations/gsw_CH.json +14 -14
  29. package/dist/runtime/editor/translations/it.json +14 -14
  30. package/dist/shared/{editor.BVregnEC.d.mts → editor.DsGJIlGn.d.mts} +19 -2
  31. package/dist/types.d.mts +1 -1
  32. package/package.json +36 -1
  33. package/dist/modules/charts/runtime/features/charts/index.vue +0 -72
  34. /package/dist/{modules/charts/runtime/features/charts → runtime/editor/features/complex-options}/index.d.vue.ts +0 -0
  35. /package/dist/{modules/charts/runtime/features/charts → runtime/editor/features/complex-options}/index.vue.d.ts +0 -0
@@ -11,15 +11,15 @@
11
11
  </button>
12
12
  </div>
13
13
 
14
- <ChartTypePicker v-model="data.type" />
14
+ <ChartTypePicker v-model="chartData.type" />
15
15
  </div>
16
16
 
17
17
  <ChartTypeOptions
18
18
  v-if="chartDef"
19
- v-model:title="data.title"
19
+ v-model:title="chartData.title"
20
20
  :options="chartDef.editor.options"
21
- :type-options="data.typeOptions || {}"
22
- @update:type-options="data.typeOptions = $event"
21
+ :type-options="chartData.typeOptions || {}"
22
+ @update:type-options="chartData.typeOptions = $event"
23
23
  />
24
24
  </div>
25
25
 
@@ -55,18 +55,18 @@
55
55
  <div class="bk-chart-editor-section">
56
56
  <label class="bk-form-label">{{ $t("chartsData", "Data") }}</label>
57
57
  <DataTable
58
- :categories="data.categories"
59
- :series="data.series"
60
- :category-colors="data.categoryColors"
58
+ :categories="chartData.categories"
59
+ :series="chartData.series"
60
+ :category-colors="chartData.categoryColors"
61
61
  :has-multiple-series="caps.hasMultipleSeries"
62
62
  :has-series-colors="caps.hasSeriesColors"
63
63
  :has-category-colors="caps.hasCategoryColors"
64
64
  :colors="COLORS"
65
65
  :remove-row="removeRow"
66
66
  :remove-series="removeSeries"
67
- @update:categories="data.categories = $event"
68
- @update:series="data.series = $event"
69
- @update:category-colors="data.categoryColors = $event"
67
+ @update:categories="chartData.categories = $event"
68
+ @update:series="chartData.series = $event"
69
+ @update:category-colors="chartData.categoryColors = $event"
70
70
  />
71
71
  <div class="bk-chart-data-table-actions">
72
72
  <button type="button" class="bk-button bk-is-small" @click="addRow">
@@ -88,8 +88,8 @@
88
88
 
89
89
  <div class="bk-chart-editor-section">
90
90
  <FootnoteEditor
91
- :footnotes="data.footnotes"
92
- @update:footnotes="data.footnotes = $event"
91
+ :footnotes="chartData.footnotes"
92
+ @update:footnotes="chartData.footnotes = $event"
93
93
  />
94
94
  </div>
95
95
  </div>
@@ -111,51 +111,48 @@ import Preview from "./Preview/index.vue";
111
111
  import ChartTypeOptions from "./ChartTypeOptions/index.vue";
112
112
  import { onBlokkliEvent } from "#blokkli/editor/composables";
113
113
  const props = defineProps({
114
+ data: { type: [Object, null], required: true },
114
115
  uuid: { type: String, required: true },
115
116
  optionKey: { type: String, required: true }
116
117
  });
117
- const { $t, state } = useBlokkli();
118
+ const { $t } = useBlokkli();
118
119
  function getCurrentData() {
119
- const rawData = state.mutatedOptions[props.uuid]?.data || state.getFieldListItem(props.uuid)?.options?.data;
120
- if (rawData) {
121
- try {
122
- const parsed = JSON.parse(rawData);
123
- if (parsed && Array.isArray(parsed.series) && parsed.series.length > 0) {
124
- const fallbackId = getFirstColorId(COLORS);
125
- for (const series of parsed.series) {
126
- if (!COLORS[series.color]) {
127
- series.color = fallbackId;
128
- }
120
+ if (props.data) {
121
+ const parsed = JSON.parse(JSON.stringify(props.data));
122
+ if (parsed && Array.isArray(parsed.series) && parsed.series.length > 0) {
123
+ const fallbackId = getFirstColorId(COLORS);
124
+ for (const series of parsed.series) {
125
+ if (!COLORS[series.color]) {
126
+ series.color = fallbackId;
129
127
  }
130
- if (Array.isArray(parsed.categoryColors)) {
131
- for (let i = 0; i < parsed.categoryColors.length; i++) {
132
- if (!COLORS[parsed.categoryColors[i]]) {
133
- parsed.categoryColors[i] = fallbackId;
134
- }
128
+ }
129
+ if (Array.isArray(parsed.categoryColors)) {
130
+ for (let i = 0; i < parsed.categoryColors.length; i++) {
131
+ if (!COLORS[parsed.categoryColors[i]]) {
132
+ parsed.categoryColors[i] = fallbackId;
135
133
  }
136
- } else {
137
- parsed.categoryColors = parsed.categories.map(
138
- (_, i) => {
139
- const ids = Object.keys(COLORS);
140
- return ids[i % ids.length] || fallbackId;
141
- }
142
- );
143
- }
144
- if (!Array.isArray(parsed.footnotes)) {
145
- parsed.footnotes = [];
146
- }
147
- if (!parsed.typeOptions || typeof parsed.typeOptions !== "object") {
148
- parsed.typeOptions = getDefaultTypeOptions(parsed.type);
149
134
  }
150
- return parsed;
135
+ } else {
136
+ parsed.categoryColors = parsed.categories.map(
137
+ (_, i) => {
138
+ const ids = Object.keys(COLORS);
139
+ return ids[i % ids.length] || fallbackId;
140
+ }
141
+ );
142
+ }
143
+ if (!Array.isArray(parsed.footnotes)) {
144
+ parsed.footnotes = [];
145
+ }
146
+ if (!parsed.typeOptions || typeof parsed.typeOptions !== "object") {
147
+ parsed.typeOptions = getDefaultTypeOptions(parsed.type);
151
148
  }
152
- } catch {
149
+ return parsed;
153
150
  }
154
151
  }
155
152
  return getDefaultChartData(COLORS);
156
153
  }
157
154
  const {
158
- data,
155
+ data: chartData,
159
156
  canUndo,
160
157
  canRedo,
161
158
  undo,
@@ -168,16 +165,16 @@ const {
168
165
  } = useChartEditorState(getCurrentData(), COLORS);
169
166
  const autoUpdate = ref(true);
170
167
  const previewData = ref(
171
- JSON.parse(JSON.stringify(data.value))
168
+ JSON.parse(JSON.stringify(chartData.value))
172
169
  );
173
170
  const isStale = ref(false);
174
171
  let debounceTimer = null;
175
172
  function refreshPreview() {
176
- previewData.value = JSON.parse(JSON.stringify(data.value));
173
+ previewData.value = JSON.parse(JSON.stringify(chartData.value));
177
174
  isStale.value = false;
178
175
  }
179
176
  watch(
180
- data,
177
+ chartData,
181
178
  () => {
182
179
  if (autoUpdate.value) {
183
180
  if (debounceTimer) clearTimeout(debounceTimer);
@@ -197,7 +194,7 @@ watch(autoUpdate, (enabled) => {
197
194
  onBeforeUnmount(() => {
198
195
  if (debounceTimer) clearTimeout(debounceTimer);
199
196
  });
200
- const chartDef = computed(() => getChartType(data.value.type, $t));
197
+ const chartDef = computed(() => getChartType(chartData.value.type, $t));
201
198
  const caps = computed(() => {
202
199
  const def = chartDef.value;
203
200
  return {
@@ -207,21 +204,21 @@ const caps = computed(() => {
207
204
  };
208
205
  });
209
206
  const typeOptionsCache = {
210
- ...data.value.typeOptions
207
+ ...chartData.value.typeOptions
211
208
  };
212
209
  watch(
213
- () => data.value.type,
210
+ () => chartData.value.type,
214
211
  (type) => {
215
212
  const defaults = getDefaultTypeOptions(type);
216
213
  const merged = {};
217
214
  for (const key of Object.keys(defaults)) {
218
215
  merged[key] = key in typeOptionsCache ? typeOptionsCache[key] : defaults[key];
219
216
  }
220
- data.value.typeOptions = merged;
217
+ chartData.value.typeOptions = merged;
221
218
  }
222
219
  );
223
220
  watch(
224
- () => data.value.typeOptions,
221
+ () => chartData.value.typeOptions,
225
222
  (opts) => {
226
223
  if (opts) {
227
224
  Object.assign(typeOptionsCache, opts);
@@ -230,7 +227,7 @@ watch(
230
227
  { deep: true }
231
228
  );
232
229
  function getData() {
233
- return data.value;
230
+ return chartData.value;
234
231
  }
235
232
  onBlokkliEvent("keyPressed", (e) => {
236
233
  if (e.code === "z" && e.meta) {
@@ -1,5 +1,6 @@
1
1
  import type { BlokkliChartData } from '../../../types.js';
2
2
  type __VLS_Props = {
3
+ data: BlokkliChartData | null;
3
4
  uuid: string;
4
5
  optionKey: string;
5
6
  };
@@ -1,4 +1,4 @@
1
- import { B as BlokkliModule } from '../../shared/editor.BVregnEC.mjs';
1
+ import { B as BlokkliModule } from '../../shared/editor.DsGJIlGn.mjs';
2
2
  import 'nuxt/schema';
3
3
  import 'consola';
4
4
  import '../../../dist/global/types/definitions.js';
@@ -2,7 +2,7 @@ import { createResolver } from '@nuxt/kit';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { join } from 'pathe';
4
4
  import { isObjectType, isInterfaceType } from 'graphql';
5
- import { d as defineBlokkliModule } from '../../shared/editor.CGf7C_0M.mjs';
5
+ import { defineBlokkliModule } from '../index.mjs';
6
6
  import { useGraphqlModuleContext } from 'nuxt-graphql-middleware/utils';
7
7
 
8
8
  function toPascalCase(text) {
@@ -0,0 +1,7 @@
1
+ export { b as Blokkli, B as BlokkliModule, d as defineBlokkliModule } from '../shared/editor.DsGJIlGn.mjs';
2
+ import 'nuxt/schema';
3
+ import 'consola';
4
+ import '../../dist/global/types/definitions.js';
5
+ import '../../dist/global/types/theme.js';
6
+ import '@nuxt/kit';
7
+ import '../../dist/global/types/features.js';
@@ -7,4 +7,4 @@ function defineBlokkliModule(init) {
7
7
  };
8
8
  }
9
9
 
10
- export { defineBlokkliModule as d };
10
+ export { defineBlokkliModule };
@@ -1,4 +1,4 @@
1
- import { B as BlokkliModule } from '../../shared/editor.BVregnEC.mjs';
1
+ import { B as BlokkliModule } from '../../shared/editor.DsGJIlGn.mjs';
2
2
  import 'nuxt/schema';
3
3
  import 'consola';
4
4
  import '../../../dist/global/types/definitions.js';
@@ -1,5 +1,5 @@
1
1
  import { createResolver, addComponent } from '@nuxt/kit';
2
- import { d as defineBlokkliModule } from '../../shared/editor.CGf7C_0M.mjs';
2
+ import { defineBlokkliModule } from '../index.mjs';
3
3
  import { fileURLToPath } from 'node:url';
4
4
 
5
5
  const index = defineBlokkliModule({
@@ -0,0 +1,5 @@
1
+ import { Config } from 'tailwindcss';
2
+
3
+ declare const tailwindConfig: Config;
4
+
5
+ export { tailwindConfig };
@@ -0,0 +1,2 @@
1
+ export { default as tailwindConfig } from '../../chunks/tailwindConfig.mjs';
2
+ import 'tailwindcss/plugin';
@@ -90,10 +90,10 @@ const backLabel = computed(() => {
90
90
  if (!entityLabel) {
91
91
  return $t("libraryItemEditOverlayBack", "Back to page");
92
92
  }
93
- return $t("libraryItemEditOverlayBackWithPage", 'Back to "@label"').replace(
94
- "@label",
95
- entityLabel
96
- );
93
+ return $t(
94
+ "libraryItemEditOverlayBackWithPage",
95
+ 'Save and go back to "@label"'
96
+ ).replace("@label", entityLabel);
97
97
  });
98
98
  const FADE_DURATION = 150;
99
99
  const EASING = "cubic-bezier(0.56, 0.04, 0.25, 1)";
@@ -118,7 +118,7 @@ defineDropHandler("new", {
118
118
  field.hostEntityBundle
119
119
  );
120
120
  const addBehaviour = definition?.editor?.addBehaviour || "form";
121
- if (definition?.editor?.disableEdit || addBehaviour === "no-form" || addBehaviour.startsWith("editable:") || !adapter.formFrameBuilder) {
121
+ if (definition?.editor?.disableEdit || addBehaviour === "no-form" || addBehaviour.startsWith("editable:") || addBehaviour.startsWith("complex-option:") || !adapter.formFrameBuilder) {
122
122
  await state.mutateWithLoadingState(
123
123
  () => adapter.addNewBlock({
124
124
  bundle: itemBundle,
@@ -11,16 +11,27 @@
11
11
  </template>
12
12
 
13
13
  <script setup>
14
- import { useBlokkli, useRoute, computed } from "#imports";
14
+ import { useBlokkli, useRoute, ref, onMounted } from "#imports";
15
15
  import { PluginBlockIndicator } from "#blokkli/editor/plugins";
16
16
  import { emitMessage } from "#blokkli/editor/events";
17
+ import { onBlokkliEvent } from "#blokkli/editor/composables";
17
18
  const route = useRoute();
18
- const { $t, adapter, dom } = useBlokkli();
19
- const items = computed(() => {
19
+ const { $t, adapter, ui } = useBlokkli();
20
+ function getAnchorItems() {
20
21
  const anchorItems = [];
21
- for (const entry of Object.entries(dom.registeredBlocks.value)) {
22
- const uuid = entry[0];
23
- const element = entry[1];
22
+ const nodes = [...ui.providerElement.querySelectorAll("[id]")];
23
+ for (const element of nodes) {
24
+ if (!(element instanceof HTMLElement)) {
25
+ continue;
26
+ }
27
+ const block = element.closest("[data-bk-uuid]");
28
+ if (!(block instanceof HTMLElement)) {
29
+ continue;
30
+ }
31
+ const uuid = block.dataset.bkUuid;
32
+ if (!uuid) {
33
+ continue;
34
+ }
24
35
  if (!element || !uuid) {
25
36
  continue;
26
37
  }
@@ -32,7 +43,8 @@ const items = computed(() => {
32
43
  }
33
44
  }
34
45
  return anchorItems;
35
- });
46
+ }
47
+ const items = ref([]);
36
48
  function getLinkForClipboard(item) {
37
49
  if (adapter.buildAnchorLink) {
38
50
  return adapter.buildAnchorLink(item.id, item.uuid);
@@ -50,4 +62,10 @@ function onClick(item) {
50
62
  emitMessage(message, "success", void 0, true);
51
63
  }
52
64
  }
65
+ onBlokkliEvent("state:reloaded", () => {
66
+ items.value = getAnchorItems();
67
+ });
68
+ onMounted(() => {
69
+ items.value = getAnchorItems();
70
+ });
53
71
  </script>
@@ -0,0 +1,98 @@
1
+ <template>
2
+ <NestedEditorOverlay
3
+ v-if="uuid"
4
+ :uuid
5
+ :title="config.editorTitle"
6
+ :icon="config.editorIcon"
7
+ theme="accent"
8
+ :element
9
+ @submit="onSubmit"
10
+ @close="onSubmit"
11
+ >
12
+ <component
13
+ :is="config.editorComponent"
14
+ ref="editorRef"
15
+ :data
16
+ :uuid
17
+ :option-key="optionKey"
18
+ />
19
+ </NestedEditorOverlay>
20
+ </template>
21
+
22
+ <script setup>
23
+ import { onBlokkliEvent } from "#blokkli/editor/composables";
24
+ import {
25
+ defineBlokkliFeature,
26
+ ref,
27
+ useTemplateRef,
28
+ useBlokkli,
29
+ computed
30
+ } from "#imports";
31
+ import { NestedEditorOverlay } from "#blokkli/editor/components";
32
+ import { COMPLEX_OPTION_TYPES } from "#blokkli-build/complex-option-types";
33
+ defineBlokkliFeature({
34
+ id: "complex-options",
35
+ icon: "bk_mdi_edit",
36
+ label: "Complex Options",
37
+ description: "Edit complex option types such as charts.",
38
+ requiredAdapterMethods: ["updateOptions"]
39
+ });
40
+ const { $t, state, adapter, dom, blocks } = useBlokkli();
41
+ const uuid = ref(null);
42
+ const optionKey = ref("");
43
+ const dataType = ref("");
44
+ const config = computed(() => {
45
+ if (!dataType.value) {
46
+ return null;
47
+ }
48
+ return COMPLEX_OPTION_TYPES[dataType.value];
49
+ });
50
+ const element = computed(() => {
51
+ if (!uuid.value) {
52
+ return null;
53
+ }
54
+ const block = blocks.getBlock(uuid.value);
55
+ if (!block) {
56
+ return null;
57
+ }
58
+ return dom.getDragElement(block);
59
+ });
60
+ const data = computed(() => {
61
+ if (!uuid.value || !optionKey.value) {
62
+ return null;
63
+ }
64
+ const rawData = state.mutatedOptions[uuid.value]?.[optionKey.value] || state.getFieldListItem(uuid.value)?.options?.[optionKey.value];
65
+ if (rawData) {
66
+ try {
67
+ return JSON.parse(rawData);
68
+ } catch {
69
+ return null;
70
+ }
71
+ }
72
+ return null;
73
+ });
74
+ const editorRef = useTemplateRef("editorRef");
75
+ async function onSubmit() {
76
+ if (!uuid.value || !editorRef.value) return;
77
+ const editorData = editorRef.value.getData();
78
+ await state.mutateWithLoadingState(
79
+ () => adapter.updateOptions([
80
+ {
81
+ uuid: uuid.value,
82
+ key: optionKey.value,
83
+ value: JSON.stringify(editorData)
84
+ }
85
+ ]),
86
+ $t("complexOptionsSaveError", "The data could not be saved.")
87
+ );
88
+ uuid.value = null;
89
+ }
90
+ onBlokkliEvent("option:edit-complex", (e) => {
91
+ if (!(e.dataType in COMPLEX_OPTION_TYPES)) {
92
+ return;
93
+ }
94
+ uuid.value = e.uuid;
95
+ optionKey.value = e.key;
96
+ dataType.value = e.dataType;
97
+ });
98
+ </script>
@@ -228,28 +228,44 @@ onBlokkliEvent("state:reloaded", async function() {
228
228
  }
229
229
  const allSelected = [...selection.uuids.value, newBlock.uuid];
230
230
  eventBus.emit("select", allSelected);
231
- if (!dropResult?.focusEditable) {
232
- return;
233
- }
234
231
  const definition = definitions.getBlockDefinition(
235
232
  newBlock.bundle,
236
233
  newBlock.fieldListType
237
234
  );
238
- if (!definition?.editor?.addBehaviour?.startsWith("editable:")) {
235
+ const addBehaviour = definition?.editor?.addBehaviour;
236
+ if (addBehaviour?.startsWith("complex-option:")) {
237
+ const optionKey = addBehaviour.split(":")[1];
238
+ if (!optionKey) {
239
+ return;
240
+ }
241
+ const option = definition?.options?.[optionKey];
242
+ if (option?.type !== "json" || !option.dataType) {
243
+ return;
244
+ }
245
+ eventBus.emit("option:edit-complex", {
246
+ uuid: newUuid,
247
+ key: optionKey,
248
+ dataType: option.dataType
249
+ });
239
250
  return;
240
251
  }
241
- const editableField = definition.editor.addBehaviour.split(":")[1];
242
- if (!editableField) {
252
+ if (!dropResult?.focusEditable) {
243
253
  return;
244
254
  }
245
- const editableFieldElement = directive.getEditablesForBlock(newUuid).find((v) => v.fieldName === editableField);
246
- if (!editableFieldElement) {
247
- return;
255
+ if (addBehaviour?.startsWith("editable:")) {
256
+ const editableField = addBehaviour.split(":")[1];
257
+ if (!editableField) {
258
+ return;
259
+ }
260
+ const editableFieldElement = directive.getEditablesForBlock(newUuid).find((v) => v.fieldName === editableField);
261
+ if (!editableFieldElement) {
262
+ return;
263
+ }
264
+ eventBus.emit("editable:open", {
265
+ fieldName: editableField,
266
+ uuid: newUuid
267
+ });
248
268
  }
249
- eventBus.emit("editable:open", {
250
- fieldName: editableField,
251
- uuid: newUuid
252
- });
253
269
  });
254
270
  onBlokkliEvent("dragging:move", (e) => {
255
271
  mouseX.value = e.x;
@@ -1267,10 +1267,6 @@
1267
1267
  "source": "Edit chart...",
1268
1268
  "translation": "Diagramm bearbeiten..."
1269
1269
  },
1270
- "chartsEditorSaveError": {
1271
- "source": "The chart could not be saved.",
1272
- "translation": "Das Diagramm konnte nicht gespeichert werden."
1273
- },
1274
1270
  "chartsEditorTitle": {
1275
1271
  "source": "Edit chart",
1276
1272
  "translation": "Diagramm bearbeiten"
@@ -1523,6 +1519,10 @@
1523
1519
  "source": "Shows all comments for the current page.",
1524
1520
  "translation": "Zeigt alle Kommentare auf der aktuellen Seite an."
1525
1521
  },
1522
+ "complexOptionsSaveError": {
1523
+ "source": "The data could not be saved.",
1524
+ "translation": ""
1525
+ },
1526
1526
  "conversionsConvertTo": {
1527
1527
  "source": "Convert to: @bundle",
1528
1528
  "translation": "Konvertieren zu: @bundle"
@@ -1636,7 +1636,7 @@
1636
1636
  "translation": "Dieser Blocktyp ist in diesem Feld nicht erlaubt."
1637
1637
  },
1638
1638
  "edit": {
1639
- "source": "Edit...",
1639
+ "source": "Edit",
1640
1640
  "translation": "Bearbeiten..."
1641
1641
  },
1642
1642
  "editDisabledByDefinition": {
@@ -1851,14 +1851,6 @@
1851
1851
  "source": "Changelog",
1852
1852
  "translation": "Änderungsprotokoll"
1853
1853
  },
1854
- "feature_charts_description": {
1855
- "source": "Add and edit interactive charts.",
1856
- "translation": "Interaktive Diagramme hinzufügen und bearbeiten."
1857
- },
1858
- "feature_charts_label": {
1859
- "source": "Charts",
1860
- "translation": "Diagramme"
1861
- },
1862
1854
  "feature_clipboard_description": {
1863
1855
  "source": "Provides clipboard integration to copy/paste existing blocks or paste supported clipboard content like text or images.",
1864
1856
  "translation": "Stellt Zwischenablage-Integration bereit zum Kopieren/Einfügen von bestehenden Blöcken oder zum Einfügen von unterstützten Inhalten wie Text oder Bildern."
@@ -1883,6 +1875,14 @@
1883
1875
  "source": "Comments",
1884
1876
  "translation": "Kommentare"
1885
1877
  },
1878
+ "feature_complex-options_description": {
1879
+ "source": "Edit complex option types such as charts.",
1880
+ "translation": ""
1881
+ },
1882
+ "feature_complex-options_label": {
1883
+ "source": "Complex Options",
1884
+ "translation": ""
1885
+ },
1886
1886
  "feature_conversions_description": {
1887
1887
  "source": "Provides block actions to convert one or more blocks to a different bundle.",
1888
1888
  "translation": "Stellt Block-Aktionen bereit, um einen oder mehrere Blöcke in einen anderen Typ zu konvertieren."
@@ -2468,8 +2468,8 @@
2468
2468
  "translation": "Zurück zur Seite"
2469
2469
  },
2470
2470
  "libraryItemEditOverlayBackWithPage": {
2471
- "source": "Back to \"@label\"",
2472
- "translation": "Zurück zu «@label»"
2471
+ "source": "Save and go back to \"@label\"",
2472
+ "translation": "Speichern und zurück zu «@label»"
2473
2473
  },
2474
2474
  "libraryItemEditOverlayTitle": {
2475
2475
  "source": "Edit reusable block",
@@ -1267,10 +1267,6 @@
1267
1267
  "source": "Edit chart...",
1268
1268
  "translation": ""
1269
1269
  },
1270
- "chartsEditorSaveError": {
1271
- "source": "The chart could not be saved.",
1272
- "translation": ""
1273
- },
1274
1270
  "chartsEditorTitle": {
1275
1271
  "source": "Edit chart",
1276
1272
  "translation": ""
@@ -1523,6 +1519,10 @@
1523
1519
  "source": "Shows all comments for the current page.",
1524
1520
  "translation": ""
1525
1521
  },
1522
+ "complexOptionsSaveError": {
1523
+ "source": "The data could not be saved.",
1524
+ "translation": ""
1525
+ },
1526
1526
  "conversionsConvertTo": {
1527
1527
  "source": "Convert to: @bundle",
1528
1528
  "translation": ""
@@ -1636,7 +1636,7 @@
1636
1636
  "translation": ""
1637
1637
  },
1638
1638
  "edit": {
1639
- "source": "Edit...",
1639
+ "source": "Edit",
1640
1640
  "translation": "Modifier"
1641
1641
  },
1642
1642
  "editDisabledByDefinition": {
@@ -1851,14 +1851,6 @@
1851
1851
  "source": "Changelog",
1852
1852
  "translation": ""
1853
1853
  },
1854
- "feature_charts_description": {
1855
- "source": "Add and edit interactive charts.",
1856
- "translation": ""
1857
- },
1858
- "feature_charts_label": {
1859
- "source": "Charts",
1860
- "translation": ""
1861
- },
1862
1854
  "feature_clipboard_description": {
1863
1855
  "source": "Provides clipboard integration to copy/paste existing blocks or paste supported clipboard content like text or images.",
1864
1856
  "translation": "Fournit l'intégration du presse-papiers pour copier/coller des blocs existants ou coller du contenu pris en charge comme du texte ou des images."
@@ -1883,6 +1875,14 @@
1883
1875
  "source": "Comments",
1884
1876
  "translation": "Commentaires"
1885
1877
  },
1878
+ "feature_complex-options_description": {
1879
+ "source": "Edit complex option types such as charts.",
1880
+ "translation": ""
1881
+ },
1882
+ "feature_complex-options_label": {
1883
+ "source": "Complex Options",
1884
+ "translation": ""
1885
+ },
1886
1886
  "feature_conversions_description": {
1887
1887
  "source": "Provides block actions to convert one or more blocks to a different bundle.",
1888
1888
  "translation": "Fournit des actions de bloc pour convertir un ou plusieurs blocs vers un type différent."
@@ -2468,7 +2468,7 @@
2468
2468
  "translation": ""
2469
2469
  },
2470
2470
  "libraryItemEditOverlayBackWithPage": {
2471
- "source": "Back to \"@label\"",
2471
+ "source": "Save and go back to \"@label\"",
2472
2472
  "translation": ""
2473
2473
  },
2474
2474
  "libraryItemEditOverlayTitle": {