mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-03-20 12:43:40 +00:00
feat(form-schema,form,editor,table): 完善表单配置类型
This commit is contained in:
parent
feefd3779e
commit
e8714c96c9
@ -63,7 +63,14 @@ import { computed, inject, nextTick, Ref, ref, useTemplateRef, watch } from 'vue
|
||||
|
||||
import type { CodeBlockContent } from '@tmagic/core';
|
||||
import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
|
||||
import { type ContainerChangeEventData, type FormConfig, type FormState, MFormBox } from '@tmagic/form';
|
||||
import {
|
||||
type ContainerChangeEventData,
|
||||
defineFormConfig,
|
||||
defineFormItem,
|
||||
type FormConfig,
|
||||
MFormBox,
|
||||
type TableColumnConfig,
|
||||
} from '@tmagic/form';
|
||||
|
||||
import FloatingBox from '@editor/components/FloatingBox.vue';
|
||||
import { useEditorContentHeight } from '@editor/hooks/use-editor-content-height';
|
||||
@ -112,7 +119,7 @@ const diffChange = () => {
|
||||
difVisible.value = false;
|
||||
};
|
||||
|
||||
const defaultParamColConfig = {
|
||||
const defaultParamColConfig = defineFormItem<TableColumnConfig>({
|
||||
type: 'row',
|
||||
label: '参数类型',
|
||||
items: [
|
||||
@ -140,76 +147,79 @@ const defaultParamColConfig = {
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const functionConfig = computed<FormConfig>(() => [
|
||||
{
|
||||
text: '名称',
|
||||
name: 'name',
|
||||
rules: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
||||
},
|
||||
{
|
||||
text: '描述',
|
||||
name: 'desc',
|
||||
},
|
||||
{
|
||||
text: '执行时机',
|
||||
name: 'timing',
|
||||
type: 'select',
|
||||
options: () => {
|
||||
const options = [
|
||||
{ text: '初始化前', value: 'beforeInit' },
|
||||
{ text: '初始化后', value: 'afterInit' },
|
||||
];
|
||||
if (props.dataSourceType !== 'base') {
|
||||
options.push({ text: '请求前', value: 'beforeRequest' });
|
||||
options.push({ text: '请求后', value: 'afterRequest' });
|
||||
}
|
||||
return options;
|
||||
},
|
||||
display: () => props.isDataSource,
|
||||
},
|
||||
{
|
||||
type: 'table',
|
||||
border: true,
|
||||
text: '参数',
|
||||
enableFullscreen: false,
|
||||
enableToggleMode: false,
|
||||
name: 'params',
|
||||
dropSort: false,
|
||||
items: [
|
||||
const functionConfig = computed(
|
||||
() =>
|
||||
defineFormConfig([
|
||||
{
|
||||
type: 'text',
|
||||
label: '参数名',
|
||||
text: '名称',
|
||||
name: 'name',
|
||||
rules: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
label: '描述',
|
||||
name: 'extra',
|
||||
text: '描述',
|
||||
name: 'desc',
|
||||
},
|
||||
codeBlockService.getParamsColConfig() || defaultParamColConfig,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'vs-code',
|
||||
options: inject('codeOptions', {}),
|
||||
autosize: { minRows: 10, maxRows: 30 },
|
||||
onChange: (formState: FormState | undefined, code: string) => {
|
||||
try {
|
||||
// 检测js代码是否存在语法错误
|
||||
getEditorConfig('parseDSL')(code);
|
||||
{
|
||||
text: '执行时机',
|
||||
name: 'timing',
|
||||
type: 'select',
|
||||
options: () => {
|
||||
const options = [
|
||||
{ text: '初始化前', value: 'beforeInit' },
|
||||
{ text: '初始化后', value: 'afterInit' },
|
||||
];
|
||||
if (props.dataSourceType !== 'base') {
|
||||
options.push({ text: '请求前', value: 'beforeRequest' });
|
||||
options.push({ text: '请求后', value: 'afterRequest' });
|
||||
}
|
||||
return options;
|
||||
},
|
||||
display: () => props.isDataSource,
|
||||
},
|
||||
{
|
||||
type: 'table',
|
||||
border: true,
|
||||
text: '参数',
|
||||
enableFullscreen: false,
|
||||
enableToggleMode: false,
|
||||
name: 'params',
|
||||
dropSort: false,
|
||||
items: [
|
||||
{
|
||||
type: 'text',
|
||||
label: '参数名',
|
||||
name: 'name',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
label: '描述',
|
||||
name: 'extra',
|
||||
},
|
||||
codeBlockService.getParamsColConfig() || defaultParamColConfig,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'vs-code',
|
||||
options: inject('codeOptions', {}),
|
||||
autosize: { minRows: 10, maxRows: 30 },
|
||||
onChange: (_formState, code: string) => {
|
||||
try {
|
||||
// 检测js代码是否存在语法错误
|
||||
getEditorConfig('parseDSL')(code);
|
||||
|
||||
return code;
|
||||
} catch (error: any) {
|
||||
tMagicMessage.error(error.message);
|
||||
return code;
|
||||
} catch (error: any) {
|
||||
tMagicMessage.error(error.message);
|
||||
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
},
|
||||
]);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
},
|
||||
]) as FormConfig,
|
||||
);
|
||||
|
||||
const parseContent = (content: any) => {
|
||||
if (typeof content === 'string') {
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, useTemplateRef } from 'vue';
|
||||
|
||||
import { type ContainerChangeEventData, type FormConfig, type FormValue, MForm } from '@tmagic/form';
|
||||
import { type ContainerChangeEventData, type FormItemConfig, type FormValue, MForm } from '@tmagic/form';
|
||||
|
||||
import type { CodeParamStatement } from '@editor/type';
|
||||
import { error } from '@editor/utils';
|
||||
@ -34,7 +34,7 @@ const emit = defineEmits(['change']);
|
||||
|
||||
const formRef = useTemplateRef<InstanceType<typeof MForm>>('form');
|
||||
|
||||
const getFormConfig = (items: FormConfig = []) => [
|
||||
const getFormConfig = (items: FormItemConfig[] = []) => [
|
||||
{
|
||||
type: 'fieldset',
|
||||
items,
|
||||
@ -51,7 +51,7 @@ const codeParamsConfig = computed(() =>
|
||||
name,
|
||||
text,
|
||||
extra,
|
||||
fieldConfig: config,
|
||||
fieldConfig: config as FormItemConfig,
|
||||
})),
|
||||
),
|
||||
);
|
||||
|
||||
@ -50,6 +50,7 @@ import {
|
||||
createValues,
|
||||
type FieldProps,
|
||||
filterFunction,
|
||||
type FormItemConfig,
|
||||
type FormState,
|
||||
MSelect,
|
||||
type SelectConfig,
|
||||
@ -141,7 +142,9 @@ const onCodeIdChangeHandler = (value: any) => {
|
||||
|
||||
changeRecords.push({
|
||||
propPath: props.prop.replace(`${props.name}`, 'params'),
|
||||
value: paramsConfig.value.length ? createValues(mForm, paramsConfig.value, {}, props.model.params) : {},
|
||||
value: paramsConfig.value.length
|
||||
? createValues(mForm, paramsConfig.value as unknown as FormItemConfig[], {}, props.model.params)
|
||||
: {},
|
||||
});
|
||||
|
||||
emit('change', value, {
|
||||
|
||||
@ -98,7 +98,9 @@ const dataSources = computed(() => dataSourceService.get('dataSources') || []);
|
||||
const disabledDataSource = computed(() => propsService.getDisabledDataSource());
|
||||
|
||||
const type = computed((): string => {
|
||||
let type = props.config.fieldConfig?.type;
|
||||
if (!props.config.fieldConfig) return '';
|
||||
|
||||
let type = 'type' in props.config.fieldConfig ? props.config.fieldConfig.type : '';
|
||||
if (typeof type === 'function') {
|
||||
type = type(mForm, {
|
||||
model: props.model,
|
||||
|
||||
@ -48,6 +48,7 @@ import {
|
||||
type DataSourceMethodSelectConfig,
|
||||
type FieldProps,
|
||||
filterFunction,
|
||||
type FormItemConfig,
|
||||
type FormState,
|
||||
MCascader,
|
||||
} from '@tmagic/form';
|
||||
@ -142,7 +143,9 @@ const onChangeHandler = (value: any) => {
|
||||
|
||||
changeRecords.push({
|
||||
propPath: props.prop.replace(`${props.name}`, 'params'),
|
||||
value: paramsConfig.value.length ? createValues(mForm, paramsConfig.value, {}, props.model.params) : {},
|
||||
value: paramsConfig.value.length
|
||||
? createValues(mForm, paramsConfig.value as unknown as FormItemConfig[], {}, props.model.params)
|
||||
: {},
|
||||
});
|
||||
|
||||
emit('change', value, {
|
||||
|
||||
@ -62,14 +62,15 @@ import type {
|
||||
CodeSelectColConfig,
|
||||
ContainerChangeEventData,
|
||||
DataSourceMethodSelectConfig,
|
||||
DynamicTypeConfig,
|
||||
EventSelectConfig,
|
||||
FieldProps,
|
||||
FormState,
|
||||
OnChangeHandlerData,
|
||||
PanelConfig,
|
||||
TableConfig,
|
||||
UISelectConfig,
|
||||
} from '@tmagic/form';
|
||||
import { MContainer as MFormContainer, MPanel, MTable } from '@tmagic/form';
|
||||
import { defineFormItem, MContainer as MFormContainer, MPanel, MTable } from '@tmagic/form';
|
||||
import { DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX, traverseNode } from '@tmagic/utils';
|
||||
|
||||
import { useServices } from '@editor/hooks/use-services';
|
||||
@ -212,12 +213,12 @@ const actionTypeConfig = computed(() => {
|
||||
|
||||
// 联动组件配置
|
||||
const targetCompConfig = computed(() => {
|
||||
const defaultTargetCompConfig = {
|
||||
const defaultTargetCompConfig: UISelectConfig = {
|
||||
name: 'to',
|
||||
text: '联动组件',
|
||||
type: 'ui-select',
|
||||
display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.COMP,
|
||||
onChange: (MForm: FormState, v: string, { setModel }: OnChangeHandlerData) => {
|
||||
display: (_mForm, { model }) => model.actionType === ActionType.COMP,
|
||||
onChange: (_MForm, _v, { setModel }) => {
|
||||
setModel('method', '');
|
||||
},
|
||||
};
|
||||
@ -226,7 +227,7 @@ const targetCompConfig = computed(() => {
|
||||
|
||||
// 联动组件动作配置
|
||||
const compActionConfig = computed(() => {
|
||||
const defaultCompActionConfig = {
|
||||
const defaultCompActionConfig: DynamicTypeConfig = {
|
||||
name: 'method',
|
||||
text: '动作',
|
||||
type: (mForm: FormState | undefined, { model }: any) => {
|
||||
@ -304,62 +305,68 @@ const dataSourceActionConfig = computed(() => {
|
||||
});
|
||||
|
||||
// 兼容旧的数据格式
|
||||
const tableConfig = computed<TableConfig>(() => ({
|
||||
type: 'table',
|
||||
name: 'events',
|
||||
items: [
|
||||
{
|
||||
name: 'name',
|
||||
label: '事件名',
|
||||
type: eventNameConfig.value.type,
|
||||
options: (mForm: FormState, { formValue }: any) =>
|
||||
eventsService.getEvent(formValue.type).map((option: any) => ({
|
||||
text: option.label,
|
||||
value: option.value,
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'to',
|
||||
label: '联动组件',
|
||||
type: 'ui-select',
|
||||
},
|
||||
{
|
||||
name: 'method',
|
||||
label: '动作',
|
||||
type: compActionConfig.value.type,
|
||||
options: (mForm: FormState, { model }: any) => {
|
||||
const node = editorService.getNodeById(model.to);
|
||||
if (!node?.type) return [];
|
||||
const tableConfig = computed(
|
||||
() =>
|
||||
defineFormItem({
|
||||
type: 'table',
|
||||
name: 'events',
|
||||
items: [
|
||||
{
|
||||
name: 'name',
|
||||
label: '事件名',
|
||||
type: eventNameConfig.value.type,
|
||||
options: (mForm: FormState, { formValue }: any) =>
|
||||
eventsService.getEvent(formValue.type).map((option: any) => ({
|
||||
text: option.label,
|
||||
value: option.value,
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'to',
|
||||
label: '联动组件',
|
||||
type: 'ui-select',
|
||||
},
|
||||
{
|
||||
name: 'method',
|
||||
label: '动作',
|
||||
type: compActionConfig.value.type,
|
||||
options: (mForm: FormState, { model }: any) => {
|
||||
const node = editorService.getNodeById(model.to);
|
||||
if (!node?.type) return [];
|
||||
|
||||
return eventsService.getMethod(node.type, model.to).map((option: any) => ({
|
||||
text: option.label,
|
||||
value: option.value,
|
||||
}));
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
return eventsService.getMethod(node.type, model.to).map((option: any) => ({
|
||||
text: option.label,
|
||||
value: option.value,
|
||||
}));
|
||||
},
|
||||
},
|
||||
],
|
||||
}) as TableConfig,
|
||||
);
|
||||
|
||||
// 组件动作组表单配置
|
||||
const actionsConfig = computed<PanelConfig>(() => ({
|
||||
type: 'panel',
|
||||
items: [
|
||||
{
|
||||
type: 'group-list',
|
||||
name: 'actions',
|
||||
expandAll: true,
|
||||
enableToggleMode: false,
|
||||
titlePrefix: '动作',
|
||||
const actionsConfig = computed(
|
||||
() =>
|
||||
defineFormItem({
|
||||
type: 'panel',
|
||||
items: [
|
||||
actionTypeConfig.value,
|
||||
targetCompConfig.value,
|
||||
compActionConfig.value,
|
||||
codeActionConfig.value,
|
||||
dataSourceActionConfig.value,
|
||||
{
|
||||
type: 'group-list',
|
||||
name: 'actions',
|
||||
expandAll: true,
|
||||
enableToggleMode: false,
|
||||
titlePrefix: '动作',
|
||||
items: [
|
||||
actionTypeConfig.value,
|
||||
targetCompConfig.value,
|
||||
compActionConfig.value,
|
||||
codeActionConfig.value,
|
||||
dataSourceActionConfig.value,
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}));
|
||||
}) as PanelConfig,
|
||||
);
|
||||
|
||||
// 是否为旧的数据格式
|
||||
const isOldVersion = computed(() => {
|
||||
|
||||
@ -39,46 +39,48 @@
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import type { ContainerChangeEventData, FormValue } from '@tmagic/form';
|
||||
import { MContainer } from '@tmagic/form';
|
||||
import { defineFormItem, type MContainer } from '@tmagic/form';
|
||||
import type { StyleSchema } from '@tmagic/schema';
|
||||
|
||||
const direction = ref('');
|
||||
|
||||
const config = computed(() => ({
|
||||
items: [
|
||||
{
|
||||
name: `border${direction.value}Width`,
|
||||
text: '边框宽度',
|
||||
labelWidth: '68px',
|
||||
type: 'data-source-field-select',
|
||||
fieldConfig: {
|
||||
type: 'text',
|
||||
const config = computed(() =>
|
||||
defineFormItem({
|
||||
items: [
|
||||
{
|
||||
name: `border${direction.value}Width`,
|
||||
text: '边框宽度',
|
||||
labelWidth: '68px',
|
||||
type: 'data-source-field-select',
|
||||
fieldConfig: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: `border${direction.value}Color`,
|
||||
text: '边框颜色',
|
||||
labelWidth: '68px',
|
||||
type: 'data-source-field-select',
|
||||
fieldConfig: {
|
||||
type: 'colorPicker',
|
||||
{
|
||||
name: `border${direction.value}Color`,
|
||||
text: '边框颜色',
|
||||
labelWidth: '68px',
|
||||
type: 'data-source-field-select',
|
||||
fieldConfig: {
|
||||
type: 'colorPicker',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: `border${direction.value}Style`,
|
||||
text: '边框样式',
|
||||
labelWidth: '68px',
|
||||
type: 'data-source-field-select',
|
||||
fieldConfig: {
|
||||
type: 'select',
|
||||
options: ['solid', 'dashed', 'dotted'].map((item) => ({
|
||||
value: item,
|
||||
text: item,
|
||||
})),
|
||||
{
|
||||
name: `border${direction.value}Style`,
|
||||
text: '边框样式',
|
||||
labelWidth: '68px',
|
||||
type: 'data-source-field-select',
|
||||
fieldConfig: {
|
||||
type: 'select',
|
||||
options: ['solid', 'dashed', 'dotted'].map((item) => ({
|
||||
value: item,
|
||||
text: item,
|
||||
})),
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
const selectDirection = (d?: string) => (direction.value = d || '');
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { markRaw } from 'vue';
|
||||
|
||||
import { ContainerChangeEventData, MContainer } from '@tmagic/form';
|
||||
import { type ContainerChangeEventData, defineFormItem, type MContainer } from '@tmagic/form';
|
||||
import type { StyleSchema } from '@tmagic/schema';
|
||||
|
||||
import BackgroundPosition from '../components/BackgroundPosition.vue';
|
||||
@ -21,7 +21,7 @@ const emit = defineEmits<{
|
||||
change: [v: StyleSchema, eventData: ContainerChangeEventData];
|
||||
}>();
|
||||
|
||||
const config = {
|
||||
const config = defineFormItem({
|
||||
items: [
|
||||
{
|
||||
name: 'backgroundColor',
|
||||
@ -39,7 +39,7 @@ const config = {
|
||||
type: 'data-source-field-select',
|
||||
fieldConfig: {
|
||||
type: 'img-upload',
|
||||
},
|
||||
} as any,
|
||||
},
|
||||
{
|
||||
name: 'backgroundSize',
|
||||
@ -74,7 +74,7 @@ const config = {
|
||||
labelWidth: '68px',
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
|
||||
emit('change', value, eventData);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { type ContainerChangeEventData, MContainer } from '@tmagic/form';
|
||||
import { type ContainerChangeEventData, defineFormItem, type MContainer } from '@tmagic/form';
|
||||
import type { StyleSchema } from '@tmagic/schema';
|
||||
|
||||
import Border from '../components/Border.vue';
|
||||
@ -19,7 +19,7 @@ const emit = defineEmits<{
|
||||
change: [v: StyleSchema, eventData: ContainerChangeEventData];
|
||||
}>();
|
||||
|
||||
const config = {
|
||||
const config = defineFormItem({
|
||||
items: [
|
||||
{
|
||||
labelWidth: '68px',
|
||||
@ -31,7 +31,7 @@ const config = {
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
|
||||
emit('change', value, eventData);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { markRaw } from 'vue';
|
||||
|
||||
import { ContainerChangeEventData, MContainer } from '@tmagic/form';
|
||||
import { type ContainerChangeEventData, defineFormItem, type MContainer } from '@tmagic/form';
|
||||
import type { StyleSchema } from '@tmagic/schema';
|
||||
|
||||
import { AlignCenter, AlignLeft, AlignRight } from '../icons/text-align';
|
||||
@ -20,7 +20,7 @@ const emit = defineEmits<{
|
||||
change: [v: StyleSchema, eventData: ContainerChangeEventData];
|
||||
}>();
|
||||
|
||||
const config = {
|
||||
const config = defineFormItem({
|
||||
items: [
|
||||
{
|
||||
type: 'row',
|
||||
@ -86,7 +86,7 @@ const config = {
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
|
||||
emit('change', value, eventData);
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { markRaw } from 'vue';
|
||||
|
||||
import type { ContainerChangeEventData } from '@tmagic/form';
|
||||
import type { ChildConfig, ContainerChangeEventData } from '@tmagic/form';
|
||||
import { defineFormItem, MContainer } from '@tmagic/form';
|
||||
import type { StyleSchema } from '@tmagic/schema';
|
||||
|
||||
@ -180,7 +180,7 @@ const config = defineFormItem({
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
}) as ChildConfig;
|
||||
|
||||
const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
|
||||
emit('change', value, eventData);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ContainerChangeEventData, MContainer } from '@tmagic/form';
|
||||
import { type ContainerChangeEventData, defineFormItem, type MContainer } from '@tmagic/form';
|
||||
import type { StyleSchema } from '@tmagic/schema';
|
||||
|
||||
const props = defineProps<{
|
||||
@ -24,7 +24,7 @@ const positionText: Record<string, string> = {
|
||||
sticky: '粘性定位',
|
||||
};
|
||||
|
||||
const config = {
|
||||
const config = defineFormItem({
|
||||
items: [
|
||||
{
|
||||
name: 'position',
|
||||
@ -95,7 +95,7 @@ const config = {
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
|
||||
emit('change', value, eventData);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { defineFormConfig } from '@tmagic/form';
|
||||
import { defineFormConfig, type FormConfig } from '@tmagic/form';
|
||||
|
||||
export default () =>
|
||||
export default (): FormConfig =>
|
||||
defineFormConfig([
|
||||
{
|
||||
name: 'id',
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { DataSchema, DataSourceFieldType, DataSourceSchema } from '@tmagic/core';
|
||||
import { CascaderOption, FormConfig, FormState } from '@tmagic/form';
|
||||
import type { DataSchema, DataSourceFieldType, DataSourceSchema } from '@tmagic/core';
|
||||
import { type CascaderOption, defineFormItem, type FormConfig } from '@tmagic/form';
|
||||
import { dataSourceTemplateRegExp, getKeysArray, isNumber } from '@tmagic/utils';
|
||||
|
||||
import BaseFormConfig from './formConfigs/base';
|
||||
import HttpFormConfig from './formConfigs/http';
|
||||
|
||||
const dataSourceFormConfig = {
|
||||
const dataSourceFormConfig = defineFormItem({
|
||||
type: 'tab',
|
||||
items: [
|
||||
{
|
||||
@ -50,7 +50,7 @@ const dataSourceFormConfig = {
|
||||
},
|
||||
{
|
||||
title: '请求参数裁剪',
|
||||
display: (_formState: FormState, { model }: any) => model.type === 'http',
|
||||
display: (_formState, { model }) => model.type === 'http',
|
||||
items: [
|
||||
{
|
||||
name: 'beforeRequest',
|
||||
@ -62,7 +62,7 @@ const dataSourceFormConfig = {
|
||||
},
|
||||
{
|
||||
title: '响应数据裁剪',
|
||||
display: (_formState: FormState, { model }: any) => model.type === 'http',
|
||||
display: (_formStat, { model }) => model.type === 'http',
|
||||
items: [
|
||||
{
|
||||
name: 'afterResponse',
|
||||
@ -73,7 +73,7 @@ const dataSourceFormConfig = {
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const fillConfig = (config: FormConfig): FormConfig => [...BaseFormConfig(), ...config, dataSourceFormConfig];
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ import {
|
||||
NODE_DISABLE_DATA_SOURCE_KEY,
|
||||
} from '@tmagic/core';
|
||||
import { tMagicMessage } from '@tmagic/design';
|
||||
import type { ChildConfig, FormConfig, TabConfig, TabPaneConfig } from '@tmagic/form';
|
||||
import type { ChildConfig, DisplayCondsConfig, FormConfig, TabConfig, TabPaneConfig } from '@tmagic/form';
|
||||
|
||||
export const arrayOptions = [
|
||||
{ text: '包含', value: 'include' },
|
||||
@ -168,7 +168,7 @@ export const advancedTabConfig: TabPaneConfig = {
|
||||
],
|
||||
};
|
||||
|
||||
export const displayTabConfig: TabPaneConfig = {
|
||||
export const displayTabConfig: TabPaneConfig<DisplayCondsConfig> = {
|
||||
title: '显示条件',
|
||||
display: (_state, { model }) => model.type !== 'page',
|
||||
items: [
|
||||
|
||||
@ -91,12 +91,10 @@ export interface FormItem {
|
||||
/** vnode的key值,默认是遍历数组时的index */
|
||||
__key?: string | number;
|
||||
/** 表单域标签的的宽度,例如 '50px'。支持 auto。 */
|
||||
labelWidth?: string;
|
||||
labelWidth?: string | number;
|
||||
/** label 标签的title属性 */
|
||||
labelTitle?: string;
|
||||
className?: string;
|
||||
/** 表单组件类型 */
|
||||
type?: string | TypeFunction;
|
||||
/** 字段名 */
|
||||
name?: string | number;
|
||||
/** 额外的提示信息,和 help 类似,当提示文案同时出现时,可以使用这个。 */
|
||||
@ -132,7 +130,12 @@ export interface FormItem {
|
||||
labelPosition?: 'top' | 'left' | 'right';
|
||||
}
|
||||
|
||||
export interface ContainerCommonConfig<T extends Record<string, any> = never> {
|
||||
export interface DynamicTypeConfig extends FormItem {
|
||||
type: TypeFunction;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface ContainerCommonConfig<T = never> extends FormItem {
|
||||
items: FormConfig<T>;
|
||||
onInitValue?: (
|
||||
mForm: FormState | undefined,
|
||||
@ -182,12 +185,12 @@ export interface Input {
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
export type TypeFunction = (
|
||||
export type TypeFunction<T extends string = string> = (
|
||||
mForm: FormState | undefined,
|
||||
data: {
|
||||
model: FormValue;
|
||||
},
|
||||
) => string;
|
||||
) => T;
|
||||
|
||||
export type FilterFunction<T = boolean> = (
|
||||
mForm: FormState | undefined,
|
||||
@ -208,6 +211,7 @@ export type FilterFunction<T = boolean> = (
|
||||
*/
|
||||
export interface SelectConfigOption {
|
||||
/** 选项的标签 */
|
||||
label?: string | SelectOptionTextFunction;
|
||||
text: string | SelectOptionTextFunction;
|
||||
/** 选项的值 */
|
||||
value: any | SelectOptionValueFunction;
|
||||
@ -499,7 +503,7 @@ export interface CheckboxGroupOption {
|
||||
* 多选框组
|
||||
*/
|
||||
export interface CheckboxGroupConfig extends FormItem {
|
||||
type: 'checkbox-group';
|
||||
type: 'checkbox-group' | 'checkboxGroup';
|
||||
options: CheckboxGroupOption[] | FilterFunction<CheckboxGroupOption[]>;
|
||||
}
|
||||
|
||||
@ -546,7 +550,7 @@ export interface SelectConfig extends FormItem, Input {
|
||||
/**
|
||||
* 链接
|
||||
*/
|
||||
export interface LinkConfig<T extends Record<string, any> = never> extends FormItem {
|
||||
export interface LinkConfig<T = never> extends FormItem {
|
||||
type: 'link';
|
||||
href?: string | ((model: Record<string, any>) => string);
|
||||
css?: {
|
||||
@ -615,7 +619,7 @@ export interface CascaderConfig extends FormItem, Input {
|
||||
}
|
||||
|
||||
export interface DynamicFieldConfig extends FormItem {
|
||||
type: 'dynamic-field';
|
||||
type: 'dynamic-field' | 'dynamicField';
|
||||
returnFields: (
|
||||
config: DynamicFieldConfig,
|
||||
model: Record<any, any>,
|
||||
@ -631,16 +635,16 @@ export interface DynamicFieldConfig extends FormItem {
|
||||
/**
|
||||
* 分组容器
|
||||
*/
|
||||
export interface RowConfig<T extends Record<string, any> = never> extends FormItem {
|
||||
export interface RowConfig<T = never> extends FormItem {
|
||||
type: 'row';
|
||||
span: number;
|
||||
items: ({ span?: number } & (ChildConfig<T> | EditorChildConfig | NoInfer<T>))[];
|
||||
items: ({ span?: number } & (ChildConfig<T> | EditorChildConfig | T))[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 标签页容器
|
||||
*/
|
||||
export interface TabPaneConfig<T extends Record<string, any> = never> {
|
||||
export interface TabPaneConfig<T = never> {
|
||||
status?: string;
|
||||
/** 标签页名称,用于关联 model 中的数据 */
|
||||
name?: string | number;
|
||||
@ -652,7 +656,7 @@ export interface TabPaneConfig<T extends Record<string, any> = never> {
|
||||
onTabClick?: (mForm: FormState | undefined, tab: any, data: any) => void;
|
||||
}
|
||||
|
||||
export interface TabConfig<T extends Record<string, any> = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
export interface TabConfig<T = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
type: 'tab' | 'dynamic-tab';
|
||||
tabType?: string;
|
||||
editable?: boolean;
|
||||
@ -673,7 +677,7 @@ export interface TabConfig<T extends Record<string, any> = never> extends FormIt
|
||||
/**
|
||||
* 分组
|
||||
*/
|
||||
export interface FieldsetConfig<T extends Record<string, any> = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
export interface FieldsetConfig<T = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
type: 'fieldset';
|
||||
checkbox?:
|
||||
| boolean
|
||||
@ -690,7 +694,7 @@ export interface FieldsetConfig<T extends Record<string, any> = never> extends F
|
||||
/**
|
||||
* 面板容器
|
||||
*/
|
||||
export interface PanelConfig<T extends Record<string, any> = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
export interface PanelConfig<T = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
type: 'panel';
|
||||
expand?: boolean;
|
||||
title?: string;
|
||||
@ -705,6 +709,7 @@ export interface TableColumnConfig extends FormItem {
|
||||
items?: FormConfig;
|
||||
itemsFunction?: (row: any) => FormConfig;
|
||||
titleTip?: FilterFunction<string>;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -765,7 +770,7 @@ export interface TableConfig extends FormItem {
|
||||
sortKey?: string;
|
||||
}
|
||||
|
||||
export interface GroupListConfig<T extends Record<string, any> = never> extends FormItem {
|
||||
export interface GroupListConfig<T = never> extends FormItem {
|
||||
type: 'table' | 'groupList' | 'group-list';
|
||||
span?: number;
|
||||
enableToggleMode?: boolean;
|
||||
@ -801,11 +806,11 @@ export interface GroupListConfig<T extends Record<string, any> = never> extends
|
||||
};
|
||||
}
|
||||
|
||||
interface StepItemConfig<T extends Record<string, any> = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
interface StepItemConfig<T = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface StepConfig<T extends Record<string, any> = never> extends FormItem {
|
||||
export interface StepConfig<T = never> extends FormItem {
|
||||
type: 'step';
|
||||
/** 每个 step 的间距,不填写将自适应间距。支持百分比。 */
|
||||
space?: string | number;
|
||||
@ -820,14 +825,14 @@ export interface ComponentConfig extends FormItem {
|
||||
component: any;
|
||||
}
|
||||
|
||||
export interface FlexLayoutConfig<T extends Record<string, any> = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
export interface FlexLayoutConfig<T = never> extends FormItem, ContainerCommonConfig<T> {
|
||||
type: 'flex-layout';
|
||||
/** flex 子项间距,默认 '16px' */
|
||||
gap?: string;
|
||||
}
|
||||
|
||||
export type ChildConfig<T extends Record<string, any> = never> =
|
||||
| (FormItem & Partial<ContainerCommonConfig<T>>)
|
||||
export type ChildConfig<T = never> =
|
||||
| ContainerCommonConfig<T>
|
||||
| TabConfig<T>
|
||||
| RowConfig<T>
|
||||
| FieldsetConfig<T>
|
||||
@ -859,6 +864,6 @@ export type ChildConfig<T extends Record<string, any> = never> =
|
||||
| ComponentConfig
|
||||
| FlexLayoutConfig<T>;
|
||||
|
||||
export type FormItemConfig<T extends Record<string, any> = never> = ChildConfig<T> | EditorChildConfig<T> | NoInfer<T>;
|
||||
export type FormItemConfig<T = never> = ChildConfig<T> | DynamicTypeConfig | EditorChildConfig<T> | T;
|
||||
|
||||
export type FormConfig<T extends Record<string, any> = never> = FormItemConfig<T>[];
|
||||
export type FormConfig<T = never> = FormItemConfig<T>[];
|
||||
|
||||
@ -2,7 +2,7 @@ import type { DataSourceFieldType, DataSourceSchema } from '@tmagic/schema';
|
||||
|
||||
import type { FilterFunction, FormItem, FormItemConfig, FormState, Input } from './base';
|
||||
|
||||
export interface DataSourceFieldSelectConfig<T extends Record<string, any> = never> extends FormItem {
|
||||
export interface DataSourceFieldSelectConfig<T = never> extends FormItem {
|
||||
type: 'data-source-field-select';
|
||||
/**
|
||||
* 是否要编译成数据源的data。
|
||||
@ -104,6 +104,7 @@ export interface DataSourceSelect extends FormItem, Input {
|
||||
}
|
||||
|
||||
export interface DisplayCondsConfig extends FormItem {
|
||||
type: 'display-conds';
|
||||
titlePrefix?: string;
|
||||
parentFields?: string[] | FilterFunction<string[]>;
|
||||
}
|
||||
@ -144,7 +145,7 @@ export interface StyleSetterConfig extends FormItem {
|
||||
type: 'style-setter';
|
||||
}
|
||||
|
||||
export type EditorChildConfig<T extends Record<string, any> = never> =
|
||||
export type EditorChildConfig<T = never> =
|
||||
| DataSourceFieldSelectConfig<T>
|
||||
| CodeConfig
|
||||
| CodeLinkConfig
|
||||
|
||||
@ -3,7 +3,6 @@ import type { FormConfig, FormItemConfig } from './base';
|
||||
export * from './base';
|
||||
export * from './editor';
|
||||
|
||||
export const defineFormConfig = <T extends Record<string, any> = never>(config: FormConfig<T>): FormConfig<T> => config;
|
||||
export const defineFormConfig = <T = never>(config: FormConfig<T>): FormConfig<T> => config;
|
||||
|
||||
export const defineFormItem = <T extends Record<string, any> = never>(config: FormItemConfig<T>): FormItemConfig<T> =>
|
||||
config;
|
||||
export const defineFormItem = <T = never>(config: FormItemConfig<T>): FormItemConfig<T> => config;
|
||||
|
||||
@ -117,19 +117,25 @@ const stepActive = ref(1);
|
||||
const bodyHeight = ref(`${document.body.clientHeight - 194}px`);
|
||||
|
||||
const stepCount = computed(() => {
|
||||
const { length } = props.config;
|
||||
for (let index = 0; index < length; index++) {
|
||||
if (props.config[index].type === 'step') {
|
||||
return (props.config[index] as StepConfig).items.length;
|
||||
if (!Array.isArray(props.config)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (const item of props.config) {
|
||||
if ('type' in item && item.type === 'step') {
|
||||
return (item as StepConfig).items.length;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
const hasStep = computed(() => {
|
||||
const { length } = props.config;
|
||||
for (let index = 0; index < length; index++) {
|
||||
if (props.config[index].type === 'step') {
|
||||
if (!Array.isArray(props.config)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const item of props.config) {
|
||||
if ('type' in item && item.type === 'step') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<TMagicCol v-show="display && config.type !== 'hidden'" :span="span">
|
||||
<TMagicCol v-show="display && 'type' in config && config.type !== 'hidden'" :span="span">
|
||||
<Container
|
||||
:model="model"
|
||||
:lastValues="lastValues"
|
||||
@ -21,7 +21,7 @@ import { computed, inject } from 'vue';
|
||||
|
||||
import { TMagicCol } from '@tmagic/design';
|
||||
|
||||
import type { ChildConfig, ContainerChangeEventData, FormState } from '../schema';
|
||||
import type { ContainerChangeEventData, FormItemConfig, FormState } from '../schema';
|
||||
import { display as displayFunction } from '../utils/form';
|
||||
|
||||
import Container from './Container.vue';
|
||||
@ -34,8 +34,8 @@ const props = defineProps<{
|
||||
model: any;
|
||||
lastValues?: any;
|
||||
isCompare?: boolean;
|
||||
config: ChildConfig;
|
||||
labelWidth?: string;
|
||||
config: FormItemConfig;
|
||||
labelWidth?: string | number;
|
||||
expandMore?: boolean;
|
||||
span?: number;
|
||||
size?: string;
|
||||
|
||||
@ -175,10 +175,10 @@ import { getValueByKeyPath } from '@tmagic/utils';
|
||||
import MHidden from '../fields/Hidden.vue';
|
||||
import type {
|
||||
CheckboxConfig,
|
||||
ChildConfig,
|
||||
ComponentConfig,
|
||||
ContainerChangeEventData,
|
||||
ContainerCommonConfig,
|
||||
FormItemConfig,
|
||||
FormState,
|
||||
FormValue,
|
||||
ToolTipConfigType,
|
||||
@ -198,10 +198,10 @@ const props = withDefaults(
|
||||
model: FormValue;
|
||||
/** 需对比的值(开启对比模式时传入) */
|
||||
lastValues?: FormValue;
|
||||
config: ChildConfig;
|
||||
config: FormItemConfig;
|
||||
prop?: string;
|
||||
disabled?: boolean;
|
||||
labelWidth?: string;
|
||||
labelWidth?: string | number;
|
||||
expandMore?: boolean;
|
||||
stepActive?: string | number;
|
||||
size?: string;
|
||||
@ -253,7 +253,7 @@ const itemProp = computed(() => {
|
||||
});
|
||||
|
||||
const type = computed((): string => {
|
||||
let { type } = props.config;
|
||||
let type = 'type' in props.config ? props.config.type : '';
|
||||
type = type && filterFunction<string>(mForm, type, props);
|
||||
if (type === 'form') return '';
|
||||
if (type === 'container') return '';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { computed, inject } from 'vue';
|
||||
|
||||
import { tMagicMessage } from '@tmagic/design';
|
||||
import type { FormState } from '@tmagic/form-schema';
|
||||
import type { FormConfig, FormState } from '@tmagic/form-schema';
|
||||
|
||||
import { initValue } from '../utils/form';
|
||||
|
||||
@ -86,7 +86,7 @@ export const useAdd = (
|
||||
}
|
||||
|
||||
inputs = await initValue(mForm, {
|
||||
config: columns,
|
||||
config: columns as FormConfig,
|
||||
initValues: inputs,
|
||||
});
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { WarningFilled } from '@element-plus/icons-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import { type TableColumnOptions, TMagicIcon, TMagicTooltip } from '@tmagic/design';
|
||||
import type { FormState, TableColumnConfig } from '@tmagic/form-schema';
|
||||
import type { FormItemConfig, FormState, TableColumnConfig } from '@tmagic/form-schema';
|
||||
|
||||
import Container from '../containers/Container.vue';
|
||||
import type { ContainerChangeEventData } from '../schema';
|
||||
@ -68,7 +68,7 @@ export const useTableColumns = (
|
||||
return `${props.prop}${props.prop ? '.' : ''}${index + 1 + currentPage.value * pageSize.value - 1}`;
|
||||
};
|
||||
|
||||
const makeConfig = (config: TableColumnConfig, row: any) => {
|
||||
const makeConfig = (config: TableColumnConfig, row: any): TableColumnConfig => {
|
||||
const newConfig = cloneDeep(config);
|
||||
if (typeof config.itemsFunction === 'function') {
|
||||
newConfig.items = config.itemsFunction(row);
|
||||
@ -199,7 +199,7 @@ export const useTableColumns = (
|
||||
disabled: props.disabled,
|
||||
prop: getProp($index),
|
||||
rules: column.rules,
|
||||
config: makeConfig(column, row),
|
||||
config: makeConfig(column, row) as FormItemConfig,
|
||||
model: row,
|
||||
lastValues: lastData.value[$index],
|
||||
isCompare: props.isCompare,
|
||||
|
||||
@ -23,13 +23,12 @@ import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import { getValueByKeyPath } from '@tmagic/utils';
|
||||
|
||||
import {
|
||||
import type {
|
||||
ChildConfig,
|
||||
ContainerCommonConfig,
|
||||
DaterangeConfig,
|
||||
FilterFunction,
|
||||
FormConfig,
|
||||
FormItem,
|
||||
FormState,
|
||||
FormValue,
|
||||
HtmlField,
|
||||
@ -120,7 +119,8 @@ const initValueItem = function (
|
||||
) {
|
||||
const { items } = item as ContainerCommonConfig;
|
||||
const { names } = item as DaterangeConfig;
|
||||
const { type, name } = item as FormItem;
|
||||
const type = 'type' in item ? item.type : '';
|
||||
const { name } = item;
|
||||
|
||||
if (isTableSelect(type) && name) {
|
||||
value[name] = initValue[name] ?? '';
|
||||
@ -172,8 +172,8 @@ export const createValues = function (
|
||||
value: FormValue = {},
|
||||
) {
|
||||
if (Array.isArray(config)) {
|
||||
config.forEach((item: ChildConfig | TabPaneConfig) => {
|
||||
initValueItem(mForm, item, initValue, value);
|
||||
config.forEach((item) => {
|
||||
initValueItem(mForm, item as ChildConfig | TabPaneConfig, initValue, value);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<MForm
|
||||
v-else-if="(config.type || config.editInlineFormConfig) && editState[index]"
|
||||
label-width="0"
|
||||
:config="config.editInlineFormConfig ?? [config]"
|
||||
:config="config.editInlineFormConfig ?? [config as FormItemConfig]"
|
||||
:init-values="editState[index]"
|
||||
@change="formChangeHandler"
|
||||
></MForm>
|
||||
@ -46,7 +46,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { TMagicButton, TMagicTag, TMagicTooltip } from '@tmagic/design';
|
||||
import { type ContainerChangeEventData, MForm } from '@tmagic/form';
|
||||
import type { FormValue } from '@tmagic/form-schema';
|
||||
import type { FormItemConfig, FormValue } from '@tmagic/form-schema';
|
||||
import { setValueByKeyPath } from '@tmagic/utils';
|
||||
|
||||
import { ColumnConfig } from './schema';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user