Skip to content

Commit 1e26ad6

Browse files
feat: form node
1 parent ede97dc commit 1e26ad6

25 files changed

Lines changed: 492 additions & 438 deletions

File tree

Lines changed: 7 additions & 0 deletions
Loading

‎ui/src/components/COMPONENT_README.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,11 @@ const formValue = ref<Dict<DynamicFormValue>>({})
10841084
`enableVisibility` 和 `leftOptions`,其中 `leftOptions` 使用 `VisibilityFieldOption[]`;公开
10851085
`validate()`、`getData()` 与 `render()`。
10861086

1087+
启用显隐设置时,配置器将 Tabs 导航与内容分开,只继承容器的最大高度,内容较少时自然撑开。
1088+
`el-scrollbar` 及其内部滚动容器使用可收缩的 Flex 布局,并覆盖默认的百分比高度;达到最大高度后
1089+
仅内容区滚动,Tabs 保持固定。普通 `MkDialog` 已提供内容最大高度,调用方不需要设置固定高度。
1090+
两个表单通过 `v-show` 切换并保持挂载,确保未选中的页签也能回填、取值和校验。
1091+
10871092
字段配置中的动态校验器和表格行表达式属于受信任的服务端协议,只允许加载可信配置;普通业务
10881093
输入不得作为脚本传入。
10891094

‎ui/src/components/global/markdown-editor/MdEditorMagnify.vue‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,14 @@ async function submitEditorDialog() {
5959
</MdEditor>
6060

6161
<MkDialog v-model="dialogVisible" :title="title" align-center>
62-
<MdEditor v-model="dialogContent" :preview="false" :toolbars="[]" :footers="[]" class="magnify-dialog-editor" />
62+
<MdEditor
63+
v-model="dialogContent"
64+
:preview="false"
65+
:toolbars="[]"
66+
:footers="[]"
67+
style="height: calc(100vh - 350px)"
68+
class="magnify-dialog-editor"
69+
/>
6370

6471
<template #footer>
6572
<el-button type="primary" @click="submitEditorDialog">确定</el-button>

‎ui/src/components/mk-dynamics-form/Demo.vue‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,6 @@ const validateForm = async () => {
167167
v-model="currentField"
168168
:enable-visibility="true"
169169
:left-options="visibilityFieldOptions"
170-
label-position="top"
171-
require-asterisk-position="right"
172170
/>
173171
<template #footer>
174172
<el-button @click="dialogVisible = false">取消</el-button>

‎ui/src/components/mk-dynamics-form/constant.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,16 @@ export const dynamicFormTypeOptions = [
1919

2020
export type DynamicFormInputType = (typeof dynamicFormTypeOptions)[number]['value']
2121
export type DynamicFormTypeOption = (typeof dynamicFormTypeOptions)[number]
22+
23+
// 引用变量为选择类字段提供选项时的格式说明。
24+
export const referenceOptionsHelp = `变量的值必须符合:
25+
[
26+
{
27+
"label": "xx",
28+
"value": "xx",
29+
"default": false
30+
}
31+
]
32+
label: 标签 必填
33+
value: 值 必填
34+
default: 是否为默认值`

‎ui/src/components/mk-dynamics-form/constructor/index.vue‎

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ import { onMounted, ref, nextTick } from 'vue'
33
import { dynamicFormTypeOptions } from '@/components/mk-dynamics-form/constant'
44
import VisibilityConstructor from './visibility/index.vue'
55
import BasicInfoConstructor from './BasicInfoConstructor.vue'
6-
import type { DynamicFormConstructorExpose, DynamicFormConstructorOption, DynamicFormConstructorState, FormField, VisibilityFieldOption, VisibilityRules } from '../type'
6+
import type {
7+
DynamicFormConstructorExpose,
8+
DynamicFormConstructorOption,
9+
DynamicFormConstructorState,
10+
FormField,
11+
VisibilityFieldOption,
12+
VisibilityRules,
13+
} from '../type'
714
815
interface VisibilityConstructorExpose {
916
getData: () => VisibilityRules | null
@@ -17,8 +24,20 @@ defineOptions({ name: 'MkDynamicsFormConstructor', inheritAttrs: false })
1724
defineEmits<{ (event: 'update:modelValue', value: Partial<FormField>): void }>()
1825
1926
const props = withDefaults(
20-
defineProps<{ modelValue?: Partial<FormField>; fieldTypeOptions?: DynamicFormConstructorOption[]; enableVisibility?: boolean; leftOptions?: VisibilityFieldOption[] }>(),
21-
{ enableVisibility: false, fieldTypeOptions: () => dynamicFormTypeOptions.map((item) => ({ label: item.label, value: `${item.value}Constructor` })) },
27+
defineProps<{
28+
modelValue?: Partial<FormField>
29+
// “基本信息”中可选的组件类型;不传时使用全部默认类型,value 使用带 Constructor 后缀的配置器名称。
30+
fieldTypeOptions?: DynamicFormConstructorOption[]
31+
// 是否展示“显隐设置”页签,默认关闭。
32+
enableVisibility?: boolean
33+
// “显隐设置”中条件左侧可引用的变量,启用显隐设置时使用;变量类型和选项用于匹配比较方式及值输入控件。
34+
// 由调用方提供可引用范围,例如上游节点字段、当前字段之前的表单字段,不控制可选的组件类型。
35+
leftOptions?: VisibilityFieldOption[]
36+
}>(),
37+
{
38+
enableVisibility: false,
39+
fieldTypeOptions: () => dynamicFormTypeOptions.map((item) => ({ label: item.label, value: `${item.value}Constructor` })),
40+
},
2241
)
2342
2443
const activeTab = ref('basic')
@@ -68,14 +87,18 @@ defineExpose({ getData, validate, render })
6887
</script>
6988

7089
<template>
71-
<el-tabs v-if="enableVisibility" v-model="activeTab">
72-
<el-tab-pane label="基本信息" name="basic">
73-
<BasicInfoConstructor ref="basicRef" v-model="formData" :input-type-list="fieldTypeOptions" v-bind="$attrs" />
74-
</el-tab-pane>
75-
<el-tab-pane label="显隐设置" name="visibility">
76-
<VisibilityConstructor ref="visibilityRef" :initial-value="visibilityRules" :left-options="leftOptions" />
77-
</el-tab-pane>
78-
</el-tabs>
90+
<div v-if="enableVisibility" class="flex max-h-[inherit] min-h-0 flex-col">
91+
<el-tabs v-model="activeTab" class="shrink-0">
92+
<el-tab-pane label="基本信息" name="basic" />
93+
<el-tab-pane label="显隐设置" name="visibility" />
94+
</el-tabs>
95+
96+
<!-- 导航固定,内容独立滚动;两个表单保持挂载,供统一回填、取值和校验。 -->
97+
<el-scrollbar class="mk-scrollbar-right mt-4 flex h-auto! min-h-0 flex-auto flex-col" wrap-class="h-auto! min-h-0 flex-auto">
98+
<BasicInfoConstructor v-show="activeTab === 'basic'" ref="basicRef" v-model="formData" :input-type-list="fieldTypeOptions" v-bind="$attrs" />
99+
<VisibilityConstructor v-show="activeTab === 'visibility'" ref="visibilityRef" :initial-value="visibilityRules" :left-options="leftOptions" />
100+
</el-scrollbar>
101+
</div>
79102

80103
<BasicInfoConstructor v-else ref="basicRef" v-model="formData" :input-type-list="fieldTypeOptions" v-bind="$attrs" />
81104
</template>

‎ui/src/components/mk-dynamics-form/constructor/items/JsonInputConstructor.vue‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,25 @@ onMounted(() => {
8989

9090
<template>
9191
<el-form-item v-if="getModel" label="赋值方式">
92-
<!-- // TODO 赋值方式待调整 -->
9392
<el-radio-group v-model="formValue.default_value_assignment_method">
9493
<el-radio :value="item.value" v-for="(item, index) in assignmentMethodOptions" :key="index">
95-
<span class="flex align-center">
94+
<span class="flex items-center gap-1">
9695
{{ item.label }}
9796

9897
<el-tooltip placement="right" v-if="item.value === 'ref_variables'">
9998
<template #content> 变量的值必须符合: JSON 格式 </template>
100-
<MkIcon name="icon_info_outlined"></MkIcon>
99+
<MkIcon name="icon_info_outlined" class="text-N600!"></MkIcon>
101100
</el-tooltip>
102101
</span>
103102
</el-radio>
104103
</el-radio-group>
105104
</el-form-item>
106-
<el-form-item v-if="formValue.default_value_assignment_method === 'ref_variables'" :required="true" prop="default_value" :rules="[referenceVariableRule]">
105+
<el-form-item
106+
v-if="formValue.default_value_assignment_method === 'ref_variables'"
107+
:required="true"
108+
prop="default_value"
109+
:rules="[referenceVariableRule]"
110+
>
107111
<NodeCascader ref="nodeCascaderRef" :nodeModel="model" placeholder="请选择变量" v-model="formValue.option_list" />
108112
</el-form-item>
109113

‎ui/src/components/mk-dynamics-form/constructor/items/MultiRowConstructor.vue‎

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup lang="ts">
2+
import { referenceOptionsHelp } from '../../constant'
23
import { computed, onMounted, inject } from 'vue'
34
import MultiRow from '@/components/mk-dynamics-form/items/MultiRow.vue'
45
import MkFormList from '@/components/mk-form-list/index.vue'
@@ -86,27 +87,15 @@ onMounted(() => {
8687

8788
<template>
8889
<el-form-item v-if="getModel" label="赋值方式">
89-
<!-- // TODO 赋值方式待调整 -->
9090
<el-radio-group @change="formValue.option_list = []" v-model="formValue.assignment_method">
9191
<el-radio :value="item.value" v-for="(item, index) in assignmentMethodOptions" :key="index">
92-
<span class="flex align-center">
92+
<span class="flex items-center gap-1">
9393
{{ item.label }}
94-
9594
<el-tooltip placement="right" v-if="item.value === 'ref_variables'">
9695
<template #content>
97-
变量的值必须符合:<br />
98-
[<br />
99-
{<br />
100-
"label": "xx",<br />
101-
"value": "xx",<br />
102-
"default": false<br />
103-
}<br />
104-
]<br />
105-
label: 标签 必填<br />
106-
value: 值 必填<br />
107-
default: 是否为默认值
96+
<div class="whitespace-pre-wrap">{{ referenceOptionsHelp }}</div>
10897
</template>
109-
<MkIcon name="icon_info_outlined"></MkIcon>
98+
<MkIcon name="icon_info_outlined" class="text-N600!"></MkIcon>
11099
</el-tooltip>
111100
</span>
112101
</el-radio>

‎ui/src/components/mk-dynamics-form/constructor/items/MultiSelectConstructor.vue‎

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup lang="ts">
2+
import { referenceOptionsHelp } from '../../constant'
23
import { computed, onMounted, inject } from 'vue'
34
import MkFormList from '@/components/mk-form-list/index.vue'
45
import NodeCascader from '@/workflow-canvas/core/NodeCascader.vue'
@@ -99,27 +100,16 @@ onMounted(() => {
99100

100101
<template>
101102
<el-form-item v-if="getModel" label="赋值方式">
102-
<!-- // TODO 赋值方式待调整 -->
103103
<el-radio-group @change="resetOptions" v-model="formValue.assignment_method">
104104
<el-radio :value="item.value" v-for="(item, index) in assignmentMethodOptions" :key="index">
105-
<span class="flex align-center">
105+
<span class="flex items-center gap-1">
106106
{{ item.label }}
107107

108108
<el-tooltip placement="right" v-if="item.value === 'ref_variables'">
109109
<template #content>
110-
变量的值必须符合:<br />
111-
[<br />
112-
{<br />
113-
"label": "xx",<br />
114-
"value": "xx",<br />
115-
"default": false<br />
116-
}<br />
117-
]<br />
118-
label: 标签 必填<br />
119-
value: 值 必填<br />
120-
default: 是否为默认值
110+
<div class="whitespace-pre-wrap">{{ referenceOptionsHelp }}</div>
121111
</template>
122-
<MkIcon name="icon_info_outlined"></MkIcon>
112+
<MkIcon name="icon_info_outlined" class="text-N600!"></MkIcon>
123113
</el-tooltip>
124114
</span>
125115
</el-radio>

‎ui/src/components/mk-dynamics-form/constructor/items/RadioCardConstructor.vue‎

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup lang="ts">
2+
import { referenceOptionsHelp } from '../../constant'
23
import { computed, onMounted, inject } from 'vue'
34
import RadioCard from '@/components/mk-dynamics-form/items/radio/RadioCard.vue'
45
import MkFormList from '@/components/mk-form-list/index.vue'
@@ -101,27 +102,16 @@ onMounted(() => {
101102

102103
<template>
103104
<el-form-item v-if="getModel" label="赋值方式">
104-
<!-- // TODO 赋值方式待调整 -->
105105
<el-radio-group @change="resetOptions" v-model="formValue.assignment_method">
106106
<el-radio :value="item.value" v-for="(item, index) in assignmentMethodOptions" :key="index">
107-
<span class="flex align-center">
107+
<span class="flex items-center gap-1">
108108
{{ item.label }}
109109

110110
<el-tooltip placement="right" v-if="item.value === 'ref_variables'">
111111
<template #content>
112-
变量的值必须符合:<br />
113-
[<br />
114-
{<br />
115-
"label": "xx",<br />
116-
"value": "xx",<br />
117-
"default": false<br />
118-
}<br />
119-
]<br />
120-
label: 标签 必填<br />
121-
value: 值 必填<br />
122-
default: 是否为默认值
112+
<div class="whitespace-pre-wrap">{{ referenceOptionsHelp }}</div>
123113
</template>
124-
<MkIcon name="icon_info_outlined"></MkIcon>
114+
<MkIcon name="icon_info_outlined" class="text-N600!"></MkIcon>
125115
</el-tooltip>
126116
</span>
127117
</el-radio>

0 commit comments

Comments
 (0)