-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add filters panel in invoice page (#1633)
* misc: minor style update and fix * misc: DatePicker can now show error in tooltip * misc: add filter elements * misc: Add filter component * misc: update invoice list and page to work with filters * misc: add related copy and graph update
- Loading branch information
Showing
23 changed files
with
1,338 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { Typography } from '@mui/material' | ||
import { useMemo } from 'react' | ||
import { useSearchParams } from 'react-router-dom' | ||
import styled from 'styled-components' | ||
|
||
import { useInternationalization } from '~/hooks/core/useInternationalization' | ||
import { theme } from '~/styles' | ||
|
||
import { AvailableFiltersEnum, mapFilterToTranslationKey } from './types' | ||
import { formatActiveFilterValueDisplay } from './utils' | ||
|
||
interface ActiveFiltersListProps { | ||
filters: AvailableFiltersEnum[] | ||
hideBorderBottom?: boolean | ||
noPadding?: boolean | ||
} | ||
|
||
export const ActiveFiltersList = ({ filters }: ActiveFiltersListProps) => { | ||
const { translate } = useInternationalization() | ||
let [searchParams] = useSearchParams() | ||
|
||
const activeFilters = useMemo(() => { | ||
const setFilters = Object.fromEntries(searchParams.entries()) | ||
|
||
const filtersToDisplay = Object.entries(setFilters).reduce( | ||
(acc, cur) => { | ||
const [key, value] = cur as [AvailableFiltersEnum, string] | ||
|
||
if (!filters.includes(key)) { | ||
return acc | ||
} | ||
|
||
return [ | ||
...acc, | ||
{ | ||
label: translate(mapFilterToTranslationKey(key)), | ||
value: formatActiveFilterValueDisplay(key, value), | ||
}, | ||
] | ||
}, | ||
[] as Record<string, string>[], | ||
) | ||
|
||
return filtersToDisplay | ||
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [filters, searchParams]) | ||
|
||
if (!activeFilters.length) { | ||
return null | ||
} | ||
|
||
return ( | ||
<> | ||
{activeFilters.map(({ label, value }, index) => ( | ||
<ActiveFilterChip key={`active-filter-${index}`}> | ||
<Typography variant="captionHl" color="grey600"> | ||
{translate(label)}: {value} | ||
</Typography> | ||
</ActiveFilterChip> | ||
))} | ||
</> | ||
) | ||
} | ||
|
||
const ActiveFilterChip = styled.div` | ||
display: flex; | ||
align-items: center; | ||
height: 32px; | ||
background-color: ${theme.palette.grey[100]}; | ||
border-radius: 100px; | ||
padding: 0 ${theme.spacing(3)}; | ||
box-sizing: border-box; | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { useNavigate, useSearchParams } from 'react-router-dom' | ||
import styled, { css } from 'styled-components' | ||
|
||
import { Button } from '~/components/designSystem' | ||
import { useInternationalization } from '~/hooks/core/useInternationalization' | ||
import { theme } from '~/styles' | ||
|
||
import { ActiveFiltersList } from './ActiveFiltersList' | ||
import { FiltersPanelPoper } from './FiltersPanelPoper' | ||
import { AvailableFiltersEnum } from './types' | ||
|
||
interface FiltersProps { | ||
filters: AvailableFiltersEnum[] | ||
hideBorderBottom?: boolean | ||
noPadding?: boolean | ||
} | ||
|
||
export const Filters = ({ filters, hideBorderBottom, noPadding, ...props }: FiltersProps) => { | ||
const navigate = useNavigate() | ||
const { translate } = useInternationalization() | ||
let [searchParams] = useSearchParams() | ||
|
||
return ( | ||
<FiltersContainer $hideBorderBottom={hideBorderBottom} $noPadding={noPadding} {...props}> | ||
<FiltersPanelPoper filters={filters} /> | ||
<ActiveFiltersList filters={filters} /> | ||
|
||
{searchParams.size > 0 && ( | ||
<Button variant="quaternary" size="small" onClick={() => navigate({ search: '' })}> | ||
{translate('text_66ab4886cc65a6006ee7258c')} | ||
</Button> | ||
)} | ||
</FiltersContainer> | ||
) | ||
} | ||
|
||
const FiltersContainer = styled.div<{ $hideBorderBottom?: boolean; $noPadding?: boolean }>` | ||
width: 100%; | ||
display: flex; | ||
flex-wrap: wrap; | ||
align-items: center; | ||
gap: ${theme.spacing(3)}; | ||
overflow-y: scroll; | ||
box-sizing: border-box; | ||
${({ $noPadding }) => | ||
!$noPadding && | ||
css` | ||
padding: ${theme.spacing(3)} ${theme.spacing(12)}; | ||
`} | ||
${({ $hideBorderBottom }) => | ||
!$hideBorderBottom && | ||
css` | ||
box-shadow: ${theme.shadows[7]}; | ||
`} | ||
${theme.breakpoints.down('md')} { | ||
padding: ${theme.spacing(4)}; | ||
} | ||
` |
77 changes: 77 additions & 0 deletions
77
src/components/designSystem/Filters/FiltersPanelItemTypeSwitch.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import styled from 'styled-components' | ||
|
||
import { Typography } from '~/components/designSystem' | ||
import { useInternationalization } from '~/hooks/core/useInternationalization' | ||
import { HEADER_TABLE_HEIGHT, theme } from '~/styles' | ||
|
||
import { FiltersItemCurrency } from './filtersElements/FiltersItemCurrency' | ||
import { FiltersItemCustomer } from './filtersElements/FiltersItemCustomer' | ||
import { FiltersItemInvoiceType } from './filtersElements/FiltersItemInvoiceType' | ||
import { FiltersItemIssuingDate } from './filtersElements/FiltersItemIssuingDate' | ||
import { FiltersItemPaymentDisputeLost } from './filtersElements/FiltersItemPaymentDisputeLost' | ||
import { FiltersItemPaymentOverdue } from './filtersElements/FiltersItemPaymentOverdue' | ||
import { FiltersItemPaymentStatus } from './filtersElements/FiltersItemPaymentStatus' | ||
import { FiltersItemStatus } from './filtersElements/FiltersItemStatus' | ||
import { FiltersFormValues } from './FiltersPanelPoper' | ||
import { AvailableFiltersEnum } from './types' | ||
|
||
type FiltersPanelItemTypeSwitchProps = { | ||
filterType: AvailableFiltersEnum | undefined | ||
value: FiltersFormValues['filters'][0]['value'] | ||
setFilterValue: (value: string) => void | ||
} | ||
|
||
export const FiltersPanelItemTypeSwitch = ({ | ||
filterType, | ||
value, | ||
setFilterValue, | ||
}: FiltersPanelItemTypeSwitchProps) => { | ||
const { translate } = useInternationalization() | ||
|
||
if (!filterType) { | ||
return <NoFilterTypePlaceholder /> | ||
} | ||
|
||
return ( | ||
<> | ||
{filterType === AvailableFiltersEnum.issuingDate ? ( | ||
<Typography variant="body" color="grey700"> | ||
{translate('text_66ab42d4ece7e6b7078993e2')} | ||
</Typography> | ||
) : ( | ||
<Typography variant="body" color="grey700"> | ||
{translate('text_66ab42d4ece7e6b7078993d0')} | ||
</Typography> | ||
)} | ||
|
||
{filterType === AvailableFiltersEnum.currency ? ( | ||
<FiltersItemCurrency value={value} setFilterValue={setFilterValue} /> | ||
) : filterType === AvailableFiltersEnum.customerExternalId ? ( | ||
<FiltersItemCustomer value={value} setFilterValue={setFilterValue} /> | ||
) : filterType === AvailableFiltersEnum.invoiceType ? ( | ||
<FiltersItemInvoiceType value={value} setFilterValue={setFilterValue} /> | ||
) : filterType === AvailableFiltersEnum.issuingDate ? ( | ||
<FiltersItemIssuingDate value={value} setFilterValue={setFilterValue} /> | ||
) : filterType === AvailableFiltersEnum.paymentDisputeLost ? ( | ||
<FiltersItemPaymentDisputeLost value={value} setFilterValue={setFilterValue} /> | ||
) : filterType === AvailableFiltersEnum.paymentOverdue ? ( | ||
<FiltersItemPaymentOverdue value={value} setFilterValue={setFilterValue} /> | ||
) : filterType === AvailableFiltersEnum.paymentStatus ? ( | ||
<FiltersItemPaymentStatus value={value} setFilterValue={setFilterValue} /> | ||
) : filterType === AvailableFiltersEnum.status ? ( | ||
<FiltersItemStatus value={value} setFilterValue={setFilterValue} /> | ||
) : null} | ||
</> | ||
) | ||
} | ||
|
||
const NoFilterTypePlaceholder = styled.div` | ||
/* -2px stand for the border witdh included on both top and bottom */ | ||
height: ${HEADER_TABLE_HEIGHT - 2}px; | ||
border: 1px dashed ${theme.palette.grey[300]}; | ||
border-radius: ${theme.shape.borderRadius}px; | ||
${theme.breakpoints.up('lg')} { | ||
flex: 1; | ||
} | ||
` |
Oops, something went wrong.