mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-04-29 15:04:05 +08:00
refactor(form): 重构 table/group-list 目录结构与新增行逻辑
- 将 table 相关文件迁移至 containers/table 与 containers/table-group-list 目录 - 将新增行处理统一上移至 TableGroupList,通过 add 事件触发 - 抽取 TableGroupListCommonConfig 公共配置类型 - useFullscreen 内聚管理 zIndex - TableColumnConfig 支持 text 作为 label 别名 Made-with: Cursor
This commit is contained in:
parent
b5af91f86c
commit
3c41091f96
@ -1,11 +1,11 @@
|
|||||||
import type { DataSchema, DataSourceFieldType, DataSourceSchema } from '@tmagic/core';
|
import type { DataSchema, DataSourceFieldType, DataSourceSchema } from '@tmagic/core';
|
||||||
import { type CascaderOption, defineFormItem, type FormConfig } from '@tmagic/form';
|
import { type CascaderOption, type FormConfig, type TabConfig } from '@tmagic/form';
|
||||||
import { dataSourceTemplateRegExp, getKeysArray, isNumber } from '@tmagic/utils';
|
import { dataSourceTemplateRegExp, getKeysArray, isNumber } from '@tmagic/utils';
|
||||||
|
|
||||||
import BaseFormConfig from './formConfigs/base';
|
import BaseFormConfig from './formConfigs/base';
|
||||||
import HttpFormConfig from './formConfigs/http';
|
import HttpFormConfig from './formConfigs/http';
|
||||||
|
|
||||||
const dataSourceFormConfig = defineFormItem({
|
const dataSourceFormConfig: TabConfig = {
|
||||||
type: 'tab',
|
type: 'tab',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -73,9 +73,13 @@ const dataSourceFormConfig = defineFormItem({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
};
|
||||||
|
|
||||||
const fillConfig = (config: FormConfig): FormConfig => [...BaseFormConfig(), ...config, dataSourceFormConfig];
|
const fillConfig = <T = never>(config: FormConfig<T>): FormConfig<T> => [
|
||||||
|
...BaseFormConfig(),
|
||||||
|
...config,
|
||||||
|
dataSourceFormConfig,
|
||||||
|
];
|
||||||
|
|
||||||
export const getFormConfig = (type: string, configs: Record<string, FormConfig>): FormConfig => {
|
export const getFormConfig = (type: string, configs: Record<string, FormConfig>): FormConfig => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
@ -701,28 +701,43 @@ export interface PanelConfig<T = never> extends FormItem, ContainerCommonConfig<
|
|||||||
schematic?: string;
|
schematic?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TableColumnConfig extends FormItem {
|
export interface TableGroupListCommonConfig extends FormItem {
|
||||||
|
type: 'table' | 'groupList' | 'group-list';
|
||||||
|
enableToggleMode?: boolean;
|
||||||
|
/** 最大行数 */
|
||||||
|
max?: number;
|
||||||
|
enum?: any[];
|
||||||
|
/** 是否显示添加按钮 */
|
||||||
|
addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
||||||
|
/** 新增的默认行,可以是函数动态生成或静态对象 */
|
||||||
|
defaultAdd?: ((mForm: FormState | undefined, data: any) => any) | Record<string, any>;
|
||||||
|
/** table 新增行时前置回调 */
|
||||||
|
beforeAddRow?: (mForm: FormState | undefined, data: any) => boolean | Promise<boolean>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TableColumnConfig<T = never> extends FormItem {
|
||||||
name?: string;
|
name?: string;
|
||||||
label: string;
|
label?: string;
|
||||||
|
text?: string;
|
||||||
width?: string | number;
|
width?: string | number;
|
||||||
sortable?: boolean;
|
sortable?: boolean;
|
||||||
items?: FormConfig;
|
items?: FormConfig<T>;
|
||||||
itemsFunction?: (row: any) => FormConfig;
|
itemsFunction?: (row: any) => FormConfig<T>;
|
||||||
titleTip?: FilterFunction<string>;
|
titleTip?: FilterFunction<string>;
|
||||||
type?: string;
|
type?: string;
|
||||||
|
addButtonConfig?: {
|
||||||
|
props?: Record<string, any>;
|
||||||
|
text?: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表格容器
|
* 表格容器
|
||||||
*/
|
*/
|
||||||
export interface TableConfig extends FormItem {
|
export interface TableConfig<T = never> extends TableGroupListCommonConfig {
|
||||||
type: 'table' | 'groupList' | 'group-list';
|
items: TableColumnConfig<T>[];
|
||||||
items: TableColumnConfig[];
|
tableItems?: TableColumnConfig<T>[];
|
||||||
tableItems?: TableColumnConfig[];
|
groupItems?: TableColumnConfig<T>[];
|
||||||
groupItems?: TableColumnConfig[];
|
|
||||||
enableToggleMode?: boolean;
|
|
||||||
/** 最大行数 */
|
|
||||||
max?: number;
|
|
||||||
/** 最大高度 */
|
/** 最大高度 */
|
||||||
maxHeight?: number | string;
|
maxHeight?: number | string;
|
||||||
border?: boolean;
|
border?: boolean;
|
||||||
@ -731,9 +746,6 @@ export interface TableConfig extends FormItem {
|
|||||||
/** 操作栏宽度 */
|
/** 操作栏宽度 */
|
||||||
operateColWidth?: number | string;
|
operateColWidth?: number | string;
|
||||||
pagination?: boolean;
|
pagination?: boolean;
|
||||||
enum?: any[];
|
|
||||||
/** 是否显示添加按钮 */
|
|
||||||
addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
|
||||||
/** 是否显示删除按钮 */
|
/** 是否显示删除按钮 */
|
||||||
delete?: (model: any, index: number, values: any) => boolean | boolean;
|
delete?: (model: any, index: number, values: any) => boolean | boolean;
|
||||||
copyable?: (model: any, data: any) => boolean | boolean;
|
copyable?: (model: any, data: any) => boolean | boolean;
|
||||||
@ -741,8 +753,6 @@ export interface TableConfig extends FormItem {
|
|||||||
importable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
importable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
||||||
/** 是否显示checkbox */
|
/** 是否显示checkbox */
|
||||||
selection?: (mForm: FormState | undefined, data: any) => boolean | boolean | 'single';
|
selection?: (mForm: FormState | undefined, data: any) => boolean | boolean | 'single';
|
||||||
/** 新增的默认行,可以是函数动态生成或静态对象 */
|
|
||||||
defaultAdd?: ((mForm: FormState | undefined, data: any) => any) | Record<string, any>;
|
|
||||||
copyHandler?: (mForm: FormState | undefined, data: any) => any;
|
copyHandler?: (mForm: FormState | undefined, data: any) => any;
|
||||||
onSelect?: (mForm: FormState | undefined, data: any) => any;
|
onSelect?: (mForm: FormState | undefined, data: any) => any;
|
||||||
/** @deprecated 请使用 defaultSort */
|
/** @deprecated 请使用 defaultSort */
|
||||||
@ -760,20 +770,12 @@ export interface TableConfig extends FormItem {
|
|||||||
itemExtra?: string | FilterFunction<string>;
|
itemExtra?: string | FilterFunction<string>;
|
||||||
titleTip?: FilterFunction<string>;
|
titleTip?: FilterFunction<string>;
|
||||||
rowKey?: string;
|
rowKey?: string;
|
||||||
/** table 新增行时前置回调 */
|
|
||||||
beforeAddRow?: (mForm: FormState | undefined, data: any) => boolean | Promise<boolean>;
|
|
||||||
addButtonConfig?: {
|
|
||||||
props?: Record<string, any>;
|
|
||||||
text?: string;
|
|
||||||
};
|
|
||||||
sort?: boolean;
|
sort?: boolean;
|
||||||
sortKey?: string;
|
sortKey?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GroupListConfig<T = never> extends FormItem {
|
export interface GroupListConfig<T = never> extends TableGroupListCommonConfig {
|
||||||
type: 'table' | 'groupList' | 'group-list';
|
|
||||||
span?: number;
|
span?: number;
|
||||||
enableToggleMode?: boolean;
|
|
||||||
items: FormConfig<T>;
|
items: FormConfig<T>;
|
||||||
groupItems?: FormConfig<T>;
|
groupItems?: FormConfig<T>;
|
||||||
tableItems?: FormConfig<T>;
|
tableItems?: FormConfig<T>;
|
||||||
@ -788,9 +790,6 @@ export interface GroupListConfig<T = never> extends FormItem {
|
|||||||
* 当未设置时,默认展开第一项
|
* 当未设置时,默认展开第一项
|
||||||
*/
|
*/
|
||||||
defaultExpandQuantity?: number;
|
defaultExpandQuantity?: number;
|
||||||
addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
|
||||||
/** 新增的默认值,可以是函数动态生成或静态对象 */
|
|
||||||
defaultAdd?: ((mForm: FormState | undefined, data: any) => any) | Record<string, any>;
|
|
||||||
delete?: (model: any, index: number | string | symbol, values: any) => boolean | boolean;
|
delete?: (model: any, index: number | string | symbol, values: any) => boolean | boolean;
|
||||||
copyable?: FilterFunction<boolean>;
|
copyable?: FilterFunction<boolean>;
|
||||||
movable?: (
|
movable?: (
|
||||||
@ -800,13 +799,6 @@ export interface GroupListConfig<T = never> extends FormItem {
|
|||||||
groupModel: any,
|
groupModel: any,
|
||||||
) => boolean | boolean;
|
) => boolean | boolean;
|
||||||
moveSpecifyLocation?: boolean;
|
moveSpecifyLocation?: boolean;
|
||||||
addButtonConfig?: {
|
|
||||||
props?: Record<string, any>;
|
|
||||||
text?: string;
|
|
||||||
};
|
|
||||||
/** 最大行数 */
|
|
||||||
max?: number;
|
|
||||||
beforeAddRow?: (mForm: FormState | undefined, data: any) => boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StepItemConfig<T = never> extends FormItem, ContainerCommonConfig<T> {
|
interface StepItemConfig<T = never> extends FormItem, ContainerCommonConfig<T> {
|
||||||
|
|||||||
@ -29,20 +29,16 @@
|
|||||||
<div class="m-fields-group-list-footer">
|
<div class="m-fields-group-list-footer">
|
||||||
<slot name="toggle-button"></slot>
|
<slot name="toggle-button"></slot>
|
||||||
<div style="display: flex; justify-content: flex-end; flex: 1">
|
<div style="display: flex; justify-content: flex-end; flex: 1">
|
||||||
<slot name="add-button" :trigger="addHandler"></slot>
|
<slot name="add-button"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { inject } from 'vue';
|
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
import { tMagicMessage } from '@tmagic/design';
|
import type { ContainerChangeEventData, GroupListConfig } from '../schema';
|
||||||
|
|
||||||
import type { ContainerChangeEventData, FormState, GroupListConfig } from '../schema';
|
|
||||||
import { initValue } from '../utils/form';
|
|
||||||
|
|
||||||
import MFieldsGroupListItem from './GroupListItem.vue';
|
import MFieldsGroupListItem from './GroupListItem.vue';
|
||||||
|
|
||||||
@ -68,59 +64,10 @@ const emit = defineEmits<{
|
|||||||
addDiffCount: [];
|
addDiffCount: [];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const mForm = inject<FormState | undefined>('mForm');
|
|
||||||
|
|
||||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
|
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
|
||||||
emit('change', props.model, eventData);
|
emit('change', props.model, eventData);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addHandler = async () => {
|
|
||||||
if (!props.name) return false;
|
|
||||||
|
|
||||||
if (props.config.max && props.model[props.name].length >= props.config.max) {
|
|
||||||
tMagicMessage.error(`最多新增配置不能超过${props.config.max}条`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof props.config.beforeAddRow === 'function') {
|
|
||||||
const beforeCheckRes = await props.config.beforeAddRow(mForm, {
|
|
||||||
model: props.model[props.name],
|
|
||||||
formValue: mForm?.values,
|
|
||||||
prop: props.prop,
|
|
||||||
});
|
|
||||||
if (!beforeCheckRes) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let initValues = {};
|
|
||||||
|
|
||||||
if (typeof props.config.defaultAdd === 'function') {
|
|
||||||
initValues = await props.config.defaultAdd(mForm, {
|
|
||||||
model: props.model[props.name],
|
|
||||||
formValue: mForm?.values,
|
|
||||||
prop: props.prop,
|
|
||||||
config: props.config,
|
|
||||||
});
|
|
||||||
} else if (props.config.defaultAdd) {
|
|
||||||
initValues = props.config.defaultAdd;
|
|
||||||
}
|
|
||||||
|
|
||||||
const groupValue = await initValue(mForm, {
|
|
||||||
config: props.config.items,
|
|
||||||
initValues,
|
|
||||||
});
|
|
||||||
|
|
||||||
props.model[props.name].push(groupValue);
|
|
||||||
|
|
||||||
emit('change', props.model[props.name], {
|
|
||||||
changeRecords: [
|
|
||||||
{
|
|
||||||
propPath: `${props.prop}.${props.model[props.name].length - 1}`,
|
|
||||||
value: groupValue,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeHandler = (index: number) => {
|
const removeHandler = (index: number) => {
|
||||||
if (!props.name) return false;
|
if (!props.name) return false;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<component
|
<component
|
||||||
:is="displayMode === 'table' ? MFormTable : MFormGroupList"
|
:is="displayMode === 'table' ? MFormTable : MFormGroupList"
|
||||||
|
ref="tableGroupList"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
:model="model"
|
:model="model"
|
||||||
:name="`${name}`"
|
:name="`${name}`"
|
||||||
@ -17,6 +18,7 @@
|
|||||||
@change="onChange"
|
@change="onChange"
|
||||||
@select="onSelect"
|
@select="onSelect"
|
||||||
@addDiffCount="onAddDiffCount"
|
@addDiffCount="onAddDiffCount"
|
||||||
|
@add="onAdd"
|
||||||
>
|
>
|
||||||
<template #toggle-button>
|
<template #toggle-button>
|
||||||
<TMagicButton
|
<TMagicButton
|
||||||
@ -29,16 +31,15 @@
|
|||||||
</TMagicButton>
|
</TMagicButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #add-button="{ trigger }">
|
<template #add-button v-if="addable">
|
||||||
<TMagicButton
|
<TMagicButton
|
||||||
v-if="addable"
|
|
||||||
:class="displayMode === 'table' ? 'm-form-table-add-button' : ''"
|
:class="displayMode === 'table' ? 'm-form-table-add-button' : ''"
|
||||||
:size="addButtonSize"
|
:size="addButtonSize"
|
||||||
:plain="displayMode === 'table'"
|
:plain="displayMode === 'table'"
|
||||||
:icon="Plus"
|
:icon="Plus"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
v-bind="currentConfig.addButtonConfig?.props || { type: 'primary' }"
|
v-bind="currentConfig.addButtonConfig?.props || { type: 'primary' }"
|
||||||
@click="trigger"
|
@click="newHandler"
|
||||||
>
|
>
|
||||||
{{ currentConfig.addButtonConfig?.text || (displayMode === 'table' ? '新增一行' : '新增') }}
|
{{ currentConfig.addButtonConfig?.text || (displayMode === 'table' ? '新增一行' : '新增') }}
|
||||||
</TMagicButton>
|
</TMagicButton>
|
||||||
@ -47,16 +48,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, inject, ref } from 'vue';
|
import { computed, ref, useTemplateRef } from 'vue';
|
||||||
import { Grid, Plus } from '@element-plus/icons-vue';
|
import { Grid, Plus } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
import { TMagicButton } from '@tmagic/design';
|
import { TMagicButton } from '@tmagic/design';
|
||||||
import type { FormState, GroupListConfig, TableConfig } from '@tmagic/form-schema';
|
import type { GroupListConfig, TableConfig } from '@tmagic/form-schema';
|
||||||
|
|
||||||
import type { ContainerChangeEventData } from '../schema';
|
import type { ContainerChangeEventData } from '../../schema';
|
||||||
|
import MFormGroupList from '../GroupList.vue';
|
||||||
import MFormTable from '../table/Table.vue';
|
import MFormTable from '../table/Table.vue';
|
||||||
|
|
||||||
import MFormGroupList from './GroupList.vue';
|
import { useAdd } from './useAdd';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'MFormTableGroupList',
|
name: 'MFormTableGroupList',
|
||||||
@ -81,28 +83,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const emit = defineEmits(['change', 'select', 'addDiffCount']);
|
const emit = defineEmits(['change', 'select', 'addDiffCount']);
|
||||||
|
|
||||||
const mForm = inject<FormState | undefined>('mForm');
|
const { addable, newHandler } = useAdd(props, emit);
|
||||||
|
|
||||||
const addable = computed(() => {
|
|
||||||
const modelName = props.name || props.config.name || '';
|
|
||||||
|
|
||||||
if (!modelName) return false;
|
|
||||||
|
|
||||||
if (!props.model[modelName].length) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof props.config.addable === 'function') {
|
|
||||||
return props.config.addable(mForm, {
|
|
||||||
model: props.model[modelName],
|
|
||||||
formValue: mForm?.values,
|
|
||||||
prop: props.prop,
|
|
||||||
config: props.config,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return typeof props.config.addable === 'undefined' ? true : props.config.addable;
|
|
||||||
});
|
|
||||||
|
|
||||||
const isGroupListType = (type: string | undefined) => type === 'groupList' || type === 'group-list';
|
const isGroupListType = (type: string | undefined) => type === 'groupList' || type === 'group-list';
|
||||||
|
|
||||||
@ -178,4 +159,15 @@ const toggleDisplayMode = () => {
|
|||||||
const onChange = (v: any, eventData?: ContainerChangeEventData) => emit('change', v, eventData);
|
const onChange = (v: any, eventData?: ContainerChangeEventData) => emit('change', v, eventData);
|
||||||
const onSelect = (...args: any[]) => emit('select', ...args);
|
const onSelect = (...args: any[]) => emit('select', ...args);
|
||||||
const onAddDiffCount = () => emit('addDiffCount');
|
const onAddDiffCount = () => emit('addDiffCount');
|
||||||
|
const onAdd = (rows: any[]) => {
|
||||||
|
rows.forEach((row: any) => {
|
||||||
|
newHandler(row);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableGroupListRef = useTemplateRef<InstanceType<typeof MFormTable>>('tableGroupList');
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
toggleRowSelection: (row: any, selected: boolean) => tableGroupListRef.value?.toggleRowSelection?.(row, selected),
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -1,18 +1,43 @@
|
|||||||
import { inject } from 'vue';
|
import { computed, inject } from 'vue';
|
||||||
|
|
||||||
import { tMagicMessage } from '@tmagic/design';
|
import { tMagicMessage } from '@tmagic/design';
|
||||||
import type { FormConfig, FormState } from '@tmagic/form-schema';
|
import type { FormConfig, FormState, TableConfig, TableGroupListCommonConfig } from '@tmagic/form-schema';
|
||||||
|
|
||||||
import { initValue } from '../utils/form';
|
import { initValue } from '../../utils/form';
|
||||||
|
import type { TableProps } from '../table/type';
|
||||||
import type { TableProps } from './type';
|
|
||||||
|
|
||||||
export const useAdd = (
|
export const useAdd = (
|
||||||
props: TableProps,
|
props: Pick<TableProps, 'name' | 'model' | 'prop' | 'sortKey'> & {
|
||||||
emit: (event: 'select' | 'change' | 'addDiffCount', ...args: any[]) => void,
|
config: Pick<TableGroupListCommonConfig, 'addable' | 'max' | 'beforeAddRow' | 'defaultAdd' | 'enum'> &
|
||||||
|
Pick<TableConfig, 'key' | 'name'> & {
|
||||||
|
items: { name?: string | number }[];
|
||||||
|
};
|
||||||
|
},
|
||||||
|
emit: (event: 'change', ...args: any[]) => void,
|
||||||
) => {
|
) => {
|
||||||
const mForm = inject<FormState | undefined>('mForm');
|
const mForm = inject<FormState | undefined>('mForm');
|
||||||
|
|
||||||
|
const addable = computed(() => {
|
||||||
|
const modelName = props.name || props.config.name || '';
|
||||||
|
|
||||||
|
if (!modelName) return false;
|
||||||
|
|
||||||
|
if (!props.model[modelName].length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof props.config.addable === 'function') {
|
||||||
|
return props.config.addable(mForm, {
|
||||||
|
model: props.model[modelName],
|
||||||
|
formValue: mForm?.values,
|
||||||
|
prop: props.prop,
|
||||||
|
config: props.config,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeof props.config.addable === 'undefined' ? true : props.config.addable;
|
||||||
|
});
|
||||||
|
|
||||||
const newHandler = async (row?: any) => {
|
const newHandler = async (row?: any) => {
|
||||||
const modelName = props.name || props.config.name || '';
|
const modelName = props.name || props.config.name || '';
|
||||||
|
|
||||||
@ -91,6 +116,7 @@ export const useAdd = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
addable,
|
||||||
newHandler,
|
newHandler,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -38,7 +38,7 @@ import { cloneDeep } from 'lodash-es';
|
|||||||
|
|
||||||
import { TMagicButton, TMagicTooltip } from '@tmagic/design';
|
import { TMagicButton, TMagicTooltip } from '@tmagic/design';
|
||||||
|
|
||||||
import type { FormState, TableConfig } from '../schema';
|
import type { FormState, TableConfig } from '../../schema';
|
||||||
|
|
||||||
const emit = defineEmits(['change']);
|
const emit = defineEmits(['change']);
|
||||||
|
|
||||||
@ -58,7 +58,7 @@
|
|||||||
>清空</TMagicButton
|
>清空</TMagicButton
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<slot name="add-button" :trigger="newHandler"></slot>
|
<slot name="add-button"></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bottom" style="text-align: right" v-if="config.pagination">
|
<div class="bottom" style="text-align: right" v-if="config.pagination">
|
||||||
@ -80,16 +80,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, useTemplateRef, watch } from 'vue';
|
import { computed, ref, useTemplateRef } from 'vue';
|
||||||
import { FullScreen } from '@element-plus/icons-vue';
|
import { FullScreen } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
import { TMagicButton, TMagicPagination, TMagicTable, TMagicTooltip, TMagicUpload, useZIndex } from '@tmagic/design';
|
import { TMagicButton, TMagicPagination, TMagicTable, TMagicTooltip, TMagicUpload } from '@tmagic/design';
|
||||||
|
|
||||||
import type { SortProp } from '../schema';
|
import type { SortProp } from '../../schema';
|
||||||
import { sortChange } from '../utils/form';
|
import { sortChange } from '../../utils/form';
|
||||||
|
|
||||||
import type { TableProps } from './type';
|
import type { TableProps } from './type';
|
||||||
import { useAdd } from './useAdd';
|
|
||||||
import { useFullscreen } from './useFullscreen';
|
import { useFullscreen } from './useFullscreen';
|
||||||
import { useImport } from './useImport';
|
import { useImport } from './useImport';
|
||||||
import { usePagination } from './usePagination';
|
import { usePagination } from './usePagination';
|
||||||
@ -109,7 +108,7 @@ const props = withDefaults(defineProps<TableProps>(), {
|
|||||||
isCompare: false,
|
isCompare: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['change', 'select', 'addDiffCount']);
|
const emit = defineEmits(['change', 'select', 'addDiffCount', 'add']);
|
||||||
|
|
||||||
const modelName = computed(() => props.name || props.config.name || '');
|
const modelName = computed(() => props.name || props.config.name || '');
|
||||||
const tMagicTableRef = useTemplateRef<InstanceType<typeof TMagicTable>>('tMagicTable');
|
const tMagicTableRef = useTemplateRef<InstanceType<typeof TMagicTable>>('tMagicTable');
|
||||||
@ -119,22 +118,13 @@ const { pageSize, currentPage, paginationData, handleSizeChange, handleCurrentCh
|
|||||||
modelName,
|
modelName,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { nextZIndex } = useZIndex();
|
|
||||||
const updateKey = ref(1);
|
const updateKey = ref(1);
|
||||||
const fullscreenZIndex = ref(nextZIndex());
|
|
||||||
|
|
||||||
const { newHandler } = useAdd(props, emit);
|
|
||||||
const { columns } = useTableColumns(props, emit, currentPage, pageSize, modelName);
|
const { columns } = useTableColumns(props, emit, currentPage, pageSize, modelName);
|
||||||
useSortable(props, emit, tMagicTableRef, modelName, updateKey);
|
useSortable(props, emit, tMagicTableRef, modelName, updateKey);
|
||||||
const { isFullscreen, toggleFullscreen } = useFullscreen();
|
const { isFullscreen, fullscreenZIndex, toggleFullscreen } = useFullscreen();
|
||||||
|
|
||||||
watch(isFullscreen, (value) => {
|
const { importable, excelHandler, clearHandler } = useImport(props, emit);
|
||||||
if (value) {
|
|
||||||
fullscreenZIndex.value = nextZIndex();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const { importable, excelHandler, clearHandler } = useImport(props, emit, newHandler);
|
|
||||||
const { selectHandle, toggleRowSelection } = useSelection(props, emit, tMagicTableRef);
|
const { selectHandle, toggleRowSelection } = useSelection(props, emit, tMagicTableRef);
|
||||||
|
|
||||||
const data = computed(() => (props.config.pagination ? paginationData.value : props.model[modelName.value]));
|
const data = computed(() => (props.config.pagination ? paginationData.value : props.model[modelName.value]));
|
||||||
31
packages/form/src/containers/table/useFullscreen.ts
Normal file
31
packages/form/src/containers/table/useFullscreen.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import { useZIndex } from '@tmagic/design';
|
||||||
|
|
||||||
|
export const useFullscreen = () => {
|
||||||
|
const { nextZIndex } = useZIndex();
|
||||||
|
|
||||||
|
const fullscreenZIndex = ref(nextZIndex());
|
||||||
|
|
||||||
|
const isFullscreen = ref(false);
|
||||||
|
|
||||||
|
const toggleFullscreen = () => {
|
||||||
|
if (isFullscreen.value) {
|
||||||
|
isFullscreen.value = false;
|
||||||
|
} else {
|
||||||
|
isFullscreen.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(isFullscreen, (value) => {
|
||||||
|
if (value) {
|
||||||
|
fullscreenZIndex.value = nextZIndex();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
isFullscreen,
|
||||||
|
fullscreenZIndex,
|
||||||
|
toggleFullscreen,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -8,8 +8,7 @@ import type { TableProps } from './type';
|
|||||||
|
|
||||||
export const useImport = (
|
export const useImport = (
|
||||||
props: TableProps,
|
props: TableProps,
|
||||||
emit: (event: 'select' | 'change' | 'addDiffCount', ...args: any[]) => void,
|
emit: (event: 'select' | 'change' | 'addDiffCount' | 'add', ...args: any[]) => void,
|
||||||
newHandler: (row: any) => void,
|
|
||||||
) => {
|
) => {
|
||||||
const mForm = inject<FormState | undefined>('mForm');
|
const mForm = inject<FormState | undefined>('mForm');
|
||||||
const modelName = computed(() => props.name || props.config.name || '');
|
const modelName = computed(() => props.name || props.config.name || '');
|
||||||
@ -41,9 +40,7 @@ export const useImport = (
|
|||||||
pdata.SheetNames.forEach((sheetName: string) => {
|
pdata.SheetNames.forEach((sheetName: string) => {
|
||||||
const arr = (globalThis as any).XLSX.utils.sheet_to_json(pdata.Sheets[sheetName], { header: 1 });
|
const arr = (globalThis as any).XLSX.utils.sheet_to_json(pdata.Sheets[sheetName], { header: 1 });
|
||||||
if (arr?.[0]) {
|
if (arr?.[0]) {
|
||||||
arr.forEach((row: any) => {
|
emit('add', arr);
|
||||||
newHandler(row);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
excelBtn.value?.clearFiles();
|
excelBtn.value?.clearFiles();
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { computed, type Ref, ref } from 'vue';
|
import { computed, type Ref, ref } from 'vue';
|
||||||
|
|
||||||
import { getDataByPage } from '../utils/form';
|
import { getDataByPage } from '../../utils/form';
|
||||||
|
|
||||||
import type { TableProps } from './type';
|
import type { TableProps } from './type';
|
||||||
|
|
||||||
@ -4,7 +4,7 @@ import type { default as SortableType, SortableEvent } from 'sortablejs';
|
|||||||
import { type TMagicTable } from '@tmagic/design';
|
import { type TMagicTable } from '@tmagic/design';
|
||||||
import type { FormState } from '@tmagic/form-schema';
|
import type { FormState } from '@tmagic/form-schema';
|
||||||
|
|
||||||
import { sortArray } from '../utils/form';
|
import { sortArray } from '../../utils/form';
|
||||||
|
|
||||||
import type { TableProps } from './type';
|
import type { TableProps } from './type';
|
||||||
|
|
||||||
@ -5,9 +5,9 @@ import { cloneDeep } from 'lodash-es';
|
|||||||
import { type TableColumnOptions, TMagicIcon, TMagicTooltip } from '@tmagic/design';
|
import { type TableColumnOptions, TMagicIcon, TMagicTooltip } from '@tmagic/design';
|
||||||
import type { FormItemConfig, 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';
|
||||||
import type { ContainerChangeEventData } from '../schema';
|
import { display as displayFunc, getDataByPage, sortArray } from '../../utils/form';
|
||||||
import { display as displayFunc, getDataByPage, sortArray } from '../utils/form';
|
import Container from '../Container.vue';
|
||||||
|
|
||||||
import ActionsColumn from './ActionsColumn.vue';
|
import ActionsColumn from './ActionsColumn.vue';
|
||||||
import SortColumn from './SortColumn.vue';
|
import SortColumn from './SortColumn.vue';
|
||||||
@ -187,7 +187,7 @@ export const useTableColumns = (
|
|||||||
columns.push({
|
columns.push({
|
||||||
props: {
|
props: {
|
||||||
prop: column.name,
|
prop: column.name,
|
||||||
label: column.label,
|
label: column.label || column.text,
|
||||||
width: column.width,
|
width: column.width,
|
||||||
sortable: column.sortable,
|
sortable: column.sortable,
|
||||||
sortOrders: ['ascending', 'descending'],
|
sortOrders: ['ascending', 'descending'],
|
||||||
@ -223,7 +223,10 @@ export const useTableColumns = (
|
|||||||
gap: '5px',
|
gap: '5px',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[h('span', column.label), h(TMagicIcon, {}, { default: () => h(WarningFilled) })],
|
[
|
||||||
|
h('span', column.label || column.text),
|
||||||
|
h(TMagicIcon, {}, { default: () => h(WarningFilled) }),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
content: () =>
|
content: () =>
|
||||||
h('div', {
|
h('div', {
|
||||||
@ -32,9 +32,9 @@ export { default as MFlexLayout } from './containers/FlexLayout.vue';
|
|||||||
export { default as MPanel } from './containers/Panel.vue';
|
export { default as MPanel } from './containers/Panel.vue';
|
||||||
export { default as MRow } from './containers/Row.vue';
|
export { default as MRow } from './containers/Row.vue';
|
||||||
export { default as MTabs } from './containers/Tabs.vue';
|
export { default as MTabs } from './containers/Tabs.vue';
|
||||||
export { default as MTable } from './containers/TableGroupList.vue';
|
export { default as MTable } from './containers/table-group-list/TableGroupList.vue';
|
||||||
export { default as MGroupList } from './containers/TableGroupList.vue';
|
export { default as MGroupList } from './containers/table-group-list/TableGroupList.vue';
|
||||||
export { default as MTableGroupList } from './containers/TableGroupList.vue';
|
export { default as MTableGroupList } from './containers/table-group-list/TableGroupList.vue';
|
||||||
export { default as MText } from './fields/Text.vue';
|
export { default as MText } from './fields/Text.vue';
|
||||||
export { default as MNumber } from './fields/Number.vue';
|
export { default as MNumber } from './fields/Number.vue';
|
||||||
export { default as MNumberRange } from './fields/NumberRange.vue';
|
export { default as MNumberRange } from './fields/NumberRange.vue';
|
||||||
|
|||||||
@ -24,7 +24,7 @@ import FlexLayout from './containers/FlexLayout.vue';
|
|||||||
import Panel from './containers/Panel.vue';
|
import Panel from './containers/Panel.vue';
|
||||||
import Row from './containers/Row.vue';
|
import Row from './containers/Row.vue';
|
||||||
import MStep from './containers/Step.vue';
|
import MStep from './containers/Step.vue';
|
||||||
import TableGroupList from './containers/TableGroupList.vue';
|
import TableGroupList from './containers/table-group-list/TableGroupList.vue';
|
||||||
import Tabs from './containers/Tabs.vue';
|
import Tabs from './containers/Tabs.vue';
|
||||||
import Cascader from './fields/Cascader.vue';
|
import Cascader from './fields/Cascader.vue';
|
||||||
import Checkbox from './fields/Checkbox.vue';
|
import Checkbox from './fields/Checkbox.vue';
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
export const useFullscreen = () => {
|
|
||||||
const isFullscreen = ref(false);
|
|
||||||
|
|
||||||
const toggleFullscreen = () => {
|
|
||||||
if (isFullscreen.value) {
|
|
||||||
isFullscreen.value = false;
|
|
||||||
} else {
|
|
||||||
isFullscreen.value = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
isFullscreen,
|
|
||||||
toggleFullscreen,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
Loading…
x
Reference in New Issue
Block a user