UNPKG

@adaptabletools/adaptable

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

169 lines (168 loc) 9.92 kB
import * as React from 'react'; import { Box, Flex } from 'rebass'; import SimpleButton from '../../../components/SimpleButton'; import { ColumnFilterInputList } from './components/ColumnFilterInputList'; import { usePredicateDef } from './hooks'; import Radio from '../../../components/Radio'; import { useAdaptable } from '../../AdaptableContext'; import { Select } from '../../../components/Select'; import { mapQlPredicateToAdaptablePredicate } from './utils'; const ColumnFilterPredicateDropdown = (props) => { const predicateDef = usePredicateDef(props.predicate?.operator, props.predicateDefs); const options = props.predicateDefs.map((predicateDef) => { return { label: (React.createElement(Box, { display: 'flex', alignItems: "center" }, React.createElement(SimpleButton, { variant: "raised", mr: 2, tone: "accent" }, predicateDef.icon), predicateDef.label)), value: predicateDef.operator, }; }); const operator = props.predicate?.operator; const isAndOr = operator === 'AND' || operator === 'OR'; return (React.createElement(Box, { display: 'flex', alignItems: "center", className: "ab-ColumnFilterPredicateDropdown", style: { //@ts-ignore ignore '--ab-cmp-input__background': 'var(--ab-color-primary)', } }, React.createElement(Select, { style: predicateDef ? { minWidth: '10rem', } : null // for AND and OR don't apply a min width , onChange: (value) => { props.onPredicateChange({ operator: value, args: [], }); }, options: options, value: isAndOr ? 'Add Condition' : props.predicate?.operator }))); }; const ColumnFilterEditor = (props) => { return (React.createElement(Box, { mb: 3 }, React.createElement(Flex, { mb: 2 }, React.createElement(ColumnFilterPredicateDropdown, { columnId: props.columnId, disabled: props.disabled, predicate: props.predicate, predicateDefs: props.predicateDefs, onPredicateChange: props.onPredicateChange }), React.createElement(Flex, { alignItems: "center", ml: 2 }, React.createElement(SimpleButton, { disabled: props.deleteDisabled, onClick: props.onDelete, variant: "text", icon: "delete" }))), React.createElement(ColumnFilterInputList, { columnId: props.columnId, disabled: props.disabled, predicate: props.predicate, onPredicateChange: props.onPredicateChange, predicateDefs: props.predicateDefs }))); }; const AndOrInput = (props) => { return ( // <Select // value={props.operator} // onChange={props.onChange} // options={[ // { label: 'AND', value: 'AND' }, // { label: 'OR', value: 'OR' }, // ]} // /> (React.createElement( Flex, { flex: 1 }, React.createElement(Radio, { mr: 2, onClick: () => props.onChange('AND'), checked: props.operator === 'AND' }, "AND"), React.createElement(Radio, { mr: 2, onClick: () => props.onChange('OR'), checked: props.operator === 'OR' }, "OR") )) ); }; export const ColumnFilterComponent = (props) => { const adaptable = useAdaptable(); const manuallyApplyColumnFilter = adaptable.api.filterApi.columnFilterApi.internalApi.shouldManuallyApplyColumnFilter(props.columnId); const [predicateNotYetApplied, setPredicateNotYetApplied] = React.useState(props.predicate); const applyFilter = () => { props.onPredicateChange(currentPredicateRef.current); setPredicateNotYetApplied(undefined); }; const onPredicateChange = (predicate) => { // even if manuallyApplyColumnFilter is false, when we explicitly clear the filter // we want to apply the filter immediately if (!manuallyApplyColumnFilter || !predicate) { props.onPredicateChange(predicate); } else { setPredicateNotYetApplied(predicate); } }; const clearAllFilters = () => { props.onPredicateChange(null); setPredicateNotYetApplied(undefined); }; const onNewPredicate = (predicateDef) => { const currentPredicate = currentPredicateRef.current; const newPredicate = { ...currentPredicate, // @ts-ignore args: [...currentPredicate.args, { operator: predicateDef.operator, args: [] }], }; onPredicateChange(newPredicate); }; const onCombineChange = (operator) => { const newPredicate = { ...currentPredicateRef.current, args: currentPredicateRef.current.args || [], operator, }; onPredicateChange(newPredicate); }; const currentPredicate = !manuallyApplyColumnFilter ? props.predicate : predicateNotYetApplied ?? props.predicate; const currentPredicateRef = React.useRef(currentPredicate); //#ref-predicate currentPredicateRef.current = currentPredicate; // Not sure how to check this but would be nice... const isLastPredicateValid = true; const filterPredicateDropdown = (React.createElement(ColumnFilterPredicateDropdown, { columnId: props.columnId, disabled: props.disabled, predicate: currentPredicate, predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => { const predicateDef = props.predicateDefs.find((predicateDef) => predicateDef.operator === predicate.operator); onNewPredicate(predicateDef); }, targetProps: { tone: 'neutral', variant: 'raised', children: 'Add Condition', } })); const isAtLeastOneColumnFilterValid = (qlPredicates) => { if (!qlPredicates?.length) { return false; } return qlPredicates .map((qlPredicate) => mapQlPredicateToAdaptablePredicate(qlPredicate)) .some((adaptablePredicate) => adaptable.api.predicateApi.isValidPredicate(adaptablePredicate)); }; return (React.createElement(React.Fragment, null, React.createElement(Flex, { flexDirection: "column", backgroundColor: "primarylight", pb: !props.hideActionButtons ? 2 : undefined, mb: props.location === 'filterForm' ? 2 : undefined, mt: props.location === 'columnMenu' ? 2 : undefined, ml: props.location === 'columnMenu' ? 2 : undefined, mr: props.location === 'columnMenu' ? 2 : undefined, style: { borderRadius: 'var(--ab__border-radius)' } }, React.createElement(Flex, { m: 2 }, React.createElement(AndOrInput, { onChange: onCombineChange, operator: currentPredicate.operator })), !props.hideActionButtons && (React.createElement(Flex, { ml: 2, mr: 2, className: "ab-ColumnFilter-actions", justifyContent: "space-between" }, React.createElement(Box, { className: "ab-ColumnFilter-action-clearall" }, React.createElement(SimpleButton, { "aria-label": 'Clear All Filters', onClick: () => clearAllFilters() }, "Clear All")), manuallyApplyColumnFilter ? (React.createElement(React.Fragment, null, React.createElement(Box, { flex: 1, "data-name": "spacer" }), React.createElement(Box, { className: "ab-ColumnFilter-action-reset", mr: 2 }, React.createElement(SimpleButton, { "aria-label": 'Reset All', tone: "neutral", variant: "raised", onClick: () => { setPredicateNotYetApplied(props.predicate); } }, "Reset")), React.createElement(Box, { className: "ab-ColumnFilter-action-apply" }, React.createElement(SimpleButton, { "aria-label": 'Apply Filter', tone: "accent", variant: "raised", onClick: applyFilter, disabled: !isAtLeastOneColumnFilterValid(predicateNotYetApplied?.args) && !isAtLeastOneColumnFilterValid(currentPredicate.args) }, "Apply")))) : null))), React.createElement(Flex, { flexDirection: "column", className: "ab-ColumnFilter", flex: 1, minHeight: 0, ...props.wrapperProps }, React.createElement(Box, { style: { overflow: 'auto' } }, currentPredicate.args.map((predicate, index) => { return (React.createElement(ColumnFilterEditor, { deleteDisabled: currentPredicate.args.length < 2, onDelete: () => { const currentPredicate = currentPredicateRef.current; const newArgs = [...currentPredicate.args]; newArgs.splice(index, 1); onPredicateChange({ operator: currentPredicate.operator, args: newArgs, }); }, key: index, columnId: props.columnId, disabled: props.disabled, predicate: predicate, predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => { // #ref-predicate - for whatever reason // the `currentPredicate` here would be one from an old render // if we weren't using a ref. we're not using memo/usecallback here, // so I don't understand why this is happening const currentPredicate = currentPredicateRef.current; const newArgs = [...currentPredicate.args]; newArgs[index] = predicate; onPredicateChange({ operator: currentPredicate.operator, args: newArgs, }); } })); }), isLastPredicateValid && filterPredicateDropdown)))); };