|
|
|
import React from 'react';
|
|
|
|
import ReactDOM from 'react-dom';
|
|
|
|
import Menu, { SubMenu, Item as MenuItem } from 'rc-menu';
|
|
|
|
import closest from 'dom-closest';
|
|
|
|
import classNames from 'classnames';
|
|
|
|
import Dropdown from '../dropdown';
|
|
|
|
import Icon from '../icon';
|
|
|
|
import Checkbox from '../checkbox';
|
|
|
|
import Radio from '../radio';
|
|
|
|
import FilterDropdownMenuWrapper from './FilterDropdownMenuWrapper';
|
|
|
|
|
|
|
|
export interface FilterMenuProps {
|
|
|
|
locale: any;
|
|
|
|
selectedKeys: string[];
|
|
|
|
column: {
|
|
|
|
filterMultiple?: boolean,
|
|
|
|
filterDropdown?: React.ReactNode,
|
|
|
|
filters?: { text: string; value: string, children?: any[] }[],
|
|
|
|
filterDropdownVisible?: boolean,
|
|
|
|
onFilterDropdownVisibleChange?: (visible: boolean) => any,
|
|
|
|
fixed?: boolean | string,
|
|
|
|
filterIcon?: React.ReactNode;
|
|
|
|
};
|
|
|
|
confirmFilter: (column: Object, selectedKeys: string[]) => any;
|
|
|
|
prefixCls: string;
|
|
|
|
dropdownPrefixCls: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
export default class FilterMenu extends React.Component<FilterMenuProps, any> {
|
|
|
|
static defaultProps = {
|
|
|
|
handleFilter() {},
|
|
|
|
column: {},
|
|
|
|
};
|
|
|
|
|
|
|
|
neverShown: boolean;
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
const visible = ('filterDropdownVisible' in props.column) ?
|
|
|
|
props.column.filterDropdownVisible : false;
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
selectedKeys: props.selectedKeys,
|
|
|
|
keyPathOfSelectedItem: {}, // 记录所有有选中子菜单的祖先菜单
|
|
|
|
visible,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
const { column } = this.props;
|
|
|
|
const rootNode = ReactDOM.findDOMNode(this);
|
|
|
|
const filterBelongToScrollBody = !!closest(rootNode, `.ant-table-scroll`);
|
|
|
|
if (filterBelongToScrollBody && column.fixed) {
|
|
|
|
// When fixed column have filters, there will be two dropdown menus
|
|
|
|
// Filter dropdown menu inside scroll body should never be shown
|
|
|
|
// To fix https://github.com/ant-design/ant-design/issues/5010
|
|
|
|
this.neverShown = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
|
|
|
const { column } = nextProps;
|
|
|
|
const newState = {} as {
|
|
|
|
selectedKeys: string[];
|
|
|
|
visible: boolean;
|
|
|
|
};
|
|
|
|
if ('selectedKeys' in nextProps) {
|
|
|
|
newState.selectedKeys = nextProps.selectedKeys;
|
|
|
|
}
|
|
|
|
if ('filterDropdownVisible' in column) {
|
|
|
|
newState.visible = column.filterDropdownVisible;
|
|
|
|
}
|
|
|
|
if (Object.keys(newState).length > 0) {
|
|
|
|
this.setState(newState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setSelectedKeys = ({ selectedKeys }) => {
|
|
|
|
this.setState({ selectedKeys });
|
|
|
|
}
|
|
|
|
|
|
|
|
setVisible(visible) {
|
|
|
|
const { column } = this.props;
|
|
|
|
if (!('filterDropdownVisible' in column)) {
|
|
|
|
this.setState({ visible });
|
|
|
|
}
|
|
|
|
if (column.onFilterDropdownVisibleChange) {
|
|
|
|
column.onFilterDropdownVisibleChange(visible);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handleClearFilters = () => {
|
|
|
|
this.setState({
|
|
|
|
selectedKeys: [],
|
|
|
|
}, this.handleConfirm);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleConfirm = () => {
|
|
|
|
this.setVisible(false);
|
|
|
|
this.confirmFilter();
|
|
|
|
}
|
|
|
|
|
|
|
|
onVisibleChange = (visible) => {
|
|
|
|
this.setVisible(visible);
|
|
|
|
if (!visible) {
|
|
|
|
this.confirmFilter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
confirmFilter() {
|
|
|
|
if (this.state.selectedKeys !== this.props.selectedKeys) {
|
|
|
|
this.props.confirmFilter(this.props.column, this.state.selectedKeys);
|
|
|
|
}
|
|