import React from 'react'; import { Definition } from 'sync-ql'; import { SvgIcon, MenuItem, Menu, Button, Tooltip, } from '@mui/material'; import { DataFilterSet, DataFilterType, DataFilterOperation, FiltersMessage, DataOption, } from '../types/filter.type'; import { FilterLabel } from './style'; import { DataTableFilterText } from './filter.text'; import { DataTableFilterDate } from './filter.date'; import { DataTableFilterNumber } from './filter.number'; import { DataTableFilterAuto } from './filter.auto'; import { DataTableFilterBoolean } from './filter.boolean'; export const operationsConstrains: Definition = { boolean: { equal: true, notEqual: true, }, number: { equal: true, notEqual: true, greaterThan: true, greaterThanOrEqual: true, lessThan: true, lessThanOrEqual: true, between: true, }, date: { equal: true, notEqual: true, greaterThan: true, greaterThanOrEqual: true, lessThan: true, lessThanOrEqual: true, between: true, }, set: { auto: true, }, text: { auto: true, equal: true, notEqual: true, greaterThan: true, greaterThanOrEqual: true, lessThan: true, lessThanOrEqual: true, startsWith: true, endsWith: true, contains: true, notContains: true, between: true, }, } interface DataTableFilterProps { type: DataFilterSet, label: string, operation: DataFilterOperation, range?: [DataFilterType, DataFilterType], value: DataFilterType | [DataFilterType, DataFilterType], messages: FiltersMessage, onChange: (operation: DataFilterOperation, value: DataFilterType | [DataFilterType, DataFilterType]) => void, onOptionsLoad: (text: string) => Promise, } export const DataTableFilter: React.FC = ({ type, label, operation, range, value, messages, onChange, onOptionsLoad }) => { const [operationMenuAnchor, setOperationMenuAnchor] = React.useState(null); const handleBooleanChange = (value: boolean | null) => { onChange(operation, value); } const handleTextChange = (value: string | null | (string | null)[]) => { onChange(operation, value as any); } const handleNumberChange = (value: string | number | null | (string | number | null)[]) => { onChange(operation, value as any); } const handleDateChange = (value: Date | null | (Date | null)[]) => { onChange(operation, value as any); } const handleAutoChange = (value: DataOption | null) => { onChange(operation, value as any); } const handleLoadOptions = async (inputText: string): Promise => { if (!!onOptionsLoad) { return await onOptionsLoad(inputText); } return []; } const getOperations = () => { const result: { [key: string]: { value: DataFilterOperation, icon: JSX.Element, component: JSX.Element } } = {}; const style: React.CSSProperties = label ? undefined : { width: 'calc(100% - 10px)', maxWidth: 'calc(100% - 10px)' } switch (type) { case 'boolean': result['equal'] = { value: 'equal', icon: , component: } result['notEqual'] = { value: 'notEqual', icon: , component: } break; case 'number': result['equal'] = { value: 'equal', icon: , component: } result['notEqual'] = { value: 'notEqual', icon: , component: } result['greaterThan'] = { value: 'greaterThan', icon: , component: } result['greaterThanOrEqual'] = { value: 'greaterThanOrEqual', icon: , component: } result['lessThan'] = { value: 'lessThan', icon: , component: } result['lessThanOrEqual'] = { value: 'lessThanOrEqual', icon: , component: } result['between'] = { value: 'between', icon: , component: } break; case 'date': result['equal'] = { value: 'equal', icon: , component: } result['notEqual'] = { value: 'notEqual', icon: , component: } result['greaterThan'] = { value: 'greaterThan', icon: , component: } result['greaterThanOrEqual'] = { value: 'greaterThanOrEqual', icon: , component: } result['lessThan'] = { value: 'lessThan', icon: , component: } result['lessThanOrEqual'] = { value: 'lessThanOrEqual', icon: , component: } result['between'] = { value: 'between', icon: , component: } break; case 'set': result['auto'] = { value: 'auto', icon: , component: } break; default: result['auto'] = { value: 'auto', icon: , component: } result['equal'] = { value: 'equal', icon: , component: } result['notEqual'] = { value: 'notEqual', icon: , component: } result['greaterThan'] = { value: 'greaterThan', icon: , component: } result['greaterThanOrEqual'] = { value: 'greaterThanOrEqual', icon: , component: } result['lessThan'] = { value: 'lessThan', icon: , component: } result['lessThanOrEqual'] = { value: 'lessThanOrEqual', icon: , component: } result['startsWith'] = { value: 'startsWith', icon: , component: } result['endsWith'] = { value: 'endsWith', icon: , component: } result['contains'] = { value: 'contains', icon: , component: } result['notContains'] = { value: 'notContains', icon: , component: } result['between'] = { value: 'between', icon: , component: } break; } return result; } const handleOpenOperationMenu = (event: React.MouseEvent) => { setOperationMenuAnchor(event.currentTarget); } const handleCloseOperationMenu = () => { setOperationMenuAnchor(null); } const handleOperationChange = (operation: DataFilterOperation) => () => { onChange(operation, null); setOperationMenuAnchor(null); } const operations = getOperations(); return ( { label && {label} } { label && { Object.values(operations).map(o => ( {o.icon} )) } } { operations[operation].component } ) } const AutoIcon = () => ( ) const ContainsIcon = () => ( ) const NotContainsIcon = () => ( ) const StartsWithIcon = () => ( ) const EndsWithIcon = () => ( ) const EqualsIcon = () => ( ) const NotEqualsIcon = () => ( ) const LessThanIcon = () => ( ) const LessThanOrEqualsIcon = () => ( ) const GreaterThanIcon = () => ( ) const GreaterThanOrEqualsIcon = () => ( ) const BetweenToIcon = () => ( )