diff --git a/packages/server/src/api/controllers/row/index.ts b/packages/server/src/api/controllers/row/index.ts index aa3aa3e21c..46c933da07 100644 --- a/packages/server/src/api/controllers/row/index.ts +++ b/packages/server/src/api/controllers/row/index.ts @@ -146,6 +146,20 @@ export async function search(ctx: any) { }) } +export async function searchView(ctx: any) { + const { viewId } = ctx.params + const view = await sdk.views.get(viewId) + const tableId = view.tableId + + ctx.status = 200 + ctx.body = await quotas.addQuery( + () => sdk.rows.search({ tableId, query: {} }), + { + datasourceId: tableId, + } + ) +} + export async function validate(ctx: Ctx) { const tableId = utils.getTableId(ctx) // external tables are hard to validate currently diff --git a/packages/server/src/api/routes/row.ts b/packages/server/src/api/routes/row.ts index 6d1cd206c6..6b393051c6 100644 --- a/packages/server/src/api/routes/row.ts +++ b/packages/server/src/api/routes/row.ts @@ -146,6 +146,11 @@ router authorized(PermissionType.TABLE, PermissionLevel.READ), rowController.search ) + .get( + "/api/views/v2/:viewId/search", + authorized(PermissionType.VIEW, PermissionLevel.READ), + rowController.searchView + ) /** * @api {post} /api/:tableId/rows Creates a new row * @apiName Creates a new row diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index 8e99c30246..7a5b85bd83 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -14,8 +14,9 @@ import { Row, Table, FieldType, + ViewV2, } from "@budibase/types" -import { structures } from "@budibase/backend-core/tests" +import { generator, structures } from "@budibase/backend-core/tests" describe("/rows", () => { let request = setup.getRequest() @@ -685,4 +686,57 @@ describe("/rows", () => { expect(row._id).toEqual(existing._id) }) }) + + describe.only("view search", () => { + function priceTable(): Table { + return { + name: "table", + type: "table", + schema: { + Price: { + type: FieldType.NUMBER, + name: "Price", + constraints: {}, + }, + Category: { + type: FieldType.STRING, + name: "Category", + constraints: { + type: "string", + }, + }, + }, + } + } + + it("returns table rows from view", async () => { + const table = await config.createTable(priceTable()) + const rows = await Promise.all( + Array(10) + .fill({}) + .map(() => config.createRow({ tableId: table._id })) + ) + const view: ViewV2 = { + name: generator.guid(), + tableId: table._id!, + } + const createViewResponse = await request + .post(`/api/views/v2`) + .send(view) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + + const response = await request + .get(`/api/views/v2/${createViewResponse.body._id}/search`) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + + expect(response.body.rows).toHaveLength(10) + expect(response.body).toEqual({ + rows: expect.arrayContaining(rows.map(expect.objectContaining)), + }) + }) + }) })