Merge branch 'master' of github.com:Budibase/budibase into feature/opinionated-sql
This commit is contained in:
commit
b6be635cb8
38 changed files with 701 additions and 153 deletions
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "0.9.25",
|
"version": "0.9.27",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/auth",
|
"name": "@budibase/auth",
|
||||||
"version": "0.9.25",
|
"version": "0.9.27",
|
||||||
"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",
|
||||||
|
|
|
@ -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.25",
|
"version": "0.9.27",
|
||||||
"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",
|
||||||
|
|
|
@ -37,3 +37,9 @@
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.spectrum-Radio-input {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "0.9.25",
|
"version": "0.9.27",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -65,10 +65,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^0.9.25",
|
"@budibase/bbui": "^0.9.27",
|
||||||
"@budibase/client": "^0.9.25",
|
"@budibase/client": "^0.9.27",
|
||||||
"@budibase/colorpicker": "1.1.2",
|
"@budibase/colorpicker": "1.1.2",
|
||||||
"@budibase/string-templates": "^0.9.25",
|
"@budibase/string-templates": "^0.9.27",
|
||||||
"@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",
|
||||||
|
|
|
@ -136,7 +136,7 @@ const getContextBindings = (asset, componentId) => {
|
||||||
if (!datasource) {
|
if (!datasource) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const info = getSchemaForDatasource(datasource)
|
const info = getSchemaForDatasource(asset, datasource)
|
||||||
schema = info.schema
|
schema = info.schema
|
||||||
readablePrefix = info.table?.name
|
readablePrefix = info.table?.name
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ const getContextBindings = (asset, componentId) => {
|
||||||
*/
|
*/
|
||||||
const getUserBindings = () => {
|
const getUserBindings = () => {
|
||||||
let bindings = []
|
let bindings = []
|
||||||
const { schema } = getSchemaForDatasource({
|
const { schema } = getSchemaForDatasource(null, {
|
||||||
type: "table",
|
type: "table",
|
||||||
tableId: TableNames.USERS,
|
tableId: TableNames.USERS,
|
||||||
})
|
})
|
||||||
|
@ -244,11 +244,15 @@ const getUrlBindings = asset => {
|
||||||
/**
|
/**
|
||||||
* Gets a schema for a datasource object.
|
* Gets a schema for a datasource object.
|
||||||
*/
|
*/
|
||||||
export const getSchemaForDatasource = (datasource, isForm = false) => {
|
export const getSchemaForDatasource = (asset, datasource, isForm = false) => {
|
||||||
let schema, table
|
let schema, table
|
||||||
if (datasource) {
|
if (datasource) {
|
||||||
const { type } = datasource
|
const { type } = datasource
|
||||||
if (type === "query") {
|
if (type === "provider") {
|
||||||
|
const component = findComponent(asset.props, datasource.providerId)
|
||||||
|
const source = getDatasourceForProvider(asset, component)
|
||||||
|
return getSchemaForDatasource(asset, source, isForm)
|
||||||
|
} else if (type === "query") {
|
||||||
const queries = get(queriesStores).list
|
const queries = get(queriesStores).list
|
||||||
table = queries.find(query => query._id === datasource._id)
|
table = queries.find(query => query._id === datasource._id)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -174,7 +174,7 @@ const fieldTypeToComponentMap = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeDatasourceFormComponents(datasource) {
|
export function makeDatasourceFormComponents(datasource) {
|
||||||
const { schema } = getSchemaForDatasource(datasource, true)
|
const { schema } = getSchemaForDatasource(null, datasource, true)
|
||||||
let components = []
|
let components = []
|
||||||
let fields = Object.keys(schema || {})
|
let fields = Object.keys(schema || {})
|
||||||
fields.forEach(field => {
|
fields.forEach(field => {
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let originalName = field.name
|
let originalName = field.name
|
||||||
|
const linkEditDisabled = originalName != null
|
||||||
let primaryDisplay =
|
let primaryDisplay =
|
||||||
$tables.selected.primaryDisplay == null ||
|
$tables.selected.primaryDisplay == null ||
|
||||||
$tables.selected.primaryDisplay === field.name
|
$tables.selected.primaryDisplay === field.name
|
||||||
|
@ -197,7 +198,7 @@
|
||||||
<Input
|
<Input
|
||||||
label="Name"
|
label="Name"
|
||||||
bind:value={field.name}
|
bind:value={field.name}
|
||||||
disabled={uneditable || field.type === LINK_TYPE}
|
disabled={uneditable || (linkEditDisabled && field.type === LINK_TYPE)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
|
@ -284,6 +285,7 @@
|
||||||
{:else if field.type === "link"}
|
{:else if field.type === "link"}
|
||||||
<Select
|
<Select
|
||||||
label="Table"
|
label="Table"
|
||||||
|
disabled={linkEditDisabled}
|
||||||
bind:value={field.tableId}
|
bind:value={field.tableId}
|
||||||
options={tableOptions}
|
options={tableOptions}
|
||||||
getOptionLabel={table => table.name}
|
getOptionLabel={table => table.name}
|
||||||
|
@ -291,7 +293,7 @@
|
||||||
/>
|
/>
|
||||||
{#if relationshipOptions && relationshipOptions.length > 0}
|
{#if relationshipOptions && relationshipOptions.length > 0}
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
disabled={originalName != null}
|
disabled={linkEditDisabled}
|
||||||
label="Define the relationship"
|
label="Define the relationship"
|
||||||
bind:value={field.relationshipType}
|
bind:value={field.relationshipType}
|
||||||
options={relationshipOptions}
|
options={relationshipOptions}
|
||||||
|
@ -299,7 +301,11 @@
|
||||||
getOptionValue={option => option.value}
|
getOptionValue={option => option.value}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
<Input label={`Column name in other table`} bind:value={field.fieldName} />
|
<Input
|
||||||
|
disabled={linkEditDisabled}
|
||||||
|
label={`Column name in other table`}
|
||||||
|
bind:value={field.fieldName}
|
||||||
|
/>
|
||||||
{:else if field.type === FORMULA_TYPE}
|
{:else if field.type === FORMULA_TYPE}
|
||||||
<ModalBindableInput
|
<ModalBindableInput
|
||||||
title="Handlebars Formula"
|
title="Handlebars Formula"
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
"longformfield",
|
"longformfield",
|
||||||
"datetimefield",
|
"datetimefield",
|
||||||
"attachmentfield",
|
"attachmentfield",
|
||||||
"relationshipfield"
|
"relationshipfield",
|
||||||
|
"daterangepicker"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import { getBindableProperties } from "builderStore/dataBinding"
|
import {
|
||||||
|
getBindableProperties,
|
||||||
|
getDataProviderComponents,
|
||||||
|
} from "builderStore/dataBinding"
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Popover,
|
Popover,
|
||||||
|
@ -61,6 +64,17 @@
|
||||||
$currentAsset,
|
$currentAsset,
|
||||||
$store.selectedComponentId
|
$store.selectedComponentId
|
||||||
)
|
)
|
||||||
|
$: dataProviders = getDataProviderComponents(
|
||||||
|
$currentAsset,
|
||||||
|
$store.selectedComponentId
|
||||||
|
).map(provider => ({
|
||||||
|
label: provider._instanceName,
|
||||||
|
name: provider._instanceName,
|
||||||
|
providerId: provider._id,
|
||||||
|
value: `{{ literal [${provider._id}] }}`,
|
||||||
|
type: "provider",
|
||||||
|
schema: provider.schema,
|
||||||
|
}))
|
||||||
$: queryBindableProperties = bindableProperties.map(property => ({
|
$: queryBindableProperties = bindableProperties.map(property => ({
|
||||||
...property,
|
...property,
|
||||||
category: property.type === "instance" ? "Component" : "Table",
|
category: property.type === "instance" ? "Component" : "Table",
|
||||||
|
@ -182,7 +196,20 @@
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
|
<Divider size="S" />
|
||||||
|
<div class="title">
|
||||||
|
<Heading size="XS">Data Providers</Heading>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
{#each dataProviders as provider}
|
||||||
|
<li
|
||||||
|
class:selected={value === provider}
|
||||||
|
on:click={() => handleSelected(provider)}
|
||||||
|
>
|
||||||
|
{provider.label}
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
{#if otherSources?.length}
|
{#if otherSources?.length}
|
||||||
<Divider size="S" />
|
<Divider size="S" />
|
||||||
<div class="title">
|
<div class="title">
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
$currentAsset,
|
$currentAsset,
|
||||||
$store.selectedComponentId
|
$store.selectedComponentId
|
||||||
)
|
)
|
||||||
$: schemaFields = getSchemaFields(parameters?.tableId)
|
$: schemaFields = getSchemaFields($currentAsset, parameters?.tableId)
|
||||||
$: tableOptions = $tables.list || []
|
$: tableOptions = $tables.list || []
|
||||||
|
|
||||||
const getSchemaFields = tableId => {
|
const getSchemaFields = (asset, tableId) => {
|
||||||
const { schema } = getSchemaForDatasource({ type: "table", tableId })
|
const { schema } = getSchemaForDatasource(asset, { type: "table", tableId })
|
||||||
return Object.values(schema || {})
|
return Object.values(schema || {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,13 @@ import ExecuteQuery from "./ExecuteQuery.svelte"
|
||||||
import TriggerAutomation from "./TriggerAutomation.svelte"
|
import TriggerAutomation from "./TriggerAutomation.svelte"
|
||||||
import ValidateForm from "./ValidateForm.svelte"
|
import ValidateForm from "./ValidateForm.svelte"
|
||||||
|
|
||||||
// defines what actions are available, when adding a new one
|
// Defines which actions are available to configure in the front end.
|
||||||
// the component is the setup panel for the action
|
// Unfortunately the "name" property is used as the identifier so please don't
|
||||||
// NOTE that the "name" is used by the client library,
|
// change them.
|
||||||
// so if you want to change it, you must change it client lib too
|
// The client library removes any spaces when processing actions, so they can
|
||||||
|
// be considered as camel case too.
|
||||||
|
// There is technical debt here to sanitize all these and standardise them
|
||||||
|
// across the packages but it's a breaking change to existing apps.
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
name: "Save Row",
|
name: "Save Row",
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
||||||
$: schema = getSchemaForDatasource(datasource).schema
|
$: schema = getSchemaForDatasource($currentAsset, datasource).schema
|
||||||
$: options = Object.keys(schema || {})
|
$: options = Object.keys(schema || {})
|
||||||
$: boundValue = getValidValue(value, options)
|
$: boundValue = getValidValue(value, options)
|
||||||
|
|
||||||
|
|
|
@ -27,19 +27,16 @@
|
||||||
? tempValue.length
|
? tempValue.length
|
||||||
: Object.keys(tempValue || {}).length
|
: Object.keys(tempValue || {}).length
|
||||||
$: dataSource = getDatasourceForProvider($currentAsset, componentInstance)
|
$: dataSource = getDatasourceForProvider($currentAsset, componentInstance)
|
||||||
$: schema = getSchemaForDatasource(dataSource)?.schema
|
$: schema = getSchemaForDatasource($currentAsset, dataSource)?.schema
|
||||||
$: schemaFields = Object.values(schema || {})
|
$: schemaFields = Object.values(schema || {})
|
||||||
$: internalTable = dataSource?.type === "table"
|
$: internalTable = dataSource?.type === "table"
|
||||||
|
|
||||||
// Reset value if value is wrong type for the datasource.
|
// Reset value if value is wrong type for the datasource.
|
||||||
// Lucene editor needs an array, and simple editor needs an object.
|
// Lucene editor needs an array, and simple editor needs an object.
|
||||||
$: {
|
$: {
|
||||||
if (internalTable && !Array.isArray(value)) {
|
if (!Array.isArray(value)) {
|
||||||
tempValue = []
|
tempValue = []
|
||||||
dispatch("change", [])
|
dispatch("change", [])
|
||||||
} else if (!internalTable && Array.isArray(value)) {
|
|
||||||
tempValue = {}
|
|
||||||
dispatch("change", {})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,28 +60,7 @@
|
||||||
constaints.
|
constaints.
|
||||||
{/if}
|
{/if}
|
||||||
</Body>
|
</Body>
|
||||||
{#if internalTable}
|
|
||||||
<LuceneFilterBuilder bind:value={tempValue} {schemaFields} />
|
<LuceneFilterBuilder bind:value={tempValue} {schemaFields} />
|
||||||
{:else}
|
|
||||||
<div class="fields">
|
|
||||||
<SaveFields
|
|
||||||
parameterFields={Array.isArray(value) ? {} : value}
|
|
||||||
{schemaFields}
|
|
||||||
valueLabel="Equals"
|
|
||||||
on:change={e => (tempValue = e.detail)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
</DrawerContent>
|
</DrawerContent>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
||||||
<style>
|
|
||||||
.fields {
|
|
||||||
display: grid;
|
|
||||||
column-gap: var(--spacing-l);
|
|
||||||
row-gap: var(--spacing-s);
|
|
||||||
align-items: center;
|
|
||||||
grid-template-columns: auto 1fr auto 1fr auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
component => component._component === "@budibase/standard-components/form"
|
component => component._component === "@budibase/standard-components/form"
|
||||||
)
|
)
|
||||||
$: datasource = getDatasourceForProvider($currentAsset, form)
|
$: datasource = getDatasourceForProvider($currentAsset, form)
|
||||||
$: schema = getSchemaForDatasource(datasource, true).schema
|
$: schema = getSchemaForDatasource($currentAsset, datasource, true).schema
|
||||||
$: options = getOptions(schema, type)
|
$: options = getOptions(schema, type)
|
||||||
|
|
||||||
const getOptions = (schema, fieldType) => {
|
const getOptions = (schema, fieldType) => {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
||||||
$: schema = getSchemaForDatasource(datasource).schema
|
$: schema = getSchemaForDatasource($currentAsset, datasource).schema
|
||||||
$: options = Object.keys(schema || {})
|
$: options = Object.keys(schema || {})
|
||||||
$: boundValue = getValidOptions(value, options)
|
$: boundValue = getValidOptions(value, options)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/cli",
|
"name": "@budibase/cli",
|
||||||
"version": "0.9.25",
|
"version": "0.9.27",
|
||||||
"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": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "0.9.25",
|
"version": "0.9.27",
|
||||||
"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,13 +18,13 @@
|
||||||
"dev:builder": "rollup -cw"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/string-templates": "^0.9.25",
|
"@budibase/string-templates": "^0.9.27",
|
||||||
"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": {
|
||||||
"@budibase/standard-components": "^0.9.25",
|
"@budibase/standard-components": "^0.9.27",
|
||||||
"@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",
|
||||||
"fs-extra": "^8.1.0",
|
"fs-extra": "^8.1.0",
|
||||||
|
|
|
@ -55,13 +55,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enriches any string component props using handlebars
|
// Enriches any string component props using handlebars
|
||||||
const updateComponentProps = async (definition, context) => {
|
const updateComponentProps = (definition, context) => {
|
||||||
// Record the timestamp so we can reference it after enrichment
|
// Record the timestamp so we can reference it after enrichment
|
||||||
latestUpdateTime = Date.now()
|
latestUpdateTime = Date.now()
|
||||||
const enrichmentTime = latestUpdateTime
|
const enrichmentTime = latestUpdateTime
|
||||||
|
|
||||||
// Enrich props with context
|
// Enrich props with context
|
||||||
const enrichedProps = await enrichProps(definition, context)
|
const enrichedProps = enrichProps(definition, context)
|
||||||
|
|
||||||
// Abandon this update if a newer update has started
|
// Abandon this update if a newer update has started
|
||||||
if (enrichmentTime !== latestUpdateTime) {
|
if (enrichmentTime !== latestUpdateTime) {
|
||||||
|
|
|
@ -5,4 +5,5 @@ export const TableNames = {
|
||||||
export const ActionTypes = {
|
export const ActionTypes = {
|
||||||
ValidateForm: "ValidateForm",
|
ValidateForm: "ValidateForm",
|
||||||
RefreshDatasource: "RefreshDatasource",
|
RefreshDatasource: "RefreshDatasource",
|
||||||
|
SetDataProviderQuery: "SetDataProviderQuery",
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
import { styleable } from "./utils/styleable"
|
import { styleable } from "./utils/styleable"
|
||||||
import transition from "./utils/transition"
|
import transition from "./utils/transition"
|
||||||
import { linkable } from "./utils/linkable"
|
import { linkable } from "./utils/linkable"
|
||||||
|
import { getAction } from "./utils/getAction"
|
||||||
import Provider from "./components/Provider.svelte"
|
import Provider from "./components/Provider.svelte"
|
||||||
import { ActionTypes } from "./constants"
|
import { ActionTypes } from "./constants"
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ export default {
|
||||||
styleable,
|
styleable,
|
||||||
transition,
|
transition,
|
||||||
linkable,
|
linkable,
|
||||||
|
getAction,
|
||||||
Provider,
|
Provider,
|
||||||
ActionTypes,
|
ActionTypes,
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ export const propsAreSame = (a, b) => {
|
||||||
* Enriches component props.
|
* Enriches component props.
|
||||||
* Data bindings are enriched, and button actions are enriched.
|
* Data bindings are enriched, and button actions are enriched.
|
||||||
*/
|
*/
|
||||||
export const enrichProps = async (props, context) => {
|
export const enrichProps = (props, context) => {
|
||||||
// Exclude all private props that start with an underscore
|
// Exclude all private props that start with an underscore
|
||||||
let validProps = {}
|
let validProps = {}
|
||||||
Object.entries(props)
|
Object.entries(props)
|
||||||
|
@ -41,7 +41,7 @@ export const enrichProps = async (props, context) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enrich all data bindings in top level props
|
// Enrich all data bindings in top level props
|
||||||
let enrichedProps = await enrichDataBindings(validProps, totalContext)
|
let enrichedProps = enrichDataBindings(validProps, totalContext)
|
||||||
|
|
||||||
// Enrich click actions if they exist
|
// Enrich click actions if they exist
|
||||||
if (enrichedProps.onClick) {
|
if (enrichedProps.onClick) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import { processString, processObject } from "@budibase/string-templates"
|
import { processString, processObjectSync } from "@budibase/string-templates"
|
||||||
|
|
||||||
// Regex to test inputs with to see if they are likely candidates for template strings
|
// Regex to test inputs with to see if they are likely candidates for template strings
|
||||||
const looksLikeTemplate = /{{.*}}/
|
const looksLikeTemplate = /{{.*}}/
|
||||||
|
@ -23,6 +23,6 @@ export const enrichDataBinding = async (input, context) => {
|
||||||
* Recursively enriches all props in a props object and returns the new props.
|
* Recursively enriches all props in a props object and returns the new props.
|
||||||
* Props are deeply cloned so that no mutation is done to the source object.
|
* Props are deeply cloned so that no mutation is done to the source object.
|
||||||
*/
|
*/
|
||||||
export const enrichDataBindings = async (props, context) => {
|
export const enrichDataBindings = (props, context) => {
|
||||||
return await processObject(cloneDeep(props), context)
|
return processObjectSync(cloneDeep(props), context)
|
||||||
}
|
}
|
||||||
|
|
19
packages/client/src/utils/getAction.js
Normal file
19
packages/client/src/utils/getAction.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { get } from "svelte/store"
|
||||||
|
import { getContext } from "svelte"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a component action.
|
||||||
|
* @param id The component ID that provides the action
|
||||||
|
* @param type The action type to get
|
||||||
|
* @returns {null|*} The action function
|
||||||
|
*/
|
||||||
|
export const getAction = (id, type) => {
|
||||||
|
if (!id || !type) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const context = getContext("context")
|
||||||
|
if (!context) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return get(context)?.[`${id}_${type}`]
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/server",
|
"name": "@budibase/server",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.9.25",
|
"version": "0.9.27",
|
||||||
"description": "Budibase Web Server",
|
"description": "Budibase Web Server",
|
||||||
"main": "src/electron.js",
|
"main": "src/electron.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -55,9 +55,9 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/auth": "^0.9.25",
|
"@budibase/auth": "^0.9.27",
|
||||||
"@budibase/client": "^0.9.25",
|
"@budibase/client": "^0.9.27",
|
||||||
"@budibase/string-templates": "^0.9.25",
|
"@budibase/string-templates": "^0.9.27",
|
||||||
"@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",
|
||||||
|
@ -110,7 +110,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.25",
|
"@budibase/standard-components": "^0.9.27",
|
||||||
"@jest/test-sequencer": "^24.8.0",
|
"@jest/test-sequencer": "^24.8.0",
|
||||||
"babel-jest": "^27.0.2",
|
"babel-jest": "^27.0.2",
|
||||||
"docker-compose": "^0.23.6",
|
"docker-compose": "^0.23.6",
|
||||||
|
|
|
@ -99,12 +99,18 @@ async function createInstance(template) {
|
||||||
// replicate the template data to the instance DB
|
// replicate the template data to the instance DB
|
||||||
// this is currently very hard to test, downloading and importing template files
|
// this is currently very hard to test, downloading and importing template files
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
|
let _rev
|
||||||
if (template && template.useTemplate === "true") {
|
if (template && template.useTemplate === "true") {
|
||||||
const { ok } = await db.load(await getTemplateStream(template))
|
const { ok } = await db.load(await getTemplateStream(template))
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
throw "Error loading database dump from template."
|
throw "Error loading database dump from template."
|
||||||
}
|
}
|
||||||
var { _rev } = await db.get(DocumentTypes.APP_METADATA)
|
try {
|
||||||
|
const response = await db.get(DocumentTypes.APP_METADATA)
|
||||||
|
_rev = response._rev
|
||||||
|
} catch (err) {
|
||||||
|
_rev = null
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// create the users table
|
// create the users table
|
||||||
await db.put(USERS_TABLE_SCHEMA)
|
await db.put(USERS_TABLE_SCHEMA)
|
||||||
|
|
|
@ -169,9 +169,14 @@ exports.inputProcessing = (user = {}, table, row) => {
|
||||||
let clonedRow = cloneDeep(row)
|
let clonedRow = cloneDeep(row)
|
||||||
// need to copy the table so it can be differenced on way out
|
// need to copy the table so it can be differenced on way out
|
||||||
const copiedTable = cloneDeep(table)
|
const copiedTable = cloneDeep(table)
|
||||||
|
const dontCleanseKeys = ["type", "_id", "_rev", "tableId"]
|
||||||
for (let [key, value] of Object.entries(clonedRow)) {
|
for (let [key, value] of Object.entries(clonedRow)) {
|
||||||
const field = table.schema[key]
|
const field = table.schema[key]
|
||||||
|
// cleanse fields that aren't in the schema
|
||||||
if (!field) {
|
if (!field) {
|
||||||
|
if (dontCleanseKeys.indexOf(key) === -1) {
|
||||||
|
delete clonedRow[key]
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
clonedRow[key] = exports.coerce(value, field.type)
|
clonedRow[key] = exports.coerce(value, field.type)
|
||||||
|
|
|
@ -1505,5 +1505,38 @@
|
||||||
"context": {
|
"context": {
|
||||||
"type": "schema"
|
"type": "schema"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"daterangepicker": {
|
||||||
|
"name": "Date Range",
|
||||||
|
"icon": "Date",
|
||||||
|
"styleable": true,
|
||||||
|
"hasChildren": false,
|
||||||
|
"info": "Your data provider will be automatically filtered to the given date range.",
|
||||||
|
"settings": [
|
||||||
|
{
|
||||||
|
"type": "dataProvider",
|
||||||
|
"label": "Provider",
|
||||||
|
"key": "dataProvider"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "field",
|
||||||
|
"label": "Date field",
|
||||||
|
"key": "field"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "select",
|
||||||
|
"label": "Default range",
|
||||||
|
"key": "defaultValue",
|
||||||
|
"options": [
|
||||||
|
"Last 1 day",
|
||||||
|
"Last 7 days",
|
||||||
|
"Last 30 days",
|
||||||
|
"Last 3 months",
|
||||||
|
"Last 6 months",
|
||||||
|
"Last 1 year"
|
||||||
|
],
|
||||||
|
"defaultValue": "Last 30 days"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,14 +29,15 @@
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"svelte"
|
"svelte"
|
||||||
],
|
],
|
||||||
"version": "0.9.25",
|
"version": "0.9.27",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc",
|
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^0.9.25",
|
"@budibase/bbui": "^0.9.27",
|
||||||
"@spectrum-css/page": "^3.0.1",
|
"@spectrum-css/page": "^3.0.1",
|
||||||
"@spectrum-css/vars": "^3.0.1",
|
"@spectrum-css/vars": "^3.0.1",
|
||||||
"apexcharts": "^3.22.1",
|
"apexcharts": "^3.22.1",
|
||||||
|
"dayjs": "^1.10.5",
|
||||||
"svelte-apexcharts": "^1.0.2",
|
"svelte-apexcharts": "^1.0.2",
|
||||||
"svelte-flatpickr": "^3.1.0"
|
"svelte-flatpickr": "^3.1.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { ProgressCircle, Pagination } from "@budibase/bbui"
|
import { ProgressCircle, Pagination } from "@budibase/bbui"
|
||||||
|
import {
|
||||||
|
buildLuceneQuery,
|
||||||
|
luceneQuery,
|
||||||
|
luceneSort,
|
||||||
|
luceneLimit,
|
||||||
|
} from "./lucene"
|
||||||
|
|
||||||
export let dataSource
|
export let dataSource
|
||||||
export let filter
|
export let filter
|
||||||
|
@ -25,9 +31,11 @@
|
||||||
let schema = {}
|
let schema = {}
|
||||||
let bookmarks = [null]
|
let bookmarks = [null]
|
||||||
let pageNumber = 0
|
let pageNumber = 0
|
||||||
|
let query = null
|
||||||
|
|
||||||
|
$: query = buildLuceneQuery(filter)
|
||||||
$: internalTable = dataSource?.type === "table"
|
$: internalTable = dataSource?.type === "table"
|
||||||
$: query = internalTable ? buildLuceneQuery(filter) : null
|
$: nestedProvider = dataSource?.type === "provider"
|
||||||
$: hasNextPage = bookmarks[pageNumber + 1] != null
|
$: hasNextPage = bookmarks[pageNumber + 1] != null
|
||||||
$: hasPrevPage = pageNumber > 0
|
$: hasPrevPage = pageNumber > 0
|
||||||
$: getSchema(dataSource)
|
$: getSchema(dataSource)
|
||||||
|
@ -48,22 +56,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$: {
|
$: {
|
||||||
// Sort and limit rows in memory when we aren't searching internal tables
|
|
||||||
if (internalTable) {
|
if (internalTable) {
|
||||||
|
// Internal tables are already processed server-side
|
||||||
rows = allRows
|
rows = allRows
|
||||||
} else {
|
} else {
|
||||||
const sortedRows = sortRows(allRows, sortColumn, sortOrder)
|
// For anything else we use client-side implementations to filter, sort
|
||||||
rows = limitRows(sortedRows, limit)
|
// and limit
|
||||||
|
const filtered = luceneQuery(allRows, query)
|
||||||
|
const sorted = luceneSort(filtered, sortColumn, sortOrder, sortType)
|
||||||
|
rows = luceneLimit(sorted, limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$: actions = [
|
$: actions = [
|
||||||
{
|
{
|
||||||
type: ActionTypes.RefreshDatasource,
|
type: ActionTypes.RefreshDatasource,
|
||||||
callback: () => fetchData(dataSource),
|
callback: () => refresh(),
|
||||||
metadata: { dataSource },
|
metadata: { dataSource },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: ActionTypes.SetDataProviderQuery,
|
||||||
|
callback: newQuery => (query = newQuery),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
$: dataContext = { rows, schema, rowsLength: rows.length }
|
$: dataContext = {
|
||||||
|
rows,
|
||||||
|
schema,
|
||||||
|
rowsLength: rows.length,
|
||||||
|
|
||||||
|
// Undocumented properties. These aren't supposed to be used in builder
|
||||||
|
// bindings, but are used internally by other components
|
||||||
|
id: $component?.id,
|
||||||
|
state: { query },
|
||||||
|
}
|
||||||
|
|
||||||
const getSortType = (schema, sortColumn) => {
|
const getSortType = (schema, sortColumn) => {
|
||||||
if (!schema || !sortColumn || !schema[sortColumn]) {
|
if (!schema || !sortColumn || !schema[sortColumn]) {
|
||||||
|
@ -73,36 +97,18 @@
|
||||||
return type === "number" ? "number" : "string"
|
return type === "number" ? "number" : "string"
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildLuceneQuery = filter => {
|
const refresh = async () => {
|
||||||
let query = {
|
if (schemaLoaded && !nestedProvider) {
|
||||||
string: {},
|
fetchData(
|
||||||
fuzzy: {},
|
dataSource,
|
||||||
range: {},
|
query,
|
||||||
equal: {},
|
limit,
|
||||||
notEqual: {},
|
sortColumn,
|
||||||
empty: {},
|
sortOrder,
|
||||||
notEmpty: {},
|
sortType,
|
||||||
|
paginate
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (Array.isArray(filter)) {
|
|
||||||
filter.forEach(({ operator, field, type, value }) => {
|
|
||||||
if (operator.startsWith("range")) {
|
|
||||||
if (!query.range[field]) {
|
|
||||||
query.range[field] = {
|
|
||||||
low: type === "number" ? Number.MIN_SAFE_INTEGER : "0000",
|
|
||||||
high: type === "number" ? Number.MAX_SAFE_INTEGER : "9999",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (operator === "rangeLow") {
|
|
||||||
query.range[field].low = value
|
|
||||||
} else if (operator === "rangeHigh") {
|
|
||||||
query.range[field].high = value
|
|
||||||
}
|
|
||||||
} else if (query[operator]) {
|
|
||||||
query[operator][field] = value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return query
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchData = async (
|
const fetchData = async (
|
||||||
|
@ -116,6 +122,7 @@
|
||||||
) => {
|
) => {
|
||||||
loading = true
|
loading = true
|
||||||
if (dataSource?.type === "table") {
|
if (dataSource?.type === "table") {
|
||||||
|
// For internal tables we use server-side processing
|
||||||
const res = await API.searchTable({
|
const res = await API.searchTable({
|
||||||
tableId: dataSource.tableId,
|
tableId: dataSource.tableId,
|
||||||
query,
|
query,
|
||||||
|
@ -132,55 +139,27 @@
|
||||||
} else {
|
} else {
|
||||||
bookmarks = [null]
|
bookmarks = [null]
|
||||||
}
|
}
|
||||||
|
} else if (dataSource?.type === "provider") {
|
||||||
|
// For providers referencing another provider, just use the rows it
|
||||||
|
// provides
|
||||||
|
allRows = dataSource?.value?.rows ?? []
|
||||||
} else {
|
} else {
|
||||||
const rows = await API.fetchDatasource(dataSource)
|
// For other data sources like queries or views, fetch all rows from the
|
||||||
allRows = inMemoryFilterRows(rows, filter)
|
// server
|
||||||
|
allRows = await API.fetchDatasource(dataSource)
|
||||||
}
|
}
|
||||||
loading = false
|
loading = false
|
||||||
loaded = true
|
loaded = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const inMemoryFilterRows = (rows, filter) => {
|
|
||||||
let filteredData = [...rows]
|
|
||||||
Object.entries(filter || {}).forEach(([field, value]) => {
|
|
||||||
if (value != null && value !== "") {
|
|
||||||
filteredData = filteredData.filter(row => {
|
|
||||||
return row[field] === value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return filteredData
|
|
||||||
}
|
|
||||||
|
|
||||||
const sortRows = (rows, sortColumn, sortOrder) => {
|
|
||||||
if (!sortColumn || !sortOrder) {
|
|
||||||
return rows
|
|
||||||
}
|
|
||||||
return rows.slice().sort((a, b) => {
|
|
||||||
const colA = a[sortColumn]
|
|
||||||
const colB = b[sortColumn]
|
|
||||||
if (sortOrder === "Descending") {
|
|
||||||
return colA > colB ? -1 : 1
|
|
||||||
} else {
|
|
||||||
return colA > colB ? 1 : -1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const limitRows = (rows, limit) => {
|
|
||||||
const numLimit = parseFloat(limit)
|
|
||||||
if (isNaN(numLimit)) {
|
|
||||||
return rows
|
|
||||||
}
|
|
||||||
return rows.slice(0, numLimit)
|
|
||||||
}
|
|
||||||
|
|
||||||
const getSchema = async dataSource => {
|
const getSchema = async dataSource => {
|
||||||
if (dataSource?.schema) {
|
if (dataSource?.schema) {
|
||||||
schema = dataSource.schema
|
schema = dataSource.schema
|
||||||
} else if (dataSource?.tableId) {
|
} else if (dataSource?.tableId) {
|
||||||
const definition = await API.fetchTableDefinition(dataSource.tableId)
|
const definition = await API.fetchTableDefinition(dataSource.tableId)
|
||||||
schema = definition?.schema ?? {}
|
schema = definition?.schema ?? {}
|
||||||
|
} else if (dataSource?.type === "provider") {
|
||||||
|
schema = dataSource.value?.schema ?? {}
|
||||||
} else {
|
} else {
|
||||||
schema = {}
|
schema = {}
|
||||||
}
|
}
|
||||||
|
|
77
packages/standard-components/src/DateRangePicker.svelte
Normal file
77
packages/standard-components/src/DateRangePicker.svelte
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
<script>
|
||||||
|
import { Select } from "@budibase/bbui"
|
||||||
|
import { getContext } from "svelte"
|
||||||
|
import dayjs from "dayjs"
|
||||||
|
import utc from "dayjs/plugin/utc"
|
||||||
|
import { onMount } from "svelte"
|
||||||
|
|
||||||
|
dayjs.extend(utc)
|
||||||
|
|
||||||
|
export let dataProvider
|
||||||
|
export let field
|
||||||
|
export let defaultValue
|
||||||
|
|
||||||
|
const dataContext = getContext("context")
|
||||||
|
const component = getContext("component")
|
||||||
|
const { styleable, builderStore, ActionTypes, getAction } = getContext("sdk")
|
||||||
|
|
||||||
|
const setQuery = getAction(dataProvider?.id, ActionTypes.SetDataProviderQuery)
|
||||||
|
const options = [
|
||||||
|
"Last 1 day",
|
||||||
|
"Last 7 days",
|
||||||
|
"Last 30 days",
|
||||||
|
"Last 3 months",
|
||||||
|
"Last 6 months",
|
||||||
|
"Last 1 year",
|
||||||
|
]
|
||||||
|
let value = options.includes(defaultValue) ? defaultValue : "Last 30 days"
|
||||||
|
|
||||||
|
const updateDateRange = option => {
|
||||||
|
const query = dataProvider?.state?.query
|
||||||
|
if (!query || !setQuery) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
value = option
|
||||||
|
let low = dayjs.utc().subtract(1, "year")
|
||||||
|
let high = dayjs.utc().add(1, "day")
|
||||||
|
|
||||||
|
if (option === "Last 1 day") {
|
||||||
|
low = dayjs.utc().subtract(1, "day")
|
||||||
|
} else if (option === "Last 7 days") {
|
||||||
|
low = dayjs.utc().subtract(7, "days")
|
||||||
|
} else if (option === "Last 30 days") {
|
||||||
|
low = dayjs.utc().subtract(30, "days")
|
||||||
|
} else if (option === "Last 3 months") {
|
||||||
|
low = dayjs.utc().subtract(3, "months")
|
||||||
|
} else if (option === "Last 6 months") {
|
||||||
|
low = dayjs.utc().subtract(6, "months")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update data provider query with the new filter
|
||||||
|
setQuery({
|
||||||
|
...query,
|
||||||
|
range: {
|
||||||
|
...query.range,
|
||||||
|
[field]: {
|
||||||
|
high: high.format(),
|
||||||
|
low: low.format(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the range on mount to the initial value
|
||||||
|
onMount(() => {
|
||||||
|
updateDateRange(value)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div use:styleable={$component.styles}>
|
||||||
|
<Select
|
||||||
|
placeholder={null}
|
||||||
|
{options}
|
||||||
|
{value}
|
||||||
|
on:change={e => updateDateRange(e.detail)}
|
||||||
|
/>
|
||||||
|
</div>
|
|
@ -22,6 +22,7 @@
|
||||||
>
|
>
|
||||||
{#if fieldState}
|
{#if fieldState}
|
||||||
<CoreTextField
|
<CoreTextField
|
||||||
|
updateOnChange={false}
|
||||||
value={$fieldState.value}
|
value={$fieldState.value}
|
||||||
on:change={e => fieldApi.setValue(e.detail)}
|
on:change={e => fieldApi.setValue(e.detail)}
|
||||||
disabled={$fieldState.disabled}
|
disabled={$fieldState.disabled}
|
||||||
|
|
|
@ -27,6 +27,7 @@ export { default as cardhorizontal } from "./CardHorizontal.svelte"
|
||||||
export { default as cardstat } from "./CardStat.svelte"
|
export { default as cardstat } from "./CardStat.svelte"
|
||||||
export { default as icon } from "./Icon.svelte"
|
export { default as icon } from "./Icon.svelte"
|
||||||
export { default as backgroundimage } from "./BackgroundImage.svelte"
|
export { default as backgroundimage } from "./BackgroundImage.svelte"
|
||||||
|
export { default as daterangepicker } from "./DateRangePicker.svelte"
|
||||||
export * from "./charts"
|
export * from "./charts"
|
||||||
export * from "./forms"
|
export * from "./forms"
|
||||||
export * from "./table"
|
export * from "./table"
|
||||||
|
|
146
packages/standard-components/src/lucene.js
Normal file
146
packages/standard-components/src/lucene.js
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
/**
|
||||||
|
* Builds a lucene JSON query from the filter structure generated in the builder
|
||||||
|
* @param filter the builder filter structure
|
||||||
|
*/
|
||||||
|
export const buildLuceneQuery = filter => {
|
||||||
|
let query = {
|
||||||
|
string: {},
|
||||||
|
fuzzy: {},
|
||||||
|
range: {},
|
||||||
|
equal: {},
|
||||||
|
notEqual: {},
|
||||||
|
empty: {},
|
||||||
|
notEmpty: {},
|
||||||
|
}
|
||||||
|
if (Array.isArray(filter)) {
|
||||||
|
filter.forEach(({ operator, field, type, value }) => {
|
||||||
|
if (operator.startsWith("range")) {
|
||||||
|
if (!query.range[field]) {
|
||||||
|
query.range[field] = {
|
||||||
|
low:
|
||||||
|
type === "number"
|
||||||
|
? Number.MIN_SAFE_INTEGER
|
||||||
|
: "0000-00-00T00:00:00.000Z",
|
||||||
|
high:
|
||||||
|
type === "number"
|
||||||
|
? Number.MAX_SAFE_INTEGER
|
||||||
|
: "9999-00-00T00:00:00.000Z",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (operator === "rangeLow" && value != null && value !== "") {
|
||||||
|
query.range[field].low = value
|
||||||
|
} else if (operator === "rangeHigh" && value != null && value !== "") {
|
||||||
|
query.range[field].high = value
|
||||||
|
}
|
||||||
|
} else if (query[operator]) {
|
||||||
|
query[operator][field] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a client-side lucene search on an array of data
|
||||||
|
* @param docs the data
|
||||||
|
* @param query the JSON lucene query
|
||||||
|
*/
|
||||||
|
export const luceneQuery = (docs, query) => {
|
||||||
|
if (!query) {
|
||||||
|
return docs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterates over a set of filters and evaluates a fail function against a doc
|
||||||
|
const match = (type, failFn) => doc => {
|
||||||
|
const filters = Object.entries(query[type] || {})
|
||||||
|
for (let i = 0; i < filters.length; i++) {
|
||||||
|
if (failFn(filters[i][0], filters[i][1], doc)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process a string match (fails if the value does not start with the string)
|
||||||
|
const stringMatch = match("string", (key, value, doc) => {
|
||||||
|
return !doc[key] || !doc[key].startsWith(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Process a range match
|
||||||
|
const rangeMatch = match("range", (key, value, doc) => {
|
||||||
|
return !doc[key] || doc[key] < value.low || doc[key] > value.high
|
||||||
|
})
|
||||||
|
|
||||||
|
// Process an equal match (fails if the value is different)
|
||||||
|
const equalMatch = match("equal", (key, value, doc) => {
|
||||||
|
return doc[key] !== value
|
||||||
|
})
|
||||||
|
|
||||||
|
// Process a not-equal match (fails if the value is the same)
|
||||||
|
const notEqualMatch = match("notEqual", (key, value, doc) => {
|
||||||
|
return doc[key] === value
|
||||||
|
})
|
||||||
|
|
||||||
|
// Process an empty match (fails if the value is not empty)
|
||||||
|
const emptyMatch = match("empty", (key, value, doc) => {
|
||||||
|
return doc[key] != null && doc[key] !== ""
|
||||||
|
})
|
||||||
|
|
||||||
|
// Process a not-empty match (fails is the value is empty)
|
||||||
|
const notEmptyMatch = match("notEmpty", (key, value, doc) => {
|
||||||
|
return doc[key] == null || doc[key] === ""
|
||||||
|
})
|
||||||
|
|
||||||
|
// Match a document against all criteria
|
||||||
|
const docMatch = doc => {
|
||||||
|
return (
|
||||||
|
stringMatch(doc) &&
|
||||||
|
rangeMatch(doc) &&
|
||||||
|
equalMatch(doc) &&
|
||||||
|
notEqualMatch(doc) &&
|
||||||
|
emptyMatch(doc) &&
|
||||||
|
notEmptyMatch(doc)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process all docs
|
||||||
|
return docs.filter(docMatch)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a client-side sort from the equivalent server-side lucene sort
|
||||||
|
* parameters.
|
||||||
|
* @param docs the data
|
||||||
|
* @param sort the sort column
|
||||||
|
* @param sortOrder the sort order ("ascending" or "descending")
|
||||||
|
* @param sortType the type of sort ("string" or "number")
|
||||||
|
*/
|
||||||
|
export const luceneSort = (docs, sort, sortOrder, sortType = "string") => {
|
||||||
|
if (!sort || !sortOrder || !sortType) {
|
||||||
|
return docs
|
||||||
|
}
|
||||||
|
const parse = sortType === "string" ? x => `${x}` : x => parseFloat(x)
|
||||||
|
return docs.slice().sort((a, b) => {
|
||||||
|
const colA = parse(a[sort])
|
||||||
|
const colB = parse(b[sort])
|
||||||
|
if (sortOrder === "Descending") {
|
||||||
|
return colA > colB ? -1 : 1
|
||||||
|
} else {
|
||||||
|
return colA > colB ? 1 : -1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limits the specified docs to the specified number of rows from the equivalent
|
||||||
|
* server-side lucene limit parameters.
|
||||||
|
* @param docs the data
|
||||||
|
* @param limit the number of docs to limit to
|
||||||
|
*/
|
||||||
|
export const luceneLimit = (docs, limit) => {
|
||||||
|
const numLimit = parseFloat(limit)
|
||||||
|
if (isNaN(numLimit)) {
|
||||||
|
return docs
|
||||||
|
}
|
||||||
|
return docs.slice(0, numLimit)
|
||||||
|
}
|
|
@ -2,6 +2,59 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@adobe/spectrum-css-workflow-icons@^1.2.1":
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@adobe/spectrum-css-workflow-icons/-/spectrum-css-workflow-icons-1.2.1.tgz#7e2cb3fcfb5c8b12d7275afafbb6ec44913551b4"
|
||||||
|
integrity sha512-uVgekyBXnOVkxp+CUssjN/gefARtudZC8duEn1vm0lBQFwGRZFlDEzU1QC+aIRWCrD1Z8OgRpmBYlSZ7QS003w==
|
||||||
|
|
||||||
|
"@budibase/bbui@^0.9.12":
|
||||||
|
version "0.9.16"
|
||||||
|
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.16.tgz#6cf454790d3e8d776d4d642379958a56260b0840"
|
||||||
|
integrity sha512-8hV4Vj3h3clzLclNTvVxPdOK9f02xTIcXA/lW1QPD9HZLOUxDogphujpDpb+E0/NevPlPYMHaX68kVtefNL5Jw==
|
||||||
|
dependencies:
|
||||||
|
"@adobe/spectrum-css-workflow-icons" "^1.2.1"
|
||||||
|
"@spectrum-css/actionbutton" "^1.0.1"
|
||||||
|
"@spectrum-css/actiongroup" "^1.0.1"
|
||||||
|
"@spectrum-css/avatar" "^3.0.2"
|
||||||
|
"@spectrum-css/button" "^3.0.1"
|
||||||
|
"@spectrum-css/buttongroup" "^3.0.2"
|
||||||
|
"@spectrum-css/checkbox" "^3.0.2"
|
||||||
|
"@spectrum-css/dialog" "^3.0.1"
|
||||||
|
"@spectrum-css/divider" "^1.0.1"
|
||||||
|
"@spectrum-css/dropzone" "^3.0.2"
|
||||||
|
"@spectrum-css/fieldgroup" "^3.0.2"
|
||||||
|
"@spectrum-css/fieldlabel" "^3.0.1"
|
||||||
|
"@spectrum-css/icon" "^3.0.1"
|
||||||
|
"@spectrum-css/illustratedmessage" "^3.0.2"
|
||||||
|
"@spectrum-css/inputgroup" "^3.0.2"
|
||||||
|
"@spectrum-css/label" "^2.0.10"
|
||||||
|
"@spectrum-css/link" "^3.1.1"
|
||||||
|
"@spectrum-css/menu" "^3.0.1"
|
||||||
|
"@spectrum-css/modal" "^3.0.1"
|
||||||
|
"@spectrum-css/pagination" "^3.0.3"
|
||||||
|
"@spectrum-css/picker" "^1.0.1"
|
||||||
|
"@spectrum-css/popover" "^3.0.1"
|
||||||
|
"@spectrum-css/progressbar" "^1.0.2"
|
||||||
|
"@spectrum-css/progresscircle" "^1.0.2"
|
||||||
|
"@spectrum-css/radio" "^3.0.2"
|
||||||
|
"@spectrum-css/search" "^3.0.2"
|
||||||
|
"@spectrum-css/sidenav" "^3.0.2"
|
||||||
|
"@spectrum-css/statuslight" "^3.0.2"
|
||||||
|
"@spectrum-css/switch" "^1.0.2"
|
||||||
|
"@spectrum-css/table" "^3.0.1"
|
||||||
|
"@spectrum-css/tabs" "^3.0.1"
|
||||||
|
"@spectrum-css/tags" "^3.0.2"
|
||||||
|
"@spectrum-css/textfield" "^3.0.1"
|
||||||
|
"@spectrum-css/toast" "^3.0.1"
|
||||||
|
"@spectrum-css/tooltip" "^3.0.3"
|
||||||
|
"@spectrum-css/treeview" "^3.0.2"
|
||||||
|
"@spectrum-css/typography" "^3.0.1"
|
||||||
|
"@spectrum-css/underlay" "^2.0.9"
|
||||||
|
"@spectrum-css/vars" "^3.0.1"
|
||||||
|
dayjs "^1.10.4"
|
||||||
|
svelte-flatpickr "^3.1.0"
|
||||||
|
svelte-portal "^1.0.0"
|
||||||
|
|
||||||
"@rollup/pluginutils@^4.1.0":
|
"@rollup/pluginutils@^4.1.0":
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.0.tgz#0dcc61c780e39257554feb7f77207dceca13c838"
|
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.0.tgz#0dcc61c780e39257554feb7f77207dceca13c838"
|
||||||
|
@ -10,6 +63,98 @@
|
||||||
estree-walker "^2.0.1"
|
estree-walker "^2.0.1"
|
||||||
picomatch "^2.2.2"
|
picomatch "^2.2.2"
|
||||||
|
|
||||||
|
"@spectrum-css/actionbutton@^1.0.1":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/actionbutton/-/actionbutton-1.0.3.tgz#8f7342a69b303c5acdcfa0a59f5e9267b9f3cb30"
|
||||||
|
integrity sha512-P9qoCPSiZ1SB6ZYqK5hub0vGty00YYqonQE0KTjtb1i+T1nYR/87vWqVPERx9j63uhgZncjwFYaThTvRqye7eQ==
|
||||||
|
|
||||||
|
"@spectrum-css/actiongroup@^1.0.1":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/actiongroup/-/actiongroup-1.0.3.tgz#4713ce65e6f5c72c404a7b638fbc3b4fd7e3874f"
|
||||||
|
integrity sha512-NlB9Q4ZlWixXxymoPIYG6g2hkwAGKFodHWPFfxHD8ddkjXWRB9G2akUP7cfsJ4DcYn4VisUORCOYQwqDiSmboQ==
|
||||||
|
|
||||||
|
"@spectrum-css/avatar@^3.0.2":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/avatar/-/avatar-3.0.2.tgz#4f1826223eae330e64b6d3cc899e9bc2e98dac95"
|
||||||
|
integrity sha512-wEczvSqxttTWSiL3cOvXV/RmGRwSkw2w6+slcHhnf0kb7ovymMM+9oz8vvEpEsSeo5u598bc+7ktrKFpAd6soQ==
|
||||||
|
|
||||||
|
"@spectrum-css/button@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/button/-/button-3.0.3.tgz#2df1efaab6c7e0b3b06cb4b59e1eae59c7f1fc84"
|
||||||
|
integrity sha512-6CnLPqqtaU/PcSSIGeGRi0iFIIxIUByYLKFO6zn5NEUc12KQ28dJ4PLwB6WBa0L8vRoAGlnWWH2ZZweTijbXgg==
|
||||||
|
|
||||||
|
"@spectrum-css/buttongroup@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/buttongroup/-/buttongroup-3.0.3.tgz#719d868845ac9d2c4f939c1b9f6044507902d5aa"
|
||||||
|
integrity sha512-eXl8U4QWMWXqyTu654FdQdEGnmczgOYlpIFSHyCMVjhtPqZp2xwnLFiGh6LKw+bLio6eeOZ0L+vpk1GcoYqgkw==
|
||||||
|
|
||||||
|
"@spectrum-css/checkbox@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/checkbox/-/checkbox-3.0.3.tgz#8577067fc8b97e4609f92bd242364937a533a7bb"
|
||||||
|
integrity sha512-QVG9uMHq+lh70Dh6mDNnY+vEvNz2p7VC6xgLfDYfijp2qeiqYPq72fQK6p/SiyqPk96ZACzNRwgeROU6Xf6Wgg==
|
||||||
|
|
||||||
|
"@spectrum-css/dialog@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/dialog/-/dialog-3.0.3.tgz#7715a4ea435e753afb623d99ca5917ed1bcd6f34"
|
||||||
|
integrity sha512-AhmKgfRIVyTe3ABiJ8lLUQL34VB/H6fN16na2LlbDRJvyRMzkdN1Xf2i6U3f4OMd3qQ8Gm5xat4BvMxIQPBAUQ==
|
||||||
|
|
||||||
|
"@spectrum-css/divider@^1.0.1":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/divider/-/divider-1.0.3.tgz#639e2ebaa0834efa40f42397668bbd5c153ea385"
|
||||||
|
integrity sha512-Zy4Rn40w8UtzMh3wx/U9+CepSCpm1aOCGftHgWDub0XZuVTzh0c1WwyzTuLCx2Hf21z5VRGNiDh8bGEEzSbtNA==
|
||||||
|
dependencies:
|
||||||
|
"@spectrum-css/vars" "^3.0.2"
|
||||||
|
|
||||||
|
"@spectrum-css/dropzone@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/dropzone/-/dropzone-3.0.3.tgz#aee71697a2c195947599d7541b858c3c198741dc"
|
||||||
|
integrity sha512-ujrswdtB6bHigklyHsm6zomFd6rUnKJ3xVVRjroVF4+ouK4DxK5tX0iVd0EW6AOfOjx4Cc28uyFot3fpxp+MQw==
|
||||||
|
|
||||||
|
"@spectrum-css/fieldgroup@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/fieldgroup/-/fieldgroup-3.0.3.tgz#85d85da048d08200f25ceab378026dd2b11e0bb2"
|
||||||
|
integrity sha512-wXUXTXN1CPnR7M4Ltd+3uh7BfcNGUV1+Xe0/h0tCpq/j+S2Sd4xo7/pUMdU19sIDrAAtpEFp1tt+nouHcU5HGQ==
|
||||||
|
|
||||||
|
"@spectrum-css/fieldlabel@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/fieldlabel/-/fieldlabel-3.0.3.tgz#f73c04d20734d4718ffb620dc46458904685b449"
|
||||||
|
integrity sha512-nEvIkEXCD5n4fW67Unq6Iu7VXoauEd/JGpfTY02VsC5p4FJLnwKfPDbJUuUsqClAxqw7nAsmXVKtn4zQFf5yPQ==
|
||||||
|
|
||||||
|
"@spectrum-css/icon@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/icon/-/icon-3.0.3.tgz#5c612822380927087aebd526855d82ed2c3e2cba"
|
||||||
|
integrity sha512-hyloKOejPCXhP3MBNsm3SjR9j8xT1R1S19p32KW/0Qhj+VMUtfyEPmevyFptpn7wcovQccdl/vZVIVDuML/imw==
|
||||||
|
|
||||||
|
"@spectrum-css/illustratedmessage@^3.0.2":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/illustratedmessage/-/illustratedmessage-3.0.2.tgz#6a480be98b027e050b086e7899e40d87adb0a8c0"
|
||||||
|
integrity sha512-dqnE8X27bGcO0HN8+dYx8O4o0dNNIAqeivOzDHhe2El+V4dTzMrNIerF6G0NLm3GjVf6XliwmitsZK+K6FmbtA==
|
||||||
|
|
||||||
|
"@spectrum-css/inputgroup@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/inputgroup/-/inputgroup-3.0.3.tgz#00c9a370ddc2c55cf0f37dd6069faa9501fd7eb5"
|
||||||
|
integrity sha512-FqRJTiLL7jiGfzDVXWUGVLqHryJjCcqQIrqAi+Tq0oenapzsBe2qc/zIrKgh2wtMI+NTIBLXTECvij3L1HlqAg==
|
||||||
|
|
||||||
|
"@spectrum-css/label@^2.0.10":
|
||||||
|
version "2.0.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/label/-/label-2.0.10.tgz#2368651d7636a19385b5d300cdf6272db1916001"
|
||||||
|
integrity sha512-xCbtEiQkZIlLdWFikuw7ifDCC21DOC/KMgVrrVJHXFc4KRQe9LTZSqmGF3tovm+CSq1adE59mYoTbojVQ9YuEQ==
|
||||||
|
|
||||||
|
"@spectrum-css/link@^3.1.1":
|
||||||
|
version "3.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/link/-/link-3.1.3.tgz#b0e560a7e0acdb4a2b329b6669696aa3438f5993"
|
||||||
|
integrity sha512-8Pmy5d73MwKcATTPaj+fSrZYnIw7GmfX40AvpC1xx5LauOxsbUb4AVNp1kn2H8rrOBmxF7czyhoBBhEiv66QUg==
|
||||||
|
|
||||||
|
"@spectrum-css/menu@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/menu/-/menu-3.0.3.tgz#46a9b221bb5f470a2f8a934bdfd512d84d2fdc4d"
|
||||||
|
integrity sha512-qKA9J/MrikNKIpCEHsAazG2vY3im5tjGCmo6p9Pdnu8/aQMsiuZDHZayukeCttJUZkrb9guDVL9OIHlK5RZvcQ==
|
||||||
|
|
||||||
|
"@spectrum-css/modal@^3.0.1":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/modal/-/modal-3.0.2.tgz#58b6621cab65f90788d310374f40df1f7090473f"
|
||||||
|
integrity sha512-YnIivJhoaao7Otu+HV7sgebPyFbO6sd/oMvTN/Rb2wwgnaMnIIuIRdGandSrcgotN2uNgs+P0knG6mv/xA1/dg==
|
||||||
|
|
||||||
"@spectrum-css/page@^3.0.1":
|
"@spectrum-css/page@^3.0.1":
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@spectrum-css/page/-/page-3.0.1.tgz#5e1c3dd5b1a1ee591f9d636b75f03665f542d846"
|
resolved "https://registry.yarnpkg.com/@spectrum-css/page/-/page-3.0.1.tgz#5e1c3dd5b1a1ee591f9d636b75f03665f542d846"
|
||||||
|
@ -17,11 +162,111 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@spectrum-css/vars" "^3.0.1"
|
"@spectrum-css/vars" "^3.0.1"
|
||||||
|
|
||||||
|
"@spectrum-css/pagination@^3.0.3":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/pagination/-/pagination-3.0.3.tgz#b204c3ada384c4af751a354bc428346d82eeea65"
|
||||||
|
integrity sha512-OJ/v9GeNXJOZ9Yr9LDBYPrR2NCiLOWP9wANT/a5sqFuugRnQbn/HYMnRp9TBxwpDY6ihaPo0T/wi7kLiAJFdDw==
|
||||||
|
|
||||||
|
"@spectrum-css/picker@^1.0.1":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/picker/-/picker-1.0.3.tgz#21379bcf8ae94277deeb6ad65dcd9e2bbfacb487"
|
||||||
|
integrity sha512-oHLGxBx5BwVCSGo7/T1C9PTHX1+/5AmVjyLiTJ4UoIdSJmOERw9YcRZbcGZgBJNWbxcjr4TyGtwj1EcSjEy97w==
|
||||||
|
|
||||||
|
"@spectrum-css/popover@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/popover/-/popover-3.0.3.tgz#6fb69873474fb968afb738eacb9e121f93e83a09"
|
||||||
|
integrity sha512-KvmXv4TV19FBx39KfmgVlDYtvtBqv/8RRK7RRLDDHGViTxZtShjVsVpwIgfkfgn4iJztCnXpWzFqRXWUu2XCpQ==
|
||||||
|
|
||||||
|
"@spectrum-css/progressbar@^1.0.2":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/progressbar/-/progressbar-1.0.3.tgz#f70bcc38a2a21cff2f422ec825724ebbb9455e67"
|
||||||
|
integrity sha512-vJHplefUuy8+NjCw1X7fLbqHVGNVBpvGFXNAeaIj4SFf4ygxiUq/5c9iRhhsCQixEsJlfD/b7BnGXU7BUDkr6Q==
|
||||||
|
|
||||||
|
"@spectrum-css/progresscircle@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/progresscircle/-/progresscircle-1.0.2.tgz#258ea9170fb70f795edda03e38a61d93bef4487c"
|
||||||
|
integrity sha512-JLULpyzjIY95lzlWR1yE1gv4l1K6p+scQ+edmuZZUHBzwM3pUtkvHJmUlA9TYdResUYW6Uka60VRdY6lZ8gnFQ==
|
||||||
|
|
||||||
|
"@spectrum-css/radio@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/radio/-/radio-3.0.3.tgz#25c3bc5e9c30a8a8ae728717b7c7fb736cdae640"
|
||||||
|
integrity sha512-LaLGfz/eGNR2iyqouXYILIA+pKRqF769iPdwM0REm5RpWvMQDD7rPZ/kWlg18owjaFsyllEp25gEjmhRJIIVOw==
|
||||||
|
|
||||||
|
"@spectrum-css/search@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/search/-/search-3.0.3.tgz#3415dc106aca0d5dd996e87084a1b47c2b95a882"
|
||||||
|
integrity sha512-kdLpKTt0obljuhS1q1tukujRlvSs8sBwij76D4Qp8KpMzwePfZyvv1kYzuWPNZfTeISxWsmyZ6Wxd1uvzjn+UA==
|
||||||
|
|
||||||
|
"@spectrum-css/sidenav@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/sidenav/-/sidenav-3.0.3.tgz#132141fbd2500a927c312fa4e1d712c438b3d597"
|
||||||
|
integrity sha512-cQ+CgwjxGftrcc79i1XnGd66QTl7H7zopSU0UTV4Qq7hvqfrjjWxfZ6b+3tezrrhNlDope1ff9o8sm67PsPXtg==
|
||||||
|
|
||||||
|
"@spectrum-css/statuslight@^3.0.2":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/statuslight/-/statuslight-3.0.2.tgz#dc54b6cd113413dcdb909c486b5d7bae60db65c5"
|
||||||
|
integrity sha512-xodB8g8vGJH20XmUj9ZsPlM1jHrGeRbvmVXkz0q7YvQrYAhim8pP3W+XKKZAletPFAuu8cmUOc6SWn6i4X4z6w==
|
||||||
|
|
||||||
|
"@spectrum-css/switch@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/switch/-/switch-1.0.2.tgz#f0b4c69271964573e02b08e90998096e49e1de44"
|
||||||
|
integrity sha512-zqmHpgWPNg1gEwdUNFYV3CBX5JaeALfIqcJIxE0FLZqr9d1C4+oLE0ItIFzt1bwr4bFAOmkEpvtiY+amluzGxQ==
|
||||||
|
|
||||||
|
"@spectrum-css/table@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/table/-/table-3.0.3.tgz#7f7f19905ef3275cbf907ce3a5818e63c30b2caf"
|
||||||
|
integrity sha512-nxwzVjLPsXoY/v4sdxOVYLcC+cEbGgJyLcLclT5LT9MGSbngFeUMJzzVR4EvehzuN4dH7hrATG7Mbuq29Mf0Hg==
|
||||||
|
|
||||||
|
"@spectrum-css/tabs@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/tabs/-/tabs-3.0.3.tgz#51dd6f168c897b0fdc3a7e9f901df7bd2288b4fc"
|
||||||
|
integrity sha512-iLP1I72bJWz9APdQB1jiw+pOv5a7N+hYOCJvRoc56Us/hJKVzowkyGRe3uH+8v36nCG9bHxiAQNLoU8eXisVrg==
|
||||||
|
|
||||||
|
"@spectrum-css/tags@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/tags/-/tags-3.0.3.tgz#fc76d2735cdc442de91b7eb3bee49a928c0767ac"
|
||||||
|
integrity sha512-SL8vPxVDfWcY5VdIuyl0TImEXcOU1I7yCyXkk7MudMwfnYs81FaIyY32hFV9OHj0Tz/36UzRzc7AVMSuRQ53pw==
|
||||||
|
|
||||||
|
"@spectrum-css/textfield@^3.0.1":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/textfield/-/textfield-3.0.2.tgz#907f62d2dc82852dd6236a820be99e252b531631"
|
||||||
|
integrity sha512-nkFgAb0cP4jUodkUBErMNfyF78jJLtgL1Mrr9/rvGpGobo10IAbb8zZY4CkZ64o8XmMy/85+wZTKcx+KHatqpg==
|
||||||
|
|
||||||
|
"@spectrum-css/toast@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/toast/-/toast-3.0.3.tgz#97c1527384707600832ecda35643ed304615250f"
|
||||||
|
integrity sha512-CjLeaMs+cjUXojCCRtbj0YkD2BoZW16kjj2o5omkEpUTjA34IJ8xJ1a+CCtDILWekhXvN0MBN4sbumcnwcnx8w==
|
||||||
|
|
||||||
|
"@spectrum-css/tooltip@^3.0.3":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/tooltip/-/tooltip-3.0.3.tgz#26b8ca3b3d30e29630244d85eb4fc11d0c841281"
|
||||||
|
integrity sha512-ztRF7WW1FzyNavXBRc+80z67UoOrY9wl3cMYsVD3MpDnyxdzP8cjza1pCcolKBaFqRTcQKkxKw3GWtGICRKR5A==
|
||||||
|
|
||||||
|
"@spectrum-css/treeview@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/treeview/-/treeview-3.0.3.tgz#aeda5175158b9f8d7529cb2b394428eb2a428046"
|
||||||
|
integrity sha512-D5gGzZC/KtRArdx86Mesc9+99W9nTbUOeyYGqoJoAfJSOttoT6Tk5CrDvlCmAqjKf5rajemAkGri1ChqvUIwkw==
|
||||||
|
|
||||||
|
"@spectrum-css/typography@^3.0.1":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/typography/-/typography-3.0.2.tgz#ea3ca0a60e18064527819d48c8c4364cab4fcd38"
|
||||||
|
integrity sha512-5ZOLmQe0edzsDMyhghUd4hBb5uxGsFrxzf+WasfcUw9klSfTsRZ09n1BsaaWbgrLjlMQ+EEHS46v5VNo0Ms2CA==
|
||||||
|
|
||||||
|
"@spectrum-css/underlay@^2.0.9":
|
||||||
|
version "2.0.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/underlay/-/underlay-2.0.10.tgz#8b75b646605a311850f6620caa18d4996cd64ed7"
|
||||||
|
integrity sha512-PmsmkzeGD/rY4pp3ILXHt9w8BW7uaEqXe08hQRS7rGki7wqCpG4mE0/8N3yEcA3QxWQclmG9gdkg5uz6wMmYzA==
|
||||||
|
|
||||||
"@spectrum-css/vars@^3.0.1":
|
"@spectrum-css/vars@^3.0.1":
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.1.tgz#561fd69098f896a647242dd8d6108af603bfa31e"
|
resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.1.tgz#561fd69098f896a647242dd8d6108af603bfa31e"
|
||||||
integrity sha512-l4oRcCOqInChYXZN6OQhpe3isk6l4OE6Ys8cgdlsiKp53suNoQxyyd9p/eGRbCjZgH3xQ8nK0t4DHa7QYC0S6w==
|
integrity sha512-l4oRcCOqInChYXZN6OQhpe3isk6l4OE6Ys8cgdlsiKp53suNoQxyyd9p/eGRbCjZgH3xQ8nK0t4DHa7QYC0S6w==
|
||||||
|
|
||||||
|
"@spectrum-css/vars@^3.0.2":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.2.tgz#ea9062c3c98dfc6ba59e5df14a03025ad8969999"
|
||||||
|
integrity sha512-vzS9KqYXot4J3AEER/u618MXWAS+IoMvYMNrOoscKiLLKYQWenaueakUWulFonToPd/9vIpqtdbwxznqrK5qDw==
|
||||||
|
|
||||||
"@sveltejs/vite-plugin-svelte@^1.0.0-next.5":
|
"@sveltejs/vite-plugin-svelte@^1.0.0-next.5":
|
||||||
version "1.0.0-next.5"
|
version "1.0.0-next.5"
|
||||||
resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.5.tgz#8cf608f7a3c33dfa5b648397aae1ba90e6a4883f"
|
resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.5.tgz#8cf608f7a3c33dfa5b648397aae1ba90e6a4883f"
|
||||||
|
@ -80,6 +325,11 @@ colorette@^1.2.2:
|
||||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
|
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
|
||||||
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
|
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
|
||||||
|
|
||||||
|
dayjs@^1.10.4, dayjs@^1.10.5:
|
||||||
|
version "1.10.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986"
|
||||||
|
integrity sha512-BUFis41ikLz+65iH6LHQCDm4YPMj5r1YFLdupPIyM4SGcXMmtiLQ7U37i+hGS8urIuqe7I/ou3IS1jVc4nbN4g==
|
||||||
|
|
||||||
debug@^4.3.2:
|
debug@^4.3.2:
|
||||||
version "4.3.2"
|
version "4.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
|
||||||
|
@ -226,6 +476,11 @@ svelte-hmr@^0.13.3:
|
||||||
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.13.3.tgz#fba5739b477ea44caf70e542a24a4352bee2b897"
|
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.13.3.tgz#fba5739b477ea44caf70e542a24a4352bee2b897"
|
||||||
integrity sha512-gagW62pLQ2lULmvNA3pIZu9pBCYOaGu3rQikUOv6Nokz5VxUgT9/mQLfMxj9phDEKHCg/lgr3i6PkqZDbO9P2Q==
|
integrity sha512-gagW62pLQ2lULmvNA3pIZu9pBCYOaGu3rQikUOv6Nokz5VxUgT9/mQLfMxj9phDEKHCg/lgr3i6PkqZDbO9P2Q==
|
||||||
|
|
||||||
|
svelte-portal@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/svelte-portal/-/svelte-portal-1.0.0.tgz#36a47c5578b1a4d9b4dc60fa32a904640ec4cdd3"
|
||||||
|
integrity sha512-nHf+DS/jZ6jjnZSleBMSaZua9JlG5rZv9lOGKgJuaZStfevtjIlUJrkLc3vbV8QdBvPPVmvcjTlazAzfKu0v3Q==
|
||||||
|
|
||||||
svelte@^3.38.2:
|
svelte@^3.38.2:
|
||||||
version "3.38.2"
|
version "3.38.2"
|
||||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.38.2.tgz#55e5c681f793ae349b5cc2fe58e5782af4275ef5"
|
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.38.2.tgz#55e5c681f793ae349b5cc2fe58e5782af4275ef5"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/string-templates",
|
"name": "@budibase/string-templates",
|
||||||
"version": "0.9.25",
|
"version": "0.9.27",
|
||||||
"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",
|
||||||
|
|
|
@ -33,7 +33,7 @@ function testObject(object) {
|
||||||
*/
|
*/
|
||||||
module.exports.processObject = async (object, context) => {
|
module.exports.processObject = async (object, context) => {
|
||||||
testObject(object)
|
testObject(object)
|
||||||
for (let key of Object.keys(object)) {
|
for (let key of Object.keys(object || {})) {
|
||||||
if (object[key] != null) {
|
if (object[key] != null) {
|
||||||
let val = object[key]
|
let val = object[key]
|
||||||
if (typeof val === "string") {
|
if (typeof val === "string") {
|
||||||
|
@ -68,7 +68,7 @@ module.exports.processString = async (string, context) => {
|
||||||
*/
|
*/
|
||||||
module.exports.processObjectSync = (object, context) => {
|
module.exports.processObjectSync = (object, context) => {
|
||||||
testObject(object)
|
testObject(object)
|
||||||
for (let key of Object.keys(object)) {
|
for (let key of Object.keys(object || {})) {
|
||||||
let val = object[key]
|
let val = object[key]
|
||||||
if (typeof val === "string") {
|
if (typeof val === "string") {
|
||||||
object[key] = module.exports.processStringSync(object[key], context)
|
object[key] = module.exports.processStringSync(object[key], context)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/worker",
|
"name": "@budibase/worker",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.9.25",
|
"version": "0.9.27",
|
||||||
"description": "Budibase background service",
|
"description": "Budibase background service",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -21,8 +21,8 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/auth": "^0.9.25",
|
"@budibase/auth": "^0.9.27",
|
||||||
"@budibase/string-templates": "^0.9.25",
|
"@budibase/string-templates": "^0.9.27",
|
||||||
"@koa/router": "^8.0.0",
|
"@koa/router": "^8.0.0",
|
||||||
"aws-sdk": "^2.811.0",
|
"aws-sdk": "^2.811.0",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
|
|
Loading…
Reference in a new issue