1
0
Fork 0
mirror of synced 2024-06-13 16:05:06 +12:00
budibase/packages/client/src/components/app/blocks/FormBlock.svelte
2022-04-01 12:51:23 +01:00

133 lines
3.5 KiB
Svelte

<script>
import { getContext } from "svelte"
import BlockComponent from "../../BlockComponent.svelte"
import Block from "../../Block.svelte"
import { Heading, Layout } from "@budibase/bbui"
import Placeholder from "../Placeholder.svelte"
export let actionType
export let dataSource
export let size
export let disabled
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
const { styleable, fetchDatasourceSchema } = 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
$: fetchSchema(dataSource)
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="form"
props={{ actionType, dataSource, size, disabled }}
context="form"
>
<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>
</Layout>
</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>