1
0
Fork 0
mirror of synced 2024-07-01 12:30:41 +12:00

Add validation for array field

This commit is contained in:
Peter Clement 2021-08-25 14:05:23 +01:00
parent 04ce0abd46
commit 84d85664ef
5 changed files with 43 additions and 13 deletions

View file

@ -9,6 +9,7 @@
Body,
Input,
DatePicker,
Multiselect,
} from "@budibase/bbui"
import { currentAsset, selectedComponent } from "builderStore"
import { findClosestMatchingComponent } from "builderStore/storeUtils"
@ -102,6 +103,11 @@
Constraints.MinLength,
Constraints.MaxLength,
],
["array"]: [
Constraints.Required,
Constraints.MinLength,
Constraints.MaxLength,
],
}
$: dataSourceSchema = getDataSourceSchema($currentAsset, $selectedComponent)
@ -109,7 +115,6 @@
$: schemaRules = parseRulesFromSchema(field, dataSourceSchema || {})
$: fieldType = type?.split("/")[1] || "string"
$: constraintOptions = getConstraintsForType(fieldType)
const getConstraintsForType = type => {
return ConstraintMap[type]
}
@ -283,7 +288,7 @@
/>
{:else}
<!-- Otherwise we render a component based on the type -->
{#if ["string", "number", "options", "longform"].includes(rule.type)}
{#if ["string", "number", "options", "longform", "array"].includes(rule.type)}
<Input
disabled={rule.constraint === "required"}
bind:value={rule.value}

View file

@ -47,6 +47,7 @@ const componentMap = {
// Some validation types are the same as others, so not all types are
// explicitly listed here. e.g. options uses string validation
"validation/string": ValidationEditor,
"validation/array": ValidationEditor,
"validation/number": ValidationEditor,
"validation/boolean": ValidationEditor,
"validation/datetime": ValidationEditor,

View file

@ -2101,7 +2101,7 @@
}
},
{
"type": "validation/string",
"type": "validation/array",
"label": "Validation",
"key": "validation"
}

View file

@ -40,10 +40,15 @@
bind:fieldApi
bind:fieldSchema
>
<Multiselect
getOptionLabel={flatOptions ? x => x : x => x.label}
getOptionValue={flatOptions ? x => x : x => x.value}
{placeholder}
{options}
/>
{#if fieldState}
<Multiselect
getOptionLabel={flatOptions ? x => x : x => x.label}
getOptionValue={flatOptions ? x => x : x => x.value}
id={$fieldState.fieldId}
disabled={$fieldState.disabled}
on:change={e => fieldApi.setValue(e.detail)}
{placeholder}
{options}
/>
{/if}
</Field>

View file

@ -25,7 +25,7 @@ export const createValidatorFromConstraints = (
schemaConstraints.presence?.allowEmpty === false
) {
rules.push({
type: "string",
type: schemaConstraints.type == "array" ? "array" : "string",
constraint: "required",
error: "Required",
})
@ -63,7 +63,7 @@ export const createValidatorFromConstraints = (
}
// Inclusion constraint
if (exists(schemaConstraints.inclusion)) {
if (!schemaConstraints.type == "array" ? exists(schemaConstraints.inclusion) : false) {
const options = schemaConstraints.inclusion || []
rules.push({
type: "string",
@ -73,6 +73,18 @@ export const createValidatorFromConstraints = (
})
}
// Inclusion constraint
if (schemaConstraints.type == "array" ? exists(schemaConstraints.inclusion[0]) : false ) {
const options = schemaConstraints.inclusion[0] || []
rules.push({
type: "array",
constraint: "inclusion",
value: options,
error: "Invalid value",
})
}
// Date constraint
if (exists(schemaConstraints.datetime?.earliest)) {
const limit = schemaConstraints.datetime.earliest
@ -142,7 +154,7 @@ const evaluateRule = (rule, value) => {
* in the same format.
* @param value the value to parse
* @param type the type to parse
* @returns {boolean|string|*|number|null} the parsed value, or null if invalid
* @returns {boolean|string|*|number|null|array} the parsed value, or null if invalid
*/
const parseType = (value, type) => {
// Treat nulls or empty strings as null
@ -202,6 +214,13 @@ const parseType = (value, type) => {
return value
}
if (type === "array") {
if (!Array.isArray(value) || !value.length) {
return null
}
return value
}
// If some unknown type, treat as null to avoid breaking validators
return null
}
@ -239,7 +258,7 @@ const maxValueHandler = (value, rule) => {
// Evaluates an inclusion constraint
const inclusionHandler = (value, rule) => {
return value == null || rule.value.includes(value)
return value == null || rule.type == "array" ? rule.value.map(val => val === value) : rule.value.includes(value)
}
// Evaluates an equal constraint