From 8592f79eaaacae58cedfbdc420c49f8ffdb8a9ca Mon Sep 17 00:00:00 2001 From: Maurits Lourens Date: Thu, 7 Jul 2022 23:06:57 +0200 Subject: [PATCH 1/4] 6538 - add validation to datasource config modal --- .../IntegrationConfigForm.svelte | 21 +++++++++++++++ .../modals/DatasourceConfigModal.svelte | 3 +++ .../src/helpers/validation/yup/index.js | 27 ++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte index 27358df0be..1f740bf35b 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte @@ -10,10 +10,14 @@ import KeyValueBuilder from "components/integration/KeyValueBuilder.svelte" import { capitalise } from "helpers" import { IntegrationTypes } from "constants/backend" + import { createValidationStore } from "helpers/validation/yup" + import { createEventDispatcher } from "svelte" export let datasource export let schema export let creating + const validation = createValidationStore() + const dispatch = createEventDispatcher() function filter([key, value]) { if (!value) { @@ -31,6 +35,17 @@ .filter(el => filter(el)) .map(([key]) => key) + // setup the validation for each required field + $: configKeys.forEach(key => { + if (schema[key].required) { + validation.addValidatorType(key, schema[key].type, schema[key].required) + } + }) + // run the validation whenever the config changes + $: validation.check(config) + // dispatch the validation result + $: dispatch("valid", $validation.valid) + let addButton function getDisplayName(key) { @@ -79,6 +94,9 @@ type={schema[configKey].type} on:change bind:value={config[configKey]} + on:blur={($validation.touched[configKey] = true)} + error={$validation.touched[configKey] && + $validation.errors[configKey]} /> {:else} @@ -88,6 +106,9 @@ type={schema[configKey].type} on:change bind:value={config[configKey]} + on:blur={($validation.touched[configKey] = true)} + error={$validation.touched[configKey] && + $validation.errors[configKey]} /> {/if} diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte index c8a5bc96eb..edbe55178f 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte @@ -13,6 +13,7 @@ // kill the reference so the input isn't saved let datasource = cloneDeep(integration) let skipFetch = false + let isValid = false $: name = IntegrationNames[datasource.type] || datasource.name || datasource.type @@ -53,6 +54,7 @@ return true }} size="L" + disabled={!isValid} > (isValid = e.detail)} /> diff --git a/packages/builder/src/helpers/validation/yup/index.js b/packages/builder/src/helpers/validation/yup/index.js index 6783ad7e58..9b38adbf9d 100644 --- a/packages/builder/src/helpers/validation/yup/index.js +++ b/packages/builder/src/helpers/validation/yup/index.js @@ -1,5 +1,5 @@ import { capitalise } from "helpers" -import { object } from "yup" +import { object, string, number } from "yup" import { writable, get } from "svelte/store" import { notifications } from "@budibase/bbui" @@ -20,6 +20,30 @@ export const createValidationStore = () => { validator[propertyName] = propertyValidator } + const addValidatorType = (propertyName, type, required) => { + if (!type || !propertyName) { + return + } + + let propertyValidator + switch (type) { + case "number": + propertyValidator = number() + break + case "email": + propertyValidator = string().email() + break + default: + propertyValidator = string() + } + + if (required) { + propertyValidator = propertyValidator.required() + } + + validator[propertyName] = propertyValidator + } + const check = async values => { const obj = object().shape(validator) // clear the previous errors @@ -62,5 +86,6 @@ export const createValidationStore = () => { set: validation.set, check, addValidator, + addValidatorType, } } From 777e8f91f1fb71e55f3c9e4b2eda9e226dbe58c2 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Mon, 24 Oct 2022 09:46:53 +0100 Subject: [PATCH 2/4] Remove touch check for error consistency --- .../TableIntegrationMenu/IntegrationConfigForm.svelte | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte index 1f740bf35b..1417de6dab 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte @@ -94,9 +94,7 @@ type={schema[configKey].type} on:change bind:value={config[configKey]} - on:blur={($validation.touched[configKey] = true)} - error={$validation.touched[configKey] && - $validation.errors[configKey]} + error={$validation.errors[configKey]} /> {:else} @@ -106,9 +104,7 @@ type={schema[configKey].type} on:change bind:value={config[configKey]} - on:blur={($validation.touched[configKey] = true)} - error={$validation.touched[configKey] && - $validation.errors[configKey]} + error={$validation.errors[configKey]} /> {/if} From 2bfeb850133c8a86922e3e9a497f97cf7f1c80b8 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Mon, 24 Oct 2022 10:18:51 +0100 Subject: [PATCH 3/4] Make NaN undefined --- packages/builder/src/helpers/helpers.js | 7 ++++++- packages/builder/src/helpers/validation/yup/index.js | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/helpers/helpers.js b/packages/builder/src/helpers/helpers.js index 9b0fa51a52..72c034d9a6 100644 --- a/packages/builder/src/helpers/helpers.js +++ b/packages/builder/src/helpers/helpers.js @@ -17,7 +17,12 @@ export const convertCamel = str => { export const pipe = (arg, funcs) => flow(funcs)(arg) -export const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1) +export const capitalise = s => { + if (!s) { + return s + } + return s.substring(0, 1).toUpperCase() + s.substring(1) +} export const lowercase = s => s.substring(0, 1).toLowerCase() + s.substring(1) diff --git a/packages/builder/src/helpers/validation/yup/index.js b/packages/builder/src/helpers/validation/yup/index.js index 9b38adbf9d..c064ffa583 100644 --- a/packages/builder/src/helpers/validation/yup/index.js +++ b/packages/builder/src/helpers/validation/yup/index.js @@ -28,7 +28,9 @@ export const createValidationStore = () => { let propertyValidator switch (type) { case "number": - propertyValidator = number() + propertyValidator = number().transform(value => + isNaN(value) ? undefined : value + ) break case "email": propertyValidator = string().email() From 46761749bf803ef519a459585be69b6aef4460f5 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Mon, 24 Oct 2022 10:39:39 +0100 Subject: [PATCH 4/4] Add validation to config screen --- .../data/datasource/[selectedDatasource]/index.svelte | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/index.svelte b/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/index.svelte index 7db07bbe6c..1b6e927270 100644 --- a/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/index.svelte @@ -23,7 +23,8 @@ let importQueriesModal - let changed + let changed, + isValid = true let integration, baseDatasource, datasource let queryList const querySchema = { @@ -101,12 +102,15 @@
Configuration - +
(isValid = e.detail)} /> {#if datasource.plus}