From e2fcd757f783d11d34782e5eb66fa05e3df09cde Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Fri, 6 Dec 2024 14:30:43 +0000 Subject: [PATCH 1/5] Stop coercing all values to strings when using CoreCheckboxGroup --- packages/bbui/src/Form/Core/CheckboxGroup.svelte | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/bbui/src/Form/Core/CheckboxGroup.svelte b/packages/bbui/src/Form/Core/CheckboxGroup.svelte index d1a107fcc5..5aca7911e8 100644 --- a/packages/bbui/src/Form/Core/CheckboxGroup.svelte +++ b/packages/bbui/src/Form/Core/CheckboxGroup.svelte @@ -13,9 +13,8 @@ const dispatch = createEventDispatcher() - const onChange = e => { - const optionValue = e.target.value - if (e.target.checked && !value.includes(optionValue)) { + const onChange = optionValue => { + if (!value.includes(optionValue)) { dispatch("change", [...value, optionValue]) } else { dispatch( @@ -39,10 +38,9 @@ class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-FieldGroup-item" > onChange(optionValue)} type="checkbox" class="spectrum-Checkbox-input" - value={optionValue} checked={value.includes(optionValue)} {disabled} /> From d4f7dc3974f98d662e5b220f2380e7f9cca6680e Mon Sep 17 00:00:00 2001 From: andz-bb Date: Mon, 9 Dec 2024 16:29:52 +0000 Subject: [PATCH 2/5] Disable filter value binding input when no column is selected in filter screen --- packages/frontend-core/src/components/CoreFilterBuilder.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/frontend-core/src/components/CoreFilterBuilder.svelte b/packages/frontend-core/src/components/CoreFilterBuilder.svelte index 3aff981082..2bf40bda37 100644 --- a/packages/frontend-core/src/components/CoreFilterBuilder.svelte +++ b/packages/frontend-core/src/components/CoreFilterBuilder.svelte @@ -407,6 +407,7 @@ /> Date: Tue, 10 Dec 2024 12:49:43 +0000 Subject: [PATCH 3/5] Fixing generated readme workflow. --- .github/workflows/readme-openapi.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/readme-openapi.yml b/.github/workflows/readme-openapi.yml index 14e9887dd6..b52787934f 100644 --- a/.github/workflows/readme-openapi.yml +++ b/.github/workflows/readme-openapi.yml @@ -20,9 +20,4 @@ jobs: - run: yarn --frozen-lockfile - name: update specs - run: cd packages/server && yarn specs - - - name: Run `openapi` command - uses: readmeio/rdme@v8 - with: - rdme: openapi specs/openapi.yaml --key=${{ secrets.README_API_KEY }} --id=6728a74f5918b50036c61841 + run: cd packages/server && yarn specs && openapi specs/openapi.yaml --key=${{ secrets.README_API_KEY }} --id=6728a74f5918b50036c61841 From 36f8ae45fe468ca4a015733b58fd4e0b82e2e037 Mon Sep 17 00:00:00 2001 From: Dean Date: Tue, 10 Dec 2024 14:17:46 +0000 Subject: [PATCH 4/5] Rejig the filtering behaviour in the builder around empty config. Empty filters wont cause errors on load and will clear when they are saved --- .../FlowChart/BranchNode.svelte | 11 ++++---- .../SetupPanel/AutomationBlockSetup.svelte | 5 ++-- .../buttons/TableFilterButton.svelte | 4 +-- .../controls/FilterEditor/FilterEditor.svelte | 5 ++-- .../app/dynamic-filter/DynamicFilter.svelte | 3 ++- packages/frontend-core/src/utils/utils.js | 25 +++++++++++++++++++ packages/shared-core/src/filters.ts | 4 +-- 7 files changed, 42 insertions(+), 15 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/BranchNode.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/BranchNode.svelte index 670067ea26..c9205d0254 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/BranchNode.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/BranchNode.svelte @@ -19,7 +19,7 @@ import FlowItemHeader from "./FlowItemHeader.svelte" import FlowItemActions from "./FlowItemActions.svelte" import { automationStore, selectedAutomation } from "stores/builder" - import { QueryUtils } from "@budibase/frontend-core" + import { QueryUtils, Utils } from "@budibase/frontend-core" import { cloneDeep } from "lodash/fp" import { createEventDispatcher, getContext } from "svelte" import DragZone from "./DragZone.svelte" @@ -36,13 +36,11 @@ const view = getContext("draggableView") let drawer - let condition let open = true let confirmDeleteModal $: branch = step.inputs?.branches?.[branchIdx] - $: editableConditionUI = cloneDeep(branch.conditionUI || {}) - $: condition = QueryUtils.buildQuery(editableConditionUI) + $: editableConditionUI = branch.conditionUI || {} // Parse all the bindings into fields for the condition builder $: schemaFields = bindings.map(binding => { @@ -80,9 +78,10 @@ slot="buttons" on:click={() => { drawer.hide() + const updatedConditionsUI = Utils.parseFilter(editableConditionUI) dispatch("change", { - conditionUI: editableConditionUI, - condition, + conditionUI: updatedConditionsUI, + condition: QueryUtils.buildQuery(updatedConditionsUI), }) }} > diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 3faf9140f4..ab01b56152 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -594,10 +594,11 @@ } function saveFilters(key) { - const query = QueryUtils.buildQuery(tempFilters) + const update = Utils.parseFilter(tempFilters) + const query = QueryUtils.buildQuery(update) onChange({ [key]: query, - [`${key}-def`]: tempFilters, // need to store the builder definition in the automation + [`${key}-def`]: update, // need to store the builder definition in the automation }) drawer.hide() diff --git a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte index c6103b1697..d4a71c9ef8 100644 --- a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte +++ b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte @@ -4,7 +4,7 @@ import FilterBuilder from "components/design/settings/controls/FilterEditor/FilterBuilder.svelte" import { getUserBindings } from "dataBinding" import { makePropSafe } from "@budibase/string-templates" - import { search } from "@budibase/frontend-core" + import { search, Utils } from "@budibase/frontend-core" import { tables } from "stores/builder" import DetailPopover from "components/common/DetailPopover.svelte" @@ -73,7 +73,7 @@ cta slot="buttons" on:click={() => { - dispatch("change", localFilters) + dispatch("change", Utils.parseFilter(localFilters)) popover.hide() }} > diff --git a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte index c48cc3b8ce..b8a6b86b4d 100644 --- a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte @@ -10,7 +10,7 @@ import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding" import FilterBuilder from "./FilterBuilder.svelte" import { tables, selectedScreen } from "stores/builder" - import { search } from "@budibase/frontend-core" + import { search, Utils } from "@budibase/frontend-core" import { utils } from "@budibase/shared-core" const dispatch = createEventDispatcher() @@ -33,7 +33,8 @@ $: text = getText(value) async function saveFilter() { - dispatch("change", localFilters) + const update = Utils.parseFilter(localFilters) + dispatch("change", update) notifications.success("Filters saved") drawer.hide() } diff --git a/packages/client/src/components/app/dynamic-filter/DynamicFilter.svelte b/packages/client/src/components/app/dynamic-filter/DynamicFilter.svelte index 4ab01de17d..28858f3112 100644 --- a/packages/client/src/components/app/dynamic-filter/DynamicFilter.svelte +++ b/packages/client/src/components/app/dynamic-filter/DynamicFilter.svelte @@ -6,6 +6,7 @@ QueryUtils, Constants, CoreFilterBuilder, + Utils, } from "@budibase/frontend-core" import Button from "../Button.svelte" @@ -95,7 +96,7 @@ } const updateQuery = () => { - filters = editableFilters + filters = Utils.parseFilter(editableFilters) } onDestroy(() => { diff --git a/packages/frontend-core/src/utils/utils.js b/packages/frontend-core/src/utils/utils.js index fef9a7a31b..c424aea5b2 100644 --- a/packages/frontend-core/src/utils/utils.js +++ b/packages/frontend-core/src/utils/utils.js @@ -1,5 +1,6 @@ import { makePropSafe as safe } from "@budibase/string-templates" import { Helpers } from "@budibase/bbui" +import { cloneDeep } from "lodash" export const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) @@ -351,3 +352,27 @@ export const buildMultiStepFormBlockDefaultProps = props => { title, } } + +/** + * Parse out empty or invalid UI filters and clear empty groups + * @param {Object} filter UI filter + * @returns {Object} parsed filter + */ +export function parseFilter(filter) { + if (!filter?.groups) { + return filter + } + + const update = cloneDeep(filter) + + update.groups = update.groups + .map(group => { + group.filters = group.filters.filter(filter => { + return filter.field && filter.operator + }) + return group.filters.length ? group : null + }) + .filter(group => group) + + return update +} diff --git a/packages/shared-core/src/filters.ts b/packages/shared-core/src/filters.ts index 61950fd523..a023015b7e 100644 --- a/packages/shared-core/src/filters.ts +++ b/packages/shared-core/src/filters.ts @@ -298,7 +298,8 @@ export class ColumnSplitter { function buildCondition(filter: undefined): undefined function buildCondition(filter: SearchFilter): SearchFilters function buildCondition(filter?: SearchFilter): SearchFilters | undefined { - if (!filter) { + // Ignore empty or invalid filters + if (!filter || !filter?.operator || !filter?.field) { return } @@ -475,7 +476,6 @@ export function buildQuery( if (group.logicalOperator) { operator = logicalOperatorFromUI(group.logicalOperator) } - return { [operator]: { conditions: filters.map(buildCondition).filter(f => f) }, } From 50323a44599e69f2ee306d5a4beaaf24885bd8b8 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 10 Dec 2024 15:52:08 +0000 Subject: [PATCH 5/5] Bump version to 3.2.27 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index afd0db6374..d893fc97bd 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.26", + "version": "3.2.27", "npmClient": "yarn", "concurrency": 20, "command": {