@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.
Files changed (50) hide show
  1. package/dist/mcp.mjs +704 -441
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{config-BxzDT_57.js → config-57-v4VXo.js} +1 -1
  4. package/dist/preview/assets/{config-2R4XkSGs.js → config-BZahzuEc.js} +1 -1
  5. package/dist/preview/assets/{config-KcLrpkc1.js → config-Be-2ZA2R.js} +1 -1
  6. package/dist/preview/assets/{config-ykJZssgx.js → config-BnZQO-Sp.js} +1 -1
  7. package/dist/preview/assets/{config-bxqg3yuv.js → config-Bp91DUdU.js} +1 -1
  8. package/dist/preview/assets/{config-CyScbxXy.js → config-DNokxY7M.js} +1 -1
  9. package/dist/preview/assets/{config-HdWYFZ09.js → config-_msO_f2R.js} +1 -1
  10. package/dist/preview/assets/{config-ja_GMXxV.js → config-_uPI8qV-.js} +1 -1
  11. 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
  12. package/dist/preview/assets/index-DDbl2Atj.js +1 -0
  13. package/dist/preview/assets/index-DGa3Oj3y.js +1075 -0
  14. package/dist/preview/assets/{index-BPKK3hGV.css → index-mbGtsgdv.css} +1 -1
  15. package/dist/preview/assets/{runtime-LBdh1D75.js → runtime-B9u14qqB.js} +1 -1
  16. package/dist/preview/assets/{runtime-B8aUJIpn.js → runtime-BBms4myv.js} +1 -1
  17. package/dist/preview/assets/{runtime-D2K1s33u.js → runtime-CfR7ZAND.js} +1 -1
  18. package/dist/preview/assets/{runtime-C9XnvD5A.js → runtime-D3EyeiyA.js} +1 -1
  19. package/dist/preview/assets/{runtime-DqZhDPHl.js → runtime-Dk9u-Ybw.js} +1 -1
  20. package/dist/preview/assets/{runtime-CpSiaWMP.js → runtime-XXqIAt53.js} +1 -1
  21. package/dist/preview/assets/{runtime-CxA8fvQP.js → runtime-cKWSGFod.js} +1 -1
  22. package/dist/preview/assets/{runtime-DAXQmtLg.js → runtime-w7V-p3t1.js} +1 -1
  23. package/dist/preview/index.html +2 -2
  24. package/dist/runtime/components/form/ai/fields-button.vue +3 -1
  25. package/dist/runtime/components/form/unit-config.vue +8 -4
  26. package/dist/runtime/components/form/utils/resolve.d.ts +48 -9
  27. package/dist/runtime/components/form/utils/resolve.js +59 -5
  28. package/dist/runtime/components/table/ai/columns-button.vue +1 -0
  29. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.d.vue.ts +10 -0
  30. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.vue +305 -0
  31. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.vue.d.ts +10 -0
  32. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/runtime.d.vue.ts +9 -0
  33. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/runtime.vue +81 -0
  34. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/runtime.vue.d.ts +9 -0
  35. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.d.ts +55 -0
  36. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.js +82 -0
  37. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.d.vue.ts +10 -0
  38. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.vue +310 -0
  39. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.vue.d.ts +10 -0
  40. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.d.vue.ts +9 -0
  41. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue +81 -0
  42. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue.d.ts +9 -0
  43. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.d.ts +66 -0
  44. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.js +71 -0
  45. package/dist/runtime/components/table/config.vue +2 -1
  46. package/dist/runtime/components/table/utils/resolve.d.ts +53 -0
  47. package/dist/runtime/components/table/utils/resolve.js +66 -1
  48. package/package.json +1 -1
  49. package/dist/preview/assets/index-D3pf2RjG.js +0 -1
  50. 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;