diff --git a/frontend/src/component/feature/FeatureToggleList/FeatureToggleFilters/LifecycleFilters.tsx b/frontend/src/component/feature/FeatureToggleList/FeatureToggleFilters/LifecycleFilters.tsx new file mode 100644 index 0000000000..24ceb5ee4d --- /dev/null +++ b/frontend/src/component/feature/FeatureToggleList/FeatureToggleFilters/LifecycleFilters.tsx @@ -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 = ({ + state, + onChange, +}) => { + const current = state.lifecycle?.values ?? []; + + return ( + + {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 ( + + ); + })} + + ); +}; diff --git a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx index 5c2c0eaa90..bbdf180216 100644 --- a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx +++ b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx @@ -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(); -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 = () => { } > + {flagsReleaseManagementUIEnabled ? ( + + ) : null} { segment: FilterItemParam, createdAt: FilterItemParam, type: FilterItemParam, + lifecycle: FilterItemParam, }; const [tableState, setTableState] = usePersistentTableState( `${storageKey}`,