Merge branch 'develop' of github.com:Budibase/budibase into feature/automation-rework

This commit is contained in:
mike12345567 2021-09-09 16:33:41 +01:00
commit 01ca02ea9c
159 changed files with 2103 additions and 1113 deletions

View File

@ -5,7 +5,6 @@ Each Budibase package has its own license:
builder: GPLv3 builder: GPLv3
server: GPLv3 server: GPLv3
client: MPLv2.0 client: MPLv2.0
standard-components: MPLv2.0
You can consider Budibase to be GPLv3 licensed. You can consider Budibase to be GPLv3 licensed.

View File

@ -1,5 +1,5 @@
{ {
"version": "0.9.122", "version": "0.9.123-alpha.3",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/*" "packages/*"

View File

@ -20,7 +20,6 @@
"setup": "node ./hosting/scripts/setup.js && yarn && yarn bootstrap && yarn build && yarn dev", "setup": "node ./hosting/scripts/setup.js && yarn && yarn bootstrap && yarn build && yarn dev",
"bootstrap": "lerna link && lerna bootstrap", "bootstrap": "lerna link && lerna bootstrap",
"build": "lerna run build", "build": "lerna run build",
"initialise": "lerna run initialise",
"publishdev": "lerna run publishdev", "publishdev": "lerna run publishdev",
"publishnpm": "yarn build && lerna publish --force-publish", "publishnpm": "yarn build && lerna publish --force-publish",
"release": "yarn build && lerna publish patch --yes --force-publish", "release": "yarn build && lerna publish patch --yes --force-publish",

View File

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

View File

@ -70,6 +70,23 @@ function isDevApp(app) {
return exports.isDevAppID(app.appId) return exports.isDevAppID(app.appId)
} }
/**
* Given an app ID this will attempt to retrieve the tenant ID from it.
* @return {null|string} The tenant ID found within the app ID.
*/
exports.getTenantIDFromAppID = appId => {
const split = appId.split(SEPARATOR)
const hasDev = split[1] === DocumentTypes.DEV
if ((hasDev && split.length === 3) || (!hasDev && split.length === 2)) {
return null
}
if (hasDev) {
return split[2]
} else {
return split[1]
}
}
/** /**
* Generates a new workspace ID. * Generates a new workspace ID.
* @returns {string} The new workspace ID which the workspace doc can be stored under. * @returns {string} The new workspace ID which the workspace doc can be stored under.

View File

@ -11,6 +11,7 @@ const {
oidc, oidc,
auditLog, auditLog,
tenancy, tenancy,
appTenancy,
} = require("./middleware") } = require("./middleware")
const { setDB } = require("./db") const { setDB } = require("./db")
const userCache = require("./cache/user") const userCache = require("./cache/user")
@ -57,6 +58,7 @@ module.exports = {
oidc, oidc,
jwt: require("jsonwebtoken"), jwt: require("jsonwebtoken"),
buildTenancyMiddleware: tenancy, buildTenancyMiddleware: tenancy,
buildAppTenancyMiddleware: appTenancy,
auditLog, auditLog,
}, },
cache: { cache: {

View File

@ -0,0 +1,25 @@
const {
isMultiTenant,
updateTenantId,
isTenantIdSet,
DEFAULT_TENANT_ID,
} = require("../tenancy")
const ContextFactory = require("../tenancy/FunctionContext")
const { getTenantIDFromAppID } = require("../db/utils")
module.exports = () => {
return ContextFactory.getMiddleware(ctx => {
// if not in multi-tenancy mode make sure its default and exit
if (!isMultiTenant()) {
updateTenantId(DEFAULT_TENANT_ID)
return
}
// if tenant ID already set no need to continue
if (isTenantIdSet()) {
return
}
const appId = ctx.appId ? ctx.appId : ctx.user ? ctx.user.appId : null
const tenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID
updateTenantId(tenantId)
})
}

View File

@ -5,6 +5,7 @@ const oidc = require("./passport/oidc")
const authenticated = require("./authenticated") const authenticated = require("./authenticated")
const auditLog = require("./auditLog") const auditLog = require("./auditLog")
const tenancy = require("./tenancy") const tenancy = require("./tenancy")
const appTenancy = require("./appTenancy")
module.exports = { module.exports = {
google, google,
@ -14,4 +15,5 @@ module.exports = {
authenticated, authenticated,
auditLog, auditLog,
tenancy, tenancy,
appTenancy,
} }

View File

@ -2,7 +2,11 @@ const { setTenantId } = require("../tenancy")
const ContextFactory = require("../tenancy/FunctionContext") const ContextFactory = require("../tenancy/FunctionContext")
const { buildMatcherRegex, matches } = require("./matchers") const { buildMatcherRegex, matches } = require("./matchers")
module.exports = (allowQueryStringPatterns, noTenancyPatterns, opts = {}) => { module.exports = (
allowQueryStringPatterns,
noTenancyPatterns,
opts = { noTenancyRequired: false }
) => {
const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns) const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns)
const noTenancyOptions = buildMatcherRegex(noTenancyPatterns) const noTenancyOptions = buildMatcherRegex(noTenancyPatterns)

View File

@ -21,9 +21,7 @@ exports.doInTenant = (tenantId, task) => {
cls.setOnContext(TENANT_ID, tenantId) cls.setOnContext(TENANT_ID, tenantId)
// invoke the task // invoke the task
const result = task() return task()
return result
}) })
} }

View File

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

View File

@ -13,6 +13,7 @@
export let enableTime = true export let enableTime = true
export let value = null export let value = null
export let placeholder = null export let placeholder = null
export let appendTo = null
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const flatpickrId = `${generateID()}-wrapper` const flatpickrId = `${generateID()}-wrapper`
@ -24,6 +25,7 @@
altInput: true, altInput: true,
altFormat: enableTime ? "F j Y, H:i" : "F j, Y", altFormat: enableTime ? "F j Y, H:i" : "F j, Y",
wrap: true, wrap: true,
appendTo,
} }
const handleChange = event => { const handleChange = event => {

View File

@ -10,6 +10,7 @@
export let error = null export let error = null
export let enableTime = true export let enableTime = true
export let placeholder = null export let placeholder = null
export let appendTo = null
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = e => {
@ -26,6 +27,7 @@
{value} {value}
{placeholder} {placeholder}
{enableTime} {enableTime}
{appendTo}
on:change={onChange} on:change={onChange}
/> />
</Field> </Field>

View File

@ -36,7 +36,7 @@
transition: color var(--spectrum-global-animation-duration-100, 130ms); transition: color var(--spectrum-global-animation-duration-100, 130ms);
} }
svg.hoverable:hover { svg.hoverable:hover {
color: var(--spectrum-alias-icon-color-selected); color: var(--spectrum-alias-icon-color-selected-hover);
cursor: pointer; cursor: pointer;
} }

View File

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

View File

@ -266,12 +266,16 @@ const getDeviceBindings = () => {
* Gets all state bindings that are globally available. * Gets all state bindings that are globally available.
*/ */
const getStateBindings = () => { const getStateBindings = () => {
let bindings = []
if (get(store).clientFeatures?.state) {
const safeState = makePropSafe("state") const safeState = makePropSafe("state")
return getAllStateVariables().map(key => ({ bindings = getAllStateVariables().map(key => ({
type: "context", type: "context",
runtimeBinding: `${safeState}.${makePropSafe(key)}`, runtimeBinding: `${safeState}.${makePropSafe(key)}`,
readableBinding: `State.${key}`, readableBinding: `State.${key}`,
})) }))
}
return bindings
} }
/** /**

View File

@ -41,6 +41,8 @@ const INITIAL_FRONTEND_STATE = {
spectrumThemes: false, spectrumThemes: false,
intelligentLoading: false, intelligentLoading: false,
deviceAwareness: false, deviceAwareness: false,
state: false,
customThemes: false,
}, },
currentFrontEndType: "none", currentFrontEndType: "none",
selectedScreenId: "", selectedScreenId: "",
@ -53,6 +55,7 @@ const INITIAL_FRONTEND_STATE = {
routes: {}, routes: {},
clientLibPath: "", clientLibPath: "",
theme: "", theme: "",
customTheme: {},
} }
export const getFrontendStore = () => { export const getFrontendStore = () => {
@ -77,6 +80,7 @@ export const getFrontendStore = () => {
layouts, layouts,
screens, screens,
theme: application.theme || "spectrum--light", theme: application.theme || "spectrum--light",
customTheme: application.customTheme,
hasAppPackage: true, hasAppPackage: true,
appInstance: application.instance, appInstance: application.instance,
clientLibPath, clientLibPath,
@ -110,6 +114,22 @@ export const getFrontendStore = () => {
} }
}, },
}, },
customTheme: {
save: async customTheme => {
const appId = get(store).appId
const response = await api.put(`/api/applications/${appId}`, {
customTheme,
})
if (response.status === 200) {
store.update(state => {
state.customTheme = customTheme
return state
})
} else {
throw new Error("Error updating theme")
}
},
},
routing: { routing: {
fetch: async () => { fetch: async () => {
const response = await api.get("/api/routing") const response = await api.get("/api/routing")

View File

@ -7,13 +7,7 @@
ProgressCircle, ProgressCircle,
} from "@budibase/bbui" } from "@budibase/bbui"
import { admin } from "stores/portal" import { admin } from "stores/portal"
import { goto } from "@roxi/routify"
const MESSAGES = {
apps: "Create your first app",
smtp: "Set up email",
adminUser: "Create your first user",
sso: "Set up single sign-on",
}
</script> </script>
<ActionMenu> <ActionMenu>
@ -28,9 +22,12 @@
</MenuItem> </MenuItem>
{#each Object.keys($admin.checklist) as checklistItem, idx} {#each Object.keys($admin.checklist) as checklistItem, idx}
<MenuItem> <MenuItem>
<div class="item"> <div
<span>{idx + 1}. {MESSAGES[checklistItem]}</span> class="item"
<Checkbox value={!!$admin.checklist[checklistItem]} /> on:click={() => $goto($admin.checklist[checklistItem].link)}
>
<span>{idx + 1}. {$admin.checklist[checklistItem].label}</span>
<Checkbox value={$admin.checklist[checklistItem].checked} />
</div> </div>
</MenuItem> </MenuItem>
{/each} {/each}

View File

@ -33,6 +33,6 @@
<style> <style>
div { div {
padding-right: 8px; width: 100px;
} }
</style> </style>

View File

@ -49,6 +49,7 @@
selectedComponentId, selectedComponentId,
previewType: $store.currentFrontEndType, previewType: $store.currentFrontEndType,
theme: $store.theme, theme: $store.theme,
customTheme: $store.customTheme,
} }
// Saving pages and screens to the DB causes them to have _revs. // Saving pages and screens to the DB causes them to have _revs.

View File

@ -0,0 +1,140 @@
<script>
import { get } from "svelte/store"
import {
ActionButton,
Modal,
ModalContent,
Layout,
ColorPicker,
Label,
Select,
Button,
} from "@budibase/bbui"
import { store } from "builderStore"
import AppThemeSelect from "./AppThemeSelect.svelte"
let modal
const defaultTheme = {
primaryColor: "var(--spectrum-global-color-blue-600)",
primaryColorHover: "var(--spectrum-global-color-blue-500)",
buttonBorderRadius: "16px",
navBackground: "var(--spectrum-global-color-gray-100)",
navTextColor: "var(--spectrum-global-color-gray-800)",
}
const buttonBorderRadiusOptions = [
{
label: "None",
value: "0",
},
{
label: "Small",
value: "4px",
},
{
label: "Medium",
value: "8px",
},
{
label: "Large",
value: "16px",
},
]
const updateProperty = property => {
return e => {
store.actions.customTheme.save({
...get(store).customTheme,
[property]: e.detail,
})
}
}
const resetTheme = () => {
store.actions.customTheme.save(null)
}
</script>
<div class="container">
<ActionButton icon="Brush" on:click={modal.show}>Theme</ActionButton>
</div>
<Modal bind:this={modal}>
<ModalContent
showConfirmButton={false}
cancelText="Close"
showCloseIcon={false}
title="Theme settings"
>
<Layout noPadding gap="S">
<div class="setting">
<Label size="L">Theme</Label>
<AppThemeSelect />
</div>
<div class="setting">
<Label size="L">Button roundness</Label>
<div class="select-wrapper">
<Select
placeholder={null}
value={$store.customTheme?.buttonBorderRadius ||
defaultTheme.buttonBorderRadius}
on:change={updateProperty("buttonBorderRadius")}
options={buttonBorderRadiusOptions}
/>
</div>
</div>
<div class="setting">
<Label size="L">Primary color</Label>
<ColorPicker
spectrumTheme={$store.theme}
value={$store.customTheme?.primaryColor || defaultTheme.primaryColor}
on:change={updateProperty("primaryColor")}
/>
</div>
<div class="setting">
<Label size="L">Primary color (hover)</Label>
<ColorPicker
spectrumTheme={$store.theme}
value={$store.customTheme?.primaryColorHover ||
defaultTheme.primaryColorHover}
on:change={updateProperty("primaryColorHover")}
/>
</div>
<div class="setting">
<Label size="L">Navigation bar background color</Label>
<ColorPicker
spectrumTheme={$store.theme}
value={$store.customTheme?.navBackground ||
defaultTheme.navBackground}
on:change={updateProperty("navBackground")}
/>
</div>
<div class="setting">
<Label size="L">Navigation bar text color</Label>
<ColorPicker
spectrumTheme={$store.theme}
value={$store.customTheme?.navTextColor || defaultTheme.navTextColor}
on:change={updateProperty("navTextColor")}
/>
</div>
</Layout>
<div slot="footer">
<Button secondary quiet on:click={resetTheme}>Reset</Button>
</div>
</ModalContent>
</Modal>
<style>
.container {
padding-right: 8px;
}
.setting {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.select-wrapper {
width: 100px;
}
</style>

View File

@ -66,7 +66,8 @@ export default `
screen, screen,
previewType, previewType,
appId, appId,
theme theme,
customTheme
} = parsed } = parsed
// Set some flags so the app knows we're in the builder // Set some flags so the app knows we're in the builder
@ -78,6 +79,7 @@ export default `
window["##BUDIBASE_PREVIEW_ID##"] = Math.random() window["##BUDIBASE_PREVIEW_ID##"] = Math.random()
window["##BUDIBASE_PREVIEW_TYPE##"] = previewType window["##BUDIBASE_PREVIEW_TYPE##"] = previewType
window["##BUDIBASE_PREVIEW_THEME##"] = theme window["##BUDIBASE_PREVIEW_THEME##"] = theme
window["##BUDIBASE_PREVIEW_CUSTOM_THEME##"] = customTheme
// Initialise app // Initialise app
try { try {

View File

@ -9,11 +9,12 @@
ActionMenu, ActionMenu,
MenuItem, MenuItem,
} from "@budibase/bbui" } from "@budibase/bbui"
import actionTypes from "./actions" import { getAvailableActions } from "./actions"
import { generate } from "shortid" import { generate } from "shortid"
const flipDurationMs = 150 const flipDurationMs = 150
const EVENT_TYPE_KEY = "##eventHandlerType" const EVENT_TYPE_KEY = "##eventHandlerType"
const actionTypes = getAvailableActions()
export let actions export let actions
export let bindings = [] export let bindings = []

View File

@ -1,3 +1,6 @@
import { store } from "builderStore"
import { get } from "svelte/store"
import NavigateTo from "./NavigateTo.svelte" import NavigateTo from "./NavigateTo.svelte"
import SaveRow from "./SaveRow.svelte" import SaveRow from "./SaveRow.svelte"
import DeleteRow from "./DeleteRow.svelte" import DeleteRow from "./DeleteRow.svelte"
@ -17,7 +20,8 @@ import UpdateStateStep from "./UpdateState.svelte"
// be considered as camel case too. // be considered as camel case too.
// There is technical debt here to sanitize all these and standardise them // There is technical debt here to sanitize all these and standardise them
// across the packages but it's a breaking change to existing apps. // across the packages but it's a breaking change to existing apps.
export default [ export const getAvailableActions = () => {
let actions = [
{ {
name: "Save Row", name: "Save Row",
component: SaveRow, component: SaveRow,
@ -58,8 +62,14 @@ export default [
name: "Change Form Step", name: "Change Form Step",
component: ChangeFormStep, component: ChangeFormStep,
}, },
{ ]
if (get(store).clientFeatures?.state) {
actions.push({
name: "Update State", name: "Update State",
component: UpdateStateStep, component: UpdateStateStep,
}, })
] }
return actions
}

View File

@ -6,7 +6,7 @@
let loaded = false let loaded = false
$: multiTenancyEnabled = $admin.multiTenancy $: multiTenancyEnabled = $admin.multiTenancy
$: hasAdminUser = !!$admin?.checklist?.adminUser $: hasAdminUser = $admin?.checklist?.adminUser.checked
$: tenantSet = $auth.tenantSet $: tenantSet = $auth.tenantSet
onMount(async () => { onMount(async () => {
@ -26,7 +26,6 @@
$redirect("./admin") $redirect("./admin")
} }
} }
// Redirect to log in at any time if the user isn't authenticated // Redirect to log in at any time if the user isn't authenticated
$: { $: {
if ( if (

View File

@ -6,7 +6,7 @@
let loaded = false let loaded = false
onMount(() => { onMount(() => {
if ($admin?.checklist?.adminUser) { if ($admin?.checklist?.adminUser.checked) {
$redirect("../") $redirect("../")
} else { } else {
loaded = true loaded = true

View File

@ -14,6 +14,7 @@
import { findComponent, findComponentPath } from "builderStore/storeUtils" import { findComponent, findComponentPath } from "builderStore/storeUtils"
import { get } from "svelte/store" import { get } from "svelte/store"
import AppThemeSelect from "components/design/AppPreview/AppThemeSelect.svelte" import AppThemeSelect from "components/design/AppPreview/AppThemeSelect.svelte"
import ThemeEditor from "components/design/AppPreview/ThemeEditor.svelte"
// Cache previous values so we don't update the URL more than necessary // Cache previous values so we don't update the URL more than necessary
let previousType let previousType
@ -150,7 +151,9 @@
{#if $currentAsset} {#if $currentAsset}
<div class="preview-header"> <div class="preview-header">
<ComponentSelectionList /> <ComponentSelectionList />
{#if $store.clientFeatures.spectrumThemes} {#if $store.clientFeatures.customThemes}
<ThemeEditor />
{:else if $store.clientFeatures.spectrumThemes}
<AppThemeSelect /> <AppThemeSelect />
{/if} {/if}
</div> </div>
@ -202,9 +205,18 @@
padding: var(--spacing-xl) 40px; padding: var(--spacing-xl) 40px;
} }
.preview-header { .preview-header {
display: grid; display: flex;
grid-template-columns: 1fr 100px; flex-direction: row;
justify-content: flex-start;
align-items: center;
} }
.preview-header > :global(*) {
flex: 0 0 auto;
}
.preview-header > :global(*:first-child) {
flex: 1 1 auto;
}
.preview-content { .preview-content {
flex: 1 1 auto; flex: 1 1 auto;
} }

View File

@ -8,7 +8,12 @@ export function createAdminStore() {
multiTenancy: false, multiTenancy: false,
sandbox: false, sandbox: false,
onboardingProgress: 0, onboardingProgress: 0,
checklist: { apps: 0, smtp: false, adminUser: false, sso: false }, checklist: {
apps: { checked: false },
smtp: { checked: false },
adminUser: { checked: false },
sso: { checked: false },
},
} }
const admin = writable(DEFAULT_CONFIG) const admin = writable(DEFAULT_CONFIG)
@ -24,7 +29,7 @@ export function createAdminStore() {
const onboardingSteps = Object.keys(json) const onboardingSteps = Object.keys(json)
const stepsComplete = onboardingSteps.reduce( const stepsComplete = onboardingSteps.reduce(
(score, step) => score + Number(!!json[step]), (score, step) => (score + step.checked ? 1 : 0),
0 0
) )

View File

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

View File

@ -2,7 +2,9 @@
"features": { "features": {
"spectrumThemes": true, "spectrumThemes": true,
"intelligentLoading": true, "intelligentLoading": true,
"deviceAwareness": true "deviceAwareness": true,
"state": true,
"customThemes": true
}, },
"layout": { "layout": {
"name": "Layout", "name": "Layout",

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/client", "name": "@budibase/client",
"version": "0.9.122", "version": "0.9.123-alpha.3",
"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",
@ -11,23 +11,33 @@
"import": "./dist/budibase-client.js", "import": "./dist/budibase-client.js",
"require": "./dist/budibase-client.js" "require": "./dist/budibase-client.js"
}, },
"./package.json": "./package.json" "./package.json": "./package.json",
"./manifest.json": "./manifest.json"
}, },
"scripts": { "scripts": {
"build": "rollup -c", "build": "rollup -c",
"dev:builder": "rollup -cw" "dev:builder": "rollup -cw"
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.122", "@budibase/bbui": "^0.9.123-alpha.3",
"@budibase/standard-components": "^0.9.122", "@budibase/string-templates": "^0.9.123-alpha.3",
"@budibase/string-templates": "^0.9.122",
"regexparam": "^1.3.0", "regexparam": "^1.3.0",
"shortid": "^2.2.15", "shortid": "^2.2.15",
"svelte-spa-router": "^3.0.5" "svelte-spa-router": "^3.0.5"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-alias": "^3.1.5",
"@rollup/plugin-commonjs": "^18.0.0", "@rollup/plugin-commonjs": "^18.0.0",
"@rollup/plugin-node-resolve": "^11.2.1", "@rollup/plugin-node-resolve": "^11.2.1",
"@spectrum-css/button": "^3.0.3",
"@spectrum-css/card": "^3.0.3",
"@spectrum-css/divider": "^1.0.3",
"@spectrum-css/link": "^3.1.3",
"@spectrum-css/page": "^3.0.1",
"@spectrum-css/typography": "^3.0.2",
"@spectrum-css/vars": "^3.0.1",
"apexcharts": "^3.22.1",
"dayjs": "^1.10.5",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"jsdom": "^16.0.1", "jsdom": "^16.0.1",
"postcss": "^8.2.10", "postcss": "^8.2.10",
@ -39,7 +49,9 @@
"rollup-plugin-svelte": "^7.1.0", "rollup-plugin-svelte": "^7.1.0",
"rollup-plugin-svg": "^2.0.0", "rollup-plugin-svg": "^2.0.0",
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",
"svelte": "^3.38.2" "svelte": "^3.38.2",
"svelte-apexcharts": "^1.0.2",
"svelte-flatpickr": "^3.1.0"
}, },
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
} }

View File

@ -1,5 +1,6 @@
import commonjs from "@rollup/plugin-commonjs" import commonjs from "@rollup/plugin-commonjs"
import resolve from "@rollup/plugin-node-resolve" import resolve from "@rollup/plugin-node-resolve"
import alias from "@rollup/plugin-alias"
import svelte from "rollup-plugin-svelte" import svelte from "rollup-plugin-svelte"
import { terser } from "rollup-plugin-terser" import { terser } from "rollup-plugin-terser"
import postcss from "rollup-plugin-postcss" import postcss from "rollup-plugin-postcss"
@ -7,6 +8,7 @@ import svg from "rollup-plugin-svg"
import json from "rollup-plugin-json" import json from "rollup-plugin-json"
import builtins from "rollup-plugin-node-builtins" import builtins from "rollup-plugin-node-builtins"
import globals from "rollup-plugin-node-globals" import globals from "rollup-plugin-node-globals"
import path from "path"
const production = !process.env.ROLLUP_WATCH const production = !process.env.ROLLUP_WATCH
const ignoredWarnings = [ const ignoredWarnings = [
@ -26,6 +28,38 @@ export default {
}, },
], ],
plugins: [ plugins: [
alias({
entries: [
{
find: "manifest.json",
replacement: path.resolve("./manifest.json"),
},
{
find: "api",
replacement: path.resolve("./src/api"),
},
{
find: "components",
replacement: path.resolve("./src/components"),
},
{
find: "stores",
replacement: path.resolve("./src/stores"),
},
{
find: "utils",
replacement: path.resolve("./src/utils"),
},
{
find: "constants",
replacement: path.resolve("./src/constants"),
},
{
find: "sdk",
replacement: path.resolve("./src/sdk"),
},
],
}),
svelte({ svelte({
emitCss: true, emitCss: true,
onwarn: (warning, handler) => { onwarn: (warning, handler) => {

View File

@ -1,5 +1,5 @@
import { notificationStore } from "../store" import { notificationStore } from "stores"
import { ApiVersion } from "../constants" import { ApiVersion } from "constants"
/** /**
* API cache for cached request responses. * API cache for cached request responses.

View File

@ -1,5 +1,6 @@
import { notificationStore } from "../store/notification" import { notificationStore } from "stores/notification"
import API from "./api" import API from "./api"
/** /**
* Executes an automation. Must have "App Action" trigger. * Executes an automation. Must have "App Action" trigger.
*/ */

View File

@ -1,4 +1,4 @@
import { notificationStore, dataSourceStore } from "../store" import { notificationStore, dataSourceStore } from "stores"
import API from "./api" import API from "./api"
/** /**

View File

@ -1,4 +1,4 @@
import { notificationStore, dataSourceStore } from "../store" import { notificationStore, dataSourceStore } from "stores"
import API from "./api" import API from "./api"
import { fetchTableDefinition } from "./tables" import { fetchTableDefinition } from "./tables"

View File

@ -1,11 +1,9 @@
<script> <script>
import { writable } from "svelte/store" import { writable } from "svelte/store"
import { setContext, onMount } from "svelte" import { setContext, onMount } from "svelte"
import { Layout, Heading, Body } from "@budibase/bbui"
import Component from "./Component.svelte" import Component from "./Component.svelte"
import NotificationDisplay from "./NotificationDisplay.svelte" import SDK from "sdk"
import ConfirmationDisplay from "./ConfirmationDisplay.svelte"
import PeekScreenDisplay from "./PeekScreenDisplay.svelte"
import SDK from "../sdk"
import { import {
createContextStore, createContextStore,
initialise, initialise,
@ -13,16 +11,19 @@
authStore, authStore,
routeStore, routeStore,
builderStore, builderStore,
appStore, themeStore,
} from "../store" } from "stores"
import SettingsBar from "./preview/SettingsBar.svelte" import NotificationDisplay from "components/overlay/NotificationDisplay.svelte"
import SelectionIndicator from "./preview/SelectionIndicator.svelte" import ConfirmationDisplay from "components/overlay/ConfirmationDisplay.svelte"
import HoverIndicator from "./preview/HoverIndicator.svelte" import PeekScreenDisplay from "components/overlay/PeekScreenDisplay.svelte"
import { Layout, Heading, Body } from "@budibase/bbui" import UserBindingsProvider from "components/context/UserBindingsProvider.svelte"
import DeviceBindingsProvider from "components/context/DeviceBindingsProvider.svelte"
import StateBindingsProvider from "components/context/StateBindingsProvider.svelte"
import SettingsBar from "components/preview/SettingsBar.svelte"
import SelectionIndicator from "components/preview/SelectionIndicator.svelte"
import HoverIndicator from "components/preview/HoverIndicator.svelte"
import CustomThemeWrapper from "./CustomThemeWrapper.svelte"
import ErrorSVG from "../../../builder/assets/error.svg" import ErrorSVG from "../../../builder/assets/error.svg"
import UserBindingsProvider from "./UserBindingsProvider.svelte"
import DeviceBindingsProvider from "./DeviceBindingsProvider.svelte"
import StateBindingsProvider from "./StateBindingsProvider.svelte"
// Provide contexts // Provide contexts
setContext("sdk", SDK) setContext("sdk", SDK)
@ -63,9 +64,6 @@
} }
} }
} }
$: themeClass =
$builderStore.theme || $appStore.application?.theme || "spectrum--light"
</script> </script>
{#if dataLoaded} {#if dataLoaded}
@ -73,7 +71,7 @@
id="spectrum-root" id="spectrum-root"
lang="en" lang="en"
dir="ltr" dir="ltr"
class="spectrum spectrum--medium {themeClass}" class="spectrum spectrum--medium {$themeStore.theme}"
> >
{#if permissionError} {#if permissionError}
<div class="error"> <div class="error">
@ -87,11 +85,13 @@
<UserBindingsProvider> <UserBindingsProvider>
<DeviceBindingsProvider> <DeviceBindingsProvider>
<StateBindingsProvider> <StateBindingsProvider>
<CustomThemeWrapper>
<div id="app-root" class:preview={$builderStore.inBuilder}> <div id="app-root" class:preview={$builderStore.inBuilder}>
{#key $screenStore.activeLayout._id} {#key $screenStore.activeLayout._id}
<Component instance={$screenStore.activeLayout.props} /> <Component instance={$screenStore.activeLayout.props} />
{/key} {/key}
</div> </div>
</CustomThemeWrapper>
<NotificationDisplay /> <NotificationDisplay />
<ConfirmationDisplay /> <ConfirmationDisplay />
<PeekScreenDisplay /> <PeekScreenDisplay />
@ -131,28 +131,6 @@
#app-root.preview { #app-root.preview {
border: 1px solid var(--spectrum-global-color-gray-300); border: 1px solid var(--spectrum-global-color-gray-300);
} }
/* Custom scrollbars */
:global(::-webkit-scrollbar) {
width: 8px;
height: 8px;
}
:global(::-webkit-scrollbar-track) {
background: var(--spectrum-alias-background-color-default);
}
:global(::-webkit-scrollbar-thumb) {
background-color: var(--spectrum-global-color-gray-400);
border-radius: 4px;
}
:global(::-webkit-scrollbar-corner) {
background: var(--spectrum-alias-background-color-default);
}
:global(*) {
scrollbar-width: thin;
scrollbar-color: var(--spectrum-global-color-gray-400)
var(--spectrum-alias-background-color-default);
}
.error { .error {
position: absolute; position: absolute;
width: 100%; width: 100%;

View File

@ -1,17 +1,14 @@
<script> <script>
import { getContext, setContext } from "svelte" import { getContext, setContext } from "svelte"
import { writable, get } from "svelte/store" import { writable, get } from "svelte/store"
import * as ComponentLibrary from "@budibase/standard-components" import * as AppComponents from "components/app"
import Router from "./Router.svelte" import Router from "./Router.svelte"
import { enrichProps, propsAreSame } from "../utils/componentProps" import { enrichProps, propsAreSame } from "utils/componentProps"
import { builderStore } from "../store" import { builderStore } from "stores"
import { hashString } from "../utils/hash" import { hashString } from "utils/helpers"
import Manifest from "@budibase/standard-components/manifest.json" import Manifest from "manifest.json"
import { Placeholder } from "@budibase/standard-components" import { getActiveConditions, reduceConditionActions } from "utils/conditions"
import { import Placeholder from "components/app/Placeholder.svelte"
getActiveConditions,
reduceConditionActions,
} from "../utils/conditions"
export let instance = {} export let instance = {}
@ -95,7 +92,7 @@
if (name === "screenslot" && $builderStore.previewType !== "layout") { if (name === "screenslot" && $builderStore.previewType !== "layout") {
return Router return Router
} }
return ComponentLibrary[name] return AppComponents[name]
} }
const getComponentDefinition = component => { const getComponentDefinition = component => {

View File

@ -0,0 +1,79 @@
<script>
import { themeStore } from "stores"
</script>
<div style={$themeStore.customThemeCss}>
<slot />
</div>
<style>
div {
display: contents;
}
/* Themes */
div {
/* Buttons */
--spectrum-semantic-cta-color-background-default: var(--primaryColor);
--spectrum-semantic-cta-color-background-hover: var(--primaryColorHover);
--spectrum-button-primary-m-border-radius: var(--buttonBorderRadius);
/* Loading spinners */
--spectrum-progresscircle-medium-track-fill-color: var(--primaryColor);
/* Form fields */
--spectrum-alias-border-color-mouse-focus: var(--primaryColor);
--spectrum-alias-border-color-focus: var(--primaryColor);
--spectrum-radio-m-emphasized-circle-border-color-selected: var(
--primaryColor
);
--spectrum-radio-m-emphasized-circle-border-color-selected-hover: var(
--primaryColorHover
);
--spectrum-checkbox-m-emphasized-box-border-color-selected: var(
--primaryColor
);
--spectrum-checkbox-m-emphasized-box-border-color-selected-hover: var(
--primaryColorHover
);
/* Icons */
--spectrum-alias-icon-color-selected: var(--primaryColor);
--spectrum-alias-icon-color-selected-hover: var(--primaryColorHover);
/* Links */
--spectrum-link-primary-m-text-color: var(--primaryColor);
--spectrum-link-primary-m-text-color-hover: var(--primaryColorHover);
}
/* Theme flatpickr */
:global(.flatpickr-day.selected) {
background: var(--primaryColor);
border-color: var(--primaryColor);
}
:global(.flatpickr-day.selected:hover) {
background: var(--primaryColorHover);
border-color: var(--primaryColorHover);
}
/* Custom scrollbars */
:global(::-webkit-scrollbar) {
width: 8px;
height: 8px;
}
:global(::-webkit-scrollbar-track) {
background: var(--spectrum-alias-background-color-default);
}
:global(::-webkit-scrollbar-thumb) {
background-color: var(--spectrum-global-color-gray-400);
border-radius: 4px;
}
:global(::-webkit-scrollbar-corner) {
background: var(--spectrum-alias-background-color-default);
}
:global(*) {
scrollbar-width: thin;
scrollbar-color: var(--spectrum-global-color-gray-400)
var(--spectrum-alias-background-color-default);
}
</style>

View File

@ -1,7 +1,7 @@
<script> <script>
import { setContext, getContext } from "svelte" import { setContext, getContext } from "svelte"
import Router, { querystring } from "svelte-spa-router" import Router, { querystring } from "svelte-spa-router"
import { routeStore } from "../store" import { routeStore } from "stores"
import Screen from "./Screen.svelte" import Screen from "./Screen.svelte"
const { styleable } = getContext("sdk") const { styleable } = getContext("sdk")

View File

@ -1,7 +1,7 @@
<script> <script>
import { screenStore, routeStore } from "../store" import { screenStore, routeStore } from "stores"
import Component from "./Component.svelte" import Component from "./Component.svelte"
import Provider from "./Provider.svelte" import Provider from "./context/Provider.svelte"
import { onMount } from "svelte" import { onMount } from "svelte"
// Keep route params up to date // Keep route params up to date

View File

@ -36,7 +36,7 @@
font-size: 2rem; font-size: 2rem;
font-weight: 600; font-weight: 600;
margin: 0 1.5rem 1.5rem 1.5rem; margin: 0 1.5rem 1.5rem 1.5rem;
color: var(--spectrum-global-color-blue-600); color: var(--spectrum-link-primary-m-text-color);
white-space: pre-wrap; white-space: pre-wrap;
} }

View File

@ -6,7 +6,7 @@
luceneQuery, luceneQuery,
luceneSort, luceneSort,
luceneLimit, luceneLimit,
} from "./lucene" } from "utils/lucene"
import Placeholder from "./Placeholder.svelte" import Placeholder from "./Placeholder.svelte"
export let dataSource export let dataSource

View File

@ -20,7 +20,12 @@
</script> </script>
{#if icon} {#if icon}
<i use:styleable={styles} class="{icon} {size}" on:click={onClick} /> <i
use:styleable={styles}
class="{icon} {size}"
on:click={onClick}
class:hoverable={onClick != null}
/>
{:else if $builderStore.inBuilder} {:else if $builderStore.inBuilder}
<div use:styleable={styles}> <div use:styleable={styles}>
<Placeholder /> <Placeholder />
@ -31,4 +36,8 @@
div { div {
font-style: italic; font-style: italic;
} }
.hoverable:hover {
color: var(--spectrum-alias-icon-color-selected-hover) !important;
cursor: pointer;
}
</style> </style>

View File

@ -1,9 +1,9 @@
<script> <script>
import { getContext } from "svelte" import { getContext } from "svelte"
import { Heading, Icon } from "@budibase/bbui" import { Heading, Icon } from "@budibase/bbui"
import { routeStore } from "../../client/src/store" import active from "svelte-spa-router/active"
const { styleable, linkable, builderStore } = getContext("sdk") const { routeStore, styleable, linkable, builderStore } = getContext("sdk")
const component = getContext("component") const component = getContext("component")
export let title export let title
@ -96,7 +96,13 @@
<div class="links" class:visible={mobileOpen}> <div class="links" class:visible={mobileOpen}>
{#each validLinks as { text, url }} {#each validLinks as { text, url }}
{#if isInternal(url)} {#if isInternal(url)}
<a class="link" href={url} use:linkable on:click={close}> <a
class="link"
href={url}
use:linkable
on:click={close}
use:active={url}
>
{text} {text}
</a> </a>
{:else} {:else}
@ -143,7 +149,7 @@
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: stretch; align-items: stretch;
background: var(--spectrum-alias-background-color-primary); background: var(--navBackground);
z-index: 2; z-index: 2;
border-bottom: 1px solid var(--spectrum-global-color-gray-300); border-bottom: 1px solid var(--spectrum-global-color-gray-300);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.05); box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.05);
@ -166,6 +172,18 @@
max-width: 100%; max-width: 100%;
gap: var(--spacing-xl); gap: var(--spacing-xl);
} }
.nav :global(.spectrum-Icon) {
color: var(--navTextColor);
opacity: 0.75;
}
.nav :global(.spectrum-Icon:hover) {
color: var(--navTextColor);
opacity: 1;
}
.nav :global(h1) {
color: var(--navTextColor);
}
.nav-header { .nav-header {
flex: 0 0 auto; flex: 0 0 auto;
display: flex; display: flex;
@ -243,13 +261,19 @@
margin-top: var(--spacing-xl); margin-top: var(--spacing-xl);
} }
.link { .link {
color: var(--spectrum-alias-text-color); opacity: 0.75;
color: var(--navTextColor);
font-size: var(--spectrum-global-dimension-font-size-200); font-size: var(--spectrum-global-dimension-font-size-200);
font-weight: 600; font-weight: 600;
transition: color 130ms ease-out; transition: color 130ms ease-out;
} }
.link.active {
opacity: 1;
}
.link:hover { .link:hover {
color: var(--spectrum-global-color-blue-600); opacity: 1;
text-decoration: underline;
text-underline-position: under;
} }
.close { .close {
display: none; display: none;
@ -333,7 +357,7 @@
transition: transform 0.26s ease-in-out, opacity 0.26s ease-in-out; transition: transform 0.26s ease-in-out, opacity 0.26s ease-in-out;
height: 100vh; height: 100vh;
opacity: 0; opacity: 0;
background: var(--spectrum-alias-background-color-secondary); background: var(--navBackground);
z-index: 999; z-index: 999;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
@ -347,8 +371,7 @@
.links.visible { .links.visible {
opacity: 1; opacity: 1;
transform: translateX(250px); transform: translateX(250px);
box-shadow: 0 0 80px 20px rgba(0, 0, 0, 0.2); box-shadow: 0 0 80px 20px rgba(0, 0, 0, 0.3);
border-right: 1px solid var(--spectrum-global-color-gray-300);
} }
.mobile-click-handler.visible { .mobile-click-handler.visible {
position: fixed; position: fixed;

View File

@ -78,7 +78,7 @@
transition: color 130ms ease-in-out; transition: color 130ms ease-in-out;
} }
a:hover { a:hover {
color: var(--spectrum-global-color-blue-600) !important; color: var(--spectrum-link-primary-m-text-color-hover) !important;
} }
.placeholder { .placeholder {
font-style: italic; font-style: italic;

View File

@ -96,7 +96,7 @@
color: var(--spectrum-alias-text-color); color: var(--spectrum-alias-text-color);
} }
a:hover { a:hover {
color: var(--spectrum-global-color-blue-600); color: var(--spectrum-link-primary-m-text-color-hover);
} }
.horizontal .spectrum-Card-coverPhoto { .horizontal .spectrum-Card-coverPhoto {

View File

@ -56,6 +56,7 @@
disabled={fieldState.disabled} disabled={fieldState.disabled}
error={fieldState.error} error={fieldState.error}
id={fieldState.fieldId} id={fieldState.fieldId}
appendTo={document.getElementById("app-root")}
{enableTime} {enableTime}
{placeholder} {placeholder}
/> />

View File

@ -2,7 +2,7 @@
import { setContext, getContext } from "svelte" import { setContext, getContext } from "svelte"
import { derived, get, writable } from "svelte/store" import { derived, get, writable } from "svelte/store"
import { createValidatorFromConstraints } from "./validation" import { createValidatorFromConstraints } from "./validation"
import { generateID } from "../helpers" import { generateID } from "utils/helpers"
export let dataSource export let dataSource
export let disabled = false export let disabled = false

View File

@ -7,9 +7,6 @@ import "@spectrum-css/vars/dist/spectrum-dark.css"
import "@spectrum-css/vars/dist/spectrum-darkest.css" import "@spectrum-css/vars/dist/spectrum-darkest.css"
import "@spectrum-css/page/dist/index-vars.css" import "@spectrum-css/page/dist/index-vars.css"
import loadSpectrumIcons from "@budibase/bbui/spectrum-icons-rollup.js"
loadSpectrumIcons()
// Non user-facing components // Non user-facing components
export { default as Placeholder } from "./Placeholder.svelte" export { default as Placeholder } from "./Placeholder.svelte"

View File

@ -1,7 +1,7 @@
<script> <script>
import { getContext, setContext, onMount } from "svelte" import { getContext, setContext, onMount } from "svelte"
import { dataSourceStore, createContextStore } from "../store" import { dataSourceStore, createContextStore } from "stores"
import { ActionTypes } from "../constants" import { ActionTypes } from "constants"
import { generate } from "shortid" import { generate } from "shortid"
export let data export let data

Some files were not shown because too many files have changed in this diff Show More