From e371759af6c218f18edc7a7dca8ba7b55cc367fb Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 17 Apr 2021 14:55:08 +0300 Subject: feat: initialize filters based on query string --- src/containers/Page.tsx | 13 +++++-------- src/lib/ServiceContext.tsx | 9 ++++++++- src/lib/ServiceList.tsx | 34 +++++++++++++++++++--------------- src/services/transfers/index.ts | 5 ++++- src/services/waybills/index.ts | 6 +++++- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/containers/Page.tsx b/src/containers/Page.tsx index d659510..467e458 100644 --- a/src/containers/Page.tsx +++ b/src/containers/Page.tsx @@ -1,13 +1,8 @@ import React from 'react'; import Paper from '../components/Paper'; import Button from '../components/Button'; -import { Action } from '../lib/ServiceContext'; -import { Option, SelectBase } from '../components/Select'; -import { Field } from '../components/ListTable'; - -export interface Filter extends Field { - options?: Option[]; -} +import { Action, Filter } from '../lib/ServiceContext'; +import { SelectBase } from '../components/Select'; interface Props { title?: string; @@ -25,7 +20,9 @@ const Page: React.FC = ({ title, actions, filters, className, children }) {title}
- {filters?.map(filter => ())} + {filters?.map(filter => ( + + ))}
{actions?.map(action => ())} diff --git a/src/lib/ServiceContext.tsx b/src/lib/ServiceContext.tsx index 67f3756..2001d00 100644 --- a/src/lib/ServiceContext.tsx +++ b/src/lib/ServiceContext.tsx @@ -2,11 +2,18 @@ import React from 'react'; import { FormikProps } from 'formik'; import { Props as ButtonProps } from '../components/Button'; import { Field } from '../components/ListTable'; +import { Option } from '../components/Select'; export interface Action extends ButtonProps { name: string; } +export interface Filter extends Field { + as?: string; + options?: Option[]; + value?: string; +} + export interface PanelProps { item: T; mutate: (item: T) => void; @@ -20,7 +27,7 @@ export interface ServiceParams { default?: Partial; routes?: Record; actions?: Action[]; - filters?: string[]; + filters?: Filter[]; rowLink?: (item: T) => string; Form?: React.FC>; Panel?: React.FC>; diff --git a/src/lib/ServiceList.tsx b/src/lib/ServiceList.tsx index 9b12d6b..5abae6b 100644 --- a/src/lib/ServiceList.tsx +++ b/src/lib/ServiceList.tsx @@ -2,42 +2,46 @@ import React, { useContext } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; import _ from 'lodash'; import Page from '../containers/Page'; -import ListTable, { Field } from '../components/ListTable'; +import ListTable from '../components/ListTable'; import hooks from '../hooks/useAPIClient'; -import ServiceContext from './ServiceContext'; +import ServiceContext, { Filter } from './ServiceContext'; +import useQuery from '../hooks/useQuery'; -const getItemField = (item: any, field: Field) => { - const value = _.get(item, field.key); - return field.transform ? field.transform(value) : value; +const getOptionLabel = (item: any, filter: Filter) => { + const value = _.get(item, filter.as || filter.key); + return filter.transform ? filter.transform(value) : value; }; const ServiceList: React.FC = () => { const service = useContext(ServiceContext); const history = useHistory(); const location = useLocation(); + const query = useQuery(); const { data } = hooks[service.route].useList(location.search); + const { data: unfilteredData } = hooks[service.route].useList('', { revalidateOnMount: !!location.search }); const actions = service.actions || [{ name: 'Добавить', route: `/${service.route}/add${location.search}`, }]; - const filters = service.filters?.map(key => { - const field = _.find(service.tableFields, { key }); - if (!field) return { key: '-', label: '-', options: [] }; - - const options = data?.map((item: any) => ({ - key: _.get(item, field.key), - label: getItemField(item, field), - })); + const filters = service.filters?.map(filter => { + const options = _ + .uniqBy(unfilteredData, filter.key) + .map((item: any) => ({ + key: _.get(item, filter.key), + label: getOptionLabel(item, filter), + })); // Add default option options?.unshift({ key: '-', - label: field.label, + label: filter.label, }); - return { ...field, options }; + const value = _.get(query, filter.key); + + return { ...filter, options, value }; }); const handleRowClick = (item: any) => { diff --git a/src/services/transfers/index.ts b/src/services/transfers/index.ts index 3feb6e2..de75d53 100644 --- a/src/services/transfers/index.ts +++ b/src/services/transfers/index.ts @@ -15,7 +15,10 @@ const service: ServiceParams = { { key: 'operation', label: 'Операция', transform: transformOperation }, { key: 'amount', label: 'Сумма' }, ], - filters: ['operation', 'contractor.name'], + filters: [ + { key: 'operation', label: 'Операция', transform: transformOperation }, + { key: 'contractor._id', label: 'Контрагент', as: 'contractor.name' }, + ], actions: [ { name: 'Загрузить выписку', diff --git a/src/services/waybills/index.ts b/src/services/waybills/index.ts index ae1c8d3..08f43fc 100644 --- a/src/services/waybills/index.ts +++ b/src/services/waybills/index.ts @@ -14,7 +14,11 @@ const service: ServiceParams = { { key: 'total', label: 'Сумма' }, { key: 'contractor.name', label: 'Контрагент' }, ], - filters: ['status', 'operation', 'contractor.name'], + filters: [ + { key: 'status', label: 'Статус', transform: transformStatus }, + { key: 'operation', label: 'Операция', transform: transformOperation }, + { key: 'contractor._id', label: 'Контрагент', as: 'contractor.name' }, + ], default: { operation: 'in', records: [], -- cgit v1.2.3