From b7af4ed65f17411fdac4adc03f58ad80e91ecea1 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 6 Aug 2021 14:54:00 +0100 Subject: [PATCH 01/22] Add validation drawer and simplify HOC's for different field types --- packages/bbui/src/Layout/Layout.svelte | 3 + .../ComponentSettingsSection.svelte | 1 + .../AttachmentFieldSelect.svelte | 5 - .../BooleanFieldSelect.svelte | 5 - .../DateTimeFieldSelect.svelte | 5 - .../PropertyControls/FormFieldSelect.svelte | 1 + .../LongFormFieldSelect.svelte | 5 - .../PropertyControls/NumberFieldSelect.svelte | 5 - .../OptionsFieldSelect.svelte | 5 - .../RelationshipFieldSelect.svelte | 5 - .../PropertyControls/StringFieldSelect.svelte | 5 - .../ValidationEditor/ValidationDrawer.svelte | 288 ++++++++++++++++++ .../ValidationEditor/ValidationEditor.svelte | 33 ++ .../PropertyControls/componentSettings.js | 34 ++- packages/standard-components/manifest.json | 45 +++ .../src/forms/validation.js | 2 +- 16 files changed, 390 insertions(+), 57 deletions(-) delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/AttachmentFieldSelect.svelte delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/BooleanFieldSelect.svelte delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/DateTimeFieldSelect.svelte delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/LongFormFieldSelect.svelte delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/NumberFieldSelect.svelte delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsFieldSelect.svelte delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/RelationshipFieldSelect.svelte delete mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/StringFieldSelect.svelte create mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte create mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationEditor.svelte diff --git a/packages/bbui/src/Layout/Layout.svelte b/packages/bbui/src/Layout/Layout.svelte index 86fd844ca1..af60675582 100644 --- a/packages/bbui/src/Layout/Layout.svelte +++ b/packages/bbui/src/Layout/Layout.svelte @@ -48,6 +48,9 @@ padding-top: var(--spacing-l); padding-bottom: var(--spacing-l); } + .gap-XXS { + grid-gap: var(--spacing-xs); + } .gap-XS { grid-gap: var(--spacing-s); } diff --git a/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte b/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte index 972a2bb7fe..35a4a9db19 100644 --- a/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/ComponentSettingsSection.svelte @@ -67,6 +67,7 @@ placeholder: setting.placeholder, }} {bindings} + {componentDefinition} /> {/if} {/each} diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/AttachmentFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/AttachmentFieldSelect.svelte deleted file mode 100644 index 44557157ba..0000000000 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/AttachmentFieldSelect.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/BooleanFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/BooleanFieldSelect.svelte deleted file mode 100644 index 131a375b22..0000000000 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/BooleanFieldSelect.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DateTimeFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DateTimeFieldSelect.svelte deleted file mode 100644 index c3b9b052c4..0000000000 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DateTimeFieldSelect.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FormFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FormFieldSelect.svelte index 0926561640..f8e4b18fe4 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FormFieldSelect.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FormFieldSelect.svelte @@ -23,6 +23,7 @@ const getOptions = (schema, fieldType) => { let entries = Object.entries(schema ?? {}) if (fieldType) { + fieldType = fieldType.split("/")[1] entries = entries.filter(entry => entry[1].type === fieldType) } return entries.map(entry => entry[0]) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/LongFormFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/LongFormFieldSelect.svelte deleted file mode 100644 index 65dd54d53a..0000000000 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/LongFormFieldSelect.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/NumberFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/NumberFieldSelect.svelte deleted file mode 100644 index 2006aca0bb..0000000000 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/NumberFieldSelect.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsFieldSelect.svelte deleted file mode 100644 index a01b837797..0000000000 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/OptionsFieldSelect.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/RelationshipFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/RelationshipFieldSelect.svelte deleted file mode 100644 index 5cdb25a112..0000000000 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/RelationshipFieldSelect.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/StringFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/StringFieldSelect.svelte deleted file mode 100644 index 62765676e3..0000000000 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/StringFieldSelect.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte new file mode 100644 index 0000000000..b769e1f60e --- /dev/null +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte @@ -0,0 +1,288 @@ + + + +
+ + + Schema validation rules + {#if schemaRules?.length} + + {/if} +
+ +
+
+
+
+
+ + diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationEditor.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationEditor.svelte new file mode 100644 index 0000000000..0b7fd12de2 --- /dev/null +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationEditor.svelte @@ -0,0 +1,33 @@ + + +Configure Validation + + + Configure validation rules for this field. + + + + diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js index 8435971714..6cf2d7e056 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js @@ -12,14 +12,8 @@ import SectionSelect from "./SectionSelect.svelte" import NavigationEditor from "./NavigationEditor/NavigationEditor.svelte" import FilterEditor from "./FilterEditor/FilterEditor.svelte" import URLSelect from "./URLSelect.svelte" -import StringFieldSelect from "./StringFieldSelect.svelte" -import NumberFieldSelect from "./NumberFieldSelect.svelte" -import OptionsFieldSelect from "./OptionsFieldSelect.svelte" -import BooleanFieldSelect from "./BooleanFieldSelect.svelte" -import LongFormFieldSelect from "./LongFormFieldSelect.svelte" -import DateTimeFieldSelect from "./DateTimeFieldSelect.svelte" -import AttachmentFieldSelect from "./AttachmentFieldSelect.svelte" -import RelationshipFieldSelect from "./RelationshipFieldSelect.svelte" +import FormFieldSelect from "./FormFieldSelect.svelte" +import ValidationEditor from "./ValidationEditor/ValidationEditor.svelte" const componentMap = { text: Input, @@ -39,14 +33,22 @@ const componentMap = { navigation: NavigationEditor, filter: FilterEditor, url: URLSelect, - "field/string": StringFieldSelect, - "field/number": NumberFieldSelect, - "field/options": OptionsFieldSelect, - "field/boolean": BooleanFieldSelect, - "field/longform": LongFormFieldSelect, - "field/datetime": DateTimeFieldSelect, - "field/attachment": AttachmentFieldSelect, - "field/link": RelationshipFieldSelect, + "field/string": FormFieldSelect, + "field/number": FormFieldSelect, + "field/options": FormFieldSelect, + "field/boolean": FormFieldSelect, + "field/longform": FormFieldSelect, + "field/datetime": FormFieldSelect, + "field/attachment": FormFieldSelect, + "field/link": FormFieldSelect, + // 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/number": ValidationEditor, + "validation/boolean": ValidationEditor, + "validation/datetime": ValidationEditor, + "validation/attachment": ValidationEditor, + "validation/link": ValidationEditor, } export const getComponentForSettingType = type => { diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index bb50c7a7e3..53aeb969fb 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -1758,6 +1758,11 @@ "label": "Disabled", "key": "disabled", "defaultValue": false + }, + { + "type": "validation/string", + "label": "Validation", + "key": "validation" } ] }, @@ -1787,6 +1792,11 @@ "label": "Disabled", "key": "disabled", "defaultValue": false + }, + { + "type": "validation/number", + "label": "Validation", + "key": "validation" } ] }, @@ -1816,6 +1826,11 @@ "label": "Disabled", "key": "disabled", "defaultValue": false + }, + { + "type": "validation/string", + "label": "Validation", + "key": "validation" } ] }, @@ -1862,6 +1877,11 @@ "label": "Disabled", "key": "disabled", "defaultValue": false + }, + { + "type": "validation/string", + "label": "Validation", + "key": "validation" } ] }, @@ -1891,6 +1911,11 @@ "label": "Disabled", "key": "disabled", "defaultValue": false + }, + { + "type": "validation/boolean", + "label": "Validation", + "key": "validation" } ] }, @@ -1921,6 +1946,11 @@ "label": "Disabled", "key": "disabled", "defaultValue": false + }, + { + "type": "validation/string", + "label": "Validation", + "key": "validation" } ] }, @@ -1956,6 +1986,11 @@ "label": "Disabled", "key": "disabled", "defaultValue": false + }, + { + "type": "validation/datetime", + "label": "Validation", + "key": "validation" } ] }, @@ -1980,6 +2015,11 @@ "label": "Disabled", "key": "disabled", "defaultValue": false + }, + { + "type": "validation/attachment", + "label": "Validation", + "key": "validation" } ] }, @@ -2009,6 +2049,11 @@ "label": "Disabled", "key": "disabled", "defaultValue": false + }, + { + "type": "validation/link", + "label": "Validation", + "key": "validation" } ] }, diff --git a/packages/standard-components/src/forms/validation.js b/packages/standard-components/src/forms/validation.js index b1df80509f..351a610912 100644 --- a/packages/standard-components/src/forms/validation.js +++ b/packages/standard-components/src/forms/validation.js @@ -66,7 +66,7 @@ const presenceConstraint = value => { } else { invalid = value == null || value === "" } - return invalid ? "Required" : null + return invalid ? "Required field" : null } const lengthConstraint = maxLength => value => { From d79748bfd90eb1084248a490ac8ee441de6621cf Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 10 Aug 2021 14:36:00 +0100 Subject: [PATCH 02/22] Allow custom validation rules to use bindings or raw values --- .../ValidationEditor/ValidationDrawer.svelte | 78 +++- .../src/forms/validation.js | 334 ++++++++++++++---- 2 files changed, 321 insertions(+), 91 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 b769e1f60e..70f9afe65a 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ValidationEditor/ValidationDrawer.svelte @@ -7,11 +7,14 @@ Select, Heading, Body, + Input, + DatePicker, } from "@budibase/bbui" import { currentAsset, selectedComponent } from "builderStore" import { findClosestMatchingComponent } from "builderStore/storeUtils" import { getSchemaForDatasource } from "builderStore/dataBinding" import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte" + import { generate } from "shortid" export let rules = [] export let bindings = [] @@ -100,10 +103,11 @@ $: dataSourceSchema = getDataSourceSchema($currentAsset, $selectedComponent) $: field = $selectedComponent?.field $: schemaRules = parseRulesFromSchema(field, dataSourceSchema || {}) - $: constraintOptions = getConstraintsForType(type) + $: fieldType = type?.split("/")[1] || "string" + $: constraintOptions = getConstraintsForType(fieldType) const getConstraintsForType = type => { - return ConstraintMap[type?.split("/")[1] || "string"] + return ConstraintMap[type] } const getDataSourceSchema = (asset, component) => { @@ -145,7 +149,7 @@ const length = constraints.length.maximum rules.push({ constraint: "maxLength", - constraintValue: length, + value: length, error: `Maximum ${length} characters`, }) } @@ -155,7 +159,7 @@ const min = constraints.numericality.greaterThanOrEqualTo rules.push({ constraint: "minValue", - constraintValue: min, + value: min, error: `Minimum value is ${min}`, }) } @@ -163,7 +167,7 @@ const max = constraints.numericality.lessThanOrEqualTo rules.push({ constraint: "maxValue", - constraintValue: max, + value: max, error: `Maximum value is ${max}`, }) } @@ -176,7 +180,14 @@ } const addRule = () => { - rules = [...(rules || []), {}] + rules = [ + ...(rules || []), + { + valueType: "Binding", + type: fieldType, + id: generate(), + }, + ] } const removeRule = id => { @@ -199,9 +210,15 @@ options={constraintOptions} disabled /> + - (rule.constraintValue = e.detail)} + placeholder={null} + bind:value={rule.valueType} + options={["Binding", "Value"]} /> + {#if rule.valueType === "Binding"} + (rule.value = e.detail)} + /> + {:else if ["string", "number", "options", "longform"].includes(rule.type)} + + {:else if fieldType === "boolean"} + - {:else if fieldType === "boolean"} - + {:else if fieldType === "boolean"} + - {:else if fieldType === "boolean"} + {:else if rule.type === "boolean"}