diff --git a/apps/console/src/pages/PeopleListPage.tsx b/apps/console/src/pages/PeopleListPage.tsx index 08762da31..38c94a3b3 100644 --- a/apps/console/src/pages/PeopleListPage.tsx +++ b/apps/console/src/pages/PeopleListPage.tsx @@ -1,22 +1,26 @@ -import { Suspense, useEffect } from "react"; +import { Suspense, useEffect, useTransition } from "react"; import { graphql, PreloadedQuery, usePreloadedQuery, useQueryLoader, } from "react-relay"; +import { useSearchParams } from "react-router"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; import { CircleUser, Globe, Shield } from "lucide-react"; +import { Button } from "@/components/ui/button"; import { Helmet } from "react-helmet-async"; import type { PeopleListPageQuery as PeopleListPageQueryType } from "./__generated__/PeopleListPageQuery.graphql"; +const ITEMS_PER_PAGE = 20; + const PeopleListPageQuery = graphql` - query PeopleListPageQuery { + query PeopleListPageQuery($first: Int, $after: CursorKey, $last: Int, $before: CursorKey) { node(id: "AZSfP_xAcAC5IAAAAAAltA") { id ... on Organization { - peoples { + peoples(first: $first, after: $after, last: $last, before: $before) { edges { node { id @@ -26,6 +30,13 @@ const PeopleListPageQuery = graphql` createdAt updatedAt } + cursor + } + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor } } } @@ -35,11 +46,31 @@ const PeopleListPageQuery = graphql` function PeopleListPageContent({ queryRef, + onPageChange, }: { queryRef: PreloadedQuery; + onPageChange: (params: { first?: number; after?: string; last?: number; before?: string }) => void; }) { const data = usePreloadedQuery(PeopleListPageQuery, queryRef); const peoples = data.node.peoples?.edges.map(edge => edge?.node) ?? []; + const pageInfo = data.node.peoples?.pageInfo; + const [isPending, startTransition] = useTransition(); + + const handlePageChange = (direction: 'prev' | 'next') => { + startTransition(() => { + if (direction === 'prev') { + onPageChange({ + last: ITEMS_PER_PAGE, + before: pageInfo?.startCursor, + }); + } else { + onPageChange({ + first: ITEMS_PER_PAGE, + after: pageInfo?.endCursor, + }); + } + }); + }; return (
@@ -79,6 +110,23 @@ function PeopleListPageContent({
))} + +
+ + +
); @@ -121,11 +169,32 @@ function PeopleListPageFallback() { } export default function PeopleListPage() { + const [searchParams] = useSearchParams(); const [queryRef, loadQuery] = useQueryLoader(PeopleListPageQuery); useEffect(() => { - loadQuery({}); - }, [loadQuery]); + const after = searchParams.get('after'); + const before = searchParams.get('before'); + + loadQuery({ + first: before ? undefined : ITEMS_PER_PAGE, + after: after || undefined, + last: before ? ITEMS_PER_PAGE : undefined, + before: before || undefined, + }); + }, [loadQuery, searchParams]); + + const handlePageChange = ({ first, after, last, before }: { first?: number; after?: string; last?: number; before?: string }) => { + loadQuery( + { + first, + after, + last, + before, + }, + { fetchPolicy: 'network-only' } + ); + }; if (!queryRef) { return ; @@ -137,8 +206,8 @@ export default function PeopleListPage() { People - Probo Console }> - - + + ); } \ No newline at end of file diff --git a/apps/console/src/pages/__generated__/PeopleListPageQuery.graphql.ts b/apps/console/src/pages/__generated__/PeopleListPageQuery.graphql.ts index 9f1f162b1..932d38d7e 100644 --- a/apps/console/src/pages/__generated__/PeopleListPageQuery.graphql.ts +++ b/apps/console/src/pages/__generated__/PeopleListPageQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<2ba907db688f627158201c0998785612>> + * @generated SignedSource<<2b0f0d83fcebe25d4dfe1209c757c792>> * @lightSyntaxTransform * @nogrep */ @@ -9,12 +9,18 @@ // @ts-nocheck import { ConcreteRequest } from 'relay-runtime'; -export type PeopleListPageQuery$variables = Record; +export type PeopleListPageQuery$variables = { + after?: any | null | undefined; + before?: any | null | undefined; + first?: number | null | undefined; + last?: number | null | undefined; +}; export type PeopleListPageQuery$data = { readonly node: { readonly id: string; readonly peoples?: { readonly edges: ReadonlyArray<{ + readonly cursor: any; readonly node: { readonly additionalEmailAddresses: ReadonlyArray; readonly createdAt: any; @@ -24,6 +30,12 @@ export type PeopleListPageQuery$data = { readonly updatedAt: any; }; }>; + readonly pageInfo: { + readonly endCursor: any | null | undefined; + readonly hasNextPage: boolean; + readonly hasPreviousPage: boolean; + readonly startCursor: any | null | undefined; + }; }; }; }; @@ -33,26 +45,67 @@ export type PeopleListPageQuery = { }; const node: ConcreteRequest = (function(){ -var v0 = [ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "after" +}, +v1 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "before" +}, +v2 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "first" +}, +v3 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "last" +}, +v4 = [ { "kind": "Literal", "name": "id", "value": "AZSfP_xAcAC5IAAAAAAltA" } ], -v1 = { +v5 = { "alias": null, "args": null, "kind": "ScalarField", "name": "id", "storageKey": null }, -v2 = { +v6 = { "kind": "InlineFragment", "selections": [ { "alias": null, - "args": null, + "args": [ + { + "kind": "Variable", + "name": "after", + "variableName": "after" + }, + { + "kind": "Variable", + "name": "before", + "variableName": "before" + }, + { + "kind": "Variable", + "name": "first", + "variableName": "first" + }, + { + "kind": "Variable", + "name": "last", + "variableName": "last" + } + ], "concreteType": "PeopleConnection", "kind": "LinkedField", "name": "peoples", @@ -74,7 +127,7 @@ v2 = { "name": "node", "plural": false, "selections": [ - (v1/*: any*/), + (v5/*: any*/), { "alias": null, "args": null, @@ -112,6 +165,52 @@ v2 = { } ], "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "cursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "PageInfo", + "kind": "LinkedField", + "name": "pageInfo", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasNextPage", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasPreviousPage", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "startCursor", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "endCursor", + "storageKey": null } ], "storageKey": null @@ -125,21 +224,26 @@ v2 = { }; return { "fragment": { - "argumentDefinitions": [], + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/), + (v2/*: any*/), + (v3/*: any*/) + ], "kind": "Fragment", "metadata": null, "name": "PeopleListPageQuery", "selections": [ { "alias": null, - "args": (v0/*: any*/), + "args": (v4/*: any*/), "concreteType": null, "kind": "LinkedField", "name": "node", "plural": false, "selections": [ - (v1/*: any*/), - (v2/*: any*/) + (v5/*: any*/), + (v6/*: any*/) ], "storageKey": "node(id:\"AZSfP_xAcAC5IAAAAAAltA\")" } @@ -149,13 +253,18 @@ return { }, "kind": "Request", "operation": { - "argumentDefinitions": [], + "argumentDefinitions": [ + (v2/*: any*/), + (v0/*: any*/), + (v3/*: any*/), + (v1/*: any*/) + ], "kind": "Operation", "name": "PeopleListPageQuery", "selections": [ { "alias": null, - "args": (v0/*: any*/), + "args": (v4/*: any*/), "concreteType": null, "kind": "LinkedField", "name": "node", @@ -168,24 +277,24 @@ return { "name": "__typename", "storageKey": null }, - (v1/*: any*/), - (v2/*: any*/) + (v5/*: any*/), + (v6/*: any*/) ], "storageKey": "node(id:\"AZSfP_xAcAC5IAAAAAAltA\")" } ] }, "params": { - "cacheID": "ce78c7ac266c38015ae2d44366f19579", + "cacheID": "0074149682b4e4a31aa559fe8431d567", "id": null, "metadata": {}, "name": "PeopleListPageQuery", "operationKind": "query", - "text": "query PeopleListPageQuery {\n node(id: \"AZSfP_xAcAC5IAAAAAAltA\") {\n __typename\n id\n ... on Organization {\n peoples {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n createdAt\n updatedAt\n }\n }\n }\n }\n }\n}\n" + "text": "query PeopleListPageQuery(\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n node(id: \"AZSfP_xAcAC5IAAAAAAltA\") {\n __typename\n id\n ... on Organization {\n peoples(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n createdAt\n updatedAt\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n}\n" } }; })(); -(node as any).hash = "a3892026d3bf2753f6d1ff00ddf0526c"; +(node as any).hash = "5ca962add045876503cb7290d20b9f8b"; export default node;