@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.
- 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-DX5M_WNF.js} +1 -1
- package/dist/preview/assets/{badge-D9_7atSJ.js → badge-DFZBH8N6.js} +1 -1
- package/dist/preview/assets/{config-B2d8SiPi.js → config-BH2BmDoD.js} +1 -1
- package/dist/preview/assets/{config-Bk2VSNeu.js → config-Bg7a8Rid.js} +1 -1
- package/dist/preview/assets/{config-DYxMKhCU.js → config-BiOW8fS2.js} +1 -1
- package/dist/preview/assets/{config-CNKb25Qo.js → config-Bnp547Nm.js} +1 -1
- package/dist/preview/assets/{config-Bf5Vckj3.js → config-CSmHhOh2.js} +1 -1
- package/dist/preview/assets/{config-CQrqVV1U.js → config-CTF5-TTQ.js} +1 -1
- package/dist/preview/assets/{config-DWA385pD.js → config-CqeWJt_H.js} +1 -1
- package/dist/preview/assets/{config-BLEovXei.js → config-DBtEKoan.js} +1 -1
- package/dist/preview/assets/{config-DyPl6K2G.js → config-DeDCNzY_.js} +1 -1
- package/dist/preview/assets/{config-C9WPOoA7.js → config-Dj3w2JkF.js} +1 -1
- package/dist/preview/assets/{config-DZlaJUlF.js → config-XGJ9V32V.js} +1 -1
- package/dist/preview/assets/{config-C8lCItmz.js → config-uIHUHvNR.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-Cu0CEKYT.js} +1 -1
- package/dist/preview/assets/index-CGChrBji.js +1 -0
- package/dist/preview/assets/{index-CXOEVGFP.js → index-CQA6q2ay.js} +1 -1
- package/dist/preview/assets/index-DX9_iE4h.js +743 -0
- package/dist/preview/assets/{index-BnJ5p1Mx.css → index-pkoEF5dC.css} +1 -1
- package/dist/preview/assets/{item-DCVX69_o.js → item-C4VJfiq8.js} +1 -1
- package/dist/preview/assets/{runtime-DEWGIyvr.js → runtime-6Zrje7Y1.js} +1 -1
- package/dist/preview/assets/{runtime-O6MNC3GA.js → runtime-BN-jMAt7.js} +1 -1
- package/dist/preview/assets/{runtime-BD1A-g1h.js → runtime-BQMnWueG.js} +1 -1
- package/dist/preview/assets/{runtime-BsNSI1XP.js → runtime-CBz5XstF.js} +1 -1
- package/dist/preview/assets/{runtime-BNk4EliL.js → runtime-CFb1tHwr.js} +1 -1
- package/dist/preview/assets/{runtime-Cbc5NH57.js → runtime-DQL6lCFp.js} +1 -1
- package/dist/preview/assets/{runtime-DSfMvph3.js → runtime-DcdmMgqL.js} +1 -1
- package/dist/preview/assets/{runtime-DJ9ElxWB.js → runtime-okYOTQd6.js} +1 -1
- package/dist/preview/assets/{runtime-BO-KY3T_.js → runtime-qPyuMgsh.js} +1 -1
- package/dist/preview/assets/{runtime-r1wbrr4k.js → runtime-yfWYeUh4.js} +1 -1
- package/dist/preview/assets/{schema-meta-ovcuERKg.js → schema-meta-6ZPO8dHv.js} +1 -1
- package/dist/preview/index.html +2 -2
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/config.d.vue.ts +2 -2
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/config.vue.d.ts +2 -2
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/runtime.d.vue.ts +4 -4
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/runtime.vue.d.ts +4 -4
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/schema.d.ts +1 -1
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +2 -2
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +2 -2
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +2 -2
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +2 -2
- package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.d.vue.ts +16 -16
- package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.vue.d.ts +16 -16
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.d.vue.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.vue.d.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.numberrange/config.d.vue.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.numberrange/config.vue.d.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.switch/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.switch/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.d.vue.ts +16 -16
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.vue.d.ts +16 -16
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.d.vue.ts +16 -16
- package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.vue.d.ts +16 -16
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +8 -8
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +8 -8
- package/dist/runtime/components/form/schema.d.ts +2 -2
- 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/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +4 -4
- 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/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +4 -4
- 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/config.d.vue.ts +10 -10
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +10 -10
- 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/config.d.vue.ts +10 -10
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +10 -10
- 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/config.d.vue.ts +10 -10
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +10 -10
- 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/config.d.vue.ts +10 -10
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +10 -10
- 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/config.vue +74 -8
- 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/schema.d.ts +3 -3
- 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
|
+
}
|
|
@@ -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
|
-
<
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
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
|
-
|
|
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));
|