Skip to content

Commit

Permalink
refactor: split filter configuration with filter visibility state (#5563
Browse files Browse the repository at this point in the history
)

This PR splits the filter configuration with filter visibility state.
This will simplify adding different filter types in future, for example
date filters.
  • Loading branch information
sjaanus committed Dec 7, 2023
1 parent 38d02e1 commit e89ebf3
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 50 deletions.
Expand Up @@ -2,7 +2,7 @@ import React, { useState } from 'react';
import Button from '@mui/material/Button';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import { IFilterItem } from './FeatureToggleFilters';
import { IFilterVisibility, IFilterItem } from './FeatureToggleFilters';
import { Box, styled } from '@mui/material';
import { Add } from '@mui/icons-material';

Expand All @@ -11,13 +11,13 @@ const StyledButton = styled(Button)(({ theme }) => ({
padding: theme.spacing(1.25),
}));
interface IAddFilterButtonProps {
availableFilters: IFilterItem[];
setAvailableFilters: (filters: IFilterItem[]) => void;
visibleFilters: IFilterVisibility;
setVisibleFilters: (filters: IFilterVisibility) => void;
}

const AddFilterButton = ({
availableFilters,
setAvailableFilters,
visibleFilters,
setVisibleFilters,
}: IAddFilterButtonProps) => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);

Expand All @@ -29,15 +29,11 @@ const AddFilterButton = ({
};

const onClick = (label: string) => {
const filters = availableFilters.map((filter) =>
filter.label === label
? {
...filter,
enabled: true,
}
: filter,
);
setAvailableFilters(filters);
const filterVisibility = {
...visibleFilters,
[label]: true,
};
setVisibleFilters(filterVisibility);
handleClose();
};

Expand All @@ -53,16 +49,12 @@ const AddFilterButton = ({
open={Boolean(anchorEl)}
onClose={handleClose}
>
{availableFilters.map(
(filter) =>
!filter.enabled && (
<MenuItem
key={filter.label}
onClick={() => onClick(filter.label)}
>
{filter.label}
</MenuItem>
),
{Object.entries(visibleFilters).map(([label, enabled]) =>
!enabled ? (
<MenuItem key={label} onClick={() => onClick(label)}>
{label}
</MenuItem>
) : null,
)}
</Menu>
</div>
Expand Down
Expand Up @@ -30,11 +30,14 @@ export interface IFilterItem {
value: string;
}[];
filterKey: keyof FeatureTogglesListFilters;
enabled?: boolean;
singularOperators: [string, ...string[]];
pluralOperators: [string, ...string[]];
}

export type IFilterVisibility = {
[key: string]: boolean | undefined;
};

export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
state,
onChange,
Expand All @@ -54,16 +57,14 @@ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
];

const [availableFilters, setAvailableFilters] = useState<IFilterItem[]>([]);
const removeFilter = (label: string) => {
const filters = availableFilters.map((filter) =>
filter.label === label
? {
...filter,
enabled: false,
}
: filter,
);
setAvailableFilters(filters);
const [visibleFilters, setVisibleFilters] = useState<IFilterVisibility>({});

const hideFilter = (label: string) => {
const filterVisibility = {
...visibleFilters,
[label]: false,
};
setVisibleFilters(filterVisibility);
};

useEffect(() => {
Expand All @@ -76,22 +77,20 @@ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
value: segment.name,
}));

const newFilterItems: IFilterItem[] = [
const availableFilters: IFilterItem[] = [
{
label: 'State',
options: stateOptions,
filterKey: 'state',
singularOperators: ['IS', 'IS_NOT'],
pluralOperators: ['IS_ANY_OF', 'IS_NONE_OF'],
enabled: Boolean(state.state),
},
{
label: 'Project',
options: projectsOptions,
filterKey: 'project',
singularOperators: ['IS', 'IS_NOT'],
pluralOperators: ['IS_ANY_OF', 'IS_NONE_OF'],
enabled: Boolean(state.project),
},
{
label: 'Segment',
Expand All @@ -104,22 +103,30 @@ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
'EXCLUDE_IF_ANY_OF',
'EXCLUDE_ALL',
],
enabled: Boolean(state.segment),
},
];

setAvailableFilters(newFilterItems);
}, [
JSON.stringify(projects),
JSON.stringify(state),
JSON.stringify(segments),
]);
setAvailableFilters(availableFilters);
}, [JSON.stringify(projects), JSON.stringify(segments)]);

useEffect(() => {
const filterVisibility: IFilterVisibility = {
State: Boolean(state.state),
Project: Boolean(state.project),
Segment: Boolean(state.segment),
};
setVisibleFilters(filterVisibility);
}, [JSON.stringify(state)]);

const hasAvailableFilters = Object.values(visibleFilters).some(
(value) => !value,
);

return (
<StyledBox>
{availableFilters.map(
(filter) =>
filter.enabled && (
visibleFilters[filter.label] && (
<FilterItem
key={filter.label}
label={filter.label}
Expand All @@ -130,16 +137,16 @@ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
}
singularOperators={filter.singularOperators}
pluralOperators={filter.pluralOperators}
onChipClose={() => removeFilter(filter.label)}
onChipClose={() => hideFilter(filter.label)}
/>
),
)}
<ConditionallyRender
condition={availableFilters.some((filter) => !filter.enabled)}
condition={hasAvailableFilters}
show={
<AddFilterButton
availableFilters={availableFilters}
setAvailableFilters={setAvailableFilters}
visibleFilters={visibleFilters}
setVisibleFilters={setVisibleFilters}
/>
}
/>
Expand Down

0 comments on commit e89ebf3

Please sign in to comment.