Merge branch 'next' of github.com:Budibase/budibase into spectrum-bbui

This commit is contained in:
Andrew Kingston 2021-04-01 13:51:48 +01:00
commit 1c8de5d52d
17 changed files with 271 additions and 7315 deletions

View File

@ -70,7 +70,7 @@ context("Create a View", () => {
.eq(1)
.select("age")
cy.contains("Save").click()
cy.wait(100)
cy.wait(1000)
cy.get(".ag-center-cols-viewport").scrollTo("100%")
cy.get("[data-cy=table-header]").then($headers => {
expect($headers).to.have.length(7)
@ -100,6 +100,7 @@ context("Create a View", () => {
cy.contains("Group By").click()
cy.get("select").select("group")
cy.contains("Save").click()
cy.wait(1000)
cy.get(".ag-center-cols-viewport").scrollTo("100%")
cy.contains("Students").should("be.visible")
cy.contains("Teachers").should("be.visible")
@ -108,7 +109,7 @@ context("Create a View", () => {
.find(".ag-cell")
.then($values => {
const values = Array.from($values).map(value => value.textContent)
expect(values).to.deep.eq([
expect(values.sort()).to.deep.eq([
"Students",
"23.333333333333332",
"1650",
@ -116,7 +117,7 @@ context("Create a View", () => {
"25",
"20",
"70",
])
].sort())
})
})
@ -129,6 +130,7 @@ context("Create a View", () => {
cy.get("input").type(" Updated")
cy.contains("Save").click()
})
cy.wait(1000)
cy.contains("Test View Updated").should("be.visible")
})
@ -138,6 +140,7 @@ context("Create a View", () => {
.click({ force: true })
cy.get("[data-cy=delete-view]").click()
cy.contains("Delete View").click()
cy.wait(1000)
cy.contains("TestView Updated").should("not.be.visible")
})
})

View File

@ -156,7 +156,7 @@ Cypress.Commands.add("addComponent", (category, component) => {
cy.get(`[data-cy="category-${category}"]`).click()
}
cy.get(`[data-cy="component-${component}"]`).click()
cy.wait(500)
cy.wait(1000)
cy.location().then(loc => {
const params = loc.pathname.split("/")
const componentId = params[params.length - 1]

View File

@ -53,9 +53,6 @@
],
"setupFilesAfterEnv": [
"@testing-library/jest-dom/extend-expect"
],
"setupFiles": [
"./scripts/jestSetup.js"
]
},
"eslintConfig": {

View File

@ -1,26 +0,0 @@
// Array.flat needs polyfilled in < Node 11
if (!Array.prototype.flat) {
Object.defineProperty(Array.prototype, "flat", {
configurable: true,
value: function flat() {
var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0])
return depth
? Array.prototype.reduce.call(
this,
function(acc, cur) {
if (Array.isArray(cur)) {
acc.push.apply(acc, flat.call(cur, depth - 1))
} else {
acc.push(cur)
}
return acc
},
[]
)
: Array.prototype.slice.call(this)
},
writable: true,
})
}

View File

@ -42,7 +42,7 @@
<EditTablePopover {table} />
{/if}
</NavItem>
{#each Object.keys(table.views || {}) as viewName}
{#each Object.keys(table.views || {}) as viewName, idx (idx)}
<NavItem
indentLevel={1}
icon="ri-eye-line"

View File

@ -107,7 +107,10 @@ export function createTablesStore() {
state.draft.indexes = indexes
}
state.draft.schema[field.name] = cloneDeep(field)
state.draft.schema = {
...state.draft.schema,
[field.name]: cloneDeep(field),
}
save(state.draft)
return state
})

View File

@ -10,7 +10,7 @@ export function createViewsStore() {
return {
subscribe,
select: view => {
select: async view => {
update(state => ({
...state,
selected: view,
@ -29,18 +29,15 @@ export function createViewsStore() {
...json,
}
update(state => {
const viewTable = get(tables).list.find(
table => table._id === view.tableId
)
if (view.originalName) delete viewTable.views[view.originalName]
viewTable.views[view.name] = viewMeta
await tables.save(viewTable)
state.tables = state.tables
state.selectedView = viewMeta
return state
})
update(state => ({ ...state, selected: viewMeta }))
},
}
}

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@
"inquirer": "^8.0.0",
"lookpath": "^1.1.0",
"pkg": "^4.4.9",
"posthog-node": "^1.0.7",
"randomstring": "^1.1.5"
},
"devDependencies": {

View File

@ -0,0 +1,38 @@
const PostHog = require("posthog-node")
const {
BUDIBASE_POSTHOG_URL,
BUDIBASE_POSTHOG_TOKEN,
AnalyticsEvents,
} = require("../constants")
const ConfigManager = require("../structures/ConfigManager")
class AnalyticsClient {
constructor() {
this.client = new PostHog(BUDIBASE_POSTHOG_TOKEN, {
host: BUDIBASE_POSTHOG_URL,
})
this.configManager = new ConfigManager()
}
capture(event) {
if (this.manager.config.analyticsDisabled) return
this.client.capture(event)
}
enable() {
this.configManager.removeKey("analyticsDisabled")
this.client.capture({ event: AnalyticsEvents.OptIn, distinctId: "cli" })
}
disable() {
this.client.capture({ event: AnalyticsEvents.OptOut, distinctId: "cli" })
this.configManager.setValue("analyticsDisabled", true)
}
status() {
return this.configManager.config.analyticsDisabled ? "disabled" : "enabled"
}
}
module.exports = AnalyticsClient

View File

@ -0,0 +1,63 @@
const Command = require("../structures/Command")
const { CommandWords } = require("../constants")
const { success, error } = require("../utils")
const AnalyticsClient = require("./Client")
const client = new AnalyticsClient()
async function optOut() {
try {
// opt them out
client.disable()
console.log(
success(
"Successfully opted out of budibase analytics. You can opt in at any time by running 'budi analytics opt-in'"
)
)
} catch (err) {
console.log(
error(
"Error opting out of budibase analytics. Please try again later.",
err
)
)
}
}
async function optIn() {
try {
// opt them in
client.enable()
console.log(
success(
"Successfully opted in to budibase analytics. Thank you for helping us make budibase better!"
)
)
} catch (err) {
console.log(
error("Error opting in to budibase analytics. Please try again later.")
)
}
}
async function status() {
try {
console.log(success(`Budibase analytics ${client.status()}`))
} catch (err) {
console.log(
error("Error fetching analytics status. Please try again later.")
)
}
}
const command = new Command(`${CommandWords.ANALYTICS}`)
.addHelp("Control the analytics you send to budibase.")
.addSubOption("--optin", "Opt in to sending analytics to budibase", optIn)
.addSubOption("--optout", "Opt out of sending analytics to budibase.", optOut)
.addSubOption(
"--status",
"Check whether you are currently opted in to budibase analytics.",
status
)
exports.command = command

View File

@ -1,5 +1,6 @@
exports.CommandWords = {
HOSTING: "hosting",
ANALYTICS: "analytics",
HELP: "help",
}
@ -7,3 +8,12 @@ exports.InitTypes = {
QUICK: "quick",
DIGITAL_OCEAN: "do",
}
exports.AnalyticsEvents = {
OptOut: "analytics_opt_out",
OptIn: "analytics_opt_in",
SelfHostInit: "hosting_init",
}
exports.BUDIBASE_POSTHOG_URL = "https://posthog.budi.live"
exports.BUDIBASE_POSTHOG_TOKEN = process.env.BUDIBASE_POSTHOG_TOKEN

View File

@ -1,5 +1,5 @@
const Command = require("../structures/Command")
const { CommandWords, InitTypes } = require("../constants")
const { CommandWords, InitTypes, AnalyticsEvents } = require("../constants")
const { lookpath } = require("lookpath")
const {
downloadFile,
@ -13,6 +13,7 @@ const fs = require("fs")
const compose = require("docker-compose")
const makeEnv = require("./makeEnv")
const axios = require("axios")
const AnalyticsClient = require("../analytics/Client")
const BUDIBASE_SERVICES = ["app-service", "worker-service"]
const ERROR_FILE = "docker-error.log"
@ -22,6 +23,8 @@ const FILE_URLS = [
]
const DO_USER_DATA_URL = "http://169.254.169.254/metadata/v1/user-data"
const client = new AnalyticsClient()
async function downloadFiles() {
const promises = []
for (let url of FILE_URLS) {
@ -70,6 +73,13 @@ async function init(type) {
return
}
}
client.capture({
distinctId: "cli",
event: AnalyticsEvents.SelfHostInit,
properties: {
type,
},
})
await downloadFiles()
const config = isQuick ? makeEnv.QUICK_CONFIG : {}
if (type === InitTypes.DIGITAL_OCEAN) {

View File

@ -1,5 +1,6 @@
const analytics = require("./analytics")
const hosting = require("./hosting")
exports.getCommands = () => {
return [hosting.command]
return [hosting.command, analytics.command]
}

View File

@ -0,0 +1,50 @@
const fs = require("fs")
const path = require("path")
const os = require("os")
const { error } = require("../utils")
class ConfigManager {
constructor() {
this.path = path.join(os.homedir(), ".budibase.json")
if (!fs.existsSync(this.path)) {
fs.writeFileSync(this.path, "{}")
}
}
get config() {
try {
return JSON.parse(fs.readFileSync(this.path, "utf8"))
} catch (err) {
console.log(
error(
"Error parsing configuration file. Please check your .budibase.json is valid."
)
)
return {}
}
}
set config(json) {
fs.writeFileSync(this.path, JSON.stringify(json))
}
getValue(key) {
return this.config[key]
}
setValue(key, value) {
const updated = {
...this.config,
[key]: value,
}
this.config = updated
}
removeKey(key) {
const updated = { ...this.config }
delete updated[key]
this.config = updated
}
}
module.exports = ConfigManager

View File

@ -42,7 +42,7 @@ exports.info = info => {
}
exports.logErrorToFile = (file, error) => {
fs.writeFileSync(path.resolve(`./${file}`), `Budiase Error\n${error}`)
fs.writeFileSync(path.resolve(`./${file}`), `Budibase Error\n${error}`)
}
exports.parseEnv = env => {

View File

@ -181,6 +181,13 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
axios-retry@^3.1.9:
version "3.1.9"
resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.1.9.tgz#6c30fc9aeb4519aebaec758b90ef56fa03fe72e8"
integrity sha512-NFCoNIHq8lYkJa6ku4m+V1837TP6lCa7n79Iuf8/AqATAHYB0ISaAS1eyIenDOfHOLtym34W65Sjke2xjg2fsA==
dependencies:
is-retry-allowed "^1.1.0"
axios@^0.21.1:
version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
@ -260,6 +267,11 @@ chardet@^0.7.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
charenc@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
cli-cursor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
@ -308,6 +320,11 @@ commander@^7.1.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-7.1.0.tgz#f2eaecf131f10e36e07d894698226e36ae0eb5ff"
integrity sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==
component-type@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9"
integrity sha1-ikeQFwAjjk/DIml3EjAibyS0Fak=
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@ -327,6 +344,11 @@ cross-spawn@^7.0.2:
shebang-command "^2.0.0"
which "^2.0.1"
crypt@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@ -832,6 +854,11 @@ into-stream@^5.1.1:
from2 "^2.3.0"
p-is-promise "^3.0.0"
is-buffer@~1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-core-module@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a"
@ -861,6 +888,11 @@ is-number@^7.0.0:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-retry-allowed@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
@ -881,6 +913,11 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
join-component@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/join-component/-/join-component-1.1.0.tgz#b8417b750661a392bee2c2537c68b2a9d4977cd5"
integrity sha1-uEF7dQZho5K+4sJTfGiyqdSXfNU=
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@ -974,6 +1011,15 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
md5@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
dependencies:
charenc "0.0.2"
crypt "0.0.2"
is-buffer "~1.1.6"
merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
@ -1028,6 +1074,11 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
multistream@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/multistream/-/multistream-2.1.1.tgz#629d3a29bd76623489980d04519a2c365948148c"
@ -1172,6 +1223,20 @@ pkg@^4.4.9:
resolve "^1.15.1"
stream-meter "^1.0.4"
posthog-node@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/posthog-node/-/posthog-node-1.0.7.tgz#a7a9525eebff23312117e57cff3ddac82afb2262"
integrity sha512-KTCwyU+PU1eAQtjy5ZSJ47mrxv2d/mMkxo+vvV5c+YqfE4mBAY1UPEPMv1nElb5Vq0UnxvyQXaUnOn8d8Xr6Eg==
dependencies:
axios "^0.21.1"
axios-retry "^3.1.9"
component-type "^1.2.1"
join-component "^1.1.0"
md5 "^2.3.0"
ms "^2.1.3"
remove-trailing-slash "^0.1.1"
uuid "^8.3.2"
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@ -1242,6 +1307,11 @@ regexpp@^3.1.0:
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
remove-trailing-slash@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz#be2285a59f39c74d1bce4f825950061915e3780d"
integrity sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==
request-progress@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe"
@ -1593,6 +1663,11 @@ uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-compile-cache@^2.0.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"