From e0c191e7134bcbe5dfd5f99441b0b2ffa2061801 Mon Sep 17 00:00:00 2001 From: Kundan Sable Date: Wed, 22 Jul 2026 14:00:00 +0530 Subject: [PATCH] fix: Schema Diff filter chip toggle broadcasting stale empty selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit selectFilterOption() read newOptions from inside the functional setSelectedFilters(prev => {...}) updater and used it to dispatch TRIGGER_CHANGE_FILTER synchronously in the same tick. React's functional updater runs lazily during render, so newOptions was still its initial [] value when the event fired — every chip toggle broadcast an empty filter, so prepareRows() returned nothing and the results tree showed "No difference found" until the whole comparison was re-run. Compute the new selection synchronously from the current selectedFilters state and use that same array for both the state update and the dispatched event, so the filter chips and the results grid stay in sync on every toggle. Fixes #10102 --- .../components/SchemaDiffButtonComponent.jsx | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffButtonComponent.jsx b/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffButtonComponent.jsx index 3cf0675e473..ef1beb066b2 100644 --- a/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffButtonComponent.jsx +++ b/web/pgadmin/tools/schema_diff/static/js/components/SchemaDiffButtonComponent.jsx @@ -112,21 +112,22 @@ export function SchemaDiffButtonComponent({ sourceData, targetData, selectedRowI }, [filters]); const selectFilterOption = (option) => { - let newOptions = []; - setSelectedFilters((prev) => { - let newSelectdOptions = [...prev]; - let removeIndex = newSelectdOptions.indexOf(option); - if (prev.includes(option)) { - newSelectdOptions.splice(removeIndex, 1); - } else { - newSelectdOptions.push(option); - } - newOptions = [...newSelectdOptions]; - return newSelectdOptions; - }); + // Derive the new selection synchronously from the current state. + // The new array must be computed here (not inside a setState updater) + // because React invokes functional updaters lazily during render, so a + // value assigned inside the updater is not yet available when the event + // below fires. Reading it there previously broadcast an empty filter + // list, which blanked the results tree on every chip toggle. #10102 + let newSelectedOptions = [...selectedFilters]; + let removeIndex = newSelectedOptions.indexOf(option); + if (removeIndex !== -1) { + newSelectedOptions.splice(removeIndex, 1); + } else { + newSelectedOptions.push(option); + } - let filterParam = newOptions; - eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_CHANGE_FILTER, { filterParams: filterParam }); + setSelectedFilters(newSelectedOptions); + eventBus.fireEvent(SCHEMA_DIFF_EVENT.TRIGGER_CHANGE_FILTER, { filterParams: newSelectedOptions }); }; const selectCompareOption = (option) => {