@shwfed/config 2.10.7 → 2.10.9
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 +1171 -1049
- package/dist/module.json +1 -1
- package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-CV3u1wuG.js → FieldGroup.vue_vue_type_script_setup_true_lang-CysVgnB5.js} +1 -1
- package/dist/preview/assets/{badge-De7TI8Ef.js → badge-DdxT1J-1.js} +1 -1
- package/dist/preview/assets/{config-A0pwpJhu.js → config-073z__NM.js} +1 -1
- package/dist/preview/assets/{config-Cc-RiKc0.js → config-91HQEKhM.js} +1 -1
- package/dist/preview/assets/{config-DccYHX13.js → config-B8k8y1J1.js} +1 -1
- package/dist/preview/assets/{config-Ckn8NixF.js → config-BK8WZ3pm.js} +1 -1
- package/dist/preview/assets/{config-RuqJAgHJ.js → config-BX05eMo3.js} +1 -1
- package/dist/preview/assets/{config-BF4I0Pko.js → config-BXP8aJwW.js} +1 -1
- package/dist/preview/assets/{config-DqHlKqr-.js → config-BhPAyftm.js} +1 -1
- package/dist/preview/assets/{config-DBrYVSus.js → config-BzHBSkht.js} +1 -1
- package/dist/preview/assets/{config-BJL5R6TO.js → config-C3eoRHUo.js} +1 -1
- package/dist/preview/assets/{config-DGj2Xh1R.js → config-CJ-NzxkH.js} +1 -1
- package/dist/preview/assets/{config-C6AzmvwL.js → config-CYRj2ZVL.js} +1 -1
- package/dist/preview/assets/{config-CtW_DgDv.js → config-DLNjjMZY.js} +1 -1
- package/dist/preview/assets/{config-Bei-4M8U.js → config-DudxzmzF.js} +1 -1
- package/dist/preview/assets/{config-CnPPWHxs.js → config-cwlK3BMD.js} +1 -1
- package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-Ceh2rttd.js → definition.vue_vue_type_script_setup_true_lang-l59C6Dgs.js} +1 -1
- package/dist/preview/assets/index-BL58N7_5.js +763 -0
- package/dist/preview/assets/index-CA4hsfRv.js +1 -0
- package/dist/preview/assets/index-CyVzfRGQ.css +1 -0
- package/dist/preview/assets/{index-DAjdcrqQ.js → index-uAwC9Itb.js} +1 -1
- package/dist/preview/assets/{item-BNOUeB-e.js → item-C79mwh5T.js} +1 -1
- package/dist/preview/assets/{runtime-DzDI7B5M.js → runtime-1_EaFcPI.js} +1 -1
- package/dist/preview/assets/{runtime-BtDC6qh0.js → runtime-2yzxOLnF.js} +1 -1
- package/dist/preview/assets/{runtime-CXSBPV7c.js → runtime-8Fe67mkZ.js} +1 -1
- package/dist/preview/assets/{runtime-B-m0fZl0.js → runtime-8oME8Env.js} +1 -1
- package/dist/preview/assets/{runtime-DDz8U0kg.js → runtime-CCMixJjP.js} +1 -1
- package/dist/preview/assets/{runtime-CdrOV1KF.js → runtime-CD1Q4rZ3.js} +1 -1
- package/dist/preview/assets/{runtime-DCyGTrMp.js → runtime-Cb-qIo5p.js} +1 -1
- package/dist/preview/assets/{runtime-Bb0APo4d.js → runtime-CvgAq3mp.js} +1 -1
- package/dist/preview/assets/{runtime-D2Qtb13C.js → runtime-DkWCpjKe.js} +1 -1
- package/dist/preview/assets/{runtime-CtG2gR_k.js → runtime-mYNyG7UH.js} +1 -1
- package/dist/preview/assets/{schema-meta-DmDYh6aL.js → schema-meta-BlTKRs15.js} +1 -1
- package/dist/preview/index.html +2 -2
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.d.vue.ts +4 -4
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.vue.d.ts +4 -4
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.d.vue.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.vue.d.ts +6 -6
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.d.vue.ts +2 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.vue +32 -1
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.vue.d.ts +2 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/runtime.vue +2 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.d.ts +2 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.js +4 -0
- package/dist/runtime/components/form/fields/2026-05-17/com.shwfed.form.field.checkbox.group/config.vue +202 -112
- package/dist/runtime/components/form/fields/2026-05-17/com.shwfed.form.field.radio.group/config.vue +202 -112
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.d.vue.ts +4 -4
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.vue.d.ts +4 -4
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/config.vue +223 -132
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/config.vue +223 -132
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/config.d.vue.ts +59 -0
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/config.vue +345 -0
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/config.vue.d.ts +59 -0
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/runtime.d.vue.ts +8 -0
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/runtime.vue +113 -0
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/runtime.vue.d.ts +8 -0
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/schema.d.ts +79 -0
- package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/schema.js +86 -0
- package/dist/runtime/components/form/unit-config.d.vue.ts +27 -0
- package/dist/runtime/components/form/unit-config.vue +117 -73
- package/dist/runtime/components/form/unit-config.vue.d.ts +27 -0
- package/dist/runtime/components/table/schema.js +24 -25
- package/dist/runtime/components/ui/date-picker/DatePickerInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.d.vue.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.vue.d.ts +1 -1
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.d.vue.ts +2 -2
- package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.vue.d.ts +2 -2
- package/dist/runtime/components/ui/markdown/Markdown.vue +19 -16
- package/dist/runtime/utils/markdown.d.ts +5 -2
- package/dist/runtime/utils/markdown.js +22 -1
- package/dist/runtime/vendor/cel-js/CLAUDE.md +1 -0
- package/dist/runtime/vendor/cel-js/lib/evaluator.d.ts +1 -0
- package/dist/runtime/vendor/cel-js/lib/evaluator.js +4 -0
- package/package.json +1 -1
- package/dist/preview/assets/index-BQIP6UfB.js +0 -763
- package/dist/preview/assets/index-Cj7bRG7B.css +0 -1
- package/dist/preview/assets/index-DpLMRp28.js +0 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { Locale } from "../../../../../share/locale.js";
|
|
3
|
+
import { FormUnit } from "../../../schema.js";
|
|
4
|
+
export const type = "com.shwfed.form.field.tabs";
|
|
5
|
+
export const compatibilityDate = "2026-06-20";
|
|
6
|
+
export const metadata = {
|
|
7
|
+
name: "\u6807\u7B7E\u9875",
|
|
8
|
+
icon: "fluent:tabs-20-regular",
|
|
9
|
+
w: { initial: 12, min: 4, max: Infinity },
|
|
10
|
+
h: { initial: 6, min: 2, max: Infinity, grow: true },
|
|
11
|
+
// Hosts a nested sub-form per tab (each tab's own fields + layout) — too
|
|
12
|
+
// complex for the fullscreen inline-config pane; keep the drill-down.
|
|
13
|
+
inlineConfig: false
|
|
14
|
+
};
|
|
15
|
+
export const TabMeta = Schema.Struct({
|
|
16
|
+
label: Locale.annotations({
|
|
17
|
+
title: "\u6807\u7B7E\u540D",
|
|
18
|
+
description: "\u8BE5\u6807\u7B7E\u9875\u7684\u672C\u5730\u5316\u663E\u793A\u540D"
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
export function schema(configure) {
|
|
22
|
+
const Unit = Schema.suspend(() => FormUnit(configure));
|
|
23
|
+
const Tab = Schema.Struct({
|
|
24
|
+
id: Schema.UUID.annotations({ description: "\u6807\u7B7E\u9875\u552F\u4E00\u6807\u8BC6" }),
|
|
25
|
+
...TabMeta.fields,
|
|
26
|
+
unit: Unit.annotations({
|
|
27
|
+
identifier: "FormFieldTabsUnit",
|
|
28
|
+
title: "\u6807\u7B7E\u5185\u5BB9",
|
|
29
|
+
description: "\u8BE5\u6807\u7B7E\u5185\u7684\u5B57\u6BB5\u4E0E\u5E03\u5C40\uFF1B\u8FD9\u4E9B\u5B57\u6BB5\u5728\u8868\u5355\u72B6\u6001\u4E2D\u4FDD\u6301\u6241\u5E73\uFF0C\u4E0D\u4F1A\u56E0\u4E3A\u5206\u7EC4\u800C\u5F15\u5165\u65B0\u7684\u72B6\u6001\u5C42\u7EA7"
|
|
30
|
+
})
|
|
31
|
+
}).annotations({
|
|
32
|
+
title: "Tab",
|
|
33
|
+
description: "\u5355\u4E2A\u6807\u7B7E\u9875\uFF1A\u540D\u79F0 + \u5185\u5BB9 Unit"
|
|
34
|
+
});
|
|
35
|
+
return Schema.Struct({
|
|
36
|
+
type: Schema.Literal(type),
|
|
37
|
+
compatibilityDate: Schema.Literal(compatibilityDate),
|
|
38
|
+
id: Schema.UUID.annotations({ description: "\u5B57\u6BB5\u552F\u4E00\u6807\u8BC6\uFF1B\u5E03\u5C40\u901A\u8FC7\u8BE5 id \u5F15\u7528\u5B57\u6BB5" }),
|
|
39
|
+
displayName: Schema.optional(Schema.String.annotations({
|
|
40
|
+
title: "\u5185\u90E8\u540D\u79F0",
|
|
41
|
+
description: "\u4EC5\u5728\u7F16\u8F91\u5668\u5185\u53EF\u89C1\u7684\u533A\u57DF\u540D\uFF0C\u7528\u4E8E\u5728\u4FA7\u8FB9\u680F\u548C\u5E03\u5C40\u7F16\u8F91\u5668\u4E2D\u8BC6\u522B\u8BE5\u6807\u7B7E\u9875\uFF1B\u8FD0\u884C\u65F6\u4E0D\u5C55\u793A"
|
|
42
|
+
})),
|
|
43
|
+
style: Schema.optional(Schema.String.annotations({
|
|
44
|
+
title: "\u5BB9\u5668\u6837\u5F0F",
|
|
45
|
+
description: "\u5E94\u7528\u5728\u6807\u7B7E\u9875\u6700\u5916\u5C42\u5BB9\u5668\u4E0A\u7684 CSS \u6837\u5F0F\u5B57\u7B26\u4E32"
|
|
46
|
+
})),
|
|
47
|
+
tabs: Schema.Array(Tab).pipe(
|
|
48
|
+
Schema.minItems(1),
|
|
49
|
+
Schema.filter((tabs) => {
|
|
50
|
+
const ids = /* @__PURE__ */ new Set();
|
|
51
|
+
for (const t of tabs) {
|
|
52
|
+
if (ids.has(t.id)) return `\u6807\u7B7E\u9875 id \u91CD\u590D: ${t.id}`;
|
|
53
|
+
ids.add(t.id);
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
})
|
|
57
|
+
).annotations({
|
|
58
|
+
title: "\u6807\u7B7E\u9875",
|
|
59
|
+
description: "\u81F3\u5C11 1 \u9879\uFF0C\u6309\u987A\u5E8F\u6E32\u67D3"
|
|
60
|
+
})
|
|
61
|
+
}).annotations({
|
|
62
|
+
title: "TabsField",
|
|
63
|
+
description: "\u5C06\u4E00\u7EC4\u5E26\u6807\u7B7E\u7684\u5B50\u8868\u5355\u5355\u5143\u4F5C\u4E3A\u6807\u7B7E\u9875\u5206\u7EC4\uFF1B\u4EC5\u7528\u4E8E\u89C6\u89C9\u5206\u7EC4\uFF0C\u4E0D\u5F71\u54CD\u5B57\u6BB5\u5728\u8868\u5355\u72B6\u6001\u4E2D\u7684\u5C42\u7EA7"
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function makeId() {
|
|
67
|
+
if (typeof crypto !== "undefined" && "randomUUID" in crypto) return crypto.randomUUID();
|
|
68
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
69
|
+
const r = Math.random() * 16 | 0;
|
|
70
|
+
return (c === "x" ? r : r & 3 | 8).toString(16);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
export function defaults() {
|
|
74
|
+
return {
|
|
75
|
+
tabs: [
|
|
76
|
+
{
|
|
77
|
+
id: makeId(),
|
|
78
|
+
label: [{ locale: "zh", message: "\u6807\u7B7E 1" }],
|
|
79
|
+
unit: {
|
|
80
|
+
fields: [],
|
|
81
|
+
layouts: [{ name: "\u9ED8\u8BA4", layout: { columns: 1, placements: {} } }]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -33,12 +33,39 @@ type __VLS_Props = {
|
|
|
33
33
|
* host component, above this provide.
|
|
34
34
|
*/
|
|
35
35
|
fieldCelScope?: CELContext;
|
|
36
|
+
/**
|
|
37
|
+
* Identity of the unit currently bound to `v-model`. When a host swaps the
|
|
38
|
+
* bound unit *in place* (e.g. the tabs field switching the active tab's
|
|
39
|
+
* unit) the editor's drill stack / active-layout index belong to the old
|
|
40
|
+
* unit and would point at fields/layouts that don't exist in the new one.
|
|
41
|
+
* Changing `scopeKey` resets that transient view state without forcing a
|
|
42
|
+
* remount (which would flicker host-injected rail content). Hosts that own
|
|
43
|
+
* a single stable unit (collapsible, list, form root) leave it undefined.
|
|
44
|
+
*/
|
|
45
|
+
scopeKey?: string;
|
|
36
46
|
};
|
|
37
47
|
type __VLS_Slots = {
|
|
38
48
|
/** Pane content for the currently-selected extra. Receives `{ id }`. */
|
|
39
49
|
'extras-pane'(props: {
|
|
40
50
|
id: string;
|
|
41
51
|
}): unknown;
|
|
52
|
+
/**
|
|
53
|
+
* Extra rail content rendered as its own half-height list above the layouts
|
|
54
|
+
* list (top-level view only — hidden while drilled into a field). The tabs
|
|
55
|
+
* field injects its tab list here so the rail reads as two parallel lists.
|
|
56
|
+
*/
|
|
57
|
+
'rail-extra'(): unknown;
|
|
58
|
+
/**
|
|
59
|
+
* Foot button for the `rail-extra` list, pinned below its scroll area (the
|
|
60
|
+
* tabs field's “新增标签页”). Mirrors the layouts list's “新增布局”.
|
|
61
|
+
*/
|
|
62
|
+
'rail-extra-foot'(): unknown;
|
|
63
|
+
/**
|
|
64
|
+
* Content rendered above the layout canvas in the 布局 view. The tabs field
|
|
65
|
+
* injects the active tab's label editor here, mirroring the block-tabs
|
|
66
|
+
* config's pane header.
|
|
67
|
+
*/
|
|
68
|
+
'pane-header'(): unknown;
|
|
42
69
|
};
|
|
43
70
|
type __VLS_ModelProps = {
|
|
44
71
|
modelValue: FormUnitValue;
|
|
@@ -31,13 +31,18 @@ const selection = defineModel("selection", { type: Object, ...{
|
|
|
31
31
|
const props = defineProps({
|
|
32
32
|
extras: { type: Array, required: false },
|
|
33
33
|
configure: { type: Function, required: false },
|
|
34
|
-
fieldCelScope: { type: Object, required: false }
|
|
34
|
+
fieldCelScope: { type: Object, required: false },
|
|
35
|
+
scopeKey: { type: String, required: false }
|
|
35
36
|
});
|
|
36
37
|
defineSlots();
|
|
37
38
|
const activeLayoutIndex = ref(0);
|
|
38
39
|
const stack = ref([{ kind: "top" }]);
|
|
39
40
|
const top = computed(() => stack.value[stack.value.length - 1]);
|
|
40
41
|
const isDrilled = computed(() => stack.value.length > 1);
|
|
42
|
+
watch(() => props.scopeKey, () => {
|
|
43
|
+
if (stack.value.length > 1) stack.value = [{ kind: "top" }];
|
|
44
|
+
activeLayoutIndex.value = 0;
|
|
45
|
+
});
|
|
41
46
|
function popOne() {
|
|
42
47
|
if (stack.value.length <= 1) return;
|
|
43
48
|
stack.value = stack.value.slice(0, -1);
|
|
@@ -313,47 +318,66 @@ function isExtraActive(id) {
|
|
|
313
318
|
:to="takeoverTarget"
|
|
314
319
|
>
|
|
315
320
|
<template v-if="!isDrilled">
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
321
|
+
<!-- Extras rows pinned at the top of the rail. -->
|
|
322
|
+
<template v-if="extras && extras.length > 0">
|
|
323
|
+
<div
|
|
324
|
+
v-for="extra in extras"
|
|
325
|
+
:key="extra.id"
|
|
326
|
+
class="row general-row pl-2"
|
|
327
|
+
:class="[
|
|
323
328
|
isExtraActive(extra.id) ? 'bg-[color-mix(in_srgb,var(--primary)_10%,white)] text-(--primary)' : 'text-zinc-600 hover:bg-zinc-50'
|
|
324
329
|
]"
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
330
|
+
@click.stop="selectExtra(extra.id)"
|
|
331
|
+
>
|
|
332
|
+
<Icon
|
|
333
|
+
:icon="extra.icon"
|
|
334
|
+
class="size-4 shrink-0"
|
|
335
|
+
/>
|
|
336
|
+
<span class="flex-1 truncate">{{ extra.label }}</span>
|
|
337
|
+
</div>
|
|
333
338
|
|
|
334
|
-
|
|
335
|
-
|
|
339
|
+
<Separator class="my-1" />
|
|
340
|
+
</template>
|
|
336
341
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
342
|
+
<!-- Host-injected rail list (e.g. the tabs field's tab list): its own
|
|
343
|
+
half-height scroll + foot button, so the rail reads as two parallel
|
|
344
|
+
lists rather than one long one. -->
|
|
345
|
+
<template v-if="$slots['rail-extra']">
|
|
346
|
+
<div class="flex flex-1 min-h-0 flex-col">
|
|
347
|
+
<ScrollArea class="flex-1">
|
|
348
|
+
<slot name="rail-extra" />
|
|
349
|
+
</ScrollArea>
|
|
350
|
+
<slot name="rail-extra-foot" />
|
|
351
|
+
</div>
|
|
345
352
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
>
|
|
351
|
-
<
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
353
|
+
<Separator class="my-1" />
|
|
354
|
+
</template>
|
|
355
|
+
|
|
356
|
+
<!-- Layouts list — its own half-height scroll + add button. -->
|
|
357
|
+
<div class="flex flex-1 min-h-0 flex-col">
|
|
358
|
+
<ScrollArea class="flex-1">
|
|
359
|
+
<LayoutsSidebar
|
|
360
|
+
ref="sidebarRef"
|
|
361
|
+
v-model="layoutsModel"
|
|
362
|
+
v-model:active-index="activeLayoutIndex"
|
|
363
|
+
:active="selection.kind === 'layout'"
|
|
364
|
+
@select="selectLayout()"
|
|
365
|
+
/>
|
|
366
|
+
</ScrollArea>
|
|
367
|
+
|
|
368
|
+
<Button
|
|
369
|
+
variant="ghost"
|
|
370
|
+
size="sm"
|
|
371
|
+
class="w-full justify-start"
|
|
372
|
+
@click="addLayout()"
|
|
373
|
+
>
|
|
374
|
+
<Icon
|
|
375
|
+
icon="fluent:add-20-regular"
|
|
376
|
+
class="size-4"
|
|
377
|
+
/>
|
|
378
|
+
<span>新增布局</span>
|
|
379
|
+
</Button>
|
|
380
|
+
</div>
|
|
357
381
|
</template>
|
|
358
382
|
<template v-else>
|
|
359
383
|
<ScrollArea class="flex-1">
|
|
@@ -390,47 +414,66 @@ function isExtraActive(id) {
|
|
|
390
414
|
class="flex w-64 shrink-0 flex-col"
|
|
391
415
|
>
|
|
392
416
|
<template v-if="!isDrilled">
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
417
|
+
<!-- Extras rows pinned at the top of the rail. -->
|
|
418
|
+
<template v-if="extras && extras.length > 0">
|
|
419
|
+
<div
|
|
420
|
+
v-for="extra in extras"
|
|
421
|
+
:key="extra.id"
|
|
422
|
+
class="row general-row pl-2"
|
|
423
|
+
:class="[
|
|
400
424
|
isExtraActive(extra.id) ? 'bg-[color-mix(in_srgb,var(--primary)_10%,white)] text-(--primary)' : 'text-zinc-600 hover:bg-zinc-50'
|
|
401
425
|
]"
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
426
|
+
@click.stop="selectExtra(extra.id)"
|
|
427
|
+
>
|
|
428
|
+
<Icon
|
|
429
|
+
:icon="extra.icon"
|
|
430
|
+
class="size-4 shrink-0"
|
|
431
|
+
/>
|
|
432
|
+
<span class="flex-1 truncate">{{ extra.label }}</span>
|
|
433
|
+
</div>
|
|
410
434
|
|
|
411
|
-
|
|
412
|
-
|
|
435
|
+
<Separator class="my-1" />
|
|
436
|
+
</template>
|
|
413
437
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
438
|
+
<!-- Host-injected rail list (e.g. the tabs field's tab list): its own
|
|
439
|
+
half-height scroll + foot button, so the rail reads as two
|
|
440
|
+
parallel lists rather than one long one. -->
|
|
441
|
+
<template v-if="$slots['rail-extra']">
|
|
442
|
+
<div class="flex flex-1 min-h-0 flex-col">
|
|
443
|
+
<ScrollArea class="flex-1">
|
|
444
|
+
<slot name="rail-extra" />
|
|
445
|
+
</ScrollArea>
|
|
446
|
+
<slot name="rail-extra-foot" />
|
|
447
|
+
</div>
|
|
422
448
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
>
|
|
428
|
-
<
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
449
|
+
<Separator class="my-1" />
|
|
450
|
+
</template>
|
|
451
|
+
|
|
452
|
+
<!-- Layouts list — its own half-height scroll + add button. -->
|
|
453
|
+
<div class="flex flex-1 min-h-0 flex-col">
|
|
454
|
+
<ScrollArea class="flex-1">
|
|
455
|
+
<LayoutsSidebar
|
|
456
|
+
ref="sidebarRef"
|
|
457
|
+
v-model="layoutsModel"
|
|
458
|
+
v-model:active-index="activeLayoutIndex"
|
|
459
|
+
:active="selection.kind === 'layout'"
|
|
460
|
+
@select="selectLayout()"
|
|
461
|
+
/>
|
|
462
|
+
</ScrollArea>
|
|
463
|
+
|
|
464
|
+
<Button
|
|
465
|
+
variant="ghost"
|
|
466
|
+
size="sm"
|
|
467
|
+
class="w-full justify-start"
|
|
468
|
+
@click="addLayout()"
|
|
469
|
+
>
|
|
470
|
+
<Icon
|
|
471
|
+
icon="fluent:add-20-regular"
|
|
472
|
+
class="size-4"
|
|
473
|
+
/>
|
|
474
|
+
<span>新增布局</span>
|
|
475
|
+
</Button>
|
|
476
|
+
</div>
|
|
434
477
|
</template>
|
|
435
478
|
<template v-else>
|
|
436
479
|
<ScrollArea class="flex-1">
|
|
@@ -473,6 +516,7 @@ function isExtraActive(id) {
|
|
|
473
516
|
v-else-if="!isDrilled && selection.kind === 'layout'"
|
|
474
517
|
class="flex flex-1 flex-col gap-2"
|
|
475
518
|
>
|
|
519
|
+
<slot name="pane-header" />
|
|
476
520
|
<LayoutMetaStrip
|
|
477
521
|
v-model="layoutsModel"
|
|
478
522
|
:index="activeLayoutIndex"
|
|
@@ -33,12 +33,39 @@ type __VLS_Props = {
|
|
|
33
33
|
* host component, above this provide.
|
|
34
34
|
*/
|
|
35
35
|
fieldCelScope?: CELContext;
|
|
36
|
+
/**
|
|
37
|
+
* Identity of the unit currently bound to `v-model`. When a host swaps the
|
|
38
|
+
* bound unit *in place* (e.g. the tabs field switching the active tab's
|
|
39
|
+
* unit) the editor's drill stack / active-layout index belong to the old
|
|
40
|
+
* unit and would point at fields/layouts that don't exist in the new one.
|
|
41
|
+
* Changing `scopeKey` resets that transient view state without forcing a
|
|
42
|
+
* remount (which would flicker host-injected rail content). Hosts that own
|
|
43
|
+
* a single stable unit (collapsible, list, form root) leave it undefined.
|
|
44
|
+
*/
|
|
45
|
+
scopeKey?: string;
|
|
36
46
|
};
|
|
37
47
|
type __VLS_Slots = {
|
|
38
48
|
/** Pane content for the currently-selected extra. Receives `{ id }`. */
|
|
39
49
|
'extras-pane'(props: {
|
|
40
50
|
id: string;
|
|
41
51
|
}): unknown;
|
|
52
|
+
/**
|
|
53
|
+
* Extra rail content rendered as its own half-height list above the layouts
|
|
54
|
+
* list (top-level view only — hidden while drilled into a field). The tabs
|
|
55
|
+
* field injects its tab list here so the rail reads as two parallel lists.
|
|
56
|
+
*/
|
|
57
|
+
'rail-extra'(): unknown;
|
|
58
|
+
/**
|
|
59
|
+
* Foot button for the `rail-extra` list, pinned below its scroll area (the
|
|
60
|
+
* tabs field's “新增标签页”). Mirrors the layouts list's “新增布局”.
|
|
61
|
+
*/
|
|
62
|
+
'rail-extra-foot'(): unknown;
|
|
63
|
+
/**
|
|
64
|
+
* Content rendered above the layout canvas in the 布局 view. The tabs field
|
|
65
|
+
* injects the active tab's label editor here, mirroring the block-tabs
|
|
66
|
+
* config's pane header.
|
|
67
|
+
*/
|
|
68
|
+
'pane-header'(): unknown;
|
|
42
69
|
};
|
|
43
70
|
type __VLS_ModelProps = {
|
|
44
71
|
modelValue: FormUnitValue;
|
|
@@ -137,52 +137,49 @@ const SORTS_VAR_DESCRIPTION = md`
|
|
|
137
137
|
|
|
138
138
|
未排序的字段,**不会出现在这个列表中**。
|
|
139
139
|
`;
|
|
140
|
+
function registerVariableIfAbsent(env, name, type, opts) {
|
|
141
|
+
const declared = env.getDefinitions().variables.some((v) => v.name === name);
|
|
142
|
+
if (!declared) env.registerVariable(name, type, opts);
|
|
143
|
+
}
|
|
140
144
|
export function configureTableActionsScope(env, configure) {
|
|
141
145
|
configure(env);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
if (!declared.has("sorts")) {
|
|
156
|
-
env.registerVariable("sorts", "list<map<string, string>>", {
|
|
157
|
-
label: "\u6392\u5E8F\u72B6\u6001",
|
|
158
|
-
description: SORTS_VAR_DESCRIPTION
|
|
159
|
-
});
|
|
160
|
-
}
|
|
146
|
+
registerVariableIfAbsent(env, "selected", "list<dyn>", {
|
|
147
|
+
label: "\u5DF2\u9009\u884C",
|
|
148
|
+
description: "\u5F53\u524D\u5DF2\u52FE\u9009\u7684\u6240\u6709\u884C\uFF08`row` \u7684\u6570\u7EC4\uFF09"
|
|
149
|
+
});
|
|
150
|
+
registerVariableIfAbsent(env, "query", "dyn", {
|
|
151
|
+
label: "\u641C\u7D22\u6761\u4EF6",
|
|
152
|
+
description: QUERY_VAR_DESCRIPTION
|
|
153
|
+
});
|
|
154
|
+
registerVariableIfAbsent(env, "sorts", "list<map<string, string>>", {
|
|
155
|
+
label: "\u6392\u5E8F\u72B6\u6001",
|
|
156
|
+
description: SORTS_VAR_DESCRIPTION
|
|
157
|
+
});
|
|
161
158
|
}
|
|
162
159
|
export function registerDataSourceRequestVars(env) {
|
|
163
|
-
env
|
|
160
|
+
registerVariableIfAbsent(env, "pageIndex", "number", {
|
|
164
161
|
label: "\u5F53\u524D\u9875\u7801",
|
|
165
162
|
description: "\u4ECE `0` \u5F00\u59CB\uFF1B\u672A\u542F\u7528\u5206\u9875\u65F6\u4E3A `0`"
|
|
166
163
|
});
|
|
167
|
-
env
|
|
164
|
+
registerVariableIfAbsent(env, "pageSize", "number", {
|
|
168
165
|
label: "\u6BCF\u9875\u884C\u6570",
|
|
169
166
|
description: "\u5F53\u524D\u6BCF\u9875\u884C\u6570\uFF1B\u672A\u542F\u7528\u5206\u9875\u65F6\u4E3A `0`"
|
|
170
167
|
});
|
|
171
|
-
env
|
|
168
|
+
registerVariableIfAbsent(env, "sorts", "list<map<string, string>>", {
|
|
172
169
|
label: "\u6392\u5E8F\u72B6\u6001",
|
|
173
170
|
description: SORTS_VAR_DESCRIPTION
|
|
174
171
|
});
|
|
175
|
-
env
|
|
172
|
+
registerVariableIfAbsent(env, "query", "dyn", {
|
|
176
173
|
label: "\u641C\u7D22\u6761\u4EF6",
|
|
177
174
|
description: QUERY_VAR_DESCRIPTION
|
|
178
175
|
});
|
|
179
176
|
}
|
|
180
177
|
export function registerDataSourceResponseVars(env) {
|
|
181
|
-
env
|
|
178
|
+
registerVariableIfAbsent(env, "json", "optional<dyn>", {
|
|
182
179
|
label: "HTTP \u54CD\u5E94\u4F53",
|
|
183
180
|
description: JSON_VAR_DESCRIPTION
|
|
184
181
|
});
|
|
185
|
-
env
|
|
182
|
+
registerVariableIfAbsent(env, "query", "dyn", {
|
|
186
183
|
label: "\u641C\u7D22\u6761\u4EF6",
|
|
187
184
|
description: QUERY_VAR_DESCRIPTION
|
|
188
185
|
});
|
|
@@ -273,6 +270,8 @@ export function TableConfig(configure) {
|
|
|
273
270
|
configure: (env) => {
|
|
274
271
|
configure(env);
|
|
275
272
|
registerRowVariablesIfAbsent(env);
|
|
273
|
+
const declared = new Set(env.getDefinitions().variables.map((v) => v.name));
|
|
274
|
+
if (declared.has("selected")) env.deleteVariable("selected");
|
|
276
275
|
env.registerVariable("id", "string", { description: "\u5217 ID" });
|
|
277
276
|
env.registerVariable("selected", "bool", { description: "\u884C\u662F\u5426\u9009\u4E2D" });
|
|
278
277
|
env.registerVariable("pinned", "dyn", { description: "\u5217\u56FA\u5B9A\u72B6\u6001" });
|
|
@@ -24,8 +24,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
24
24
|
"onUpdate:modelValue"?: ((args_0: Date | undefined) => any) | undefined;
|
|
25
25
|
}>, {
|
|
26
26
|
size: "sm" | "md" | "lg";
|
|
27
|
-
clearable: boolean;
|
|
28
27
|
clearIcon: string;
|
|
28
|
+
clearable: boolean;
|
|
29
29
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
30
|
declare const _default: typeof __VLS_export;
|
|
31
31
|
export default _default;
|
|
@@ -24,8 +24,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
24
24
|
"onUpdate:modelValue"?: ((args_0: Date | undefined) => any) | undefined;
|
|
25
25
|
}>, {
|
|
26
26
|
size: "sm" | "md" | "lg";
|
|
27
|
-
clearable: boolean;
|
|
28
27
|
clearIcon: string;
|
|
28
|
+
clearable: boolean;
|
|
29
29
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
30
|
declare const _default: typeof __VLS_export;
|
|
31
31
|
export default _default;
|
|
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
22
22
|
size: "sm" | "md" | "lg";
|
|
23
23
|
granularity: "hour" | "minute" | "second";
|
|
24
24
|
hourCycle: 12 | 24;
|
|
25
|
-
clearable: boolean;
|
|
26
25
|
clearIcon: string;
|
|
26
|
+
clearable: boolean;
|
|
27
27
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
28
|
declare const _default: typeof __VLS_export;
|
|
29
29
|
export default _default;
|
|
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
22
22
|
size: "sm" | "md" | "lg";
|
|
23
23
|
granularity: "hour" | "minute" | "second";
|
|
24
24
|
hourCycle: 12 | 24;
|
|
25
|
-
clearable: boolean;
|
|
26
25
|
clearIcon: string;
|
|
26
|
+
clearable: boolean;
|
|
27
27
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
28
|
declare const _default: typeof __VLS_export;
|
|
29
29
|
export default _default;
|
|
@@ -29,8 +29,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
29
29
|
"onUpdate:endValue"?: ((args_0: Date | undefined) => any) | undefined;
|
|
30
30
|
}>, {
|
|
31
31
|
size: "sm" | "md" | "lg";
|
|
32
|
-
clearable: boolean;
|
|
33
32
|
clearIcon: string;
|
|
33
|
+
clearable: boolean;
|
|
34
34
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
35
|
declare const _default: typeof __VLS_export;
|
|
36
36
|
export default _default;
|
|
@@ -29,8 +29,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
29
29
|
"onUpdate:endValue"?: ((args_0: Date | undefined) => any) | undefined;
|
|
30
30
|
}>, {
|
|
31
31
|
size: "sm" | "md" | "lg";
|
|
32
|
-
clearable: boolean;
|
|
33
32
|
clearIcon: string;
|
|
33
|
+
clearable: boolean;
|
|
34
34
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
35
|
declare const _default: typeof __VLS_export;
|
|
36
36
|
export default _default;
|
|
@@ -26,9 +26,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
26
26
|
size: "sm" | "md" | "lg";
|
|
27
27
|
granularity: "hour" | "minute" | "second";
|
|
28
28
|
hourCycle: 12 | 24;
|
|
29
|
-
clearable: boolean;
|
|
30
|
-
clearIcon: string;
|
|
31
29
|
rangeSeparatorIcon: string;
|
|
30
|
+
clearIcon: string;
|
|
31
|
+
clearable: boolean;
|
|
32
32
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
33
|
declare const _default: typeof __VLS_export;
|
|
34
34
|
export default _default;
|
|
@@ -26,9 +26,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
26
26
|
size: "sm" | "md" | "lg";
|
|
27
27
|
granularity: "hour" | "minute" | "second";
|
|
28
28
|
hourCycle: 12 | 24;
|
|
29
|
-
clearable: boolean;
|
|
30
|
-
clearIcon: string;
|
|
31
29
|
rangeSeparatorIcon: string;
|
|
30
|
+
clearIcon: string;
|
|
31
|
+
clearable: boolean;
|
|
32
32
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
33
|
declare const _default: typeof __VLS_export;
|
|
34
34
|
export default _default;
|