1
0
mirror of synced 2026-04-03 22:48:36 +08:00

feat: 支持迭代器容器

This commit is contained in:
roymondchen
2024-03-07 16:56:05 +08:00
parent 6dbac52c50
commit e692e01c4f
35 changed files with 1008 additions and 111 deletions

View File

@@ -1,23 +1,32 @@
<template>
<m-form-container
:config="{
...config,
...cascaderConfig,
}"
<MCascader
:config="cascaderConfig"
:model="model"
:name="name"
:disabled="disabled"
:size="size"
:last-values="lastValues"
:init-values="initValues"
:values="values"
:prop="`${prop}${prop ? '.' : ''}${name}`"
@change="onChangeHandler"
></m-form-container>
></MCascader>
</template>
<script setup lang="ts">
import { computed, inject } from 'vue';
import type { CascaderOption, FieldProps } from '@tmagic/form';
import type { DataSchema } from '@tmagic/schema';
import type { CascaderConfig, CascaderOption, FieldProps } from '@tmagic/form';
import { MCascader } from '@tmagic/form';
import type { DataSchema, DataSourceFieldType } from '@tmagic/schema';
import { DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX } from '@tmagic/utils';
import type { DataSourceFieldSelectConfig, Services } from '@editor/type';
defineOptions({
name: 'MEditorDataSourceFieldSelect',
});
const services = inject<Services>('services');
const emit = defineEmits(['change']);
@@ -27,29 +36,31 @@ const props = withDefaults(defineProps<FieldProps<DataSourceFieldSelectConfig>>(
const dataSources = computed(() => services?.dataSourceService.get('dataSources'));
const getOptionChildren = (fields: DataSchema[] = []): CascaderOption[] =>
fields.map((field) => ({
label: field.title || field.name,
value: field.name,
children: field.type === 'array' ? [] : getOptionChildren(field.fields),
}));
const getOptionChildren = (fields: DataSchema[] = [], fieldType: DataSourceFieldType[] = []): CascaderOption[] =>
fields
.filter((field) => !fieldType.length || fieldType.includes(field.type || 'string') || field.type === 'object')
.map((field) => ({
label: field.title || field.name,
value: field.name,
children: field.type === 'array' ? [] : getOptionChildren(field.fields, fieldType),
}));
const cascaderConfig = computed(() => {
const cascaderConfig = computed<CascaderConfig>(() => {
const valueIsKey = props.config.value === 'key';
return {
type: 'cascader',
name: props.name,
checkStrictly: !valueIsKey,
text: '',
options: () =>
dataSources.value
?.filter((ds) => ds.fields?.length)
?.map((ds) => ({
checkStrictly: props.config.checkStrictly ?? !valueIsKey,
popperClass: 'm-editor-data-source-field-select-popper',
options: () => {
const options =
dataSources.value?.map((ds) => ({
label: ds.title || ds.id,
value: valueIsKey ? ds.id : `${DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX}${ds.id}`,
children: getOptionChildren(ds.fields),
})) || [],
children: getOptionChildren(ds.fields, props.config.fieldType),
})) || [];
return options.filter((option) => option.children.length);
},
};
});

View File

@@ -37,7 +37,7 @@ import { computed, inject, ref } from 'vue';
import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
import { type FieldProps, type FormConfig, type FormState, MFormDrawer } from '@tmagic/form';
import type { DataSchema } from '@tmagic/schema';
import { MagicTable } from '@tmagic/table';
import { type ColumnConfig, MagicTable } from '@tmagic/table';
import { getDefaultValueFromFields } from '@tmagic/utils';
import type { Services } from '@editor/type';
@@ -86,7 +86,7 @@ const fieldChange = ({ index, ...value }: Record<string, any>) => {
emit('change', props.model[props.name]);
};
const fieldColumns = [
const fieldColumns: ColumnConfig[] = [
{
label: '属性名称',
prop: 'title',
@@ -102,6 +102,13 @@ const fieldColumns = [
{
label: '默认值',
prop: 'defaultValue',
formatter(item, row) {
try {
return JSON.stringify(row.defaultValue);
} catch (e) {
return row.defaultValue;
}
},
},
{
label: '操作',

View File

@@ -24,7 +24,7 @@
import { TMagicButton } from '@tmagic/design';
import type { FieldProps } from '@tmagic/form';
import type { CodeBlockContent } from '@tmagic/schema';
import { MagicTable } from '@tmagic/table';
import { type ColumnConfig, MagicTable } from '@tmagic/table';
import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
import { useDataSourceMethod } from '@editor/hooks/use-data-source-method';
@@ -49,7 +49,7 @@ const emit = defineEmits(['change']);
const { codeConfig, codeBlockEditor, createCode, editCode, deleteCode, submitCode } = useDataSourceMethod();
const methodColumns = [
const methodColumns: ColumnConfig[] = [
{
label: '名称',
prop: 'name',

View File

@@ -26,7 +26,7 @@ import { computed, inject, ref } from 'vue';
import { TMagicButton, tMagicMessageBox, TMagicSwitch } from '@tmagic/design';
import { type FieldProps, type FormConfig, type FormState, MFormDrawer } from '@tmagic/form';
import type { MockSchema } from '@tmagic/schema';
import { MagicTable } from '@tmagic/table';
import { type ColumnConfig, MagicTable } from '@tmagic/table';
import { getDefaultValueFromFields } from '@tmagic/utils';
import CodeEditor from '@editor/layouts/CodeEditor.vue';
@@ -117,7 +117,7 @@ const formConfig: FormConfig = [
},
];
const columns = [
const columns: ColumnConfig[] = [
{
type: 'expand',
component: CodeEditor,

View File

@@ -640,7 +640,9 @@ export interface DataSourceFieldSelectConfig extends FormItem {
* value: 要编译数据源data[`${filed}`]
* */
value?: 'key' | 'value';
fieldType?: DataSourceFieldType;
/** 是否严格的遵守父子节点不互相关联 */
checkStrictly?: boolean;
fieldType?: DataSourceFieldType[];
}
/** 可新增的数据源类型选项 */

View File

@@ -91,6 +91,19 @@ export const styleTabConfig: TabPaneConfig = {
name: 'height',
text: '高度',
},
{
text: 'overflow',
name: 'overflow',
type: 'select',
options: [
{ text: 'visible', value: 'visible' },
{ text: 'hidden', value: 'hidden' },
{ text: 'clip', value: 'clip' },
{ text: 'scroll', value: 'scroll' },
{ text: 'auto', value: 'auto' },
{ text: 'overlay', value: 'overlay' },
],
},
],
},
{
@@ -247,15 +260,23 @@ export const displayTabConfig: TabPaneConfig = {
name: 'field',
value: 'key',
label: '字段',
checkStrictly: false,
fieldType: ['string', 'number', 'boolean', 'any'],
},
{
type: 'select',
options: (mForm, { model }) => {
const [id, field] = model.field;
const [id, ...fieldNames] = model.field;
const ds = dataSourceService.getDataSourceById(id);
const type = ds?.fields.find((f) => f.name === field)?.type;
let fields = ds?.fields || [];
let type = '';
(fieldNames || []).forEach((fieldName: string) => {
const field = fields.find((f) => f.name === fieldName);
fields = field?.fields || [];
type = field?.type || '';
});
if (type === 'array') {
return arrayOptions;
@@ -287,11 +308,17 @@ export const displayTabConfig: TabPaneConfig = {
{
name: 'value',
type: (mForm, { model }) => {
const [id, field] = model.field;
const [id, ...fieldNames] = model.field;
const ds = dataSourceService.getDataSourceById(id);
const type = ds?.fields.find((f) => f.name === field)?.type;
let fields = ds?.fields || [];
let type = '';
(fieldNames || []).forEach((fieldName: string) => {
const field = fields.find((f) => f.name === fieldName);
fields = field?.fields || [];
type = field?.type || '';
});
if (type === 'number') {
return 'number';