@shwfed/config 2.3.22 → 2.3.23

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 (60) hide show
  1. package/dist/mcp.mjs +1073 -624
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{config-B3mv60t8.js → config-5rB9Rnmf.js} +1 -1
  4. package/dist/preview/assets/{config-DY7n8WvE.js → config-BLxl7ROb.js} +1 -1
  5. package/dist/preview/assets/{config-CpvkgqGg.js → config-BWMtPN22.js} +1 -1
  6. package/dist/preview/assets/{config-DX6QxjI7.js → config-C-EOrL-v.js} +1 -1
  7. package/dist/preview/assets/{config-Cb9lQXQG.js → config-CJADmi-_.js} +1 -1
  8. package/dist/preview/assets/{config-D4fS9GYw.js → config-DUNvg-mJ.js} +1 -1
  9. package/dist/preview/assets/{config-CLjwrQXG.js → config-EtlOM9yx.js} +1 -1
  10. package/dist/preview/assets/{config-BiFAbTJq.js → config-f66PEpZ5.js} +1 -1
  11. package/dist/preview/assets/{config-DhwLB2Ee.js → config-pVNUrcvS.js} +1 -1
  12. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-Hx2iV358.js → definition.vue_vue_type_script_setup_true_lang-DUu-CoTZ.js} +1 -1
  13. package/dist/preview/assets/index-B4xolIUJ.js +643 -0
  14. package/dist/preview/assets/{index-CDhwf1Dw.css → index-CJMxrUKZ.css} +1 -1
  15. package/dist/preview/assets/index-DFYLO8qf.js +1 -0
  16. package/dist/preview/assets/{runtime-CShAGyQk.js → runtime-B9GkQToM.js} +1 -1
  17. package/dist/preview/assets/{runtime-DIcMvC6H.js → runtime-C0v-S40R.js} +1 -1
  18. package/dist/preview/assets/{runtime-usxovPqT.js → runtime-CFPeFbAB.js} +1 -1
  19. package/dist/preview/assets/{runtime-ECoXJ0-J.js → runtime-CI38ypkY.js} +1 -1
  20. package/dist/preview/assets/{runtime-HQv4w652.js → runtime-CUBGWRtC.js} +1 -1
  21. package/dist/preview/assets/{runtime-Dl0d8KFj.js → runtime-DcqfhaaX.js} +1 -1
  22. package/dist/preview/assets/{runtime-BXZROm-z.js → runtime-DoLJtHV2.js} +1 -1
  23. package/dist/preview/assets/{runtime-BarNw942.js → runtime-P99-0gRD.js} +1 -1
  24. package/dist/preview/assets/{runtime-BazV3vOW.js → runtime-qQ5mJdRv.js} +1 -1
  25. package/dist/preview/index.html +2 -2
  26. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.d.vue.ts +99 -0
  27. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.vue +329 -0
  28. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.vue.d.ts +99 -0
  29. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/runtime.d.vue.ts +8 -0
  30. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/runtime.vue +265 -0
  31. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/runtime.vue.d.ts +8 -0
  32. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/schema.d.ts +79 -0
  33. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/schema.js +71 -0
  34. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/config.d.vue.ts +133 -0
  35. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/config.vue +533 -0
  36. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/config.vue.d.ts +133 -0
  37. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/runtime.d.vue.ts +9 -0
  38. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/runtime.vue +247 -0
  39. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/runtime.vue.d.ts +9 -0
  40. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/schema.d.ts +124 -0
  41. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/schema.js +94 -0
  42. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +109 -0
  43. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue +426 -0
  44. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +109 -0
  45. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/runtime.d.vue.ts +9 -0
  46. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/runtime.vue +356 -0
  47. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/runtime.vue.d.ts +9 -0
  48. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/schema.d.ts +85 -0
  49. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/schema.js +147 -0
  50. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +137 -0
  51. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue +586 -0
  52. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +137 -0
  53. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/runtime.d.vue.ts +9 -0
  54. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/runtime.vue +287 -0
  55. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/runtime.vue.d.ts +9 -0
  56. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/schema.d.ts +126 -0
  57. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/schema.js +125 -0
  58. package/package.json +1 -1
  59. package/dist/preview/assets/index-B2gp2q3H.js +0 -643
  60. package/dist/preview/assets/index-Jytc_ICm.js +0 -1
@@ -0,0 +1,356 @@
1
+ <script setup>
2
+ import { Icon } from "@iconify/vue";
3
+ import { watchDebounced } from "@vueuse/core";
4
+ import { Effect } from "effect";
5
+ import { Fetch } from "fx-fetch";
6
+ import { toast } from "vue-sonner";
7
+ import { computed, ref, watch } from "vue";
8
+ import { useI18n } from "vue-i18n";
9
+ import { cel as _rawCel } from "../../../../../utils/cel";
10
+ import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
11
+ import { getLocalizedText } from "../../../../../share/locale";
12
+ import { dispatchTriggers, useEventChannel } from "../../../../../share/event-bus";
13
+ import {
14
+ Command,
15
+ CommandEmpty,
16
+ CommandGroup,
17
+ CommandInput,
18
+ CommandItem,
19
+ CommandList
20
+ } from "../../../../ui/command";
21
+ import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "../../../../ui/input-group";
22
+ import { Markdown } from "../../../../ui/markdown";
23
+ import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../../../../ui/popover";
24
+ import { interpolateMarkdown } from "../../../utils/runtime";
25
+ import { useSharedFetchLayer } from "../../../utils/shared-fetch";
26
+ defineOptions({ name: "ShwfedTableComboboxMultiRemoteOptionsRemoteRuntime" });
27
+ const props = defineProps({
28
+ column: { type: null, required: true },
29
+ ctx: { type: Object, required: true }
30
+ });
31
+ const { locale, t } = useI18n({
32
+ inheritLocale: true,
33
+ messages: {
34
+ zh: {
35
+ "combobox-multi-placeholder": "\u8BF7\u9009\u62E9",
36
+ "combobox-multi-search-placeholder": "\u641C\u7D22\u2026",
37
+ "combobox-multi-empty": "\u65E0\u5339\u914D\u9879",
38
+ "combobox-multi-loading": "\u52A0\u8F7D\u4E2D\u2026"
39
+ },
40
+ en: {
41
+ "combobox-multi-placeholder": "Select\u2026",
42
+ "combobox-multi-search-placeholder": "Search\u2026",
43
+ "combobox-multi-empty": "No matches",
44
+ "combobox-multi-loading": "Loading\u2026"
45
+ },
46
+ ja: {
47
+ "combobox-multi-placeholder": "\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044",
48
+ "combobox-multi-search-placeholder": "\u691C\u7D22\u2026",
49
+ "combobox-multi-empty": "\u4E00\u81F4\u306A\u3057",
50
+ "combobox-multi-loading": "\u8AAD\u307F\u8FBC\u307F\u4E2D\u2026"
51
+ }
52
+ }
53
+ });
54
+ const inherited = injectCELContext();
55
+ const $cel = (expression, context) => _rawCel(expression, { ...celBindings(inherited), ...context });
56
+ const eventChannel = useEventChannel();
57
+ const sharedFetchLayer = useSharedFetchLayer();
58
+ const row = computed(() => props.ctx.row.original);
59
+ const rowIndex = computed(() => props.ctx.row.index);
60
+ const placeholderText = computed(
61
+ () => props.column.placeholder ? getLocalizedText(props.column.placeholder, locale.value) : t("combobox-multi-placeholder")
62
+ );
63
+ function evalBool(expression, label) {
64
+ if (!expression) return false;
65
+ try {
66
+ return Effect.runSync($cel(expression, { row: row.value, index: rowIndex.value })) === true;
67
+ } catch (e) {
68
+ console.error(`[shwfed-table] combobox-multi.remote.options-remote ${label} failed`, e);
69
+ return false;
70
+ }
71
+ }
72
+ const isHidden = computed(() => evalBool(props.column.hidden, "hidden"));
73
+ const isDisabledByConfig = computed(() => evalBool(props.column.disabled, "disabled"));
74
+ const isReadonly = computed(() => evalBool(props.column.readonly, "readonly"));
75
+ const isInteractive = computed(() => !!props.column.onChange);
76
+ const pending = ref(false);
77
+ const json = ref(null);
78
+ const isLoading = ref(false);
79
+ const requestSignature = computed(() => {
80
+ const expr = props.column.request;
81
+ if (!expr) return null;
82
+ try {
83
+ const builder = Effect.runSync(
84
+ $cel(expr, { row: row.value, index: rowIndex.value })
85
+ );
86
+ return JSON.stringify(builder.describe());
87
+ } catch {
88
+ return null;
89
+ }
90
+ });
91
+ let fetchSeq = 0;
92
+ async function fetchOptions() {
93
+ const seq = ++fetchSeq;
94
+ if (requestSignature.value == null) {
95
+ json.value = null;
96
+ isLoading.value = false;
97
+ return;
98
+ }
99
+ const expr = props.column.request;
100
+ isLoading.value = true;
101
+ const program = Effect.gen(function* () {
102
+ const builder = yield* $cel(expr, { row: row.value, index: rowIndex.value });
103
+ return yield* builder.json();
104
+ });
105
+ try {
106
+ const result = await Effect.runPromise(Effect.provide(program, sharedFetchLayer));
107
+ if (seq === fetchSeq) json.value = result;
108
+ } catch {
109
+ if (seq === fetchSeq) json.value = null;
110
+ } finally {
111
+ if (seq === fetchSeq) isLoading.value = false;
112
+ }
113
+ }
114
+ watchDebounced(
115
+ requestSignature,
116
+ () => {
117
+ void fetchOptions();
118
+ },
119
+ { debounce: 200, immediate: true }
120
+ );
121
+ function valueOf(option) {
122
+ try {
123
+ return Effect.runSync($cel(props.column.optionValue, {
124
+ row: row.value,
125
+ index: rowIndex.value,
126
+ option
127
+ }));
128
+ } catch (e) {
129
+ console.error("[shwfed-table] combobox-multi.remote.options-remote optionValue failed", e);
130
+ return void 0;
131
+ }
132
+ }
133
+ function labelOf(option) {
134
+ const tpl = getLocalizedText(props.column.optionLabel, locale.value) ?? "";
135
+ if (!tpl) return "";
136
+ try {
137
+ return interpolateMarkdown(tpl, $cel, { row: row.value, index: rowIndex.value, option });
138
+ } catch (e) {
139
+ console.error("[shwfed-table] combobox-multi.remote.options-remote optionLabel failed", e);
140
+ return "";
141
+ }
142
+ }
143
+ const entries = computed(() => {
144
+ let raw;
145
+ try {
146
+ raw = Effect.runSync($cel(props.column.options, {
147
+ row: row.value,
148
+ index: rowIndex.value,
149
+ json: json.value
150
+ }));
151
+ } catch (e) {
152
+ console.error("[shwfed-table] combobox-multi.remote.options-remote options failed", e);
153
+ return [];
154
+ }
155
+ if (!Array.isArray(raw)) return [];
156
+ return raw.map((option, idx) => ({
157
+ key: String(idx),
158
+ label: labelOf(option),
159
+ value: valueOf(option)
160
+ }));
161
+ });
162
+ const cellValue = computed(() => {
163
+ const raw = props.ctx.cell.getValue();
164
+ return Array.isArray(raw) ? raw : [];
165
+ });
166
+ function isEqual(a, b) {
167
+ if (a === b) return true;
168
+ if (a == null || b == null) return false;
169
+ if (typeof a === "object" && typeof b === "object") {
170
+ try {
171
+ return JSON.stringify(a) === JSON.stringify(b);
172
+ } catch {
173
+ return false;
174
+ }
175
+ }
176
+ return false;
177
+ }
178
+ const selectedEntries = computed(() => {
179
+ const list = [];
180
+ for (const v of cellValue.value) {
181
+ const entry = entries.value.find((e) => isEqual(e.value, v));
182
+ if (entry) list.push(entry);
183
+ }
184
+ return list;
185
+ });
186
+ const selectedKeys = computed(() => selectedEntries.value.map((e) => e.key));
187
+ const selectedKeySet = computed(() => new Set(selectedKeys.value));
188
+ const triggerLabel = computed(() => {
189
+ const arr = selectedEntries.value;
190
+ if (arr.length === 0) return "";
191
+ if (arr.length === 1) return arr[0].label;
192
+ return `${arr[0].label} +${arr.length - 1}`;
193
+ });
194
+ const open = ref(false);
195
+ const isDisabled = computed(
196
+ () => !isInteractive.value || isDisabledByConfig.value || pending.value
197
+ );
198
+ async function submit(next) {
199
+ const { onChange, successMessage } = props.column;
200
+ if (!onChange) return;
201
+ pending.value = true;
202
+ const program = Effect.gen(function* () {
203
+ const builder = yield* $cel(onChange, {
204
+ row: row.value,
205
+ index: rowIndex.value,
206
+ value: next
207
+ });
208
+ return yield* builder.json();
209
+ });
210
+ try {
211
+ const body = await Effect.runPromise(Effect.provide(program, Fetch.layer));
212
+ if (successMessage) {
213
+ try {
214
+ const message = Effect.runSync($cel(successMessage, { json: body }));
215
+ if (message) toast.success(message);
216
+ } catch (e) {
217
+ console.error("[shwfed-table] combobox-multi.remote.options-remote successMessage failed", e);
218
+ }
219
+ }
220
+ await Effect.runPromise(dispatchTriggers(eventChannel, props.column.triggers));
221
+ } catch (e) {
222
+ console.error("[shwfed-table] combobox-multi.remote.options-remote onChange failed", e);
223
+ toast.error("\u8BF7\u6C42\u5931\u8D25");
224
+ } finally {
225
+ pending.value = false;
226
+ }
227
+ }
228
+ function handleSelect(next) {
229
+ const keys = Array.isArray(next) ? next.filter((k) => typeof k === "string") : [];
230
+ const mapped = [];
231
+ for (const key of keys) {
232
+ const entry = entries.value.find((e) => e.key === key);
233
+ if (entry) mapped.push(entry.value);
234
+ }
235
+ void submit(mapped);
236
+ }
237
+ const showClear = computed(
238
+ () => !isDisabled.value && selectedEntries.value.length > 0
239
+ );
240
+ function handleClear() {
241
+ open.value = false;
242
+ void submit([]);
243
+ }
244
+ const hoveredKey = ref(null);
245
+ watch(open, (isOpen) => {
246
+ hoveredKey.value = isOpen ? entries.value[0]?.key ?? null : null;
247
+ });
248
+ </script>
249
+
250
+ <template>
251
+ <div class="p-[0.125rem] w-full">
252
+ <span
253
+ v-if="isHidden"
254
+ class="block h-7 w-full"
255
+ />
256
+ <span
257
+ v-else-if="isReadonly || !isInteractive"
258
+ class="flex items-center h-7 w-full px-2 text-[0.75rem] text-zinc-700 truncate"
259
+ >
260
+ {{ triggerLabel || "\u2014" }}
261
+ </span>
262
+ <Popover
263
+ v-else
264
+ v-model:open="open"
265
+ >
266
+ <PopoverAnchor as-child>
267
+ <InputGroup
268
+ class="group/combobox-multi-remote h-7 rounded border-zinc-200/30 hover:border-zinc-200 focus-within:border-zinc-200 transition-colors ease-out duration-180"
269
+ :data-disabled="isDisabled ? 'true' : void 0"
270
+ >
271
+ <PopoverTrigger as-child>
272
+ <InputGroupInput
273
+ :model-value="triggerLabel"
274
+ :disabled="isDisabled"
275
+ :placeholder="placeholderText"
276
+ class="h-7 text-[0.75rem] md:text-[0.75rem] px-2 cursor-pointer text-left"
277
+ readonly
278
+ />
279
+ </PopoverTrigger>
280
+ <InputGroupAddon
281
+ v-if="pending || isLoading"
282
+ align="inline-end"
283
+ class="text-zinc-400"
284
+ >
285
+ <Icon
286
+ icon="fluent:spinner-ios-20-regular"
287
+ class="size-3 animate-spin"
288
+ />
289
+ </InputGroupAddon>
290
+ <InputGroupAddon
291
+ v-else-if="showClear"
292
+ align="inline-end"
293
+ class="[@media(hover:hover)]:opacity-0 transition-opacity group-hover/combobox-multi-remote:opacity-100 focus-within:opacity-100"
294
+ >
295
+ <InputGroupButton
296
+ size="icon-xs"
297
+ data-slot="combobox-multi-remote-clear"
298
+ class="size-4 text-zinc-500 hover:text-zinc-700"
299
+ tabindex="-1"
300
+ @mousedown.prevent
301
+ @click.stop="handleClear"
302
+ >
303
+ <Icon
304
+ icon="fluent:dismiss-20-regular"
305
+ class="size-3"
306
+ />
307
+ </InputGroupButton>
308
+ </InputGroupAddon>
309
+ </InputGroup>
310
+ </PopoverAnchor>
311
+ <PopoverContent
312
+ class="w-auto p-0 [&_[data-slot=command-input-wrapper]]:h-7 [&_[data-slot=command-input-wrapper]]:px-2 [&_[data-slot=command-input-wrapper]_svg]:size-3 [&_[data-slot=command-input]]:h-7 [&_[data-slot=command-input]]:py-0 [&_[data-slot=command-input]]:text-[0.75rem] [&_[data-slot=command-item]]:px-2 [&_[data-slot=command-item]]:py-1 [&_[data-slot=command-item]]:text-[0.75rem]"
313
+ :style="{ width: 'var(--reka-popover-trigger-width)' }"
314
+ >
315
+ <Command
316
+ :model-value="selectedKeys"
317
+ :multiple="true"
318
+ :disabled="isDisabled"
319
+ @update:model-value="handleSelect"
320
+ >
321
+ <CommandInput :placeholder="t('combobox-multi-search-placeholder')" />
322
+ <CommandList>
323
+ <div
324
+ v-if="entries.length === 0"
325
+ data-slot="combobox-multi-remote-empty"
326
+ class="py-3 text-center text-[0.75rem] text-zinc-500"
327
+ >
328
+ {{ isLoading ? t("combobox-multi-loading") : t("combobox-multi-empty") }}
329
+ </div>
330
+ <template v-else>
331
+ <CommandEmpty class="py-3 text-center text-[0.75rem] text-zinc-500">
332
+ {{ t("combobox-multi-empty") }}
333
+ </CommandEmpty>
334
+ <CommandGroup>
335
+ <CommandItem
336
+ v-for="entry in entries"
337
+ :key="entry.key"
338
+ :value="entry.key"
339
+ @mouseenter="hoveredKey = entry.key"
340
+ @focus="hoveredKey = entry.key"
341
+ >
342
+ <span class="flex-1"><Markdown :source="entry.label" /></span>
343
+ <Icon
344
+ v-if="selectedKeySet.has(entry.key)"
345
+ icon="fluent:checkmark-20-regular"
346
+ class="size-3 text-zinc-700"
347
+ />
348
+ </CommandItem>
349
+ </CommandGroup>
350
+ </template>
351
+ </CommandList>
352
+ </Command>
353
+ </PopoverContent>
354
+ </Popover>
355
+ </div>
356
+ </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,85 @@
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 } from '../../../utils/resolve.js';
5
+ export declare const type: "com.shwfed.table.column.combobox-multi.remote.options-remote";
6
+ export declare const compatibilityDate: "2026-05-25";
7
+ export declare const metadata: {
8
+ readonly name: "远程下拉多选";
9
+ readonly icon: "fluent:cloud-arrow-down-20-regular";
10
+ };
11
+ export declare const OPTION_VAR: {
12
+ readonly type: "dyn";
13
+ readonly label: "当前选项";
14
+ readonly description: "`选项` 表达式产出的数组中迭代到的单个元素";
15
+ };
16
+ export declare const JSON_VAR: {
17
+ readonly type: "dyn";
18
+ readonly label: "HTTP 响应体";
19
+ readonly description: "HTTP 响应体(已解析 JSON);请求失败或尚未完成时为 `null`";
20
+ };
21
+ export declare function schema(configure: (env: Environment) => void): Schema.Struct<{
22
+ placeholder: Schema.optional<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
+ hidden: Schema.optional<Schema.Schema<string, string, never>>;
30
+ disabled: Schema.optional<Schema.Schema<string, string, never>>;
31
+ readonly: Schema.optional<Schema.Schema<string, string, never>>;
32
+ request: Schema.Schema<string, string, never>;
33
+ options: Schema.Schema<string, string, never>;
34
+ optionValue: Schema.optionalWith<Schema.Schema<string, string, never>, {
35
+ default: () => string;
36
+ }>;
37
+ optionLabel: Schema.optionalWith<Schema.refine<readonly [{
38
+ readonly locale: "zh";
39
+ readonly message: string;
40
+ }, ...{
41
+ readonly locale: "en" | "ja" | "ko";
42
+ readonly message: string;
43
+ }[]], Schema.TupleType<readonly [Schema.Struct<{
44
+ locale: Schema.Literal<["zh"]>;
45
+ message: Schema.SchemaClass<string, string, never>;
46
+ }>], [Schema.Struct<{
47
+ locale: Schema.Literal<["ja", "en", "ko"]>;
48
+ message: Schema.SchemaClass<string, string, never>;
49
+ }>]>>, {
50
+ default: () => readonly [{
51
+ readonly locale: "zh";
52
+ readonly message: "";
53
+ }];
54
+ }>;
55
+ onChange: Schema.optional<Schema.Schema<string, string, never>>;
56
+ successMessage: Schema.optional<Schema.Schema<string, string, never>>;
57
+ triggers: Schema.optional<Schema.Array$<Schema.Struct<{
58
+ target: Schema.refine<string, typeof Schema.String>;
59
+ operation: Schema.SchemaClass<string, string, never>;
60
+ }>>>;
61
+ title: Schema.TupleType<readonly [Schema.Struct<{
62
+ locale: Schema.Literal<["zh"]>;
63
+ message: Schema.SchemaClass<string, string, never>;
64
+ }>], [Schema.Struct<{
65
+ locale: Schema.Literal<["ja", "en", "ko"]>;
66
+ message: Schema.SchemaClass<string, string, never>;
67
+ }>]>;
68
+ accessor: Schema.Schema<string, string, never>;
69
+ enableSorting: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
70
+ size: Schema.optional<Schema.refine<number, Schema.filter<typeof Schema.Number>>>;
71
+ grow: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
72
+ tooltip: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{
73
+ locale: Schema.Literal<["zh"]>;
74
+ message: Schema.SchemaClass<string, string, never>;
75
+ }>], [Schema.Struct<{
76
+ locale: Schema.Literal<["ja", "en", "ko"]>;
77
+ message: Schema.SchemaClass<string, string, never>;
78
+ }>]>>;
79
+ id: Schema.refine<string, typeof Schema.String>;
80
+ groupId: Schema.optional<typeof Schema.UUID>;
81
+ type: Schema.Literal<["com.shwfed.table.column.combobox-multi.remote.options-remote"]>;
82
+ compatibilityDate: Schema.Literal<["2026-05-25"]>;
83
+ }>;
84
+ export type Value = Schema.Schema.Type<ReturnType<typeof schema>>;
85
+ export declare function toColumnDef(value: Value, { getLocaleText, $cel, inheritedContext }: ColumnDefDeps): Partial<ColumnDef<unknown, unknown>>;
@@ -0,0 +1,147 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { Expression, LocaleMarkdown } from "../../../../../share/expression.js";
3
+ import { Locale } from "../../../../../share/locale.js";
4
+ import { Triggers } from "../../../../../share/event-bus.js";
5
+ import {
6
+ CelRowAccess,
7
+ columnFields,
8
+ editableHeader,
9
+ registerRowVariablesIfAbsent
10
+ } from "../../../utils/shared.js";
11
+ export const type = "com.shwfed.table.column.combobox-multi.remote.options-remote";
12
+ export const compatibilityDate = "2026-05-25";
13
+ export const metadata = {
14
+ name: "\u8FDC\u7A0B\u4E0B\u62C9\u591A\u9009",
15
+ icon: "fluent:cloud-arrow-down-20-regular"
16
+ };
17
+ export const OPTION_VAR = {
18
+ type: "dyn",
19
+ label: "\u5F53\u524D\u9009\u9879",
20
+ description: "`\u9009\u9879` \u8868\u8FBE\u5F0F\u4EA7\u51FA\u7684\u6570\u7EC4\u4E2D\u8FED\u4EE3\u5230\u7684\u5355\u4E2A\u5143\u7D20"
21
+ };
22
+ export const JSON_VAR = {
23
+ type: "dyn",
24
+ label: "HTTP \u54CD\u5E94\u4F53",
25
+ description: "HTTP \u54CD\u5E94\u4F53\uFF08\u5DF2\u89E3\u6790 JSON\uFF09\uFF1B\u8BF7\u6C42\u5931\u8D25\u6216\u5C1A\u672A\u5B8C\u6210\u65F6\u4E3A `null`"
26
+ };
27
+ const isListType = (actual) => actual === "dyn" || actual.startsWith("list");
28
+ export function schema(configure) {
29
+ const CelBool = CelRowAccess(configure, { resultType: "bool" });
30
+ const CelRequest = Expression({
31
+ configure: (env) => {
32
+ configure(env);
33
+ registerRowVariablesIfAbsent(env);
34
+ },
35
+ resultType: "HttpRequest"
36
+ });
37
+ const CelOptions = Expression({
38
+ configure: (env) => {
39
+ configure(env);
40
+ registerRowVariablesIfAbsent(env);
41
+ env.registerVariable("json", JSON_VAR.type, { description: JSON_VAR.description });
42
+ },
43
+ resultType: isListType
44
+ });
45
+ const CelOptionValue = Expression({
46
+ configure: (env) => {
47
+ configure(env);
48
+ registerRowVariablesIfAbsent(env);
49
+ env.registerVariable("option", OPTION_VAR.type, { description: OPTION_VAR.description });
50
+ },
51
+ resultType: "dyn"
52
+ });
53
+ const LocaleOptionLabel = LocaleMarkdown({
54
+ configure: (env) => {
55
+ configure(env);
56
+ registerRowVariablesIfAbsent(env);
57
+ env.registerVariable("option", OPTION_VAR.type, { description: OPTION_VAR.description });
58
+ }
59
+ });
60
+ const CelOnChange = Expression({
61
+ configure: (env) => {
62
+ configure(env);
63
+ registerRowVariablesIfAbsent(env);
64
+ env.registerVariable("value", "dyn", { description: "\u7528\u6237\u5F53\u524D\u9009\u4E2D\u9879 `value` \u7EC4\u6210\u7684\u6570\u7EC4\uFF1B\u6E05\u7A7A\u65F6\u4E3A\u7A7A\u6570\u7EC4 `[]`" });
65
+ },
66
+ resultType: "HttpRequest"
67
+ });
68
+ const CelMessage = Expression({
69
+ configure: (env) => {
70
+ configure(env);
71
+ env.registerVariable("json", "dyn", { description: "HTTP \u54CD\u5E94\u4F53\uFF08\u5DF2\u89E3\u6790 JSON\uFF09" });
72
+ },
73
+ resultType: "string"
74
+ });
75
+ return Schema.Struct({
76
+ type: Schema.Literal(type),
77
+ compatibilityDate: Schema.Literal(compatibilityDate),
78
+ ...columnFields(configure),
79
+ placeholder: Schema.optional(Locale.annotations({
80
+ title: "\u5360\u4F4D\u7B26",
81
+ description: "\u672A\u9009\u4E2D\u4EFB\u4F55\u9009\u9879\u65F6\u8F93\u5165\u6846\u4E2D\u7684\u5360\u4F4D\u6587\u672C"
82
+ })),
83
+ hidden: Schema.optional(CelBool.annotations({
84
+ title: "\u9690\u85CF\u6761\u4EF6",
85
+ description: "\u8FD4\u56DE `true` \u65F6\u8BE5\u884C\u7684\u4E0B\u62C9\u6846\u4E0D\u6E32\u67D3\uFF08\u5176\u4F59\u884C\u4E0D\u53D7\u5F71\u54CD\uFF09"
86
+ })),
87
+ disabled: Schema.optional(CelBool.annotations({
88
+ title: "\u7981\u7528\u6761\u4EF6",
89
+ description: "\u8FD4\u56DE `true` \u65F6\u4E0B\u62C9\u6846\u4ECD\u7136\u6E32\u67D3\u4F46\u4E0D\u53EF\u9009\u62E9"
90
+ })),
91
+ readonly: Schema.optional(CelBool.annotations({
92
+ title: "\u53EA\u8BFB\u6761\u4EF6",
93
+ description: "\u8FD4\u56DE `true` \u65F6\u4EC5\u4EE5\u7EAF\u6587\u672C\u5C55\u793A\u5F53\u524D\u5DF2\u9009\u9879\u7684\u6807\u7B7E"
94
+ })),
95
+ request: CelRequest.annotations({
96
+ title: "\u8BF7\u6C42",
97
+ description: "\u8FD4\u56DE `HttpRequest` \u7684 CEL \u8868\u8FBE\u5F0F\uFF1B\u53EF\u8BBF\u95EE `row` \u4E0E `index`\u3002\u76F8\u540C\u7B7E\u540D\u7684\u8BF7\u6C42\u4F1A\u5728\u8BE5\u8868\u683C\u5185\u81EA\u52A8\u53BB\u91CD"
98
+ }),
99
+ options: CelOptions.annotations({
100
+ title: "\u9009\u9879",
101
+ description: "\u4ECE HTTP \u54CD\u5E94\u4F53\u63D0\u53D6\u9009\u9879\u6570\u7EC4\u7684 CEL \u8868\u8FBE\u5F0F\uFF1B\u53EF\u8BBF\u95EE `row`\u3001`index` \u4E0E `json`\u3002\u4F8B\uFF1A`json.data`"
102
+ }),
103
+ optionValue: Schema.optionalWith(CelOptionValue.annotations({
104
+ title: "\u9009\u9879\u503C",
105
+ description: "\u4ECE\u5F53\u524D `option` \u63D0\u53D6\u5199\u5165\u503C\u7684 CEL\uFF1B\u4F8B\uFF1A`option.value`"
106
+ }), { default: () => "option" }),
107
+ optionLabel: Schema.optionalWith(LocaleOptionLabel.annotations({
108
+ title: "\u9009\u9879\u6807\u7B7E",
109
+ description: "\u6BCF\u4E2A\u9009\u9879\u5C55\u793A\u7684\u672C\u5730\u5316\u6587\u672C\uFF0C\u652F\u6301 `{{ string(option.foo) }}` \u63D2\u503C"
110
+ }), { default: () => [{ locale: "zh", message: "" }] }),
111
+ onChange: Schema.optional(CelOnChange.annotations({
112
+ title: "\u5207\u6362\u8BF7\u6C42",
113
+ description: "\u7528\u6237\u9009\u62E9\u540E\u7ACB\u5373\u6C42\u503C\u5E76\u53D1\u8D77\u7684 HTTP \u8BF7\u6C42\uFF1B`value` \u4E3A\u65B0\u6570\u7EC4\u3002\u672A\u914D\u7F6E\u65F6\u4E0B\u62C9\u6846\u53EA\u8BFB"
114
+ })),
115
+ successMessage: Schema.optional(CelMessage.annotations({
116
+ title: "\u6210\u529F\u6D88\u606F",
117
+ description: "\u8BF7\u6C42\u6210\u529F\u540E\u5F39\u51FA\u7684 toast \u5185\u5BB9\uFF1B\u672A\u914D\u7F6E\u5219\u9759\u9ED8"
118
+ })),
119
+ triggers: Schema.optional(Triggers.annotations({
120
+ title: "\u6210\u529F\u540E\u89E6\u53D1",
121
+ 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"
122
+ }))
123
+ }).annotations({
124
+ title: "ComboboxMultiRemoteOptionsRemoteRenderer",
125
+ description: "\u4E0B\u62C9\u591A\u9009\u6E32\u67D3\u5668\uFF08\u8FDC\u7A0B\u5199\u5165\xB7\u8FDC\u7A0B\u9009\u9879\uFF09"
126
+ });
127
+ }
128
+ export function toColumnDef(value, { getLocaleText, $cel, inheritedContext }) {
129
+ return {
130
+ header: editableHeader(getLocaleText(value.title)),
131
+ accessorFn: (row, index) => {
132
+ try {
133
+ return Effect.runSync($cel(value.accessor, { ...inheritedContext, row, index }));
134
+ } catch (e) {
135
+ console.error("[shwfed-table] combobox-multi.remote.options-remote accessor failed", e);
136
+ return void 0;
137
+ }
138
+ },
139
+ enableSorting: value.enableSorting ?? false,
140
+ sortingFn: "basic",
141
+ size: value.size,
142
+ meta: {
143
+ grow: value.grow ?? false,
144
+ tooltip: getLocaleText(value.tooltip)
145
+ }
146
+ };
147
+ }