@shwfed/config 2.3.28 → 2.4.0

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 (146) hide show
  1. package/dist/mcp.mjs +3128 -1272
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{config-CQHS6cZe.js → config-BcQQl4v6.js} +1 -1
  4. package/dist/preview/assets/{config-fvkC2rB8.js → config-BdFIFUa_.js} +1 -1
  5. package/dist/preview/assets/{config-DDfTl9Cs.js → config-Bi9F-Jdh.js} +1 -1
  6. package/dist/preview/assets/{config-CJHPt8Gx.js → config-Bxkq2ZRm.js} +1 -1
  7. package/dist/preview/assets/{config-D0_1yZdF.js → config-C32yfrlg.js} +1 -1
  8. package/dist/preview/assets/{config--PcXQV_r.js → config-CHHX7vhb.js} +1 -1
  9. package/dist/preview/assets/{config-5KVDXgUF.js → config-CZ0f5xdI.js} +1 -1
  10. package/dist/preview/assets/{config-B5avpKJE.js → config-D9xGgFnF.js} +1 -1
  11. package/dist/preview/assets/{config-CNo3isHa.js → config-Ddh8pxIi.js} +1 -1
  12. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-RM-qDh0R.js → definition.vue_vue_type_script_setup_true_lang-C_cjxvm1.js} +1 -1
  13. package/dist/preview/assets/{index-a2QwAots.css → index-BqOX70Hd.css} +1 -1
  14. package/dist/preview/assets/index-D-VR1i8D.js +659 -0
  15. package/dist/preview/assets/index-ihZGlPdX.js +1 -0
  16. package/dist/preview/assets/{runtime-BPjZQmcY.js → runtime-Bn8mqeDH.js} +1 -1
  17. package/dist/preview/assets/{runtime-DcrzodsN.js → runtime-Cc_Wk3o-.js} +1 -1
  18. package/dist/preview/assets/{runtime-BGTWf-O7.js → runtime-CttAjIgg.js} +1 -1
  19. package/dist/preview/assets/{runtime-Dy4ZmQ-n.js → runtime-Cx4f2UTl.js} +1 -1
  20. package/dist/preview/assets/{runtime-CCbyrqQT.js → runtime-D1dESjXR.js} +1 -1
  21. package/dist/preview/assets/{runtime-C_XX6a0C.js → runtime-DIEP1Xbh.js} +1 -1
  22. package/dist/preview/assets/{runtime-CtqwtTE_.js → runtime-DKceWuBx.js} +1 -1
  23. package/dist/preview/assets/{runtime-Dr_10emf.js → runtime-Dhid9O5c.js} +1 -1
  24. package/dist/preview/assets/{runtime-Bq3fmxeF.js → runtime-YMiqi6WY.js} +1 -1
  25. package/dist/preview/index.html +2 -2
  26. package/dist/runtime/components/block-layout-editor/index.d.vue.ts +10 -2
  27. package/dist/runtime/components/block-layout-editor/index.vue +44 -8
  28. package/dist/runtime/components/block-layout-editor/index.vue.d.ts +10 -2
  29. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/config.d.vue.ts +2 -0
  30. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/config.vue.d.ts +2 -0
  31. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/runtime.d.vue.ts +2 -0
  32. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/runtime.vue.d.ts +2 -0
  33. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/schema.d.ts +2 -0
  34. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +2 -0
  35. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +2 -0
  36. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +2 -0
  37. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +2 -0
  38. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +3 -0
  39. package/dist/runtime/components/config/config.vue +35 -0
  40. package/dist/runtime/components/config/use-editor.d.ts +11 -1
  41. package/dist/runtime/components/config/use-editor.js +27 -1
  42. package/dist/runtime/components/form/config.vue +32 -0
  43. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/config.d.vue.ts +163 -0
  44. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/config.vue +745 -0
  45. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/config.vue.d.ts +163 -0
  46. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/runtime.d.vue.ts +8 -0
  47. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/runtime.vue +383 -0
  48. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/runtime.vue.d.ts +8 -0
  49. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/schema.d.ts +264 -0
  50. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/schema.js +183 -0
  51. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/config.d.vue.ts +163 -0
  52. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/config.vue +745 -0
  53. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/config.vue.d.ts +163 -0
  54. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/runtime.d.vue.ts +8 -0
  55. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/runtime.vue +402 -0
  56. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/runtime.vue.d.ts +8 -0
  57. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/schema.d.ts +264 -0
  58. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/schema.js +209 -0
  59. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +129 -0
  60. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue +618 -0
  61. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +129 -0
  62. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/runtime.d.vue.ts +8 -0
  63. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/runtime.vue +501 -0
  64. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/runtime.vue.d.ts +8 -0
  65. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/schema.d.ts +99 -0
  66. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/schema.js +133 -0
  67. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +127 -0
  68. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue +550 -0
  69. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +127 -0
  70. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/runtime.d.vue.ts +8 -0
  71. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/runtime.vue +496 -0
  72. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/runtime.vue.d.ts +8 -0
  73. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/schema.d.ts +96 -0
  74. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/schema.js +125 -0
  75. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +133 -0
  76. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue +605 -0
  77. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +133 -0
  78. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/runtime.d.vue.ts +8 -0
  79. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/runtime.vue +401 -0
  80. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/runtime.vue.d.ts +8 -0
  81. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/schema.d.ts +102 -0
  82. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/schema.js +142 -0
  83. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +131 -0
  84. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue +560 -0
  85. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +131 -0
  86. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/runtime.d.vue.ts +8 -0
  87. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/runtime.vue +395 -0
  88. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/runtime.vue.d.ts +8 -0
  89. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/schema.d.ts +96 -0
  90. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/schema.js +118 -0
  91. package/dist/runtime/components/form/fields/2026-05-28/tree-combobox-shared.d.ts +35 -0
  92. package/dist/runtime/components/form/fields/2026-05-28/tree-combobox-shared.js +31 -0
  93. package/dist/runtime/components/form/index.vue +7 -5
  94. package/dist/runtime/components/form/schema.d.ts +4 -0
  95. package/dist/runtime/components/form/schema.js +4 -0
  96. package/dist/runtime/components/form/unit-config.vue +45 -1
  97. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.select/config.vue +0 -22
  98. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.select/header.vue +3 -15
  99. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.select/schema.d.ts +0 -1
  100. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.select/schema.js +0 -4
  101. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +183 -0
  102. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue +931 -0
  103. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +183 -0
  104. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/runtime.d.vue.ts +9 -0
  105. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/runtime.vue +463 -0
  106. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/runtime.vue.d.ts +9 -0
  107. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/schema.d.ts +283 -0
  108. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/schema.js +275 -0
  109. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +183 -0
  110. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue +931 -0
  111. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +183 -0
  112. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/runtime.d.vue.ts +9 -0
  113. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/runtime.vue +414 -0
  114. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/runtime.vue.d.ts +9 -0
  115. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/schema.d.ts +283 -0
  116. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/schema.js +275 -0
  117. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +133 -0
  118. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.vue +632 -0
  119. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +133 -0
  120. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/runtime.d.vue.ts +9 -0
  121. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/runtime.vue +461 -0
  122. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/runtime.vue.d.ts +9 -0
  123. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/schema.d.ts +93 -0
  124. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/schema.js +161 -0
  125. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +131 -0
  126. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.vue +563 -0
  127. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +131 -0
  128. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/runtime.d.vue.ts +9 -0
  129. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/runtime.vue +443 -0
  130. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/runtime.vue.d.ts +9 -0
  131. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/schema.d.ts +90 -0
  132. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/schema.js +153 -0
  133. package/dist/runtime/components/table/columns/2026-05-28/tree-combobox-shared.d.ts +35 -0
  134. package/dist/runtime/components/table/columns/2026-05-28/tree-combobox-shared.js +31 -0
  135. package/dist/runtime/components/table/config.vue +55 -82
  136. package/dist/runtime/components/table/schema.d.ts +4 -0
  137. package/dist/runtime/components/ui/command/CommandItem.d.vue.ts +7 -0
  138. package/dist/runtime/components/ui/command/CommandItem.vue +13 -4
  139. package/dist/runtime/components/ui/command/CommandItem.vue.d.ts +7 -0
  140. package/dist/runtime/share/clipboard.d.ts +26 -0
  141. package/dist/runtime/share/clipboard.js +82 -0
  142. package/dist/runtime/share/layout.d.ts +4 -0
  143. package/dist/runtime/share/layout.js +35 -0
  144. package/package.json +1 -1
  145. package/dist/preview/assets/index-DNd8J9Zv.js +0 -643
  146. package/dist/preview/assets/index-DrIMqXAa.js +0 -1
@@ -0,0 +1,931 @@
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 { Textarea } from "../../../../ui/textarea";
12
+ import {
13
+ InputGroup,
14
+ InputGroupAddon,
15
+ InputGroupButton,
16
+ InputGroupInput,
17
+ InputGroupNumberField
18
+ } from "../../../../ui/input-group";
19
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../../../ui/tabs";
20
+ import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
21
+ import { Markdown } from "../../../../ui/markdown";
22
+ import TriggersField from "../../../../actions/components/triggers-field.vue";
23
+ import { itemSchema, remoteOptionsSchema, schema, writeSchema } from "./schema";
24
+ defineOptions({ name: "ShwfedTableComboboxSingleConfig" });
25
+ const value = defineModel({ type: null, ...{ required: true } });
26
+ const fieldSchema = schema(() => {
27
+ });
28
+ const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
29
+ const fieldDescription = (field) => getStructFieldDescription(fieldSchema, field);
30
+ const itemFieldSchema = itemSchema(() => {
31
+ });
32
+ const itemFieldTitle = (f) => getStructFieldTitle(itemFieldSchema, f) ?? f;
33
+ const itemFieldDescription = (f) => getStructFieldDescription(itemFieldSchema, f);
34
+ const remoteSchema = remoteOptionsSchema(() => {
35
+ });
36
+ const remoteFieldTitle = (f) => getStructFieldTitle(remoteSchema, f) ?? f;
37
+ const remoteFieldDescription = (f) => getStructFieldDescription(remoteSchema, f);
38
+ const writeUnion = writeSchema(() => {
39
+ });
40
+ const writeMembers = (writeUnion.ast.types ?? []).map(
41
+ (ast) => (
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ { ast }
44
+ )
45
+ );
46
+ const writeFieldTitle = (f) => {
47
+ for (const m of writeMembers) {
48
+ const t = getStructFieldTitle(m, f);
49
+ if (t) return t;
50
+ }
51
+ return f;
52
+ };
53
+ const writeFieldDescription = (f) => {
54
+ for (const m of writeMembers) {
55
+ const d = getStructFieldDescription(m, f);
56
+ if (d) return d;
57
+ }
58
+ return void 0;
59
+ };
60
+ const ROW_VARS = {
61
+ row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
62
+ index: { type: "number", label: "\u884C\u7D22\u5F15" }
63
+ };
64
+ const ROW_JSON_VARS = {
65
+ ...ROW_VARS,
66
+ json: { type: "dyn", label: "HTTP \u54CD\u5E94\u4F53\uFF08\u5DF2\u89E3\u6790 JSON\uFF09" }
67
+ };
68
+ const ROW_OPTION_VARS = {
69
+ ...ROW_VARS,
70
+ option: { type: "dyn", label: "\u5F53\u524D\u9009\u9879" }
71
+ };
72
+ const ROW_VALUE_VARS = {
73
+ ...ROW_VARS,
74
+ value: { type: "dyn", label: "\u7528\u6237\u9009\u4E2D\u7684\u65B0\u503C\uFF08\u6E05\u7A7A\u65F6\u4E3A `null`\uFF09" }
75
+ };
76
+ const JSON_VARS = {
77
+ json: { type: "dyn", label: "HTTP \u54CD\u5E94\u4F53" }
78
+ };
79
+ function celModel(field) {
80
+ return computed({
81
+ get: () => value.value[field] ?? "",
82
+ set: (v) => {
83
+ if (v === "") {
84
+ const { [field]: _omit, ...rest } = value.value;
85
+ value.value = rest;
86
+ } else {
87
+ value.value = { ...value.value, [field]: v };
88
+ }
89
+ }
90
+ });
91
+ }
92
+ const hiddenModel = celModel("hidden");
93
+ const disabledModel = celModel("disabled");
94
+ const readonlyModel = celModel("readonly");
95
+ const writeKind = computed(() => value.value.write.kind);
96
+ function setWriteKind(kind) {
97
+ if (value.value.write.kind === kind) return;
98
+ const write = kind === "binding" ? { kind: "binding", binding: "" } : { kind: "remote", accessor: "" };
99
+ value.value = { ...value.value, write };
100
+ }
101
+ function patchRemoteWrite(patch) {
102
+ if (value.value.write.kind !== "remote") return;
103
+ value.value = { ...value.value, write: { ...value.value.write, ...patch } };
104
+ }
105
+ function remoteWriteCelModel(field) {
106
+ return computed({
107
+ get: () => value.value.write.kind === "remote" ? value.value.write[field] ?? "" : "",
108
+ set: (v) => {
109
+ if (value.value.write.kind !== "remote") return;
110
+ if (v === "") {
111
+ const { [field]: _omit, ...rest } = value.value.write;
112
+ value.value = { ...value.value, write: rest };
113
+ } else {
114
+ patchRemoteWrite({ [field]: v });
115
+ }
116
+ }
117
+ });
118
+ }
119
+ const bindingModel = computed({
120
+ get: () => value.value.write.kind === "binding" ? value.value.write.binding : "",
121
+ set: (v) => {
122
+ if (value.value.write.kind !== "binding") return;
123
+ value.value = { ...value.value, write: { kind: "binding", binding: v.trim() } };
124
+ }
125
+ });
126
+ const accessorModel = computed({
127
+ get: () => value.value.write.kind === "remote" ? value.value.write.accessor : "",
128
+ set: (v) => patchRemoteWrite({ accessor: v })
129
+ });
130
+ const onChangeModel = remoteWriteCelModel("onChange");
131
+ const successMessageModel = remoteWriteCelModel("successMessage");
132
+ const triggers = computed(
133
+ () => value.value.write.kind === "remote" ? value.value.write.triggers ?? [] : []
134
+ );
135
+ function updateTriggers(next) {
136
+ if (value.value.write.kind !== "remote") return;
137
+ if (next.length === 0) {
138
+ const { triggers: _omit, ...rest } = value.value.write;
139
+ value.value = { ...value.value, write: rest };
140
+ } else {
141
+ value.value = { ...value.value, write: { ...value.value.write, triggers: [...next] } };
142
+ }
143
+ }
144
+ const optionsKind = computed(() => value.value.options.kind);
145
+ function emptyStatic() {
146
+ return { kind: "static", items: [] };
147
+ }
148
+ function emptyRemote() {
149
+ return {
150
+ kind: "remote",
151
+ request: "",
152
+ options: "",
153
+ optionValue: "option",
154
+ optionLabel: [{ locale: "zh", message: "" }]
155
+ };
156
+ }
157
+ function setKind(kind) {
158
+ if (value.value.options.kind === kind) return;
159
+ value.value = {
160
+ ...value.value,
161
+ options: kind === "static" ? emptyStatic() : emptyRemote()
162
+ };
163
+ }
164
+ const items = computed(() => {
165
+ return value.value.options.kind === "static" ? value.value.options.items : [];
166
+ });
167
+ function patchStatic(patch) {
168
+ if (value.value.options.kind !== "static") return;
169
+ value.value = {
170
+ ...value.value,
171
+ options: { ...value.value.options, ...patch }
172
+ };
173
+ }
174
+ function patchRemote(patch) {
175
+ if (value.value.options.kind !== "remote") return;
176
+ value.value = {
177
+ ...value.value,
178
+ options: { ...value.value.options, ...patch }
179
+ };
180
+ }
181
+ const requestModel = computed({
182
+ get: () => value.value.options.kind === "remote" ? value.value.options.request : "",
183
+ set: (v) => patchRemote({ request: v })
184
+ });
185
+ const optionsExprModel = computed({
186
+ get: () => value.value.options.kind === "remote" ? value.value.options.options : "",
187
+ set: (v) => patchRemote({ options: v })
188
+ });
189
+ const optionValueModel = computed({
190
+ get: () => value.value.options.kind === "remote" ? value.value.options.optionValue : "option",
191
+ set: (v) => patchRemote({ optionValue: v })
192
+ });
193
+ const optionLabelModel = computed({
194
+ get: () => value.value.options.kind === "remote" ? value.value.options.optionLabel : [{ locale: "zh", message: "" }],
195
+ set: (v) => patchRemote({ optionLabel: v })
196
+ });
197
+ const optionKeywordsModel = computed({
198
+ get: () => value.value.options.kind === "remote" ? value.value.options.optionKeywords ?? "" : "",
199
+ set: (v) => {
200
+ if (value.value.options.kind !== "remote") return;
201
+ if (v === "") {
202
+ const { optionKeywords: _omit, ...rest } = value.value.options;
203
+ value.value = { ...value.value, options: rest };
204
+ } else {
205
+ patchRemote({ optionKeywords: v });
206
+ }
207
+ }
208
+ });
209
+ function newId() {
210
+ return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
211
+ const r = Math.random() * 16 | 0;
212
+ const v = c === "x" ? r : r & 3 | 8;
213
+ return v.toString(16);
214
+ });
215
+ }
216
+ function newItem() {
217
+ return {
218
+ id: newId(),
219
+ label: [{ locale: "zh", message: "" }],
220
+ value: { kind: "text", value: "" }
221
+ };
222
+ }
223
+ function patchItem(index, patch) {
224
+ if (value.value.options.kind !== "static") return;
225
+ const next = [...value.value.options.items];
226
+ const cur = next[index];
227
+ if (!cur) return;
228
+ next[index] = { ...cur, ...patch };
229
+ patchStatic({ items: next });
230
+ }
231
+ function addItem() {
232
+ if (value.value.options.kind !== "static") return;
233
+ patchStatic({ items: [...value.value.options.items, newItem()] });
234
+ }
235
+ function removeItem(index) {
236
+ if (value.value.options.kind !== "static") return;
237
+ const next = [...value.value.options.items];
238
+ next.splice(index, 1);
239
+ patchStatic({ items: next });
240
+ }
241
+ function setItemKind(index, kind) {
242
+ if (value.value.options.kind !== "static") return;
243
+ const cur = value.value.options.items[index];
244
+ if (!cur || cur.value.kind === kind) return;
245
+ patchItem(index, {
246
+ value: kind === "text" ? { kind: "text", value: "" } : { kind: "number", value: 0 }
247
+ });
248
+ }
249
+ function setItemTextValue(index, text) {
250
+ patchItem(index, { value: { kind: "text", value: text } });
251
+ }
252
+ function setItemNumberValue(index, n) {
253
+ patchItem(index, {
254
+ value: {
255
+ kind: "number",
256
+ value: typeof n === "number" && Number.isFinite(n) ? n : 0
257
+ }
258
+ });
259
+ }
260
+ function setItemLabel(index, label) {
261
+ patchItem(index, { label });
262
+ }
263
+ function setItemTooltip(index, tooltip) {
264
+ const isEmpty = !tooltip || tooltip.every((l) => l.message.trim().length === 0);
265
+ if (value.value.options.kind !== "static") return;
266
+ if (isEmpty) {
267
+ const cur = value.value.options.items[index];
268
+ if (!cur) return;
269
+ const { tooltip: _omit, ...rest } = cur;
270
+ const next = [...value.value.options.items];
271
+ next[index] = rest;
272
+ patchStatic({ items: next });
273
+ } else {
274
+ patchItem(index, { tooltip });
275
+ }
276
+ }
277
+ function keywordsText(item) {
278
+ return (item.keywords ?? []).join("\n");
279
+ }
280
+ function setItemKeywords(index, text) {
281
+ if (value.value.options.kind !== "static") return;
282
+ const list = text.split("\n").map((s) => s.trim()).filter((s) => s.length > 0);
283
+ const cur = value.value.options.items[index];
284
+ if (!cur) return;
285
+ const next = [...value.value.options.items];
286
+ if (list.length === 0) {
287
+ const { keywords: _omit, ...rest } = cur;
288
+ next[index] = rest;
289
+ } else {
290
+ next[index] = { ...cur, keywords: list };
291
+ }
292
+ patchStatic({ items: next });
293
+ }
294
+ </script>
295
+
296
+ <template>
297
+ <div class="space-y-5">
298
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
299
+ <Field orientation="vertical">
300
+ <FieldLabel class="text-xs text-zinc-500">
301
+ <template
302
+ v-if="fieldDescription('title')"
303
+ #tooltip
304
+ >
305
+ <Markdown
306
+ :source="fieldDescription('title')"
307
+ block
308
+ class="prose prose-sm prose-zinc"
309
+ />
310
+ </template>
311
+ {{ fieldTitle("title") }}
312
+ </FieldLabel>
313
+ <Locale v-model="value.title" />
314
+ </Field>
315
+ <Field orientation="vertical">
316
+ <FieldLabel class="text-xs text-zinc-500">
317
+ <template
318
+ v-if="fieldDescription('tooltip')"
319
+ #tooltip
320
+ >
321
+ <Markdown
322
+ :source="fieldDescription('tooltip')"
323
+ block
324
+ class="prose prose-sm prose-zinc"
325
+ />
326
+ </template>
327
+ {{ fieldTitle("tooltip") }}
328
+ </FieldLabel>
329
+ <Locale
330
+ v-model="value.tooltip"
331
+ markdown
332
+ />
333
+ </Field>
334
+ </div>
335
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
336
+ <Field orientation="vertical">
337
+ <FieldLabel class="text-xs text-zinc-500">
338
+ <template
339
+ v-if="fieldDescription('placeholder')"
340
+ #tooltip
341
+ >
342
+ <Markdown
343
+ :source="fieldDescription('placeholder')"
344
+ block
345
+ class="prose prose-sm prose-zinc"
346
+ />
347
+ </template>
348
+ {{ fieldTitle("placeholder") }}
349
+ </FieldLabel>
350
+ <Locale v-model="value.placeholder" />
351
+ </Field>
352
+ <Field orientation="vertical">
353
+ <FieldLabel class="text-xs text-zinc-500">
354
+ <template
355
+ v-if="fieldDescription('size')"
356
+ #tooltip
357
+ >
358
+ <Markdown
359
+ :source="fieldDescription('size')"
360
+ block
361
+ class="prose prose-sm prose-zinc"
362
+ />
363
+ </template>
364
+ {{ fieldTitle("size") }}
365
+ </FieldLabel>
366
+ <InputGroup>
367
+ <InputGroupNumberField
368
+ :model-value="value.size"
369
+ :disabled="value.grow"
370
+ :min="0"
371
+ @update:model-value="(v) => value = { ...value, size: v }"
372
+ />
373
+ <InputGroupAddon align="inline-end">
374
+ <InputGroupButton
375
+ :variant="value.grow ? 'primary' : 'ghost'"
376
+ size="xs"
377
+ @click="value = { ...value, grow: !value.grow }"
378
+ >
379
+ <Icon :icon="value.grow ? 'fluent:lock-closed-20-regular' : 'fluent:arrow-autofit-width-20-regular'" />
380
+ {{ fieldTitle("grow") }}
381
+ </InputGroupButton>
382
+ </InputGroupAddon>
383
+ </InputGroup>
384
+ </Field>
385
+ </div>
386
+
387
+ <Field orientation="vertical">
388
+ <FieldLabel class="text-xs text-zinc-500">
389
+ <template #tooltip>
390
+ <Markdown
391
+ source="选项可以是静态配置的固定列表,也可以由远程接口实时加载"
392
+ block
393
+ class="prose prose-sm prose-zinc"
394
+ />
395
+ </template>
396
+ 选项来源
397
+ </FieldLabel>
398
+
399
+ <Tabs
400
+ :model-value="optionsKind"
401
+ @update:model-value="(v) => {
402
+ if (v === 'static' || v === 'remote') setKind(v);
403
+ }"
404
+ >
405
+ <TabsList>
406
+ <TabsTrigger value="static">
407
+ 静态
408
+ </TabsTrigger>
409
+ <TabsTrigger value="remote">
410
+ 远程
411
+ </TabsTrigger>
412
+ </TabsList>
413
+ <TabsContent
414
+ value="static"
415
+ class="outline-none"
416
+ >
417
+ <div class="flex flex-col gap-3 pt-3">
418
+ <div
419
+ v-for="(item, index) in items"
420
+ :key="item.id"
421
+ data-slot="combobox-single-item"
422
+ class="relative pt-8 grid grid-cols-2 gap-3 rounded border border-zinc-200 bg-zinc-50/40 p-3"
423
+ >
424
+ <InputGroupButton
425
+ variant="destructive"
426
+ size="icon-xs"
427
+ data-slot="combobox-single-item-delete"
428
+ aria-label="删除选项"
429
+ class="absolute right-2 top-2 z-10"
430
+ @click="removeItem(index)"
431
+ >
432
+ <Icon icon="fluent:delete-20-regular" />
433
+ </InputGroupButton>
434
+
435
+ <Field orientation="vertical">
436
+ <FieldLabel class="text-xs text-zinc-500">
437
+ <template
438
+ v-if="itemFieldDescription('label')"
439
+ #tooltip
440
+ >
441
+ <Markdown
442
+ :source="itemFieldDescription('label')"
443
+ block
444
+ class="prose prose-sm prose-zinc"
445
+ />
446
+ </template>
447
+ {{ itemFieldTitle("label") }}
448
+ </FieldLabel>
449
+ <Locale
450
+ markdown
451
+ translate-hint="combobox option label"
452
+ :model-value="item.label"
453
+ @update:model-value="(v) => setItemLabel(index, v)"
454
+ />
455
+ </Field>
456
+
457
+ <Field orientation="vertical">
458
+ <FieldLabel class="text-xs text-zinc-500">
459
+ <template
460
+ v-if="itemFieldDescription('value')"
461
+ #tooltip
462
+ >
463
+ <Markdown
464
+ :source="itemFieldDescription('value')"
465
+ block
466
+ class="prose prose-sm prose-zinc"
467
+ />
468
+ </template>
469
+ {{ itemFieldTitle("value") }}
470
+ </FieldLabel>
471
+ <InputGroup>
472
+ <InputGroupAddon align="inline-start">
473
+ <DropdownMenu>
474
+ <DropdownMenuTrigger as-child>
475
+ <InputGroupButton
476
+ size="icon-sm"
477
+ as-child
478
+ >
479
+ <button
480
+ type="button"
481
+ data-slot="combobox-single-item-kind-trigger"
482
+ class="text-zinc-500 transition-colors hover:text-zinc-700 [&_svg:not([class*='size-'])]:size-3.5"
483
+ aria-label="切换值类型"
484
+ >
485
+ <Icon
486
+ :icon="item.value.kind === 'number' ? 'fluent:number-symbol-20-regular' : 'fluent:textbox-20-regular'"
487
+ />
488
+ </button>
489
+ </InputGroupButton>
490
+ </DropdownMenuTrigger>
491
+ <DropdownMenuContent align="start">
492
+ <DropdownMenuItem @select="setItemKind(index, 'text')">
493
+ <Icon icon="fluent:textbox-20-regular" />
494
+ <span>文本</span>
495
+ </DropdownMenuItem>
496
+ <DropdownMenuItem @select="setItemKind(index, 'number')">
497
+ <Icon icon="fluent:number-symbol-20-regular" />
498
+ <span>数字</span>
499
+ </DropdownMenuItem>
500
+ </DropdownMenuContent>
501
+ </DropdownMenu>
502
+ </InputGroupAddon>
503
+
504
+ <InputGroupInput
505
+ v-if="item.value.kind === 'text'"
506
+ :model-value="item.value.value"
507
+ placeholder="例:admin"
508
+ @update:model-value="(v) => setItemTextValue(index, String(v ?? ''))"
509
+ />
510
+ <InputGroupNumberField
511
+ v-else
512
+ :model-value="item.value.value"
513
+ @update:model-value="(v) => setItemNumberValue(index, v)"
514
+ />
515
+ </InputGroup>
516
+ </Field>
517
+
518
+ <Field orientation="vertical">
519
+ <FieldLabel class="text-xs text-zinc-500">
520
+ <template
521
+ v-if="itemFieldDescription('tooltip')"
522
+ #tooltip
523
+ >
524
+ <Markdown
525
+ :source="itemFieldDescription('tooltip')"
526
+ block
527
+ class="prose prose-sm prose-zinc"
528
+ />
529
+ </template>
530
+ {{ itemFieldTitle("tooltip") }}
531
+ </FieldLabel>
532
+ <Locale
533
+ markdown
534
+ translate-hint="combobox option tooltip"
535
+ :model-value="item.tooltip"
536
+ @update:model-value="(v) => setItemTooltip(index, v)"
537
+ />
538
+ </Field>
539
+
540
+ <Field orientation="vertical">
541
+ <FieldLabel class="text-xs text-zinc-500">
542
+ <template
543
+ v-if="itemFieldDescription('keywords')"
544
+ #tooltip
545
+ >
546
+ <Markdown
547
+ :source="itemFieldDescription('keywords')"
548
+ block
549
+ class="prose prose-sm prose-zinc"
550
+ />
551
+ </template>
552
+ {{ itemFieldTitle("keywords") }}
553
+ </FieldLabel>
554
+ <Textarea
555
+ data-slot="combobox-single-item-keywords"
556
+ :model-value="keywordsText(item)"
557
+ placeholder="每行一个关键词"
558
+ :rows="2"
559
+ @update:model-value="(v) => setItemKeywords(index, String(v ?? ''))"
560
+ />
561
+ </Field>
562
+ </div>
563
+
564
+ <Button
565
+ type="button"
566
+ data-slot="combobox-single-add-item"
567
+ class="w-full justify-center"
568
+ @click="addItem"
569
+ >
570
+ <Icon icon="fluent:add-20-regular" />
571
+ <span>增加选项</span>
572
+ </Button>
573
+ </div>
574
+ </TabsContent>
575
+ <TabsContent
576
+ value="remote"
577
+ class="outline-none"
578
+ >
579
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4 pt-3">
580
+ <Field orientation="vertical">
581
+ <FieldLabel class="text-xs text-zinc-500">
582
+ <template
583
+ v-if="remoteFieldDescription('request')"
584
+ #tooltip
585
+ >
586
+ <Markdown
587
+ :source="remoteFieldDescription('request')"
588
+ block
589
+ class="prose prose-sm prose-zinc"
590
+ />
591
+ </template>
592
+ {{ remoteFieldTitle("request") }}
593
+ </FieldLabel>
594
+ <ExpressionEditor
595
+ v-model="requestModel"
596
+ placeholder="如 http.get('/api/roles')"
597
+ result-type="HttpRequest"
598
+ :extra-vars="ROW_VARS"
599
+ multiline
600
+ />
601
+ </Field>
602
+ <Field orientation="vertical">
603
+ <FieldLabel class="text-xs text-zinc-500">
604
+ <template
605
+ v-if="remoteFieldDescription('options')"
606
+ #tooltip
607
+ >
608
+ <Markdown
609
+ :source="remoteFieldDescription('options')"
610
+ block
611
+ class="prose prose-sm prose-zinc"
612
+ />
613
+ </template>
614
+ {{ remoteFieldTitle("options") }}
615
+ </FieldLabel>
616
+ <ExpressionEditor
617
+ v-model="optionsExprModel"
618
+ placeholder="如 json.data"
619
+ result-type="dyn"
620
+ :extra-vars="ROW_JSON_VARS"
621
+ multiline
622
+ />
623
+ </Field>
624
+ <Field orientation="vertical">
625
+ <FieldLabel class="text-xs text-zinc-500">
626
+ <template
627
+ v-if="remoteFieldDescription('optionValue')"
628
+ #tooltip
629
+ >
630
+ <Markdown
631
+ :source="remoteFieldDescription('optionValue')"
632
+ block
633
+ class="prose prose-sm prose-zinc"
634
+ />
635
+ </template>
636
+ {{ remoteFieldTitle("optionValue") }}
637
+ </FieldLabel>
638
+ <ExpressionEditor
639
+ v-model="optionValueModel"
640
+ placeholder="如 option.id"
641
+ result-type="dyn"
642
+ :extra-vars="ROW_OPTION_VARS"
643
+ />
644
+ </Field>
645
+ <Field orientation="vertical">
646
+ <FieldLabel class="text-xs text-zinc-500">
647
+ <template
648
+ v-if="remoteFieldDescription('optionLabel')"
649
+ #tooltip
650
+ >
651
+ <Markdown
652
+ :source="remoteFieldDescription('optionLabel')"
653
+ block
654
+ class="prose prose-sm prose-zinc"
655
+ />
656
+ </template>
657
+ {{ remoteFieldTitle("optionLabel") }}
658
+ </FieldLabel>
659
+ <Locale
660
+ :model-value="optionLabelModel"
661
+ markdown
662
+ translate-hint="combobox option label"
663
+ @update:model-value="(v) => optionLabelModel = v"
664
+ />
665
+ </Field>
666
+ <Field orientation="vertical">
667
+ <FieldLabel class="text-xs text-zinc-500">
668
+ <template
669
+ v-if="remoteFieldDescription('optionKeywords')"
670
+ #tooltip
671
+ >
672
+ <Markdown
673
+ :source="remoteFieldDescription('optionKeywords')"
674
+ block
675
+ class="prose prose-sm prose-zinc"
676
+ />
677
+ </template>
678
+ {{ remoteFieldTitle("optionKeywords") }}
679
+ </FieldLabel>
680
+ <ExpressionEditor
681
+ v-model="optionKeywordsModel"
682
+ placeholder="如 option.aliases"
683
+ result-type="dyn"
684
+ :extra-vars="ROW_OPTION_VARS"
685
+ />
686
+ </Field>
687
+ </div>
688
+ </TabsContent>
689
+ </Tabs>
690
+ </Field>
691
+
692
+ <Field orientation="vertical">
693
+ <FieldLabel class="text-xs text-zinc-500">
694
+ <template #tooltip>
695
+ <Markdown
696
+ source="**绑定**:单元格行内可编辑,读写同一 dot-prop 路径;**远程**:只读回显行数据,选择后发起请求写入服务端"
697
+ block
698
+ class="prose prose-sm prose-zinc"
699
+ />
700
+ </template>
701
+ 写入方式
702
+ </FieldLabel>
703
+
704
+ <Tabs
705
+ :model-value="writeKind"
706
+ @update:model-value="(v) => {
707
+ if (v === 'binding' || v === 'remote') setWriteKind(v);
708
+ }"
709
+ >
710
+ <TabsList>
711
+ <TabsTrigger value="binding">
712
+ 绑定
713
+ </TabsTrigger>
714
+ <TabsTrigger value="remote">
715
+ 远程
716
+ </TabsTrigger>
717
+ </TabsList>
718
+ <TabsContent
719
+ value="binding"
720
+ class="outline-none"
721
+ >
722
+ <div class="pt-3">
723
+ <Field orientation="vertical">
724
+ <FieldLabel class="text-xs text-zinc-500">
725
+ <template
726
+ v-if="writeFieldDescription('binding')"
727
+ #tooltip
728
+ >
729
+ <Markdown
730
+ :source="writeFieldDescription('binding')"
731
+ block
732
+ class="prose prose-sm prose-zinc"
733
+ />
734
+ </template>
735
+ {{ writeFieldTitle("binding") }}
736
+ </FieldLabel>
737
+ <InputGroup>
738
+ <InputGroupInput
739
+ v-model="bindingModel"
740
+ placeholder="例:role"
741
+ class="font-mono"
742
+ />
743
+ </InputGroup>
744
+ </Field>
745
+ </div>
746
+ </TabsContent>
747
+ <TabsContent
748
+ value="remote"
749
+ class="outline-none"
750
+ >
751
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4 pt-3">
752
+ <Field orientation="vertical">
753
+ <FieldLabel class="text-xs text-zinc-500">
754
+ <template
755
+ v-if="writeFieldDescription('accessor')"
756
+ #tooltip
757
+ >
758
+ <Markdown
759
+ :source="writeFieldDescription('accessor')"
760
+ block
761
+ class="prose prose-sm prose-zinc"
762
+ />
763
+ </template>
764
+ {{ writeFieldTitle("accessor") }}
765
+ </FieldLabel>
766
+ <ExpressionEditor
767
+ v-model="accessorModel"
768
+ placeholder="如 row.role"
769
+ result-type="dyn"
770
+ :extra-vars="ROW_VARS"
771
+ />
772
+ </Field>
773
+ <Field orientation="vertical">
774
+ <FieldLabel class="text-xs text-zinc-500">
775
+ <template
776
+ v-if="writeFieldDescription('onChange')"
777
+ #tooltip
778
+ >
779
+ <Markdown
780
+ :source="writeFieldDescription('onChange')"
781
+ block
782
+ class="prose prose-sm prose-zinc"
783
+ />
784
+ </template>
785
+ {{ writeFieldTitle("onChange") }}
786
+ </FieldLabel>
787
+ <ExpressionEditor
788
+ v-model="onChangeModel"
789
+ placeholder="如 http.patch('/api/items/' + row.id).body({ role: value })"
790
+ result-type="HttpRequest"
791
+ :extra-vars="ROW_VALUE_VARS"
792
+ multiline
793
+ />
794
+ </Field>
795
+ <Field orientation="vertical">
796
+ <FieldLabel class="text-xs text-zinc-500">
797
+ <template
798
+ v-if="writeFieldDescription('successMessage')"
799
+ #tooltip
800
+ >
801
+ <Markdown
802
+ :source="writeFieldDescription('successMessage')"
803
+ block
804
+ class="prose prose-sm prose-zinc"
805
+ />
806
+ </template>
807
+ {{ writeFieldTitle("successMessage") }}
808
+ </FieldLabel>
809
+ <ExpressionEditor
810
+ v-model="successMessageModel"
811
+ placeholder="如 '已更新'"
812
+ result-type="string"
813
+ :extra-vars="JSON_VARS"
814
+ />
815
+ </Field>
816
+ <Field orientation="vertical">
817
+ <FieldLabel class="text-xs text-zinc-500">
818
+ <template
819
+ v-if="writeFieldDescription('triggers')"
820
+ #tooltip
821
+ >
822
+ <Markdown
823
+ :source="writeFieldDescription('triggers')"
824
+ block
825
+ class="prose prose-sm prose-zinc"
826
+ />
827
+ </template>
828
+ {{ writeFieldTitle("triggers") }}
829
+ </FieldLabel>
830
+ <TriggersField
831
+ :triggers="triggers"
832
+ @update:triggers="updateTriggers"
833
+ />
834
+ </Field>
835
+ </div>
836
+ </TabsContent>
837
+ </Tabs>
838
+ </Field>
839
+
840
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
841
+ <Field orientation="vertical">
842
+ <FieldLabel class="text-xs text-zinc-500">
843
+ <template
844
+ v-if="fieldDescription('hidden')"
845
+ #tooltip
846
+ >
847
+ <Markdown
848
+ :source="fieldDescription('hidden')"
849
+ block
850
+ class="prose prose-sm prose-zinc"
851
+ />
852
+ </template>
853
+ {{ fieldTitle("hidden") }}
854
+ </FieldLabel>
855
+ <ExpressionEditor
856
+ v-model="hiddenModel"
857
+ placeholder="例:row.archived"
858
+ result-type="bool"
859
+ :extra-vars="ROW_VARS"
860
+ />
861
+ </Field>
862
+ <Field orientation="vertical">
863
+ <FieldLabel class="text-xs text-zinc-500">
864
+ <template
865
+ v-if="fieldDescription('disabled')"
866
+ #tooltip
867
+ >
868
+ <Markdown
869
+ :source="fieldDescription('disabled')"
870
+ block
871
+ class="prose prose-sm prose-zinc"
872
+ />
873
+ </template>
874
+ {{ fieldTitle("disabled") }}
875
+ </FieldLabel>
876
+ <ExpressionEditor
877
+ v-model="disabledModel"
878
+ placeholder="例:row.locked"
879
+ result-type="bool"
880
+ :extra-vars="ROW_VARS"
881
+ />
882
+ </Field>
883
+ <Field orientation="vertical">
884
+ <FieldLabel class="text-xs text-zinc-500">
885
+ <template
886
+ v-if="fieldDescription('readonly')"
887
+ #tooltip
888
+ >
889
+ <Markdown
890
+ :source="fieldDescription('readonly')"
891
+ block
892
+ class="prose prose-sm prose-zinc"
893
+ />
894
+ </template>
895
+ {{ fieldTitle("readonly") }}
896
+ </FieldLabel>
897
+ <ExpressionEditor
898
+ v-model="readonlyModel"
899
+ placeholder="例:row.id == null"
900
+ result-type="bool"
901
+ :extra-vars="ROW_VARS"
902
+ />
903
+ </Field>
904
+ </div>
905
+ <Separator />
906
+ <div class="flex flex-wrap gap-x-8 gap-y-3">
907
+ <Field
908
+ orientation="horizontal"
909
+ class="w-auto gap-2"
910
+ >
911
+ <Switch
912
+ :model-value="value.enableSorting ?? false"
913
+ @update:model-value="(v) => value = { ...value, enableSorting: v }"
914
+ />
915
+ <FieldLabel class="text-sm text-zinc-600">
916
+ <template
917
+ v-if="fieldDescription('enableSorting')"
918
+ #tooltip
919
+ >
920
+ <Markdown
921
+ :source="fieldDescription('enableSorting')"
922
+ block
923
+ class="prose prose-sm prose-zinc"
924
+ />
925
+ </template>
926
+ {{ fieldTitle("enableSorting") }}
927
+ </FieldLabel>
928
+ </Field>
929
+ </div>
930
+ </div>
931
+ </template>