mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: add tags selection to feature creation (#7674)

This commit is contained in:
		
							parent
							
								
									901f4dd682
								
							
						
					
					
						commit
						b55d6f46d0
					
				| @ -3,6 +3,7 @@ import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi'; | |||||||
| import useQueryParams from 'hooks/useQueryParams'; | import useQueryParams from 'hooks/useQueryParams'; | ||||||
| import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; | import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; | ||||||
| import { formatUnknownError } from 'utils/formatUnknownError'; | import { formatUnknownError } from 'utils/formatUnknownError'; | ||||||
|  | import type { ITag } from 'interfaces/tags'; | ||||||
| 
 | 
 | ||||||
| const useFeatureForm = ( | const useFeatureForm = ( | ||||||
|     initialName = '', |     initialName = '', | ||||||
| @ -16,6 +17,7 @@ const useFeatureForm = ( | |||||||
|     const { validateFeatureToggleName } = useFeatureApi(); |     const { validateFeatureToggleName } = useFeatureApi(); | ||||||
|     const toggleQueryName = params.get('name'); |     const toggleQueryName = params.get('name'); | ||||||
|     const [type, setType] = useState(initialType); |     const [type, setType] = useState(initialType); | ||||||
|  |     const [tags, setTags] = useState<Set<string>>(new Set()); | ||||||
|     const [name, setName] = useState(toggleQueryName || initialName); |     const [name, setName] = useState(toggleQueryName || initialName); | ||||||
|     const [project, setProject] = useState(projectId || initialProject); |     const [project, setProject] = useState(projectId || initialProject); | ||||||
|     const [description, setDescription] = useState(initialDescription); |     const [description, setDescription] = useState(initialDescription); | ||||||
| @ -48,11 +50,17 @@ const useFeatureForm = ( | |||||||
|     }, [initialImpressionData]); |     }, [initialImpressionData]); | ||||||
| 
 | 
 | ||||||
|     const getTogglePayload = () => { |     const getTogglePayload = () => { | ||||||
|  |         const splitTags: ITag[] = Array.from(tags).map((tag) => { | ||||||
|  |             const [type, value] = tag.split(':'); | ||||||
|  |             return { type, value }; | ||||||
|  |         }); | ||||||
|  |         const tagsPayload = tags.size > 0 ? { tags: splitTags } : {}; | ||||||
|         return { |         return { | ||||||
|             type, |             type, | ||||||
|             name, |             name, | ||||||
|             description, |             description, | ||||||
|             impressionData, |             impressionData, | ||||||
|  |             ...tagsPayload, | ||||||
|         }; |         }; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| @ -77,6 +85,8 @@ const useFeatureForm = ( | |||||||
|     return { |     return { | ||||||
|         type, |         type, | ||||||
|         setType, |         setType, | ||||||
|  |         tags, | ||||||
|  |         setTags, | ||||||
|         name, |         name, | ||||||
|         setName, |         setName, | ||||||
|         project, |         project, | ||||||
|  | |||||||
| @ -31,7 +31,10 @@ import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons'; | |||||||
| import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes'; | import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes'; | ||||||
| import { DialogFormTemplate } from 'component/common/DialogFormTemplate/DialogFormTemplate'; | import { DialogFormTemplate } from 'component/common/DialogFormTemplate/DialogFormTemplate'; | ||||||
| import { SingleSelectConfigButton } from 'component/common/DialogFormTemplate/ConfigButtons/SingleSelectConfigButton'; | import { SingleSelectConfigButton } from 'component/common/DialogFormTemplate/ConfigButtons/SingleSelectConfigButton'; | ||||||
|  | import useAllTags from 'hooks/api/getters/useAllTags/useAllTags'; | ||||||
|  | import Label from '@mui/icons-material/Label'; | ||||||
| import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon'; | import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon'; | ||||||
|  | import { MultiSelectConfigButton } from 'component/common/DialogFormTemplate/ConfigButtons/MultiSelectConfigButton'; | ||||||
| 
 | 
 | ||||||
| interface ICreateFeatureDialogProps { | interface ICreateFeatureDialogProps { | ||||||
|     open: boolean; |     open: boolean; | ||||||
| @ -56,6 +59,10 @@ const configButtonData = { | |||||||
|         icon: <ProjectIcon />, |         icon: <ProjectIcon />, | ||||||
|         text: 'Projects allow you to group feature flags together in the management UI.', |         text: 'Projects allow you to group feature flags together in the management UI.', | ||||||
|     }, |     }, | ||||||
|  |     tags: { | ||||||
|  |         icon: <Label />, | ||||||
|  |         text: 'Tags are used to group flags together in Unleash.', | ||||||
|  |     }, | ||||||
|     type: { |     type: { | ||||||
|         icon: <FlagIcon />, |         icon: <FlagIcon />, | ||||||
|         text: "A flag's type conveys its purpose.", |         text: "A flag's type conveys its purpose.", | ||||||
| @ -79,6 +86,8 @@ export const CreateFeatureDialog = ({ | |||||||
|     const { |     const { | ||||||
|         type, |         type, | ||||||
|         setType, |         setType, | ||||||
|  |         tags, | ||||||
|  |         setTags, | ||||||
|         name, |         name, | ||||||
|         setName, |         setName, | ||||||
|         project, |         project, | ||||||
| @ -150,6 +159,7 @@ export const CreateFeatureDialog = ({ | |||||||
|         useGlobalFeatureSearch(); |         useGlobalFeatureSearch(); | ||||||
| 
 | 
 | ||||||
|     const { project: projectInfo } = useProjectOverview(project); |     const { project: projectInfo } = useProjectOverview(project); | ||||||
|  |     const { tags: allTags } = useAllTags(); | ||||||
| 
 | 
 | ||||||
|     const resourceLimitsEnabled = useUiFlag('resourceLimits'); |     const resourceLimitsEnabled = useUiFlag('resourceLimits'); | ||||||
| 
 | 
 | ||||||
| @ -262,6 +272,34 @@ export const CreateFeatureDialog = ({ | |||||||
|                                     /> |                                     /> | ||||||
|                                 } |                                 } | ||||||
|                             /> |                             /> | ||||||
|  |                             <MultiSelectConfigButton | ||||||
|  |                                 tooltip={{ | ||||||
|  |                                     header: 'Select tags', | ||||||
|  |                                 }} | ||||||
|  |                                 description={configButtonData.tags.text} | ||||||
|  |                                 selectedOptions={tags} | ||||||
|  |                                 options={allTags.map((tag) => ({ | ||||||
|  |                                     label: `${tag.type}:${tag.value}`, | ||||||
|  |                                     value: `${tag.type}:${tag.value}`, | ||||||
|  |                                 }))} | ||||||
|  |                                 onChange={setTags} | ||||||
|  |                                 button={{ | ||||||
|  |                                     label: | ||||||
|  |                                         tags.size > 0 | ||||||
|  |                                             ? `${tags.size} selected` | ||||||
|  |                                             : 'Tags', | ||||||
|  |                                     labelWidth: `${'nn selected'.length}ch`, | ||||||
|  |                                     icon: <Label />, | ||||||
|  |                                 }} | ||||||
|  |                                 search={{ | ||||||
|  |                                     label: 'Filter tags', | ||||||
|  |                                     placeholder: 'Select tags', | ||||||
|  |                                 }} | ||||||
|  |                                 onOpen={() => | ||||||
|  |                                     setDocumentation(configButtonData.tags) | ||||||
|  |                                 } | ||||||
|  |                                 onClose={clearDocumentationOverride} | ||||||
|  |                             /> | ||||||
|                             <SingleSelectConfigButton |                             <SingleSelectConfigButton | ||||||
|                                 tooltip={{ |                                 tooltip={{ | ||||||
|                                     header: 'Select a flag type', |                                     header: 'Select a flag type', | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user