1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-04 00:18:01 +01:00
unleash.unleash/frontend/src/component/project/Project/CreateProject/CreateProject.tsx

155 lines
5.4 KiB
TypeScript
Raw Normal View History

import { Navigate, useNavigate } from 'react-router-dom';
import ProjectForm from '../ProjectForm/ProjectForm';
import useProjectForm, {
DEFAULT_PROJECT_STICKINESS,
} from '../hooks/useProjectForm';
import { CreateButton } from 'component/common/CreateButton/CreateButton';
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
import { CREATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import useToast from 'hooks/useToast';
import { formatUnknownError } from 'utils/formatUnknownError';
import { GO_BACK } from 'constants/navigate';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
import { Button, styled } from '@mui/material';
import { useUiFlag } from 'hooks/useUiFlag';
import { useState } from 'react';
const CREATE_PROJECT_BTN = 'CREATE_PROJECT_BTN';
const StyledButton = styled(Button)(({ theme }) => ({
marginLeft: theme.spacing(3),
}));
const CreateProject = () => {
const { setToastData, setToastApiError } = useToast();
const { refetchUser } = useAuthUser();
const { uiConfig } = useUiConfig();
const useNewProjectForm = useUiFlag('newCreateProjectUI');
const navigate = useNavigate();
const { trackEvent } = usePlausibleTracker();
const {
projectId,
projectName,
projectDesc,
projectMode,
support setting mode and stickiness in new project form (#6972) This PR is a combination of two PRs: This PR adds a functioning environment selection button to the new project creation form. Selected environments are added to the payload and to the API preview. The implementation is mostly lifted from the existing FilterItem component we have for search filters. However, our need here is less complex, so I've removed some of the things we don't need. There is still more cleanup to be done, however, but I'd like to implement the rest of the submenus first, to see what we really do need in the end. --- This PR adds support for stickiness and project mode in the new project creation form. Achieve this, it does a few things: 1. Moves `resolveStickinessOptions` from `frontend/src/component/feature/StrategyTypes/FlexibleStrategy/StickinessSelect/StickinessSelect.tsx` and into a separate hook. This component was used by the old project creation form. Because the new form has a different input, but needs the same option, moved that code into a reusable hook. 2. It adds functioning buttons for project stickiness and mode. 3. It adds labels to the search inputs for the dropdowns. Inputs *must* have labels to meet a11y requirements. However, the designs don't have labels, so we can hide them visually. Though that leads to another issue (refer to the screen shot below). 4. It updates the `SelectionButton` component to handle both single- and multiselect cases. It instead exports these two subcomponents. These are currently in one file, but I'll split them out into their separate files in a later PR. As a side effect of working with the selection buttons, it also improves how we handle keyboard interaction for these buttons. Here's what it looks like for single-select lists. Notice the missing part of the input's border around the top (where the label *would* be if we showed it). We should figure out how best to handle it. I've done like this for now, but we can sort it out later. ![image](https://github.com/Unleash/unleash/assets/17786332/5af979c2-6635-481e-8d3e-5aad1c0ab46f)
2024-05-03 07:27:13 +02:00
projectEnvironments,
projectChangeRequestConfiguration,
setProjectMode,
setProjectId,
setProjectName,
setProjectDesc,
support setting mode and stickiness in new project form (#6972) This PR is a combination of two PRs: This PR adds a functioning environment selection button to the new project creation form. Selected environments are added to the payload and to the API preview. The implementation is mostly lifted from the existing FilterItem component we have for search filters. However, our need here is less complex, so I've removed some of the things we don't need. There is still more cleanup to be done, however, but I'd like to implement the rest of the submenus first, to see what we really do need in the end. --- This PR adds support for stickiness and project mode in the new project creation form. Achieve this, it does a few things: 1. Moves `resolveStickinessOptions` from `frontend/src/component/feature/StrategyTypes/FlexibleStrategy/StickinessSelect/StickinessSelect.tsx` and into a separate hook. This component was used by the old project creation form. Because the new form has a different input, but needs the same option, moved that code into a reusable hook. 2. It adds functioning buttons for project stickiness and mode. 3. It adds labels to the search inputs for the dropdowns. Inputs *must* have labels to meet a11y requirements. However, the designs don't have labels, so we can hide them visually. Though that leads to another issue (refer to the screen shot below). 4. It updates the `SelectionButton` component to handle both single- and multiselect cases. It instead exports these two subcomponents. These are currently in one file, but I'll split them out into their separate files in a later PR. As a side effect of working with the selection buttons, it also improves how we handle keyboard interaction for these buttons. Here's what it looks like for single-select lists. Notice the missing part of the input's border around the top (where the label *would* be if we showed it). We should figure out how best to handle it. I've done like this for now, but we can sort it out later. ![image](https://github.com/Unleash/unleash/assets/17786332/5af979c2-6635-481e-8d3e-5aad1c0ab46f)
2024-05-03 07:27:13 +02:00
setProjectEnvironments,
updateProjectChangeRequestConfig,
getCreateProjectPayload,
clearErrors,
validateProjectId,
validateName,
setProjectStickiness,
projectStickiness,
errors,
} = useProjectForm();
if (useNewProjectForm) {
return <Navigate to={`/projects?create=true`} replace />;
}
const generalDocumentation =
'Projects allows you to group feature flags together in the management UI.';
const [documentation, setDocumentation] = useState(generalDocumentation);
const clearDocumentationOverride = () =>
setDocumentation(generalDocumentation);
const { createProject, loading } = useProjectApi();
const handleSubmit = async (e: Event) => {
e.preventDefault();
clearErrors();
const validName = validateName();
const validId = useNewProjectForm || (await validateProjectId());
2022-01-25 12:30:55 +01:00
if (validName && validId) {
const payload = getCreateProjectPayload({
omitId: useNewProjectForm,
});
try {
const createdProject = await createProject(payload);
refetchUser();
navigate(`/projects/${createdProject.id}`, { replace: true });
setToastData({
title: 'Project created',
text: 'Now you can add flags to this project',
confetti: true,
type: 'success',
});
if (projectStickiness !== DEFAULT_PROJECT_STICKINESS) {
trackEvent('project_stickiness_set');
}
trackEvent('project-mode', {
props: { mode: projectMode, action: 'added' },
});
refactor: fix misc TS errors (#729) * refactor: update test deps * refactor: remove unused ts-expect-error annotations * refactor: add missing arg and return types * refactor: the loading prop is optional * refactor: add missing arg and return types * reafactor: fix value arg type * refactor: fix missing array type * refactor: the parameters field is an array * refactor: use undefined instead of null in state * refactor: add missing params type * refactor: add missing children prop * refactor: add missing array type * refactor: add missing React imports * refactor: use correct IProjectEnvironment type * refactor: type errors as unknown * refactor: the index prop is required * refactor: fix date prop type * refactor: fix tooltip placement prop type * refactor: fix environments state type * refactor: add missing arg types * refactor: add guard for undefined field * refactor: fix ChangePassword prop types * refactor: fix MUI import paths * refactor: add missing arg type * refactor: fix showDialog prop type * refactor: remove unused openUpdateDialog prop * refactor: add missing non-null assertion * refactor: remove unused types prop * refactor: stricten API error handler types * refactor: add missing undefined check * refactor: add missing IProject id field * refactor: fix ConditionallyRender condition prop types * refactor: remove unused args * refactor: add AddVariant prop types * refactor: add types to UIContext * refactor: fix event arg type * refactor: add missing default impressionData field * refactor: fix handleDeleteEnvironment prop args * refactor: fix IFeatureMetrics field requirements * refactor: add missing element types to ConditionallyRender * refactor: remove unused ProjectAccess projectId prop * refactor: add missing undefined check * refactor: fix getCreateTogglePath arg type * refactor: add missing IStrategyPayload import * refactor: remove unused user arg * refactor: add missing event arg type * refactor: add missing style object types * refactor: improve userApiErrors prop type * refactor: the Dialogue onClose prop is optional * refactor: fix the AddonEvents setEventValue prop type
2022-02-25 10:55:39 +01:00
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
}
};
const formatApiCode = () => {
return `curl --location --request POST '${uiConfig.unleashUrl}/api/admin/projects' \\
--header 'Authorization: INSERT_API_KEY' \\
--header 'Content-Type: application/json' \\
--data-raw '${JSON.stringify(
getCreateProjectPayload({ omitId: useNewProjectForm }),
undefined,
2,
)}'`;
};
const handleCancel = () => {
navigate(GO_BACK);
};
return (
<FormTemplate
loading={loading}
title='Create project'
description='Projects allows you to group feature flags together in the management UI.'
documentationLink='https://docs.getunleash.io/reference/projects'
documentationLinkLabel='Projects documentation'
formatApiCode={formatApiCode}
>
<ProjectForm
errors={errors}
handleSubmit={handleSubmit}
projectId={projectId}
setProjectId={setProjectId}
projectName={projectName}
projectStickiness={projectStickiness}
projectMode={projectMode}
2023-03-16 15:29:52 +01:00
setProjectMode={setProjectMode}
setProjectStickiness={setProjectStickiness}
setProjectName={setProjectName}
projectDesc={projectDesc}
setProjectDesc={setProjectDesc}
mode='Create'
clearErrors={clearErrors}
validateProjectId={validateProjectId}
>
<CreateButton
name='project'
permission={CREATE_PROJECT}
data-testid={CREATE_PROJECT_BTN}
/>
<StyledButton onClick={handleCancel}>Cancel</StyledButton>
</ProjectForm>
</FormTemplate>
);
};
export default CreateProject;