budibase/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte

191 lines
4.5 KiB
Svelte

<script>
import { API } from "api"
import {
Input,
Select,
DatePicker,
Toggle,
Multiselect,
Label,
RichTextField,
TextArea,
CoreSignature,
ActionButton,
notifications,
} from "@budibase/bbui"
import Dropzone from "components/common/Dropzone.svelte"
import { capitalise } from "helpers"
import LinkedRowSelector from "components/common/LinkedRowSelector.svelte"
import Editor from "../../integration/QueryEditor.svelte"
import { SignatureModal } from "@budibase/frontend-core/src/components"
import { themeStore } from "stores/portal"
export let meta
export let value
export let readonly
export let error
const resolveTimeStamp = timestamp => {
if (!timestamp) {
return null
}
let maskedDate = new Date(`0-${timestamp}`)
if (maskedDate instanceof Date && !isNaN(maskedDate.getTime())) {
return maskedDate
} else {
return null
}
}
$: stringVal =
typeof value === "object" ? JSON.stringify(value, null, 2) : value
$: type = meta?.type
$: label = meta.name ? capitalise(meta.name) : ""
const timeStamp = resolveTimeStamp(value)
const isTimeStamp = !!timeStamp || meta?.timeOnly
$: currentTheme = $themeStore?.theme
$: darkMode = !currentTheme.includes("light")
let signatureModal
</script>
<SignatureModal
{darkMode}
onConfirm={async sigCanvas => {
const signatureFile = sigCanvas.toFile()
let attachRequest = new FormData()
attachRequest.append("file", signatureFile)
try {
const uploadReq = await API.uploadBuilderAttachment(attachRequest)
const [signatureAttachment] = uploadReq
value = signatureAttachment
} catch (error) {
$notifications.error(error.message || "Failed to save signature")
value = []
}
}}
title={meta.name}
{value}
bind:this={signatureModal}
/>
{#if type === "options" && meta.constraints.inclusion.length !== 0}
<Select
{label}
bind:value
options={meta.constraints.inclusion}
sort
{error}
/>
{:else if type === "datetime"}
<DatePicker
{error}
{label}
timeOnly={isTimeStamp}
enableTime={!meta?.dateOnly}
ignoreTimezones={meta?.ignoreTimezones}
bind:value
/>
{:else if type === "attachment"}
<Dropzone
{label}
{error}
{value}
on:change={e => {
value = e.detail
}}
/>
{:else if type === "attachment_single"}
<Dropzone
{label}
{error}
value={value ? [value] : []}
on:change={e => {
value = e.detail?.[0]
}}
maximum={1}
/>
{:else if type === "signature_single"}
<div class="signature">
<Label>{label}</Label>
<div class="sig-wrap" class:display={value}>
{#if value}
<CoreSignature
{darkMode}
{value}
editable={false}
on:clear={() => {
value = null
}}
/>
{:else}
<ActionButton
fullWidth
on:click={() => {
signatureModal.show()
}}
>
Add signature
</ActionButton>
{/if}
</div>
</div>
{:else if type === "boolean"}
<Toggle text={label} {error} bind:value />
{:else if type === "array" && meta.constraints.inclusion.length !== 0}
<Multiselect
bind:value
{error}
{label}
options={meta.constraints.inclusion}
/>
{:else if type === "link"}
<LinkedRowSelector
{error}
linkedData={value}
schema={meta}
on:change={e => (value = e.detail)}
/>
{:else if type === "longform"}
{#if meta.useRichText}
<RichTextField {error} {label} height="150px" bind:value />
{:else}
<TextArea {error} {label} height="150px" bind:value />
{/if}
{:else if type === "json"}
<Label>{label}</Label>
<Editor
editorHeight="250"
editorWidth="320"
mode="json"
on:change={({ detail }) => (value = detail.value)}
value={stringVal}
{error}
/>
{:else}
<Input {label} {type} {error} bind:value disabled={readonly} />
{/if}
<style>
.signature :global(label.spectrum-FieldLabel) {
padding-top: var(--spectrum-fieldlabel-padding-top);
padding-bottom: var(--spectrum-fieldlabel-padding-bottom);
}
.sig-wrap.display {
min-height: 50px;
justify-content: center;
width: 100%;
display: flex;
flex-direction: column;
background-color: var(--spectrum-global-color-gray-50);
box-sizing: border-box;
border: var(--spectrum-alias-border-size-thin)
var(--spectrum-alias-border-color) solid;
border-radius: var(--spectrum-alias-border-radius-regular);
}
</style>