Refactor form block layout and add functional update and view multi step forms
This commit is contained in:
parent
ac0f034ff4
commit
08cd5bbb91
|
@ -78,7 +78,7 @@
|
||||||
var(--spacing-xl);
|
var(--spacing-xl);
|
||||||
}
|
}
|
||||||
.property-panel.no-title {
|
.property-panel.no-title {
|
||||||
padding-top: 0;
|
padding-top: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.show {
|
.show {
|
||||||
|
|
|
@ -32,21 +32,19 @@
|
||||||
const generalSettings = settings.filter(
|
const generalSettings = settings.filter(
|
||||||
setting => !setting.section && setting.tag === tag
|
setting => !setting.section && setting.tag === tag
|
||||||
)
|
)
|
||||||
|
|
||||||
const customSections = settings.filter(
|
const customSections = settings.filter(
|
||||||
setting => setting.section && setting.tag === tag
|
setting => setting.section && setting.tag === tag
|
||||||
)
|
)
|
||||||
let sections = [
|
let sections = []
|
||||||
...(generalSettings?.length
|
if (generalSettings.length) {
|
||||||
? [
|
sections.push({
|
||||||
{
|
|
||||||
name: "General",
|
name: "General",
|
||||||
settings: generalSettings,
|
settings: generalSettings,
|
||||||
},
|
})
|
||||||
]
|
}
|
||||||
: []),
|
if (customSections.length) {
|
||||||
...(customSections || []),
|
sections = sections.concat(customSections)
|
||||||
]
|
}
|
||||||
|
|
||||||
// Filter out settings which shouldn't be rendered
|
// Filter out settings which shouldn't be rendered
|
||||||
sections.forEach(section => {
|
sections.forEach(section => {
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import BlockComponent from "components/BlockComponent.svelte"
|
import BlockComponent from "components/BlockComponent.svelte"
|
||||||
import Block from "components/Block.svelte"
|
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { builderStore } from "stores"
|
import { builderStore } from "stores"
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
|
import FormBlockWrapper from "./form/FormBlockWrapper.svelte"
|
||||||
|
|
||||||
|
export let actionType
|
||||||
|
export let rowId
|
||||||
|
export let noRowsMessage
|
||||||
export let steps
|
export let steps
|
||||||
export let dataSource
|
export let dataSource
|
||||||
export let initialFormStep = 1
|
export let initialFormStep = 1
|
||||||
|
@ -102,6 +105,8 @@
|
||||||
_id: id,
|
_id: id,
|
||||||
stepCount: safeSteps.length,
|
stepCount: safeSteps.length,
|
||||||
currentStep: idx,
|
currentStep: idx,
|
||||||
|
actionType,
|
||||||
|
dataSource,
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
fields: getDefaultFields(fields || [], schema),
|
fields: getDefaultFields(fields || [], schema),
|
||||||
|
@ -113,20 +118,17 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Block>
|
<FormBlockWrapper {actionType} {dataSource} {rowId} {noRowsMessage}>
|
||||||
<BlockComponent
|
<BlockComponent
|
||||||
type="form"
|
type="form"
|
||||||
|
context="form"
|
||||||
props={{
|
props={{
|
||||||
dataSource,
|
dataSource,
|
||||||
initialFormStep,
|
initialFormStep,
|
||||||
step: currentStep,
|
step: currentStep,
|
||||||
|
actionType: actionType === "Create" ? "Create" : "Update",
|
||||||
|
readonly: actionType === "View",
|
||||||
}}
|
}}
|
||||||
context="form"
|
|
||||||
>
|
|
||||||
{#each enrichedSteps as step, idx}
|
|
||||||
<BlockComponent
|
|
||||||
type="formstep"
|
|
||||||
props={{ step: idx + 1, _instanceName: `Step ${idx + 1}` }}
|
|
||||||
styles={{
|
styles={{
|
||||||
normal: {
|
normal: {
|
||||||
width: "600px",
|
width: "600px",
|
||||||
|
@ -134,6 +136,11 @@
|
||||||
"margin-right": "auto",
|
"margin-right": "auto",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
>
|
||||||
|
{#each enrichedSteps as step, idx}
|
||||||
|
<BlockComponent
|
||||||
|
type="formstep"
|
||||||
|
props={{ step: idx + 1, _instanceName: `Step ${idx + 1}` }}
|
||||||
>
|
>
|
||||||
<BlockComponent
|
<BlockComponent
|
||||||
type="container"
|
type="container"
|
||||||
|
@ -176,4 +183,4 @@
|
||||||
</BlockComponent>
|
</BlockComponent>
|
||||||
{/each}
|
{/each}
|
||||||
</BlockComponent>
|
</BlockComponent>
|
||||||
</Block>
|
</FormBlockWrapper>
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import BlockComponent from "components/BlockComponent.svelte"
|
|
||||||
import Block from "components/Block.svelte"
|
|
||||||
import { makePropSafe as safe } from "@budibase/string-templates"
|
|
||||||
import InnerFormBlock from "./InnerFormBlock.svelte"
|
import InnerFormBlock from "./InnerFormBlock.svelte"
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
|
import FormBlockWrapper from "./FormBlockWrapper.svelte"
|
||||||
|
|
||||||
export let actionType
|
export let actionType
|
||||||
export let dataSource
|
export let dataSource
|
||||||
|
@ -71,22 +69,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let schema
|
let schema
|
||||||
let providerId
|
|
||||||
let repeaterId
|
|
||||||
|
|
||||||
$: formattedFields = convertOldFieldFormat(fields)
|
$: formattedFields = convertOldFieldFormat(fields)
|
||||||
$: fieldsOrDefault = getDefaultFields(formattedFields, schema)
|
$: fieldsOrDefault = getDefaultFields(formattedFields, schema)
|
||||||
$: fetchSchema(dataSource)
|
$: fetchSchema(dataSource)
|
||||||
$: dataProvider = `{{ literal ${safe(providerId)} }}`
|
|
||||||
$: filter = [
|
|
||||||
{
|
|
||||||
field: "_id",
|
|
||||||
operator: "equal",
|
|
||||||
type: "string",
|
|
||||||
value: !rowId ? `{{ ${safe("url")}.${safe("id")} }}` : rowId,
|
|
||||||
valueType: "Binding",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
// We could simply spread $$props into the inner form and append our
|
// We could simply spread $$props into the inner form and append our
|
||||||
// additions, but that would create svelte warnings about unused props and
|
// additions, but that would create svelte warnings about unused props and
|
||||||
// make maintenance in future more confusing as we typically always have a
|
// make maintenance in future more confusing as we typically always have a
|
||||||
|
@ -102,7 +88,6 @@
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
schema,
|
schema,
|
||||||
repeaterId,
|
|
||||||
notificationOverride,
|
notificationOverride,
|
||||||
buttons:
|
buttons:
|
||||||
buttons ||
|
buttons ||
|
||||||
|
@ -124,43 +109,6 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Block>
|
<FormBlockWrapper {actionType} {dataSource} {rowId} {noRowsMessage}>
|
||||||
{#if actionType === "Create"}
|
|
||||||
<BlockComponent
|
|
||||||
type="container"
|
|
||||||
props={{
|
|
||||||
direction: "column",
|
|
||||||
hAlign: "left",
|
|
||||||
vAlign: "stretch",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<InnerFormBlock {...innerProps} />
|
<InnerFormBlock {...innerProps} />
|
||||||
</BlockComponent>
|
</FormBlockWrapper>
|
||||||
{:else}
|
|
||||||
<BlockComponent
|
|
||||||
type="dataprovider"
|
|
||||||
context="provider"
|
|
||||||
bind:id={providerId}
|
|
||||||
props={{
|
|
||||||
dataSource,
|
|
||||||
filter,
|
|
||||||
limit: 1,
|
|
||||||
paginate: false,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<BlockComponent
|
|
||||||
type="repeater"
|
|
||||||
context="repeater"
|
|
||||||
bind:id={repeaterId}
|
|
||||||
props={{
|
|
||||||
dataProvider,
|
|
||||||
noRowsMessage: noRowsMessage || "We couldn't find a row to display",
|
|
||||||
direction: "column",
|
|
||||||
hAlign: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<InnerFormBlock {...innerProps} />
|
|
||||||
</BlockComponent>
|
|
||||||
</BlockComponent>
|
|
||||||
{/if}
|
|
||||||
</Block>
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
<script>
|
||||||
|
import BlockComponent from "components/BlockComponent.svelte"
|
||||||
|
import Block from "components/Block.svelte"
|
||||||
|
import { makePropSafe as safe } from "@budibase/string-templates"
|
||||||
|
import { getContext } from "svelte"
|
||||||
|
|
||||||
|
export let actionType
|
||||||
|
export let dataSource
|
||||||
|
export let rowId
|
||||||
|
export let noRowsMessage
|
||||||
|
|
||||||
|
const component = getContext("component")
|
||||||
|
|
||||||
|
$: providerId = `${$component.id}-provider`
|
||||||
|
$: dataProvider = `{{ literal ${safe(providerId)} }}`
|
||||||
|
$: filter = [
|
||||||
|
{
|
||||||
|
field: "_id",
|
||||||
|
operator: "equal",
|
||||||
|
type: "string",
|
||||||
|
value: !rowId ? `{{ ${safe("url")}.${safe("id")} }}` : rowId,
|
||||||
|
valueType: "Binding",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Block>
|
||||||
|
{#if actionType === "Create"}
|
||||||
|
<BlockComponent
|
||||||
|
type="container"
|
||||||
|
props={{
|
||||||
|
direction: "column",
|
||||||
|
hAlign: "left",
|
||||||
|
vAlign: "stretch",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</BlockComponent>
|
||||||
|
{:else}
|
||||||
|
<BlockComponent
|
||||||
|
type="dataprovider"
|
||||||
|
context="provider"
|
||||||
|
props={{
|
||||||
|
dataSource,
|
||||||
|
filter,
|
||||||
|
limit: 1,
|
||||||
|
paginate: false,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BlockComponent
|
||||||
|
type="repeater"
|
||||||
|
context="repeater"
|
||||||
|
props={{
|
||||||
|
dataProvider,
|
||||||
|
noRowsMessage: noRowsMessage || "We couldn't find a row to display",
|
||||||
|
direction: "column",
|
||||||
|
hAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</BlockComponent>
|
||||||
|
</BlockComponent>
|
||||||
|
{/if}
|
||||||
|
</Block>
|
|
@ -242,15 +242,16 @@ export const buildFormBlockButtonConfig = props => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const buildMultiStepFormBlockDefaultProps = props => {
|
export const buildMultiStepFormBlockDefaultProps = props => {
|
||||||
const { _id, stepCount, currentStep } = props || {}
|
const { _id, stepCount, currentStep, actionType, dataSource } = props || {}
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (!_id || !stepCount) {
|
if (!_id || !stepCount) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default the title to "Step X"
|
|
||||||
const title = `Step {{ [${_id}-form].[__currentStep] }}`
|
const title = `Step {{ [${_id}-form].[__currentStep] }}`
|
||||||
|
const resourceId = dataSource?.resourceId
|
||||||
|
const formId = `${_id}-form`
|
||||||
let buttons = []
|
let buttons = []
|
||||||
|
|
||||||
// Add previous step button if we aren't the first step
|
// Add previous step button if we aren't the first step
|
||||||
|
@ -266,7 +267,7 @@ export const buildMultiStepFormBlockDefaultProps = props => {
|
||||||
{
|
{
|
||||||
parameters: {
|
parameters: {
|
||||||
type: "prev",
|
type: "prev",
|
||||||
componentId: `${_id}-form`,
|
componentId: formId,
|
||||||
},
|
},
|
||||||
"##eventHandlerType": "Change Form Step",
|
"##eventHandlerType": "Change Form Step",
|
||||||
},
|
},
|
||||||
|
@ -287,13 +288,13 @@ export const buildMultiStepFormBlockDefaultProps = props => {
|
||||||
{
|
{
|
||||||
"##eventHandlerType": "Validate Form",
|
"##eventHandlerType": "Validate Form",
|
||||||
parameters: {
|
parameters: {
|
||||||
componentId: `${_id}-form`,
|
componentId: formId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
parameters: {
|
parameters: {
|
||||||
type: "next",
|
type: "next",
|
||||||
componentId: `${_id}-form`,
|
componentId: formId,
|
||||||
},
|
},
|
||||||
"##eventHandlerType": "Change Form Step",
|
"##eventHandlerType": "Change Form Step",
|
||||||
},
|
},
|
||||||
|
@ -302,7 +303,7 @@ export const buildMultiStepFormBlockDefaultProps = props => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add save button if we are the last step
|
// Add save button if we are the last step
|
||||||
if (currentStep === stepCount - 1) {
|
if (actionType !== "View" && currentStep === stepCount - 1) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
_id: Helpers.uuid(),
|
_id: Helpers.uuid(),
|
||||||
_component: "@budibase/standard-components/button",
|
_component: "@budibase/standard-components/button",
|
||||||
|
@ -314,9 +315,27 @@ export const buildMultiStepFormBlockDefaultProps = props => {
|
||||||
{
|
{
|
||||||
"##eventHandlerType": "Validate Form",
|
"##eventHandlerType": "Validate Form",
|
||||||
parameters: {
|
parameters: {
|
||||||
componentId: `${_id}-form`,
|
componentId: formId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"##eventHandlerType": "Save Row",
|
||||||
|
parameters: {
|
||||||
|
tableId: resourceId,
|
||||||
|
providerId: formId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Clear a create form once submitted
|
||||||
|
...(actionType !== "Create"
|
||||||
|
? []
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
"##eventHandlerType": "Clear Form",
|
||||||
|
parameters: {
|
||||||
|
componentId: formId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue