1
0
Fork 0
mirror of synced 2024-06-01 18:20:18 +12:00

Remove form block and rename form block plus to form block

This commit is contained in:
Andrew Kingston 2022-08-23 14:58:56 +01:00
parent 69ef8a1367
commit c99b5398b2
5 changed files with 165 additions and 394 deletions

View file

@ -6,8 +6,7 @@
"tableblock",
"cardsblock",
"repeaterblock",
"formblock",
"formblockplus"
"formblock"
]
},
{

View file

@ -4389,142 +4389,12 @@
"type": "select",
"label": "Type",
"key": "actionType",
"options": ["Create", "Update"],
"defaultValue": "Create"
},
{
"type": "dataSource",
"label": "Schema",
"key": "dataSource"
},
{
"type": "text",
"label": "Title",
"key": "title"
},
{
"section": true,
"name": "Fields",
"settings": [
{
"type": "multifield",
"label": "Fields",
"key": "fields"
},
{
"type": "select",
"label": "Field labels",
"key": "labelPosition",
"defaultValue": "left",
"options": [
{
"label": "Left",
"value": "left"
},
{
"label": "Right",
"value": "right"
},
{
"label": "Above",
"value": "above"
}
]
},
{
"type": "select",
"label": "Size",
"key": "size",
"options": [
{
"label": "Medium",
"value": "spectrum--medium"
},
{
"label": "Large",
"value": "spectrum--large"
}
],
"defaultValue": "spectrum--medium"
},
{
"type": "boolean",
"label": "Disabled",
"key": "disabled",
"defaultValue": false
}
]
},
{
"section": true,
"name": "Buttons",
"settings": [
{
"type": "boolean",
"label": "Show primary button",
"key": "showPrimaryButton",
"defaultValue": true
},
{
"type": "text",
"label": "Text",
"key": "primaryButtonText",
"defaultValue": "Submit",
"dependsOn": "showPrimaryButton"
},
{
"type": "event",
"label": "On click",
"key": "primaryButtonOnClick",
"nested": true,
"dependsOn": "showPrimaryButton"
},
{
"type": "boolean",
"label": "Show secondary button",
"key": "showSecondaryButton",
"defaultValue": false
},
{
"type": "text",
"label": "Text",
"key": "secondaryButtonText",
"defaultValue": "Action",
"dependsOn": "showSecondaryButton"
},
{
"type": "event",
"label": "On click",
"key": "secondaryButtonOnClick",
"nested": true,
"dependsOn": "showSecondaryButton"
}
]
}
],
"context": [
{
"type": "form",
"suffix": "form"
}
]
},
"formblockplus": {
"name": "Form Block+",
"icon": "Form",
"styles": ["size"],
"block": true,
"settings": [
{
"type": "select",
"label": "Type",
"key": "actionType",
"options": ["Create", "Update"],
"options": ["Create", "Update", "View"],
"defaultValue": "Create"
},
{
"type": "table",
"label": "Schema",
"label": "Table",
"key": "dataSource"
},
{
@ -4561,10 +4431,6 @@
"label": "Left",
"value": "left"
},
{
"label": "Right",
"value": "right"
},
{
"label": "Above",
"value": "above"
@ -4591,7 +4457,12 @@
"type": "boolean",
"label": "Disabled",
"key": "disabled",
"defaultValue": false
"defaultValue": false,
"dependsOn": {
"setting": "actionType",
"value": "View",
"invert": true
}
}
]
},
@ -4603,7 +4474,12 @@
"type": "boolean",
"label": "Show save button",
"key": "showSaveButton",
"defaultValue": true
"defaultValue": true,
"dependsOn": {
"setting": "actionType",
"value": "View",
"invert": true
}
},
{
"type": "boolean",
@ -4614,6 +4490,17 @@
"setting": "actionType",
"value": "Update"
}
},
{
"type": "url",
"label": "Navigate after button press",
"key": "actionUrl",
"placeholder": "Choose a screen",
"dependsOn": {
"setting": "actionType",
"value": "View",
"invert": true
}
}
]
}

View file

@ -2,8 +2,9 @@
import { getContext } from "svelte"
import BlockComponent from "../../BlockComponent.svelte"
import Block from "../../Block.svelte"
import { Heading, Layout } from "@budibase/bbui"
import { Layout } from "@budibase/bbui"
import Placeholder from "../Placeholder.svelte"
import { makePropSafe as safe } from "@budibase/string-templates"
export let actionType
export let dataSource
@ -12,14 +13,12 @@
export let fields
export let labelPosition
export let title
export let showPrimaryButton
export let primaryButtonOnClick
export let primaryButtonText
export let showSecondaryButton
export let secondaryButtonOnClick
export let secondaryButtonText
export let showSaveButton
export let showDeleteButton
export let rowId
export let actionUrl
const { styleable, fetchDatasourceSchema } = getContext("sdk")
const { styleable, fetchDatasourceSchema, builderStore } = getContext("sdk")
const component = getContext("component")
const FieldTypeToComponentMap = {
string: "stringfield",
@ -35,7 +34,65 @@
}
let schema
let formId
let providerId
let repeaterId
$: fetchSchema(dataSource)
$: onSave = [
{
"##eventHandlerType": "Save Row",
parameters: {
providerId: formId,
tableId: dataSource?.tableId,
},
},
{
"##eventHandlerType": "Close Screen Modal",
},
{
"##eventHandlerType": "Navigate To",
parameters: {
url: actionUrl,
},
},
]
$: onDelete = [
{
"##eventHandlerType": "Delete Row",
parameters: {
confirm: true,
tableId: dataSource?.tableId,
rowId: `{{ ${safe(repeaterId)}.${safe("_id")} }}`,
revId: `{{ ${safe(repeaterId)}.${safe("_rev")} }}`,
},
},
{
"##eventHandlerType": "Close Screen Modal",
},
{
"##eventHandlerType": "Navigate To",
parameters: {
url: actionUrl,
},
},
]
$: filter = [
{
field: "_id",
operator: "equal",
type: "string",
value: rowId,
valueType: "binding",
},
]
// If we're using an "update" form, use the real data provider. If we're
// using a create form, we just want a fake array so that our repeater
// will actually render the form, but data doesn't matter.
$: dataProvider =
actionType === "Update"
? `{{ literal ${safe(providerId)} }}`
: { rows: [{}] }
const fetchSchema = async () => {
schema = (await fetchDatasourceSchema(dataSource)) || {}
@ -54,57 +111,85 @@
<div use:styleable={$component.styles}>
{#if fields?.length}
<BlockComponent
type="form"
props={{ actionType, dataSource, size, disabled }}
context="form"
type="dataprovider"
context="provider"
bind:id={providerId}
props={{
dataSource,
filter,
limit: rowId ? 1 : $builderStore.inBuilder ? 1 : 0,
paginate: false,
}}
>
<Layout noPadding gap="M">
<div class="title" class:with-text={!!title}>
<Heading>{title || ""}</Heading>
<div class="buttons">
{#if showSecondaryButton}
<BlockComponent
type="button"
props={{
text: secondaryButtonText,
onClick: secondaryButtonOnClick,
quiet: true,
type: "secondary",
}}
/>
{/if}
{#if showPrimaryButton}
<BlockComponent
type="button"
props={{
text: primaryButtonText,
onClick: primaryButtonOnClick,
type: "cta",
}}
/>
{/if}
</div>
</div>
<BlockComponent type="fieldgroup" props={{ labelPosition }}>
{#each fields as field}
{#if getComponentForField(field)}
<BlockComponent
type={getComponentForField(field)}
props={{
field,
label: field,
placeholder: field,
disabled,
}}
/>
{/if}
{/each}
<BlockComponent
type="repeater"
context="repeater"
bind:id={repeaterId}
props={{
dataProvider,
noRowsMessage: "We couldn't find a row to display",
}}
>
<BlockComponent
type="form"
props={{
actionType,
dataSource,
size,
disabled: disabled || actionType === "View",
}}
context="form"
bind:id={formId}
>
<Layout noPadding gap="M">
<div class="title" class:with-text={!!title}>
<BlockComponent type="heading" props={{ text: title || "" }} />
<div class="buttons">
{#if showDeleteButton && actionType === "Update"}
<BlockComponent
type="button"
props={{
text: "Delete",
onClick: onDelete,
quiet: true,
type: "secondary",
}}
/>
{/if}
{#if showSaveButton && actionType !== "View"}
<BlockComponent
type="button"
props={{
text: "Save",
onClick: onSave,
type: "cta",
}}
/>
{/if}
</div>
</div>
<BlockComponent type="fieldgroup" props={{ labelPosition }}>
{#each fields as field}
{#if getComponentForField(field)}
<BlockComponent
type={getComponentForField(field)}
props={{
field,
label: field,
placeholder: field,
disabled,
}}
/>
{/if}
{/each}
</BlockComponent>
</Layout>
</BlockComponent>
</Layout>
</BlockComponent>
</BlockComponent>
{:else}
<Placeholder
text="Choose your schema and add some fields to your form to get started"
text="Choose your table and add some fields to your form to get started"
/>
{/if}
</div>

View file

@ -1,199 +0,0 @@
<script>
import { getContext } from "svelte"
import BlockComponent from "../../BlockComponent.svelte"
import Block from "../../Block.svelte"
import { Layout } from "@budibase/bbui"
import Placeholder from "../Placeholder.svelte"
import { makePropSafe as safe } from "@budibase/string-templates"
export let actionType
export let dataSource
export let size
export let disabled
export let fields
export let labelPosition
export let title
export let showSaveButton
export let showDeleteButton
export let rowId
const { styleable, fetchDatasourceSchema, builderStore } = getContext("sdk")
const component = getContext("component")
const FieldTypeToComponentMap = {
string: "stringfield",
number: "numberfield",
options: "optionsfield",
array: "multifieldselect",
boolean: "booleanfield",
longform: "longformfield",
datetime: "datetimefield",
attachment: "attachmentfield",
link: "relationshipfield",
json: "jsonfield",
}
let schema
let formId
let providerId
let repeaterId
$: fetchSchema(dataSource)
$: onSave = [
{
"##eventHandlerType": "Save Row",
parameters: {
providerId: formId,
tableId: dataSource?.tableId,
},
},
{
"##eventHandlerType": "Close Screen Modal",
},
]
$: onDelete = [
{
"##eventHandlerType": "Delete Row",
parameters: {
confirm: true,
tableId: dataSource?.tableId,
rowId: `{{ ${safe(repeaterId)}.${safe("_id")} }}`,
revId: `{{ ${safe(repeaterId)}.${safe("_rev")} }}`,
},
},
{
"##eventHandlerType": "Close Screen Modal",
},
]
$: filter = [
{
field: "_id",
operator: "equal",
type: "string",
value: rowId,
valueType: "binding",
},
]
// If we're using an "update" form, use the real data provider. If we're
// using a create form, we just want a fake array so that our repeater
// will actually render the form, but data doesn't matter.
$: dataProvider =
actionType === "Update"
? `{{ literal ${safe(providerId)} }}`
: { rows: [{}] }
const fetchSchema = async () => {
schema = (await fetchDatasourceSchema(dataSource)) || {}
}
const getComponentForField = field => {
if (!field || !schema?.[field]) {
return null
}
const type = schema[field].type
return FieldTypeToComponentMap[type]
}
</script>
<Block>
<div use:styleable={$component.styles}>
{#if fields?.length}
<BlockComponent
type="dataprovider"
context="provider"
bind:id={providerId}
props={{
dataSource,
filter,
limit: rowId ? 1 : $builderStore.inBuilder ? 1 : 0,
paginate: false,
}}
>
<BlockComponent
type="repeater"
context="repeater"
bind:id={repeaterId}
props={{
dataProvider,
noRowsMessage: "We couldn't find a row to display",
}}
>
<BlockComponent
type="form"
props={{ actionType, dataSource, size, disabled }}
context="form"
bind:id={formId}
>
<Layout noPadding gap="M">
<div class="title" class:with-text={!!title}>
<BlockComponent type="heading" props={{ text: title || "" }} />
<div class="buttons">
{#if showDeleteButton}
<BlockComponent
type="button"
props={{
text: "Delete",
onClick: onDelete,
quiet: true,
type: "secondary",
}}
/>
{/if}
{#if showSaveButton}
<BlockComponent
type="button"
props={{
text: "Save",
onClick: onSave,
type: "cta",
}}
/>
{/if}
</div>
</div>
<BlockComponent type="fieldgroup" props={{ labelPosition }}>
{#each fields as field}
{#if getComponentForField(field)}
<BlockComponent
type={getComponentForField(field)}
props={{
field,
label: field,
placeholder: field,
disabled,
}}
/>
{/if}
{/each}
</BlockComponent>
</Layout>
</BlockComponent>
</BlockComponent>
</BlockComponent>
{:else}
<Placeholder
text="Choose your schema and add some fields to your form to get started"
/>
{/if}
</div>
</Block>
<style>
.title {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: var(--spacing-m);
order: 2;
}
.title.with-text {
order: 0;
}
.buttons {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
gap: var(--spacing-m);
}
</style>

View file

@ -2,4 +2,3 @@ export { default as tableblock } from "./TableBlock.svelte"
export { default as cardsblock } from "./CardsBlock.svelte"
export { default as repeaterblock } from "./RepeaterBlock.svelte"
export { default as formblock } from "./FormBlock.svelte"
export { default as formblockplus } from "./FormBlockPlus.svelte"