import React from 'react'; import {RendererProps} from '../../factory'; import {Action} from '../../types'; import {Icon} from '../../components/icons'; import Overlay from '../../components/Overlay'; import {findDOMNode} from 'react-dom'; import PopOver from '../../components/PopOver'; import {ITableStore} from '../../store/table'; import {setVariable} from '../../utils/helper'; export interface QuickSearchConfig { type?: string; controls?: any; tabs?: any; fieldSet?: any; [propName: string]: any; } export interface HeadCellSearchProps extends RendererProps { name: string; searchable: boolean | QuickSearchConfig; classPrefix: string; onQuery: (values: object) => void; } export class HeadCellSearchDropDown extends React.Component< HeadCellSearchProps, any > { state = { isOpened: false }; formItems: Array = []; constructor(props: HeadCellSearchProps) { super(props); this.open = this.open.bind(this); this.close = this.close.bind(this); this.close = this.close.bind(this); this.handleSubmit = this.handleSubmit.bind(this); this.handleAction = this.handleAction.bind(this); } buildSchema() { const {searchable, sortable, name, label, translate: __} = this.props; let schema: any; if (searchable === true) { schema = { title: '', controls: [ { type: 'text', name, placeholder: label, clearable: true } ] }; } else if (searchable) { if (searchable.controls || searchable.tabs || searchable.fieldSet) { schema = { title: '', ...searchable, controls: Array.isArray(searchable.controls) ? searchable.controls.concat() : undefined }; } else { schema = { title: '', className: searchable.formClassName, controls: [ { type: searchable.type || 'text', name: searchable.name || name, placeholder: label, ...searchable } ] }; } } if (schema && schema.controls && sortable) { schema.controls.unshift( { type: 'hidden', name: 'orderBy', value: name }, { type: 'button-group', name: 'orderDir', label: __('sort'), options: [ { label: __('asc'), value: 'asc' }, { label: __('desc'), value: 'desc' } ] } ); } if (schema) { const formItems: Array = []; schema.controls?.forEach( (item: any) => item.name && item.name !== 'orderBy' && item.name !== 'orderDir' && formItems.push(item.name) ); this.formItems = formItems; schema = { ...schema, type: 'form', wrapperComponent: 'div', actions: [ { type: 'button', label: __('reset'), actionType: 'clear-and-submit' }, { type: 'button', label: __('cancel'), actionType: 'cancel' }, { label: __('search'), type: 'submit', primary: true } ] }; } return schema || 'error'; } handleClickOutside() { this.close(); } open() { this.setState({ isOpened: true }); } close() { this.setState({ isOpened: false }); } handleAction(e: any, action: Action, ctx: object) { const {onAction} = this.props; if (action.actionType === 'cancel' || action.actionType === 'close') { this.close(); return; } if (action.actionType === 'reset') { this.close(); this.handleReset(); return; } onAction && onAction(e, action, ctx); } handleReset() { const {onQuery, data, name} = this.props; const values = {...data}; this.formItems.forEach(key => setVariable(values, key, undefined)); if (values.orderBy === name) { values.orderBy = ''; values.orderDir = 'asc'; } onQuery(values); } handleSubmit(values: any) { const {onQuery, name} = this.props; this.close(); if (values.orderDir) { values = { ...values, orderBy: name }; } onQuery(values); } isActive() { const {data, name, orderBy} = this.props; return orderBy === name || this.formItems.some(key => data?.[key]); } render() { const { render, name, data, searchable, store, orderBy, popOverContainer, classPrefix: ns, classnames: cx } = this.props; const formSchema = this.buildSchema(); const isActive = this.isActive(); return ( {this.state.isOpened ? ( findDOMNode(this))} placement="left-bottom-left-top right-bottom-right-top" target={ popOverContainer ? () => findDOMNode(this)!.parentNode : null } show > { render('quick-search-form', formSchema, { data: { ...data, orderBy: orderBy, orderDir: orderBy === name ? (store as ITableStore).orderDir : '' }, onSubmit: this.handleSubmit, onAction: this.handleAction }) as JSX.Element } ) : null} ); } }