import styled from '@emotion/styled'; import DropdownButton from './DropdownButton'; import { FilterType, SelectedFilterType, SelectedSortType, SortType, } from './interface'; import { ReactNode, useCallback, useState } from 'react'; import { SortDropdownButton } from './SortDropdownButton'; import { FilterDropdownButton } from './FilterDropdownButton'; import SortAndFilterBar from './SortAndFilterBar'; type OwnProps = { viewName: string; viewIcon?: ReactNode; availableSorts?: Array>; availableFilters?: FilterType[]; filterSearchResults?: { results: { displayValue: string; value: any }[]; loading: boolean; }; onSortsUpdate?: (sorts: Array>) => void; onFiltersUpdate?: ( sorts: Array>, ) => void; onFilterSearch?: ( filter: FilterType | null, searchValue: string, ) => void; }; const StyledContainer = styled.div` display: flex; flex-direction: column; `; const StyledTableHeader = styled.div` display: flex; flex-direction: row; align-items: center; justify-content: space-between; height: 40px; color: ${(props) => props.theme.text60}; font-weight: 500; padding-left: ${(props) => props.theme.spacing(3)}; padding-right: ${(props) => props.theme.spacing(1)}; `; const StyledIcon = styled.div` display: flex; margin-right: ${(props) => props.theme.spacing(2)}; & > svg { font-size: ${(props) => props.theme.fontSizeLarge}; } `; const StyledViewSection = styled.div` display: flex; `; const StyledFilters = styled.div` display: flex; font-weight: 400; margin-right: ${(props) => props.theme.spacing(2)}; `; function TableHeader({ viewName, viewIcon, availableSorts, availableFilters, filterSearchResults, onSortsUpdate, onFiltersUpdate, onFilterSearch, }: OwnProps) { const [sorts, innerSetSorts] = useState>>( [], ); const [filters, innerSetFilters] = useState< Array> >([]); const sortSelect = useCallback( (newSort: SelectedSortType) => { const newSorts = updateSortOrFilterByKey(sorts, newSort); innerSetSorts(newSorts); onSortsUpdate && onSortsUpdate(newSorts); }, [onSortsUpdate, sorts], ); const sortUnselect = useCallback( (sortKey: string) => { const newSorts = sorts.filter((sort) => sort.key !== sortKey); innerSetSorts(newSorts); onSortsUpdate && onSortsUpdate(newSorts); }, [onSortsUpdate, sorts], ); const filterSelect = useCallback( (filter: SelectedFilterType) => { const newFilters = updateSortOrFilterByKey(filters, filter); innerSetFilters(newFilters); onFiltersUpdate && onFiltersUpdate(newFilters); }, [onFiltersUpdate, filters], ); const filterUnselect = useCallback( (filterId: SelectedFilterType['key']) => { const newFilters = filters.filter((filter) => filter.key !== filterId); innerSetFilters(newFilters); onFiltersUpdate && onFiltersUpdate(newFilters); }, [onFiltersUpdate, filters], ); const filterSearch = useCallback( (filter: FilterType | null, searchValue: string) => { onFilterSearch && onFilterSearch(filter, searchValue); }, [onFilterSearch], ); return ( {viewIcon} {viewName} 0} availableFilters={availableFilters || []} filterSearchResults={filterSearchResults} onFilterSelect={filterSelect} onFilterSearch={filterSearch} /> isSortSelected={sorts.length > 0} availableSorts={availableSorts || []} onSortSelect={sortSelect} /> {sorts.length + filters.length > 0 && ( )} ); } export default TableHeader; function updateSortOrFilterByKey( sorts: Readonly, newSort: SortOrFilter, ): SortOrFilter[] { const newSorts = [...sorts]; const existingSortIndex = sorts.findIndex((sort) => sort.key === newSort.key); if (existingSortIndex !== -1) { newSorts[existingSortIndex] = newSort; } else { newSorts.push(newSort); } return newSorts; }