From 863587ef300cf138faffa863696434038ebfc273 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 29 Dec 2023 12:25:25 +0100 Subject: [PATCH 001/128] Fix scripts --- scripts/add-app-migration.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/add-app-migration.js b/scripts/add-app-migration.js index a58d3a4fbe..a4e01be635 100644 --- a/scripts/add-app-migration.js +++ b/scripts/add-app-migration.js @@ -21,7 +21,9 @@ const generateTimestamp = () => { } const createMigrationFile = () => { - const migrationFilename = `${generateTimestamp()}_${title}` + const migrationFilename = `${generateTimestamp()}_${title + .replace(/-/g, "_") + .replace(/ /g, "_")}` const migrationsDir = "../packages/server/src/appMigrations" const template = `const migration = async () => { From 90db9efb7045d0dfbf7db6e294442d64e150e816 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 29 Dec 2023 12:43:39 +0100 Subject: [PATCH 002/128] Allow skipping migrations --- packages/backend-core/src/environment.ts | 1 + packages/server/src/middleware/appMigrations.ts | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/packages/backend-core/src/environment.ts b/packages/backend-core/src/environment.ts index 138dbbd9e0..66c91b19fb 100644 --- a/packages/backend-core/src/environment.ts +++ b/packages/backend-core/src/environment.ts @@ -183,6 +183,7 @@ const environment = { environment[key] = value }, ROLLING_LOG_MAX_SIZE: process.env.ROLLING_LOG_MAX_SIZE || "10M", + SKIP_APP_MIGRATIONS: process.env.SKIP_APP_MIGRATIONS || false, } // clean up any environment variable edge cases diff --git a/packages/server/src/middleware/appMigrations.ts b/packages/server/src/middleware/appMigrations.ts index 36e021c7ed..1fb13094c6 100644 --- a/packages/server/src/middleware/appMigrations.ts +++ b/packages/server/src/middleware/appMigrations.ts @@ -1,9 +1,14 @@ import { UserCtx } from "@budibase/types" import { checkMissingMigrations } from "../appMigrations" +import { env } from "@budibase/backend-core" export default async (ctx: UserCtx, next: any) => { const { appId } = ctx + if (env.SKIP_APP_MIGRATIONS) { + return next() + } + if (!appId) { return next() } From f484c6dabd9b135128115707d1627d625c92f95d Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 29 Dec 2023 12:43:53 +0100 Subject: [PATCH 003/128] Fix initial run --- packages/server/src/appMigrations/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/appMigrations/index.ts b/packages/server/src/appMigrations/index.ts index b382d8b533..0758b9f324 100644 --- a/packages/server/src/appMigrations/index.ts +++ b/packages/server/src/appMigrations/index.ts @@ -17,7 +17,7 @@ export const getLatestMigrationId = () => .sort() .reverse()[0] -const getTimestamp = (versionId: string) => versionId?.split("_")[0] +const getTimestamp = (versionId: string) => versionId?.split("_")[0] || "" export async function checkMissingMigrations( ctx: UserCtx, From 61e16b63a510ec19dcc47a03f9bd5ceb0a95a743 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 29 Dec 2023 12:55:14 +0100 Subject: [PATCH 004/128] Fix initial run --- packages/server/src/appMigrations/appMigrationMetadata.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/appMigrations/appMigrationMetadata.ts b/packages/server/src/appMigrations/appMigrationMetadata.ts index 202e78d964..d87ddff3ef 100644 --- a/packages/server/src/appMigrations/appMigrationMetadata.ts +++ b/packages/server/src/appMigrations/appMigrationMetadata.ts @@ -33,7 +33,7 @@ export async function getAppMigrationVersion(appId: string): Promise { let version try { metadata = await getFromDB(appId) - version = metadata.version + version = metadata.version || "" } catch (err: any) { if (err.status !== 404) { throw err From 4a481877def0483bf3864af5e0f11467835356d9 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 29 Dec 2023 12:55:52 +0100 Subject: [PATCH 005/128] Add empty migration --- packages/server/src/appMigrations/migrations.ts | 6 ++++++ .../migrations/20231229122514_update_link_documents.ts | 5 +++++ 2 files changed, 11 insertions(+) create mode 100644 packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts diff --git a/packages/server/src/appMigrations/migrations.ts b/packages/server/src/appMigrations/migrations.ts index d66e2e8895..544e702867 100644 --- a/packages/server/src/appMigrations/migrations.ts +++ b/packages/server/src/appMigrations/migrations.ts @@ -2,6 +2,12 @@ import { AppMigration } from "." +import m20231229122514_update_link_documents from "./migrations/20231229122514_update_link_documents" + export const MIGRATIONS: AppMigration[] = [ // Migrations will be executed sorted by id + { + id: "20231229122514_update_link_documents", + func: m20231229122514_update_link_documents + }, ] diff --git a/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts b/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts new file mode 100644 index 0000000000..f23f72e070 --- /dev/null +++ b/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts @@ -0,0 +1,5 @@ +const migration = async () => { + // Add your migration logic here +} + +export default migration From e1c37e75a41a6613080c638e088d4a5dfe7c1753 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 29 Dec 2023 13:03:59 +0100 Subject: [PATCH 006/128] Add allLinkDocs utils --- packages/server/src/db/utils.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/server/src/db/utils.ts b/packages/server/src/db/utils.ts index 1712563085..a487c562b6 100644 --- a/packages/server/src/db/utils.ts +++ b/packages/server/src/db/utils.ts @@ -1,5 +1,5 @@ import newid from "./newid" -import { db as dbCore } from "@budibase/backend-core" +import { context, db as dbCore } from "@budibase/backend-core" import { DocumentType, FieldSchema, @@ -7,6 +7,7 @@ import { VirtualDocumentType, INTERNAL_TABLE_SOURCE_ID, DatabaseQueryOpts, + LinkDocument, } from "@budibase/types" import { FieldTypes } from "../constants" @@ -127,10 +128,24 @@ export function generateLinkID( /** * Gets parameters for retrieving link docs, this is a utility function for the getDocParams function. */ -export function getLinkParams(otherProps: any = {}) { +function getLinkParams(otherProps: Partial = {}) { return getDocParams(DocumentType.LINK, null, otherProps) } +/** + * Gets all the link docs document from the current app db. + */ +export async function allLinkDocs() { + const db = context.getAppDB() + + const response = await db.allDocs( + getLinkParams({ + include_docs: true, + }) + ) + return response.rows.map(row => row.doc!) +} + /** * Generates a new layout ID. * @returns The new layout ID which the layout doc can be stored under. From 4a1b99a9dc5f1b650a4ffe3cfa7602b51f6eedb3 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 29 Dec 2023 13:32:45 +0100 Subject: [PATCH 007/128] Add migration --- .../20231229122514_update_link_documents.ts | 23 ++++++++++++++++++- packages/types/src/documents/app/links.ts | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts b/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts index f23f72e070..e1e1d4efc6 100644 --- a/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts +++ b/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts @@ -1,5 +1,26 @@ +import { SEPARATOR, context } from "@budibase/backend-core" +import { allLinkDocs } from "../../db/utils" + const migration = async () => { - // Add your migration logic here + const linkDocs = await allLinkDocs() + + const docsToUpdate = [] + for (const linkDoc of linkDocs) { + if (linkDoc.tableId) { + // It already had the required data + continue + } + + linkDoc.tableId = [linkDoc.doc1.tableId, linkDoc.doc2.tableId] + .sort() + .join(SEPARATOR) + docsToUpdate.push(linkDoc) + } + + if (docsToUpdate.length) { + const db = context.getAppDB() + await db.bulkDocs(docsToUpdate) + } } export default migration diff --git a/packages/types/src/documents/app/links.ts b/packages/types/src/documents/app/links.ts index ae7e4de78e..2a9595d99f 100644 --- a/packages/types/src/documents/app/links.ts +++ b/packages/types/src/documents/app/links.ts @@ -8,6 +8,7 @@ export interface LinkInfo { export interface LinkDocument extends Document { type: string + tableId: string doc1: LinkInfo doc2: LinkInfo } From e265cc635c3b1f0ad66773078b1b657cbd4c0589 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 29 Dec 2023 13:41:46 +0100 Subject: [PATCH 008/128] Create link docs to new docs --- packages/backend-core/src/users/db.ts | 2 +- .../20231229122514_update_link_documents.ts | 14 ++++++++++---- packages/server/src/db/linkedRows/LinkDocument.ts | 7 ++++++- packages/server/src/db/linkedRows/index.ts | 1 - 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/backend-core/src/users/db.ts b/packages/backend-core/src/users/db.ts index 326bed3cc5..01fa4899d1 100644 --- a/packages/backend-core/src/users/db.ts +++ b/packages/backend-core/src/users/db.ts @@ -2,7 +2,7 @@ import env from "../environment" import * as eventHelpers from "./events" import * as accountSdk from "../accounts" import * as cache from "../cache" -import { doInTenant, getGlobalDB, getIdentity, getTenantId } from "../context" +import { getGlobalDB, getIdentity, getTenantId } from "../context" import * as dbUtils from "../db" import { EmailUnavailableError, HTTPError } from "../errors" import * as platform from "../platform" diff --git a/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts b/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts index e1e1d4efc6..adaa0653c4 100644 --- a/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts +++ b/packages/server/src/appMigrations/migrations/20231229122514_update_link_documents.ts @@ -1,5 +1,6 @@ -import { SEPARATOR, context } from "@budibase/backend-core" +import { context } from "@budibase/backend-core" import { allLinkDocs } from "../../db/utils" +import LinkDocumentImpl from "../../db/linkedRows/LinkDocument" const migration = async () => { const linkDocs = await allLinkDocs() @@ -11,9 +12,14 @@ const migration = async () => { continue } - linkDoc.tableId = [linkDoc.doc1.tableId, linkDoc.doc2.tableId] - .sort() - .join(SEPARATOR) + linkDoc.tableId = new LinkDocumentImpl( + linkDoc.doc1.tableId, + linkDoc.doc1.fieldName, + linkDoc.doc1.rowId, + linkDoc.doc2.tableId, + linkDoc.doc2.fieldName, + linkDoc.doc2.rowId + ).tableId docsToUpdate.push(linkDoc) } diff --git a/packages/server/src/db/linkedRows/LinkDocument.ts b/packages/server/src/db/linkedRows/LinkDocument.ts index 234f43cb48..05097ed84f 100644 --- a/packages/server/src/db/linkedRows/LinkDocument.ts +++ b/packages/server/src/db/linkedRows/LinkDocument.ts @@ -1,6 +1,6 @@ import { generateLinkID } from "../utils" import { FieldTypes } from "../../constants" -import { LinkDocument } from "@budibase/types" +import { LinkDocument, SEPARATOR } from "@budibase/types" /** * Creates a new link document structure which can be put to the database. It is important to @@ -17,6 +17,7 @@ import { LinkDocument } from "@budibase/types" class LinkDocumentImpl implements LinkDocument { _id: string type: string + tableId: string doc1: { rowId: string fieldName: string @@ -54,7 +55,11 @@ class LinkDocumentImpl implements LinkDocument { fieldName: fieldName2, rowId: rowId2, } + this.tableId = [this.doc1.tableId, this.doc2.tableId].sort().join(SEPARATOR) } + _rev?: string | undefined + createdAt?: string | number | undefined + updatedAt?: string | undefined } export default LinkDocumentImpl diff --git a/packages/server/src/db/linkedRows/index.ts b/packages/server/src/db/linkedRows/index.ts index 7af3f9392f..934b9d4a75 100644 --- a/packages/server/src/db/linkedRows/index.ts +++ b/packages/server/src/db/linkedRows/index.ts @@ -18,7 +18,6 @@ import { Row, LinkDocumentValue, FieldType, - LinkDocument, ContextUser, } from "@budibase/types" import sdk from "../../sdk" From 896c262c943ae0874fba548f398ffe6aa930f47b Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 30 May 2024 10:52:17 +0200 Subject: [PATCH 009/128] Add readonly option in view columns --- .../backend/DataTable/ViewV2DataTable.svelte | 1 + .../grid/controls/ColumnsSettingButton.svelte | 41 ++++++++++++++----- .../src/components/grid/layout/Grid.svelte | 3 +- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte b/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte index 3b628c7b53..9b0e45a1b2 100644 --- a/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte +++ b/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte @@ -28,6 +28,7 @@ showAvatars={false} on:updatedatasource={handleGridViewUpdate} isCloud={$admin.cloud} + allowReadonlyColumns > diff --git a/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte b/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte index 0a85e41966..70655bd5a3 100644 --- a/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte @@ -1,9 +1,11 @@
@@ -15,7 +14,7 @@ dispatch("click", option.value)} - {disabled} + disabled={option.disabled} size="S" icon={option.icon} quiet From 8e72f1f0facd831a62c385fb88754d0a36972710 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 30 May 2024 11:07:30 +0200 Subject: [PATCH 011/128] Lock readonly --- packages/builder/src/stores/portal/licensing.js | 6 ++++++ .../grid/controls/ColumnsSettingButton.svelte | 10 ++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/stores/portal/licensing.js b/packages/builder/src/stores/portal/licensing.js index 179d0918bb..1378a734e8 100644 --- a/packages/builder/src/stores/portal/licensing.js +++ b/packages/builder/src/stores/portal/licensing.js @@ -138,6 +138,11 @@ export const createLicensingStore = () => { const isViewPermissionsEnabled = license.features.includes( Constants.Features.VIEW_PERMISSIONS ) + + const isViewReadonlyColumnsEnabled = license.features.includes( + Constants.Features.VIEW_READONLY_COLUMNS + ) + store.update(state => { return { ...state, @@ -157,6 +162,7 @@ export const createLicensingStore = () => { triggerAutomationRunEnabled, isViewPermissionsEnabled, perAppBuildersEnabled, + isViewReadonlyColumnsEnabled, } }) }, diff --git a/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte b/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte index 7e330b77e4..8faf603b80 100644 --- a/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte @@ -1,6 +1,7 @@ diff --git a/packages/frontend-core/src/components/grid/stores/columns.js b/packages/frontend-core/src/components/grid/stores/columns.js index a3281be936..b76dcbfe0e 100644 --- a/packages/frontend-core/src/components/grid/stores/columns.js +++ b/packages/frontend-core/src/components/grid/stores/columns.js @@ -146,6 +146,7 @@ export const initialise = context => { schema: fieldSchema, width: fieldSchema.width || oldColumn?.width || DefaultColumnWidth, visible: fieldSchema.visible ?? true, + readonly: fieldSchema.readonly, order: fieldSchema.order ?? oldColumn?.order, primaryDisplay: field === primaryDisplay, } From fbfe85c903c5d0b95419e6f5071d594204e566a7 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 30 May 2024 11:43:28 +0200 Subject: [PATCH 013/128] Mark readonly as restricted --- .../components/grid/controls/ColumnsSettingButton.svelte | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte b/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte index c07adf9fcb..fd0afd48f2 100644 --- a/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/ColumnsSettingButton.svelte @@ -29,8 +29,10 @@ } const getText = columns => { - const hidden = columns.filter(col => !col.visible).length - return hidden ? `Columns (${hidden} restricted)` : "Columns" + const restricted = columns.filter( + col => !col.visible || col.readonly + ).length + return restricted ? `Columns (${restricted} restricted)` : "Columns" } $: isViewReadonlyColumnsEnabled = $licensing.isViewReadonlyColumnsEnabled From 6ce0b3c368356459ad4d683e2f28f7acec549d66 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 30 May 2024 11:46:57 +0200 Subject: [PATCH 014/128] Copy change --- packages/server/src/api/routes/tests/viewV2.spec.ts | 4 ++-- packages/server/src/sdk/app/views/index.ts | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 8069fadf10..962d6e82a3 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -424,7 +424,7 @@ describe.each([ await config.api.viewV2.create(newView, { status: 400, body: { - message: "Readonly fields are not enabled for your tenant", + message: "Readonly fields are not enabled", status: 400, }, }) @@ -690,7 +690,7 @@ describe.each([ await config.api.viewV2.update(view, { status: 400, body: { - message: "Readonly fields are not enabled for your tenant", + message: "Readonly fields are not enabled", }, }) }) diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index ea05ecf512..18ab94be21 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -55,10 +55,7 @@ async function guardViewSchema( if (viewSchema[field].readonly) { if (!(await features.isViewReadonlyColumnsEnabled())) { - throw new HTTPError( - `Readonly fields are not enabled for your tenant`, - 400 - ) + throw new HTTPError(`Readonly fields are not enabled`, 400) } if (isRequired(tableSchemaField.constraints)) { From 4dbfa28febd21889e271af769a1619cd5d2c44db Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 30 May 2024 17:12:46 +0200 Subject: [PATCH 015/128] Move licence check out of frontend-core --- .../backend/DataTable/ViewV2DataTable.svelte | 5 +++-- .../grid/controls/ColumnsSettingButton.svelte | 12 +++++------- .../src/components/grid/layout/Grid.svelte | 8 ++++++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte b/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte index 9b0e45a1b2..45cdeeee07 100644 --- a/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte +++ b/packages/builder/src/components/backend/DataTable/ViewV2DataTable.svelte @@ -1,6 +1,6 @@
@@ -47,6 +57,16 @@ />