import React from 'react';
import { Popover, Button, Checkbox, Space, Input, Divider } from 'antd';
import { SearchOutlined } from "@ant-design/icons";
import 'g-userGroup/src/component/IUserBehaviorSequence/EventFilter/index.less';
import _ from 'lodash';
interface IFilterProps {
title?: string,
onChange?: (value: any[]) => void,
value?: any[],
options: {
label: string,
value: string
}[],
position?: 'top' | 'left' | 'right' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop',
canSelectAll?: boolean,
loading?: boolean,
triggerNode?: React.ReactNode,
size?: 'small' | 'middle' | 'large'
style?: any,
}
export default class EventFilter extends React.Component<IFilterProps, {}> {
state = {
visible: false,
value: [],
searchKeywords: '',
}
lastValue: any[] = []
componentDidMount() {
const { value } = this.props;
if (value) {
this.setState({ value })
this.lastValue = value
}
}
componentDidUpdate(preProps) {
const lastValue = preProps?.value
const curValue = this.props?.value
if (lastValue && curValue && !(_.isEqual(lastValue, curValue))) {
this.setState({ value: curValue })
this.lastValue = curValue
}
}
handleVisibleChange = (visible: boolean) => {
this.setState({ visible, searchKeywords: '', value: this.props.value })
}
handleChange = (checkedList: any[]) => {
let { options } = this.props;
let value = this.lastValue;
const { searchKeywords } = this.state;
let realOptions = options.filter(it => it.label.includes(searchKeywords));
let realOptionsValues = realOptions.map((it) => it.value);
realOptionsValues.forEach((item) => {
if (
value.includes(item) &&
!checkedList.includes(item)
) {
value = value.filter(
(it) => it !== item
);
}
});
let changeValues = checkedList.filter((it) => {
return !value.includes(it);
});
let newCheckedList = [...value, ...changeValues];
this.lastValue = newCheckedList
this.setState({ value: newCheckedList })
}
onCheckAllChange = (e, hasSearch?: boolean) => {
const { options } = this.props
const { searchKeywords } = this.state
if (e.target.checked) {
if (hasSearch) {
this.handleChange(options.filter(it => it.label?.includes(searchKeywords)).map(({ value }) => value) || []);
} else {
this.handleChange(options.map(({ value }) => value));
}
} else {
this.handleChange([]);
}
};
handleOk = () => {
const { onChange } = this.props
onChange && onChange(this.state.value)
this.setState({ visible: false })
}
handleFilterReset = () => {
const { value } = this.state
if (value.length) {
this.setState({ value: [] })
this.lastValue = []
}
}
getContent = () => {
const { options, canSelectAll } = this.props;
const { value } = this.state;
const { searchKeywords } = this.state;
let renderOptions = options.filter(it => it.label?.includes(searchKeywords)) || [];
return <div className='d-flex flex-column' onClick={(e) => e.stopPropagation()}>
<Input
onChange={(e)=>{
this.setState({ searchKeywords: e.target.value })
}}
value={searchKeywords}
style={{ width: '100%', marginBottom: 15 }}
prefix={<SearchOutlined />}
placeholder="请输入"
/>
<div className='filter-checbox-group-content'>
{canSelectAll && (
<>
<Checkbox
indeterminate={value.length && value.length < options.length}
onChange={(value) => this.onCheckAllChange(value, Boolean(searchKeywords))}
checked={value.length && value.length === options.length}
>
全选
</Checkbox>
<Divider className='my-2' />
</>
)}
<Checkbox.Group onChange={this.handleChange} value={value}>
<Space direction="vertical">
{
renderOptions.map((item) => {
return (
<Checkbox
key={item.value}
value={item.value}
>
<div style={{ whiteSpace: 'nowrap' }} title={item.label}>{item.label}</div>
</Checkbox>
);
})
}
</Space>
</Checkbox.Group>
</div>
<div className='m-checbox-group-content-footer'>
<div
style={{
color: value.length ? '#5BB7E1' : "#C9C9C9",
cursor: value.length ? 'pointer' : 'not-allowed',
userSelect: 'none'
}}
onClick={this.handleFilterReset}
>
重置
</div>
<Button type='primary' size='small' onClick={this.handleOk}>确定</Button>
</div>
</div>
}
render() {
const { position, title, loading, triggerNode, style, size } = this.props;
const { visible } = this.state;
const content = this.getContent()
return <div>
<Popover
overlayClassName='m-checkbox-dropdown-content m-arrow-close'
content={content}
trigger="click"
visible={visible}
placement={position || 'bottomRight'}
onVisibleChange={this.handleVisibleChange}
overlayStyle={{ ...style, zIndex: 1 }}
>
{
!triggerNode ? <Button size={size ? size : 'small'} loading={loading}>{title}</Button> :
<div style={{ userSelect: 'none' }} onClick={(e) => e.stopPropagation()}>{triggerNode}</div>
}
</Popover>
</div>
}
}