Merge remote-tracking branch 'origin/develop' into feature/foreach-block
This commit is contained in:
commit
97c49b11d2
|
@ -93,6 +93,8 @@ then `cd ` into your local copy.
|
|||
|
||||
#### 3. Install and Build
|
||||
|
||||
| **NOTE**: On Windows, all yarn commands must be executed on a bash shell (e.g. git bash)
|
||||
|
||||
To develop the Budibase platform you'll need [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) installed.
|
||||
|
||||
##### Quick method
|
||||
|
|
|
@ -28,6 +28,7 @@ jobs:
|
|||
|
||||
- name: Cypress run
|
||||
id: cypress
|
||||
continue-on-error: true
|
||||
uses: cypress-io/github-action@v2
|
||||
with:
|
||||
install: false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/backend-core",
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"description": "Budibase backend core libraries used in server and worker",
|
||||
"main": "src/index.js",
|
||||
"author": "Budibase",
|
||||
|
|
|
@ -16,6 +16,7 @@ exports.Headers = {
|
|||
API_VER: "x-budibase-api-version",
|
||||
APP_ID: "x-budibase-app-id",
|
||||
TYPE: "x-budibase-type",
|
||||
PREVIEW_ROLE: "x-budibase-role",
|
||||
TENANT_ID: "x-budibase-tenant-id",
|
||||
TOKEN: "x-budibase-token",
|
||||
CSRF_TOKEN: "x-csrf-token",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/bbui",
|
||||
"description": "A UI solution used in the different Budibase projects.",
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"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.105-alpha.9",
|
||||
"@budibase/string-templates": "^1.0.105-alpha.19",
|
||||
"@spectrum-css/actionbutton": "^1.0.1",
|
||||
"@spectrum-css/actiongroup": "^1.0.1",
|
||||
"@spectrum-css/avatar": "^3.0.2",
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
padding-left: var(--spacing-l);
|
||||
padding-right: var(--spacing-l);
|
||||
}
|
||||
.paddingX-XL {
|
||||
padding-left: var(--spacing-xl);
|
||||
padding-right: var(--spacing-xl);
|
||||
}
|
||||
.paddingY-S {
|
||||
padding-top: var(--spacing-s);
|
||||
padding-bottom: var(--spacing-s);
|
||||
|
@ -48,6 +52,10 @@
|
|||
padding-top: var(--spacing-l);
|
||||
padding-bottom: var(--spacing-l);
|
||||
}
|
||||
.paddingY-XL {
|
||||
padding-top: var(--spacing-xl);
|
||||
padding-bottom: var(--spacing-xl);
|
||||
}
|
||||
.gap-XXS {
|
||||
grid-gap: var(--spacing-xs);
|
||||
}
|
||||
|
|
|
@ -1,42 +1,21 @@
|
|||
<script>
|
||||
import Icon from "../Icon/Icon.svelte"
|
||||
import { copyToClipboard } from "../helpers"
|
||||
import { notifications } from "../Stores/notifications"
|
||||
|
||||
export let value
|
||||
|
||||
const onClick = e => {
|
||||
const onClick = async e => {
|
||||
e.stopPropagation()
|
||||
copyToClipboard(value)
|
||||
}
|
||||
|
||||
const copyToClipboard = value => {
|
||||
return new Promise(res => {
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
// Try using the clipboard API first
|
||||
navigator.clipboard.writeText(value).then(res)
|
||||
} else {
|
||||
// Fall back to the textarea hack
|
||||
let textArea = document.createElement("textarea")
|
||||
textArea.value = value
|
||||
textArea.style.position = "fixed"
|
||||
textArea.style.left = "-9999px"
|
||||
textArea.style.top = "-9999px"
|
||||
document.body.appendChild(textArea)
|
||||
textArea.focus()
|
||||
textArea.select()
|
||||
document.execCommand("copy")
|
||||
textArea.remove()
|
||||
res()
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
try {
|
||||
await copyToClipboard(value)
|
||||
notifications.success("Copied to clipboard")
|
||||
})
|
||||
.catch(() => {
|
||||
} catch (error) {
|
||||
notifications.error(
|
||||
"Failed to copy to clipboard. Check the dev console for the value."
|
||||
)
|
||||
console.warn("Failed to copy the value", value)
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
padding-left: var(--spacing-xl);
|
||||
padding-right: var(--spacing-xl);
|
||||
position: relative;
|
||||
border-bottom: var(--border-light);
|
||||
border-bottom: 1px solid var(--spectrum-global-color-gray-300);
|
||||
}
|
||||
.spectrum-Tabs-content {
|
||||
margin-top: var(--spectrum-global-dimension-static-size-150);
|
||||
|
|
|
@ -106,3 +106,29 @@ export const deepSet = (obj, key, value) => {
|
|||
export const cloneDeep = obj => {
|
||||
return JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a value to the clipboard
|
||||
* @param value the value to copy
|
||||
*/
|
||||
export const copyToClipboard = value => {
|
||||
return new Promise(res => {
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
// Try using the clipboard API first
|
||||
navigator.clipboard.writeText(value).then(res)
|
||||
} else {
|
||||
// Fall back to the textarea hack
|
||||
let textArea = document.createElement("textarea")
|
||||
textArea.value = value
|
||||
textArea.style.position = "fixed"
|
||||
textArea.style.left = "-9999px"
|
||||
textArea.style.top = "-9999px"
|
||||
document.body.appendChild(textArea)
|
||||
textArea.focus()
|
||||
textArea.select()
|
||||
document.execCommand("copy")
|
||||
textArea.remove()
|
||||
res()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -53,10 +53,10 @@
|
|||
to-gfm-code-block "^0.1.1"
|
||||
year "^0.2.1"
|
||||
|
||||
"@budibase/string-templates@^1.0.104":
|
||||
version "1.0.104"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.104.tgz#f812700f2b21f638fd1e48dde065ae693fae2897"
|
||||
integrity sha512-3caq3qwpIieyb9m8eSl8OhcE0ppzuyJ/0ubDlWmtpbmwmG2v3ynI+DwxpbG4CcVQFuebD2yxU0CZfioU76vKCQ==
|
||||
"@budibase/string-templates@^1.0.105-alpha.4":
|
||||
version "1.0.108"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.108.tgz#14949560148ef11b6b385952ed5787c12b890f2c"
|
||||
integrity sha512-7Tts91Dzy+A7OdObTIaBNAdaixC7wmabnNTWYqk1d6TM6H5yv++bd/a9gVdUM7ptsuMy7uoP/ZoTZZRhp3ozfA==
|
||||
dependencies:
|
||||
"@budibase/handlebars-helpers" "^0.11.8"
|
||||
dayjs "^1.10.4"
|
||||
|
|
|
@ -25,9 +25,13 @@ filterTests(['smoke', 'all'], () => {
|
|||
cy.visit(`${Cypress.config().baseUrl}/builder`)
|
||||
cy.wait(500)
|
||||
|
||||
if (Cypress.env("TEST_ENV")) {
|
||||
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.get(".template-category-filters").should("exist")
|
||||
cy.get(".template-categories").should("exist")
|
||||
|
|
|
@ -55,13 +55,14 @@ filterTests(["smoke", "all"], () => {
|
|||
|
||||
if (Cypress.env("TEST_ENV")) {
|
||||
// No Pagination in CI - Test env only for the next two tests
|
||||
it("Adds 15 rows and checks pagination", () => {
|
||||
xit("Adds 15 rows and checks pagination", () => {
|
||||
// 10 rows per page, 15 rows should create 2 pages within table
|
||||
const totalRows = 16
|
||||
for (let i = 1; i < totalRows; i++) {
|
||||
cy.addRow([i])
|
||||
}
|
||||
cy.wait(1000)
|
||||
cy.reload()
|
||||
cy.wait(2000)
|
||||
cy.get(".spectrum-Pagination").within(() => {
|
||||
cy.get(".spectrum-ActionButton").eq(1).click()
|
||||
})
|
||||
|
@ -70,13 +71,13 @@ filterTests(["smoke", "all"], () => {
|
|||
})
|
||||
})
|
||||
|
||||
it("Deletes rows and checks pagination", () => {
|
||||
// Delete rows, removing second page of rows from table
|
||||
const deleteRows = 5
|
||||
xit("Deletes rows and checks pagination", () => {
|
||||
// Delete rows, removing second page from table
|
||||
cy.get(".spectrum-Checkbox-input").check({ force: true })
|
||||
cy.get(".spectrum-Table")
|
||||
cy.contains("Delete 5 row(s)").click()
|
||||
cy.get(".spectrum-Modal").contains("Delete").click()
|
||||
cy.get(".popovers").within(() => {
|
||||
cy.get(".spectrum-Button").click({ force: true })
|
||||
})
|
||||
cy.get(".spectrum-Dialog-grid").contains("Delete").click({ force: true })
|
||||
cy.wait(1000)
|
||||
|
||||
// Confirm table only has one page
|
||||
|
|
|
@ -19,6 +19,7 @@ filterTests(["all"], () => {
|
|||
cy.get(".spectrum-Button")
|
||||
.contains("Save and fetch tables")
|
||||
.click({ force: true })
|
||||
cy.wait(500)
|
||||
// Intercept Request after button click & apply assertions
|
||||
cy.wait("@datasource")
|
||||
cy.get("@datasource")
|
||||
|
@ -31,6 +32,7 @@ filterTests(["all"], () => {
|
|||
cy.get("@datasource")
|
||||
.its("response.body")
|
||||
.should("have.property", "status", 500)
|
||||
cy.get(".spectrum-Button").contains("Skip table fetch").click({ force: true })
|
||||
})
|
||||
|
||||
it("should add MySQL data source and fetch tables", () => {
|
||||
|
@ -72,10 +74,13 @@ filterTests(["all"], () => {
|
|||
cy.get(".spectrum-Popover").contains("COUNTRIES").click()
|
||||
cy.get(".spectrum-Picker").eq(4).click()
|
||||
cy.get(".spectrum-Popover").contains("REGION_ID").click()
|
||||
// Save relationship & reload page
|
||||
cy.get(".spectrum-Button").contains("Save").click({ force: true })
|
||||
cy.reload()
|
||||
})
|
||||
// Save relationship & reload page
|
||||
cy.get(".spectrum-ButtonGroup").within(() => {
|
||||
cy.get(".spectrum-Button").contains("Save").click({ force: true })
|
||||
})
|
||||
cy.reload()
|
||||
|
||||
// Confirm table length & column name
|
||||
cy.get(".spectrum-Table")
|
||||
.eq(1)
|
||||
|
@ -131,7 +136,7 @@ filterTests(["all"], () => {
|
|||
cy.get(".spectrum-Table")
|
||||
.eq(1)
|
||||
.within(() => {
|
||||
cy.get(".spectrum-Table-row").eq(0).click()
|
||||
cy.get(".spectrum-Table-row").eq(0).click({ force: true })
|
||||
cy.wait(500)
|
||||
})
|
||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
||||
|
@ -175,11 +180,12 @@ filterTests(["all"], () => {
|
|||
})
|
||||
|
||||
it("should duplicate a query", () => {
|
||||
// Get last nav item - The query
|
||||
/// Get query nav item - QueryName
|
||||
cy.get(".nav-item")
|
||||
.last()
|
||||
.contains(queryName)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get(".icon").eq(1).click({ force: true })
|
||||
cy.get(".spectrum-Icon").eq(1).click({ force: true })
|
||||
})
|
||||
// Select and confirm duplication
|
||||
cy.get(".spectrum-Menu").contains("Duplicate").click()
|
||||
|
@ -199,12 +205,12 @@ filterTests(["all"], () => {
|
|||
})
|
||||
|
||||
it("should delete a query", () => {
|
||||
// Get last nav item - The query
|
||||
for (let i = 0; i < 2; i++) {
|
||||
// Get query nav item - QueryName
|
||||
cy.get(".nav-item")
|
||||
.last()
|
||||
.contains(queryName)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get(".icon").eq(1).click({ force: true })
|
||||
cy.get(".spectrum-Icon").eq(1).click({ force: true })
|
||||
})
|
||||
// Select Delete
|
||||
cy.get(".spectrum-Menu").contains("Delete").click()
|
||||
|
@ -212,10 +218,8 @@ filterTests(["all"], () => {
|
|||
.contains("Delete Query")
|
||||
.click({ force: true })
|
||||
cy.wait(1000)
|
||||
}
|
||||
// Confirm deletion
|
||||
cy.get(".nav-item").should("not.contain", queryName)
|
||||
cy.get(".nav-item").should("not.contain", queryRename)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
|
@ -46,9 +46,10 @@ filterTests(["all"], () => {
|
|||
cy.get("@datasource")
|
||||
.its("response.body")
|
||||
.should("have.property", "status", 500)
|
||||
cy.get(".spectrum-Button").contains("Skip table fetch").click({ force: true })
|
||||
})
|
||||
|
||||
it("should add Oracle data source and fetch tables", () => {
|
||||
xit("should add Oracle data source and fetch tables", () => {
|
||||
// Add & configure Oracle data source
|
||||
cy.selectExternalDatasource(datasource)
|
||||
cy.intercept("**/datasources").as("datasource")
|
||||
|
@ -64,7 +65,7 @@ filterTests(["all"], () => {
|
|||
.should("be.gt", 0)
|
||||
})
|
||||
|
||||
it("should define a One relationship type", () => {
|
||||
xit("should define a One relationship type", () => {
|
||||
// Select relationship type & configure
|
||||
cy.get(".spectrum-Button")
|
||||
.contains("Define relationship")
|
||||
|
@ -93,7 +94,7 @@ filterTests(["all"], () => {
|
|||
cy.get(".spectrum-Table-cell").should("contain", "COUNTRIES to REGIONS")
|
||||
})
|
||||
|
||||
it("should define a Many relationship type", () => {
|
||||
xit("should define a Many relationship type", () => {
|
||||
// Select relationship type & configure
|
||||
cy.get(".spectrum-Button")
|
||||
.contains("Define relationship")
|
||||
|
@ -127,7 +128,7 @@ filterTests(["all"], () => {
|
|||
)
|
||||
})
|
||||
|
||||
it("should delete relationships", () => {
|
||||
xit("should delete relationships", () => {
|
||||
// Delete both relationships
|
||||
cy.get(".spectrum-Table")
|
||||
.eq(1)
|
||||
|
@ -156,7 +157,7 @@ filterTests(["all"], () => {
|
|||
})
|
||||
})
|
||||
|
||||
it("should add a query", () => {
|
||||
xit("should add a query", () => {
|
||||
// Add query
|
||||
cy.get(".spectrum-Button").contains("Add query").click({ force: true })
|
||||
cy.get(".spectrum-Form-item")
|
||||
|
@ -181,7 +182,7 @@ filterTests(["all"], () => {
|
|||
cy.get(".nav-item").should("contain", queryName)
|
||||
})
|
||||
|
||||
it("should duplicate a query", () => {
|
||||
xit("should duplicate a query", () => {
|
||||
// Get query nav item
|
||||
cy.get(".nav-item")
|
||||
.contains(queryName)
|
||||
|
@ -194,7 +195,7 @@ filterTests(["all"], () => {
|
|||
cy.get(".nav-item").should("contain", queryName + " (1)")
|
||||
})
|
||||
|
||||
it("should edit a query name", () => {
|
||||
xit("should edit a query name", () => {
|
||||
// Rename query
|
||||
cy.get(".spectrum-Form-item")
|
||||
.eq(0)
|
||||
|
@ -206,7 +207,7 @@ filterTests(["all"], () => {
|
|||
cy.get(".nav-item").should("contain", queryRename)
|
||||
})
|
||||
|
||||
it("should delete a query", () => {
|
||||
xit("should delete a query", () => {
|
||||
// Get query nav item - QueryName
|
||||
cy.get(".nav-item")
|
||||
.contains(queryName)
|
||||
|
|
|
@ -21,16 +21,10 @@ filterTests(["all"], () => {
|
|||
.click({ force: true })
|
||||
// Intercept Request after button click & apply assertions
|
||||
cy.wait("@datasource")
|
||||
cy.get("@datasource")
|
||||
.its("response.body")
|
||||
.should(
|
||||
"have.property",
|
||||
"message",
|
||||
"connect ECONNREFUSED 127.0.0.1:5432"
|
||||
)
|
||||
cy.get("@datasource")
|
||||
.its("response.body")
|
||||
.should("have.property", "status", 500)
|
||||
cy.get(".spectrum-Button").contains("Skip table fetch").click({ force: true })
|
||||
})
|
||||
|
||||
it("should add PostgreSQL data source and fetch tables", () => {
|
||||
|
@ -113,13 +107,13 @@ filterTests(["all"], () => {
|
|||
})
|
||||
|
||||
it("should delete a relationship", () => {
|
||||
cy.get(".hierarchy-items-container").contains(datasource).click()
|
||||
cy.get(".hierarchy-items-container").contains("PostgreSQL-2").click()
|
||||
cy.reload()
|
||||
// Delete one relationship
|
||||
cy.get(".spectrum-Table")
|
||||
.eq(1)
|
||||
.within(() => {
|
||||
cy.get(".spectrum-Table-row").eq(0).click()
|
||||
cy.get(".spectrum-Table-row").eq(0).click({ force: true })
|
||||
cy.wait(500)
|
||||
})
|
||||
cy.get(".spectrum-Dialog-grid").within(() => {
|
||||
|
@ -161,7 +155,7 @@ filterTests(["all"], () => {
|
|||
|
||||
it("should switch to schema with no tables", () => {
|
||||
// Switch Schema - To one without any tables
|
||||
cy.get(".hierarchy-items-container").contains(datasource).click()
|
||||
cy.get(".hierarchy-items-container").contains("PostgreSQL-2").click()
|
||||
switchSchema("randomText")
|
||||
|
||||
// No tables displayed
|
||||
|
@ -208,11 +202,12 @@ filterTests(["all"], () => {
|
|||
})
|
||||
|
||||
it("should duplicate a query", () => {
|
||||
// Get last nav item - The query
|
||||
// Locate previously created query
|
||||
cy.get(".nav-item")
|
||||
.last()
|
||||
.contains(queryName)
|
||||
.siblings(".actions")
|
||||
.within(() => {
|
||||
cy.get(".icon").eq(1).click({ force: true })
|
||||
cy.get(".icon").click({ force: true })
|
||||
})
|
||||
// Select and confirm duplication
|
||||
cy.get(".spectrum-Menu").contains("Duplicate").click()
|
||||
|
@ -240,12 +235,12 @@ filterTests(["all"], () => {
|
|||
})
|
||||
|
||||
it("should delete a query", () => {
|
||||
// Get last nav item - The query
|
||||
for (let i = 0; i < 2; i++) {
|
||||
// Get query nav item - QueryName
|
||||
cy.get(".nav-item")
|
||||
.last()
|
||||
.contains(queryName)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get(".icon").eq(1).click({ force: true })
|
||||
cy.get(".spectrum-Icon").eq(1).click({ force: true })
|
||||
})
|
||||
// Select Delete
|
||||
cy.get(".spectrum-Menu").contains("Delete").click()
|
||||
|
@ -253,10 +248,8 @@ filterTests(["all"], () => {
|
|||
.contains("Delete Query")
|
||||
.click({ force: true })
|
||||
cy.wait(1000)
|
||||
}
|
||||
// Confirm deletion
|
||||
cy.get(".nav-item").should("not.contain", queryName)
|
||||
cy.get(".nav-item").should("not.contain", queryRename)
|
||||
})
|
||||
|
||||
const switchSchema = schema => {
|
||||
|
|
|
@ -60,6 +60,8 @@ Cypress.Commands.add("deleteApp", name => {
|
|||
cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`)
|
||||
.its("body")
|
||||
.then(val => {
|
||||
const findAppName = val.some(val => val.name == name)
|
||||
if (findAppName) {
|
||||
if (val.length > 0) {
|
||||
if (Cypress.env("TEST_ENV")) {
|
||||
cy.searchForApplication(name)
|
||||
|
@ -100,6 +102,9 @@ Cypress.Commands.add("deleteApp", name => {
|
|||
} else {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -410,7 +415,9 @@ Cypress.Commands.add("addDatasourceConfig", (datasource, skipFetch) => {
|
|||
if (datasource == "Oracle") {
|
||||
cy.get("input").clear().type(Cypress.env("oracle").HOST)
|
||||
} else {
|
||||
cy.get("input").clear().type(Cypress.env("HOST_IP"))
|
||||
cy.get("input")
|
||||
.clear({ force: true })
|
||||
.type(Cypress.env("mysql").HOST, { force: true })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/builder",
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"license": "GPL-3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -65,10 +65,10 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "^1.0.105-alpha.9",
|
||||
"@budibase/client": "^1.0.105-alpha.9",
|
||||
"@budibase/frontend-core": "^1.0.105-alpha.9",
|
||||
"@budibase/string-templates": "^1.0.105-alpha.9",
|
||||
"@budibase/bbui": "^1.0.105-alpha.19",
|
||||
"@budibase/client": "^1.0.105-alpha.19",
|
||||
"@budibase/frontend-core": "^1.0.105-alpha.19",
|
||||
"@budibase/string-templates": "^1.0.105-alpha.19",
|
||||
"@sentry/browser": "5.19.1",
|
||||
"@spectrum-css/page": "^3.0.1",
|
||||
"@spectrum-css/vars": "^3.0.1",
|
||||
|
|
|
@ -127,6 +127,8 @@
|
|||
outputs.map(([name, value]) => {
|
||||
let runtimeName = isLoopBlock
|
||||
? `loop.${name}`
|
||||
: block.name.startsWith("JS")
|
||||
? `steps[${idx}].${name}`
|
||||
: `steps.${idx}.${name}`
|
||||
const runtime = idx === 0 ? `trigger.${name}` : runtimeName
|
||||
return {
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
.map(query => ({
|
||||
label: query.name,
|
||||
name: query.name,
|
||||
tableId: query._id,
|
||||
...query,
|
||||
type: "query",
|
||||
}))
|
||||
|
|
|
@ -10,9 +10,15 @@
|
|||
let drawer
|
||||
let tempValue = value || []
|
||||
|
||||
const saveFilter = async () => {
|
||||
// Filter out incomplete options
|
||||
tempValue = tempValue.filter(option => option.value && option.label)
|
||||
const saveOptions = async () => {
|
||||
// Filter out incomplete options, default if needed
|
||||
tempValue = tempValue.filter(option => option.value || option.label)
|
||||
for (let i = 0; i < tempValue.length; i++) {
|
||||
let option = tempValue[i]
|
||||
option.label = option.label ? option.label : option.value
|
||||
option.value = option.value ? option.value : option.label
|
||||
tempValue[i] = option
|
||||
}
|
||||
dispatch("change", tempValue)
|
||||
drawer.hide()
|
||||
}
|
||||
|
@ -23,6 +29,6 @@
|
|||
<svelte:fragment slot="description">
|
||||
Define the options for this picker.
|
||||
</svelte:fragment>
|
||||
<Button cta slot="buttons" on:click={saveFilter}>Save</Button>
|
||||
<Button cta slot="buttons" on:click={saveOptions}>Save</Button>
|
||||
<OptionsDrawer bind:options={tempValue} slot="body" />
|
||||
</Drawer>
|
||||
|
|
|
@ -15,16 +15,14 @@
|
|||
|
||||
const dispatch = createEventDispatcher()
|
||||
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
||||
$: schema = getSchemaForDatasource($currentAsset, datasource, {
|
||||
searchableSchema: true,
|
||||
}).schema
|
||||
$: schema = getSchemaForDatasource($currentAsset, datasource).schema
|
||||
$: options = getOptions(datasource, schema || {})
|
||||
$: boundValue = getSelectedOption(value, options)
|
||||
|
||||
function getOptions(ds, dsSchema) {
|
||||
let base = Object.values(dsSchema)
|
||||
if (!ds?.tableId) {
|
||||
return base
|
||||
return base.map(field => field.name)
|
||||
}
|
||||
const currentTable = $tables.list.find(table => table._id === ds.tableId)
|
||||
return getFields(base, { allowLinks: currentTable?.sql }).map(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/cli",
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||
"main": "src/index.js",
|
||||
"bin": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/client",
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"license": "MPL-2.0",
|
||||
"module": "dist/budibase-client.js",
|
||||
"main": "dist/budibase-client.js",
|
||||
|
@ -19,9 +19,9 @@
|
|||
"dev:builder": "rollup -cw"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "^1.0.105-alpha.9",
|
||||
"@budibase/frontend-core": "^1.0.105-alpha.9",
|
||||
"@budibase/string-templates": "^1.0.105-alpha.9",
|
||||
"@budibase/bbui": "^1.0.105-alpha.19",
|
||||
"@budibase/frontend-core": "^1.0.105-alpha.19",
|
||||
"@budibase/string-templates": "^1.0.105-alpha.19",
|
||||
"@spectrum-css/button": "^3.0.3",
|
||||
"@spectrum-css/card": "^3.0.3",
|
||||
"@spectrum-css/divider": "^1.0.3",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createAPIClient } from "@budibase/frontend-core"
|
||||
import { notificationStore, authStore } from "../stores"
|
||||
import { notificationStore, authStore, devToolsStore } from "../stores"
|
||||
import { get } from "svelte/store"
|
||||
|
||||
export const API = createAPIClient({
|
||||
|
@ -21,6 +21,12 @@ export const API = createAPIClient({
|
|||
if (auth?.csrfToken) {
|
||||
headers["x-csrf-token"] = auth.csrfToken
|
||||
}
|
||||
|
||||
// Add role header
|
||||
const role = get(devToolsStore).role
|
||||
if (role) {
|
||||
headers["x-budibase-role"] = role
|
||||
}
|
||||
},
|
||||
|
||||
// Show an error notification for all API failures.
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
routeStore,
|
||||
builderStore,
|
||||
themeStore,
|
||||
appStore,
|
||||
devToolsStore,
|
||||
} from "stores"
|
||||
import NotificationDisplay from "components/overlay/NotificationDisplay.svelte"
|
||||
import ConfirmationDisplay from "components/overlay/ConfirmationDisplay.svelte"
|
||||
|
@ -28,6 +30,8 @@
|
|||
import CustomThemeWrapper from "./CustomThemeWrapper.svelte"
|
||||
import DNDHandler from "components/preview/DNDHandler.svelte"
|
||||
import KeyboardManager from "components/preview/KeyboardManager.svelte"
|
||||
import DevToolsHeader from "components/devtools/DevToolsHeader.svelte"
|
||||
import DevTools from "components/devtools/DevTools.svelte"
|
||||
|
||||
// Provide contexts
|
||||
setContext("sdk", SDK)
|
||||
|
@ -55,8 +59,22 @@
|
|||
if ($authStore) {
|
||||
// There is a logged in user, so handle them
|
||||
if ($screenStore.screens.length) {
|
||||
let firstRoute
|
||||
|
||||
// If using devtools, find the first screen matching our role
|
||||
if ($devToolsStore.role) {
|
||||
const roleRoutes = $screenStore.screens.filter(
|
||||
screen => screen.routing?.roleId === $devToolsStore.role
|
||||
)
|
||||
firstRoute = roleRoutes[0]?.routing?.route || "/"
|
||||
}
|
||||
|
||||
// Otherwise just use the first route
|
||||
else {
|
||||
firstRoute = $screenStore.screens[0]?.routing?.route ?? "/"
|
||||
}
|
||||
|
||||
// Screens exist so navigate back to the home screen
|
||||
const firstRoute = $screenStore.screens[0].routing?.route ?? "/"
|
||||
routeStore.actions.navigate(firstRoute)
|
||||
} else {
|
||||
// No screens likely means the user has no permissions to view this app
|
||||
|
@ -70,6 +88,8 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$: isDevPreview = $appStore.isDevApp && !$builderStore.inBuilder
|
||||
</script>
|
||||
|
||||
{#if dataLoaded}
|
||||
|
@ -109,6 +129,11 @@
|
|||
>
|
||||
<!-- Actual app -->
|
||||
<div id="app-root">
|
||||
{#if isDevPreview}
|
||||
<DevToolsHeader />
|
||||
{/if}
|
||||
|
||||
<div id="app-body">
|
||||
<CustomThemeWrapper>
|
||||
{#key `${$screenStore.activeLayout._id}-${$builderStore.previewType}`}
|
||||
<Component
|
||||
|
@ -132,16 +157,21 @@
|
|||
<ConfirmationDisplay />
|
||||
<PeekScreenDisplay />
|
||||
</CustomThemeWrapper>
|
||||
|
||||
{#if $appStore.isDevApp && !$builderStore.inBuilder}
|
||||
<DevTools />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Selection indicators should be bounded by device -->
|
||||
<!--
|
||||
We don't want to key these by componentID as they control their own
|
||||
re-mounting to avoid flashes.
|
||||
-->
|
||||
{#if $builderStore.inBuilder}
|
||||
<!-- Preview and dev tools utilities -->
|
||||
{#if $appStore.isDevApp}
|
||||
<SelectionIndicator />
|
||||
{/if}
|
||||
{#if $builderStore.inBuilder || $devToolsStore.allowSelection}
|
||||
<HoverIndicator />
|
||||
{/if}
|
||||
{#if $builderStore.inBuilder}
|
||||
<DNDHandler />
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -167,6 +197,7 @@
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#clip-root {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
|
@ -176,10 +207,24 @@
|
|||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#app-root {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
#app-body {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.error {
|
||||
|
@ -192,19 +237,23 @@
|
|||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.error :global(svg) {
|
||||
fill: var(--spectrum-global-color-gray-500);
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.error :global(h1),
|
||||
.error :global(p) {
|
||||
color: var(--spectrum-global-color-gray-800);
|
||||
}
|
||||
|
||||
.error :global(p) {
|
||||
font-style: italic;
|
||||
margin-top: -0.5em;
|
||||
}
|
||||
|
||||
.error :global(h1) {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
@ -214,14 +263,17 @@
|
|||
#clip-root.preview {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#clip-root.tablet-preview {
|
||||
width: calc(1024px + 6px);
|
||||
height: calc(768px + 6px);
|
||||
}
|
||||
|
||||
#clip-root.mobile-preview {
|
||||
width: calc(390px + 6px);
|
||||
height: calc(844px + 6px);
|
||||
}
|
||||
|
||||
.preview #app-root {
|
||||
border: 1px solid var(--spectrum-global-color-gray-300);
|
||||
border-radius: 4px;
|
||||
|
|
|
@ -9,12 +9,16 @@
|
|||
</script>
|
||||
|
||||
<script>
|
||||
import { getContext, setContext } from "svelte"
|
||||
import { getContext, setContext, onMount, onDestroy } from "svelte"
|
||||
import { writable, get } from "svelte/store"
|
||||
import * as AppComponents from "components/app"
|
||||
import Router from "./Router.svelte"
|
||||
import { enrichProps, propsAreSame } from "utils/componentProps"
|
||||
import { builderStore } from "stores"
|
||||
import {
|
||||
enrichProps,
|
||||
propsAreSame,
|
||||
getSettingsDefinition,
|
||||
} from "utils/componentProps"
|
||||
import { builderStore, devToolsStore, componentStore, appStore } from "stores"
|
||||
import { Helpers } from "@budibase/bbui"
|
||||
import Manifest from "manifest.json"
|
||||
import { getActiveConditions, reduceConditionActions } from "utils/conditions"
|
||||
|
@ -30,8 +34,8 @@
|
|||
const insideScreenslot = !!getContext("screenslot")
|
||||
|
||||
// Create component context
|
||||
const componentStore = writable({})
|
||||
setContext("component", componentStore)
|
||||
const store = writable({})
|
||||
setContext("component", store)
|
||||
|
||||
// Ref to the svelte component
|
||||
let ref
|
||||
|
@ -90,7 +94,7 @@
|
|||
// leading to the selected component
|
||||
$: selected =
|
||||
$builderStore.inBuilder && $builderStore.selectedComponentId === id
|
||||
$: inSelectedPath = $builderStore.selectedComponentPath?.includes(id)
|
||||
$: inSelectedPath = $componentStore.selectedComponentPath?.includes(id)
|
||||
$: inDragPath = inSelectedPath && $builderStore.editMode
|
||||
|
||||
// Derive definition properties which can all be optional, so need to be
|
||||
|
@ -101,10 +105,12 @@
|
|||
|
||||
// Interactive components can be selected, dragged and highlighted inside
|
||||
// the builder preview
|
||||
$: interactive =
|
||||
$: builderInteractive =
|
||||
$builderStore.inBuilder &&
|
||||
($builderStore.previewType === "layout" || insideScreenslot) &&
|
||||
!isBlock
|
||||
$: devToolsInteractive = $devToolsStore.allowSelection && !isBlock
|
||||
$: interactive = builderInteractive || devToolsInteractive
|
||||
$: editing = editable && selected && $builderStore.editMode
|
||||
$: draggable =
|
||||
!inDragPath &&
|
||||
|
@ -133,7 +139,7 @@
|
|||
$: applySettings(staticSettings, enrichedSettings, conditionalSettings)
|
||||
|
||||
// Update component context
|
||||
$: componentStore.set({
|
||||
$: store.set({
|
||||
id,
|
||||
children: children.length,
|
||||
styles: {
|
||||
|
@ -217,22 +223,6 @@
|
|||
return type ? Manifest[type] : null
|
||||
}
|
||||
|
||||
// Gets the definition of this component's settings from the manifest
|
||||
const getSettingsDefinition = definition => {
|
||||
if (!definition) {
|
||||
return []
|
||||
}
|
||||
let settings = []
|
||||
definition.settings?.forEach(setting => {
|
||||
if (setting.section) {
|
||||
settings = settings.concat(setting.settings || [])
|
||||
} else {
|
||||
settings.push(setting)
|
||||
}
|
||||
})
|
||||
return settings
|
||||
}
|
||||
|
||||
const getSettingsDefinitionMap = settingsDefinition => {
|
||||
let map = {}
|
||||
settingsDefinition?.forEach(setting => {
|
||||
|
@ -385,6 +375,28 @@
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
if (
|
||||
$appStore.isDevApp &&
|
||||
!componentStore.actions.isComponentRegistered(id)
|
||||
) {
|
||||
componentStore.actions.registerInstance(id, {
|
||||
getSettings: () => cachedSettings,
|
||||
getRawSettings: () => ({ ...staticSettings, ...dynamicSettings }),
|
||||
getDataContext: () => get(context),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
if (
|
||||
$appStore.isDevApp &&
|
||||
componentStore.actions.isComponentRegistered(id)
|
||||
) {
|
||||
componentStore.actions.unregisterInstance(id)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if constructor && initialSettings && (visible || inSelectedPath)}
|
||||
|
@ -419,12 +431,15 @@
|
|||
.component {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.interactive :global(*:hover) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.draggable :global(*:hover) {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.editing :global(*:hover) {
|
||||
cursor: auto;
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
height: 100%;
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
position: relative;
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
}
|
||||
|
||||
const fetchTable = async dataSource => {
|
||||
if (dataSource?.tableId) {
|
||||
if (dataSource?.tableId && dataSource?.type !== "query") {
|
||||
try {
|
||||
table = await API.fetchTableDefinition(dataSource.tableId)
|
||||
} catch (error) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
export let step = 1
|
||||
|
||||
const { styleable, builderStore } = getContext("sdk")
|
||||
const { styleable, builderStore, componentStore } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
const formContext = getContext("form")
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
|||
if (
|
||||
formContext &&
|
||||
$builderStore.inBuilder &&
|
||||
$builderStore.selectedComponentPath?.includes($component.id)
|
||||
$componentStore.selectedComponentPath?.includes($component.id)
|
||||
) {
|
||||
formContext.formApi.setStep(step)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import Provider from "./Provider.svelte"
|
||||
import { authStore } from "stores"
|
||||
import { authStore, devToolsStore } from "stores"
|
||||
import { ActionTypes } from "constants"
|
||||
import { Constants } from "@budibase/frontend-core"
|
||||
|
||||
|
@ -17,6 +17,10 @@
|
|||
]
|
||||
</script>
|
||||
|
||||
<Provider key="user" data={$authStore} {actions}>
|
||||
<Provider
|
||||
key="user"
|
||||
data={{ ...$authStore, roleId: $devToolsStore.role || $authStore?.roleId }}
|
||||
{actions}
|
||||
>
|
||||
<slot />
|
||||
</Provider>
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { Layout, Heading, Tabs, Tab, Icon } from "@budibase/bbui"
|
||||
import DevToolsStatsTab from "./DevToolsStatsTab.svelte"
|
||||
import DevToolsComponentTab from "./DevToolsComponentTab.svelte"
|
||||
import { devToolsStore } from "stores"
|
||||
|
||||
const context = getContext("context")
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="devtools"
|
||||
class:hidden={!$devToolsStore.visible}
|
||||
class:mobile={$context.device.mobile}
|
||||
>
|
||||
{#if $devToolsStore.visible}
|
||||
<Layout noPadding gap="XS">
|
||||
<div class="header">
|
||||
<Heading size="XS">Budibase DevTools</Heading>
|
||||
<Icon
|
||||
hoverable
|
||||
name="Close"
|
||||
on:click={() => devToolsStore.actions.setVisible(false)}
|
||||
/>
|
||||
</div>
|
||||
<Tabs selected="Application">
|
||||
<Tab title="Application">
|
||||
<div class="tab-content">
|
||||
<DevToolsStatsTab />
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab title="Components">
|
||||
<div class="tab-content">
|
||||
<DevToolsComponentTab />
|
||||
</div>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Layout>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.devtools {
|
||||
background: var(--spectrum-alias-background-color-primary);
|
||||
flex: 0 0 320px;
|
||||
border-left: 1px solid var(--spectrum-global-color-gray-300);
|
||||
overflow: auto;
|
||||
transition: margin-right 300ms ease;
|
||||
margin-right: 0;
|
||||
}
|
||||
.devtools.hidden {
|
||||
margin-right: -320px;
|
||||
}
|
||||
.devtools.mobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: var(--spacing-xl) var(--spacing-xl) 0 var(--spacing-xl);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 0 var(--spacing-xl);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,113 @@
|
|||
<script>
|
||||
import { Layout, Select, Body } from "@budibase/bbui"
|
||||
import { componentStore } from "stores/index.js"
|
||||
import DevToolsStat from "./DevToolsStat.svelte"
|
||||
|
||||
const ReadableBindingMap = {
|
||||
user: "Current user",
|
||||
state: "State",
|
||||
url: "URL",
|
||||
device: "Device",
|
||||
rowSelection: "Selected rows",
|
||||
}
|
||||
|
||||
let category
|
||||
|
||||
$: selectedInstance = $componentStore.selectedComponentInstance
|
||||
$: context = selectedInstance?.getDataContext()
|
||||
$: bindingCategories = getContextProviders(context)
|
||||
$: bindings = Object.entries(context?.[category] || {})
|
||||
|
||||
const getContextProviders = context => {
|
||||
const filteredContext = { ...context }
|
||||
|
||||
// Remove some keys from context
|
||||
delete filteredContext.key
|
||||
delete filteredContext.closestComponentId
|
||||
delete filteredContext.user_RefreshDataSource
|
||||
|
||||
// Keep track of encountered IDs so we can find actions
|
||||
let actions = []
|
||||
let encounteredCategories = []
|
||||
|
||||
// Create readable bindings
|
||||
let categories = []
|
||||
Object.keys(filteredContext)
|
||||
.sort()
|
||||
.forEach(category => {
|
||||
let isAction = false
|
||||
for (let cat of encounteredCategories) {
|
||||
if (category.startsWith(`${cat}_`)) {
|
||||
isAction = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (isAction) {
|
||||
actions.push(category)
|
||||
return
|
||||
}
|
||||
|
||||
// Mark category as encountered so we can find any matching actions
|
||||
encounteredCategories.push(category)
|
||||
|
||||
// Map any static categories to pretty names
|
||||
if (ReadableBindingMap[category]) {
|
||||
categories.push({
|
||||
label: ReadableBindingMap[category],
|
||||
value: category,
|
||||
})
|
||||
} else {
|
||||
const component = componentStore.actions.getComponentById(category)
|
||||
if (component) {
|
||||
categories.push({
|
||||
label: component._instanceName,
|
||||
value: category,
|
||||
})
|
||||
} else {
|
||||
// Check if its a block
|
||||
if (category.includes("-")) {
|
||||
const split = category.split("-")
|
||||
const potentialId = split[0]
|
||||
const component =
|
||||
componentStore.actions.getComponentById(potentialId)
|
||||
if (component) {
|
||||
categories.push({
|
||||
label: `${component._instanceName} (${split[1]})`,
|
||||
value: category,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise we don't know
|
||||
categories.push({
|
||||
label: "Unknown - " + category,
|
||||
value: category,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return categories
|
||||
}
|
||||
</script>
|
||||
|
||||
<Layout noPadding gap="S">
|
||||
<Body size="S">
|
||||
Choose a category to see the value of all its available bindings.
|
||||
</Body>
|
||||
<Select bind:value={category} label="Category" options={bindingCategories} />
|
||||
{#if bindings?.length}
|
||||
<Layout noPadding gap="XS">
|
||||
{#each bindings as binding}
|
||||
<DevToolsStat
|
||||
copyable
|
||||
label={binding[0]}
|
||||
value={JSON.stringify(binding[1])}
|
||||
/>
|
||||
{/each}
|
||||
</Layout>
|
||||
{:else if category}
|
||||
<Body size="XS">There aren't any bindings available in this category.</Body>
|
||||
{/if}
|
||||
</Layout>
|
|
@ -0,0 +1,13 @@
|
|||
<script>
|
||||
import DevToolsStat from "./DevToolsStat.svelte"
|
||||
|
||||
export let name
|
||||
export let value
|
||||
export let settingsMap
|
||||
|
||||
$: prettyName = settingsMap?.[name]?.label
|
||||
</script>
|
||||
|
||||
{#if prettyName}
|
||||
<DevToolsStat label={prettyName} value={JSON.stringify(value)} />
|
||||
{/if}
|
|
@ -0,0 +1,30 @@
|
|||
<script>
|
||||
import { Layout, Toggle } from "@budibase/bbui"
|
||||
import DevToolsStat from "./DevToolsStat.svelte"
|
||||
import { componentStore } from "stores/index.js"
|
||||
import { getSettingsDefinition } from "utils/componentProps.js"
|
||||
|
||||
let showEnrichedSettings = true
|
||||
|
||||
$: selectedInstance = $componentStore.selectedComponentInstance
|
||||
$: settingsDefinition = getSettingsDefinition(
|
||||
$componentStore.selectedComponentDefinition
|
||||
)
|
||||
$: rawSettings = selectedInstance?.getRawSettings()
|
||||
$: settings = selectedInstance?.getSettings()
|
||||
</script>
|
||||
|
||||
<Layout noPadding gap="S">
|
||||
<Toggle text="Show enriched settings" bind:value={showEnrichedSettings} />
|
||||
<Layout noPadding gap="XS">
|
||||
{#each settingsDefinition as setting}
|
||||
<DevToolsStat
|
||||
copyable
|
||||
label={setting.label}
|
||||
value={JSON.stringify(
|
||||
(showEnrichedSettings ? settings : rawSettings)?.[setting.key]
|
||||
)}
|
||||
/>
|
||||
{/each}
|
||||
</Layout>
|
||||
</Layout>
|
|
@ -0,0 +1,102 @@
|
|||
<script>
|
||||
import { Body, Layout, Heading, Button, Tabs, Tab } from "@budibase/bbui"
|
||||
import { builderStore, devToolsStore, componentStore } from "stores"
|
||||
import DevToolsStat from "./DevToolsStat.svelte"
|
||||
import DevToolsComponentSettingsTab from "./DevToolsComponentSettingsTab.svelte"
|
||||
import DevToolsComponentContextTab from "./DevToolsComponentContextTab.svelte"
|
||||
|
||||
$: {
|
||||
// Reset selection store if we can't find a matching instance
|
||||
if (!$componentStore.selectedComponentInstance) {
|
||||
builderStore.actions.selectComponent(null)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if !$builderStore.selectedComponentId}
|
||||
<Layout noPadding gap="S">
|
||||
<Heading size="XS">Please choose a component</Heading>
|
||||
<Body size="S">
|
||||
Press the button below to enable component selection, then click a
|
||||
component in your app to view its settings and available data bindings.
|
||||
</Body>
|
||||
<div>
|
||||
<Button
|
||||
cta
|
||||
on:click={() => devToolsStore.actions.setAllowSelection(true)}
|
||||
>
|
||||
Choose component
|
||||
</Button>
|
||||
</div>
|
||||
</Layout>
|
||||
{:else}
|
||||
<Layout noPadding gap="S">
|
||||
<Heading size="XS">
|
||||
{$componentStore.selectedComponent?._instanceName}
|
||||
</Heading>
|
||||
<Layout noPadding gap="XS">
|
||||
<DevToolsStat
|
||||
label="Type"
|
||||
value={$componentStore.selectedComponentDefinition?.name}
|
||||
/>
|
||||
<DevToolsStat
|
||||
copyable
|
||||
label="Component ID"
|
||||
value={$componentStore.selectedComponent?._id}
|
||||
/>
|
||||
</Layout>
|
||||
<div class="buttons">
|
||||
<Button
|
||||
cta
|
||||
on:click={() => devToolsStore.actions.setAllowSelection(true)}
|
||||
>
|
||||
Change component
|
||||
</Button>
|
||||
<Button
|
||||
quiet
|
||||
secondary
|
||||
on:click={() => builderStore.actions.selectComponent(null)}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="data">
|
||||
<Layout noPadding gap="XS">
|
||||
<Tabs selected="Settings">
|
||||
<Tab title="Settings">
|
||||
<div class="tab-content">
|
||||
<DevToolsComponentSettingsTab />
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab title="Bindings">
|
||||
<div class="tab-content">
|
||||
<DevToolsComponentContextTab />
|
||||
</div>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Layout>
|
||||
</div>
|
||||
</Layout>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
.data {
|
||||
margin: 0 calc(-1 * var(--spacing-xl));
|
||||
}
|
||||
.data :global(.spectrum-Textfield-input) {
|
||||
min-height: 200px !important;
|
||||
white-space: pre;
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
.tab-content {
|
||||
padding: 0 var(--spacing-xl);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,74 @@
|
|||
<script>
|
||||
import { Heading, Button, Select } from "@budibase/bbui"
|
||||
import { devToolsStore } from "../../stores"
|
||||
import { getContext } from "svelte"
|
||||
|
||||
const context = getContext("context")
|
||||
|
||||
$: previewOptions = [
|
||||
{
|
||||
label: "View as yourself",
|
||||
value: "self",
|
||||
},
|
||||
{
|
||||
label: "View as public user",
|
||||
value: "PUBLIC",
|
||||
},
|
||||
{
|
||||
label: "View as basic user",
|
||||
value: "BASIC",
|
||||
},
|
||||
{
|
||||
label: "View as power user",
|
||||
value: "POWER",
|
||||
},
|
||||
{
|
||||
label: "View as admin user",
|
||||
value: "ADMIN",
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<div class="dev-preview-header" class:mobile={$context.device.mobile}>
|
||||
<Heading size="XS">Budibase App Preview</Heading>
|
||||
<Select
|
||||
quiet
|
||||
options={previewOptions}
|
||||
value={$devToolsStore.role || "self"}
|
||||
placeholder={null}
|
||||
autoWidth
|
||||
on:change={e => devToolsStore.actions.changeRole(e.detail)}
|
||||
/>
|
||||
{#if !$context.device.mobile}
|
||||
<Button
|
||||
quiet
|
||||
overBackground
|
||||
icon="Code"
|
||||
on:click={() => devToolsStore.actions.setVisible(!$devToolsStore.visible)}
|
||||
>
|
||||
{$devToolsStore.visible ? "Close" : "Open"} DevTools
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.dev-preview-header {
|
||||
flex: 0 0 50px;
|
||||
height: 50px;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
background-color: var(--spectrum-global-color-blue-400);
|
||||
padding: 0 var(--spacing-xl);
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-gap: var(--spacing-xl);
|
||||
}
|
||||
.dev-preview-header.mobile {
|
||||
flex: 0 0 50px;
|
||||
grid-template-columns: 1fr auto;
|
||||
}
|
||||
.dev-preview-header :global(.spectrum-Heading),
|
||||
.dev-preview-header :global(.spectrum-Picker-menuIcon),
|
||||
.dev-preview-header :global(.spectrum-Picker-label) {
|
||||
color: white !important;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,75 @@
|
|||
<script>
|
||||
import { Helpers } from "@budibase/bbui"
|
||||
import { notificationStore } from "stores"
|
||||
|
||||
export let label
|
||||
export let value
|
||||
export let copyable = false
|
||||
|
||||
$: prettyLabel = label == null ? "-" : label
|
||||
$: prettyValue = value == null ? "-" : value
|
||||
$: empty = value == null
|
||||
$: canCopy = copyable && !empty
|
||||
|
||||
const copyValue = async () => {
|
||||
try {
|
||||
await Helpers.copyToClipboard(value)
|
||||
notificationStore.actions.success("Copied to clipboard")
|
||||
} catch (error) {
|
||||
notificationStore.actions.error(
|
||||
"Failed to copy to clipboard. Check the dev console for the value."
|
||||
)
|
||||
console.warn("Failed to copy the value", value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="stat">
|
||||
<div class="stat-label" title={prettyLabel}>{prettyLabel}</div>
|
||||
<div
|
||||
class="stat-value"
|
||||
class:copyable={canCopy}
|
||||
class:empty
|
||||
title={prettyValue}
|
||||
on:click={canCopy ? copyValue : null}
|
||||
>
|
||||
{prettyValue}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.stat {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--spacing-xl);
|
||||
}
|
||||
.stat-label {
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--spectrum-global-color-gray-600);
|
||||
text-transform: uppercase;
|
||||
flex: 0 0 auto;
|
||||
width: 120px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.stat-value {
|
||||
flex: 1 1 auto;
|
||||
width: 0;
|
||||
text-align: right;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
transition: color var(--spectrum-global-animation-duration-100, 130ms)
|
||||
ease-in-out;
|
||||
}
|
||||
.stat-value.empty {
|
||||
color: var(--spectrum-global-color-gray-500);
|
||||
}
|
||||
.stat-value.copyable:hover {
|
||||
color: var(--spectrum-global-color-blue-600);
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,27 @@
|
|||
<script>
|
||||
import { Layout } from "@budibase/bbui"
|
||||
import { authStore, appStore, screenStore, componentStore } from "stores"
|
||||
import DevToolsStat from "./DevToolsStat.svelte"
|
||||
</script>
|
||||
|
||||
<Layout noPadding gap="XS">
|
||||
<DevToolsStat label="App" value={$appStore.application?.name} />
|
||||
<DevToolsStat label="Tenant" value={$appStore.application?.tenantId} />
|
||||
<DevToolsStat label="Version" value={$appStore.application?.version} />
|
||||
{#if $appStore.clientLoadTime}
|
||||
<DevToolsStat
|
||||
label="Client load time"
|
||||
value={`${$appStore.clientLoadTime} ms`}
|
||||
/>
|
||||
{/if}
|
||||
<DevToolsStat label="App layouts" value={$screenStore.layouts?.length || 0} />
|
||||
<DevToolsStat label="Active layout" value={$screenStore.activeLayout?.name} />
|
||||
<DevToolsStat label="App screens" value={$screenStore.screens?.length || 0} />
|
||||
<DevToolsStat
|
||||
label="Active screen"
|
||||
value={$screenStore.activeScreen?.routing.route}
|
||||
/>
|
||||
<DevToolsStat label="Components" value={$componentStore.mountedComponents} />
|
||||
<DevToolsStat label="User" value={$authStore.email} />
|
||||
<DevToolsStat label="Role" value={$authStore.roleId} />
|
||||
</Layout>
|
|
@ -2,6 +2,7 @@
|
|||
import { onMount, onDestroy } from "svelte"
|
||||
import Indicator from "./Indicator.svelte"
|
||||
import { domDebounce } from "utils/domDebounce"
|
||||
import { builderStore } from "stores"
|
||||
|
||||
export let componentId
|
||||
export let color
|
||||
|
@ -13,6 +14,7 @@
|
|||
let interval
|
||||
let text
|
||||
$: visibleIndicators = indicators.filter(x => x.visible)
|
||||
$: offset = $builderStore.inBuilder ? 0 : 2
|
||||
|
||||
let updating = false
|
||||
let observers = []
|
||||
|
@ -88,8 +90,8 @@
|
|||
|
||||
const elBounds = child.getBoundingClientRect()
|
||||
nextIndicators.push({
|
||||
top: elBounds.top + scrollY - deviceBounds.top,
|
||||
left: elBounds.left + scrollX - deviceBounds.left,
|
||||
top: elBounds.top + scrollY - deviceBounds.top - offset,
|
||||
left: elBounds.left + scrollX - deviceBounds.left - offset,
|
||||
width: elBounds.width + 4,
|
||||
height: elBounds.height + 4,
|
||||
visible: false,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import SettingsButton from "./SettingsButton.svelte"
|
||||
import SettingsColorPicker from "./SettingsColorPicker.svelte"
|
||||
import SettingsPicker from "./SettingsPicker.svelte"
|
||||
import { builderStore } from "stores"
|
||||
import { builderStore, componentStore } from "stores"
|
||||
import { domDebounce } from "utils/domDebounce"
|
||||
|
||||
const verticalOffset = 28
|
||||
|
@ -15,7 +15,7 @@
|
|||
let self
|
||||
let measured = false
|
||||
|
||||
$: definition = $builderStore.selectedComponentDefinition
|
||||
$: definition = $componentStore.selectedComponentDefinition
|
||||
$: showBar = definition?.showSettingsBar && !$builderStore.isDragging
|
||||
$: settings = getBarSettings(definition)
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
|||
}
|
||||
|
||||
//If element is at the very top of the screen, put the bar below the element
|
||||
if (elBounds.top < elBounds.height) {
|
||||
if (elBounds.top < elBounds.height && elBounds.height < 80) {
|
||||
newTop = elBounds.bottom + verticalOffset
|
||||
}
|
||||
|
||||
|
@ -163,9 +163,7 @@
|
|||
<SettingsButton
|
||||
icon="Delete"
|
||||
on:click={() => {
|
||||
builderStore.actions.deleteComponent(
|
||||
$builderStore.selectedComponent._id
|
||||
)
|
||||
builderStore.actions.deleteComponent($builderStore.selectedComponentId)
|
||||
}}
|
||||
title="Delete component"
|
||||
/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { Icon } from "@budibase/bbui"
|
||||
import { builderStore } from "stores"
|
||||
import { builderStore, componentStore } from "stores"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
|
||||
export let prop
|
||||
|
@ -11,7 +11,7 @@
|
|||
export let bool = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
$: currentValue = $builderStore.selectedComponent?.[prop]
|
||||
$: currentValue = $componentStore.selectedComponent?.[prop]
|
||||
$: active = prop && (bool ? !!currentValue : currentValue === value)
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
import { ColorPicker } from "@budibase/bbui"
|
||||
import { builderStore } from "stores"
|
||||
import { builderStore, componentStore } from "stores"
|
||||
|
||||
export let prop
|
||||
|
||||
$: currentValue = $builderStore.selectedComponent?.[prop]
|
||||
$: currentValue = $componentStore.selectedComponent?.[prop]
|
||||
</script>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script>
|
||||
import { Select } from "@budibase/bbui"
|
||||
import { builderStore } from "stores"
|
||||
import { builderStore, componentStore } from "stores"
|
||||
|
||||
export let prop
|
||||
export let options
|
||||
export let label
|
||||
|
||||
$: currentValue = $builderStore.selectedComponent?.[prop]
|
||||
$: currentValue = $componentStore.selectedComponent?.[prop]
|
||||
</script>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import { API } from "api"
|
||||
import { get, writable } from "svelte/store"
|
||||
|
||||
const initialState = {
|
||||
appId: null,
|
||||
isDevApp: false,
|
||||
clientLoadTime: window.INIT_TIME ? Date.now() - window.INIT_TIME : null,
|
||||
}
|
||||
|
||||
const createAppStore = () => {
|
||||
const store = writable(null)
|
||||
const store = writable(initialState)
|
||||
|
||||
// Fetches the app definition including screens, layouts and theme
|
||||
const fetchAppDefinition = async () => {
|
||||
|
@ -13,11 +19,13 @@ const createAppStore = () => {
|
|||
try {
|
||||
const appDefinition = await API.fetchAppPackage(appId)
|
||||
store.set({
|
||||
...initialState,
|
||||
...appDefinition,
|
||||
appId: appDefinition?.application?.appId,
|
||||
isDevApp: appId.startsWith("app_dev"),
|
||||
})
|
||||
} catch (error) {
|
||||
store.set(null)
|
||||
store.set(initialState)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { writable, derived, get } from "svelte/store"
|
||||
import Manifest from "manifest.json"
|
||||
import { findComponentById, findComponentPathById } from "../utils/components"
|
||||
import { writable, get } from "svelte/store"
|
||||
import { API } from "api"
|
||||
import { devToolsStore } from "./devTools.js"
|
||||
|
||||
const dispatchEvent = (type, data = {}) => {
|
||||
window.parent.postMessage({ type, data })
|
||||
|
@ -22,38 +21,18 @@ const createBuilderStore = () => {
|
|||
previewDevice: "desktop",
|
||||
isDragging: false,
|
||||
}
|
||||
const writableStore = writable(initialState)
|
||||
const derivedStore = derived(writableStore, $state => {
|
||||
// Avoid any of this logic if we aren't in the builder preview
|
||||
if (!$state.inBuilder) {
|
||||
return $state
|
||||
}
|
||||
|
||||
// Derive the selected component instance and definition
|
||||
const { layout, screen, previewType, selectedComponentId } = $state
|
||||
const asset = previewType === "layout" ? layout : screen
|
||||
const component = findComponentById(asset?.props, selectedComponentId)
|
||||
const prefix = "@budibase/standard-components/"
|
||||
const type = component?._component?.replace(prefix, "")
|
||||
const definition = type ? Manifest[type] : null
|
||||
|
||||
// Derive the selected component path
|
||||
const path = findComponentPathById(asset.props, selectedComponentId) || []
|
||||
|
||||
return {
|
||||
...$state,
|
||||
selectedComponent: component,
|
||||
selectedComponentDefinition: definition,
|
||||
selectedComponentPath: path?.map(component => component._id),
|
||||
}
|
||||
})
|
||||
|
||||
const store = writable(initialState)
|
||||
const actions = {
|
||||
selectComponent: id => {
|
||||
if (id === get(writableStore).selectedComponentId) {
|
||||
if (id === get(store).selectedComponentId) {
|
||||
return
|
||||
}
|
||||
writableStore.update(state => ({ ...state, editMode: false }))
|
||||
store.update(state => ({
|
||||
...state,
|
||||
editMode: false,
|
||||
selectedComponentId: id,
|
||||
}))
|
||||
devToolsStore.actions.setAllowSelection(false)
|
||||
dispatchEvent("select-component", { id })
|
||||
},
|
||||
updateProp: (prop, value) => {
|
||||
|
@ -76,7 +55,7 @@ const createBuilderStore = () => {
|
|||
}
|
||||
},
|
||||
setSelectedPath: path => {
|
||||
writableStore.update(state => ({ ...state, selectedPath: path }))
|
||||
store.update(state => ({ ...state, selectedPath: path }))
|
||||
},
|
||||
moveComponent: (componentId, destinationComponentId, mode) => {
|
||||
dispatchEvent("move-component", {
|
||||
|
@ -86,22 +65,21 @@ const createBuilderStore = () => {
|
|||
})
|
||||
},
|
||||
setDragging: dragging => {
|
||||
if (dragging === get(writableStore).isDragging) {
|
||||
if (dragging === get(store).isDragging) {
|
||||
return
|
||||
}
|
||||
writableStore.update(state => ({ ...state, isDragging: dragging }))
|
||||
store.update(state => ({ ...state, isDragging: dragging }))
|
||||
},
|
||||
setEditMode: enabled => {
|
||||
if (enabled === get(writableStore).editMode) {
|
||||
if (enabled === get(store).editMode) {
|
||||
return
|
||||
}
|
||||
writableStore.update(state => ({ ...state, editMode: enabled }))
|
||||
store.update(state => ({ ...state, editMode: enabled }))
|
||||
},
|
||||
}
|
||||
return {
|
||||
...writableStore,
|
||||
set: state => writableStore.set({ ...initialState, ...state }),
|
||||
subscribe: derivedStore.subscribe,
|
||||
...store,
|
||||
set: state => store.set({ ...initialState, ...state }),
|
||||
actions,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
import { get, writable, derived } from "svelte/store"
|
||||
import Manifest from "manifest.json"
|
||||
import { findComponentById, findComponentPathById } from "../utils/components"
|
||||
import { devToolsStore } from "./devTools"
|
||||
import { screenStore } from "./screens"
|
||||
import { builderStore } from "./builder"
|
||||
|
||||
const createComponentStore = () => {
|
||||
const store = writable({})
|
||||
|
||||
const derivedStore = derived(
|
||||
[store, builderStore, devToolsStore, screenStore],
|
||||
([$store, $builderState, $devToolsState, $screenState]) => {
|
||||
// Avoid any of this logic if we aren't in the builder preview
|
||||
if (!$builderState.inBuilder && !$devToolsState.visible) {
|
||||
return {}
|
||||
}
|
||||
|
||||
// Derive the selected component instance and definition
|
||||
let asset
|
||||
const { layout, screen, previewType, selectedComponentId } = $builderState
|
||||
if ($builderState.inBuilder) {
|
||||
asset = previewType === "layout" ? layout : screen
|
||||
} else {
|
||||
asset = $screenState.activeScreen
|
||||
}
|
||||
const component = findComponentById(asset?.props, selectedComponentId)
|
||||
const prefix = "@budibase/standard-components/"
|
||||
const type = component?._component?.replace(prefix, "")
|
||||
const definition = type ? Manifest[type] : null
|
||||
|
||||
// Derive the selected component path
|
||||
const path =
|
||||
findComponentPathById(asset?.props, selectedComponentId) || []
|
||||
|
||||
return {
|
||||
selectedComponentInstance: $store[selectedComponentId],
|
||||
selectedComponent: component,
|
||||
selectedComponentDefinition: definition,
|
||||
selectedComponentPath: path?.map(component => component._id),
|
||||
mountedComponents: Object.keys($store).length,
|
||||
currentAsset: asset,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const registerInstance = (id, instance) => {
|
||||
store.update(state => ({
|
||||
...state,
|
||||
[id]: instance,
|
||||
}))
|
||||
}
|
||||
|
||||
const unregisterInstance = id => {
|
||||
store.update(state => {
|
||||
delete state[id]
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
||||
const isComponentRegistered = id => {
|
||||
return get(store)[id] != null
|
||||
}
|
||||
|
||||
const getComponentById = id => {
|
||||
const asset = get(derivedStore).currentAsset
|
||||
return findComponentById(asset?.props, id)
|
||||
}
|
||||
|
||||
return {
|
||||
...derivedStore,
|
||||
actions: {
|
||||
registerInstance,
|
||||
unregisterInstance,
|
||||
isComponentRegistered,
|
||||
getComponentById,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const componentStore = createComponentStore()
|
|
@ -0,0 +1,47 @@
|
|||
import { get } from "svelte/store"
|
||||
import { createLocalStorageStore } from "@budibase/frontend-core"
|
||||
import { appStore } from "./app"
|
||||
import { initialise } from "./initialise"
|
||||
import { authStore } from "./auth"
|
||||
|
||||
const initialState = {
|
||||
visible: false,
|
||||
allowSelection: false,
|
||||
role: null,
|
||||
}
|
||||
|
||||
const createDevToolStore = () => {
|
||||
const localStorageKey = `${get(appStore).appId}.devTools`
|
||||
const store = createLocalStorageStore(localStorageKey, initialState)
|
||||
|
||||
const setVisible = visible => {
|
||||
store.update(state => ({
|
||||
...state,
|
||||
visible: visible,
|
||||
}))
|
||||
}
|
||||
|
||||
const setAllowSelection = allowSelection => {
|
||||
store.update(state => ({
|
||||
...state,
|
||||
allowSelection,
|
||||
}))
|
||||
}
|
||||
|
||||
const changeRole = async role => {
|
||||
store.update(state => ({
|
||||
...state,
|
||||
role: role === "self" ? null : role,
|
||||
}))
|
||||
// location.reload()
|
||||
await authStore.actions.fetchUser()
|
||||
await initialise()
|
||||
}
|
||||
|
||||
return {
|
||||
subscribe: store.subscribe,
|
||||
actions: { setVisible, setAllowSelection, changeRole },
|
||||
}
|
||||
}
|
||||
|
||||
export const devToolsStore = createDevToolStore()
|
|
@ -9,6 +9,8 @@ export { confirmationStore } from "./confirmation"
|
|||
export { peekStore } from "./peek"
|
||||
export { stateStore } from "./state"
|
||||
export { themeStore } from "./theme"
|
||||
export { devToolsStore } from "./devTools"
|
||||
export { componentStore } from "./components"
|
||||
export { uploadStore } from "./uploads.js"
|
||||
export { rowSelectionStore } from "./rowSelection.js"
|
||||
// Context stores are layered and duplicated, so it is not a singleton
|
||||
|
|
|
@ -66,7 +66,6 @@ const createScreenStore = () => {
|
|||
}
|
||||
let children = []
|
||||
findChildrenByType(component, type, children)
|
||||
console.log(children)
|
||||
return children
|
||||
},
|
||||
}
|
||||
|
|
|
@ -107,3 +107,21 @@ export const propsUseBinding = (props, bindingKey) => {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definition of this component's settings from the manifest
|
||||
*/
|
||||
export const getSettingsDefinition = definition => {
|
||||
if (!definition) {
|
||||
return []
|
||||
}
|
||||
let settings = []
|
||||
definition.settings?.forEach(setting => {
|
||||
if (setting.section) {
|
||||
settings = settings.concat(setting.settings || [])
|
||||
} else {
|
||||
settings.push(setting)
|
||||
}
|
||||
})
|
||||
return settings
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "@budibase/frontend-core",
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"description": "Budibase frontend core libraries used in builder and client",
|
||||
"author": "Budibase",
|
||||
"license": "MPL-2.0",
|
||||
"svelte": "src/index.js",
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "^1.0.105-alpha.9",
|
||||
"@budibase/bbui": "^1.0.105-alpha.19",
|
||||
"lodash": "^4.17.21",
|
||||
"svelte": "^3.46.2"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/server",
|
||||
"email": "hi@budibase.com",
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"description": "Budibase Web Server",
|
||||
"main": "src/index.ts",
|
||||
"repository": {
|
||||
|
@ -9,7 +9,7 @@
|
|||
"url": "https://github.com/Budibase/budibase.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rimraf dist/ && tsc && mv dist/src/* dist/ && rmdir dist/src/ && yarn postbuild",
|
||||
"build": "rimraf dist/ && tsc && mv dist/src/* dist/ && rimraf dist/src/ && yarn postbuild",
|
||||
"postbuild": "copyfiles -u 1 src/**/*.svelte dist/ && copyfiles -u 1 src/**/*.hbs dist/ && copyfiles -u 1 src/**/*.json dist/",
|
||||
"test": "jest --coverage --maxWorkers=2",
|
||||
"test:watch": "jest --watch",
|
||||
|
@ -68,9 +68,9 @@
|
|||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@apidevtools/swagger-parser": "^10.0.3",
|
||||
"@budibase/backend-core": "^1.0.105-alpha.9",
|
||||
"@budibase/client": "^1.0.105-alpha.9",
|
||||
"@budibase/string-templates": "^1.0.105-alpha.9",
|
||||
"@budibase/backend-core": "^1.0.105-alpha.19",
|
||||
"@budibase/client": "^1.0.105-alpha.19",
|
||||
"@budibase/string-templates": "^1.0.105-alpha.19",
|
||||
"@bull-board/api": "^3.7.0",
|
||||
"@bull-board/koa": "^3.7.0",
|
||||
"@elastic/elasticsearch": "7.10.0",
|
||||
|
|
|
@ -78,6 +78,9 @@
|
|||
app.
|
||||
</h2>
|
||||
</div>
|
||||
<script type="application/javascript">
|
||||
window.INIT_TIME = Date.now()
|
||||
</script>
|
||||
<script type="application/javascript" src={clientLibPath}>
|
||||
</script>
|
||||
<script type="application/javascript">
|
||||
|
|
|
@ -25,7 +25,7 @@ function getFormulaThatUseColumn(table, columnNames) {
|
|||
if (!isStaticFormula(column)) {
|
||||
continue
|
||||
}
|
||||
if (!doesContainStrings(column.formula, columnNames)) {
|
||||
if (!doesContainStrings(column?.formula ?? "", columnNames)) {
|
||||
continue
|
||||
}
|
||||
formula.push(column.name)
|
||||
|
|
|
@ -4,7 +4,7 @@ const {
|
|||
getCookie,
|
||||
clearCookie,
|
||||
} = require("@budibase/backend-core/utils")
|
||||
const { Cookies } = require("@budibase/backend-core/constants")
|
||||
const { Cookies, Headers } = require("@budibase/backend-core/constants")
|
||||
const { getRole } = require("@budibase/backend-core/roles")
|
||||
const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
|
||||
const { generateUserMetadataID, isDevAppID } = require("../db/utils")
|
||||
|
@ -63,6 +63,21 @@ module.exports = async (ctx, next) => {
|
|||
appId = requestAppId
|
||||
// retrieving global user gets the right role
|
||||
roleId = globalUser.roleId || roleId
|
||||
|
||||
// Allow builders to specify their role via a header
|
||||
const isBuilder =
|
||||
globalUser && globalUser.builder && globalUser.builder.global
|
||||
const isDevApp = appId && isDevAppID(appId)
|
||||
const roleHeader = ctx.request && ctx.request.headers[Headers.PREVIEW_ROLE]
|
||||
if (isBuilder && isDevApp && roleHeader) {
|
||||
// Ensure the role is valid by ensuring a definition exists
|
||||
try {
|
||||
await getRole(roleHeader)
|
||||
roleId = roleHeader
|
||||
} catch (error) {
|
||||
// Swallow error and do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nothing more to do
|
||||
|
|
|
@ -995,10 +995,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@budibase/backend-core@^1.0.97":
|
||||
version "1.0.97"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.97.tgz#32bd09324437256bcfedda11d34fc4c4cb1a5b9b"
|
||||
integrity sha512-NLH6fbWpU0Ej0dTL37PoEAMRMI8zYVwnJI1b74VqWFmyR/moOmyPcptfLnysY1aD5hizHgz+P8sFYsSGKiMozg==
|
||||
"@budibase/backend-core@^1.0.105-alpha.10":
|
||||
version "1.0.112"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.112.tgz#38d5f8faadc08d863b13eeadefce067fd572ae27"
|
||||
integrity sha512-/MS1+QZjEpwcy1Lj4tkvXE3V8Q1Kd41/30y8Y2yaDosnDoKZmUs5muZjXZJnmYADajPwA3u7uop2psEdg5diLg==
|
||||
dependencies:
|
||||
"@techpass/passport-openidconnect" "^0.3.0"
|
||||
aws-sdk "^2.901.0"
|
||||
|
@ -1068,13 +1068,13 @@
|
|||
svelte-flatpickr "^3.2.3"
|
||||
svelte-portal "^1.0.0"
|
||||
|
||||
"@budibase/bbui@^1.0.97":
|
||||
version "1.0.97"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.0.97.tgz#6d36cdbeeaaf3a7b299a8a677f0739b682b49bf3"
|
||||
integrity sha512-AMwDCz0qm4rZp50TY83JJTjqOAlZPdirzsLM4Iydn2dWlaqpcwnB3VZOzgb+mC72uH5eKeqI74Nu7hh3CvtXBw==
|
||||
"@budibase/bbui@^1.0.112":
|
||||
version "1.0.112"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.0.112.tgz#93fa44b5051caee6bb6883be678700fca1f91682"
|
||||
integrity sha512-ooc3yZnKCpXTZulq55dqvJrdUPgAaC+kHL5eo5S62qBSoHx3RHUxPEAG+aOpVuj2I8UJ05/2iVCxlgTQCcYp3A==
|
||||
dependencies:
|
||||
"@adobe/spectrum-css-workflow-icons" "^1.2.1"
|
||||
"@budibase/string-templates" "^1.0.97"
|
||||
"@budibase/string-templates" "^1.0.112"
|
||||
"@spectrum-css/actionbutton" "^1.0.1"
|
||||
"@spectrum-css/actiongroup" "^1.0.1"
|
||||
"@spectrum-css/avatar" "^3.0.2"
|
||||
|
@ -1120,14 +1120,14 @@
|
|||
svelte-flatpickr "^3.2.3"
|
||||
svelte-portal "^1.0.0"
|
||||
|
||||
"@budibase/client@^1.0.97":
|
||||
version "1.0.97"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-1.0.97.tgz#e110737c98fb0f7145cf1f5ec41912ff46fc0c3f"
|
||||
integrity sha512-bdXVVZe6m+P4azdGvU2AoVMDC+bQ2MUkot5hTcRTfyCAwqCQABlkL/t+iA4Zv8feFc5ZUtfrsCIm+jOKGEUUow==
|
||||
"@budibase/client@^1.0.105-alpha.10":
|
||||
version "1.0.112"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-1.0.112.tgz#babd4e75de9f4161aa40c15138afb810d0a91993"
|
||||
integrity sha512-pl8kZHvJN0EMcDUscH4RHXKXQhcHa5wDDIe6C4FMZ18TCp6hDM47Cv/xeejOqajllixASV8oD0ZymNZi3sLGvQ==
|
||||
dependencies:
|
||||
"@budibase/bbui" "^1.0.97"
|
||||
"@budibase/frontend-core" "^1.0.97"
|
||||
"@budibase/string-templates" "^1.0.97"
|
||||
"@budibase/bbui" "^1.0.112"
|
||||
"@budibase/frontend-core" "^1.0.112"
|
||||
"@budibase/string-templates" "^1.0.112"
|
||||
"@spectrum-css/button" "^3.0.3"
|
||||
"@spectrum-css/card" "^3.0.3"
|
||||
"@spectrum-css/divider" "^1.0.3"
|
||||
|
@ -1139,20 +1139,23 @@
|
|||
apexcharts "^3.22.1"
|
||||
dayjs "^1.10.5"
|
||||
downloadjs "1.4.7"
|
||||
leaflet "^1.7.1"
|
||||
regexparam "^1.3.0"
|
||||
rollup-plugin-polyfill-node "^0.8.0"
|
||||
sanitize-html "^2.7.0"
|
||||
screenfull "^6.0.1"
|
||||
shortid "^2.2.15"
|
||||
svelte "^3.38.2"
|
||||
svelte-apexcharts "^1.0.2"
|
||||
svelte-flatpickr "^3.1.0"
|
||||
svelte-spa-router "^3.0.5"
|
||||
|
||||
"@budibase/frontend-core@^1.0.97":
|
||||
version "1.0.97"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/frontend-core/-/frontend-core-1.0.97.tgz#530a0c716fbc93dd38d7abcc22b3131030f9cd16"
|
||||
integrity sha512-B2LG9UIEKSLE0NBhPlVLYXAypjBZgiPdqGwoNm7xcWZHG12YzYWqflV3NLwaDx9Qt3UTIaRzXqBGoNNQCGdUdQ==
|
||||
"@budibase/frontend-core@^1.0.112":
|
||||
version "1.0.112"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/frontend-core/-/frontend-core-1.0.112.tgz#b1615e6cf6690fa6672fa579f6ccd74e94f702d9"
|
||||
integrity sha512-NcElXZk9wSld2kl3YbCwrGlQaqM+fqiGU0czurFieGLKanKuIRquLtyfxGGRqxC8zxKacxhWKpaVRoUt87dTnw==
|
||||
dependencies:
|
||||
"@budibase/bbui" "^1.0.97"
|
||||
"@budibase/bbui" "^1.0.112"
|
||||
lodash "^4.17.21"
|
||||
svelte "^3.46.2"
|
||||
|
||||
|
@ -1199,10 +1202,10 @@
|
|||
svelte-apexcharts "^1.0.2"
|
||||
svelte-flatpickr "^3.1.0"
|
||||
|
||||
"@budibase/string-templates@^1.0.97":
|
||||
version "1.0.97"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.97.tgz#b7485cb8774d6dff8280fbf411c6383b82add72d"
|
||||
integrity sha512-8NfpYzDJgSkic3E0ARfNsPsFEMmOcH+kEeTioLkNnkKrviIRhSQ9Oa3S87QIYo5WGYxpEFEfhYutXsbp3GTLbg==
|
||||
"@budibase/string-templates@^1.0.105-alpha.10", "@budibase/string-templates@^1.0.112":
|
||||
version "1.0.112"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.112.tgz#754f8f725262e58dfeac946de5f87d8d333077b7"
|
||||
integrity sha512-UOVpMT87eR8ZfoZo5D3UsxR0Qsfj0FmE6bxcJLYd5ey/RIeMErnl8fKu/0Chj6JOxGc3q/U7dIYsqzdVsJFhyQ==
|
||||
dependencies:
|
||||
"@budibase/handlebars-helpers" "^0.11.8"
|
||||
dayjs "^1.10.4"
|
||||
|
@ -4985,11 +4988,25 @@ doctrine@3.0.0, doctrine@^3.0.0:
|
|||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
dom-serializer@^1.0.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
|
||||
integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
|
||||
dependencies:
|
||||
domelementtype "^2.0.1"
|
||||
domhandler "^4.2.0"
|
||||
entities "^2.0.0"
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
|
||||
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
|
||||
|
||||
domelementtype@^2.0.1, domelementtype@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
|
||||
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
|
||||
|
||||
domexception@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
|
||||
|
@ -5004,6 +5021,22 @@ domexception@^2.0.1:
|
|||
dependencies:
|
||||
webidl-conversions "^5.0.0"
|
||||
|
||||
domhandler@^4.0.0, domhandler@^4.2.0:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
|
||||
integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
|
||||
dependencies:
|
||||
domelementtype "^2.2.0"
|
||||
|
||||
domutils@^2.5.2:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
||||
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
|
||||
dependencies:
|
||||
dom-serializer "^1.0.1"
|
||||
domelementtype "^2.2.0"
|
||||
domhandler "^4.2.0"
|
||||
|
||||
dot-prop@^5.2.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
|
||||
|
@ -5190,6 +5223,11 @@ ent@^2.2.0:
|
|||
resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
|
||||
integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0=
|
||||
|
||||
entities@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||
|
||||
entities@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
|
||||
|
@ -5433,6 +5471,11 @@ escape-string-regexp@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
|
||||
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
escodegen@^1.9.1:
|
||||
version "1.14.3"
|
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503"
|
||||
|
@ -6764,6 +6807,16 @@ html-tag@^2.0.0:
|
|||
is-self-closing "^1.0.1"
|
||||
kind-of "^6.0.0"
|
||||
|
||||
htmlparser2@^6.0.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
|
||||
integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
|
||||
dependencies:
|
||||
domelementtype "^2.0.1"
|
||||
domhandler "^4.0.0"
|
||||
domutils "^2.5.2"
|
||||
entities "^2.0.0"
|
||||
|
||||
http-assert@^1.3.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f"
|
||||
|
@ -7312,6 +7365,11 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4:
|
|||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
|
||||
is-plain-object@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
|
||||
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
|
||||
|
||||
is-potential-custom-element-name@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
|
||||
|
@ -8904,6 +8962,11 @@ lcid@^2.0.0:
|
|||
dependencies:
|
||||
invert-kv "^2.0.0"
|
||||
|
||||
leaflet@^1.7.1:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19"
|
||||
integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==
|
||||
|
||||
left-pad@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
|
||||
|
@ -9688,6 +9751,11 @@ nanoid@^2.1.0:
|
|||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
|
||||
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
|
||||
|
||||
nanoid@^3.3.1:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557"
|
||||
integrity sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.13"
|
||||
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
||||
|
@ -10245,6 +10313,11 @@ parse-json@^4.0.0:
|
|||
error-ex "^1.3.1"
|
||||
json-parse-better-errors "^1.0.1"
|
||||
|
||||
parse-srcset@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1"
|
||||
integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE=
|
||||
|
||||
parse5@4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
|
||||
|
@ -10598,6 +10671,15 @@ posix-character-classes@^0.1.0:
|
|||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
|
||||
|
||||
postcss@^8.3.11:
|
||||
version "8.4.12"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905"
|
||||
integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==
|
||||
dependencies:
|
||||
nanoid "^3.3.1"
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
postgres-array@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
|
||||
|
@ -11636,6 +11718,18 @@ sane@^4.0.3:
|
|||
minimist "^1.1.1"
|
||||
walker "~1.0.5"
|
||||
|
||||
sanitize-html@^2.7.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.7.0.tgz#e106205b468aca932e2f9baf241f24660d34e279"
|
||||
integrity sha512-jfQelabOn5voO7FAfnQF7v+jsA6z9zC/O4ec0z3E35XPEtHYJT/OdUziVWlKW4irCr2kXaQAyXTXDHWAibg1tA==
|
||||
dependencies:
|
||||
deepmerge "^4.2.2"
|
||||
escape-string-regexp "^4.0.0"
|
||||
htmlparser2 "^6.0.0"
|
||||
is-plain-object "^5.0.0"
|
||||
parse-srcset "^1.0.2"
|
||||
postcss "^8.3.11"
|
||||
|
||||
sanitize-s3-objectkey@^0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/sanitize-s3-objectkey/-/sanitize-s3-objectkey-0.0.1.tgz#efa9887cd45275b40234fb4bb12fc5754fe64e7e"
|
||||
|
@ -11674,6 +11768,11 @@ schema-utils@^3.1.0, schema-utils@^3.1.1:
|
|||
ajv "^6.12.5"
|
||||
ajv-keywords "^3.5.2"
|
||||
|
||||
screenfull@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-6.0.1.tgz#3b71e6f06b72d817a8d3be73c45ebe71fa8da1ce"
|
||||
integrity sha512-yzQW+j4zMUBQC51xxWaoDYjxOtl8Kn+xvue3p6v/fv2pIi1jH4AldgVLU8TBfFVgH2x3VXlf3+YiA/AYIPlaew==
|
||||
|
||||
search-params@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/search-params/-/search-params-3.0.0.tgz#dbc7c243058e5a33ae1e9870be91f5aced4100d8"
|
||||
|
@ -11940,6 +12039,11 @@ source-list-map@^2.0.1:
|
|||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
||||
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
|
||||
|
||||
source-map-js@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||
|
||||
source-map-resolve@^0.5.0:
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a"
|
||||
|
@ -13187,9 +13291,9 @@ uri-js@^4.2.2:
|
|||
punycode "^2.1.0"
|
||||
|
||||
urijs@^1.19.0:
|
||||
version "1.19.8"
|
||||
resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.8.tgz#ee0407a18528934d3c383e691912f47043a58feb"
|
||||
integrity sha512-iIXHrjomQ0ZCuDRy44wRbyTZVnfVNLVo3Ksz1yxNyE5wV1IDZW2S5Jszy45DTlw/UdsnRT7DyDhIz7Gy+vJumw==
|
||||
version "1.19.11"
|
||||
resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.11.tgz#204b0d6b605ae80bea54bea39280cdb7c9f923cc"
|
||||
integrity sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==
|
||||
|
||||
urix@^0.1.0:
|
||||
version "0.1.0"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/string-templates",
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"description": "Handlebars wrapper for Budibase templating.",
|
||||
"main": "src/index.cjs",
|
||||
"module": "dist/bundle.mjs",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/worker",
|
||||
"email": "hi@budibase.com",
|
||||
"version": "1.0.105-alpha.9",
|
||||
"version": "1.0.105-alpha.19",
|
||||
"description": "Budibase background service",
|
||||
"main": "src/index.ts",
|
||||
"repository": {
|
||||
|
@ -31,8 +31,8 @@
|
|||
"author": "Budibase",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "^1.0.105-alpha.9",
|
||||
"@budibase/string-templates": "^1.0.105-alpha.9",
|
||||
"@budibase/backend-core": "^1.0.105-alpha.19",
|
||||
"@budibase/string-templates": "^1.0.105-alpha.19",
|
||||
"@koa/router": "^8.0.0",
|
||||
"@sentry/node": "^6.0.0",
|
||||
"@techpass/passport-openidconnect": "^0.3.0",
|
||||
|
|
|
@ -286,10 +286,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@budibase/backend-core@^1.0.104":
|
||||
version "1.0.104"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.104.tgz#eb435c27327a1f2ea5e83b3cf242b9f85b7a5f8a"
|
||||
integrity sha512-YXI8R/bdWDO5RhcMdqu88DQ7Dn26v3SUTs5FuHvXG4b2mKDTHduecqTuhIhrbqQ5KjnTYuhAEz2iG0sP2rj5rg==
|
||||
"@budibase/backend-core@^1.0.105-alpha.10":
|
||||
version "1.0.112"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.112.tgz#38d5f8faadc08d863b13eeadefce067fd572ae27"
|
||||
integrity sha512-/MS1+QZjEpwcy1Lj4tkvXE3V8Q1Kd41/30y8Y2yaDosnDoKZmUs5muZjXZJnmYADajPwA3u7uop2psEdg5diLg==
|
||||
dependencies:
|
||||
"@techpass/passport-openidconnect" "^0.3.0"
|
||||
aws-sdk "^2.901.0"
|
||||
|
@ -335,10 +335,10 @@
|
|||
to-gfm-code-block "^0.1.1"
|
||||
year "^0.2.1"
|
||||
|
||||
"@budibase/string-templates@^1.0.104":
|
||||
version "1.0.104"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.104.tgz#f812700f2b21f638fd1e48dde065ae693fae2897"
|
||||
integrity sha512-3caq3qwpIieyb9m8eSl8OhcE0ppzuyJ/0ubDlWmtpbmwmG2v3ynI+DwxpbG4CcVQFuebD2yxU0CZfioU76vKCQ==
|
||||
"@budibase/string-templates@^1.0.105-alpha.10":
|
||||
version "1.0.112"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.112.tgz#754f8f725262e58dfeac946de5f87d8d333077b7"
|
||||
integrity sha512-UOVpMT87eR8ZfoZo5D3UsxR0Qsfj0FmE6bxcJLYd5ey/RIeMErnl8fKu/0Chj6JOxGc3q/U7dIYsqzdVsJFhyQ==
|
||||
dependencies:
|
||||
"@budibase/handlebars-helpers" "^0.11.8"
|
||||
dayjs "^1.10.4"
|
||||
|
@ -6805,9 +6805,9 @@ uri-js@^4.2.2:
|
|||
punycode "^2.1.0"
|
||||
|
||||
urijs@^1.19.2:
|
||||
version "1.19.8"
|
||||
resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.8.tgz#ee0407a18528934d3c383e691912f47043a58feb"
|
||||
integrity sha512-iIXHrjomQ0ZCuDRy44wRbyTZVnfVNLVo3Ksz1yxNyE5wV1IDZW2S5Jszy45DTlw/UdsnRT7DyDhIz7Gy+vJumw==
|
||||
version "1.19.11"
|
||||
resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.11.tgz#204b0d6b605ae80bea54bea39280cdb7c9f923cc"
|
||||
integrity sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==
|
||||
|
||||
urix@^0.1.0:
|
||||
version "0.1.0"
|
||||
|
|
Loading…
Reference in New Issue