feat: 支持迭代器容器
This commit is contained in:
@@ -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);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -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: '操作',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -640,7 +640,9 @@ export interface DataSourceFieldSelectConfig extends FormItem {
|
||||
* value: 要编译(数据源data[`${filed}`])
|
||||
* */
|
||||
value?: 'key' | 'value';
|
||||
fieldType?: DataSourceFieldType;
|
||||
/** 是否严格的遵守父子节点不互相关联 */
|
||||
checkStrictly?: boolean;
|
||||
fieldType?: DataSourceFieldType[];
|
||||
}
|
||||
|
||||
/** 可新增的数据源类型选项 */
|
||||
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user