diff --git a/.github/workflows/release-selfhost.yml b/.github/workflows/release-selfhost.yml
new file mode 100644
index 0000000000..a4cbc4e70a
--- /dev/null
+++ b/.github/workflows/release-selfhost.yml
@@ -0,0 +1,57 @@
+name: Budibase Release
+
+on:
+ workflow_dispatch:
+
+env:
+ POSTHOG_TOKEN: ${{ secrets.POSTHOG_TOKEN }}
+ INTERCOM_TOKEN: ${{ secrets.INTERCOM_TOKEN }}
+ POSTHOG_URL: ${{ secrets.POSTHOG_URL }}
+ SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v1
+ with:
+ node-version: 12.x
+ - run: yarn
+ - run: yarn bootstrap
+
+ - name: Configure AWS Credentials
+ uses: aws-actions/configure-aws-credentials@v1
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ aws-region: eu-west-1
+
+ - name: 'Get Previous tag'
+ id: previoustag
+ uses: "WyriHaximus/github-action-get-previous-tag@v1"
+
+ - name: Build/release Docker images (Self Host)
+ if: ${{ github.event.inputs.release_self_host == 'Y' }}
+ run: |
+ docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
+ yarn build
+ yarn build:docker:production
+ env:
+ DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
+ DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }}
+ BUDIBASE_RELEASE_VERSION: ${{ steps.previoustag.outputs.tag }}
+
+ - uses: azure/setup-helm@v1
+ id: install
+
+ # So, we need to inject the values into this
+ - run: yarn release:helm
+
+ - name: Run chart-releaser
+ uses: helm/chart-releaser-action@v1.1.0
+ with:
+ charts_dir: docs
+ env:
+ CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 7b38a70eb7..40154be992 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -4,12 +4,6 @@ on:
push:
branches:
- master
- workflow_dispatch:
- inputs:
- release_self_host:
- description: 'Release to self hosters? (Y/N)'
- required: true
- default: 'N'
env:
POSTHOG_TOKEN: ${{ secrets.POSTHOG_TOKEN }}
@@ -54,7 +48,6 @@ jobs:
uses: "WyriHaximus/github-action-get-previous-tag@v1"
- name: Build/release Docker images
- if: ${{ github.event.inputs.release_self_host != 'Y' }}
run: |
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
yarn build
@@ -62,28 +55,4 @@ jobs:
env:
DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }}
- BUDIBASE_RELEASE_VERSION: ${{ steps.previoustag.outputs.tag }}
-
- - name: Build/release Docker images (Self Host)
- if: ${{ github.event.inputs.release_self_host == 'Y' }}
- run: |
- docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
- yarn build
- yarn build:docker
- env:
- DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
- DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }}
- BUDIBASE_RELEASE_VERSION: ${{ steps.previoustag.outputs.tag }}
-
- - uses: azure/setup-helm@v1
- id: install
-
- # So, we need to inject the values into this
- - run: yarn release:helm
-
- - name: Run chart-releaser
- uses: helm/chart-releaser-action@v1.1.0
- with:
- charts_dir: docs
- env:
- CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+ BUDIBASE_RELEASE_VERSION: ${{ steps.previoustag.outputs.tag }}
\ No newline at end of file
diff --git a/lerna.json b/lerna.json
index 9ac2a8d4d2..a687b57552 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "version": "0.9.153-alpha.1",
+ "version": "0.9.160-alpha.0",
"npmClient": "yarn",
"packages": [
"packages/*"
diff --git a/packages/auth/package.json b/packages/auth/package.json
index 88d5ace67b..6469114278 100644
--- a/packages/auth/package.json
+++ b/packages/auth/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/auth",
- "version": "0.9.153-alpha.1",
+ "version": "0.9.160-alpha.0",
"description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js",
"author": "Budibase",
diff --git a/packages/auth/src/db/constants.js b/packages/auth/src/db/constants.js
index ad4f6c9f66..477968975a 100644
--- a/packages/auth/src/db/constants.js
+++ b/packages/auth/src/db/constants.js
@@ -1,5 +1,20 @@
exports.SEPARATOR = "_"
+const PRE_APP = "app"
+const PRE_DEV = "dev"
+
+exports.DocumentTypes = {
+ USER: "us",
+ WORKSPACE: "workspace",
+ CONFIG: "config",
+ TEMPLATE: "template",
+ APP: PRE_APP,
+ DEV: PRE_DEV,
+ APP_DEV: `${PRE_APP}${exports.SEPARATOR}${PRE_DEV}`,
+ APP_METADATA: `${PRE_APP}${exports.SEPARATOR}metadata`,
+ ROLE: "role",
+}
+
exports.StaticDatabases = {
GLOBAL: {
name: "global-db",
diff --git a/packages/auth/src/db/utils.js b/packages/auth/src/db/utils.js
index 09e2ff6314..fa162603e6 100644
--- a/packages/auth/src/db/utils.js
+++ b/packages/auth/src/db/utils.js
@@ -2,8 +2,8 @@ const { newid } = require("../hashing")
const Replication = require("./Replication")
const { DEFAULT_TENANT_ID } = require("../constants")
const env = require("../environment")
-const { StaticDatabases, SEPARATOR } = require("./constants")
-const { getTenantId } = require("../tenancy")
+const { StaticDatabases, SEPARATOR, DocumentTypes } = require("./constants")
+const { getTenantId, getTenantIDFromAppID } = require("../tenancy")
const fetch = require("node-fetch")
const { getCouch } = require("./index")
@@ -15,25 +15,11 @@ exports.ViewNames = {
exports.StaticDatabases = StaticDatabases
-const PRE_APP = "app"
-const PRE_DEV = "dev"
-
-const DocumentTypes = {
- USER: "us",
- WORKSPACE: "workspace",
- CONFIG: "config",
- TEMPLATE: "template",
- APP: PRE_APP,
- DEV: PRE_DEV,
- APP_DEV: `${PRE_APP}${SEPARATOR}${PRE_DEV}`,
- APP_METADATA: `${PRE_APP}${SEPARATOR}metadata`,
- ROLE: "role",
-}
-
exports.DocumentTypes = DocumentTypes
exports.APP_PREFIX = DocumentTypes.APP + SEPARATOR
exports.APP_DEV = exports.APP_DEV_PREFIX = DocumentTypes.APP_DEV + SEPARATOR
exports.SEPARATOR = SEPARATOR
+exports.getTenantIDFromAppID = getTenantIDFromAppID
/**
* If creating DB allDocs/query params with only a single top level ID this can be used, this
@@ -70,26 +56,6 @@ function isDevApp(app) {
return exports.isDevAppID(app.appId)
}
-/**
- * Given an app ID this will attempt to retrieve the tenant ID from it.
- * @return {null|string} The tenant ID found within the app ID.
- */
-exports.getTenantIDFromAppID = appId => {
- if (!appId) {
- return null
- }
- const split = appId.split(SEPARATOR)
- const hasDev = split[1] === DocumentTypes.DEV
- if ((hasDev && split.length === 3) || (!hasDev && split.length === 2)) {
- return null
- }
- if (hasDev) {
- return split[2]
- } else {
- return split[1]
- }
-}
-
/**
* Generates a new workspace ID.
* @returns {string} The new workspace ID which the workspace doc can be stored under.
diff --git a/packages/auth/src/redis/index.js b/packages/auth/src/redis/index.js
index 48a24ad0bc..0ee17265ce 100644
--- a/packages/auth/src/redis/index.js
+++ b/packages/auth/src/redis/index.js
@@ -191,6 +191,12 @@ class RedisWrapper {
}
}
+ async getTTL(key) {
+ const db = this._db
+ const prefixedKey = addDbPrefix(db, key)
+ return CLIENT.ttl(prefixedKey)
+ }
+
async setExpiry(key, expirySeconds) {
const db = this._db
const prefixedKey = addDbPrefix(db, key)
diff --git a/packages/auth/src/tenancy/tenancy.js b/packages/auth/src/tenancy/tenancy.js
index 67dbfd5619..2cd05ea925 100644
--- a/packages/auth/src/tenancy/tenancy.js
+++ b/packages/auth/src/tenancy/tenancy.js
@@ -1,5 +1,5 @@
const { getDB } = require("../db")
-const { SEPARATOR, StaticDatabases } = require("../db/constants")
+const { SEPARATOR, StaticDatabases, DocumentTypes } = require("../db/constants")
const { getTenantId, DEFAULT_TENANT_ID, isMultiTenant } = require("./context")
const env = require("../environment")
@@ -117,3 +117,34 @@ exports.getTenantUser = async identifier => {
return null
}
}
+
+/**
+ * Given an app ID this will attempt to retrieve the tenant ID from it.
+ * @return {null|string} The tenant ID found within the app ID.
+ */
+exports.getTenantIDFromAppID = appId => {
+ if (!appId) {
+ return null
+ }
+ const split = appId.split(SEPARATOR)
+ const hasDev = split[1] === DocumentTypes.DEV
+ if ((hasDev && split.length === 3) || (!hasDev && split.length === 2)) {
+ return null
+ }
+ if (hasDev) {
+ return split[2]
+ } else {
+ return split[1]
+ }
+}
+
+exports.isUserInAppTenant = (appId, user = null) => {
+ let userTenantId
+ if (user) {
+ userTenantId = user.tenantId || DEFAULT_TENANT_ID
+ } else {
+ userTenantId = getTenantId()
+ }
+ const tenantId = exports.getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID
+ return tenantId === userTenantId
+}
diff --git a/packages/bbui/package.json b/packages/bbui/package.json
index facc46b82d..6c838587b0 100644
--- a/packages/bbui/package.json
+++ b/packages/bbui/package.json
@@ -1,7 +1,7 @@
{
"name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.",
- "version": "0.9.153-alpha.1",
+ "version": "0.9.160-alpha.0",
"license": "AGPL-3.0",
"svelte": "src/index.js",
"module": "dist/bbui.es.js",
diff --git a/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js
new file mode 100644
index 0000000000..bc2619c53d
--- /dev/null
+++ b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js
@@ -0,0 +1,41 @@
+context("Add Multi-Option Datatype", () => {
+ before(() => {
+ cy.login()
+ cy.createTestApp()
+ })
+
+ it("should create a new table, with data", () => {
+ cy.createTable("Multi Data")
+ cy.addColumn("Multi Data", "Test Data", "Multi-select", "1\n2\n3\n4\n5")
+ cy.addRowMultiValue(["1", "2", "3", "4", "5"])
+ })
+
+ it ("should add form with multi select picker, containing 5 options", () => {
+ cy.navigateToFrontend()
+ cy.wait(500)
+ // Add data provider
+ cy.get(`[data-cy="category-Data Provider"]`).click()
+ cy.get('[data-cy="dataSource-prop-control"]').click()
+ cy.get(".dropdown").contains("Multi Data").click()
+ cy.wait(500)
+ // Add Form with schema to match table
+ cy.addComponent("Form", "Form")
+ cy.get('[data-cy="dataSource-prop-control"').click()
+ cy.get(".dropdown").contains("Multi Data").click()
+ cy.wait(500)
+ // Add multi-select picker to form
+ cy.addComponent("Form", "Multi-select Picker").then((componentId) => {
+ cy.get('[data-cy="field-prop-control"]').type("Test Data").type('{enter}')
+ cy.wait(1000)
+ cy.getComponent(componentId).contains("Choose some options").click()
+ // Check picker has 5 items
+ cy.getComponent(componentId).find('li').should('have.length', 5)
+ // Select all items
+ for (let i = 1; i < 6; i++) {
+ cy.getComponent(componentId).find('li').contains(i).click()
+ }
+ // Check items have been selected
+ cy.getComponent(componentId).find('.spectrum-Picker-label').contains("(5)")
+ })
+ })
+})
diff --git a/packages/builder/cypress/integration/addRadioButtons.spec.js b/packages/builder/cypress/integration/addRadioButtons.spec.js
new file mode 100644
index 0000000000..68d0a74d55
--- /dev/null
+++ b/packages/builder/cypress/integration/addRadioButtons.spec.js
@@ -0,0 +1,35 @@
+context("Add Radio Buttons", () => {
+ before(() => {
+ cy.login()
+ cy.createTestApp()
+ })
+
+it("should add Radio Buttons options picker on form, add data, and confirm", () => {
+ cy.navigateToFrontend()
+ cy.addComponent("Form", "Form")
+ cy.addComponent("Form", "Options Picker").then((componentId) => {
+ // Provide field setting
+ cy.get(`[data-cy="field-prop-control"]`).type("1")
+ // Open dropdown and select Radio buttons
+ cy.get(`[data-cy="optionsType-prop-control"]`).click().then(() => {
+ cy.get('.spectrum-Popover').contains('Radio buttons')
+ .wait(500)
+ .click()
+ })
+ const radioButtonsTotal = 3
+ // Add values and confirm total
+ addRadioButtonData(radioButtonsTotal)
+ cy.getComponent(componentId).find('[type="radio"]')
+ .should('have.length', radioButtonsTotal)
+ })
+ })
+
+ const addRadioButtonData = (totalRadioButtons) => {
+ cy.get(`[data-cy="optionsSource-prop-control"]`).click().then(() => {
+ cy.get('.spectrum-Popover').contains('Custom')
+ .wait(500)
+ .click()
+ })
+ cy.addCustomSourceOptions(totalRadioButtons)
+ }
+})
diff --git a/packages/builder/cypress/integration/createTable.spec.js b/packages/builder/cypress/integration/createTable.spec.js
index 876894e5aa..ccb9ae7929 100644
--- a/packages/builder/cypress/integration/createTable.spec.js
+++ b/packages/builder/cypress/integration/createTable.spec.js
@@ -37,7 +37,7 @@ context("Create a Table", () => {
cy.get(".spectrum-Modal input").clear()
cy.get(".spectrum-Modal input").type("RoverUpdated")
cy.contains("Save").click()
- cy.contains("RoverUpdated").should("have.text", "RoverUpdated")
+ cy.contains("Updated").should("have.text", "Updated")
})
it("deletes a row", () => {
diff --git a/packages/builder/cypress/integration/createView.spec.js b/packages/builder/cypress/integration/createView.spec.js
index 62d0740a39..e82ab67c0d 100644
--- a/packages/builder/cypress/integration/createView.spec.js
+++ b/packages/builder/cypress/integration/createView.spec.js
@@ -62,7 +62,7 @@ context("Create a View", () => {
cy.get(".spectrum-Picker-label").eq(1).click()
cy.contains("age").click({ force: true })
- cy.contains("Save").click()
+ cy.get(".spectrum-Button").contains("Save").click({ force: true })
})
cy.wait(1000)
@@ -123,7 +123,7 @@ context("Create a View", () => {
cy.contains(".nav-item", "Test View")
.find(".actions .icon")
.click({ force: true })
- cy.contains("Edit").click()
+ cy.get(".spectrum-Menu-itemLabel").contains("Edit").click()
cy.get(".modal-inner-wrapper").within(() => {
cy.get("input").type(" Updated")
cy.contains("Save").click()
@@ -138,8 +138,8 @@ context("Create a View", () => {
.click({ force: true })
cy.contains("Delete").click()
cy.contains("Delete View").click()
- cy.wait(1000)
- cy.contains("TestView Updated").should("not.be.visible")
+ cy.wait(500)
+ cy.contains("TestView Updated").should("not.exist")
})
})
diff --git a/packages/builder/cypress/integration/customThemingProperties.spec.js b/packages/builder/cypress/integration/customThemingProperties.spec.js
new file mode 100644
index 0000000000..47cb81a8a6
--- /dev/null
+++ b/packages/builder/cypress/integration/customThemingProperties.spec.js
@@ -0,0 +1,61 @@
+context("Custom Theming Properties", () => {
+ before(() => {
+ cy.login()
+ cy.createTestApp()
+ cy.navigateToFrontend()
+ })
+
+ // Default Values
+ // Button roundness = Large
+ // Primary colour = Blue 600
+ // Primary colour (hover) = Blue 500
+ // Navigation bar background colour = Gray 100
+ // Navigation bar text colour = Gray 800
+ it("should reset the color property values", () => {
+ // Open Theme modal and change colours
+ cy.get(".spectrum-ActionButton-label").contains("Theme").click()
+ cy.get(".spectrum-Picker").contains("Large").click()
+ .parents()
+ .get(".spectrum-Menu-itemLabel").contains("None").click()
+ changeThemeColors()
+ // Reset colours
+ cy.get(".spectrum-Button-label").contains("Reset").click({force: true})
+ // Check values have reset
+ checkThemeColorDefaults()
+ })
+
+ const changeThemeColors = () => {
+ // Changes the theme colours
+ cy.get(".spectrum-FieldLabel").contains("Primary color")
+ .parent().find(".container.svelte-z3cm5a").click()
+ .find('[title="Red 400"]').click()
+ cy.get(".spectrum-FieldLabel").contains("Primary color (hover)")
+ .parent().find(".container.svelte-z3cm5a").click()
+ .find('[title="Orange 400"]').click()
+ cy.get(".spectrum-FieldLabel").contains("Navigation bar background color")
+ .parent().find(".container.svelte-z3cm5a").click()
+ .find('[title="Yellow 400"]').click()
+ cy.get(".spectrum-FieldLabel").contains("Navigation bar text color")
+ .parent().find(".container.svelte-z3cm5a").click()
+ .find('[title="Green 400"]').click()
+ }
+
+ const checkThemeColorDefaults = () => {
+ cy.get(".spectrum-FieldLabel").contains("Primary color")
+ .parent().find(".container.svelte-z3cm5a").click()
+ .get('[title="Blue 600"]').children().find('[aria-label="Checkmark"]')
+ cy.get(".spectrum-Dialog-grid").click()
+ cy.get(".spectrum-FieldLabel").contains("Primary color (hover)")
+ .parent().find(".container.svelte-z3cm5a").click()
+ .get('[title="Blue 500"]').children().find('[aria-label="Checkmark"]')
+ cy.get(".spectrum-Dialog-grid").click()
+ cy.get(".spectrum-FieldLabel").contains("Navigation bar background color")
+ .parent().find(".container.svelte-z3cm5a").click()
+ .get('[title="Gray 100"]').children().find('[aria-label="Checkmark"]')
+ cy.get(".spectrum-Dialog-grid").click()
+ cy.get(".spectrum-FieldLabel").contains("Navigation bar text color")
+ .parent().find(".container.svelte-z3cm5a").click()
+ .get('[title="Gray 800"]').children().find('[aria-label="Checkmark"]')
+ }
+
+})
diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js
index cbdaa27270..c8e01435aa 100644
--- a/packages/builder/cypress/support/commands.js
+++ b/packages/builder/cypress/support/commands.js
@@ -5,9 +5,13 @@
// ***********************************************
//
+Cypress.on('uncaught:exception', (err, runnable) => {
+ return false
+})
+
Cypress.Commands.add("login", () => {
cy.visit(`localhost:${Cypress.env("PORT")}/builder`)
- cy.wait(500)
+ cy.wait(2000)
cy.url().then(url => {
if (url.includes("builder/admin")) {
// create admin user
@@ -22,6 +26,7 @@ Cypress.Commands.add("login", () => {
cy.get("input").first().type("test@test.com")
cy.get('input[type="password"]').type("test")
cy.get("button").first().click()
+ cy.wait(1000)
})
}
})
@@ -100,24 +105,32 @@ Cypress.Commands.add("createTable", tableName => {
cy.contains(tableName).should("be.visible")
})
-Cypress.Commands.add("addColumn", (tableName, columnName, type) => {
- // Select Table
- cy.selectTable(tableName)
- cy.contains(".nav-item", tableName).click()
- cy.contains("Create column").click()
+Cypress.Commands.add(
+ "addColumn",
+ (tableName, columnName, type, multiOptions = null) => {
+ // Select Table
+ cy.selectTable(tableName)
+ cy.contains(".nav-item", tableName).click()
+ cy.contains("Create column").click()
- // Configure column
- cy.get(".spectrum-Modal").within(() => {
- cy.get("input").first().type(columnName).blur()
+ // Configure column
+ cy.get(".spectrum-Modal").within(() => {
+ cy.get("input").first().type(columnName).blur()
- // Unset table display column
- cy.contains("display column").click({ force: true })
- cy.get(".spectrum-Picker-label").click()
- cy.contains(type).click()
+ // Unset table display column
+ cy.contains("display column").click({ force: true })
+ cy.get(".spectrum-Picker-label").click()
+ cy.contains(type).click()
- cy.contains("Save Column").click()
- })
-})
+ // Add options for Multi-select Type
+ if (multiOptions !== null) {
+ cy.get(".spectrum-Textfield-input").eq(1).type(multiOptions)
+ }
+
+ cy.contains("Save Column").click()
+ })
+ }
+)
Cypress.Commands.add("addRow", values => {
cy.contains("Create row").click()
@@ -129,6 +142,21 @@ Cypress.Commands.add("addRow", values => {
})
})
+Cypress.Commands.add("addRowMultiValue", values => {
+ cy.contains("Create row").click()
+ cy.get(".spectrum-Form-itemField")
+ .click()
+ .then(() => {
+ cy.get(".spectrum-Popover").within(() => {
+ for (let i = 0; i < values.length; i++) {
+ cy.get(".spectrum-Menu-item").eq(i).click()
+ }
+ })
+ cy.get(".spectrum-Dialog-grid").click("top")
+ cy.get(".spectrum-ButtonGroup").contains("Create").click()
+ })
+})
+
Cypress.Commands.add("createUser", email => {
// quick hacky recorded way to create a user
cy.contains("Users").click()
@@ -147,7 +175,9 @@ Cypress.Commands.add("addComponent", (category, component) => {
if (category) {
cy.get(`[data-cy="category-${category}"]`).click()
}
- cy.get(`[data-cy="component-${component}"]`).click()
+ if (component) {
+ cy.get(`[data-cy="component-${component}"]`).click()
+ }
cy.wait(1000)
cy.location().then(loc => {
const params = loc.pathname.split("/")
@@ -169,8 +199,11 @@ Cypress.Commands.add("getComponent", componentId => {
})
Cypress.Commands.add("navigateToFrontend", () => {
+ // Clicks on Design tab and then the Home nav item
cy.wait(1000)
cy.contains("Design").click()
+ cy.get(".spectrum-Search").type("/")
+ cy.get(".nav-item").contains("Home").click()
})
Cypress.Commands.add("createScreen", (screenName, route) => {
@@ -193,3 +226,24 @@ Cypress.Commands.add("selectTable", tableName => {
cy.expandBudibaseConnection()
cy.contains(".nav-item", tableName).click()
})
+
+Cypress.Commands.add("addCustomSourceOptions", totalOptions => {
+ cy.get(".spectrum-ActionButton")
+ .contains("Define Options")
+ .click()
+ .then(() => {
+ for (let i = 0; i < totalOptions; i++) {
+ // Add radio button options
+ cy.get(".spectrum-Button")
+ .contains("Add Option")
+ .click({ force: true })
+ .then(() => {
+ cy.wait(500)
+ cy.get("[placeholder='Label']").eq(i).type(i)
+ cy.get("[placeholder='Value']").eq(i).type(i)
+ })
+ }
+ // Save options
+ cy.get(".spectrum-Button").contains("Save").click({ force: true })
+ })
+})
diff --git a/packages/builder/package.json b/packages/builder/package.json
index 9ee2044a1a..71e7e8c9a8 100644
--- a/packages/builder/package.json
+++ b/packages/builder/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/builder",
- "version": "0.9.153-alpha.1",
+ "version": "0.9.160-alpha.0",
"license": "AGPL-3.0",
"private": true,
"scripts": {
@@ -65,10 +65,10 @@
}
},
"dependencies": {
- "@budibase/bbui": "^0.9.153-alpha.1",
- "@budibase/client": "^0.9.153-alpha.1",
+ "@budibase/bbui": "^0.9.160-alpha.0",
+ "@budibase/client": "^0.9.160-alpha.0",
"@budibase/colorpicker": "1.1.2",
- "@budibase/string-templates": "^0.9.153-alpha.1",
+ "@budibase/string-templates": "^0.9.160-alpha.0",
"@sentry/browser": "5.19.1",
"@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1",
diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js
index c567454eff..9110aa1430 100644
--- a/packages/builder/src/builderStore/store/frontend.js
+++ b/packages/builder/src/builderStore/store/frontend.js
@@ -67,6 +67,14 @@ export const getFrontendStore = () => {
initialise: async pkg => {
const { layouts, screens, application, clientLibPath } = pkg
const components = await fetchComponentLibDefinitions(application.appId)
+ // make sure app isn't locked
+ if (
+ components &&
+ components.status === 400 &&
+ components.message?.includes("lock")
+ ) {
+ throw { ok: false, reason: "locked" }
+ }
store.update(state => ({
...state,
libraries: application.componentLibraries,
diff --git a/packages/builder/src/components/backend/DataTable/ViewDataTable.svelte b/packages/builder/src/components/backend/DataTable/ViewDataTable.svelte
index 9913333054..a52fbdb177 100644
--- a/packages/builder/src/components/backend/DataTable/ViewDataTable.svelte
+++ b/packages/builder/src/components/backend/DataTable/ViewDataTable.svelte
@@ -68,5 +68,5 @@
{/if}