diff options
Diffstat (limited to 'src/lib/ServiceFilters.tsx')
-rw-r--r-- | src/lib/ServiceFilters.tsx | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/lib/ServiceFilters.tsx b/src/lib/ServiceFilters.tsx new file mode 100644 index 0000000..4a7f166 --- /dev/null +++ b/src/lib/ServiceFilters.tsx @@ -0,0 +1,74 @@ +import React, { useContext } from 'react'; +import { useHistory } from 'react-router-dom'; +import _ from 'lodash'; +import hooks from '../hooks/useAPIClient'; +import useQuery from '../hooks/useQuery'; +import ServiceContext, { Filter } from './ServiceContext'; +import { SelectBase } from '../components/Select'; + +const getOptionLabel = (item: any, filter: Filter) => { + const value = _.get(item, filter.as || filter.key); + return filter.transform ? filter.transform(value) : value; +}; + + +const ServiceFilters: React.FC = () => { + const service = useContext(ServiceContext); + const query = useQuery(); + const history = useHistory(); + const { data } = hooks[service.route].useList('', { revalidateOnMount: !_.isEmpty(query) }); + + const filters = service.filters?.map(filter => { + const options = _ + .uniqBy(data, filter.key) + .map((item: any) => ({ + key: _.get(item, filter.key), + label: getOptionLabel(item, filter), + })); + + // Add default option + options?.unshift({ + key: '-', + label: filter.label, + }); + + const value = _.get(query, filter.key) || '-'; + + return { ...filter, options, value }; + }); + + const handleFilterChange = (key: string) => (event: React.ChangeEvent<HTMLSelectElement>) => { + const { value } = event.target; + const updatedQuery = { ...query, [key]: value }; + if (value === '-') delete updatedQuery[key]; + + const queryString = new URLSearchParams(updatedQuery); + history.push(`${service.route}?${queryString}`); + }; + + const resetFilters = () => history.push(service.route); + + return ( + <div className="mr-6 flex items-center"> + {filters && !_.isEmpty(query) && ( + <span + onClick={resetFilters} + role="presentation" + className="underline mr-2 cursor-pointer" + > + Сбросить фильтры + </span> + )} + {filters?.map(filter => ( + <SelectBase + key={filter.key} + options={filter.options || []} + value={filter.value} + onChange={handleFilterChange(filter.key)} + /> + ))} + </div> + ); +}; + +export default ServiceFilters; |