mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
fix: handle existing feature name (#641)
* fix: handle existing feature name * refactor: change feature input order
This commit is contained in:
parent
d69c024bbe
commit
3488bb5fd6
@ -27,8 +27,8 @@ const CreateFeature = () => {
|
|||||||
setProject,
|
setProject,
|
||||||
description,
|
description,
|
||||||
setDescription,
|
setDescription,
|
||||||
|
validateToggleName,
|
||||||
getTogglePayload,
|
getTogglePayload,
|
||||||
validateName,
|
|
||||||
clearErrors,
|
clearErrors,
|
||||||
errors,
|
errors,
|
||||||
} = useFeatureForm();
|
} = useFeatureForm();
|
||||||
@ -38,20 +38,23 @@ const CreateFeature = () => {
|
|||||||
const handleSubmit = async (e: Event) => {
|
const handleSubmit = async (e: Event) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
clearErrors();
|
clearErrors();
|
||||||
await validateName(name);
|
const validToggleName = await validateToggleName();
|
||||||
const payload = getTogglePayload();
|
|
||||||
try {
|
if (validToggleName) {
|
||||||
await createFeatureToggle(project, payload);
|
const payload = getTogglePayload();
|
||||||
history.push(`/projects/${project}/features2/${name}`);
|
try {
|
||||||
setToastData({
|
await createFeatureToggle(project, payload);
|
||||||
title: 'Toggle created successfully',
|
history.push(`/projects/${project}/features2/${name}`);
|
||||||
text: 'Now you can start using your toggle.',
|
setToastData({
|
||||||
confetti: true,
|
title: 'Toggle created successfully',
|
||||||
type: 'success',
|
text: 'Now you can start using your toggle.',
|
||||||
});
|
confetti: true,
|
||||||
setShowFeedback(true);
|
type: 'success',
|
||||||
} catch (e: any) {
|
});
|
||||||
setToastApiError(e.toString());
|
setShowFeedback(true);
|
||||||
|
} catch (e: any) {
|
||||||
|
setToastApiError(e.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,6 +89,7 @@ const CreateFeature = () => {
|
|||||||
setName={setName}
|
setName={setName}
|
||||||
setProject={setProject}
|
setProject={setProject}
|
||||||
setDescription={setDescription}
|
setDescription={setDescription}
|
||||||
|
validateToggleName={validateToggleName}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
handleSubmit={handleSubmit}
|
handleSubmit={handleSubmit}
|
||||||
handleCancel={handleCancel}
|
handleCancel={handleCancel}
|
||||||
|
@ -3,11 +3,7 @@ import Input from '../../../common/Input/Input';
|
|||||||
import { Button } from '@material-ui/core';
|
import { Button } from '@material-ui/core';
|
||||||
import { useStyles } from './FeatureForm.styles';
|
import { useStyles } from './FeatureForm.styles';
|
||||||
import FeatureTypeSelect from '../../FeatureView2/FeatureSettings/FeatureSettingsMetadata/FeatureTypeSelect/FeatureTypeSelect';
|
import FeatureTypeSelect from '../../FeatureView2/FeatureSettings/FeatureSettingsMetadata/FeatureTypeSelect/FeatureTypeSelect';
|
||||||
import {
|
import { CF_DESC_ID, CF_NAME_ID, CF_TYPE_ID } from '../../../../testIds';
|
||||||
CF_DESC_ID,
|
|
||||||
CF_NAME_ID,
|
|
||||||
CF_TYPE_ID,
|
|
||||||
} from '../../../../testIds';
|
|
||||||
import useFeatureTypes from '../../../../hooks/api/getters/useFeatureTypes/useFeatureTypes';
|
import useFeatureTypes from '../../../../hooks/api/getters/useFeatureTypes/useFeatureTypes';
|
||||||
import { KeyboardArrowDownOutlined } from '@material-ui/icons';
|
import { KeyboardArrowDownOutlined } from '@material-ui/icons';
|
||||||
import useUser from '../../../../hooks/api/getters/useUser/useUser';
|
import useUser from '../../../../hooks/api/getters/useUser/useUser';
|
||||||
@ -25,6 +21,7 @@ interface IFeatureToggleForm {
|
|||||||
setName: React.Dispatch<React.SetStateAction<string>>;
|
setName: React.Dispatch<React.SetStateAction<string>>;
|
||||||
setDescription: React.Dispatch<React.SetStateAction<string>>;
|
setDescription: React.Dispatch<React.SetStateAction<string>>;
|
||||||
setProject: React.Dispatch<React.SetStateAction<string>>;
|
setProject: React.Dispatch<React.SetStateAction<string>>;
|
||||||
|
validateToggleName: () => void;
|
||||||
handleSubmit: (e: any) => void;
|
handleSubmit: (e: any) => void;
|
||||||
handleCancel: () => void;
|
handleCancel: () => void;
|
||||||
errors: { [key: string]: string };
|
errors: { [key: string]: string };
|
||||||
@ -42,6 +39,7 @@ const FeatureForm: React.FC<IFeatureToggleForm> = ({
|
|||||||
setName,
|
setName,
|
||||||
setDescription,
|
setDescription,
|
||||||
setProject,
|
setProject,
|
||||||
|
validateToggleName,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
handleCancel,
|
handleCancel,
|
||||||
errors,
|
errors,
|
||||||
@ -60,6 +58,23 @@ const FeatureForm: React.FC<IFeatureToggleForm> = ({
|
|||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit} className={styles.form}>
|
<form onSubmit={handleSubmit} className={styles.form}>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
|
<p className={styles.inputDescription}>
|
||||||
|
What would you like to call your toggle?
|
||||||
|
</p>
|
||||||
|
<Input
|
||||||
|
disabled={mode === 'Edit'}
|
||||||
|
className={styles.input}
|
||||||
|
label="Name"
|
||||||
|
error={Boolean(errors.name)}
|
||||||
|
errorText={errors.name}
|
||||||
|
onFocus={() => clearErrors()}
|
||||||
|
value={name}
|
||||||
|
onChange={e => setName(trim(e.target.value))}
|
||||||
|
inputProps={{
|
||||||
|
'data-test': CF_NAME_ID,
|
||||||
|
}}
|
||||||
|
onBlur={validateToggleName}
|
||||||
|
/>
|
||||||
<p className={styles.inputDescription}>
|
<p className={styles.inputDescription}>
|
||||||
What kind of feature toggle do you want to create?
|
What kind of feature toggle do you want to create?
|
||||||
</p>
|
</p>
|
||||||
@ -80,23 +95,6 @@ const FeatureForm: React.FC<IFeatureToggleForm> = ({
|
|||||||
<p className={styles.typeDescription}>
|
<p className={styles.typeDescription}>
|
||||||
{renderToggleDescription()}
|
{renderToggleDescription()}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className={styles.inputDescription}>
|
|
||||||
What would you like to call your toggle?
|
|
||||||
</p>
|
|
||||||
<Input
|
|
||||||
disabled={mode === 'Edit'}
|
|
||||||
className={styles.input}
|
|
||||||
label="Name"
|
|
||||||
error={Boolean(errors.name)}
|
|
||||||
errorText={errors.name}
|
|
||||||
onFocus={() => clearErrors()}
|
|
||||||
value={name}
|
|
||||||
onChange={e => setName(trim(e.target.value))}
|
|
||||||
inputProps={{
|
|
||||||
'data-test': CF_NAME_ID,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={editable}
|
condition={editable}
|
||||||
show={
|
show={
|
||||||
|
@ -47,23 +47,24 @@ const useFeatureForm = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateName = async (name: string) => {
|
const NAME_EXISTS_ERROR = 'Error: A toggle with that name already exists';
|
||||||
|
|
||||||
|
const validateToggleName = async () => {
|
||||||
if (name.length === 0) {
|
if (name.length === 0) {
|
||||||
setErrors(prev => ({ ...prev, name: 'Name can not be empty.' }));
|
setErrors(prev => ({ ...prev, name: 'Name can not be empty.' }));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (name.length > 0) {
|
try {
|
||||||
try {
|
await validateFeatureToggleName(name);
|
||||||
await validateFeatureToggleName(name);
|
return true;
|
||||||
} catch (err: any) {
|
} catch (e: any) {
|
||||||
|
if (e.toString().includes(NAME_EXISTS_ERROR)) {
|
||||||
setErrors(prev => ({
|
setErrors(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
name:
|
name: 'A feature with this name already exists',
|
||||||
err && err.message
|
|
||||||
? err.message
|
|
||||||
: 'Could not check name',
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,7 +82,7 @@ const useFeatureForm = (
|
|||||||
description,
|
description,
|
||||||
setDescription,
|
setDescription,
|
||||||
getTogglePayload,
|
getTogglePayload,
|
||||||
validateName,
|
validateToggleName,
|
||||||
clearErrors,
|
clearErrors,
|
||||||
errors,
|
errors,
|
||||||
};
|
};
|
||||||
|
@ -56,6 +56,7 @@ const useProjectForm = (
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateProjectId = () => {
|
const validateProjectId = () => {
|
||||||
if (projectId.length === 0) {
|
if (projectId.length === 0) {
|
||||||
setErrors(prev => ({ ...prev, id: 'id can not be empty.' }));
|
setErrors(prev => ({ ...prev, id: 'id can not be empty.' }));
|
||||||
|
Loading…
Reference in New Issue
Block a user