Improve setting rendering and add dynamic section title
This commit is contained in:
parent
1bf556b4f2
commit
173a76dc52
|
@ -4,7 +4,6 @@
|
|||
export let name
|
||||
export let initiallyShow = false
|
||||
export let collapsible = true
|
||||
export let noPadding = false
|
||||
|
||||
let show = initiallyShow
|
||||
|
||||
|
@ -29,7 +28,6 @@
|
|||
class="property-panel"
|
||||
class:show={show || !collapsible}
|
||||
class:no-title={!name}
|
||||
class:no-padding={noPadding}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
@ -83,10 +81,6 @@
|
|||
padding: var(--spacing-xl);
|
||||
}
|
||||
|
||||
.property-panel.no-title.no-padding {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
|
@ -26,6 +26,7 @@ import FieldConfiguration from "./controls/FieldConfiguration/FieldConfiguration
|
|||
import ButtonConfiguration from "./controls/ButtonConfiguration/ButtonConfiguration.svelte"
|
||||
import RelationshipFilterEditor from "./controls/RelationshipFilterEditor.svelte"
|
||||
import FormStepConfiguration from "./controls/FormStepConfiguration.svelte"
|
||||
import FormStepControls from "components/design/settings/controls/FormStepControls.svelte"
|
||||
|
||||
const componentMap = {
|
||||
text: DrawerBindableInput,
|
||||
|
@ -53,6 +54,7 @@ const componentMap = {
|
|||
fieldConfiguration: FieldConfiguration,
|
||||
buttonConfiguration: ButtonConfiguration,
|
||||
stepConfiguration: FormStepConfiguration,
|
||||
formStepControls: FormStepControls,
|
||||
columns: ColumnEditor,
|
||||
"columns/basic": BasicColumnEditor,
|
||||
"columns/grid": GridColumnEditor,
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
import { getDatasourceForProvider } from "builderStore/dataBinding"
|
||||
import { currentAsset, store } from "builderStore"
|
||||
import { Helpers } from "@budibase/bbui"
|
||||
import FormStepControls from "./FormStepControls.svelte"
|
||||
import { writable } from "svelte/store"
|
||||
import { buildMultiStepFormBlockButtonConfig } from "@budibase/frontend-core/src/utils/utils"
|
||||
|
||||
|
@ -14,61 +13,70 @@
|
|||
export let bindings
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let stepState = [...(value || [])]
|
||||
|
||||
const stepStore = writable({
|
||||
stepsCount: stepState?.length || 1,
|
||||
const multiStepStore = writable({
|
||||
stepCount: value?.length ?? 0,
|
||||
currentStep: 0,
|
||||
})
|
||||
|
||||
setContext("step-form-block", stepStore)
|
||||
setContext("multi-step-form-block", multiStepStore)
|
||||
|
||||
$: ({ currentStep } = $stepStore)
|
||||
$: if (stepState.length) {
|
||||
stepStore.update(state => ({
|
||||
...state,
|
||||
stepsCount: stepState.length || 0,
|
||||
}))
|
||||
}
|
||||
$: currentStep = $multiStepStore.currentStep
|
||||
$: stepCount = value?.length || 0
|
||||
$: multiStepStore.update(state => ({ ...state, stepCount }))
|
||||
$: defaultButtonConfig = buildMultiStepFormBlockButtonConfig({
|
||||
_id: componentInstance._id,
|
||||
stepCount: value?.length,
|
||||
currentStep,
|
||||
stepCount: stepCount,
|
||||
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
|
||||
let compSettings = [
|
||||
{
|
||||
customType: "formStepControl",
|
||||
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,
|
||||
},
|
||||
]
|
||||
const getSectionName = ({ stepCount, currentStep }) => {
|
||||
if (stepCount <= 1) {
|
||||
return "Details"
|
||||
}
|
||||
return `Details (Step ${currentStep + 1}/${stepCount})`
|
||||
}
|
||||
|
||||
const emitCurrentStep = step => {
|
||||
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 newStepIdx = currentStep + 1
|
||||
|
||||
stepState = [
|
||||
...stepState.slice(0, newStepIdx),
|
||||
const nextStep = currentStep + 1
|
||||
dispatch("change", [
|
||||
...value.slice(0, nextStep),
|
||||
{},
|
||||
...stepState.slice(newStepIdx),
|
||||
]
|
||||
|
||||
stepStore.update(state => ({
|
||||
...value.slice(nextStep),
|
||||
])
|
||||
multiStepStore.update(state => ({
|
||||
...state,
|
||||
currentStep: newStepIdx,
|
||||
currentStep: nextStep,
|
||||
}))
|
||||
|
||||
dispatch("change", stepState)
|
||||
emitCurrentStep(newStepIdx)
|
||||
}
|
||||
|
||||
const removeStep = () => {
|
||||
const clone = stepState.map(x => x)
|
||||
clone.splice(currentStep, 1)
|
||||
|
||||
const targetStepIdx = Math.max(currentStep - 1, 0)
|
||||
stepState = clone.map(x => x)
|
||||
|
||||
stepStore.update(state => ({
|
||||
dispatch("change", value.toSpliced(currentStep, 1))
|
||||
const newStep = Math.min(currentStep, stepCount - 2)
|
||||
multiStepStore.update(state => ({
|
||||
...state,
|
||||
currentStep: targetStepIdx,
|
||||
currentStep: newStep,
|
||||
}))
|
||||
|
||||
dispatch("change", stepState)
|
||||
emitCurrentStep(targetStepIdx)
|
||||
}
|
||||
|
||||
const previousStep = () => {
|
||||
const prevStepIdx = Math.max(currentStep - 1, 0)
|
||||
stepStore.update(state => ({
|
||||
multiStepStore.update(state => ({
|
||||
...state,
|
||||
currentStep: prevStepIdx,
|
||||
}))
|
||||
emitCurrentStep(prevStepIdx)
|
||||
}
|
||||
|
||||
const nextStep = () => {
|
||||
const nextStepIdx = currentStep + 1
|
||||
stepStore.update(state => ({
|
||||
multiStepStore.update(state => ({
|
||||
...state,
|
||||
currentStep: Math.min(nextStepIdx, stepState.length - 1),
|
||||
currentStep: Math.min(nextStepIdx, value.length - 1),
|
||||
}))
|
||||
emitCurrentStep(nextStepIdx)
|
||||
}
|
||||
|
||||
const updateStep = (field, val) => {
|
||||
stepState[currentStep] ||= {}
|
||||
stepState[currentStep][field.key] = val
|
||||
dispatch("change", stepState)
|
||||
const newStep = {
|
||||
...value[currentStep],
|
||||
[field.key]: val,
|
||||
}
|
||||
let newValue = value.slice()
|
||||
newValue[currentStep] = newStep
|
||||
dispatch("change", newValue)
|
||||
}
|
||||
|
||||
const handleStepAction = action => {
|
||||
|
@ -158,9 +148,6 @@
|
|||
break
|
||||
case "previousStep":
|
||||
previousStep()
|
||||
break
|
||||
default:
|
||||
console.log("Nothing")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,32 +173,27 @@
|
|||
}
|
||||
}
|
||||
|
||||
$: stepConfigInstance = buildPseudoInstance(stepState?.[currentStep] || {})
|
||||
$: stepConfigInstance = buildPseudoInstance(value[currentStep] || {})
|
||||
</script>
|
||||
|
||||
<span class="settings-wrap">
|
||||
<div class="nested-section">
|
||||
<ComponentSettingsSection
|
||||
includeHidden
|
||||
componentInstance={stepConfigInstance}
|
||||
componentDefinition={stepDef}
|
||||
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}
|
||||
isScreen={false}
|
||||
noPadding={true}
|
||||
nested={true}
|
||||
{bindings}
|
||||
{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>
|
||||
|
|
|
@ -2,15 +2,10 @@
|
|||
import { createEventDispatcher, getContext } from "svelte"
|
||||
import { ActionButton } from "@budibase/bbui"
|
||||
|
||||
const stepState = getContext("step-form-block")
|
||||
const multiStepStore = getContext("multi-step-form-block")
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
$: ({ stepsCount, currentStep } = $stepState)
|
||||
|
||||
const parseLastIdx = stepsCount => {
|
||||
return Math.max(stepsCount - 1, 0)
|
||||
}
|
||||
$: lastIdx = parseLastIdx(stepsCount)
|
||||
$: ({ stepCount, currentStep } = $multiStepStore)
|
||||
|
||||
const stepAction = action => {
|
||||
dispatch("change", {
|
||||
|
@ -19,7 +14,7 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
{#if stepsCount === 1}
|
||||
{#if stepCount === 1}
|
||||
<ActionButton
|
||||
icon="MultipleAdd"
|
||||
secondary
|
||||
|
@ -43,7 +38,7 @@
|
|||
<ActionButton
|
||||
size="S"
|
||||
secondary
|
||||
disabled={currentStep === lastIdx}
|
||||
disabled={currentStep === stepCount - 1}
|
||||
icon="ChevronRight"
|
||||
on:click={() => {
|
||||
stepAction("nextStep")
|
||||
|
@ -53,7 +48,7 @@
|
|||
size="S"
|
||||
secondary
|
||||
icon="Close"
|
||||
disabled={stepsCount === 1}
|
||||
disabled={stepCount === 1}
|
||||
on:click={() => {
|
||||
stepAction("removeStep")
|
||||
}}
|
||||
|
|
|
@ -15,12 +15,9 @@
|
|||
export let componentBindings
|
||||
export let isScreen = false
|
||||
export let onUpdateSetting
|
||||
export let getCustomComponent
|
||||
export let getCustomSectionTitle
|
||||
export let showSectionTitle = true
|
||||
export let includeHidden = false
|
||||
export let tag
|
||||
export let noPadding = false
|
||||
|
||||
$: sections = getSections(
|
||||
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) => {
|
||||
// Prevent rendering on click setting for screens
|
||||
if (setting?.type === "event" && isScreen) {
|
||||
return false
|
||||
}
|
||||
// Check we have a component to render for this setting
|
||||
const control = resolveComponentByType(setting)
|
||||
const control = getComponentForSetting(setting)
|
||||
if (!control) {
|
||||
return false
|
||||
}
|
||||
|
@ -172,9 +152,8 @@
|
|||
{#if section.visible}
|
||||
<DetailSummary
|
||||
name={showSectionTitle ? section.name : ""}
|
||||
show={section.collapsed !== true}
|
||||
{noPadding}
|
||||
initiallyShow={section.collapsed !== true}
|
||||
collapsible={section.name !== "General"}
|
||||
>
|
||||
{#if section.info}
|
||||
<div class="section-info">
|
||||
|
@ -191,7 +170,7 @@
|
|||
{#if setting.visible}
|
||||
<PropertyControl
|
||||
type={setting.type}
|
||||
control={resolveComponentByType(setting)}
|
||||
control={getComponentForSetting(setting)}
|
||||
label={setting.label}
|
||||
labelHidden={setting.labelHidden}
|
||||
wide={setting.wide}
|
||||
|
|
|
@ -6057,18 +6057,12 @@
|
|||
"defaultValue": "Create"
|
||||
},
|
||||
{
|
||||
"name": "Details",
|
||||
"section": true,
|
||||
"settings": [
|
||||
{
|
||||
"type": "stepConfiguration",
|
||||
"key": "steps",
|
||||
"nested": true,
|
||||
"labelHidden": true,
|
||||
"resetOn": ["dataSource", "actionType"],
|
||||
"defaultValue": [{}]
|
||||
}
|
||||
]
|
||||
"type": "stepConfiguration",
|
||||
"key": "steps",
|
||||
"nested": true,
|
||||
"labelHidden": true,
|
||||
"resetOn": ["dataSource", "actionType"],
|
||||
"defaultValue": [{}]
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
buttons ||
|
||||
Utils.buildMultiStepFormBlockButtonConfig({
|
||||
_id: $component.id,
|
||||
stepCount: steps?.length,
|
||||
stepCount: steps?.length ?? 0,
|
||||
currentStep: idx,
|
||||
}),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue