Skip to content

A generic filter created by the programmatic API becomes broken after navigating to the view a second time #5425#5504

Open
fractal3000 wants to merge 2 commits into
release_3_0from
bug/5425-generic-filter-broken-on-re-navigation
Open

A generic filter created by the programmatic API becomes broken after navigating to the view a second time #5425#5504
fractal3000 wants to merge 2 commits into
release_3_0from
bug/5425-generic-filter-broken-on-re-navigation

Conversation

@fractal3000

@fractal3000 fractal3000 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Fixes #5425 and #5487

Problem

A GenericFilter bound via the urlQueryParameters facet broke on a clean re-navigation to the same view. When Vaadin reuses the view instance, onInit is not called again, and applyInitialState() wiped the current configuration instead of restoring it:

Fix

On re-navigation the binder now restores the captured initial state instead of clearing it:

  • Structure — the configuration tree is reconciled recursively: conditions removed by the user are re-added, conditions added afterwards (e.g. from the URL) are dropped, order and modified flags are restored, component instances are preserved.
  • Values/operations — the captured operation and value of each condition are restored for every configuration type, including design-time (GenericFilter: a design-time configuration value changed via the URL is not reset on re-navigation #5487); structural and default-value restore stay runtime-specific.
  • Event storm — the reconciliation unbinds the components-change listener and rebinds once, so it no longer pushes URL parameters per add/remove.

Supporting changes: the duplicated base-condition capture/compose logic in GenericFilter and GroupFilter was extracted into @Internal BaseConditionSupport (behaviour unchanged); the internal InitialState/ComponentNode records and the single-filter state helper are marked @Internal; generic-filter test views were renamed to the *TestView convention.

Tests

Facet-level re-navigation tests driving the real event chain (RestoreComponentsStateEventQueryParametersChangeEvent): programmatic-baseline survival, empty-configuration clearing, URL value/operation/condition reset, design-time value reset (#5487), nested-group restore, pure-user-action scope, and an event-storm regression. Also a regression test for removing a condition nested in a group (#5486).

Commits

  • restore configuration state on same-view re-navigation (5425, 5487) — the fix and its tests.
  • add a regression test for removing a condition nested in a group (5486) — the regression test.

Backward compatibility

No public API contract is removed or changed: the HasInitialState interface is untouched, GenericFilter.updateDataLoaderInitialCondition is kept as @Deprecated(forRemoval = true) rather than removed, and the only new public types (BaseConditionSupport, SingleFilterComponentStateSupport) are @Internal and purely additive. The behavioural changes are the bug fixes themselves — re-navigation now restores the configuration instead of clearing it (#5425) and resets a URL-changed design-time value (#5487); both correct broken behaviour, so no application migration is required.

However, the following protected members of the URL query-parameter binders changed shape. They are now marked @Internal, and all usages are confined to the flowui module (no references in jmix-premium or sample apps), but a subclass that referenced them would break at source/binary level. Worth a release-note line for anyone who extended these binders:

  • BC-1 — PropertyFilterUrlQueryParametersBinder (sharpest break): the protected record InitialState(Operation, Object) is removed, and the type of the protected field initialState changed from InitialState to SingleFilterComponentStateSupport.State. A subclass reading that field or the record no longer compiles.
  • BC-2 — DataGridFilterUrlQueryParametersBinder.InitialState: record signature changed from (String key, String property, PropertyFilter.Operation operation, Object value) to (String key, String property, SingleFilterComponentStateSupport.State state).
  • BC-3 — GenericFilterUrlQueryParametersBinder.InitialState: record signature changed from (Configuration configuration) to (Configuration configuration, List<ComponentNode> structure, Map<…> states, Map<…> defaultValues); a new ComponentNode record was added.

Mitigations already in place: all three records carry @Internal, the public HasInitialState contract does not expose them, and the new SingleFilterComponentStateSupport bean is resolved from the standard io.jmix.flowui component scan (no manual wiring needed).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A generic filter created by the programmatic API becomes broken after navigating to the view a second time

1 participant