From ce6c5bfa683ad1124ed513b7e4dca6c7982e812c Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 5 May 2023 15:47:55 +0100 Subject: [PATCH 01/99] Base connection work - extending the base integration to include the option of a connection check function. --- packages/server/src/integrations/airtable.ts | 10 ++++++++-- packages/server/src/integrations/arangodb.ts | 6 ++++++ packages/server/src/integrations/couchdb.ts | 6 ++++++ packages/server/src/integrations/dynamodb.ts | 2 ++ packages/server/src/integrations/elasticsearch.ts | 2 ++ packages/server/src/integrations/firebase.ts | 2 ++ packages/server/src/integrations/googlesheets.ts | 2 ++ .../server/src/integrations/microsoftSqlServer.ts | 2 ++ packages/server/src/integrations/mongodb.ts | 2 ++ packages/server/src/integrations/mysql.ts | 2 ++ packages/server/src/integrations/oracle.ts | 2 ++ packages/server/src/integrations/postgres.ts | 2 ++ packages/server/src/integrations/redis.ts | 11 +++++++++-- packages/server/src/integrations/s3.ts | 2 ++ packages/server/src/integrations/snowflake.ts | 8 +++++++- packages/types/src/sdk/datasources.ts | 10 ++++++++++ 16 files changed, 66 insertions(+), 5 deletions(-) diff --git a/packages/server/src/integrations/airtable.ts b/packages/server/src/integrations/airtable.ts index 1f56f0619b..58232ad56c 100644 --- a/packages/server/src/integrations/airtable.ts +++ b/packages/server/src/integrations/airtable.ts @@ -1,8 +1,9 @@ import { - Integration, + DatasourceFeature, DatasourceFieldType, - QueryType, + Integration, IntegrationBase, + QueryType, } from "@budibase/types" const Airtable = require("airtable") @@ -18,6 +19,7 @@ const SCHEMA: Integration = { "Airtable is a spreadsheet-database hybrid, with the features of a database but applied to a spreadsheet.", friendlyName: "Airtable", type: "Spreadsheet", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { apiKey: { type: DatasourceFieldType.PASSWORD, @@ -88,6 +90,10 @@ class AirtableIntegration implements IntegrationBase { this.client = new Airtable(config).base(config.base) } + async connection() { + return { connected: true } + } + async create(query: { table: any; json: any }) { const { table, json } = query diff --git a/packages/server/src/integrations/arangodb.ts b/packages/server/src/integrations/arangodb.ts index e28940f36e..3a61193577 100644 --- a/packages/server/src/integrations/arangodb.ts +++ b/packages/server/src/integrations/arangodb.ts @@ -3,6 +3,7 @@ import { DatasourceFieldType, QueryType, IntegrationBase, + DatasourceFeature, } from "@budibase/types" const { Database, aql } = require("arangojs") @@ -21,6 +22,7 @@ const SCHEMA: Integration = { type: "Non-relational", description: "ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. ", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { url: { type: DatasourceFieldType.STRING, @@ -74,6 +76,10 @@ class ArangoDBIntegration implements IntegrationBase { this.client = new Database(newConfig) } + async connection() { + return { connected: true } + } + async read(query: { sql: any }) { try { const result = await this.client.query(query.sql) diff --git a/packages/server/src/integrations/couchdb.ts b/packages/server/src/integrations/couchdb.ts index 257b84ca13..dfb0daa2e8 100644 --- a/packages/server/src/integrations/couchdb.ts +++ b/packages/server/src/integrations/couchdb.ts @@ -1,4 +1,5 @@ import { + DatasourceFeature, DatasourceFieldType, Document, Integration, @@ -18,6 +19,7 @@ const SCHEMA: Integration = { type: "Non-relational", description: "Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang.", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { url: { type: DatasourceFieldType.STRING, @@ -69,6 +71,10 @@ class CouchDBIntegration implements IntegrationBase { this.client = dbCore.DatabaseWithConnection(config.database, config.url) } + async connection() { + return { connected: true } + } + async query( command: string, errorMsg: string, diff --git a/packages/server/src/integrations/dynamodb.ts b/packages/server/src/integrations/dynamodb.ts index 28c1c7b52b..c682f355f9 100644 --- a/packages/server/src/integrations/dynamodb.ts +++ b/packages/server/src/integrations/dynamodb.ts @@ -3,6 +3,7 @@ import { DatasourceFieldType, QueryType, IntegrationBase, + DatasourceFeature, } from "@budibase/types" import AWS from "aws-sdk" @@ -22,6 +23,7 @@ const SCHEMA: Integration = { "Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.", friendlyName: "DynamoDB", type: "Non-relational", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { region: { type: DatasourceFieldType.STRING, diff --git a/packages/server/src/integrations/elasticsearch.ts b/packages/server/src/integrations/elasticsearch.ts index aeba628d30..475ddc0bd1 100644 --- a/packages/server/src/integrations/elasticsearch.ts +++ b/packages/server/src/integrations/elasticsearch.ts @@ -3,6 +3,7 @@ import { DatasourceFieldType, QueryType, IntegrationBase, + DatasourceFeature, } from "@budibase/types" import { Client, ClientOptions } from "@elastic/elasticsearch" @@ -20,6 +21,7 @@ const SCHEMA: Integration = { "Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.", friendlyName: "ElasticSearch", type: "Non-relational", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { url: { type: DatasourceFieldType.STRING, diff --git a/packages/server/src/integrations/firebase.ts b/packages/server/src/integrations/firebase.ts index a82b3be782..0646c98eba 100644 --- a/packages/server/src/integrations/firebase.ts +++ b/packages/server/src/integrations/firebase.ts @@ -3,6 +3,7 @@ import { Integration, QueryType, IntegrationBase, + DatasourceFeature, } from "@budibase/types" import { Firestore, WhereFilterOp } from "@google-cloud/firestore" @@ -18,6 +19,7 @@ const SCHEMA: Integration = { type: "Non-relational", description: "Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { email: { type: DatasourceFieldType.STRING, diff --git a/packages/server/src/integrations/googlesheets.ts b/packages/server/src/integrations/googlesheets.ts index 476a6511e9..8884c8de13 100644 --- a/packages/server/src/integrations/googlesheets.ts +++ b/packages/server/src/integrations/googlesheets.ts @@ -1,4 +1,5 @@ import { + DatasourceFeature, DatasourceFieldType, DatasourcePlus, FieldType, @@ -64,6 +65,7 @@ const SCHEMA: Integration = { "Create and collaborate on online spreadsheets in real-time and from any device. ", friendlyName: "Google Sheets", type: "Spreadsheet", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { spreadsheetId: { display: "Google Sheet URL", diff --git a/packages/server/src/integrations/microsoftSqlServer.ts b/packages/server/src/integrations/microsoftSqlServer.ts index eb87c1ccf1..b6f360ce32 100644 --- a/packages/server/src/integrations/microsoftSqlServer.ts +++ b/packages/server/src/integrations/microsoftSqlServer.ts @@ -8,6 +8,7 @@ import { QueryType, SqlQuery, DatasourcePlus, + DatasourceFeature, } from "@budibase/types" import { getSqlQuery, @@ -39,6 +40,7 @@ const SCHEMA: Integration = { "Microsoft SQL Server is a relational database management system developed by Microsoft. ", friendlyName: "MS SQL Server", type: "Relational", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { user: { type: DatasourceFieldType.STRING, diff --git a/packages/server/src/integrations/mongodb.ts b/packages/server/src/integrations/mongodb.ts index 38b3891fe4..20ba2acada 100644 --- a/packages/server/src/integrations/mongodb.ts +++ b/packages/server/src/integrations/mongodb.ts @@ -3,6 +3,7 @@ import { DatasourceFieldType, QueryType, IntegrationBase, + DatasourceFeature, } from "@budibase/types" import { MongoClient, @@ -38,6 +39,7 @@ const getSchema = () => { type: "Non-relational", description: "MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { connectionString: { type: DatasourceFieldType.STRING, diff --git a/packages/server/src/integrations/mysql.ts b/packages/server/src/integrations/mysql.ts index 8d984ed402..6083223042 100644 --- a/packages/server/src/integrations/mysql.ts +++ b/packages/server/src/integrations/mysql.ts @@ -7,6 +7,7 @@ import { Table, TableSchema, DatasourcePlus, + DatasourceFeature, } from "@budibase/types" import { getSqlQuery, @@ -41,6 +42,7 @@ const SCHEMA: Integration = { type: "Relational", description: "MySQL Database Service is a fully managed database service to deploy cloud-native applications. ", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { host: { type: DatasourceFieldType.STRING, diff --git a/packages/server/src/integrations/oracle.ts b/packages/server/src/integrations/oracle.ts index 65e0829905..bbe2189bdc 100644 --- a/packages/server/src/integrations/oracle.ts +++ b/packages/server/src/integrations/oracle.ts @@ -7,6 +7,7 @@ import { SqlQuery, Table, DatasourcePlus, + DatasourceFeature, } from "@budibase/types" import { buildExternalTableId, @@ -53,6 +54,7 @@ const SCHEMA: Integration = { type: "Relational", description: "Oracle Database is an object-relational database management system developed by Oracle Corporation", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { host: { type: DatasourceFieldType.STRING, diff --git a/packages/server/src/integrations/postgres.ts b/packages/server/src/integrations/postgres.ts index c981c3acc5..a968b71064 100644 --- a/packages/server/src/integrations/postgres.ts +++ b/packages/server/src/integrations/postgres.ts @@ -6,6 +6,7 @@ import { SqlQuery, Table, DatasourcePlus, + DatasourceFeature, } from "@budibase/types" import { getSqlQuery, @@ -50,6 +51,7 @@ const SCHEMA: Integration = { type: "Relational", description: "PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { host: { type: DatasourceFieldType.STRING, diff --git a/packages/server/src/integrations/redis.ts b/packages/server/src/integrations/redis.ts index 73ef2bb55c..f596b6eb0d 100644 --- a/packages/server/src/integrations/redis.ts +++ b/packages/server/src/integrations/redis.ts @@ -1,4 +1,9 @@ -import { DatasourceFieldType, Integration, QueryType } from "@budibase/types" +import { + DatasourceFeature, + DatasourceFieldType, + Integration, + QueryType, +} from "@budibase/types" import Redis from "ioredis" interface RedisConfig { @@ -11,9 +16,11 @@ interface RedisConfig { const SCHEMA: Integration = { docs: "https://redis.io/docs/", - description: "", + description: + "Redis is a caching tool, providing powerful key-value store capabilities.", friendlyName: "Redis", type: "Non-relational", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { host: { type: "string", diff --git a/packages/server/src/integrations/s3.ts b/packages/server/src/integrations/s3.ts index ad3bb09109..cc368760f8 100644 --- a/packages/server/src/integrations/s3.ts +++ b/packages/server/src/integrations/s3.ts @@ -3,6 +3,7 @@ import { QueryType, IntegrationBase, DatasourceFieldType, + DatasourceFeature, } from "@budibase/types" const AWS = require("aws-sdk") @@ -22,6 +23,7 @@ const SCHEMA: Integration = { "Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.", friendlyName: "Amazon S3", type: "Object store", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { region: { type: "string", diff --git a/packages/server/src/integrations/snowflake.ts b/packages/server/src/integrations/snowflake.ts index db702520f9..877405d447 100644 --- a/packages/server/src/integrations/snowflake.ts +++ b/packages/server/src/integrations/snowflake.ts @@ -1,4 +1,9 @@ -import { Integration, QueryType, SqlQuery } from "@budibase/types" +import { + DatasourceFeature, + Integration, + QueryType, + SqlQuery, +} from "@budibase/types" import { Snowflake } from "snowflake-promise" interface SnowflakeConfig { @@ -16,6 +21,7 @@ const SCHEMA: Integration = { "Snowflake is a solution for data warehousing, data lakes, data engineering, data science, data application development, and securely sharing and consuming shared data.", friendlyName: "Snowflake", type: "Relational", + features: [DatasourceFeature.CONNECTION_CHECKING], datasource: { account: { type: "string", diff --git a/packages/types/src/sdk/datasources.ts b/packages/types/src/sdk/datasources.ts index 605b431d9e..ccd6f7b9c6 100644 --- a/packages/types/src/sdk/datasources.ts +++ b/packages/types/src/sdk/datasources.ts @@ -74,6 +74,10 @@ export enum FilterType { ONE_OF = "oneOf", } +export enum DatasourceFeature { + CONNECTION_CHECKING = "connection", +} + export interface StepDefinition { key: string template: string @@ -112,6 +116,7 @@ export interface Integration { docs: string plus?: boolean auth?: { type: string } + features?: DatasourceFeature[] relationships?: boolean description: string friendlyName: string @@ -124,11 +129,16 @@ export interface Integration { extra?: ExtraQueryConfig } +export interface ConnectionInformation { + connected: boolean +} + export interface IntegrationBase { create?(query: any): Promise read?(query: any): Promise update?(query: any): Promise delete?(query: any): Promise + connection?(): Promise } export interface DatasourcePlus extends IntegrationBase { From 57a633b926f5fbcedc53e549bd63314a1e8d6870 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 5 May 2023 17:40:39 +0100 Subject: [PATCH 02/99] Implementing main body of connection verification endpoint. --- .../server/src/api/controllers/datasource.ts | 121 +++++++++++------- packages/server/src/api/routes/datasource.ts | 5 + packages/types/src/api/web/app/datasource.ts | 8 ++ 3 files changed, 85 insertions(+), 49 deletions(-) diff --git a/packages/server/src/api/controllers/datasource.ts b/packages/server/src/api/controllers/datasource.ts index b61b168980..e6866d528c 100644 --- a/packages/server/src/api/controllers/datasource.ts +++ b/packages/server/src/api/controllers/datasource.ts @@ -18,11 +18,68 @@ import { Row, CreateDatasourceResponse, UpdateDatasourceResponse, - UpdateDatasourceRequest, CreateDatasourceRequest, + VerifyDatasourceRequest, + VerifyDatasourceResponse, + IntegrationBase, + DatasourcePlus, } from "@budibase/types" import sdk from "../../sdk" +function getErrorTables(errors: any, errorType: string) { + return Object.entries(errors) + .filter(entry => entry[1] === errorType) + .map(([name]) => name) +} + +function updateError(error: any, newError: any, tables: string[]) { + if (!error) { + error = "" + } + if (error.length > 0) { + error += "\n" + } + error += `${newError} ${tables.join(", ")}` + return error +} + +async function getConnector( + datasource: Datasource +): Promise { + const Connector = await getIntegration(datasource.source) + datasource = await sdk.datasources.enrich(datasource) + // Connect to the DB and build the schema + return new Connector(datasource.config) +} + +async function buildSchemaHelper(datasource: Datasource) { + const connector = (await getConnector(datasource)) as DatasourcePlus + await connector.buildSchema(datasource._id!, datasource.entities!) + + const errors = connector.schemaErrors + let error = null + if (errors && Object.keys(errors).length > 0) { + const noKey = getErrorTables(errors, BuildSchemaErrors.NO_KEY) + const invalidCol = getErrorTables(errors, BuildSchemaErrors.INVALID_COLUMN) + if (noKey.length) { + error = updateError( + error, + "No primary key constraint found for the following:", + noKey + ) + } + if (invalidCol.length) { + const invalidCols = Object.values(InvalidColumns).join(", ") + error = updateError( + error, + `Cannot use columns ${invalidCols} found in following:`, + invalidCol + ) + } + } + return { tables: connector.tables, error } +} + export async function fetch(ctx: UserCtx) { // Get internal tables const db = context.getAppDB() @@ -66,6 +123,20 @@ export async function fetch(ctx: UserCtx) { ctx.body = [bbInternalDb, ...datasources] } +export async function verify( + ctx: UserCtx +) { + const datasource = ctx.request.body.datasource + const connector = (await getConnector(datasource)) as IntegrationBase + if (!connector.connection) { + ctx.throw(400, "Connection information verification not supported") + } + const connectionInfo = await connector.connection() + ctx.body = { + connected: connectionInfo.connected, + } +} + export async function buildSchemaFromDb(ctx: UserCtx) { const db = context.getAppDB() const datasource = await sdk.datasources.get(ctx.params.datasourceId) @@ -311,51 +382,3 @@ export async function query(ctx: UserCtx) { ctx.throw(400, err) } } - -function getErrorTables(errors: any, errorType: string) { - return Object.entries(errors) - .filter(entry => entry[1] === errorType) - .map(([name]) => name) -} - -function updateError(error: any, newError: any, tables: string[]) { - if (!error) { - error = "" - } - if (error.length > 0) { - error += "\n" - } - error += `${newError} ${tables.join(", ")}` - return error -} - -async function buildSchemaHelper(datasource: Datasource) { - const Connector = await getIntegration(datasource.source) - datasource = await sdk.datasources.enrich(datasource) - // Connect to the DB and build the schema - const connector = new Connector(datasource.config) - await connector.buildSchema(datasource._id, datasource.entities) - - const errors = connector.schemaErrors - let error = null - if (errors && Object.keys(errors).length > 0) { - const noKey = getErrorTables(errors, BuildSchemaErrors.NO_KEY) - const invalidCol = getErrorTables(errors, BuildSchemaErrors.INVALID_COLUMN) - if (noKey.length) { - error = updateError( - error, - "No primary key constraint found for the following:", - noKey - ) - } - if (invalidCol.length) { - const invalidCols = Object.values(InvalidColumns).join(", ") - error = updateError( - error, - `Cannot use columns ${invalidCols} found in following:`, - invalidCol - ) - } - } - return { tables: connector.tables, error } -} diff --git a/packages/server/src/api/routes/datasource.ts b/packages/server/src/api/routes/datasource.ts index 85929d2180..654fb794e3 100644 --- a/packages/server/src/api/routes/datasource.ts +++ b/packages/server/src/api/routes/datasource.ts @@ -15,6 +15,11 @@ router authorized(permissions.BUILDER), datasourceController.fetch ) + .post( + "/api/datasources/verify", + authorized(permissions.BUILDER), + datasourceController.verify + ) .get( "/api/datasources/:datasourceId", authorized( diff --git a/packages/types/src/api/web/app/datasource.ts b/packages/types/src/api/web/app/datasource.ts index d54259eab5..36e081d9f6 100644 --- a/packages/types/src/api/web/app/datasource.ts +++ b/packages/types/src/api/web/app/datasource.ts @@ -14,6 +14,14 @@ export interface CreateDatasourceRequest { fetchSchema?: boolean } +export interface VerifyDatasourceRequest { + datasource: Datasource +} + +export interface VerifyDatasourceResponse { + connected: boolean +} + export interface UpdateDatasourceRequest extends Datasource { datasource: Datasource } From 58878ac57c2735b9238d49391cff66e88b96c12b Mon Sep 17 00:00:00 2001 From: jvcalderon Date: Thu, 11 May 2023 08:20:52 +0200 Subject: [PATCH 03/99] Adds account locking if user limit is exceeded --- .../licensing/AccountLockedModal.svelte | 31 +++++++++++++++++++ .../portal/licensing/licensingBanners.js | 15 +++------ .../src/components/start/AppRow.svelte | 11 +++++-- .../src/pages/builder/apps/index.svelte | 2 +- .../pages/builder/portal/apps/index.svelte | 28 ++++++++++++++--- .../users/_components/AddUserModal.svelte | 4 +-- .../users/_components/ImportUsersModal.svelte | 6 ++-- .../builder/portal/users/users/index.svelte | 12 +++---- .../builder/src/stores/portal/licensing.js | 22 ++++++------- 9 files changed, 89 insertions(+), 42 deletions(-) create mode 100644 packages/builder/src/components/portal/licensing/AccountLockedModal.svelte diff --git a/packages/builder/src/components/portal/licensing/AccountLockedModal.svelte b/packages/builder/src/components/portal/licensing/AccountLockedModal.svelte new file mode 100644 index 0000000000..63bb6dcfd9 --- /dev/null +++ b/packages/builder/src/components/portal/licensing/AccountLockedModal.svelte @@ -0,0 +1,31 @@ + + + + + Due to the free plan user limit being exceeded, your account has been + de-activated. Upgrade your plan to re-activate your account. + + diff --git a/packages/builder/src/components/portal/licensing/licensingBanners.js b/packages/builder/src/components/portal/licensing/licensingBanners.js index dafa8cfaed..ea4a1bb946 100644 --- a/packages/builder/src/components/portal/licensing/licensingBanners.js +++ b/packages/builder/src/components/portal/licensing/licensingBanners.js @@ -3,7 +3,6 @@ import { temporalStore } from "builderStore" import { admin, auth, licensing } from "stores/portal" import { get } from "svelte/store" import { BANNER_TYPES } from "@budibase/bbui" -import { capitalise } from "helpers" const oneDayInSeconds = 86400 @@ -146,23 +145,19 @@ const buildUsersAboveLimitBanner = EXPIRY_KEY => { const userLicensing = get(licensing) return { key: EXPIRY_KEY, - type: BANNER_TYPES.WARNING, + type: BANNER_TYPES.NEGATIVE, onChange: () => { defaultCacheFn(EXPIRY_KEY) }, criteria: () => { - return userLicensing.warnUserLimit + return userLicensing.errUserLimit }, - message: `${capitalise( - userLicensing.license.plan.type - )} plan changes - Users will be limited to ${ - userLicensing.userLimit - } users in ${userLicensing.userLimitDays}`, + message: "Your Budibase account is de-activated. Upgrade your plan", ...{ - extraButtonText: "Find out more", + extraButtonText: "View plans", extraButtonAction: () => { defaultCacheFn(ExpiringKeys.LICENSING_USERS_ABOVE_LIMIT_BANNER) - window.location.href = "/builder/portal/users/users" + window.location.href = "https://budibase.com/pricing/" }, }, showCloseButton: true, diff --git a/packages/builder/src/components/start/AppRow.svelte b/packages/builder/src/components/start/AppRow.svelte index 34d083a096..194f897fdc 100644 --- a/packages/builder/src/components/start/AppRow.svelte +++ b/packages/builder/src/components/start/AppRow.svelte @@ -6,6 +6,8 @@ export let app + export let lockedAction + const handleDefaultClick = () => { if (window.innerWidth < 640) { goToOverview() @@ -29,7 +31,7 @@ } -
+
@@ -58,8 +60,11 @@
- - + +
diff --git a/packages/builder/src/pages/builder/apps/index.svelte b/packages/builder/src/pages/builder/apps/index.svelte index 23f4df5bb5..4b77671345 100644 --- a/packages/builder/src/pages/builder/apps/index.svelte +++ b/packages/builder/src/pages/builder/apps/index.svelte @@ -133,7 +133,7 @@ - {#if $licensing.usageMetrics?.dayPasses >= 100} + {#if $licensing.usageMetrics?.dayPasses >= 100 || $licensing.errUserLimit}
spaceman diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte index 783cac49d7..edd308f382 100644 --- a/packages/builder/src/pages/builder/portal/apps/index.svelte +++ b/packages/builder/src/pages/builder/portal/apps/index.svelte @@ -14,6 +14,7 @@ import Spinner from "components/common/Spinner.svelte" import CreateAppModal from "components/start/CreateAppModal.svelte" import AppLimitModal from "components/portal/licensing/AppLimitModal.svelte" + import AccountLockedModal from "components/portal/licensing/AccountLockedModal.svelte" import { store, automationStore } from "builderStore" import { API } from "api" @@ -28,6 +29,7 @@ let template let creationModal let appLimitModal + let accountLockedModal let creatingApp = false let searchTerm = "" let creatingFromTemplate = false @@ -49,6 +51,10 @@ ) $: automationErrors = getAutomationErrors(enrichedApps) + const usersLimitLockAction = $licensing?.errUserLimit + ? () => accountLockedModal.show() + : null + const enrichApps = (apps, user, sortBy) => { const enrichedApps = apps.map(app => ({ ...app, @@ -189,6 +195,9 @@ creatingFromTemplate = true createAppFromTemplateUrl(initInfo.init_template) } + if (usersLimitLockAction) { + usersLimitLockAction() + } } catch (error) { notifications.error("Error getting init info") } @@ -230,20 +239,30 @@
- {#if $apps?.length > 0} {/if} {#if !$apps?.length} - {/if} @@ -267,7 +286,7 @@
{#each filteredApps as app (app.appId)} - + {/each}
@@ -294,6 +313,7 @@ + diff --git a/packages/bbui/src/FancyForm/FancyField.svelte b/packages/bbui/src/FancyForm/FancyField.svelte index 89f2dec7d0..0c99394599 100644 --- a/packages/bbui/src/FancyForm/FancyField.svelte +++ b/packages/bbui/src/FancyForm/FancyField.svelte @@ -1,7 +1,7 @@ + +
+ + a-happy-budibase-user +
+ "{testimonial.text}" +
+
+
{testimonial.name}
+
{testimonial.role}
+
+
+
+ + diff --git a/packages/frontend-core/src/components/TestimonialPage.svelte b/packages/frontend-core/src/components/TestimonialPage.svelte index bbb61d2276..94983384a8 100644 --- a/packages/frontend-core/src/components/TestimonialPage.svelte +++ b/packages/frontend-core/src/components/TestimonialPage.svelte @@ -1,58 +1,15 @@
{#if enabled} -
- - a-happy-budibase-user -
- "{testimonial.text}" -
-
-
{testimonial.name}
-
{testimonial.role}
-
-
-
+ {/if}
@@ -64,20 +21,4 @@ display: grid; place-items: center; } - .testimonial { - width: 380px; - padding: 40px; - } - .text { - font-size: var(--font-size-l); - font-style: italic; - } - .name { - font-weight: bold; - color: var(--spectrum-global-color-gray-900); - font-size: var(--font-size-l); - } - .company { - color: var(--spectrum-global-color-gray-700); - } diff --git a/packages/frontend-core/src/components/index.js b/packages/frontend-core/src/components/index.js index 2b7033ad8f..88107da535 100644 --- a/packages/frontend-core/src/components/index.js +++ b/packages/frontend-core/src/components/index.js @@ -1,3 +1,4 @@ export { default as SplitPage } from "./SplitPage.svelte" export { default as TestimonialPage } from "./TestimonialPage.svelte" +export { default as Testimonial } from "./Testimonial.svelte" export { Grid } from "./grid" From 00cbe5a2d574a1cdc52b7f72f2af9531430bf59a Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Wed, 17 May 2023 10:00:25 +0000 Subject: [PATCH 94/99] Bump version to 2.6.16-alpha.3 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index e56d307592..5253871cbc 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.6.16-alpha.2", + "version": "2.6.16-alpha.3", "npmClient": "yarn", "packages": [ "packages/backend-core", From 79bc2afeca550368f5495e53183c56723080c5aa Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 17 May 2023 12:04:06 +0200 Subject: [PATCH 95/99] Run validators nightly --- .../validators/{arango.spec.ts => arango.nightly.spec.ts} | 0 .../validators/{couch.spec.ts => couch.nightly.spec.ts} | 0 .../validators/{dynamodb.spec.ts => dynamodb.nightly.spec.ts} | 0 .../validators/{elastic.spec.ts => elastic.nightly.spec.ts} | 0 .../validators/{mongo.spec.ts => mongo.nightly.spec.ts} | 0 .../validators/{mssql.spec.ts => mssql.nightly.spec.ts} | 0 .../validators/{mysql.spec.ts => mysql.nightly.spec.ts} | 0 .../validators/{postgres.spec.ts => postgres.nightly.spec.ts} | 0 .../validators/{redis.spec.ts => redis.nightly.spec.ts} | 0 .../integrations/validators/{s3.spec.ts => s3.nightly.spec.ts} | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename qa-core/src/integrations/validators/{arango.spec.ts => arango.nightly.spec.ts} (100%) rename qa-core/src/integrations/validators/{couch.spec.ts => couch.nightly.spec.ts} (100%) rename qa-core/src/integrations/validators/{dynamodb.spec.ts => dynamodb.nightly.spec.ts} (100%) rename qa-core/src/integrations/validators/{elastic.spec.ts => elastic.nightly.spec.ts} (100%) rename qa-core/src/integrations/validators/{mongo.spec.ts => mongo.nightly.spec.ts} (100%) rename qa-core/src/integrations/validators/{mssql.spec.ts => mssql.nightly.spec.ts} (100%) rename qa-core/src/integrations/validators/{mysql.spec.ts => mysql.nightly.spec.ts} (100%) rename qa-core/src/integrations/validators/{postgres.spec.ts => postgres.nightly.spec.ts} (100%) rename qa-core/src/integrations/validators/{redis.spec.ts => redis.nightly.spec.ts} (100%) rename qa-core/src/integrations/validators/{s3.spec.ts => s3.nightly.spec.ts} (100%) diff --git a/qa-core/src/integrations/validators/arango.spec.ts b/qa-core/src/integrations/validators/arango.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/arango.spec.ts rename to qa-core/src/integrations/validators/arango.nightly.spec.ts diff --git a/qa-core/src/integrations/validators/couch.spec.ts b/qa-core/src/integrations/validators/couch.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/couch.spec.ts rename to qa-core/src/integrations/validators/couch.nightly.spec.ts diff --git a/qa-core/src/integrations/validators/dynamodb.spec.ts b/qa-core/src/integrations/validators/dynamodb.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/dynamodb.spec.ts rename to qa-core/src/integrations/validators/dynamodb.nightly.spec.ts diff --git a/qa-core/src/integrations/validators/elastic.spec.ts b/qa-core/src/integrations/validators/elastic.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/elastic.spec.ts rename to qa-core/src/integrations/validators/elastic.nightly.spec.ts diff --git a/qa-core/src/integrations/validators/mongo.spec.ts b/qa-core/src/integrations/validators/mongo.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/mongo.spec.ts rename to qa-core/src/integrations/validators/mongo.nightly.spec.ts diff --git a/qa-core/src/integrations/validators/mssql.spec.ts b/qa-core/src/integrations/validators/mssql.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/mssql.spec.ts rename to qa-core/src/integrations/validators/mssql.nightly.spec.ts diff --git a/qa-core/src/integrations/validators/mysql.spec.ts b/qa-core/src/integrations/validators/mysql.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/mysql.spec.ts rename to qa-core/src/integrations/validators/mysql.nightly.spec.ts diff --git a/qa-core/src/integrations/validators/postgres.spec.ts b/qa-core/src/integrations/validators/postgres.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/postgres.spec.ts rename to qa-core/src/integrations/validators/postgres.nightly.spec.ts diff --git a/qa-core/src/integrations/validators/redis.spec.ts b/qa-core/src/integrations/validators/redis.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/redis.spec.ts rename to qa-core/src/integrations/validators/redis.nightly.spec.ts diff --git a/qa-core/src/integrations/validators/s3.spec.ts b/qa-core/src/integrations/validators/s3.nightly.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/s3.spec.ts rename to qa-core/src/integrations/validators/s3.nightly.spec.ts From b2109e6160f1422bc81a3ce246fa8fef1d80cce9 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Wed, 17 May 2023 10:20:20 +0000 Subject: [PATCH 96/99] Bump version to 2.6.16-alpha.4 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 5253871cbc..45abc9671f 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.6.16-alpha.3", + "version": "2.6.16-alpha.4", "npmClient": "yarn", "packages": [ "packages/backend-core", From eb46037344e512fe1a9614ba01f65c3b669747ee Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 17 May 2023 12:59:20 +0200 Subject: [PATCH 97/99] Rename validator integration tests --- .../{arango.nightly.spec.ts => arango.integration.spec.ts} | 0 .../{couch.nightly.spec.ts => couch.integration.spec.ts} | 0 .../{dynamodb.nightly.spec.ts => dynamodb.integration.spec.ts} | 0 .../{elastic.nightly.spec.ts => elastic.integration.spec.ts} | 0 .../{mongo.nightly.spec.ts => mongo.integration.spec.ts} | 0 .../{mssql.nightly.spec.ts => mssql.integration.spec.ts} | 0 .../{mysql.nightly.spec.ts => mysql.integration.spec.ts} | 0 .../{postgres.nightly.spec.ts => postgres.integration.spec.ts} | 1 - .../{redis.nightly.spec.ts => redis.integration.spec.ts} | 0 .../validators/{s3.nightly.spec.ts => s3.integration.spec.ts} | 0 10 files changed, 1 deletion(-) rename qa-core/src/integrations/validators/{arango.nightly.spec.ts => arango.integration.spec.ts} (100%) rename qa-core/src/integrations/validators/{couch.nightly.spec.ts => couch.integration.spec.ts} (100%) rename qa-core/src/integrations/validators/{dynamodb.nightly.spec.ts => dynamodb.integration.spec.ts} (100%) rename qa-core/src/integrations/validators/{elastic.nightly.spec.ts => elastic.integration.spec.ts} (100%) rename qa-core/src/integrations/validators/{mongo.nightly.spec.ts => mongo.integration.spec.ts} (100%) rename qa-core/src/integrations/validators/{mssql.nightly.spec.ts => mssql.integration.spec.ts} (100%) rename qa-core/src/integrations/validators/{mysql.nightly.spec.ts => mysql.integration.spec.ts} (100%) rename qa-core/src/integrations/validators/{postgres.nightly.spec.ts => postgres.integration.spec.ts} (94%) rename qa-core/src/integrations/validators/{redis.nightly.spec.ts => redis.integration.spec.ts} (100%) rename qa-core/src/integrations/validators/{s3.nightly.spec.ts => s3.integration.spec.ts} (100%) diff --git a/qa-core/src/integrations/validators/arango.nightly.spec.ts b/qa-core/src/integrations/validators/arango.integration.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/arango.nightly.spec.ts rename to qa-core/src/integrations/validators/arango.integration.spec.ts diff --git a/qa-core/src/integrations/validators/couch.nightly.spec.ts b/qa-core/src/integrations/validators/couch.integration.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/couch.nightly.spec.ts rename to qa-core/src/integrations/validators/couch.integration.spec.ts diff --git a/qa-core/src/integrations/validators/dynamodb.nightly.spec.ts b/qa-core/src/integrations/validators/dynamodb.integration.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/dynamodb.nightly.spec.ts rename to qa-core/src/integrations/validators/dynamodb.integration.spec.ts diff --git a/qa-core/src/integrations/validators/elastic.nightly.spec.ts b/qa-core/src/integrations/validators/elastic.integration.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/elastic.nightly.spec.ts rename to qa-core/src/integrations/validators/elastic.integration.spec.ts diff --git a/qa-core/src/integrations/validators/mongo.nightly.spec.ts b/qa-core/src/integrations/validators/mongo.integration.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/mongo.nightly.spec.ts rename to qa-core/src/integrations/validators/mongo.integration.spec.ts diff --git a/qa-core/src/integrations/validators/mssql.nightly.spec.ts b/qa-core/src/integrations/validators/mssql.integration.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/mssql.nightly.spec.ts rename to qa-core/src/integrations/validators/mssql.integration.spec.ts diff --git a/qa-core/src/integrations/validators/mysql.nightly.spec.ts b/qa-core/src/integrations/validators/mysql.integration.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/mysql.nightly.spec.ts rename to qa-core/src/integrations/validators/mysql.integration.spec.ts diff --git a/qa-core/src/integrations/validators/postgres.nightly.spec.ts b/qa-core/src/integrations/validators/postgres.integration.spec.ts similarity index 94% rename from qa-core/src/integrations/validators/postgres.nightly.spec.ts rename to qa-core/src/integrations/validators/postgres.integration.spec.ts index 5101cf1d2d..029d929df0 100644 --- a/qa-core/src/integrations/validators/postgres.nightly.spec.ts +++ b/qa-core/src/integrations/validators/postgres.integration.spec.ts @@ -1,5 +1,4 @@ import { GenericContainer } from "testcontainers" -import postgres from "../../../../packages/server/src/integrations/postgres" jest.unmock("pg") diff --git a/qa-core/src/integrations/validators/redis.nightly.spec.ts b/qa-core/src/integrations/validators/redis.integration.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/redis.nightly.spec.ts rename to qa-core/src/integrations/validators/redis.integration.spec.ts diff --git a/qa-core/src/integrations/validators/s3.nightly.spec.ts b/qa-core/src/integrations/validators/s3.integration.spec.ts similarity index 100% rename from qa-core/src/integrations/validators/s3.nightly.spec.ts rename to qa-core/src/integrations/validators/s3.integration.spec.ts From 02fc795d982b3b57129b811f65d8f1ac4332311f Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 17 May 2023 13:00:08 +0200 Subject: [PATCH 98/99] Rename nightly.spec to integration.spec --- qa-core/package.json | 2 +- .../{mariaDB.nightly.spec.ts => mariaDB.integration.spec.ts} | 0 .../{mongoDB.nightly.spec.ts => mongoDB.integration.spec.ts} | 0 ...tgresSQL.nightly.spec.ts => postgresSQL.integration.spec.ts} | 0 .../{restAPI.nightly.spec.ts => restAPI.integration.spec.ts} | 0 5 files changed, 1 insertion(+), 1 deletion(-) rename qa-core/src/internal-api/tests/dataSources/{mariaDB.nightly.spec.ts => mariaDB.integration.spec.ts} (100%) rename qa-core/src/internal-api/tests/dataSources/{mongoDB.nightly.spec.ts => mongoDB.integration.spec.ts} (100%) rename qa-core/src/internal-api/tests/dataSources/{postgresSQL.nightly.spec.ts => postgresSQL.integration.spec.ts} (100%) rename qa-core/src/internal-api/tests/dataSources/{restAPI.nightly.spec.ts => restAPI.integration.spec.ts} (100%) diff --git a/qa-core/package.json b/qa-core/package.json index a6f9537d0f..2cfc8e2865 100644 --- a/qa-core/package.json +++ b/qa-core/package.json @@ -14,7 +14,7 @@ "test:watch": "yarn run test --watch", "test:debug": "DEBUG=1 yarn run test", "test:notify": "node scripts/testResultsWebhook", - "test:smoke": "yarn run test --testPathIgnorePatterns=/.+\\.nightly\\.spec\\.ts", + "test:smoke": "yarn run test --testPathIgnorePatterns=/.+\\.integration\\.spec\\.ts", "test:ci": "start-server-and-test dev:built http://localhost:4001/health test:smoke", "dev:built": "cd ../ && yarn dev:built" }, diff --git a/qa-core/src/internal-api/tests/dataSources/mariaDB.nightly.spec.ts b/qa-core/src/internal-api/tests/dataSources/mariaDB.integration.spec.ts similarity index 100% rename from qa-core/src/internal-api/tests/dataSources/mariaDB.nightly.spec.ts rename to qa-core/src/internal-api/tests/dataSources/mariaDB.integration.spec.ts diff --git a/qa-core/src/internal-api/tests/dataSources/mongoDB.nightly.spec.ts b/qa-core/src/internal-api/tests/dataSources/mongoDB.integration.spec.ts similarity index 100% rename from qa-core/src/internal-api/tests/dataSources/mongoDB.nightly.spec.ts rename to qa-core/src/internal-api/tests/dataSources/mongoDB.integration.spec.ts diff --git a/qa-core/src/internal-api/tests/dataSources/postgresSQL.nightly.spec.ts b/qa-core/src/internal-api/tests/dataSources/postgresSQL.integration.spec.ts similarity index 100% rename from qa-core/src/internal-api/tests/dataSources/postgresSQL.nightly.spec.ts rename to qa-core/src/internal-api/tests/dataSources/postgresSQL.integration.spec.ts diff --git a/qa-core/src/internal-api/tests/dataSources/restAPI.nightly.spec.ts b/qa-core/src/internal-api/tests/dataSources/restAPI.integration.spec.ts similarity index 100% rename from qa-core/src/internal-api/tests/dataSources/restAPI.nightly.spec.ts rename to qa-core/src/internal-api/tests/dataSources/restAPI.integration.spec.ts From d5439e1fb6961003d3523d2734442835556e6b1d Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Wed, 17 May 2023 13:51:09 +0000 Subject: [PATCH 99/99] Bump version to 2.6.16-alpha.5 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 45abc9671f..c9f5201e0d 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.6.16-alpha.4", + "version": "2.6.16-alpha.5", "npmClient": "yarn", "packages": [ "packages/backend-core",