diff --git a/packages/builder/cypress/integration/createAutomation.spec.js b/packages/builder/cypress/integration/createAutomation.spec.js
index afd405d5ab..6ff013cd7a 100644
--- a/packages/builder/cypress/integration/createAutomation.spec.js
+++ b/packages/builder/cypress/integration/createAutomation.spec.js
@@ -12,7 +12,7 @@ context("Create a automation", () => {
cy.get("[data-cy='new-screen'] > .spectrum-Icon").click()
cy.get(".modal-inner-wrapper").within(() => {
cy.get("input").type("Add Row")
- cy.contains("Row Created").click()
+ cy.contains("Row Created").click({ force: true })
cy.wait(500)
cy.get(".spectrum-Button--cta").click()
})
diff --git a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte
index cf3dc8f314..36723d7726 100644
--- a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte
+++ b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte
@@ -3,7 +3,14 @@
import { database } from "stores/backend"
import { automationStore } from "builderStore"
import { notifications } from "@budibase/bbui"
- import { Input, ModalContent, Layout, Body, Icon } from "@budibase/bbui"
+ import {
+ Input,
+ InlineAlert,
+ ModalContent,
+ Layout,
+ Body,
+ Icon,
+ } from "@budibase/bbui"
import analytics, { Events } from "analytics"
let name
@@ -56,6 +63,10 @@
onConfirm={createAutomation}
disabled={!selectedTrigger || !name}
>
+
Please name your automation, then select a trigger. Every automation must
start with a trigger.
diff --git a/packages/builder/src/components/integration/QueryViewer.svelte b/packages/builder/src/components/integration/QueryViewer.svelte
index 54e455b92f..550da98d6b 100644
--- a/packages/builder/src/components/integration/QueryViewer.svelte
+++ b/packages/builder/src/components/integration/QueryViewer.svelte
@@ -32,31 +32,22 @@
import { onMount } from "svelte"
export let query
- export let fields = []
+ let fields = query.schema ? schemaToFields(query.schema) : []
let parameters
let data = []
let roleId
const transformerDocs =
"https://docs.budibase.com/building-apps/data/transformers"
const typeOptions = [
- { label: "Text", value: "STRING" },
- { label: "Number", value: "NUMBER" },
- { label: "Boolean", value: "BOOLEAN" },
- { label: "Datetime", value: "DATETIME" },
+ { label: "Text", value: "string" },
+ { label: "Number", value: "number" },
+ { label: "Boolean", value: "boolean" },
+ { label: "Datetime", value: "datetime" },
]
$: datasource = $datasources.list.find(ds => ds._id === query.datasourceId)
- $: query.schema = fields.reduce(
- (acc, next) => ({
- ...acc,
- [next.name]: {
- name: next.name,
- type: "string",
- },
- }),
- {}
- )
+ $: query.schema = fieldsToSchema(fields)
$: datasourceType = datasource?.source
$: integrationInfo = $integrations[datasourceType]
$: queryConfig = integrationInfo?.query
@@ -135,7 +126,7 @@
// unique fields returned by the server
fields = json.schemaFields.map(field => ({
name: field,
- type: "STRING",
+ type: "string",
}))
} catch (err) {
notifications.error(`Query Error: ${err.message}`)
@@ -155,6 +146,26 @@
}
}
+ function schemaToFields(schema) {
+ return Object.keys(schema).map(key => ({
+ name: key,
+ type: query.schema[key].type,
+ }))
+ }
+
+ function fieldsToSchema(fieldsToConvert) {
+ return fieldsToConvert.reduce(
+ (acc, next) => ({
+ ...acc,
+ [next.name]: {
+ name: next.name,
+ type: next.type,
+ },
+ }),
+ {}
+ )
+ }
+
onMount(async () => {
if (!query || !query._id) {
roleId = Roles.BASIC
diff --git a/packages/builder/src/components/start/CreateAppModal.svelte b/packages/builder/src/components/start/CreateAppModal.svelte
index 68845e075b..75df17e532 100644
--- a/packages/builder/src/components/start/CreateAppModal.svelte
+++ b/packages/builder/src/components/start/CreateAppModal.svelte
@@ -83,12 +83,11 @@
}
async function createNewApp() {
- const letTemplateToUse =
- Object.keys(template).length === 0 ? null : template
+ const templateToUse = Object.keys(template).length === 0 ? null : template
submitting = true
// Check a template exists if we are important
- if (letTemplateToUse?.fromFile && !$values.file) {
+ if (templateToUse?.fromFile && !$values.file) {
$errors.file = "Please choose a file to import"
valid = false
submitting = false
@@ -99,10 +98,10 @@
// Create form data to create app
let data = new FormData()
data.append("name", $values.name.trim())
- data.append("useTemplate", letTemplateToUse != null)
- if (letTemplateToUse) {
- data.append("templateName", letTemplateToUse.name)
- data.append("templateKey", letTemplateToUse.key)
+ data.append("useTemplate", templateToUse != null)
+ if (templateToUse) {
+ data.append("templateName", templateToUse.name)
+ data.append("templateKey", templateToUse.key)
data.append("templateFile", $values.file)
}
@@ -116,7 +115,7 @@
analytics.captureEvent(Events.APP.CREATED, {
name: $values.name,
appId: appJson.instance._id,
- letTemplateToUse,
+ templateToUse,
})
// Select Correct Application/DB in prep for creating user
diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte
index da0d977a42..15076a9a53 100644
--- a/packages/builder/src/pages/builder/portal/apps/index.svelte
+++ b/packages/builder/src/pages/builder/portal/apps/index.svelte
@@ -13,9 +13,11 @@
notifications,
Search,
} from "@budibase/bbui"
+ import Spinner from "components/common/Spinner.svelte"
import CreateAppModal from "components/start/CreateAppModal.svelte"
import UpdateAppModal from "components/start/UpdateAppModal.svelte"
- import { del } from "builderStore/api"
+ import { store, automationStore } from "builderStore"
+ import api, { del, post, get } from "builderStore/api"
import { onMount } from "svelte"
import { apps, auth, admin } from "stores/portal"
import download from "downloadjs"
@@ -24,6 +26,7 @@
import AppCard from "components/start/AppCard.svelte"
import AppRow from "components/start/AppRow.svelte"
import { AppStatus } from "constants"
+ import analytics, { Events } from "analytics"
let layout = "grid"
let sortBy = "name"
@@ -38,6 +41,7 @@
let searchTerm = ""
let cloud = $admin.cloud
let appName = ""
+ let creatingFromTemplate = false
$: enrichedApps = enrichApps($apps, $auth.user, sortBy)
$: filteredApps = enrichedApps.filter(app =>
@@ -92,6 +96,62 @@
creatingApp = true
}
+ const autoCreateApp = async () => {
+ try {
+ // Auto name app if has same name
+ let appName = template.key
+ const appsWithSameName = $apps.filter(app =>
+ app.name?.startsWith(appName)
+ )
+ appName = `${appName}-${appsWithSameName.length + 1}`
+
+ // Create form data to create app
+ let data = new FormData()
+ data.append("name", appName)
+ data.append("useTemplate", true)
+ data.append("templateKey", template.key)
+
+ // Create App
+ const appResp = await post("/api/applications", data, {})
+ const appJson = await appResp.json()
+ if (!appResp.ok) {
+ throw new Error(appJson.message)
+ }
+
+ analytics.captureEvent(Events.APP.CREATED, {
+ name: appName,
+ appId: appJson.instance._id,
+ template,
+ fromTemplateMarketplace: true,
+ })
+
+ // Select Correct Application/DB in prep for creating user
+ const applicationPkg = await get(
+ `/api/applications/${appJson.instance._id}/appPackage`
+ )
+ const pkg = await applicationPkg.json()
+ if (applicationPkg.ok) {
+ await store.actions.initialise(pkg)
+ await automationStore.actions.fetch()
+ // update checklist - incase first app
+ await admin.init()
+ } else {
+ throw new Error(pkg)
+ }
+
+ // Create user
+ const userResp = await api.post(`/api/users/metadata/self`, {
+ roleId: "BASIC",
+ })
+ await userResp.json()
+ await auth.setInitInfo({})
+ $goto(`/builder/app/${appJson.instance._id}`)
+ } catch (error) {
+ console.error(error)
+ notifications.error(error)
+ }
+ }
+
const stopAppCreation = () => {
template = null
creatingApp = false
@@ -194,7 +254,7 @@
template = {
key: templateKey,
}
- initiateAppCreation()
+ autoCreateApp()
} else {
notifications.error("Your Template URL is invalid. Please try another.")
}
@@ -202,12 +262,14 @@
onMount(async () => {
await apps.load()
- loaded = true
// if the portal is loaded from an external URL with a template param
const initInfo = await auth.getInitInfo()
if (initInfo.init_template) {
+ creatingFromTemplate = true
createAppFromTemplateUrl(initInfo.init_template)
+ return
}
+ loaded = true
})
@@ -285,6 +347,12 @@
{/if}
+ {#if creatingFromTemplate}
+
+
Creating your Budibase app from your selected template...
+
+
+ {/if}
=2.3.x"
-
-svg.filter.js@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/svg.filter.js/-/svg.filter.js-2.0.2.tgz#91008e151389dd9230779fcbe6e2c9a362d1c203"
- integrity sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM=
- dependencies:
- svg.js "^2.2.5"
-
-svg.js@>=2.3.x, svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5:
- version "2.7.1"
- resolved "https://registry.yarnpkg.com/svg.js/-/svg.js-2.7.1.tgz#eb977ed4737001eab859949b4a398ee1bb79948d"
- integrity sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==
-
-svg.pathmorphing.js@^0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz#c25718a1cc7c36e852ecabc380e758ac09bb2b65"
- integrity sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==
- dependencies:
- svg.js "^2.4.0"
-
-svg.resize.js@^1.4.3:
- version "1.4.3"
- resolved "https://registry.yarnpkg.com/svg.resize.js/-/svg.resize.js-1.4.3.tgz#885abd248e0cd205b36b973c4b578b9a36f23332"
- integrity sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==
- dependencies:
- svg.js "^2.6.5"
- svg.select.js "^2.1.2"
-
-svg.select.js@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-2.1.2.tgz#e41ce13b1acff43a7441f9f8be87a2319c87be73"
- integrity sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==
- dependencies:
- svg.js "^2.2.5"
-
-svg.select.js@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-3.0.1.tgz#a4198e359f3825739226415f82176a90ea5cc917"
- integrity sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==
- dependencies:
- svg.js "^2.6.5"
-
symbol-observable@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
@@ -6474,14 +5748,6 @@ throttleit@^1.0.0:
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
integrity sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=
-through2@^2.0.0:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
- integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
- dependencies:
- readable-stream "~2.3.6"
- xtend "~4.0.1"
-
through@2, through@~2.3, through@~2.3.1:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
@@ -6504,11 +5770,6 @@ to-fast-properties@^2.0.0:
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
-to-gfm-code-block@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/to-gfm-code-block/-/to-gfm-code-block-0.1.1.tgz#25d045a5fae553189e9637b590900da732d8aa82"
- integrity sha1-JdBFpfrlUxielje1kJANpzLYqoI=
-
to-object-path@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
@@ -6636,18 +5897,6 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-typeof-article@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/typeof-article/-/typeof-article-0.1.1.tgz#9f07e733c3fbb646ffa9e61c08debacd460e06af"
- integrity sha1-nwfnM8P7tkb/qeYcCN66zUYOBq8=
- dependencies:
- kind-of "^3.1.0"
-
-uglify-js@^3.1.4:
- version "3.14.3"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf"
- integrity sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==
-
unicode-canonical-property-names-ecmascript@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"
@@ -6789,11 +6038,6 @@ vite@^2.1.5:
optionalDependencies:
fsevents "~2.3.2"
-vm2@^3.9.4:
- version "3.9.5"
- resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.5.tgz#5288044860b4bbace443101fcd3bddb2a0aa2496"
- integrity sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==
-
w3c-hr-time@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
@@ -6894,11 +6138,6 @@ word-wrap@~1.2.3:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
-wordwrap@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
- integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
-
wrap-ansi@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba"
@@ -6946,11 +6185,6 @@ xmlchars@^2.2.0:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
-xtend@~4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
- integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
-
y18n@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
@@ -6994,11 +6228,6 @@ yauzl@^2.10.0:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
-year@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/year/-/year-0.2.1.tgz#4083ae520a318b23ec86037f3000cb892bdf9bb0"
- integrity sha1-QIOuUgoxiyPshgN/MADLiSvfm7A=
-
yup@0.29.2:
version "0.29.2"
resolved "https://registry.yarnpkg.com/yup/-/yup-0.29.2.tgz#5302abd9024cca335b987793f8df868e410b7b67"