diff --git a/packages/server/src/automations/steps/queryRows.js b/packages/server/src/automations/steps/queryRows.js index 58e7313dd2..b02f31b1ec 100644 --- a/packages/server/src/automations/steps/queryRows.js +++ b/packages/server/src/automations/steps/queryRows.js @@ -14,6 +14,16 @@ const SortOrdersPretty = { [SortOrders.DESCENDING]: "Descending", } +const EmptyFilterOptions = { + RETURN_ALL: "all", + RETURN_NONE: "none", +} + +const EmptyFilterOptionsPretty = { + [EmptyFilterOptions.RETURN_ALL]: "Return all table rows", + [EmptyFilterOptions.RETURN_NONE]: "Return no rows", +} + exports.definition = { description: "Query rows from the database", icon: "Search", @@ -52,6 +62,12 @@ exports.definition = { title: "Limit", customType: "queryLimit", }, + onEmptyFilter: { + pretty: Object.values(EmptyFilterOptionsPretty), + enum: Object.values(EmptyFilterOptions), + type: "string", + title: "When Filter Empty", + }, }, required: ["tableId"], }, @@ -103,6 +119,10 @@ function typeCoercion(filters, table) { return filters } +const hasNullFilters = filters => + filters.length === 0 || + filters.some(filter => filter.value === null || filter.value === "") + exports.run = async function ({ inputs, appId }) { const { tableId, filters, sortColumn, sortOrder, limit } = inputs const table = await getTable(appId, tableId) @@ -127,9 +147,21 @@ exports.run = async function ({ inputs, appId }) { version: "1", }) try { - await rowController.search(ctx) + let rows + + if ( + inputs.onEmptyFilter === EmptyFilterOptions.RETURN_NONE && + inputs["filters-def"] && + hasNullFilters(inputs["filters-def"]) + ) { + rows = [] + } else { + await rowController.search(ctx) + rows = ctx.body ? ctx.body.rows : [] + } + return { - rows: ctx.body ? ctx.body.rows : [], + rows, success: ctx.status === 200, } } catch (err) { diff --git a/packages/server/src/automations/tests/queryRows.spec.js b/packages/server/src/automations/tests/queryRows.spec.js index ec966302a8..1ce7460806 100644 --- a/packages/server/src/automations/tests/queryRows.spec.js +++ b/packages/server/src/automations/tests/queryRows.spec.js @@ -16,7 +16,7 @@ describe("Test a query step automation", () => { let table let config = setup.getConfig() - beforeEach(async () => { + beforeAll(async () => { await config.init() table = await config.createTable() const row = { @@ -48,4 +48,70 @@ describe("Test a query step automation", () => { expect(res.rows.length).toBe(2) expect(res.rows[0].name).toBe(NAME) }) + + it("Returns all rows when onEmptyFilter has no value and no filters are passed", async () => { + const inputs = { + tableId: table._id, + filters: {}, + sortColumn: "name", + sortOrder: "ascending", + limit: 10, + } + const res = await setup.runStep(setup.actions.QUERY_ROWS.stepId, inputs) + expect(res.success).toBe(true) + expect(res.rows).toBeDefined() + expect(res.rows.length).toBe(2) + expect(res.rows[0].name).toBe(NAME) + }) + + it("Returns no rows when onEmptyFilter is RETURN_NONE and theres no filters", async () => { + const inputs = { + tableId: table._id, + filters: {}, + "filters-def": [], + sortColumn: "name", + sortOrder: "ascending", + limit: 10, + onEmptyFilter: "none", + } + const res = await setup.runStep(setup.actions.QUERY_ROWS.stepId, inputs) + expect(res.success).toBe(false) + expect(res.rows).toBeDefined() + expect(res.rows.length).toBe(0) + }) + + it("Returns no rows when onEmptyFilters RETURN_NONE and a filter is passed with a null value", async () => { + const inputs = { + tableId: table._id, + onEmptyFilter: "none", + filters: {}, + "filters-def": [ + { + value: null + } + ], + sortColumn: "name", + sortOrder: "ascending", + limit: 10, + } + const res = await setup.runStep(setup.actions.QUERY_ROWS.stepId, inputs) + expect(res.success).toBe(false) + expect(res.rows).toBeDefined() + expect(res.rows.length).toBe(0) + }) + + it("Returns rows when onEmptyFilter is RETURN_ALL and no filter is passed", async () => { + const inputs = { + tableId: table._id, + onEmptyFilter: "all", + filters: {}, + sortColumn: "name", + sortOrder: "ascending", + limit: 10, + } + const res = await setup.runStep(setup.actions.QUERY_ROWS.stepId, inputs) + expect(res.success).toBe(true) + expect(res.rows).toBeDefined() + expect(res.rows.length).toBe(2) + }) })