diff --git a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte index 27358df0be..1417de6dab 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,7 @@ type={schema[configKey].type} on:change bind:value={config[configKey]} + error={$validation.errors[configKey]} /> {:else} @@ -88,6 +104,7 @@ type={schema[configKey].type} on:change bind:value={config[configKey]} + error={$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/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 6783ad7e58..c064ffa583 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,32 @@ export const createValidationStore = () => { validator[propertyName] = propertyValidator } + const addValidatorType = (propertyName, type, required) => { + if (!type || !propertyName) { + return + } + + let propertyValidator + switch (type) { + case "number": + propertyValidator = number().transform(value => + isNaN(value) ? undefined : value + ) + 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 +88,6 @@ export const createValidationStore = () => { set: validation.set, check, addValidator, + addValidatorType, } } 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}