import { useTranslation } from 'react-i18next'; import { CloseIcon } from '../icons/CloseIcon'; import { AppliedFiltersCssClasses } from './AppliedFilters'; import { useClearFiltersCallback } from '../hooks/useClearFiltersCallback'; import { FieldValueFilter, useSearchActions } from '@yext/search-headless-react'; import { isDuplicateFieldValueFilter } from '../utils/filterutils'; import { executeSearch } from '../utils'; import React, { useCallback, useMemo } from 'react'; /** * A representation of a filter that can be removed from the AppliedFilters component. * * @internal */ export interface RemovableFilter { displayName: string, handleRemove: () => void, filter: FieldValueFilter } /** * Properties for {@link AppliedFilters}. * * @internal */ export interface AppliedFiltersDisplayProps { removableFilters?: RemovableFilter[], /** * The display values of filters that are applied to the search results * from the backend's natural language processing. */ nlpFilterDisplayNames?: string[], /** CSS classes for customizing the component styling. */ cssClasses?: AppliedFiltersCssClasses } /** * A component that renders applied filters based on the provided GroupedFilters. * * @param props - {@link AppliedFiltersDisplayProps} * @returns A React element for the applied filters */ export function AppliedFiltersDisplay(props: AppliedFiltersDisplayProps): React.JSX.Element | null { const { t } = useTranslation(); const { nlpFilterDisplayNames = [], removableFilters = [], cssClasses = {} } = props; const handleClickClearAllButton = useClearFiltersCallback(); const searchActions = useSearchActions(); const dedupedNlpFilterDisplayNames = nlpFilterDisplayNames.filter(displayName => { return !removableFilters.some(f => f.displayName === displayName); }); const dedupedRemovableFilters = getDedupedRemovableFilters(removableFilters); const handleRemoveDedupedFilter = useCallback((dedupedFilter: DedupedRemovableFilter) => { dedupedFilter.handleRemove(); for (const f of dedupedFilter.duplicates ?? []) { f.handleRemove(); } searchActions.setOffset(0); executeSearch(searchActions); }, [searchActions]); const removableFiltersWithHandlers = useMemo(() => { return dedupedRemovableFilters.map(filter => ({ filter, handleRemove: () => handleRemoveDedupedFilter(filter) })); }, [dedupedRemovableFilters, handleRemoveDedupedFilter]); if (removableFilters.length + nlpFilterDisplayNames.length === 0) { return null; } return (