@shwfed/config 2.3.23 → 2.3.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/mcp.mjs +1426 -592
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{config-C-EOrL-v.js → config-BYTuKQZr.js} +1 -1
  4. package/dist/preview/assets/{config-BLxl7ROb.js → config-BoE06fMj.js} +1 -1
  5. package/dist/preview/assets/{config-BWMtPN22.js → config-CV5P2_b2.js} +1 -1
  6. package/dist/preview/assets/{config-CJADmi-_.js → config-CVAFGzPb.js} +1 -1
  7. package/dist/preview/assets/{config-5rB9Rnmf.js → config-CdH0Nxqa.js} +1 -1
  8. package/dist/preview/assets/{config-pVNUrcvS.js → config-CjlRnKnY.js} +1 -1
  9. package/dist/preview/assets/{config-DUNvg-mJ.js → config-CrvG15To.js} +1 -1
  10. package/dist/preview/assets/{config-EtlOM9yx.js → config-DZXC8YJ4.js} +1 -1
  11. package/dist/preview/assets/{config-f66PEpZ5.js → config-QaYy6DCp.js} +1 -1
  12. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-DUu-CoTZ.js → definition.vue_vue_type_script_setup_true_lang-CBPR0zl_.js} +1 -1
  13. package/dist/preview/assets/{index-CJMxrUKZ.css → index-BCE-G4Ha.css} +1 -1
  14. package/dist/preview/assets/index-BbnG2cVz.js +643 -0
  15. package/dist/preview/assets/index-NFKAYzMi.js +1 -0
  16. package/dist/preview/assets/{runtime-P99-0gRD.js → runtime-1AP_-j3e.js} +1 -1
  17. package/dist/preview/assets/{runtime-CFPeFbAB.js → runtime-BQiYt6n7.js} +1 -1
  18. package/dist/preview/assets/{runtime-B9GkQToM.js → runtime-BsiLYYky.js} +1 -1
  19. package/dist/preview/assets/{runtime-qQ5mJdRv.js → runtime-C-h7PIyx.js} +1 -1
  20. package/dist/preview/assets/{runtime-DcqfhaaX.js → runtime-CGW3z1YJ.js} +1 -1
  21. package/dist/preview/assets/{runtime-DoLJtHV2.js → runtime-C_R-VCbd.js} +1 -1
  22. package/dist/preview/assets/{runtime-CUBGWRtC.js → runtime-DGdEDDUA.js} +1 -1
  23. package/dist/preview/assets/{runtime-CI38ypkY.js → runtime-DwXjew7j.js} +1 -1
  24. package/dist/preview/assets/{runtime-C0v-S40R.js → runtime-pM3u8QsQ.js} +1 -1
  25. package/dist/preview/index.html +2 -2
  26. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +4 -4
  27. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +4 -4
  28. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +4 -4
  29. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +4 -4
  30. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.d.vue.ts +163 -0
  31. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.vue +699 -0
  32. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.vue.d.ts +163 -0
  33. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/runtime.d.vue.ts +9 -0
  34. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/runtime.vue +368 -0
  35. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/runtime.vue.d.ts +9 -0
  36. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/schema.d.ts +251 -0
  37. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/schema.js +178 -0
  38. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +167 -0
  39. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue +732 -0
  40. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +167 -0
  41. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/runtime.d.vue.ts +9 -0
  42. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/runtime.vue +402 -0
  43. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/runtime.vue.d.ts +9 -0
  44. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.d.ts +253 -0
  45. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.js +230 -0
  46. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.d.vue.ts +163 -0
  47. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.vue +699 -0
  48. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.vue.d.ts +163 -0
  49. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.d.vue.ts +9 -0
  50. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.vue +349 -0
  51. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.vue.d.ts +9 -0
  52. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/schema.d.ts +251 -0
  53. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/schema.js +178 -0
  54. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +167 -0
  55. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue +732 -0
  56. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +167 -0
  57. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.d.vue.ts +9 -0
  58. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.vue +383 -0
  59. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.vue.d.ts +9 -0
  60. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.d.ts +253 -0
  61. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.js +230 -0
  62. package/dist/runtime/components/table/config.vue +40 -0
  63. package/package.json +1 -1
  64. package/dist/preview/assets/index-B4xolIUJ.js +0 -643
  65. package/dist/preview/assets/index-DFYLO8qf.js +0 -1
@@ -0,0 +1,732 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import { Icon } from "@iconify/vue";
4
+ import { Button } from "../../../../ui/button";
5
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../../../ui/dropdown-menu";
6
+ import { ExpressionEditor } from "../../../../ui/expression-editor";
7
+ import { Switch } from "../../../../ui/switch";
8
+ import { Separator } from "../../../../ui/separator";
9
+ import { Field, FieldLabel } from "../../../../ui/field";
10
+ import { Locale } from "../../../../ui/locale";
11
+ import {
12
+ InputGroup,
13
+ InputGroupAddon,
14
+ InputGroupButton,
15
+ InputGroupInput,
16
+ InputGroupNumberField
17
+ } from "../../../../ui/input-group";
18
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../../../ui/tabs";
19
+ import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
20
+ import { Markdown } from "../../../../ui/markdown";
21
+ import TriggersField from "../../../../actions/components/triggers-field.vue";
22
+ import { itemSchema, remoteOptionsSchema, schema } from "./schema";
23
+ defineOptions({ name: "ShwfedTableComboboxSingleRemoteConfig" });
24
+ const value = defineModel({ type: null, ...{ required: true } });
25
+ const fieldSchema = schema(() => {
26
+ });
27
+ const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
28
+ const fieldDescription = (field) => getStructFieldDescription(fieldSchema, field);
29
+ const itemFieldSchema = itemSchema(() => {
30
+ });
31
+ const itemFieldTitle = (f) => getStructFieldTitle(itemFieldSchema, f) ?? f;
32
+ const itemFieldDescription = (f) => getStructFieldDescription(itemFieldSchema, f);
33
+ const remoteSchema = remoteOptionsSchema(() => {
34
+ });
35
+ const remoteFieldTitle = (f) => getStructFieldTitle(remoteSchema, f) ?? f;
36
+ const remoteFieldDescription = (f) => getStructFieldDescription(remoteSchema, f);
37
+ const ROW_VARS = {
38
+ row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
39
+ index: { type: "number", label: "\u884C\u7D22\u5F15" }
40
+ };
41
+ const ROW_JSON_VARS = {
42
+ ...ROW_VARS,
43
+ json: { type: "dyn", label: "HTTP \u54CD\u5E94\u4F53\uFF08\u5DF2\u89E3\u6790 JSON\uFF09" }
44
+ };
45
+ const ROW_OPTION_VARS = {
46
+ ...ROW_VARS,
47
+ option: { type: "dyn", label: "\u5F53\u524D\u9009\u9879" }
48
+ };
49
+ const ROW_VALUE_VARS = {
50
+ ...ROW_VARS,
51
+ value: { type: "dyn", label: "\u7528\u6237\u9009\u4E2D\u7684\u65B0\u503C\uFF08\u6E05\u7A7A\u65F6\u4E3A `null`\uFF09" }
52
+ };
53
+ const JSON_VARS = {
54
+ json: { type: "dyn", label: "HTTP \u54CD\u5E94\u4F53" }
55
+ };
56
+ function celModel(field) {
57
+ return computed({
58
+ get: () => value.value[field] ?? "",
59
+ set: (v) => {
60
+ if (v === "") {
61
+ const { [field]: _omit, ...rest } = value.value;
62
+ value.value = rest;
63
+ } else {
64
+ value.value = { ...value.value, [field]: v };
65
+ }
66
+ }
67
+ });
68
+ }
69
+ const hiddenModel = celModel("hidden");
70
+ const disabledModel = celModel("disabled");
71
+ const readonlyModel = celModel("readonly");
72
+ const onChangeModel = celModel("onChange");
73
+ const successMessageModel = celModel("successMessage");
74
+ const triggers = computed(() => value.value.triggers ?? []);
75
+ function updateTriggers(next) {
76
+ if (next.length === 0) {
77
+ const { triggers: _omit, ...rest } = value.value;
78
+ value.value = rest;
79
+ } else {
80
+ value.value = { ...value.value, triggers: [...next] };
81
+ }
82
+ }
83
+ const optionsKind = computed(() => value.value.options.kind);
84
+ function emptyStatic() {
85
+ return { kind: "static", items: [] };
86
+ }
87
+ function emptyRemote() {
88
+ return {
89
+ kind: "remote",
90
+ request: "",
91
+ options: "",
92
+ optionValue: "option",
93
+ optionLabel: [{ locale: "zh", message: "" }]
94
+ };
95
+ }
96
+ function setKind(kind) {
97
+ if (value.value.options.kind === kind) return;
98
+ value.value = {
99
+ ...value.value,
100
+ options: kind === "static" ? emptyStatic() : emptyRemote()
101
+ };
102
+ }
103
+ const items = computed(() => {
104
+ return value.value.options.kind === "static" ? value.value.options.items : [];
105
+ });
106
+ function patchStatic(patch) {
107
+ if (value.value.options.kind !== "static") return;
108
+ value.value = {
109
+ ...value.value,
110
+ options: { ...value.value.options, ...patch }
111
+ };
112
+ }
113
+ function patchRemote(patch) {
114
+ if (value.value.options.kind !== "remote") return;
115
+ value.value = {
116
+ ...value.value,
117
+ options: { ...value.value.options, ...patch }
118
+ };
119
+ }
120
+ const requestModel = computed({
121
+ get: () => value.value.options.kind === "remote" ? value.value.options.request : "",
122
+ set: (v) => patchRemote({ request: v })
123
+ });
124
+ const optionsExprModel = computed({
125
+ get: () => value.value.options.kind === "remote" ? value.value.options.options : "",
126
+ set: (v) => patchRemote({ options: v })
127
+ });
128
+ const optionValueModel = computed({
129
+ get: () => value.value.options.kind === "remote" ? value.value.options.optionValue : "option",
130
+ set: (v) => patchRemote({ optionValue: v })
131
+ });
132
+ const optionLabelModel = computed({
133
+ get: () => value.value.options.kind === "remote" ? value.value.options.optionLabel : [{ locale: "zh", message: "" }],
134
+ set: (v) => patchRemote({ optionLabel: v })
135
+ });
136
+ function newId() {
137
+ return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
138
+ const r = Math.random() * 16 | 0;
139
+ const v = c === "x" ? r : r & 3 | 8;
140
+ return v.toString(16);
141
+ });
142
+ }
143
+ function newItem() {
144
+ return {
145
+ id: newId(),
146
+ label: [{ locale: "zh", message: "" }],
147
+ value: { kind: "text", value: "" }
148
+ };
149
+ }
150
+ function patchItem(index, patch) {
151
+ if (value.value.options.kind !== "static") return;
152
+ const next = [...value.value.options.items];
153
+ const cur = next[index];
154
+ if (!cur) return;
155
+ next[index] = { ...cur, ...patch };
156
+ patchStatic({ items: next });
157
+ }
158
+ function addItem() {
159
+ if (value.value.options.kind !== "static") return;
160
+ patchStatic({ items: [...value.value.options.items, newItem()] });
161
+ }
162
+ function removeItem(index) {
163
+ if (value.value.options.kind !== "static") return;
164
+ const next = [...value.value.options.items];
165
+ next.splice(index, 1);
166
+ patchStatic({ items: next });
167
+ }
168
+ function setItemKind(index, kind) {
169
+ if (value.value.options.kind !== "static") return;
170
+ const cur = value.value.options.items[index];
171
+ if (!cur || cur.value.kind === kind) return;
172
+ patchItem(index, {
173
+ value: kind === "text" ? { kind: "text", value: "" } : { kind: "number", value: 0 }
174
+ });
175
+ }
176
+ function setItemTextValue(index, text) {
177
+ patchItem(index, { value: { kind: "text", value: text } });
178
+ }
179
+ function setItemNumberValue(index, n) {
180
+ patchItem(index, {
181
+ value: {
182
+ kind: "number",
183
+ value: typeof n === "number" && Number.isFinite(n) ? n : 0
184
+ }
185
+ });
186
+ }
187
+ function setItemLabel(index, label) {
188
+ patchItem(index, { label });
189
+ }
190
+ function setItemTooltip(index, tooltip) {
191
+ const isEmpty = !tooltip || tooltip.every((l) => l.message.trim().length === 0);
192
+ if (value.value.options.kind !== "static") return;
193
+ if (isEmpty) {
194
+ const cur = value.value.options.items[index];
195
+ if (!cur) return;
196
+ const { tooltip: _omit, ...rest } = cur;
197
+ const next = [...value.value.options.items];
198
+ next[index] = rest;
199
+ patchStatic({ items: next });
200
+ } else {
201
+ patchItem(index, { tooltip });
202
+ }
203
+ }
204
+ </script>
205
+
206
+ <template>
207
+ <div class="space-y-5">
208
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
209
+ <Field orientation="vertical">
210
+ <FieldLabel class="text-xs text-zinc-500">
211
+ <template
212
+ v-if="fieldDescription('title')"
213
+ #tooltip
214
+ >
215
+ <Markdown
216
+ :source="fieldDescription('title')"
217
+ block
218
+ class="prose prose-sm prose-zinc"
219
+ />
220
+ </template>
221
+ {{ fieldTitle("title") }}
222
+ </FieldLabel>
223
+ <Locale v-model="value.title" />
224
+ </Field>
225
+ <Field orientation="vertical">
226
+ <FieldLabel class="text-xs text-zinc-500">
227
+ <template
228
+ v-if="fieldDescription('tooltip')"
229
+ #tooltip
230
+ >
231
+ <Markdown
232
+ :source="fieldDescription('tooltip')"
233
+ block
234
+ class="prose prose-sm prose-zinc"
235
+ />
236
+ </template>
237
+ {{ fieldTitle("tooltip") }}
238
+ </FieldLabel>
239
+ <Locale
240
+ v-model="value.tooltip"
241
+ markdown
242
+ />
243
+ </Field>
244
+ </div>
245
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
246
+ <Field orientation="vertical">
247
+ <FieldLabel class="text-xs text-zinc-500">
248
+ <template
249
+ v-if="fieldDescription('accessor')"
250
+ #tooltip
251
+ >
252
+ <Markdown
253
+ :source="fieldDescription('accessor')"
254
+ block
255
+ class="prose prose-sm prose-zinc"
256
+ />
257
+ </template>
258
+ {{ fieldTitle("accessor") }}
259
+ </FieldLabel>
260
+ <ExpressionEditor
261
+ v-model="value.accessor"
262
+ placeholder="如 row.role"
263
+ result-type="dyn"
264
+ :extra-vars="ROW_VARS"
265
+ />
266
+ </Field>
267
+ <Field orientation="vertical">
268
+ <FieldLabel class="text-xs text-zinc-500">
269
+ <template
270
+ v-if="fieldDescription('placeholder')"
271
+ #tooltip
272
+ >
273
+ <Markdown
274
+ :source="fieldDescription('placeholder')"
275
+ block
276
+ class="prose prose-sm prose-zinc"
277
+ />
278
+ </template>
279
+ {{ fieldTitle("placeholder") }}
280
+ </FieldLabel>
281
+ <Locale v-model="value.placeholder" />
282
+ </Field>
283
+ <Field orientation="vertical">
284
+ <FieldLabel class="text-xs text-zinc-500">
285
+ <template
286
+ v-if="fieldDescription('size')"
287
+ #tooltip
288
+ >
289
+ <Markdown
290
+ :source="fieldDescription('size')"
291
+ block
292
+ class="prose prose-sm prose-zinc"
293
+ />
294
+ </template>
295
+ {{ fieldTitle("size") }}
296
+ </FieldLabel>
297
+ <InputGroup>
298
+ <InputGroupNumberField
299
+ :model-value="value.size"
300
+ :disabled="value.grow"
301
+ :min="0"
302
+ @update:model-value="(v) => value = { ...value, size: v }"
303
+ />
304
+ <InputGroupAddon align="inline-end">
305
+ <InputGroupButton
306
+ :variant="value.grow ? 'primary' : 'ghost'"
307
+ size="xs"
308
+ @click="value = { ...value, grow: !value.grow }"
309
+ >
310
+ <Icon :icon="value.grow ? 'fluent:lock-closed-20-regular' : 'fluent:arrow-autofit-width-20-regular'" />
311
+ {{ fieldTitle("grow") }}
312
+ </InputGroupButton>
313
+ </InputGroupAddon>
314
+ </InputGroup>
315
+ </Field>
316
+ </div>
317
+
318
+ <Field orientation="vertical">
319
+ <FieldLabel class="text-xs text-zinc-500">
320
+ <template #tooltip>
321
+ <Markdown
322
+ source="选项可以是静态配置的固定列表,也可以由远程接口实时加载"
323
+ block
324
+ class="prose prose-sm prose-zinc"
325
+ />
326
+ </template>
327
+ 选项来源
328
+ </FieldLabel>
329
+
330
+ <Tabs
331
+ :model-value="optionsKind"
332
+ @update:model-value="(v) => {
333
+ if (v === 'static' || v === 'remote') setKind(v);
334
+ }"
335
+ >
336
+ <TabsList>
337
+ <TabsTrigger value="static">
338
+ 静态
339
+ </TabsTrigger>
340
+ <TabsTrigger value="remote">
341
+ 远程
342
+ </TabsTrigger>
343
+ </TabsList>
344
+ <TabsContent
345
+ value="static"
346
+ class="outline-none"
347
+ >
348
+ <div class="flex flex-col gap-3 pt-3">
349
+ <div
350
+ v-for="(item, index) in items"
351
+ :key="item.id"
352
+ data-slot="combobox-single-item"
353
+ class="relative pt-8 grid grid-cols-3 gap-3 rounded border border-zinc-200 bg-zinc-50/40 p-3"
354
+ >
355
+ <InputGroupButton
356
+ variant="destructive"
357
+ size="icon-xs"
358
+ data-slot="combobox-single-item-delete"
359
+ aria-label="删除选项"
360
+ class="absolute right-2 top-2 z-10"
361
+ @click="removeItem(index)"
362
+ >
363
+ <Icon icon="fluent:delete-20-regular" />
364
+ </InputGroupButton>
365
+
366
+ <Field orientation="vertical">
367
+ <FieldLabel class="text-xs text-zinc-500">
368
+ <template
369
+ v-if="itemFieldDescription('label')"
370
+ #tooltip
371
+ >
372
+ <Markdown
373
+ :source="itemFieldDescription('label')"
374
+ block
375
+ class="prose prose-sm prose-zinc"
376
+ />
377
+ </template>
378
+ {{ itemFieldTitle("label") }}
379
+ </FieldLabel>
380
+ <Locale
381
+ markdown
382
+ translate-hint="combobox option label"
383
+ :model-value="item.label"
384
+ @update:model-value="(v) => setItemLabel(index, v)"
385
+ />
386
+ </Field>
387
+
388
+ <Field orientation="vertical">
389
+ <FieldLabel class="text-xs text-zinc-500">
390
+ <template
391
+ v-if="itemFieldDescription('value')"
392
+ #tooltip
393
+ >
394
+ <Markdown
395
+ :source="itemFieldDescription('value')"
396
+ block
397
+ class="prose prose-sm prose-zinc"
398
+ />
399
+ </template>
400
+ {{ itemFieldTitle("value") }}
401
+ </FieldLabel>
402
+ <InputGroup>
403
+ <InputGroupAddon align="inline-start">
404
+ <DropdownMenu>
405
+ <DropdownMenuTrigger as-child>
406
+ <InputGroupButton
407
+ size="icon-sm"
408
+ as-child
409
+ >
410
+ <button
411
+ type="button"
412
+ data-slot="combobox-single-item-kind-trigger"
413
+ class="text-zinc-500 transition-colors hover:text-zinc-700 [&_svg:not([class*='size-'])]:size-3.5"
414
+ aria-label="切换值类型"
415
+ >
416
+ <Icon
417
+ :icon="item.value.kind === 'number' ? 'fluent:number-symbol-20-regular' : 'fluent:textbox-20-regular'"
418
+ />
419
+ </button>
420
+ </InputGroupButton>
421
+ </DropdownMenuTrigger>
422
+ <DropdownMenuContent align="start">
423
+ <DropdownMenuItem @select="setItemKind(index, 'text')">
424
+ <Icon icon="fluent:textbox-20-regular" />
425
+ <span>文本</span>
426
+ </DropdownMenuItem>
427
+ <DropdownMenuItem @select="setItemKind(index, 'number')">
428
+ <Icon icon="fluent:number-symbol-20-regular" />
429
+ <span>数字</span>
430
+ </DropdownMenuItem>
431
+ </DropdownMenuContent>
432
+ </DropdownMenu>
433
+ </InputGroupAddon>
434
+
435
+ <InputGroupInput
436
+ v-if="item.value.kind === 'text'"
437
+ :model-value="item.value.value"
438
+ placeholder="例:admin"
439
+ @update:model-value="(v) => setItemTextValue(index, String(v ?? ''))"
440
+ />
441
+ <InputGroupNumberField
442
+ v-else
443
+ :model-value="item.value.value"
444
+ @update:model-value="(v) => setItemNumberValue(index, v)"
445
+ />
446
+ </InputGroup>
447
+ </Field>
448
+
449
+ <Field orientation="vertical">
450
+ <FieldLabel class="text-xs text-zinc-500">
451
+ <template
452
+ v-if="itemFieldDescription('tooltip')"
453
+ #tooltip
454
+ >
455
+ <Markdown
456
+ :source="itemFieldDescription('tooltip')"
457
+ block
458
+ class="prose prose-sm prose-zinc"
459
+ />
460
+ </template>
461
+ {{ itemFieldTitle("tooltip") }}
462
+ </FieldLabel>
463
+ <Locale
464
+ markdown
465
+ translate-hint="combobox option tooltip"
466
+ :model-value="item.tooltip"
467
+ @update:model-value="(v) => setItemTooltip(index, v)"
468
+ />
469
+ </Field>
470
+ </div>
471
+
472
+ <Button
473
+ type="button"
474
+ data-slot="combobox-single-add-item"
475
+ class="w-full justify-center"
476
+ @click="addItem"
477
+ >
478
+ <Icon icon="fluent:add-20-regular" />
479
+ <span>增加选项</span>
480
+ </Button>
481
+ </div>
482
+ </TabsContent>
483
+ <TabsContent
484
+ value="remote"
485
+ class="outline-none"
486
+ >
487
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4 pt-3">
488
+ <Field orientation="vertical">
489
+ <FieldLabel class="text-xs text-zinc-500">
490
+ <template
491
+ v-if="remoteFieldDescription('request')"
492
+ #tooltip
493
+ >
494
+ <Markdown
495
+ :source="remoteFieldDescription('request')"
496
+ block
497
+ class="prose prose-sm prose-zinc"
498
+ />
499
+ </template>
500
+ {{ remoteFieldTitle("request") }}
501
+ </FieldLabel>
502
+ <ExpressionEditor
503
+ v-model="requestModel"
504
+ placeholder="如 http.get('/api/roles')"
505
+ result-type="HttpRequest"
506
+ :extra-vars="ROW_VARS"
507
+ multiline
508
+ />
509
+ </Field>
510
+ <Field orientation="vertical">
511
+ <FieldLabel class="text-xs text-zinc-500">
512
+ <template
513
+ v-if="remoteFieldDescription('options')"
514
+ #tooltip
515
+ >
516
+ <Markdown
517
+ :source="remoteFieldDescription('options')"
518
+ block
519
+ class="prose prose-sm prose-zinc"
520
+ />
521
+ </template>
522
+ {{ remoteFieldTitle("options") }}
523
+ </FieldLabel>
524
+ <ExpressionEditor
525
+ v-model="optionsExprModel"
526
+ placeholder="如 json.data"
527
+ result-type="dyn"
528
+ :extra-vars="ROW_JSON_VARS"
529
+ multiline
530
+ />
531
+ </Field>
532
+ <Field orientation="vertical">
533
+ <FieldLabel class="text-xs text-zinc-500">
534
+ <template
535
+ v-if="remoteFieldDescription('optionValue')"
536
+ #tooltip
537
+ >
538
+ <Markdown
539
+ :source="remoteFieldDescription('optionValue')"
540
+ block
541
+ class="prose prose-sm prose-zinc"
542
+ />
543
+ </template>
544
+ {{ remoteFieldTitle("optionValue") }}
545
+ </FieldLabel>
546
+ <ExpressionEditor
547
+ v-model="optionValueModel"
548
+ placeholder="如 option.id"
549
+ result-type="dyn"
550
+ :extra-vars="ROW_OPTION_VARS"
551
+ />
552
+ </Field>
553
+ <Field orientation="vertical">
554
+ <FieldLabel class="text-xs text-zinc-500">
555
+ <template
556
+ v-if="remoteFieldDescription('optionLabel')"
557
+ #tooltip
558
+ >
559
+ <Markdown
560
+ :source="remoteFieldDescription('optionLabel')"
561
+ block
562
+ class="prose prose-sm prose-zinc"
563
+ />
564
+ </template>
565
+ {{ remoteFieldTitle("optionLabel") }}
566
+ </FieldLabel>
567
+ <Locale
568
+ :model-value="optionLabelModel"
569
+ markdown
570
+ translate-hint="combobox option label"
571
+ @update:model-value="(v) => optionLabelModel = v"
572
+ />
573
+ </Field>
574
+ </div>
575
+ </TabsContent>
576
+ </Tabs>
577
+ </Field>
578
+
579
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
580
+ <Field orientation="vertical">
581
+ <FieldLabel class="text-xs text-zinc-500">
582
+ <template
583
+ v-if="fieldDescription('hidden')"
584
+ #tooltip
585
+ >
586
+ <Markdown
587
+ :source="fieldDescription('hidden')"
588
+ block
589
+ class="prose prose-sm prose-zinc"
590
+ />
591
+ </template>
592
+ {{ fieldTitle("hidden") }}
593
+ </FieldLabel>
594
+ <ExpressionEditor
595
+ v-model="hiddenModel"
596
+ placeholder="例:row.archived"
597
+ result-type="bool"
598
+ :extra-vars="ROW_VARS"
599
+ />
600
+ </Field>
601
+ <Field orientation="vertical">
602
+ <FieldLabel class="text-xs text-zinc-500">
603
+ <template
604
+ v-if="fieldDescription('disabled')"
605
+ #tooltip
606
+ >
607
+ <Markdown
608
+ :source="fieldDescription('disabled')"
609
+ block
610
+ class="prose prose-sm prose-zinc"
611
+ />
612
+ </template>
613
+ {{ fieldTitle("disabled") }}
614
+ </FieldLabel>
615
+ <ExpressionEditor
616
+ v-model="disabledModel"
617
+ placeholder="例:row.locked"
618
+ result-type="bool"
619
+ :extra-vars="ROW_VARS"
620
+ />
621
+ </Field>
622
+ <Field orientation="vertical">
623
+ <FieldLabel class="text-xs text-zinc-500">
624
+ <template
625
+ v-if="fieldDescription('readonly')"
626
+ #tooltip
627
+ >
628
+ <Markdown
629
+ :source="fieldDescription('readonly')"
630
+ block
631
+ class="prose prose-sm prose-zinc"
632
+ />
633
+ </template>
634
+ {{ fieldTitle("readonly") }}
635
+ </FieldLabel>
636
+ <ExpressionEditor
637
+ v-model="readonlyModel"
638
+ placeholder="例:row.id == null"
639
+ result-type="bool"
640
+ :extra-vars="ROW_VARS"
641
+ />
642
+ </Field>
643
+ <Field orientation="vertical">
644
+ <FieldLabel class="text-xs text-zinc-500">
645
+ <template
646
+ v-if="fieldDescription('onChange')"
647
+ #tooltip
648
+ >
649
+ <Markdown
650
+ :source="fieldDescription('onChange')"
651
+ block
652
+ class="prose prose-sm prose-zinc"
653
+ />
654
+ </template>
655
+ {{ fieldTitle("onChange") }}
656
+ </FieldLabel>
657
+ <ExpressionEditor
658
+ v-model="onChangeModel"
659
+ placeholder="如 http.patch('/api/items/' + row.id).body({ role: value })"
660
+ result-type="HttpRequest"
661
+ :extra-vars="ROW_VALUE_VARS"
662
+ multiline
663
+ />
664
+ </Field>
665
+ <Field orientation="vertical">
666
+ <FieldLabel class="text-xs text-zinc-500">
667
+ <template
668
+ v-if="fieldDescription('successMessage')"
669
+ #tooltip
670
+ >
671
+ <Markdown
672
+ :source="fieldDescription('successMessage')"
673
+ block
674
+ class="prose prose-sm prose-zinc"
675
+ />
676
+ </template>
677
+ {{ fieldTitle("successMessage") }}
678
+ </FieldLabel>
679
+ <ExpressionEditor
680
+ v-model="successMessageModel"
681
+ placeholder="如 '已更新'"
682
+ result-type="string"
683
+ :extra-vars="JSON_VARS"
684
+ />
685
+ </Field>
686
+ <Field orientation="vertical">
687
+ <FieldLabel class="text-xs text-zinc-500">
688
+ <template
689
+ v-if="fieldDescription('triggers')"
690
+ #tooltip
691
+ >
692
+ <Markdown
693
+ :source="fieldDescription('triggers')"
694
+ block
695
+ class="prose prose-sm prose-zinc"
696
+ />
697
+ </template>
698
+ {{ fieldTitle("triggers") }}
699
+ </FieldLabel>
700
+ <TriggersField
701
+ :triggers="triggers"
702
+ @update:triggers="updateTriggers"
703
+ />
704
+ </Field>
705
+ </div>
706
+ <Separator />
707
+ <div class="flex flex-wrap gap-x-8 gap-y-3">
708
+ <Field
709
+ orientation="horizontal"
710
+ class="w-auto gap-2"
711
+ >
712
+ <Switch
713
+ :model-value="value.enableSorting ?? false"
714
+ @update:model-value="(v) => value = { ...value, enableSorting: v }"
715
+ />
716
+ <FieldLabel class="text-sm text-zinc-600">
717
+ <template
718
+ v-if="fieldDescription('enableSorting')"
719
+ #tooltip
720
+ >
721
+ <Markdown
722
+ :source="fieldDescription('enableSorting')"
723
+ block
724
+ class="prose prose-sm prose-zinc"
725
+ />
726
+ </template>
727
+ {{ fieldTitle("enableSorting") }}
728
+ </FieldLabel>
729
+ </Field>
730
+ </div>
731
+ </div>
732
+ </template>