Skip to content

Commit 0afb275

Browse files
leadingtw273mike
andauthored
feat(table): 新增 filter 與 sort 受控方式 (#9060)
* feat(table): 調整 filters 為受控組件 * feat(table): 調整 sort 為受控組件 * feat(table): 設置重置時將排序與篩選設回預設值 * fix(table): 修正未設置篩選項會出現 filteredValue 為 null 的狀況 * feat(table): 設置限定服務端排序與篩選默認值儲存 * tests(table/filter): 修正 table filter 測試問題 "filter test by namePath is array" 測試項 其 filters 與 onFilter 配置依照文件所示 其為本地篩選 將不會觸發 服務端請求 修正為正確服務端請求配置 onFilter => false * fix(table): 修正 filter 使用自訂篩選項時無法被正確綁定值問題 * fix(table): 修正服務端排序清空時無法正確被設置問題 * tests(table/filter): 新增篩選排序測試 1. 新增篩選/排序本地端測試 2. 新增篩選/排序服務端測試 3. 新增服務端預設值重置測試 --------- Co-authored-by: mike <[email protected]>
1 parent d7f4ae2 commit 0afb275

File tree

3 files changed

+637
-46
lines changed

3 files changed

+637
-46
lines changed

packages/table/src/Table.tsx

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -134,29 +134,6 @@ function TableRender<T extends Record<string, any>, U, ValueType>(
134134
return loopFilter(tableColumns);
135135
}, [counter.columnsMap, tableColumns]);
136136

137-
/** 如果所有列中的 filters = true | undefined 说明是用的是本地筛选 任何一列配置 filters=false,就能绕过这个判断 */
138-
const useLocaleFilter = useMemo(() => {
139-
const _columns: any[] = [];
140-
// 平铺所有columns, 用于判断是用的是本地筛选
141-
const loopColumns = (data: any[]) => {
142-
for (let i = 0; i < data.length; i++) {
143-
const _curItem = data[i];
144-
if (_curItem.children) {
145-
loopColumns(_curItem.children);
146-
} else {
147-
_columns.push(_curItem);
148-
}
149-
}
150-
};
151-
loopColumns(columns);
152-
return _columns?.every((column) => {
153-
return (
154-
(!!column.filters && !!column.onFilter) ||
155-
(column.filters === undefined && column.onFilter === undefined)
156-
);
157-
});
158-
}, [columns]);
159-
160137
/**
161138
* 如果是分页的新增,总是加到最后一行
162139
*
@@ -226,9 +203,8 @@ function TableRender<T extends Record<string, any>, U, ValueType>(
226203
extra: TableCurrentDataSource<T>,
227204
) => {
228205
rest.onChange?.(changePagination, filters, sorter, extra);
229-
if (!useLocaleFilter) {
230-
onFilterChange(omitUndefined<any>(filters));
231-
}
206+
207+
onFilterChange(omitUndefined<any>(filters));
232208

233209
// 制造筛选的数据
234210
// 制造一个排序的数据
@@ -240,7 +216,7 @@ function TableRender<T extends Record<string, any>, U, ValueType>(
240216
}),
241217
{},
242218
);
243-
onSortChange(omitUndefined<any>(data));
219+
onSortChange(omitUndefined<any>(data) ?? {});
244220
} else {
245221
const sorterOfColumn = sorter.column?.sorter;
246222
const isSortByField = sorterOfColumn?.toString() === sorterOfColumn;
@@ -249,7 +225,7 @@ function TableRender<T extends Record<string, any>, U, ValueType>(
249225
omitUndefined({
250226
[`${isSortByField ? sorterOfColumn : sorter.field}`]:
251227
sorter.order as SortOrder,
252-
}),
228+
}) ?? {},
253229
);
254230
}
255231
},
@@ -522,11 +498,44 @@ const ProTable = <
522498
{},
523499
);
524500

525-
/** 设置默认排序和筛选值 */
501+
// 平铺所有columns, 用于判断是用的是本地筛选/排序
502+
const loopColumns = useCallback((data: any[]) => {
503+
const _columns: any[] = [];
504+
505+
for (let i = 0; i < data.length; i++) {
506+
const _curItem = data[i];
507+
if (_curItem.children) {
508+
loopColumns(_curItem.children);
509+
} else {
510+
_columns.push(_curItem);
511+
}
512+
}
513+
514+
return _columns
515+
}, []);
516+
517+
/** 如果所有列中的 filters = true | undefined 说明是用的是本地筛选 任何一列配置 filters=false,就能绕过这个判断 */
518+
const useLocaleFilter = useMemo(() => {
519+
const _columns: any[] = loopColumns(propsColumns);
520+
return _columns?.every((column) => {
521+
return (
522+
(!!column.filters && !!column.onFilter) ||
523+
(column.filters === undefined && column.onFilter === undefined)
524+
);
525+
});
526+
}, [loopColumns, propsColumns]);
527+
528+
/** 如果所有列中的 sorter != true 说明是用的是本地排序 任何一列配置 sorter=true,就能绕过这个判断 */
529+
const useLocaleSorter = useMemo(() => {
530+
const _columns: any[] = loopColumns(propsColumns);
531+
return _columns?.every((column) => column.sorter !== true);
532+
}, [loopColumns, propsColumns]);
533+
534+
/** 设置默认的服務端排序和筛选值 */
526535
useEffect(() => {
527536
const { sort, filter } = parseDefaultColumnConfig(propsColumns);
528-
setProFilter(filter);
529-
setProSort(sort);
537+
if(!useLocaleFilter) setProFilter(filter);
538+
if(!useLocaleSorter) setProSort(sort);
530539
// eslint-disable-next-line react-hooks/exhaustive-deps
531540
}, []);
532541

@@ -746,10 +755,13 @@ const ProTable = <
746755
resetAll: () => {
747756
// 清空选中行
748757
onCleanSelected();
758+
759+
const { sort, filter } = parseDefaultColumnConfig(propsColumns);
749760
// 清空筛选
750-
setProFilter({});
761+
setProFilter(filter);
751762
// 清空排序
752-
setProSort({});
763+
setProSort(sort);
764+
753765
// 清空 toolbar 搜索
754766
counter.setKeyWords(undefined);
755767
// 重置页码
@@ -778,6 +790,8 @@ const ProTable = <
778790
editableUtils,
779791
rowKey,
780792
childrenColumnName: props.expandable?.childrenColumnName,
793+
proFilter,
794+
proSort,
781795
}).sort(columnSort(counter.columnsMap));
782796
// eslint-disable-next-line react-hooks/exhaustive-deps
783797
}, [
@@ -788,6 +802,8 @@ const ProTable = <
788802
type,
789803
// eslint-disable-next-line react-hooks/exhaustive-deps
790804
editableUtils.editableKeys && editableUtils.editableKeys.join(','),
805+
proFilter,
806+
proSort,
791807
]);
792808

793809
/** Table Column 变化的时候更新一下,这个参数将会用于渲染 */
@@ -990,11 +1006,11 @@ const ProTable = <
9901006
toolbarDom={toolbarDom}
9911007
hideToolbar={hideToolbar}
9921008
onSortChange={(sortConfig) => {
993-
if (proSort === sortConfig) return;
994-
setProSort(sortConfig ?? {});
1009+
if (useLocaleSorter || sortConfig === proSort) return;
1010+
setProSort(sortConfig);
9951011
}}
9961012
onFilterChange={(filterConfig) => {
997-
if (filterConfig === proFilter) return;
1013+
if (useLocaleFilter || filterConfig === proFilter) return;
9981014
setProFilter(filterConfig);
9991015
}}
10001016
editableUtils={editableUtils}

packages/table/src/utils/genProColumnToColumn.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
renderColumnsTitle,
2121
} from './columnRender';
2222
import { genColumnKey } from './index';
23+
import { SortOrder } from 'antd/lib/table/interface';
2324

2425
type ColumnToColumnReturnType<T> = (TableColumnType<T> & {
2526
index?: number;
@@ -31,6 +32,8 @@ type ColumnToColumnParams<T> = {
3132
columnEmptyText: ProFieldEmptyText;
3233
type: ProSchemaComponentTypes;
3334
editableUtils: UseEditableUtilType;
35+
proFilter: Record<string, (string | number)[] | null>;
36+
proSort: Record<string, SortOrder>;
3437
} & Pick<TableProps<T>, 'rowKey' | 'childrenColumnName'>;
3538

3639
/**
@@ -53,6 +56,8 @@ export function genProColumnToColumn<T extends AnyObject>(
5356
marginSM,
5457
rowKey = 'id',
5558
childrenColumnName = 'children',
59+
proFilter,
60+
proSort,
5661
} = params;
5762

5863
const subNameRecord = new Map();
@@ -69,6 +74,7 @@ export function genProColumnToColumn<T extends AnyObject>(
6974
children,
7075
onFilter,
7176
filters = [],
77+
sorter,
7278
} = columnProps as ProColumns<T, any>;
7379
const columnKey = genColumnKey(
7480
key || dataIndex?.toString(),
@@ -94,6 +100,15 @@ export function genProColumnToColumn<T extends AnyObject>(
94100
return omitBoolean(onFilter);
95101
};
96102

103+
// 对应筛选值,用作双向绑定
104+
const filteredValue = columnKey && proFilter[columnKey] !== undefined
105+
? proFilter[columnKey]
106+
: null;
107+
// 对应排序值,用作双向绑定
108+
const sortOrder = columnKey && proSort[columnKey] !== undefined
109+
? proSort[columnKey]
110+
: null;
111+
97112
let keyName: string | number | symbol = rowKey as string;
98113

99114
const tempColumns = {
@@ -109,6 +124,8 @@ export function genProColumnToColumn<T extends AnyObject>(
109124
).filter((valueItem) => valueItem && valueItem.value !== 'all')
110125
: filters,
111126
onFilter: genOnFilter(),
127+
filteredValue: filters && genOnFilter() == null? filteredValue : undefined,
128+
sortOrder: sorter === true ? sortOrder : undefined,
112129
fixed: config.fixed,
113130
width: columnProps.width || (columnProps.fixed ? 200 : undefined),
114131
children: (columnProps as ProColumns<T, any>).children

0 commit comments

Comments
 (0)