@shwfed/config 2.10.0 → 2.10.2

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 (149) hide show
  1. package/dist/mcp.mjs +4125 -3183
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-CCaOWk_7.js → FieldGroup.vue_vue_type_script_setup_true_lang-DX5M_WNF.js} +1 -1
  4. package/dist/preview/assets/{badge-D9_7atSJ.js → badge-DFZBH8N6.js} +1 -1
  5. package/dist/preview/assets/{config-B2d8SiPi.js → config-BH2BmDoD.js} +1 -1
  6. package/dist/preview/assets/{config-Bk2VSNeu.js → config-Bg7a8Rid.js} +1 -1
  7. package/dist/preview/assets/{config-DYxMKhCU.js → config-BiOW8fS2.js} +1 -1
  8. package/dist/preview/assets/{config-CNKb25Qo.js → config-Bnp547Nm.js} +1 -1
  9. package/dist/preview/assets/{config-Bf5Vckj3.js → config-CSmHhOh2.js} +1 -1
  10. package/dist/preview/assets/{config-CQrqVV1U.js → config-CTF5-TTQ.js} +1 -1
  11. package/dist/preview/assets/{config-DWA385pD.js → config-CqeWJt_H.js} +1 -1
  12. package/dist/preview/assets/{config-BLEovXei.js → config-DBtEKoan.js} +1 -1
  13. package/dist/preview/assets/{config-DyPl6K2G.js → config-DeDCNzY_.js} +1 -1
  14. package/dist/preview/assets/{config-C9WPOoA7.js → config-Dj3w2JkF.js} +1 -1
  15. package/dist/preview/assets/{config-DZlaJUlF.js → config-XGJ9V32V.js} +1 -1
  16. package/dist/preview/assets/{config-C8lCItmz.js → config-uIHUHvNR.js} +1 -1
  17. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-CFzQ7icU.js → definition.vue_vue_type_script_setup_true_lang-Cu0CEKYT.js} +1 -1
  18. package/dist/preview/assets/index-CGChrBji.js +1 -0
  19. package/dist/preview/assets/{index-CXOEVGFP.js → index-CQA6q2ay.js} +1 -1
  20. package/dist/preview/assets/index-DX9_iE4h.js +743 -0
  21. package/dist/preview/assets/{index-BnJ5p1Mx.css → index-pkoEF5dC.css} +1 -1
  22. package/dist/preview/assets/{item-DCVX69_o.js → item-C4VJfiq8.js} +1 -1
  23. package/dist/preview/assets/{runtime-DEWGIyvr.js → runtime-6Zrje7Y1.js} +1 -1
  24. package/dist/preview/assets/{runtime-O6MNC3GA.js → runtime-BN-jMAt7.js} +1 -1
  25. package/dist/preview/assets/{runtime-BD1A-g1h.js → runtime-BQMnWueG.js} +1 -1
  26. package/dist/preview/assets/{runtime-BsNSI1XP.js → runtime-CBz5XstF.js} +1 -1
  27. package/dist/preview/assets/{runtime-BNk4EliL.js → runtime-CFb1tHwr.js} +1 -1
  28. package/dist/preview/assets/{runtime-Cbc5NH57.js → runtime-DQL6lCFp.js} +1 -1
  29. package/dist/preview/assets/{runtime-DSfMvph3.js → runtime-DcdmMgqL.js} +1 -1
  30. package/dist/preview/assets/{runtime-DJ9ElxWB.js → runtime-okYOTQd6.js} +1 -1
  31. package/dist/preview/assets/{runtime-BO-KY3T_.js → runtime-qPyuMgsh.js} +1 -1
  32. package/dist/preview/assets/{runtime-r1wbrr4k.js → runtime-yfWYeUh4.js} +1 -1
  33. package/dist/preview/assets/{schema-meta-ovcuERKg.js → schema-meta-6ZPO8dHv.js} +1 -1
  34. package/dist/preview/index.html +2 -2
  35. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/config.d.vue.ts +2 -2
  36. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/config.vue.d.ts +2 -2
  37. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/runtime.d.vue.ts +4 -4
  38. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/runtime.vue.d.ts +4 -4
  39. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/schema.d.ts +1 -1
  40. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +2 -2
  41. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +2 -2
  42. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +2 -2
  43. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +2 -2
  44. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +2 -2
  45. package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.d.vue.ts +16 -16
  46. package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.vue.d.ts +16 -16
  47. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.d.vue.ts +6 -6
  48. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.vue.d.ts +6 -6
  49. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.numberrange/config.d.vue.ts +6 -6
  50. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.numberrange/config.vue.d.ts +6 -6
  51. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.switch/config.d.vue.ts +22 -22
  52. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.switch/config.vue.d.ts +22 -22
  53. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.d.vue.ts +16 -16
  54. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.vue.d.ts +16 -16
  55. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +8 -8
  56. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +8 -8
  57. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.d.vue.ts +16 -16
  58. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.vue.d.ts +16 -16
  59. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +8 -8
  60. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +8 -8
  61. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +8 -8
  62. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +8 -8
  63. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +8 -8
  64. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +8 -8
  65. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +8 -8
  66. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +8 -8
  67. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +8 -8
  68. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +8 -8
  69. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +8 -8
  70. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +8 -8
  71. package/dist/runtime/components/form/schema.d.ts +2 -2
  72. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/runtime.vue +5 -1
  73. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.vue +16 -3
  74. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/runtime.vue +5 -1
  75. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue +5 -1
  76. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.vue +17 -3
  77. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +4 -4
  78. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +4 -4
  79. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/runtime.vue +5 -1
  80. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/runtime.vue +5 -1
  81. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/runtime.vue +5 -1
  82. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +4 -4
  83. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +4 -4
  84. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/runtime.vue +5 -1
  85. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/runtime.vue +5 -1
  86. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/runtime.vue +5 -1
  87. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/runtime.vue +5 -1
  88. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.vue +5 -1
  89. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.vue +5 -1
  90. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +10 -10
  91. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +10 -10
  92. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/runtime.vue +5 -1
  93. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +10 -10
  94. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +10 -10
  95. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/runtime.vue +5 -1
  96. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/runtime.vue +5 -1
  97. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/runtime.vue +5 -1
  98. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +10 -10
  99. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +10 -10
  100. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/runtime.vue +5 -1
  101. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +10 -10
  102. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +10 -10
  103. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/runtime.vue +5 -1
  104. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +179 -0
  105. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue +942 -0
  106. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +179 -0
  107. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/runtime.d.vue.ts +9 -0
  108. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/runtime.vue +499 -0
  109. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/runtime.vue.d.ts +9 -0
  110. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.d.ts +223 -0
  111. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.js +276 -0
  112. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +179 -0
  113. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue +942 -0
  114. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +179 -0
  115. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/runtime.d.vue.ts +9 -0
  116. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/runtime.vue +438 -0
  117. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/runtime.vue.d.ts +9 -0
  118. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.d.ts +223 -0
  119. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.js +276 -0
  120. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +123 -0
  121. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue +646 -0
  122. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +123 -0
  123. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/runtime.d.vue.ts +9 -0
  124. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/runtime.vue +500 -0
  125. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/runtime.vue.d.ts +9 -0
  126. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.d.ts +83 -0
  127. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.js +179 -0
  128. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +121 -0
  129. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue +577 -0
  130. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +121 -0
  131. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/runtime.d.vue.ts +9 -0
  132. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/runtime.vue +465 -0
  133. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/runtime.vue.d.ts +9 -0
  134. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.d.ts +80 -0
  135. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.js +171 -0
  136. package/dist/runtime/components/table/columns/2026-06-14/combobox-migrate.d.ts +18 -0
  137. package/dist/runtime/components/table/columns/2026-06-14/combobox-migrate.js +36 -0
  138. package/dist/runtime/components/table/columns/2026-06-14/tree-combobox-shared.d.ts +35 -0
  139. package/dist/runtime/components/table/columns/2026-06-14/tree-combobox-shared.js +31 -0
  140. package/dist/runtime/components/table/config.vue +74 -8
  141. package/dist/runtime/components/table/index.d.vue.ts +2 -0
  142. package/dist/runtime/components/table/index.vue +24 -0
  143. package/dist/runtime/components/table/index.vue.d.ts +2 -0
  144. package/dist/runtime/components/table/schema.d.ts +3 -3
  145. package/dist/runtime/components/table/utils/shared.d.ts +1 -0
  146. package/dist/runtime/components/table/utils/shared.js +7 -13
  147. package/package.json +1 -1
  148. package/dist/preview/assets/index-7BE56IYF.js +0 -739
  149. package/dist/preview/assets/index-Bwv0Yz_L.js +0 -1
@@ -0,0 +1,171 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { getProperty } from "dot-prop";
3
+ import { Locale } from "../../../../../share/locale.js";
4
+ import { Expression, HttpRequestResult, LocaleMarkdown } from "../../../../../share/expression.js";
5
+ import {
6
+ CelRowAccess,
7
+ derivedRowField,
8
+ editableColumnFields,
9
+ editableHeader,
10
+ registerRowVariablesIfAbsent
11
+ } from "../../../utils/shared.js";
12
+ import { localeLabelToExpression } from "../combobox-migrate.js";
13
+ export const type = "com.shwfed.table.column.tree-combobox-single";
14
+ export const compatibilityDate = "2026-06-14";
15
+ export const metadata = {
16
+ name: "\u4E0B\u62C9\u6811\uFF08\u5355\u9009\uFF09",
17
+ icon: "fluent:tree-evergreen-20-regular",
18
+ // Publishes its resolved node (backend record) to the per-row `selections` registry (runtime.vue), readable via `selections["<id>"]`.
19
+ selection: true
20
+ };
21
+ const isListLike = (t) => t === "dyn" || t.startsWith("list") || t.startsWith("optional");
22
+ const isKeyType = (t) => t === "string" || t === "number" || t === "dyn";
23
+ function withRowAndNode(configure) {
24
+ return (env) => {
25
+ configure(env);
26
+ registerRowVariablesIfAbsent(env);
27
+ env.registerVariable("node", "dyn", { description: "`\u6570\u636E\u6E90` \u8FD4\u56DE\u7684\u8282\u70B9\uFF1B\u7531\u6811\u9010\u5C42\u5411\u4E0B\u8BFB\u53D6" });
28
+ };
29
+ }
30
+ export function schema(configure) {
31
+ const CelBool = CelRowAccess(configure, { resultType: "bool" });
32
+ const CelNodeKey = Expression({ configure: withRowAndNode(configure), resultType: isKeyType });
33
+ const CelNodeChildren = Expression({ configure: withRowAndNode(configure), resultType: isListLike });
34
+ const CelNodeBool = Expression({ configure: withRowAndNode(configure), resultType: "bool" });
35
+ const CelKeywords = Expression({ configure: withRowAndNode(configure), resultType: isListLike });
36
+ const CelNodeLabel = Expression({ configure: withRowAndNode(configure), resultType: "dyn" });
37
+ const NodeLocaleMd = LocaleMarkdown({ configure: withRowAndNode(configure) });
38
+ const dataSourceConfigure = (env) => {
39
+ configure(env);
40
+ registerRowVariablesIfAbsent(env);
41
+ };
42
+ const CelDataSourceRequest = Expression({
43
+ configure: dataSourceConfigure,
44
+ resultType: HttpRequestResult
45
+ });
46
+ const CelDataSourceData = Expression({
47
+ configure: (env) => {
48
+ dataSourceConfigure(env);
49
+ env.registerVariable("json", "optional<dyn>", {
50
+ description: "HTTP \u54CD\u5E94\u4F53\uFF08\u5DF2\u89E3\u6790 JSON\uFF09\uFF1B\u672A\u914D\u7F6E `request` \u65F6\u4E3A `none`"
51
+ });
52
+ },
53
+ resultType: (t) => t.startsWith("list") || t === "dyn" || t.startsWith("optional")
54
+ });
55
+ const TreeDataSource = Schema.Struct({
56
+ request: Schema.optional(CelDataSourceRequest).annotations({
57
+ title: "\u8BF7\u6C42",
58
+ description: "\u53EF\u9009\u7684 HTTP \u8BF7\u6C42\u8868\u8FBE\u5F0F\uFF1B\u672A\u914D\u7F6E\u65F6\u6570\u636E\u4ECE `data` \u8868\u8FBE\u5F0F\u4E2D\u8BFB\u53D6"
59
+ }),
60
+ data: CelDataSourceData.annotations({
61
+ title: "\u6570\u636E",
62
+ description: "\u8FD4\u56DE\u884C\u6570\u636E\u5217\u8868\u7684 CEL \u8868\u8FBE\u5F0F\uFF1B\u914D\u7F6E\u4E86 `request` \u65F6\u53EF\u901A\u8FC7 `json` \u5F15\u7528\u54CD\u5E94\u4F53"
63
+ })
64
+ }).annotations({ title: "DataSource", description: "\u6570\u636E\u6E90\u914D\u7F6E" });
65
+ return Schema.Struct({
66
+ type: Schema.Literal(type),
67
+ compatibilityDate: Schema.Literal(compatibilityDate),
68
+ ...editableColumnFields(),
69
+ placeholder: Schema.optional(Locale.annotations({
70
+ title: "\u5360\u4F4D\u7B26",
71
+ description: "\u672A\u9009\u4E2D\u4EFB\u4F55\u9009\u9879\u65F6\u8F93\u5165\u6846\u4E2D\u7684\u5360\u4F4D\u6587\u672C"
72
+ })),
73
+ hidden: Schema.optional(CelBool.annotations({
74
+ title: "\u9690\u85CF\u6761\u4EF6",
75
+ description: "\u8FD4\u56DE `true` \u65F6\u8BE5\u884C\u7684\u4E0B\u62C9\u6811\u4E0D\u6E32\u67D3\uFF08\u5176\u4F59\u884C\u4E0D\u53D7\u5F71\u54CD\uFF09"
76
+ })),
77
+ disabled: Schema.optional(CelBool.annotations({
78
+ title: "\u7981\u7528\u6761\u4EF6",
79
+ description: "\u8FD4\u56DE `true` \u65F6\u4E0B\u62C9\u6811\u4ECD\u7136\u6E32\u67D3\u4F46\u4E0D\u53EF\u9009\u62E9"
80
+ })),
81
+ readonly: Schema.optional(CelBool.annotations({
82
+ title: "\u53EA\u8BFB\u6761\u4EF6",
83
+ description: "\u8FD4\u56DE `true` \u65F6\u4EC5\u4EE5\u7EAF\u6587\u672C\u5C55\u793A\u5F53\u524D\u9009\u9879\u7684\u6807\u7B7E"
84
+ })),
85
+ derived: derivedRowField(configure, "dyn"),
86
+ dataSource: TreeDataSource.annotations({
87
+ title: "\u6570\u636E\u6E90",
88
+ description: "\u8FD4\u56DE\u5B8C\u6574\u6811\uFF08\u6839\u8282\u70B9\u5217\u8868\uFF09\u7684\u6570\u636E\u6E90\uFF1B\u901A\u8FC7 `\u8282\u70B9\u5B50\u7EA7` \u8868\u8FBE\u5F0F\u9010\u5C42\u5411\u4E0B\u8BFB\u53D6\uFF1B\u53EF\u8BBF\u95EE `row`\u3001`index`"
89
+ }),
90
+ nodeKey: CelNodeKey.annotations({
91
+ title: "\u8282\u70B9 ID",
92
+ description: "\u4E3A\u6BCF\u4E2A\u8282\u70B9\u8BA1\u7B97\u7A33\u5B9A\u552F\u4E00 ID \u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u53EF\u8BBF\u95EE `node`\u3001`row`\u3001`index`\uFF1B\u8FD0\u884C\u65F6\u4EE5\u5B57\u7B26\u4E32\u5F62\u5F0F\u5B58\u50A8"
93
+ }),
94
+ nodeChildren: CelNodeChildren.annotations({
95
+ title: "\u8282\u70B9\u5B50\u7EA7",
96
+ description: "\u8FD4\u56DE\u5F53\u524D\u8282\u70B9\u5B50\u7EA7\u5217\u8868\u7684 CEL \u8868\u8FBE\u5F0F\uFF1B\u8FD4\u56DE `none`/`null` \u6216\u7A7A\u6570\u7EC4\u65F6\u8BE5\u8282\u70B9\u89C6\u4E3A\u53F6\u5B50\uFF08\u7EC8\u7AEF\u8282\u70B9\uFF09"
97
+ }),
98
+ nodeLabel: CelNodeLabel.annotations({
99
+ title: "\u8282\u70B9\u6807\u7B7E",
100
+ description: '\u8FD4\u56DE\u8282\u70B9\u5C55\u793A\u6587\u672C\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u53EF\u8BBF\u95EE `node`\u3001`row`\u3001`index`\uFF1B\u4F8B\uFF1A`node.label` \u6216 `string(node.code) + " " + node.name`'
101
+ }),
102
+ nodeTooltip: Schema.optional(NodeLocaleMd.annotations({
103
+ title: "\u8282\u70B9\u63D0\u793A",
104
+ description: "\u9F20\u6807\u60AC\u505C\u5728\u8282\u70B9\u4E0A\u65F6\u5C55\u793A\u7684\u672C\u5730\u5316\u63D0\u793A"
105
+ })),
106
+ keywords: Schema.optional(CelKeywords.annotations({
107
+ title: "\u989D\u5916\u5173\u952E\u8BCD",
108
+ description: "\u8FD4\u56DE\u5B57\u7B26\u4E32\u5217\u8868\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u53EF\u8BBF\u95EE `node`\u3001`row`\u3001`index`\uFF1B\u641C\u7D22\u65F6\u53EA\u8981 `\u8282\u70B9\u6807\u7B7E` \u6216 \u4EFB\u4E00\u5173\u952E\u8BCD \u5305\u542B\u67E5\u8BE2\u8BCD\uFF08\u4E0D\u533A\u5206\u5927\u5C0F\u5199\uFF09\u5373\u547D\u4E2D"
109
+ })),
110
+ nodeSelectable: Schema.optional(CelNodeBool.annotations({
111
+ title: "\u8282\u70B9\u53EF\u9009\u6761\u4EF6",
112
+ description: "\u8FD4\u56DE `true` \u8868\u793A\u8BE5\u8282\u70B9\u53EF\u88AB\u9009\u4E2D\uFF1B\u9ED8\u8BA4\u5168\u90E8\u53EF\u9009"
113
+ })),
114
+ expandAll: Schema.optionalWith(Schema.Boolean, { default: () => false }).annotations({
115
+ title: "\u9ED8\u8BA4\u5168\u90E8\u5C55\u5F00",
116
+ description: "\u5F00\u542F\u540E\u6302\u8F7D\u65F6\u5C55\u5F00\u6240\u6709\u975E\u53F6\u5B50\u8282\u70B9"
117
+ })
118
+ }).annotations({ title: "TreeComboboxSingleRenderer", description: "\u4E0B\u62C9\u6811\u5355\u9009\u6E32\u67D3\u5668\uFF08\u53EF\u7F16\u8F91\uFF09" });
119
+ }
120
+ export function defaults() {
121
+ return {
122
+ title: [{ locale: "zh", message: "" }],
123
+ binding: "",
124
+ size: 200,
125
+ dataSource: { data: "[]" },
126
+ nodeKey: "string(node.id)",
127
+ nodeChildren: "has(node.children) ? node.children : null",
128
+ nodeLabel: "node.label",
129
+ expandAll: false
130
+ };
131
+ }
132
+ export const migrateFrom = [
133
+ { type: "com.shwfed.table.column.tree-combobox-single", compatibilityDate: "2026-05-28" }
134
+ ];
135
+ export const migrate = (prev) => Effect.try({
136
+ try: () => {
137
+ if (!prev || typeof prev !== "object") {
138
+ throw new Error("\u4E0B\u62C9\u6811\uFF08\u5355\u9009\uFF09\u8FC1\u79FB\u5931\u8D25\uFF1A\u539F\u503C\u4E0D\u662F\u5BF9\u8C61");
139
+ }
140
+ const src = prev;
141
+ const srcType = src.type;
142
+ const srcDate = src.compatibilityDate;
143
+ if (srcType === "com.shwfed.table.column.tree-combobox-single" && srcDate === "2026-05-28") {
144
+ const { nodeLabel, type: _t, compatibilityDate: _c, ...rest } = src;
145
+ return {
146
+ ...rest,
147
+ type,
148
+ compatibilityDate,
149
+ nodeLabel: localeLabelToExpression(nodeLabel)
150
+ };
151
+ }
152
+ throw new Error(`\u4E0B\u62C9\u6811\uFF08\u5355\u9009\uFF09\u8FC1\u79FB\u5931\u8D25\uFF1A\u672A\u8BC6\u522B\u7684\u6765\u6E90 ${String(srcType)}@${String(srcDate)}`);
153
+ },
154
+ catch: (e) => e instanceof Error ? e : new Error(String(e))
155
+ });
156
+ export function toColumnDef(value, { getLocaleText }) {
157
+ return {
158
+ header: editableHeader(getLocaleText(value.title)),
159
+ accessorFn: (row) => {
160
+ if (!row || typeof row !== "object") return void 0;
161
+ return getProperty(row, value.binding);
162
+ },
163
+ enableSorting: value.enableSorting ?? false,
164
+ sortingFn: "basic",
165
+ size: value.size,
166
+ meta: {
167
+ grow: value.grow ?? false,
168
+ tooltip: getLocaleText(value.tooltip)
169
+ }
170
+ };
171
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Rewrite a `{{ }}`-interpolated template into a single CEL expression.
3
+ *
4
+ * - `''` / no content → `''` (valid empty-string literal)
5
+ * - whole template is one `{{ expr }}` → `expr` (kept bare; runtime coerces to string)
6
+ * - mixed literal + interpolation → `"lit" + string(expr) + …`
7
+ *
8
+ * Interpolated segments are wrapped in `string(...)` in the mixed case because
9
+ * CEL `+` requires matching operand types and the literal segments are strings;
10
+ * the old runtime stringified every interpolation, so this preserves behavior.
11
+ */
12
+ export declare function templateToExpression(template: string): string;
13
+ /**
14
+ * Collapse a legacy label (a Locale list of `{{ }}` templates) into the single
15
+ * CEL expression the 2026-06-14 schema expects. Picks the zh entry (or the
16
+ * first), then rewrites its template. Anything unrecognized → `''`.
17
+ */
18
+ export declare function localeLabelToExpression(label: unknown): string;
@@ -0,0 +1,36 @@
1
+ const INTERPOLATION_RE = /\{\{(.*?)\}\}/gs;
2
+ function celString(text) {
3
+ const body = text.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
4
+ return `"${body}"`;
5
+ }
6
+ export function templateToExpression(template) {
7
+ const trimmed = template.trim();
8
+ if (trimmed.length === 0) return `''`;
9
+ const sole = /^\{\{([\s\S]*)\}\}$/.exec(trimmed);
10
+ if (sole && !sole[1].includes("{{")) {
11
+ const expr = sole[1].trim();
12
+ return expr.length > 0 ? expr : `''`;
13
+ }
14
+ const parts = [];
15
+ let last = 0;
16
+ let match;
17
+ INTERPOLATION_RE.lastIndex = 0;
18
+ while ((match = INTERPOLATION_RE.exec(template)) !== null) {
19
+ if (match.index > last) parts.push(celString(template.slice(last, match.index)));
20
+ const expr = match[1].trim();
21
+ if (expr.length > 0) parts.push(`string(${expr})`);
22
+ last = match.index + match[0].length;
23
+ }
24
+ if (last < template.length) parts.push(celString(template.slice(last)));
25
+ if (parts.length === 0) return `''`;
26
+ return parts.join(" + ");
27
+ }
28
+ export function localeLabelToExpression(label) {
29
+ if (!Array.isArray(label)) return `''`;
30
+ const zh = label.find(
31
+ (item) => !!item && typeof item === "object" && item.locale === "zh"
32
+ );
33
+ const chosen = zh ?? label[0];
34
+ const message = chosen && typeof chosen.message === "string" ? chosen.message : "";
35
+ return templateToExpression(message);
36
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Wrapping + adapter helpers shared by `tree-combobox-single` and
3
+ * `tree-combobox-multi`. The whole tree comes from `dataSource` in one
4
+ * shot, so wrapping is a pure walk over CEL-derived children: each raw
5
+ * node either has children (`branch`) or it doesn't (`terminal`).
6
+ */
7
+ export type WrappedNode = {
8
+ readonly kind: 'branch';
9
+ readonly raw: unknown;
10
+ readonly key: string;
11
+ readonly children: WrappedNode[];
12
+ } | {
13
+ readonly kind: 'terminal';
14
+ readonly raw: unknown;
15
+ readonly key: string;
16
+ };
17
+ export interface WrapStructureContext {
18
+ /** Stringified node id; one per raw node. Reuses `nodeKey` CEL. */
19
+ nodeKey: (raw: unknown) => string;
20
+ /**
21
+ * Normalised children array. `undefined`/`null`/empty all collapse to
22
+ * `undefined` here — the wrapping logic interprets that as
23
+ * "this node has no children" → `terminal`.
24
+ */
25
+ nodeChildren: (raw: unknown) => unknown[] | undefined;
26
+ }
27
+ export declare function wrapStructural(raw: unknown, ctx: WrapStructureContext): WrappedNode;
28
+ export declare function wrapStructuralAll(raws: unknown[], ctx: WrapStructureContext): WrappedNode[];
29
+ /** Synchronous `getChildren` adapter for ui/tree. */
30
+ export declare function getWrappedChildren(w: WrappedNode): WrappedNode[] | undefined;
31
+ /**
32
+ * Find the path from root to a node whose `key` matches. Returns `null`
33
+ * if the key isn't present in `roots`.
34
+ */
35
+ export declare function findWrappedPath(roots: WrappedNode[], key: string): WrappedNode[] | null;
@@ -0,0 +1,31 @@
1
+ export function wrapStructural(raw, ctx) {
2
+ const kids = ctx.nodeChildren(raw);
3
+ if (!kids || kids.length === 0) {
4
+ return { kind: "terminal", raw, key: ctx.nodeKey(raw) };
5
+ }
6
+ return {
7
+ kind: "branch",
8
+ raw,
9
+ key: ctx.nodeKey(raw),
10
+ children: kids.map((c) => wrapStructural(c, ctx))
11
+ };
12
+ }
13
+ export function wrapStructuralAll(raws, ctx) {
14
+ return raws.map((r) => wrapStructural(r, ctx));
15
+ }
16
+ export function getWrappedChildren(w) {
17
+ return w.kind === "branch" ? w.children : void 0;
18
+ }
19
+ export function findWrappedPath(roots, key) {
20
+ const trail = [];
21
+ function walk(siblings) {
22
+ for (const n of siblings) {
23
+ trail.push(n);
24
+ if (n.key === key) return true;
25
+ if (n.kind === "branch" && n.children.length > 0 && walk(n.children)) return true;
26
+ trail.pop();
27
+ }
28
+ return false;
29
+ }
30
+ return walk(roots) ? trail.slice() : null;
31
+ }
@@ -1,12 +1,13 @@
1
1
  <script setup>
2
2
  import { computed, defineComponent, inject, onBeforeUnmount, provide, ref, watch } from "vue";
3
- import { provideCELContext, provideScopeAncestor, provideSelectionRoster, SELECTIONS_VAR } from "../../utils/cel-context";
3
+ import { celBindings, injectCELContext, provideCELContext, provideScopeAncestor, provideSelectionRoster, SELECTIONS_VAR } from "../../utils/cel-context";
4
4
  import { BREADCRUMB_EXTENSION_KEY } from "../config/breadcrumb-extension";
5
5
  import { TABLE_COLUMN_LAYOUT_KEY } from "./column-layout";
6
6
  import { Icon } from "@iconify/vue";
7
- import { ParseResult, Schema } from "effect";
7
+ import { Effect, ParseResult, Schema } from "effect";
8
8
  import { TableConfig, Pagination, ColumnGroup, tableDataSource, configureTableActionsScope, registerDataSourceRequestVars, registerDataSourceResponseVars, metadata as tableMetadata } from "./schema";
9
9
  import { COLUMNS, findColumn as findColumnEntry } from "./utils/resolve";
10
+ import { registerRowVariablesIfAbsent } from "./utils/shared";
10
11
  import {
11
12
  useTreeDnd
12
13
  } from "../../composables/useTreeDnd";
@@ -35,6 +36,9 @@ import ActionsConfigEditor from "../actions/config.vue";
35
36
  import ShwfedFormConfig from "../form/config.vue";
36
37
  import { defaultFormConfig } from "../form/schema";
37
38
  import { Environment } from "../../vendor/cel-js/lib/index";
39
+ import { cel as rawCel } from "../../utils/cel";
40
+ import { Button } from "../ui/button";
41
+ import { toast } from "vue-sonner";
38
42
  defineOptions({ name: "ShwfedTableConfig" });
39
43
  function probeCELContext(register) {
40
44
  const probe = new Environment({ unlistedVariablesAreDyn: false });
@@ -110,6 +114,16 @@ const CellStyleCELContext = defineComponent({
110
114
  return () => slots.default?.();
111
115
  }
112
116
  });
117
+ const ColumnCELContext = defineComponent({
118
+ name: "ColumnCELContext",
119
+ setup(_, { slots }) {
120
+ provideCELContext(probeCELContext((env) => {
121
+ configure(env);
122
+ registerRowVariablesIfAbsent(env);
123
+ }));
124
+ return () => slots.default?.();
125
+ }
126
+ });
113
127
  const RequestCELContext = defineComponent({
114
128
  name: "RequestCELContext",
115
129
  setup(_, { slots }) {
@@ -574,6 +588,33 @@ function patchSelectedColumn(next) {
574
588
  if (selected.value.kind !== "column") return;
575
589
  patchColumn(selected.value.id, next);
576
590
  }
591
+ const inheritedCEL = injectCELContext();
592
+ function celForMigration(expression, context) {
593
+ return rawCel(expression, { ...celBindings(inheritedCEL), ...context });
594
+ }
595
+ const migrationContext = { $cel: celForMigration };
596
+ const columnMigrationTarget = computed(() => {
597
+ const e = selectedColumnEntry.value;
598
+ if (!e?.deprecated || !e.supersededBy) return null;
599
+ return findColumnEntry(e.supersededBy.type, e.supersededBy.compatibilityDate) ?? null;
600
+ });
601
+ const canMigrateColumn = computed(() => !!columnMigrationTarget.value?.migrate);
602
+ async function migrateSelectedColumn() {
603
+ const sel = selectedColumnRef.value;
604
+ const target = columnMigrationTarget.value;
605
+ if (!sel || !target?.migrate) return;
606
+ try {
607
+ const next = await Effect.runPromise(target.migrate(sel, migrationContext));
608
+ patchSelectedColumn(next);
609
+ const isSameType = target.type === sel.type;
610
+ toast.success(
611
+ isSameType ? `\u5DF2\u8FC1\u79FB\u5230 ${target.compatibilityDate} \u7248\u672C` : `\u5DF2\u8FC1\u79FB\u5230 ${target.type}@${target.compatibilityDate}`
612
+ );
613
+ } catch (err) {
614
+ const message = err instanceof Error ? err.message : String(err);
615
+ toast.error("\u8FC1\u79FB\u5931\u8D25", { description: message });
616
+ }
617
+ }
577
618
  function patchSelectedGroup(next) {
578
619
  if (selected.value.kind !== "group") return;
579
620
  const id = selected.value.id;
@@ -1654,12 +1695,37 @@ const tableQueryValue = computed({
1654
1695
  v-else-if="selectedColumnRef"
1655
1696
  :class="columnFullPane ? '' : 'space-y-5'"
1656
1697
  >
1657
- <component
1658
- :is="selectedColumnEntry.config"
1659
- v-if="selectedColumnEntry"
1660
- :model-value="selectedColumnRef"
1661
- @update:model-value="(v) => patchSelectedColumn(v)"
1662
- />
1698
+ <div
1699
+ v-if="selectedColumnEntry?.deprecated && selectedColumnEntry.supersededBy"
1700
+ class="mb-4 flex items-center gap-2 rounded border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800"
1701
+ role="alert"
1702
+ >
1703
+ <Icon
1704
+ icon="fluent:warning-20-regular"
1705
+ class="size-4 shrink-0"
1706
+ />
1707
+ <span class="flex-1">
1708
+ 此列类型已弃用,建议迁移至 <span class="tabular-nums font-medium">{{ selectedColumnEntry.supersededBy.type === selectedColumnEntry.type ? selectedColumnEntry.supersededBy.compatibilityDate : `${selectedColumnEntry.supersededBy.type}@${selectedColumnEntry.supersededBy.compatibilityDate}` }}</span>。
1709
+ </span>
1710
+ <Button
1711
+ v-if="canMigrateColumn"
1712
+ variant="ghost"
1713
+ size="sm"
1714
+ class="text-amber-800 hover:bg-amber-100 hover:text-amber-900"
1715
+ data-slot="column-migrate"
1716
+ @click="migrateSelectedColumn"
1717
+ >
1718
+ <Icon icon="fluent:arrow-sync-20-regular" />
1719
+ 迁移
1720
+ </Button>
1721
+ </div>
1722
+ <ColumnCELContext v-if="selectedColumnEntry">
1723
+ <component
1724
+ :is="selectedColumnEntry.config"
1725
+ :model-value="selectedColumnRef"
1726
+ @update:model-value="(v) => patchSelectedColumn(v)"
1727
+ />
1728
+ </ColumnCELContext>
1663
1729
  <div
1664
1730
  v-else
1665
1731
  class="text-xs text-red-500"
@@ -6,6 +6,8 @@ declare module '@tanstack/vue-table' {
6
6
  interface ColumnMeta<TData extends import('@tanstack/vue-table').RowData, TValue> {
7
7
  tooltip?: string;
8
8
  grow?: boolean;
9
+ editable?: boolean;
10
+ readonlyExpr?: string;
9
11
  }
10
12
  }
11
13
  declare const _default: typeof __VLS_export;
@@ -32,6 +32,8 @@ import { provideSharedFetchLayer } from "./utils/shared-fetch";
32
32
  import { provideEventTarget } from "../../share/event-bus";
33
33
  import { usePersistedQuery } from "../../share/use-persisted-query";
34
34
  import { findColumn } from "./utils/resolve";
35
+ import { isEditableHeader } from "./utils/shared";
36
+ import { useFormReadonly } from "../form/utils/readonly";
35
37
  import { interpolateMarkdown } from "./utils/runtime";
36
38
  import { carrySymbolId, createRowKeyResolver } from "./utils/row-key";
37
39
  import { provideReorderContext } from "./utils/reorder";
@@ -98,6 +100,15 @@ const { t, locale } = useI18n({
98
100
  const inheritedContext = injectCELContext();
99
101
  const containerRef = ref(null);
100
102
  const appliedInitialStateKey = ref("");
103
+ const formReadonly = useFormReadonly();
104
+ function isHeaderReadonly(readonlyExpr) {
105
+ if (readonlyExpr == null) return formReadonly.value;
106
+ try {
107
+ return Effect.runSync($cel(readonlyExpr, celBindings(inheritedContext))) === true;
108
+ } catch {
109
+ return false;
110
+ }
111
+ }
101
112
  function getLocaleText(value) {
102
113
  return getLocalizedText(value, locale.value);
103
114
  }
@@ -116,8 +127,11 @@ function translateColumn(column) {
116
127
  throw new Error(`[shwfed-table] no column registered for ${column.type}@${column.compatibilityDate}`);
117
128
  }
118
129
  const contribution = entry.toColumnDef(column, { getLocaleText, $cel, inheritedContext: celBindings(inheritedContext) });
130
+ const editable = isEditableHeader(contribution.header);
131
+ const readonlyExpr = editable ? column.readonly : void 0;
119
132
  return {
120
133
  ...contribution,
134
+ meta: { ...contribution.meta, editable, readonlyExpr },
121
135
  id: column.id,
122
136
  // `ctx` is the functional-component props object Vue mutates in place on
123
137
  // every update, so its identity stays stable across data refetches.
@@ -744,6 +758,16 @@ export { TableConfig, createTableConfig, getColumnTechnicalKey } from "./schema"
744
758
  :props="header.getContext()"
745
759
  />
746
760
 
761
+ <!-- Edit affordance: marks an editable column, hidden when
762
+ the column reads as readonly (form-wide or its own
763
+ `readonly` condition). -->
764
+ <Icon
765
+ v-if="!header.isPlaceholder && header.column.columnDef.meta?.editable && !isHeaderReadonly(header.column.columnDef.meta?.readonlyExpr)"
766
+ icon="fluent:edit-20-regular"
767
+ class="size-3 shrink-0 text-zinc-400"
768
+ aria-hidden="true"
769
+ />
770
+
747
771
  <!-- Sort toggle -->
748
772
  <Tooltip
749
773
  v-if="!header.isPlaceholder && header.column.getCanSort()"
@@ -6,6 +6,8 @@ declare module '@tanstack/vue-table' {
6
6
  interface ColumnMeta<TData extends import('@tanstack/vue-table').RowData, TValue> {
7
7
  tooltip?: string;
8
8
  grow?: boolean;
9
+ editable?: boolean;
10
+ readonlyExpr?: string;
9
11
  }
10
12
  }
11
13
  declare const _default: typeof __VLS_export;
@@ -143,6 +143,7 @@ export declare function TableConfig(configure: (env: Environment) => void): Sche
143
143
  readonly displayName?: string | undefined;
144
144
  readonly kind: "shwfed.component.form";
145
145
  readonly fields: readonly any[];
146
+ readonly readonly?: string | undefined;
146
147
  readonly layouts: readonly {
147
148
  readonly name: string;
148
149
  readonly layout: {
@@ -160,7 +161,6 @@ export declare function TableConfig(configure: (env: Environment) => void): Sche
160
161
  };
161
162
  readonly media?: string | undefined;
162
163
  }[];
163
- readonly readonly?: string | undefined;
164
164
  } | undefined;
165
165
  readonly dataSource?: {
166
166
  readonly data: string;
@@ -646,6 +646,7 @@ export declare function TableConfig(configure: (env: Environment) => void): Sche
646
646
  readonly displayName?: string | undefined;
647
647
  readonly kind: "shwfed.component.form";
648
648
  readonly fields: readonly any[];
649
+ readonly readonly?: string | undefined;
649
650
  readonly layouts: readonly {
650
651
  readonly name: string;
651
652
  readonly layout: {
@@ -663,7 +664,6 @@ export declare function TableConfig(configure: (env: Environment) => void): Sche
663
664
  };
664
665
  readonly media?: string | undefined;
665
666
  }[];
666
- readonly readonly?: string | undefined;
667
667
  }, Schema.Struct<{
668
668
  fields: Schema.Array$<Schema.Schema<any, any, never>>;
669
669
  layouts: Schema.refine<readonly {
@@ -788,6 +788,7 @@ export declare function createTableConfig(body: Omit<Schema.Schema.Type<ReturnTy
788
788
  readonly displayName?: string | undefined;
789
789
  readonly kind: "shwfed.component.form";
790
790
  readonly fields: readonly any[];
791
+ readonly readonly?: string | undefined;
791
792
  readonly layouts: readonly {
792
793
  readonly name: string;
793
794
  readonly layout: {
@@ -805,7 +806,6 @@ export declare function createTableConfig(body: Omit<Schema.Schema.Type<ReturnTy
805
806
  };
806
807
  readonly media?: string | undefined;
807
808
  }[];
808
- readonly readonly?: string | undefined;
809
809
  } | undefined;
810
810
  dataSource?: {
811
811
  readonly data: string;
@@ -54,6 +54,7 @@ export declare function editableColumnFields(): {
54
54
  groupId: Schema.optional<typeof Schema.UUID>;
55
55
  };
56
56
  export declare function editableHeader(titleText: string | undefined): () => VNode;
57
+ export declare function isEditableHeader(header: unknown): boolean;
57
58
  export declare function registerRowVariablesIfAbsent(env: Environment): void;
58
59
  export declare function CelRowAccess(configure: (env: Environment) => void, options?: {
59
60
  resultType?: ResultType;
@@ -1,5 +1,4 @@
1
1
  import { Schema } from "effect";
2
- import { Icon } from "@iconify/vue";
3
2
  import { h } from "vue";
4
3
  import { SELECTIONS_VAR } from "../../../utils/cel-context.js";
5
4
  import { Expression, LocaleMarkdown } from "../../../share/expression.js";
@@ -76,19 +75,14 @@ export function editableColumnFields() {
76
75
  tooltip: Schema.optional(Locale.annotations({ title: "\u63D0\u793A", description: "\u5217\u6807\u9898\u60AC\u6D6E\u63D0\u793A\uFF0C\u652F\u6301 Markdown" }))
77
76
  };
78
77
  }
78
+ const EDITABLE_HEADER_MARKER = Symbol("shwfed-editable-header");
79
79
  export function editableHeader(titleText) {
80
- return () => h(
81
- "span",
82
- { class: "inline-flex items-center gap-1" },
83
- [
84
- titleText ?? "",
85
- h(Icon, {
86
- "icon": "fluent:edit-20-regular",
87
- "class": "size-3 text-zinc-400",
88
- "aria-hidden": "true"
89
- })
90
- ]
91
- );
80
+ const render = () => h("span", { class: "inline-flex items-center" }, titleText ?? "");
81
+ render[EDITABLE_HEADER_MARKER] = true;
82
+ return render;
83
+ }
84
+ export function isEditableHeader(header) {
85
+ return typeof header === "function" && header[EDITABLE_HEADER_MARKER] === true;
92
86
  }
93
87
  export function registerRowVariablesIfAbsent(env) {
94
88
  const declared = new Set(env.getDefinitions().variables.map((v) => v.name));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shwfed/config",
3
- "version": "2.10.0",
3
+ "version": "2.10.2",
4
4
  "description": "Configurable UI for SHWFED",
5
5
  "type": "module",
6
6
  "publishConfig": {