Add pagination on people
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -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 clsx from "clsx";
|
||||||
import {
|
import {
|
||||||
createContext,
|
createContext,
|
||||||
@@ -28,10 +36,17 @@ const defaultOrder = {
|
|||||||
|
|
||||||
export function SortableTable({
|
export function SortableTable({
|
||||||
refetch,
|
refetch,
|
||||||
|
hasNext,
|
||||||
|
loadNext,
|
||||||
|
isLoading,
|
||||||
...props
|
...props
|
||||||
}: ComponentProps<typeof Table> & {
|
}: ComponentProps<typeof Table> & {
|
||||||
refetch: (o: { order: Order }) => void;
|
refetch: (o: { order: Order }) => void;
|
||||||
|
hasNext: boolean;
|
||||||
|
loadNext: () => void;
|
||||||
|
isLoading: boolean;
|
||||||
}) {
|
}) {
|
||||||
|
const { __ } = useTranslate();
|
||||||
const [order, setOrder] = useState(defaultOrder);
|
const [order, setOrder] = useState(defaultOrder);
|
||||||
const onOrderChange = (o: Order) => {
|
const onOrderChange = (o: Order) => {
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
@@ -41,7 +56,20 @@ export function SortableTable({
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<SortableContext value={{ order, onOrderChange }}>
|
<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>
|
</SortableContext>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { PeopleGraphQuery } from "./__generated__/PeopleGraphQuery.graphql"
|
|||||||
import {
|
import {
|
||||||
useLazyLoadQuery,
|
useLazyLoadQuery,
|
||||||
useMutation,
|
useMutation,
|
||||||
|
usePaginationFragment,
|
||||||
usePreloadedQuery,
|
usePreloadedQuery,
|
||||||
useRefetchableFragment,
|
useRefetchableFragment,
|
||||||
type PreloadedQuery,
|
type PreloadedQuery,
|
||||||
@@ -91,15 +92,15 @@ export function usePeopleQuery(
|
|||||||
queryRef: PreloadedQuery<PeopleGraphPaginatedQuery>
|
queryRef: PreloadedQuery<PeopleGraphPaginatedQuery>
|
||||||
) {
|
) {
|
||||||
const data = usePreloadedQuery(paginatedPeopleQuery, queryRef);
|
const data = usePreloadedQuery(paginatedPeopleQuery, queryRef);
|
||||||
const [dataFragment, refetch] = useRefetchableFragment(
|
const pagination = usePaginationFragment(
|
||||||
paginatedPeopleFragment,
|
paginatedPeopleFragment,
|
||||||
data.organization as PeopleGraphPaginatedFragment$key
|
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 {
|
return {
|
||||||
|
...pagination,
|
||||||
people,
|
people,
|
||||||
refetch,
|
connectionId: pagination.data.peoples.__id,
|
||||||
connectionId: dataFragment.peoples.__id,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<e4fcd65491a7570cf56382a3f977e06d>>
|
* @generated SignedSource<<452165e3b8b1cdef4b8e62d53c8a73ed>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -58,7 +58,7 @@ return {
|
|||||||
"name": "before"
|
"name": "before"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": 50,
|
"defaultValue": 1,
|
||||||
"kind": "LocalArgument",
|
"kind": "LocalArgument",
|
||||||
"name": "first"
|
"name": "first"
|
||||||
},
|
},
|
||||||
@@ -247,6 +247,6 @@ return {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "c163b7909a337efd22088852b9908045";
|
(node as any).hash = "e1720a7dc0b7914edb8a07f63d5cf95a";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<43878b22fe8a689f41bcd506711ddb5f>>
|
* @generated SignedSource<<56d7fa0e53727e6a52fc6ab7bc805ceb>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -57,7 +57,7 @@ v4 = [
|
|||||||
{
|
{
|
||||||
"kind": "Literal",
|
"kind": "Literal",
|
||||||
"name": "first",
|
"name": "first",
|
||||||
"value": 50
|
"value": 1
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
@@ -233,7 +233,7 @@ return {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": "peoples(first:50)"
|
"storageKey": "peoples(first:1)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
@@ -256,12 +256,12 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "b154e94ac7e783a492bc5aed7d44229d",
|
"cacheID": "838b4fd1617a05fcb681c1e533cc0a9f",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "PeopleGraphPaginatedQuery",
|
"name": "PeopleGraphPaginatedQuery",
|
||||||
"operationKind": "query",
|
"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"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<bc0fdc02fb8b596386e290ae0cf0b8b8>>
|
* @generated SignedSource<<b6d154d843de3da0a803639f428f7152>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -46,7 +46,7 @@ v1 = {
|
|||||||
"name": "before"
|
"name": "before"
|
||||||
},
|
},
|
||||||
v2 = {
|
v2 = {
|
||||||
"defaultValue": 50,
|
"defaultValue": 1,
|
||||||
"kind": "LocalArgument",
|
"kind": "LocalArgument",
|
||||||
"name": "first"
|
"name": "first"
|
||||||
},
|
},
|
||||||
@@ -329,16 +329,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "a17ff68897dbcf3daa33b073bc83f1bb",
|
"cacheID": "e26cb4d1b42b5500dd12ee294ccce2e5",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "PeopleListQuery",
|
"name": "PeopleListQuery",
|
||||||
"operationKind": "query",
|
"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;
|
export default node;
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ export default function PeopleListPage({
|
|||||||
queryRef: PreloadedQuery<PeopleGraphPaginatedQuery>;
|
queryRef: PreloadedQuery<PeopleGraphPaginatedQuery>;
|
||||||
}) {
|
}) {
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
const { people, refetch, connectionId } = usePeopleQuery(queryRef);
|
const { people, refetch, connectionId, hasNext, loadNext, isLoadingNext } =
|
||||||
|
usePeopleQuery(queryRef);
|
||||||
|
|
||||||
usePageTitle(__("Members"));
|
usePageTitle(__("Members"));
|
||||||
|
|
||||||
@@ -48,7 +49,12 @@ export default function PeopleListPage({
|
|||||||
<Button icon={IconPlusLarge}>{__("Add member")}</Button>
|
<Button icon={IconPlusLarge}>{__("Add member")}</Button>
|
||||||
</CreatePeopleDialog>
|
</CreatePeopleDialog>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<SortableTable refetch={refetch}>
|
<SortableTable
|
||||||
|
refetch={refetch}
|
||||||
|
hasNext={hasNext}
|
||||||
|
loadNext={loadNext}
|
||||||
|
isLoading={isLoadingNext}
|
||||||
|
>
|
||||||
<Thead>
|
<Thead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<SortableTh field="FULL_NAME">{__("Name")}</SortableTh>
|
<SortableTh field="FULL_NAME">{__("Name")}</SortableTh>
|
||||||
|
|||||||
Reference in New Issue
Block a user