diff --git a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/IdentityTab.tsx b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/IdentityTab.tsx index 9d0adf893..356bce379 100644 --- a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/IdentityTab.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/IdentityTab.tsx @@ -1,18 +1,19 @@ +import { useState } from "react"; import { subject } from "@casl/ability"; import { faArrowDown, faArrowUp, - faChevronDown, faCircleXmark, faClock, faEllipsisV, - faLink, faMagnifyingGlass, faPlus, faServer } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useNavigate } from "@tanstack/react-router"; +import { AnimatePresence, motion } from "framer-motion"; +import { LinkIcon, PlusIcon } from "lucide-react"; import { twMerge } from "tailwind-merge"; import { createNotification } from "@app/components/notifications"; @@ -30,6 +31,8 @@ import { HoverCardTrigger, IconButton, Input, + Modal, + ModalContent, Pagination, Spinner, Table, @@ -79,12 +82,20 @@ import { ProjectLinkIdentityModal } from "./components/ProjectLinkIdentityModal" const MAX_ROLES_TO_BE_SHOWN_IN_TABLE = 2; +enum WizardSteps { + SelectAction = "select-action", + LinkIdentity = "link-identity", + ProjectIdentity = "project-identity" +} + export const IdentityTab = withProjectPermission( () => { const { currentProject, projectId } = useProject(); const navigate = useNavigate(); const { isSubOrganization, currentOrg } = useOrganization(); + const [wizardStep, setWizardStep] = useState(WizardSteps.SelectAction); + const { offset, limit, @@ -133,7 +144,6 @@ export const IdentityTab = withProjectPermission( const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([ "createIdentity", - "linkIdentity", "deleteIdentity", "upgradePlan", "addOptions" @@ -201,37 +211,6 @@ export const IdentityTab = withProjectPermission( )} - handlePopUpToggle("addOptions", isOpen)} - > - - - - - - {(isAllowed) => ( - - )} - - - )} - handlePopUpToggle("createIdentity", isOpen)} - /> - + onOpenChange={(open) => { + handlePopUpToggle("createIdentity", open); + if (!open) setWizardStep(WizardSteps.SelectAction); + }} + > + + + {wizardStep === WizardSteps.SelectAction && ( + +
setWizardStep(WizardSteps.ProjectIdentity)} + onKeyDown={(e) => { + if (e.key === "Enter") { + setWizardStep(WizardSteps.ProjectIdentity); + } + }} + > +
+ +
Create New Identity
+
+
+ Create a new machine identity specifically for this project. This identity + will be managed at the project-level. +
+
+
setWizardStep(WizardSteps.LinkIdentity)} + onKeyDown={(e) => { + if (e.key === "Enter") { + setWizardStep(WizardSteps.LinkIdentity); + } + }} + > +
+ +
Assign Existing Identity
+
+
+ Assign an existing identity from your organization or namespace to this + project. The identity will continue to be managed at its original scope. +
+
+
+ )} + {wizardStep === WizardSteps.ProjectIdentity && ( + + handlePopUpClose("createIdentity")} /> + + )} + {wizardStep === WizardSteps.LinkIdentity && ( + + + + )} +
+
+ { +export const ProjectIdentityModal = ({ onClose, identity }: ContentProps) => { const navigate = useNavigate(); const { currentProject } = useProject(); @@ -289,22 +287,3 @@ const Content = ({ onClose, identity }: ContentProps) => { ); }; - -type Props = { - isOpen: boolean; - onOpenChange: (isOpen: boolean) => void; - identity?: TProjectIdentity; -}; - -export const ProjectIdentityModal = ({ isOpen, onOpenChange, identity }: Props) => { - return ( - onOpenChange(open)}> - - onOpenChange(false)} /> - - - ); -}; diff --git a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectLinkIdentityModal.tsx b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectLinkIdentityModal.tsx index 1738c1ec3..20629d46d 100644 --- a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectLinkIdentityModal.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectLinkIdentityModal.tsx @@ -5,15 +5,7 @@ import { useQuery } from "@tanstack/react-query"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; -import { - Button, - FilterableSelect, - FormControl, - Modal, - ModalClose, - ModalContent, - Spinner -} from "@app/components/v2"; +import { Button, FilterableSelect, FormControl, ModalClose, Spinner } from "@app/components/v2"; import { useProject } from "@app/context"; import { projectIdentityMembershipQuery, @@ -34,11 +26,10 @@ const schema = z.object({ export type FormData = z.infer; type Props = { - popUp: UsePopUpState<["linkIdentity"]>; - handlePopUpToggle: (popUpName: keyof UsePopUpState<["linkIdentity"]>, state?: boolean) => void; + handlePopUpToggle: (popUpName: keyof UsePopUpState<["createIdentity"]>, state?: boolean) => void; }; -const Content = ({ popUp, handlePopUpToggle }: Props) => { +export const ProjectLinkIdentityModal = ({ handlePopUpToggle }: Props) => { const { projectId } = useProject(); // const [searchValue, setSearchValue] = useState(""); @@ -107,7 +98,7 @@ const Content = ({ popUp, handlePopUpToggle }: Props) => { id: nextAvailableMembership?.id } }); - handlePopUpToggle("linkIdentity", false); + handlePopUpToggle("createIdentity", false); }; if (isMembershipsLoading || isRolesLoading) @@ -168,7 +159,7 @@ const Content = ({ popUp, handlePopUpToggle }: Props) => { isLoading={isSubmitting} isDisabled={isSubmitting} > - {popUp?.linkIdentity?.data ? "Update" : "Link"} + Link