mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01: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