mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-11 03:28:58 +00:00
173 lines
5.2 KiB
TypeScript
173 lines
5.2 KiB
TypeScript
import { useState } from "react";
|
|
import { faMagnifyingGlass, faUsers } from "@fortawesome/free-solid-svg-icons";
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
|
|
import { createNotification } from "@app/components/notifications";
|
|
import { OrgPermissionCan } from "@app/components/permissions";
|
|
import {
|
|
Button,
|
|
EmptyState,
|
|
Input,
|
|
Modal,
|
|
ModalContent,
|
|
Pagination,
|
|
Table,
|
|
TableContainer,
|
|
TableSkeleton,
|
|
TBody,
|
|
Td,
|
|
Th,
|
|
THead,
|
|
Tr
|
|
} from "@app/components/v2";
|
|
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
|
import { useDebounce, useResetPageHelper } from "@app/hooks";
|
|
import { useAddUserToGroup, useListGroupUsers } from "@app/hooks/api";
|
|
import { EFilterReturnedUsers } from "@app/hooks/api/groups/types";
|
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
|
|
|
type Props = {
|
|
popUp: UsePopUpState<["addGroupMembers"]>;
|
|
handlePopUpToggle: (popUpName: keyof UsePopUpState<["addGroupMembers"]>, state?: boolean) => void;
|
|
};
|
|
|
|
export const AddGroupMembersModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|
const [page, setPage] = useState(1);
|
|
const [perPage, setPerPage] = useState(10);
|
|
const [searchMemberFilter, setSearchMemberFilter] = useState("");
|
|
const [debouncedSearch] = useDebounce(searchMemberFilter);
|
|
|
|
const popUpData = popUp?.addGroupMembers?.data as {
|
|
groupId: string;
|
|
slug: string;
|
|
};
|
|
|
|
const offset = (page - 1) * perPage;
|
|
const { data, isLoading } = useListGroupUsers({
|
|
id: popUpData?.groupId,
|
|
groupSlug: popUpData?.slug,
|
|
offset,
|
|
limit: perPage,
|
|
search: debouncedSearch,
|
|
filter: EFilterReturnedUsers.NON_MEMBERS
|
|
});
|
|
|
|
const { totalCount = 0 } = data ?? {};
|
|
|
|
useResetPageHelper({
|
|
totalCount,
|
|
offset,
|
|
setPage
|
|
});
|
|
|
|
const { mutateAsync: addUserToGroupMutateAsync } = useAddUserToGroup();
|
|
|
|
const handleAddMember = async (username: string) => {
|
|
try {
|
|
if (!popUpData?.slug) {
|
|
createNotification({
|
|
text: "Some data is missing, please refresh the page and try again",
|
|
type: "error"
|
|
});
|
|
return;
|
|
}
|
|
|
|
await addUserToGroupMutateAsync({
|
|
groupId: popUpData.groupId,
|
|
username,
|
|
slug: popUpData.slug
|
|
});
|
|
|
|
createNotification({
|
|
text: "Successfully assigned user to the group",
|
|
type: "success"
|
|
});
|
|
} catch (err) {
|
|
createNotification({
|
|
text: "Failed to assign user to the group",
|
|
type: "error"
|
|
});
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Modal
|
|
isOpen={popUp?.addGroupMembers?.isOpen}
|
|
onOpenChange={(isOpen) => {
|
|
handlePopUpToggle("addGroupMembers", isOpen);
|
|
}}
|
|
>
|
|
<ModalContent title="Add Group Members">
|
|
<Input
|
|
value={searchMemberFilter}
|
|
onChange={(e) => setSearchMemberFilter(e.target.value)}
|
|
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
|
placeholder="Search members..."
|
|
/>
|
|
<TableContainer className="mt-4">
|
|
<Table>
|
|
<THead>
|
|
<Tr>
|
|
<Th>User</Th>
|
|
<Th />
|
|
</Tr>
|
|
</THead>
|
|
<TBody>
|
|
{isLoading && <TableSkeleton columns={2} innerKey="group-users" />}
|
|
{!isLoading &&
|
|
data?.users?.map(({ id, firstName, lastName, username }) => {
|
|
return (
|
|
<Tr className="items-center" key={`group-user-${id}`}>
|
|
<Td>
|
|
<p>{`${firstName ?? "-"} ${lastName ?? ""}`}</p>
|
|
<p>{username}</p>
|
|
</Td>
|
|
<Td className="flex justify-end">
|
|
<OrgPermissionCan
|
|
I={OrgPermissionActions.Edit}
|
|
a={OrgPermissionSubjects.Groups}
|
|
>
|
|
{(isAllowed) => {
|
|
return (
|
|
<Button
|
|
isLoading={isLoading}
|
|
isDisabled={!isAllowed}
|
|
colorSchema="primary"
|
|
variant="outline_bg"
|
|
type="submit"
|
|
onClick={() => handleAddMember(username)}
|
|
>
|
|
Assign
|
|
</Button>
|
|
);
|
|
}}
|
|
</OrgPermissionCan>
|
|
</Td>
|
|
</Tr>
|
|
);
|
|
})}
|
|
</TBody>
|
|
</Table>
|
|
{!isLoading && totalCount > 0 && (
|
|
<Pagination
|
|
count={totalCount}
|
|
page={page}
|
|
perPage={perPage}
|
|
onChangePage={(newPage) => setPage(newPage)}
|
|
onChangePerPage={(newPerPage) => setPerPage(newPerPage)}
|
|
/>
|
|
)}
|
|
{!isLoading && !data?.users?.length && (
|
|
<EmptyState
|
|
title={
|
|
debouncedSearch ? "No users match search" : "All users are already in the group"
|
|
}
|
|
icon={faUsers}
|
|
/>
|
|
)}
|
|
</TableContainer>
|
|
</ModalContent>
|
|
</Modal>
|
|
);
|
|
};
|