Merge remote-tracking branch 'origin/master' into feature/screen-deselect
This commit is contained in:
commit
a5da7946db
|
@ -197,7 +197,9 @@
|
||||||
>
|
>
|
||||||
<Icon name="ChevronRight" />
|
<Icon name="ChevronRight" />
|
||||||
</div>
|
</div>
|
||||||
|
{#if maximum !== 1}
|
||||||
<div class="footer">File {selectedImageIdx + 1} of {fileCount}</div>
|
<div class="footer">File {selectedImageIdx + 1} of {fileCount}</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else if value?.length}
|
{:else if value?.length}
|
||||||
{#each value as file}
|
{#each value as file}
|
||||||
|
|
|
@ -470,7 +470,7 @@
|
||||||
newError.name = `Column name already in use.`
|
newError.name = `Column name already in use.`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldInfo.type === "auto" && !fieldInfo.subtype) {
|
if (fieldInfo.type === FieldType.AUTO && !fieldInfo.subtype) {
|
||||||
newError.subtype = `Auto Column requires a type`
|
newError.subtype = `Auto Column requires a type`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,18 +531,18 @@
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{#if editableColumn.type === "string"}
|
{#if editableColumn.type === FieldType.STRING}
|
||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
label="Max Length"
|
label="Max Length"
|
||||||
bind:value={editableColumn.constraints.length.maximum}
|
bind:value={editableColumn.constraints.length.maximum}
|
||||||
/>
|
/>
|
||||||
{:else if editableColumn.type === "options"}
|
{:else if editableColumn.type === FieldType.OPTIONS}
|
||||||
<OptionSelectDnD
|
<OptionSelectDnD
|
||||||
bind:constraints={editableColumn.constraints}
|
bind:constraints={editableColumn.constraints}
|
||||||
bind:optionColors={editableColumn.optionColors}
|
bind:optionColors={editableColumn.optionColors}
|
||||||
/>
|
/>
|
||||||
{:else if editableColumn.type === "longform"}
|
{:else if editableColumn.type === FieldType.LONGFORM}
|
||||||
<div>
|
<div>
|
||||||
<div class="tooltip-alignment">
|
<div class="tooltip-alignment">
|
||||||
<Label size="M">Formatting</Label>
|
<Label size="M">Formatting</Label>
|
||||||
|
@ -560,12 +560,12 @@
|
||||||
text="Enable rich text support (markdown)"
|
text="Enable rich text support (markdown)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{:else if editableColumn.type === "array"}
|
{:else if editableColumn.type === FieldType.ARRAY}
|
||||||
<OptionSelectDnD
|
<OptionSelectDnD
|
||||||
bind:constraints={editableColumn.constraints}
|
bind:constraints={editableColumn.constraints}
|
||||||
bind:optionColors={editableColumn.optionColors}
|
bind:optionColors={editableColumn.optionColors}
|
||||||
/>
|
/>
|
||||||
{:else if editableColumn.type === "datetime" && !editableColumn.autocolumn}
|
{:else if editableColumn.type === FieldType.DATETIME && !editableColumn.autocolumn}
|
||||||
<div class="split-label">
|
<div class="split-label">
|
||||||
<div class="label-length">
|
<div class="label-length">
|
||||||
<Label size="M">Earliest</Label>
|
<Label size="M">Earliest</Label>
|
||||||
|
@ -604,7 +604,7 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<Toggle bind:value={editableColumn.dateOnly} text="Date only" />
|
<Toggle bind:value={editableColumn.dateOnly} text="Date only" />
|
||||||
{:else if editableColumn.type === "number" && !editableColumn.autocolumn}
|
{:else if editableColumn.type === FieldType.NUMBER && !editableColumn.autocolumn}
|
||||||
<div class="split-label">
|
<div class="split-label">
|
||||||
<div class="label-length">
|
<div class="label-length">
|
||||||
<Label size="M">Min Value</Label>
|
<Label size="M">Min Value</Label>
|
||||||
|
@ -629,7 +629,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else if editableColumn.type === "link"}
|
{:else if editableColumn.type === FieldType.LINK}
|
||||||
<RelationshipSelector
|
<RelationshipSelector
|
||||||
bind:relationshipPart1
|
bind:relationshipPart1
|
||||||
bind:relationshipPart2
|
bind:relationshipPart2
|
||||||
|
@ -703,6 +703,24 @@
|
||||||
thin
|
thin
|
||||||
text="Allow multiple users"
|
text="Allow multiple users"
|
||||||
/>
|
/>
|
||||||
|
{:else if editableColumn.type === FieldType.ATTACHMENT}
|
||||||
|
<Toggle
|
||||||
|
value={editableColumn.constraints?.length?.maximum !== 1}
|
||||||
|
on:change={e => {
|
||||||
|
if (!e.detail) {
|
||||||
|
editableColumn.constraints ??= { length: {} }
|
||||||
|
editableColumn.constraints.length ??= {}
|
||||||
|
editableColumn.constraints.length.maximum = 1
|
||||||
|
editableColumn.constraints.length.message =
|
||||||
|
"cannot contain multiple files"
|
||||||
|
} else {
|
||||||
|
delete editableColumn.constraints?.length?.maximum
|
||||||
|
delete editableColumn.constraints?.length?.message
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
thin
|
||||||
|
text="Allow multiple"
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
{#if editableColumn.type === AUTO_TYPE || editableColumn.autocolumn}
|
{#if editableColumn.type === AUTO_TYPE || editableColumn.autocolumn}
|
||||||
<Select
|
<Select
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<script>
|
||||||
|
import BlockComponent from "components/BlockComponent.svelte"
|
||||||
|
import { FieldType } from "@budibase/types"
|
||||||
|
|
||||||
|
export let field
|
||||||
|
export let schema
|
||||||
|
export let order
|
||||||
|
|
||||||
|
const FieldTypeToComponentMap = {
|
||||||
|
string: "stringfield",
|
||||||
|
number: "numberfield",
|
||||||
|
bigint: "bigintfield",
|
||||||
|
options: "optionsfield",
|
||||||
|
array: "multifieldselect",
|
||||||
|
boolean: "booleanfield",
|
||||||
|
longform: "longformfield",
|
||||||
|
datetime: "datetimefield",
|
||||||
|
attachment: "attachmentfield",
|
||||||
|
link: "relationshipfield",
|
||||||
|
json: "jsonfield",
|
||||||
|
barcodeqr: "codescanner",
|
||||||
|
bb_reference: "bbreferencefield",
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFieldSchema = field => {
|
||||||
|
const fieldSchemaName = field.field || field.name
|
||||||
|
if (!fieldSchemaName || !schema?.[fieldSchemaName]) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return schema[fieldSchemaName]
|
||||||
|
}
|
||||||
|
|
||||||
|
const getComponentForField = field => {
|
||||||
|
const fieldSchema = getFieldSchema(field)
|
||||||
|
if (!fieldSchema) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const { type } = fieldSchema
|
||||||
|
return FieldTypeToComponentMap[type]
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPropsForField = field => {
|
||||||
|
let fieldProps = field._component
|
||||||
|
? {
|
||||||
|
...field,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
field: field.name,
|
||||||
|
label: field.name,
|
||||||
|
placeholder: field.name,
|
||||||
|
_instanceName: field.name,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldProps = {
|
||||||
|
...getPropsByType(field),
|
||||||
|
...fieldProps,
|
||||||
|
}
|
||||||
|
return fieldProps
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPropsByType(field) {
|
||||||
|
const propsMapByType = {
|
||||||
|
[FieldType.ATTACHMENT]: (_field, schema) => {
|
||||||
|
return {
|
||||||
|
maximum: schema?.constraints?.length?.maximum,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const fieldSchema = getFieldSchema(field)
|
||||||
|
const mapper = propsMapByType[fieldSchema.type]
|
||||||
|
if (mapper) {
|
||||||
|
return mapper(field, fieldSchema)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if getComponentForField(field) && field.active}
|
||||||
|
<BlockComponent
|
||||||
|
type={getComponentForField(field)}
|
||||||
|
props={getPropsForField(field)}
|
||||||
|
{order}
|
||||||
|
interactive
|
||||||
|
name={field?.field}
|
||||||
|
/>
|
||||||
|
{/if}
|
|
@ -6,6 +6,7 @@
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
import FormBlockWrapper from "./form/FormBlockWrapper.svelte"
|
import FormBlockWrapper from "./form/FormBlockWrapper.svelte"
|
||||||
import { get, writable } from "svelte/store"
|
import { get, writable } from "svelte/store"
|
||||||
|
import FormBlockComponent from "./FormBlockComponent.svelte"
|
||||||
|
|
||||||
export let actionType
|
export let actionType
|
||||||
export let rowId
|
export let rowId
|
||||||
|
@ -23,22 +24,6 @@
|
||||||
const currentStep = writable(1)
|
const currentStep = writable(1)
|
||||||
setContext("current-step", currentStep)
|
setContext("current-step", currentStep)
|
||||||
|
|
||||||
const FieldTypeToComponentMap = {
|
|
||||||
string: "stringfield",
|
|
||||||
number: "numberfield",
|
|
||||||
bigint: "bigintfield",
|
|
||||||
options: "optionsfield",
|
|
||||||
array: "multifieldselect",
|
|
||||||
boolean: "booleanfield",
|
|
||||||
longform: "longformfield",
|
|
||||||
datetime: "datetimefield",
|
|
||||||
attachment: "attachmentfield",
|
|
||||||
link: "relationshipfield",
|
|
||||||
json: "jsonfield",
|
|
||||||
barcodeqr: "codescanner",
|
|
||||||
bb_reference: "bbreferencefield",
|
|
||||||
}
|
|
||||||
|
|
||||||
let schema
|
let schema
|
||||||
|
|
||||||
$: fetchSchema(dataSource)
|
$: fetchSchema(dataSource)
|
||||||
|
@ -78,27 +63,6 @@
|
||||||
currentStep.set(newStep + 1)
|
currentStep.set(newStep + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPropsForField = field => {
|
|
||||||
if (field._component) {
|
|
||||||
return field
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
field: field.name,
|
|
||||||
label: field.name,
|
|
||||||
placeholder: field.name,
|
|
||||||
_instanceName: field.name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getComponentForField = field => {
|
|
||||||
const fieldSchemaName = field.field || field.name
|
|
||||||
if (!fieldSchemaName || !schema?.[fieldSchemaName]) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const type = schema[fieldSchemaName].type
|
|
||||||
return FieldTypeToComponentMap[type]
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchSchema = async () => {
|
const fetchSchema = async () => {
|
||||||
schema = (await fetchDatasourceSchema(dataSource)) || {}
|
schema = (await fetchDatasourceSchema(dataSource)) || {}
|
||||||
}
|
}
|
||||||
|
@ -205,15 +169,7 @@
|
||||||
class:mobile={$context.device.mobile}
|
class:mobile={$context.device.mobile}
|
||||||
>
|
>
|
||||||
{#each step.fields as field, fieldIdx (`${field.field || field.name}_${fieldIdx}`)}
|
{#each step.fields as field, fieldIdx (`${field.field || field.name}_${fieldIdx}`)}
|
||||||
{#if getComponentForField(field)}
|
<FormBlockComponent {field} {schema} order={fieldIdx} />
|
||||||
<BlockComponent
|
|
||||||
type={getComponentForField(field)}
|
|
||||||
props={getPropsForField(field)}
|
|
||||||
order={fieldIdx}
|
|
||||||
interactive
|
|
||||||
name={field.field}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</BlockComponent>
|
</BlockComponent>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import BlockComponent from "components/BlockComponent.svelte"
|
import BlockComponent from "components/BlockComponent.svelte"
|
||||||
import Placeholder from "components/app/Placeholder.svelte"
|
import Placeholder from "components/app/Placeholder.svelte"
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
|
import FormBlockComponent from "../FormBlockComponent.svelte"
|
||||||
|
|
||||||
export let dataSource
|
export let dataSource
|
||||||
export let actionType
|
export let actionType
|
||||||
|
@ -14,49 +15,11 @@
|
||||||
export let buttonPosition = "bottom"
|
export let buttonPosition = "bottom"
|
||||||
export let schema
|
export let schema
|
||||||
|
|
||||||
const FieldTypeToComponentMap = {
|
|
||||||
string: "stringfield",
|
|
||||||
number: "numberfield",
|
|
||||||
bigint: "bigintfield",
|
|
||||||
options: "optionsfield",
|
|
||||||
array: "multifieldselect",
|
|
||||||
boolean: "booleanfield",
|
|
||||||
longform: "longformfield",
|
|
||||||
datetime: "datetimefield",
|
|
||||||
attachment: "attachmentfield",
|
|
||||||
link: "relationshipfield",
|
|
||||||
json: "jsonfield",
|
|
||||||
barcodeqr: "codescanner",
|
|
||||||
bb_reference: "bbreferencefield",
|
|
||||||
}
|
|
||||||
const context = getContext("context")
|
const context = getContext("context")
|
||||||
|
|
||||||
let formId
|
let formId
|
||||||
|
|
||||||
$: renderHeader = buttons || title
|
$: renderHeader = buttons || title
|
||||||
|
|
||||||
const getComponentForField = field => {
|
|
||||||
const fieldSchemaName = field.field || field.name
|
|
||||||
if (!fieldSchemaName || !schema?.[fieldSchemaName]) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const type = schema[fieldSchemaName].type
|
|
||||||
return FieldTypeToComponentMap[type]
|
|
||||||
}
|
|
||||||
|
|
||||||
const getPropsForField = field => {
|
|
||||||
let fieldProps = field._component
|
|
||||||
? {
|
|
||||||
...field,
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
field: field.name,
|
|
||||||
label: field.name,
|
|
||||||
placeholder: field.name,
|
|
||||||
_instanceName: field.name,
|
|
||||||
}
|
|
||||||
return fieldProps
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if fields?.length}
|
{#if fields?.length}
|
||||||
|
@ -132,15 +95,7 @@
|
||||||
<BlockComponent type="container">
|
<BlockComponent type="container">
|
||||||
<div class="form-block fields" class:mobile={$context.device.mobile}>
|
<div class="form-block fields" class:mobile={$context.device.mobile}>
|
||||||
{#each fields as field, idx}
|
{#each fields as field, idx}
|
||||||
{#if getComponentForField(field) && field.active}
|
<FormBlockComponent {field} {schema} order={idx} />
|
||||||
<BlockComponent
|
|
||||||
type={getComponentForField(field)}
|
|
||||||
props={getPropsForField(field)}
|
|
||||||
order={idx}
|
|
||||||
interactive
|
|
||||||
name={field?.field}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</BlockComponent>
|
</BlockComponent>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
export let api
|
export let api
|
||||||
export let invertX = false
|
export let invertX = false
|
||||||
export let invertY = false
|
export let invertY = false
|
||||||
|
export let schema
|
||||||
|
|
||||||
const { API, notifications } = getContext("grid")
|
const { API, notifications } = getContext("grid")
|
||||||
const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"]
|
const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"]
|
||||||
|
@ -97,6 +98,7 @@
|
||||||
{value}
|
{value}
|
||||||
compact
|
compact
|
||||||
on:change={e => onChange(e.detail)}
|
on:change={e => onChange(e.detail)}
|
||||||
|
maximum={schema.constraints?.length?.maximum}
|
||||||
{processFiles}
|
{processFiles}
|
||||||
{deleteAttachments}
|
{deleteAttachments}
|
||||||
{handleFileTooLarge}
|
{handleFileTooLarge}
|
||||||
|
|
Loading…
Reference in New Issue