GenericFilter defautl configrations not restored for non-first tabs in JmixTabSheet (Jmix 2.8.0)

Environment: Jmix 2.8.0, Flow UI

Problem

When a view has a JmixTabSheet where each tab contains its own GenericFilter, only the first tab’s filter correctly restores its saved default configuration on re-opening the view. All other tabs’ filters appear blank.
This worked correctly in CUBA 7.

Root Cause

JmixTabSheet.updateContent() only appends the selected tab’s content element to the Vaadin element tree on view load — non-selected tabs’ elements remain detached (element.getParent() == null).

During view initialization, GenericFilterLoader runs an InitTask that calls loadConfigurationsAndApplyDefault() on every GenericFilter. That method calls FilterUtils.generateFilterPath(filter), which walks up the
component tree via component.getParent() to find the owning view:

// FilterUtils.java
public static String generateFilterPath(GenericFilter filter) {
    Composite<?> owner = findCurrentOwner(filter); // walks up via getParent()
    return (owner != null ? "[" + owner.getId().orElse("ownerWithoutId") + "]" : "")
            + UiComponentUtils.getComponentId(filter).orElse("filterWithoutId");
}

Since non-selected tabs have detached elements, getParent() returns empty partway up the tree and findCurrentOwner returns null. This causes a path mismatch:

┌───────┬───────────────────┬───────────────────┬────────────────────────────┐
│  Tab  │ Attached on open? │ Path at load time │ Path when config was saved │
├───────┼───────────────────┼───────────────────┼────────────────────────────┤
│ Tab 1 │ ✓                 │ [myView.id]filter │ [myView.id]filter ✓        │
├───────┼───────────────────┼───────────────────┼────────────────────────────┤
│ Tab 2 │ ✗                 │ filter2           │ [myView.id]filter2 ✗       │
├───────┼───────────────────┼───────────────────┼────────────────────────────┤
│ Tab 3 │ ✗                 │ filter3           │ [myView.id]filter3 ✗       │
└───────┴───────────────────┴───────────────────┴────────────────────────────┘

Configurations were saved correctly (the user was on the tab when saving, so it was attached). But on the next open, the bare path finds nothing in ui_filter_configuration and no default is applied.

Workaround

Re-call loadConfigurationsAndApplyDefault() on first activation of each non-first tab inside onTabSheetSelectedChange. By that point the tab content is attached and the path resolves correctly:

private boolean filter2Initialized = false;

@Subscribe("tabSheet")
public void onTabSheetSelectedChange(JmixTabSheet.SelectedChangeEvent event) {
    String tabId = event.getSelectedTab().getId().orElse("");
    switch (tabId) {
        case "tab2":
            if (!filter2Initialized) {
                filter2.loadConfigurationsAndApplyDefault();
                filter2Initialized = true;
            }
            loader2.load();
            break;
        // repeat for other tabs...
    }
}

Suggested Fix

In GenericFilterLoader, defer loadConfigurationsAndApplyDefault() until the component is actually attached to the view, for example via an AttachListener:

resultComponent.addAttachListener(e -> {
    if (!resultComponent.isConfigurationsLoaded()) {
        resultComponent.loadConfigurationsAndApplyDefault();
    }
});

Alternatively, generateFilterPath could resolve the owner lazily once the element is attached, rather than at InitTask execution time.