@shwfed/config 2.3.10 → 2.3.11
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 +704 -441
- package/dist/module.json +1 -1
- package/dist/preview/assets/{config-BxzDT_57.js → config-57-v4VXo.js} +1 -1
- package/dist/preview/assets/{config-2R4XkSGs.js → config-BZahzuEc.js} +1 -1
- package/dist/preview/assets/{config-KcLrpkc1.js → config-Be-2ZA2R.js} +1 -1
- package/dist/preview/assets/{config-ykJZssgx.js → config-BnZQO-Sp.js} +1 -1
- package/dist/preview/assets/{config-bxqg3yuv.js → config-Bp91DUdU.js} +1 -1
- package/dist/preview/assets/{config-CyScbxXy.js → config-DNokxY7M.js} +1 -1
- package/dist/preview/assets/{config-HdWYFZ09.js → config-_msO_f2R.js} +1 -1
- package/dist/preview/assets/{config-ja_GMXxV.js → config-_uPI8qV-.js} +1 -1
- package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-CWyVRSOh.js → definition.vue_vue_type_script_setup_true_lang-BtScXbs1.js} +1 -1
- package/dist/preview/assets/index-DDbl2Atj.js +1 -0
- package/dist/preview/assets/index-DGa3Oj3y.js +1075 -0
- package/dist/preview/assets/{index-BPKK3hGV.css → index-mbGtsgdv.css} +1 -1
- package/dist/preview/assets/{runtime-LBdh1D75.js → runtime-B9u14qqB.js} +1 -1
- package/dist/preview/assets/{runtime-B8aUJIpn.js → runtime-BBms4myv.js} +1 -1
- package/dist/preview/assets/{runtime-D2K1s33u.js → runtime-CfR7ZAND.js} +1 -1
- package/dist/preview/assets/{runtime-C9XnvD5A.js → runtime-D3EyeiyA.js} +1 -1
- package/dist/preview/assets/{runtime-DqZhDPHl.js → runtime-Dk9u-Ybw.js} +1 -1
- package/dist/preview/assets/{runtime-CpSiaWMP.js → runtime-XXqIAt53.js} +1 -1
- package/dist/preview/assets/{runtime-CxA8fvQP.js → runtime-cKWSGFod.js} +1 -1
- package/dist/preview/assets/{runtime-DAXQmtLg.js → runtime-w7V-p3t1.js} +1 -1
- package/dist/preview/index.html +2 -2
- package/dist/runtime/components/form/ai/fields-button.vue +3 -1
- package/dist/runtime/components/form/unit-config.vue +8 -4
- package/dist/runtime/components/form/utils/resolve.d.ts +48 -9
- package/dist/runtime/components/form/utils/resolve.js +59 -5
- package/dist/runtime/components/table/ai/columns-button.vue +1 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.d.vue.ts +10 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.vue +305 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.vue.d.ts +10 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/runtime.d.vue.ts +9 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/runtime.vue +81 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/runtime.vue.d.ts +9 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.d.ts +55 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.js +82 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.d.vue.ts +10 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.vue +310 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.vue.d.ts +10 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.d.vue.ts +9 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue +81 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue.d.ts +9 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.d.ts +66 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.js +71 -0
- package/dist/runtime/components/table/config.vue +2 -1
- package/dist/runtime/components/table/utils/resolve.d.ts +53 -0
- package/dist/runtime/components/table/utils/resolve.js +66 -1
- package/package.json +1 -1
- package/dist/preview/assets/index-D3pf2RjG.js +0 -1
- package/dist/preview/assets/index-OUd02U3g.js +0 -1075
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CellContext } from '@tanstack/vue-table';
|
|
2
|
+
import type { Value } from './schema.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
column: Value;
|
|
5
|
+
ctx: CellContext<unknown, unknown>;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref } from "vue";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
import { Fetch } from "fx-fetch";
|
|
5
|
+
import { toast } from "vue-sonner";
|
|
6
|
+
import { cel as $cel } from "../../../../../utils/cel";
|
|
7
|
+
import { Switch } from "../../../../ui/switch";
|
|
8
|
+
import { JUSTIFY_CLASS } from "../../../utils/runtime";
|
|
9
|
+
import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
|
|
10
|
+
import { dispatchTriggers, useEventChannel } from "../../../../../share/event-bus";
|
|
11
|
+
defineOptions({ name: "ShwfedTableSwitchRendererRuntime" });
|
|
12
|
+
const props = defineProps({
|
|
13
|
+
column: { type: null, required: true },
|
|
14
|
+
ctx: { type: Object, required: true }
|
|
15
|
+
});
|
|
16
|
+
const celContext = injectCELContext();
|
|
17
|
+
const eventChannel = useEventChannel();
|
|
18
|
+
const rawValue = computed(() => props.ctx.cell.getValue());
|
|
19
|
+
const isMissing = computed(() => rawValue.value === void 0 || rawValue.value === null);
|
|
20
|
+
const checked = computed(() => rawValue.value === true);
|
|
21
|
+
const justifyClass = computed(
|
|
22
|
+
() => JUSTIFY_CLASS[props.column.align ?? "center"] ?? JUSTIFY_CLASS.center
|
|
23
|
+
);
|
|
24
|
+
const pending = ref(false);
|
|
25
|
+
const isDisabledByConfig = computed(() => {
|
|
26
|
+
if (!props.column.disabled) return false;
|
|
27
|
+
try {
|
|
28
|
+
return Effect.runSync($cel(props.column.disabled, celBindings(celContext))) === true;
|
|
29
|
+
} catch (e) {
|
|
30
|
+
console.error("[shwfed-table] switch disabled failed", e);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const isInteractive = computed(() => !!props.column.onChange);
|
|
35
|
+
const isDisabled = computed(() => !isInteractive.value || isDisabledByConfig.value || pending.value);
|
|
36
|
+
async function onUpdate(next) {
|
|
37
|
+
const { onChange, successMessage } = props.column;
|
|
38
|
+
if (!onChange) return;
|
|
39
|
+
pending.value = true;
|
|
40
|
+
const program = Effect.gen(function* () {
|
|
41
|
+
const builder = yield* $cel(onChange, {
|
|
42
|
+
...celBindings(celContext),
|
|
43
|
+
value: next
|
|
44
|
+
});
|
|
45
|
+
return yield* builder.json();
|
|
46
|
+
});
|
|
47
|
+
try {
|
|
48
|
+
const body = await Effect.runPromise(Effect.provide(program, Fetch.layer));
|
|
49
|
+
if (successMessage) {
|
|
50
|
+
try {
|
|
51
|
+
const message = Effect.runSync($cel(successMessage, { json: body }));
|
|
52
|
+
if (message) toast.success(message);
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.error("[shwfed-table] switch successMessage failed", e);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
await Effect.runPromise(dispatchTriggers(eventChannel, props.column.triggers));
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.error("[shwfed-table] switch onChange failed", e);
|
|
60
|
+
toast.error("\u8BF7\u6C42\u5931\u8D25");
|
|
61
|
+
} finally {
|
|
62
|
+
pending.value = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<template>
|
|
68
|
+
<span :class="['w-full py-2 px-1 flex items-center text-xs', justifyClass]">
|
|
69
|
+
<span
|
|
70
|
+
v-if="isMissing"
|
|
71
|
+
class="font-mono text-zinc-300 select-none"
|
|
72
|
+
>-</span>
|
|
73
|
+
<Switch
|
|
74
|
+
v-else
|
|
75
|
+
size="sm"
|
|
76
|
+
:model-value="checked"
|
|
77
|
+
:disabled="isDisabled"
|
|
78
|
+
@update:model-value="(v) => onUpdate(v)"
|
|
79
|
+
/>
|
|
80
|
+
</span>
|
|
81
|
+
</template>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CellContext } from '@tanstack/vue-table';
|
|
2
|
+
import type { Value } from './schema.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
column: Value;
|
|
5
|
+
ctx: CellContext<unknown, unknown>;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import type { ColumnDef } from '@tanstack/vue-table';
|
|
3
|
+
import type { Environment } from '../../../../../vendor/cel-js/lib/index.js';
|
|
4
|
+
import type { ColumnDefDeps, MigrateFn, MigrateSource } from '../../../utils/resolve.js';
|
|
5
|
+
export declare const type: "com.shwfed.table.column.switch.remote";
|
|
6
|
+
export declare const compatibilityDate: "2026-05-13";
|
|
7
|
+
export declare const metadata: {
|
|
8
|
+
readonly name: "开关(远程)";
|
|
9
|
+
readonly icon: "fluent:toggle-left-20-regular";
|
|
10
|
+
};
|
|
11
|
+
export declare function schema(configure: (env: Environment) => void): Schema.Struct<{
|
|
12
|
+
align: Schema.optionalWith<Schema.Literal<["left", "center", "right"]>, {
|
|
13
|
+
default: () => "center";
|
|
14
|
+
}>;
|
|
15
|
+
disabled: Schema.optional<Schema.Schema<string, string, never>>;
|
|
16
|
+
onChange: Schema.optional<Schema.Schema<string, string, never>>;
|
|
17
|
+
successMessage: Schema.optional<Schema.Schema<string, string, never>>;
|
|
18
|
+
triggers: Schema.optional<Schema.Array$<Schema.Struct<{
|
|
19
|
+
target: Schema.refine<string, typeof Schema.String>;
|
|
20
|
+
operation: Schema.SchemaClass<string, string, never>;
|
|
21
|
+
}>>>;
|
|
22
|
+
title: Schema.TupleType<readonly [Schema.Struct<{
|
|
23
|
+
locale: Schema.Literal<["zh"]>;
|
|
24
|
+
message: Schema.SchemaClass<string, string, never>;
|
|
25
|
+
}>], [Schema.Struct<{
|
|
26
|
+
locale: Schema.Literal<["ja", "en", "ko"]>;
|
|
27
|
+
message: Schema.SchemaClass<string, string, never>;
|
|
28
|
+
}>]>;
|
|
29
|
+
accessor: Schema.Schema<string, string, never>;
|
|
30
|
+
enableSorting: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
|
|
31
|
+
size: Schema.optional<Schema.refine<number, Schema.filter<typeof Schema.Number>>>;
|
|
32
|
+
grow: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
|
|
33
|
+
tooltip: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{
|
|
34
|
+
locale: Schema.Literal<["zh"]>;
|
|
35
|
+
message: Schema.SchemaClass<string, string, never>;
|
|
36
|
+
}>], [Schema.Struct<{
|
|
37
|
+
locale: Schema.Literal<["ja", "en", "ko"]>;
|
|
38
|
+
message: Schema.SchemaClass<string, string, never>;
|
|
39
|
+
}>]>>;
|
|
40
|
+
id: Schema.refine<string, typeof Schema.String>;
|
|
41
|
+
groupId: Schema.optional<typeof Schema.UUID>;
|
|
42
|
+
type: Schema.Literal<["com.shwfed.table.column.switch.remote"]>;
|
|
43
|
+
compatibilityDate: Schema.Literal<["2026-05-13"]>;
|
|
44
|
+
}>;
|
|
45
|
+
export type Value = Schema.Schema.Type<ReturnType<typeof schema>>;
|
|
46
|
+
/**
|
|
47
|
+
* Adopts values that were stored under the pre-split `com.shwfed.table.column.switch`
|
|
48
|
+
* type at the same `compatibilityDate`. The field shape is byte-identical to
|
|
49
|
+
* this entry's schema — only the discriminator changes. Migration declarations
|
|
50
|
+
* live exclusively on this (new) entry; the old folder was removed and is
|
|
51
|
+
* never touched by this rewrite.
|
|
52
|
+
*/
|
|
53
|
+
export declare const migrateFrom: ReadonlyArray<MigrateSource>;
|
|
54
|
+
export declare const migrate: MigrateFn;
|
|
55
|
+
export declare function toColumnDef(value: Value, { getLocaleText, $cel, inheritedContext }: ColumnDefDeps): Partial<ColumnDef<unknown, unknown>>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { Expression } from "../../../../../share/expression.js";
|
|
3
|
+
import { Triggers } from "../../../../../share/event-bus.js";
|
|
4
|
+
import { Align, CelRowAccess, columnFields, registerRowVariablesIfAbsent } from "../../../utils/shared.js";
|
|
5
|
+
export const type = "com.shwfed.table.column.switch.remote";
|
|
6
|
+
export const compatibilityDate = "2026-05-13";
|
|
7
|
+
export const metadata = {
|
|
8
|
+
name: "\u5F00\u5173\uFF08\u8FDC\u7A0B\uFF09",
|
|
9
|
+
icon: "fluent:toggle-left-20-regular"
|
|
10
|
+
};
|
|
11
|
+
export function schema(configure) {
|
|
12
|
+
const CelBool = CelRowAccess(configure, { resultType: "bool" });
|
|
13
|
+
const CelOnChange = Expression({
|
|
14
|
+
configure: (env) => {
|
|
15
|
+
configure(env);
|
|
16
|
+
registerRowVariablesIfAbsent(env);
|
|
17
|
+
env.registerVariable("value", "bool", { description: "\u5207\u6362\u540E\u7684\u65B0\u503C" });
|
|
18
|
+
},
|
|
19
|
+
resultType: "HttpRequest"
|
|
20
|
+
});
|
|
21
|
+
const CelMessage = Expression({
|
|
22
|
+
configure: (env) => {
|
|
23
|
+
configure(env);
|
|
24
|
+
env.registerVariable("json", "dyn", { description: "HTTP \u54CD\u5E94\u4F53\uFF08\u5DF2\u89E3\u6790 JSON\uFF09" });
|
|
25
|
+
},
|
|
26
|
+
resultType: "string"
|
|
27
|
+
});
|
|
28
|
+
return Schema.Struct({
|
|
29
|
+
type: Schema.Literal(type),
|
|
30
|
+
compatibilityDate: Schema.Literal(compatibilityDate),
|
|
31
|
+
...columnFields(configure),
|
|
32
|
+
align: Schema.optionalWith(Align.annotations({ title: "\u5BF9\u9F50" }), { default: () => "center" }),
|
|
33
|
+
disabled: Schema.optional(CelBool.annotations({
|
|
34
|
+
title: "\u7981\u7528\u6761\u4EF6",
|
|
35
|
+
description: "\u8FD4\u56DE `true` \u65F6\u5F00\u5173\u4ECD\u7136\u6E32\u67D3\u4F46\u4E0D\u53EF\u5207\u6362"
|
|
36
|
+
})),
|
|
37
|
+
onChange: Schema.optional(CelOnChange.annotations({
|
|
38
|
+
title: "\u5207\u6362\u8BF7\u6C42",
|
|
39
|
+
description: "\u7528\u6237\u5207\u6362\u540E\u7ACB\u5373\u6C42\u503C\u5E76\u53D1\u8D77\u7684 HTTP \u8BF7\u6C42\uFF1B`value` \u4E3A\u5207\u6362\u540E\u7684\u65B0\u503C\u3002\u672A\u914D\u7F6E\u65F6\u5F00\u5173\u53EA\u8BFB"
|
|
40
|
+
})),
|
|
41
|
+
successMessage: Schema.optional(CelMessage.annotations({
|
|
42
|
+
title: "\u6210\u529F\u6D88\u606F",
|
|
43
|
+
description: "\u8BF7\u6C42\u6210\u529F\u540E\u5F39\u51FA\u7684 toast \u5185\u5BB9\uFF1B\u672A\u914D\u7F6E\u5219\u9759\u9ED8"
|
|
44
|
+
})),
|
|
45
|
+
triggers: Schema.optional(Triggers.annotations({
|
|
46
|
+
title: "\u6210\u529F\u540E\u89E6\u53D1",
|
|
47
|
+
description: "\u8BF7\u6C42\u6210\u529F\u540E\u6309\u5217\u8868\u987A\u5E8F\u5192\u6CE1\u7684\u64CD\u4F5C\u8BF7\u6C42\uFF1B\u672A\u914D\u7F6E\u5219\u4EC0\u4E48\u90FD\u4E0D\u505A"
|
|
48
|
+
}))
|
|
49
|
+
}).annotations({ title: "SwitchRenderer", description: "\u5F00\u5173\u6E32\u67D3\u5668\uFF08\u53EF\u7F16\u8F91\uFF09" });
|
|
50
|
+
}
|
|
51
|
+
export const migrateFrom = [
|
|
52
|
+
{ type: "com.shwfed.table.column.switch", compatibilityDate }
|
|
53
|
+
];
|
|
54
|
+
export const migrate = (prev) => Effect.try({
|
|
55
|
+
try: () => {
|
|
56
|
+
if (!prev || typeof prev !== "object") {
|
|
57
|
+
throw new Error("\u5F00\u5173\uFF08\u8FDC\u7A0B\uFF09\u8FC1\u79FB\u5931\u8D25\uFF1A\u539F\u503C\u4E0D\u662F\u5BF9\u8C61");
|
|
58
|
+
}
|
|
59
|
+
return { ...prev, type, compatibilityDate };
|
|
60
|
+
},
|
|
61
|
+
catch: (e) => e instanceof Error ? e : new Error(String(e))
|
|
62
|
+
});
|
|
63
|
+
export function toColumnDef(value, { getLocaleText, $cel, inheritedContext }) {
|
|
64
|
+
return {
|
|
65
|
+
header: getLocaleText(value.title),
|
|
66
|
+
accessorFn: (row, index) => {
|
|
67
|
+
try {
|
|
68
|
+
return Effect.runSync($cel(value.accessor, { ...inheritedContext, row, index }));
|
|
69
|
+
} catch (e) {
|
|
70
|
+
console.error("[shwfed-table] switch accessor failed", e);
|
|
71
|
+
return void 0;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
enableSorting: value.enableSorting ?? false,
|
|
75
|
+
sortingFn: "basic",
|
|
76
|
+
size: value.size,
|
|
77
|
+
meta: {
|
|
78
|
+
grow: value.grow ?? false,
|
|
79
|
+
tooltip: getLocaleText(value.tooltip)
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type __VLS_ModelProps = {
|
|
2
|
+
modelValue: Record<string, any>;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
6
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
7
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
8
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { Icon } from "@iconify/vue";
|
|
4
|
+
import { ExpressionEditor } from "../../../../ui/expression-editor";
|
|
5
|
+
import { Switch } from "../../../../ui/switch";
|
|
6
|
+
import { Separator } from "../../../../ui/separator";
|
|
7
|
+
import { Field, FieldLabel } from "../../../../ui/field";
|
|
8
|
+
import { Locale } from "../../../../ui/locale";
|
|
9
|
+
import {
|
|
10
|
+
InputGroup,
|
|
11
|
+
InputGroupAddon,
|
|
12
|
+
InputGroupButton,
|
|
13
|
+
InputGroupInput,
|
|
14
|
+
InputGroupNumberField
|
|
15
|
+
} from "../../../../ui/input-group";
|
|
16
|
+
import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
|
|
17
|
+
import { Markdown } from "../../../../ui/markdown";
|
|
18
|
+
import DerivedValueEditor from "../../../../form/DerivedValueEditor.vue";
|
|
19
|
+
import { schema } from "./schema";
|
|
20
|
+
defineOptions({ name: "ShwfedTableSwitchRendererConfig" });
|
|
21
|
+
const value = defineModel({ type: Object, ...{ required: true } });
|
|
22
|
+
const fieldSchema = schema(() => {
|
|
23
|
+
});
|
|
24
|
+
const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
|
|
25
|
+
const fieldDescription = (field) => getStructFieldDescription(fieldSchema, field);
|
|
26
|
+
const ROW_VARS = {
|
|
27
|
+
row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
|
|
28
|
+
index: { type: "number", label: "\u884C\u7D22\u5F15" }
|
|
29
|
+
};
|
|
30
|
+
const bindingText = computed({
|
|
31
|
+
get: () => value.value.binding ?? "",
|
|
32
|
+
set: (v) => {
|
|
33
|
+
const trimmed = v.trim();
|
|
34
|
+
if (trimmed === "") delete value.value.binding;
|
|
35
|
+
else value.value.binding = trimmed;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
const hiddenModel = computed({
|
|
39
|
+
get: () => value.value.hidden ?? "",
|
|
40
|
+
set: (v) => {
|
|
41
|
+
if (v === "") delete value.value.hidden;
|
|
42
|
+
else value.value.hidden = v;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const disabledModel = computed({
|
|
46
|
+
get: () => value.value.disabled ?? "",
|
|
47
|
+
set: (v) => {
|
|
48
|
+
if (v === "") delete value.value.disabled;
|
|
49
|
+
else value.value.disabled = v;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const readonlyModel = computed({
|
|
53
|
+
get: () => value.value.readonly ?? "",
|
|
54
|
+
set: (v) => {
|
|
55
|
+
if (v === "") delete value.value.readonly;
|
|
56
|
+
else value.value.readonly = v;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const derivedModel = computed({
|
|
60
|
+
get: () => value.value.derived,
|
|
61
|
+
set: (v) => {
|
|
62
|
+
if (v == null) delete value.value.derived;
|
|
63
|
+
else value.value.derived = v;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<template>
|
|
69
|
+
<div class="space-y-5">
|
|
70
|
+
<div class="grid grid-cols-2 gap-x-6 gap-y-4">
|
|
71
|
+
<Field orientation="vertical">
|
|
72
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
73
|
+
<template
|
|
74
|
+
v-if="fieldDescription('title')"
|
|
75
|
+
#tooltip
|
|
76
|
+
>
|
|
77
|
+
<Markdown
|
|
78
|
+
:source="fieldDescription('title')"
|
|
79
|
+
block
|
|
80
|
+
class="prose prose-sm prose-zinc"
|
|
81
|
+
/>
|
|
82
|
+
</template>
|
|
83
|
+
{{ fieldTitle("title") }}
|
|
84
|
+
</FieldLabel>
|
|
85
|
+
<Locale v-model="value.title" />
|
|
86
|
+
</Field>
|
|
87
|
+
<Field orientation="vertical">
|
|
88
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
89
|
+
<template
|
|
90
|
+
v-if="fieldDescription('tooltip')"
|
|
91
|
+
#tooltip
|
|
92
|
+
>
|
|
93
|
+
<Markdown
|
|
94
|
+
:source="fieldDescription('tooltip')"
|
|
95
|
+
block
|
|
96
|
+
class="prose prose-sm prose-zinc"
|
|
97
|
+
/>
|
|
98
|
+
</template>
|
|
99
|
+
{{ fieldTitle("tooltip") }}
|
|
100
|
+
</FieldLabel>
|
|
101
|
+
<Locale
|
|
102
|
+
v-model="value.tooltip"
|
|
103
|
+
markdown
|
|
104
|
+
/>
|
|
105
|
+
</Field>
|
|
106
|
+
</div>
|
|
107
|
+
<div class="grid grid-cols-2 gap-x-6 gap-y-4">
|
|
108
|
+
<Field orientation="vertical">
|
|
109
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
110
|
+
<template
|
|
111
|
+
v-if="fieldDescription('binding')"
|
|
112
|
+
#tooltip
|
|
113
|
+
>
|
|
114
|
+
<Markdown
|
|
115
|
+
:source="fieldDescription('binding')"
|
|
116
|
+
block
|
|
117
|
+
class="prose prose-sm prose-zinc"
|
|
118
|
+
/>
|
|
119
|
+
</template>
|
|
120
|
+
{{ fieldTitle("binding") }}
|
|
121
|
+
</FieldLabel>
|
|
122
|
+
<InputGroup>
|
|
123
|
+
<InputGroupInput
|
|
124
|
+
v-model="bindingText"
|
|
125
|
+
placeholder="例:enabled"
|
|
126
|
+
class="font-mono"
|
|
127
|
+
/>
|
|
128
|
+
</InputGroup>
|
|
129
|
+
</Field>
|
|
130
|
+
<Field orientation="vertical">
|
|
131
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
132
|
+
<template
|
|
133
|
+
v-if="fieldDescription('size')"
|
|
134
|
+
#tooltip
|
|
135
|
+
>
|
|
136
|
+
<Markdown
|
|
137
|
+
:source="fieldDescription('size')"
|
|
138
|
+
block
|
|
139
|
+
class="prose prose-sm prose-zinc"
|
|
140
|
+
/>
|
|
141
|
+
</template>
|
|
142
|
+
{{ fieldTitle("size") }}
|
|
143
|
+
</FieldLabel>
|
|
144
|
+
<InputGroup>
|
|
145
|
+
<InputGroupNumberField
|
|
146
|
+
:model-value="value.size"
|
|
147
|
+
:disabled="value.grow"
|
|
148
|
+
:min="0"
|
|
149
|
+
@update:model-value="(v) => value.size = v"
|
|
150
|
+
/>
|
|
151
|
+
<InputGroupAddon align="inline-end">
|
|
152
|
+
<InputGroupButton
|
|
153
|
+
:variant="value.grow ? 'primary' : 'ghost'"
|
|
154
|
+
size="xs"
|
|
155
|
+
@click="value.grow = !value.grow"
|
|
156
|
+
>
|
|
157
|
+
<Icon :icon="value.grow ? 'fluent:lock-closed-20-regular' : 'fluent:arrow-autofit-width-20-regular'" />
|
|
158
|
+
{{ fieldTitle("grow") }}
|
|
159
|
+
</InputGroupButton>
|
|
160
|
+
</InputGroupAddon>
|
|
161
|
+
</InputGroup>
|
|
162
|
+
</Field>
|
|
163
|
+
<Field orientation="vertical">
|
|
164
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
165
|
+
<template
|
|
166
|
+
v-if="fieldDescription('trueLabel')"
|
|
167
|
+
#tooltip
|
|
168
|
+
>
|
|
169
|
+
<Markdown
|
|
170
|
+
:source="fieldDescription('trueLabel')"
|
|
171
|
+
block
|
|
172
|
+
class="prose prose-sm prose-zinc"
|
|
173
|
+
/>
|
|
174
|
+
</template>
|
|
175
|
+
{{ fieldTitle("trueLabel") }}
|
|
176
|
+
</FieldLabel>
|
|
177
|
+
<Locale v-model="value.trueLabel" />
|
|
178
|
+
</Field>
|
|
179
|
+
<Field orientation="vertical">
|
|
180
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
181
|
+
<template
|
|
182
|
+
v-if="fieldDescription('falseLabel')"
|
|
183
|
+
#tooltip
|
|
184
|
+
>
|
|
185
|
+
<Markdown
|
|
186
|
+
:source="fieldDescription('falseLabel')"
|
|
187
|
+
block
|
|
188
|
+
class="prose prose-sm prose-zinc"
|
|
189
|
+
/>
|
|
190
|
+
</template>
|
|
191
|
+
{{ fieldTitle("falseLabel") }}
|
|
192
|
+
</FieldLabel>
|
|
193
|
+
<Locale v-model="value.falseLabel" />
|
|
194
|
+
</Field>
|
|
195
|
+
</div>
|
|
196
|
+
<div class="grid grid-cols-2 gap-x-6 gap-y-4">
|
|
197
|
+
<Field orientation="vertical">
|
|
198
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
199
|
+
<template
|
|
200
|
+
v-if="fieldDescription('hidden')"
|
|
201
|
+
#tooltip
|
|
202
|
+
>
|
|
203
|
+
<Markdown
|
|
204
|
+
:source="fieldDescription('hidden')"
|
|
205
|
+
block
|
|
206
|
+
class="prose prose-sm prose-zinc"
|
|
207
|
+
/>
|
|
208
|
+
</template>
|
|
209
|
+
{{ fieldTitle("hidden") }}
|
|
210
|
+
</FieldLabel>
|
|
211
|
+
<ExpressionEditor
|
|
212
|
+
v-model="hiddenModel"
|
|
213
|
+
placeholder="例:row.archived"
|
|
214
|
+
result-type="bool"
|
|
215
|
+
:extra-vars="ROW_VARS"
|
|
216
|
+
/>
|
|
217
|
+
</Field>
|
|
218
|
+
<Field orientation="vertical">
|
|
219
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
220
|
+
<template
|
|
221
|
+
v-if="fieldDescription('disabled')"
|
|
222
|
+
#tooltip
|
|
223
|
+
>
|
|
224
|
+
<Markdown
|
|
225
|
+
:source="fieldDescription('disabled')"
|
|
226
|
+
block
|
|
227
|
+
class="prose prose-sm prose-zinc"
|
|
228
|
+
/>
|
|
229
|
+
</template>
|
|
230
|
+
{{ fieldTitle("disabled") }}
|
|
231
|
+
</FieldLabel>
|
|
232
|
+
<ExpressionEditor
|
|
233
|
+
v-model="disabledModel"
|
|
234
|
+
placeholder="例:row.locked"
|
|
235
|
+
result-type="bool"
|
|
236
|
+
:extra-vars="ROW_VARS"
|
|
237
|
+
/>
|
|
238
|
+
</Field>
|
|
239
|
+
<Field orientation="vertical">
|
|
240
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
241
|
+
<template
|
|
242
|
+
v-if="fieldDescription('readonly')"
|
|
243
|
+
#tooltip
|
|
244
|
+
>
|
|
245
|
+
<Markdown
|
|
246
|
+
:source="fieldDescription('readonly')"
|
|
247
|
+
block
|
|
248
|
+
class="prose prose-sm prose-zinc"
|
|
249
|
+
/>
|
|
250
|
+
</template>
|
|
251
|
+
{{ fieldTitle("readonly") }}
|
|
252
|
+
</FieldLabel>
|
|
253
|
+
<ExpressionEditor
|
|
254
|
+
v-model="readonlyModel"
|
|
255
|
+
placeholder="例:row.id != null"
|
|
256
|
+
result-type="bool"
|
|
257
|
+
:extra-vars="ROW_VARS"
|
|
258
|
+
/>
|
|
259
|
+
</Field>
|
|
260
|
+
<Field
|
|
261
|
+
orientation="vertical"
|
|
262
|
+
class="col-span-2"
|
|
263
|
+
>
|
|
264
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
265
|
+
<template
|
|
266
|
+
v-if="fieldDescription('derived')"
|
|
267
|
+
#tooltip
|
|
268
|
+
>
|
|
269
|
+
<Markdown
|
|
270
|
+
:source="fieldDescription('derived')"
|
|
271
|
+
block
|
|
272
|
+
class="prose prose-sm prose-zinc"
|
|
273
|
+
/>
|
|
274
|
+
</template>
|
|
275
|
+
{{ fieldTitle("derived") }}
|
|
276
|
+
</FieldLabel>
|
|
277
|
+
<DerivedValueEditor
|
|
278
|
+
v-model="derivedModel"
|
|
279
|
+
result-type="bool"
|
|
280
|
+
placeholder="例:row.quantity > 0"
|
|
281
|
+
/>
|
|
282
|
+
</Field>
|
|
283
|
+
</div>
|
|
284
|
+
<Separator />
|
|
285
|
+
<div class="flex flex-wrap gap-x-8 gap-y-3">
|
|
286
|
+
<Field
|
|
287
|
+
orientation="horizontal"
|
|
288
|
+
class="w-auto gap-2"
|
|
289
|
+
>
|
|
290
|
+
<Switch
|
|
291
|
+
:model-value="value.enableSorting ?? false"
|
|
292
|
+
@update:model-value="(v) => value.enableSorting = v"
|
|
293
|
+
/>
|
|
294
|
+
<FieldLabel class="text-sm text-zinc-600">
|
|
295
|
+
<template
|
|
296
|
+
v-if="fieldDescription('enableSorting')"
|
|
297
|
+
#tooltip
|
|
298
|
+
>
|
|
299
|
+
<Markdown
|
|
300
|
+
:source="fieldDescription('enableSorting')"
|
|
301
|
+
block
|
|
302
|
+
class="prose prose-sm prose-zinc"
|
|
303
|
+
/>
|
|
304
|
+
</template>
|
|
305
|
+
{{ fieldTitle("enableSorting") }}
|
|
306
|
+
</FieldLabel>
|
|
307
|
+
</Field>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
</template>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type __VLS_ModelProps = {
|
|
2
|
+
modelValue: Record<string, any>;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
6
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
7
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
8
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CellContext } from '@tanstack/vue-table';
|
|
2
|
+
import type { Value } from './schema.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
column: Value;
|
|
5
|
+
ctx: CellContext<unknown, unknown>;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { computed } from "vue";
|
|
4
|
+
import { useI18n } from "vue-i18n";
|
|
5
|
+
import { cel as _rawCel } from "../../../../../utils/cel";
|
|
6
|
+
import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
|
|
7
|
+
import { getLocalizedText } from "../../../../../share/locale";
|
|
8
|
+
import { Switch } from "../../../../ui/switch";
|
|
9
|
+
import { useFieldValue } from "../../../../form/utils/field-value";
|
|
10
|
+
defineOptions({ name: "ShwfedTableSwitchRendererRuntime" });
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
column: { type: null, required: true },
|
|
13
|
+
ctx: { type: Object, required: true }
|
|
14
|
+
});
|
|
15
|
+
const { locale } = useI18n();
|
|
16
|
+
const inherited = injectCELContext();
|
|
17
|
+
const $cel = (expression, context) => _rawCel(expression, { ...celBindings(inherited), ...context });
|
|
18
|
+
function evalBool(expression, label) {
|
|
19
|
+
if (!expression) return false;
|
|
20
|
+
try {
|
|
21
|
+
return Effect.runSync($cel(expression)) === true;
|
|
22
|
+
} catch (e) {
|
|
23
|
+
console.error(`[shwfed-table] switch ${label} failed`, e);
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const isHidden = computed(() => evalBool(props.column.hidden, "hidden"));
|
|
28
|
+
const isDisabled = computed(() => evalBool(props.column.disabled, "disabled"));
|
|
29
|
+
const isReadonly = computed(() => evalBool(props.column.readonly, "readonly"));
|
|
30
|
+
const effectiveReadonly = computed(
|
|
31
|
+
() => isReadonly.value || props.column.derived?.mode === "formula"
|
|
32
|
+
);
|
|
33
|
+
const trueText = computed(
|
|
34
|
+
() => getLocalizedText(props.column.trueLabel, locale.value) || "\u662F"
|
|
35
|
+
);
|
|
36
|
+
const falseText = computed(
|
|
37
|
+
() => getLocalizedText(props.column.falseLabel, locale.value) || "\u5426"
|
|
38
|
+
);
|
|
39
|
+
const { draft, commit } = useFieldValue({
|
|
40
|
+
binding: () => props.column.binding,
|
|
41
|
+
fromState: (raw) => raw === true,
|
|
42
|
+
toState: (next) => next === true
|
|
43
|
+
});
|
|
44
|
+
function onUpdate(next) {
|
|
45
|
+
draft.value = next;
|
|
46
|
+
commit();
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<!--
|
|
52
|
+
Row budget matches the editable text/number cells: 2px outer inset around
|
|
53
|
+
an `h-7` (28px) row — 32px total. The switch is centered inside that row;
|
|
54
|
+
`sm` size (h-3.5) keeps it visually compact against the surrounding cells.
|
|
55
|
+
Every branch (hidden / readonly / editable) is sized identically so rows
|
|
56
|
+
do not jump when a CEL condition flips.
|
|
57
|
+
-->
|
|
58
|
+
<div class="p-[0.125rem] w-full">
|
|
59
|
+
<span
|
|
60
|
+
v-if="isHidden"
|
|
61
|
+
class="block h-7 w-full"
|
|
62
|
+
/>
|
|
63
|
+
<span
|
|
64
|
+
v-else-if="effectiveReadonly"
|
|
65
|
+
class="flex items-center justify-center h-7 w-full px-2 text-[0.75rem] text-zinc-700 truncate"
|
|
66
|
+
>
|
|
67
|
+
{{ draft ? trueText : falseText }}
|
|
68
|
+
</span>
|
|
69
|
+
<span
|
|
70
|
+
v-else
|
|
71
|
+
class="flex items-center justify-center h-7 w-full"
|
|
72
|
+
>
|
|
73
|
+
<Switch
|
|
74
|
+
size="sm"
|
|
75
|
+
:model-value="draft"
|
|
76
|
+
:disabled="isDisabled"
|
|
77
|
+
@update:model-value="onUpdate"
|
|
78
|
+
/>
|
|
79
|
+
</span>
|
|
80
|
+
</div>
|
|
81
|
+
</template>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CellContext } from '@tanstack/vue-table';
|
|
2
|
+
import type { Value } from './schema.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
column: Value;
|
|
5
|
+
ctx: CellContext<unknown, unknown>;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
declare const _default: typeof __VLS_export;
|
|
9
|
+
export default _default;
|