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:
parent
1a85b46acc
commit
b120c97717
@ -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>
|
||||
);
|
||||
};
|
@ -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}
|
||||
|
@ -31,6 +31,7 @@ export const useGlobalFeatureSearch = (pageLimit = DEFAULT_PAGE_LIMIT) => {
|
||||
segment: FilterItemParam,
|
||||
createdAt: FilterItemParam,
|
||||
type: FilterItemParam,
|
||||
lifecycle: FilterItemParam,
|
||||
};
|
||||
const [tableState, setTableState] = usePersistentTableState(
|
||||
`${storageKey}`,
|
||||
|
Loading…
Reference in New Issue
Block a user