import React, { useCallback, useMemo, useState } from 'react'; import cx from 'classnames'; import type { FilterFieldsData, FilterGroupFieldData } from '../../types'; import { FlexStack } from '../../layout/flex-stack'; import { Stack } from '../../layout/stack'; import { Button } from '../button'; import { ControlGroup } from '../control-group'; import { Dropdown, DropdownItem } from '../dropdown'; import { InputSearch } from '../input-search'; import * as I18N from './filters.i18n'; import { getGroupFiltersLabelSuffix, LABELS } from './filters.utils'; import css from './filters.module.css'; interface FilterBooleanProps extends React.ComponentProps<'input'> { label: string; } const Filter = (props: FilterBooleanProps) => { const { className = '', label, name, ...inputProps } = props; return ( {label} ); }; interface FilterGroupProps extends React.ComponentProps<'div'> { groupKey: string; data: FilterGroupFieldData; values: Record; onCheckboxChange: FilterBooleanProps['onChange']; toggleFilters: (newFilters: Record) => void; } const FilterGroup = (props: FilterGroupProps) => { const { className = '', groupKey, data, values, onCheckboxChange, toggleFilters } = props; const { label: groupLabel, children: groupItems } = data; const [search, setSearch] = useState(''); const areAllGroupItemsChecked = groupItems .map(({ key: itemKey }) => values?.[`${groupKey}.${itemKey}`]) .reduce((agg, val) => agg && val, true); const filterSuffix = getGroupFiltersLabelSuffix(groupItems); const hasCustomFilterSuffix = !Object.values(LABELS).includes(filterSuffix); const dropdownLabel = ( <> {`${groupLabel}:`}   {filterSuffix} ); const getOnGroupCheck = (value: boolean, overrides = {}) => () => { const newFilters = groupItems.reduce( (agg, { key: itemKey }) => ({ ...agg, [`${groupKey}.${itemKey}`]: value, }), {}, ); toggleFilters({ ...newFilters, ...overrides, }); }; const filteredGroupItems = useMemo(() => { if (!search) { return groupItems; } return groupItems.filter((item) => item.label.match(new RegExp(`${search}`, 'i'))); }, [search, groupItems]); return ( {groupItems.length > 10 && (
)}
{filteredGroupItems.length === 0 && (

{I18N.GROUP_NOT_FOUND}

)} {filteredGroupItems.map(({ key: itemKey, ...itemData }) => { const id = [groupKey, itemKey].join('.'); const getOnOnlyClick = () => getOnGroupCheck(false, { [id]: true }); return ( ); })}
{filteredGroupItems.length !== 0 && (
{areAllGroupItemsChecked ? ( {I18N.CLEAR} ) : ( {I18N.CHECK} )}
)}
); }; interface FiltersProps extends React.ComponentProps<'div'> { values: Record; filters: FilterFieldsData; toggleFilter: (name: string, value: boolean) => void; toggleFilters: FilterGroupProps['toggleFilters']; } export const Filters = (props: FiltersProps) => { const { className = '', values, filters, toggleFilter, toggleFilters } = props; /** * Toggle filter value on checkbox change */ const onCheckboxChange = useCallback( (event: any) => { const { name } = event.target; toggleFilter(name, !values[name]); }, [toggleFilter, values], ); const filterList = Object.entries(filters); const filterCount = filterList.length; return ( {filterList.map(([name, data], index) => { const lastItem = index === filterCount - 1; if ('defaultValue' in data) { return ( ); } return ( ); })} ); };