Form Block Improvements (#10404)
* Form Block Improvements * PR Fixes * PR feedback
This commit is contained in:
parent
c08db11859
commit
0c38124f6a
|
@ -21,6 +21,7 @@ import DrawerBindableCombobox from "components/common/bindings/DrawerBindableCom
|
|||
import ColumnEditor from "./controls/ColumnEditor/ColumnEditor.svelte"
|
||||
import BasicColumnEditor from "./controls/ColumnEditor/BasicColumnEditor.svelte"
|
||||
import BarButtonList from "./controls/BarButtonList.svelte"
|
||||
import FieldConfiguration from "./controls/FieldConfiguration/FieldConfiguration.svelte"
|
||||
|
||||
const componentMap = {
|
||||
text: DrawerBindableCombobox,
|
||||
|
@ -43,6 +44,7 @@ const componentMap = {
|
|||
section: SectionSelect,
|
||||
filter: FilterEditor,
|
||||
url: URLSelect,
|
||||
fieldConfiguration: FieldConfiguration,
|
||||
columns: ColumnEditor,
|
||||
"columns/basic": BasicColumnEditor,
|
||||
"field/sortable": SortableFieldSelect,
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
<script>
|
||||
import { Button, ActionButton, Drawer } from "@budibase/bbui"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import ColumnDrawer from "./ColumnDrawer.svelte"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import {
|
||||
getDatasourceForProvider,
|
||||
getSchemaForDatasource,
|
||||
} from "builderStore/dataBinding"
|
||||
import { currentAsset } from "builderStore"
|
||||
import { getFields } from "helpers/searchFields"
|
||||
|
||||
export let componentInstance
|
||||
export let value = []
|
||||
export let allowCellEditing = true
|
||||
export let subject = "Table"
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let drawer
|
||||
let boundValue
|
||||
|
||||
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
||||
$: schema = getSchema($currentAsset, datasource)
|
||||
$: options = allowCellEditing
|
||||
? Object.keys(schema || {})
|
||||
: enrichedSchemaFields?.map(field => field.name)
|
||||
$: sanitisedValue = getValidColumns(value, options)
|
||||
$: updateBoundValue(sanitisedValue)
|
||||
$: enrichedSchemaFields = getFields(Object.values(schema || {}), {
|
||||
allowLinks: true,
|
||||
})
|
||||
|
||||
const getSchema = (asset, datasource) => {
|
||||
const schema = getSchemaForDatasource(asset, datasource).schema
|
||||
|
||||
// Don't show ID and rev in tables
|
||||
if (schema) {
|
||||
delete schema._id
|
||||
delete schema._rev
|
||||
}
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
const updateBoundValue = value => {
|
||||
boundValue = cloneDeep(value)
|
||||
}
|
||||
|
||||
const getValidColumns = (columns, options) => {
|
||||
if (!Array.isArray(columns) || !columns.length) {
|
||||
return []
|
||||
}
|
||||
// We need to account for legacy configs which would just be an array
|
||||
// of strings
|
||||
if (typeof columns[0] === "string") {
|
||||
columns = columns.map(col => ({
|
||||
name: col,
|
||||
displayName: col,
|
||||
}))
|
||||
}
|
||||
return columns.filter(column => {
|
||||
return options.includes(column.name)
|
||||
})
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
updateBoundValue(sanitisedValue)
|
||||
drawer.show()
|
||||
}
|
||||
|
||||
const save = () => {
|
||||
dispatch("change", getValidColumns(boundValue, options))
|
||||
drawer.hide()
|
||||
}
|
||||
</script>
|
||||
|
||||
<ActionButton on:click={open}>Configure columns</ActionButton>
|
||||
<Drawer bind:this={drawer} title="{subject} Columns">
|
||||
<svelte:fragment slot="description">
|
||||
Configure the columns in your {subject.toLowerCase()}.
|
||||
</svelte:fragment>
|
||||
<Button cta slot="buttons" on:click={save}>Save</Button>
|
||||
<ColumnDrawer
|
||||
slot="body"
|
||||
bind:columns={boundValue}
|
||||
{options}
|
||||
{schema}
|
||||
{allowCellEditing}
|
||||
/>
|
||||
</Drawer>
|
|
@ -0,0 +1,26 @@
|
|||
<script>
|
||||
import { DrawerContent, Drawer, Button, Icon } from "@budibase/bbui"
|
||||
import ValidationDrawer from "components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte"
|
||||
export let column
|
||||
export let type
|
||||
|
||||
let drawer
|
||||
</script>
|
||||
|
||||
<Icon name="Settings" hoverable size="S" on:click={drawer.show} />
|
||||
<Drawer bind:this={drawer} title="Field Validation">
|
||||
<svelte:fragment slot="description">
|
||||
"{column.name}" field validation
|
||||
</svelte:fragment>
|
||||
<Button cta slot="buttons" on:click={drawer.hide}>Save</Button>
|
||||
<DrawerContent slot="body">
|
||||
<div class="container">
|
||||
<ValidationDrawer
|
||||
slot="body"
|
||||
bind:rules={column.validation}
|
||||
fieldName={column.name}
|
||||
{type}
|
||||
/>
|
||||
</div>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
|
@ -0,0 +1,202 @@
|
|||
<script>
|
||||
import {
|
||||
Button,
|
||||
Icon,
|
||||
DrawerContent,
|
||||
Layout,
|
||||
Select,
|
||||
Label,
|
||||
Body,
|
||||
Input,
|
||||
} from "@budibase/bbui"
|
||||
import { flip } from "svelte/animate"
|
||||
import { dndzone } from "svelte-dnd-action"
|
||||
import { generate } from "shortid"
|
||||
import CellEditor from "./CellEditor.svelte"
|
||||
|
||||
export let columns = []
|
||||
export let options = []
|
||||
export let schema = {}
|
||||
|
||||
const flipDurationMs = 150
|
||||
let dragDisabled = true
|
||||
|
||||
$: unselectedColumns = getUnselectedColumns(options, columns)
|
||||
$: columns.forEach(column => {
|
||||
if (!column.id) {
|
||||
column.id = generate()
|
||||
}
|
||||
})
|
||||
|
||||
const getUnselectedColumns = (allColumns, selectedColumns) => {
|
||||
let optionsObj = {}
|
||||
allColumns.forEach(option => {
|
||||
optionsObj[option] = true
|
||||
})
|
||||
selectedColumns?.forEach(column => {
|
||||
delete optionsObj[column.name]
|
||||
})
|
||||
return Object.keys(optionsObj)
|
||||
}
|
||||
|
||||
const getRemainingColumnOptions = selectedColumn => {
|
||||
if (!selectedColumn || unselectedColumns.includes(selectedColumn)) {
|
||||
return unselectedColumns
|
||||
}
|
||||
return [selectedColumn, ...unselectedColumns]
|
||||
}
|
||||
|
||||
const addColumn = () => {
|
||||
columns = [...columns, {}]
|
||||
}
|
||||
|
||||
const removeColumn = id => {
|
||||
columns = columns.filter(column => column.id !== id)
|
||||
}
|
||||
|
||||
const updateColumnOrder = e => {
|
||||
columns = e.detail.items
|
||||
}
|
||||
|
||||
const handleFinalize = e => {
|
||||
updateColumnOrder(e)
|
||||
dragDisabled = true
|
||||
}
|
||||
|
||||
const addAllColumns = () => {
|
||||
let newColumns = columns || []
|
||||
options.forEach(field => {
|
||||
const fieldSchema = schema[field]
|
||||
const hasCol = columns && columns.findIndex(x => x.name === field) !== -1
|
||||
if (!fieldSchema?.autocolumn && !hasCol) {
|
||||
newColumns.push({
|
||||
name: field,
|
||||
displayName: field,
|
||||
})
|
||||
}
|
||||
})
|
||||
columns = newColumns
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
columns = []
|
||||
}
|
||||
|
||||
const getFieldType = column => {
|
||||
return `validation/${schema[column.name]?.type}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<DrawerContent>
|
||||
<div class="container">
|
||||
<Layout noPadding gap="S">
|
||||
{#if columns?.length}
|
||||
<Layout noPadding gap="XS">
|
||||
<div class="column">
|
||||
<div />
|
||||
<Label size="L">Column</Label>
|
||||
<Label size="L">Label</Label>
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
class="columns"
|
||||
use:dndzone={{
|
||||
items: columns,
|
||||
flipDurationMs,
|
||||
dropTargetStyle: { outline: "none" },
|
||||
dragDisabled,
|
||||
}}
|
||||
on:finalize={handleFinalize}
|
||||
on:consider={updateColumnOrder}
|
||||
>
|
||||
{#each columns as column (column.id)}
|
||||
<div class="column" animate:flip={{ duration: flipDurationMs }}>
|
||||
<div
|
||||
class="handle"
|
||||
aria-label="drag-handle"
|
||||
style={dragDisabled ? "cursor: grab" : "cursor: grabbing"}
|
||||
on:mousedown={() => (dragDisabled = false)}
|
||||
>
|
||||
<Icon name="DragHandle" size="XL" />
|
||||
</div>
|
||||
<Select
|
||||
bind:value={column.name}
|
||||
placeholder="Column"
|
||||
options={getRemainingColumnOptions(column.name)}
|
||||
on:change={e => (column.displayName = e.detail)}
|
||||
/>
|
||||
<Input bind:value={column.displayName} placeholder="Label" />
|
||||
<CellEditor type={getFieldType(column)} bind:column />
|
||||
<Icon
|
||||
name="Close"
|
||||
hoverable
|
||||
size="S"
|
||||
on:click={() => removeColumn(column.id)}
|
||||
disabled={columns.length === 1}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Layout>
|
||||
{:else}
|
||||
<div class="column">
|
||||
<div class="wide">
|
||||
<Body size="S">Add columns to be included in your form below.</Body>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="column">
|
||||
<div class="buttons wide">
|
||||
<Button secondary icon="Add" on:click={addColumn}>Add column</Button>
|
||||
<Button secondary quiet on:click={addAllColumns}>
|
||||
Add all columns
|
||||
</Button>
|
||||
{#if columns?.length}
|
||||
<Button secondary quiet on:click={reset}>Reset columns</Button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
</div>
|
||||
</DrawerContent>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.columns {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
gap: var(--spacing-m);
|
||||
}
|
||||
.column {
|
||||
gap: var(--spacing-l);
|
||||
display: grid;
|
||||
grid-template-columns: 20px 1fr 1fr 16px 16px;
|
||||
align-items: center;
|
||||
border-radius: var(--border-radius-s);
|
||||
transition: background-color ease-in-out 130ms;
|
||||
}
|
||||
.column:hover {
|
||||
background-color: var(--spectrum-global-color-gray-100);
|
||||
}
|
||||
.handle {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
.wide {
|
||||
grid-column: 2 / -1;
|
||||
}
|
||||
.buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: var(--spacing-m);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,89 @@
|
|||
<script>
|
||||
import { Button, ActionButton, Drawer } from "@budibase/bbui"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import ColumnDrawer from "./ColumnDrawer.svelte"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import {
|
||||
getDatasourceForProvider,
|
||||
getSchemaForDatasource,
|
||||
} from "builderStore/dataBinding"
|
||||
import { currentAsset } from "builderStore"
|
||||
import { getFields } from "helpers/searchFields"
|
||||
|
||||
export let componentInstance
|
||||
export let value = []
|
||||
|
||||
const convertOldColumnFormat = oldColumns => {
|
||||
if (typeof oldColumns?.[0] === "string") {
|
||||
value = oldColumns.map(field => ({ name: field, displayName: field }))
|
||||
}
|
||||
}
|
||||
|
||||
$: convertOldColumnFormat(value)
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let drawer
|
||||
let boundValue
|
||||
|
||||
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
||||
$: schema = getSchema($currentAsset, datasource)
|
||||
$: options = Object.keys(schema || {})
|
||||
$: sanitisedValue = getValidColumns(value, options)
|
||||
$: updateBoundValue(sanitisedValue)
|
||||
$: enrichedSchemaFields = getFields(Object.values(schema || {}), {
|
||||
allowLinks: true,
|
||||
})
|
||||
|
||||
const getSchema = (asset, datasource) => {
|
||||
const schema = getSchemaForDatasource(asset, datasource).schema
|
||||
|
||||
// Don't show ID and rev in tables
|
||||
if (schema) {
|
||||
delete schema._id
|
||||
delete schema._rev
|
||||
}
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
const updateBoundValue = value => {
|
||||
boundValue = cloneDeep(value)
|
||||
}
|
||||
|
||||
const getValidColumns = (columns, options) => {
|
||||
if (!Array.isArray(columns) || !columns.length) {
|
||||
return []
|
||||
}
|
||||
// We need to account for legacy configs which would just be an array
|
||||
// of strings
|
||||
if (typeof columns[0] === "string") {
|
||||
columns = columns.map(col => ({
|
||||
name: col,
|
||||
displayName: col,
|
||||
}))
|
||||
}
|
||||
return columns.filter(column => {
|
||||
return options.includes(column.name)
|
||||
})
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
updateBoundValue(sanitisedValue)
|
||||
drawer.show()
|
||||
}
|
||||
|
||||
const save = () => {
|
||||
dispatch("change", getValidColumns(boundValue, options))
|
||||
drawer.hide()
|
||||
}
|
||||
</script>
|
||||
|
||||
<ActionButton on:click={open}>Configure fields</ActionButton>
|
||||
<Drawer bind:this={drawer} title="Form Fields">
|
||||
<svelte:fragment slot="description">
|
||||
Configure the fields in your form.
|
||||
</svelte:fragment>
|
||||
<Button cta slot="buttons" on:click={save}>Save</Button>
|
||||
<ColumnDrawer slot="body" bind:columns={boundValue} {options} {schema} />
|
||||
</Drawer>
|
|
@ -16,6 +16,7 @@
|
|||
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte"
|
||||
import { generate } from "shortid"
|
||||
|
||||
export let fieldName = null
|
||||
export let rules = []
|
||||
export let bindings = []
|
||||
export let type
|
||||
|
@ -124,7 +125,7 @@
|
|||
}
|
||||
|
||||
$: dataSourceSchema = getDataSourceSchema($currentAsset, $selectedComponent)
|
||||
$: field = $selectedComponent?.field
|
||||
$: field = fieldName || $selectedComponent?.field
|
||||
$: schemaRules = parseRulesFromSchema(field, dataSourceSchema || {})
|
||||
$: fieldType = type?.split("/")[1] || "string"
|
||||
$: constraintOptions = getConstraintsForType(fieldType)
|
||||
|
@ -140,8 +141,12 @@
|
|||
const formParent = findClosestMatchingComponent(
|
||||
asset.props,
|
||||
component._id,
|
||||
component => component._component.endsWith("/form")
|
||||
component =>
|
||||
component._component.endsWith("/form") ||
|
||||
component._component.endsWith("/formblock") ||
|
||||
component._component.endsWith("/tableblock")
|
||||
)
|
||||
|
||||
return getSchemaForDatasource(asset, formParent?.dataSource)
|
||||
}
|
||||
|
||||
|
|
|
@ -4435,6 +4435,48 @@
|
|||
"key": "row"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Fields",
|
||||
"type": "fieldConfiguration",
|
||||
"key": "sidePanelFields",
|
||||
"nested": true,
|
||||
"dependsOn": {
|
||||
"setting": "clickBehaviour",
|
||||
"value": "details"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Show delete",
|
||||
"type": "boolean",
|
||||
"key": "sidePanelShowDelete",
|
||||
"nested": true,
|
||||
"dependsOn": {
|
||||
"setting": "clickBehaviour",
|
||||
"value": "details"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Save label",
|
||||
"type": "text",
|
||||
"key": "sidePanelSaveLabel",
|
||||
"defaultValue": "Save",
|
||||
"nested": true,
|
||||
"dependsOn": {
|
||||
"setting": "clickBehaviour",
|
||||
"value": "details"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Delete label",
|
||||
"type": "text",
|
||||
"key": "sidePanelDeleteLabel",
|
||||
"defaultValue": "Delete",
|
||||
"nested": true,
|
||||
"dependsOn": {
|
||||
"setting": "clickBehaviour",
|
||||
"value": "details"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -4979,7 +5021,7 @@
|
|||
"name": "Fields",
|
||||
"settings": [
|
||||
{
|
||||
"type": "multifield",
|
||||
"type": "fieldConfiguration",
|
||||
"label": "Fields",
|
||||
"key": "fields",
|
||||
"selectAllFields": true
|
||||
|
@ -5028,6 +5070,17 @@
|
|||
"invert": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "saveButtonLabel",
|
||||
"label": "Save button label",
|
||||
"nested": true,
|
||||
"defaultValue": "Save",
|
||||
"dependsOn": {
|
||||
"setting": "showSaveButton",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"label": "Allow delete",
|
||||
|
@ -5038,6 +5091,17 @@
|
|||
"value": "Update"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "deleteButtonLabel",
|
||||
"label": "Delete button label",
|
||||
"nested": true,
|
||||
"defaultValue": "Delete",
|
||||
"dependsOn": {
|
||||
"setting": "showDeleteButton",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "Navigate after button press",
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
export let titleButtonClickBehaviour
|
||||
export let onClickTitleButton
|
||||
export let noRowsMessage
|
||||
export let sidePanelFields
|
||||
export let sidePanelShowDelete
|
||||
export let sidePanelSaveLabel
|
||||
export let sidePanelDeleteLabel
|
||||
|
||||
const { fetchDatasourceSchema, API } = getContext("sdk")
|
||||
const stateKey = `ID_${generate()}`
|
||||
|
@ -241,10 +245,12 @@
|
|||
props={{
|
||||
dataSource,
|
||||
showSaveButton: true,
|
||||
showDeleteButton: true,
|
||||
showDeleteButton: sidePanelShowDelete,
|
||||
saveButtonLabel: sidePanelSaveLabel,
|
||||
deleteButtonLabel: sidePanelDeleteLabel,
|
||||
actionType: "Update",
|
||||
rowId: `{{ ${safe("state")}.${safe(stateKey)} }}`,
|
||||
fields: normalFields,
|
||||
fields: sidePanelFields || normalFields,
|
||||
title: editTitle,
|
||||
labelPosition: "left",
|
||||
}}
|
||||
|
@ -266,8 +272,9 @@
|
|||
dataSource,
|
||||
showSaveButton: true,
|
||||
showDeleteButton: false,
|
||||
saveButtonLabel: sidePanelSaveLabel,
|
||||
actionType: "Create",
|
||||
fields: normalFields,
|
||||
fields: sidePanelFields || normalFields,
|
||||
title: "Create Row",
|
||||
labelPosition: "left",
|
||||
}}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
export let fields
|
||||
export let labelPosition
|
||||
export let title
|
||||
export let saveButtonLabel
|
||||
export let deleteButtonLabel
|
||||
export let showSaveButton
|
||||
export let showDeleteButton
|
||||
export let rowId
|
||||
|
@ -20,10 +22,40 @@
|
|||
|
||||
const { fetchDatasourceSchema } = getContext("sdk")
|
||||
|
||||
const convertOldFieldFormat = fields => {
|
||||
if (typeof fields?.[0] === "string") {
|
||||
return fields.map(field => ({ name: field, displayName: field }))
|
||||
}
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
const getDefaultFields = (fields, schema) => {
|
||||
if (schema && (!fields || fields.length === 0)) {
|
||||
const defaultFields = []
|
||||
|
||||
Object.values(schema).forEach(field => {
|
||||
if (field.autocolumn) return
|
||||
|
||||
defaultFields.push({
|
||||
name: field.name,
|
||||
displayName: field.name,
|
||||
})
|
||||
})
|
||||
|
||||
return defaultFields
|
||||
}
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
let schema
|
||||
let providerId
|
||||
let repeaterId
|
||||
|
||||
$: formattedFields = convertOldFieldFormat(fields)
|
||||
$: fieldsOrDefault = getDefaultFields(formattedFields, schema)
|
||||
|
||||
$: fetchSchema(dataSource)
|
||||
$: dataProvider = `{{ literal ${safe(providerId)} }}`
|
||||
$: filter = [
|
||||
|
@ -46,9 +78,11 @@
|
|||
actionType,
|
||||
size,
|
||||
disabled,
|
||||
fields,
|
||||
fields: fieldsOrDefault,
|
||||
labelPosition,
|
||||
title,
|
||||
saveButtonLabel,
|
||||
deleteButtonLabel,
|
||||
showSaveButton,
|
||||
showDeleteButton,
|
||||
schema,
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
export let fields
|
||||
export let labelPosition
|
||||
export let title
|
||||
export let saveButtonLabel
|
||||
export let deleteButtonLabel
|
||||
export let showSaveButton
|
||||
export let showDeleteButton
|
||||
export let schema
|
||||
|
@ -33,6 +35,12 @@
|
|||
let formId
|
||||
|
||||
$: onSave = [
|
||||
{
|
||||
"##eventHandlerType": "Validate Form",
|
||||
parameters: {
|
||||
componentId: formId,
|
||||
},
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Save Row",
|
||||
parameters: {
|
||||
|
@ -163,7 +171,7 @@
|
|||
<BlockComponent
|
||||
type="button"
|
||||
props={{
|
||||
text: "Delete",
|
||||
text: deleteButtonLabel || "Delete",
|
||||
onClick: onDelete,
|
||||
quiet: true,
|
||||
type: "secondary",
|
||||
|
@ -175,7 +183,7 @@
|
|||
<BlockComponent
|
||||
type="button"
|
||||
props={{
|
||||
text: "Save",
|
||||
text: saveButtonLabel || "Save",
|
||||
onClick: onSave,
|
||||
type: "cta",
|
||||
}}
|
||||
|
@ -188,14 +196,14 @@
|
|||
{/if}
|
||||
<BlockComponent type="fieldgroup" props={{ labelPosition }} order={1}>
|
||||
{#each fields as field, idx}
|
||||
{#if getComponentForField(field)}
|
||||
{#if getComponentForField(field.name)}
|
||||
<BlockComponent
|
||||
type={getComponentForField(field)}
|
||||
type={getComponentForField(field.name)}
|
||||
props={{
|
||||
field,
|
||||
label: field,
|
||||
placeholder: field,
|
||||
disabled,
|
||||
validation: field.validation,
|
||||
field: field.name,
|
||||
label: field.displayName,
|
||||
placeholder: field.displayName,
|
||||
}}
|
||||
order={idx}
|
||||
/>
|
||||
|
|
Loading…
Reference in New Issue