enhancement
major
minor
defect
critical
major
minor
major
#30082
React-Oberfläche: Reiter eines Dialogs verändern die Adresse der Seite und bleiben nach dem Schließen in der URL stehen
Problem
Ein <tab-bar> in einem modalen Dialog nahm am Routing der Seite teil: Seine aktiven Reiter wurden als Pfadsegmente an die URL der Seite angehängt, und nach dem Schließen des Dialogs blieb das Segment stehen.
Reproduktion in tl-demo-react (/view/, root / root1234):
- Seite "Attribute → Tabelle": URL …/view/attributes/table.
- Benutzermenü → "Einstellungen": URL wurde zu …/attributes/table/account (RouteChangeEvent mit replace: true).
- Reiter "Sicherheit": URL wurde zu …/attributes/table/security (replace: false, also ein neuer Eintrag in der Browser-Historie).
- "Abbrechen": Der Dialog schloss, es folgte aber kein RouteChangeEvent. Die URL blieb …/security, bis zur nächsten Navigation.
Folgen: Die Adresszeile nannte etwas, das nicht angezeigt wurde; "Zurück" schaltete zwischen Reitern eines bereits geschlossenen Dialogs um; ein Neuladen öffnete den Dialog nicht wieder, das Segment wurde stillschweigend verworfen.
Ursache
- Jeder Reiter erhält standardmäßig eine Route aus seiner Id, daher meldete sich jede Reiterleiste in einem Dialog beim RouteManager des Fensters an. Absichtlich routet keine ausgelieferte View in einen Dialog; betroffen waren settings.view.xml (mit settings-tabs.view.xml und dessen Overlays) und demo/edit-constraint-test.view.xml.
- Die fehlende Korrektur beim Schließen war ein eigener Fehler: ReactDialogManagerControl.closeDialog hängt den Dialog per cleanupTree() ab, bevor er aus dem Zustand des Dialogstapels entfernt wird. Die URL, die RouteManager.unregister() dabei zusammensetzte, enthielt deshalb noch die abgehängte Reiterleiste und war gleich der zuletzt gemeldeten - es wurde nichts gesendet. Das trifft jeden Container, der Entferntes vor der Aktualisierung seines Zustands abhängt.
Lösung
- Ein modaler Dialog ist keine Seite: ReactControl.isContentOutsidePage() (Standard false) kennzeichnet einen Inhalt, der über der Seite liegt, ohne zu ihr zu gehören; ReactDialogManagerControl liefert true. Ein Routing-Teilnehmer darin meldet sich nicht beim RouteManager an (RouteManager.setOutsidePage(...)), wird beim Zusammensetzen von URL und Titel nicht gesammelt und bekommt auch keine Segmente einer gerade übernommenen URL angeboten. Öffnen, Reiterwechsel und Schließen eines Dialogs lassen die URL unverändert, die Browser-Historie erhält keine Einträge. Reiterleisten in Dialogen funktionieren unverändert, nur ohne Routing.
- Abgemeldete Teilnehmer tragen nichts bei: URL und Titel werden nur aus angemeldeten Teilnehmern zusammengesetzt. Ein Teilnehmer, der die Anzeige verlässt, korrigiert die URL damit auch dann, wenn er vor der Zustandsaktualisierung seines Containers abgehängt wird.
- Dokumentation: Entwicklerartikel view-layer/navigation (Dialoge, Reiter).
Verifikation
Tests TestDialogRouting (Seite mit gerouteter Reiterleiste und Dialog mit Reiterleiste: Öffnen, Reiterwechsel, Schließen melden keine URL; Titel unverändert; eine beim Öffnen übernommene URL mit Dialogsegment schaltet keinen Dialogreiter um; Seitenreiter routen danach weiter) und TestParticipantLeavingDisplay (Container entfernt eine geroutete Reiterleiste vor und nach seiner Zustandsaktualisierung); vor der Korrektur schlugen 5 der 6 Tests fehl. Volle Suiten com.top_logic.layout.react und com.top_logic.layout.view grün. Im Browser (tl-demo-react) obiger Ablauf: URL und history.length bleiben unverändert, "Zurück" verlässt die Seite statt Dialogreiter umzuschalten, Seitenreiter routen weiter, eine veraltete Adresse …/attributes/table/security wird auf …/attributes/table korrigiert, ohne dass ein Dialog aufgeht.