@tmagic/form 1.6.0 → 1.7.0-beta.0

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.
Files changed (43) hide show
  1. package/dist/style.css +29 -3
  2. package/dist/tmagic-form.js +1788 -1581
  3. package/dist/tmagic-form.umd.cjs +1830 -1619
  4. package/package.json +6 -6
  5. package/src/Form.vue +18 -5
  6. package/src/containers/Container.vue +109 -134
  7. package/src/containers/Fieldset.vue +31 -7
  8. package/src/containers/FlexLayout.vue +59 -0
  9. package/src/containers/Tabs.vue +11 -1
  10. package/src/fields/Cascader.vue +25 -16
  11. package/src/fields/Checkbox.vue +3 -3
  12. package/src/fields/CheckboxGroup.vue +1 -1
  13. package/src/fields/ColorPicker.vue +2 -2
  14. package/src/fields/Date.vue +2 -2
  15. package/src/fields/DateTime.vue +2 -2
  16. package/src/fields/Daterange.vue +2 -2
  17. package/src/fields/Number.vue +2 -2
  18. package/src/fields/NumberRange.vue +6 -6
  19. package/src/fields/RadioGroup.vue +18 -16
  20. package/src/fields/Select.vue +2 -2
  21. package/src/fields/Switch.vue +2 -2
  22. package/src/fields/Text.vue +21 -9
  23. package/src/fields/Textarea.vue +2 -2
  24. package/src/fields/Time.vue +2 -2
  25. package/src/fields/Timerange.vue +2 -2
  26. package/src/index.ts +5 -2
  27. package/src/table/ActionsColumn.vue +97 -0
  28. package/src/table/SortColumn.vue +101 -0
  29. package/src/table/Table.vue +170 -0
  30. package/src/table/type.ts +18 -0
  31. package/src/table/useAdd.ts +111 -0
  32. package/src/table/useFullscreen.ts +28 -0
  33. package/src/table/useImport.ts +68 -0
  34. package/src/table/usePagination.ts +30 -0
  35. package/src/table/useSelection.ts +34 -0
  36. package/src/table/useSortable.ts +48 -0
  37. package/src/table/useTableColumns.ts +194 -0
  38. package/src/theme/container.scss +17 -0
  39. package/src/theme/form.scss +15 -3
  40. package/src/theme/text.scss +6 -0
  41. package/src/utils/form.ts +56 -2
  42. package/types/index.d.ts +103 -56
  43. package/src/containers/Table.vue +0 -681
@@ -0,0 +1,194 @@
1
+ import { computed, h, inject, type Ref } from 'vue';
2
+ import { cloneDeep } from 'lodash-es';
3
+
4
+ import type { TableColumnOptions } from '@tmagic/design';
5
+ import type { FormState, TableColumnConfig } from '@tmagic/form-schema';
6
+
7
+ import Container from '../containers/Container.vue';
8
+ import type { ContainerChangeEventData } from '../schema';
9
+ import { display as displayFunc, getDataByPage, sortArray } from '../utils/form';
10
+
11
+ import ActionsColumn from './ActionsColumn.vue';
12
+ import SortColumn from './SortColumn.vue';
13
+ import type { TableProps } from './type';
14
+
15
+ export const useTableColumns = (
16
+ props: TableProps,
17
+ emit: (event: 'select' | 'change' | 'addDiffCount', ...args: any[]) => void,
18
+ currentPage: Ref<number>,
19
+ pageSize: Ref<number>,
20
+ modelName: Ref<string | number>,
21
+ ) => {
22
+ const mForm = inject<FormState | undefined>('mForm');
23
+
24
+ const display = (fuc: any) => displayFunc(mForm, fuc, props);
25
+
26
+ const lastData = computed(() =>
27
+ props.config.pagination
28
+ ? getDataByPage(props.lastValues[modelName.value], currentPage.value, pageSize.value)
29
+ : props.lastValues[modelName.value] || [],
30
+ );
31
+
32
+ const itemExtra = (fuc: any, index: number) => {
33
+ if (typeof fuc === 'function') {
34
+ return fuc(mForm, {
35
+ values: mForm?.initValues,
36
+ model: props.model,
37
+ formValue: mForm ? mForm.values : props.model,
38
+ prop: props.prop,
39
+ index,
40
+ });
41
+ }
42
+
43
+ return fuc;
44
+ };
45
+
46
+ const selection = computed(() => {
47
+ if (typeof props.config.selection === 'function') {
48
+ return props.config.selection(mForm, { model: props.model[modelName.value] });
49
+ }
50
+ return props.config.selection;
51
+ });
52
+
53
+ const getProp = (index: number) => {
54
+ return `${props.prop}${props.prop ? '.' : ''}${index + 1 + currentPage.value * pageSize.value - 1}`;
55
+ };
56
+
57
+ const makeConfig = (config: TableColumnConfig, row: any) => {
58
+ const newConfig = cloneDeep(config);
59
+ if (typeof config.itemsFunction === 'function') {
60
+ newConfig.items = config.itemsFunction(row);
61
+ }
62
+ delete newConfig.display;
63
+ return newConfig;
64
+ };
65
+
66
+ const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
67
+ emit('change', props.model, eventData);
68
+ };
69
+
70
+ const onAddDiffCount = () => emit('addDiffCount');
71
+
72
+ const columns = computed<TableColumnOptions[]>(() => {
73
+ const columns: TableColumnOptions[] = [];
74
+
75
+ if (props.config.itemExtra && !props.config.dropSort) {
76
+ columns.push({
77
+ props: {
78
+ fixed: 'left',
79
+ width: 30,
80
+ type: 'expand',
81
+ },
82
+ cell: ({ $index }: any) =>
83
+ h('span', {
84
+ innerHTML: itemExtra(props.config.itemExtra, $index),
85
+ class: 'm-form-tip',
86
+ }),
87
+ });
88
+ }
89
+
90
+ columns.push({
91
+ props: {
92
+ label: '操作',
93
+ fixed: props.config.fixed === false ? undefined : 'left',
94
+ width: props.config.operateColWidth || 112,
95
+ align: 'center',
96
+ },
97
+ cell: ({ row, $index }: any) =>
98
+ h(ActionsColumn, {
99
+ row,
100
+ index: $index,
101
+ model: props.model,
102
+ config: props.config,
103
+ prop: props.prop,
104
+ disabled: props.disabled,
105
+ sortKey: props.sortKey,
106
+ name: modelName.value,
107
+ currentPage: currentPage.value,
108
+ pageSize: pageSize.value,
109
+ onChange: (v: any) => {
110
+ emit('change', v);
111
+ },
112
+ }),
113
+ });
114
+
115
+ if (props.sort && props.model[modelName.value] && props.model[modelName.value].length > 1) {
116
+ columns.push({
117
+ props: {
118
+ label: '排序',
119
+ width: 80,
120
+ },
121
+ cell: ({ $index }: any) =>
122
+ h(SortColumn, {
123
+ index: $index,
124
+ model: props.model,
125
+ disabled: props.disabled,
126
+ name: modelName.value,
127
+ currentPage: currentPage.value,
128
+ pageSize: pageSize.value,
129
+ onSwap: (index1: number, index2: number) => {
130
+ const newData = sortArray(props.model[modelName.value], index1, index2, props.sortKey);
131
+ emit('change', newData);
132
+ mForm?.$emit('field-change', newData);
133
+ },
134
+ }),
135
+ });
136
+ }
137
+
138
+ if (selection.value) {
139
+ columns.push({
140
+ props: {
141
+ align: 'center',
142
+ headerAlign: 'center',
143
+ type: 'selection',
144
+ width: 45,
145
+ },
146
+ });
147
+ }
148
+
149
+ if (props.showIndex && props.config.showIndex) {
150
+ columns.push({
151
+ props: {
152
+ label: '序号',
153
+ width: 60,
154
+ },
155
+ cell: ({ $index }: any) => h('span', $index + 1 + currentPage.value * pageSize.value),
156
+ });
157
+ }
158
+
159
+ for (const column of props.config.items) {
160
+ if (column.type !== 'hidden' && display(column.display)) {
161
+ columns.push({
162
+ props: {
163
+ prop: column.name,
164
+ label: column.label,
165
+ width: column.width,
166
+ sortable: column.sortable,
167
+ sortOrders: ['ascending', 'descending'],
168
+ class: props.config.dropSort === true ? 'el-table__column--dropable' : '',
169
+ },
170
+ cell: ({ row, $index }: any) =>
171
+ h(Container, {
172
+ labelWidth: '0',
173
+ disabled: props.disabled,
174
+ prop: getProp($index),
175
+ rules: column.rules,
176
+ config: makeConfig(column, row),
177
+ model: row,
178
+ lastValues: lastData.value[$index],
179
+ isCompare: props.isCompare,
180
+ size: props.size,
181
+ onChange: changeHandler,
182
+ onAddDiffCount,
183
+ }),
184
+ });
185
+ }
186
+ }
187
+
188
+ return columns;
189
+ });
190
+
191
+ return {
192
+ columns,
193
+ };
194
+ };
@@ -3,3 +3,20 @@
3
3
  display: inline-flex;
4
4
  }
5
5
  }
6
+
7
+ .m-form-container {
8
+ &.has-tip {
9
+ display: flex;
10
+ align-items: baseline;
11
+
12
+ .tmagic-design-form-item {
13
+ flex: 1;
14
+ }
15
+ }
16
+
17
+ .tmagic-design-form-item {
18
+ &.show-diff {
19
+ background: #f7dadd;
20
+ }
21
+ }
22
+ }
@@ -19,17 +19,21 @@
19
19
  height: 100%;
20
20
  }
21
21
 
22
- .el-table {
22
+ .tmagic-design-table {
23
23
  .cell > div.m-form-container {
24
24
  display: block;
25
+
26
+ &.has-tip {
27
+ display: flex;
28
+ }
25
29
  }
26
30
  }
27
31
 
28
- .el-tabs {
32
+ .tmagic-design-tabs {
29
33
  margin-bottom: 10px;
30
34
  }
31
35
 
32
- .el-form-item.tmagic-form-hidden {
36
+ .tmagic-design-form-item.tmagic-form-hidden {
33
37
  > .el-form-item__label {
34
38
  display: none;
35
39
  }
@@ -39,5 +43,13 @@
39
43
  > .t-form__label {
40
44
  display: none;
41
45
  }
46
+
47
+ > .t-form__controls {
48
+ margin-left: 0 !important;
49
+ }
50
+ }
51
+
52
+ &.t-form:not(.t-form-inline) .t-form__item:last-of-type {
53
+ margin-bottom: var(--td-comp-margin-xxl);
42
54
  }
43
55
  }
@@ -1,3 +1,9 @@
1
+ .m-fields-text {
2
+ display: flex;
3
+ align-items: center;
4
+ width: 100%;
5
+ }
6
+
1
7
  .m-form-validate__warning {
2
8
  color: var(--el-color-warning);
3
9
  font-size: 12px;
package/src/utils/form.ts CHANGED
@@ -21,6 +21,8 @@ import dayjs from 'dayjs';
21
21
  import utc from 'dayjs/plugin/utc';
22
22
  import { cloneDeep } from 'lodash-es';
23
23
 
24
+ import { getValueByKeyPath } from '@tmagic/utils';
25
+
24
26
  import {
25
27
  ChildConfig,
26
28
  ContainerCommonConfig,
@@ -31,6 +33,7 @@ import {
31
33
  FormValue,
32
34
  HtmlField,
33
35
  Rule,
36
+ SortProp,
34
37
  TabPaneConfig,
35
38
  TypeFunction,
36
39
  } from '../schema';
@@ -89,8 +92,13 @@ const setValue = (mForm: FormState | undefined, value: FormValue, initValue: For
89
92
 
90
93
  // 如果fieldset配置checkbox,checkbox的值保存在value中
91
94
  if (type === 'fieldset' && checkbox) {
92
- if (typeof value[name] === 'object') {
93
- value[name].value = typeof initValue[name] === 'object' ? initValue[name].value || 0 : 0;
95
+ const checkboxName = typeof checkbox === 'object' && typeof checkbox.name === 'string' ? checkbox.name : 'value';
96
+ const checkboxFalseValue =
97
+ typeof checkbox === 'object' && typeof checkbox.falseValue !== 'undefined' ? checkbox.falseValue : 0;
98
+
99
+ if (name && typeof value[name] === 'object') {
100
+ value[name][checkboxName] =
101
+ typeof initValue[name] === 'object' ? initValue[name][checkboxName] || checkboxFalseValue : checkboxFalseValue;
94
102
  }
95
103
  }
96
104
  };
@@ -136,6 +144,18 @@ const initValueItem = function (
136
144
 
137
145
  setValue(mForm, value, initValue, item);
138
146
 
147
+ if (type === 'table') {
148
+ if (item.defautSort) {
149
+ sortChange(value[name], item.defautSort);
150
+ } else if (item.defaultSort) {
151
+ sortChange(value[name], item.defaultSort);
152
+ }
153
+
154
+ if (item.sort && item.sortKey) {
155
+ value[name].sort((a: any, b: any) => b[item.sortKey] - a[item.sortKey]);
156
+ }
157
+ }
158
+
139
159
  return value;
140
160
  };
141
161
 
@@ -197,6 +217,7 @@ export const filterFunction = <T = any>(
197
217
  prop: props.prop,
198
218
  config: props.config,
199
219
  index: props.index,
220
+ getFormValue: (prop: string) => getValueByKeyPath(prop, mForm?.values || props.model),
200
221
  });
201
222
  }
202
223
 
@@ -297,3 +318,36 @@ export const datetimeFormatter = (
297
318
  }
298
319
  return defaultValue;
299
320
  };
321
+
322
+ export const getDataByPage = (data: any[] = [], pagecontext: number, pagesize: number) =>
323
+ data.filter(
324
+ (item: any, index: number) => index >= pagecontext * pagesize && index + 1 <= (pagecontext + 1) * pagesize,
325
+ );
326
+
327
+ export const sortArray = (data: any[], newIndex: number, oldIndex: number, sortKey?: string) => {
328
+ if (newIndex === oldIndex) {
329
+ return data;
330
+ }
331
+
332
+ if (newIndex < 0 || newIndex >= data.length || oldIndex < 0 || oldIndex >= data.length) {
333
+ return data;
334
+ }
335
+
336
+ const newData = data.toSpliced(newIndex, 0, ...data.splice(oldIndex, 1));
337
+
338
+ if (sortKey) {
339
+ for (let i = newData.length - 1, v = 0; i >= 0; i--, v++) {
340
+ newData[v][sortKey] = i;
341
+ }
342
+ }
343
+
344
+ return newData;
345
+ };
346
+
347
+ export const sortChange = (data: any[], { prop, order }: SortProp) => {
348
+ if (order === 'ascending') {
349
+ data = data.sort((a: any, b: any) => a[prop] - b[prop]);
350
+ } else if (order === 'descending') {
351
+ data = data.sort((a: any, b: any) => b[prop] - a[prop]);
352
+ }
353
+ };