@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
87 lines (86 loc) • 5.27 kB
JavaScript
import * as React from 'react';
import { Box, Flex } from 'rebass';
import OverlayTrigger from '../../../components/OverlayTrigger';
import SimpleButton from '../../../components/SimpleButton';
import { useAdaptable } from '../../AdaptableContext';
import { AdaptableIconComponent } from '../AdaptableIconComponent';
import { ColumnFilterMenu } from './components/ColumnFilterMenu';
import { FloatingFilterInputList } from './components/FloatingFilterInputList';
import { isPredicateEmpty, qlPredicateToString } from './utils';
export const FloatingFilter = (props) => {
const adaptable = useAdaptable();
const columnFilterOptions = adaptable.adaptableOptions.filterOptions.columnFilterOptions;
/**
* We always have a syntetic predicate with AND or OR, so the logic is easyer.
* The wrapper is in charge of constructing the correct column filter.
*/
const isMultiple = props.predicate?.args?.length > 1;
const isManualApply = !columnFilterOptions.autoApplyColumnFilter;
const isInlineEditable = !isMultiple && !isManualApply;
// only used when there is only one filter selected
let singleFilterPredicateDef = null;
if (props.predicate.args.length === 1) {
singleFilterPredicateDef = props.predicateDefs.find((predicateDef) => predicateDef.operator === props.predicate.args[0].operator);
}
const noInputs = !singleFilterPredicateDef?.inputs || singleFilterPredicateDef.inputs.length === 0;
const showLabel = isMultiple || noInputs || isManualApply;
let label = qlPredicateToString(props.predicate, props.predicateDefs);
if (isManualApply &&
singleFilterPredicateDef &&
isPredicateEmpty(props.predicate.args[0], singleFilterPredicateDef)) {
label = '';
}
const showQuickFilterDropdown = adaptable.api.filterApi.columnFilterApi.internalApi.showQuickFilterDropdown(props.columnId);
const handleClear = () => props.onClear?.();
const showEvent = 'click';
const hideEvent = 'blur';
let filterDropdown = null;
let filterDropdownButton = (React.createElement(SimpleButton, { variant: "text", "data-name": "floating-filter-button", "data-value": props.predicate?.args[0]?.operator, onClick: () => {
if (!isInlineEditable) {
adaptable.api.filterApi.columnFilterApi.internalApi.openColumnFilterPopup(props.columnId);
}
}, style: {
textAlign: 'left',
marginRight: 1, // just so that the focus outline is not cut off
...(!isInlineEditable
? {
minWidth: 0,
flex: 1,
}
: {}),
} },
React.createElement(Box, null, !isManualApply && singleFilterPredicateDef?.icon ? (singleFilterPredicateDef?.icon) : (React.createElement(AdaptableIconComponent, { icon: { name: 'filter' } }))),
showLabel && (React.createElement(Box, { ml: 2, className: "ab-FloatingFilter-label", title: label, flex: 1 }, label))));
if (isInlineEditable) {
filterDropdown = showQuickFilterDropdown && (React.createElement(OverlayTrigger, { className: "ab-FloatingFilter-overlay", showEvent: showEvent, hideEvent: hideEvent, preventPortalEventPropagation: showEvent === 'click', targetOffset: 10, hideDelay: 50, "data-name": "floating-filter-overlay", render: () => {
// we render this only for single filter
return (React.createElement(ColumnFilterMenu, { columnId: props.columnId, disabled: props.disabled, predicate: props.predicate.args[0], predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
props.onPredicateChange({
operator: props.predicate.operator,
args: [predicate],
});
} }));
} }, filterDropdownButton));
}
else {
filterDropdown = filterDropdownButton;
}
return (React.createElement(Flex, { className: "ab-FloatingFilter", style: { width: '100%' } },
filterDropdown,
isInlineEditable && (React.createElement(Flex, { flex: 1, minWidth: 0 },
React.createElement(FloatingFilterInputList, { onKeyDown: props.onKeydown, columnId: props.columnId, disabled: props.disabled,
// It works only with a predicate
predicate: props.predicate.args[0], predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
props.onPredicateChange({
operator: props.predicate.operator,
args: [predicate],
});
} }))),
isInlineEditable && (React.createElement(SimpleButton, { px: 0, onClick: () => {
adaptable.api.filterApi.columnFilterApi.internalApi.openColumnFilterPopup(props.columnId, {
onChange: props.onChange,
});
}, "data-name": "expand-filter", icon: "expand", variant: "text" })),
(isMultiple ||
!isPredicateEmpty(props.predicate.args[0], singleFilterPredicateDef)) && (React.createElement(SimpleButton, { "data-name": "clear-filter", p: 0, variant: "text", onClick: handleClear, icon: "close" }))));
};