1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-17 13:46:47 +02:00

refactor: split filter configuration with filter visibility state (#5563)

This PR splits the filter configuration with filter visibility state.
This will simplify adding different filter types in future, for example
date filters.
This commit is contained in:
Jaanus Sellin 2023-12-07 11:59:35 +02:00 committed by GitHub
parent 38d02e1a85
commit e89ebf358e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 50 deletions

View File

@ -2,7 +2,7 @@ import React, { useState } from 'react';
import Button from '@mui/material/Button'; import Button from '@mui/material/Button';
import Menu from '@mui/material/Menu'; import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem'; import MenuItem from '@mui/material/MenuItem';
import { IFilterItem } from './FeatureToggleFilters'; import { IFilterVisibility, IFilterItem } from './FeatureToggleFilters';
import { Box, styled } from '@mui/material'; import { Box, styled } from '@mui/material';
import { Add } from '@mui/icons-material'; import { Add } from '@mui/icons-material';
@ -11,13 +11,13 @@ const StyledButton = styled(Button)(({ theme }) => ({
padding: theme.spacing(1.25), padding: theme.spacing(1.25),
})); }));
interface IAddFilterButtonProps { interface IAddFilterButtonProps {
availableFilters: IFilterItem[]; visibleFilters: IFilterVisibility;
setAvailableFilters: (filters: IFilterItem[]) => void; setVisibleFilters: (filters: IFilterVisibility) => void;
} }
const AddFilterButton = ({ const AddFilterButton = ({
availableFilters, visibleFilters,
setAvailableFilters, setVisibleFilters,
}: IAddFilterButtonProps) => { }: IAddFilterButtonProps) => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null); const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
@ -29,15 +29,11 @@ const AddFilterButton = ({
}; };
const onClick = (label: string) => { const onClick = (label: string) => {
const filters = availableFilters.map((filter) => const filterVisibility = {
filter.label === label ...visibleFilters,
? { [label]: true,
...filter, };
enabled: true, setVisibleFilters(filterVisibility);
}
: filter,
);
setAvailableFilters(filters);
handleClose(); handleClose();
}; };
@ -53,16 +49,12 @@ const AddFilterButton = ({
open={Boolean(anchorEl)} open={Boolean(anchorEl)}
onClose={handleClose} onClose={handleClose}
> >
{availableFilters.map( {Object.entries(visibleFilters).map(([label, enabled]) =>
(filter) => !enabled ? (
!filter.enabled && ( <MenuItem key={label} onClick={() => onClick(label)}>
<MenuItem {label}
key={filter.label} </MenuItem>
onClick={() => onClick(filter.label)} ) : null,
>
{filter.label}
</MenuItem>
),
)} )}
</Menu> </Menu>
</div> </div>

View File

@ -30,11 +30,14 @@ export interface IFilterItem {
value: string; value: string;
}[]; }[];
filterKey: keyof FeatureTogglesListFilters; filterKey: keyof FeatureTogglesListFilters;
enabled?: boolean;
singularOperators: [string, ...string[]]; singularOperators: [string, ...string[]];
pluralOperators: [string, ...string[]]; pluralOperators: [string, ...string[]];
} }
export type IFilterVisibility = {
[key: string]: boolean | undefined;
};
export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
state, state,
onChange, onChange,
@ -54,16 +57,14 @@ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
]; ];
const [availableFilters, setAvailableFilters] = useState<IFilterItem[]>([]); const [availableFilters, setAvailableFilters] = useState<IFilterItem[]>([]);
const removeFilter = (label: string) => { const [visibleFilters, setVisibleFilters] = useState<IFilterVisibility>({});
const filters = availableFilters.map((filter) =>
filter.label === label const hideFilter = (label: string) => {
? { const filterVisibility = {
...filter, ...visibleFilters,
enabled: false, [label]: false,
} };
: filter, setVisibleFilters(filterVisibility);
);
setAvailableFilters(filters);
}; };
useEffect(() => { useEffect(() => {
@ -76,14 +77,13 @@ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
value: segment.name, value: segment.name,
})); }));
const newFilterItems: IFilterItem[] = [ const availableFilters: IFilterItem[] = [
{ {
label: 'State', label: 'State',
options: stateOptions, options: stateOptions,
filterKey: 'state', filterKey: 'state',
singularOperators: ['IS', 'IS_NOT'], singularOperators: ['IS', 'IS_NOT'],
pluralOperators: ['IS_ANY_OF', 'IS_NONE_OF'], pluralOperators: ['IS_ANY_OF', 'IS_NONE_OF'],
enabled: Boolean(state.state),
}, },
{ {
label: 'Project', label: 'Project',
@ -91,7 +91,6 @@ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
filterKey: 'project', filterKey: 'project',
singularOperators: ['IS', 'IS_NOT'], singularOperators: ['IS', 'IS_NOT'],
pluralOperators: ['IS_ANY_OF', 'IS_NONE_OF'], pluralOperators: ['IS_ANY_OF', 'IS_NONE_OF'],
enabled: Boolean(state.project),
}, },
{ {
label: 'Segment', label: 'Segment',
@ -104,22 +103,30 @@ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
'EXCLUDE_IF_ANY_OF', 'EXCLUDE_IF_ANY_OF',
'EXCLUDE_ALL', 'EXCLUDE_ALL',
], ],
enabled: Boolean(state.segment),
}, },
]; ];
setAvailableFilters(newFilterItems); setAvailableFilters(availableFilters);
}, [ }, [JSON.stringify(projects), JSON.stringify(segments)]);
JSON.stringify(projects),
JSON.stringify(state), useEffect(() => {
JSON.stringify(segments), 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 ( return (
<StyledBox> <StyledBox>
{availableFilters.map( {availableFilters.map(
(filter) => (filter) =>
filter.enabled && ( visibleFilters[filter.label] && (
<FilterItem <FilterItem
key={filter.label} key={filter.label}
label={filter.label} label={filter.label}
@ -130,16 +137,16 @@ export const FeatureToggleFilters: VFC<IFeatureToggleFiltersProps> = ({
} }
singularOperators={filter.singularOperators} singularOperators={filter.singularOperators}
pluralOperators={filter.pluralOperators} pluralOperators={filter.pluralOperators}
onChipClose={() => removeFilter(filter.label)} onChipClose={() => hideFilter(filter.label)}
/> />
), ),
)} )}
<ConditionallyRender <ConditionallyRender
condition={availableFilters.some((filter) => !filter.enabled)} condition={hasAvailableFilters}
show={ show={
<AddFilterButton <AddFilterButton
availableFilters={availableFilters} visibleFilters={visibleFilters}
setAvailableFilters={setAvailableFilters} setVisibleFilters={setVisibleFilters}
/> />
} }
/> />