@shwfed/config 2.3.23 → 2.3.24

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