Add ability for components to provide example data context that they provide so that more bindings work with live eval
This commit is contained in:
parent
461418390d
commit
5f6b846937
|
@ -69,8 +69,6 @@
|
||||||
return names
|
return names
|
||||||
}
|
}
|
||||||
|
|
||||||
$: console.log(context)
|
|
||||||
|
|
||||||
const getBindingValue = binding => {
|
const getBindingValue = binding => {
|
||||||
const hbs = `{{ ${binding.runtimeBinding} }}`
|
const hbs = `{{ ${binding.runtimeBinding} }}`
|
||||||
return processStringSync(hbs, context)
|
return processStringSync(hbs, context)
|
||||||
|
|
|
@ -575,6 +575,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getDataContext = () => {
|
||||||
|
const normalContext = get(context)
|
||||||
|
const additionalContext = ref?.getAdditionalDataContext?.()
|
||||||
|
return {
|
||||||
|
...normalContext,
|
||||||
|
...additionalContext,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Register this component instance for external access
|
// Register this component instance for external access
|
||||||
if ($appStore.isDevApp) {
|
if ($appStore.isDevApp) {
|
||||||
|
@ -583,7 +592,7 @@
|
||||||
component: instance._component,
|
component: instance._component,
|
||||||
getSettings: () => cachedSettings,
|
getSettings: () => cachedSettings,
|
||||||
getRawSettings: () => ({ ...staticSettings, ...dynamicSettings }),
|
getRawSettings: () => ({ ...staticSettings, ...dynamicSettings }),
|
||||||
getDataContext: () => get(context),
|
getDataContext: getDataContext,
|
||||||
reload: () => initialise(instance, true),
|
reload: () => initialise(instance, true),
|
||||||
setEphemeralStyles: styles => (ephemeralStyles = styles),
|
setEphemeralStyles: styles => (ephemeralStyles = styles),
|
||||||
state: store,
|
state: store,
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
ActionTypes,
|
ActionTypes,
|
||||||
createContextStore,
|
createContextStore,
|
||||||
Provider,
|
Provider,
|
||||||
|
generateGoldenSample,
|
||||||
} = getContext("sdk")
|
} = getContext("sdk")
|
||||||
|
|
||||||
let grid
|
let grid
|
||||||
|
@ -48,6 +49,19 @@
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Provide additional data context for live binding eval
|
||||||
|
export const getAdditionalDataContext = () => {
|
||||||
|
const rows = get(grid?.getContext()?.rows)
|
||||||
|
const goldenRow = generateGoldenSample(rows)
|
||||||
|
const id = [get(component).id]
|
||||||
|
return {
|
||||||
|
[id]: goldenRow,
|
||||||
|
eventContext: {
|
||||||
|
row: goldenRow,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parses columns to fix older formats
|
// Parses columns to fix older formats
|
||||||
const getParsedColumns = columns => {
|
const getParsedColumns = columns => {
|
||||||
// If the first element has an active key all elements should be in the new format
|
// If the first element has an active key all elements should be in the new format
|
||||||
|
|
|
@ -28,6 +28,7 @@ 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 } from "@budibase/frontend-core"
|
||||||
|
|
||||||
|
@ -65,6 +66,7 @@ export default {
|
||||||
processStringSync,
|
processStringSync,
|
||||||
makePropSafe,
|
makePropSafe,
|
||||||
createContextStore,
|
createContextStore,
|
||||||
|
generateGoldenSample,
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
Provider,
|
Provider,
|
||||||
|
|
|
@ -82,3 +82,52 @@ 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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue