@lx-frontend/wrap-element-ui 1.0.0-beta.8 → 1.0.1-7.beta-2

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 (31) hide show
  1. package/README.md +2 -2
  2. package/package.json +6 -5
  3. package/src/components/AddMembers/index.vue +32 -40
  4. package/src/components/EditableTable/bizHooks/index.ts +7 -0
  5. package/src/components/EditableTable/{useCellHover.ts → bizHooks/useCellHover.ts} +1 -1
  6. package/src/components/EditableTable/bizHooks/useColumnHeaderOperation.ts +329 -0
  7. package/src/components/EditableTable/{useDefaultOperation.ts → bizHooks/useDefaultOperation.ts} +2 -2
  8. package/src/components/EditableTable/{useDragSort.ts → bizHooks/useDragSort.ts} +4 -4
  9. package/src/components/EditableTable/{usePagination.ts → bizHooks/usePagination.ts} +3 -3
  10. package/src/components/EditableTable/{useRowBgColor.ts → bizHooks/useRowBgColor.ts} +9 -16
  11. package/src/components/EditableTable/bizHooks/useViewSetting.ts +125 -0
  12. package/src/components/EditableTable/features/bizColorSelect.vue +63 -0
  13. package/src/components/EditableTable/features/bizEditCell.vue +44 -0
  14. package/src/components/EditableTable/features/bizTableHeaderPopover/BizCheckboxFilter.vue +40 -0
  15. package/src/components/EditableTable/features/bizTableHeaderPopover/BizColorRadioFilter.vue +56 -0
  16. package/src/components/EditableTable/features/bizTableHeaderPopover/BizDoubleDatePickerFilter.vue +91 -0
  17. package/src/components/EditableTable/features/bizTableHeaderPopover/BizInputFilter.vue +26 -0
  18. package/src/components/EditableTable/features/bizTableHeaderPopover/BizMonthDayPicker.helper.ts +131 -0
  19. package/src/components/EditableTable/features/bizTableHeaderPopover/BizMonthDayPicker.vue +115 -0
  20. package/src/components/EditableTable/features/bizTableHeaderPopover/BizRadioFilter.vue +39 -0
  21. package/src/components/EditableTable/features/bizTableHeaderPopover/BizSortFilter.vue +50 -0
  22. package/src/components/EditableTable/features/bizTableHeaderPopover/index.vue +155 -0
  23. package/src/components/EditableTable/features/bizTableOperatePopover.vue +67 -0
  24. package/src/components/EditableTable/features/bizViewSettingDialog.vue +137 -0
  25. package/src/components/EditableTable/index.less +524 -428
  26. package/src/components/EditableTable/index.vue +167 -456
  27. package/src/components/EditableTable/{types.ts → types/index.ts} +176 -116
  28. package/src/components/SearchForm/index.vue +7 -4
  29. package/src/components/SearchForm/types/index.ts +63 -0
  30. package/src/components/EditableTable/useColumnHeaderOperation.ts +0 -326
  31. package/src/components/EditableTable/useViewSetting.ts +0 -119
@@ -1,326 +0,0 @@
1
- import { computed, ref, watch, nextTick, Ref } from "vue"
2
- import { IColumnConfig, IEmits, IProps } from './types';
3
-
4
- interface IUseColumnHeaderOperationParams {
5
- props: IProps
6
- tableDomRef: any
7
- sortFilterPopoverRef: any
8
- emit: IEmits;
9
- showingColumns: Ref<string[]>
10
- }
11
-
12
- export default function useColumnHeaderOperation({ props, tableDomRef, sortFilterPopoverRef, emit, showingColumns }: IUseColumnHeaderOperationParams) {
13
-
14
- // column如果有sortable属性,点击列头部,会直接触发排序,为了在弹窗点确定时再触发排序,需要阻止点击立即排序
15
- // 所以,初始渲染时,将sortable设置为false,在触发排序逻辑时再设置成真实的值,再利用el-table自身的排序逻辑触发排序
16
- const inSorting = ref(false);
17
-
18
- // 生效中的排序配置
19
- const sortType = ref<'ascending' | 'descending' | null>(null);
20
- const sortingColumn = ref<IColumnConfig | null>(null);
21
-
22
- // 临时的排序配置
23
- const tempSortType = ref<'ascending' | 'descending' | null>(null);
24
- const tempSortingColumn = ref<IColumnConfig | null>(null);
25
-
26
- // 生效中的过滤配置 和 临时过滤配置
27
- const filteredValue = ref<Record<string, string | number | number[] | string[]>>({});
28
- const tempFilteredValue = ref<Record<string, string | number | number[] | string[]>>({});
29
-
30
- // 生效中的统计配置 和 临时统计配置
31
- const tempSummaryList = ref<string[]>([]);
32
- const summaryList = ref<string[]>([]);
33
-
34
- // 生效中的搜索配置 和 临时搜索配置
35
- const searchValue = ref<Record<string, string>>({});
36
- const tempSearchValue = ref<Record<string, string>>({});
37
-
38
- const isColumnFiltering = computed(() => Object.keys(tempFilteredValue.value).some(k => {
39
- if (!Array.isArray(tempFilteredValue.value[k])) return tempFilteredValue.value[k]
40
- return tempFilteredValue.value[k]?.length;
41
- }));
42
-
43
- const showColumnHeadSortIcon = (column: IColumnConfig) => column.filters || column.isColumnSortable || column.search || column.summary;
44
-
45
- watch(
46
- () => props.columnConfig,
47
- (val) => {
48
- filteredValue.value = val.reduce((prev, curr) => ({ ...prev, [curr.prop]: [] }), {});
49
- tempFilteredValue.value = { ...filteredValue.value };
50
- },
51
- { immediate: true }
52
- )
53
-
54
- const tableSummaryMethod = (param) => {
55
- const { columns, data } = param;
56
- const sums: (string | number)[] = []
57
- columns.forEach((column, index) => {
58
- if (index === 0) {
59
- sums[index] = '合计';
60
- return;
61
- }
62
- if (!summaryList.value.includes(column.property)) {
63
- sums[index] = '';
64
- } else {
65
- const values = data.map(item => item[column.property]);
66
- // 找到对应列的summaryMethod函数
67
- const summaryMethod = props.columnConfig.find(c => c.prop === column.property)?.summaryMethod ?? (() => '');
68
- sums[index] = summaryMethod(values);
69
- }
70
- })
71
-
72
- return sums
73
- }
74
-
75
- const isColumnHeadActive = (column: IColumnConfig) => {
76
- return (
77
- column.filters && (Array.isArray(column.filters)
78
- ? (filteredValue.value[column.prop] as any[]).length
79
- : column.filters.type === 'radio'
80
- ? filteredValue.value[column.prop]
81
- : (filteredValue.value[column.prop] as any[]).length)
82
- ) ||
83
- (
84
- column.search
85
- ? Array.isArray(column.search) && column.search?.some(v => searchValue.value[v.prop])
86
- : searchValue.value[column.prop]
87
- ) ||
88
- sortingColumn.value?.prop === column.prop ||
89
- summaryList.value.includes(column.prop);
90
- }
91
-
92
- const handleHeaderPopoverShow = (column) => {
93
- // 关闭其他的排序和筛选弹窗(理论上不写也能关闭其他,但是就是有些列会出现两个弹窗同时出现的情况)
94
- closeSortAndFilterPopover(column.prop);
95
- tempFilteredValue.value = { ...filteredValue.value };
96
- tempSearchValue.value = { ...searchValue.value };
97
- tempSortType.value = sortType.value;
98
- tempSortingColumn.value = sortingColumn.value ? { ...sortingColumn.value } as IColumnConfig : null;
99
- // 临时合计项设置成实际的合计项
100
- tempSummaryList.value = [...summaryList.value];
101
- }
102
-
103
- const closeSortAndFilterPopover = (exceptProp?: string) => {
104
- sortFilterPopoverRef.value?.forEach((item: any) => {
105
- if (!exceptProp || exceptProp !== item.$el.dataset.prop) {
106
- item.doClose();
107
- }
108
- });
109
- }
110
-
111
- const handleSort = (type: 'ascending' | 'descending', column) => {
112
- tempSortType.value = type;
113
- tempSortingColumn.value = column;
114
- }
115
-
116
- const columnMap = computed(() => {
117
- const obj: Record<string, IColumnConfig> = {}
118
- props.columnConfig.forEach(column => {
119
- obj[column.prop] = column
120
- })
121
- return obj
122
- })
123
-
124
- const emitSearch = () => {
125
- const params: Record<string, any> = {};
126
- // 仅提交显示的列的相关数据
127
- showingColumns.value.forEach(prop => {
128
- const column = columnMap.value[prop]
129
- if (column.filters) {
130
- params[prop] = filteredValue.value[prop]
131
- }
132
- if (column.search) {
133
- if (Array.isArray(column.search)) {
134
- column.search.forEach(v => {
135
- params[v.prop] = searchValue.value[v.prop]
136
- })
137
- } else {
138
- params[prop] = searchValue.value[prop]
139
- }
140
- }
141
- })
142
-
143
- Object.keys(params).forEach(key => {
144
- if (params[key] === undefined) delete params[key]
145
- })
146
-
147
- emit('search', params);
148
- };
149
-
150
- const handleHeaderOperationConfirm = async (column: IColumnConfig, scope) => {
151
- if (column.search) {
152
- // 校验
153
- if (Array.isArray(column.search)) {
154
- let validate = true;
155
- column.search.forEach(v => {
156
- if (!tempSearchValue.value[v.prop]) tempSearchValue.value[v.prop] = ''
157
- if (!validate) return
158
- if (v.validator) {
159
- const result = v.validator(tempSearchValue.value[v.prop]);
160
- if (validate && !result) validate = false;
161
- }
162
- })
163
- // 校验未通过
164
- if (!validate) return
165
- } else {
166
- if (!tempSearchValue.value[column.prop]) tempSearchValue.value[column.prop] = ''
167
- }
168
- }
169
-
170
- summaryList.value = [...tempSummaryList.value];
171
- sortingColumn.value = tempSortingColumn.value ? { ...tempSortingColumn.value } : null;
172
- sortType.value = tempSortType.value;
173
-
174
- if (sortingColumn.value) { // 确认时提交排序
175
- if (props.localSort) {
176
- // 恢复列配置的sortable属性,只有列配置的sortable为true,才能用下面的sort方法
177
- inSorting.value = true;
178
- await nextTick();
179
- tableDomRef.value?.sort(sortingColumn.value.prop, sortType.value);
180
- inSorting.value = false
181
- } else {
182
- emit('sort-change', { order: sortType.value, prop: sortingColumn.value.prop });
183
- }
184
- }
185
-
186
- filteredValue.value = { ...tempFilteredValue.value };
187
- searchValue.value = { ...tempSearchValue.value };
188
-
189
- emitSearch();
190
-
191
- filterColumns(scope.store);
192
-
193
- closeSortAndFilterPopover();
194
- await nextTick()
195
- tableDomRef.value?.doLayout();
196
- }
197
-
198
- const clearSort = () => {
199
- sortingColumn.value = null;
200
- sortType.value = null;
201
- if (props.localSort) { // 前端过滤
202
- tableDomRef.value?.clearSort();
203
- } else { // 接口过滤
204
- emit('sort-change', { order: null, prop: '' });
205
- }
206
- }
207
-
208
- const setSort = (params: { order: 'ascending' | 'descending', prop: string }) => {
209
- const column = props.columnConfig.find(c => c.prop === params.prop);
210
- if (column) {
211
- sortingColumn.value = column;
212
- sortType.value = params.order;
213
- if (props.localSort) {
214
- tableDomRef.value?.sort(params.prop, params.order);
215
- }
216
- }
217
- }
218
-
219
- const handleHeaderOperationReset = async (column: IColumnConfig, scope) => {
220
- if (sortingColumn.value && sortingColumn.value.prop === column.prop) {
221
- clearSort();
222
- }
223
-
224
- // 合计
225
- summaryList.value = summaryList.value.filter(item => item !== column.prop);
226
-
227
- if (column.filters) {
228
- filteredValue.value[column.prop] = Array.isArray(column.filters)
229
- ? []
230
- : column.filters.default ?? []
231
- }
232
- if (column.search) {
233
- if (!Array.isArray(column.search)) {
234
- searchValue.value[column.prop] = '';
235
- } else {
236
- column.search.forEach(v => {
237
- searchValue.value[v.prop] = '';
238
- })
239
- }
240
- }
241
-
242
- emitSearch();
243
-
244
- filterColumns(scope.store);
245
-
246
- closeSortAndFilterPopover();
247
- await nextTick();
248
- tableDomRef.value?.doLayout();
249
- }
250
-
251
- const filterColumns = (store) => {
252
- if (!props.localFilter) return
253
- store.states.columns.forEach(column => {
254
- if (filteredValue.value[column.property]) {
255
- store.commit('filterChange', {
256
- column,
257
- values: filteredValue.value[column.property],
258
- });
259
- }
260
- });
261
-
262
- // 根据searchValue过滤数据
263
- const data = store.states.data.filter(item => {
264
- const flag = Object.keys(searchValue.value)
265
- .filter(key => searchValue.value[key])
266
- .reduce((pre, key) => {
267
- const value = searchValue.value[key];
268
-
269
- return pre && item[key] && `${item[key]}`.indexOf(value) > -1;
270
- }, true);
271
-
272
- return flag;
273
- });
274
-
275
- store.states.data = data;
276
- }
277
-
278
- const setSearchParams = (params: Record<string, any>) => {
279
- const _searchValue = {};
280
- const _filteredValue = {};
281
-
282
- // 设置搜索和过滤参数时,如果使用 showingColumns 遍历,会导致通过外部设置未显示的列的搜索和过滤参数丢失
283
- props.columnConfig.forEach(column => {
284
- if (column.search) {
285
- if (Array.isArray(column.search)) {
286
- column.search.forEach(v => {
287
- _searchValue[v.prop] = params[v.prop];
288
- });
289
- } else {
290
- _searchValue[column.prop] = params[column.prop] ?? '';
291
- }
292
- }
293
- if (column.filters) {
294
- const value = params[column.prop] ?? (Array.isArray(column.filters) ? [] : column.filters.default);
295
- _filteredValue[column.prop] = value;
296
- }
297
- })
298
-
299
- searchValue.value = { ...searchValue.value, ..._searchValue }
300
- filteredValue.value = { ...filteredValue.value, ..._filteredValue }
301
- }
302
-
303
- return {
304
- setSort,
305
- clearSort,
306
- setSearchParams,
307
- isColumnHeadActive,
308
- handleHeaderPopoverShow,
309
- handleSort,
310
- handleHeaderOperationConfirm,
311
- handleHeaderOperationReset,
312
- summaryList,
313
- tableSummaryMethod,
314
- filteredValue,
315
- showColumnHeadSortIcon,
316
- tempSortingColumn,
317
- tempSearchValue,
318
- tempFilteredValue,
319
- tempSummaryList,
320
- tempSortType,
321
- sortingColumn,
322
- isColumnFiltering,
323
- searchValue,
324
- inSorting,
325
- }
326
- }
@@ -1,119 +0,0 @@
1
- import { ref, nextTick, watch, ComputedRef, Ref, onMounted, computed } from "vue"
2
- import { IColumnConfig, IProps } from "./types"
3
-
4
- interface IViewSettingParams {
5
- tableDomRef: any
6
- showingColumns: Ref<string[]>
7
- actualColumns: ComputedRef<IColumnConfig[]>
8
- props: IProps
9
- }
10
-
11
- export default function useViewSetting({ tableDomRef, showingColumns, actualColumns, props }: IViewSettingParams) {
12
- const viewSettingDragSortOptions = ref<IColumnConfig[]>([]);
13
- const columnsToBeShown = ref<string[]>([]); // 显示设置弹窗中勾选的列
14
- const viewSettingVisible = ref(false);
15
- const leftFixedColumnCount = ref(0);
16
- const tempLeftFixedColumnCount = ref(0);
17
-
18
- const storageKey = computed(() => `@lx-frontend/wrap-element-ui/table_setting_cloumns/${props.settingStorgeKey || (location.pathname === '/' ? location.hash : location.pathname)}`);
19
-
20
- const saveSettingToStorge = () => localStorage.setItem(storageKey.value, JSON.stringify({
21
- showingColumns: showingColumns.value,
22
- leftFixedColumnCount: leftFixedColumnCount.value
23
- }));
24
-
25
- watch(
26
- () => props.columnConfig,
27
- (val) => {
28
- const _keys = new Set(props.columnConfig.map(c => (c.prop)));
29
- const _cache = localStorage.getItem(storageKey.value);
30
- const setColumns = () => (showingColumns.value = val.filter(v => !v.defaultHide).map(c => c.prop));
31
- if (!_cache) {
32
- setColumns();
33
- leftFixedColumnCount.value = props.leftFixedCount as number;
34
- } else {
35
- try {
36
- // 缓存数据字段可能随着更新导致对不上,清理无效数据,防止出问题
37
- const cache = JSON.parse(_cache);
38
- if (!cache.showingColumns || !Array.isArray(cache.showingColumns)) {
39
- setColumns();
40
- } else {
41
- showingColumns.value = cache.showingColumns.filter(key => _keys.has(key));
42
- }
43
- const _leftFixedColumnCount = Number(cache?.leftFixedColumnCount)
44
- leftFixedColumnCount.value = isNaN(_leftFixedColumnCount) ? (props.leftFixedCount as number) : _leftFixedColumnCount;
45
- // 写入清理后的数据
46
- saveSettingToStorge();
47
- } catch (error) {
48
- console.error(error);
49
- localStorage.removeItem(storageKey.value);
50
- setColumns();
51
- }
52
- }
53
- },
54
- { immediate: true }
55
- )
56
-
57
- watch(
58
- () => columnsToBeShown.value,
59
- (val) => {
60
- viewSettingDragSortOptions.value = props.columnConfig
61
- .filter(c => val.includes(c.prop));
62
- if (tempLeftFixedColumnCount.value > val.length) tempLeftFixedColumnCount.value = val.length
63
- },
64
- { immediate: true }
65
- )
66
-
67
- watch(
68
- () => showingColumns.value,
69
- (val) => {
70
- // 只要正在显示的列发生变化,dialog中的显示项也要同步变化,反之不然
71
- columnsToBeShown.value = [...val];
72
- },
73
- { immediate: true }
74
- )
75
-
76
- onMounted(() => {
77
- leftFixedColumnCount.value = props.leftFixedCount as number;
78
- })
79
-
80
- const handleViewSettingShow = () => {
81
- viewSettingDragSortOptions.value = actualColumns.value
82
- .filter(c => columnsToBeShown.value.includes(c.prop));
83
- tempLeftFixedColumnCount.value = leftFixedColumnCount.value;
84
- viewSettingVisible.value = true;
85
- }
86
-
87
- const handleViewSettingClose = () => {
88
- viewSettingVisible.value = false;
89
- // 恢复显示的列
90
- showingColumns.value = actualColumns.value.map(c => c.prop);
91
- }
92
-
93
- const handleViewSettingConfirm = async () => {
94
- viewSettingVisible.value = false;
95
- showingColumns.value = viewSettingDragSortOptions.value.map(c => c.prop);
96
- leftFixedColumnCount.value = tempLeftFixedColumnCount.value;
97
- saveSettingToStorge()
98
- await nextTick();
99
- tableDomRef.value?.doLayout();
100
- }
101
-
102
- const handleInputTempLeftFixedColumnCount = (value: string) => {
103
- const _value = Number(value)
104
- if (isNaN(_value)) return
105
- tempLeftFixedColumnCount.value = Math.max(0, Math.min(columnsToBeShown.value.length, Math.floor(_value)))
106
- }
107
-
108
- return {
109
- viewSettingDragSortOptions,
110
- columnsToBeShown,
111
- viewSettingVisible,
112
- leftFixedColumnCount,
113
- tempLeftFixedColumnCount,
114
- handleInputTempLeftFixedColumnCount,
115
- handleViewSettingShow,
116
- handleViewSettingClose,
117
- handleViewSettingConfirm
118
- }
119
- }