From 84d85664efc345454876fc6303a75e07464aff2a Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Wed, 25 Aug 2021 14:05:23 +0100 Subject: [PATCH] Add validation for array field --- .../ValidationEditor/ValidationDrawer.svelte | 9 +++++-- .../PropertyControls/componentSettings.js | 1 + packages/standard-components/manifest.json | 2 +- .../src/forms/MultiFieldSelect.svelte | 17 +++++++----- .../src/forms/validation.js | 27 ++++++++++++++++--- 5 files changed, 43 insertions(+), 13 deletions(-) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte index b4da2e8e6e..e24a779b62 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte @@ -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} - {#if ["string", "number", "options", "longform"].includes(rule.type)} + {#if ["string", "number", "options", "longform", "array"].includes(rule.type)} - x : x => x.label} - getOptionValue={flatOptions ? x => x : x => x.value} - {placeholder} - {options} - /> + {#if fieldState} + 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} diff --git a/packages/standard-components/src/forms/validation.js b/packages/standard-components/src/forms/validation.js index 30b6fd7ca7..6109d7e2cb 100644 --- a/packages/standard-components/src/forms/validation.js +++ b/packages/standard-components/src/forms/validation.js @@ -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