Fix state bindings not being generated for some nested instances

This commit is contained in:
Andrew Kingston 2024-05-02 11:33:34 +01:00
parent b08bfc2517
commit a8b74f5f8c
2 changed files with 42 additions and 40 deletions

View File

@ -21,26 +21,24 @@
const currentStep = derived(multiStepStore, state => state.currentStep) const currentStep = derived(multiStepStore, state => state.currentStep)
const componentType = "@budibase/standard-components/multistepformblockstep" const componentType = "@budibase/standard-components/multistepformblockstep"
setContext("multi-step-form-block", multiStepStore)
let cachedValue let cachedValue
let cachedInstance = {} let cachedInstance = {}
$: if (!isEqual(cachedValue, value)) { $: if (!isEqual(cachedValue, value)) {
cachedValue = value cachedValue = value
} }
$: if (!isEqual(componentInstance, cachedInstance)) { $: if (!isEqual(componentInstance, cachedInstance)) {
cachedInstance = componentInstance cachedInstance = componentInstance
} }
setContext("multi-step-form-block", multiStepStore)
$: stepCount = cachedValue?.length || 0 $: stepCount = cachedValue?.length || 0
$: updateStore(stepCount) $: updateStore(stepCount)
$: dataSource = getDatasourceForProvider($selectedScreen, cachedInstance) $: dataSource = getDatasourceForProvider($selectedScreen, cachedInstance)
$: emitCurrentStep($currentStep) $: emitCurrentStep($currentStep)
$: stepLabel = getStepLabel($multiStepStore) $: stepLabel = getStepLabel($multiStepStore)
$: stepDef = getDefinition(stepLabel) $: stepDef = getDefinition(stepLabel)
$: stepSettings = cachedValue?.[$currentStep] || {} $: savedInstance = cachedValue?.[$currentStep] || {}
$: defaults = Utils.buildMultiStepFormBlockDefaultProps({ $: defaults = Utils.buildMultiStepFormBlockDefaultProps({
_id: cachedInstance._id, _id: cachedInstance._id,
stepCount: $multiStepStore.stepCount, stepCount: $multiStepStore.stepCount,
@ -48,14 +46,16 @@
actionType: cachedInstance.actionType, actionType: cachedInstance.actionType,
dataSource: cachedInstance.dataSource, dataSource: cachedInstance.dataSource,
}) })
// For backwards compatibility we need to sometimes manually set base
// properties like _id and _component as we didn't used to save these
$: stepInstance = { $: stepInstance = {
_id: Helpers.uuid(), _id: savedInstance._id || Helpers.uuid(),
_component: componentType, _component: savedInstance._component || componentType,
_instanceName: `Step ${currentStep + 1}`, _instanceName: `Step ${currentStep + 1}`,
title: stepSettings.title ?? defaults?.title, title: savedInstance.title ?? defaults?.title,
buttons: stepSettings.buttons || defaults?.buttons, buttons: savedInstance.buttons || defaults?.buttons,
fields: stepSettings.fields, fields: savedInstance.fields,
desc: stepSettings.desc, desc: savedInstance.desc,
// Needed for field configuration // Needed for field configuration
dataSource, dataSource,
@ -92,7 +92,8 @@
} }
const addStep = () => { const addStep = () => {
value = value.toSpliced($currentStep + 1, 0, {}) const newInstance = componentStore.createInstance(componentType)
value = value.toSpliced($currentStep + 1, 0, newInstance)
dispatch("change", value) dispatch("change", value)
multiStepStore.update(state => ({ multiStepStore.update(state => ({
...state, ...state,

View File

@ -1106,50 +1106,51 @@ export const getAllStateVariables = () => {
getAllAssets().forEach(asset => { getAllAssets().forEach(asset => {
findAllMatchingComponents(asset.props, component => { findAllMatchingComponents(asset.props, component => {
const settings = componentStore.getComponentSettings(component._component) const settings = componentStore.getComponentSettings(component._component)
const nestedTypes = [
"buttonConfiguration",
"fieldConfiguration",
"stepConfiguration",
]
// Extracts all event settings from a component instance.
// Recurses into nested types to find all event-like settings at any
// depth.
const parseEventSettings = (settings, comp) => { const parseEventSettings = (settings, comp) => {
if (!settings?.length) {
return
}
// Extract top level event settings
settings settings
.filter(setting => setting.type === "event") .filter(setting => setting.type === "event")
.forEach(setting => { .forEach(setting => {
eventSettings.push(comp[setting.key]) eventSettings.push(comp[setting.key])
}) })
}
const parseComponentSettings = (settings, component) => { // Recurse into any nested instance types
// Parse the nested button configurations
settings settings
.filter(setting => setting.type === "buttonConfiguration") .filter(setting => nestedTypes.includes(setting.type))
.forEach(setting => { .forEach(setting => {
const buttonConfig = component[setting.key] const instances = comp[setting.key]
if (Array.isArray(instances) && instances.length) {
instances.forEach(instance => {
let type = instance?._component
if (Array.isArray(buttonConfig)) { // Backwards compatibility for multi-step from blocks which
buttonConfig.forEach(button => { // didn't set a proper component type previously.
const nestedSettings = componentStore.getComponentSettings( if (setting.type === "stepConfiguration" && !type) {
button._component type = "@budibase/standard-components/multistepformblockstep"
) }
parseEventSettings(nestedSettings, button)
// Parsed nested component instances inside this setting
const nestedSettings = componentStore.getComponentSettings(type)
parseEventSettings(nestedSettings, instance)
}) })
} }
}) })
}
parseEventSettings(settings, component) parseEventSettings(settings, component)
}
// Parse the base component settings
parseComponentSettings(settings, component)
// Parse step configuration
const stepSetting = settings.find(
setting => setting.type === "stepConfiguration"
)
const steps = stepSetting ? component[stepSetting.key] : []
const stepDefinition = componentStore.getComponentSettings(
"@budibase/standard-components/multistepformblockstep"
)
steps?.forEach(step => {
parseComponentSettings(stepDefinition, step)
})
}) })
}) })