1
0
Fork 0
mirror of synced 2024-10-05 12:34:50 +13:00

Improve setting rendering and add dynamic section title

This commit is contained in:
Andrew Kingston 2023-12-08 16:10:56 +00:00
parent 1bf556b4f2
commit 173a76dc52
7 changed files with 105 additions and 159 deletions

View file

@ -4,7 +4,6 @@
export let name export let name
export let initiallyShow = false export let initiallyShow = false
export let collapsible = true export let collapsible = true
export let noPadding = false
let show = initiallyShow let show = initiallyShow
@ -29,7 +28,6 @@
class="property-panel" class="property-panel"
class:show={show || !collapsible} class:show={show || !collapsible}
class:no-title={!name} class:no-title={!name}
class:no-padding={noPadding}
> >
<slot /> <slot />
</div> </div>
@ -83,10 +81,6 @@
padding: var(--spacing-xl); padding: var(--spacing-xl);
} }
.property-panel.no-title.no-padding {
padding: 0px;
}
.show { .show {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View file

@ -26,6 +26,7 @@ import FieldConfiguration from "./controls/FieldConfiguration/FieldConfiguration
import ButtonConfiguration from "./controls/ButtonConfiguration/ButtonConfiguration.svelte" import ButtonConfiguration from "./controls/ButtonConfiguration/ButtonConfiguration.svelte"
import RelationshipFilterEditor from "./controls/RelationshipFilterEditor.svelte" import RelationshipFilterEditor from "./controls/RelationshipFilterEditor.svelte"
import FormStepConfiguration from "./controls/FormStepConfiguration.svelte" import FormStepConfiguration from "./controls/FormStepConfiguration.svelte"
import FormStepControls from "components/design/settings/controls/FormStepControls.svelte"
const componentMap = { const componentMap = {
text: DrawerBindableInput, text: DrawerBindableInput,
@ -53,6 +54,7 @@ const componentMap = {
fieldConfiguration: FieldConfiguration, fieldConfiguration: FieldConfiguration,
buttonConfiguration: ButtonConfiguration, buttonConfiguration: ButtonConfiguration,
stepConfiguration: FormStepConfiguration, stepConfiguration: FormStepConfiguration,
formStepControls: FormStepControls,
columns: ColumnEditor, columns: ColumnEditor,
"columns/basic": BasicColumnEditor, "columns/basic": BasicColumnEditor,
"columns/grid": GridColumnEditor, "columns/grid": GridColumnEditor,

View file

@ -4,7 +4,6 @@
import { getDatasourceForProvider } from "builderStore/dataBinding" import { getDatasourceForProvider } from "builderStore/dataBinding"
import { currentAsset, store } from "builderStore" import { currentAsset, store } from "builderStore"
import { Helpers } from "@budibase/bbui" import { Helpers } from "@budibase/bbui"
import FormStepControls from "./FormStepControls.svelte"
import { writable } from "svelte/store" import { writable } from "svelte/store"
import { buildMultiStepFormBlockButtonConfig } from "@budibase/frontend-core/src/utils/utils" import { buildMultiStepFormBlockButtonConfig } from "@budibase/frontend-core/src/utils/utils"
@ -14,61 +13,70 @@
export let bindings export let bindings
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const multiStepStore = writable({
let stepState = [...(value || [])] stepCount: value?.length ?? 0,
const stepStore = writable({
stepsCount: stepState?.length || 1,
currentStep: 0, currentStep: 0,
}) })
setContext("step-form-block", stepStore) setContext("multi-step-form-block", multiStepStore)
$: ({ currentStep } = $stepStore) $: currentStep = $multiStepStore.currentStep
$: if (stepState.length) { $: stepCount = value?.length || 0
stepStore.update(state => ({ $: multiStepStore.update(state => ({ ...state, stepCount }))
...state,
stepsCount: stepState.length || 0,
}))
}
$: defaultButtonConfig = buildMultiStepFormBlockButtonConfig({ $: defaultButtonConfig = buildMultiStepFormBlockButtonConfig({
_id: componentInstance._id, _id: componentInstance._id,
stepCount: value?.length, stepCount: stepCount,
currentStep, currentStep: currentStep,
}) })
$: dataSource = getDatasourceForProvider($currentAsset, componentInstance)
$: emitCurrentStep(currentStep)
$: sectionName = getSectionName($multiStepStore)
$: stepDef = {
settings: [
{
section: true,
name: sectionName,
settings: [
{
type: "formStepControls",
label: "Multi-steps",
key: "steps",
},
{
type: "text",
label: "Title",
key: "title",
nested: true,
},
{
type: "text",
label: "Description",
key: "desc",
nested: true,
},
{
type: "fieldConfiguration",
key: "fields",
nested: true,
},
{
type: "buttonConfiguration",
label: "Buttons",
key: "buttons",
wide: true,
nested: true,
},
],
},
],
}
// Step Definition Settings const getSectionName = ({ stepCount, currentStep }) => {
let compSettings = [ if (stepCount <= 1) {
{ return "Details"
customType: "formStepControl", }
label: "Multi-steps", return `Details (Step ${currentStep + 1}/${stepCount})`
key: "steps", }
},
{
type: "text",
label: "Title",
key: "title",
nested: true,
},
{
type: "text",
label: "Description",
key: "desc",
nested: true,
},
{
type: "fieldConfiguration",
key: "fields",
nested: true,
},
{
type: "buttonConfiguration",
label: "Buttons",
key: "buttons",
wide: true,
nested: true,
},
]
const emitCurrentStep = step => { const emitCurrentStep = step => {
store.actions.preview.sendEvent("builder-meta", { store.actions.preview.sendEvent("builder-meta", {
@ -79,70 +87,52 @@
}) })
} }
$: dataSource = getDatasourceForProvider($currentAsset, componentInstance)
$: stepDef = {
component: "@budibase/standard-components/multistepformblock-step",
name: "Formblock step",
settings: compSettings,
}
const addStep = () => { const addStep = () => {
const newStepIdx = currentStep + 1 const nextStep = currentStep + 1
dispatch("change", [
stepState = [ ...value.slice(0, nextStep),
...stepState.slice(0, newStepIdx),
{}, {},
...stepState.slice(newStepIdx), ...value.slice(nextStep),
] ])
multiStepStore.update(state => ({
stepStore.update(state => ({
...state, ...state,
currentStep: newStepIdx, currentStep: nextStep,
})) }))
dispatch("change", stepState)
emitCurrentStep(newStepIdx)
} }
const removeStep = () => { const removeStep = () => {
const clone = stepState.map(x => x) dispatch("change", value.toSpliced(currentStep, 1))
clone.splice(currentStep, 1) const newStep = Math.min(currentStep, stepCount - 2)
multiStepStore.update(state => ({
const targetStepIdx = Math.max(currentStep - 1, 0)
stepState = clone.map(x => x)
stepStore.update(state => ({
...state, ...state,
currentStep: targetStepIdx, currentStep: newStep,
})) }))
dispatch("change", stepState)
emitCurrentStep(targetStepIdx)
} }
const previousStep = () => { const previousStep = () => {
const prevStepIdx = Math.max(currentStep - 1, 0) const prevStepIdx = Math.max(currentStep - 1, 0)
stepStore.update(state => ({ multiStepStore.update(state => ({
...state, ...state,
currentStep: prevStepIdx, currentStep: prevStepIdx,
})) }))
emitCurrentStep(prevStepIdx)
} }
const nextStep = () => { const nextStep = () => {
const nextStepIdx = currentStep + 1 const nextStepIdx = currentStep + 1
stepStore.update(state => ({ multiStepStore.update(state => ({
...state, ...state,
currentStep: Math.min(nextStepIdx, stepState.length - 1), currentStep: Math.min(nextStepIdx, value.length - 1),
})) }))
emitCurrentStep(nextStepIdx)
} }
const updateStep = (field, val) => { const updateStep = (field, val) => {
stepState[currentStep] ||= {} const newStep = {
stepState[currentStep][field.key] = val ...value[currentStep],
dispatch("change", stepState) [field.key]: val,
}
let newValue = value.slice()
newValue[currentStep] = newStep
dispatch("change", newValue)
} }
const handleStepAction = action => { const handleStepAction = action => {
@ -158,9 +148,6 @@
break break
case "previousStep": case "previousStep":
previousStep() previousStep()
break
default:
console.log("Nothing")
} }
} }
@ -186,32 +173,27 @@
} }
} }
$: stepConfigInstance = buildPseudoInstance(stepState?.[currentStep] || {}) $: stepConfigInstance = buildPseudoInstance(value[currentStep] || {})
</script> </script>
<span class="settings-wrap"> <div class="nested-section">
<ComponentSettingsSection <ComponentSettingsSection
includeHidden includeHidden
componentInstance={stepConfigInstance} componentInstance={stepConfigInstance}
componentDefinition={stepDef} componentDefinition={stepDef}
onUpdateSetting={processUpdate} onUpdateSetting={processUpdate}
getCustomComponent={type => {
const types = { formStepControl: FormStepControls }
return types[type]
}}
getCustomSectionTitle={section => {
console.log(section.name)
if (section.name === "Details" && stepState?.length > 0) {
return `Details (${currentStep}/${stepState?.length})`
}
return section.name
}}
showSectionTitle={false}
showInstanceName={false} showInstanceName={false}
isScreen={false} isScreen={false}
noPadding={true}
nested={true} nested={true}
{bindings} {bindings}
{componentBindings} {componentBindings}
/> />
</span> </div>
<style>
.nested-section {
margin: 0 calc(-1 * var(--spacing-xl)) calc(-1 * var(--spacing-xl))
calc(-1 * var(--spacing-xl));
border-top: var(--border-light);
}
</style>

View file

@ -2,15 +2,10 @@
import { createEventDispatcher, getContext } from "svelte" import { createEventDispatcher, getContext } from "svelte"
import { ActionButton } from "@budibase/bbui" import { ActionButton } from "@budibase/bbui"
const stepState = getContext("step-form-block") const multiStepStore = getContext("multi-step-form-block")
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
$: ({ stepsCount, currentStep } = $stepState) $: ({ stepCount, currentStep } = $multiStepStore)
const parseLastIdx = stepsCount => {
return Math.max(stepsCount - 1, 0)
}
$: lastIdx = parseLastIdx(stepsCount)
const stepAction = action => { const stepAction = action => {
dispatch("change", { dispatch("change", {
@ -19,7 +14,7 @@
} }
</script> </script>
{#if stepsCount === 1} {#if stepCount === 1}
<ActionButton <ActionButton
icon="MultipleAdd" icon="MultipleAdd"
secondary secondary
@ -43,7 +38,7 @@
<ActionButton <ActionButton
size="S" size="S"
secondary secondary
disabled={currentStep === lastIdx} disabled={currentStep === stepCount - 1}
icon="ChevronRight" icon="ChevronRight"
on:click={() => { on:click={() => {
stepAction("nextStep") stepAction("nextStep")
@ -53,7 +48,7 @@
size="S" size="S"
secondary secondary
icon="Close" icon="Close"
disabled={stepsCount === 1} disabled={stepCount === 1}
on:click={() => { on:click={() => {
stepAction("removeStep") stepAction("removeStep")
}} }}

View file

@ -15,12 +15,9 @@
export let componentBindings export let componentBindings
export let isScreen = false export let isScreen = false
export let onUpdateSetting export let onUpdateSetting
export let getCustomComponent
export let getCustomSectionTitle
export let showSectionTitle = true export let showSectionTitle = true
export let includeHidden = false export let includeHidden = false
export let tag export let tag
export let noPadding = false
$: sections = getSections( $: sections = getSections(
componentInstance, componentInstance,
@ -133,30 +130,13 @@
}) })
} }
const resolveComponentByType = setting => {
if (setting.type) {
return getComponentForSetting(setting)
} else if (setting.customType && typeof getCustomComponent === "function") {
return getCustomComponent(setting.customType)
}
}
const resolveSectionName = section => {
console.log(resolveSectionName)
if (typeof getCustomSectionTitle === "function") {
return getCustomSectionTitle(section)
} else {
return section.name
}
}
const canRenderControl = (instance, setting, isScreen, includeHidden) => { const canRenderControl = (instance, setting, isScreen, includeHidden) => {
// Prevent rendering on click setting for screens // Prevent rendering on click setting for screens
if (setting?.type === "event" && isScreen) { if (setting?.type === "event" && isScreen) {
return false return false
} }
// Check we have a component to render for this setting // Check we have a component to render for this setting
const control = resolveComponentByType(setting) const control = getComponentForSetting(setting)
if (!control) { if (!control) {
return false return false
} }
@ -172,9 +152,8 @@
{#if section.visible} {#if section.visible}
<DetailSummary <DetailSummary
name={showSectionTitle ? section.name : ""} name={showSectionTitle ? section.name : ""}
show={section.collapsed !== true}
{noPadding}
initiallyShow={section.collapsed !== true} initiallyShow={section.collapsed !== true}
collapsible={section.name !== "General"}
> >
{#if section.info} {#if section.info}
<div class="section-info"> <div class="section-info">
@ -191,7 +170,7 @@
{#if setting.visible} {#if setting.visible}
<PropertyControl <PropertyControl
type={setting.type} type={setting.type}
control={resolveComponentByType(setting)} control={getComponentForSetting(setting)}
label={setting.label} label={setting.label}
labelHidden={setting.labelHidden} labelHidden={setting.labelHidden}
wide={setting.wide} wide={setting.wide}

View file

@ -6057,18 +6057,12 @@
"defaultValue": "Create" "defaultValue": "Create"
}, },
{ {
"name": "Details", "type": "stepConfiguration",
"section": true, "key": "steps",
"settings": [ "nested": true,
{ "labelHidden": true,
"type": "stepConfiguration", "resetOn": ["dataSource", "actionType"],
"key": "steps", "defaultValue": [{}]
"nested": true,
"labelHidden": true,
"resetOn": ["dataSource", "actionType"],
"defaultValue": [{}]
}
]
} }
], ],
"actions": [ "actions": [

View file

@ -102,7 +102,7 @@
buttons || buttons ||
Utils.buildMultiStepFormBlockButtonConfig({ Utils.buildMultiStepFormBlockButtonConfig({
_id: $component.id, _id: $component.id,
stepCount: steps?.length, stepCount: steps?.length ?? 0,
currentStep: idx, currentStep: idx,
}), }),
} }