Add pagination on people

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Jonathan
2025-06-17 17:14:03 +02:00
committed by Bryan Frimin
parent ab54d13b87
commit fdc2b107a3
6 changed files with 56 additions and 21 deletions

View File

@@ -1,4 +1,12 @@
import { IconChevronTriangleDownSmall, Table, Th } from "@probo/ui";
import { useTranslate } from "@probo/i18n";
import {
Button,
IconChevronDown,
IconChevronTriangleDownSmall,
Spinner,
Table,
Th,
} from "@probo/ui";
import clsx from "clsx";
import {
createContext,
@@ -28,10 +36,17 @@ const defaultOrder = {
export function SortableTable({
refetch,
hasNext,
loadNext,
isLoading,
...props
}: ComponentProps<typeof Table> & {
refetch: (o: { order: Order }) => void;
hasNext: boolean;
loadNext: () => void;
isLoading: boolean;
}) {
const { __ } = useTranslate();
const [order, setOrder] = useState(defaultOrder);
const onOrderChange = (o: Order) => {
startTransition(() => {
@@ -41,7 +56,20 @@ export function SortableTable({
};
return (
<SortableContext value={{ order, onOrderChange }}>
<Table {...props} />
<div className="space-y-4">
<Table {...props} />
{hasNext && (
<Button
variant="tertiary"
onClick={() => loadNext()}
className="mt-3 mx-auto"
disabled={isLoading}
icon={isLoading ? Spinner : IconChevronDown}
>
{__("Show more")}
</Button>
)}
</div>
</SortableContext>
);
}

View File

@@ -3,6 +3,7 @@ import type { PeopleGraphQuery } from "./__generated__/PeopleGraphQuery.graphql"
import {
useLazyLoadQuery,
useMutation,
usePaginationFragment,
usePreloadedQuery,
useRefetchableFragment,
type PreloadedQuery,
@@ -91,15 +92,15 @@ export function usePeopleQuery(
queryRef: PreloadedQuery<PeopleGraphPaginatedQuery>
) {
const data = usePreloadedQuery(paginatedPeopleQuery, queryRef);
const [dataFragment, refetch] = useRefetchableFragment(
const pagination = usePaginationFragment(
paginatedPeopleFragment,
data.organization as PeopleGraphPaginatedFragment$key
);
const people = dataFragment?.peoples?.edges.map((edge) => edge.node);
const people = pagination.data.peoples?.edges.map((edge) => edge.node);
return {
...pagination,
people,
refetch,
connectionId: dataFragment.peoples.__id,
connectionId: pagination.data.peoples.__id,
};
}

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<e4fcd65491a7570cf56382a3f977e06d>>
* @generated SignedSource<<452165e3b8b1cdef4b8e62d53c8a73ed>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -58,7 +58,7 @@ return {
"name": "before"
},
{
"defaultValue": 50,
"defaultValue": 1,
"kind": "LocalArgument",
"name": "first"
},
@@ -247,6 +247,6 @@ return {
};
})();
(node as any).hash = "c163b7909a337efd22088852b9908045";
(node as any).hash = "e1720a7dc0b7914edb8a07f63d5cf95a";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<43878b22fe8a689f41bcd506711ddb5f>>
* @generated SignedSource<<56d7fa0e53727e6a52fc6ab7bc805ceb>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -57,7 +57,7 @@ v4 = [
{
"kind": "Literal",
"name": "first",
"value": 50
"value": 1
}
];
return {
@@ -233,7 +233,7 @@ return {
]
}
],
"storageKey": "peoples(first:50)"
"storageKey": "peoples(first:1)"
},
{
"alias": null,
@@ -256,12 +256,12 @@ return {
]
},
"params": {
"cacheID": "b154e94ac7e783a492bc5aed7d44229d",
"cacheID": "838b4fd1617a05fcb681c1e533cc0a9f",
"id": null,
"metadata": {},
"name": "PeopleGraphPaginatedQuery",
"operationKind": "query",
"text": "query PeopleGraphPaginatedQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n ...PeopleGraphPaginatedFragment\n }\n id\n }\n}\n\nfragment PeopleGraphPaginatedFragment on Organization {\n peoples(first: 50) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n kind\n additionalEmailAddresses\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
"text": "query PeopleGraphPaginatedQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n ...PeopleGraphPaginatedFragment\n }\n id\n }\n}\n\nfragment PeopleGraphPaginatedFragment on Organization {\n peoples(first: 1) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n kind\n additionalEmailAddresses\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
}
};
})();

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<bc0fdc02fb8b596386e290ae0cf0b8b8>>
* @generated SignedSource<<b6d154d843de3da0a803639f428f7152>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -46,7 +46,7 @@ v1 = {
"name": "before"
},
v2 = {
"defaultValue": 50,
"defaultValue": 1,
"kind": "LocalArgument",
"name": "first"
},
@@ -329,16 +329,16 @@ return {
]
},
"params": {
"cacheID": "a17ff68897dbcf3daa33b073bc83f1bb",
"cacheID": "e26cb4d1b42b5500dd12ee294ccce2e5",
"id": null,
"metadata": {},
"name": "PeopleListQuery",
"operationKind": "query",
"text": "query PeopleListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 50\n $last: Int = null\n $order: PeopleOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...PeopleGraphPaginatedFragment_16fISc\n id\n }\n}\n\nfragment PeopleGraphPaginatedFragment_16fISc on Organization {\n peoples(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n kind\n additionalEmailAddresses\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
"text": "query PeopleListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 1\n $last: Int = null\n $order: PeopleOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...PeopleGraphPaginatedFragment_16fISc\n id\n }\n}\n\nfragment PeopleGraphPaginatedFragment_16fISc on Organization {\n peoples(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n kind\n additionalEmailAddresses\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
}
};
})();
(node as any).hash = "c163b7909a337efd22088852b9908045";
(node as any).hash = "e1720a7dc0b7914edb8a07f63d5cf95a";
export default node;

View File

@@ -32,7 +32,8 @@ export default function PeopleListPage({
queryRef: PreloadedQuery<PeopleGraphPaginatedQuery>;
}) {
const { __ } = useTranslate();
const { people, refetch, connectionId } = usePeopleQuery(queryRef);
const { people, refetch, connectionId, hasNext, loadNext, isLoadingNext } =
usePeopleQuery(queryRef);
usePageTitle(__("Members"));
@@ -48,7 +49,12 @@ export default function PeopleListPage({
<Button icon={IconPlusLarge}>{__("Add member")}</Button>
</CreatePeopleDialog>
</PageHeader>
<SortableTable refetch={refetch}>
<SortableTable
refetch={refetch}
hasNext={hasNext}
loadNext={loadNext}
isLoading={isLoadingNext}
>
<Thead>
<Tr>
<SortableTh field="FULL_NAME">{__("Name")}</SortableTh>