Merge branch 'develop' into autocomplete_component

This commit is contained in:
Maurits Lourens 2021-08-17 14:26:57 +02:00
commit 51f680ebea
20 changed files with 274 additions and 30 deletions

View File

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

View File

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

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/bbui", "name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.", "description": "A UI solution used in the different Budibase projects.",
"version": "0.9.105-alpha.12", "version": "0.9.105-alpha.15",
"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

@ -1,6 +1,6 @@
{ {
"name": "@budibase/builder", "name": "@budibase/builder",
"version": "0.9.105-alpha.12", "version": "0.9.105-alpha.15",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"private": true, "private": true,
"scripts": { "scripts": {
@ -65,10 +65,10 @@
} }
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.105-alpha.12", "@budibase/bbui": "^0.9.105-alpha.15",
"@budibase/client": "^0.9.105-alpha.12", "@budibase/client": "^0.9.105-alpha.15",
"@budibase/colorpicker": "1.1.2", "@budibase/colorpicker": "1.1.2",
"@budibase/string-templates": "^0.9.105-alpha.12", "@budibase/string-templates": "^0.9.105-alpha.15",
"@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

@ -31,7 +31,12 @@
.flat() .flat()
// Prevent modal closing if there were errors // Prevent modal closing if there were errors
return false return false
} else if (rowResponse.status === 400 || rowResponse.status === 500) { } else if (rowResponse.status === 400 && rowResponse.validationErrors) {
errors = Object.keys(rowResponse.validationErrors).map(field => ({
message: `${field} ${rowResponse.validationErrors[field][0]}`,
}))
return false
} else if (rowResponse.status === 500) {
errors = [{ message: rowResponse.message }] errors = [{ message: rowResponse.message }]
return false return false
} }

View File

@ -32,9 +32,29 @@
if (!control) { if (!control) {
return false return false
} }
if (setting.dependsOn && isEmpty(componentInstance[setting.dependsOn])) {
return false // Parse dependant settings
if (setting.dependsOn) {
let dependantSetting = setting.dependsOn
let dependantValue = null
if (typeof setting.dependsOn === "object") {
dependantSetting = setting.dependsOn.setting
dependantValue = setting.dependsOn.value
}
if (!dependantSetting) {
return false
}
// If no specific value is depended upon, check if a value exists at all
// for the dependent setting
if (dependantValue == null) {
return !isEmpty(componentInstance[dependantSetting])
}
// Otherwise check the value matches
return componentInstance[dependantSetting] === dependantValue
} }
return true return true
} }
</script> </script>

View File

@ -0,0 +1,82 @@
<script>
import {
Icon,
Button,
Input,
DrawerContent,
Layout,
Body,
} from "@budibase/bbui"
import { generate } from "shortid"
export let options = []
const removeOption = id => {
options = options.filter(option => option.id !== id)
}
const addOption = () => {
options = [
...options,
{
id: generate(),
label: null,
value: null,
},
]
}
</script>
<DrawerContent>
<div class="container">
<Layout noPadding gap="S">
{#if !options.length}
<Body size="S">Add an option to get started.</Body>
{/if}
{#if options?.length}
<div class="options">
{#each options as option (option.id)}
<Input
placeholder="Label"
bind:value={option.label}
label="Label"
labelPosition="left"
/>
<Input
placeholder="Value"
bind:value={option.value}
label="Value"
labelPosition="left"
/>
<Icon
name="Close"
hoverable
size="S"
on:click={() => removeOption(option.id)}
/>
{/each}
</div>
{/if}
<div>
<Button icon="AddCircle" size="M" on:click={addOption} secondary>
Add Option
</Button>
</div>
</Layout>
</div>
</DrawerContent>
<style>
.container {
width: 100%;
max-width: 800px;
margin: 0 auto;
}
.options {
display: grid;
column-gap: var(--spacing-l);
row-gap: var(--spacing-s);
align-items: center;
grid-template-columns: 1fr 1fr auto;
}
</style>

View File

@ -0,0 +1,28 @@
<script>
import { ActionButton, Button, Drawer } from "@budibase/bbui"
import { createEventDispatcher } from "svelte"
import OptionsDrawer from "./OptionsDrawer.svelte"
const dispatch = createEventDispatcher()
export let value
let drawer
let tempValue = value || []
const saveFilter = async () => {
// Filter out incomplete options
tempValue = tempValue.filter(option => option.value && option.label)
dispatch("change", tempValue)
drawer.hide()
}
</script>
<ActionButton on:click={drawer.show}>Define Options</ActionButton>
<Drawer bind:this={drawer} title="Options">
<svelte:fragment slot="description">
Define the options for this picker.
</svelte:fragment>
<Button cta slot="buttons" on:click={saveFilter}>Save</Button>
<OptionsDrawer bind:options={tempValue} slot="body" />
</Drawer>

View File

@ -12,6 +12,7 @@ import SectionSelect from "./SectionSelect.svelte"
import NavigationEditor from "./NavigationEditor/NavigationEditor.svelte" import NavigationEditor from "./NavigationEditor/NavigationEditor.svelte"
import FilterEditor from "./FilterEditor/FilterEditor.svelte" import FilterEditor from "./FilterEditor/FilterEditor.svelte"
import URLSelect from "./URLSelect.svelte" import URLSelect from "./URLSelect.svelte"
import OptionsEditor from "./OptionsEditor/OptionsEditor.svelte"
import FormFieldSelect from "./FormFieldSelect.svelte" import FormFieldSelect from "./FormFieldSelect.svelte"
import ValidationEditor from "./ValidationEditor/ValidationEditor.svelte" import ValidationEditor from "./ValidationEditor/ValidationEditor.svelte"
@ -28,6 +29,7 @@ const componentMap = {
icon: IconSelect, icon: IconSelect,
field: FieldSelect, field: FieldSelect,
multifield: MultiFieldSelect, multifield: MultiFieldSelect,
options: OptionsEditor,
schema: SchemaSelect, schema: SchemaSelect,
section: SectionSelect, section: SectionSelect,
navigation: NavigationEditor, navigation: NavigationEditor,

View File

@ -53,7 +53,7 @@
label={def.label} label={def.label}
key={def.key} key={def.key}
value={deepGet($currentAsset, def.key)} value={deepGet($currentAsset, def.key)}
on:change={event => setAssetProps(def.key, event.detail, def.parser)} onChange={val => setAssetProps(def.key, val, def.parser)}
{bindings} {bindings}
/> />
{/each} {/each}

View File

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

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/client", "name": "@budibase/client",
"version": "0.9.105-alpha.12", "version": "0.9.105-alpha.15",
"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",
@ -18,9 +18,9 @@
"dev:builder": "rollup -cw" "dev:builder": "rollup -cw"
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.105-alpha.12", "@budibase/bbui": "^0.9.105-alpha.15",
"@budibase/standard-components": "^0.9.105-alpha.12", "@budibase/standard-components": "^0.9.105-alpha.15",
"@budibase/string-templates": "^0.9.105-alpha.12", "@budibase/string-templates": "^0.9.105-alpha.15",
"regexparam": "^1.3.0", "regexparam": "^1.3.0",
"shortid": "^2.2.15", "shortid": "^2.2.15",
"svelte-spa-router": "^3.0.5" "svelte-spa-router": "^3.0.5"

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/server", "name": "@budibase/server",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "0.9.105-alpha.12", "version": "0.9.105-alpha.15",
"description": "Budibase Web Server", "description": "Budibase Web Server",
"main": "src/index.js", "main": "src/index.js",
"repository": { "repository": {
@ -62,9 +62,9 @@
"author": "Budibase", "author": "Budibase",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@budibase/auth": "^0.9.105-alpha.12", "@budibase/auth": "^0.9.105-alpha.15",
"@budibase/client": "^0.9.105-alpha.12", "@budibase/client": "^0.9.105-alpha.15",
"@budibase/string-templates": "^0.9.105-alpha.12", "@budibase/string-templates": "^0.9.105-alpha.15",
"@elastic/elasticsearch": "7.10.0", "@elastic/elasticsearch": "7.10.0",
"@koa/router": "8.0.0", "@koa/router": "8.0.0",
"@sendgrid/mail": "7.1.1", "@sendgrid/mail": "7.1.1",
@ -117,7 +117,7 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.14.3", "@babel/core": "^7.14.3",
"@babel/preset-env": "^7.14.4", "@babel/preset-env": "^7.14.4",
"@budibase/standard-components": "^0.9.105-alpha.12", "@budibase/standard-components": "^0.9.105-alpha.15",
"@jest/test-sequencer": "^24.8.0", "@jest/test-sequencer": "^24.8.0",
"@types/bull": "^3.15.1", "@types/bull": "^3.15.1",
"@types/jest": "^26.0.23", "@types/jest": "^26.0.23",

View File

@ -57,7 +57,7 @@ exports.patch = async ctx => {
}) })
if (!validateResult.valid) { if (!validateResult.valid) {
throw validateResult.errors throw { validation: validateResult.errors }
} }
// returned row is cleaned and prepared for writing to DB // returned row is cleaned and prepared for writing to DB
@ -105,7 +105,7 @@ exports.save = async function (ctx) {
}) })
if (!validateResult.valid) { if (!validateResult.valid) {
throw validateResult.errors throw { validation: validateResult.errors }
} }
// make sure link rows are up to date // make sure link rows are up to date

View File

@ -58,6 +58,7 @@ router.use(async (ctx, next) => {
ctx.body = { ctx.body = {
message: err.message, message: err.message,
status: ctx.status, status: ctx.status,
validationErrors: err.validation,
} }
if (env.NODE_ENV !== "jest") { if (env.NODE_ENV !== "jest") {
ctx.log.error(err) ctx.log.error(err)

View File

@ -1908,6 +1908,7 @@
"type": "select", "type": "select",
"label": "Type", "label": "Type",
"key": "optionsType", "key": "optionsType",
"defaultValue": "select",
"placeholder": "Pick an options type", "placeholder": "Pick an options type",
"options": [ "options": [
{ {
@ -1935,6 +1936,62 @@
"key": "disabled", "key": "disabled",
"defaultValue": false "defaultValue": false
}, },
{
"type": "select",
"label": "Options source",
"key": "optionsSource",
"defaultValue": "schema",
"placeholder": "Pick an options source",
"options": [
{
"label": "Schema",
"value": "schema"
},
{
"label": "Data provider",
"value": "provider"
},
{
"label": "Custom",
"value": "custom"
}
]
},
{
"type": "dataProvider",
"label": "Options Provider",
"key": "dataProvider",
"dependsOn": {
"setting": "optionsSource",
"value": "provider"
}
},
{
"type": "field",
"label": "Label Column",
"key": "labelColumn",
"dependsOn": {
"setting": "optionsSource",
"value": "provider"
}
},
{
"type": "field",
"label": "Value Column",
"key": "valueColumn",
"dependsOn": {
"setting": "optionsSource",
"value": "provider"
}
},
{
"type": "options",
"key": "customOptions",
"dependsOn": {
"setting": "optionsSource",
"value": "custom"
}
},
{ {
"type": "validation/string", "type": "validation/string",
"label": "Validation", "label": "Validation",

View File

@ -29,11 +29,11 @@
"keywords": [ "keywords": [
"svelte" "svelte"
], ],
"version": "0.9.105-alpha.12", "version": "0.9.105-alpha.15",
"license": "MIT", "license": "MIT",
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc", "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc",
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.105-alpha.12", "@budibase/bbui": "^0.9.105-alpha.15",
"@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",

View File

@ -9,10 +9,57 @@
export let optionsType = "select" export let optionsType = "select"
export let validation export let validation
export let defaultValue export let defaultValue
export let optionsSource = "schema"
export let dataProvider
export let labelColumn
export let valueColumn
export let customOptions
let fieldState let fieldState
let fieldApi let fieldApi
let fieldSchema let fieldSchema
$: flatOptions = optionsSource == null || optionsSource === "schema"
$: options = getOptions(
optionsSource,
fieldSchema,
dataProvider,
labelColumn,
valueColumn
)
const getOptions = (
optionsSource,
fieldSchema,
dataProvider,
labelColumn,
valueColumn
) => {
// Take options from schema
if (optionsSource == null || optionsSource === "schema") {
return fieldSchema?.constraints?.inclusion ?? []
}
// Extract options from data provider
if (optionsSource === "provider" && valueColumn) {
let optionsSet = {}
dataProvider?.rows?.forEach(row => {
const value = row?.[valueColumn]
if (value) {
const label = row[labelColumn] || value
optionsSet[value] = { value, label }
}
})
return Object.values(optionsSet)
}
// Extract custom options
if (optionsSource === "custom" && customOptions) {
return customOptions
}
return []
}
</script> </script>
<Field <Field
@ -33,9 +80,11 @@
id={$fieldState.fieldId} id={$fieldState.fieldId}
disabled={$fieldState.disabled} disabled={$fieldState.disabled}
error={$fieldState.error} error={$fieldState.error}
options={fieldSchema?.constraints?.inclusion ?? []} {options}
{placeholder} {placeholder}
on:change={e => fieldApi.setValue(e.detail)} on:change={e => fieldApi.setValue(e.detail)}
getOptionLabel={flatOptions ? x => x : x => x.label}
getOptionValue={flatOptions ? x => x : x => x.value}
/> />
{:else if optionsType === "autocomplete"} {:else if optionsType === "autocomplete"}
<CoreAutocomplete <CoreAutocomplete

View File

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

View File

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