191 lines
4.5 KiB
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>
|