diff --git a/components/dashboard/src/data/configurations/configuration-queries.ts b/components/dashboard/src/data/configurations/configuration-queries.ts index 00afb2236f1885..939c4d4c951ed6 100644 --- a/components/dashboard/src/data/configurations/configuration-queries.ts +++ b/components/dashboard/src/data/configurations/configuration-queries.ts @@ -4,7 +4,7 @@ * See License.AGPL.txt in the project root for license information. */ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useCurrentOrg } from "../organizations/orgs-query"; import { configurationClient } from "../../service/public-api"; import type { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb"; @@ -13,16 +13,16 @@ const BASE_KEY = "configurations"; type ListConfigurationsArgs = { pageSize: number; - token?: string; searchTerm?: string; }; -export const useListConfigurations = ({ searchTerm = "", token, pageSize }: ListConfigurationsArgs) => { +export const useListConfigurations = ({ searchTerm = "", pageSize }: ListConfigurationsArgs) => { const { data: org } = useCurrentOrg(); - return useQuery( - getListConfigurationsQueryKey(org?.id || "", { searchTerm, token, pageSize }), - async () => { + return useInfiniteQuery( + getListConfigurationsQueryKey(org?.id || "", { searchTerm, pageSize }), + // QueryFn receives the past page's pageParam as it's argument + async ({ pageParam: nextToken }) => { if (!org) { throw new Error("No org currently selected"); } @@ -30,8 +30,7 @@ export const useListConfigurations = ({ searchTerm = "", token, pageSize }: List const { configurations, pagination } = await configurationClient.listConfigurations({ organizationId: org.id, searchTerm, - // TODO: add support for nextToken - pagination: { pageSize }, + pagination: { pageSize, token: nextToken }, }); return { @@ -42,6 +41,11 @@ export const useListConfigurations = ({ searchTerm = "", token, pageSize }: List { enabled: !!org, keepPreviousData: true, + // This enables the query to know if there are nore pages, and passes the last page's nextToken to the queryFn + getNextPageParam: (lastPage) => { + // Must ensure we return undefined if there are no more pages + return lastPage.pagination?.nextToken || undefined; + }, }, ); }; diff --git a/components/dashboard/src/repositories/list/RepositoryList.tsx b/components/dashboard/src/repositories/list/RepositoryList.tsx index de3faccb4669e4..b0c25d1e38170b 100644 --- a/components/dashboard/src/repositories/list/RepositoryList.tsx +++ b/components/dashboard/src/repositories/list/RepositoryList.tsx @@ -19,6 +19,7 @@ import { useDocumentTitle } from "../../hooks/use-document-title"; import { Table, TableBody, TableHead, TableHeader, TableRow } from "@podkit/tables/Table"; import { ImportRepositoryModal } from "../create/ImportRepositoryModal"; import type { Configuration } from "@gitpod/public-api/lib/gitpod/v1/configuration_pb"; +import { LoadingButton } from "@podkit/buttons/LoadingButton"; const RepositoryListPage: FC = () => { useDocumentTitle("Imported repositories"); @@ -26,21 +27,22 @@ const RepositoryListPage: FC = () => { const history = useHistory(); // TODO: Move this state into url search params - const [nextToken, setNextToken] = useState(); + // const [nextToken, setNextToken] = useState(); const [searchTerm, setSearchTerm, debouncedSearchTerm] = useStateWithDebounce(""); // Reset to page 1 when debounced search term changes (when we perform a new search) useEffect(() => { - setNextToken(undefined); + // setNextToken(undefined); + // TODO: reset query to page 1 somehow? }, [debouncedSearchTerm]); // Have this set to a low value for now to test pagination while we develop this // TODO: move this into state and add control for changing it - const pageSize = 5; + const pageSize = 2; - const { data, isFetching, isPreviousData } = useListConfigurations({ + const { data, isFetching, isFetchingNextPage, isPreviousData, hasNextPage, fetchNextPage } = useListConfigurations({ searchTerm: debouncedSearchTerm, - token: nextToken, + // token: nextToken, pageSize, }); const [showCreateProjectModal, setShowCreateProjectModal] = useState(false); @@ -58,6 +60,7 @@ const RepositoryListPage: FC = () => { [history], ); + console.log("hasNextPage", hasNextPage, data?.pageParams); return ( <>
@@ -125,15 +128,19 @@ const RepositoryListPage: FC = () => { - {data?.configurations.map((configuration) => ( - - ))} + {data?.pages.map((page) => { + return page.configurations.map((configuration) => { + return ; + }); + })} - {data?.pagination?.nextToken && ( -
- + {hasNextPage && ( +
+ fetchNextPage()} loading={isFetchingNextPage}> + Load more +
)}