@tmagic/form 1.7.10 → 1.7.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/containers/GroupList.vue_vue_type_script_setup_true_lang.js +17 -47
- package/dist/es/containers/TableGroupList.js +5 -0
- package/dist/es/containers/TableGroupList.vue_vue_type_script_setup_true_lang.js +162 -0
- package/dist/es/index.js +2 -3
- package/dist/es/plugin.js +3 -4
- package/dist/es/table/Table.vue_vue_type_script_setup_true_lang.js +12 -53
- package/dist/es/table/useAdd.js +3 -16
- package/dist/tmagic-form.umd.cjs +182 -107
- package/package.json +6 -6
- package/src/containers/GroupList.vue +19 -41
- package/src/containers/TableGroupList.vue +181 -0
- package/src/index.ts +3 -2
- package/src/plugin.ts +3 -4
- package/src/table/Table.vue +14 -49
- package/src/table/type.ts +0 -1
- package/src/table/useAdd.ts +2 -18
- package/types/index.d.ts +243 -286
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component
|
|
3
|
+
:is="displayMode === 'table' ? MFormTable : MFormGroupList"
|
|
4
|
+
v-bind="$attrs"
|
|
5
|
+
:model="model"
|
|
6
|
+
:name="`${name}`"
|
|
7
|
+
:config="currentConfig"
|
|
8
|
+
:disabled="disabled"
|
|
9
|
+
:size="size"
|
|
10
|
+
:is-compare="isCompare"
|
|
11
|
+
:last-values="lastValues"
|
|
12
|
+
:prop="prop"
|
|
13
|
+
:label-width="labelWidth"
|
|
14
|
+
:show-index="showIndex"
|
|
15
|
+
:sort-key="sortKey"
|
|
16
|
+
:sort="sort"
|
|
17
|
+
@change="onChange"
|
|
18
|
+
@select="onSelect"
|
|
19
|
+
@addDiffCount="onAddDiffCount"
|
|
20
|
+
>
|
|
21
|
+
<template #toggle-button>
|
|
22
|
+
<TMagicButton
|
|
23
|
+
v-if="config.enableToggleMode || enableToggleMode"
|
|
24
|
+
:icon="Grid"
|
|
25
|
+
size="small"
|
|
26
|
+
@click="toggleDisplayMode"
|
|
27
|
+
>
|
|
28
|
+
{{ displayMode === 'table' ? '展开配置' : '切换为表格' }}
|
|
29
|
+
</TMagicButton>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<template #add-button="{ trigger }">
|
|
33
|
+
<TMagicButton
|
|
34
|
+
v-if="addable"
|
|
35
|
+
:class="displayMode === 'table' ? 'm-form-table-add-button' : ''"
|
|
36
|
+
:size="addButtonSize"
|
|
37
|
+
:plain="displayMode === 'table'"
|
|
38
|
+
:icon="Plus"
|
|
39
|
+
:disabled="disabled"
|
|
40
|
+
v-bind="currentConfig.addButtonConfig?.props || { type: 'primary' }"
|
|
41
|
+
@click="trigger"
|
|
42
|
+
>
|
|
43
|
+
{{ currentConfig.addButtonConfig?.text || (displayMode === 'table' ? '新增一行' : '新增') }}
|
|
44
|
+
</TMagicButton>
|
|
45
|
+
</template>
|
|
46
|
+
</component>
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
|
+
<script setup lang="ts">
|
|
50
|
+
import { computed, inject, ref } from 'vue';
|
|
51
|
+
import { Grid, Plus } from '@element-plus/icons-vue';
|
|
52
|
+
|
|
53
|
+
import { TMagicButton } from '@tmagic/design';
|
|
54
|
+
import type { FormState, GroupListConfig, TableConfig } from '@tmagic/form-schema';
|
|
55
|
+
|
|
56
|
+
import type { ContainerChangeEventData } from '../schema';
|
|
57
|
+
import MFormTable from '../table/Table.vue';
|
|
58
|
+
|
|
59
|
+
import MFormGroupList from './GroupList.vue';
|
|
60
|
+
|
|
61
|
+
defineOptions({
|
|
62
|
+
name: 'MFormTableGroupList',
|
|
63
|
+
inheritAttrs: false,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const props = defineProps<{
|
|
67
|
+
model: any;
|
|
68
|
+
lastValues?: any;
|
|
69
|
+
isCompare?: boolean;
|
|
70
|
+
config: TableConfig | GroupListConfig;
|
|
71
|
+
name: string;
|
|
72
|
+
prop?: string;
|
|
73
|
+
labelWidth?: string;
|
|
74
|
+
disabled?: boolean;
|
|
75
|
+
size?: string;
|
|
76
|
+
enableToggleMode?: true;
|
|
77
|
+
showIndex?: boolean;
|
|
78
|
+
sortKey?: string;
|
|
79
|
+
sort?: boolean;
|
|
80
|
+
}>();
|
|
81
|
+
|
|
82
|
+
const emit = defineEmits(['change', 'select', 'addDiffCount']);
|
|
83
|
+
|
|
84
|
+
const mForm = inject<FormState | undefined>('mForm');
|
|
85
|
+
|
|
86
|
+
const addable = computed(() => {
|
|
87
|
+
const modelName = props.name || props.config.name || '';
|
|
88
|
+
|
|
89
|
+
if (!modelName) return false;
|
|
90
|
+
|
|
91
|
+
if (!props.model[modelName].length) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (typeof props.config.addable === 'function') {
|
|
96
|
+
return props.config.addable(mForm, {
|
|
97
|
+
model: props.model[modelName],
|
|
98
|
+
formValue: mForm?.values,
|
|
99
|
+
prop: props.prop,
|
|
100
|
+
config: props.config,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return typeof props.config.addable === 'undefined' ? true : props.config.addable;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const isGroupListType = (type: string | undefined) => type === 'groupList' || type === 'group-list';
|
|
108
|
+
|
|
109
|
+
const displayMode = ref<'table' | 'groupList'>(isGroupListType(props.config.type) ? 'groupList' : 'table');
|
|
110
|
+
|
|
111
|
+
const calcLabelWidth = (label: string) => {
|
|
112
|
+
if (!label) return '0px';
|
|
113
|
+
const zhLength = label.match(/[^\x00-\xff]/g)?.length || 0;
|
|
114
|
+
const chLength = label.length - zhLength;
|
|
115
|
+
return `${Math.max(chLength * 8 + zhLength * 20, 80)}px`;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// 当原始 config 是 table 形态时,table 模式直接透传;
|
|
119
|
+
// 若原始是 groupList,则基于它派生出 table 所需的 config
|
|
120
|
+
const tableConfig = computed<TableConfig>(() => {
|
|
121
|
+
if (!isGroupListType(props.config.type)) {
|
|
122
|
+
return props.config as TableConfig;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const source = props.config as GroupListConfig;
|
|
126
|
+
return {
|
|
127
|
+
...props.config,
|
|
128
|
+
type: 'table',
|
|
129
|
+
groupItems: source.items,
|
|
130
|
+
items:
|
|
131
|
+
source.tableItems ||
|
|
132
|
+
(source.items as any[]).map((item: any) => ({
|
|
133
|
+
...item,
|
|
134
|
+
label: item.label || item.text,
|
|
135
|
+
text: null,
|
|
136
|
+
})),
|
|
137
|
+
} as any as TableConfig;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// 反向派生 groupList 所需的 config
|
|
141
|
+
const groupListConfig = computed<GroupListConfig>(() => {
|
|
142
|
+
if (isGroupListType(props.config.type)) {
|
|
143
|
+
return props.config as GroupListConfig;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const source = props.config as TableConfig;
|
|
147
|
+
return {
|
|
148
|
+
...props.config,
|
|
149
|
+
type: 'groupList',
|
|
150
|
+
tableItems: source.items,
|
|
151
|
+
items:
|
|
152
|
+
source.groupItems ||
|
|
153
|
+
(source.items as any[]).map((item: any) => {
|
|
154
|
+
const text = item.text || item.label;
|
|
155
|
+
return {
|
|
156
|
+
...item,
|
|
157
|
+
text,
|
|
158
|
+
labelWidth: calcLabelWidth(text),
|
|
159
|
+
span: item.span || 12,
|
|
160
|
+
};
|
|
161
|
+
}),
|
|
162
|
+
} as any as GroupListConfig;
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// 运行时类型由 displayMode 决定,`<component :is>` 无法做联合类型收窄,统一转 any 交给子组件处理
|
|
166
|
+
const currentConfig = computed<any>(() => (displayMode.value === 'table' ? tableConfig.value : groupListConfig.value));
|
|
167
|
+
|
|
168
|
+
// 保持原 Table/GroupList 模式下新增按钮的不同尺寸策略
|
|
169
|
+
const addButtonSize = computed(() => {
|
|
170
|
+
if (displayMode.value === 'table') return 'small';
|
|
171
|
+
return props.config.enableToggleMode !== false ? 'small' : 'default';
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const toggleDisplayMode = () => {
|
|
175
|
+
displayMode.value = displayMode.value === 'table' ? 'groupList' : 'table';
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const onChange = (v: any, eventData?: ContainerChangeEventData) => emit('change', v, eventData);
|
|
179
|
+
const onSelect = (...args: any[]) => emit('select', ...args);
|
|
180
|
+
const onAddDiffCount = () => emit('addDiffCount');
|
|
181
|
+
</script>
|
package/src/index.ts
CHANGED
|
@@ -32,8 +32,9 @@ export { default as MFlexLayout } from './containers/FlexLayout.vue';
|
|
|
32
32
|
export { default as MPanel } from './containers/Panel.vue';
|
|
33
33
|
export { default as MRow } from './containers/Row.vue';
|
|
34
34
|
export { default as MTabs } from './containers/Tabs.vue';
|
|
35
|
-
export { default as MTable } from './
|
|
36
|
-
export { default as MGroupList } from './containers/
|
|
35
|
+
export { default as MTable } from './containers/TableGroupList.vue';
|
|
36
|
+
export { default as MGroupList } from './containers/TableGroupList.vue';
|
|
37
|
+
export { default as MTableGroupList } from './containers/TableGroupList.vue';
|
|
37
38
|
export { default as MText } from './fields/Text.vue';
|
|
38
39
|
export { default as MNumber } from './fields/Number.vue';
|
|
39
40
|
export { default as MNumberRange } from './fields/NumberRange.vue';
|
package/src/plugin.ts
CHANGED
|
@@ -21,10 +21,10 @@ import { type App } from 'vue';
|
|
|
21
21
|
import Container from './containers/Container.vue';
|
|
22
22
|
import Fieldset from './containers/Fieldset.vue';
|
|
23
23
|
import FlexLayout from './containers/FlexLayout.vue';
|
|
24
|
-
import GroupList from './containers/GroupList.vue';
|
|
25
24
|
import Panel from './containers/Panel.vue';
|
|
26
25
|
import Row from './containers/Row.vue';
|
|
27
26
|
import MStep from './containers/Step.vue';
|
|
27
|
+
import TableGroupList from './containers/TableGroupList.vue';
|
|
28
28
|
import Tabs from './containers/Tabs.vue';
|
|
29
29
|
import Cascader from './fields/Cascader.vue';
|
|
30
30
|
import Checkbox from './fields/Checkbox.vue';
|
|
@@ -46,7 +46,6 @@ import Text from './fields/Text.vue';
|
|
|
46
46
|
import Textarea from './fields/Textarea.vue';
|
|
47
47
|
import Time from './fields/Time.vue';
|
|
48
48
|
import Timerange from './fields/Timerange.vue';
|
|
49
|
-
import Table from './table/Table.vue';
|
|
50
49
|
import { setConfig } from './utils/config';
|
|
51
50
|
import Form from './Form.vue';
|
|
52
51
|
import FormDialog from './FormDialog.vue';
|
|
@@ -70,11 +69,11 @@ export default {
|
|
|
70
69
|
app.component('m-form-dialog', FormDialog);
|
|
71
70
|
app.component('m-form-container', Container);
|
|
72
71
|
app.component('m-form-fieldset', Fieldset);
|
|
73
|
-
app.component('m-form-group-list',
|
|
72
|
+
app.component('m-form-group-list', TableGroupList);
|
|
74
73
|
app.component('m-form-panel', Panel);
|
|
75
74
|
app.component('m-form-row', Row);
|
|
76
75
|
app.component('m-form-step', MStep);
|
|
77
|
-
app.component('m-form-table',
|
|
76
|
+
app.component('m-form-table', TableGroupList);
|
|
78
77
|
app.component('m-form-tab', Tabs);
|
|
79
78
|
app.component('m-form-flex-layout', FlexLayout);
|
|
80
79
|
app.component('m-fields-text', Text);
|
package/src/table/Table.vue
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
v-bind="$attrs"
|
|
5
5
|
class="m-fields-table-wrap"
|
|
6
6
|
:class="{ fixed: isFullscreen }"
|
|
7
|
-
:style="isFullscreen ? `z-index: ${
|
|
7
|
+
:style="isFullscreen ? `z-index: ${fullscreenZIndex}` : ''"
|
|
8
8
|
>
|
|
9
9
|
<div class="m-fields-table" :class="{ 'm-fields-table-item-extra': config.itemExtra }">
|
|
10
10
|
<span v-if="config.extra" style="color: rgba(0, 0, 0, 0.45)" v-html="config.extra"></span>
|
|
@@ -34,13 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
<div style="display: flex; justify-content: space-between; margin: 10px 0">
|
|
36
36
|
<div style="display: flex">
|
|
37
|
-
<
|
|
38
|
-
:icon="Grid"
|
|
39
|
-
size="small"
|
|
40
|
-
@click="toggleMode"
|
|
41
|
-
v-if="enableToggleMode && config.enableToggleMode !== false && !isFullscreen"
|
|
42
|
-
>展开配置</TMagicButton
|
|
43
|
-
>
|
|
37
|
+
<slot name="toggle-button" v-if="!isFullscreen"></slot>
|
|
44
38
|
<TMagicButton
|
|
45
39
|
:icon="FullScreen"
|
|
46
40
|
size="small"
|
|
@@ -64,17 +58,7 @@
|
|
|
64
58
|
>清空</TMagicButton
|
|
65
59
|
>
|
|
66
60
|
</div>
|
|
67
|
-
<
|
|
68
|
-
v-if="addable"
|
|
69
|
-
class="m-form-table-add-button"
|
|
70
|
-
size="small"
|
|
71
|
-
plain
|
|
72
|
-
:icon="Plus"
|
|
73
|
-
v-bind="config.addButtonConfig?.props || { type: 'primary' }"
|
|
74
|
-
:disabled="disabled"
|
|
75
|
-
@click="newHandler()"
|
|
76
|
-
>{{ config.addButtonConfig?.text || '新增一行' }}</TMagicButton
|
|
77
|
-
>
|
|
61
|
+
<slot name="add-button" :trigger="newHandler"></slot>
|
|
78
62
|
</div>
|
|
79
63
|
|
|
80
64
|
<div class="bottom" style="text-align: right" v-if="config.pagination">
|
|
@@ -96,8 +80,8 @@
|
|
|
96
80
|
</template>
|
|
97
81
|
|
|
98
82
|
<script setup lang="ts">
|
|
99
|
-
import { computed, ref, useTemplateRef } from 'vue';
|
|
100
|
-
import { FullScreen
|
|
83
|
+
import { computed, ref, useTemplateRef, watch } from 'vue';
|
|
84
|
+
import { FullScreen } from '@element-plus/icons-vue';
|
|
101
85
|
|
|
102
86
|
import { TMagicButton, TMagicPagination, TMagicTable, TMagicTooltip, TMagicUpload, useZIndex } from '@tmagic/design';
|
|
103
87
|
|
|
@@ -120,7 +104,6 @@ defineOptions({
|
|
|
120
104
|
const props = withDefaults(defineProps<TableProps>(), {
|
|
121
105
|
prop: '',
|
|
122
106
|
sortKey: '',
|
|
123
|
-
enableToggleMode: true,
|
|
124
107
|
showIndex: true,
|
|
125
108
|
lastValues: () => ({}),
|
|
126
109
|
isCompare: false,
|
|
@@ -138,42 +121,24 @@ const { pageSize, currentPage, paginationData, handleSizeChange, handleCurrentCh
|
|
|
138
121
|
|
|
139
122
|
const { nextZIndex } = useZIndex();
|
|
140
123
|
const updateKey = ref(1);
|
|
124
|
+
const fullscreenZIndex = ref(nextZIndex());
|
|
141
125
|
|
|
142
|
-
const {
|
|
126
|
+
const { newHandler } = useAdd(props, emit);
|
|
143
127
|
const { columns } = useTableColumns(props, emit, currentPage, pageSize, modelName);
|
|
144
128
|
useSortable(props, emit, tMagicTableRef, modelName, updateKey);
|
|
145
129
|
const { isFullscreen, toggleFullscreen } = useFullscreen();
|
|
130
|
+
|
|
131
|
+
watch(isFullscreen, (value) => {
|
|
132
|
+
if (value) {
|
|
133
|
+
fullscreenZIndex.value = nextZIndex();
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
146
137
|
const { importable, excelHandler, clearHandler } = useImport(props, emit, newHandler);
|
|
147
138
|
const { selectHandle, toggleRowSelection } = useSelection(props, emit, tMagicTableRef);
|
|
148
139
|
|
|
149
140
|
const data = computed(() => (props.config.pagination ? paginationData.value : props.model[modelName.value]));
|
|
150
141
|
|
|
151
|
-
const toggleMode = () => {
|
|
152
|
-
const calcLabelWidth = (label: string) => {
|
|
153
|
-
if (!label) return '0px';
|
|
154
|
-
const zhLength = label.match(/[^\x00-\xff]/g)?.length || 0;
|
|
155
|
-
const chLength = label.length - zhLength;
|
|
156
|
-
return `${Math.max(chLength * 8 + zhLength * 20, 80)}px`;
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
// 切换为groupList的形式
|
|
160
|
-
props.config.type = 'groupList';
|
|
161
|
-
props.config.enableToggleMode = true;
|
|
162
|
-
props.config.tableItems = props.config.items;
|
|
163
|
-
props.config.items =
|
|
164
|
-
props.config.groupItems ||
|
|
165
|
-
props.config.items.map((item: any) => {
|
|
166
|
-
const text = item.text || item.label;
|
|
167
|
-
const labelWidth = calcLabelWidth(text);
|
|
168
|
-
return {
|
|
169
|
-
...item,
|
|
170
|
-
text,
|
|
171
|
-
labelWidth,
|
|
172
|
-
span: item.span || 12,
|
|
173
|
-
};
|
|
174
|
-
});
|
|
175
|
-
};
|
|
176
|
-
|
|
177
142
|
const sortChangeHandler = (sortOptions: SortProp) => {
|
|
178
143
|
const modelName = props.name || props.config.name || '';
|
|
179
144
|
sortChange(props.model[modelName], sortOptions);
|
package/src/table/type.ts
CHANGED
package/src/table/useAdd.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { inject } from 'vue';
|
|
2
2
|
|
|
3
3
|
import { tMagicMessage } from '@tmagic/design';
|
|
4
4
|
import type { FormConfig, FormState } from '@tmagic/form-schema';
|
|
@@ -13,21 +13,6 @@ export const useAdd = (
|
|
|
13
13
|
) => {
|
|
14
14
|
const mForm = inject<FormState | undefined>('mForm');
|
|
15
15
|
|
|
16
|
-
const addable = computed(() => {
|
|
17
|
-
const modelName = props.name || props.config.name || '';
|
|
18
|
-
if (!props.model[modelName].length) {
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
if (typeof props.config.addable === 'function') {
|
|
22
|
-
return props.config.addable(mForm, {
|
|
23
|
-
model: props.model[modelName],
|
|
24
|
-
formValue: mForm?.values,
|
|
25
|
-
prop: props.prop,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
return typeof props.config.addable === 'undefined' ? true : props.config.addable;
|
|
29
|
-
});
|
|
30
|
-
|
|
31
16
|
const newHandler = async (row?: any) => {
|
|
32
17
|
const modelName = props.name || props.config.name || '';
|
|
33
18
|
|
|
@@ -37,7 +22,7 @@ export const useAdd = (
|
|
|
37
22
|
}
|
|
38
23
|
|
|
39
24
|
if (typeof props.config.beforeAddRow === 'function') {
|
|
40
|
-
const beforeCheckRes = props.config.beforeAddRow(mForm, {
|
|
25
|
+
const beforeCheckRes = await props.config.beforeAddRow(mForm, {
|
|
41
26
|
model: props.model[modelName],
|
|
42
27
|
formValue: mForm?.values,
|
|
43
28
|
prop: props.prop,
|
|
@@ -106,7 +91,6 @@ export const useAdd = (
|
|
|
106
91
|
};
|
|
107
92
|
|
|
108
93
|
return {
|
|
109
|
-
addable,
|
|
110
94
|
newHandler,
|
|
111
95
|
};
|
|
112
96
|
};
|