1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-05 17:53:12 +02:00

refactor: filters

This commit is contained in:
Tymoteusz Czech 2025-08-01 11:11:18 +02:00
parent c9df6c370f
commit c8cc9ad3a5
No known key found for this signature in database
GPG Key ID: 133555230D88D75F
3 changed files with 37 additions and 50 deletions

View File

@ -38,17 +38,15 @@ const StyledIcon = styled(Icon)(({ theme }) => ({
interface IAddFilterButtonProps { interface IAddFilterButtonProps {
visibleOptions: string[]; visibleOptions: string[];
setVisibleOptions: (filters: string[]) => void;
hiddenOptions: string[]; hiddenOptions: string[];
setHiddenOptions: (filters: string[]) => void; onSelectedOptionsChange: (filters: string[]) => void;
availableFilters: IFilterItem[]; availableFilters: IFilterItem[];
} }
export const AddFilterButton = ({ export const AddFilterButton = ({
visibleOptions, visibleOptions,
setVisibleOptions,
hiddenOptions, hiddenOptions,
setHiddenOptions, onSelectedOptionsChange,
availableFilters, availableFilters,
}: IAddFilterButtonProps) => { }: IAddFilterButtonProps) => {
const projectId = useOptionalPathParam('projectId'); const projectId = useOptionalPathParam('projectId');
@ -69,11 +67,7 @@ export const AddFilterButton = ({
}; };
const onSelect = (label: string) => { const onSelect = (label: string) => {
const newVisibleOptions = visibleOptions.filter((f) => f !== label); onSelectedOptionsChange([...hiddenOptions, label]);
const newHiddenOptions = [...hiddenOptions, label];
setHiddenOptions(newHiddenOptions);
setVisibleOptions(newVisibleOptions);
handleClose(); handleClose();
}; };

View File

@ -1,6 +1,5 @@
import { type FC, useEffect, useState } from 'react'; import { type FC, useEffect, useMemo, useState } from 'react';
import { Box, Icon, styled } from '@mui/material'; import { Box, Icon, styled } from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { AddFilterButton } from '../AddFilterButton.tsx'; import { AddFilterButton } from '../AddFilterButton.tsx';
import { FilterDateItem } from 'component/common/FilterDateItem/FilterDateItem'; import { FilterDateItem } from 'component/common/FilterDateItem/FilterDateItem';
import { import {
@ -165,6 +164,22 @@ const SingleFilter: FC<SingleFilterProps> = ({
); );
}; };
const mergeArraysKeepingOrder = (
firstArray: string[],
secondArray: string[],
): string[] => {
const resultArray: string[] = [...firstArray];
const elementsSet = new Set(firstArray);
secondArray.forEach((element) => {
if (!elementsSet.has(element)) {
resultArray.push(element);
}
});
return resultArray;
};
type MultiFilterProps = IFilterProps & { type MultiFilterProps = IFilterProps & {
rangeChangeHandler: RangeChangeHandler; rangeChangeHandler: RangeChangeHandler;
}; };
@ -176,31 +191,12 @@ const MultiFilter: FC<MultiFilterProps> = ({
rangeChangeHandler, rangeChangeHandler,
className, className,
}) => { }) => {
const [unselectedFilters, setUnselectedFilters] = useState<string[]>([]);
const [selectedFilters, setSelectedFilters] = useState<string[]>([]); const [selectedFilters, setSelectedFilters] = useState<string[]>([]);
const deselectFilter = (label: string) => { const deselectFilter = (label: string) => {
const newSelectedFilters = selectedFilters.filter((f) => f !== label); const newSelectedFilters = selectedFilters.filter((f) => f !== label);
const newUnselectedFilters = [...unselectedFilters, label].sort();
setSelectedFilters(newSelectedFilters); setSelectedFilters(newSelectedFilters);
setUnselectedFilters(newUnselectedFilters);
};
const mergeArraysKeepingOrder = (
firstArray: string[],
secondArray: string[],
): string[] => {
const resultArray: string[] = [...firstArray];
const elementsSet = new Set(firstArray);
secondArray.forEach((element) => {
if (!elementsSet.has(element)) {
resultArray.push(element);
}
});
return resultArray;
}; };
useEffect(() => { useEffect(() => {
@ -219,15 +215,16 @@ const MultiFilter: FC<MultiFilterProps> = ({
newSelectedFilters, newSelectedFilters,
); );
setSelectedFilters(allSelectedFilters); setSelectedFilters(allSelectedFilters);
const newUnselectedFilters = availableFilters
.filter((item) => !allSelectedFilters.includes(item.label))
.map((field) => field.label)
.sort();
setUnselectedFilters(newUnselectedFilters);
}, [JSON.stringify(state), JSON.stringify(availableFilters)]); }, [JSON.stringify(state), JSON.stringify(availableFilters)]);
const hasAvailableFilters = unselectedFilters.length > 0; const unselectedFilters = useMemo(
() =>
availableFilters
.filter((item) => !selectedFilters.includes(item.label))
.map((field) => field.label)
.sort(),
[availableFilters, selectedFilters],
);
return ( return (
<StyledBox className={className}> <StyledBox className={className}>
@ -251,19 +248,14 @@ const MultiFilter: FC<MultiFilterProps> = ({
/> />
); );
})} })}
{unselectedFilters.length > 0 ? (
<ConditionallyRender <AddFilterButton
condition={hasAvailableFilters} availableFilters={availableFilters}
show={ visibleOptions={unselectedFilters}
<AddFilterButton hiddenOptions={selectedFilters}
availableFilters={availableFilters} onSelectedOptionsChange={setSelectedFilters}
visibleOptions={unselectedFilters} />
setVisibleOptions={setUnselectedFilters} ) : null}
hiddenOptions={selectedFilters}
setHiddenOptions={setSelectedFilters}
/>
}
/>
</StyledBox> </StyledBox>
); );
}; };

View File

@ -114,6 +114,7 @@ export const ProjectFeatureToggles = ({
createdBy: tableState.createdBy, createdBy: tableState.createdBy,
archived: tableState.archived, archived: tableState.archived,
lifecycle: tableState.lifecycle, lifecycle: tableState.lifecycle,
lastSeenAt: tableState.lastSeenAt,
}; };
const { favorite, unfavorite } = useFavoriteFeaturesApi(); const { favorite, unfavorite } = useFavoriteFeaturesApi();