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, } }