Merge branch 'develop' into oracle-datasource

This commit is contained in:
Rory Powell 2021-11-23 09:27:55 +00:00
commit 1a0c66beb6
22 changed files with 130 additions and 44 deletions

View File

@ -1,5 +1,5 @@
{ {
"version": "0.9.185-alpha.12", "version": "0.9.185-alpha.14",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/*" "packages/*"

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/auth", "name": "@budibase/auth",
"version": "0.9.185-alpha.12", "version": "0.9.185-alpha.14",
"description": "Authentication middlewares for budibase builder and apps", "description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js", "main": "src/index.js",
"author": "Budibase", "author": "Budibase",

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/bbui", "name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.", "description": "A UI solution used in the different Budibase projects.",
"version": "0.9.185-alpha.12", "version": "0.9.185-alpha.14",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"svelte": "src/index.js", "svelte": "src/index.js",
"module": "dist/bbui.es.js", "module": "dist/bbui.es.js",

View File

@ -11,6 +11,7 @@
export let readonly = false export let readonly = false
export let updateOnChange = true export let updateOnChange = true
export let quiet = false export let quiet = false
export let dataCy
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let focus = false let focus = false
@ -78,6 +79,7 @@
{disabled} {disabled}
{readonly} {readonly}
{id} {id}
data-cy={dataCy}
value={value || ""} value={value || ""}
placeholder={placeholder || ""} placeholder={placeholder || ""}
on:click on:click

View File

@ -13,6 +13,7 @@
export let error = null export let error = null
export let updateOnChange = true export let updateOnChange = true
export let quiet = false export let quiet = false
export let dataCy
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = e => {
@ -23,6 +24,7 @@
<Field {label} {labelPosition} {error}> <Field {label} {labelPosition} {error}>
<TextField <TextField
{dataCy}
{updateOnChange} {updateOnChange}
{error} {error}
{disabled} {disabled}

View File

@ -53,6 +53,7 @@ context("Create a Table", () => {
cy.get(".spectrum-Table-editIcon > use").click() cy.get(".spectrum-Table-editIcon > use").click()
cy.contains("Delete").click() cy.contains("Delete").click()
cy.wait(50) cy.wait(50)
cy.get(`[data-cy="delete-column-confirm"]`).type("nameupdated")
cy.contains("Delete Column").click() cy.contains("Delete Column").click()
cy.contains("nameupdated").should("not.exist") cy.contains("nameupdated").should("not.exist")
}) })
@ -66,6 +67,7 @@ context("Create a Table", () => {
cy.get(".actions .spectrum-Icon").click({ force: true }) cy.get(".actions .spectrum-Icon").click({ force: true })
}) })
cy.get(".spectrum-Menu > :nth-child(2)").click() cy.get(".spectrum-Menu > :nth-child(2)").click()
cy.get(`[data-cy="delete-table-confirm"]`).type("dog")
cy.contains("Delete Table").click() cy.contains("Delete Table").click()
cy.contains("dog").should("not.exist") cy.contains("dog").should("not.exist")
}) })

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/builder", "name": "@budibase/builder",
"version": "0.9.185-alpha.12", "version": "0.9.185-alpha.14",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"private": true, "private": true,
"scripts": { "scripts": {
@ -65,10 +65,10 @@
} }
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.185-alpha.12", "@budibase/bbui": "^0.9.185-alpha.14",
"@budibase/client": "^0.9.185-alpha.12", "@budibase/client": "^0.9.185-alpha.14",
"@budibase/colorpicker": "1.1.2", "@budibase/colorpicker": "1.1.2",
"@budibase/string-templates": "^0.9.185-alpha.12", "@budibase/string-templates": "^0.9.185-alpha.14",
"@sentry/browser": "5.19.1", "@sentry/browser": "5.19.1",
"@spectrum-css/page": "^3.0.1", "@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1", "@spectrum-css/vars": "^3.0.1",

View File

@ -62,6 +62,7 @@
let indexes = [...($tables.selected.indexes || [])] let indexes = [...($tables.selected.indexes || [])]
let confirmDeleteDialog let confirmDeleteDialog
let deletion let deletion
let deleteColName
$: checkConstraints(field) $: checkConstraints(field)
$: required = !!field?.constraints?.presence || primaryDisplay $: required = !!field?.constraints?.presence || primaryDisplay
@ -179,6 +180,7 @@
function hideDeleteDialog() { function hideDeleteDialog() {
confirmDeleteDialog.hide() confirmDeleteDialog.hide()
deleteColName = ""
deletion = false deletion = false
} }
@ -408,9 +410,20 @@
</ModalContent> </ModalContent>
<ConfirmDialog <ConfirmDialog
bind:this={confirmDeleteDialog} bind:this={confirmDeleteDialog}
body={`Are you sure you wish to delete this column? Your data will be deleted and this action cannot be undone.`}
okText="Delete Column" okText="Delete Column"
onOk={deleteColumn} onOk={deleteColumn}
onCancel={hideDeleteDialog} onCancel={hideDeleteDialog}
title="Confirm Deletion" title="Confirm Deletion"
/> disabled={deleteColName !== field.name}
>
<p>
Are you sure you wish to delete the column <b>{field.name}?</b>
Your data will be deleted and this action cannot be undone - enter the column
name to confirm.
</p>
<Input
dataCy="delete-column-confirm"
bind:value={deleteColName}
placeholder={field.name}
/>
</ConfirmDialog>

View File

@ -21,8 +21,10 @@
let originalName = table.name let originalName = table.name
let templateScreens let templateScreens
let willBeDeleted let willBeDeleted
let deleteTableName
$: external = table?.type === "external" $: external = table?.type === "external"
$: allowDeletion = !external || table?.created
function showDeleteModal() { function showDeleteModal() {
templateScreens = $allScreens.filter( templateScreens = $allScreens.filter(
@ -36,16 +38,24 @@
async function deleteTable() { async function deleteTable() {
const wasSelectedTable = $tables.selected const wasSelectedTable = $tables.selected
try {
await tables.delete(table) await tables.delete(table)
store.actions.screens.delete(templateScreens) await store.actions.screens.delete(templateScreens)
await tables.fetch() await tables.fetch()
notifications.success("Table deleted")
if (table.type === "external") { if (table.type === "external") {
await datasources.fetch() await datasources.fetch()
} }
notifications.success("Table deleted")
if (wasSelectedTable && wasSelectedTable._id === table._id) { if (wasSelectedTable && wasSelectedTable._id === table._id) {
$goto("./table") $goto("./table")
} }
} catch (err) {
notifications.error(err)
}
}
function hideDeleteDialog() {
deleteTableName = ""
} }
async function save() { async function save() {
@ -67,7 +77,9 @@
<Icon s hoverable name="MoreSmallList" /> <Icon s hoverable name="MoreSmallList" />
</div> </div>
<MenuItem icon="Edit" on:click={editorModal.show}>Edit</MenuItem> <MenuItem icon="Edit" on:click={editorModal.show}>Edit</MenuItem>
{#if allowDeletion}
<MenuItem icon="Delete" on:click={showDeleteModal}>Delete</MenuItem> <MenuItem icon="Delete" on:click={showDeleteModal}>Delete</MenuItem>
{/if}
</ActionMenu> </ActionMenu>
<Modal bind:this={editorModal}> <Modal bind:this={editorModal}>
@ -90,11 +102,15 @@
bind:this={confirmDeleteDialog} bind:this={confirmDeleteDialog}
okText="Delete Table" okText="Delete Table"
onOk={deleteTable} onOk={deleteTable}
onCancel={hideDeleteDialog}
title="Confirm Deletion" title="Confirm Deletion"
disabled={deleteTableName !== table.name}
> >
<p>
Are you sure you wish to delete the table Are you sure you wish to delete the table
<i>{table.name}?</i> <b>{table.name}?</b>
The following will also be deleted: The following will also be deleted:
</p>
<b> <b>
<div class="delete-items"> <div class="delete-items">
{#each willBeDeleted as item} {#each willBeDeleted as item}
@ -102,7 +118,15 @@
{/each} {/each}
</div> </div>
</b> </b>
This action cannot be undone. <p>
This action cannot be undone - to continue please enter the table name below
to confirm.
</p>
<Input
bind:value={deleteTableName}
placeholder={table.name}
dataCy="delete-table-confirm"
/>
</ConfirmDialog> </ConfirmDialog>
<style> <style>

View File

@ -305,7 +305,11 @@
Are you sure you want to delete the app <b>{selectedApp?.name}</b>? Are you sure you want to delete the app <b>{selectedApp?.name}</b>?
<p>Please enter the app name below to confirm.</p> <p>Please enter the app name below to confirm.</p>
<Input bind:value={appName} data-cy="delete-app-confirmation" /> <Input
bind:value={appName}
data-cy="delete-app-confirmation"
placeholder={selectedApp?.name}
/>
</ConfirmDialog> </ConfirmDialog>
<ConfirmDialog <ConfirmDialog
bind:this={unpublishModal} bind:this={unpublishModal}

View File

@ -1,5 +1,5 @@
import { writable, get } from "svelte/store" import { get, writable } from "svelte/store"
import { views, queries, datasources } from "./" import { datasources, queries, views } from "./"
import { cloneDeep } from "lodash/fp" import { cloneDeep } from "lodash/fp"
import api from "builderStore/api" import api from "builderStore/api"
import { SWITCHABLE_TYPES } from "../../constants/backend" import { SWITCHABLE_TYPES } from "../../constants/backend"
@ -97,7 +97,12 @@ export function createTablesStore() {
}) })
}, },
delete: async table => { delete: async table => {
await api.delete(`/api/tables/${table._id}/${table._rev}`) const response = await api.delete(
`/api/tables/${table._id}/${table._rev}`
)
if (response.status !== 200) {
throw (await response.json()).message
}
update(state => ({ update(state => ({
...state, ...state,
list: state.list.filter(existing => existing._id !== table._id), list: state.list.filter(existing => existing._id !== table._id),

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/cli", "name": "@budibase/cli",
"version": "0.9.185-alpha.12", "version": "0.9.185-alpha.14",
"description": "Budibase CLI, for developers, self hosting and migrations.", "description": "Budibase CLI, for developers, self hosting and migrations.",
"main": "src/index.js", "main": "src/index.js",
"bin": { "bin": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/client", "name": "@budibase/client",
"version": "0.9.185-alpha.12", "version": "0.9.185-alpha.14",
"license": "MPL-2.0", "license": "MPL-2.0",
"module": "dist/budibase-client.js", "module": "dist/budibase-client.js",
"main": "dist/budibase-client.js", "main": "dist/budibase-client.js",
@ -19,9 +19,9 @@
"dev:builder": "rollup -cw" "dev:builder": "rollup -cw"
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.185-alpha.12", "@budibase/bbui": "^0.9.185-alpha.14",
"@budibase/standard-components": "^0.9.139", "@budibase/standard-components": "^0.9.139",
"@budibase/string-templates": "^0.9.185-alpha.12", "@budibase/string-templates": "^0.9.185-alpha.14",
"regexparam": "^1.3.0", "regexparam": "^1.3.0",
"shortid": "^2.2.15", "shortid": "^2.2.15",
"svelte-spa-router": "^3.0.5" "svelte-spa-router": "^3.0.5"

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/server", "name": "@budibase/server",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "0.9.185-alpha.12", "version": "0.9.185-alpha.14",
"description": "Budibase Web Server", "description": "Budibase Web Server",
"main": "src/index.js", "main": "src/index.js",
"repository": { "repository": {
@ -68,9 +68,9 @@
"author": "Budibase", "author": "Budibase",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@budibase/auth": "^0.9.185-alpha.12", "@budibase/auth": "^0.9.185-alpha.14",
"@budibase/client": "^0.9.185-alpha.12", "@budibase/client": "^0.9.185-alpha.14",
"@budibase/string-templates": "^0.9.185-alpha.12", "@budibase/string-templates": "^0.9.185-alpha.14",
"@bull-board/api": "^3.7.0", "@bull-board/api": "^3.7.0",
"@bull-board/koa": "^3.7.0", "@bull-board/koa": "^3.7.0",
"@elastic/elasticsearch": "7.10.0", "@elastic/elasticsearch": "7.10.0",

View File

@ -50,6 +50,7 @@ async function init() {
SELF_HOSTED: 1, SELF_HOSTED: 1,
DISABLE_ACCOUNT_PORTAL: "", DISABLE_ACCOUNT_PORTAL: "",
MULTI_TENANCY: "", MULTI_TENANCY: "",
DISABLE_THREADING: 1,
} }
let envFile = "" let envFile = ""
Object.keys(envFileJson).forEach(key => { Object.keys(envFileJson).forEach(key => {

View File

@ -161,9 +161,13 @@ function isRelationshipSetup(column) {
exports.save = async function (ctx) { exports.save = async function (ctx) {
const appId = ctx.appId const appId = ctx.appId
const table = ctx.request.body const table = ctx.request.body
// can't do this // can't do this right now
delete table.dataImport delete table.dataImport
const datasourceId = getDatasourceId(ctx.request.body) const datasourceId = getDatasourceId(ctx.request.body)
// table doesn't exist already, note that it is created
if (!table._id) {
table.created = true
}
let tableToSave = { let tableToSave = {
type: "table", type: "table",
_id: buildExternalTableId(datasourceId, table.name), _id: buildExternalTableId(datasourceId, table.name),
@ -265,6 +269,9 @@ exports.save = async function (ctx) {
exports.destroy = async function (ctx) { exports.destroy = async function (ctx) {
const appId = ctx.appId const appId = ctx.appId
const tableToDelete = await getTable(appId, ctx.params.tableId) const tableToDelete = await getTable(appId, ctx.params.tableId)
if (!tableToDelete || !tableToDelete.created) {
ctx.throw(400, "Cannot delete tables which weren't created in Budibase.")
}
const datasourceId = getDatasourceId(tableToDelete) const datasourceId = getDatasourceId(tableToDelete)
const db = new CouchDB(appId) const db = new CouchDB(appId)

View File

@ -23,6 +23,8 @@ if (!LOADED && isDev() && !isTest()) {
LOADED = true LOADED = true
} }
let inThread = false
module.exports = { module.exports = {
// important // important
PORT: process.env.PORT, PORT: process.env.PORT,
@ -62,6 +64,7 @@ module.exports = {
USERID_API_KEY: process.env.USERID_API_KEY, USERID_API_KEY: process.env.USERID_API_KEY,
DEPLOYMENT_CREDENTIALS_URL: process.env.DEPLOYMENT_CREDENTIALS_URL, DEPLOYMENT_CREDENTIALS_URL: process.env.DEPLOYMENT_CREDENTIALS_URL,
ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS, ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS,
DISABLE_THREADING: process.env.DISABLE_THREADING,
_set(key, value) { _set(key, value) {
process.env[key] = value process.env[key] = value
module.exports[key] = value module.exports[key] = value
@ -72,6 +75,18 @@ module.exports = {
isProd: () => { isProd: () => {
return !isDev() return !isDev()
}, },
// used to check if already in a thread, don't thread further
setInThread: () => {
inThread = true
},
isInThread: () => {
return inThread
},
}
// threading can cause memory issues with node-ts in development
if (isDev() && module.exports.DISABLE_THREADING == null) {
module.exports._set("DISABLE_THREADING", "1")
} }
// clean up any environment variable edge cases // clean up any environment variable edge cases

View File

@ -1,3 +1,6 @@
// when thread starts, make sure it is recorded
const env = require("../environment")
env.setInThread()
const actions = require("../automations/actions") const actions = require("../automations/actions")
const automationUtils = require("../automations/automationUtils") const automationUtils = require("../automations/automationUtils")
const AutomationEmitter = require("../events/AutomationEmitter") const AutomationEmitter = require("../events/AutomationEmitter")
@ -6,7 +9,6 @@ const { DEFAULT_TENANT_ID } = require("@budibase/auth").constants
const CouchDB = require("../db") const CouchDB = require("../db")
const { DocumentTypes, isDevAppID } = require("../db/utils") const { DocumentTypes, isDevAppID } = require("../db/utils")
const { doInTenant } = require("@budibase/auth/tenancy") const { doInTenant } = require("@budibase/auth/tenancy")
const env = require("../environment")
const usage = require("../utilities/usageQuota") const usage = require("../utilities/usageQuota")
const { definitions: triggerDefs } = require("../automations/triggerInfo") const { definitions: triggerDefs } = require("../automations/triggerInfo")

View File

@ -24,10 +24,16 @@ function typeToFile(type) {
class Thread { class Thread {
constructor(type, opts = { timeoutMs: null, count: 1 }) { constructor(type, opts = { timeoutMs: null, count: 1 }) {
this.type = type this.type = type
if (!env.isTest()) { this.count = opts.count ? opts.count : 1
this.disableThreading =
env.isTest() ||
env.DISABLE_THREADING ||
this.count === 0 ||
env.isInThread()
if (!this.disableThreading) {
const workerOpts = { const workerOpts = {
autoStart: true, autoStart: true,
maxConcurrentWorkers: opts.count ? opts.count : 1, maxConcurrentWorkers: this.count,
} }
if (opts.timeoutMs) { if (opts.timeoutMs) {
workerOpts.maxCallTime = opts.timeoutMs workerOpts.maxCallTime = opts.timeoutMs
@ -40,7 +46,7 @@ class Thread {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let fncToCall let fncToCall
// if in test then don't use threading // if in test then don't use threading
if (env.isTest()) { if (this.disableThreading) {
fncToCall = require(typeToFile(this.type)) fncToCall = require(typeToFile(this.type))
} else { } else {
fncToCall = this.workers fncToCall = this.workers

View File

@ -1,3 +1,6 @@
// when thread starts, make sure it is recorded
const env = require("../environment")
env.setInThread()
const ScriptRunner = require("../utilities/scriptRunner") const ScriptRunner = require("../utilities/scriptRunner")
const { integrations } = require("../integrations") const { integrations } = require("../integrations")

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/string-templates", "name": "@budibase/string-templates",
"version": "0.9.185-alpha.12", "version": "0.9.185-alpha.14",
"description": "Handlebars wrapper for Budibase templating.", "description": "Handlebars wrapper for Budibase templating.",
"main": "src/index.cjs", "main": "src/index.cjs",
"module": "dist/bundle.mjs", "module": "dist/bundle.mjs",

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/worker", "name": "@budibase/worker",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "0.9.185-alpha.12", "version": "0.9.185-alpha.14",
"description": "Budibase background service", "description": "Budibase background service",
"main": "src/index.js", "main": "src/index.js",
"repository": { "repository": {
@ -29,8 +29,8 @@
"author": "Budibase", "author": "Budibase",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@budibase/auth": "^0.9.185-alpha.12", "@budibase/auth": "^0.9.185-alpha.14",
"@budibase/string-templates": "^0.9.185-alpha.12", "@budibase/string-templates": "^0.9.185-alpha.14",
"@koa/router": "^8.0.0", "@koa/router": "^8.0.0",
"@sentry/node": "^6.0.0", "@sentry/node": "^6.0.0",
"@techpass/passport-openidconnect": "^0.3.0", "@techpass/passport-openidconnect": "^0.3.0",