@shwfed/nuxt 0.11.46 → 0.11.48
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/runtime/components/fields.d.vue.ts +6 -810
- package/dist/runtime/components/fields.vue +2 -0
- package/dist/runtime/components/fields.vue.d.ts +6 -810
- package/dist/runtime/components/ui/fields/Fields.d.vue.ts +10 -1618
- package/dist/runtime/components/ui/fields/Fields.vue +180 -610
- package/dist/runtime/components/ui/fields/Fields.vue.d.ts +10 -1618
- package/dist/runtime/components/ui/fields/FieldsBody.d.vue.ts +17 -0
- package/dist/runtime/components/ui/fields/FieldsBody.vue +720 -0
- package/dist/runtime/components/ui/fields/FieldsBody.vue.d.ts +17 -0
- package/dist/runtime/components/ui/fields/render-context.d.ts +120 -0
- package/dist/runtime/components/ui/fields/render-context.js +0 -0
- package/dist/runtime/components/ui/fields/schema.d.ts +95 -5260
- package/dist/runtime/components/ui/fields/schema.js +89 -82
- package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.d.vue.ts +5 -809
- package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue +703 -242
- package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue.d.ts +5 -809
- package/package.json +1 -1
|
@@ -7,12 +7,14 @@ import { computed, nextTick, ref, toRaw, watch } from "vue";
|
|
|
7
7
|
import { useI18n } from "vue-i18n";
|
|
8
8
|
import {
|
|
9
9
|
CalendarFieldC,
|
|
10
|
+
ContainerFieldC,
|
|
10
11
|
EmptyFieldC,
|
|
11
12
|
FieldGroupC,
|
|
12
13
|
FieldGroupStyleC,
|
|
13
14
|
FieldsBodyC,
|
|
14
15
|
FieldsConfigC,
|
|
15
16
|
FieldsStyleC,
|
|
17
|
+
MarkdownBodyFieldC,
|
|
16
18
|
MarkdownFieldC,
|
|
17
19
|
NumberFieldC,
|
|
18
20
|
RadioGroupFieldC,
|
|
@@ -45,6 +47,8 @@ import { NativeSelect, NativeSelectOption } from "../native-select";
|
|
|
45
47
|
import { Switch } from "../switch";
|
|
46
48
|
import { Textarea } from "../textarea";
|
|
47
49
|
const ROOT_FIELD_GROUP_VALUE = "__root__";
|
|
50
|
+
const GROUP_OWNER_PREFIX = "group:";
|
|
51
|
+
const CONTAINER_OWNER_PREFIX = "container:";
|
|
48
52
|
const props = defineProps({
|
|
49
53
|
config: { type: null, required: true }
|
|
50
54
|
});
|
|
@@ -72,10 +76,12 @@ const fieldTypeOptions = computed(() => [
|
|
|
72
76
|
{ type: "textarea", label: t("field-type-textarea") },
|
|
73
77
|
{ type: "number", label: t("field-type-number") },
|
|
74
78
|
{ type: "markdown", label: t("field-type-markdown") },
|
|
79
|
+
{ type: "markdown-body", label: t("field-type-markdown-body") },
|
|
75
80
|
{ type: "select", label: t("field-type-select") },
|
|
76
81
|
{ type: "radio", label: t("field-type-radio") },
|
|
77
82
|
{ type: "calendar", label: t("field-type-calendar") },
|
|
78
83
|
{ type: "upload", label: t("field-type-upload") },
|
|
84
|
+
{ type: "container", label: t("field-type-container") },
|
|
79
85
|
{ type: "empty", label: t("field-type-empty") },
|
|
80
86
|
{ type: "slot", label: t("field-type-slot") }
|
|
81
87
|
]);
|
|
@@ -84,28 +90,83 @@ const generalItem = computed(() => ({
|
|
|
84
90
|
label: t("general")
|
|
85
91
|
}));
|
|
86
92
|
const normalizedSearch = computed(() => search.value.trim().toLocaleLowerCase());
|
|
93
|
+
function cloneValue(value) {
|
|
94
|
+
return JSON.parse(JSON.stringify(toRaw(value)));
|
|
95
|
+
}
|
|
96
|
+
function createContainerDraftField(field) {
|
|
97
|
+
const { fields, ...rest } = cloneValue(field);
|
|
98
|
+
return {
|
|
99
|
+
draftId: createDraftId(),
|
|
100
|
+
field: {
|
|
101
|
+
...rest,
|
|
102
|
+
fields: []
|
|
103
|
+
},
|
|
104
|
+
children: cloneFields(fields)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function findDraftField(fields, draftId) {
|
|
108
|
+
for (const field of fields) {
|
|
109
|
+
if (field.draftId === draftId) {
|
|
110
|
+
return field;
|
|
111
|
+
}
|
|
112
|
+
const child = findDraftField(field.children, draftId);
|
|
113
|
+
if (child) {
|
|
114
|
+
return child;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return void 0;
|
|
118
|
+
}
|
|
119
|
+
function findFieldOwnerInFields(fields, draftId, owner) {
|
|
120
|
+
for (const field of fields) {
|
|
121
|
+
if (field.draftId === draftId) {
|
|
122
|
+
return owner;
|
|
123
|
+
}
|
|
124
|
+
if (field.field.type !== "container") {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const childOwner = findFieldOwnerInFields(field.children, draftId, {
|
|
128
|
+
kind: "container",
|
|
129
|
+
draftId: field.draftId
|
|
130
|
+
});
|
|
131
|
+
if (childOwner) {
|
|
132
|
+
return childOwner;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return void 0;
|
|
136
|
+
}
|
|
137
|
+
function findFieldOwnerByDraftId(draftId) {
|
|
138
|
+
const rootOwner = findFieldOwnerInFields(draftFields.value, draftId, {
|
|
139
|
+
kind: "root"
|
|
140
|
+
});
|
|
141
|
+
if (rootOwner) {
|
|
142
|
+
return rootOwner;
|
|
143
|
+
}
|
|
144
|
+
for (const group of draftGroups.value) {
|
|
145
|
+
const groupOwner = findFieldOwnerInFields(group.fields, draftId, {
|
|
146
|
+
kind: "group",
|
|
147
|
+
draftId: group.draftId
|
|
148
|
+
});
|
|
149
|
+
if (groupOwner) {
|
|
150
|
+
return groupOwner;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return void 0;
|
|
154
|
+
}
|
|
87
155
|
const selectedGroup = computed(() => draftGroups.value.find((group) => group.draftId === selectedItemId.value));
|
|
88
156
|
const selectedField = computed(() => {
|
|
89
|
-
const rootField = draftFields.value
|
|
157
|
+
const rootField = findDraftField(draftFields.value, selectedItemId.value);
|
|
90
158
|
if (rootField) {
|
|
91
159
|
return rootField;
|
|
92
160
|
}
|
|
93
161
|
for (const group of draftGroups.value) {
|
|
94
|
-
const field = group.fields
|
|
162
|
+
const field = findDraftField(group.fields, selectedItemId.value);
|
|
95
163
|
if (field) {
|
|
96
164
|
return field;
|
|
97
165
|
}
|
|
98
166
|
}
|
|
99
167
|
return void 0;
|
|
100
168
|
});
|
|
101
|
-
const
|
|
102
|
-
for (const group of draftGroups.value) {
|
|
103
|
-
if (group.fields.some((item) => item.draftId === selectedItemId.value)) {
|
|
104
|
-
return group;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return void 0;
|
|
108
|
-
});
|
|
169
|
+
const selectedFieldOwner = computed(() => findFieldOwnerByDraftId(selectedItemId.value));
|
|
109
170
|
const usesContentsOrientation = computed(() => draftOrientation.value === "contents");
|
|
110
171
|
const selectedFieldValidationRules = computed(() => {
|
|
111
172
|
const field = selectedField.value?.field;
|
|
@@ -127,9 +188,13 @@ function createDefaultLocaleValue() {
|
|
|
127
188
|
return [{ locale: "zh", message: "" }];
|
|
128
189
|
}
|
|
129
190
|
function createDraftField(field) {
|
|
191
|
+
if (field.type === "container") {
|
|
192
|
+
return createContainerDraftField(field);
|
|
193
|
+
}
|
|
130
194
|
return {
|
|
131
195
|
draftId: createDraftId(),
|
|
132
|
-
field:
|
|
196
|
+
field: cloneValue(field),
|
|
197
|
+
children: []
|
|
133
198
|
};
|
|
134
199
|
}
|
|
135
200
|
function cloneFields(fields) {
|
|
@@ -138,11 +203,11 @@ function cloneFields(fields) {
|
|
|
138
203
|
function createDraftGroup(group) {
|
|
139
204
|
return {
|
|
140
205
|
draftId: createDraftId(),
|
|
141
|
-
group:
|
|
206
|
+
group: cloneValue({
|
|
142
207
|
id: group.id,
|
|
143
208
|
style: group.style,
|
|
144
209
|
fields: []
|
|
145
|
-
})
|
|
210
|
+
}),
|
|
146
211
|
fields: cloneFields(group.fields)
|
|
147
212
|
};
|
|
148
213
|
}
|
|
@@ -162,33 +227,54 @@ function getFieldTypeLabel(type) {
|
|
|
162
227
|
return t(`field-type-${type}`);
|
|
163
228
|
}
|
|
164
229
|
function isPassiveField(field) {
|
|
165
|
-
return field.type === "
|
|
230
|
+
return field.type === "empty";
|
|
166
231
|
}
|
|
167
232
|
function isMarkdownField(field) {
|
|
168
233
|
return field.type === "markdown";
|
|
169
234
|
}
|
|
235
|
+
function isMarkdownBodyField(field) {
|
|
236
|
+
return field.type === "markdown-body";
|
|
237
|
+
}
|
|
238
|
+
function isMarkdownContentField(field) {
|
|
239
|
+
return isMarkdownField(field) || isMarkdownBodyField(field);
|
|
240
|
+
}
|
|
241
|
+
function hasFieldLabel(field) {
|
|
242
|
+
return field.type !== "empty" && !isMarkdownBodyField(field);
|
|
243
|
+
}
|
|
244
|
+
function supportsFieldCellStyles(field) {
|
|
245
|
+
return field.type !== "empty" && !isMarkdownBodyField(field);
|
|
246
|
+
}
|
|
170
247
|
function isPathlessField(field) {
|
|
171
|
-
return
|
|
248
|
+
return field.type === "slot" || field.type === "empty" || isMarkdownContentField(field) || field.type === "container";
|
|
172
249
|
}
|
|
173
250
|
function isInteractiveField(field) {
|
|
174
251
|
return !isPathlessField(field);
|
|
175
252
|
}
|
|
176
|
-
function getSlotFieldLabel(
|
|
177
|
-
return getFieldTypeLabel("slot");
|
|
253
|
+
function getSlotFieldLabel(field) {
|
|
254
|
+
return getFieldChineseTitle(field) ?? getFieldTypeLabel("slot");
|
|
178
255
|
}
|
|
179
256
|
function getEmptyFieldLabel(_) {
|
|
180
257
|
return getFieldTypeLabel("empty");
|
|
181
258
|
}
|
|
259
|
+
function getContainerFieldLabel(field) {
|
|
260
|
+
return getFieldChineseTitle(field) ?? getUnnamedFieldLabel(field);
|
|
261
|
+
}
|
|
182
262
|
function getUnnamedFieldLabel(field) {
|
|
183
263
|
return t("unnamed-field", {
|
|
184
264
|
type: getFieldTypeLabel(field.type)
|
|
185
265
|
});
|
|
186
266
|
}
|
|
267
|
+
function getFieldTitleValue(field) {
|
|
268
|
+
if (!hasFieldLabel(field)) {
|
|
269
|
+
return createDefaultLocaleValue();
|
|
270
|
+
}
|
|
271
|
+
return field.title ?? createDefaultLocaleValue();
|
|
272
|
+
}
|
|
187
273
|
function getFieldChineseTitle(field) {
|
|
188
|
-
if (
|
|
274
|
+
if (!hasFieldLabel(field)) {
|
|
189
275
|
return void 0;
|
|
190
276
|
}
|
|
191
|
-
const zhTitle = field.title
|
|
277
|
+
const zhTitle = field.title?.find((item) => item.locale === "zh");
|
|
192
278
|
if (!zhTitle) {
|
|
193
279
|
return void 0;
|
|
194
280
|
}
|
|
@@ -199,6 +285,9 @@ function getFieldListLabel(field) {
|
|
|
199
285
|
if (field.type === "slot") {
|
|
200
286
|
return getSlotFieldLabel(field);
|
|
201
287
|
}
|
|
288
|
+
if (field.type === "container") {
|
|
289
|
+
return getContainerFieldLabel(field);
|
|
290
|
+
}
|
|
202
291
|
if (field.type === "empty") {
|
|
203
292
|
return getEmptyFieldLabel(field);
|
|
204
293
|
}
|
|
@@ -209,32 +298,49 @@ function getGroupListLabel(index) {
|
|
|
209
298
|
index: index + 1
|
|
210
299
|
});
|
|
211
300
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
301
|
+
function buildFieldSearchMeta(field) {
|
|
302
|
+
return isPathlessField(field) ? [field.id, getFieldChineseTitle(field)].filter(Boolean).join(" ") : [field.path, field.id, getFieldChineseTitle(field)].filter(Boolean).join(" ");
|
|
303
|
+
}
|
|
304
|
+
function flattenFieldItems(fields, depth, groupItemId) {
|
|
305
|
+
return fields.flatMap((item) => {
|
|
306
|
+
const currentItem = {
|
|
307
|
+
itemId: item.draftId,
|
|
308
|
+
groupItemId,
|
|
309
|
+
fieldId: item.field.id,
|
|
310
|
+
label: getFieldListLabel(item.field),
|
|
311
|
+
path: isPathlessField(item.field) ? void 0 : item.field.path,
|
|
312
|
+
searchMeta: buildFieldSearchMeta(item.field),
|
|
313
|
+
type: item.field.type,
|
|
314
|
+
depth
|
|
315
|
+
};
|
|
316
|
+
if (item.field.type !== "container") {
|
|
317
|
+
return [currentItem];
|
|
318
|
+
}
|
|
319
|
+
return [
|
|
320
|
+
currentItem,
|
|
321
|
+
...flattenFieldItems(item.children, depth + 1, groupItemId)
|
|
322
|
+
];
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
const rootFieldItems = computed(() => flattenFieldItems(draftFields.value, 0));
|
|
220
326
|
const groupItems = computed(() => draftGroups.value.map((group, index) => {
|
|
221
|
-
const fields = group.fields.map((item) => ({
|
|
222
|
-
itemId: item.draftId,
|
|
223
|
-
groupItemId: group.draftId,
|
|
224
|
-
fieldId: item.field.id,
|
|
225
|
-
label: getFieldListLabel(item.field),
|
|
226
|
-
path: isPathlessField(item.field) ? void 0 : item.field.path,
|
|
227
|
-
searchMeta: isPathlessField(item.field) ? item.field.id : [item.field.path, item.field.id].filter(Boolean).join(" "),
|
|
228
|
-
type: item.field.type
|
|
229
|
-
}));
|
|
230
327
|
return {
|
|
231
328
|
itemId: group.draftId,
|
|
232
329
|
groupId: group.group.id,
|
|
233
330
|
label: getGroupListLabel(index),
|
|
234
331
|
searchMeta: group.group.id,
|
|
235
|
-
fields
|
|
332
|
+
fields: flattenFieldItems(group.fields, 0, group.draftId)
|
|
236
333
|
};
|
|
237
334
|
}));
|
|
335
|
+
function getFieldOwnerValue(owner) {
|
|
336
|
+
if (owner.kind === "root") {
|
|
337
|
+
return ROOT_FIELD_GROUP_VALUE;
|
|
338
|
+
}
|
|
339
|
+
if (owner.kind === "group") {
|
|
340
|
+
return `${GROUP_OWNER_PREFIX}${owner.draftId}`;
|
|
341
|
+
}
|
|
342
|
+
return `${CONTAINER_OWNER_PREFIX}${owner.draftId}`;
|
|
343
|
+
}
|
|
238
344
|
const filteredGroupItems = computed(() => {
|
|
239
345
|
if (!normalizedSearch.value) {
|
|
240
346
|
return groupItems.value;
|
|
@@ -265,6 +371,52 @@ const filteredRootFieldItems = computed(() => {
|
|
|
265
371
|
});
|
|
266
372
|
});
|
|
267
373
|
const selectedItemLabel = computed(() => selectedField.value ? getFieldListLabel(selectedField.value.field) : selectedGroup.value ? getGroupListLabel(Math.max(draftGroups.value.findIndex((group) => group.draftId === selectedGroup.value?.draftId), 0)) : generalItem.value.label);
|
|
374
|
+
function collectDraftFieldIds(fields) {
|
|
375
|
+
return fields.flatMap((field) => [field.draftId, ...collectDraftFieldIds(field.children)]);
|
|
376
|
+
}
|
|
377
|
+
function buildFieldOwnerOptions(fields, depth, options, excludedDraftIds) {
|
|
378
|
+
for (const field of fields) {
|
|
379
|
+
if (field.field.type !== "container") {
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
if (!excludedDraftIds.has(field.draftId)) {
|
|
383
|
+
options.push({
|
|
384
|
+
value: getFieldOwnerValue({
|
|
385
|
+
kind: "container",
|
|
386
|
+
draftId: field.draftId
|
|
387
|
+
}),
|
|
388
|
+
label: `${" ".repeat(depth)}${getFieldListLabel(field.field)}`
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
buildFieldOwnerOptions(field.children, depth + 1, options, excludedDraftIds);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const selectedFieldOwnerOptions = computed(() => {
|
|
395
|
+
const options = [{
|
|
396
|
+
value: ROOT_FIELD_GROUP_VALUE,
|
|
397
|
+
label: t("field-group-none")
|
|
398
|
+
}];
|
|
399
|
+
const excludedDraftIds = new Set(
|
|
400
|
+
selectedField.value ? collectDraftFieldIds([selectedField.value]) : []
|
|
401
|
+
);
|
|
402
|
+
for (const group of groupItems.value) {
|
|
403
|
+
options.push({
|
|
404
|
+
value: `${GROUP_OWNER_PREFIX}${group.itemId}`,
|
|
405
|
+
label: group.label
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
buildFieldOwnerOptions(draftFields.value, 1, options, excludedDraftIds);
|
|
409
|
+
for (const group of draftGroups.value) {
|
|
410
|
+
buildFieldOwnerOptions(group.fields, 1, options, excludedDraftIds);
|
|
411
|
+
}
|
|
412
|
+
return options;
|
|
413
|
+
});
|
|
414
|
+
const selectedContainerChildItems = computed(() => {
|
|
415
|
+
if (selectedField.value?.field.type !== "container") {
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
return flattenFieldItems(selectedField.value.children, 1);
|
|
419
|
+
});
|
|
268
420
|
function getFieldErrorKey(draftId, fieldKey) {
|
|
269
421
|
return `${draftId}:${fieldKey}`;
|
|
270
422
|
}
|
|
@@ -347,6 +499,13 @@ function normalizeField(field) {
|
|
|
347
499
|
contentStyle: normalizeOptionalString(field.contentStyle ?? ""),
|
|
348
500
|
hidden: normalizeOptionalString(field.hidden ?? "")
|
|
349
501
|
};
|
|
502
|
+
case "markdown-body":
|
|
503
|
+
return {
|
|
504
|
+
...field,
|
|
505
|
+
style: normalizeOptionalString(field.style ?? ""),
|
|
506
|
+
hidden: normalizeOptionalString(field.hidden ?? ""),
|
|
507
|
+
inline: field.inline ? true : void 0
|
|
508
|
+
};
|
|
350
509
|
case "number":
|
|
351
510
|
return {
|
|
352
511
|
...field,
|
|
@@ -426,8 +585,27 @@ function normalizeField(field) {
|
|
|
426
585
|
case "slot":
|
|
427
586
|
return {
|
|
428
587
|
...field,
|
|
588
|
+
title: field.title,
|
|
589
|
+
hideLabel: field.hideLabel ? true : void 0,
|
|
590
|
+
required: field.required ? true : void 0,
|
|
591
|
+
hidden: normalizeOptionalString(field.hidden ?? ""),
|
|
592
|
+
labelStyle: normalizeOptionalString(field.labelStyle ?? ""),
|
|
593
|
+
contentStyle: normalizeOptionalString(field.contentStyle ?? ""),
|
|
429
594
|
style: normalizeOptionalString(field.style ?? "")
|
|
430
595
|
};
|
|
596
|
+
case "container":
|
|
597
|
+
return {
|
|
598
|
+
...field,
|
|
599
|
+
hideLabel: field.hideLabel ? true : void 0,
|
|
600
|
+
required: field.required ? true : void 0,
|
|
601
|
+
hidden: normalizeOptionalString(field.hidden ?? ""),
|
|
602
|
+
labelStyle: normalizeOptionalString(field.labelStyle ?? ""),
|
|
603
|
+
contentStyle: normalizeOptionalString(field.contentStyle ?? ""),
|
|
604
|
+
bodyOrientation: field.bodyOrientation ? normalizeOrientation(field.bodyOrientation) : void 0,
|
|
605
|
+
bodyBordered: field.bodyBordered ? true : void 0,
|
|
606
|
+
bodyStyle: normalizeOptionalString(field.bodyStyle ?? ""),
|
|
607
|
+
fields: []
|
|
608
|
+
};
|
|
431
609
|
case "empty":
|
|
432
610
|
return {
|
|
433
611
|
...field,
|
|
@@ -464,6 +642,12 @@ function createField(type) {
|
|
|
464
642
|
title,
|
|
465
643
|
locale: createDefaultLocaleValue()
|
|
466
644
|
};
|
|
645
|
+
case "markdown-body":
|
|
646
|
+
return {
|
|
647
|
+
id,
|
|
648
|
+
type,
|
|
649
|
+
locale: createDefaultLocaleValue()
|
|
650
|
+
};
|
|
467
651
|
case "select":
|
|
468
652
|
case "radio":
|
|
469
653
|
return {
|
|
@@ -495,6 +679,14 @@ function createField(type) {
|
|
|
495
679
|
path: "",
|
|
496
680
|
title
|
|
497
681
|
};
|
|
682
|
+
case "container":
|
|
683
|
+
return {
|
|
684
|
+
id,
|
|
685
|
+
type,
|
|
686
|
+
hideLabel: void 0,
|
|
687
|
+
title,
|
|
688
|
+
fields: []
|
|
689
|
+
};
|
|
498
690
|
case "empty":
|
|
499
691
|
return {
|
|
500
692
|
id,
|
|
@@ -542,6 +734,120 @@ function moveField(fields, oldIndex, newIndex) {
|
|
|
542
734
|
nextFields.splice(newIndex, 0, movedField);
|
|
543
735
|
return nextFields;
|
|
544
736
|
}
|
|
737
|
+
function mapDraftFields(fields, updater) {
|
|
738
|
+
return fields.map((item) => {
|
|
739
|
+
const nextItem = updater(item);
|
|
740
|
+
if (nextItem.field.type !== "container") {
|
|
741
|
+
return nextItem;
|
|
742
|
+
}
|
|
743
|
+
return {
|
|
744
|
+
...nextItem,
|
|
745
|
+
children: mapDraftFields(nextItem.children, updater)
|
|
746
|
+
};
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
function updateContainerFields(fields, containerDraftId, updater) {
|
|
750
|
+
return fields.map((item) => {
|
|
751
|
+
if (item.field.type !== "container") {
|
|
752
|
+
return item;
|
|
753
|
+
}
|
|
754
|
+
if (item.draftId === containerDraftId) {
|
|
755
|
+
return {
|
|
756
|
+
...item,
|
|
757
|
+
children: updater(item.children)
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
return {
|
|
761
|
+
...item,
|
|
762
|
+
children: updateContainerFields(item.children, containerDraftId, updater)
|
|
763
|
+
};
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
function findContainerChildren(fields, containerDraftId) {
|
|
767
|
+
for (const item of fields) {
|
|
768
|
+
if (item.field.type !== "container") {
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
if (item.draftId === containerDraftId) {
|
|
772
|
+
return item.children;
|
|
773
|
+
}
|
|
774
|
+
const children = findContainerChildren(item.children, containerDraftId);
|
|
775
|
+
if (children) {
|
|
776
|
+
return children;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
return void 0;
|
|
780
|
+
}
|
|
781
|
+
function updateOwnerFields(owner, updater) {
|
|
782
|
+
if (owner.kind === "root") {
|
|
783
|
+
draftFields.value = updater(draftFields.value);
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
if (owner.kind === "group") {
|
|
787
|
+
draftGroups.value = draftGroups.value.map((group) => group.draftId === owner.draftId ? {
|
|
788
|
+
...group,
|
|
789
|
+
fields: updater(group.fields)
|
|
790
|
+
} : group);
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
draftFields.value = updateContainerFields(draftFields.value, owner.draftId, updater);
|
|
794
|
+
draftGroups.value = draftGroups.value.map((group) => ({
|
|
795
|
+
...group,
|
|
796
|
+
fields: updateContainerFields(group.fields, owner.draftId, updater)
|
|
797
|
+
}));
|
|
798
|
+
}
|
|
799
|
+
function getOwnerFields(owner) {
|
|
800
|
+
if (owner.kind === "root") {
|
|
801
|
+
return draftFields.value;
|
|
802
|
+
}
|
|
803
|
+
if (owner.kind === "group") {
|
|
804
|
+
return draftGroups.value.find((group) => group.draftId === owner.draftId)?.fields ?? [];
|
|
805
|
+
}
|
|
806
|
+
return findContainerChildren(draftFields.value, owner.draftId) ?? draftGroups.value.flatMap((group) => findContainerChildren(group.fields, owner.draftId) ?? []);
|
|
807
|
+
}
|
|
808
|
+
function removeFieldFromOwner(owner, fieldDraftId) {
|
|
809
|
+
let movedField;
|
|
810
|
+
updateOwnerFields(owner, (fields) => fields.filter((field) => {
|
|
811
|
+
if (field.draftId !== fieldDraftId) {
|
|
812
|
+
return true;
|
|
813
|
+
}
|
|
814
|
+
movedField = field;
|
|
815
|
+
return false;
|
|
816
|
+
}));
|
|
817
|
+
return movedField;
|
|
818
|
+
}
|
|
819
|
+
function insertFieldIntoOwner(owner, field, newIndex) {
|
|
820
|
+
updateOwnerFields(owner, (fields) => {
|
|
821
|
+
const nextFields = fields.slice();
|
|
822
|
+
const insertIndex = Math.min(Math.max(newIndex, 0), nextFields.length);
|
|
823
|
+
nextFields.splice(insertIndex, 0, field);
|
|
824
|
+
return nextFields;
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
function getOwnerItemCount(owner) {
|
|
828
|
+
return getOwnerFields(owner).length;
|
|
829
|
+
}
|
|
830
|
+
function getFieldOwnerFromValue(value) {
|
|
831
|
+
const ownerValue = String(value);
|
|
832
|
+
if (ownerValue === ROOT_FIELD_GROUP_VALUE) {
|
|
833
|
+
return {
|
|
834
|
+
kind: "root"
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
if (ownerValue.startsWith(GROUP_OWNER_PREFIX)) {
|
|
838
|
+
return {
|
|
839
|
+
kind: "group",
|
|
840
|
+
draftId: ownerValue.slice(GROUP_OWNER_PREFIX.length)
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
if (ownerValue.startsWith(CONTAINER_OWNER_PREFIX)) {
|
|
844
|
+
return {
|
|
845
|
+
kind: "container",
|
|
846
|
+
draftId: ownerValue.slice(CONTAINER_OWNER_PREFIX.length)
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
return void 0;
|
|
850
|
+
}
|
|
545
851
|
function setSortableGroupListRef(groupDraftId, element) {
|
|
546
852
|
sortableGroupListRefs.value[groupDraftId] = element instanceof HTMLElement ? element : null;
|
|
547
853
|
}
|
|
@@ -577,84 +883,41 @@ function reorderRootFields(oldIndex, newIndex) {
|
|
|
577
883
|
draftFields.value = moveField(draftFields.value, oldIndex, newIndex);
|
|
578
884
|
}
|
|
579
885
|
function moveFieldBetweenGroups(sourceGroupDraftId, targetGroupDraftId, fieldDraftId, newIndex) {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
if (field.draftId !== fieldDraftId) {
|
|
585
|
-
return true;
|
|
586
|
-
}
|
|
587
|
-
movedField = field;
|
|
588
|
-
return false;
|
|
589
|
-
});
|
|
590
|
-
return {
|
|
591
|
-
...group,
|
|
592
|
-
fields: nextFields
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
return group;
|
|
596
|
-
});
|
|
886
|
+
const movedField = removeFieldFromOwner({
|
|
887
|
+
kind: "group",
|
|
888
|
+
draftId: sourceGroupDraftId
|
|
889
|
+
}, fieldDraftId);
|
|
597
890
|
if (!movedField) {
|
|
598
891
|
return;
|
|
599
892
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
}
|
|
605
|
-
const nextFields = group.fields.slice();
|
|
606
|
-
const insertIndex = Math.min(Math.max(newIndex, 0), nextFields.length);
|
|
607
|
-
nextFields.splice(insertIndex, 0, nextMovedField);
|
|
608
|
-
return {
|
|
609
|
-
...group,
|
|
610
|
-
fields: nextFields
|
|
611
|
-
};
|
|
612
|
-
});
|
|
893
|
+
insertFieldIntoOwner({
|
|
894
|
+
kind: "group",
|
|
895
|
+
draftId: targetGroupDraftId
|
|
896
|
+
}, movedField, newIndex);
|
|
613
897
|
}
|
|
614
898
|
function moveFieldToRoot(sourceGroupDraftId, fieldDraftId, newIndex) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
}
|
|
620
|
-
const nextFields2 = group.fields.filter((field) => {
|
|
621
|
-
if (field.draftId !== fieldDraftId) {
|
|
622
|
-
return true;
|
|
623
|
-
}
|
|
624
|
-
movedField = field;
|
|
625
|
-
return false;
|
|
626
|
-
});
|
|
627
|
-
return {
|
|
628
|
-
...group,
|
|
629
|
-
fields: nextFields2
|
|
630
|
-
};
|
|
631
|
-
});
|
|
899
|
+
const movedField = removeFieldFromOwner({
|
|
900
|
+
kind: "group",
|
|
901
|
+
draftId: sourceGroupDraftId
|
|
902
|
+
}, fieldDraftId);
|
|
632
903
|
if (!movedField) {
|
|
633
904
|
return;
|
|
634
905
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
draftFields.value = nextFields;
|
|
906
|
+
insertFieldIntoOwner({
|
|
907
|
+
kind: "root"
|
|
908
|
+
}, movedField, newIndex);
|
|
639
909
|
}
|
|
640
910
|
function moveRootFieldToGroup(targetGroupDraftId, fieldDraftId, newIndex) {
|
|
641
|
-
const movedField =
|
|
911
|
+
const movedField = removeFieldFromOwner({
|
|
912
|
+
kind: "root"
|
|
913
|
+
}, fieldDraftId);
|
|
642
914
|
if (!movedField) {
|
|
643
915
|
return;
|
|
644
916
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
650
|
-
const nextFields = group.fields.slice();
|
|
651
|
-
const insertIndex = Math.min(Math.max(newIndex, 0), nextFields.length);
|
|
652
|
-
nextFields.splice(insertIndex, 0, movedField);
|
|
653
|
-
return {
|
|
654
|
-
...group,
|
|
655
|
-
fields: nextFields
|
|
656
|
-
};
|
|
657
|
-
});
|
|
917
|
+
insertFieldIntoOwner({
|
|
918
|
+
kind: "group",
|
|
919
|
+
draftId: targetGroupDraftId
|
|
920
|
+
}, movedField, newIndex);
|
|
658
921
|
}
|
|
659
922
|
async function refreshSortable() {
|
|
660
923
|
for (const sortable of sortables.value) {
|
|
@@ -806,14 +1069,14 @@ function updateDraftStyle(value) {
|
|
|
806
1069
|
draftStyle.value = normalizeOptionalString(String(value));
|
|
807
1070
|
}
|
|
808
1071
|
function updateDraftField(draftId, updater) {
|
|
809
|
-
draftFields.value = draftFields.value
|
|
810
|
-
|
|
1072
|
+
draftFields.value = mapDraftFields(draftFields.value, (item) => item.draftId === draftId ? {
|
|
1073
|
+
...item,
|
|
811
1074
|
field: updater(item.field)
|
|
812
1075
|
} : item);
|
|
813
1076
|
draftGroups.value = draftGroups.value.map((group) => ({
|
|
814
1077
|
...group,
|
|
815
|
-
fields: group.fields
|
|
816
|
-
|
|
1078
|
+
fields: mapDraftFields(group.fields, (item) => item.draftId === draftId ? {
|
|
1079
|
+
...item,
|
|
817
1080
|
field: updater(item.field)
|
|
818
1081
|
} : item)
|
|
819
1082
|
}));
|
|
@@ -834,38 +1097,39 @@ function updateSelectedGroupStyle(value) {
|
|
|
834
1097
|
}
|
|
835
1098
|
function updateSelectedFieldGroup(value) {
|
|
836
1099
|
const selected = selectedField.value;
|
|
837
|
-
const
|
|
838
|
-
|
|
1100
|
+
const sourceOwner = selectedFieldOwner.value;
|
|
1101
|
+
const targetOwner = getFieldOwnerFromValue(value);
|
|
1102
|
+
if (!selected || !sourceOwner || !targetOwner) {
|
|
839
1103
|
return;
|
|
840
1104
|
}
|
|
841
|
-
|
|
842
|
-
if (!targetGroupDraftId) {
|
|
1105
|
+
if (getFieldOwnerValue(sourceOwner) === getFieldOwnerValue(targetOwner)) {
|
|
843
1106
|
return;
|
|
844
1107
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
return;
|
|
848
|
-
}
|
|
849
|
-
moveFieldToRoot(sourceGroup.draftId, selected.draftId, draftFields.value.length);
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
if (sourceGroup && targetGroupDraftId === sourceGroup.draftId) {
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
855
|
-
if (!sourceGroup) {
|
|
856
|
-
moveRootFieldToGroup(targetGroupDraftId, selected.draftId, Number.MAX_SAFE_INTEGER);
|
|
1108
|
+
const movedField = removeFieldFromOwner(sourceOwner, selected.draftId);
|
|
1109
|
+
if (!movedField) {
|
|
857
1110
|
return;
|
|
858
1111
|
}
|
|
859
|
-
|
|
1112
|
+
insertFieldIntoOwner(targetOwner, movedField, getOwnerItemCount(targetOwner));
|
|
860
1113
|
}
|
|
861
|
-
function
|
|
1114
|
+
function getInsertionOwner() {
|
|
1115
|
+
if (selectedField.value?.field.type === "container") {
|
|
1116
|
+
return {
|
|
1117
|
+
kind: "container",
|
|
1118
|
+
draftId: selectedField.value.draftId
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
862
1121
|
if (selectedGroup.value) {
|
|
863
|
-
return
|
|
1122
|
+
return {
|
|
1123
|
+
kind: "group",
|
|
1124
|
+
draftId: selectedGroup.value.draftId
|
|
1125
|
+
};
|
|
864
1126
|
}
|
|
865
|
-
if (
|
|
866
|
-
return
|
|
1127
|
+
if (selectedFieldOwner.value) {
|
|
1128
|
+
return selectedFieldOwner.value;
|
|
867
1129
|
}
|
|
868
|
-
return
|
|
1130
|
+
return {
|
|
1131
|
+
kind: "root"
|
|
1132
|
+
};
|
|
869
1133
|
}
|
|
870
1134
|
function addGroup() {
|
|
871
1135
|
const draftGroup = createDraftGroup(createGroup());
|
|
@@ -875,36 +1139,10 @@ function addGroup() {
|
|
|
875
1139
|
}
|
|
876
1140
|
function addField(type) {
|
|
877
1141
|
const draftField = createDraftField(createField(type));
|
|
878
|
-
const
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
return group;
|
|
883
|
-
}
|
|
884
|
-
if (selectedFieldGroup.value?.draftId === targetGroupDraftId && selectedField.value) {
|
|
885
|
-
const currentIndex = group.fields.findIndex((field) => field.draftId === selectedField.value?.draftId);
|
|
886
|
-
if (currentIndex >= 0) {
|
|
887
|
-
const nextFields = group.fields.slice();
|
|
888
|
-
nextFields.splice(currentIndex + 1, 0, draftField);
|
|
889
|
-
return {
|
|
890
|
-
...group,
|
|
891
|
-
fields: nextFields
|
|
892
|
-
};
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
return {
|
|
896
|
-
...group,
|
|
897
|
-
fields: [...group.fields, draftField]
|
|
898
|
-
};
|
|
899
|
-
});
|
|
900
|
-
} else if (selectedField.value && !selectedFieldGroup.value) {
|
|
901
|
-
const currentIndex = draftFields.value.findIndex((field) => field.draftId === selectedField.value?.draftId);
|
|
902
|
-
const nextFields = draftFields.value.slice();
|
|
903
|
-
nextFields.splice(currentIndex >= 0 ? currentIndex + 1 : nextFields.length, 0, draftField);
|
|
904
|
-
draftFields.value = nextFields;
|
|
905
|
-
} else {
|
|
906
|
-
draftFields.value = [...draftFields.value, draftField];
|
|
907
|
-
}
|
|
1142
|
+
const targetOwner = getInsertionOwner();
|
|
1143
|
+
const ownerFields = getOwnerFields(targetOwner);
|
|
1144
|
+
const currentIndex = selectedField.value && selectedFieldOwner.value && getFieldOwnerValue(selectedFieldOwner.value) === getFieldOwnerValue(targetOwner) && selectedField.value.field.type !== "container" ? ownerFields.findIndex((field) => field.draftId === selectedField.value?.draftId) : -1;
|
|
1145
|
+
insertFieldIntoOwner(targetOwner, draftField, currentIndex >= 0 ? currentIndex + 1 : ownerFields.length);
|
|
908
1146
|
selectedItemId.value = draftField.draftId;
|
|
909
1147
|
clearFieldErrors(draftField.draftId);
|
|
910
1148
|
}
|
|
@@ -919,7 +1157,7 @@ function deleteGroup(itemId) {
|
|
|
919
1157
|
if (deletedGroup) {
|
|
920
1158
|
clearFieldErrors(deletedGroup.draftId);
|
|
921
1159
|
for (const field of deletedGroup.fields) {
|
|
922
|
-
|
|
1160
|
+
clearNestedFieldErrors(field);
|
|
923
1161
|
}
|
|
924
1162
|
}
|
|
925
1163
|
if (selectedItemId.value !== itemId) {
|
|
@@ -929,30 +1167,33 @@ function deleteGroup(itemId) {
|
|
|
929
1167
|
selectedItemId.value = nextGroup?.draftId ?? "general";
|
|
930
1168
|
}
|
|
931
1169
|
function deleteField(itemId) {
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
}
|
|
945
|
-
const nextFields = group.fields.filter((field) => field.draftId !== itemId);
|
|
946
|
-
const nextField = nextFields[deleteIndex] ?? nextFields[deleteIndex - 1];
|
|
947
|
-
nextSelectedItemId = nextField?.draftId ?? group.draftId;
|
|
948
|
-
return {
|
|
949
|
-
...group,
|
|
950
|
-
fields: nextFields
|
|
951
|
-
};
|
|
952
|
-
});
|
|
1170
|
+
const owner = selectedItemId.value === itemId ? selectedFieldOwner.value : findFieldOwnerByDraftId(itemId);
|
|
1171
|
+
if (!owner) {
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
const currentFields = getOwnerFields(owner);
|
|
1175
|
+
const deleteIndex = currentFields.findIndex((field) => field.draftId === itemId);
|
|
1176
|
+
if (deleteIndex < 0) {
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
1179
|
+
removeFieldFromOwner(owner, itemId);
|
|
1180
|
+
const nextFields = getOwnerFields(owner);
|
|
1181
|
+
const nextField = nextFields[deleteIndex] ?? nextFields[deleteIndex - 1];
|
|
953
1182
|
clearFieldErrors(itemId);
|
|
954
1183
|
if (selectedItemId.value === itemId) {
|
|
955
|
-
|
|
1184
|
+
if (nextField) {
|
|
1185
|
+
selectedItemId.value = nextField.draftId;
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
if (owner.kind === "group") {
|
|
1189
|
+
selectedItemId.value = owner.draftId;
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
if (owner.kind === "container") {
|
|
1193
|
+
selectedItemId.value = owner.draftId;
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
selectedItemId.value = "general";
|
|
956
1197
|
}
|
|
957
1198
|
}
|
|
958
1199
|
function handleAddItem(type) {
|
|
@@ -963,7 +1204,10 @@ function handleAddItem(type) {
|
|
|
963
1204
|
addField(type);
|
|
964
1205
|
}
|
|
965
1206
|
function isFieldLabelConfigurable(field) {
|
|
966
|
-
return
|
|
1207
|
+
return hasFieldLabel(field);
|
|
1208
|
+
}
|
|
1209
|
+
function hasDirectFieldStyle(field) {
|
|
1210
|
+
return field.type !== "container";
|
|
967
1211
|
}
|
|
968
1212
|
function getFieldHideLabelValue(field) {
|
|
969
1213
|
if (!isFieldLabelConfigurable(field)) {
|
|
@@ -973,14 +1217,14 @@ function getFieldHideLabelValue(field) {
|
|
|
973
1217
|
}
|
|
974
1218
|
function updateSelectedFieldTitle(value) {
|
|
975
1219
|
const selected = selectedField.value;
|
|
976
|
-
if (!selected) {
|
|
1220
|
+
if (!selected || !hasFieldLabel(selected.field)) {
|
|
977
1221
|
return;
|
|
978
1222
|
}
|
|
979
1223
|
clearFieldError(selected.draftId, "title");
|
|
980
|
-
updateDraftField(selected.draftId, (field) => ({
|
|
1224
|
+
updateDraftField(selected.draftId, (field) => hasFieldLabel(field) ? {
|
|
981
1225
|
...field,
|
|
982
1226
|
title: value
|
|
983
|
-
})
|
|
1227
|
+
} : field);
|
|
984
1228
|
}
|
|
985
1229
|
function updateSelectedFieldHideLabel(value) {
|
|
986
1230
|
const selected = selectedField.value;
|
|
@@ -999,15 +1243,25 @@ function updateSelectedFieldHideLabel(value) {
|
|
|
999
1243
|
}
|
|
1000
1244
|
function updateSelectedMarkdownLocale(value) {
|
|
1001
1245
|
const selected = selectedField.value;
|
|
1002
|
-
if (!selected || selected.field
|
|
1246
|
+
if (!selected || !isMarkdownContentField(selected.field)) {
|
|
1003
1247
|
return;
|
|
1004
1248
|
}
|
|
1005
1249
|
clearFieldError(selected.draftId, "locale");
|
|
1006
|
-
updateDraftField(selected.draftId, (field) => field
|
|
1250
|
+
updateDraftField(selected.draftId, (field) => isMarkdownContentField(field) ? {
|
|
1007
1251
|
...field,
|
|
1008
1252
|
locale: value
|
|
1009
1253
|
} : field);
|
|
1010
1254
|
}
|
|
1255
|
+
function updateSelectedMarkdownInline(value) {
|
|
1256
|
+
const selected = selectedField.value;
|
|
1257
|
+
if (!selected || !isMarkdownBodyField(selected.field)) {
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
updateDraftField(selected.draftId, (field) => isMarkdownBodyField(field) ? {
|
|
1261
|
+
...field,
|
|
1262
|
+
inline: value ? true : void 0
|
|
1263
|
+
} : field);
|
|
1264
|
+
}
|
|
1011
1265
|
function updateSelectedFieldId(value) {
|
|
1012
1266
|
const selected = selectedField.value;
|
|
1013
1267
|
if (!selected || selected.field.type !== "slot") {
|
|
@@ -1042,36 +1296,73 @@ function updateSelectedFieldPath(value) {
|
|
|
1042
1296
|
}
|
|
1043
1297
|
function updateSelectedFieldStyle(value) {
|
|
1044
1298
|
const selected = selectedField.value;
|
|
1045
|
-
if (!selected) {
|
|
1299
|
+
if (!selected || !hasDirectFieldStyle(selected.field)) {
|
|
1046
1300
|
return;
|
|
1047
1301
|
}
|
|
1048
1302
|
clearFieldError(selected.draftId, "style");
|
|
1049
|
-
updateDraftField(selected.draftId, (field) =>
|
|
1303
|
+
updateDraftField(selected.draftId, (field) => {
|
|
1304
|
+
if (!hasDirectFieldStyle(field)) {
|
|
1305
|
+
return field;
|
|
1306
|
+
}
|
|
1307
|
+
return {
|
|
1308
|
+
...field,
|
|
1309
|
+
style: normalizeOptionalString(String(value))
|
|
1310
|
+
};
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
function updateSelectedContainerBodyOrientation(value) {
|
|
1314
|
+
const selected = selectedField.value;
|
|
1315
|
+
if (!selected || selected.field.type !== "container") {
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
const normalizedValue = normalizeOrientation(value);
|
|
1319
|
+
updateDraftField(selected.draftId, (field) => field.type === "container" ? {
|
|
1050
1320
|
...field,
|
|
1051
|
-
|
|
1052
|
-
})
|
|
1321
|
+
bodyOrientation: normalizedValue === "horizontal" ? void 0 : normalizedValue
|
|
1322
|
+
} : field);
|
|
1323
|
+
}
|
|
1324
|
+
function updateSelectedContainerBodyBordered(value) {
|
|
1325
|
+
const selected = selectedField.value;
|
|
1326
|
+
if (!selected || selected.field.type !== "container") {
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1329
|
+
updateDraftField(selected.draftId, (field) => field.type === "container" ? {
|
|
1330
|
+
...field,
|
|
1331
|
+
bodyBordered: value ? true : void 0
|
|
1332
|
+
} : field);
|
|
1333
|
+
}
|
|
1334
|
+
function updateSelectedContainerBodyStyle(value) {
|
|
1335
|
+
const selected = selectedField.value;
|
|
1336
|
+
if (!selected || selected.field.type !== "container") {
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
clearFieldError(selected.draftId, "bodyStyle");
|
|
1340
|
+
updateDraftField(selected.draftId, (field) => field.type === "container" ? {
|
|
1341
|
+
...field,
|
|
1342
|
+
bodyStyle: normalizeOptionalString(String(value))
|
|
1343
|
+
} : field);
|
|
1053
1344
|
}
|
|
1054
1345
|
function updateSelectedFieldLabelStyle(value) {
|
|
1055
1346
|
const selected = selectedField.value;
|
|
1056
|
-
if (!selected ||
|
|
1347
|
+
if (!selected || !supportsFieldCellStyles(selected.field)) {
|
|
1057
1348
|
return;
|
|
1058
1349
|
}
|
|
1059
1350
|
clearFieldError(selected.draftId, "labelStyle");
|
|
1060
|
-
updateDraftField(selected.draftId, (field) =>
|
|
1351
|
+
updateDraftField(selected.draftId, (field) => supportsFieldCellStyles(field) ? {
|
|
1061
1352
|
...field,
|
|
1062
1353
|
labelStyle: normalizeOptionalString(String(value))
|
|
1063
|
-
});
|
|
1354
|
+
} : field);
|
|
1064
1355
|
}
|
|
1065
1356
|
function updateSelectedFieldContentStyle(value) {
|
|
1066
1357
|
const selected = selectedField.value;
|
|
1067
|
-
if (!selected ||
|
|
1358
|
+
if (!selected || !supportsFieldCellStyles(selected.field)) {
|
|
1068
1359
|
return;
|
|
1069
1360
|
}
|
|
1070
1361
|
clearFieldError(selected.draftId, "contentStyle");
|
|
1071
|
-
updateDraftField(selected.draftId, (field) =>
|
|
1362
|
+
updateDraftField(selected.draftId, (field) => supportsFieldCellStyles(field) ? {
|
|
1072
1363
|
...field,
|
|
1073
1364
|
contentStyle: normalizeOptionalString(String(value))
|
|
1074
|
-
});
|
|
1365
|
+
} : field);
|
|
1075
1366
|
}
|
|
1076
1367
|
function updateSelectedFieldHidden(value) {
|
|
1077
1368
|
const selected = selectedField.value;
|
|
@@ -1108,17 +1399,17 @@ function updateSelectedFieldInitialValue(value) {
|
|
|
1108
1399
|
}
|
|
1109
1400
|
function updateSelectedFieldRequired(value) {
|
|
1110
1401
|
const selected = selectedField.value;
|
|
1111
|
-
if (!selected || !isInteractiveField(selected.field)) {
|
|
1402
|
+
if (!selected || selected.field.type !== "slot" && selected.field.type !== "container" && !isInteractiveField(selected.field)) {
|
|
1112
1403
|
return;
|
|
1113
1404
|
}
|
|
1114
1405
|
updateDraftField(selected.draftId, (field) => {
|
|
1115
|
-
if (
|
|
1116
|
-
return
|
|
1406
|
+
if (field.type === "slot" || field.type === "container" || isInteractiveField(field)) {
|
|
1407
|
+
return {
|
|
1408
|
+
...field,
|
|
1409
|
+
required: value ? true : void 0
|
|
1410
|
+
};
|
|
1117
1411
|
}
|
|
1118
|
-
return
|
|
1119
|
-
...field,
|
|
1120
|
-
required: value ? true : void 0
|
|
1121
|
-
};
|
|
1412
|
+
return field;
|
|
1122
1413
|
});
|
|
1123
1414
|
}
|
|
1124
1415
|
function updateSelectedStringDiscardEmpty(value) {
|
|
@@ -1566,6 +1857,10 @@ function getSchemaIssues(field) {
|
|
|
1566
1857
|
const result = MarkdownFieldC.safeParse(field);
|
|
1567
1858
|
return result.success ? [] : result.error.issues;
|
|
1568
1859
|
}
|
|
1860
|
+
case "markdown-body": {
|
|
1861
|
+
const result = MarkdownBodyFieldC.safeParse(field);
|
|
1862
|
+
return result.success ? [] : result.error.issues;
|
|
1863
|
+
}
|
|
1569
1864
|
case "select": {
|
|
1570
1865
|
const result = SelectFieldC.safeParse(field);
|
|
1571
1866
|
return result.success ? [] : result.error.issues;
|
|
@@ -1586,6 +1881,10 @@ function getSchemaIssues(field) {
|
|
|
1586
1881
|
const result = SlotFieldC.safeParse(field);
|
|
1587
1882
|
return result.success ? [] : result.error.issues;
|
|
1588
1883
|
}
|
|
1884
|
+
case "container": {
|
|
1885
|
+
const result = ContainerFieldC.safeParse(field);
|
|
1886
|
+
return result.success ? [] : result.error.issues;
|
|
1887
|
+
}
|
|
1589
1888
|
case "empty": {
|
|
1590
1889
|
const result = EmptyFieldC.safeParse(field);
|
|
1591
1890
|
return result.success ? [] : result.error.issues;
|
|
@@ -1621,9 +1920,32 @@ function normalizeGroup(group) {
|
|
|
1621
1920
|
return {
|
|
1622
1921
|
...group,
|
|
1623
1922
|
style: normalizeOptionalString(group.style ?? ""),
|
|
1624
|
-
fields: group.fields
|
|
1923
|
+
fields: group.fields
|
|
1924
|
+
};
|
|
1925
|
+
}
|
|
1926
|
+
function normalizeDraftField(item) {
|
|
1927
|
+
const normalizedField = normalizeField(item.field);
|
|
1928
|
+
return {
|
|
1929
|
+
...item,
|
|
1930
|
+
field: normalizedField,
|
|
1931
|
+
children: item.children.map((child) => normalizeDraftField(child))
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
function buildFieldFromDraft(item) {
|
|
1935
|
+
if (item.field.type !== "container") {
|
|
1936
|
+
return item.field;
|
|
1937
|
+
}
|
|
1938
|
+
return {
|
|
1939
|
+
...item.field,
|
|
1940
|
+
fields: item.children.map((child) => buildFieldFromDraft(child))
|
|
1625
1941
|
};
|
|
1626
1942
|
}
|
|
1943
|
+
function clearNestedFieldErrors(item) {
|
|
1944
|
+
clearFieldErrors(item.draftId);
|
|
1945
|
+
for (const child of item.children) {
|
|
1946
|
+
clearNestedFieldErrors(child);
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1627
1949
|
function validateDraftFields(fields, errors, idOwners, pathOwners) {
|
|
1628
1950
|
let firstInvalidItemId;
|
|
1629
1951
|
for (const item of fields) {
|
|
@@ -1661,25 +1983,21 @@ function validateDraftFields(fields, errors, idOwners, pathOwners) {
|
|
|
1661
1983
|
setError(errors, issueKey, getSchemaIssueMessage(issue, issuePath));
|
|
1662
1984
|
firstInvalidItemId = firstInvalidItemId ?? item.draftId;
|
|
1663
1985
|
}
|
|
1986
|
+
const childInvalidItemId = validateDraftFields(item.children, errors, idOwners, pathOwners);
|
|
1987
|
+
firstInvalidItemId = firstInvalidItemId ?? childInvalidItemId;
|
|
1664
1988
|
}
|
|
1665
1989
|
return firstInvalidItemId;
|
|
1666
1990
|
}
|
|
1667
1991
|
function validateDraftState() {
|
|
1668
1992
|
const errors = {};
|
|
1669
|
-
const normalizedFields = draftFields.value.map((item) => (
|
|
1670
|
-
draftId: item.draftId,
|
|
1671
|
-
field: normalizeField(item.field)
|
|
1672
|
-
}));
|
|
1993
|
+
const normalizedFields = draftFields.value.map((item) => normalizeDraftField(item));
|
|
1673
1994
|
const normalizedGroups = draftGroups.value.map((group) => ({
|
|
1674
1995
|
draftId: group.draftId,
|
|
1675
1996
|
group: normalizeGroup({
|
|
1676
1997
|
...group.group,
|
|
1677
|
-
fields: group.fields.map((item) => item
|
|
1998
|
+
fields: group.fields.map((item) => buildFieldFromDraft(normalizeDraftField(item)))
|
|
1678
1999
|
}),
|
|
1679
|
-
fields: group.fields.map((item) => (
|
|
1680
|
-
draftId: item.draftId,
|
|
1681
|
-
field: normalizeField(item.field)
|
|
1682
|
-
}))
|
|
2000
|
+
fields: group.fields.map((item) => normalizeDraftField(item))
|
|
1683
2001
|
}));
|
|
1684
2002
|
const groupIdOwners = {};
|
|
1685
2003
|
const idOwners = {};
|
|
@@ -1741,10 +2059,10 @@ function buildDraftConfig() {
|
|
|
1741
2059
|
return void 0;
|
|
1742
2060
|
}
|
|
1743
2061
|
const nextBody = {
|
|
1744
|
-
fields: validatedDraftState.normalizedFields.map((item) => item
|
|
2062
|
+
fields: validatedDraftState.normalizedFields.map((item) => buildFieldFromDraft(item)),
|
|
1745
2063
|
groups: validatedDraftState.normalizedGroups.map((group) => ({
|
|
1746
2064
|
...group.group,
|
|
1747
|
-
fields: group.fields.map((item) => item
|
|
2065
|
+
fields: group.fields.map((item) => buildFieldFromDraft(item))
|
|
1748
2066
|
}))
|
|
1749
2067
|
};
|
|
1750
2068
|
if (draftOrientation.value !== "horizontal") {
|
|
@@ -1825,13 +2143,16 @@ function buildDslGuideMarkdown() {
|
|
|
1825
2143
|
"### 3. \u5B57\u6BB5\u7C7B\u578B\u7EA6\u675F",
|
|
1826
2144
|
"- \u9876\u5C42\u914D\u7F6E\u53EF\u4EE5\u76F4\u63A5\u4F7F\u7528 `fields` \u653E\u6839\u7EA7\u5B57\u6BB5\uFF0C\u4E5F\u53EF\u4EE5\u4F7F\u7528 `groups` \u653E\u5206\u7EC4\u5B57\u6BB5\uFF0C\u4E24\u8005\u53EF\u4EE5\u540C\u65F6\u5B58\u5728\u3002",
|
|
1827
2145
|
"- \u6BCF\u4E2A\u5B57\u6BB5\u7EC4\u90FD\u5FC5\u987B\u5305\u542B\u552F\u4E00\u4E14\u5408\u6CD5\u7684 UUID `id`\u3002",
|
|
1828
|
-
"- \u5B57\u6BB5\u7EC4\u53EA\u8D1F\u8D23\u7ED3\u6784\u4E0E\u6837\u5F0F\uFF0C\u4E0D\u63D0\u4F9B\u6807\u9898\uFF1B\u5206\u7EC4\u8BF4\u660E\
|
|
2146
|
+
"- \u5B57\u6BB5\u7EC4\u53EA\u8D1F\u8D23\u7ED3\u6784\u4E0E\u6837\u5F0F\uFF0C\u4E0D\u63D0\u4F9B\u6807\u9898\uFF1B\u5206\u7EC4\u8BF4\u660E\u4F18\u5148\u4F7F\u7528 `markdown-body` \u5B57\u6BB5\uFF0C\u82E5\u9700\u8981\u6807\u7B7E\u884C\u518D\u4F7F\u7528 `markdown` \u5B57\u6BB5\u3002",
|
|
1829
2147
|
"- \u4EE3\u7801\u91CC\u5E94\u5148\u751F\u6210\u5E76\u4F7F\u7528 UUID\uFF0C\u518D\u628A\u540C\u4E00\u4E2A `id` \u7C98\u8D34\u56DE\u5B57\u6BB5\u914D\u7F6E\u3002",
|
|
1830
2148
|
"- \u6240\u6709\u5B57\u6BB5\u90FD\u5FC5\u987B\u5305\u542B\u552F\u4E00\u4E14\u5408\u6CD5\u7684 UUID `id`\u3002",
|
|
1831
2149
|
"- \u53EA\u6709\u53EF\u7ED1\u5B9A\u503C\u7684\u5B57\u6BB5\u53EF\u4EE5\u914D\u7F6E `path`\uFF0C\u5E76\u53C2\u4E0E\u8868\u5355\u503C\u8BFB\u5199\u3002",
|
|
1832
|
-
"- `slot` \
|
|
2150
|
+
"- `slot` \u5B57\u6BB5\u4E0D\u4F1A\u7ED1\u5B9A\u6A21\u578B\u503C\uFF1B\u53EF\u9009 `title`\u3001`hideLabel`\u3001`required`\u3001`hidden`\u3001`labelStyle`\u3001`contentStyle` \u4E0E `style`\u3002",
|
|
2151
|
+
"- `container` \u5B57\u6BB5\u4E0D\u4F1A\u7ED1\u5B9A\u6A21\u578B\u503C\uFF1B\u4F7F\u7528 `fields` \u627F\u8F7D\u9012\u5F52\u5D4C\u5957\u5B57\u6BB5\uFF0C\u53EF\u9009 `bodyOrientation`\u3001`bodyBordered` \u4E0E `bodyStyle` \u63A7\u5236\u5185\u90E8\u5E03\u5C40\u3002",
|
|
2152
|
+
"- `empty` \u5B57\u6BB5\u4E0D\u4F1A\u7ED1\u5B9A\u6A21\u578B\u503C\uFF0C\u53EA\u5141\u8BB8 `id`\u3001`type` \u548C\u53EF\u9009\u7684 `style`\u3002",
|
|
1833
2153
|
"- `markdown` \u5B57\u6BB5\u4F7F\u7528 `title` \u4E0E `locale` \u5C55\u793A\u5E26\u6807\u7B7E\u7684 Markdown \u5185\u5BB9\uFF0C\u4E0D\u7ED1\u5B9A `path`\u3002",
|
|
1834
|
-
"-
|
|
2154
|
+
"- `markdown-body` \u5B57\u6BB5\u4F7F\u7528 `locale` \u5C55\u793A\u65E0\u6807\u7B7E\u7684\u7EAF Markdown \u5185\u5BB9\uFF0C\u53EF\u9009 `inline` \u63A7\u5236\u5185\u8054\u6E32\u67D3\uFF0C\u4E0D\u7ED1\u5B9A `path`\u3002",
|
|
2155
|
+
"- \u9664 `empty` \u4E0E `markdown-body` \u5916\uFF0C\u5176\u5B83\u5E26\u6807\u7B7E\u5B57\u6BB5\u90FD\u53EF\u4EE5\u8BBE\u7F6E `hideLabel` \u9690\u85CF\u6807\u7B7E\u3002",
|
|
1835
2156
|
"- \u666E\u901A\u5B57\u6BB5\u53EF\u989D\u5916\u4F7F\u7528 `labelStyle` \u4E0E `contentStyle`\uFF0C\u7528\u4E8E contents \u5E03\u5C40\u6A21\u5F0F\u4E0B\u5206\u522B\u63A7\u5236\u6807\u7B7E\u4E0E\u5185\u5BB9\u5355\u5143\u683C\u3002"
|
|
1836
2157
|
].join("\n");
|
|
1837
2158
|
}
|
|
@@ -1842,10 +2163,13 @@ function buildMarkdownNotes() {
|
|
|
1842
2163
|
"- \u5148\u5728\u4EE3\u7801\u91CC\u751F\u6210\u5E76\u4F7F\u7528 UUID\uFF0C\u518D\u628A\u540C\u4E00\u4E2A `id` \u7C98\u8D34\u5230\u5B57\u6BB5\u914D\u7F6E\u4E2D\u3002",
|
|
1843
2164
|
"- \u6240\u6709\u5B57\u6BB5\u7EC4 `id` \u90FD\u5FC5\u987B\u552F\u4E00\u4E14\u7B26\u5408 UUID \u683C\u5F0F\u3002",
|
|
1844
2165
|
"- \u6240\u6709\u5B57\u6BB5 `id` \u90FD\u5FC5\u987B\u552F\u4E00\u4E14\u7B26\u5408 UUID \u683C\u5F0F\u3002",
|
|
1845
|
-
"- \u5B57\u6BB5\u7EC4\u6CA1\u6709\u6807\u9898\uFF1B\u5982\u679C\u9700\u8981\u5206\u6BB5\u6807\u9898\u6216\u8BF4\u660E\uFF0C\
|
|
1846
|
-
"- `slot` \
|
|
1847
|
-
"- `
|
|
1848
|
-
"-
|
|
2166
|
+
"- \u5B57\u6BB5\u7EC4\u6CA1\u6709\u6807\u9898\uFF1B\u5982\u679C\u9700\u8981\u5206\u6BB5\u6807\u9898\u6216\u8BF4\u660E\uFF0C\u4F18\u5148\u63D2\u5165 `markdown-body` \u5B57\u6BB5\uFF1B\u9700\u8981\u6807\u7B7E\u884C\u65F6\u518D\u4F7F\u7528 `markdown` \u5B57\u6BB5\u3002",
|
|
2167
|
+
"- `slot` \u5B57\u6BB5\u4E0D\u7ED1\u5B9A `path`\uFF0C\u53EF\u9009 `title`\u3001`hideLabel`\u3001`required`\u3001`hidden`\u3001`labelStyle`\u3001`contentStyle` \u4E0E `style`\u3002",
|
|
2168
|
+
"- `container` \u5B57\u6BB5\u4E0D\u7ED1\u5B9A `path`\uFF0C\u901A\u8FC7 `fields` \u9012\u5F52\u5D4C\u5957\u5B50\u5B57\u6BB5\uFF0C\u4E0D\u652F\u6301\u5D4C\u5957 `groups`\u3002",
|
|
2169
|
+
"- `empty` \u5B57\u6BB5\u53EA\u80FD\u4F7F\u7528 `id`\u3001`type` \u548C\u53EF\u9009\u7684 `style`\u3002",
|
|
2170
|
+
"- `markdown` \u5B57\u6BB5\u4E0D\u4F7F\u7528 `path`\uFF0C\u5185\u5BB9\u6765\u81EA `title` \u4E0E `locale` \u672C\u5730\u5316 Markdown\u3002",
|
|
2171
|
+
"- `markdown-body` \u5B57\u6BB5\u4E0D\u4F7F\u7528 `path`\uFF0C\u5185\u5BB9\u6765\u81EA `locale` \u672C\u5730\u5316 Markdown\uFF0C\u53EF\u9009 `inline` \u63A7\u5236\u6E32\u67D3\u65B9\u5F0F\u3002",
|
|
2172
|
+
"- \u9664 `empty` \u4E0E `markdown-body` \u5916\uFF0C\u5176\u5B83\u5E26\u6807\u7B7E\u5B57\u6BB5\u90FD\u53EF\u4EE5\u8BBE\u7F6E `hideLabel`\u3002",
|
|
1849
2173
|
"- \u666E\u901A\u5B57\u6BB5\u5728 contents \u5E03\u5C40\u6A21\u5F0F\u4E0B\u53EF\u989D\u5916\u4F7F\u7528 `labelStyle` \u4E0E `contentStyle`\u3002",
|
|
1850
2174
|
"- \u53EA\u6709\u5E26 `path` \u7684\u5B57\u6BB5\u624D\u8981\u6C42 `path` \u552F\u4E00\u4E14\u4E0D\u80FD\u4E3A\u7A7A\u3002",
|
|
1851
2175
|
"- \u8868\u8FBE\u5F0F\u5B57\u6BB5\u5FC5\u987B\u4E25\u683C\u9075\u5B88 schema \u7EA6\u675F\uFF1B\u5982\u679C schema \u4E0D\u652F\u6301\uFF0C\u5C31\u76F4\u63A5\u8BF4\u660E\u9650\u5236\u3002"
|
|
@@ -2004,10 +2328,10 @@ function confirmChanges() {
|
|
|
2004
2328
|
if (!result) {
|
|
2005
2329
|
return;
|
|
2006
2330
|
}
|
|
2007
|
-
draftFields.value = result.normalizedFields.map((item) => createDraftField(item
|
|
2331
|
+
draftFields.value = result.normalizedFields.map((item) => createDraftField(buildFieldFromDraft(item)));
|
|
2008
2332
|
draftGroups.value = result.normalizedGroups.map((group) => createDraftGroup({
|
|
2009
2333
|
...group.group,
|
|
2010
|
-
fields: group.fields.map((item) => item
|
|
2334
|
+
fields: group.fields.map((item) => buildFieldFromDraft(item))
|
|
2011
2335
|
}));
|
|
2012
2336
|
emit("confirm", result.config);
|
|
2013
2337
|
open.value = false;
|
|
@@ -2117,6 +2441,7 @@ function confirmChanges() {
|
|
|
2117
2441
|
:data-field-id="item.fieldId"
|
|
2118
2442
|
:data-field-path="item.path"
|
|
2119
2443
|
:data-selected="selectedItemId === item.itemId ? 'true' : 'false'"
|
|
2444
|
+
:style="{ paddingLeft: `${item.depth * 12 + 4}px` }"
|
|
2120
2445
|
:class="cn(
|
|
2121
2446
|
'flex min-w-0 items-center gap-2 rounded-md border p-1 transition-colors',
|
|
2122
2447
|
selectedItemId === item.itemId ? 'border-(--primary)/25 bg-[color-mix(in_srgb,var(--primary)_10%,white)]' : 'border-transparent hover:border-zinc-200 hover:bg-zinc-50'
|
|
@@ -2229,8 +2554,9 @@ function confirmChanges() {
|
|
|
2229
2554
|
:data-field-id="item.fieldId"
|
|
2230
2555
|
:data-field-path="item.path"
|
|
2231
2556
|
:data-selected="selectedItemId === item.itemId ? 'true' : 'false'"
|
|
2557
|
+
:style="{ paddingLeft: `${item.depth * 12 + 16}px` }"
|
|
2232
2558
|
:class="cn(
|
|
2233
|
-
'flex min-w-0 items-center gap-2 rounded-md border p-1
|
|
2559
|
+
'flex min-w-0 items-center gap-2 rounded-md border p-1 transition-colors',
|
|
2234
2560
|
selectedItemId === item.itemId ? 'border-(--primary)/25 bg-[color-mix(in_srgb,var(--primary)_10%,white)]' : 'border-transparent hover:border-zinc-200 hover:bg-zinc-50'
|
|
2235
2561
|
)"
|
|
2236
2562
|
>
|
|
@@ -2496,25 +2822,22 @@ function confirmChanges() {
|
|
|
2496
2822
|
</span>
|
|
2497
2823
|
<NativeSelect
|
|
2498
2824
|
data-slot="fields-configurator-field-group-select"
|
|
2499
|
-
:model-value="
|
|
2825
|
+
:model-value="selectedFieldOwner ? getFieldOwnerValue(selectedFieldOwner) : ROOT_FIELD_GROUP_VALUE"
|
|
2500
2826
|
@update:model-value="updateSelectedFieldGroup"
|
|
2501
2827
|
>
|
|
2502
|
-
<NativeSelectOption :value="ROOT_FIELD_GROUP_VALUE">
|
|
2503
|
-
{{ t("field-group-none") }}
|
|
2504
|
-
</NativeSelectOption>
|
|
2505
2828
|
<NativeSelectOption
|
|
2506
|
-
v-for="
|
|
2507
|
-
:key="
|
|
2508
|
-
:value="
|
|
2829
|
+
v-for="option in selectedFieldOwnerOptions"
|
|
2830
|
+
:key="option.value"
|
|
2831
|
+
:value="option.value"
|
|
2509
2832
|
>
|
|
2510
|
-
{{
|
|
2833
|
+
{{ option.label }}
|
|
2511
2834
|
</NativeSelectOption>
|
|
2512
2835
|
</NativeSelect>
|
|
2513
2836
|
</label>
|
|
2514
2837
|
</section>
|
|
2515
2838
|
|
|
2516
2839
|
<section
|
|
2517
|
-
v-if="
|
|
2840
|
+
v-if="hasFieldLabel(selectedField.field)"
|
|
2518
2841
|
data-slot="fields-configurator-field-label-section"
|
|
2519
2842
|
class="flex flex-col gap-2"
|
|
2520
2843
|
>
|
|
@@ -2524,7 +2847,7 @@ function confirmChanges() {
|
|
|
2524
2847
|
|
|
2525
2848
|
<Locale
|
|
2526
2849
|
data-slot="fields-configurator-field-title-locale"
|
|
2527
|
-
:model-value="selectedField.field
|
|
2850
|
+
:model-value="getFieldTitleValue(selectedField.field)"
|
|
2528
2851
|
@update:model-value="updateSelectedFieldTitle"
|
|
2529
2852
|
/>
|
|
2530
2853
|
|
|
@@ -2538,7 +2861,7 @@ function confirmChanges() {
|
|
|
2538
2861
|
</section>
|
|
2539
2862
|
|
|
2540
2863
|
<section
|
|
2541
|
-
v-if="selectedField.field
|
|
2864
|
+
v-if="isMarkdownContentField(selectedField.field)"
|
|
2542
2865
|
data-slot="fields-configurator-field-markdown-section"
|
|
2543
2866
|
class="flex flex-col gap-2"
|
|
2544
2867
|
>
|
|
@@ -2565,6 +2888,21 @@ function confirmChanges() {
|
|
|
2565
2888
|
>
|
|
2566
2889
|
{{ validationErrors[getFieldErrorKey(selectedField.draftId, "locale")] }}
|
|
2567
2890
|
</p>
|
|
2891
|
+
|
|
2892
|
+
<label
|
|
2893
|
+
v-if="isMarkdownBodyField(selectedField.field)"
|
|
2894
|
+
class="flex items-center justify-between gap-3 rounded-md border border-zinc-200 px-3 py-2"
|
|
2895
|
+
>
|
|
2896
|
+
<div class="flex flex-col gap-1">
|
|
2897
|
+
<span class="text-sm font-medium text-zinc-800">{{ t("field-markdown-inline") }}</span>
|
|
2898
|
+
<span class="text-xs text-zinc-500">{{ t("field-markdown-inline-description") }}</span>
|
|
2899
|
+
</div>
|
|
2900
|
+
<Switch
|
|
2901
|
+
data-slot="fields-configurator-field-markdown-inline-switch"
|
|
2902
|
+
:model-value="selectedField.field.inline ?? false"
|
|
2903
|
+
@update:model-value="updateSelectedMarkdownInline"
|
|
2904
|
+
/>
|
|
2905
|
+
</label>
|
|
2568
2906
|
</section>
|
|
2569
2907
|
|
|
2570
2908
|
<section
|
|
@@ -2599,7 +2937,7 @@ function confirmChanges() {
|
|
|
2599
2937
|
class="grid gap-4 md:grid-cols-2"
|
|
2600
2938
|
>
|
|
2601
2939
|
<label
|
|
2602
|
-
v-if="isInteractiveField(selectedField.field)"
|
|
2940
|
+
v-if="isInteractiveField(selectedField.field) || selectedField.field.type === 'slot' || selectedField.field.type === 'container'"
|
|
2603
2941
|
class="flex items-center justify-between gap-3 rounded-md border border-zinc-200 px-3 py-2 md:col-span-2"
|
|
2604
2942
|
>
|
|
2605
2943
|
<div class="flex flex-col gap-1">
|
|
@@ -2629,7 +2967,7 @@ function confirmChanges() {
|
|
|
2629
2967
|
</label>
|
|
2630
2968
|
|
|
2631
2969
|
<label
|
|
2632
|
-
v-if="!usesContentsOrientation"
|
|
2970
|
+
v-if="hasDirectFieldStyle(selectedField.field) && (!usesContentsOrientation || isMarkdownBodyField(selectedField.field) || selectedField.field.type === 'slot')"
|
|
2633
2971
|
class="flex flex-col gap-2"
|
|
2634
2972
|
>
|
|
2635
2973
|
<span class="text-xs font-medium text-zinc-500">
|
|
@@ -2637,7 +2975,7 @@ function confirmChanges() {
|
|
|
2637
2975
|
</span>
|
|
2638
2976
|
<Textarea
|
|
2639
2977
|
data-slot="fields-configurator-field-style-input"
|
|
2640
|
-
:model-value="selectedField.field.style ?? ''"
|
|
2978
|
+
:model-value="hasDirectFieldStyle(selectedField.field) ? selectedField.field.style ?? '' : ''"
|
|
2641
2979
|
:aria-invalid="validationErrors[getFieldErrorKey(selectedField.draftId, 'style')] ? 'true' : void 0"
|
|
2642
2980
|
:placeholder="t('field-style-placeholder')"
|
|
2643
2981
|
class="min-h-20 font-mono text-sm"
|
|
@@ -2652,7 +2990,7 @@ function confirmChanges() {
|
|
|
2652
2990
|
</label>
|
|
2653
2991
|
|
|
2654
2992
|
<label
|
|
2655
|
-
v-else
|
|
2993
|
+
v-else-if="supportsFieldCellStyles(selectedField.field)"
|
|
2656
2994
|
class="flex flex-col gap-2"
|
|
2657
2995
|
>
|
|
2658
2996
|
<span class="text-xs font-medium text-zinc-500">
|
|
@@ -2675,7 +3013,7 @@ function confirmChanges() {
|
|
|
2675
3013
|
</label>
|
|
2676
3014
|
|
|
2677
3015
|
<label
|
|
2678
|
-
v-if="usesContentsOrientation"
|
|
3016
|
+
v-if="usesContentsOrientation && supportsFieldCellStyles(selectedField.field)"
|
|
2679
3017
|
class="flex flex-col gap-2"
|
|
2680
3018
|
>
|
|
2681
3019
|
<span class="text-xs font-medium text-zinc-500">
|
|
@@ -2764,6 +3102,99 @@ function confirmChanges() {
|
|
|
2764
3102
|
</label>
|
|
2765
3103
|
</section>
|
|
2766
3104
|
|
|
3105
|
+
<section
|
|
3106
|
+
v-if="selectedField.field.type === 'container'"
|
|
3107
|
+
data-slot="fields-configurator-container-options"
|
|
3108
|
+
class="grid gap-4 md:grid-cols-2"
|
|
3109
|
+
>
|
|
3110
|
+
<label class="flex flex-col gap-2">
|
|
3111
|
+
<span class="text-xs font-medium text-zinc-500">
|
|
3112
|
+
{{ t("container-body-orientation") }}
|
|
3113
|
+
</span>
|
|
3114
|
+
<NativeSelect
|
|
3115
|
+
data-slot="fields-configurator-container-body-orientation-select"
|
|
3116
|
+
:model-value="selectedField.field.bodyOrientation ?? 'horizontal'"
|
|
3117
|
+
@update:model-value="updateSelectedContainerBodyOrientation"
|
|
3118
|
+
>
|
|
3119
|
+
<NativeSelectOption value="horizontal">
|
|
3120
|
+
{{ t("fields-orientation-horizontal") }}
|
|
3121
|
+
</NativeSelectOption>
|
|
3122
|
+
<NativeSelectOption value="vertical">
|
|
3123
|
+
{{ t("fields-orientation-vertical") }}
|
|
3124
|
+
</NativeSelectOption>
|
|
3125
|
+
<NativeSelectOption value="floating">
|
|
3126
|
+
{{ t("fields-orientation-floating") }}
|
|
3127
|
+
</NativeSelectOption>
|
|
3128
|
+
<NativeSelectOption value="contents">
|
|
3129
|
+
{{ t("fields-orientation-contents") }}
|
|
3130
|
+
</NativeSelectOption>
|
|
3131
|
+
</NativeSelect>
|
|
3132
|
+
</label>
|
|
3133
|
+
|
|
3134
|
+
<label class="flex items-center justify-between gap-3 rounded-md border border-zinc-200 px-3 py-2">
|
|
3135
|
+
<div class="flex flex-col gap-1">
|
|
3136
|
+
<span class="text-sm font-medium text-zinc-800">{{ t("container-body-bordered") }}</span>
|
|
3137
|
+
<span class="text-xs text-zinc-500">{{ t("container-body-bordered-description") }}</span>
|
|
3138
|
+
</div>
|
|
3139
|
+
<Switch
|
|
3140
|
+
data-slot="fields-configurator-container-body-bordered-switch"
|
|
3141
|
+
:model-value="selectedField.field.bodyBordered ?? false"
|
|
3142
|
+
@update:model-value="updateSelectedContainerBodyBordered"
|
|
3143
|
+
/>
|
|
3144
|
+
</label>
|
|
3145
|
+
|
|
3146
|
+
<label class="flex flex-col gap-2 md:col-span-2">
|
|
3147
|
+
<span class="text-xs font-medium text-zinc-500">
|
|
3148
|
+
{{ t("container-body-style") }}
|
|
3149
|
+
</span>
|
|
3150
|
+
<Textarea
|
|
3151
|
+
data-slot="fields-configurator-container-body-style-input"
|
|
3152
|
+
:model-value="selectedField.field.bodyStyle ?? ''"
|
|
3153
|
+
:aria-invalid="validationErrors[getFieldErrorKey(selectedField.draftId, 'bodyStyle')] ? 'true' : void 0"
|
|
3154
|
+
:placeholder="t('group-style-placeholder')"
|
|
3155
|
+
class="min-h-20 font-mono text-sm"
|
|
3156
|
+
@update:model-value="updateSelectedContainerBodyStyle"
|
|
3157
|
+
/>
|
|
3158
|
+
<p
|
|
3159
|
+
v-if="validationErrors[getFieldErrorKey(selectedField.draftId, 'bodyStyle')]"
|
|
3160
|
+
class="text-xs text-red-500"
|
|
3161
|
+
>
|
|
3162
|
+
{{ validationErrors[getFieldErrorKey(selectedField.draftId, "bodyStyle")] }}
|
|
3163
|
+
</p>
|
|
3164
|
+
</label>
|
|
3165
|
+
|
|
3166
|
+
<div
|
|
3167
|
+
data-slot="fields-configurator-container-children"
|
|
3168
|
+
class="flex flex-col gap-2 md:col-span-2"
|
|
3169
|
+
>
|
|
3170
|
+
<p class="text-xs font-medium text-zinc-500">
|
|
3171
|
+
{{ t("field-children") }}
|
|
3172
|
+
</p>
|
|
3173
|
+
<div
|
|
3174
|
+
v-if="selectedContainerChildItems.length > 0"
|
|
3175
|
+
class="flex flex-col gap-1"
|
|
3176
|
+
>
|
|
3177
|
+
<button
|
|
3178
|
+
v-for="item in selectedContainerChildItems"
|
|
3179
|
+
:key="item.itemId"
|
|
3180
|
+
type="button"
|
|
3181
|
+
data-slot="fields-configurator-container-child"
|
|
3182
|
+
class="rounded-md border border-zinc-200 px-3 py-2 text-left text-sm text-zinc-700 transition-colors hover:border-zinc-300 hover:bg-zinc-50"
|
|
3183
|
+
:style="{ paddingLeft: `${item.depth * 12 + 12}px` }"
|
|
3184
|
+
@click="selectItem(item.itemId)"
|
|
3185
|
+
>
|
|
3186
|
+
{{ item.label }}
|
|
3187
|
+
</button>
|
|
3188
|
+
</div>
|
|
3189
|
+
<p
|
|
3190
|
+
v-else
|
|
3191
|
+
class="text-xs text-zinc-500"
|
|
3192
|
+
>
|
|
3193
|
+
{{ t("field-children-empty") }}
|
|
3194
|
+
</p>
|
|
3195
|
+
</div>
|
|
3196
|
+
</section>
|
|
3197
|
+
|
|
2767
3198
|
<section
|
|
2768
3199
|
v-if="selectedField.field.type === 'string' || selectedField.field.type === 'textarea'"
|
|
2769
3200
|
data-slot="fields-configurator-string-options"
|
|
@@ -3358,10 +3789,12 @@ function confirmChanges() {
|
|
|
3358
3789
|
"field-type-textarea": "多行文本",
|
|
3359
3790
|
"field-type-number": "数字",
|
|
3360
3791
|
"field-type-markdown": "Markdown",
|
|
3792
|
+
"field-type-markdown-body": "纯 Markdown",
|
|
3361
3793
|
"field-type-select": "选择",
|
|
3362
3794
|
"field-type-radio": "单选按钮组",
|
|
3363
3795
|
"field-type-calendar": "日期",
|
|
3364
3796
|
"field-type-upload": "上传",
|
|
3797
|
+
"field-type-container": "容器",
|
|
3365
3798
|
"field-type-empty": "空白",
|
|
3366
3799
|
"field-type-slot": "插槽",
|
|
3367
3800
|
"field-id": "字段 ID",
|
|
@@ -3379,12 +3812,16 @@ function confirmChanges() {
|
|
|
3379
3812
|
"copy-field-id-failed": "复制字段 ID 失败,请检查剪贴板权限。",
|
|
3380
3813
|
"field-group": "所属分组",
|
|
3381
3814
|
"field-group-none": "不分组",
|
|
3815
|
+
"field-children": "子字段",
|
|
3816
|
+
"field-children-empty": "这个容器还没有子字段。",
|
|
3382
3817
|
"field-label": "字段标题",
|
|
3383
3818
|
"group-style": "分组样式表达式",
|
|
3384
3819
|
"group-style-placeholder": "例如返回一个 style map,例如 display: grid",
|
|
3385
3820
|
"group-style-invalid": "分组样式表达式无效",
|
|
3386
3821
|
"field-markdown-content": "Markdown 内容",
|
|
3387
3822
|
"field-markdown-content-description": "支持 Markdown 编辑,并支持双花括号表达式求值。",
|
|
3823
|
+
"field-markdown-inline": "内联渲染",
|
|
3824
|
+
"field-markdown-inline-description": "开启后使用内联 Markdown 渲染;关闭时按块级 Markdown 渲染。",
|
|
3388
3825
|
"field-required": "显示必填提示",
|
|
3389
3826
|
"field-required-description": "开启后仅在标签后显示红色星号,不会自动添加校验规则。",
|
|
3390
3827
|
"field-hide-label": "隐藏标签",
|
|
@@ -3394,6 +3831,10 @@ function confirmChanges() {
|
|
|
3394
3831
|
"field-style": "样式表达式",
|
|
3395
3832
|
"field-label-style": "标签样式表达式",
|
|
3396
3833
|
"field-content-style": "内容样式表达式",
|
|
3834
|
+
"container-body-orientation": "容器内部布局",
|
|
3835
|
+
"container-body-bordered": "容器内部表格式边框",
|
|
3836
|
+
"container-body-bordered-description": "仅在 contents 布局下生效,用于容器内部字段网格。",
|
|
3837
|
+
"container-body-style": "容器内部样式表达式",
|
|
3397
3838
|
"field-style-placeholder": "例如 width: 100%",
|
|
3398
3839
|
"field-hidden": "隐藏条件",
|
|
3399
3840
|
"field-hidden-placeholder": "返回 true 时隐藏字段",
|
|
@@ -3493,10 +3934,12 @@ function confirmChanges() {
|
|
|
3493
3934
|
"field-type-textarea": "複数行テキスト",
|
|
3494
3935
|
"field-type-number": "数値",
|
|
3495
3936
|
"field-type-markdown": "Markdown",
|
|
3937
|
+
"field-type-markdown-body": "プレーン Markdown",
|
|
3496
3938
|
"field-type-select": "選択",
|
|
3497
3939
|
"field-type-radio": "ラジオグループ",
|
|
3498
3940
|
"field-type-calendar": "日付",
|
|
3499
3941
|
"field-type-upload": "アップロード",
|
|
3942
|
+
"field-type-container": "コンテナ",
|
|
3500
3943
|
"field-type-empty": "空白",
|
|
3501
3944
|
"field-type-slot": "スロット",
|
|
3502
3945
|
"field-id": "フィールド ID",
|
|
@@ -3514,12 +3957,16 @@ function confirmChanges() {
|
|
|
3514
3957
|
"copy-field-id-failed": "フィールド ID のコピーに失敗しました。クリップボード権限を確認してください。",
|
|
3515
3958
|
"field-group": "所属グループ",
|
|
3516
3959
|
"field-group-none": "グループなし",
|
|
3960
|
+
"field-children": "子フィールド",
|
|
3961
|
+
"field-children-empty": "このコンテナにはまだ子フィールドがありません。",
|
|
3517
3962
|
"field-label": "フィールドラベル",
|
|
3518
3963
|
"group-style": "グループスタイル式",
|
|
3519
3964
|
"group-style-placeholder": "例: style map を返す式。例: display: grid",
|
|
3520
3965
|
"group-style-invalid": "グループスタイル式が無効です",
|
|
3521
3966
|
"field-markdown-content": "Markdown 内容",
|
|
3522
3967
|
"field-markdown-content-description": "Markdown で編集でき、二重波括弧式も利用できます。",
|
|
3968
|
+
"field-markdown-inline": "インライン描画",
|
|
3969
|
+
"field-markdown-inline-description": "有効にするとインライン Markdown として描画し、無効ならブロック Markdown として描画します。",
|
|
3523
3970
|
"field-required": "必須ヒントを表示",
|
|
3524
3971
|
"field-required-description": "有効にするとラベルの後ろに赤い星印だけを表示し、検証ルールは自動追加しません。",
|
|
3525
3972
|
"field-hide-label": "ラベルを非表示",
|
|
@@ -3529,6 +3976,10 @@ function confirmChanges() {
|
|
|
3529
3976
|
"field-style": "スタイル式",
|
|
3530
3977
|
"field-label-style": "ラベルスタイル式",
|
|
3531
3978
|
"field-content-style": "コンテンツスタイル式",
|
|
3979
|
+
"container-body-orientation": "内部レイアウト",
|
|
3980
|
+
"container-body-bordered": "内部テーブル枠線",
|
|
3981
|
+
"container-body-bordered-description": "contents レイアウト時のみ有効で、内部フィールドグリッドに適用します。",
|
|
3982
|
+
"container-body-style": "内部スタイル式",
|
|
3532
3983
|
"field-style-placeholder": "例: width: 100%",
|
|
3533
3984
|
"field-hidden": "非表示条件",
|
|
3534
3985
|
"field-hidden-placeholder": "true を返すと非表示になります",
|
|
@@ -3628,10 +4079,12 @@ function confirmChanges() {
|
|
|
3628
4079
|
"field-type-textarea": "Textarea",
|
|
3629
4080
|
"field-type-number": "Number",
|
|
3630
4081
|
"field-type-markdown": "Markdown",
|
|
4082
|
+
"field-type-markdown-body": "Plain Markdown",
|
|
3631
4083
|
"field-type-select": "Select",
|
|
3632
4084
|
"field-type-radio": "Radio Group",
|
|
3633
4085
|
"field-type-calendar": "Date",
|
|
3634
4086
|
"field-type-upload": "Upload",
|
|
4087
|
+
"field-type-container": "Container",
|
|
3635
4088
|
"field-type-empty": "Empty",
|
|
3636
4089
|
"field-type-slot": "Slot",
|
|
3637
4090
|
"field-id": "Field ID",
|
|
@@ -3649,12 +4102,16 @@ function confirmChanges() {
|
|
|
3649
4102
|
"copy-field-id-failed": "Failed to copy the field ID. Check clipboard permissions.",
|
|
3650
4103
|
"field-group": "Belong group",
|
|
3651
4104
|
"field-group-none": "No group",
|
|
4105
|
+
"field-children": "Child fields",
|
|
4106
|
+
"field-children-empty": "This container does not have child fields yet.",
|
|
3652
4107
|
"field-label": "Field label",
|
|
3653
4108
|
"group-style": "Group style expression",
|
|
3654
4109
|
"group-style-placeholder": "Return a style map, for example display: grid",
|
|
3655
4110
|
"group-style-invalid": "The group style expression is invalid",
|
|
3656
4111
|
"field-markdown-content": "Markdown content",
|
|
3657
4112
|
"field-markdown-content-description": "Supports Markdown and can evaluate double-curly expressions.",
|
|
4113
|
+
"field-markdown-inline": "Inline rendering",
|
|
4114
|
+
"field-markdown-inline-description": "When enabled, render as inline Markdown. Otherwise render as block Markdown.",
|
|
3658
4115
|
"field-required": "Show required hint",
|
|
3659
4116
|
"field-required-description": "When enabled, only a red asterisk is shown after the label. No validation rule is added automatically.",
|
|
3660
4117
|
"field-hide-label": "Hide label",
|
|
@@ -3664,6 +4121,10 @@ function confirmChanges() {
|
|
|
3664
4121
|
"field-style": "Style expression",
|
|
3665
4122
|
"field-label-style": "Label style expression",
|
|
3666
4123
|
"field-content-style": "Content style expression",
|
|
4124
|
+
"container-body-orientation": "Nested layout",
|
|
4125
|
+
"container-body-bordered": "Nested table borders",
|
|
4126
|
+
"container-body-bordered-description": "Only applies in contents layout for the nested field grid.",
|
|
4127
|
+
"container-body-style": "Nested style expression",
|
|
3667
4128
|
"field-style-placeholder": "For example width: 100%",
|
|
3668
4129
|
"field-hidden": "Hidden expression",
|
|
3669
4130
|
"field-hidden-placeholder": "Return true to hide the field",
|