mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: allow adding project to segment (#3290)
https://linear.app/unleash/issue/2-741/add-project-dropdown-into-creation-of-segments Allows users to bind a segment to a project when creating or editing a segment. <img width="1051" alt="image" src="https://user-images.githubusercontent.com/14320932/224103846-1fe1f849-496c-4a77-9831-53bcb36f822e.png">
This commit is contained in:
		
							parent
							
								
									9b563f60e6
								
							
						
					
					
						commit
						ff7185fe5b
					
				| @ -30,6 +30,8 @@ export const CreateSegment = () => { | ||||
|         setName, | ||||
|         description, | ||||
|         setDescription, | ||||
|         project, | ||||
|         setProject, | ||||
|         constraints, | ||||
|         setConstraints, | ||||
|         getSegmentPayload, | ||||
| @ -91,6 +93,8 @@ export const CreateSegment = () => { | ||||
|                 setName={setName} | ||||
|                 description={description} | ||||
|                 setDescription={setDescription} | ||||
|                 project={project} | ||||
|                 setProject={setProject} | ||||
|                 constraints={constraints} | ||||
|                 setConstraints={setConstraints} | ||||
|                 errors={errors} | ||||
|  | ||||
| @ -33,6 +33,8 @@ export const EditSegment = () => { | ||||
|         setName, | ||||
|         description, | ||||
|         setDescription, | ||||
|         project, | ||||
|         setProject, | ||||
|         constraints, | ||||
|         setConstraints, | ||||
|         getSegmentPayload, | ||||
| @ -41,6 +43,7 @@ export const EditSegment = () => { | ||||
|     } = useSegmentForm( | ||||
|         segment?.name, | ||||
|         segment?.description, | ||||
|         segment?.project, | ||||
|         segment?.constraints | ||||
|     ); | ||||
| 
 | ||||
| @ -94,6 +97,8 @@ export const EditSegment = () => { | ||||
|                 setName={setName} | ||||
|                 description={description} | ||||
|                 setDescription={setDescription} | ||||
|                 project={project} | ||||
|                 setProject={setProject} | ||||
|                 constraints={constraints} | ||||
|                 setConstraints={setConstraints} | ||||
|                 errors={errors} | ||||
|  | ||||
| @ -12,9 +12,11 @@ export type SegmentFormMode = 'create' | 'edit'; | ||||
| interface ISegmentProps { | ||||
|     name: string; | ||||
|     description: string; | ||||
|     project: string | null; | ||||
|     constraints: IConstraint[]; | ||||
|     setName: React.Dispatch<React.SetStateAction<string>>; | ||||
|     setDescription: React.Dispatch<React.SetStateAction<string>>; | ||||
|     setProject: React.Dispatch<React.SetStateAction<string | null>>; | ||||
|     setConstraints: React.Dispatch<React.SetStateAction<IConstraint[]>>; | ||||
|     handleSubmit: (e: any) => void; | ||||
|     errors: { [key: string]: string }; | ||||
| @ -32,9 +34,11 @@ export const SegmentForm: React.FC<ISegmentProps> = ({ | ||||
|     children, | ||||
|     name, | ||||
|     description, | ||||
|     project, | ||||
|     constraints, | ||||
|     setName, | ||||
|     setDescription, | ||||
|     setProject, | ||||
|     setConstraints, | ||||
|     handleSubmit, | ||||
|     errors, | ||||
| @ -54,8 +58,10 @@ export const SegmentForm: React.FC<ISegmentProps> = ({ | ||||
|                         <SegmentFormStepOne | ||||
|                             name={name} | ||||
|                             description={description} | ||||
|                             project={project} | ||||
|                             setName={setName} | ||||
|                             setDescription={setDescription} | ||||
|                             setProject={setProject} | ||||
|                             errors={errors} | ||||
|                             clearErrors={clearErrors} | ||||
|                             setCurrentStep={setCurrentStep} | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { Button, styled } from '@mui/material'; | ||||
| import { Autocomplete, Button, styled, TextField } from '@mui/material'; | ||||
| import Input from 'component/common/Input/Input'; | ||||
| import React from 'react'; | ||||
| import React, { useEffect } from 'react'; | ||||
| import { useNavigate } from 'react-router-dom'; | ||||
| import { SegmentFormStep } from './SegmentForm'; | ||||
| import { | ||||
| @ -8,12 +8,17 @@ import { | ||||
|     SEGMENT_DESC_ID, | ||||
|     SEGMENT_NEXT_BTN_ID, | ||||
| } from 'utils/testIds'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||||
| import useProjects from 'hooks/api/getters/useProjects/useProjects'; | ||||
| 
 | ||||
| interface ISegmentFormPartOneProps { | ||||
|     name: string; | ||||
|     description: string; | ||||
|     project: string | null; | ||||
|     setName: React.Dispatch<React.SetStateAction<string>>; | ||||
|     setDescription: React.Dispatch<React.SetStateAction<string>>; | ||||
|     setProject: React.Dispatch<React.SetStateAction<string | null>>; | ||||
|     errors: { [key: string]: string }; | ||||
|     clearErrors: () => void; | ||||
|     setCurrentStep: React.Dispatch<React.SetStateAction<SegmentFormStep>>; | ||||
| @ -52,13 +57,25 @@ export const SegmentFormStepOne: React.FC<ISegmentFormPartOneProps> = ({ | ||||
|     children, | ||||
|     name, | ||||
|     description, | ||||
|     project, | ||||
|     setName, | ||||
|     setDescription, | ||||
|     setProject, | ||||
|     errors, | ||||
|     clearErrors, | ||||
|     setCurrentStep, | ||||
| }) => { | ||||
|     const { uiConfig } = useUiConfig(); | ||||
|     const navigate = useNavigate(); | ||||
|     const { projects } = useProjects(); | ||||
| 
 | ||||
|     const [selectedProject, setSelectedProject] = React.useState( | ||||
|         projects.find(({ id }) => id === project) ?? null | ||||
|     ); | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|         setSelectedProject(projects.find(({ id }) => id === project) ?? null); | ||||
|     }, [project, projects]); | ||||
| 
 | ||||
|     return ( | ||||
|         <StyledForm> | ||||
| @ -87,6 +104,28 @@ export const SegmentFormStepOne: React.FC<ISegmentFormPartOneProps> = ({ | ||||
|                     errorText={errors.description} | ||||
|                     data-testid={SEGMENT_DESC_ID} | ||||
|                 /> | ||||
|                 <ConditionallyRender | ||||
|                     condition={Boolean(uiConfig.flags.projectScopedSegments)} | ||||
|                     show={ | ||||
|                         <> | ||||
|                             <StyledInputDescription> | ||||
|                                 Is this segment tied to a specific project? | ||||
|                             </StyledInputDescription> | ||||
|                             <Autocomplete | ||||
|                                 size="small" | ||||
|                                 value={selectedProject} | ||||
|                                 onChange={(_, newValue) => { | ||||
|                                     setProject(newValue?.id ?? null); | ||||
|                                 }} | ||||
|                                 options={projects} | ||||
|                                 getOptionLabel={option => option.name} | ||||
|                                 renderInput={params => ( | ||||
|                                     <TextField {...params} label="Project" /> | ||||
|                                 )} | ||||
|                             /> | ||||
|                         </> | ||||
|                     } | ||||
|                 /> | ||||
|             </StyledContainer> | ||||
|             <StyledButtonContainer> | ||||
|                 <Button | ||||
|  | ||||
| @ -5,10 +5,12 @@ import { useSegmentValidation } from 'hooks/api/getters/useSegmentValidation/use | ||||
| export const useSegmentForm = ( | ||||
|     initialName = '', | ||||
|     initialDescription = '', | ||||
|     initialProject: string | null = null, | ||||
|     initialConstraints: IConstraint[] = [] | ||||
| ) => { | ||||
|     const [name, setName] = useState(initialName); | ||||
|     const [description, setDescription] = useState(initialDescription); | ||||
|     const [project, setProject] = useState<string | null>(initialProject); | ||||
|     const [constraints, setConstraints] = | ||||
|         useState<IConstraint[]>(initialConstraints); | ||||
|     const [errors, setErrors] = useState({}); | ||||
| @ -22,6 +24,10 @@ export const useSegmentForm = ( | ||||
|         setDescription(initialDescription); | ||||
|     }, [initialDescription]); | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|         setProject(initialProject); | ||||
|     }, [initialProject]); | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|         setConstraints(initialConstraints); | ||||
|         // eslint-disable-next-line
 | ||||
| @ -38,6 +44,7 @@ export const useSegmentForm = ( | ||||
|         return { | ||||
|             name, | ||||
|             description, | ||||
|             project, | ||||
|             constraints, | ||||
|         }; | ||||
|     }; | ||||
| @ -51,6 +58,8 @@ export const useSegmentForm = ( | ||||
|         setName, | ||||
|         description, | ||||
|         setDescription, | ||||
|         project, | ||||
|         setProject, | ||||
|         constraints, | ||||
|         setConstraints, | ||||
|         getSegmentPayload, | ||||
|  | ||||
| @ -4,6 +4,7 @@ export interface ISegment { | ||||
|     id: number; | ||||
|     name: string; | ||||
|     description: string; | ||||
|     project: string | null; | ||||
|     createdAt: string; | ||||
|     createdBy: string; | ||||
|     constraints: IConstraint[]; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user