1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-17 13:46:47 +02:00

feat: front end can create projects without ids (#7009)

This PR updates the new project creation form to not include the project
ID in the payload (because it's generated by the back end now).
This commit is contained in:
Thomas Heartman 2024-05-08 14:57:07 +02:00 committed by GitHub
parent 9f532834c8
commit b043bcdd4a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 28 deletions

View File

@ -68,14 +68,16 @@ const CreateProject = () => {
e.preventDefault(); e.preventDefault();
clearErrors(); clearErrors();
const validName = validateName(); const validName = validateName();
const validId = await validateProjectId(); const validId = useNewProjectForm || (await validateProjectId());
if (validName && validId) { if (validName && validId) {
const payload = getCreateProjectPayload(); const payload = getCreateProjectPayload({
omitId: useNewProjectForm,
});
try { try {
await createProject(payload); const createdProject = await createProject(payload);
refetchUser(); refetchUser();
navigate(`/projects/${projectId}`, { replace: true }); navigate(`/projects/${createdProject.id}`, { replace: true });
setToastData({ setToastData({
title: 'Project created', title: 'Project created',
text: 'Now you can add toggles to this project', text: 'Now you can add toggles to this project',
@ -99,7 +101,11 @@ const CreateProject = () => {
return `curl --location --request POST '${uiConfig.unleashUrl}/api/admin/projects' \\ return `curl --location --request POST '${uiConfig.unleashUrl}/api/admin/projects' \\
--header 'Authorization: INSERT_API_KEY' \\ --header 'Authorization: INSERT_API_KEY' \\
--header 'Content-Type: application/json' \\ --header 'Content-Type: application/json' \\
--data-raw '${JSON.stringify(getCreateProjectPayload(), undefined, 2)}'`; --data-raw '${JSON.stringify(
getCreateProjectPayload({ omitId: useNewProjectForm }),
undefined,
2,
)}'`;
}; };
const handleCancel = () => { const handleCancel = () => {

View File

@ -1,5 +1,4 @@
import { Typography, styled } from '@mui/material'; import { Typography, styled } from '@mui/material';
import { v4 as uuidv4 } from 'uuid';
import Input from 'component/common/Input/Input'; import Input from 'component/common/Input/Input';
import type { ProjectMode } from '../hooks/useProjectEnterpriseSettingsForm'; import type { ProjectMode } from '../hooks/useProjectEnterpriseSettingsForm';
import { ReactComponent as ProjectIcon } from 'assets/icons/projectIconSmall.svg'; import { ReactComponent as ProjectIcon } from 'assets/icons/projectIconSmall.svg';
@ -133,7 +132,6 @@ export const NewProjectForm: React.FC<FormProps> = ({
setProjectName, setProjectName,
setProjectDesc, setProjectDesc,
setProjectStickiness, setProjectStickiness,
// setProjectChangeRequestConfiguration,
updateProjectChangeRequestConfig, updateProjectChangeRequestConfig,
setFeatureLimit, setFeatureLimit,
errors, errors,
@ -151,12 +149,6 @@ export const NewProjectForm: React.FC<FormProps> = ({
) => { ) => {
const input = e.target.value; const input = e.target.value;
setProjectName(input); setProjectName(input);
// todo: handle this in a real manner. This is a hack for now.
const maybeProjectId = input
? `${encodeURIComponent(input.trim())}-${uuidv4().slice(-12)}`
: '';
setProjectId(maybeProjectId);
}; };
const projectModeOptions = [ const projectModeOptions = [

View File

@ -94,7 +94,7 @@ const useProjectForm = (
setProjectMode(initialProjectMode); setProjectMode(initialProjectMode);
}, [initialProjectMode]); }, [initialProjectMode]);
const getCreateProjectPayload = () => { const getCreateProjectPayload = (options?: { omitId?: boolean }) => {
const environmentsPayload = const environmentsPayload =
projectEnvironments.size > 0 projectEnvironments.size > 0
? { environments: [...projectEnvironments] } ? { environments: [...projectEnvironments] }
@ -107,23 +107,21 @@ const useProjectForm = (
requiredApprovals, requiredApprovals,
})); }));
const ossPayload = {
...(options?.omitId ? {} : { id: projectId }),
name: projectName,
description: projectDesc,
defaultStickiness: projectStickiness,
...environmentsPayload,
};
return isEnterprise() return isEnterprise()
? { ? {
id: projectId, ...ossPayload,
name: projectName,
description: projectDesc,
defaultStickiness: projectStickiness,
mode: projectMode, mode: projectMode,
...environmentsPayload,
changeRequestEnvironments, changeRequestEnvironments,
} }
: { : ossPayload;
id: projectId,
name: projectName,
description: projectDesc,
defaultStickiness: projectStickiness,
...environmentsPayload,
};
}; };
const getEditProjectPayload = () => { const getEditProjectPayload = () => {

View File

@ -4,6 +4,7 @@ import type {
CreateProjectSchema, CreateProjectSchema,
UpdateProjectSchema, UpdateProjectSchema,
UpdateProjectEnterpriseSettingsSchema, UpdateProjectEnterpriseSettingsSchema,
ProjectCreatedSchema,
} from 'openapi'; } from 'openapi';
import useAPI from '../useApi/useApi'; import useAPI from '../useApi/useApi';
@ -18,7 +19,9 @@ const useProjectApi = () => {
propagateErrors: true, propagateErrors: true,
}); });
const createProject = async (payload: CreateProjectSchema) => { const createProject = async (
payload: CreateProjectSchema,
): Promise<ProjectCreatedSchema> => {
const path = `api/admin/projects`; const path = `api/admin/projects`;
const req = createRequest(path, { const req = createRequest(path, {
method: 'POST', method: 'POST',
@ -27,7 +30,7 @@ const useProjectApi = () => {
const res = await makeRequest(req.caller, req.id); const res = await makeRequest(req.caller, req.id);
return res; return res.json();
}; };
const validateId = async (id: CreateProjectSchema['id']) => { const validateId = async (id: CreateProjectSchema['id']) => {