@tmagic/form 1.8.0-beta.25 → 1.8.0-beta.27
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/Form.vue_vue_type_script_setup_true_lang.js +47 -120
- package/dist/es/FormBox.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/FormDialog.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/FormDrawer.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/containers/Col.vue_vue_type_script_setup_true_lang.js +3 -0
- package/dist/es/containers/Container.vue_vue_type_script_setup_true_lang.js +36 -51
- package/dist/es/containers/Fieldset.vue_vue_type_script_setup_true_lang.js +6 -0
- package/dist/es/containers/FlexLayout.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/es/containers/GroupList.vue_vue_type_script_setup_true_lang.js +37 -15
- package/dist/es/containers/GroupListItem.vue_vue_type_script_setup_true_lang.js +109 -97
- package/dist/es/containers/Panel.vue_vue_type_script_setup_true_lang.js +7 -2
- package/dist/es/containers/Row.vue_vue_type_script_setup_true_lang.js +3 -0
- package/dist/es/containers/Step.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/es/containers/Tabs.vue_vue_type_script_setup_true_lang.js +7 -0
- package/dist/es/containers/table/Table.vue_vue_type_script_setup_true_lang.js +7 -5
- package/dist/es/containers/table/useTableColumns.js +5 -13
- package/dist/es/containers/table-group-list/TableGroupList.vue_vue_type_script_setup_true_lang.js +71 -78
- package/dist/es/containers/table-group-list/useAdd.js +26 -16
- package/dist/es/containers/table-group-list/useScrollLastItemIntoView.js +72 -0
- package/dist/es/fields/Cascader.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/CheckboxGroup/Index.js +5 -0
- package/dist/es/fields/{CheckboxGroup.vue_vue_type_script_setup_true_lang.js → CheckboxGroup/Index.vue_vue_type_script_setup_true_lang.js} +6 -7
- package/dist/es/fields/CheckboxGroup/effect.js +8 -0
- package/dist/es/fields/Date/Index.js +5 -0
- package/dist/es/fields/{Date.vue_vue_type_script_setup_true_lang.js → Date/Index.vue_vue_type_script_setup_true_lang.js} +5 -7
- package/dist/es/fields/Date/effect.js +10 -0
- package/dist/es/fields/DateTime/Index.js +5 -0
- package/dist/es/fields/{DateTime.vue_vue_type_script_setup_true_lang.js → DateTime/Index.vue_vue_type_script_setup_true_lang.js} +5 -9
- package/dist/es/fields/DateTime/effect.js +15 -0
- package/dist/es/fields/Display/Index.js +5 -0
- package/dist/es/fields/{Display.vue_vue_type_script_setup_true_lang.js → Display/Index.vue_vue_type_script_setup_true_lang.js} +6 -7
- package/dist/es/fields/Display/effect.js +8 -0
- package/dist/es/fields/DynamicField/Index.js +5 -0
- package/dist/es/fields/{DynamicField.vue_vue_type_script_setup_true_lang.js → DynamicField/Index.vue_vue_type_script_setup_true_lang.js} +11 -15
- package/dist/es/fields/DynamicField/effect.js +40 -0
- package/dist/es/fields/Link.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Number.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/NumberRange/Index.js +5 -0
- package/dist/es/fields/{NumberRange.vue_vue_type_script_setup_true_lang.js → NumberRange/Index.vue_vue_type_script_setup_true_lang.js} +5 -6
- package/dist/es/fields/NumberRange/effect.js +8 -0
- package/dist/es/fields/Select.vue_vue_type_script_setup_true_lang.js +13 -6
- package/dist/es/fields/Text.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/headless.js +13 -0
- package/dist/es/index.js +17 -12
- package/dist/es/plugin.js +57 -41
- package/dist/es/schema.js +6 -8
- package/dist/es/style.css +81 -1
- package/dist/es/submitForm.js +44 -194
- package/dist/es/utils/builtInFields.js +49 -0
- package/dist/es/utils/collectFields.js +407 -0
- package/dist/es/utils/config.js +1 -8
- package/dist/es/utils/fieldInnerConfig.js +42 -0
- package/dist/es/utils/fieldValueEffects.js +80 -0
- package/dist/es/utils/form.js +96 -43
- package/dist/es/utils/formStateProxy.js +111 -0
- package/dist/es/utils/registerField.js +158 -0
- package/dist/es/utils/submitHeadless.js +54 -0
- package/dist/es/utils/tableGroupList.js +85 -0
- package/dist/es/utils/typeMatch.js +17 -19
- package/dist/es/utils/validateError.js +57 -0
- package/dist/es/utils/validateValues.js +115 -0
- package/dist/style.css +81 -1
- package/dist/themes/magic-admin.css +83 -7
- package/dist/tmagic-form-headless.umd.cjs +4080 -0
- package/dist/tmagic-form.umd.cjs +2020 -876
- package/package.json +10 -4
- package/src/Form.vue +49 -149
- package/src/FormBox.vue +5 -4
- package/src/FormDialog.vue +5 -5
- package/src/FormDrawer.vue +5 -5
- package/src/containers/Col.vue +2 -0
- package/src/containers/Container.vue +86 -157
- package/src/containers/Fieldset.vue +5 -0
- package/src/containers/FlexLayout.vue +2 -0
- package/src/containers/GroupList.vue +41 -11
- package/src/containers/GroupListItem.vue +83 -80
- package/src/containers/Panel.vue +3 -0
- package/src/containers/Row.vue +2 -0
- package/src/containers/Step.vue +2 -0
- package/src/containers/Tabs.vue +13 -0
- package/src/containers/table/ActionsColumn.vue +1 -1
- package/src/containers/table/Table.vue +4 -3
- package/src/containers/table/usePagination.ts +1 -1
- package/src/containers/table/useSortable.ts +1 -1
- package/src/containers/table/useTableColumns.ts +9 -19
- package/src/containers/table-group-list/TableGroupList.vue +43 -71
- package/src/containers/table-group-list/useAdd.ts +40 -25
- package/src/containers/table-group-list/useScrollLastItemIntoView.ts +94 -0
- package/src/fields/{CheckboxGroup.vue → CheckboxGroup/Index.vue} +3 -8
- package/src/fields/CheckboxGroup/effect.ts +27 -0
- package/src/fields/{Date.vue → Date/Index.vue} +2 -5
- package/src/fields/Date/effect.ts +29 -0
- package/src/fields/{DateTime.vue → DateTime/Index.vue} +2 -16
- package/src/fields/DateTime/effect.ts +36 -0
- package/src/fields/{Display.vue → Display/Index.vue} +3 -7
- package/src/fields/Display/effect.ts +28 -0
- package/src/fields/{DynamicField.vue → DynamicField/Index.vue} +11 -11
- package/src/fields/DynamicField/effect.ts +74 -0
- package/src/fields/{NumberRange.vue → NumberRange/Index.vue} +2 -6
- package/src/fields/NumberRange/effect.ts +27 -0
- package/src/fields/Select.vue +13 -4
- package/src/headless.ts +78 -0
- package/src/index.ts +32 -15
- package/src/plugin.ts +63 -42
- package/src/schema.ts +6 -8
- package/src/submitForm.ts +81 -409
- package/src/theme/group-list.scss +107 -1
- package/src/theme/themes/magic-admin/index.scss +2 -8
- package/src/utils/builtInFields.ts +69 -0
- package/src/utils/collectFields.ts +561 -0
- package/src/utils/config.ts +1 -15
- package/src/utils/fieldInnerConfig.ts +127 -0
- package/src/utils/fieldValueEffects.ts +140 -0
- package/src/utils/form.ts +141 -75
- package/src/utils/formStateProxy.ts +149 -0
- package/src/utils/registerField.ts +308 -0
- package/src/utils/submitHeadless.ts +206 -0
- package/src/utils/tableGroupList.ts +120 -0
- package/src/utils/typeMatch.ts +19 -15
- package/src/utils/validateError.ts +92 -0
- package/src/utils/validateValues.ts +177 -0
- package/types/headless.d.ts +682 -0
- package/types/index.d.ts +631 -272
- package/dist/es/fields/CheckboxGroup.js +0 -5
- package/dist/es/fields/Date.js +0 -5
- package/dist/es/fields/DateTime.js +0 -5
- package/dist/es/fields/Display.js +0 -5
- package/dist/es/fields/DynamicField.js +0 -5
- package/dist/es/fields/NumberRange.js +0 -5
- package/dist/es/utils/silentLeafFieldTypes.js +0 -49
- package/src/utils/silentLeafFieldTypes.ts +0 -71
|
@@ -6,89 +6,95 @@
|
|
|
6
6
|
<TMagicIcon><ArrowDown v-if="expand" /><ArrowRight v-else /></TMagicIcon>
|
|
7
7
|
</TMagicButton>
|
|
8
8
|
|
|
9
|
-
<
|
|
10
|
-
|
|
9
|
+
<div class="m-fields-group-list-item-title">
|
|
10
|
+
<slot name="title" :model="model" :index="index" :last-values="lastValues" :prop="rowProp" :title="title">
|
|
11
|
+
<span v-html="title"></span>
|
|
12
|
+
</slot>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="m-fields-group-list-item-actions">
|
|
11
15
|
<TMagicButton
|
|
12
|
-
v-if="!isCompare"
|
|
13
|
-
v-show="showDelete"
|
|
14
|
-
size="default"
|
|
15
|
-
link
|
|
16
|
-
class="delete-button"
|
|
17
|
-
:icon="Delete"
|
|
18
|
-
:disabled="disabled"
|
|
19
|
-
@click="removeHandler"
|
|
20
|
-
></TMagicButton>
|
|
21
|
-
</TMagicTooltip>
|
|
22
|
-
|
|
23
|
-
<TMagicButton
|
|
24
|
-
v-if="copyable && !isCompare"
|
|
25
|
-
link
|
|
26
|
-
size="default"
|
|
27
|
-
type="primary"
|
|
28
|
-
:icon="DocumentCopy"
|
|
29
|
-
:disabled="disabled"
|
|
30
|
-
@click="copyHandler"
|
|
31
|
-
>复制</TMagicButton
|
|
32
|
-
>
|
|
33
|
-
|
|
34
|
-
<template v-if="movable && !isCompare">
|
|
35
|
-
<TMagicButton
|
|
36
|
-
v-show="index !== 0"
|
|
37
|
-
link
|
|
38
|
-
size="default"
|
|
39
|
-
:disabled="disabled"
|
|
40
|
-
:icon="Top"
|
|
41
|
-
@click="changeOrder(-1)"
|
|
42
|
-
>上移</TMagicButton
|
|
43
|
-
>
|
|
44
|
-
<TMagicButton
|
|
45
|
-
v-show="index !== length - 1"
|
|
16
|
+
v-if="copyable && !isCompare"
|
|
46
17
|
link
|
|
47
18
|
size="default"
|
|
19
|
+
type="primary"
|
|
20
|
+
:icon="DocumentCopy"
|
|
48
21
|
:disabled="disabled"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
>下移</TMagicButton
|
|
22
|
+
@click="copyHandler"
|
|
23
|
+
>复制</TMagicButton
|
|
52
24
|
>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
25
|
+
|
|
26
|
+
<template v-if="movable && !isCompare">
|
|
27
|
+
<TMagicButton
|
|
28
|
+
v-show="index !== 0"
|
|
29
|
+
link
|
|
30
|
+
size="default"
|
|
31
|
+
:disabled="disabled"
|
|
32
|
+
:icon="Top"
|
|
33
|
+
@click="changeOrder(-1)"
|
|
34
|
+
>上移</TMagicButton
|
|
35
|
+
>
|
|
63
36
|
<TMagicButton
|
|
37
|
+
v-show="index !== length - 1"
|
|
64
38
|
link
|
|
65
|
-
size="
|
|
66
|
-
type="primary"
|
|
67
|
-
:icon="Position"
|
|
39
|
+
size="default"
|
|
68
40
|
:disabled="disabled"
|
|
69
|
-
|
|
70
|
-
|
|
41
|
+
:icon="Bottom"
|
|
42
|
+
@click="changeOrder(1)"
|
|
43
|
+
>下移</TMagicButton
|
|
71
44
|
>
|
|
72
45
|
</template>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
46
|
+
|
|
47
|
+
<TMagicPopover
|
|
48
|
+
v-if="config.moveSpecifyLocation && !isCompare"
|
|
49
|
+
trigger="click"
|
|
50
|
+
placement="top"
|
|
51
|
+
width="200"
|
|
52
|
+
:visible="moveSpecifyLocationVisible"
|
|
53
|
+
>
|
|
54
|
+
<template #reference>
|
|
55
|
+
<TMagicButton
|
|
56
|
+
link
|
|
78
57
|
size="small"
|
|
79
|
-
|
|
58
|
+
type="primary"
|
|
59
|
+
:icon="Position"
|
|
80
60
|
:disabled="disabled"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
<
|
|
61
|
+
@click="moveSpecifyLocationVisible = true"
|
|
62
|
+
>移动至</TMagicButton
|
|
63
|
+
>
|
|
64
|
+
</template>
|
|
65
|
+
<div>
|
|
66
|
+
<div>
|
|
67
|
+
第<TMagicInputNumber
|
|
68
|
+
style="margin: 0 5px"
|
|
69
|
+
v-model="moveSpecifyLocationIndex"
|
|
70
|
+
size="small"
|
|
71
|
+
:min="1"
|
|
72
|
+
:disabled="disabled"
|
|
73
|
+
></TMagicInputNumber
|
|
74
|
+
>行
|
|
75
|
+
</div>
|
|
76
|
+
<div style="text-align: right; margin-top: 20px">
|
|
77
|
+
<TMagicButton size="small" text @click="moveSpecifyLocationVisible = false">取消</TMagicButton>
|
|
78
|
+
<TMagicButton size="small" type="primary" @click="moveSpecifyLocationHandler">确认</TMagicButton>
|
|
79
|
+
</div>
|
|
87
80
|
</div>
|
|
88
|
-
</
|
|
89
|
-
|
|
81
|
+
</TMagicPopover>
|
|
82
|
+
|
|
83
|
+
<!-- v-if 必须挂在 Tooltip 上:子节点为 false 时 ElOnlyChild 会报 no valid child node found -->
|
|
84
|
+
<TMagicTooltip v-if="!isCompare" :content="`删除 ${title}`">
|
|
85
|
+
<TMagicButton
|
|
86
|
+
v-show="showDelete"
|
|
87
|
+
size="default"
|
|
88
|
+
link
|
|
89
|
+
class="delete-button"
|
|
90
|
+
:icon="Delete"
|
|
91
|
+
:disabled="disabled"
|
|
92
|
+
@click="removeHandler"
|
|
93
|
+
></TMagicButton>
|
|
94
|
+
</TMagicTooltip>
|
|
90
95
|
|
|
91
|
-
|
|
96
|
+
<span v-if="itemExtra" v-html="itemExtra" class="m-form-tip"></span>
|
|
97
|
+
</div>
|
|
92
98
|
</div>
|
|
93
99
|
</template>
|
|
94
100
|
|
|
@@ -99,7 +105,8 @@
|
|
|
99
105
|
:lastValues="lastValues"
|
|
100
106
|
:is-compare="isCompare"
|
|
101
107
|
:labelWidth="labelWidth"
|
|
102
|
-
:
|
|
108
|
+
:labelPosition="labelPosition"
|
|
109
|
+
:prop="rowProp"
|
|
103
110
|
:size="size"
|
|
104
111
|
:disabled="disabled"
|
|
105
112
|
@change="changeHandler"
|
|
@@ -115,7 +122,8 @@ import { ArrowDown, ArrowRight, Bottom, Delete, DocumentCopy, Position, Top } fr
|
|
|
115
122
|
import { TMagicButton, TMagicCard, TMagicIcon, TMagicInputNumber, TMagicPopover, TMagicTooltip } from '@tmagic/design';
|
|
116
123
|
|
|
117
124
|
import type { ContainerChangeEventData, FormState, GroupListConfig } from '../schema';
|
|
118
|
-
import { filterFunction } from '../utils/form';
|
|
125
|
+
import { appendProp, filterFunction } from '../utils/form';
|
|
126
|
+
import { getGroupListRowConfig } from '../utils/tableGroupList';
|
|
119
127
|
|
|
120
128
|
import Container from './Container.vue';
|
|
121
129
|
|
|
@@ -130,6 +138,7 @@ const props = defineProps<{
|
|
|
130
138
|
groupModel: any[];
|
|
131
139
|
config: GroupListConfig;
|
|
132
140
|
labelWidth?: string;
|
|
141
|
+
labelPosition?: 'top' | 'left' | 'right';
|
|
133
142
|
prop?: string;
|
|
134
143
|
size?: string;
|
|
135
144
|
index: number;
|
|
@@ -143,15 +152,9 @@ const mForm = inject<FormState | undefined>('mForm');
|
|
|
143
152
|
const defaultExpandQuantity = props.config.defaultExpandQuantity ?? 7;
|
|
144
153
|
const expand = ref(props.config.expandAll || defaultExpandQuantity > props.index);
|
|
145
154
|
|
|
146
|
-
const rowConfig = computed(() => (
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
items: props.config.items,
|
|
150
|
-
labelWidth: props.config.labelWidth,
|
|
151
|
-
[mForm?.keyProp || '__key']: `${(props.config as Record<string, any>)[mForm?.keyProp || '__key']}${String(
|
|
152
|
-
props.index,
|
|
153
|
-
)}`,
|
|
154
|
-
}));
|
|
155
|
+
const rowConfig = computed(() => getGroupListRowConfig(props.config, props.index, mForm?.keyProp));
|
|
156
|
+
|
|
157
|
+
const rowProp = computed(() => appendProp(props.prop, props.index));
|
|
155
158
|
|
|
156
159
|
const title = computed(() => {
|
|
157
160
|
if (props.config.titleKey && props.model[props.config.titleKey]) {
|
package/src/containers/Panel.vue
CHANGED
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
:size="size"
|
|
40
40
|
:disabled="disabled"
|
|
41
41
|
:label-width="config.labelWidth || labelWidth"
|
|
42
|
+
:label-position="config.labelPosition || labelPosition"
|
|
42
43
|
@change="changeHandler"
|
|
43
44
|
@addDiffCount="onAddDiffCount()"
|
|
44
45
|
></Container>
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
:size="size"
|
|
60
61
|
:disabled="disabled"
|
|
61
62
|
:label-width="config.labelWidth || labelWidth"
|
|
63
|
+
:label-position="config.labelPosition || labelPosition"
|
|
62
64
|
@change="changeHandler"
|
|
63
65
|
@addDiffCount="onAddDiffCount()"
|
|
64
66
|
></Container>
|
|
@@ -89,6 +91,7 @@ const props = defineProps<{
|
|
|
89
91
|
config: PanelConfig;
|
|
90
92
|
name?: string;
|
|
91
93
|
labelWidth?: string;
|
|
94
|
+
labelPosition?: 'top' | 'left' | 'right';
|
|
92
95
|
prop?: string;
|
|
93
96
|
size?: string;
|
|
94
97
|
disabled?: boolean;
|
package/src/containers/Row.vue
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
:span="col.span || config.span || 24 / config.items.length"
|
|
7
7
|
:config="col"
|
|
8
8
|
:labelWidth="config.labelWidth || labelWidth"
|
|
9
|
+
:labelPosition="config.labelPosition || labelPosition"
|
|
9
10
|
:expandMore="expandMore"
|
|
10
11
|
:model="name ? model[name] : model"
|
|
11
12
|
:lastValues="name ? lastValues[name] : lastValues"
|
|
@@ -39,6 +40,7 @@ const props = defineProps<{
|
|
|
39
40
|
config: RowConfig;
|
|
40
41
|
name: string;
|
|
41
42
|
labelWidth?: string;
|
|
43
|
+
labelPosition?: 'top' | 'left' | 'right';
|
|
42
44
|
prop?: string;
|
|
43
45
|
size?: string;
|
|
44
46
|
expandMore?: boolean;
|
package/src/containers/Step.vue
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
:size="size"
|
|
25
25
|
:disabled="disabled"
|
|
26
26
|
:label-width="config.labelWidth || labelWidth"
|
|
27
|
+
:label-position="config.labelPosition || labelPosition"
|
|
27
28
|
@change="changeHandler"
|
|
28
29
|
@addDiffCount="onAddDiffCount()"
|
|
29
30
|
></Container>
|
|
@@ -54,6 +55,7 @@ const props = withDefaults(
|
|
|
54
55
|
config: StepConfig;
|
|
55
56
|
stepActive?: number;
|
|
56
57
|
labelWidth?: string;
|
|
58
|
+
labelPosition?: 'top' | 'left' | 'right';
|
|
57
59
|
size?: string;
|
|
58
60
|
disabled?: boolean;
|
|
59
61
|
}>(),
|
package/src/containers/Tabs.vue
CHANGED
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
"
|
|
71
71
|
:size="size"
|
|
72
72
|
:label-width="tab.labelWidth || labelWidth"
|
|
73
|
+
:label-position="tab.labelPosition || labelPosition"
|
|
73
74
|
:expand-more="expandMore"
|
|
74
75
|
@change="changeHandler"
|
|
75
76
|
@addDiffCount="onAddDiffCount(Number(tabIndex))"
|
|
@@ -85,6 +86,7 @@ import { isEmpty } from 'lodash-es';
|
|
|
85
86
|
import { getDesignConfig, TMagicBadge } from '@tmagic/design';
|
|
86
87
|
|
|
87
88
|
import type { ContainerChangeEventData, FormState, TabConfig, TabPaneConfig } from '../schema';
|
|
89
|
+
import { applyMountValueEffects } from '../utils/collectFields';
|
|
88
90
|
import { display as displayFunc, filterFunction, initValue } from '../utils/form';
|
|
89
91
|
|
|
90
92
|
import Container from './Container.vue';
|
|
@@ -106,6 +108,7 @@ const props = withDefaults(
|
|
|
106
108
|
name: string;
|
|
107
109
|
size?: string;
|
|
108
110
|
labelWidth?: string;
|
|
111
|
+
labelPosition?: 'top' | 'left' | 'right';
|
|
109
112
|
prop?: string;
|
|
110
113
|
expandMore?: boolean;
|
|
111
114
|
disabled?: boolean;
|
|
@@ -203,6 +206,13 @@ const onTabAdd = async () => {
|
|
|
203
206
|
prop: props.prop,
|
|
204
207
|
config: props.config,
|
|
205
208
|
});
|
|
209
|
+
// 自定义回调可能直接 push 原始对象;对现有标签页再规整一遍(effect 必须幂等)
|
|
210
|
+
const tabsModel = props.model[props.name];
|
|
211
|
+
if (Array.isArray(tabsModel) && Array.isArray(props.config.items)) {
|
|
212
|
+
for (const tab of tabsModel) {
|
|
213
|
+
applyMountValueEffects(mForm, props.config.items, tab);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
206
216
|
emit('change', props.model[props.name]);
|
|
207
217
|
} else {
|
|
208
218
|
const newObj = await initValue(mForm, {
|
|
@@ -210,6 +220,9 @@ const onTabAdd = async () => {
|
|
|
210
220
|
initValues: {},
|
|
211
221
|
});
|
|
212
222
|
|
|
223
|
+
// 新增标签页的值在挂到表单上之前先规整一遍,与整表初始化走同一份登记表
|
|
224
|
+
applyMountValueEffects(mForm, props.config.items, newObj);
|
|
225
|
+
|
|
213
226
|
newObj.title = `标签${tabs.value.length + 1}`;
|
|
214
227
|
|
|
215
228
|
props.model[props.name].push(newObj);
|
|
@@ -43,7 +43,7 @@ import { cloneDeep } from 'lodash-es';
|
|
|
43
43
|
|
|
44
44
|
import { TMagicButton, TMagicTooltip } from '@tmagic/design';
|
|
45
45
|
|
|
46
|
-
import type { FormState, TableConfig } from '
|
|
46
|
+
import type { FormState, TableConfig } from '@form/schema';
|
|
47
47
|
|
|
48
48
|
const emit = defineEmits(['change']);
|
|
49
49
|
|
|
@@ -8,13 +8,14 @@
|
|
|
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>
|
|
11
|
+
<!-- v-if 必须挂在 Tooltip 上:表格未就绪时 ElOnlyChild 会报 no valid child node found -->
|
|
11
12
|
<TMagicTooltip
|
|
13
|
+
v-if="model[modelName]"
|
|
12
14
|
content="拖拽可排序"
|
|
13
15
|
placement="left-start"
|
|
14
16
|
:disabled="config.dropSort !== true || config.dropSortHandle"
|
|
15
17
|
>
|
|
16
18
|
<TMagicTable
|
|
17
|
-
v-if="model[modelName]"
|
|
18
19
|
ref="tMagicTable"
|
|
19
20
|
style="width: 100%"
|
|
20
21
|
show-header
|
|
@@ -92,8 +93,8 @@ import { FullScreen } from '@element-plus/icons-vue';
|
|
|
92
93
|
|
|
93
94
|
import { TMagicButton, TMagicPagination, TMagicTable, TMagicTooltip, TMagicUpload } from '@tmagic/design';
|
|
94
95
|
|
|
95
|
-
import type { SortProp } from '
|
|
96
|
-
import { sortChange } from '
|
|
96
|
+
import type { SortProp } from '@form/schema';
|
|
97
|
+
import { sortChange } from '@form/utils/form';
|
|
97
98
|
|
|
98
99
|
import type { TableProps } from './type';
|
|
99
100
|
import { useFullscreen } from './useFullscreen';
|
|
@@ -4,7 +4,7 @@ import type { default as SortableType, SortableEvent } from 'sortablejs';
|
|
|
4
4
|
import { type TMagicTable } from '@tmagic/design';
|
|
5
5
|
import type { FormState } from '@tmagic/form-schema';
|
|
6
6
|
|
|
7
|
-
import { sortArray } from '
|
|
7
|
+
import { sortArray } from '@form/utils/form';
|
|
8
8
|
|
|
9
9
|
import type { TableProps } from './type';
|
|
10
10
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { computed, h, inject, type Ref } from 'vue';
|
|
2
2
|
import { WarningFilled } from '@element-plus/icons-vue';
|
|
3
|
-
import { cloneDeep } from 'lodash-es';
|
|
4
3
|
|
|
5
4
|
import { type TableColumnOptions, TMagicIcon, TMagicTooltip } from '@tmagic/design';
|
|
6
|
-
import type { FormItemConfig, FormState
|
|
5
|
+
import type { FormItemConfig, FormState } from '@tmagic/form-schema';
|
|
6
|
+
|
|
7
|
+
import type { ContainerChangeEventData } from '@form/schema';
|
|
8
|
+
import { isGlobalFlat } from '@form/utils/config';
|
|
9
|
+
import { appendProp, display as displayFunc, getDataByPage, sortArray } from '@form/utils/form';
|
|
10
|
+
import { isTableColumnRendered, makeTableColumnConfig } from '@form/utils/tableGroupList';
|
|
7
11
|
|
|
8
|
-
import type { ContainerChangeEventData } from '../../schema';
|
|
9
|
-
import { isGlobalFlat } from '../../utils/config';
|
|
10
|
-
import { display as displayFunc, getDataByPage, sortArray } from '../../utils/form';
|
|
11
12
|
import Container from '../Container.vue';
|
|
12
13
|
|
|
13
14
|
import ActionsColumn from './ActionsColumn.vue';
|
|
@@ -65,18 +66,7 @@ export const useTableColumns = (
|
|
|
65
66
|
return props.config.selection;
|
|
66
67
|
});
|
|
67
68
|
|
|
68
|
-
const getProp = (index: number) =>
|
|
69
|
-
return `${props.prop}${props.prop ? '.' : ''}${index + 1 + currentPage.value * pageSize.value - 1}`;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const makeConfig = (config: TableColumnConfig, row: any): TableColumnConfig => {
|
|
73
|
-
const newConfig = cloneDeep(config);
|
|
74
|
-
if (typeof config.itemsFunction === 'function') {
|
|
75
|
-
newConfig.items = config.itemsFunction(row);
|
|
76
|
-
}
|
|
77
|
-
delete newConfig.display;
|
|
78
|
-
return newConfig;
|
|
79
|
-
};
|
|
69
|
+
const getProp = (index: number) => appendProp(props.prop, index + currentPage.value * pageSize.value);
|
|
80
70
|
|
|
81
71
|
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
|
|
82
72
|
emit('change', props.model, eventData);
|
|
@@ -185,7 +175,7 @@ export const useTableColumns = (
|
|
|
185
175
|
}
|
|
186
176
|
|
|
187
177
|
for (const column of props.config.items) {
|
|
188
|
-
if (column
|
|
178
|
+
if (isTableColumnRendered(column, display)) {
|
|
189
179
|
const titleTipValue = titleTip(column.titleTip);
|
|
190
180
|
|
|
191
181
|
columns.push({
|
|
@@ -203,7 +193,7 @@ export const useTableColumns = (
|
|
|
203
193
|
disabled: props.disabled,
|
|
204
194
|
prop: getProp($index),
|
|
205
195
|
rules: column.rules,
|
|
206
|
-
config:
|
|
196
|
+
config: makeTableColumnConfig(column, row) as FormItemConfig,
|
|
207
197
|
model: row,
|
|
208
198
|
lastValues: lastData.value[$index],
|
|
209
199
|
isCompare: props.isCompare,
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
:last-values="lastValues"
|
|
13
13
|
:prop="prop"
|
|
14
14
|
:label-width="labelWidth"
|
|
15
|
+
:label-position="labelPosition"
|
|
15
16
|
:show-index="showIndex"
|
|
16
17
|
:sort-key="sortKey"
|
|
17
18
|
:sort="sort"
|
|
@@ -20,13 +21,8 @@
|
|
|
20
21
|
@addDiffCount="onAddDiffCount"
|
|
21
22
|
@add="onAdd"
|
|
22
23
|
>
|
|
23
|
-
<template #toggle-button>
|
|
24
|
-
<TMagicButton
|
|
25
|
-
v-if="config.enableToggleMode || enableToggleMode"
|
|
26
|
-
:icon="Grid"
|
|
27
|
-
size="small"
|
|
28
|
-
@click="toggleDisplayMode"
|
|
29
|
-
>
|
|
24
|
+
<template #toggle-button v-if="config.enableToggleMode || enableToggleMode">
|
|
25
|
+
<TMagicButton :icon="Grid" size="small" @click="toggleDisplayMode">
|
|
30
26
|
{{ displayMode === 'table' ? '展开配置' : '切换为表格' }}
|
|
31
27
|
</TMagicButton>
|
|
32
28
|
</template>
|
|
@@ -35,12 +31,10 @@
|
|
|
35
31
|
<TMagicButton
|
|
36
32
|
:class="displayMode === 'table' ? 'm-form-table-add-button' : ''"
|
|
37
33
|
:size="addButtonSize"
|
|
38
|
-
:plain="displayMode === 'table'"
|
|
39
34
|
:icon="Plus"
|
|
40
|
-
text
|
|
41
35
|
:disabled="disabled"
|
|
42
|
-
v-bind="
|
|
43
|
-
@click="
|
|
36
|
+
v-bind="addButtonProps"
|
|
37
|
+
@click="handleAdd"
|
|
44
38
|
>
|
|
45
39
|
{{
|
|
46
40
|
currentConfig.addButtonConfig?.text ||
|
|
@@ -50,6 +44,10 @@
|
|
|
50
44
|
}}
|
|
51
45
|
</TMagicButton>
|
|
52
46
|
</template>
|
|
47
|
+
|
|
48
|
+
<template #title="slotProps" v-if="$slots.title">
|
|
49
|
+
<slot name="title" v-bind="slotProps"></slot>
|
|
50
|
+
</template>
|
|
53
51
|
</component>
|
|
54
52
|
</template>
|
|
55
53
|
|
|
@@ -60,11 +58,14 @@ import { Grid, Plus } from '@element-plus/icons-vue';
|
|
|
60
58
|
import { TMagicButton } from '@tmagic/design';
|
|
61
59
|
import type { GroupListConfig, TableConfig } from '@tmagic/form-schema';
|
|
62
60
|
|
|
63
|
-
import type { ContainerChangeEventData } from '
|
|
61
|
+
import type { ContainerChangeEventData } from '@form/schema';
|
|
62
|
+
import { isGroupListType, toGroupListConfig, toTableConfig } from '@form/utils/tableGroupList';
|
|
63
|
+
|
|
64
64
|
import MFormGroupList from '../GroupList.vue';
|
|
65
65
|
import MFormTable from '../table/Table.vue';
|
|
66
66
|
|
|
67
67
|
import { useAdd } from './useAdd';
|
|
68
|
+
import { useScrollLastItemIntoView } from './useScrollLastItemIntoView';
|
|
68
69
|
|
|
69
70
|
defineOptions({
|
|
70
71
|
name: 'MFormTableGroupList',
|
|
@@ -79,6 +80,7 @@ const props = defineProps<{
|
|
|
79
80
|
name: string;
|
|
80
81
|
prop?: string;
|
|
81
82
|
labelWidth?: string;
|
|
83
|
+
labelPosition?: 'top' | 'left' | 'right';
|
|
82
84
|
disabled?: boolean;
|
|
83
85
|
size?: string;
|
|
84
86
|
enableToggleMode?: true;
|
|
@@ -91,88 +93,58 @@ const emit = defineEmits(['change', 'select', 'addDiffCount']);
|
|
|
91
93
|
|
|
92
94
|
const { addable, newHandler } = useAdd(props, emit);
|
|
93
95
|
|
|
94
|
-
const isGroupListType = (type: string | undefined) => type === 'groupList' || type === 'group-list';
|
|
95
|
-
|
|
96
96
|
const displayMode = ref<'table' | 'groupList'>(isGroupListType(props.config.type) ? 'groupList' : 'table');
|
|
97
97
|
|
|
98
|
-
const calcLabelWidth = (label: string) => {
|
|
99
|
-
if (!label) return '0px';
|
|
100
|
-
const zhLength = label.match(/[^\x00-\xff]/g)?.length || 0;
|
|
101
|
-
const chLength = label.length - zhLength;
|
|
102
|
-
return `${Math.max(chLength * 8 + zhLength * 20, 80)}px`;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
98
|
// 当原始 config 是 table 形态时,table 模式直接透传;
|
|
106
|
-
// 若原始是 groupList,则基于它派生出 table 所需的 config
|
|
107
|
-
const tableConfig = computed<TableConfig>(() =>
|
|
108
|
-
if (!isGroupListType(props.config.type)) {
|
|
109
|
-
return props.config as TableConfig;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const source = props.config as GroupListConfig;
|
|
113
|
-
return {
|
|
114
|
-
...props.config,
|
|
115
|
-
type: 'table',
|
|
116
|
-
groupItems: source.items,
|
|
117
|
-
items:
|
|
118
|
-
source.tableItems ||
|
|
119
|
-
(source.items as any[]).map((item: any) => ({
|
|
120
|
-
...item,
|
|
121
|
-
label: item.label || item.text,
|
|
122
|
-
text: null,
|
|
123
|
-
})),
|
|
124
|
-
} as any as TableConfig;
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
// 反向派生 groupList 所需的 config
|
|
128
|
-
const groupListConfig = computed<GroupListConfig>(() => {
|
|
129
|
-
if (isGroupListType(props.config.type)) {
|
|
130
|
-
return props.config as GroupListConfig;
|
|
131
|
-
}
|
|
99
|
+
// 若原始是 groupList,则基于它派生出 table 所需的 config(反之同理)
|
|
100
|
+
const tableConfig = computed<TableConfig>(() => toTableConfig(props.config));
|
|
132
101
|
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
...props.config,
|
|
136
|
-
type: 'groupList',
|
|
137
|
-
tableItems: source.items,
|
|
138
|
-
items:
|
|
139
|
-
source.groupItems ||
|
|
140
|
-
(source.items as any[]).map((item: any) => {
|
|
141
|
-
const text = item.text || item.label;
|
|
142
|
-
return {
|
|
143
|
-
...item,
|
|
144
|
-
text,
|
|
145
|
-
labelWidth: calcLabelWidth(text),
|
|
146
|
-
span: item.span || 12,
|
|
147
|
-
};
|
|
148
|
-
}),
|
|
149
|
-
} as any as GroupListConfig;
|
|
150
|
-
});
|
|
102
|
+
const groupListConfig = computed<GroupListConfig>(() => toGroupListConfig(props.config));
|
|
151
103
|
|
|
152
104
|
// 运行时类型由 displayMode 决定,`<component :is>` 无法做联合类型收窄,统一转 any 交给子组件处理
|
|
153
105
|
const currentConfig = computed<any>(() => (displayMode.value === 'table' ? tableConfig.value : groupListConfig.value));
|
|
154
106
|
|
|
155
107
|
// 保持原 Table/GroupList 模式下新增按钮的不同尺寸策略
|
|
156
108
|
const addButtonSize = computed(() => {
|
|
109
|
+
if (currentConfig.value.addButtonConfig?.sticky) return 'default';
|
|
157
110
|
if (displayMode.value === 'table') return 'small';
|
|
158
111
|
return props.config.enableToggleMode !== false ? 'small' : 'default';
|
|
159
112
|
});
|
|
160
113
|
|
|
114
|
+
const addButtonProps = computed(() => {
|
|
115
|
+
const custom = currentConfig.value.addButtonConfig?.props;
|
|
116
|
+
if (custom) return { type: 'primary', ...custom };
|
|
117
|
+
if (displayMode.value === 'table') return { type: 'primary', plain: true };
|
|
118
|
+
return { type: 'primary', text: true };
|
|
119
|
+
});
|
|
120
|
+
|
|
161
121
|
const toggleDisplayMode = () => {
|
|
162
122
|
displayMode.value = displayMode.value === 'table' ? 'groupList' : 'table';
|
|
163
123
|
};
|
|
164
124
|
|
|
125
|
+
const tableGroupListRef = useTemplateRef<InstanceType<typeof MFormTable>>('tableGroupList');
|
|
126
|
+
|
|
127
|
+
const { scrollLastItemIntoView } = useScrollLastItemIntoView(
|
|
128
|
+
tableGroupListRef,
|
|
129
|
+
() => Boolean(currentConfig.value.scrollLastItemIntoView) && displayMode.value === 'groupList',
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
const handleAdd = async () => {
|
|
133
|
+
const expectedCount = await newHandler();
|
|
134
|
+
if (expectedCount !== null) await scrollLastItemIntoView(expectedCount);
|
|
135
|
+
};
|
|
136
|
+
|
|
165
137
|
const onChange = (v: any, eventData?: ContainerChangeEventData) => emit('change', v, eventData);
|
|
166
138
|
const onSelect = (...args: any[]) => emit('select', ...args);
|
|
167
139
|
const onAddDiffCount = () => emit('addDiffCount');
|
|
168
|
-
const onAdd = (rows: any[]) => {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
140
|
+
const onAdd = async (rows: any[]) => {
|
|
141
|
+
let expectedCount: number | null = null;
|
|
142
|
+
for (const row of rows) {
|
|
143
|
+
expectedCount = (await newHandler(row)) ?? expectedCount;
|
|
144
|
+
}
|
|
145
|
+
if (expectedCount !== null) await scrollLastItemIntoView(expectedCount);
|
|
172
146
|
};
|
|
173
147
|
|
|
174
|
-
const tableGroupListRef = useTemplateRef<InstanceType<typeof MFormTable>>('tableGroupList');
|
|
175
|
-
|
|
176
148
|
defineExpose({
|
|
177
149
|
toggleRowSelection: (row: any, selected: boolean) => tableGroupListRef.value?.toggleRowSelection?.(row, selected),
|
|
178
150
|
});
|