1
0
Fork 0
mirror of synced 2024-07-02 13:01:09 +12:00

Add ability for user to select 'List' data type for a column

This commit is contained in:
Peter Clement 2021-08-19 16:54:44 +01:00
parent 8f82f13e1b
commit 17438372d0
9 changed files with 78 additions and 4 deletions

View file

@ -0,0 +1,17 @@
<script>
import "@spectrum-css/label/dist/index-vars.css"
import { Badge } from "@budibase/bbui"
export let value
const displayLimit = 5
$: badges = value?.slice(0, displayLimit) ?? []
$: leftover = (value?.length ?? 0) - badges.length
</script>
{#each badges as badge}
<Badge size="S" grey>{badge}</Badge>
{/each}
{#if leftover}
<div>+{leftover} more</div>
{/if}

View file

@ -4,7 +4,7 @@
import DateTimeRenderer from "./DateTimeRenderer.svelte" import DateTimeRenderer from "./DateTimeRenderer.svelte"
import RelationshipRenderer from "./RelationshipRenderer.svelte" import RelationshipRenderer from "./RelationshipRenderer.svelte"
import AttachmentRenderer from "./AttachmentRenderer.svelte" import AttachmentRenderer from "./AttachmentRenderer.svelte"
import ArrayRenderer from "./ArrayRenderer.svelte"
export let row export let row
export let schema export let schema
export let value export let value
@ -19,6 +19,7 @@
options: StringRenderer, options: StringRenderer,
number: StringRenderer, number: StringRenderer,
longform: StringRenderer, longform: StringRenderer,
array: ArrayRenderer,
} }
$: type = schema?.type ?? "string" $: type = schema?.type ?? "string"
$: customRenderer = customRenderers?.find(x => x.column === schema?.name) $: customRenderer = customRenderers?.find(x => x.column === schema?.name)

View file

@ -1,5 +1,12 @@
<script> <script>
import { Input, Select, DatePicker, Toggle, TextArea } from "@budibase/bbui" import {
Input,
Select,
DatePicker,
Toggle,
TextArea,
Multiselect,
} from "@budibase/bbui"
import Dropzone from "components/common/Dropzone.svelte" import Dropzone from "components/common/Dropzone.svelte"
import { capitalise } from "helpers" import { capitalise } from "helpers"
import LinkedRowSelector from "components/common/LinkedRowSelector.svelte" import LinkedRowSelector from "components/common/LinkedRowSelector.svelte"
@ -26,6 +33,11 @@
<Dropzone {label} bind:value /> <Dropzone {label} bind:value />
{:else if type === "boolean"} {:else if type === "boolean"}
<Toggle text={label} bind:value data-cy="{meta.name}-input" /> <Toggle text={label} bind:value data-cy="{meta.name}-input" />
{:else if type === "array"}
<Multiselect
bind:value
options={meta.constraints.inclusion.reduce((p, n) => p.concat(n), [])}
/>
{:else if type === "link"} {:else if type === "link"}
<LinkedRowSelector bind:linkedRows={value} schema={meta} /> <LinkedRowSelector bind:linkedRows={value} schema={meta} />
{:else if type === "longform"} {:else if type === "longform"}

View file

@ -29,6 +29,7 @@
const AUTO_TYPE = "auto" const AUTO_TYPE = "auto"
const FORMULA_TYPE = FIELDS.FORMULA.type const FORMULA_TYPE = FIELDS.FORMULA.type
const ARRAY_TYPE = FIELDS.ARRAY.type
const LINK_TYPE = FIELDS.LINK.type const LINK_TYPE = FIELDS.LINK.type
let fieldDefinitions = cloneDeep(FIELDS) let fieldDefinitions = cloneDeep(FIELDS)
const { hide } = getContext(Context.Modal) const { hide } = getContext(Context.Modal)
@ -81,6 +82,13 @@
if (field.type === AUTO_TYPE) { if (field.type === AUTO_TYPE) {
field = buildAutoColumn($tables.draft.name, field.name, field.subtype) field = buildAutoColumn($tables.draft.name, field.name, field.subtype)
} }
if (field.type === ARRAY_TYPE) {
let arr = field.constraints.inclusion
let newArr = []
newArr.push(arr)
console.log(newArr)
field.constraints.inclusion = newArr
}
tables.saveField({ tables.saveField({
originalName, originalName,
field, field,
@ -262,6 +270,11 @@
label="Options (one per line)" label="Options (one per line)"
bind:values={field.constraints.inclusion} bind:values={field.constraints.inclusion}
/> />
{:else if field.type === "array"}
<ValuesList
label="Options (one per line)"
bind:values={field.constraints.inclusion}
/>
{:else if field.type === "datetime"} {:else if field.type === "datetime"}
<DatePicker <DatePicker
label="Earliest" label="Earliest"

View file

@ -113,6 +113,10 @@
label: "Options", label: "Options",
value: FIELDS.OPTIONS.type, value: FIELDS.OPTIONS.type,
}, },
{
label: "List",
value: FIELDS.ARRAY.type,
},
] ]
</script> </script>

View file

@ -26,6 +26,15 @@ export const FIELDS = {
inclusion: [], inclusion: [],
}, },
}, },
ARRAY: {
name: "List",
type: "array",
constraints: {
type: "array",
presence: false,
inclusion: [],
},
},
NUMBER: { NUMBER: {
name: "Number", name: "Number",
type: "number", type: "number",

View file

@ -58,12 +58,24 @@ exports.validate = async ({ appId, tableId, row, table }) => {
const constraints = cloneDeep(table.schema[fieldName].constraints) const constraints = cloneDeep(table.schema[fieldName].constraints)
// special case for options, need to always allow unselected (null) // special case for options, need to always allow unselected (null)
if ( if (
table.schema[fieldName].type === FieldTypes.OPTIONS && table.schema[fieldName].type ===
(FieldTypes.OPTIONS || FieldTypes.ARRAY) &&
constraints.inclusion constraints.inclusion
) { ) {
constraints.inclusion.push(null) constraints.inclusion.push(null)
} }
const res = validateJs.single(row[fieldName], constraints) let res
// Validate.js doesn't seem to handle array of array very well
if (table.schema[fieldName].type === FieldTypes.ARRAY) {
row[fieldName].map(val => {
if (constraints.inclusion.includes(val)) {
errors[fieldName] = "Field not in list"
}
})
} else {
res = validateJs.single(row[fieldName], constraints)
}
if (res) errors[fieldName] = res if (res) errors[fieldName] = res
} }
return { valid: Object.keys(errors).length === 0, errors } return { valid: Object.keys(errors).length === 0, errors }

View file

@ -12,6 +12,7 @@ exports.FieldTypes = {
OPTIONS: "options", OPTIONS: "options",
NUMBER: "number", NUMBER: "number",
BOOLEAN: "boolean", BOOLEAN: "boolean",
ARRAY: "array",
DATETIME: "datetime", DATETIME: "datetime",
ATTACHMENT: "attachment", ATTACHMENT: "attachment",
LINK: "link", LINK: "link",

View file

@ -29,6 +29,11 @@ const TYPE_TRANSFORM_MAP = {
[null]: null, [null]: null,
[undefined]: undefined, [undefined]: undefined,
}, },
[FieldTypes.ARRAY]: {
"": [],
[null]: [],
[undefined]: undefined,
},
[FieldTypes.STRING]: { [FieldTypes.STRING]: {
"": "", "": "",
[null]: "", [null]: "",