diff --git a/lerna.json b/lerna.json
index c188d0d8d0..0071cf1031 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "version": "1.0.159-alpha.2",
+ "version": "1.0.164-alpha.3",
"npmClient": "yarn",
"packages": [
"packages/*"
diff --git a/package.json b/package.json
index fb6d9da990..84f1999ead 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,8 @@
"private": true,
"devDependencies": {
"@rollup/plugin-json": "^4.0.2",
+ "@types/mongodb": "3.6.3",
+ "@typescript-eslint/parser": "4.28.0",
"babel-eslint": "^10.0.3",
"eslint": "^7.28.0",
"eslint-plugin-cypress": "^2.11.3",
@@ -16,7 +18,6 @@
"rimraf": "^3.0.2",
"rollup-plugin-replace": "^2.2.0",
"svelte": "^3.38.2",
- "@typescript-eslint/parser": "4.28.0",
"typescript": "4.5.5"
},
"scripts": {
diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json
index fc1fa48c6c..e78c8a7c2b 100644
--- a/packages/backend-core/package.json
+++ b/packages/backend-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/backend-core",
- "version": "1.0.159-alpha.2",
+ "version": "1.0.164-alpha.3",
"description": "Budibase backend core libraries used in server and worker",
"main": "src/index.js",
"author": "Budibase",
diff --git a/packages/backend-core/src/db/tests/utils.spec.js b/packages/backend-core/src/db/tests/utils.spec.js
index ebef670a81..f8b9549d46 100644
--- a/packages/backend-core/src/db/tests/utils.spec.js
+++ b/packages/backend-core/src/db/tests/utils.spec.js
@@ -1,61 +1,194 @@
+require("../../tests/utilities/dbConfig");
const {
generateAppID,
getDevelopmentAppID,
getProdAppID,
isDevAppID,
isProdAppID,
+ getPlatformUrl,
+ getScopedConfig
} = require("../utils")
+const tenancy = require("../../tenancy");
+const { Configs, DEFAULT_TENANT_ID } = require("../../constants");
+const env = require("../../environment")
-function getID() {
- const appId = generateAppID()
- const split = appId.split("_")
- const uuid = split[split.length - 1]
- const devAppId = `app_dev_${uuid}`
- return { appId, devAppId, split, uuid }
+describe("utils", () => {
+ describe("app ID manipulation", () => {
+
+ function getID() {
+ const appId = generateAppID()
+ const split = appId.split("_")
+ const uuid = split[split.length - 1]
+ const devAppId = `app_dev_${uuid}`
+ return { appId, devAppId, split, uuid }
+ }
+
+ it("should be able to generate a new app ID", () => {
+ expect(generateAppID().startsWith("app_")).toEqual(true)
+ })
+
+ it("should be able to convert a production app ID to development", () => {
+ const { appId, uuid } = getID()
+ expect(getDevelopmentAppID(appId)).toEqual(`app_dev_${uuid}`)
+ })
+
+ it("should be able to convert a development app ID to development", () => {
+ const { devAppId, uuid } = getID()
+ expect(getDevelopmentAppID(devAppId)).toEqual(`app_dev_${uuid}`)
+ })
+
+ it("should be able to convert a development ID to a production", () => {
+ const { devAppId, uuid } = getID()
+ expect(getProdAppID(devAppId)).toEqual(`app_${uuid}`)
+ })
+
+ it("should be able to convert a production ID to production", () => {
+ const { appId, uuid } = getID()
+ expect(getProdAppID(appId)).toEqual(`app_${uuid}`)
+ })
+
+ it("should be able to confirm dev app ID is development", () => {
+ const { devAppId } = getID()
+ expect(isDevAppID(devAppId)).toEqual(true)
+ })
+
+ it("should be able to confirm prod app ID is not development", () => {
+ const { appId } = getID()
+ expect(isDevAppID(appId)).toEqual(false)
+ })
+
+ it("should be able to confirm prod app ID is prod", () => {
+ const { appId } = getID()
+ expect(isProdAppID(appId)).toEqual(true)
+ })
+
+ it("should be able to confirm dev app ID is not prod", () => {
+ const { devAppId } = getID()
+ expect(isProdAppID(devAppId)).toEqual(false)
+ })
+ })
+})
+
+const DB_URL = "http://dburl.com"
+const DEFAULT_URL = "http://localhost:10000"
+const ENV_URL = "http://env.com"
+
+const setDbPlatformUrl = async () => {
+ const db = tenancy.getGlobalDB()
+ db.put({
+ _id: "config_settings",
+ type: Configs.SETTINGS,
+ config: {
+ platformUrl: DB_URL
+ }
+ })
}
-describe("app ID manipulation", () => {
- it("should be able to generate a new app ID", () => {
- expect(generateAppID().startsWith("app_")).toEqual(true)
+const clearSettingsConfig = async () => {
+ await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
+ const db = tenancy.getGlobalDB()
+ try {
+ const config = await db.get("config_settings")
+ await db.remove("config_settings", config._rev)
+ } catch (e) {
+ if (e.status !== 404) {
+ throw e
+ }
+ }
+ })
+}
+
+describe("getPlatformUrl", () => {
+ describe("self host", () => {
+
+ beforeEach(async () => {
+ env._set("SELF_HOST", 1)
+ await clearSettingsConfig()
+ })
+
+ it("gets the default url", async () => {
+ await tenancy.doInTenant(null, async () => {
+ const url = await getPlatformUrl()
+ expect(url).toBe(DEFAULT_URL)
+ })
+ })
+
+ it("gets the platform url from the environment", async () => {
+ await tenancy.doInTenant(null, async () => {
+ env._set("PLATFORM_URL", ENV_URL)
+ const url = await getPlatformUrl()
+ expect(url).toBe(ENV_URL)
+ })
+ })
+
+ it("gets the platform url from the database", async () => {
+ await tenancy.doInTenant(null, async () => {
+ await setDbPlatformUrl()
+ const url = await getPlatformUrl()
+ expect(url).toBe(DB_URL)
+ })
+ })
})
- it("should be able to convert a production app ID to development", () => {
- const { appId, uuid } = getID()
- expect(getDevelopmentAppID(appId)).toEqual(`app_dev_${uuid}`)
- })
- it("should be able to convert a development app ID to development", () => {
- const { devAppId, uuid } = getID()
- expect(getDevelopmentAppID(devAppId)).toEqual(`app_dev_${uuid}`)
- })
+ describe("cloud", () => {
+ const TENANT_AWARE_URL = "http://default.env.com"
- it("should be able to convert a development ID to a production", () => {
- const { devAppId, uuid } = getID()
- expect(getProdAppID(devAppId)).toEqual(`app_${uuid}`)
- })
+ beforeEach(async () => {
+ env._set("SELF_HOSTED", 0)
+ env._set("MULTI_TENANCY", 1)
+ env._set("PLATFORM_URL", ENV_URL)
+ await clearSettingsConfig()
+ })
- it("should be able to convert a production ID to production", () => {
- const { appId, uuid } = getID()
- expect(getProdAppID(appId)).toEqual(`app_${uuid}`)
- })
+ it("gets the platform url from the environment without tenancy", async () => {
+ await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
+ const url = await getPlatformUrl({ tenantAware: false })
+ expect(url).toBe(ENV_URL)
+ })
+ })
- it("should be able to confirm dev app ID is development", () => {
- const { devAppId } = getID()
- expect(isDevAppID(devAppId)).toEqual(true)
- })
+ it("gets the platform url from the environment with tenancy", async () => {
+ await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
+ const url = await getPlatformUrl()
+ expect(url).toBe(TENANT_AWARE_URL)
+ })
+ })
- it("should be able to confirm prod app ID is not development", () => {
- const { appId } = getID()
- expect(isDevAppID(appId)).toEqual(false)
+ it("never gets the platform url from the database", async () => {
+ await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
+ await setDbPlatformUrl()
+ const url = await getPlatformUrl()
+ expect(url).toBe(TENANT_AWARE_URL)
+ })
+ })
})
+})
- it("should be able to confirm prod app ID is prod", () => {
- const { appId } = getID()
- expect(isProdAppID(appId)).toEqual(true)
- })
+describe("getScopedConfig", () => {
+ describe("settings config", () => {
- it("should be able to confirm dev app ID is not prod", () => {
- const { devAppId } = getID()
- expect(isProdAppID(devAppId)).toEqual(false)
+ beforeEach(async () => {
+ env._set("SELF_HOSTED", 1)
+ env._set("PLATFORM_URL", "")
+ await clearSettingsConfig()
+ })
+
+ it("returns the platform url with an existing config", async () => {
+ await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
+ await setDbPlatformUrl()
+ const db = tenancy.getGlobalDB()
+ const config = await getScopedConfig(db, { type: Configs.SETTINGS })
+ expect(config.platformUrl).toBe(DB_URL)
+ })
+ })
+
+ it("returns the platform url without an existing config", async () => {
+ await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
+ const db = tenancy.getGlobalDB()
+ const config = await getScopedConfig(db, { type: Configs.SETTINGS })
+ expect(config.platformUrl).toBe(DEFAULT_URL)
+ })
+ })
})
-})
\ No newline at end of file
+})
diff --git a/packages/backend-core/src/db/utils.js b/packages/backend-core/src/db/utils.js
index 5f7bf794c2..d6eb0aa89e 100644
--- a/packages/backend-core/src/db/utils.js
+++ b/packages/backend-core/src/db/utils.js
@@ -9,7 +9,7 @@ const {
APP_PREFIX,
APP_DEV,
} = require("./constants")
-const { getTenantId, getGlobalDBName } = require("../tenancy")
+const { getTenantId, getGlobalDBName, getGlobalDB } = require("../tenancy")
const fetch = require("node-fetch")
const { doWithDB, allDbs } = require("./index")
const { getCouchInfo } = require("./pouch")
@@ -392,9 +392,7 @@ const getScopedFullConfig = async function (db, { type, user, workspace }) {
// always provide the platform URL
if (type === Configs.SETTINGS) {
if (scopedConfig && scopedConfig.doc) {
- scopedConfig.doc.config.platformUrl = await getPlatformUrl(
- scopedConfig.doc.config
- )
+ scopedConfig.doc.config.platformUrl = await getPlatformUrl()
} else {
scopedConfig = {
doc: {
@@ -409,19 +407,30 @@ const getScopedFullConfig = async function (db, { type, user, workspace }) {
return scopedConfig && scopedConfig.doc
}
-const getPlatformUrl = async settings => {
+const getPlatformUrl = async (opts = { tenantAware: true }) => {
let platformUrl = env.PLATFORM_URL || "http://localhost:10000"
- if (!env.SELF_HOSTED && env.MULTI_TENANCY) {
+ if (!env.SELF_HOSTED && env.MULTI_TENANCY && opts.tenantAware) {
// cloud and multi tenant - add the tenant to the default platform url
const tenantId = getTenantId()
if (!platformUrl.includes("localhost:")) {
platformUrl = platformUrl.replace("://", `://${tenantId}.`)
}
- } else {
+ } else if (env.SELF_HOSTED) {
+ const db = getGlobalDB()
+ // get the doc directly instead of with getScopedConfig to prevent loop
+ let settings
+ try {
+ settings = await db.get(generateConfigID({ type: Configs.SETTINGS }))
+ } catch (e) {
+ if (e.status !== 404) {
+ throw e
+ }
+ }
+
// self hosted - check for platform url override
- if (settings && settings.platformUrl) {
- platformUrl = settings.platformUrl
+ if (settings && settings.config && settings.config.platformUrl) {
+ platformUrl = settings.config.platformUrl
}
}
diff --git a/packages/backend-core/src/middleware/passport/datasource/google.js b/packages/backend-core/src/middleware/passport/datasource/google.js
index 96c7f99953..53719b8350 100644
--- a/packages/backend-core/src/middleware/passport/datasource/google.js
+++ b/packages/backend-core/src/middleware/passport/datasource/google.js
@@ -21,20 +21,12 @@ async function fetchGoogleCreds() {
)
}
-async function platformUrl() {
- const db = getGlobalDB()
- const publicConfig = await getScopedConfig(db, {
- type: Configs.SETTINGS,
- })
- return getPlatformUrl(publicConfig)
-}
-
async function preAuth(passport, ctx, next) {
// get the relevant config
const googleConfig = await fetchGoogleCreds()
- const platUrl = await platformUrl()
+ const platformUrl = await getPlatformUrl({ tenantAware: false })
- let callbackUrl = `${platUrl}/api/global/auth/datasource/google/callback`
+ let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`
const strategy = await google.strategyFactory(googleConfig, callbackUrl)
if (!ctx.query.appId || !ctx.query.datasourceId) {
@@ -51,9 +43,9 @@ async function preAuth(passport, ctx, next) {
async function postAuth(passport, ctx, next) {
// get the relevant config
const config = await fetchGoogleCreds()
- const platUrl = await platformUrl()
+ const platformUrl = await getPlatformUrl({ tenantAware: false })
- let callbackUrl = `${platUrl}/api/global/auth/datasource/google/callback`
+ let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`
const strategy = await google.strategyFactory(
config,
callbackUrl,
diff --git a/packages/backend-core/src/middleware/passport/tests/oidc.spec.js b/packages/backend-core/src/middleware/passport/tests/oidc.spec.js
index bfe9f97dc0..c5e9fe0034 100644
--- a/packages/backend-core/src/middleware/passport/tests/oidc.spec.js
+++ b/packages/backend-core/src/middleware/passport/tests/oidc.spec.js
@@ -71,7 +71,7 @@ describe("oidc", () => {
describe("authenticate", () => {
afterEach(() => {
- jest.clearAllMocks();
+ jest.clearAllMocks()
});
// mock third party common authentication
@@ -80,10 +80,10 @@ describe("oidc", () => {
// mock the passport callback
const mockDone = jest.fn()
+ const mockSaveUserFn = jest.fn()
async function doAuthenticate() {
const oidc = require("../oidc")
- const mockSaveUserFn = jest.fn()
const authenticate = await oidc.buildVerifyFn(mockSaveUserFn)
await authenticate(
@@ -105,11 +105,13 @@ describe("oidc", () => {
expect(authenticateThirdParty).toHaveBeenCalledWith(
user,
false,
- mockDone)
+ mockDone,
+ mockSaveUserFn,
+ )
}
it("delegates authentication to third party common", async () => {
- doTest()
+ await doTest()
})
it("uses JWT email to get email", async () => {
@@ -118,7 +120,7 @@ describe("oidc", () => {
email : "mock@budibase.com"
}
- doTest()
+ await doTest()
})
it("uses JWT username to get email", async () => {
@@ -127,7 +129,7 @@ describe("oidc", () => {
preferred_username : "mock@budibase.com"
}
- doTest()
+ await doTest()
})
it("uses JWT invalid username to get email", async () => {
diff --git a/packages/bbui/package.json b/packages/bbui/package.json
index 68a84afcdb..9b067e3b14 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": "1.0.159-alpha.2",
+ "version": "1.0.164-alpha.3",
"license": "MPL-2.0",
"svelte": "src/index.js",
"module": "dist/bbui.es.js",
@@ -38,7 +38,7 @@
],
"dependencies": {
"@adobe/spectrum-css-workflow-icons": "^1.2.1",
- "@budibase/string-templates": "^1.0.159-alpha.2",
+ "@budibase/string-templates": "^1.0.164-alpha.3",
"@spectrum-css/actionbutton": "^1.0.1",
"@spectrum-css/actiongroup": "^1.0.1",
"@spectrum-css/avatar": "^3.0.2",
diff --git a/packages/bbui/src/Form/Core/DatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker.svelte
index 1d0d32b03c..73ba7bb642 100644
--- a/packages/bbui/src/Form/Core/DatePicker.svelte
+++ b/packages/bbui/src/Form/Core/DatePicker.svelte
@@ -58,6 +58,11 @@
if (timeOnly) {
newValue = `2000-01-01T${newValue.split("T")[1]}`
}
+ // date only, offset for timezone so always right date
+ else if (!enableTime) {
+ const offset = dates[0].getTimezoneOffset() * 60000
+ newValue = new Date(dates[0].getTime() - offset).toISOString()
+ }
dispatch("change", newValue)
}
diff --git a/packages/bbui/src/Form/Core/TextField.svelte b/packages/bbui/src/Form/Core/TextField.svelte
index 78b698eed2..6a64876a2c 100644
--- a/packages/bbui/src/Form/Core/TextField.svelte
+++ b/packages/bbui/src/Form/Core/TextField.svelte
@@ -1,6 +1,6 @@
{/if}
{
@@ -33,6 +34,7 @@
{placeholder}
{type}
{quiet}
+ {autofocus}
on:change={onChange}
on:click
on:input
diff --git a/packages/builder/cypress/fixtures/exported-app.txt b/packages/builder/cypress/fixtures/exported-app.txt
new file mode 100644
index 0000000000..28aeaf958a
--- /dev/null
+++ b/packages/builder/cypress/fixtures/exported-app.txt
@@ -0,0 +1,3 @@
+{"version":"1.2.9","db_type":"http","start_time":"2022-05-12T13:47:50.453Z","db_info":{"db_name":"app_dev_7cae7fa4db8745da848f91430a8211bf","purge_seq":"0-g1AAAABXeJzLYWBgYMpgTmEQTM4vTc5ISXIwNDLXMwBCwxyQVB4LkGRoAFL_gSArkQGP2kSGpHqIoiwAtOgYRA","update_seq":"11-g1AAAACbeJzLYWBgYMpgTmEQTM4vTc5ISXIwNDLXMwBCwxyQVB4LkGRoAFL_gSArgzmRPRcowJ5klmZgaZmKTR8e0xIZkuqhxrBAjEk0NzcwMsSmIQsA89QoWg","sizes":{"file":94626,"external":5665,"active":7627},"props":{},"doc_del_count":0,"doc_count":7,"disk_format_version":8,"compact_running":false,"cluster":{"q":2,"n":1,"w":1,"r":1},"instance_start_time":"0","host":"http://localhost:4005/app_dev_7cae7fa4db8745da848f91430a8211bf/","auto_compaction":false,"adapter":"http"}}
+{"docs":[{"_id":"_design/database","_rev":"4-ad6d41ef604ab34da380438c1be89521","views":{"by_link":{"map":"function (doc) {\n // everything in this must remain constant as its going to Pouch, no external variables\n if (doc.type === \"link\") {\n let doc1 = doc.doc1;\n let doc2 = doc.doc2;\n // eslint-disable-next-line no-undef\n emit([doc1.tableId, doc1.rowId], {\n id: doc2.rowId,\n thisId: doc1.rowId,\n fieldName: doc1.fieldName,\n });\n // if linking to same table can't emit twice\n if (doc1.tableId !== doc2.tableId) {\n // eslint-disable-next-line no-undef\n emit([doc2.tableId, doc2.rowId], {\n id: doc1.rowId,\n thisId: doc2.rowId,\n fieldName: doc2.fieldName,\n });\n }\n }\n }"},"screen_routes":{"map":"function(doc) {\n if (doc._id.startsWith(\"screen_\")) {\n emit(doc._id, {\n id: doc._id,\n routing: doc.routing,\n })\n }\n }"}},"indexes":{"rows":{"index":"function (doc) {\n function idx(input, prev) {\n for (let key of Object.keys(input)) {\n let idxKey = prev != null ? `${prev}.${key}` : key;\n idxKey = idxKey.replace(/ /g, \"_\");\n if (Array.isArray(input[key])) {\n for (let val of input[key]) {\n if (typeof val !== \"object\") {\n // eslint-disable-next-line no-undef\n index(idxKey, val, { store: true });\n }\n }\n }\n else if (key === \"_id\" || key === \"_rev\" || input[key] == null) {\n continue;\n }\n if (typeof input[key] === \"string\") {\n // eslint-disable-next-line no-undef\n index(idxKey, input[key].toLowerCase(), { store: true });\n }\n else if (typeof input[key] !== \"object\") {\n // eslint-disable-next-line no-undef\n index(idxKey, input[key], { store: true });\n }\n else {\n idx(input[key], idxKey);\n }\n }\n }\n if (doc._id.startsWith(\"ro_\")) {\n // eslint-disable-next-line no-undef\n index(\"default\", doc._id);\n idx(doc);\n }\n }","analyzer":"keyword"}},"_revisions":{"start":4,"ids":["ad6d41ef604ab34da380438c1be89521","cb47f4fd824d5e096ac8b76117e6f93d","68a9a1d1b01b327676ecbaa4b1e5b8a7","0b24e44a44af45e51e562fd124ce3007"]}},{"_id":"app_metadata","_rev":"2-a4fe55378bfec0fc71e58a1364ac9965","appId":"app_dev_7cae7fa4db8745da848f91430a8211bf","type":"app","version":"1.0.155-alpha.0","componentLibraries":["@budibase/standard-components"],"name":"My app","url":"/my-app","instance":{"_id":"app_dev_7cae7fa4db8745da848f91430a8211bf"},"tenantId":"default","updatedAt":"2022-05-12T13:47:28.756Z","createdAt":"2022-05-12T13:47:26.825Z","status":"development","_revisions":{"start":2,"ids":["a4fe55378bfec0fc71e58a1364ac9965","f0d06bdb6e6ae4781eb5c4aa224002ff"]}},{"_id":"layout_private_master","_rev":"1-c02411b58d697e38763889a375d52159","componentLibraries":["@budibase/standard-components"],"title":"My app","favicon":"./_shared/favicon.png","stylesheets":[],"name":"Navigation Layout","props":{"_id":"4f569166-a4f3-47ea-a09e-6d218c75586f","_instanceName":"Navigation Layout","_component":"@budibase/standard-components/layout","_children":[{"_id":"7fcf11e4-6f5b-4085-8e0d-9f3d44c98967","_component":"@budibase/standard-components/screenslot","_instanceName":"Screen slot","_styles":{"normal":{"flex":"1 1 auto","display":"flex","flex-direction":"column","justify-content":"flex-start","align-items":"stretch"},"hover":{},"active":{},"selected":{}},"_children":[]}],"_styles":{"active":{},"hover":{},"normal":{},"selected":{}},"title":"My app","navigation":"Top","width":"Large","links":[{"text":"Home","url":"/"}]}},{"_id":"layout_public_master","_rev":"1-d6bce47046d4d0de4f19a6ff95064109","componentLibraries":["@budibase/standard-components"],"title":"My app","favicon":"./_shared/favicon.png","stylesheets":[],"name":"Empty Layout","props":{"_id":"3723ffa1-f9e0-4c05-8013-98195c788ed6","_instanceName":"Empty Layout","_component":"@budibase/standard-components/layout","_children":[{"_id":"7fcf11e4-6f5b-4085-8e0d-9f3d44c98967","_component":"@budibase/standard-components/screenslot","_instanceName":"Screen slot","_styles":{"normal":{"flex":"1 1 auto","display":"flex","flex-direction":"column","justify-content":"flex-start","align-items":"stretch"},"hover":{},"active":{},"selected":{}},"_children":[]}],"_styles":{"active":{},"hover":{},"normal":{},"selected":{}},"navigation":"None","width":"Large","links":[{"text":"Home","url":"/"}]}},{"_id":"screen_b19c454fa5ae41ab874a8860623ab37c","_rev":"1-02dddd460ad14de50dc885aa362452c6","layoutId":"layout_private_master","props":{"_id":"c87457efbc05a43f39064d9dacc9d4b67","_component":"@budibase/standard-components/container","_styles":{"normal":{},"hover":{},"active":{},"selected":{}},"_children":[],"_instanceName":"New Screen","direction":"column","hAlign":"stretch","vAlign":"top","size":"grow","gap":"M"},"routing":{"route":"/home","roleId":"BASIC","roldId":"BASIC"},"name":"screen-id"},{"_id":"ta_users","_rev":"1-30a4344f056c24cf776d5736eb3c7ed5","type":"table","views":{},"name":"Users","schema":{"email":{"type":"string","constraints":{"type":"string","email":true,"length":{"maximum":""},"presence":true},"fieldName":"email","name":"email"},"firstName":{"name":"firstName","fieldName":"firstName","type":"string","constraints":{"type":"string","presence":false}},"lastName":{"name":"lastName","fieldName":"lastName","type":"string","constraints":{"type":"string","presence":false}},"roleId":{"fieldName":"roleId","name":"roleId","type":"options","constraints":{"type":"string","presence":false,"inclusion":["ADMIN","POWER","BASIC","PUBLIC"]}},"status":{"fieldName":"status","name":"status","type":"options","constraints":{"type":"string","presence":false,"inclusion":["active","inactive"]}}},"primaryDisplay":"email"}]}
+{"seq":"11-g1AAAACbeJzLYWBgYMpgTmEQTM4vTc5ISXIwNDLXMwBCwxyQVCJDUv3___-zMpgTWXKBAuxJiebmBkaG2DTgMSaPBUgyNACp_1DT2CGmmaUZWFqmYtOXBQAWQiha"}
diff --git a/packages/builder/cypress/integration/createApp.spec.js b/packages/builder/cypress/integration/createApp.spec.js
index a0b9924008..ce5e2bd0c2 100644
--- a/packages/builder/cypress/integration/createApp.spec.js
+++ b/packages/builder/cypress/integration/createApp.spec.js
@@ -1,4 +1,5 @@
import filterTests from '../support/filterTests'
+const interact = require('../support/interact')
filterTests(['smoke', 'all'], () => {
context("Create an Application", () => {
@@ -10,14 +11,14 @@ filterTests(['smoke', 'all'], () => {
if (!(Cypress.env("TEST_ENV"))) {
it("should show the new user UI/UX", () => {
- cy.visit(`${Cypress.config().baseUrl}/builder`)
- cy.get(`[data-cy="create-app-btn"]`).contains('Start from scratch').should("exist")
- cy.get(`[data-cy="import-app-btn"]`).should("exist")
+ cy.visit(`${Cypress.config().baseUrl}/builder/portal/apps/create`) //added /portal/apps/create
+ cy.get(interact.CREATE_APP_BUTTON).contains('Start from scratch').should("exist")
+ cy.get(interact.CREATE_APP_BUTTON).should("exist")
- cy.get(".template-category-filters").should("exist")
- cy.get(".template-categories").should("exist")
+ cy.get(interact.TEMPLATE_CATEGORY_FILTER).should("exist")
+ cy.get(interact.TEMPLATE_CATEGORY).should("exist")
- cy.get(".appTable").should("not.exist")
+ cy.get(interact.APP_TABLE).should("not.exist")
})
}
@@ -29,21 +30,21 @@ filterTests(['smoke', 'all'], () => {
.its("body")
.then(val => {
if (val.length > 0) {
- cy.get(".spectrum-Button").contains("Templates").click({force: true})
+ cy.get(interact.SPECTRUM_BUTTON_TEMPLATE).contains("Templates").click({force: true})
}
})
- cy.get(".template-category-filters").should("exist")
- cy.get(".template-categories").should("exist")
+ cy.get(interact.TEMPLATE_CATEGORY_FILTER).should("exist")
+ cy.get(interact.TEMPLATE_CATEGORY).should("exist")
- cy.get(".template-category").its('length').should('be.gt', 1)
- cy.get(".template-category-filters .spectrum-ActionButton").its('length').should('be.gt', 2)
+ cy.get(interact.TEMPLATE_CATEGORY_ACTIONGROUP).its('length').should('be.gt', 1)
+ cy.get(interact.TEMPLATE_CATEGORY_FILTER_ACTIONBUTTON).its('length').should('be.gt', 2)
- cy.get(".template-category-filters .spectrum-ActionButton").eq(1).click()
- cy.get(".template-category").should('have.length', 1)
+ cy.get(interact.TEMPLATE_CATEGORY_FILTER_ACTIONBUTTON).eq(1).click()
+ cy.get(interact.TEMPLATE_CATEGORY_ACTIONGROUP).should('have.length', 1)
- cy.get(".template-category-filters .spectrum-ActionButton").eq(0).click()
- cy.get(".template-category").its('length').should('be.gt', 1)
+ cy.get(interact.TEMPLATE_CATEGORY_FILTER_ACTIONBUTTON).eq(0).click()
+ cy.get(interact.TEMPLATE_CATEGORY_ACTIONGROUP).its('length').should('be.gt', 1)
})
it("should enforce a valid url before submission", () => {
@@ -51,37 +52,40 @@ filterTests(['smoke', 'all'], () => {
cy.wait(500)
// Start create app process. If apps already exist, click second button
- cy.get(`[data-cy="create-app-btn"]`).click({ force: true })
+ cy.get(interact.CREATE_APP_BUTTON).click({ force: true })
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
.its("body")
.then(val => {
if (val.length > 0) {
- cy.get(`[data-cy="create-app-btn"]`).click({ force: true })
+ cy.get(interact.CREATE_APP_BUTTON).click({ force: true })
}
})
const appName = "Cypress Tests"
- cy.get(".spectrum-Modal").within(() => {
+ cy.get(interact.SPECTRUM_MODAL).within(() => {
+
+ cy.get(interact.APP_NAME_INPUT).eq(0).should('have.focus')
//Auto fill
- cy.get("input").eq(0).type(appName).should("have.value", appName).blur()
- cy.get("input").eq(1).should("have.value", "/cypress-tests")
- cy.get(".spectrum-ButtonGroup").contains("Create app").should('not.be.disabled')
+ cy.get(interact.APP_NAME_INPUT).eq(0).clear()
+ cy.get(interact.APP_NAME_INPUT).eq(0).type(appName).should("have.value", appName).blur()
+ cy.get(interact.APP_NAME_INPUT).eq(1).should("have.value", "/cypress-tests")
+ cy.get(interact.SPECTRUM_BUTTON_GROUP).contains("Create app").should('not.be.disabled')
//Empty the app url - disabled create
- cy.get("input").eq(1).clear().blur()
- cy.get(".spectrum-ButtonGroup").contains("Create app").should('be.disabled')
+ cy.get(interact.APP_NAME_INPUT).eq(1).clear().blur()
+ cy.get(interact.SPECTRUM_BUTTON_GROUP).contains("Create app").should('be.disabled')
//Invalid url
- cy.get("input").eq(1).type("/new app-url").blur()
- cy.get(".spectrum-ButtonGroup").contains("Create app").should('be.disabled')
+ cy.get(interact.APP_NAME_INPUT).eq(1).type("/new app-url").blur()
+ cy.get(interact.SPECTRUM_BUTTON_GROUP).contains("Create app").should('be.disabled')
//Specifically alter the url
- cy.get("input").eq(1).clear()
- cy.get("input").eq(1).type("another-app-name").blur()
- cy.get("input").eq(1).should("have.value", "/another-app-name")
- cy.get("input").eq(0).should("have.value", appName)
- cy.get(".spectrum-ButtonGroup").contains("Create app").should('not.be.disabled')
+ cy.get(interact.APP_NAME_INPUT).eq(1).clear()
+ cy.get(interact.APP_NAME_INPUT).eq(1).type("another-app-name").blur()
+ cy.get(interact.APP_NAME_INPUT).eq(1).should("have.value", "/another-app-name")
+ cy.get(interact.APP_NAME_INPUT).eq(0).should("have.value", appName)
+ cy.get(interact.SPECTRUM_BUTTON_GROUP).contains("Create app").should('not.be.disabled')
})
})
@@ -97,6 +101,77 @@ filterTests(['smoke', 'all'], () => {
cy.deleteApp(appName)
})
+ it("should create the first application from scratch with a default name", () => {
+ cy.createApp()
+
+ cy.visit(`${Cypress.config().baseUrl}/builder`)
+ cy.wait(1000)
+
+ cy.applicationInAppTable("My app")
+ cy.deleteApp("My app")
+ })
+
+ it("should create the first application from scratch, using the users first name as the default app name", () => {
+ cy.visit(`${Cypress.config().baseUrl}/builder`)
+
+ cy.updateUserInformation("Ted", "Userman")
+
+ cy.createApp()
+
+ cy.visit(`${Cypress.config().baseUrl}/builder`)
+ cy.wait(1000)
+
+ cy.applicationInAppTable("Teds app")
+ cy.deleteApp("Teds app")
+ cy.wait(2000)
+
+ //Accomodate names that end in 'S'
+ cy.updateUserInformation("Chris", "Userman")
+
+ cy.createApp()
+
+ cy.visit(`${Cypress.config().baseUrl}/builder`)
+ cy.wait(1000)
+
+ cy.applicationInAppTable("Chris app")
+ cy.deleteApp("Chris app")
+ cy.wait(2000)
+
+ cy.updateUserInformation("", "")
+ })
+
+ it("should create an application from an export", () => {
+ const exportedApp = 'cypress/fixtures/exported-app.txt'
+
+ cy.importApp(exportedApp, "")
+
+ cy.visit(`${Cypress.config().baseUrl}/builder`)
+
+ cy.applicationInAppTable("My app")
+
+ cy.get(".appTable .name").eq(0).click()
+
+ cy.deleteApp("My app")
+ })
+
+ it("should create an application from an export, using the users first name as the default app name", () => {
+ const exportedApp = 'cypress/fixtures/exported-app.txt'
+
+ cy.updateUserInformation("Ted", "Userman")
+
+ cy.importApp(exportedApp, "")
+
+ cy.visit(`${Cypress.config().baseUrl}/builder`)
+
+ cy.applicationInAppTable("Teds app")
+
+ cy.get(".appTable .name").eq(0).click()
+
+ cy.deleteApp("Teds app")
+
+ cy.updateUserInformation("", "")
+ })
+
it("should generate the first application from a template", () => {
cy.visit(`${Cypress.config().baseUrl}/builder`)
cy.wait(500)
@@ -106,15 +181,15 @@ filterTests(['smoke', 'all'], () => {
.its("body")
.then(val => {
if (val.length > 0) {
- cy.get(`[data-cy="create-app-btn"]`).click({ force: true })
+ cy.get(interact.CREATE_APP_BUTTON).click({ force: true })
}
})
- cy.get(".template-category-filters").should("exist")
- cy.get(".template-categories").should("exist")
+ cy.get(interact.TEMPLATE_CATEGORY_FILTER).should("exist")
+ cy.get(interact.TEMPLATE_CATEGORY).should("exist")
// Select template
- cy.get('.template-category').eq(0).within(() => {
+ cy.get(interact.TEMPLATE_CATEGORY_ACTIONGROUP).eq(0).within(() => {
const card = cy.get('.template-card').eq(0).should("exist");
const cardOverlay = card.get('.template-thumbnail-action-overlay').should("exist")
cardOverlay.invoke("show")
@@ -128,8 +203,8 @@ filterTests(['smoke', 'all'], () => {
templateName.invoke('text')
.then(templateNameText => {
const templateNameParsed = "/"+templateNameText.toLowerCase().replace(/\s+/g, "-")
- cy.get(".spectrum-Modal input").eq(0).should("have.value", templateNameText)
- cy.get(".spectrum-Modal input").eq(1).should("have.value", templateNameParsed)
+ cy.get(interact.SPECTRUM_MODAL_INPUT).eq(0).should("have.value", templateNameText)
+ cy.get(interact.SPECTRUM_MODAL_INPUT).eq(1).should("have.value", templateNameParsed)
cy.get(".spectrum-Modal .spectrum-ButtonGroup").contains("Create app").click()
cy.wait(5000)
diff --git a/packages/builder/cypress/integration/createUserAndRoles.spec.js b/packages/builder/cypress/integration/createUserAndRoles.spec.js
index 2dbe91ce19..ac7ec1b5fd 100644
--- a/packages/builder/cypress/integration/createUserAndRoles.spec.js
+++ b/packages/builder/cypress/integration/createUserAndRoles.spec.js
@@ -4,6 +4,8 @@ filterTests(["smoke", "all"], () => {
context("Create a User and Assign Roles", () => {
before(() => {
cy.login()
+ cy.deleteApp("Cypress Tests")
+ cy.createApp("Cypress Tests")
})
it("should create a user", () => {
@@ -52,7 +54,7 @@ filterTests(["smoke", "all"], () => {
cy.get(".spectrum-Table").contains("bbuser").click()
cy.wait(1000)
for (let i = 0; i < 3; i++) {
- cy.get(".spectrum-Table")
+ cy.get(".spectrum-Table", { timeout: 3000})
.eq(1)
.find(".spectrum-Table-row")
.eq(0)
@@ -79,6 +81,7 @@ filterTests(["smoke", "all"], () => {
.contains("Update role")
.click({ force: true })
})
+ cy.reload()
}
// Confirm roles exist within Configure roles table
cy.wait(2000)
diff --git a/packages/builder/cypress/integration/templates/HR/jobApplicationTracker.spec.js b/packages/builder/cypress/integration/templates/HR/jobApplicationTracker.spec.js
index efb9e58c75..ff6cb91bad 100644
--- a/packages/builder/cypress/integration/templates/HR/jobApplicationTracker.spec.js
+++ b/packages/builder/cypress/integration/templates/HR/jobApplicationTracker.spec.js
@@ -1,7 +1,7 @@
import filterTests from "../../../support/filterTests"
filterTests(["all"], () => {
- context("Job Application Functionality", () => {
+ context("Job Application Tracker Template Functionality", () => {
const templateName = "Job Application Tracker"
const templateNameParsed = templateName.toLowerCase().replace(/\s+/g, '-')
@@ -14,15 +14,7 @@ filterTests(["all"], () => {
}
})
cy.wait(2000)
-
- // Template navigation
- cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
- .its("body")
- .then(val => {
- if (val.length > 0) {
- cy.get(".spectrum-Button").contains("Templates").click({force: true})
- }
- })
+ cy.templateNavigation()
})
it("should create and publish app with Job Application Tracker template", () => {
diff --git a/packages/builder/cypress/integration/templates/IT/ITTicketingSystem.spec.js b/packages/builder/cypress/integration/templates/IT/ITTicketingSystem.spec.js
new file mode 100644
index 0000000000..118625ac65
--- /dev/null
+++ b/packages/builder/cypress/integration/templates/IT/ITTicketingSystem.spec.js
@@ -0,0 +1,81 @@
+import filterTests from "../../../support/filterTests"
+
+filterTests(["all"], () => {
+ context("IT Ticketing System Template Functionality", () => {
+ const templateName = "IT Ticketing System"
+ const templateNameParsed = templateName.toLowerCase().replace(/\s+/g, '-')
+
+ before(() => {
+ cy.login()
+ cy.deleteApp(templateName)
+ cy.visit(`${Cypress.config().baseUrl}/builder`, {
+ onBeforeLoad(win) {
+ cy.stub(win, 'open')
+ }
+ })
+ cy.wait(2000)
+ cy.templateNavigation()
+ })
+
+ it("should create and publish app with IT Ticketing System template", () => {
+ // Select IT Ticketing System template
+ cy.get(".template-thumbnail-text")
+ .contains(templateName).parentsUntil(".template-grid").within(() => {
+ cy.get(".spectrum-Button").contains("Use template").click({ force: true })
+ })
+
+ // Confirm URL matches template name
+ const appUrl = cy.get(".app-server")
+ appUrl.invoke('text').then(appUrlText => {
+ expect(appUrlText).to.equal(`${Cypress.config().baseUrl}/app/` + templateNameParsed)
+ })
+
+ // Create App
+ cy.get(".spectrum-Dialog-grid").within(() => {
+ cy.get(".spectrum-Button").contains("Create app").click({ force: true })
+ })
+
+ // Publish App
+ cy.wait(2000) // Wait for app to generate
+ cy.get(".toprightnav").contains("Publish").click({ force: true })
+ cy.get(".spectrum-Dialog-grid").within(() => {
+ cy.get(".spectrum-Button").contains("Publish").click({ force: true })
+ })
+
+ // Verify Published app
+ cy.wait(2000) // Wait for App to publish and modal to appear
+ cy.get(".spectrum-Dialog-grid").within(() => {
+ cy.get(".spectrum-Button").contains("View App").click({ force: true })
+ cy.window().its('open').should('be.calledOnce')
+ })
+ })
+
+ xit("should filter tickets by status", () => {
+ // Visit published app
+ cy.visit(`${Cypress.config().baseUrl}/app/` + templateNameParsed)
+ cy.wait(1000)
+
+ // Tickets section
+ cy.get(".links").contains("Tickets").click({ force: true })
+ cy.wait(1000)
+
+ // Filter by stage - Confirm table updates
+ cy.get(".spectrum-Picker").contains("Filter by status").click({ force: true })
+ cy.get(".spectrum-Menu").find('li').its('length').then(len => {
+ for (let i = 1; i < len; i++) {
+ cy.get(".spectrum-Menu-item").eq(i).click()
+ const stage = cy.get(".spectrum-Picker-label")
+ stage.invoke('text').then(stageText => {
+ if (stageText == "In progress" || stageText == "On hold" || stageText == "Triaged") {
+ cy.get(".placeholder").should('contain', 'No rows found')
+ }
+ else {
+ cy.get(".spectrum-Table-row").should('contain', stageText)
+ }
+ cy.get(".spectrum-Picker").contains(stageText).click({ force: true })
+ })
+ }
+ })
+ })
+ })
+})
diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js
index e2e3850259..0c01c0c828 100644
--- a/packages/builder/cypress/support/commands.js
+++ b/packages/builder/cypress/support/commands.js
@@ -39,6 +39,71 @@ Cypress.Commands.add("closeModal", () => {
})
})
+Cypress.Commands.add("importApp", (exportFilePath, name) => {
+ cy.visit(`${Cypress.config().baseUrl}/builder`)
+
+ cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
+ .its("body")
+ .then(val => {
+ if (val.length > 0) {
+ cy.get(`[data-cy="create-app-btn"]`).click({ force: true })
+ cy.wait(500)
+ }
+ cy.get(`[data-cy="import-app-btn"]`).click({ force: true })
+ })
+
+ cy.get(".spectrum-Modal").within(() => {
+ cy.get("input").eq(1).should("have.focus")
+
+ cy.get(".spectrum-Dropzone").selectFile(exportFilePath, {
+ action: "drag-drop",
+ })
+
+ cy.get(".gallery .filename").contains("exported-app.txt")
+
+ if (name && name != "") {
+ cy.get("input").eq(0).type(name).should("have.value", name).blur()
+ }
+ cy.get(".confirm-wrap button")
+ .should("not.be.disabled")
+ .click({ force: true })
+ cy.wait(5000)
+ })
+})
+
+Cypress.Commands.add("updateUserInformation", (firstName, lastName) => {
+ cy.get(".user-dropdown .avatar > .icon").click({ force: true })
+
+ cy.get(".spectrum-Popover[data-cy='user-menu']").within(() => {
+ cy.get("li[data-cy='user-info']").click({ force: true })
+ })
+
+ cy.get(".spectrum-Modal.is-open").within(() => {
+ cy.get("[data-cy='user-first-name']").clear()
+
+ if (!firstName || firstName == "") {
+ cy.get("[data-cy='user-first-name']").invoke("val").should("be.empty")
+ } else {
+ cy.get("[data-cy='user-first-name']")
+ .type(firstName)
+ .should("have.value", firstName)
+ .blur()
+ }
+
+ cy.get("[data-cy='user-last-name']").clear()
+
+ if (!lastName || lastName == "") {
+ cy.get("[data-cy='user-last-name']").invoke("val").should("be.empty")
+ } else {
+ cy.get("[data-cy='user-last-name']")
+ .type(lastName)
+ .should("have.value", lastName)
+ .blur()
+ }
+ cy.get("button").contains("Update information").click({ force: true })
+ })
+})
+
Cypress.Commands.add("createApp", (name, addDefaultTable) => {
const shouldCreateDefaultTable =
typeof addDefaultTable != "boolean" ? true : addDefaultTable
@@ -57,7 +122,11 @@ Cypress.Commands.add("createApp", (name, addDefaultTable) => {
})
cy.get(".spectrum-Modal").within(() => {
- cy.get("input").eq(0).type(name).should("have.value", name).blur()
+ cy.get("input").eq(0).should("have.focus")
+ if (name && name != "") {
+ cy.get("input").eq(0).clear()
+ cy.get("input").eq(0).type(name).should("have.value", name).blur()
+ }
cy.get(".spectrum-ButtonGroup")
.contains("Create app")
.click({ force: true })
@@ -455,7 +524,12 @@ Cypress.Commands.add("createAppFromScratch", appName => {
.contains("Start from scratch")
.click({ force: true })
cy.get(".spectrum-Modal").within(() => {
- cy.get("input").eq(0).type(appName).should("have.value", appName).blur()
+ cy.get("input")
+ .eq(0)
+ .clear()
+ .type(appName)
+ .should("have.value", appName)
+ .blur()
cy.get(".spectrum-ButtonGroup").contains("Create app").click()
cy.wait(10000)
})
@@ -573,7 +647,8 @@ Cypress.Commands.add("addDatasourceConfig", (datasource, skipFetch) => {
cy.get(".spectrum-Button")
.contains("Save and fetch tables")
.click({ force: true })
- cy.wait(3000)
+ // Check modal closes after datasource config & fetch
+ cy.get(".spectrum-Dialog-grid", { timeout: 7000 }).should("not.exist")
})
}
})
@@ -595,3 +670,15 @@ Cypress.Commands.add("createRestQuery", (method, restUrl, queryPrettyName) => {
.should("contain", method)
.and("contain", queryPrettyName)
})
+
+Cypress.Commands.add("templateNavigation", () => {
+ // Navigates to templates section
+ cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
+ .its("body")
+ .then(val => {
+ // Templates button needs clicked if apps already exist
+ if (val.length > 0) {
+ cy.get(".spectrum-Button").contains("Templates").click({ force: true })
+ }
+ })
+})
diff --git a/packages/builder/cypress/support/interact.js b/packages/builder/cypress/support/interact.js
new file mode 100644
index 0000000000..46954227de
--- /dev/null
+++ b/packages/builder/cypress/support/interact.js
@@ -0,0 +1,13 @@
+// createApp test
+export const CREATE_APP_BUTTON = '[data-cy="create-app-btn"]'
+export const TEMPLATE_CATEGORY_FILTER = ".template-category-filters"
+export const TEMPLATE_CATEGORY = ".template-categories"
+export const APP_TABLE = ".appTable"
+export const SPECTRUM_BUTTON_TEMPLATE = ".spectrum-Button"
+export const TEMPLATE_CATEGORY_ACTIONGROUP = ".template-category"
+export const TEMPLATE_CATEGORY_FILTER_ACTIONBUTTON =
+ ".template-category-filters .spectrum-ActionButton"
+export const SPECTRUM_MODAL = ".spectrum-Modal"
+export const APP_NAME_INPUT = "input" // we need to update this with atribute cy-data
+export const SPECTRUM_BUTTON_GROUP = ".spectrum-ButtonGroup"
+export const SPECTRUM_MODAL_INPUT = ".spectrum-Modal input"
diff --git a/packages/builder/package.json b/packages/builder/package.json
index 44ecd34f2b..a112102180 100644
--- a/packages/builder/package.json
+++ b/packages/builder/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/builder",
- "version": "1.0.159-alpha.2",
+ "version": "1.0.164-alpha.3",
"license": "GPL-3.0",
"private": true,
"scripts": {
@@ -67,10 +67,10 @@
}
},
"dependencies": {
- "@budibase/bbui": "^1.0.159-alpha.2",
- "@budibase/client": "^1.0.159-alpha.2",
- "@budibase/frontend-core": "^1.0.159-alpha.2",
- "@budibase/string-templates": "^1.0.159-alpha.2",
+ "@budibase/bbui": "^1.0.164-alpha.3",
+ "@budibase/client": "^1.0.164-alpha.3",
+ "@budibase/frontend-core": "^1.0.164-alpha.3",
+ "@budibase/string-templates": "^1.0.164-alpha.3",
"@sentry/browser": "5.19.1",
"@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1",
diff --git a/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte b/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte
index dcd96ce2b9..9ba4140b51 100644
--- a/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte
+++ b/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte
@@ -12,4 +12,4 @@
}
-
+
diff --git a/packages/builder/src/components/common/inputs/CopyInput.svelte b/packages/builder/src/components/common/inputs/CopyInput.svelte
index 102fd5682a..589623f542 100644
--- a/packages/builder/src/components/common/inputs/CopyInput.svelte
+++ b/packages/builder/src/components/common/inputs/CopyInput.svelte
@@ -3,7 +3,6 @@
export let label = null
export let value
- export let copyValue
export let dataCy = null
const copyToClipboard = val => {
@@ -19,7 +18,7 @@
-
copyToClipboard(value || copyValue)}>
+
copyToClipboard(value)}>
diff --git a/packages/builder/src/components/settings/UpdateUserInfoModal.svelte b/packages/builder/src/components/settings/UpdateUserInfoModal.svelte
index ea0cb827f8..5734f613ad 100644
--- a/packages/builder/src/components/settings/UpdateUserInfoModal.svelte
+++ b/packages/builder/src/components/settings/UpdateUserInfoModal.svelte
@@ -27,6 +27,14 @@
Personalise the platform by adding your first name and last name.