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 (