@blokkli/editor 2.0.0-alpha.49 → 2.0.0-alpha.50
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/module.json +1 -1
- package/dist/module.mjs +2 -1
- package/dist/modules/agent/runtime/app/features/agent/types.d.ts +0 -4
- package/dist/modules/agent/runtime/app/tools/add_paragraphs/index.js +29 -10
- package/dist/modules/agent/runtime/app/tools/get_bundle_info/index.js +7 -2
- package/dist/modules/agent/runtime/app/tools/get_paragraph_context/index.js +1 -1
- package/dist/modules/agent/runtime/app/tools/get_paragraph_options/index.js +1 -1
- package/dist/modules/agent/runtime/app/tools/set_paragraph_options/index.js +1 -1
- package/dist/modules/agent/runtime/app/tools/swap_paragraphs/index.js +9 -48
- package/dist/modules/charts/runtime/blokkli/tools/chart_schemas.js +1 -1
- package/dist/modules/charts/runtime/blokkli/tools/get_chart_data/index.js +1 -1
- package/dist/modules/charts/runtime/blokkli/tools/update_chart/index.js +1 -1
- package/dist/runtime/editor/components/EditProvider.vue +2 -1
- package/dist/runtime/editor/components/ItemIcon/index.vue +1 -1
- package/dist/runtime/editor/composables/useEditableFieldOverride.js +7 -2
- package/dist/runtime/editor/features/changelog/changelog.json +9 -1
- package/dist/runtime/editor/features/dragging-overlay/index.vue +2 -1
- package/dist/runtime/editor/features/edit/index.vue +35 -19
- package/dist/runtime/editor/features/swap/index.d.vue.ts +3 -0
- package/dist/runtime/editor/features/swap/index.vue +57 -0
- package/dist/runtime/editor/features/swap/index.vue.d.ts +3 -0
- package/dist/runtime/editor/features/swap/types.d.ts +8 -0
- package/dist/runtime/editor/features/swap/types.js +0 -0
- package/dist/runtime/editor/helpers/swap.d.ts +13 -0
- package/dist/runtime/editor/helpers/swap.js +31 -0
- package/dist/runtime/editor/plugins/ItemAction/index.d.vue.ts +6 -0
- package/dist/runtime/editor/plugins/ItemAction/index.vue +2 -0
- package/dist/runtime/editor/plugins/ItemAction/index.vue.d.ts +6 -0
- package/dist/runtime/editor/providers/definition.d.ts +1 -1
- package/dist/runtime/editor/providers/fieldValue.d.ts +2 -1
- package/dist/runtime/editor/providers/fieldValue.js +7 -2
- package/dist/runtime/editor/translations/de.json +21 -1
- package/dist/runtime/editor/translations/fr.json +21 -1
- package/dist/runtime/editor/translations/gsw_CH.json +21 -1
- package/dist/runtime/editor/translations/it.json +21 -1
- package/package.json +12 -12
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -18,7 +18,7 @@ import 'typescript';
|
|
|
18
18
|
import 'oxc-walker';
|
|
19
19
|
|
|
20
20
|
const name = "@blokkli/editor";
|
|
21
|
-
const version = "2.0.0-alpha.
|
|
21
|
+
const version = "2.0.0-alpha.50";
|
|
22
22
|
|
|
23
23
|
function validateOption(optionKey, option, icons) {
|
|
24
24
|
const errors = [];
|
|
@@ -1554,6 +1554,7 @@ const USED_MATERIAL_ICONS = [
|
|
|
1554
1554
|
"bk_mdi_stream",
|
|
1555
1555
|
"bk_mdi_swap_horiz",
|
|
1556
1556
|
"bk_mdi_swap_horizontal_circle",
|
|
1557
|
+
"bk_mdi_swap_vert",
|
|
1557
1558
|
"bk_mdi_text_compare",
|
|
1558
1559
|
"bk_mdi_text_select_end",
|
|
1559
1560
|
"bk_mdi_texture",
|
|
@@ -18,10 +18,6 @@ declare module '#blokkli/editor/types/permissions' {
|
|
|
18
18
|
}
|
|
19
19
|
declare module '#blokkli/editor/adapter' {
|
|
20
20
|
interface BlokkliAdapter<T> {
|
|
21
|
-
/**
|
|
22
|
-
* Swap two blocks.
|
|
23
|
-
*/
|
|
24
|
-
swapBlocks?: (first: string, second: string) => Promise<MutationResponseLike<T>>;
|
|
25
21
|
/**
|
|
26
22
|
* Rearrange blocks within a field by specifying the desired order.
|
|
27
23
|
*
|
|
@@ -78,10 +78,14 @@ function validateContentFields(ctx, block, path) {
|
|
|
78
78
|
}
|
|
79
79
|
return void 0;
|
|
80
80
|
}
|
|
81
|
-
function validateBlockOptions(ctx, block, path) {
|
|
81
|
+
function validateBlockOptions(ctx, block, path, parentBundle) {
|
|
82
82
|
if (!block.options) return void 0;
|
|
83
83
|
const { definitions } = ctx.app;
|
|
84
|
-
const definition = definitions.getBlockDefinition(
|
|
84
|
+
const definition = definitions.getBlockDefinition(
|
|
85
|
+
block.bundle,
|
|
86
|
+
"default",
|
|
87
|
+
parentBundle
|
|
88
|
+
);
|
|
85
89
|
if (!definition) {
|
|
86
90
|
return `${path}: Paragraph definition not found for bundle "${block.bundle}".`;
|
|
87
91
|
}
|
|
@@ -103,7 +107,7 @@ function validateBlockOptions(ctx, block, path) {
|
|
|
103
107
|
}
|
|
104
108
|
return void 0;
|
|
105
109
|
}
|
|
106
|
-
function validateBlockTree(ctx, blocks, allowedBundles, fieldLabel, pathPrefix) {
|
|
110
|
+
function validateBlockTree(ctx, blocks, allowedBundles, fieldLabel, pathPrefix, parentBundle) {
|
|
107
111
|
const { types } = ctx.app;
|
|
108
112
|
for (let i = 0; i < blocks.length; i++) {
|
|
109
113
|
const block = blocks[i];
|
|
@@ -120,7 +124,7 @@ function validateBlockTree(ctx, blocks, allowedBundles, fieldLabel, pathPrefix)
|
|
|
120
124
|
}
|
|
121
125
|
const contentError = validateContentFields(ctx, block, path);
|
|
122
126
|
if (contentError) return contentError;
|
|
123
|
-
const optionsError = validateBlockOptions(ctx, block, path);
|
|
127
|
+
const optionsError = validateBlockOptions(ctx, block, path, parentBundle);
|
|
124
128
|
if (optionsError) return optionsError;
|
|
125
129
|
if (block.children) {
|
|
126
130
|
for (const [childFieldName, childBlocks] of Object.entries(
|
|
@@ -141,7 +145,8 @@ function validateBlockTree(ctx, blocks, allowedBundles, fieldLabel, pathPrefix)
|
|
|
141
145
|
childBlocks,
|
|
142
146
|
childFieldConfig.allowedBundles,
|
|
143
147
|
childFieldName,
|
|
144
|
-
`${path} > ${childFieldName} >
|
|
148
|
+
`${path} > ${childFieldName} > `,
|
|
149
|
+
block.bundle
|
|
145
150
|
);
|
|
146
151
|
if (childError) return childError;
|
|
147
152
|
}
|
|
@@ -149,7 +154,7 @@ function validateBlockTree(ctx, blocks, allowedBundles, fieldLabel, pathPrefix)
|
|
|
149
154
|
}
|
|
150
155
|
return void 0;
|
|
151
156
|
}
|
|
152
|
-
function buildEventBlocks(ctx, blocks) {
|
|
157
|
+
function buildEventBlocks(ctx, blocks, parentBundle) {
|
|
153
158
|
const { definitions } = ctx.app;
|
|
154
159
|
return blocks.map((block) => {
|
|
155
160
|
const blockUuid = generateUUID();
|
|
@@ -159,7 +164,11 @@ function buildEventBlocks(ctx, blocks) {
|
|
|
159
164
|
})) : void 0;
|
|
160
165
|
let options;
|
|
161
166
|
if (block.options) {
|
|
162
|
-
const definition = definitions.getBlockDefinition(
|
|
167
|
+
const definition = definitions.getBlockDefinition(
|
|
168
|
+
block.bundle,
|
|
169
|
+
"default",
|
|
170
|
+
parentBundle
|
|
171
|
+
);
|
|
163
172
|
if (definition) {
|
|
164
173
|
const availableOptions = getAvailableOptions(
|
|
165
174
|
definition.options,
|
|
@@ -180,7 +189,11 @@ function buildEventBlocks(ctx, blocks) {
|
|
|
180
189
|
children = {};
|
|
181
190
|
for (const [fieldName, childBlocks] of Object.entries(block.children)) {
|
|
182
191
|
if (childBlocks.length) {
|
|
183
|
-
children[fieldName] = buildEventBlocks(
|
|
192
|
+
children[fieldName] = buildEventBlocks(
|
|
193
|
+
ctx,
|
|
194
|
+
childBlocks,
|
|
195
|
+
block.bundle
|
|
196
|
+
);
|
|
184
197
|
}
|
|
185
198
|
}
|
|
186
199
|
}
|
|
@@ -253,17 +266,23 @@ export default defineBlokkliAgentTool({
|
|
|
253
266
|
};
|
|
254
267
|
}
|
|
255
268
|
}
|
|
269
|
+
const topLevelParentBundle = isRootEntity ? null : bundle;
|
|
256
270
|
const validationError = validateBlockTree(
|
|
257
271
|
ctx,
|
|
258
272
|
params.paragraphs,
|
|
259
273
|
field.allowedBundles,
|
|
260
274
|
params.parent.field,
|
|
261
|
-
""
|
|
275
|
+
"",
|
|
276
|
+
topLevelParentBundle
|
|
262
277
|
);
|
|
263
278
|
if (validationError) {
|
|
264
279
|
return { error: validationError };
|
|
265
280
|
}
|
|
266
|
-
const eventBlocks = buildEventBlocks(
|
|
281
|
+
const eventBlocks = buildEventBlocks(
|
|
282
|
+
ctx,
|
|
283
|
+
params.paragraphs,
|
|
284
|
+
topLevelParentBundle
|
|
285
|
+
);
|
|
267
286
|
const totalCount = countBlocks(eventBlocks);
|
|
268
287
|
const blockUuids = collectAllUuids(eventBlocks);
|
|
269
288
|
const { $t } = ctx.app;
|
|
@@ -58,7 +58,7 @@ export default defineBlokkliAgentTool({
|
|
|
58
58
|
paramsSchema,
|
|
59
59
|
resultSchema,
|
|
60
60
|
execute(ctx, params) {
|
|
61
|
-
const { fields, types, state, definitions, $t } = ctx.app;
|
|
61
|
+
const { fields, types, state, definitions, $t, context, blocks } = ctx.app;
|
|
62
62
|
const label = $t(
|
|
63
63
|
"aiAgentGetBundleInfoDone",
|
|
64
64
|
"Got bundle info for @field"
|
|
@@ -79,6 +79,7 @@ export default defineBlokkliAgentTool({
|
|
|
79
79
|
const currentCount = state.getFieldBlockCount(fieldKey);
|
|
80
80
|
const allowedBundles = params.bundles ? field.allowedBundles.filter((b) => params.bundles.includes(b)) : field.allowedBundles;
|
|
81
81
|
const includeOptions = allowedBundles.length < 3;
|
|
82
|
+
const parentBundle = params.parentUuid === context.value.entityUuid ? null : blocks.getBlock(params.parentUuid)?.bundle ?? null;
|
|
82
83
|
const bundles = allowedBundles.map((bundle) => {
|
|
83
84
|
const bundleDefinition = types.getBlockBundleDefinition(bundle);
|
|
84
85
|
const contentFields = {};
|
|
@@ -106,7 +107,11 @@ export default defineBlokkliAgentTool({
|
|
|
106
107
|
}
|
|
107
108
|
let options;
|
|
108
109
|
if (includeOptions) {
|
|
109
|
-
const definition = definitions.getBlockDefinition(
|
|
110
|
+
const definition = definitions.getBlockDefinition(
|
|
111
|
+
bundle,
|
|
112
|
+
"default",
|
|
113
|
+
parentBundle
|
|
114
|
+
);
|
|
110
115
|
if (definition) {
|
|
111
116
|
const availableOptions = getAvailableOptions(
|
|
112
117
|
definition.options,
|
|
@@ -241,7 +241,7 @@ export default defineBlokkliAgentTool({
|
|
|
241
241
|
const definition = definitions.getBlockDefinition(
|
|
242
242
|
block.bundle,
|
|
243
243
|
selectionItem?.fieldListType ?? "default",
|
|
244
|
-
selectionItem?.parentBlockBundle
|
|
244
|
+
selectionItem?.parentBlockBundle ?? null
|
|
245
245
|
);
|
|
246
246
|
if (definition) {
|
|
247
247
|
const availableOptions = getAvailableOptions(
|
|
@@ -35,7 +35,7 @@ export default defineBlokkliAgentTool({
|
|
|
35
35
|
const definition = definitions.getBlockDefinition(
|
|
36
36
|
bundle,
|
|
37
37
|
selectionItem?.fieldListType ?? "default",
|
|
38
|
-
selectionItem?.parentBlockBundle
|
|
38
|
+
selectionItem?.parentBlockBundle ?? null
|
|
39
39
|
);
|
|
40
40
|
if (!definition) continue;
|
|
41
41
|
const availableOptions = getAvailableOptions(
|
|
@@ -60,7 +60,7 @@ export default defineBlokkliAgentTool({
|
|
|
60
60
|
const definition = definitions.getBlockDefinition(
|
|
61
61
|
bundle,
|
|
62
62
|
selectionItem?.fieldListType ?? "default",
|
|
63
|
-
selectionItem?.parentBlockBundle
|
|
63
|
+
selectionItem?.parentBlockBundle ?? null
|
|
64
64
|
);
|
|
65
65
|
if (!definition) {
|
|
66
66
|
return {
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { defineBlokkliAgentTool } from "#blokkli/agent/app/composables";
|
|
3
3
|
import { mutationResultSchema } from "../schemas.js";
|
|
4
|
-
import {
|
|
5
|
-
requireBundlePermission,
|
|
6
|
-
requireNoRestrictedAncestor
|
|
7
|
-
} from "../../helpers/validation.js";
|
|
4
|
+
import { getSwapDisabledReason } from "#blokkli/editor/helpers/swap";
|
|
8
5
|
const paramsSchema = z.object({
|
|
9
6
|
uuidA: z.string().describe("First paragraph UUID"),
|
|
10
7
|
uuidB: z.string().describe("Second paragraph UUID")
|
|
@@ -23,10 +20,7 @@ export default defineBlokkliAgentTool({
|
|
|
23
20
|
resultSchema: mutationResultSchema,
|
|
24
21
|
requiredAdapterMethods: ["swapBlocks"],
|
|
25
22
|
execute(ctx, params) {
|
|
26
|
-
const { blocks, types, $t } = ctx.app;
|
|
27
|
-
if (params.uuidA === params.uuidB) {
|
|
28
|
-
return { error: "Both UUIDs refer to the same paragraph" };
|
|
29
|
-
}
|
|
23
|
+
const { blocks, types, $t, permissions } = ctx.app;
|
|
30
24
|
const blockA = blocks.getBlock(params.uuidA);
|
|
31
25
|
if (!blockA) {
|
|
32
26
|
return { error: `Paragraph not found: ${params.uuidA}` };
|
|
@@ -35,46 +29,13 @@ export default defineBlokkliAgentTool({
|
|
|
35
29
|
if (!blockB) {
|
|
36
30
|
return { error: `Paragraph not found: ${params.uuidB}` };
|
|
37
31
|
}
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
);
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
params.uuidA,
|
|
46
|
-
params.uuidB
|
|
47
|
-
]);
|
|
48
|
-
if (ancestorDenied) return ancestorDenied;
|
|
49
|
-
const fieldConfigA = types.getFieldConfig(
|
|
50
|
-
blockA.host.type,
|
|
51
|
-
blockA.host.bundle,
|
|
52
|
-
blockA.host.fieldName
|
|
53
|
-
);
|
|
54
|
-
if (!fieldConfigA) {
|
|
55
|
-
return {
|
|
56
|
-
error: `Could not find field config for paragraph A's parent field`
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
const fieldConfigB = types.getFieldConfig(
|
|
60
|
-
blockB.host.type,
|
|
61
|
-
blockB.host.bundle,
|
|
62
|
-
blockB.host.fieldName
|
|
63
|
-
);
|
|
64
|
-
if (!fieldConfigB) {
|
|
65
|
-
return {
|
|
66
|
-
error: `Could not find field config for paragraph B's parent field`
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
if (!fieldConfigB.allowedBundles.includes(blockA.bundle)) {
|
|
70
|
-
return {
|
|
71
|
-
error: `Cannot swap: bundle "${blockA.bundle}" (uuid: ${params.uuidA}) is not allowed in field "${blockB.host.fieldName}" (parent: ${blockB.host.uuid}). Allowed bundles: ${fieldConfigB.allowedBundles.join(", ")}`
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
if (!fieldConfigA.allowedBundles.includes(blockB.bundle)) {
|
|
75
|
-
return {
|
|
76
|
-
error: `Cannot swap: bundle "${blockB.bundle}" (uuid: ${params.uuidB}) is not allowed in field "${blockA.host.fieldName}" (parent: ${blockA.host.uuid}). Allowed bundles: ${fieldConfigA.allowedBundles.join(", ")}`
|
|
77
|
-
};
|
|
32
|
+
const reason = getSwapDisabledReason(blockA, blockB, {
|
|
33
|
+
getFieldConfig: types.getFieldConfig,
|
|
34
|
+
checkBlockBundlePermission: permissions.checkBlockBundlePermission,
|
|
35
|
+
blockHasRestrictedAncestor: permissions.blockHasRestrictedAncestor
|
|
36
|
+
});
|
|
37
|
+
if (reason) {
|
|
38
|
+
return { error: reason };
|
|
78
39
|
}
|
|
79
40
|
const labelA = types.getBlockLabel(blockA.bundle);
|
|
80
41
|
const labelB = types.getBlockLabel(blockB.bundle);
|
|
@@ -105,7 +105,7 @@ export function findChartOptionKey(ctx, uuid) {
|
|
|
105
105
|
const definition = definitions.getBlockDefinition(
|
|
106
106
|
bundle,
|
|
107
107
|
selectionItem?.fieldListType ?? "default",
|
|
108
|
-
selectionItem?.parentBlockBundle
|
|
108
|
+
selectionItem?.parentBlockBundle ?? null
|
|
109
109
|
);
|
|
110
110
|
if (!definition?.options) {
|
|
111
111
|
return { error: `Paragraph "${uuid}" (${bundle}) has no chart option.` };
|
|
@@ -38,7 +38,7 @@ export default defineBlokkliAgentTool({
|
|
|
38
38
|
const chartOption = findChartOptionKey(ctx, params.uuid);
|
|
39
39
|
if ("error" in chartOption) return chartOption;
|
|
40
40
|
const item = state.getFieldListItem(params.uuid);
|
|
41
|
-
const rawData = item?.options?.[chartOption.key];
|
|
41
|
+
const rawData = state.mutatedOptions[params.uuid]?.[chartOption.key] || item?.options?.[chartOption.key];
|
|
42
42
|
let data;
|
|
43
43
|
if (rawData) {
|
|
44
44
|
try {
|
|
@@ -47,7 +47,7 @@ export default defineBlokkliAgentTool({
|
|
|
47
47
|
if ("error" in chartOption) return chartOption;
|
|
48
48
|
let current;
|
|
49
49
|
const item = state.getFieldListItem(params.uuid);
|
|
50
|
-
const rawData = item?.options?.[chartOption.key];
|
|
50
|
+
const rawData = state.mutatedOptions[params.uuid]?.[chartOption.key] || item?.options?.[chartOption.key];
|
|
51
51
|
if (rawData) {
|
|
52
52
|
try {
|
|
53
53
|
current = JSON.parse(rawData);
|
|
@@ -24,7 +24,7 @@ const iconName = computed(() => {
|
|
|
24
24
|
if (props.bundle === fromLibraryBlockBundle) {
|
|
25
25
|
return "reusable";
|
|
26
26
|
} else if (props.bundle) {
|
|
27
|
-
const name = definitions.getBlockDefinition(props.bundle, "default")?.editor?.icon;
|
|
27
|
+
const name = definitions.getBlockDefinition(props.bundle, "default", null)?.editor?.icon;
|
|
28
28
|
if (name) {
|
|
29
29
|
return name;
|
|
30
30
|
}
|
|
@@ -12,7 +12,7 @@ const NOOP_OVERRIDE = {
|
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
14
|
export function useEditableFieldOverride(fieldName, host) {
|
|
15
|
-
const { eventBus, state, types, definitions, directive, fieldValue } = useBlokkli();
|
|
15
|
+
const { eventBus, state, types, definitions, directive, fieldValue, blocks } = useBlokkli();
|
|
16
16
|
const el = directive.findEditableElement(fieldName, host);
|
|
17
17
|
if (!el) {
|
|
18
18
|
return NOOP_OVERRIDE;
|
|
@@ -42,7 +42,12 @@ export function useEditableFieldOverride(fieldName, host) {
|
|
|
42
42
|
);
|
|
43
43
|
let matchingProp = null;
|
|
44
44
|
if (host.type === itemEntityType) {
|
|
45
|
-
const
|
|
45
|
+
const block = blocks.getBlock(host.uuid);
|
|
46
|
+
const defintion = definitions.getBlockDefinition(
|
|
47
|
+
host.bundle,
|
|
48
|
+
block?.fieldListType ?? "default",
|
|
49
|
+
block?.parentBlockBundle ?? null
|
|
50
|
+
);
|
|
46
51
|
if (defintion?.propsFieldMapping) {
|
|
47
52
|
matchingProp = findMatchingProp(defintion.propsFieldMapping);
|
|
48
53
|
}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "2.0.0-alpha.50",
|
|
4
|
+
"date": "2026-03-24",
|
|
5
|
+
"body": {
|
|
6
|
+
"en": "<h3>New Features</h3>\n<h4>Swap block positions</h4>\n<p>Select two blocks and use the new "Swap block positions" action to exchange\ntheir positions. This works across different fields, as long as both block types\nare allowed in each other's field.</p>\n<h3>Improvements</h3>\n<ul>\n<li>Blocks with an editor option (e.g. chart data) now show the edit button even\nwhen regular editing is disabled. Clicking it opens the option editor directly.</li>\n</ul>\n",
|
|
7
|
+
"de": "<h3>Neue Funktionen</h3>\n<h4>Blockpositionen tauschen</h4>\n<p>Zwei Blöcke auswählen und über die neue Aktion «Blockpositionen tauschen» ihre\nPositionen vertauschen. Dies funktioniert auch feldübergreifend, sofern beide\nBlocktypen im jeweiligen Feld erlaubt sind.</p>\n<h3>Verbesserungen</h3>\n<ul>\n<li>Blöcke mit einer Option mit Editor (z.B. Diagrammdaten) zeigen jetzt den\nBearbeiten-Button an, auch wenn die reguläre Bearbeitung deaktiviert ist. Ein\nKlick öffnet direkt den Options-Editor.</li>\n</ul>\n"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
2
10
|
{
|
|
3
11
|
"version": "2.0.0-alpha.48",
|
|
4
12
|
"date": "2026-03-20",
|
|
5
13
|
"body": {
|
|
6
14
|
"en": "<h3>Improvements</h3>\n<ul>\n<li>The media library filters now use custom dropdown selects with keyboard\nnavigation and a search field for long lists, replacing the native browser\nselects.</li>\n</ul>\n",
|
|
7
|
-
"de": "<h3>Verbesserungen</h3>\n<ul>\n<li>Die Filter in der Medienbibliothek verwenden jetzt eigene
|
|
15
|
+
"de": "<h3>Verbesserungen</h3>\n<ul>\n<li>Die Filter in der Medienbibliothek verwenden jetzt eigene Dropdowns mit\nTastaturnavigation und einem Suchfeld bei langen Listen.</li>\n</ul>\n"
|
|
8
16
|
}
|
|
9
17
|
},
|
|
10
18
|
{
|
|
@@ -230,7 +230,8 @@ onBlokkliEvent("state:reloaded", async function() {
|
|
|
230
230
|
eventBus.emit("select", allSelected);
|
|
231
231
|
const definition = definitions.getBlockDefinition(
|
|
232
232
|
newBlock.bundle,
|
|
233
|
-
newBlock.fieldListType
|
|
233
|
+
newBlock.fieldListType,
|
|
234
|
+
newBlock.parentBlockBundle
|
|
234
235
|
);
|
|
235
236
|
const addBehaviour = definition?.editor?.addBehaviour;
|
|
236
237
|
if (addBehaviour?.startsWith("complex-option:")) {
|
|
@@ -29,6 +29,24 @@ const { eventBus, selection, state, $t, adapter, definitions, permissions } = us
|
|
|
29
29
|
const userCanEditLibraryItems = computed(
|
|
30
30
|
() => permissions.hasPermission("edit_library_item")
|
|
31
31
|
);
|
|
32
|
+
function getComplexOption(item) {
|
|
33
|
+
const definition = definitions.getBlockDefinition(
|
|
34
|
+
item.bundle,
|
|
35
|
+
item.fieldListType,
|
|
36
|
+
item.parentBlockBundle
|
|
37
|
+
);
|
|
38
|
+
if (!definition?.options) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const keys = Object.keys(definition.options);
|
|
42
|
+
for (let i = 0; i < keys.length; i++) {
|
|
43
|
+
const key = keys[i];
|
|
44
|
+
if (!key) continue;
|
|
45
|
+
const option = definition.options[key];
|
|
46
|
+
if (option?.type !== "json" || !option.dataType) continue;
|
|
47
|
+
return { key, dataType: option.dataType };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
32
50
|
function isFragment(item) {
|
|
33
51
|
return item.bundle === fragmentBlockBundle;
|
|
34
52
|
}
|
|
@@ -48,7 +66,7 @@ const editDisabledReason = computed(() => {
|
|
|
48
66
|
item.fieldListType,
|
|
49
67
|
item.parentBlockBundle
|
|
50
68
|
);
|
|
51
|
-
if (definition?.editor?.disableEdit) {
|
|
69
|
+
if (definition?.editor?.disableEdit && !getComplexOption(item)) {
|
|
52
70
|
return $t(
|
|
53
71
|
"editDisabledByDefinition",
|
|
54
72
|
"Editing is disabled for this block type."
|
|
@@ -107,32 +125,30 @@ function onClick(items) {
|
|
|
107
125
|
}
|
|
108
126
|
return;
|
|
109
127
|
}
|
|
128
|
+
const complexOption = getComplexOption(item);
|
|
129
|
+
if (complexOption) {
|
|
130
|
+
eventBus.emit("option:edit-complex", {
|
|
131
|
+
uuid: item.uuid,
|
|
132
|
+
key: complexOption.key,
|
|
133
|
+
dataType: complexOption.dataType
|
|
134
|
+
});
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
110
137
|
eventBus.emit("item:edit", {
|
|
111
138
|
uuid: item.uuid,
|
|
112
139
|
bundle: item.bundle
|
|
113
140
|
});
|
|
114
141
|
}
|
|
115
142
|
onBlokkliEvent("item:doubleClick", function(block) {
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
143
|
+
const complexOption = getComplexOption(block);
|
|
144
|
+
if (complexOption) {
|
|
145
|
+
eventBus.emit("option:edit-complex", {
|
|
146
|
+
uuid: block.uuid,
|
|
147
|
+
key: complexOption.key,
|
|
148
|
+
dataType: complexOption.dataType
|
|
149
|
+
});
|
|
118
150
|
return;
|
|
119
151
|
}
|
|
120
|
-
const options = definition.options;
|
|
121
|
-
if (options) {
|
|
122
|
-
const keys = Object.keys(options);
|
|
123
|
-
for (let i = 0; i < keys.length; i++) {
|
|
124
|
-
const key = keys[i];
|
|
125
|
-
if (!key) continue;
|
|
126
|
-
const option = options[key];
|
|
127
|
-
if (option?.type !== "json" || !option.dataType) continue;
|
|
128
|
-
eventBus.emit("option:edit-complex", {
|
|
129
|
-
uuid: block.uuid,
|
|
130
|
-
key,
|
|
131
|
-
dataType: option.dataType
|
|
132
|
-
});
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
152
|
onClick([block]);
|
|
137
153
|
});
|
|
138
154
|
</script>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<PluginItemAction
|
|
3
|
+
id="swap"
|
|
4
|
+
edit-only
|
|
5
|
+
:title="$t('swapButton', 'Swap block positions')"
|
|
6
|
+
:disabled="swapDisabledReason"
|
|
7
|
+
:hidden="selection.items.value.length !== 2"
|
|
8
|
+
multiple
|
|
9
|
+
icon="bk_mdi_swap_vert"
|
|
10
|
+
:weight="7e3"
|
|
11
|
+
@click="onClick"
|
|
12
|
+
/>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup>
|
|
16
|
+
import { useBlokkli, defineBlokkliFeature, computed } from "#imports";
|
|
17
|
+
import { PluginItemAction } from "#blokkli/editor/plugins";
|
|
18
|
+
import { getSwapDisabledReason } from "#blokkli/editor/helpers/swap";
|
|
19
|
+
const { state, $t, selection, types, permissions } = useBlokkli();
|
|
20
|
+
const { adapter } = defineBlokkliFeature({
|
|
21
|
+
id: "swap",
|
|
22
|
+
icon: "bk_mdi_swap_vert",
|
|
23
|
+
label: "Swap",
|
|
24
|
+
description: "Provides an action to swap two selected blocks.",
|
|
25
|
+
requiredAdapterMethods: ["swapBlocks"]
|
|
26
|
+
});
|
|
27
|
+
const swapDisabledReason = computed(() => {
|
|
28
|
+
const items = selection.items.value;
|
|
29
|
+
if (items.length !== 2) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const reason = getSwapDisabledReason(items[0], items[1], {
|
|
33
|
+
getFieldConfig: types.getFieldConfig,
|
|
34
|
+
checkBlockBundlePermission: permissions.checkBlockBundlePermission,
|
|
35
|
+
blockHasRestrictedAncestor: permissions.blockHasRestrictedAncestor
|
|
36
|
+
});
|
|
37
|
+
if (reason) {
|
|
38
|
+
return $t("swapNotPossible", "Block positions cannot be swapped.");
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
});
|
|
42
|
+
async function onClick(items) {
|
|
43
|
+
if (items.length !== 2) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
await state.mutateWithLoadingState(
|
|
47
|
+
() => adapter.swapBlocks(items[0].uuid, items[1].uuid),
|
|
48
|
+
$t("swapError", "The blocks could not be swapped.")
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<script>
|
|
54
|
+
export default {
|
|
55
|
+
name: "Swap"
|
|
56
|
+
};
|
|
57
|
+
</script>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RenderedFieldListItem } from '../types/field.js';
|
|
2
|
+
import type { FieldConfig } from '../types/definitions.js';
|
|
3
|
+
type SwapValidationContext = {
|
|
4
|
+
getFieldConfig: (entityType: string, entityBundle: string, fieldName: string) => FieldConfig | undefined;
|
|
5
|
+
checkBlockBundlePermission: (bundle: string, operation: 'edit') => boolean;
|
|
6
|
+
blockHasRestrictedAncestor: (uuid: string) => boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Check whether two blocks can be swapped.
|
|
10
|
+
* Returns null if swap is possible, or a reason string if not.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getSwapDisabledReason(blockA: RenderedFieldListItem, blockB: RenderedFieldListItem, ctx: SwapValidationContext): string | null;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function getSwapDisabledReason(blockA, blockB, ctx) {
|
|
2
|
+
if (blockA.uuid === blockB.uuid) {
|
|
3
|
+
return "Cannot swap a block with itself.";
|
|
4
|
+
}
|
|
5
|
+
if (!ctx.checkBlockBundlePermission(blockA.bundle, "edit") || !ctx.checkBlockBundlePermission(blockB.bundle, "edit")) {
|
|
6
|
+
return "You do not have permission to edit one or both blocks.";
|
|
7
|
+
}
|
|
8
|
+
if (ctx.blockHasRestrictedAncestor(blockA.uuid) || ctx.blockHasRestrictedAncestor(blockB.uuid)) {
|
|
9
|
+
return "One or both blocks are inside a parent with restricted editing permissions.";
|
|
10
|
+
}
|
|
11
|
+
const fieldConfigA = ctx.getFieldConfig(
|
|
12
|
+
blockA.host.type,
|
|
13
|
+
blockA.host.bundle,
|
|
14
|
+
blockA.host.fieldName
|
|
15
|
+
);
|
|
16
|
+
const fieldConfigB = ctx.getFieldConfig(
|
|
17
|
+
blockB.host.type,
|
|
18
|
+
blockB.host.bundle,
|
|
19
|
+
blockB.host.fieldName
|
|
20
|
+
);
|
|
21
|
+
if (!fieldConfigA || !fieldConfigB) {
|
|
22
|
+
return "Could not determine field configuration for one or both blocks.";
|
|
23
|
+
}
|
|
24
|
+
if (fieldConfigA.allowedBundles.length && !fieldConfigA.allowedBundles.includes(blockB.bundle)) {
|
|
25
|
+
return `Bundle "${blockB.bundle}" is not allowed in field "${blockA.host.fieldName}".`;
|
|
26
|
+
}
|
|
27
|
+
if (fieldConfigB.allowedBundles.length && !fieldConfigB.allowedBundles.includes(blockA.bundle)) {
|
|
28
|
+
return `Bundle "${blockA.bundle}" is not allowed in field "${blockB.host.fieldName}".`;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
@@ -53,6 +53,12 @@ type __VLS_Props = {
|
|
|
53
53
|
* Lower weights appear first. Use 'last' to always position at the end.
|
|
54
54
|
*/
|
|
55
55
|
weight?: number | string | 'last';
|
|
56
|
+
/**
|
|
57
|
+
* Whether the action should be hidden.
|
|
58
|
+
*
|
|
59
|
+
* Unlike disabled, this completely hides the button via v-show.
|
|
60
|
+
*/
|
|
61
|
+
hidden?: boolean;
|
|
56
62
|
/**
|
|
57
63
|
* Optional icon to display in the button.
|
|
58
64
|
*/
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
<Teleport to="#bk-blokkli-item-actions">
|
|
3
3
|
<button
|
|
4
4
|
v-if="shouldRender"
|
|
5
|
+
v-show="!hidden"
|
|
5
6
|
ref="el"
|
|
6
7
|
:disabled="isDisabled"
|
|
7
8
|
class="bk-item-action"
|
|
@@ -51,6 +52,7 @@ const props = defineProps({
|
|
|
51
52
|
multiple: { type: Boolean, required: false },
|
|
52
53
|
editOnly: { type: Boolean, required: false },
|
|
53
54
|
weight: { type: [Number, String], required: false },
|
|
55
|
+
hidden: { type: Boolean, required: false },
|
|
54
56
|
icon: { type: null, required: false },
|
|
55
57
|
tourText: { type: String, required: false }
|
|
56
58
|
});
|
|
@@ -53,6 +53,12 @@ type __VLS_Props = {
|
|
|
53
53
|
* Lower weights appear first. Use 'last' to always position at the end.
|
|
54
54
|
*/
|
|
55
55
|
weight?: number | string | 'last';
|
|
56
|
+
/**
|
|
57
|
+
* Whether the action should be hidden.
|
|
58
|
+
*
|
|
59
|
+
* Unlike disabled, this completely hides the button via v-show.
|
|
60
|
+
*/
|
|
61
|
+
hidden?: boolean;
|
|
56
62
|
/**
|
|
57
63
|
* Optional icon to display in the button.
|
|
58
64
|
*/
|
|
@@ -19,7 +19,7 @@ export type DefinitionProvider = {
|
|
|
19
19
|
* @param parentBundle - Optional parent block bundle for nested blocks
|
|
20
20
|
* @returns The block definition, or undefined if not found
|
|
21
21
|
*/
|
|
22
|
-
getBlockDefinition: (bundleOrBlock: string | RenderedFieldListItem, fieldListType
|
|
22
|
+
getBlockDefinition: (bundleOrBlock: string | RenderedFieldListItem, fieldListType: ValidFieldListTypes | null, parentBundle: BlockBundleWithNested | null) => BlockDefinition | undefined;
|
|
23
23
|
/**
|
|
24
24
|
* Get the default block definition for a bundle.
|
|
25
25
|
*
|
|
@@ -4,6 +4,7 @@ import type { DefinitionProvider } from './definition.js';
|
|
|
4
4
|
import type { DirectiveProvider } from './directive.js';
|
|
5
5
|
import type { StateProvider } from './state.js';
|
|
6
6
|
import type { BlockDefinitionProvider } from './types.js';
|
|
7
|
+
import type { BlocksProvider } from './blocks.js';
|
|
7
8
|
import './fieldValueAdapterTypes.js';
|
|
8
9
|
/**
|
|
9
10
|
* Simplified field type for editable fields.
|
|
@@ -51,4 +52,4 @@ export type FieldValueProvider = {
|
|
|
51
52
|
*/
|
|
52
53
|
getTextFieldValues: () => Promise<TextFieldValue[]>;
|
|
53
54
|
};
|
|
54
|
-
export default function fieldValueProvider(adapters: AdaptersProvider, directive: DirectiveProvider, state: StateProvider, types: BlockDefinitionProvider, definitions: DefinitionProvider): FieldValueProvider;
|
|
55
|
+
export default function fieldValueProvider(adapters: AdaptersProvider, directive: DirectiveProvider, state: StateProvider, types: BlockDefinitionProvider, definitions: DefinitionProvider, blocks: BlocksProvider): FieldValueProvider;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { itemEntityType } from "#blokkli-build/config";
|
|
2
2
|
import "./fieldValueAdapterTypes";
|
|
3
|
-
export default function fieldValueProvider(adapters, directive, state, types, definitions) {
|
|
3
|
+
export default function fieldValueProvider(adapters, directive, state, types, definitions, blocks) {
|
|
4
4
|
function resolveFieldType(entityType, bundle, fieldName) {
|
|
5
5
|
const config = types.editableFieldConfig.forName(
|
|
6
6
|
entityType,
|
|
@@ -40,7 +40,12 @@ export default function fieldValueProvider(adapters, directive, state, types, de
|
|
|
40
40
|
);
|
|
41
41
|
let matchingProp = null;
|
|
42
42
|
if (host.type === itemEntityType) {
|
|
43
|
-
const
|
|
43
|
+
const block = blocks.getBlock(host.uuid);
|
|
44
|
+
const definition = definitions.getBlockDefinition(
|
|
45
|
+
host.bundle,
|
|
46
|
+
block?.fieldListType ?? "default",
|
|
47
|
+
block?.parentBlockBundle ?? null
|
|
48
|
+
);
|
|
44
49
|
if (definition?.propsFieldMapping) {
|
|
45
50
|
matchingProp = findMatchingProp(definition.propsFieldMapping, fieldName);
|
|
46
51
|
}
|
|
@@ -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": {
|
|
@@ -2199,6 +2199,14 @@
|
|
|
2199
2199
|
"source": "Structure",
|
|
2200
2200
|
"translation": "Struktur"
|
|
2201
2201
|
},
|
|
2202
|
+
"feature_swap_description": {
|
|
2203
|
+
"source": "Provides an action to swap two selected blocks.",
|
|
2204
|
+
"translation": ""
|
|
2205
|
+
},
|
|
2206
|
+
"feature_swap_label": {
|
|
2207
|
+
"source": "Swap",
|
|
2208
|
+
"translation": ""
|
|
2209
|
+
},
|
|
2202
2210
|
"feature_templates_description": {
|
|
2203
2211
|
"source": "Add blocks from templates.",
|
|
2204
2212
|
"translation": "Blöcke aus Vorlagen hinzufügen."
|
|
@@ -3043,6 +3051,18 @@
|
|
|
3043
3051
|
"source": "Shows a structured list of all blocks on the current page. Click on any block to quickly jump to it.",
|
|
3044
3052
|
"translation": "Zeigt eine strukturierte Liste aller Blöcke auf der aktuellen Seite. Klicken Sie auf einen Block, um ihn auf der Seite anzuzeigen."
|
|
3045
3053
|
},
|
|
3054
|
+
"swapButton": {
|
|
3055
|
+
"source": "Swap block positions",
|
|
3056
|
+
"translation": "Blockpositionen tauschen"
|
|
3057
|
+
},
|
|
3058
|
+
"swapError": {
|
|
3059
|
+
"source": "The blocks could not be swapped.",
|
|
3060
|
+
"translation": "Die Blöcke konnten nicht getauscht werden."
|
|
3061
|
+
},
|
|
3062
|
+
"swapNotPossible": {
|
|
3063
|
+
"source": "Block positions cannot be swapped.",
|
|
3064
|
+
"translation": "Blockpositionen können nicht getauscht werden."
|
|
3065
|
+
},
|
|
3046
3066
|
"systemRequirementsDialogButton": {
|
|
3047
3067
|
"source": "Continue anyway",
|
|
3048
3068
|
"translation": "Trotzdem fortfahren"
|
|
@@ -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": {
|
|
@@ -2199,6 +2199,14 @@
|
|
|
2199
2199
|
"source": "Structure",
|
|
2200
2200
|
"translation": "Structure"
|
|
2201
2201
|
},
|
|
2202
|
+
"feature_swap_description": {
|
|
2203
|
+
"source": "Provides an action to swap two selected blocks.",
|
|
2204
|
+
"translation": ""
|
|
2205
|
+
},
|
|
2206
|
+
"feature_swap_label": {
|
|
2207
|
+
"source": "Swap",
|
|
2208
|
+
"translation": ""
|
|
2209
|
+
},
|
|
2202
2210
|
"feature_templates_description": {
|
|
2203
2211
|
"source": "Add blocks from templates.",
|
|
2204
2212
|
"translation": ""
|
|
@@ -3043,6 +3051,18 @@
|
|
|
3043
3051
|
"source": "Shows a structured list of all blocks on the current page. Click on any block to quickly jump to it.",
|
|
3044
3052
|
"translation": ""
|
|
3045
3053
|
},
|
|
3054
|
+
"swapButton": {
|
|
3055
|
+
"source": "Swap block positions",
|
|
3056
|
+
"translation": ""
|
|
3057
|
+
},
|
|
3058
|
+
"swapError": {
|
|
3059
|
+
"source": "The blocks could not be swapped.",
|
|
3060
|
+
"translation": ""
|
|
3061
|
+
},
|
|
3062
|
+
"swapNotPossible": {
|
|
3063
|
+
"source": "Block positions cannot be swapped.",
|
|
3064
|
+
"translation": ""
|
|
3065
|
+
},
|
|
3046
3066
|
"systemRequirementsDialogButton": {
|
|
3047
3067
|
"source": "Continue anyway",
|
|
3048
3068
|
"translation": ""
|
|
@@ -1636,7 +1636,7 @@
|
|
|
1636
1636
|
"translation": "Dr Blocktyp isch in dem Fäld nid erlaubt."
|
|
1637
1637
|
},
|
|
1638
1638
|
"edit": {
|
|
1639
|
-
"source": "Edit",
|
|
1639
|
+
"source": "Edit...",
|
|
1640
1640
|
"translation": "Bearbeite"
|
|
1641
1641
|
},
|
|
1642
1642
|
"editDisabledByDefinition": {
|
|
@@ -2199,6 +2199,14 @@
|
|
|
2199
2199
|
"source": "Structure",
|
|
2200
2200
|
"translation": "Struktur"
|
|
2201
2201
|
},
|
|
2202
|
+
"feature_swap_description": {
|
|
2203
|
+
"source": "Provides an action to swap two selected blocks.",
|
|
2204
|
+
"translation": ""
|
|
2205
|
+
},
|
|
2206
|
+
"feature_swap_label": {
|
|
2207
|
+
"source": "Swap",
|
|
2208
|
+
"translation": ""
|
|
2209
|
+
},
|
|
2202
2210
|
"feature_templates_description": {
|
|
2203
2211
|
"source": "Add blocks from templates.",
|
|
2204
2212
|
"translation": "Blöck us Vorlage drzuefüege."
|
|
@@ -3043,6 +3051,18 @@
|
|
|
3043
3051
|
"source": "Shows a structured list of all blocks on the current page. Click on any block to quickly jump to it.",
|
|
3044
3052
|
"translation": "Zeigt e strukturierti Lischt vo allne Blöck uf dr aktuälle Sitte aa. Klick uf e belibige Block zum schnäll dohii z'springe."
|
|
3045
3053
|
},
|
|
3054
|
+
"swapButton": {
|
|
3055
|
+
"source": "Swap block positions",
|
|
3056
|
+
"translation": ""
|
|
3057
|
+
},
|
|
3058
|
+
"swapError": {
|
|
3059
|
+
"source": "The blocks could not be swapped.",
|
|
3060
|
+
"translation": ""
|
|
3061
|
+
},
|
|
3062
|
+
"swapNotPossible": {
|
|
3063
|
+
"source": "Block positions cannot be swapped.",
|
|
3064
|
+
"translation": ""
|
|
3065
|
+
},
|
|
3046
3066
|
"systemRequirementsDialogButton": {
|
|
3047
3067
|
"source": "Continue anyway",
|
|
3048
3068
|
"translation": "Trotzdem wiiterfahre"
|
|
@@ -1636,7 +1636,7 @@
|
|
|
1636
1636
|
"translation": ""
|
|
1637
1637
|
},
|
|
1638
1638
|
"edit": {
|
|
1639
|
-
"source": "Edit",
|
|
1639
|
+
"source": "Edit...",
|
|
1640
1640
|
"translation": "Modifica"
|
|
1641
1641
|
},
|
|
1642
1642
|
"editDisabledByDefinition": {
|
|
@@ -2199,6 +2199,14 @@
|
|
|
2199
2199
|
"source": "Structure",
|
|
2200
2200
|
"translation": "Struttura"
|
|
2201
2201
|
},
|
|
2202
|
+
"feature_swap_description": {
|
|
2203
|
+
"source": "Provides an action to swap two selected blocks.",
|
|
2204
|
+
"translation": ""
|
|
2205
|
+
},
|
|
2206
|
+
"feature_swap_label": {
|
|
2207
|
+
"source": "Swap",
|
|
2208
|
+
"translation": ""
|
|
2209
|
+
},
|
|
2202
2210
|
"feature_templates_description": {
|
|
2203
2211
|
"source": "Add blocks from templates.",
|
|
2204
2212
|
"translation": ""
|
|
@@ -3043,6 +3051,18 @@
|
|
|
3043
3051
|
"source": "Shows a structured list of all blocks on the current page. Click on any block to quickly jump to it.",
|
|
3044
3052
|
"translation": ""
|
|
3045
3053
|
},
|
|
3054
|
+
"swapButton": {
|
|
3055
|
+
"source": "Swap block positions",
|
|
3056
|
+
"translation": ""
|
|
3057
|
+
},
|
|
3058
|
+
"swapError": {
|
|
3059
|
+
"source": "The blocks could not be swapped.",
|
|
3060
|
+
"translation": ""
|
|
3061
|
+
},
|
|
3062
|
+
"swapNotPossible": {
|
|
3063
|
+
"source": "Block positions cannot be swapped.",
|
|
3064
|
+
"translation": ""
|
|
3065
|
+
},
|
|
3046
3066
|
"systemRequirementsDialogButton": {
|
|
3047
3067
|
"source": "Continue anyway",
|
|
3048
3068
|
"translation": ""
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blokkli/editor",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.50",
|
|
4
4
|
"description": "Interactive page building experience for Nuxt",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms",
|
|
@@ -186,21 +186,21 @@
|
|
|
186
186
|
"vue-tsc": "^3.1.8"
|
|
187
187
|
},
|
|
188
188
|
"peerDependencies": {
|
|
189
|
-
"@anthropic-ai/sdk": "
|
|
190
|
-
"@lunarisapp/readability": "
|
|
191
|
-
"@thedutchcoder/postcss-rem-to-px": "
|
|
189
|
+
"@anthropic-ai/sdk": "*",
|
|
190
|
+
"@lunarisapp/readability": "*",
|
|
191
|
+
"@thedutchcoder/postcss-rem-to-px": "*",
|
|
192
192
|
"acorn": "^8.0.0",
|
|
193
|
-
"axe-core": "
|
|
193
|
+
"axe-core": "*",
|
|
194
194
|
"esbuild": ">=0.20.0",
|
|
195
|
-
"magic-string": "
|
|
195
|
+
"magic-string": ">=0.30.0",
|
|
196
196
|
"mammoth": "^1.11.0",
|
|
197
197
|
"micromatch": "^4.0.0",
|
|
198
|
-
"openai": "
|
|
199
|
-
"oxc-walker": "
|
|
200
|
-
"postcss": "
|
|
201
|
-
"postcss-import": "
|
|
202
|
-
"postcss-replace": "
|
|
203
|
-
"tailwindcss": "
|
|
198
|
+
"openai": "*",
|
|
199
|
+
"oxc-walker": ">=0.5.0",
|
|
200
|
+
"postcss": "*",
|
|
201
|
+
"postcss-import": "*",
|
|
202
|
+
"postcss-replace": "*",
|
|
203
|
+
"tailwindcss": "*",
|
|
204
204
|
"turndown": "^7.2.2",
|
|
205
205
|
"typescript": "^5.0.0"
|
|
206
206
|
},
|