diff --git a/packages/builder/src/components/design/settings/controls/FormStepConfiguration.svelte b/packages/builder/src/components/design/settings/controls/FormStepConfiguration.svelte index cfaeb3700f..d9257545c9 100644 --- a/packages/builder/src/components/design/settings/controls/FormStepConfiguration.svelte +++ b/packages/builder/src/components/design/settings/controls/FormStepConfiguration.svelte @@ -21,26 +21,24 @@ const currentStep = derived(multiStepStore, state => state.currentStep) const componentType = "@budibase/standard-components/multistepformblockstep" + setContext("multi-step-form-block", multiStepStore) + let cachedValue let cachedInstance = {} $: if (!isEqual(cachedValue, value)) { cachedValue = value } - $: if (!isEqual(componentInstance, cachedInstance)) { cachedInstance = componentInstance } - - setContext("multi-step-form-block", multiStepStore) - $: stepCount = cachedValue?.length || 0 $: updateStore(stepCount) $: dataSource = getDatasourceForProvider($selectedScreen, cachedInstance) $: emitCurrentStep($currentStep) $: stepLabel = getStepLabel($multiStepStore) $: stepDef = getDefinition(stepLabel) - $: stepSettings = cachedValue?.[$currentStep] || {} + $: savedInstance = cachedValue?.[$currentStep] || {} $: defaults = Utils.buildMultiStepFormBlockDefaultProps({ _id: cachedInstance._id, stepCount: $multiStepStore.stepCount, @@ -48,14 +46,16 @@ actionType: cachedInstance.actionType, 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 = { - _id: Helpers.uuid(), - _component: componentType, + _id: savedInstance._id || Helpers.uuid(), + _component: savedInstance._component || componentType, _instanceName: `Step ${currentStep + 1}`, - title: stepSettings.title ?? defaults?.title, - buttons: stepSettings.buttons || defaults?.buttons, - fields: stepSettings.fields, - desc: stepSettings.desc, + title: savedInstance.title ?? defaults?.title, + buttons: savedInstance.buttons || defaults?.buttons, + fields: savedInstance.fields, + desc: savedInstance.desc, // Needed for field configuration dataSource, @@ -92,7 +92,8 @@ } const addStep = () => { - value = value.toSpliced($currentStep + 1, 0, {}) + const newInstance = componentStore.createInstance(componentType) + value = value.toSpliced($currentStep + 1, 0, newInstance) dispatch("change", value) multiStepStore.update(state => ({ ...state, diff --git a/packages/builder/src/dataBinding.js b/packages/builder/src/dataBinding.js index 5efbb79611..aaccbd0e6b 100644 --- a/packages/builder/src/dataBinding.js +++ b/packages/builder/src/dataBinding.js @@ -1106,50 +1106,51 @@ export const getAllStateVariables = () => { getAllAssets().forEach(asset => { findAllMatchingComponents(asset.props, 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) => { + if (!settings?.length) { + return + } + + // Extract top level event settings settings .filter(setting => setting.type === "event") .forEach(setting => { eventSettings.push(comp[setting.key]) }) - } - const parseComponentSettings = (settings, component) => { - // Parse the nested button configurations + // Recurse into any nested instance types settings - .filter(setting => setting.type === "buttonConfiguration") + .filter(setting => nestedTypes.includes(setting.type)) .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)) { - buttonConfig.forEach(button => { - const nestedSettings = componentStore.getComponentSettings( - button._component - ) - parseEventSettings(nestedSettings, button) + // Backwards compatibility for multi-step from blocks which + // didn't set a proper component type previously. + if (setting.type === "stepConfiguration" && !type) { + type = "@budibase/standard-components/multistepformblockstep" + } + + // Parsed nested component instances inside this setting + const nestedSettings = componentStore.getComponentSettings(type) + parseEventSettings(nestedSettings, instance) }) } }) - - 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) - }) + parseEventSettings(settings, component) }) })