One condition is shown but another is applied in GenericFilter - #5634
Merged
fractal3000 merged 5 commits intoSep 7, 2026
Conversation
fractal3000
force-pushed
the
bug/5516-one-condition-is-shown-but-another-is-applied-in-generic-filter
branch
from
August 28, 2026 16:38
88b93de to
9180cfe
Compare
fractal3000
marked this pull request as draft
August 31, 2026 06:34
KremnevDmitry
requested changes
Aug 31, 2026
fractal3000
force-pushed
the
bug/5516-one-condition-is-shown-but-another-is-applied-in-generic-filter
branch
from
September 4, 2026 08:41
9180cfe to
8ce8da9
Compare
…replaced base keeps the shown configuration The composition 'base AND current configuration' ran only on a configuration switch; apply(), the Apply button and a standalone GroupFilter.apply() just loaded, so a base replaced by the application after activation (allowed since the base-adoption rule) was loaded alone while the filter kept showing its configuration. These entry points now recompose before loading - but only when the loader condition actually diverged: the filter remembers the condition object it set last and recomposes only if the application has replaced it since. An untouched loader condition is not rewritten: the condition object stays stable across applies, an empty configuration without a base keeps the loader condition null, and the moment the base is first captured is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…load A value change (Enter, a dropdown selection) and an operation change load the data loader directly from the condition component or from the delegated group, bypassing the owner's composition. When the application had replaced the loader condition, such a load ran by the new base alone while the filter kept showing its configuration. Before these loads the component now finds the nearest non-delegated owner (GenericFilter or a standalone GroupFilter) up the component tree and lets it recompose - under the same divergence guard as apply(), so an untouched loader condition is left exactly as before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fractal3000
force-pushed
the
bug/5516-one-condition-is-shown-but-another-is-applied-in-generic-filter
branch
from
September 4, 2026 11:57
0e4a1ce to
bbbe357
Compare
fractal3000
marked this pull request as ready for review
September 4, 2026 11:57
KremnevDmitry
requested changes
Sep 5, 2026
Review follow-up. The delegated component no longer walks the component tree looking for its owner through a marker interface: it receives a recomposition delegate from the owner itself. A group hands its chain to children when they are added (and clears it on removal), the filter sets it on a configuration's root group, the converters set it on the components they create; late-bound method references let a request from any nesting level reach the outermost owner. The interface and the traversal are removed; the apply entry points call recomposeLoaderConditionIfOutdated() instead of inlining its body. DataGridHeaderFilter stays outside the wiring, pinned by a new test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The root-group construction in RunTimeConfigurationBuilder duplicated GenericFilter.createConfigurationRootLogicalFilterComponent line by line - the builder now calls it. The single-condition branch of the converter wiring is removed: such a component always joins a group before it can load, and the group re-wires it. The staleness predicate lives once in BaseConditionSupport.isReplacedExternally and is reused by the recompose routine and both filters. GroupFilter merges the two recomposition methods into one recomposeLoaderConditionIfOutdated, mirroring GenericFilter, so children receive the same-named delegate. A delegated condition now recomposes on apply() regardless of autoApply, consistently with the other apply entry points, which is pinned by a test. Javadoc inaccuracies fixed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
Rework pushed: |
KremnevDmitry
requested changes
Sep 7, 2026
KremnevDmitry
approved these changes
Sep 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See #5516
GenericFiltercomposes the data loader condition asbase AND current configuration, where the base is whatever the application set on the loader itself. Until now that composition ran only when the configuration was switched; every other applying gesture just loaded. When the application replaced the loader condition after a configuration was already active (allowed since #5400), the loader kept loading by the new base alone while the filter showed the configuration's condition.Now every applying gesture recomposes before loading — but only when the loader condition actually diverged: the filter remembers the condition object it set last (
lastConditionSetByFilter, the rule introduced by #5400) and recomposes only if the application has replaced it since. An untouched loader condition is not rewritten, so applications that never replace the base see byte-for-byte the previous behavior. The covered gestures:GenericFilter.apply(), the Apply button and its shortcut; a standaloneGroupFilter.apply()— recompose in place;GenericFilteror standaloneGroupFilter, maintained by the owner itself (a group hands its chain to children inadd()and clears it inremove(), the filter sets it on a configuration's root group, the converters set it on components they create). Works at any nesting level, including a group nested in a standalonegroupFilter;DataGridHeaderFilterstays outside this wiring, which is pinned by a test.Tests:
GenericFilterApplyAfterBaseChangeTest(flowui, 12 cases) andDataGridHeaderFilterApplyTest(the header filter is outside the recomposition wiring) — apply()/Apply button/value change/operation change after the base was replaced, forGenericFilterand standaloneGroupFilterincl. a nested group,autoApply=falsevariants, repeated apply() does not accumulate conditions, exactly one load per gesture, the empty configuration without a base, and the delegated root group leaving an untouched loader condition alone. Six of the original eight fail without the apply-path fix; the four gesture cases fail without the gesture fix. Full:flowui:test(1122) and:flowui-data:test(31) pass; thefilter-testscenario app was swept with Playwright on 3.0.1 and on this branch — 47 views, the only differences are the scenarios that reproduce this issue.Notes for review and release notes:
dataLoader.setCondition(...)while a configuration is shown, any applying gesture composesbase AND configuration. An application that replaced the loader condition specifically to override the filter will see the configuration re-applied. Repro: replace the loader condition after a configuration is active, then press Enter in a condition field.DataLoader: alternating applying gestures adopt the neighbour's composition as the base and re-add their own output — the condition tree grows with duplicate (idempotent) AND entries; query results stay correct. Repro:GenericFilter+ standalonegroupFilteron one loader, alternate gestures between them. Root cause is the shared loader condition, out of scope here.propertyFilter/jpqlFilterthat is not part of a composite filter, and a configuration whose condition components are all invisible, still load by a replaced base. Both are reachable only programmatically.GroupFilter.addregisters an unconditional operation-change listener). This PR does not change the number of loads; the fix is GenericFilter: restoring filter state from the URL fires a redundant data load when a condition operation differs #5659, stacked on this PR.QA (
filter-testfrom #5586, Scenarios 16, 25, 26 — the attached archive of #5586 predates 25/26; the current project has them):AND[amount greater_or_equal 100, AND[status equal OPEN]]and only Open orders — notamount greater_or_equal 100alone.GroupFilter), Replace base, then apply(), and Replace base only + change the Status value or operation: both conditions.autoApply="false": pressing Apply after the application replaced the loader condition loads by both conditions.🤖 Generated with Claude Code