mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-28 13:09:40 +08:00
fix: custom table filterDropdown (#28850)
* fix: get origin keys from nested filters. * fix: unexpected transformed filteredKyes with custom filterDropdown. * fix: simplify code.
This commit is contained in:
parent
6f69c89470
commit
0f0dc1577f
@ -5,6 +5,7 @@ import Table from '..';
|
||||
import Input from '../../input';
|
||||
import Tooltip from '../../tooltip';
|
||||
import Button from '../../button';
|
||||
import Select from '../../select';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
|
||||
// https://github.com/Semantic-Org/Semantic-UI-React/blob/72c45080e4f20b531fda2e3e430e384083d6766b/test/specs/modules/Dropdown/Dropdown-test.js#L73
|
||||
@ -507,6 +508,7 @@ describe('Table.filter', () => {
|
||||
});
|
||||
|
||||
it('three levels menu', () => {
|
||||
const onChange = jest.fn();
|
||||
const filters = [
|
||||
{ text: 'Upper', value: 'Upper' },
|
||||
{ text: 'Lower', value: 'Lower' },
|
||||
@ -536,6 +538,7 @@ describe('Table.filter', () => {
|
||||
filters,
|
||||
},
|
||||
],
|
||||
onChange,
|
||||
}),
|
||||
);
|
||||
jest.useFakeTimers();
|
||||
@ -551,6 +554,10 @@ describe('Table.filter', () => {
|
||||
dropdownWrapper = getDropdownWrapper(wrapper);
|
||||
dropdownWrapper.find('MenuItem').last().simulate('click');
|
||||
dropdownWrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
|
||||
onChange.mock.calls.forEach(([, currentFilters]) => {
|
||||
const [, val] = Object.entries(currentFilters)[0];
|
||||
expect(val).toEqual(['Jack']);
|
||||
});
|
||||
wrapper.update();
|
||||
expect(renderedNames(wrapper)).toEqual(['Jack']);
|
||||
dropdownWrapper.find('MenuItem').last().simulate('click');
|
||||
@ -906,6 +913,87 @@ describe('Table.filter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should work as expected with complex custom filterDropdown', () => {
|
||||
const onChange = jest.fn();
|
||||
const filterDropdown = ({ setSelectedKeys, selectedKeys, confirm }) => {
|
||||
const handleChange = selectedValues => {
|
||||
setSelectedKeys(selectedValues);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
labelInValue
|
||||
style={{ width: 200 }}
|
||||
value={selectedKeys}
|
||||
onChange={handleChange}
|
||||
options={[
|
||||
{
|
||||
value: 1,
|
||||
label: 'Not Identified',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: 'Closed',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: 'Communicated',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<button className="confirm-btn" type="submit" onClick={confirm}>
|
||||
Confirm
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const filteredValue = [
|
||||
{
|
||||
value: 2,
|
||||
label: 'Closed',
|
||||
},
|
||||
];
|
||||
const selectedValue = [
|
||||
{
|
||||
key: 2,
|
||||
value: 2,
|
||||
label: 'Closed',
|
||||
},
|
||||
{
|
||||
key: 1,
|
||||
value: 1,
|
||||
label: 'Not Identified',
|
||||
},
|
||||
];
|
||||
const wrapper = mount(
|
||||
createTable({
|
||||
onChange,
|
||||
columns: [
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
filterDropdown,
|
||||
filteredValue,
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
expect(wrapper.find('FilterDropdown').props().filterState.filteredKeys).toEqual(filteredValue);
|
||||
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
|
||||
wrapper.find('.ant-select-selector').simulate('mousedown');
|
||||
wrapper.find('.ant-select-item-option').first().simulate('click');
|
||||
wrapper.find('.confirm-btn').first().simulate('click');
|
||||
expect(onChange).toHaveBeenCalled();
|
||||
onChange.mock.calls.forEach(([, currentFilters]) => {
|
||||
const [, val] = Object.entries(currentFilters)[0];
|
||||
expect(val).toEqual(selectedValue);
|
||||
});
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/17089
|
||||
it('not crash when dynamic change filter', () => {
|
||||
const onChange = jest.fn();
|
||||
|
@ -34,9 +34,10 @@ function collectFilterStates<RecordType>(
|
||||
} else if (column.filters || 'filterDropdown' in column || 'onFilter' in column) {
|
||||
if ('filteredValue' in column) {
|
||||
// Controlled
|
||||
const filteredValues = Array.isArray(column.filteredValue)
|
||||
? column.filteredValue.map(String)
|
||||
: column.filteredValue;
|
||||
let filteredValues = column.filteredValue;
|
||||
if (!('filterDropdown' in column)) {
|
||||
filteredValues = filteredValues?.map(String) ?? filteredValues;
|
||||
}
|
||||
filterStates.push({
|
||||
column,
|
||||
key: getColumnKey(column, columnPos),
|
||||
@ -119,31 +120,6 @@ function injectFilter<RecordType>(
|
||||
});
|
||||
}
|
||||
|
||||
function generateFilterInfo<RecordType>(filterStates: FilterState<RecordType>[]) {
|
||||
const currentFilters: Record<string, (Key | boolean)[] | null> = {};
|
||||
|
||||
filterStates.forEach(({ key, filteredKeys, column }) => {
|
||||
const { filters, filterDropdown } = column;
|
||||
if (filterDropdown) {
|
||||
currentFilters[key] = filteredKeys || null;
|
||||
} else {
|
||||
const originKeys: ColumnFilterItem['value'][] = [];
|
||||
if (Array.isArray(filteredKeys)) {
|
||||
filters?.forEach((filter: ColumnFilterItem) => {
|
||||
if (filteredKeys.includes(String(filter.value))) {
|
||||
originKeys.push(filter.value);
|
||||
}
|
||||
});
|
||||
currentFilters[key] = originKeys;
|
||||
} else {
|
||||
currentFilters[key] = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return currentFilters;
|
||||
}
|
||||
|
||||
function flattenKeys(filters?: ColumnFilterItem[]) {
|
||||
let keys: (string | number | boolean)[] = [];
|
||||
(filters || []).forEach(({ value, children }) => {
|
||||
@ -155,6 +131,24 @@ function flattenKeys(filters?: ColumnFilterItem[]) {
|
||||
return keys;
|
||||
}
|
||||
|
||||
function generateFilterInfo<RecordType>(filterStates: FilterState<RecordType>[]) {
|
||||
const currentFilters: Record<string, (Key | boolean)[] | null> = {};
|
||||
|
||||
filterStates.forEach(({ key, filteredKeys, column }) => {
|
||||
const { filters, filterDropdown } = column;
|
||||
if (filterDropdown) {
|
||||
currentFilters[key] = filteredKeys || null;
|
||||
} else if (Array.isArray(filteredKeys)) {
|
||||
const keys = flattenKeys(filters);
|
||||
currentFilters[key] = keys.filter(originKey => filteredKeys.includes(String(originKey)));
|
||||
} else {
|
||||
currentFilters[key] = null;
|
||||
}
|
||||
});
|
||||
|
||||
return currentFilters;
|
||||
}
|
||||
|
||||
export function getFilterData<RecordType>(
|
||||
data: RecordType[],
|
||||
filterStates: FilterState<RecordType>[],
|
||||
|
Loading…
Reference in New Issue
Block a user