import { FC, useEffect } from "react"; import { Controller, useForm } from "react-hook-form"; import { faInfoCircle } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { zodResolver } from "@hookform/resolvers/zod"; import { useNavigate } from "@tanstack/react-router"; import z from "zod"; import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button, FormControl, Input, Modal, ModalClose, ModalContent, Select, SelectItem, TextArea } from "@app/components/v2"; import { OrgPermissionActions, OrgPermissionSubjects, useOrganization, useOrgPermission, useSubscription, useUser } from "@app/context"; import { getProjectHomePage } from "@app/helpers/project"; import { useCreateWorkspace, useGetExternalKmsList, useGetUserWorkspaces } from "@app/hooks/api"; import { INTERNAL_KMS_KEY_ID } from "@app/hooks/api/kms/types"; import { InfisicalProjectTemplate, useListProjectTemplates } from "@app/hooks/api/projectTemplates"; const formSchema = z.object({ name: z.string().trim().min(1, "Required").max(64, "Too long, maximum length is 64 characters"), description: z .string() .trim() .max(256, "Description too long, max length is 256 characters") .optional(), kmsKeyId: z.string(), template: z.string() }); type TAddProjectFormData = z.infer; interface NewProjectModalProps { isOpen: boolean; onOpenChange: (isOpen: boolean) => void; } type NewProjectFormProps = Pick; const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => { const navigate = useNavigate(); const { currentOrg } = useOrganization(); const { permission } = useOrgPermission(); const { user } = useUser(); const createWs = useCreateWorkspace(); const { refetch: refetchWorkspaces } = useGetUserWorkspaces(); const { subscription } = useSubscription(); const canReadProjectTemplates = permission.can( OrgPermissionActions.Read, OrgPermissionSubjects.ProjectTemplates ); const { data: projectTemplates = [] } = useListProjectTemplates({ enabled: Boolean(canReadProjectTemplates && subscription?.projectTemplates) }); const { data: externalKmsList } = useGetExternalKmsList(currentOrg.id, { enabled: permission.can(OrgPermissionActions.Read, OrgPermissionSubjects.Kms) }); const { control, handleSubmit, reset, formState: { isSubmitting, errors } } = useForm({ resolver: zodResolver(formSchema), defaultValues: { kmsKeyId: INTERNAL_KMS_KEY_ID, template: InfisicalProjectTemplate.Default } }); useEffect(() => { if (Object.keys(errors).length > 0) { console.log("Current form errors:", errors); } }, [errors]); const onCreateProject = async ({ name, description, kmsKeyId, template }: TAddProjectFormData) => { // type check if (!currentOrg) return; if (!user) return; try { const { data: { project } } = await createWs.mutateAsync({ projectName: name, projectDescription: description, kmsKeyId: kmsKeyId !== INTERNAL_KMS_KEY_ID ? kmsKeyId : undefined, template }); await refetchWorkspaces(); createNotification({ text: "Project created", type: "success" }); reset(); onOpenChange(false); navigate({ to: getProjectHomePage(project.defaultProduct), params: { projectId: project.id } }); } catch (err) { console.error(err); createNotification({ text: "Failed to create project", type: "error" }); } }; const onSubmit = handleSubmit((data) => { return onCreateProject(data); }); return (
( )} /> (