enhancement
major
minor
defect
critical
major
minor
major
#30082
React UI: Tabs in a dialog change the page's address and remain in the URL after the dialog is closed
Problem
A <tab-bar> in a modal dialog was involved in the page's routing: Its active tabs were appended to the page's URL as path segments, and after the dialog was closed, the segment remained.
Reproduction in tl-demo-react (/view/, root / root1234):
- "Attributes → Table" page: URL …/view/attributes/table.
- User menu → "Settings": URL changed to …/attributes/table/account (RouteChangeEvent with replace: true).
- "Security" tab: URL changed to …/attributes/table/security (replace: false, meaning a new entry in the browser history).
- "Cancel": The dialog closed, but no RouteChangeEvent followed. The URL remained …/security until the next navigation.
Consequences: The address bar displayed something that wasn’t shown on the screen; clicking “Back” switched between tabs of a dialog that had already been closed; reloading the page did not reopen the dialog—the segment was silently discarded.
Cause
- By default, each tab receives a route based on its ID, so every tab bar in a dialog registered with the window’s RouteManager. Intentionally, no delivered view routes to a dialog; the affected files were settings.view.xml (along with settings-tabs.view.xml and its overlays) and demo/edit-constraint-test.view.xml.
- The lack of a fix upon closing was a separate bug: ReactDialogManagerControl.closeDialog detaches the dialog via cleanupTree() before removing it from the dialog stack. The URL that RouteManager.unregister() constructed as a result still contained the detached tab bar and was identical to the last one reported—nothing was sent. This affects any container that detaches removed elements before updating its state.
Solution
- A modal dialog is not a page: ReactControl.isContentOutsidePage() (default false) flags content that overlays the page without belonging to it; ReactDialogManagerControl returns true. A routing component within it does not register with the RouteManager (RouteManager.setOutsidePage(...)), is not included when the URL and title are constructed, and is not offered segments from a URL that has just been taken over. Opening, switching tabs, and closing a dialog leave the URL unchanged; no entries are added to the browser history. Tab bars in dialogs function as usual, but without routing.
- Logged-out participants do not contribute anything: URLs and titles are composed solely from logged-in participants. A participant that leaves the view corrects the URL even if it is detached before its container’s state is updated.
- Documentation: Developer article view-layer/navigation (dialogs, tabs).
Verification
Tests TestDialogRouting (page with routed tab bar and dialog with tab bar: Open, switch tabs, Close do not report a URL; title remains unchanged; a URL with a dialog segment taken over upon opening does not switch a dialog tab; page tabs continue routing afterward) and TestParticipantLeavingDisplay (container removes a routed tab bar before and after its state update); before the fix, 5 of the 6 tests failed. Full suites com.top_logic.layout.react and com.top_logic.layout.view passed. In the browser (tl-demo-react), the above sequence: The URL and ` history.length ` remain unchanged; clicking “Back” leaves the page instead of switching dialog tabs; page tabs continue routing; a stale address …/attributes/table/security is corrected to …/attributes/table without opening a dialog.