diff --git a/packages/server/src/api/controllers/row/views.ts b/packages/server/src/api/controllers/row/views.ts index 9ac052c1e9..204cb6b4bc 100644 --- a/packages/server/src/api/controllers/row/views.ts +++ b/packages/server/src/api/controllers/row/views.ts @@ -33,13 +33,17 @@ export async function searchView( ctx.status = 200 + const { body } = ctx.request + const searchOptions: RequiredKeys & RequiredKeys> = { tableId: view.tableId, query: view.query || {}, fields: viewFields, - ...getSortOptions(ctx.request.body, view), - limit: ctx.request.body.limit, + ...getSortOptions(body, view), + limit: body.limit, + bookmark: body.bookmark, + paginate: body.paginate, } const result = await quotas.addQuery(() => sdk.rows.search(searchOptions), { diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index 8f7c6741be..b9f584706e 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -1279,6 +1279,63 @@ describe("/rows", () => { expect(response.body.rows).toHaveLength(limit) }) + + it("can handle pagination", async () => { + const table = await config.createTable(userTable()) + const rows = [] + for (let i = 0; i < 10; i++) { + rows.push(await config.createRow({ tableId: table._id })) + } + // rows.sort((a, b) => (a._id! > b._id! ? 1 : -1)) + + const createViewResponse = await config.api.viewV2.create() + const allRows = (await config.api.viewV2.search(createViewResponse.id)) + .body.rows + + const firstPageResponse = await config.api.viewV2.search( + createViewResponse.id, + { + paginate: true, + limit: 4, + } + ) + expect(firstPageResponse.body).toEqual({ + rows: expect.arrayContaining(allRows.slice(0, 4)), + totalRows: 10, + hasNextPage: true, + bookmark: expect.any(String), + }) + + const secondPageResponse = await config.api.viewV2.search( + createViewResponse.id, + { + paginate: true, + limit: 4, + bookmark: firstPageResponse.body.bookmark, + } + ) + expect(secondPageResponse.body).toEqual({ + rows: expect.arrayContaining(allRows.slice(4, 8)), + totalRows: 10, + hasNextPage: true, + bookmark: expect.any(String), + }) + + const lastPageResponse = await config.api.viewV2.search( + createViewResponse.id, + { + paginate: true, + limit: 4, + bookmark: secondPageResponse.body.bookmark, + } + ) + expect(lastPageResponse.body).toEqual({ + rows: expect.arrayContaining(allRows.slice(8)), + totalRows: 10, + hasNextPage: false, + bookmark: expect.any(String), + }) + }) }) }) }) diff --git a/packages/types/src/api/web/app/rows.ts b/packages/types/src/api/web/app/rows.ts index e95afa6e59..f1890ef777 100644 --- a/packages/types/src/api/web/app/rows.ts +++ b/packages/types/src/api/web/app/rows.ts @@ -12,7 +12,10 @@ export interface PatchRowResponse extends Row {} export interface SearchRowRequest extends Omit {} export interface SearchViewRowRequest - extends Pick {} + extends Pick< + SearchRowRequest, + "sort" | "sortOrder" | "sortType" | "limit" | "bookmark" | "paginate" + > {} export interface SearchRowResponse { rows: any[]