@shwfed/config 2.10.0 → 2.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp.mjs +4125 -3183
- package/dist/module.json +1 -1
- package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-CCaOWk_7.js → FieldGroup.vue_vue_type_script_setup_true_lang-CuFusz5A.js} +1 -1
- package/dist/preview/assets/{badge-D9_7atSJ.js → badge-D5FPHSix.js} +1 -1
- package/dist/preview/assets/{config-B2d8SiPi.js → config-BHPiQ1lB.js} +1 -1
- package/dist/preview/assets/{config-DYxMKhCU.js → config-BWC-Zw21.js} +1 -1
- package/dist/preview/assets/{config-CNKb25Qo.js → config-Bg94Z7XN.js} +1 -1
- package/dist/preview/assets/{config-CQrqVV1U.js → config-BqSL4UAL.js} +1 -1
- package/dist/preview/assets/{config-Bk2VSNeu.js → config-CeRBpZbE.js} +1 -1
- package/dist/preview/assets/{config-C9WPOoA7.js → config-CfjcFb_E.js} +1 -1
- package/dist/preview/assets/{config-DZlaJUlF.js → config-DNUKa3lN.js} +1 -1
- package/dist/preview/assets/{config-BLEovXei.js → config-DVjZmomc.js} +1 -1
- package/dist/preview/assets/{config-DyPl6K2G.js → config-Djv6EQBY.js} +1 -1
- package/dist/preview/assets/{config-DWA385pD.js → config-PNpa6ENz.js} +1 -1
- package/dist/preview/assets/{config-C8lCItmz.js → config-ucxtM3wX.js} +1 -1
- package/dist/preview/assets/{config-Bf5Vckj3.js → config-urZuasV7.js} +1 -1
- package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-CFzQ7icU.js → definition.vue_vue_type_script_setup_true_lang-BzryfjdG.js} +1 -1
- package/dist/preview/assets/index-BE9O1XgB.js +1 -0
- package/dist/preview/assets/{index-CXOEVGFP.js → index-DCRQGu0g.js} +1 -1
- package/dist/preview/assets/index-yvElpEK3.js +743 -0
- package/dist/preview/assets/{item-DCVX69_o.js → item-CTkdtkvl.js} +1 -1
- package/dist/preview/assets/{runtime-r1wbrr4k.js → runtime-3rajYvjp.js} +1 -1
- package/dist/preview/assets/{runtime-BNk4EliL.js → runtime-4A3oiig9.js} +1 -1
- package/dist/preview/assets/{runtime-Cbc5NH57.js → runtime-BOGZFWxF.js} +1 -1
- package/dist/preview/assets/{runtime-BO-KY3T_.js → runtime-BqroTX7H.js} +1 -1
- package/dist/preview/assets/{runtime-O6MNC3GA.js → runtime-CBBae0-H.js} +1 -1
- package/dist/preview/assets/{runtime-DEWGIyvr.js → runtime-CBuV3vwL.js} +1 -1
- package/dist/preview/assets/{runtime-DJ9ElxWB.js → runtime-CI8yzwXd.js} +1 -1
- package/dist/preview/assets/{runtime-DSfMvph3.js → runtime-CcyhgOum.js} +1 -1
- package/dist/preview/assets/{runtime-BD1A-g1h.js → runtime-CkQ-mNoH.js} +1 -1
- package/dist/preview/assets/{runtime-BsNSI1XP.js → runtime-DmxKfudS.js} +1 -1
- package/dist/preview/assets/{schema-meta-ovcuERKg.js → schema-meta-BFzIzGiN.js} +1 -1
- package/dist/preview/index.html +1 -1
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.vue +16 -3
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.vue +17 -3
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/runtime.vue +5 -1
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +179 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue +942 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +179 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/runtime.d.vue.ts +9 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/runtime.vue +499 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/runtime.vue.d.ts +9 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.d.ts +223 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.js +276 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +179 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue +942 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +179 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/runtime.d.vue.ts +9 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/runtime.vue +438 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/runtime.vue.d.ts +9 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.d.ts +223 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.js +276 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +123 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue +646 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +123 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/runtime.d.vue.ts +9 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/runtime.vue +500 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/runtime.vue.d.ts +9 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.d.ts +83 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.js +179 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +121 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue +577 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +121 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/runtime.d.vue.ts +9 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/runtime.vue +465 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/runtime.vue.d.ts +9 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.d.ts +80 -0
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.js +171 -0
- package/dist/runtime/components/table/columns/2026-06-14/combobox-migrate.d.ts +18 -0
- package/dist/runtime/components/table/columns/2026-06-14/combobox-migrate.js +36 -0
- package/dist/runtime/components/table/columns/2026-06-14/tree-combobox-shared.d.ts +35 -0
- package/dist/runtime/components/table/columns/2026-06-14/tree-combobox-shared.js +31 -0
- package/dist/runtime/components/table/index.d.vue.ts +2 -0
- package/dist/runtime/components/table/index.vue +24 -0
- package/dist/runtime/components/table/index.vue.d.ts +2 -0
- package/dist/runtime/components/table/utils/shared.d.ts +1 -0
- package/dist/runtime/components/table/utils/shared.js +7 -13
- package/package.json +1 -1
- package/dist/preview/assets/index-7BE56IYF.js +0 -739
- 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
|
+
}
|
|
@@ -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;
|
|
@@ -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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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));
|