summaryrefslogtreecommitdiff
path: root/src/lib/ServiceFilters.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/ServiceFilters.tsx')
-rw-r--r--src/lib/ServiceFilters.tsx74
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;