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

feat: lifecycle filters UI (#9713)

This commit is contained in:
Mateusz Kwasniewski 2025-04-08 10:04:07 +02:00 committed by GitHub
parent 1a85b46acc
commit b120c97717
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 98 additions and 3 deletions

View File

@ -0,0 +1,86 @@
import { Box, Chip, styled } from '@mui/material';
import type { FC } from 'react';
import type { FilterItemParamHolder } from '../../../filter/Filters/Filters';
import type { LifecycleStage } from '../../FeatureView/FeatureOverview/FeatureLifecycle/LifecycleStage';
const StyledChip = styled(Chip, {
shouldForwardProp: (prop) => prop !== 'isActive',
})<{
isActive?: boolean;
}>(({ theme, isActive = false }) => ({
borderRadius: `${theme.shape.borderRadius}px`,
padding: theme.spacing(0.5),
fontSize: theme.typography.body2.fontSize,
height: 'auto',
...(isActive && {
backgroundColor: theme.palette.secondary.light,
fontWeight: 'bold',
borderColor: theme.palette.primary.main,
color: theme.palette.primary.main,
}),
':focus-visible': {
outline: `1px solid ${theme.palette.primary.main}`,
borderColor: theme.palette.primary.main,
},
}));
interface ILifecycleFiltersProps {
state: FilterItemParamHolder;
onChange: (value: FilterItemParamHolder) => void;
}
const Wrapper = styled(Box)(({ theme }) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(1),
padding: theme.spacing(2, 3, 0, 3),
}));
const lifecycleOptions: {
label: string;
value: LifecycleStage['name'] | null;
}[] = [
{ label: 'All flags', value: null },
{ label: 'Develop', value: 'pre-live' },
{ label: 'Rollout production', value: 'live' },
{ label: 'Cleanup', value: 'completed' },
{ label: 'Archived', value: 'archived' },
];
export const LifecycleFilters: FC<ILifecycleFiltersProps> = ({
state,
onChange,
}) => {
const current = state.lifecycle?.values ?? [];
return (
<Wrapper>
{lifecycleOptions.map(({ label, value }) => {
const isActive =
value === null ? !state.lifecycle : current.includes(value);
const handleClick = () =>
onChange(
value === null
? { lifecycle: null }
: {
lifecycle: {
operator: 'IS',
values: [value],
},
},
);
return (
<StyledChip
key={label}
label={label}
variant='outlined'
isActive={isActive}
onClick={handleClick}
/>
);
})}
</Wrapper>
);
};

View File

@ -18,7 +18,6 @@ import { FavoriteIconCell } from 'component/common/Table/cells/FavoriteIconCell/
import { FavoriteIconHeader } from 'component/common/Table/FavoriteIconHeader/FavoriteIconHeader';
import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments';
import { ExportDialog } from './ExportDialog';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { focusable } from 'themes/themeStyles';
import { FeatureEnvironmentSeenCell } from 'component/common/Table/cells/FeatureSeenCell/FeatureEnvironmentSeenCell';
import useToast from 'hooks/useToast';
@ -30,6 +29,8 @@ import { FeatureToggleListActions } from './FeatureToggleListActions/FeatureTogg
import useLoading from 'hooks/useLoading';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
import { useGlobalFeatureSearch } from './useGlobalFeatureSearch';
import { LifecycleFilters } from './FeatureToggleFilters/LifecycleFilters';
import { useUiFlag } from 'hooks/useUiFlag';
export const featuresPlaceholder = Array(15).fill({
name: 'Name of the feature',
@ -40,7 +41,6 @@ export const featuresPlaceholder = Array(15).fill({
});
const columnHelper = createColumnHelper<FeatureSearchResponseSchema>();
const feedbackCategory = 'search';
export const FeatureToggleListTable: VFC = () => {
const theme = useTheme();
@ -54,7 +54,9 @@ export const FeatureToggleListTable: VFC = () => {
const [showExportDialog, setShowExportDialog] = useState(false);
const { setToastApiError } = useToast();
const { uiConfig } = useUiConfig();
const flagsReleaseManagementUIEnabled = useUiFlag(
'flagsReleaseManagementUI',
);
const {
features,
@ -306,6 +308,12 @@ export const FeatureToggleListTable: VFC = () => {
</PageHeader>
}
>
{flagsReleaseManagementUIEnabled ? (
<LifecycleFilters
state={filterState}
onChange={setTableState}
/>
) : null}
<FeatureToggleFilters
onChange={setTableState}
state={filterState}

View File

@ -31,6 +31,7 @@ export const useGlobalFeatureSearch = (pageLimit = DEFAULT_PAGE_LIMIT) => {
segment: FilterItemParam,
createdAt: FilterItemParam,
type: FilterItemParam,
lifecycle: FilterItemParam,
};
const [tableState, setTableState] = usePersistentTableState(
`${storageKey}`,