improvement: user groups table pagination

This commit is contained in:
Scott Wilson
2024-11-28 14:10:45 -08:00
parent 8afa65c272
commit 4293665130
@@ -1,6 +1,27 @@
import { faFolder } from "@fortawesome/free-solid-svg-icons"; import { useMemo } from "react";
import {
faArrowDown,
faArrowUp,
faMagnifyingGlass,
faSearch,
faUser
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { EmptyState, Table, TableContainer, TBody, Th, THead, Tr } from "@app/components/v2"; import {
EmptyState,
IconButton,
Input,
Pagination,
Table,
TableContainer,
TBody,
Th,
THead,
Tr
} from "@app/components/v2";
import { usePagination, useResetPageHelper } from "@app/hooks";
import { OrderByDirection } from "@app/hooks/api/generic/types";
import { OrgUser } from "@app/hooks/api/types"; import { OrgUser } from "@app/hooks/api/types";
import { useListUserGroupMemberships } from "@app/hooks/api/users/queries"; import { useListUserGroupMemberships } from "@app/hooks/api/users/queries";
import { UsePopUpState } from "@app/hooks/usePopUp"; import { UsePopUpState } from "@app/hooks/usePopUp";
@@ -12,31 +33,105 @@ type Props = {
handlePopUpOpen: (popUpName: keyof UsePopUpState<["removeUserFromGroup"]>, data?: {}) => void; handlePopUpOpen: (popUpName: keyof UsePopUpState<["removeUserFromGroup"]>, data?: {}) => void;
}; };
export const UserGroupsTable = ({ handlePopUpOpen, orgMembership }: Props) => { enum UserGroupsOrderBy {
const { data: groups, isLoading } = useListUserGroupMemberships(orgMembership.user.username); Name = "name"
}
export const UserGroupsTable = ({ handlePopUpOpen, orgMembership }: Props) => {
const { data: groupMemberships = [], isLoading } = useListUserGroupMemberships(
orgMembership.user.username
);
const {
search,
setSearch,
setPage,
page,
perPage,
setPerPage,
offset,
orderDirection,
toggleOrderDirection
} = usePagination(UserGroupsOrderBy.Name, { initPerPage: 10 });
const filteredGroupMemberships = useMemo(
() =>
groupMemberships
?.filter((group) => group.name.toLowerCase().includes(search.trim().toLowerCase()))
.sort((a, b) => {
const [membershipOne, membershipTwo] =
orderDirection === OrderByDirection.ASC ? [a, b] : [b, a];
return membershipOne.name.toLowerCase().localeCompare(membershipTwo.name.toLowerCase());
}),
[groupMemberships, orderDirection, search]
);
useResetPageHelper({
totalCount: filteredGroupMemberships.length,
offset,
setPage
});
return ( return (
<TableContainer> <div>
<Table> <Input
<THead> value={search}
<Tr> onChange={(e) => setSearch(e.target.value)}
<Th>Name</Th> leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
<Th className="w-5" /> placeholder="Search projects..."
</Tr> />
</THead> <TableContainer className="mt-4">
<TBody> <Table>
{groups?.map((group) => ( <THead>
<UserGroupsRow <Tr>
key={`user-group-${group.id}`} <Th className="w-full">
group={group} <div className="flex items-center">
handlePopUpOpen={handlePopUpOpen} Name
/> <IconButton
))} variant="plain"
</TBody> className="ml-2"
</Table> ariaLabel="sort"
{!isLoading && !groups?.length && ( onClick={toggleOrderDirection}
<EmptyState title="This user has not been assigned to any groups" icon={faFolder} /> >
)} <FontAwesomeIcon
</TableContainer> icon={orderDirection === OrderByDirection.DESC ? faArrowUp : faArrowDown}
/>
</IconButton>
</div>
</Th>
<Th className="w-5" />
</Tr>
</THead>
<TBody>
{filteredGroupMemberships.slice(offset, perPage * page).map((group) => (
<UserGroupsRow
key={`user-group-${group.id}`}
group={group}
handlePopUpOpen={handlePopUpOpen}
/>
))}
</TBody>
</Table>
{Boolean(filteredGroupMemberships.length) && (
<Pagination
count={filteredGroupMemberships.length}
page={page}
perPage={perPage}
onChangePage={setPage}
onChangePerPage={setPerPage}
/>
)}
{!isLoading && !filteredGroupMemberships?.length && (
<EmptyState
title={
groupMemberships.length
? "No groups match search..."
: "This user has not been assigned to any groups"
}
icon={groupMemberships.length ? faSearch : faUser}
/>
)}
</TableContainer>
</div>
); );
}; };