import { Helmet } from "react-helmet"; import { useTranslation } from "react-i18next"; import { faChevronLeft } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Link, useNavigate, useParams } from "@tanstack/react-router"; import { formatRelative } from "date-fns"; import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; import { Button, ConfirmActionModal, DeleteActionModal, EmptyState, PageHeader, Spinner } from "@app/components/v2"; import { ProjectPermissionActions, ProjectPermissionMemberActions, ProjectPermissionSub, useOrganization, useProject } from "@app/context"; import { getProjectBaseURL, getProjectHomePage } from "@app/helpers/project"; import { usePopUp } from "@app/hooks"; import { useAssumeProjectPrivileges, useDeleteUserFromWorkspace, useGetWorkspaceUserDetails } from "@app/hooks/api"; import { ActorType } from "@app/hooks/api/auditLogs/enums"; import { ProjectAccessControlTabs } from "@app/types/project"; import { MemberProjectAdditionalPrivilegeSection } from "./components/MemberProjectAdditionalPrivilegeSection"; import { MemberRoleDetailsSection } from "./components/MemberRoleDetailsSection"; export const Page = () => { const navigate = useNavigate(); const membershipId = useParams({ strict: false, select: (el) => el.membershipId as string }); const { currentOrg, isSubOrganization } = useOrganization(); const { currentProject, projectId } = useProject(); const { data: membershipDetails, isPending: isMembershipDetailsLoading } = useGetWorkspaceUserDetails(projectId, membershipId); const { mutateAsync: removeUserFromWorkspace, isPending: isRemovingUserFromWorkspace } = useDeleteUserFromWorkspace(); const assumePrivileges = useAssumeProjectPrivileges(); const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([ "removeMember", "upgradePlan", "assumePrivileges" ] as const); const handleAssumePrivileges = async () => { const { userId } = popUp?.assumePrivileges?.data as { userId: string }; assumePrivileges.mutate( { actorId: userId, actorType: ActorType.USER, projectId }, { onSuccess: () => { createNotification({ type: "success", text: "User privilege assumption has started" }); const url = `${getProjectHomePage(currentProject.type, currentProject.environments)}${isSubOrganization ? `?subOrganization=${currentOrg.slug}` : ""}`; window.location.assign( url.replace("$orgId", currentOrg.id).replace("$projectId", currentProject.id) ); } } ); }; const handleRemoveUser = async () => { if (!currentOrg?.id || !currentProject?.id || !membershipDetails?.user?.username) return; await removeUserFromWorkspace({ projectId, usernames: [membershipDetails?.user?.username], orgId: currentOrg.id }); createNotification({ text: "Successfully removed user from project", type: "success" }); navigate({ to: `${getProjectBaseURL(currentProject.type)}/access-management` as const, params: { projectId: currentProject.id, orgId: currentOrg.id } }); handlePopUpClose("removeMember"); }; if (isMembershipDetailsLoading) { return (
); } return (
{membershipDetails ? ( <> Project Users {(isAllowed) => ( )} {(isAllowed) => ( )} handlePopUpOpen("upgradePlan", { text: "Assigning custom roles to members can be unlocked if you upgrade to Infisical Pro plan." }) } /> handlePopUpToggle("removeMember", isOpen)} onDeleteApproved={handleRemoveUser} /> handlePopUpToggle("assumePrivileges", isOpen)} onConfirmed={handleAssumePrivileges} buttonText="Confirm" /> handlePopUpToggle("upgradePlan", isOpen)} text={popUp.upgradePlan?.data?.text} /> ) : ( )}
); }; export const MemberDetailsByIDPage = () => { const { t } = useTranslation(); return ( <> {t("common.head-title", { title: t("settings.members.title") })} ); };