From 77856eb35a8072c8c71d63178c6cc8a13ef3de0b Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 1 Oct 2024 17:23:21 +0100 Subject: [PATCH 1/5] Add a test to make sure fields on the underlying table that are required are not required on the view. --- .../src/api/routes/tests/viewV2.spec.ts | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 1d6c1d50cd..f76b6eb470 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -2546,6 +2546,51 @@ describe.each([ } }) }) + + !isLucene && + it("should not need required fields to be present", async () => { + const table = await config.api.table.save( + saveTableRequest({ + schema: { + name: { + name: "name", + type: FieldType.STRING, + constraints: { + presence: true, + }, + }, + age: { + name: "age", + type: FieldType.NUMBER, + }, + }, + }) + ) + + await Promise.all([ + config.api.row.save(table._id!, { name: "Steve", age: 30 }), + config.api.row.save(table._id!, { name: "Jane", age: 31 }), + ]) + + const view = await config.api.viewV2.create({ + tableId: table._id!, + name: generator.guid(), + schema: { + sum: { + visible: true, + calculationType: CalculationType.SUM, + field: "age", + }, + }, + }) + + const response = await config.api.viewV2.search(view.id, { + query: {}, + }) + + expect(response.rows).toHaveLength(1) + expect(response.rows[0].sum).toEqual(61) + }) }) describe("permissions", () => { From cc6b2f6717cce5ea7dfb2830aa1f1e4de9410e68 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 2 Oct 2024 09:35:47 +0100 Subject: [PATCH 2/5] add failing test --- .../src/api/routes/tests/viewV2.spec.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index f76b6eb470..954047d536 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -25,6 +25,7 @@ import { ViewFieldMetadata, FeatureFlag, BBReferenceFieldSubType, + ViewCalculationFieldMetadata, } from "@budibase/types" import { generator, mocks } from "@budibase/backend-core/tests" import { DatabaseName, getDatasource } from "../../../integrations/tests/utils" @@ -540,6 +541,31 @@ describe.each([ status: 201, }) }) + + it.only("can create a view with calculation fields", async () => { + let view = await config.api.viewV2.create({ + tableId: table._id!, + name: generator.guid(), + schema: { + sum: { + visible: true, + calculationType: CalculationType.SUM, + field: "Price", + }, + }, + }) + + let sum = view.schema!.sum as ViewCalculationFieldMetadata + expect(sum).toBeDefined() + expect(sum.calculationType).toEqual(CalculationType.SUM) + expect(sum.field).toEqual("Price") + + view = await config.api.viewV2.get(view.id) + sum = view.schema!.sum as ViewCalculationFieldMetadata + expect(sum).toBeDefined() + expect(sum.calculationType).toEqual(CalculationType.SUM) + expect(sum.field).toEqual("Price") + }) }) describe("update", () => { From 0679ec89931879158f2ef3fd43bc9de89540321b Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 2 Oct 2024 10:36:45 +0100 Subject: [PATCH 3/5] Make sure calculation views are created and returned correctly. --- .../src/api/routes/tests/viewV2.spec.ts | 4 ++- packages/server/src/sdk/app/views/index.ts | 31 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 954047d536..669d35ba5b 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -542,7 +542,7 @@ describe.each([ }) }) - it.only("can create a view with calculation fields", async () => { + it("can create a view with calculation fields", async () => { let view = await config.api.viewV2.create({ tableId: table._id!, name: generator.guid(), @@ -555,6 +555,8 @@ describe.each([ }, }) + expect(Object.keys(view.schema!)).toHaveLength(1) + let sum = view.schema!.sum as ViewCalculationFieldMetadata expect(sum).toBeDefined() expect(sum.calculationType).toEqual(CalculationType.SUM) diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index 24e4da3172..d218a3c7e8 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -258,19 +258,12 @@ export async function enrichSchema( view: ViewV2, tableSchema: TableSchema ): Promise { - const tableCache: Record = {} - async function populateRelTableSchema( tableId: string, viewFields: Record ) { - if (!tableCache[tableId]) { - tableCache[tableId] = await sdk.tables.getTable(tableId) - } - const relTable = tableCache[tableId] - + const relTable = await sdk.tables.getTable(tableId) const result: Record = {} - for (const relTableFieldName of Object.keys(relTable.schema)) { const relTableField = relTable.schema[relTableFieldName] if ([FieldType.LINK, FieldType.FORMULA].includes(relTableField.type)) { @@ -299,15 +292,22 @@ export async function enrichSchema( const viewSchema = view.schema || {} const anyViewOrder = Object.values(viewSchema).some(ui => ui.order != null) - for (const key of Object.keys(tableSchema).filter( - k => tableSchema[k].visible !== false - )) { + + const visibleSchemaFields = Object.keys(viewSchema).filter( + key => viewSchema[key].visible !== false + ) + const visibleTableFields = Object.keys(tableSchema).filter( + key => tableSchema[key].visible !== false + ) + const visibleFields = new Set([...visibleSchemaFields, ...visibleTableFields]) + + for (const key of visibleFields) { // if nothing specified in view, then it is not visible const ui = viewSchema[key] || { visible: false } schema[key] = { - ...tableSchema[key], + ...(tableSchema[key] || {}), ...ui, - order: anyViewOrder ? ui?.order ?? undefined : tableSchema[key].order, + order: anyViewOrder ? ui?.order ?? undefined : tableSchema[key]?.order, columns: undefined, } @@ -319,10 +319,7 @@ export async function enrichSchema( } } - return { - ...view, - schema: schema, - } + return { ...view, schema } } export function syncSchema( From 45a6f0680f2c2dd4d14d82e019f0dd7390b026f0 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 2 Oct 2024 13:58:23 +0100 Subject: [PATCH 4/5] Fix view.spec.ts tests. --- packages/server/src/sdk/app/views/index.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index d218a3c7e8..2bd90822c7 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -293,14 +293,16 @@ export async function enrichSchema( const viewSchema = view.schema || {} const anyViewOrder = Object.values(viewSchema).some(ui => ui.order != null) - const visibleSchemaFields = Object.keys(viewSchema).filter( - key => viewSchema[key].visible !== false - ) + const visibleSchemaFields = Object.keys(viewSchema).filter(key => { + if (helpers.views.isCalculationField(viewSchema[key])) { + return viewSchema[key].visible !== false + } + return key in tableSchema && tableSchema[key].visible !== false + }) const visibleTableFields = Object.keys(tableSchema).filter( key => tableSchema[key].visible !== false ) const visibleFields = new Set([...visibleSchemaFields, ...visibleTableFields]) - for (const key of visibleFields) { // if nothing specified in view, then it is not visible const ui = viewSchema[key] || { visible: false } From 73613ce8bfda5720aca62a3a65dd35ca97d3113e Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 2 Oct 2024 16:52:40 +0100 Subject: [PATCH 5/5] Fix spread operator use. --- packages/server/src/sdk/app/views/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index 2bd90822c7..83ee78e165 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -307,7 +307,7 @@ export async function enrichSchema( // if nothing specified in view, then it is not visible const ui = viewSchema[key] || { visible: false } schema[key] = { - ...(tableSchema[key] || {}), + ...tableSchema[key], ...ui, order: anyViewOrder ? ui?.order ?? undefined : tableSchema[key]?.order, columns: undefined,