diff --git a/packages/builder/src/pages/builder/app/[application]/data/datasource/[datasourceId]/_components/panels/Tables/CreateExternalTableModal.svelte b/packages/builder/src/pages/builder/app/[application]/data/datasource/[datasourceId]/_components/panels/Tables/CreateExternalTableModal.svelte index 129b975309..b5a8dfc8ac 100644 --- a/packages/builder/src/pages/builder/app/[application]/data/datasource/[datasourceId]/_components/panels/Tables/CreateExternalTableModal.svelte +++ b/packages/builder/src/pages/builder/app/[application]/data/datasource/[datasourceId]/_components/panels/Tables/CreateExternalTableModal.svelte @@ -23,6 +23,7 @@ sourceType: DB_TYPE_EXTERNAL, schema: { id: { + name: "id", autocolumn: true, type: "number", }, diff --git a/packages/client/src/components/app/container/GridContainer.svelte b/packages/client/src/components/app/container/GridContainer.svelte index 4dc75f3513..696b65abcd 100644 --- a/packages/client/src/components/app/container/GridContainer.svelte +++ b/packages/client/src/components/app/container/GridContainer.svelte @@ -4,6 +4,8 @@ import { GridRowHeight, GridColumns } from "constants" import { memo } from "@budibase/frontend-core" + export let onClick + const component = getContext("component") const { styleable, builderStore } = getContext("sdk") const context = getContext("context") @@ -121,15 +123,19 @@ }) + +
{#if inBuilder}
@@ -176,6 +182,9 @@ .placeholder.first-col { border-left: 1px solid var(--spectrum-global-color-gray-900); } + .clickable { + cursor: pointer; + } /* Highlight grid lines when resizing children */ :global(.grid.highlight > .underlay) { diff --git a/packages/server/src/api/controllers/table/index.ts b/packages/server/src/api/controllers/table/index.ts index efe1a88e4a..2f2f93bffe 100644 --- a/packages/server/src/api/controllers/table/index.ts +++ b/packages/server/src/api/controllers/table/index.ts @@ -71,19 +71,20 @@ export async function fetch(ctx: UserCtx) { const datasources = await sdk.datasources.getExternalDatasources() - const external = datasources.flatMap(datasource => { + const external: Table[] = [] + for (const datasource of datasources) { let entities = datasource.entities if (entities) { - return Object.values(entities).map((entity: Table) => ({ - ...entity, - sourceType: TableSourceType.EXTERNAL, - sourceId: datasource._id!, - sql: isSQL(datasource), - })) - } else { - return [] + for (const entity of Object.values(entities)) { + external.push({ + ...(await processTable(entity)), + sourceType: TableSourceType.EXTERNAL, + sourceId: datasource._id!, + sql: isSQL(datasource), + }) + } } - }) + } const result: FetchTablesResponse = [] for (const table of [...internal, ...external]) { 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/sdk/app/tables/getters.ts b/packages/server/src/sdk/app/tables/getters.ts index 5ff000fe12..280fb5378a 100644 --- a/packages/server/src/sdk/app/tables/getters.ts +++ b/packages/server/src/sdk/app/tables/getters.ts @@ -20,7 +20,13 @@ export async function processTable(table: Table): Promise
{ if (!table) { return table } + + table = { ...table } if (table._id && isExternalTableID(table._id)) { + // Old created external tables via Budibase might have a missing field name breaking some UI such as filters + if (table.schema["id"] && !table.schema["id"].name) { + table.schema["id"].name = "id" + } return { ...table, type: "table", diff --git a/packages/server/src/utilities/rowProcessor/index.ts b/packages/server/src/utilities/rowProcessor/index.ts index e63750bff9..dd17bc9ba6 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 { 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 {