Merge branch 'develop' of github.com:Budibase/budibase into spreadsheet-integration
This commit is contained in:
commit
31f6f9db7b
48 changed files with 862 additions and 572 deletions
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/backend-core",
|
"name": "@budibase/backend-core",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"description": "Budibase backend core libraries used in server and worker",
|
"description": "Budibase backend core libraries used in server and worker",
|
||||||
"main": "dist/src/index.js",
|
"main": "dist/src/index.js",
|
||||||
"types": "dist/src/index.d.ts",
|
"types": "dist/src/index.d.ts",
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/nano": "10.1.2",
|
"@budibase/nano": "10.1.2",
|
||||||
"@budibase/pouchdb-replication-stream": "1.2.10",
|
"@budibase/pouchdb-replication-stream": "1.2.10",
|
||||||
"@budibase/types": "2.4.27-alpha.9",
|
"@budibase/types": "2.4.27-alpha.12",
|
||||||
"@shopify/jest-koa-mocks": "5.0.1",
|
"@shopify/jest-koa-mocks": "5.0.1",
|
||||||
"@techpass/passport-openidconnect": "0.3.2",
|
"@techpass/passport-openidconnect": "0.3.2",
|
||||||
"aws-cloudfront-sign": "2.2.0",
|
"aws-cloudfront-sign": "2.2.0",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/bbui",
|
"name": "@budibase/bbui",
|
||||||
"description": "A UI solution used in the different Budibase projects.",
|
"description": "A UI solution used in the different Budibase projects.",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"module": "dist/bbui.es.js",
|
"module": "dist/bbui.es.js",
|
||||||
|
@ -38,8 +38,8 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adobe/spectrum-css-workflow-icons": "1.2.1",
|
"@adobe/spectrum-css-workflow-icons": "1.2.1",
|
||||||
"@budibase/shared-core": "2.4.27-alpha.9",
|
"@budibase/shared-core": "2.4.27-alpha.12",
|
||||||
"@budibase/string-templates": "2.4.27-alpha.9",
|
"@budibase/string-templates": "2.4.27-alpha.12",
|
||||||
"@spectrum-css/accordion": "3.0.24",
|
"@spectrum-css/accordion": "3.0.24",
|
||||||
"@spectrum-css/actionbutton": "1.0.1",
|
"@spectrum-css/actionbutton": "1.0.1",
|
||||||
"@spectrum-css/actiongroup": "1.0.1",
|
"@spectrum-css/actiongroup": "1.0.1",
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
export let title
|
export let title
|
||||||
export let fillWidth
|
export let fillWidth
|
||||||
export let left = "314px"
|
export let left = "314px"
|
||||||
export let width = "calc(100% - 576px)"
|
export let width = "calc(100% - 626px)"
|
||||||
|
|
||||||
let visible = false
|
let visible = false
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFieldText = (value, options, placeholder) => {
|
const getFieldText = (value, options, placeholder) => {
|
||||||
// Always use placeholder if no value
|
|
||||||
if (value == null || value === "") {
|
if (value == null || value === "") {
|
||||||
|
// Explicit false means use no placeholder and allow an empty fields
|
||||||
if (placeholder === false) {
|
if (placeholder === false) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
// Otherwise we use the placeholder if possible
|
||||||
return placeholder || "Choose an option"
|
return placeholder || "Choose an option"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -58,11 +58,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "2.4.27-alpha.9",
|
"@budibase/bbui": "2.4.27-alpha.12",
|
||||||
"@budibase/client": "2.4.27-alpha.9",
|
"@budibase/client": "2.4.27-alpha.12",
|
||||||
"@budibase/frontend-core": "2.4.27-alpha.9",
|
"@budibase/frontend-core": "2.4.27-alpha.12",
|
||||||
"@budibase/shared-core": "2.4.27-alpha.9",
|
"@budibase/shared-core": "2.4.27-alpha.12",
|
||||||
"@budibase/string-templates": "2.4.27-alpha.9",
|
"@budibase/string-templates": "2.4.27-alpha.12",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.2.1",
|
"@fortawesome/fontawesome-svg-core": "^6.2.1",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.2.1",
|
"@fortawesome/free-brands-svg-icons": "^6.2.1",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.2.1",
|
"@fortawesome/free-solid-svg-icons": "^6.2.1",
|
||||||
|
|
|
@ -22,6 +22,7 @@ import {
|
||||||
findComponent,
|
findComponent,
|
||||||
getComponentSettings,
|
getComponentSettings,
|
||||||
makeComponentUnique,
|
makeComponentUnique,
|
||||||
|
findComponentPath,
|
||||||
} from "../componentUtils"
|
} from "../componentUtils"
|
||||||
import { Helpers } from "@budibase/bbui"
|
import { Helpers } from "@budibase/bbui"
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
|
@ -30,7 +31,12 @@ import {
|
||||||
DB_TYPE_INTERNAL,
|
DB_TYPE_INTERNAL,
|
||||||
DB_TYPE_EXTERNAL,
|
DB_TYPE_EXTERNAL,
|
||||||
} from "constants/backend"
|
} from "constants/backend"
|
||||||
import { getSchemaForDatasource } from "builderStore/dataBinding"
|
import {
|
||||||
|
buildFormSchema,
|
||||||
|
getSchemaForDatasource,
|
||||||
|
} from "builderStore/dataBinding"
|
||||||
|
import { makePropSafe as safe } from "@budibase/string-templates"
|
||||||
|
import { getComponentFieldOptions } from "helpers/formFields"
|
||||||
|
|
||||||
const INITIAL_FRONTEND_STATE = {
|
const INITIAL_FRONTEND_STATE = {
|
||||||
apps: [],
|
apps: [],
|
||||||
|
@ -63,17 +69,19 @@ const INITIAL_FRONTEND_STATE = {
|
||||||
customTheme: {},
|
customTheme: {},
|
||||||
previewDevice: "desktop",
|
previewDevice: "desktop",
|
||||||
highlightedSettingKey: null,
|
highlightedSettingKey: null,
|
||||||
|
builderSidePanel: false,
|
||||||
|
|
||||||
// URL params
|
// URL params
|
||||||
selectedScreenId: null,
|
selectedScreenId: null,
|
||||||
selectedComponentId: null,
|
selectedComponentId: null,
|
||||||
selectedLayoutId: null,
|
selectedLayoutId: null,
|
||||||
|
|
||||||
// onboarding
|
// Client state
|
||||||
|
selectedComponentInstance: null,
|
||||||
|
|
||||||
|
// Onboarding
|
||||||
onboarding: false,
|
onboarding: false,
|
||||||
tourNodes: null,
|
tourNodes: null,
|
||||||
|
|
||||||
builderSidePanel: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getFrontendStore = () => {
|
export const getFrontendStore = () => {
|
||||||
|
@ -262,22 +270,27 @@ export const getFrontendStore = () => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
save: async screen => {
|
save: async screen => {
|
||||||
/*
|
// Validate screen structure
|
||||||
Temporarily disabled to accomodate migration issues.
|
// Temporarily disabled to accommodate migration issues
|
||||||
store.actions.screens.validate(screen)
|
// store.actions.screens.validate(screen)
|
||||||
*/
|
|
||||||
const state = get(store)
|
// Check screen definition for any component settings which need updated
|
||||||
|
store.actions.screens.enrichEmptySettings(screen)
|
||||||
|
|
||||||
|
// Save screen
|
||||||
const creatingNewScreen = screen._id === undefined
|
const creatingNewScreen = screen._id === undefined
|
||||||
const savedScreen = await API.saveScreen(screen)
|
const savedScreen = await API.saveScreen(screen)
|
||||||
const routesResponse = await API.fetchAppRoutes()
|
const routesResponse = await API.fetchAppRoutes()
|
||||||
let usedPlugins = state.usedPlugins
|
|
||||||
|
|
||||||
// If plugins changed we need to fetch the latest app metadata
|
// If plugins changed we need to fetch the latest app metadata
|
||||||
|
const state = get(store)
|
||||||
|
let usedPlugins = state.usedPlugins
|
||||||
if (savedScreen.pluginAdded) {
|
if (savedScreen.pluginAdded) {
|
||||||
const { application } = await API.fetchAppPackage(state.appId)
|
const { application } = await API.fetchAppPackage(state.appId)
|
||||||
usedPlugins = application.usedPlugins || []
|
usedPlugins = application.usedPlugins || []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update state
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
// Update screen object
|
// Update screen object
|
||||||
const idx = state.screens.findIndex(x => x._id === savedScreen._id)
|
const idx = state.screens.findIndex(x => x._id === savedScreen._id)
|
||||||
|
@ -298,7 +311,6 @@ export const getFrontendStore = () => {
|
||||||
|
|
||||||
// Update used plugins
|
// Update used plugins
|
||||||
state.usedPlugins = usedPlugins
|
state.usedPlugins = usedPlugins
|
||||||
|
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
return savedScreen
|
return savedScreen
|
||||||
|
@ -406,6 +418,17 @@ export const getFrontendStore = () => {
|
||||||
}
|
}
|
||||||
await store.actions.screens.patch(patch, screen._id)
|
await store.actions.screens.patch(patch, screen._id)
|
||||||
},
|
},
|
||||||
|
enrichEmptySettings: screen => {
|
||||||
|
// Flatten the recursive component tree
|
||||||
|
const components = findAllMatchingComponents(screen.props, x => x)
|
||||||
|
|
||||||
|
// Iterate over all components and run checks
|
||||||
|
components.forEach(component => {
|
||||||
|
store.actions.components.enrichEmptySettings(component, {
|
||||||
|
screen,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
preview: {
|
preview: {
|
||||||
setDevice: device => {
|
setDevice: device => {
|
||||||
|
@ -493,65 +516,155 @@ export const getFrontendStore = () => {
|
||||||
}
|
}
|
||||||
return get(store).components[componentName]
|
return get(store).components[componentName]
|
||||||
},
|
},
|
||||||
createInstance: (componentName, presetProps) => {
|
getDefaultDatasource: () => {
|
||||||
|
// Ignore users table
|
||||||
|
const validTables = get(tables).list.filter(x => x._id !== "ta_users")
|
||||||
|
|
||||||
|
// Try to use their own internal table first
|
||||||
|
let table = validTables.find(table => {
|
||||||
|
return (
|
||||||
|
table.sourceId !== BUDIBASE_INTERNAL_DB_ID &&
|
||||||
|
table.type === DB_TYPE_INTERNAL
|
||||||
|
)
|
||||||
|
})
|
||||||
|
if (table) {
|
||||||
|
return table
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then try sample data
|
||||||
|
table = validTables.find(table => {
|
||||||
|
return (
|
||||||
|
table.sourceId === BUDIBASE_INTERNAL_DB_ID &&
|
||||||
|
table.type === DB_TYPE_INTERNAL
|
||||||
|
)
|
||||||
|
})
|
||||||
|
if (table) {
|
||||||
|
return table
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally try an external table
|
||||||
|
return validTables.find(table => table.type === DB_TYPE_EXTERNAL)
|
||||||
|
},
|
||||||
|
enrichEmptySettings: (component, opts) => {
|
||||||
|
if (!component?._component) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const defaultDS = store.actions.components.getDefaultDatasource()
|
||||||
|
const settings = getComponentSettings(component._component)
|
||||||
|
const { parent, screen, useDefaultValues } = opts || {}
|
||||||
|
const treeId = parent?._id || component._id
|
||||||
|
if (!screen) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
settings.forEach(setting => {
|
||||||
|
const value = component[setting.key]
|
||||||
|
|
||||||
|
// Fill empty settings
|
||||||
|
if (value == null || value === "") {
|
||||||
|
if (setting.type === "multifield" && setting.selectAllFields) {
|
||||||
|
// Select all schema fields where required
|
||||||
|
component[setting.key] = Object.keys(defaultDS?.schema || {})
|
||||||
|
} else if (
|
||||||
|
(setting.type === "dataSource" || setting.type === "table") &&
|
||||||
|
defaultDS
|
||||||
|
) {
|
||||||
|
// Select default datasource where required
|
||||||
|
component[setting.key] = {
|
||||||
|
label: defaultDS.name,
|
||||||
|
tableId: defaultDS._id,
|
||||||
|
type: "table",
|
||||||
|
}
|
||||||
|
} else if (setting.type === "dataProvider") {
|
||||||
|
// Pick closest data provider where required
|
||||||
|
const path = findComponentPath(screen.props, treeId)
|
||||||
|
const providers = path.filter(component =>
|
||||||
|
component._component?.endsWith("/dataprovider")
|
||||||
|
)
|
||||||
|
if (providers.length) {
|
||||||
|
const id = providers[providers.length - 1]?._id
|
||||||
|
component[setting.key] = `{{ literal ${safe(id)} }}`
|
||||||
|
}
|
||||||
|
} else if (setting.type.startsWith("field/")) {
|
||||||
|
// Autofill form field names
|
||||||
|
// Get all available field names in this form schema
|
||||||
|
let fieldOptions = getComponentFieldOptions(
|
||||||
|
screen.props,
|
||||||
|
treeId,
|
||||||
|
setting.type,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get all currently used fields
|
||||||
|
const form = findClosestMatchingComponent(
|
||||||
|
screen.props,
|
||||||
|
treeId,
|
||||||
|
x => x._component === "@budibase/standard-components/form"
|
||||||
|
)
|
||||||
|
const usedFields = Object.keys(buildFormSchema(form) || {})
|
||||||
|
|
||||||
|
// Filter out already used fields
|
||||||
|
fieldOptions = fieldOptions.filter(x => !usedFields.includes(x))
|
||||||
|
|
||||||
|
// Set field name and also assume we have a label setting
|
||||||
|
if (fieldOptions[0]) {
|
||||||
|
component[setting.key] = fieldOptions[0]
|
||||||
|
component.label = fieldOptions[0]
|
||||||
|
}
|
||||||
|
} else if (useDefaultValues && setting.defaultValue !== undefined) {
|
||||||
|
// Use default value where required
|
||||||
|
component[setting.key] = setting.defaultValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate non-empty settings
|
||||||
|
else {
|
||||||
|
if (setting.type === "dataProvider") {
|
||||||
|
// Validate data provider exists, or else clear it
|
||||||
|
const treeId = parent?._id || component._id
|
||||||
|
const path = findComponentPath(screen?.props, treeId)
|
||||||
|
const providers = path.filter(component =>
|
||||||
|
component._component?.endsWith("/dataprovider")
|
||||||
|
)
|
||||||
|
// Validate non-empty values
|
||||||
|
const valid = providers?.some(dp => value.includes?.(dp._id))
|
||||||
|
if (!valid) {
|
||||||
|
if (providers.length) {
|
||||||
|
const id = providers[providers.length - 1]?._id
|
||||||
|
component[setting.key] = `{{ literal ${safe(id)} }}`
|
||||||
|
} else {
|
||||||
|
delete component[setting.key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
createInstance: (componentName, presetProps, parent) => {
|
||||||
const definition = store.actions.components.getDefinition(componentName)
|
const definition = store.actions.components.getDefinition(componentName)
|
||||||
if (!definition) {
|
if (!definition) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flattened settings
|
// Generate basic component structure
|
||||||
const settings = getComponentSettings(componentName)
|
let instance = {
|
||||||
|
_id: Helpers.uuid(),
|
||||||
let dataSourceField = settings.find(
|
_component: definition.component,
|
||||||
setting => setting.type == "dataSource" || setting.type == "table"
|
_styles: {
|
||||||
)
|
normal: {},
|
||||||
|
hover: {},
|
||||||
let defaultDatasource
|
active: {},
|
||||||
if (dataSourceField) {
|
},
|
||||||
const _tables = get(tables)
|
_instanceName: `New ${definition.friendlyName || definition.name}`,
|
||||||
const filteredTables = _tables.list.filter(
|
...presetProps,
|
||||||
table => table._id != "ta_users"
|
|
||||||
)
|
|
||||||
|
|
||||||
const internalTable = filteredTables.find(
|
|
||||||
table =>
|
|
||||||
table.sourceId === BUDIBASE_INTERNAL_DB_ID &&
|
|
||||||
table.type == DB_TYPE_INTERNAL
|
|
||||||
)
|
|
||||||
|
|
||||||
const defaultSourceTable = filteredTables.find(
|
|
||||||
table =>
|
|
||||||
table.sourceId !== BUDIBASE_INTERNAL_DB_ID &&
|
|
||||||
table.type == DB_TYPE_INTERNAL
|
|
||||||
)
|
|
||||||
|
|
||||||
const defaultExternalTable = filteredTables.find(
|
|
||||||
table => table.type == DB_TYPE_EXTERNAL
|
|
||||||
)
|
|
||||||
|
|
||||||
defaultDatasource =
|
|
||||||
defaultSourceTable || internalTable || defaultExternalTable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate default props
|
// Enrich empty settings
|
||||||
let props = { ...presetProps }
|
store.actions.components.enrichEmptySettings(instance, {
|
||||||
settings.forEach(setting => {
|
parent,
|
||||||
if (setting.type === "multifield" && setting.selectAllFields) {
|
screen: get(selectedScreen),
|
||||||
props[setting.key] = Object.keys(defaultDatasource.schema || {})
|
useDefaultValues: true,
|
||||||
} else if (setting.defaultValue !== undefined) {
|
|
||||||
props[setting.key] = setting.defaultValue
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Set a default datasource
|
|
||||||
if (dataSourceField && defaultDatasource) {
|
|
||||||
props[dataSourceField.key] = {
|
|
||||||
label: defaultDatasource.name,
|
|
||||||
tableId: defaultDatasource._id,
|
|
||||||
type: "table",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add any extra properties the component needs
|
// Add any extra properties the component needs
|
||||||
let extras = {}
|
let extras = {}
|
||||||
if (definition.hasChildren) {
|
if (definition.hasChildren) {
|
||||||
|
@ -569,17 +682,8 @@ export const getFrontendStore = () => {
|
||||||
extras.step = formSteps.length + 1
|
extras.step = formSteps.length + 1
|
||||||
extras._instanceName = `Step ${formSteps.length + 1}`
|
extras._instanceName = `Step ${formSteps.length + 1}`
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_id: Helpers.uuid(),
|
...cloneDeep(instance),
|
||||||
_component: definition.component,
|
|
||||||
_styles: {
|
|
||||||
normal: {},
|
|
||||||
hover: {},
|
|
||||||
active: {},
|
|
||||||
},
|
|
||||||
_instanceName: `New ${definition.friendlyName || definition.name}`,
|
|
||||||
...cloneDeep(props),
|
|
||||||
...extras,
|
...extras,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -587,7 +691,8 @@ export const getFrontendStore = () => {
|
||||||
const state = get(store)
|
const state = get(store)
|
||||||
const componentInstance = store.actions.components.createInstance(
|
const componentInstance = store.actions.components.createInstance(
|
||||||
componentName,
|
componentName,
|
||||||
presetProps
|
presetProps,
|
||||||
|
parent
|
||||||
)
|
)
|
||||||
if (!componentInstance) {
|
if (!componentInstance) {
|
||||||
return
|
return
|
||||||
|
@ -1123,6 +1228,52 @@ export const getFrontendStore = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
addParent: async (componentId, parentType) => {
|
||||||
|
if (!componentId || !parentType) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new parent instance
|
||||||
|
const newParentDefinition = store.actions.components.createInstance(
|
||||||
|
parentType,
|
||||||
|
null,
|
||||||
|
parent
|
||||||
|
)
|
||||||
|
if (!newParentDefinition) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace component with a version wrapped in a new parent
|
||||||
|
await store.actions.screens.patch(screen => {
|
||||||
|
// Get this component definition and parent definition
|
||||||
|
let definition = findComponent(screen.props, componentId)
|
||||||
|
let oldParentDefinition = findComponentParent(
|
||||||
|
screen.props,
|
||||||
|
componentId
|
||||||
|
)
|
||||||
|
if (!definition || !oldParentDefinition) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace component with parent
|
||||||
|
const index = oldParentDefinition._children.findIndex(
|
||||||
|
component => component._id === componentId
|
||||||
|
)
|
||||||
|
if (index === -1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
oldParentDefinition._children[index] = {
|
||||||
|
...newParentDefinition,
|
||||||
|
_children: [definition],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Select the new parent
|
||||||
|
store.update(state => {
|
||||||
|
state.selectedComponentId = newParentDefinition._id
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
links: {
|
links: {
|
||||||
save: async (url, title) => {
|
save: async (url, title) => {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
export let title
|
export let title
|
||||||
export let icon
|
export let icon
|
||||||
export let expandable = false
|
|
||||||
export let showAddButton = false
|
export let showAddButton = false
|
||||||
export let showBackButton = false
|
export let showBackButton = false
|
||||||
export let showCloseButton = false
|
export let showCloseButton = false
|
||||||
|
@ -12,8 +11,8 @@
|
||||||
export let onClickCloseButton
|
export let onClickCloseButton
|
||||||
export let borderLeft = false
|
export let borderLeft = false
|
||||||
export let borderRight = false
|
export let borderRight = false
|
||||||
|
export let wide = false
|
||||||
|
|
||||||
let wide = false
|
|
||||||
$: customHeaderContent = $$slots["panel-header-content"]
|
$: customHeaderContent = $$slots["panel-header-content"]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -28,13 +27,6 @@
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<Heading size="XXS">{title || ""}</Heading>
|
<Heading size="XXS">{title || ""}</Heading>
|
||||||
</div>
|
</div>
|
||||||
{#if expandable}
|
|
||||||
<Icon
|
|
||||||
name={wide ? "Minimize" : "Maximize"}
|
|
||||||
hoverable
|
|
||||||
on:click={() => (wide = !wide)}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
{#if showAddButton}
|
{#if showAddButton}
|
||||||
<div class="add-button" on:click={onClickAddButton}>
|
<div class="add-button" on:click={onClickAddButton}>
|
||||||
<Icon name="Add" />
|
<Icon name="Add" />
|
||||||
|
@ -74,8 +66,8 @@
|
||||||
border-right: var(--border-light);
|
border-right: var(--border-light);
|
||||||
}
|
}
|
||||||
.panel.wide {
|
.panel.wide {
|
||||||
width: 420px;
|
width: 310px;
|
||||||
flex: 0 0 420px;
|
flex: 0 0 310px;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
flex: 0 0 48px;
|
flex: 0 0 48px;
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
: enrichedSchemaFields?.map(field => field.name)
|
: enrichedSchemaFields?.map(field => field.name)
|
||||||
$: sanitisedValue = getValidColumns(value, options)
|
$: sanitisedValue = getValidColumns(value, options)
|
||||||
$: updateBoundValue(sanitisedValue)
|
$: updateBoundValue(sanitisedValue)
|
||||||
$: enrichedSchemaFields = getFields(Object.values(schema) || [], {
|
$: enrichedSchemaFields = getFields(Object.values(schema || {}), {
|
||||||
allowLinks: true,
|
allowLinks: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -3,23 +3,13 @@
|
||||||
import { makePropSafe } from "@budibase/string-templates"
|
import { makePropSafe } from "@budibase/string-templates"
|
||||||
import { currentAsset, store } from "builderStore"
|
import { currentAsset, store } from "builderStore"
|
||||||
import { findComponentPath } from "builderStore/componentUtils"
|
import { findComponentPath } from "builderStore/componentUtils"
|
||||||
import { createEventDispatcher, onMount } from "svelte"
|
|
||||||
|
|
||||||
export let value
|
export let value
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
|
||||||
const getValue = component => `{{ literal ${makePropSafe(component._id)} }}`
|
const getValue = component => `{{ literal ${makePropSafe(component._id)} }}`
|
||||||
|
|
||||||
$: path = findComponentPath($currentAsset?.props, $store.selectedComponentId)
|
$: path = findComponentPath($currentAsset?.props, $store.selectedComponentId)
|
||||||
$: providers = path.filter(c => c._component?.endsWith("/dataprovider"))
|
$: providers = path.filter(c => c._component?.endsWith("/dataprovider"))
|
||||||
|
|
||||||
// Set initial value to closest data provider
|
|
||||||
onMount(() => {
|
|
||||||
const valid = value && providers.find(x => getValue(x) === value) != null
|
|
||||||
if (!valid && providers.length) {
|
|
||||||
dispatch("change", getValue(providers[providers.length - 1]))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
|
|
|
@ -1,43 +1,17 @@
|
||||||
<script>
|
<script>
|
||||||
import { Combobox } from "@budibase/bbui"
|
import { Combobox } from "@budibase/bbui"
|
||||||
import {
|
|
||||||
getDatasourceForProvider,
|
|
||||||
getSchemaForDatasource,
|
|
||||||
} from "builderStore/dataBinding"
|
|
||||||
import { currentAsset } from "builderStore"
|
import { currentAsset } from "builderStore"
|
||||||
import { findClosestMatchingComponent } from "builderStore/componentUtils"
|
import { getComponentFieldOptions } from "helpers/formFields"
|
||||||
|
|
||||||
export let componentInstance
|
export let componentInstance
|
||||||
export let value
|
export let value
|
||||||
export let type
|
export let type
|
||||||
|
|
||||||
$: form = findClosestMatchingComponent(
|
$: options = getComponentFieldOptions(
|
||||||
$currentAsset?.props,
|
$currentAsset?.props,
|
||||||
componentInstance._id,
|
componentInstance?._id,
|
||||||
component => component._component === "@budibase/standard-components/form"
|
type
|
||||||
)
|
)
|
||||||
$: datasource = getDatasourceForProvider($currentAsset, form)
|
|
||||||
$: schema = getSchemaForDatasource($currentAsset, datasource, {
|
|
||||||
formSchema: true,
|
|
||||||
}).schema
|
|
||||||
$: options = getOptions(schema, type)
|
|
||||||
|
|
||||||
const getOptions = (schema, type) => {
|
|
||||||
let entries = Object.entries(schema ?? {})
|
|
||||||
let types = []
|
|
||||||
if (type === "field/options" || type === "field/longform") {
|
|
||||||
// allow options and longform to be used on string fields as well
|
|
||||||
types = [type, "field/string"]
|
|
||||||
} else {
|
|
||||||
types = [type]
|
|
||||||
}
|
|
||||||
|
|
||||||
types = types.map(type => type.slice(type.indexOf("/") + 1))
|
|
||||||
|
|
||||||
entries = entries.filter(entry => types.includes(entry[1].type))
|
|
||||||
|
|
||||||
return entries.map(entry => entry[0])
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Combobox on:change {value} {options} />
|
<Combobox on:change {value} {options} />
|
||||||
|
|
|
@ -74,11 +74,13 @@
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="property-control" class:highlighted={highlighted && nullishValue}>
|
<div
|
||||||
{#if type !== "boolean" && label}
|
class="property-control"
|
||||||
<div class="label">
|
class:wide={!label}
|
||||||
<Label>{label}</Label>
|
class:highlighted={highlighted && nullishValue}
|
||||||
</div>
|
>
|
||||||
|
{#if label}
|
||||||
|
<Label size="M">{label}</Label>
|
||||||
{/if}
|
{/if}
|
||||||
<div id={`${key}-prop-control`} class="control">
|
<div id={`${key}-prop-control`} class="control">
|
||||||
<svelte:component
|
<svelte:component
|
||||||
|
@ -90,7 +92,6 @@
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
bindings={allBindings}
|
bindings={allBindings}
|
||||||
name={key}
|
name={key}
|
||||||
text={label}
|
|
||||||
{nested}
|
{nested}
|
||||||
{key}
|
{key}
|
||||||
{type}
|
{type}
|
||||||
|
@ -105,28 +106,34 @@
|
||||||
<style>
|
<style>
|
||||||
.property-control {
|
.property-control {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
grid-template-columns: 90px 1fr;
|
||||||
justify-content: flex-start;
|
align-items: center;
|
||||||
align-items: stretch;
|
|
||||||
transition: background 130ms ease-out, border-color 130ms ease-out;
|
transition: background 130ms ease-out, border-color 130ms ease-out;
|
||||||
border-left: 4px solid transparent;
|
border-left: 4px solid transparent;
|
||||||
margin: -6px calc(-1 * var(--spacing-xl));
|
margin: 0 calc(-1 * var(--spacing-xl));
|
||||||
padding: 6px var(--spacing-xl) 6px calc(var(--spacing-xl) - 4px);
|
padding: 0 var(--spacing-xl) 0 calc(var(--spacing-xl) - 4px);
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.property-control :global(.spectrum-FieldLabel) {
|
||||||
|
white-space: normal;
|
||||||
}
|
}
|
||||||
.property-control.highlighted {
|
.property-control.highlighted {
|
||||||
background: var(--spectrum-global-color-gray-300);
|
background: var(--spectrum-global-color-gray-300);
|
||||||
border-color: var(--spectrum-global-color-blue-400);
|
border-color: var(--spectrum-global-color-static-red-600);
|
||||||
}
|
|
||||||
.label {
|
|
||||||
padding-bottom: var(--spectrum-global-dimension-size-65);
|
|
||||||
}
|
}
|
||||||
.control {
|
.control {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
.property-control.wide .control {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
.text {
|
.text {
|
||||||
margin-top: var(--spectrum-global-dimension-size-65);
|
|
||||||
font-size: var(--spectrum-global-dimension-font-size-75);
|
font-size: var(--spectrum-global-dimension-font-size-75);
|
||||||
color: var(--grey-6);
|
color: var(--grey-6);
|
||||||
|
grid-column: 2 / 2;
|
||||||
|
}
|
||||||
|
.property-control.wide .text {
|
||||||
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
32
packages/builder/src/helpers/formFields.js
Normal file
32
packages/builder/src/helpers/formFields.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { findClosestMatchingComponent } from "builderStore/componentUtils"
|
||||||
|
import {
|
||||||
|
getDatasourceForProvider,
|
||||||
|
getSchemaForDatasource,
|
||||||
|
} from "builderStore/dataBinding"
|
||||||
|
|
||||||
|
export const getComponentFieldOptions = (asset, id, type, loose = true) => {
|
||||||
|
const form = findClosestMatchingComponent(
|
||||||
|
asset,
|
||||||
|
id,
|
||||||
|
component => component._component === "@budibase/standard-components/form"
|
||||||
|
)
|
||||||
|
const datasource = getDatasourceForProvider(asset, form)
|
||||||
|
const schema = getSchemaForDatasource(asset, datasource, {
|
||||||
|
formSchema: true,
|
||||||
|
}).schema
|
||||||
|
|
||||||
|
// Get valid types for this field
|
||||||
|
let types = [type]
|
||||||
|
if (loose) {
|
||||||
|
if (type === "field/options" || type === "field/longform") {
|
||||||
|
// Allow options and longform to be used on string fields as well
|
||||||
|
types = [type, "field/string"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
types = types.map(type => type.slice(type.indexOf("/") + 1))
|
||||||
|
|
||||||
|
// Find fields of valid types
|
||||||
|
return Object.entries(schema || {})
|
||||||
|
.filter(entry => types.includes(entry[1].type))
|
||||||
|
.map(entry => entry[0])
|
||||||
|
}
|
|
@ -41,13 +41,13 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.tenantId !== urlTenantId) {
|
if (urlTenantId && user.tenantId !== urlTenantId) {
|
||||||
// user should not be here - play it safe and log them out
|
// user should not be here - play it safe and log them out
|
||||||
try {
|
try {
|
||||||
await auth.logout()
|
await auth.logout()
|
||||||
await auth.setOrganisation(null)
|
await auth.setOrganisation(null)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Swallow error and do nothing
|
console.error("Tenant mis-match, logout.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -220,6 +220,9 @@
|
||||||
} else if (type === "drop-new-component") {
|
} else if (type === "drop-new-component") {
|
||||||
const { component, parent, index } = data
|
const { component, parent, index } = data
|
||||||
await store.actions.components.create(component, null, parent, index)
|
await store.actions.components.create(component, null, parent, index)
|
||||||
|
} else if (type === "add-parent-component") {
|
||||||
|
const { componentId, parentType } = data
|
||||||
|
await store.actions.components.addParent(componentId, parentType)
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Client sent unknown event type: ${type}`)
|
console.warn(`Client sent unknown event type: ${type}`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
{#if $selectedComponent}
|
{#if $selectedComponent}
|
||||||
{#key $selectedComponent._id}
|
{#key $selectedComponent._id}
|
||||||
<Panel {title} icon={componentDefinition?.icon} borderLeft>
|
<Panel {title} icon={componentDefinition?.icon} borderLeft wide>
|
||||||
<span slot="panel-header-content">
|
<span slot="panel-header-content">
|
||||||
<div class="settings-tabs">
|
<div class="settings-tabs">
|
||||||
{#each tabs as tab}
|
{#each tabs as tab}
|
||||||
|
|
|
@ -117,6 +117,7 @@
|
||||||
{#each sections as section, idx (section.name)}
|
{#each sections as section, idx (section.name)}
|
||||||
{#if section.visible}
|
{#if section.visible}
|
||||||
<DetailSummary name={section.name} collapsible={false}>
|
<DetailSummary name={section.name} collapsible={false}>
|
||||||
|
<div class="settings">
|
||||||
{#if idx === 0 && !componentInstance._component.endsWith("/layout") && !isScreen}
|
{#if idx === 0 && !componentInstance._component.endsWith("/layout") && !isScreen}
|
||||||
<PropertyControl
|
<PropertyControl
|
||||||
control={Input}
|
control={Input}
|
||||||
|
@ -160,6 +161,7 @@
|
||||||
{#if idx === 0 && componentDefinition?.component?.endsWith("/fieldgroup")}
|
{#if idx === 0 && componentDefinition?.component?.endsWith("/fieldgroup")}
|
||||||
<ResetFieldsButton {componentInstance} />
|
<ResetFieldsButton {componentInstance} />
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
</DetailSummary>
|
</DetailSummary>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -168,3 +170,13 @@
|
||||||
<EjectBlockButton />
|
<EjectBlockButton />
|
||||||
</DetailSummary>
|
</DetailSummary>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.settings {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
<StyleSection
|
<StyleSection
|
||||||
{style}
|
{style}
|
||||||
name={style.label}
|
name={style.label}
|
||||||
columns={style.columns}
|
|
||||||
properties={style.settings}
|
properties={style.settings}
|
||||||
{componentInstance}
|
{componentInstance}
|
||||||
{bindings}
|
{bindings}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
|
|
||||||
export let name
|
export let name
|
||||||
export let columns
|
|
||||||
export let properties
|
export let properties
|
||||||
export let componentInstance
|
export let componentInstance
|
||||||
export let bindings = []
|
export let bindings = []
|
||||||
|
@ -34,9 +33,8 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DetailSummary collapsible={false} name={`${name}${changed ? " *" : ""}`}>
|
<DetailSummary collapsible={false} name={`${name}${changed ? " *" : ""}`}>
|
||||||
<div class="group-content" style="grid-template-columns: {columns || '1fr'}">
|
<div class="styles">
|
||||||
{#each properties as prop (`${componentInstance._id}-${prop.key}-${prop.label}`)}
|
{#each properties as prop (`${componentInstance._id}-${prop.key}-${prop.label}`)}
|
||||||
<div style="grid-column: {prop.column || 'auto'}">
|
|
||||||
<PropertyControl
|
<PropertyControl
|
||||||
label={`${prop.label}${hasPropChanged(style, prop) ? " *" : ""}`}
|
label={`${prop.label}${hasPropChanged(style, prop) ? " *" : ""}`}
|
||||||
control={prop.control}
|
control={prop.control}
|
||||||
|
@ -46,15 +44,16 @@
|
||||||
props={getControlProps(prop)}
|
props={getControlProps(prop)}
|
||||||
{bindings}
|
{bindings}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</DetailSummary>
|
</DetailSummary>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.group-content {
|
.styles {
|
||||||
display: grid;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: var(--spacing-l);
|
gap: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3,7 +3,6 @@ import ColorPicker from "components/design/settings/controls/ColorPicker.svelte"
|
||||||
|
|
||||||
export const margin = {
|
export const margin = {
|
||||||
label: "Margin",
|
label: "Margin",
|
||||||
columns: "1fr 1fr",
|
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
label: "Top",
|
label: "Top",
|
||||||
|
@ -90,7 +89,6 @@ export const margin = {
|
||||||
|
|
||||||
export const padding = {
|
export const padding = {
|
||||||
label: "Padding",
|
label: "Padding",
|
||||||
columns: "1fr 1fr",
|
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
label: "Top",
|
label: "Top",
|
||||||
|
@ -177,7 +175,6 @@ export const padding = {
|
||||||
|
|
||||||
export const size = {
|
export const size = {
|
||||||
label: "Size",
|
label: "Size",
|
||||||
columns: "1fr 1fr",
|
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
label: "Width",
|
label: "Width",
|
||||||
|
@ -196,7 +193,6 @@ export const size = {
|
||||||
|
|
||||||
export const background = {
|
export const background = {
|
||||||
label: "Background",
|
label: "Background",
|
||||||
columns: "auto 1fr",
|
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
label: "Color",
|
label: "Color",
|
||||||
|
@ -285,7 +281,6 @@ export const background = {
|
||||||
|
|
||||||
export const border = {
|
export const border = {
|
||||||
label: "Border",
|
label: "Border",
|
||||||
columns: "1fr 1fr",
|
|
||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
label: "Color",
|
label: "Color",
|
||||||
|
|
|
@ -1,22 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import Panel from "components/design/Panel.svelte"
|
import Panel from "components/design/Panel.svelte"
|
||||||
import { goto } from "@roxi/routify"
|
import { goto } from "@roxi/routify"
|
||||||
import {
|
import { Layout, Search, Icon, Body, notifications } from "@budibase/bbui"
|
||||||
Layout,
|
|
||||||
ActionGroup,
|
|
||||||
ActionButton,
|
|
||||||
Search,
|
|
||||||
Icon,
|
|
||||||
Body,
|
|
||||||
notifications,
|
|
||||||
} from "@budibase/bbui"
|
|
||||||
import structure from "./componentStructure.json"
|
import structure from "./componentStructure.json"
|
||||||
import { store, selectedComponent, selectedScreen } from "builderStore"
|
import { store, selectedComponent, selectedScreen } from "builderStore"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { fly } from "svelte/transition"
|
import { fly } from "svelte/transition"
|
||||||
import { findComponentPath } from "builderStore/componentUtils"
|
import { findComponentPath } from "builderStore/componentUtils"
|
||||||
|
|
||||||
let section = "components"
|
|
||||||
let searchString
|
let searchString
|
||||||
let searchRef
|
let searchRef
|
||||||
let selectedIndex
|
let selectedIndex
|
||||||
|
@ -37,7 +28,6 @@
|
||||||
allowedComponents,
|
allowedComponents,
|
||||||
searchString
|
searchString
|
||||||
)
|
)
|
||||||
$: blocks = enrichedStructure.find(x => x.name === "Blocks").children
|
|
||||||
$: orderMap = createComponentOrderMap(componentList)
|
$: orderMap = createComponentOrderMap(componentList)
|
||||||
|
|
||||||
const getAllowedComponents = (allComponents, screen, component) => {
|
const getAllowedComponents = (allComponents, screen, component) => {
|
||||||
|
@ -127,6 +117,11 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Swap blocks and plugins
|
||||||
|
let tmp = enrichedStructure[1]
|
||||||
|
enrichedStructure[1] = enrichedStructure[0]
|
||||||
|
enrichedStructure[0] = tmp
|
||||||
|
|
||||||
return enrichedStructure
|
return enrichedStructure
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,11 +132,6 @@
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove blocks if there is no search string
|
|
||||||
if (!search) {
|
|
||||||
structure = structure.filter(category => category.name !== "Blocks")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return only items which match the search string
|
// Return only items which match the search string
|
||||||
let filteredStructure = []
|
let filteredStructure = []
|
||||||
structure.forEach(category => {
|
structure.forEach(category => {
|
||||||
|
@ -225,6 +215,7 @@
|
||||||
showCloseButton
|
showCloseButton
|
||||||
onClickCloseButton={() => $goto("../")}
|
onClickCloseButton={() => $goto("../")}
|
||||||
borderLeft
|
borderLeft
|
||||||
|
wide
|
||||||
>
|
>
|
||||||
<Layout paddingX="L" paddingY="XL" gap="S">
|
<Layout paddingX="L" paddingY="XL" gap="S">
|
||||||
<Search
|
<Search
|
||||||
|
@ -233,21 +224,6 @@
|
||||||
on:change={e => (searchString = e.detail)}
|
on:change={e => (searchString = e.detail)}
|
||||||
bind:inputRef={searchRef}
|
bind:inputRef={searchRef}
|
||||||
/>
|
/>
|
||||||
{#if !searchString}
|
|
||||||
<ActionGroup compact justified>
|
|
||||||
<ActionButton
|
|
||||||
fullWidth
|
|
||||||
selected={section === "components"}
|
|
||||||
on:click={() => (section = "components")}>Components</ActionButton
|
|
||||||
>
|
|
||||||
<ActionButton
|
|
||||||
fullWidth
|
|
||||||
selected={section === "blocks"}
|
|
||||||
on:click={() => (section = "blocks")}>Blocks</ActionButton
|
|
||||||
>
|
|
||||||
</ActionGroup>
|
|
||||||
{/if}
|
|
||||||
{#if searchString || section === "components"}
|
|
||||||
{#if filteredStructure.length}
|
{#if filteredStructure.length}
|
||||||
{#each filteredStructure as category}
|
{#each filteredStructure as category}
|
||||||
<Layout noPadding gap="XS">
|
<Layout noPadding gap="XS">
|
||||||
|
@ -258,8 +234,7 @@
|
||||||
on:dragstart={() => onDragStart(component.component)}
|
on:dragstart={() => onDragStart(component.component)}
|
||||||
on:dragend={onDragEnd}
|
on:dragend={onDragEnd}
|
||||||
class="component"
|
class="component"
|
||||||
class:selected={selectedIndex ===
|
class:selected={selectedIndex === orderMap[component.component]}
|
||||||
orderMap[component.component]}
|
|
||||||
on:click={() => addComponent(component.component)}
|
on:click={() => addComponent(component.component)}
|
||||||
on:mouseover={() => (selectedIndex = null)}
|
on:mouseover={() => (selectedIndex = null)}
|
||||||
on:focus
|
on:focus
|
||||||
|
@ -275,23 +250,6 @@
|
||||||
There aren't any components matching the current filter
|
There aren't any components matching the current filter
|
||||||
</Body>
|
</Body>
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
|
||||||
<Body size="S">Blocks are collections of pre-built components</Body>
|
|
||||||
<Layout noPadding gap="XS">
|
|
||||||
{#each blocks as block}
|
|
||||||
<div
|
|
||||||
draggable="true"
|
|
||||||
class="component"
|
|
||||||
on:click={() => addComponent(block.component)}
|
|
||||||
on:dragstart={() => onDragStart(block.component)}
|
|
||||||
on:dragend={onDragEnd}
|
|
||||||
>
|
|
||||||
<Icon name={block.icon} />
|
|
||||||
<Body size="XS">{block.name}</Body>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</Layout>
|
|
||||||
{/if}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
</Panel>
|
</Panel>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/cli",
|
"name": "@budibase/cli",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -29,9 +29,9 @@
|
||||||
"outputPath": "build"
|
"outputPath": "build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/backend-core": "2.4.27-alpha.9",
|
"@budibase/backend-core": "2.4.27-alpha.12",
|
||||||
"@budibase/string-templates": "2.4.27-alpha.9",
|
"@budibase/string-templates": "2.4.27-alpha.12",
|
||||||
"@budibase/types": "2.4.27-alpha.9",
|
"@budibase/types": "2.4.27-alpha.12",
|
||||||
"axios": "0.21.2",
|
"axios": "0.21.2",
|
||||||
"chalk": "4.1.0",
|
"chalk": "4.1.0",
|
||||||
"cli-progress": "3.11.2",
|
"cli-progress": "3.11.2",
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"module": "dist/budibase-client.js",
|
"module": "dist/budibase-client.js",
|
||||||
"main": "dist/budibase-client.js",
|
"main": "dist/budibase-client.js",
|
||||||
|
@ -19,11 +19,11 @@
|
||||||
"dev:builder": "rollup -cw"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "2.4.27-alpha.9",
|
"@budibase/bbui": "2.4.27-alpha.12",
|
||||||
"@budibase/frontend-core": "2.4.27-alpha.9",
|
"@budibase/frontend-core": "2.4.27-alpha.12",
|
||||||
"@budibase/shared-core": "2.4.27-alpha.9",
|
"@budibase/shared-core": "2.4.27-alpha.12",
|
||||||
"@budibase/string-templates": "2.4.27-alpha.9",
|
"@budibase/string-templates": "2.4.27-alpha.12",
|
||||||
"@budibase/types": "2.4.27-alpha.9",
|
"@budibase/types": "2.4.27-alpha.12",
|
||||||
"@spectrum-css/button": "^3.0.3",
|
"@spectrum-css/button": "^3.0.3",
|
||||||
"@spectrum-css/card": "^3.0.3",
|
"@spectrum-css/card": "^3.0.3",
|
||||||
"@spectrum-css/divider": "^1.0.3",
|
"@spectrum-css/divider": "^1.0.3",
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
// Provide contexts
|
// Provide contexts
|
||||||
setContext("sdk", SDK)
|
setContext("sdk", SDK)
|
||||||
setContext("component", writable({}))
|
setContext("component", writable({ id: null, ancestors: [] }))
|
||||||
setContext("context", createContextStore())
|
setContext("context", createContextStore())
|
||||||
|
|
||||||
let dataLoaded = false
|
let dataLoaded = false
|
||||||
|
|
|
@ -26,19 +26,20 @@
|
||||||
} from "stores"
|
} from "stores"
|
||||||
import { Helpers } from "@budibase/bbui"
|
import { Helpers } from "@budibase/bbui"
|
||||||
import { getActiveConditions, reduceConditionActions } from "utils/conditions"
|
import { getActiveConditions, reduceConditionActions } from "utils/conditions"
|
||||||
import Placeholder from "components/app/Placeholder.svelte"
|
import EmptyPlaceholder from "components/app/EmptyPlaceholder.svelte"
|
||||||
import ScreenPlaceholder from "components/app/ScreenPlaceholder.svelte"
|
import ScreenPlaceholder from "components/app/ScreenPlaceholder.svelte"
|
||||||
import ComponentPlaceholder from "components/app/ComponentPlaceholder.svelte"
|
import ComponentErrorState from "components/error-states/ComponentErrorState.svelte"
|
||||||
|
import { BudibasePrefix } from "../stores/components.js"
|
||||||
|
|
||||||
export let instance = {}
|
export let instance = {}
|
||||||
export let isLayout = false
|
export let isLayout = false
|
||||||
export let isScreen = false
|
export let isScreen = false
|
||||||
export let isBlock = false
|
export let isBlock = false
|
||||||
export let parent = null
|
|
||||||
|
|
||||||
// Get parent contexts
|
// Get parent contexts
|
||||||
const context = getContext("context")
|
const context = getContext("context")
|
||||||
const insideScreenslot = !!getContext("screenslot")
|
const insideScreenslot = !!getContext("screenslot")
|
||||||
|
const component = getContext("component")
|
||||||
|
|
||||||
// Create component context
|
// Create component context
|
||||||
const store = writable({})
|
const store = writable({})
|
||||||
|
@ -120,6 +121,12 @@
|
||||||
$: showEmptyState = definition?.showEmptyState !== false
|
$: showEmptyState = definition?.showEmptyState !== false
|
||||||
$: hasMissingRequiredSettings = missingRequiredSettings?.length > 0
|
$: hasMissingRequiredSettings = missingRequiredSettings?.length > 0
|
||||||
$: editable = !!definition?.editable && !hasMissingRequiredSettings
|
$: editable = !!definition?.editable && !hasMissingRequiredSettings
|
||||||
|
$: requiredAncestors = definition?.requiredAncestors || []
|
||||||
|
$: missingRequiredAncestors = requiredAncestors.filter(
|
||||||
|
ancestor => !$component.ancestors.includes(`${BudibasePrefix}${ancestor}`)
|
||||||
|
)
|
||||||
|
$: hasMissingRequiredAncestors = missingRequiredAncestors?.length > 0
|
||||||
|
$: errorState = hasMissingRequiredSettings || hasMissingRequiredAncestors
|
||||||
|
|
||||||
// Interactive components can be selected, dragged and highlighted inside
|
// Interactive components can be selected, dragged and highlighted inside
|
||||||
// the builder preview
|
// the builder preview
|
||||||
|
@ -183,6 +190,7 @@
|
||||||
custom: customCSS,
|
custom: customCSS,
|
||||||
id,
|
id,
|
||||||
empty: emptyState,
|
empty: emptyState,
|
||||||
|
selected,
|
||||||
interactive,
|
interactive,
|
||||||
draggable,
|
draggable,
|
||||||
editable,
|
editable,
|
||||||
|
@ -193,7 +201,9 @@
|
||||||
name,
|
name,
|
||||||
editing,
|
editing,
|
||||||
type: instance._component,
|
type: instance._component,
|
||||||
missingRequiredSettings,
|
errorState,
|
||||||
|
parent: id,
|
||||||
|
ancestors: [...$component?.ancestors, instance._component],
|
||||||
})
|
})
|
||||||
|
|
||||||
const initialise = (instance, force = false) => {
|
const initialise = (instance, force = false) => {
|
||||||
|
@ -482,6 +492,7 @@
|
||||||
getDataContext: () => get(context),
|
getDataContext: () => get(context),
|
||||||
reload: () => initialise(instance, true),
|
reload: () => initialise(instance, true),
|
||||||
setEphemeralStyles: styles => (ephemeralStyles = styles),
|
setEphemeralStyles: styles => (ephemeralStyles = styles),
|
||||||
|
state: store,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -509,24 +520,28 @@
|
||||||
class:pad
|
class:pad
|
||||||
class:parent={hasChildren}
|
class:parent={hasChildren}
|
||||||
class:block={isBlock}
|
class:block={isBlock}
|
||||||
|
class:error={errorState}
|
||||||
data-id={id}
|
data-id={id}
|
||||||
data-name={name}
|
data-name={name}
|
||||||
data-icon={icon}
|
data-icon={icon}
|
||||||
data-parent={parent}
|
data-parent={$component.id}
|
||||||
>
|
>
|
||||||
{#if hasMissingRequiredSettings}
|
{#if errorState}
|
||||||
<ComponentPlaceholder />
|
<ComponentErrorState
|
||||||
|
{missingRequiredSettings}
|
||||||
|
{missingRequiredAncestors}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<svelte:component this={constructor} bind:this={ref} {...initialSettings}>
|
<svelte:component this={constructor} bind:this={ref} {...initialSettings}>
|
||||||
{#if children.length}
|
{#if children.length}
|
||||||
{#each children as child (child._id)}
|
{#each children as child (child._id)}
|
||||||
<svelte:self instance={child} parent={id} />
|
<svelte:self instance={child} />
|
||||||
{/each}
|
{/each}
|
||||||
{:else if emptyState}
|
{:else if emptyState}
|
||||||
{#if isScreen}
|
{#if isScreen}
|
||||||
<ScreenPlaceholder />
|
<ScreenPlaceholder />
|
||||||
{:else}
|
{:else}
|
||||||
<Placeholder />
|
<EmptyPlaceholder />
|
||||||
{/if}
|
{/if}
|
||||||
{:else if isBlock}
|
{:else if isBlock}
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
<script>
|
|
||||||
import { getContext } from "svelte"
|
|
||||||
import { builderStore } from "stores"
|
|
||||||
|
|
||||||
const component = getContext("component")
|
|
||||||
const { styleable } = getContext("sdk")
|
|
||||||
|
|
||||||
$: requiredSetting = $component.missingRequiredSettings?.[0]
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if $builderStore.inBuilder && requiredSetting}
|
|
||||||
<div class="component-placeholder" use:styleable={$component.styles}>
|
|
||||||
<span>
|
|
||||||
Add the <mark>{requiredSetting.label}</mark> setting to start using your component
|
|
||||||
-
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="spectrum-Link"
|
|
||||||
on:click={() => {
|
|
||||||
builderStore.actions.highlightSetting(requiredSetting.key)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Show me
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.component-placeholder {
|
|
||||||
color: var(--spectrum-global-color-gray-600);
|
|
||||||
font-size: var(--font-size-s);
|
|
||||||
padding: var(--spacing-xs);
|
|
||||||
}
|
|
||||||
.component-placeholder mark {
|
|
||||||
background-color: var(--spectrum-global-color-gray-400);
|
|
||||||
padding: 0 4px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
.component-placeholder .spectrum-Link {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
45
packages/client/src/components/app/EmptyPlaceholder.svelte
Normal file
45
packages/client/src/components/app/EmptyPlaceholder.svelte
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte"
|
||||||
|
import { Icon } from "@budibase/bbui"
|
||||||
|
|
||||||
|
const component = getContext("component")
|
||||||
|
const { builderStore, componentStore } = getContext("sdk")
|
||||||
|
|
||||||
|
$: definition = componentStore.actions.getComponentDefinition($component.type)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if $builderStore.inBuilder}
|
||||||
|
<div class="component-placeholder">
|
||||||
|
<Icon name="Help" color="var(--spectrum-global-color-blue-600)" />
|
||||||
|
<span
|
||||||
|
class="spectrum-Link"
|
||||||
|
on:click={() => {
|
||||||
|
builderStore.actions.requestAddComponent()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add components inside your {definition?.name || $component.type}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.component-placeholder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--spectrum-global-color-gray-600);
|
||||||
|
font-size: var(--font-size-s);
|
||||||
|
gap: var(--spacing-s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Common styles for all error states to use */
|
||||||
|
.component-placeholder :global(mark) {
|
||||||
|
background-color: var(--spectrum-global-color-gray-400);
|
||||||
|
padding: 0 4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.component-placeholder :global(.spectrum-Link) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
let width = window.innerWidth
|
let width = window.innerWidth
|
||||||
let height = window.innerHeight
|
let height = window.innerHeight
|
||||||
const tabletBreakpoint = 768
|
const tabletBreakpoint = 720
|
||||||
const desktopBreakpoint = 1280
|
const desktopBreakpoint = 1280
|
||||||
const resizeObserver = new ResizeObserver(entries => {
|
const resizeObserver = new ResizeObserver(entries => {
|
||||||
if (entries?.[0]) {
|
if (entries?.[0]) {
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte"
|
||||||
|
import { Icon } from "@budibase/bbui"
|
||||||
|
import MissingRequiredSetting from "./MissingRequiredSetting.svelte"
|
||||||
|
import MissingRequiredAncestor from "./MissingRequiredAncestor.svelte"
|
||||||
|
|
||||||
|
export let missingRequiredSettings
|
||||||
|
export let missingRequiredAncestors
|
||||||
|
|
||||||
|
const component = getContext("component")
|
||||||
|
const { styleable, builderStore } = getContext("sdk")
|
||||||
|
|
||||||
|
$: styles = { ...$component.styles, normal: {}, custom: null, empty: true }
|
||||||
|
$: requiredSetting = missingRequiredSettings?.[0]
|
||||||
|
$: requiredAncestor = missingRequiredAncestors?.[0]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if $builderStore.inBuilder}
|
||||||
|
{#if $component.errorState}
|
||||||
|
<div class="component-placeholder" use:styleable={styles}>
|
||||||
|
<Icon name="Alert" color="var(--spectrum-global-color-static-red-600)" />
|
||||||
|
{#if requiredAncestor}
|
||||||
|
<MissingRequiredAncestor {requiredAncestor} />
|
||||||
|
{:else if requiredSetting}
|
||||||
|
<MissingRequiredSetting {requiredSetting} />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.component-placeholder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--spectrum-global-color-gray-600);
|
||||||
|
font-size: var(--font-size-s);
|
||||||
|
padding: var(--spacing-xs);
|
||||||
|
gap: var(--spacing-s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Common styles for all error states to use */
|
||||||
|
.component-placeholder :global(mark) {
|
||||||
|
background-color: var(--spectrum-global-color-gray-400);
|
||||||
|
padding: 0 4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.component-placeholder :global(.spectrum-Link) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,41 @@
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte"
|
||||||
|
import { BudibasePrefix } from "stores/components"
|
||||||
|
|
||||||
|
export let requiredAncestor
|
||||||
|
|
||||||
|
const component = getContext("component")
|
||||||
|
const { builderStore, componentStore } = getContext("sdk")
|
||||||
|
|
||||||
|
$: definition = componentStore.actions.getComponentDefinition($component.type)
|
||||||
|
$: fullAncestorType = `${BudibasePrefix}${requiredAncestor}`
|
||||||
|
$: ancestorDefinition =
|
||||||
|
componentStore.actions.getComponentDefinition(fullAncestorType)
|
||||||
|
$: pluralName = getPluralName(definition?.name, $component.type)
|
||||||
|
$: ancestorName = getAncestorName(ancestorDefinition?.name, requiredAncestor)
|
||||||
|
|
||||||
|
const getPluralName = (name, type) => {
|
||||||
|
if (!name) {
|
||||||
|
name = type.replace(BudibasePrefix, "")
|
||||||
|
}
|
||||||
|
return name.endsWith("s") ? `${name}'` : `${name}s`
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAncestorName = name => {
|
||||||
|
return name || requiredAncestor
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
{pluralName} need to be inside a
|
||||||
|
<mark>{ancestorName}</mark>
|
||||||
|
</span>
|
||||||
|
<span>-</span>
|
||||||
|
<span
|
||||||
|
class="spectrum-Link"
|
||||||
|
on:click={() => {
|
||||||
|
builderStore.actions.addParentComponent($component.id, fullAncestorType)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add {ancestorName}
|
||||||
|
</span>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte"
|
||||||
|
|
||||||
|
export let requiredSetting
|
||||||
|
|
||||||
|
const { builderStore } = getContext("sdk")
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
Add the <mark>{requiredSetting.label}</mark> setting to start using your component
|
||||||
|
</span>
|
||||||
|
<span>-</span>
|
||||||
|
<span
|
||||||
|
class="spectrum-Link"
|
||||||
|
on:click={() => {
|
||||||
|
builderStore.actions.highlightSetting(requiredSetting.key)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Show me
|
||||||
|
</span>
|
|
@ -12,7 +12,8 @@
|
||||||
$: id = dragInfo?.id || id
|
$: id = dragInfo?.id || id
|
||||||
|
|
||||||
// Set ephemeral grid styles on the dragged component
|
// Set ephemeral grid styles on the dragged component
|
||||||
$: componentStore.actions.getComponentInstance(id)?.setEphemeralStyles({
|
$: instance = componentStore.actions.getComponentInstance(id)
|
||||||
|
$: $instance?.setEphemeralStyles({
|
||||||
...gridStyles,
|
...gridStyles,
|
||||||
...(gridStyles ? { "z-index": 999 } : null),
|
...(gridStyles ? { "z-index": 999 } : null),
|
||||||
})
|
})
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
let text
|
let text
|
||||||
let icon
|
let icon
|
||||||
let insideGrid = false
|
let insideGrid = false
|
||||||
|
let errorState = false
|
||||||
|
|
||||||
$: visibleIndicators = indicators.filter(x => x.visible)
|
$: visibleIndicators = indicators.filter(x => x.visible)
|
||||||
$: offset = $builderStore.inBuilder ? 0 : 2
|
$: offset = $builderStore.inBuilder ? 0 : 2
|
||||||
|
@ -85,6 +86,7 @@
|
||||||
icon = parents[0].dataset.icon
|
icon = parents[0].dataset.icon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
errorState = parents?.[0]?.classList.contains("error")
|
||||||
|
|
||||||
// Batch reads to minimize reflow
|
// Batch reads to minimize reflow
|
||||||
const scrollX = window.scrollX
|
const scrollX = window.scrollX
|
||||||
|
@ -152,10 +154,10 @@
|
||||||
text={idx === 0 ? text : null}
|
text={idx === 0 ? text : null}
|
||||||
icon={idx === 0 ? icon : null}
|
icon={idx === 0 ? icon : null}
|
||||||
showResizeAnchors={allowResizeAnchors && insideGrid}
|
showResizeAnchors={allowResizeAnchors && insideGrid}
|
||||||
|
color={errorState ? "var(--spectrum-global-color-static-red-600)" : color}
|
||||||
{componentId}
|
{componentId}
|
||||||
{transition}
|
{transition}
|
||||||
{zIndex}
|
{zIndex}
|
||||||
{color}
|
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
{/key}
|
{/key}
|
||||||
|
|
|
@ -15,17 +15,22 @@
|
||||||
let self
|
let self
|
||||||
let measured = false
|
let measured = false
|
||||||
|
|
||||||
|
$: id = $builderStore.selectedComponentId
|
||||||
|
$: instance = componentStore.actions.getComponentInstance(id)
|
||||||
|
$: state = $instance?.state
|
||||||
$: definition = $componentStore.selectedComponentDefinition
|
$: definition = $componentStore.selectedComponentDefinition
|
||||||
$: showBar =
|
$: showBar =
|
||||||
definition?.showSettingsBar !== false && !$dndIsDragging && definition
|
definition?.showSettingsBar !== false &&
|
||||||
|
!$dndIsDragging &&
|
||||||
|
definition &&
|
||||||
|
!$state?.errorState
|
||||||
$: {
|
$: {
|
||||||
if (!showBar) {
|
if (!showBar) {
|
||||||
measured = false
|
measured = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$: settings = getBarSettings(definition)
|
$: settings = getBarSettings(definition)
|
||||||
$: isScreen =
|
$: isScreen = id === $builderStore.screen?.props?._id
|
||||||
$builderStore.selectedComponentId === $builderStore.screen?.props?._id
|
|
||||||
|
|
||||||
const getBarSettings = definition => {
|
const getBarSettings = definition => {
|
||||||
let allSettings = []
|
let allSettings = []
|
||||||
|
|
|
@ -109,6 +109,12 @@ const createBuilderStore = () => {
|
||||||
// Notify the builder so we can reload component definitions
|
// Notify the builder so we can reload component definitions
|
||||||
eventStore.actions.dispatchEvent("reload-plugin")
|
eventStore.actions.dispatchEvent("reload-plugin")
|
||||||
},
|
},
|
||||||
|
addParentComponent: (componentId, parentType) => {
|
||||||
|
eventStore.actions.dispatchEvent("add-parent-component", {
|
||||||
|
componentId,
|
||||||
|
parentType,
|
||||||
|
})
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...store,
|
...store,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import Router from "../components/Router.svelte"
|
||||||
import * as AppComponents from "../components/app/index.js"
|
import * as AppComponents from "../components/app/index.js"
|
||||||
import { ScreenslotType } from "../constants.js"
|
import { ScreenslotType } from "../constants.js"
|
||||||
|
|
||||||
const budibasePrefix = "@budibase/standard-components/"
|
export const BudibasePrefix = "@budibase/standard-components/"
|
||||||
|
|
||||||
const createComponentStore = () => {
|
const createComponentStore = () => {
|
||||||
const store = writable({
|
const store = writable({
|
||||||
|
@ -107,12 +107,12 @@ const createComponentStore = () => {
|
||||||
|
|
||||||
// Screenslot is an edge case
|
// Screenslot is an edge case
|
||||||
if (type === ScreenslotType) {
|
if (type === ScreenslotType) {
|
||||||
type = `${budibasePrefix}${type}`
|
type = `${BudibasePrefix}${type}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle built-in components
|
// Handle built-in components
|
||||||
if (type.startsWith(budibasePrefix)) {
|
if (type.startsWith(BudibasePrefix)) {
|
||||||
type = type.replace(budibasePrefix, "")
|
type = type.replace(BudibasePrefix, "")
|
||||||
return type ? Manifest[type] : null
|
return type ? Manifest[type] : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ const createComponentStore = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle budibase components
|
// Handle budibase components
|
||||||
if (type.startsWith(budibasePrefix)) {
|
if (type.startsWith(BudibasePrefix)) {
|
||||||
const split = type.split("/")
|
const split = type.split("/")
|
||||||
const name = split[split.length - 1]
|
const name = split[split.length - 1]
|
||||||
return AppComponents[name]
|
return AppComponents[name]
|
||||||
|
@ -145,7 +145,7 @@ const createComponentStore = () => {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return get(store).mountedComponents[id]
|
return derived(store, $store => $store.mountedComponents[id])
|
||||||
}
|
}
|
||||||
|
|
||||||
const registerCustomComponent = ({ Component, schema, version }) => {
|
const registerCustomComponent = ({ Component, schema, version }) => {
|
||||||
|
|
|
@ -29,9 +29,13 @@ export const styleable = (node, styles = {}) => {
|
||||||
|
|
||||||
let baseStyles = {}
|
let baseStyles = {}
|
||||||
if (newStyles.empty) {
|
if (newStyles.empty) {
|
||||||
baseStyles.border = "2px dashed var(--spectrum-global-color-gray-400)"
|
|
||||||
baseStyles.padding = "var(--spacing-l)"
|
baseStyles.padding = "var(--spacing-l)"
|
||||||
baseStyles.overflow = "hidden"
|
baseStyles.overflow = "hidden"
|
||||||
|
if (newStyles.selected) {
|
||||||
|
baseStyles.border = "2px solid transparent"
|
||||||
|
} else {
|
||||||
|
baseStyles.border = "2px dashed var(--spectrum-global-color-gray-400)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const componentId = newStyles.id
|
const componentId = newStyles.id
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/frontend-core",
|
"name": "@budibase/frontend-core",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"description": "Budibase frontend core libraries used in builder and client",
|
"description": "Budibase frontend core libraries used in builder and client",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "2.4.27-alpha.9",
|
"@budibase/bbui": "2.4.27-alpha.12",
|
||||||
"@budibase/shared-core": "2.4.27-alpha.9",
|
"@budibase/shared-core": "2.4.27-alpha.12",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"socket.io-client": "^4.6.1",
|
"socket.io-client": "^4.6.1",
|
||||||
|
|
|
@ -78,6 +78,8 @@
|
||||||
reorder.actions.moveColumnRight(column.name)
|
reorder.actions.moveColumnRight(column.name)
|
||||||
open = false
|
open = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const makeDisplayColumn = () => {}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -148,6 +150,9 @@
|
||||||
<MenuItem disabled={!canMoveRight} icon="ArrowRight" on:click={moveRight}>
|
<MenuItem disabled={!canMoveRight} icon="ArrowRight" on:click={moveRight}>
|
||||||
Move right
|
Move right
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem icon="Label" on:click={makeDisplayColumn}
|
||||||
|
>Use as display column</MenuItem
|
||||||
|
>
|
||||||
</Menu>
|
</Menu>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/sdk",
|
"name": "@budibase/sdk",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"description": "Budibase Public API SDK",
|
"description": "Budibase Public API SDK",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/server",
|
"name": "@budibase/server",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"description": "Budibase Web Server",
|
"description": "Budibase Web Server",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -44,12 +44,12 @@
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apidevtools/swagger-parser": "10.0.3",
|
"@apidevtools/swagger-parser": "10.0.3",
|
||||||
"@budibase/backend-core": "2.4.27-alpha.9",
|
"@budibase/backend-core": "2.4.27-alpha.12",
|
||||||
"@budibase/client": "2.4.27-alpha.9",
|
"@budibase/client": "2.4.27-alpha.12",
|
||||||
"@budibase/pro": "2.4.27-alpha.9",
|
"@budibase/pro": "2.4.27-alpha.12",
|
||||||
"@budibase/shared-core": "2.4.27-alpha.9",
|
"@budibase/shared-core": "2.4.27-alpha.12",
|
||||||
"@budibase/string-templates": "2.4.27-alpha.9",
|
"@budibase/string-templates": "2.4.27-alpha.12",
|
||||||
"@budibase/types": "2.4.27-alpha.9",
|
"@budibase/types": "2.4.27-alpha.12",
|
||||||
"@bull-board/api": "3.7.0",
|
"@bull-board/api": "3.7.0",
|
||||||
"@bull-board/koa": "3.9.4",
|
"@bull-board/koa": "3.9.4",
|
||||||
"@elastic/elasticsearch": "7.10.0",
|
"@elastic/elasticsearch": "7.10.0",
|
||||||
|
|
|
@ -1290,14 +1290,14 @@
|
||||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||||
|
|
||||||
"@budibase/backend-core@2.4.27-alpha.9":
|
"@budibase/backend-core@2.4.27-alpha.12":
|
||||||
version "2.4.27-alpha.9"
|
version "2.4.27-alpha.12"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.27-alpha.9.tgz#76dee792f6928f4a133b25f4842048cdb5e40cc9"
|
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.27-alpha.12.tgz#655367eaa16a8bf1a28ff38eb0ab2127decb5b23"
|
||||||
integrity sha512-dAMqy8I+bmClDEyYgB/Frsq9VQvTiWXzSrKdCfzoAGPFIWQSLaXBzhvj32YI/q7j1oo5MHtECuPKERXd/umh3w==
|
integrity sha512-qCszwPDuYvMYZLl54T82ZrpM5xHD6nTEzPAkPQFrZIDtkW1dfKd2z+E2OirIOYb1CRN4GwrnIDjR0+u231Qo5w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/nano" "10.1.2"
|
"@budibase/nano" "10.1.2"
|
||||||
"@budibase/pouchdb-replication-stream" "1.2.10"
|
"@budibase/pouchdb-replication-stream" "1.2.10"
|
||||||
"@budibase/types" "2.4.27-alpha.9"
|
"@budibase/types" "2.4.27-alpha.12"
|
||||||
"@shopify/jest-koa-mocks" "5.0.1"
|
"@shopify/jest-koa-mocks" "5.0.1"
|
||||||
"@techpass/passport-openidconnect" "0.3.2"
|
"@techpass/passport-openidconnect" "0.3.2"
|
||||||
aws-cloudfront-sign "2.2.0"
|
aws-cloudfront-sign "2.2.0"
|
||||||
|
@ -1429,14 +1429,14 @@
|
||||||
pouchdb-promise "^6.0.4"
|
pouchdb-promise "^6.0.4"
|
||||||
through2 "^2.0.0"
|
through2 "^2.0.0"
|
||||||
|
|
||||||
"@budibase/pro@2.4.27-alpha.9":
|
"@budibase/pro@2.4.27-alpha.12":
|
||||||
version "2.4.27-alpha.9"
|
version "2.4.27-alpha.12"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.27-alpha.9.tgz#68e74c0541abda731ab2785bd9e33e21b78f6328"
|
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.27-alpha.12.tgz#c3f74e4ef04ea1355bdc1333dd033f4a47087ac2"
|
||||||
integrity sha512-BUFpjAcySWdhxosNtTQa6nOYbVKvX0ifrVCwXlveBE4+YXYK+e8vsVn56oMtkffYfhrhHx1D/u5NSNPKCJLHZw==
|
integrity sha512-Hl/zalqmtlINgylFqQz3zWG/4dTXm/Skck2Q/j69gyqy0DotWXfRko03CbDQCyHGWhM/oXXiYJK54HIkn+kOTw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/backend-core" "2.4.27-alpha.9"
|
"@budibase/backend-core" "2.4.27-alpha.12"
|
||||||
"@budibase/string-templates" "2.3.20"
|
"@budibase/string-templates" "2.3.20"
|
||||||
"@budibase/types" "2.4.27-alpha.9"
|
"@budibase/types" "2.4.27-alpha.12"
|
||||||
"@koa/router" "8.0.8"
|
"@koa/router" "8.0.8"
|
||||||
bull "4.10.1"
|
bull "4.10.1"
|
||||||
joi "17.6.0"
|
joi "17.6.0"
|
||||||
|
@ -1475,10 +1475,10 @@
|
||||||
lodash "^4.17.20"
|
lodash "^4.17.20"
|
||||||
vm2 "^3.9.4"
|
vm2 "^3.9.4"
|
||||||
|
|
||||||
"@budibase/types@2.4.27-alpha.9":
|
"@budibase/types@2.4.27-alpha.12":
|
||||||
version "2.4.27-alpha.9"
|
version "2.4.27-alpha.12"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.27-alpha.9.tgz#fabf342ea50986532b395d01bfa2c55dcbe790f8"
|
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.27-alpha.12.tgz#4c0dd66434f52c41080c17b810262ff8f195cb6c"
|
||||||
integrity sha512-geugj3sHPHEoA+p9j9vNWeyINNxp0Pv0iCxEUrQKzFcj8nypchJZFOxEByzxCsy2SU2w/TPzWKJZzouanWcoiA==
|
integrity sha512-mpzlQM49WWQyWnysFcMkJDD3jY6Wf5HG7R8/eb5PRbSWx92+17g0iCbhuaswfCJdz0GIi73hebmvaFeuQ/glMg==
|
||||||
|
|
||||||
"@bull-board/api@3.7.0":
|
"@bull-board/api@3.7.0":
|
||||||
version "3.7.0"
|
version "3.7.0"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/shared-core",
|
"name": "@budibase/shared-core",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"description": "Shared data utils",
|
"description": "Shared data utils",
|
||||||
"main": "dist/cjs/src/index.js",
|
"main": "dist/cjs/src/index.js",
|
||||||
"types": "dist/mjs/src/index.d.ts",
|
"types": "dist/mjs/src/index.d.ts",
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
"dev:builder": "yarn prebuild && concurrently \"tsc -p tsconfig.build.json --watch\" \"tsc -p tsconfig-cjs.build.json --watch\""
|
"dev:builder": "yarn prebuild && concurrently \"tsc -p tsconfig.build.json --watch\" \"tsc -p tsconfig-cjs.build.json --watch\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/types": "2.4.27-alpha.9"
|
"@budibase/types": "2.4.27-alpha.12"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"concurrently": "^7.6.0",
|
"concurrently": "^7.6.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/string-templates",
|
"name": "@budibase/string-templates",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"description": "Handlebars wrapper for Budibase templating.",
|
"description": "Handlebars wrapper for Budibase templating.",
|
||||||
"main": "src/index.cjs",
|
"main": "src/index.cjs",
|
||||||
"module": "dist/bundle.mjs",
|
"module": "dist/bundle.mjs",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/types",
|
"name": "@budibase/types",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"description": "Budibase types",
|
"description": "Budibase types",
|
||||||
"main": "dist/cjs/index.js",
|
"main": "dist/cjs/index.js",
|
||||||
"types": "dist/mjs/index.d.ts",
|
"types": "dist/mjs/index.d.ts",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/worker",
|
"name": "@budibase/worker",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "2.4.27-alpha.9",
|
"version": "2.4.27-alpha.12",
|
||||||
"description": "Budibase background service",
|
"description": "Budibase background service",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -36,10 +36,10 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/backend-core": "2.4.27-alpha.9",
|
"@budibase/backend-core": "2.4.27-alpha.12",
|
||||||
"@budibase/pro": "2.4.27-alpha.9",
|
"@budibase/pro": "2.4.27-alpha.12",
|
||||||
"@budibase/string-templates": "2.4.27-alpha.9",
|
"@budibase/string-templates": "2.4.27-alpha.12",
|
||||||
"@budibase/types": "2.4.27-alpha.9",
|
"@budibase/types": "2.4.27-alpha.12",
|
||||||
"@koa/router": "8.0.8",
|
"@koa/router": "8.0.8",
|
||||||
"@sentry/node": "6.17.7",
|
"@sentry/node": "6.17.7",
|
||||||
"@techpass/passport-openidconnect": "0.3.2",
|
"@techpass/passport-openidconnect": "0.3.2",
|
||||||
|
|
|
@ -475,14 +475,14 @@
|
||||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||||
|
|
||||||
"@budibase/backend-core@2.4.27-alpha.9":
|
"@budibase/backend-core@2.4.27-alpha.12":
|
||||||
version "2.4.27-alpha.9"
|
version "2.4.27-alpha.12"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.27-alpha.9.tgz#76dee792f6928f4a133b25f4842048cdb5e40cc9"
|
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.27-alpha.12.tgz#655367eaa16a8bf1a28ff38eb0ab2127decb5b23"
|
||||||
integrity sha512-dAMqy8I+bmClDEyYgB/Frsq9VQvTiWXzSrKdCfzoAGPFIWQSLaXBzhvj32YI/q7j1oo5MHtECuPKERXd/umh3w==
|
integrity sha512-qCszwPDuYvMYZLl54T82ZrpM5xHD6nTEzPAkPQFrZIDtkW1dfKd2z+E2OirIOYb1CRN4GwrnIDjR0+u231Qo5w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/nano" "10.1.2"
|
"@budibase/nano" "10.1.2"
|
||||||
"@budibase/pouchdb-replication-stream" "1.2.10"
|
"@budibase/pouchdb-replication-stream" "1.2.10"
|
||||||
"@budibase/types" "2.4.27-alpha.9"
|
"@budibase/types" "2.4.27-alpha.12"
|
||||||
"@shopify/jest-koa-mocks" "5.0.1"
|
"@shopify/jest-koa-mocks" "5.0.1"
|
||||||
"@techpass/passport-openidconnect" "0.3.2"
|
"@techpass/passport-openidconnect" "0.3.2"
|
||||||
aws-cloudfront-sign "2.2.0"
|
aws-cloudfront-sign "2.2.0"
|
||||||
|
@ -564,14 +564,14 @@
|
||||||
pouchdb-promise "^6.0.4"
|
pouchdb-promise "^6.0.4"
|
||||||
through2 "^2.0.0"
|
through2 "^2.0.0"
|
||||||
|
|
||||||
"@budibase/pro@2.4.27-alpha.9":
|
"@budibase/pro@2.4.27-alpha.12":
|
||||||
version "2.4.27-alpha.9"
|
version "2.4.27-alpha.12"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.27-alpha.9.tgz#68e74c0541abda731ab2785bd9e33e21b78f6328"
|
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.27-alpha.12.tgz#c3f74e4ef04ea1355bdc1333dd033f4a47087ac2"
|
||||||
integrity sha512-BUFpjAcySWdhxosNtTQa6nOYbVKvX0ifrVCwXlveBE4+YXYK+e8vsVn56oMtkffYfhrhHx1D/u5NSNPKCJLHZw==
|
integrity sha512-Hl/zalqmtlINgylFqQz3zWG/4dTXm/Skck2Q/j69gyqy0DotWXfRko03CbDQCyHGWhM/oXXiYJK54HIkn+kOTw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/backend-core" "2.4.27-alpha.9"
|
"@budibase/backend-core" "2.4.27-alpha.12"
|
||||||
"@budibase/string-templates" "2.3.20"
|
"@budibase/string-templates" "2.3.20"
|
||||||
"@budibase/types" "2.4.27-alpha.9"
|
"@budibase/types" "2.4.27-alpha.12"
|
||||||
"@koa/router" "8.0.8"
|
"@koa/router" "8.0.8"
|
||||||
bull "4.10.1"
|
bull "4.10.1"
|
||||||
joi "17.6.0"
|
joi "17.6.0"
|
||||||
|
@ -592,10 +592,10 @@
|
||||||
lodash "^4.17.20"
|
lodash "^4.17.20"
|
||||||
vm2 "^3.9.4"
|
vm2 "^3.9.4"
|
||||||
|
|
||||||
"@budibase/types@2.4.27-alpha.9":
|
"@budibase/types@2.4.27-alpha.12":
|
||||||
version "2.4.27-alpha.9"
|
version "2.4.27-alpha.12"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.27-alpha.9.tgz#fabf342ea50986532b395d01bfa2c55dcbe790f8"
|
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.27-alpha.12.tgz#4c0dd66434f52c41080c17b810262ff8f195cb6c"
|
||||||
integrity sha512-geugj3sHPHEoA+p9j9vNWeyINNxp0Pv0iCxEUrQKzFcj8nypchJZFOxEByzxCsy2SU2w/TPzWKJZzouanWcoiA==
|
integrity sha512-mpzlQM49WWQyWnysFcMkJDD3jY6Wf5HG7R8/eb5PRbSWx92+17g0iCbhuaswfCJdz0GIi73hebmvaFeuQ/glMg==
|
||||||
|
|
||||||
"@cspotcode/source-map-support@^0.8.0":
|
"@cspotcode/source-map-support@^0.8.0":
|
||||||
version "0.8.1"
|
version "0.8.1"
|
||||||
|
|
Loading…
Reference in a new issue