Add binding eval for non relationship fields when editing formula columns
This commit is contained in:
parent
334c6de304
commit
08ad9d9c4e
|
@ -36,6 +36,8 @@
|
||||||
import { ValidColumnNameRegex } from "@budibase/shared-core"
|
import { ValidColumnNameRegex } from "@budibase/shared-core"
|
||||||
import { FieldType, FieldSubtype, SourceName } from "@budibase/types"
|
import { FieldType, FieldSubtype, SourceName } from "@budibase/types"
|
||||||
import RelationshipSelector from "components/common/RelationshipSelector.svelte"
|
import RelationshipSelector from "components/common/RelationshipSelector.svelte"
|
||||||
|
import { RowUtils } from "@budibase/frontend-core"
|
||||||
|
import ServerBindingPanel from "components/common/bindings/ServerBindingPanel.svelte"
|
||||||
|
|
||||||
const AUTO_TYPE = FIELDS.AUTO.type
|
const AUTO_TYPE = FIELDS.AUTO.type
|
||||||
const FORMULA_TYPE = FIELDS.FORMULA.type
|
const FORMULA_TYPE = FIELDS.FORMULA.type
|
||||||
|
@ -93,6 +95,7 @@
|
||||||
}
|
}
|
||||||
let autoColumnInfo = getAutoColumnInformation()
|
let autoColumnInfo = getAutoColumnInformation()
|
||||||
|
|
||||||
|
$: rowGoldenSample = RowUtils.generateGoldenSample($rows)
|
||||||
$: if (primaryDisplay) {
|
$: if (primaryDisplay) {
|
||||||
editableColumn.constraints.presence = { allowEmpty: false }
|
editableColumn.constraints.presence = { allowEmpty: false }
|
||||||
}
|
}
|
||||||
|
@ -667,6 +670,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="input-length">
|
<div class="input-length">
|
||||||
<ModalBindableInput
|
<ModalBindableInput
|
||||||
|
panel={ServerBindingPanel}
|
||||||
title="Formula"
|
title="Formula"
|
||||||
value={editableColumn.formula}
|
value={editableColumn.formula}
|
||||||
on:change={e => {
|
on:change={e => {
|
||||||
|
@ -677,6 +681,7 @@
|
||||||
}}
|
}}
|
||||||
bindings={getBindings({ table })}
|
bindings={getBindings({ table })}
|
||||||
allowJS
|
allowJS
|
||||||
|
context={rowGoldenSample}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
export let key
|
export let key
|
||||||
export let disableBindings = false
|
export let disableBindings = false
|
||||||
export let forceModal = false
|
export let forceModal = false
|
||||||
|
export let context = null
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@ -102,6 +103,7 @@
|
||||||
{bindings}
|
{bindings}
|
||||||
{allowJS}
|
{allowJS}
|
||||||
{allowHelpers}
|
{allowHelpers}
|
||||||
|
{context}
|
||||||
/>
|
/>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
export let valid
|
export let valid
|
||||||
export let value = ""
|
export let value = ""
|
||||||
export let allowJS = false
|
export let allowJS = false
|
||||||
|
export let context = null
|
||||||
|
|
||||||
$: enrichedBindings = enrichBindings(bindings)
|
$: enrichedBindings = enrichBindings(bindings)
|
||||||
|
|
||||||
|
@ -23,5 +24,6 @@
|
||||||
bindings={enrichedBindings}
|
bindings={enrichedBindings}
|
||||||
{value}
|
{value}
|
||||||
{allowJS}
|
{allowJS}
|
||||||
|
{context}
|
||||||
on:change
|
on:change
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -28,9 +28,13 @@ import { ActionTypes } from "./constants"
|
||||||
import { fetchDatasourceSchema } from "./utils/schema.js"
|
import { fetchDatasourceSchema } from "./utils/schema.js"
|
||||||
import { getAPIKey } from "./utils/api.js"
|
import { getAPIKey } from "./utils/api.js"
|
||||||
import { enrichButtonActions } from "./utils/buttonActions.js"
|
import { enrichButtonActions } from "./utils/buttonActions.js"
|
||||||
import { generateGoldenSample } from "./utils/components.js"
|
|
||||||
import { processStringSync, makePropSafe } from "@budibase/string-templates"
|
import { processStringSync, makePropSafe } from "@budibase/string-templates"
|
||||||
import { fetchData, LuceneUtils, Constants } from "@budibase/frontend-core"
|
import {
|
||||||
|
fetchData,
|
||||||
|
LuceneUtils,
|
||||||
|
Constants,
|
||||||
|
RowUtils,
|
||||||
|
} from "@budibase/frontend-core"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
API,
|
API,
|
||||||
|
@ -66,7 +70,7 @@ export default {
|
||||||
processStringSync,
|
processStringSync,
|
||||||
makePropSafe,
|
makePropSafe,
|
||||||
createContextStore,
|
createContextStore,
|
||||||
generateGoldenSample,
|
generateGoldenSample: RowUtils.generateGoldenSample,
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
Provider,
|
Provider,
|
||||||
|
|
|
@ -82,52 +82,3 @@ export const findComponentParent = (rootComponent, id, parentComponent) => {
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Util to check is a given value is "better" than another. "Betterness" is
|
|
||||||
* defined as presence and length.
|
|
||||||
*/
|
|
||||||
const isBetterSample = (newValue, oldValue) => {
|
|
||||||
// Prefer non-null values
|
|
||||||
if (oldValue == null && newValue != null) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't change type
|
|
||||||
const oldType = typeof oldValue
|
|
||||||
const newType = typeof newValue
|
|
||||||
if (oldType !== newType) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prefer longer values
|
|
||||||
if (newType === "string" && newValue.length > oldValue.length) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
newType === "object" &&
|
|
||||||
Object.keys(newValue).length > Object.keys(oldValue).length
|
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a best-case example object of the provided samples.
|
|
||||||
* The generated sample does not necessarily exist - it simply is a sample that
|
|
||||||
* contains "good" examples for every property of all the samples.
|
|
||||||
* The generate sample will have a value for all keys across all samples.
|
|
||||||
*/
|
|
||||||
export const generateGoldenSample = samples => {
|
|
||||||
let goldenSample = {}
|
|
||||||
samples?.forEach(sample => {
|
|
||||||
Object.keys(sample).forEach(key => {
|
|
||||||
if (isBetterSample(sample[key], goldenSample[key])) {
|
|
||||||
goldenSample[key] = sample[key]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return goldenSample
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ export * as JSONUtils from "./json"
|
||||||
export * as CookieUtils from "./cookies"
|
export * as CookieUtils from "./cookies"
|
||||||
export * as RoleUtils from "./roles"
|
export * as RoleUtils from "./roles"
|
||||||
export * as Utils from "./utils"
|
export * as Utils from "./utils"
|
||||||
|
export * as RowUtils from "./rows"
|
||||||
export { memo, derivedMemo } from "./memo"
|
export { memo, derivedMemo } from "./memo"
|
||||||
export { createWebsocket } from "./websocket"
|
export { createWebsocket } from "./websocket"
|
||||||
export * from "./download"
|
export * from "./download"
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* Util to check is a given value is "better" than another. "Betterness" is
|
||||||
|
* defined as presence and length.
|
||||||
|
*/
|
||||||
|
const isBetterSample = (newValue, oldValue) => {
|
||||||
|
// Prefer non-null values
|
||||||
|
if (oldValue == null && newValue != null) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't change type
|
||||||
|
const oldType = typeof oldValue
|
||||||
|
const newType = typeof newValue
|
||||||
|
if (oldType !== newType) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefer longer values
|
||||||
|
if (newType === "string" && newValue.length > oldValue.length) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
newType === "object" &&
|
||||||
|
Object.keys(newValue).length > Object.keys(oldValue).length
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a best-case example object of the provided samples.
|
||||||
|
* The generated sample does not necessarily exist - it simply is a sample that
|
||||||
|
* contains "good" examples for every property of all the samples.
|
||||||
|
* The generate sample will have a value for all keys across all samples.
|
||||||
|
*/
|
||||||
|
export const generateGoldenSample = samples => {
|
||||||
|
let goldenSample = {}
|
||||||
|
samples?.slice(0, 100).forEach(sample => {
|
||||||
|
Object.keys(sample).forEach(key => {
|
||||||
|
if (isBetterSample(sample[key], goldenSample[key])) {
|
||||||
|
goldenSample[key] = sample[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return goldenSample
|
||||||
|
}
|
Loading…
Reference in New Issue