From e9ad3e58bec11d4f8cd105318e51b824b2943de7 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 14 Oct 2024 12:14:41 +0100 Subject: [PATCH] Support default values on multi-user columns. --- .../server/src/api/routes/tests/row.spec.ts | 33 +++++++++++++++++++ .../src/utilities/rowProcessor/index.ts | 15 ++++++--- packages/shared-core/src/table.ts | 2 +- .../types/src/documents/app/table/schema.ts | 1 + 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index 6490b4770a..2717a1b7d5 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -789,6 +789,39 @@ describe.each([ }) }) + describe("multi-user column", () => { + beforeAll(async () => { + table = await config.api.table.save( + saveTableRequest({ + schema: { + users: { + name: "users", + type: FieldType.BB_REFERENCE, + subtype: BBReferenceFieldSubType.USER, + default: ["{{ [Current User]._id }}"], + }, + }, + }) + ) + }) + + it("creates a new row with a default value successfully", async () => { + const row = await config.api.row.save(table._id!, {}) + expect(row.users).toHaveLength(1) + expect(row.users[0]._id).toEqual(config.getUser()._id) + }) + + it("does not use default value if value specified", async () => { + const id = `us_${utils.newid()}` + await config.createUser({ _id: id }) + const row = await config.api.row.save(table._id!, { + users: [id], + }) + expect(row.users).toHaveLength(1) + expect(row.users[0]._id).toEqual(id) + }) + }) + describe("bindings", () => { describe("string column", () => { beforeAll(async () => { diff --git a/packages/server/src/utilities/rowProcessor/index.ts b/packages/server/src/utilities/rowProcessor/index.ts index e63750bff9..717ac01969 100644 --- a/packages/server/src/utilities/rowProcessor/index.ts +++ b/packages/server/src/utilities/rowProcessor/index.ts @@ -33,7 +33,7 @@ import { PROTECTED_EXTERNAL_COLUMNS, PROTECTED_INTERNAL_COLUMNS, } from "@budibase/shared-core" -import { processString } from "@budibase/string-templates" +import { processString, processStringSync } from "@budibase/string-templates" import { getTableFromSource, isUserMetadataTable, @@ -134,10 +134,15 @@ async function processDefaultValues(table: Table, row: Row) { for (const [key, schema] of Object.entries(table.schema)) { if ("default" in schema && schema.default != null && row[key] == null) { - const processed = - typeof schema.default === "string" - ? await processString(schema.default, ctx) - : schema.default + let processed: string | string[] + if (Array.isArray(schema.default)) { + processed = schema.default.map(val => processStringSync(val, ctx)) + } else if (typeof schema.default === "string") { + processed = processStringSync(schema.default, ctx) + } else { + processed = schema.default + } + try { row[key] = coerce(processed, schema.type) } catch (err: any) { diff --git a/packages/shared-core/src/table.ts b/packages/shared-core/src/table.ts index 677b1e2357..e81e8266cc 100644 --- a/packages/shared-core/src/table.ts +++ b/packages/shared-core/src/table.ts @@ -66,7 +66,7 @@ const allowDefaultColumnByType: Record = { [FieldType.ATTACHMENT_SINGLE]: false, [FieldType.SIGNATURE_SINGLE]: false, [FieldType.LINK]: false, - [FieldType.BB_REFERENCE]: false, + [FieldType.BB_REFERENCE]: true, [FieldType.BB_REFERENCE_SINGLE]: true, } diff --git a/packages/types/src/documents/app/table/schema.ts b/packages/types/src/documents/app/table/schema.ts index f5bb081fd5..b98a0a3d4a 100644 --- a/packages/types/src/documents/app/table/schema.ts +++ b/packages/types/src/documents/app/table/schema.ts @@ -121,6 +121,7 @@ export interface BBReferenceFieldMetadata type: FieldType.BB_REFERENCE subtype: BBReferenceFieldSubType relationshipType?: RelationshipType + default?: string[] } export interface BBReferenceSingleFieldMetadata extends Omit {