diff --git a/site/src/api/api.ts b/site/src/api/api.ts index 966c8902c3e73..7bad235d6bf25 100644 --- a/site/src/api/api.ts +++ b/site/src/api/api.ts @@ -1187,9 +1187,9 @@ class ApiMethods { }; getWorkspaces = async ( - options: TypesGen.WorkspacesRequest, + req: TypesGen.WorkspacesRequest, ): Promise => { - const url = getURLWithSearchParams("/api/v2/workspaces", options); + const url = getURLWithSearchParams("/api/v2/workspaces", req); const response = await this.axios.get(url); return response.data; }; diff --git a/site/src/api/queries/workspaces.ts b/site/src/api/queries/workspaces.ts index bcfb07b75452b..1c3e82a8816c2 100644 --- a/site/src/api/queries/workspaces.ts +++ b/site/src/api/queries/workspaces.ts @@ -139,15 +139,14 @@ async function findMatchWorkspace(q: string): Promise { } } -function workspacesKey(config: WorkspacesRequest = {}) { - const { q, limit } = config; - return ["workspaces", { q, limit }] as const; +function workspacesKey(req: WorkspacesRequest = {}) { + return ["workspaces", req] as const; } -export function workspaces(config: WorkspacesRequest = {}) { +export function workspaces(req: WorkspacesRequest = {}) { return { - queryKey: workspacesKey(config), - queryFn: () => API.getWorkspaces(config), + queryKey: workspacesKey(req), + queryFn: () => API.getWorkspaces(req), } as const satisfies QueryOptions; } diff --git a/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx b/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx index 988e9a5385098..b80da553de6d6 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx @@ -305,6 +305,67 @@ describe("WorkspacesPage", () => { MockStoppedWorkspace.latest_build.template_version_id, ); }); + + it("correctly handles pagination by including pagination parameters in query key", async () => { + const totalWorkspaces = 50; + const workspacesPage1 = Array.from({ length: 25 }, (_, i) => ({ + ...MockWorkspace, + id: `page1-workspace-${i}`, + name: `page1-workspace-${i}`, + })); + const workspacesPage2 = Array.from({ length: 25 }, (_, i) => ({ + ...MockWorkspace, + id: `page2-workspace-${i}`, + name: `page2-workspace-${i}`, + })); + + const getWorkspacesSpy = jest.spyOn(API, "getWorkspaces"); + + getWorkspacesSpy.mockImplementation(({ offset }) => { + switch (offset) { + case 0: + return Promise.resolve({ + workspaces: workspacesPage1, + count: totalWorkspaces, + }); + case 25: + return Promise.resolve({ + workspaces: workspacesPage2, + count: totalWorkspaces, + }); + default: + return Promise.reject(new Error("Unexpected offset")); + } + }); + + const user = userEvent.setup(); + renderWithAuth(); + + await waitFor(() => { + expect(screen.getByText("page1-workspace-0")).toBeInTheDocument(); + }); + + expect(getWorkspacesSpy).toHaveBeenLastCalledWith({ + q: "owner:me", + offset: 0, + limit: 25, + }); + + const nextPageButton = screen.getByRole("button", { name: /next page/i }); + await user.click(nextPageButton); + + await waitFor(() => { + expect(screen.getByText("page2-workspace-0")).toBeInTheDocument(); + }); + + expect(getWorkspacesSpy).toHaveBeenLastCalledWith({ + q: "owner:me", + offset: 25, + limit: 25, + }); + + expect(screen.queryByText("page1-workspace-0")).not.toBeInTheDocument(); + }); }); const getWorkspaceCheckbox = (workspace: Workspace) => { diff --git a/site/src/pages/WorkspacesPage/WorkspacesPage.tsx b/site/src/pages/WorkspacesPage/WorkspacesPage.tsx index 62ed7bfed7fe4..0488fc0730e5d 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPage.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPage.tsx @@ -116,7 +116,8 @@ const WorkspacesPage: FC = () => { }); const workspacesQueryOptions = workspaces({ - ...pagination, + limit: pagination.limit, + offset: pagination.offset, q: filterState.filter.query, }); const { data, error, refetch } = useQuery({ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy