import { Dispatch, SetStateAction, useState } from "react"; import { faEllipsisV, faMagnifyingGlass, faPlus, faShieldHalved, faTrash, faUsers, faUserXmark, faWarning, faXmark } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { InfiniteData } from "@tanstack/react-query"; import { twMerge } from "tailwind-merge"; import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; import { createNotification } from "@app/components/notifications"; import { Badge, Button, Checkbox, DeleteActionModal, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, EmptyState, IconButton, Input, Table, TableContainer, TableSkeleton, TBody, Td, Th, THead, Tooltip, Tr } from "@app/components/v2"; import { useSubscription, useUser } from "@app/context"; import { useDebounce, usePopUp } from "@app/hooks"; import { useAdminBulkDeleteUsers, useAdminDeleteUser, useAdminGetUsers, useRemoveUserServerAdminAccess } from "@app/hooks/api"; import { User } from "@app/hooks/api/users/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; import { AddServerAdminModal } from "@app/pages/admin/AccessManagementPage/components/AddServerAdminModal"; const removeServerAdminUpgradePlanMessage = "Removing Server Admin permissions from user"; const ServerAdminsPanelTable = ({ handlePopUpOpen, users: usersPages, isPending, searchUserFilter, setSearchUserFilter, isFetchingNextPage, fetchNextPage, hasNextPage, selectedUsers, setSelectedUsers }: { handlePopUpOpen: ( popUpName: keyof UsePopUpState< ["removeUser", "upgradePlan", "addServerAdmin", "removeServerAdmin"] >, data?: { username: string; id: string; message?: string; } ) => void; isPending: boolean; users: InfiniteData | undefined; searchUserFilter: string; setSearchUserFilter: (filter: string) => void; selectedUsers: User[]; setSelectedUsers: Dispatch>; isFetchingNextPage: boolean; fetchNextPage: () => void; hasNextPage: boolean; }) => { const { subscription } = useSubscription(); const users = usersPages?.pages.flat(); const isEmpty = !isPending && !users?.length; const selectedUserIds = selectedUsers.map((user) => user.id); const isPageSelected = users?.length ? users.every((user) => selectedUserIds.includes(user.id)) : false; // eslint-disable-next-line no-nested-ternary const isPageIndeterminate = isPageSelected ? false : users?.length ? users?.some((user) => selectedUserIds.includes(user.id)) : false; return ( <>
setSearchUserFilter(e.target.value)} leftIcon={} placeholder="Search admins..." className="flex-1" />
{isPending && } {!isPending && users?.map((user) => { const { username, email, firstName, lastName, id } = user; const name = firstName || lastName ? `${firstName} ${lastName}` : null; const isSelected = selectedUserIds.includes(id); return ( ); })}
{ if (isPageSelected) { setSelectedUsers((prev) => prev.filter((u) => !users?.find((user) => user.id === u.id)) ); } else { setSelectedUsers((prev) => [ ...prev, ...(users?.filter((u) => !prev.find((user) => user.id === u.id)) ?? []) ]); } }} /> Name Username
{ e.stopPropagation(); setSelectedUsers((prev) => isSelected ? prev.filter((u) => u.id !== id) : [...prev, user] ); }} />

{name ?? Not Set}

{username || email}

{ e.stopPropagation(); handlePopUpOpen("removeUser", { username, id }); }} icon={} > Remove User
} onClick={(e) => { e.stopPropagation(); if (!subscription?.instanceUserManagement) { handlePopUpOpen("upgradePlan", { username, id, message: removeServerAdminUpgradePlanMessage }); return; } handlePopUpOpen("removeServerAdmin", { username, id }); }} > Remove Server Admin
{!isPending && isEmpty && }
{!isEmpty && ( )}
); }; export const ServerAdminsTable = () => { const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([ "removeUser", "upgradePlan", "addServerAdmin", "removeServerAdmin", "removeUsers" ] as const); const { user: { id: userId } } = useUser(); const { mutateAsync: deleteUser } = useAdminDeleteUser(); const { mutateAsync: deleteUsers } = useAdminBulkDeleteUsers(); const { mutateAsync: removeAdminAccess } = useRemoveUserServerAdminAccess(); const [selectedUsers, setSelectedUsers] = useState([]); const [searchUserFilter, setSearchUserFilter] = useState(""); const [debouncedSearchTerm] = useDebounce(searchUserFilter, 500); const { data: users, isPending, isFetchingNextPage, hasNextPage, fetchNextPage } = useAdminGetUsers({ limit: 20, searchTerm: debouncedSearchTerm, adminsOnly: true }); const handleRemoveUser = async () => { const { id } = popUp?.removeUser?.data as { id: string; username: string }; try { await deleteUser(id); createNotification({ type: "success", text: "Successfully deleted user" }); } catch { createNotification({ type: "error", text: "Error deleting user" }); } handlePopUpClose("removeUser"); }; const handleRemoveServerAdminAccess = async () => { const { id } = popUp?.removeServerAdmin?.data as { id: string; username: string }; try { await removeAdminAccess(id); createNotification({ type: "success", text: "Successfully removed server admin access from user" }); } catch { createNotification({ type: "error", text: "Error removing server admin access from user" }); } handlePopUpClose("removeServerAdmin"); }; const handleRemoveUsers = async () => { try { await deleteUsers(selectedUsers.map((user) => user.id)); createNotification({ text: "Successfully removed users", type: "success" }); setSelectedUsers([]); handlePopUpClose("removeUsers"); } catch { createNotification({ text: "Failed to remove users", type: "error" }); } }; return ( <>
0 && "h-16" )} >
{selectedUsers.length} Selected
handlePopUpToggle("removeUser", isOpen)} onDeleteApproved={handleRemoveUser} /> handlePopUpToggle("removeServerAdmin", isOpen)} deleteKey="confirm" onDeleteApproved={handleRemoveServerAdminAccess} buttonText="Remove Access" /> handlePopUpToggle("addServerAdmin", isOpen)} /> handlePopUpToggle("upgradePlan", isOpen)} text={`${popUp?.upgradePlan?.data?.message} is only available on Infisical's Pro plan and above.`} /> handlePopUpToggle("removeUsers", isOpen)} deleteKey="confirm" onDeleteApproved={() => handleRemoveUsers()} buttonText="Remove" >
The following members will be removed:
    {selectedUsers?.map((user) => { const email = user.email ?? user.username; return (
  • {user.firstName || user.lastName ? ( <> {`${`${user.firstName} ${user.lastName}`.trim()} `}( {email}) ) : ( {email} )}{" "}

    {userId === user.id && (
    Removing Yourself
    )}
  • ); })}
); };