From ff57b982f8d8b46f1fc3b938c535cf454b0e20cf Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 24 Jul 2023 15:57:17 +0200 Subject: [PATCH] Move enrich view schemas to view sdk --- packages/server/src/sdk/app/views/index.ts | 43 ++- .../src/sdk/app/views/tests/views.spec.ts | 265 ++++++++++++++++++ 2 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 packages/server/src/sdk/app/views/tests/views.spec.ts diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index e4d6f061eb..17691c999d 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -1,8 +1,9 @@ import { HTTPError, context } from "@budibase/backend-core" -import { View, ViewV2 } from "@budibase/types" +import { TableSchema, UIFieldMetadata, View, ViewV2 } from "@budibase/types" import sdk from "../../../sdk" import * as utils from "../../../db/utils" +import _ from "lodash" export async function get(viewId: string): Promise { const { tableId } = utils.extractViewInfoFromID(viewId) @@ -48,3 +49,43 @@ export async function remove(viewId: string): Promise { delete table.views![view?.name] await db.put(table) } + +export function enrichSchema(view: View | ViewV2, tableSchema: TableSchema) { + if (!sdk.views.isV2(view)) { + return view + } + + return { + ...view, + schema: + !view?.columns || !Object.entries(view?.columns).length + ? tableSchema + : enrichViewV2Schema(tableSchema, view.columns), + } +} + +function enrichViewV2Schema( + tableSchema: TableSchema, + viewOverrides: Record +) { + const result: TableSchema = {} + const viewOverridesEntries = Object.entries(viewOverrides) + const viewSetsOrder = viewOverridesEntries.some(([_, v]) => v.order) + for (const [columnName, columnUIMetadata] of viewOverridesEntries) { + if (!columnUIMetadata.visible) { + continue + } + + if (!tableSchema[columnName]) { + continue + } + + const tableFieldSchema = tableSchema[columnName] + if (viewSetsOrder) { + delete tableFieldSchema.order + } + + result[columnName] = _.merge(tableFieldSchema, columnUIMetadata) + } + return result +} diff --git a/packages/server/src/sdk/app/views/tests/views.spec.ts b/packages/server/src/sdk/app/views/tests/views.spec.ts new file mode 100644 index 0000000000..cbcd98eb91 --- /dev/null +++ b/packages/server/src/sdk/app/views/tests/views.spec.ts @@ -0,0 +1,265 @@ +import { FieldType, Table, ViewV2 } from "@budibase/types" +import { generator } from "@budibase/backend-core/tests" +import { enrichSchema } from ".." + +describe("table sdk", () => { + describe("enrichViewSchemas", () => { + const basicTable: Table = { + _id: generator.guid(), + name: "TestTable", + type: "table", + schema: { + name: { + type: FieldType.STRING, + name: "name", + visible: true, + width: 80, + order: 2, + constraints: { + type: "string", + }, + }, + description: { + type: FieldType.STRING, + name: "description", + visible: true, + width: 200, + constraints: { + type: "string", + }, + }, + id: { + type: FieldType.NUMBER, + name: "id", + visible: true, + order: 1, + constraints: { + type: "number", + }, + }, + hiddenField: { + type: FieldType.STRING, + name: "hiddenField", + visible: false, + constraints: { + type: "string", + }, + }, + }, + } + + it("should fetch the default schema if not overriden", async () => { + const tableId = basicTable._id! + const view: ViewV2 = { + version: 2, + id: generator.guid(), + name: generator.guid(), + tableId, + } + + const res = enrichSchema(view, basicTable.schema) + + expect(res).toEqual({ + ...view, + schema: { + name: { + type: "string", + name: "name", + visible: true, + order: 2, + width: 80, + constraints: { + type: "string", + }, + }, + description: { + type: "string", + name: "description", + visible: true, + width: 200, + constraints: { + type: "string", + }, + }, + id: { + type: "number", + name: "id", + visible: true, + order: 1, + constraints: { + type: "number", + }, + }, + hiddenField: { + type: "string", + name: "hiddenField", + visible: false, + constraints: { + type: "string", + }, + }, + }, + }) + }) + + it("if view schema only defines visiblility, should only fetch the selected fields", async () => { + const tableId = basicTable._id! + const view: ViewV2 = { + version: 2, + id: generator.guid(), + name: generator.guid(), + tableId, + columns: { + name: { visible: true }, + id: { visible: true }, + description: { visible: false }, + }, + } + + const res = enrichSchema(view, basicTable.schema) + + expect(res).toEqual({ + ...view, + schema: { + name: { + type: "string", + name: "name", + visible: true, + order: 2, + width: 80, + constraints: { + type: "string", + }, + }, + id: { + type: "number", + name: "id", + visible: true, + order: 1, + constraints: { + type: "number", + }, + }, + }, + }) + }) + + it("schema does not break if the view has corrupted columns", async () => { + const tableId = basicTable._id! + const view: ViewV2 = { + version: 2, + id: generator.guid(), + name: generator.guid(), + tableId, + columns: { unnexisting: { visible: true }, name: { visible: true } }, + } + + const res = enrichSchema(view, basicTable.schema) + + expect(res).toEqual( + expect.objectContaining({ + ...view, + schema: { + name: { + type: "string", + name: "name", + order: 2, + visible: true, + width: 80, + constraints: { + type: "string", + }, + }, + }, + }) + ) + }) + + it("if view schema only defines visiblility, should only fetch the selected fields", async () => { + const tableId = basicTable._id! + const view: ViewV2 = { + version: 2, + id: generator.guid(), + name: generator.guid(), + tableId, + columns: { + name: { visible: true }, + id: { visible: true }, + description: { visible: false }, + }, + } + + const res = enrichSchema(view, basicTable.schema) + + expect(res).toEqual( + expect.objectContaining({ + ...view, + schema: { + name: { + type: "string", + name: "name", + order: 2, + visible: true, + width: 80, + constraints: { + type: "string", + }, + }, + id: { + type: "number", + name: "id", + order: 1, + visible: true, + constraints: { + type: "number", + }, + }, + }, + }) + ) + }) + + it("if view defines order, the table schema order should be ignored", async () => { + const tableId = basicTable._id! + const view: ViewV2 = { + version: 2, + id: generator.guid(), + name: generator.guid(), + tableId, + columns: { + name: { visible: true, order: 1 }, + id: { visible: true }, + description: { visible: false, order: 2 }, + }, + } + + const res = enrichSchema(view, basicTable.schema) + + expect(res).toEqual( + expect.objectContaining({ + ...view, + schema: { + name: { + type: "string", + name: "name", + order: 1, + visible: true, + width: 80, + constraints: { + type: "string", + }, + }, + id: { + type: "number", + name: "id", + visible: true, + constraints: { + type: "number", + }, + }, + }, + }) + ) + }) + }) +})