mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +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