Clean up and improve multi step form block
This commit is contained in:
parent
01c8ef9f0f
commit
69ea28ad46
|
@ -465,8 +465,8 @@ const filterCategoryByContext = (component, context) => {
|
|||
const { _component } = component
|
||||
if (_component.endsWith("formblock")) {
|
||||
if (
|
||||
(component.actionType == "Create" && context.type === "schema") ||
|
||||
(component.actionType == "View" && context.type === "form")
|
||||
(component.actionType === "Create" && context.type === "schema") ||
|
||||
(component.actionType === "View" && context.type === "form")
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
@ -474,20 +474,21 @@ const filterCategoryByContext = (component, context) => {
|
|||
return true
|
||||
}
|
||||
|
||||
// Enrich binding category information for certain components
|
||||
const getComponentBindingCategory = (component, context, def) => {
|
||||
let icon = def.icon
|
||||
let category = component._instanceName
|
||||
|
||||
if (component._component.endsWith("formblock")) {
|
||||
let contextCategorySuffix = {
|
||||
form: "Fields",
|
||||
schema: "Row",
|
||||
if (context.type === "form") {
|
||||
category = `${component._instanceName} - Fields`
|
||||
icon = "Form"
|
||||
} else if (context.type === "schema") {
|
||||
category = `${component._instanceName} - Row`
|
||||
icon = "Data"
|
||||
}
|
||||
category = `${component._instanceName} - ${
|
||||
contextCategorySuffix[context.type]
|
||||
}`
|
||||
icon = context.type === "form" ? "Form" : "Data"
|
||||
}
|
||||
|
||||
return {
|
||||
icon,
|
||||
category,
|
||||
|
|
|
@ -1289,15 +1289,14 @@ export const getFrontendStore = () => {
|
|||
const settings = getComponentSettings(component._component)
|
||||
const updatedSetting = settings.find(setting => setting.key === name)
|
||||
|
||||
// Can be a single string or array of strings
|
||||
const resetFields = settings.filter(setting => {
|
||||
return (
|
||||
// Reset dependent fields
|
||||
settings.forEach(setting => {
|
||||
const needsReset =
|
||||
name === setting.resetOn ||
|
||||
(Array.isArray(setting.resetOn) && setting.resetOn.includes(name))
|
||||
)
|
||||
})
|
||||
resetFields?.forEach(setting => {
|
||||
component[setting.key] = null
|
||||
if (needsReset) {
|
||||
component[setting.key] = setting.defaultValue || null
|
||||
}
|
||||
})
|
||||
|
||||
if (
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import { currentAsset, store } from "builderStore"
|
||||
import { Helpers } from "@budibase/bbui"
|
||||
import { writable } from "svelte/store"
|
||||
import { buildMultiStepFormBlockButtonConfig } from "@budibase/frontend-core/src/utils/utils"
|
||||
import { Utils } from "@budibase/frontend-core"
|
||||
|
||||
export let componentInstance
|
||||
export let componentBindings
|
||||
|
@ -20,18 +20,18 @@
|
|||
|
||||
setContext("multi-step-form-block", multiStepStore)
|
||||
|
||||
$: currentStep = $multiStepStore.currentStep
|
||||
$: stepCount = value?.length || 0
|
||||
$: multiStepStore.update(state => ({ ...state, stepCount }))
|
||||
$: defaultButtonConfig = buildMultiStepFormBlockButtonConfig({
|
||||
$: defaultProps = Utils.buildMultiStepFormBlockDefaultProps({
|
||||
_id: componentInstance._id,
|
||||
stepCount: stepCount,
|
||||
currentStep: currentStep,
|
||||
})
|
||||
$: currentStep = $multiStepStore.currentStep
|
||||
$: stepCount = value?.length || 0
|
||||
$: multiStepStore.update(state => ({ ...state, stepCount }))
|
||||
$: dataSource = getDatasourceForProvider($currentAsset, componentInstance)
|
||||
$: emitCurrentStep(currentStep)
|
||||
$: sectionName = getSectionName($multiStepStore)
|
||||
$: stepConfigInstance = buildPseudoInstance(value[currentStep] || {})
|
||||
$: stepInstance = buildPseudoInstance(value[currentStep], defaultProps)
|
||||
$: stepDef = {
|
||||
settings: [
|
||||
{
|
||||
|
@ -150,14 +150,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
const buildPseudoInstance = ({ buttons, fields, title, desc }) => {
|
||||
const buildPseudoInstance = (instance, defaultProps) => {
|
||||
const { buttons, fields, title, desc } = instance || {}
|
||||
return {
|
||||
_id: Helpers.uuid(),
|
||||
_component: "@budibase/standard-components/multistepformblockstep",
|
||||
_instanceName: `Step ${currentStep + 1}`,
|
||||
buttons: buttons || defaultButtonConfig,
|
||||
title: title ?? defaultProps.title,
|
||||
buttons: buttons || defaultProps.buttons,
|
||||
fields,
|
||||
title,
|
||||
desc,
|
||||
|
||||
// Needed for field configuration
|
||||
|
@ -169,7 +170,7 @@
|
|||
<div class="nested-section">
|
||||
<ComponentSettingsSection
|
||||
includeHidden
|
||||
componentInstance={stepConfigInstance}
|
||||
componentInstance={stepInstance}
|
||||
componentDefinition={stepDef}
|
||||
onUpdateSetting={processUpdate}
|
||||
showInstanceName={false}
|
||||
|
|
|
@ -6095,6 +6095,7 @@
|
|||
},
|
||||
{
|
||||
"type": "static",
|
||||
"suffix": "form",
|
||||
"values": [
|
||||
{
|
||||
"label": "Value",
|
||||
|
|
|
@ -13,56 +13,6 @@
|
|||
const { fetchDatasourceSchema } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
|
||||
let schema
|
||||
let formId
|
||||
|
||||
const getCurrentStep = () => {
|
||||
if ($builderStore?.component?._id === $component.id) {
|
||||
return $builderStore?.component.step
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
$: currentStep = getCurrentStep(
|
||||
$builderStore?.component?._id,
|
||||
componentInstance
|
||||
)
|
||||
|
||||
$: fetchSchema(dataSource)
|
||||
|
||||
const getPropsForField = field => {
|
||||
let fieldProps = field._component
|
||||
? {
|
||||
...field,
|
||||
}
|
||||
: {
|
||||
field: field.name,
|
||||
label: field.name,
|
||||
placeholder: field.name,
|
||||
_instanceName: field.name,
|
||||
}
|
||||
return fieldProps
|
||||
}
|
||||
|
||||
const getDefaultFields = (fields, schema) => {
|
||||
if (!schema) {
|
||||
return []
|
||||
}
|
||||
let defaultFields = []
|
||||
|
||||
if (!fields || fields.length === 0) {
|
||||
Object.values(schema)
|
||||
.filter(field => !field.autocolumn)
|
||||
.forEach(field => {
|
||||
defaultFields.push({
|
||||
name: field.name,
|
||||
active: true,
|
||||
})
|
||||
})
|
||||
}
|
||||
return [...fields, ...defaultFields].filter(field => field.active)
|
||||
}
|
||||
|
||||
const FieldTypeToComponentMap = {
|
||||
string: "stringfield",
|
||||
number: "numberfield",
|
||||
|
@ -79,6 +29,35 @@
|
|||
bb_reference: "bbreferencefield",
|
||||
}
|
||||
|
||||
let schema
|
||||
|
||||
$: fetchSchema(dataSource)
|
||||
$: enrichedSteps = enrichSteps(steps, schema, $component.id)
|
||||
$: currentStep = getCurrentStep(
|
||||
$builderStore?.component?._id,
|
||||
componentInstance
|
||||
)
|
||||
|
||||
const getCurrentStep = () => {
|
||||
if ($builderStore?.component?._id === $component.id) {
|
||||
return $builderStore?.component.step
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
const getPropsForField = field => {
|
||||
return field._component
|
||||
? {
|
||||
...field,
|
||||
}
|
||||
: {
|
||||
field: field.name,
|
||||
label: field.name,
|
||||
placeholder: field.name,
|
||||
_instanceName: field.name,
|
||||
}
|
||||
}
|
||||
|
||||
const getComponentForField = field => {
|
||||
const fieldSchemaName = field.field || field.name
|
||||
if (!fieldSchemaName || !schema?.[fieldSchemaName]) {
|
||||
|
@ -92,24 +71,37 @@
|
|||
schema = (await fetchDatasourceSchema(dataSource)) || {}
|
||||
}
|
||||
|
||||
$: stepProps = steps?.map((step, idx) => {
|
||||
const { title, desc, fields, buttons } = step
|
||||
return {
|
||||
fields: getDefaultFields(fields || [], schema),
|
||||
title,
|
||||
desc,
|
||||
buttons:
|
||||
buttons ||
|
||||
Utils.buildMultiStepFormBlockButtonConfig({
|
||||
_id: $component.id,
|
||||
stepCount: steps?.length ?? 0,
|
||||
currentStep: idx,
|
||||
}),
|
||||
const getDefaultFields = (fields, schema) => {
|
||||
if (fields?.length) {
|
||||
return fields.filter(field => field.active)
|
||||
}
|
||||
})
|
||||
return Object.values(schema || {})
|
||||
.filter(field => !field.autocolumn)
|
||||
.map(field => ({
|
||||
name: field.name,
|
||||
}))
|
||||
}
|
||||
|
||||
const enrichSteps = (steps, schema, id) => {
|
||||
const safeSteps = steps?.length ? steps : [{}]
|
||||
return safeSteps.map((step, idx) => {
|
||||
const { title, desc, fields, buttons } = step
|
||||
const defaultProps = Utils.buildMultiStepFormBlockDefaultProps({
|
||||
_id: id,
|
||||
stepCount: safeSteps.length,
|
||||
currentStep: idx,
|
||||
})
|
||||
return {
|
||||
fields: getDefaultFields(fields || [], schema),
|
||||
title: title ?? defaultProps.title,
|
||||
desc,
|
||||
buttons: buttons || defaultProps.buttons,
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
{#key stepProps}
|
||||
{#key enrichedSteps}
|
||||
<Block>
|
||||
<BlockComponent
|
||||
type="form"
|
||||
|
@ -119,9 +111,8 @@
|
|||
step: $builderStore.inBuilder === true ? currentStep + 1 : null,
|
||||
}}
|
||||
context="form"
|
||||
bind:id={formId}
|
||||
>
|
||||
{#each steps || [] as step, idx ("step" + step._id)}
|
||||
{#each enrichedSteps as step, idx}
|
||||
<BlockComponent
|
||||
type="formstep"
|
||||
props={{ step: idx + 1, _instanceName: `Step ${idx + 1}` }}
|
||||
|
@ -143,39 +134,32 @@
|
|||
size: "shrink",
|
||||
}}
|
||||
>
|
||||
<BlockComponent type="container">
|
||||
<BlockComponent
|
||||
type="heading"
|
||||
props={{ text: stepProps?.[idx]?.title }}
|
||||
/>
|
||||
<BlockComponent type="container" order={0}>
|
||||
<BlockComponent type="heading" props={{ text: step.title }} />
|
||||
</BlockComponent>
|
||||
|
||||
<BlockComponent
|
||||
type="text"
|
||||
props={{ text: stepProps?.[idx]?.desc }}
|
||||
/>
|
||||
|
||||
<BlockComponent type="fieldgroup">
|
||||
{#each stepProps?.[idx]?.fields || [] as field, fieldIdx ("field_" + fieldIdx)}
|
||||
{#if getComponentForField(field) && field.active}
|
||||
<BlockComponent type="text" props={{ text: step.desc }} order={1} />
|
||||
<BlockComponent type="fieldgroup" order={2}>
|
||||
{#each step.fields as field, fieldIdx}
|
||||
{#if getComponentForField(field)}
|
||||
<BlockComponent
|
||||
type={getComponentForField(field)}
|
||||
props={getPropsForField(field)}
|
||||
order={idx}
|
||||
order={fieldIdx}
|
||||
interactive
|
||||
name={field?.field}
|
||||
name={field.field}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
</BlockComponent>
|
||||
<BlockComponent
|
||||
type="buttongroup"
|
||||
props={{ buttons: stepProps?.[idx]?.buttons }}
|
||||
props={{ buttons: step.buttons }}
|
||||
styles={{
|
||||
normal: {
|
||||
"margin-top": "16px",
|
||||
},
|
||||
}}
|
||||
order={3}
|
||||
/>
|
||||
</BlockComponent>
|
||||
</BlockComponent>
|
||||
|
|
|
@ -227,7 +227,7 @@ export const buildFormBlockButtonConfig = props => {
|
|||
})
|
||||
}
|
||||
|
||||
if (actionType == "Update" && showDeleteButton !== false) {
|
||||
if (actionType === "Update" && showDeleteButton !== false) {
|
||||
defaultButtons.push({
|
||||
text: deleteText || "Delete",
|
||||
_id: Helpers.uuid(),
|
||||
|
@ -241,7 +241,7 @@ export const buildFormBlockButtonConfig = props => {
|
|||
return defaultButtons
|
||||
}
|
||||
|
||||
export const buildMultiStepFormBlockButtonConfig = props => {
|
||||
export const buildMultiStepFormBlockDefaultProps = props => {
|
||||
const { _id, stepCount, currentStep } = props || {}
|
||||
|
||||
// Sanity check
|
||||
|
@ -249,6 +249,8 @@ export const buildMultiStepFormBlockButtonConfig = props => {
|
|||
return
|
||||
}
|
||||
|
||||
// Default the title to "Step X"
|
||||
const title = `Step {{ [${_id}-form].[__currentStep] }}`
|
||||
let buttons = []
|
||||
|
||||
// Add previous step button if we aren't the first step
|
||||
|
@ -319,5 +321,8 @@ export const buildMultiStepFormBlockButtonConfig = props => {
|
|||
})
|
||||
}
|
||||
|
||||
return buttons
|
||||
return {
|
||||
buttons,
|
||||
title,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue