From 0c80e8c5b5f088207c4e383223f80b17a975ed61 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 21 Jul 2021 08:46:02 +0100 Subject: [PATCH 01/14] Move lucene options into common file and add initial work on conditional UI components --- .../ConditionalUISection.svelte | 38 +++++ .../PropertiesPanel/PropertiesPanel.svelte | 2 + .../ConditionalUIDrawer.svelte | 156 ++++++++++++++++++ .../FilterEditor/LuceneFilterBuilder.svelte | 81 +-------- packages/builder/src/helpers/lucene.js | 80 +++++++++ 5 files changed, 277 insertions(+), 80 deletions(-) create mode 100644 packages/builder/src/components/design/PropertiesPanel/ConditionalUISection.svelte create mode 100644 packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte create mode 100644 packages/builder/src/helpers/lucene.js diff --git a/packages/builder/src/components/design/PropertiesPanel/ConditionalUISection.svelte b/packages/builder/src/components/design/PropertiesPanel/ConditionalUISection.svelte new file mode 100644 index 0000000000..5071354813 --- /dev/null +++ b/packages/builder/src/components/design/PropertiesPanel/ConditionalUISection.svelte @@ -0,0 +1,38 @@ + + + +
+ Configure conditions +
+
+{#key componentInstance?._id} + + + Show, hide and update components in response to conditions being met. + + + + +{/key} diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte index c1e26e68cd..a1b05ed19c 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte @@ -5,6 +5,7 @@ import ComponentSettingsSection from "./ComponentSettingsSection.svelte" import DesignSection from "./DesignSection.svelte" import CustomStylesSection from "./CustomStylesSection.svelte" + import ConditionalUISection from "./ConditionalUISection.svelte" $: componentInstance = $selectedComponent $: componentDefinition = store.actions.components.getDefinition( @@ -19,6 +20,7 @@ + diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte new file mode 100644 index 0000000000..8bd7341d7c --- /dev/null +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte @@ -0,0 +1,156 @@ + + + +
+ + {#if conditions?.length} +
+ {#each conditions as condition (condition.id)} +
+ +
TO
+ (condition.settingValue = e.detail)} + value={condition.settingValue} + /> + {/if} +
IF
+ (condition.newValue = e.detail)} + /> + onOperatorChange(condition, e.detail)} /> - (condition.referenceValue = e.detail)} + + {/if} .container { width: 100%; - max-width: 1200px; + max-width: 1400px; margin: 0 auto; } .conditions { @@ -190,12 +262,12 @@ gap: var(--spacing-l); display: grid; align-items: center; - grid-template-columns: auto 1fr auto 1fr 1fr 1fr auto; + grid-template-columns: auto 1fr auto 1fr 1fr 1fr 1fr auto; border-radius: var(--border-radius-s); transition: background-color ease-in-out 130ms; } .condition.update { - grid-template-columns: auto 1fr 1fr auto 1fr auto 1fr 1fr 1fr auto; + grid-template-columns: auto 1fr 1fr auto 1fr auto 1fr 1fr 1fr 1fr auto; } .condition:hover { background-color: var(--spectrum-global-color-gray-100); diff --git a/packages/client/src/utils/conditions.js b/packages/client/src/utils/conditions.js index 89d40037d3..9e4465cd5d 100644 --- a/packages/client/src/utils/conditions.js +++ b/packages/client/src/utils/conditions.js @@ -9,14 +9,35 @@ export const getActiveConditions = conditions => { } return conditions.filter(condition => { - const luceneCompatibleCondition = { + // Parse values into correct types + if (condition.valueType === "number") { + condition.referenceValue = parseFloat(condition.referenceValue) + condition.newValue = parseFloat(condition.newValue) + } else if (condition.valueType === "datetime") { + if (condition.referenceValue) { + condition.referenceValue = new Date( + condition.referenceValue + ).toISOString() + } + if (condition.newValue) { + condition.newValue = new Date(condition.newValue).toISOString() + } + } else if (condition.valueType === "boolean") { + condition.referenceValue = + `${condition.referenceValue}`.toLowerCase() === "true" + condition.newValue = `${condition.newValue}`.toLowerCase() === "true" + } + + // Build lucene compatible condition expression + const luceneCondition = { ...condition, - type: "string", + type: condition.valueType, field: "newValue", value: condition.referenceValue, } - const query = buildLuceneQuery([luceneCompatibleCondition]) - const result = luceneQuery([luceneCompatibleCondition], query) + + const query = buildLuceneQuery([luceneCondition]) + const result = luceneQuery([luceneCondition], query) return result.length > 0 }) } From 8a09494348ea5792120a590ed4f17686af96d641 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 26 Jul 2021 12:56:47 +0100 Subject: [PATCH 09/14] Fix bug with resetting operators when an incompatible value type is chosen --- .../PropertyControls/ConditionalUIDrawer.svelte | 5 ++--- .../FilterEditor/LuceneFilterBuilder.svelte | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte index cdb41d6da4..5521085056 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte @@ -125,10 +125,9 @@ condition.referenceValue = null // Ensure a valid operator is set - const validOperators = getValidOperatorsForType(newType) + const validOperators = getValidOperatorsForType(newType).map(x => x.value) if (!validOperators.includes(condition.operator)) { - condition.operator = - validOperators[0]?.value ?? OperatorOptions.Equals.value + condition.operator = validOperators[0] ?? OperatorOptions.Equals.value onOperatorChange(condition, condition.operator) } } diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FilterEditor/LuceneFilterBuilder.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FilterEditor/LuceneFilterBuilder.svelte index 76953933d0..e30c7dd63d 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FilterEditor/LuceneFilterBuilder.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FilterEditor/LuceneFilterBuilder.svelte @@ -47,10 +47,11 @@ expression.type = schemaFields.find(x => x.name === field)?.type // Ensure a valid operator is set - const validOperators = getValidOperatorsForType(expression.type) + const validOperators = getValidOperatorsForType(expression.type).map( + x => x.value + ) if (!validOperators.includes(expression.operator)) { - expression.operator = - validOperators[0]?.value ?? OperatorOptions.Equals.value + expression.operator = validOperators[0] ?? OperatorOptions.Equals.value onOperatorChange(expression, expression.operator) } } From 06e5a038f201a8c190cf49200dc2fcbb9bded30e Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 26 Jul 2021 13:08:22 +0100 Subject: [PATCH 10/14] Fix crash when building lucene query with a bool value already as a bool type --- packages/standard-components/src/lucene.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/standard-components/src/lucene.js b/packages/standard-components/src/lucene.js index 19566acc64..50aae1f32c 100644 --- a/packages/standard-components/src/lucene.js +++ b/packages/standard-components/src/lucene.js @@ -23,7 +23,7 @@ export const buildLuceneQuery = filter => { value = parseFloat(value) } if (type === "boolean") { - value = value?.toLowerCase() === "true" + value = `${value}`?.toLowerCase() === "true" } if (operator.startsWith("range")) { if (!query.range[field]) { From 93d6da7ebe0317914c3718c3ec3c986a80ceab6d Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 26 Jul 2021 13:10:00 +0100 Subject: [PATCH 11/14] Lint --- .../PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte index 5521085056..5839453258 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte @@ -6,7 +6,6 @@ DrawerContent, Layout, Select, - Input, DatePicker, } from "@budibase/bbui" import { flip } from "svelte/animate" From 73643793c93bfd7238a1ec9dffabe9f2e6b71308 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 26 Jul 2021 13:16:45 +0100 Subject: [PATCH 12/14] Simplify logic for determine default visibility for a conditional UI component --- packages/client/src/components/Component.svelte | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index 8969395490..8c7437e523 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -159,20 +159,17 @@ } // Default visible to false if there is a show condition - let nextVisible = true - for (let condition of conditions) { - if (condition.action === "show") { - nextVisible = false - } - } + let nextVisible = !conditions.find(condition => condition.action === "show") + // Execute conditions and determine settings and visibility changes const activeConditions = getActiveConditions(conditions) const result = reduceConditionActions(activeConditions) - conditionalSettings = result.settingUpdates if (result.visible != null) { nextVisible = result.visible } + // Update state from condition results + conditionalSettings = result.settingUpdates visible = nextVisible } From 7a9197975db2d480a5068e9b66e266b946636104 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 26 Jul 2021 14:09:14 +0100 Subject: [PATCH 13/14] Fix svelte-dnd-action throwing an error when interacting with a spectrum field inside a draggable --- .../ConditionalUIDrawer.svelte | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte index 5839453258..ebe60c7110 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ConditionalUIDrawer.svelte @@ -54,6 +54,7 @@ }, ] + let dragDisabled = true $: definition = store.actions.components.getDefinition( $selectedComponent?._component ) @@ -96,11 +97,16 @@ ] } - const removeLink = id => { + const removeCondition = id => { conditions = conditions.filter(link => link.id !== id) } - const updateLinks = e => { + const handleFinalize = e => { + updateConditions(e) + dragDisabled = true + } + + const updateConditions = e => { conditions = e.detail.items } @@ -142,9 +148,10 @@ items: conditions, flipDurationMs, dropTargetStyle: { outline: "none" }, + dragDisabled, }} - on:finalize={updateLinks} - on:consider={updateLinks} + on:finalize={handleFinalize} + on:consider={updateConditions} > {#each conditions as condition (condition.id)}
- +
(dragDisabled = false)} + > + +