@shwfed/nuxt 0.10.0 → 0.10.1
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 +56 -2
- package/dist/runtime/components/fields.vue +1 -0
- package/dist/runtime/components/fields.vue.d.ts +56 -2
- package/dist/runtime/components/ui/fields/Fields.d.vue.ts +110 -2
- package/dist/runtime/components/ui/fields/Fields.vue +81 -8
- package/dist/runtime/components/ui/fields/Fields.vue.d.ts +110 -2
- package/dist/runtime/components/ui/fields/schema.d.ts +99 -0
- package/dist/runtime/components/ui/fields/schema.js +26 -1
- package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.d.vue.ts +54 -0
- package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue +110 -33
- package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue.d.ts +54 -0
- package/dist/runtime/components/ui/input-group/index.js +2 -2
- package/package.json +1 -1
|
@@ -11,6 +11,21 @@ export const StringFieldC = z.object({
|
|
|
11
11
|
type: z.literal("string").describe("\u5355\u884C\u6587\u672C\u8F93\u5165\u5B57\u6BB5\uFF0C\u7ED1\u5B9A string \u7C7B\u578B\u7684\u503C"),
|
|
12
12
|
path: dotPropC,
|
|
13
13
|
title: localeC.describe("\u5B57\u6BB5\u6807\u7B7E\u7684\u672C\u5730\u5316\u663E\u793A\u6587\u672C"),
|
|
14
|
+
required: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u4EC5\u5728\u5B57\u6BB5\u6807\u7B7E\u540E\u663E\u793A\u5FC5\u586B\u63D0\u793A\u661F\u53F7\uFF0C\u4E0D\u5F71\u54CD\u5B9E\u9645\u6821\u9A8C\u903B\u8F91"),
|
|
15
|
+
icon: z.string().optional().describe("Iconify \u56FE\u6807\u6807\u8BC6\u7B26\uFF0C\u663E\u793A\u5728\u8F93\u5165\u6846\u5185\u4FA7"),
|
|
16
|
+
style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
|
|
17
|
+
discardEmptyString: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u7A7A\u5B57\u7B26\u4E32\u4F5C\u4E3A\u6709\u6548\u503C\u5B58\u50A8\uFF1B\u5426\u5219\u6E05\u7A7A\u8F93\u5165\u5C06\u5220\u9664\u5BF9\u5E94\u5C5E\u6027"),
|
|
18
|
+
maxLength: expressionC("int").optional().describe('\u8FD4\u56DE\u6574\u6570\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u9650\u5236\u8F93\u5165\u7684\u6700\u5927\u5B57\u7B26\u6570\uFF0C\u5982 "100"'),
|
|
19
|
+
hidden: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5"),
|
|
20
|
+
disabled: expressionC("bool", { form: "map<string, dyn>" }).optional().describe("\u4E3A true \u65F6\uFF0C\u7981\u7528\u8FD9\u4E2A\u5B57\u6BB5"),
|
|
21
|
+
validation: validationC
|
|
22
|
+
});
|
|
23
|
+
export const TextareaFieldC = z.object({
|
|
24
|
+
id: fieldIdC,
|
|
25
|
+
type: z.literal("textarea").describe("\u591A\u884C\u6587\u672C\u8F93\u5165\u5B57\u6BB5\uFF0C\u7ED1\u5B9A string \u7C7B\u578B\u7684\u503C"),
|
|
26
|
+
path: dotPropC,
|
|
27
|
+
title: localeC.describe("\u5B57\u6BB5\u6807\u7B7E\u7684\u672C\u5730\u5316\u663E\u793A\u6587\u672C"),
|
|
28
|
+
required: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u4EC5\u5728\u5B57\u6BB5\u6807\u7B7E\u540E\u663E\u793A\u5FC5\u586B\u63D0\u793A\u661F\u53F7\uFF0C\u4E0D\u5F71\u54CD\u5B9E\u9645\u6821\u9A8C\u903B\u8F91"),
|
|
14
29
|
icon: z.string().optional().describe("Iconify \u56FE\u6807\u6807\u8BC6\u7B26\uFF0C\u663E\u793A\u5728\u8F93\u5165\u6846\u5185\u4FA7"),
|
|
15
30
|
style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
|
|
16
31
|
discardEmptyString: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u7A7A\u5B57\u7B26\u4E32\u4F5C\u4E3A\u6709\u6548\u503C\u5B58\u50A8\uFF1B\u5426\u5219\u6E05\u7A7A\u8F93\u5165\u5C06\u5220\u9664\u5BF9\u5E94\u5C5E\u6027"),
|
|
@@ -24,6 +39,7 @@ export const NumberFieldC = z.object({
|
|
|
24
39
|
type: z.literal("number").describe("\u6570\u5B57\u8F93\u5165\u5B57\u6BB5\uFF0C\u7ED1\u5B9A number \u7C7B\u578B\u7684\u503C"),
|
|
25
40
|
path: dotPropC,
|
|
26
41
|
title: localeC.describe("\u5B57\u6BB5\u6807\u7B7E\u7684\u672C\u5730\u5316\u663E\u793A\u6587\u672C"),
|
|
42
|
+
required: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u4EC5\u5728\u5B57\u6BB5\u6807\u7B7E\u540E\u663E\u793A\u5FC5\u586B\u63D0\u793A\u661F\u53F7\uFF0C\u4E0D\u5F71\u54CD\u5B9E\u9645\u6821\u9A8C\u903B\u8F91"),
|
|
27
43
|
icon: z.string().optional().describe("Iconify \u56FE\u6807\u6807\u8BC6\u7B26\uFF0C\u663E\u793A\u5728\u8F93\u5165\u6846\u5185\u4FA7"),
|
|
28
44
|
style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
|
|
29
45
|
min: expressionC("double").optional().describe('\u8FD4\u56DE\u6D6E\u70B9\u6570\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u9650\u5236\u5141\u8BB8\u7684\u6700\u5C0F\u503C\uFF0C\u5982 "0.0"'),
|
|
@@ -38,6 +54,7 @@ export const SelectFieldC = z.object({
|
|
|
38
54
|
type: z.literal("select").describe("\u4E0B\u62C9\u9009\u62E9\u5B57\u6BB5\uFF0C\u4ECE\u9884\u5B9A\u4E49\u9009\u9879\u4E2D\u9009\u53D6\u4E00\u4E2A\u503C"),
|
|
39
55
|
path: dotPropC,
|
|
40
56
|
title: localeC.describe("\u5B57\u6BB5\u6807\u7B7E\u7684\u672C\u5730\u5316\u663E\u793A\u6587\u672C"),
|
|
57
|
+
required: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u4EC5\u5728\u5B57\u6BB5\u6807\u7B7E\u540E\u663E\u793A\u5FC5\u586B\u63D0\u793A\u661F\u53F7\uFF0C\u4E0D\u5F71\u54CD\u5B9E\u9645\u6821\u9A8C\u903B\u8F91"),
|
|
41
58
|
icon: z.string().optional().describe("Iconify \u56FE\u6807\u6807\u8BC6\u7B26\uFF0C\u663E\u793A\u5728\u8F93\u5165\u6846\u5185\u4FA7"),
|
|
42
59
|
options: expressionC(/^list/).describe("\u5168\u90E8\u5019\u9009\u9879"),
|
|
43
60
|
label: expressionC("string", { option: "dyn" }).describe("\u8FD4\u56DE\u5B57\u7B26\u4E32\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u63D0\u4F9B option \u53D8\u91CF\uFF0C\u751F\u6210\u8BE5\u9009\u9879\u7684\u663E\u793A\u6587\u672C"),
|
|
@@ -53,6 +70,7 @@ export const CalendarFieldC = z.object({
|
|
|
53
70
|
type: z.literal("calendar").describe("\u65E5\u671F\u9009\u62E9\u5B57\u6BB5\uFF0C\u901A\u8FC7\u5F39\u51FA\u65E5\u5386\u9762\u677F\u9009\u62E9\u65E5\u671F"),
|
|
54
71
|
path: dotPropC,
|
|
55
72
|
title: localeC.describe("\u5B57\u6BB5\u6807\u7B7E\u7684\u672C\u5730\u5316\u663E\u793A\u6587\u672C"),
|
|
73
|
+
required: z.boolean().optional().describe("\u4E3A true \u65F6\uFF0C\u4EC5\u5728\u5B57\u6BB5\u6807\u7B7E\u540E\u663E\u793A\u5FC5\u586B\u63D0\u793A\u661F\u53F7\uFF0C\u4E0D\u5F71\u54CD\u5B9E\u9645\u6821\u9A8C\u903B\u8F91"),
|
|
56
74
|
icon: z.string().optional().describe("Iconify \u56FE\u6807\u6807\u8BC6\u7B26\uFF0C\u663E\u793A\u5728\u8F93\u5165\u6846\u5185\u4FA7"),
|
|
57
75
|
style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
|
|
58
76
|
mode: z.enum(["year", "month", "date"]).describe("\u65E5\u5386\u9009\u62E9\u7CBE\u5EA6\uFF1Ayear \u4EC5\u9009\u5E74\uFF0Cmonth \u9009\u5E74\u6708\uFF0Cdate \u9009\u5E74\u6708\u65E5"),
|
|
@@ -68,12 +86,19 @@ export const SlotFieldC = z.strictObject({
|
|
|
68
86
|
type: z.literal("slot").describe("\u5177\u540D\u63D2\u69FD\u5B57\u6BB5\uFF0C\u901A\u8FC7\u5B57\u6BB5 id \u5BF9\u5E94\u7684\u5177\u540D\u63D2\u69FD\u6E32\u67D3\u5185\u5BB9"),
|
|
69
87
|
style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u6C42\u503C\u540E\u901A\u8FC7 scoped slot \u7684 style prop \u4F20\u7ED9\u6D88\u8D39\u8005")
|
|
70
88
|
});
|
|
89
|
+
export const EmptyFieldC = z.strictObject({
|
|
90
|
+
id: fieldIdC,
|
|
91
|
+
type: z.literal("empty").describe("\u7A7A\u767D\u5B57\u6BB5\uFF0C\u6309\u987A\u5E8F\u6E32\u67D3\u4E00\u4E2A\u7A7A div\uFF0C\u53EA\u80FD\u901A\u8FC7 style \u63A7\u5236\u5E03\u5C40"),
|
|
92
|
+
style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u6C42\u503C\u540E\u4F5C\u4E3A\u7A7A div \u7684\u5185\u8054\u6837\u5F0F")
|
|
93
|
+
});
|
|
71
94
|
export const FieldC = z.discriminatedUnion("type", [
|
|
72
95
|
StringFieldC,
|
|
96
|
+
TextareaFieldC,
|
|
73
97
|
NumberFieldC,
|
|
74
98
|
SelectFieldC,
|
|
75
99
|
CalendarFieldC,
|
|
76
|
-
SlotFieldC
|
|
100
|
+
SlotFieldC,
|
|
101
|
+
EmptyFieldC
|
|
77
102
|
]);
|
|
78
103
|
export const FieldsOrientationC = z.enum(["horizontal", "vertical", "floating"]);
|
|
79
104
|
export const FieldsStyleC = expressionC(/^map/, {
|
|
@@ -17,6 +17,26 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
17
17
|
locale: "zh" | "ja" | "en" | "ko";
|
|
18
18
|
message: string;
|
|
19
19
|
}[];
|
|
20
|
+
required?: boolean | undefined;
|
|
21
|
+
icon?: string | undefined;
|
|
22
|
+
style?: string | undefined;
|
|
23
|
+
discardEmptyString?: boolean | undefined;
|
|
24
|
+
maxLength?: string | undefined;
|
|
25
|
+
hidden?: string | undefined;
|
|
26
|
+
disabled?: string | undefined;
|
|
27
|
+
validation?: readonly Readonly<{
|
|
28
|
+
expression: string;
|
|
29
|
+
message: string;
|
|
30
|
+
}>[] | undefined;
|
|
31
|
+
} | {
|
|
32
|
+
id: string;
|
|
33
|
+
type: "textarea";
|
|
34
|
+
path: string;
|
|
35
|
+
title: readonly {
|
|
36
|
+
locale: "zh" | "ja" | "en" | "ko";
|
|
37
|
+
message: string;
|
|
38
|
+
}[];
|
|
39
|
+
required?: boolean | undefined;
|
|
20
40
|
icon?: string | undefined;
|
|
21
41
|
style?: string | undefined;
|
|
22
42
|
discardEmptyString?: boolean | undefined;
|
|
@@ -35,6 +55,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
35
55
|
locale: "zh" | "ja" | "en" | "ko";
|
|
36
56
|
message: string;
|
|
37
57
|
}[];
|
|
58
|
+
required?: boolean | undefined;
|
|
38
59
|
icon?: string | undefined;
|
|
39
60
|
style?: string | undefined;
|
|
40
61
|
min?: string | undefined;
|
|
@@ -58,6 +79,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
58
79
|
label: string;
|
|
59
80
|
value: string;
|
|
60
81
|
key: string;
|
|
82
|
+
required?: boolean | undefined;
|
|
61
83
|
icon?: string | undefined;
|
|
62
84
|
style?: string | undefined;
|
|
63
85
|
hidden?: string | undefined;
|
|
@@ -76,6 +98,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
76
98
|
}[];
|
|
77
99
|
mode: "date" | "month" | "year";
|
|
78
100
|
value: string;
|
|
101
|
+
required?: boolean | undefined;
|
|
79
102
|
icon?: string | undefined;
|
|
80
103
|
style?: string | undefined;
|
|
81
104
|
display?: string | undefined;
|
|
@@ -90,6 +113,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
90
113
|
id: string;
|
|
91
114
|
type: "slot";
|
|
92
115
|
style?: string | undefined;
|
|
116
|
+
} | {
|
|
117
|
+
id: string;
|
|
118
|
+
type: "empty";
|
|
119
|
+
style?: string | undefined;
|
|
93
120
|
})[];
|
|
94
121
|
orientation?: "vertical" | "horizontal" | "floating" | undefined;
|
|
95
122
|
style?: string | undefined;
|
|
@@ -105,6 +132,26 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
105
132
|
locale: "zh" | "ja" | "en" | "ko";
|
|
106
133
|
message: string;
|
|
107
134
|
}[];
|
|
135
|
+
required?: boolean | undefined;
|
|
136
|
+
icon?: string | undefined;
|
|
137
|
+
style?: string | undefined;
|
|
138
|
+
discardEmptyString?: boolean | undefined;
|
|
139
|
+
maxLength?: string | undefined;
|
|
140
|
+
hidden?: string | undefined;
|
|
141
|
+
disabled?: string | undefined;
|
|
142
|
+
validation?: readonly Readonly<{
|
|
143
|
+
expression: string;
|
|
144
|
+
message: string;
|
|
145
|
+
}>[] | undefined;
|
|
146
|
+
} | {
|
|
147
|
+
id: string;
|
|
148
|
+
type: "textarea";
|
|
149
|
+
path: string;
|
|
150
|
+
title: readonly {
|
|
151
|
+
locale: "zh" | "ja" | "en" | "ko";
|
|
152
|
+
message: string;
|
|
153
|
+
}[];
|
|
154
|
+
required?: boolean | undefined;
|
|
108
155
|
icon?: string | undefined;
|
|
109
156
|
style?: string | undefined;
|
|
110
157
|
discardEmptyString?: boolean | undefined;
|
|
@@ -123,6 +170,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
123
170
|
locale: "zh" | "ja" | "en" | "ko";
|
|
124
171
|
message: string;
|
|
125
172
|
}[];
|
|
173
|
+
required?: boolean | undefined;
|
|
126
174
|
icon?: string | undefined;
|
|
127
175
|
style?: string | undefined;
|
|
128
176
|
min?: string | undefined;
|
|
@@ -146,6 +194,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
146
194
|
label: string;
|
|
147
195
|
value: string;
|
|
148
196
|
key: string;
|
|
197
|
+
required?: boolean | undefined;
|
|
149
198
|
icon?: string | undefined;
|
|
150
199
|
style?: string | undefined;
|
|
151
200
|
hidden?: string | undefined;
|
|
@@ -164,6 +213,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
164
213
|
}[];
|
|
165
214
|
mode: "date" | "month" | "year";
|
|
166
215
|
value: string;
|
|
216
|
+
required?: boolean | undefined;
|
|
167
217
|
icon?: string | undefined;
|
|
168
218
|
style?: string | undefined;
|
|
169
219
|
display?: string | undefined;
|
|
@@ -178,6 +228,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
178
228
|
id: string;
|
|
179
229
|
type: "slot";
|
|
180
230
|
style?: string | undefined;
|
|
231
|
+
} | {
|
|
232
|
+
id: string;
|
|
233
|
+
type: "empty";
|
|
234
|
+
style?: string | undefined;
|
|
181
235
|
})[];
|
|
182
236
|
orientation?: "vertical" | "horizontal" | "floating" | undefined;
|
|
183
237
|
style?: string | undefined;
|
|
@@ -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
|
+
EmptyFieldC,
|
|
10
11
|
FieldsConfigC,
|
|
12
|
+
FieldsStyleC,
|
|
11
13
|
NumberFieldC,
|
|
12
14
|
SelectFieldC,
|
|
13
15
|
SlotFieldC,
|
|
14
16
|
StringFieldC,
|
|
15
|
-
|
|
17
|
+
TextareaFieldC
|
|
16
18
|
} from "../fields/schema";
|
|
17
19
|
import { cn } from "../../../utils/cn";
|
|
18
20
|
import { Button } from "../button";
|
|
@@ -54,9 +56,11 @@ const sortableItemIds = ref([]);
|
|
|
54
56
|
const validationErrors = ref({});
|
|
55
57
|
const fieldTypeOptions = computed(() => [
|
|
56
58
|
{ type: "string", label: t("field-type-string") },
|
|
59
|
+
{ type: "textarea", label: t("field-type-textarea") },
|
|
57
60
|
{ type: "number", label: t("field-type-number") },
|
|
58
61
|
{ type: "select", label: t("field-type-select") },
|
|
59
62
|
{ type: "calendar", label: t("field-type-calendar") },
|
|
63
|
+
{ type: "empty", label: t("field-type-empty") },
|
|
60
64
|
{ type: "slot", label: t("field-type-slot") }
|
|
61
65
|
]);
|
|
62
66
|
const generalItem = computed(() => ({
|
|
@@ -67,7 +71,7 @@ const normalizedSearch = computed(() => search.value.trim().toLocaleLowerCase())
|
|
|
67
71
|
const selectedField = computed(() => draftFields.value.find((field) => field.draftId === selectedItemId.value));
|
|
68
72
|
const selectedFieldValidationRules = computed(() => {
|
|
69
73
|
const field = selectedField.value?.field;
|
|
70
|
-
if (!field || field.type === "slot") {
|
|
74
|
+
if (!field || field.type === "slot" || field.type === "empty") {
|
|
71
75
|
return [];
|
|
72
76
|
}
|
|
73
77
|
return field.validation ?? [];
|
|
@@ -99,10 +103,14 @@ function normalizeOrientation(value) {
|
|
|
99
103
|
function getFieldTypeLabel(type) {
|
|
100
104
|
return t(`field-type-${type}`);
|
|
101
105
|
}
|
|
102
|
-
function
|
|
103
|
-
return
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
function isPassiveField(field) {
|
|
107
|
+
return field.type === "slot" || field.type === "empty";
|
|
108
|
+
}
|
|
109
|
+
function getSlotFieldLabel(_) {
|
|
110
|
+
return getFieldTypeLabel("slot");
|
|
111
|
+
}
|
|
112
|
+
function getEmptyFieldLabel(_) {
|
|
113
|
+
return getFieldTypeLabel("empty");
|
|
106
114
|
}
|
|
107
115
|
function getUnnamedFieldLabel(field) {
|
|
108
116
|
return t("unnamed-field", {
|
|
@@ -110,7 +118,7 @@ function getUnnamedFieldLabel(field) {
|
|
|
110
118
|
});
|
|
111
119
|
}
|
|
112
120
|
function getFieldChineseTitle(field) {
|
|
113
|
-
if (field
|
|
121
|
+
if (isPassiveField(field)) {
|
|
114
122
|
return void 0;
|
|
115
123
|
}
|
|
116
124
|
const zhTitle = field.title.find((item) => item.locale === "zh");
|
|
@@ -124,14 +132,17 @@ function getFieldListLabel(field) {
|
|
|
124
132
|
if (field.type === "slot") {
|
|
125
133
|
return getSlotFieldLabel(field);
|
|
126
134
|
}
|
|
135
|
+
if (field.type === "empty") {
|
|
136
|
+
return getEmptyFieldLabel(field);
|
|
137
|
+
}
|
|
127
138
|
return getFieldChineseTitle(field) ?? getUnnamedFieldLabel(field);
|
|
128
139
|
}
|
|
129
140
|
const fieldItems = computed(() => draftFields.value.map((item) => ({
|
|
130
141
|
itemId: item.draftId,
|
|
131
142
|
fieldId: item.field.id,
|
|
132
143
|
label: getFieldListLabel(item.field),
|
|
133
|
-
path: item.field
|
|
134
|
-
searchMeta: item.field
|
|
144
|
+
path: isPassiveField(item.field) ? void 0 : item.field.path,
|
|
145
|
+
searchMeta: isPassiveField(item.field) ? item.field.id : [item.field.path, item.field.id].filter(Boolean).join(" "),
|
|
135
146
|
type: item.field.type
|
|
136
147
|
})));
|
|
137
148
|
const filteredFieldItems = computed(() => {
|
|
@@ -201,9 +212,11 @@ function normalizeValidationRules(validation) {
|
|
|
201
212
|
function normalizeField(field) {
|
|
202
213
|
switch (field.type) {
|
|
203
214
|
case "string":
|
|
215
|
+
case "textarea":
|
|
204
216
|
return {
|
|
205
217
|
...field,
|
|
206
218
|
path: field.path.trim(),
|
|
219
|
+
required: field.required ? true : void 0,
|
|
207
220
|
icon: normalizeOptionalString(field.icon ?? ""),
|
|
208
221
|
style: normalizeOptionalString(field.style ?? ""),
|
|
209
222
|
maxLength: normalizeOptionalString(field.maxLength ?? ""),
|
|
@@ -216,6 +229,7 @@ function normalizeField(field) {
|
|
|
216
229
|
return {
|
|
217
230
|
...field,
|
|
218
231
|
path: field.path.trim(),
|
|
232
|
+
required: field.required ? true : void 0,
|
|
219
233
|
icon: normalizeOptionalString(field.icon ?? ""),
|
|
220
234
|
style: normalizeOptionalString(field.style ?? ""),
|
|
221
235
|
min: normalizeOptionalString(field.min ?? ""),
|
|
@@ -229,6 +243,7 @@ function normalizeField(field) {
|
|
|
229
243
|
return {
|
|
230
244
|
...field,
|
|
231
245
|
path: field.path.trim(),
|
|
246
|
+
required: field.required ? true : void 0,
|
|
232
247
|
icon: normalizeOptionalString(field.icon ?? ""),
|
|
233
248
|
style: normalizeOptionalString(field.style ?? ""),
|
|
234
249
|
options: field.options.trim(),
|
|
@@ -243,6 +258,7 @@ function normalizeField(field) {
|
|
|
243
258
|
return {
|
|
244
259
|
...field,
|
|
245
260
|
path: field.path.trim(),
|
|
261
|
+
required: field.required ? true : void 0,
|
|
246
262
|
icon: normalizeOptionalString(field.icon ?? ""),
|
|
247
263
|
style: normalizeOptionalString(field.style ?? ""),
|
|
248
264
|
display: normalizeOptionalString(field.display ?? ""),
|
|
@@ -257,6 +273,11 @@ function normalizeField(field) {
|
|
|
257
273
|
...field,
|
|
258
274
|
style: normalizeOptionalString(field.style ?? "")
|
|
259
275
|
};
|
|
276
|
+
case "empty":
|
|
277
|
+
return {
|
|
278
|
+
...field,
|
|
279
|
+
style: normalizeOptionalString(field.style ?? "")
|
|
280
|
+
};
|
|
260
281
|
}
|
|
261
282
|
}
|
|
262
283
|
function createField(type) {
|
|
@@ -264,6 +285,7 @@ function createField(type) {
|
|
|
264
285
|
const id = createFieldId();
|
|
265
286
|
switch (type) {
|
|
266
287
|
case "string":
|
|
288
|
+
case "textarea":
|
|
267
289
|
return {
|
|
268
290
|
id,
|
|
269
291
|
type,
|
|
@@ -297,6 +319,11 @@ function createField(type) {
|
|
|
297
319
|
mode: "date",
|
|
298
320
|
value: "yyyy-MM-dd"
|
|
299
321
|
};
|
|
322
|
+
case "empty":
|
|
323
|
+
return {
|
|
324
|
+
id,
|
|
325
|
+
type
|
|
326
|
+
};
|
|
300
327
|
case "slot":
|
|
301
328
|
return {
|
|
302
329
|
id,
|
|
@@ -469,7 +496,7 @@ async function copyFieldId(fieldId) {
|
|
|
469
496
|
}
|
|
470
497
|
function updateSelectedFieldPath(value) {
|
|
471
498
|
const selected = selectedField.value;
|
|
472
|
-
if (!selected || selected.field
|
|
499
|
+
if (!selected || isPassiveField(selected.field)) {
|
|
473
500
|
return;
|
|
474
501
|
}
|
|
475
502
|
clearFieldError(selected.draftId, "path");
|
|
@@ -511,13 +538,28 @@ function updateSelectedFieldDisabled(value) {
|
|
|
511
538
|
disabled: normalizeOptionalString(String(value))
|
|
512
539
|
}));
|
|
513
540
|
}
|
|
541
|
+
function updateSelectedFieldRequired(value) {
|
|
542
|
+
const selected = selectedField.value;
|
|
543
|
+
if (!selected || isPassiveField(selected.field)) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
updateDraftField(selected.draftId, (field) => {
|
|
547
|
+
if (isPassiveField(field)) {
|
|
548
|
+
return field;
|
|
549
|
+
}
|
|
550
|
+
return {
|
|
551
|
+
...field,
|
|
552
|
+
required: value ? true : void 0
|
|
553
|
+
};
|
|
554
|
+
});
|
|
555
|
+
}
|
|
514
556
|
function updateSelectedStringDiscardEmpty(value) {
|
|
515
557
|
const selected = selectedField.value;
|
|
516
|
-
if (!selected || selected.field.type !== "string") {
|
|
558
|
+
if (!selected || selected.field.type !== "string" && selected.field.type !== "textarea") {
|
|
517
559
|
return;
|
|
518
560
|
}
|
|
519
561
|
updateDraftField(selected.draftId, (field) => {
|
|
520
|
-
if (field.type !== "string") {
|
|
562
|
+
if (field.type !== "string" && field.type !== "textarea") {
|
|
521
563
|
return field;
|
|
522
564
|
}
|
|
523
565
|
return {
|
|
@@ -528,12 +570,12 @@ function updateSelectedStringDiscardEmpty(value) {
|
|
|
528
570
|
}
|
|
529
571
|
function updateSelectedStringMaxLength(value) {
|
|
530
572
|
const selected = selectedField.value;
|
|
531
|
-
if (!selected || selected.field.type !== "string") {
|
|
573
|
+
if (!selected || selected.field.type !== "string" && selected.field.type !== "textarea") {
|
|
532
574
|
return;
|
|
533
575
|
}
|
|
534
576
|
clearFieldError(selected.draftId, "maxLength");
|
|
535
577
|
updateDraftField(selected.draftId, (field) => {
|
|
536
|
-
if (field.type !== "string") {
|
|
578
|
+
if (field.type !== "string" && field.type !== "textarea") {
|
|
537
579
|
return field;
|
|
538
580
|
}
|
|
539
581
|
return {
|
|
@@ -724,11 +766,11 @@ function updateSelectedCalendarDisableDate(value) {
|
|
|
724
766
|
}
|
|
725
767
|
function addValidationRule() {
|
|
726
768
|
const selected = selectedField.value;
|
|
727
|
-
if (!selected || selected.field
|
|
769
|
+
if (!selected || isPassiveField(selected.field)) {
|
|
728
770
|
return;
|
|
729
771
|
}
|
|
730
772
|
updateDraftField(selected.draftId, (field) => {
|
|
731
|
-
if (field
|
|
773
|
+
if (isPassiveField(field)) {
|
|
732
774
|
return field;
|
|
733
775
|
}
|
|
734
776
|
return {
|
|
@@ -745,7 +787,7 @@ function addValidationRule() {
|
|
|
745
787
|
}
|
|
746
788
|
function updateValidationRule(index, updater) {
|
|
747
789
|
const selected = selectedField.value;
|
|
748
|
-
if (!selected || selected.field
|
|
790
|
+
if (!selected || isPassiveField(selected.field)) {
|
|
749
791
|
return;
|
|
750
792
|
}
|
|
751
793
|
const validation = selected.field.validation ?? [];
|
|
@@ -755,7 +797,7 @@ function updateValidationRule(index, updater) {
|
|
|
755
797
|
}
|
|
756
798
|
const nextValidation = validation.map((rule, ruleIndex) => ruleIndex === index ? updater(rule) : rule);
|
|
757
799
|
updateDraftField(selected.draftId, (field) => {
|
|
758
|
-
if (field
|
|
800
|
+
if (isPassiveField(field)) {
|
|
759
801
|
return field;
|
|
760
802
|
}
|
|
761
803
|
return {
|
|
@@ -788,7 +830,7 @@ function updateSelectedValidationMessage(index, value) {
|
|
|
788
830
|
}
|
|
789
831
|
function moveValidationRule(index, offset) {
|
|
790
832
|
const selected = selectedField.value;
|
|
791
|
-
if (!selected || selected.field
|
|
833
|
+
if (!selected || isPassiveField(selected.field)) {
|
|
792
834
|
return;
|
|
793
835
|
}
|
|
794
836
|
const validation = selected.field.validation ?? [];
|
|
@@ -805,7 +847,7 @@ function moveValidationRule(index, offset) {
|
|
|
805
847
|
nextValidation[index] = targetRule;
|
|
806
848
|
nextValidation[nextIndex] = currentRule;
|
|
807
849
|
updateDraftField(selected.draftId, (field) => {
|
|
808
|
-
if (field
|
|
850
|
+
if (isPassiveField(field)) {
|
|
809
851
|
return field;
|
|
810
852
|
}
|
|
811
853
|
return {
|
|
@@ -817,7 +859,7 @@ function moveValidationRule(index, offset) {
|
|
|
817
859
|
}
|
|
818
860
|
function deleteValidationRule(index) {
|
|
819
861
|
const selected = selectedField.value;
|
|
820
|
-
if (!selected || selected.field
|
|
862
|
+
if (!selected || isPassiveField(selected.field)) {
|
|
821
863
|
return;
|
|
822
864
|
}
|
|
823
865
|
const validation = selected.field.validation ?? [];
|
|
@@ -827,7 +869,7 @@ function deleteValidationRule(index) {
|
|
|
827
869
|
clearValidationRuleError(selected.draftId, index, "expression");
|
|
828
870
|
clearValidationRuleError(selected.draftId, index, "message");
|
|
829
871
|
updateDraftField(selected.draftId, (field) => {
|
|
830
|
-
if (field
|
|
872
|
+
if (isPassiveField(field)) {
|
|
831
873
|
return field;
|
|
832
874
|
}
|
|
833
875
|
const validation2 = field.validation ?? [];
|
|
@@ -848,6 +890,10 @@ function getSchemaIssues(field) {
|
|
|
848
890
|
const result = StringFieldC.safeParse(field);
|
|
849
891
|
return result.success ? [] : result.error.issues;
|
|
850
892
|
}
|
|
893
|
+
case "textarea": {
|
|
894
|
+
const result = TextareaFieldC.safeParse(field);
|
|
895
|
+
return result.success ? [] : result.error.issues;
|
|
896
|
+
}
|
|
851
897
|
case "number": {
|
|
852
898
|
const result = NumberFieldC.safeParse(field);
|
|
853
899
|
return result.success ? [] : result.error.issues;
|
|
@@ -864,6 +910,10 @@ function getSchemaIssues(field) {
|
|
|
864
910
|
const result = SlotFieldC.safeParse(field);
|
|
865
911
|
return result.success ? [] : result.error.issues;
|
|
866
912
|
}
|
|
913
|
+
case "empty": {
|
|
914
|
+
const result = EmptyFieldC.safeParse(field);
|
|
915
|
+
return result.success ? [] : result.error.issues;
|
|
916
|
+
}
|
|
867
917
|
}
|
|
868
918
|
}
|
|
869
919
|
function normalizeIssuePath(path) {
|
|
@@ -903,7 +953,7 @@ function validateDraftFields() {
|
|
|
903
953
|
} else {
|
|
904
954
|
idOwners[item.field.id] = item.draftId;
|
|
905
955
|
}
|
|
906
|
-
if (item.field
|
|
956
|
+
if (!isPassiveField(item.field)) {
|
|
907
957
|
const existingPathOwner = pathOwners[item.field.path];
|
|
908
958
|
if (item.field.path.length === 0) {
|
|
909
959
|
setError(errors, getFieldErrorKey(item.draftId, "path"), t("field-path-required"));
|
|
@@ -1020,16 +1070,16 @@ function buildDslGuideMarkdown() {
|
|
|
1020
1070
|
"",
|
|
1021
1071
|
"### 3. \u5B57\u6BB5\u7C7B\u578B\u7EA6\u675F",
|
|
1022
1072
|
"- \u6240\u6709\u5B57\u6BB5\u90FD\u5FC5\u987B\u5305\u542B\u7A33\u5B9A\u7684 UUID `id`\u3002",
|
|
1023
|
-
"- \u53EA\u6709\u975E `slot` \u5B57\u6BB5\u53EF\u4EE5\u914D\u7F6E `path`\uFF0C\u5E76\u53C2\u4E0E\u8868\u5355\u503C\u8BFB\u5199\u3002",
|
|
1024
|
-
"- `slot` \u5B57\u6BB5\u4E0D\u4F1A\u7ED1\u5B9A\u6A21\u578B\u503C\uFF0C\u53EA\
|
|
1073
|
+
"- \u53EA\u6709\u975E `slot` / `empty` \u5B57\u6BB5\u53EF\u4EE5\u914D\u7F6E `path`\uFF0C\u5E76\u53C2\u4E0E\u8868\u5355\u503C\u8BFB\u5199\u3002",
|
|
1074
|
+
"- `slot` \u548C `empty` \u5B57\u6BB5\u90FD\u4E0D\u4F1A\u7ED1\u5B9A\u6A21\u578B\u503C\uFF0C\u53EA\u5141\u8BB8 `id`\u3001`type` \u548C\u53EF\u9009\u7684 `style`\u3002"
|
|
1025
1075
|
].join("\n");
|
|
1026
1076
|
}
|
|
1027
1077
|
function buildMarkdownNotes() {
|
|
1028
1078
|
return [
|
|
1029
1079
|
"## \u6CE8\u610F\u4E8B\u9879",
|
|
1030
1080
|
"- \u6240\u6709\u5B57\u6BB5\u90FD\u5FC5\u987B\u4FDD\u7559\u73B0\u6709 `id`\uFF0C\u4E0D\u8981\u751F\u6210\u65B0\u7684 `id` \u66FF\u6362\u5DF2\u6709\u5B57\u6BB5\u3002",
|
|
1031
|
-
"- `slot` \u5B57\u6BB5\u53EA\u80FD\u4F7F\u7528 `id`\u3001`type` \u548C\u53EF\u9009\u7684 `style`\u3002",
|
|
1032
|
-
"- \u975E `slot` \u5B57\u6BB5\u7684 `path` \u5FC5\u987B\u552F\u4E00\u4E14\u4E0D\u80FD\u4E3A\u7A7A\u3002",
|
|
1081
|
+
"- `slot` \u4E0E `empty` \u5B57\u6BB5\u53EA\u80FD\u4F7F\u7528 `id`\u3001`type` \u548C\u53EF\u9009\u7684 `style`\u3002",
|
|
1082
|
+
"- \u975E `slot` / `empty` \u5B57\u6BB5\u7684 `path` \u5FC5\u987B\u552F\u4E00\u4E14\u4E0D\u80FD\u4E3A\u7A7A\u3002",
|
|
1033
1083
|
"- \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"
|
|
1034
1084
|
].join("\n");
|
|
1035
1085
|
}
|
|
@@ -1454,7 +1504,7 @@ function confirmChanges() {
|
|
|
1454
1504
|
</p>
|
|
1455
1505
|
|
|
1456
1506
|
<section
|
|
1457
|
-
v-if="selectedField.field
|
|
1507
|
+
v-if="!isPassiveField(selectedField.field)"
|
|
1458
1508
|
data-slot="fields-configurator-field-path-section"
|
|
1459
1509
|
class="flex flex-col gap-2"
|
|
1460
1510
|
>
|
|
@@ -1483,7 +1533,7 @@ function confirmChanges() {
|
|
|
1483
1533
|
</section>
|
|
1484
1534
|
|
|
1485
1535
|
<section
|
|
1486
|
-
v-if="selectedField.field
|
|
1536
|
+
v-if="!isPassiveField(selectedField.field)"
|
|
1487
1537
|
data-slot="fields-configurator-field-label-section"
|
|
1488
1538
|
class="flex flex-col gap-2"
|
|
1489
1539
|
>
|
|
@@ -1507,8 +1557,8 @@ function confirmChanges() {
|
|
|
1507
1557
|
</section>
|
|
1508
1558
|
|
|
1509
1559
|
<section
|
|
1510
|
-
v-if="selectedField.field
|
|
1511
|
-
data-slot="fields-configurator-
|
|
1560
|
+
v-if="isPassiveField(selectedField.field)"
|
|
1561
|
+
data-slot="fields-configurator-passive-options"
|
|
1512
1562
|
class="grid gap-4 md:grid-cols-2"
|
|
1513
1563
|
>
|
|
1514
1564
|
<label class="flex flex-col gap-2 md:col-span-2">
|
|
@@ -1537,6 +1587,18 @@ function confirmChanges() {
|
|
|
1537
1587
|
data-slot="fields-configurator-field-general-options"
|
|
1538
1588
|
class="grid gap-4 md:grid-cols-2"
|
|
1539
1589
|
>
|
|
1590
|
+
<label class="flex items-center justify-between gap-3 rounded-md border border-zinc-200 px-3 py-2 md:col-span-2">
|
|
1591
|
+
<div class="flex flex-col gap-1">
|
|
1592
|
+
<span class="text-sm font-medium text-zinc-800">{{ t("field-required") }}</span>
|
|
1593
|
+
<span class="text-xs text-zinc-500">{{ t("field-required-description") }}</span>
|
|
1594
|
+
</div>
|
|
1595
|
+
<Switch
|
|
1596
|
+
data-slot="fields-configurator-field-required-switch"
|
|
1597
|
+
:model-value="selectedField.field.required ?? false"
|
|
1598
|
+
@update:model-value="updateSelectedFieldRequired"
|
|
1599
|
+
/>
|
|
1600
|
+
</label>
|
|
1601
|
+
|
|
1540
1602
|
<label class="flex flex-col gap-2">
|
|
1541
1603
|
<span class="text-xs font-medium text-zinc-500">
|
|
1542
1604
|
{{ t("field-style") }}
|
|
@@ -1599,7 +1661,7 @@ function confirmChanges() {
|
|
|
1599
1661
|
</section>
|
|
1600
1662
|
|
|
1601
1663
|
<section
|
|
1602
|
-
v-if="selectedField.field.type === 'string'"
|
|
1664
|
+
v-if="selectedField.field.type === 'string' || selectedField.field.type === 'textarea'"
|
|
1603
1665
|
data-slot="fields-configurator-string-options"
|
|
1604
1666
|
class="grid gap-4 md:grid-cols-2"
|
|
1605
1667
|
>
|
|
@@ -1867,7 +1929,7 @@ function confirmChanges() {
|
|
|
1867
1929
|
</section>
|
|
1868
1930
|
|
|
1869
1931
|
<section
|
|
1870
|
-
v-if="selectedField.field
|
|
1932
|
+
v-if="!isPassiveField(selectedField.field)"
|
|
1871
1933
|
data-slot="fields-configurator-validation"
|
|
1872
1934
|
class="flex flex-col gap-4"
|
|
1873
1935
|
>
|
|
@@ -2077,9 +2139,11 @@ function confirmChanges() {
|
|
|
2077
2139
|
"add-field": "新增字段",
|
|
2078
2140
|
"field-type": "字段类型",
|
|
2079
2141
|
"field-type-string": "文本",
|
|
2142
|
+
"field-type-textarea": "多行文本",
|
|
2080
2143
|
"field-type-number": "数字",
|
|
2081
2144
|
"field-type-select": "选择",
|
|
2082
2145
|
"field-type-calendar": "日期",
|
|
2146
|
+
"field-type-empty": "空白",
|
|
2083
2147
|
"field-type-slot": "插槽",
|
|
2084
2148
|
"field-id": "字段 ID",
|
|
2085
2149
|
"field-id-duplicate": "字段 ID 不能重复",
|
|
@@ -2091,6 +2155,8 @@ function confirmChanges() {
|
|
|
2091
2155
|
"copy-field-id-short": "复制 ID",
|
|
2092
2156
|
"copy-field-id-failed": "复制字段 ID 失败,请检查剪贴板权限。",
|
|
2093
2157
|
"field-label": "字段标题",
|
|
2158
|
+
"field-required": "显示必填提示",
|
|
2159
|
+
"field-required-description": "开启后仅在标签后显示红色星号,不会自动添加校验规则。",
|
|
2094
2160
|
"field-icon": "图标",
|
|
2095
2161
|
"field-icon-placeholder": "例如 fluent:person-20-regular",
|
|
2096
2162
|
"field-style": "样式表达式",
|
|
@@ -2139,6 +2205,7 @@ function confirmChanges() {
|
|
|
2139
2205
|
"no-matches": "没有匹配的字段。",
|
|
2140
2206
|
"no-validation-rules": "暂未配置校验规则。",
|
|
2141
2207
|
"unnamed-field": "未命名{type}字段",
|
|
2208
|
+
"empty-field": "空白 {id}",
|
|
2142
2209
|
"slot-field": "插槽 {id}",
|
|
2143
2210
|
"no-fields": "还没有字段。",
|
|
2144
2211
|
"drag-field": "拖拽调整字段顺序:{field}",
|
|
@@ -2173,9 +2240,11 @@ function confirmChanges() {
|
|
|
2173
2240
|
"add-field": "フィールドを追加",
|
|
2174
2241
|
"field-type": "フィールド種別",
|
|
2175
2242
|
"field-type-string": "テキスト",
|
|
2243
|
+
"field-type-textarea": "複数行テキスト",
|
|
2176
2244
|
"field-type-number": "数値",
|
|
2177
2245
|
"field-type-select": "選択",
|
|
2178
2246
|
"field-type-calendar": "日付",
|
|
2247
|
+
"field-type-empty": "空白",
|
|
2179
2248
|
"field-type-slot": "スロット",
|
|
2180
2249
|
"field-id": "フィールド ID",
|
|
2181
2250
|
"field-id-duplicate": "フィールド ID は重複できません",
|
|
@@ -2187,6 +2256,8 @@ function confirmChanges() {
|
|
|
2187
2256
|
"copy-field-id-short": "ID をコピー",
|
|
2188
2257
|
"copy-field-id-failed": "フィールド ID のコピーに失敗しました。クリップボード権限を確認してください。",
|
|
2189
2258
|
"field-label": "フィールドラベル",
|
|
2259
|
+
"field-required": "必須ヒントを表示",
|
|
2260
|
+
"field-required-description": "有効にするとラベルの後ろに赤い星印だけを表示し、検証ルールは自動追加しません。",
|
|
2190
2261
|
"field-icon": "アイコン",
|
|
2191
2262
|
"field-icon-placeholder": "例: fluent:person-20-regular",
|
|
2192
2263
|
"field-style": "スタイル式",
|
|
@@ -2235,6 +2306,7 @@ function confirmChanges() {
|
|
|
2235
2306
|
"no-matches": "一致するフィールドがありません。",
|
|
2236
2307
|
"no-validation-rules": "検証ルールはまだありません。",
|
|
2237
2308
|
"unnamed-field": "未命名の{type}フィールド",
|
|
2309
|
+
"empty-field": "空白 {id}",
|
|
2238
2310
|
"slot-field": "スロット {id}",
|
|
2239
2311
|
"no-fields": "フィールドがありません。",
|
|
2240
2312
|
"drag-field": "{field} の順序をドラッグで変更",
|
|
@@ -2269,9 +2341,11 @@ function confirmChanges() {
|
|
|
2269
2341
|
"add-field": "Add field",
|
|
2270
2342
|
"field-type": "Field type",
|
|
2271
2343
|
"field-type-string": "Text",
|
|
2344
|
+
"field-type-textarea": "Textarea",
|
|
2272
2345
|
"field-type-number": "Number",
|
|
2273
2346
|
"field-type-select": "Select",
|
|
2274
2347
|
"field-type-calendar": "Date",
|
|
2348
|
+
"field-type-empty": "Empty",
|
|
2275
2349
|
"field-type-slot": "Slot",
|
|
2276
2350
|
"field-id": "Field ID",
|
|
2277
2351
|
"field-id-duplicate": "Field ID must be unique",
|
|
@@ -2283,6 +2357,8 @@ function confirmChanges() {
|
|
|
2283
2357
|
"copy-field-id-short": "Copy ID",
|
|
2284
2358
|
"copy-field-id-failed": "Failed to copy the field ID. Check clipboard permissions.",
|
|
2285
2359
|
"field-label": "Field label",
|
|
2360
|
+
"field-required": "Show required hint",
|
|
2361
|
+
"field-required-description": "When enabled, only a red asterisk is shown after the label. No validation rule is added automatically.",
|
|
2286
2362
|
"field-icon": "Icon",
|
|
2287
2363
|
"field-icon-placeholder": "For example fluent:person-20-regular",
|
|
2288
2364
|
"field-style": "Style expression",
|
|
@@ -2331,6 +2407,7 @@ function confirmChanges() {
|
|
|
2331
2407
|
"no-matches": "No matching fields.",
|
|
2332
2408
|
"no-validation-rules": "No validation rules yet.",
|
|
2333
2409
|
"unnamed-field": "Untitled {type} field",
|
|
2410
|
+
"empty-field": "Empty {id}",
|
|
2334
2411
|
"slot-field": "Slot {id}",
|
|
2335
2412
|
"no-fields": "No fields yet.",
|
|
2336
2413
|
"drag-field": "Drag to reorder field {field}",
|