fix(tickets): Tab + Scrollposition überleben Browser-Zurück
Zwei Ursachen, warum es auf der Tickets-Seite nicht ging (am echten Firefox/Chromium gegen die Live-App verifiziert): 1) Tab ging verloren: der gewählte Filter-Tab (z. B. „Geschlossen") war reiner Component-State und sprang nach „Zurück" (Remount) auf „Offen" zurück — also war man in der falschen, kurzen Liste. Jetzt wird der Tab in der Session gemerkt und wiederhergestellt (userPicked startet weiterhin false, damit ?focus=-Deep-Links weiter funktionieren). 2) Scroll-Save-Heuristik zu unzuverlässig: Beim Wegnavigieren schrumpft der Inhalt von .app-main → der Container klemmt auf eine kleinere Position → dieses scroll-Event überschrieb die gemerkte Stelle. Erkennung präzisiert: nur verwerfen, wenn Position UND scrollHeight gleichzeitig SINKEN (= Inhalt geschrumpft/Seitenwechsel). Eine echte Nutzer-Scrollung verkleinert die scrollHeight nie — damit kein fälschliches Verwerfen echter Positionen mehr (vorherige „Höhe geändert"-Heuristik schluckte zu viel). Tests: scroll-restore.spec erweitert (realistisches 2-Schritt-Scrollen + Tickets-Tab überlebt Zurück), desktop+phone grün; vitest 149 grün. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -260,7 +260,18 @@ export default function TicketsPage() {
|
||||
// Default-Ansicht: „Offen" (neue, noch unbearbeitete Tickets) — fällt auf die erste
|
||||
// nicht-leere Gruppe zurück, falls „Offen" leer ist. Solange die Nutzerin keinen Filter
|
||||
// selbst gewählt hat (userPicked), darf ein ?focus=-Sprung die Ansicht bestimmen.
|
||||
const [view, setView] = useState<TicketView>('open')
|
||||
// Der zuletzt gewählte Tab wird in der Session gemerkt, damit man nach „Zurück" (Remount)
|
||||
// NICHT wieder im falschen Tab („Offen") landet. userPicked startet bewusst false, damit ein
|
||||
// frischer ?focus=-Deep-Link weiterhin in den passenden Tab springen darf.
|
||||
const [view, setView] = useState<TicketView>(() => {
|
||||
try {
|
||||
const v = sessionStorage.getItem('tickets-view')
|
||||
if (v === 'dialog' || v === 'open' || v === 'closed' || v === 'deleted') return v
|
||||
} catch {
|
||||
/* ignorieren */
|
||||
}
|
||||
return 'open'
|
||||
})
|
||||
const [userPicked, setUserPicked] = useState(false)
|
||||
|
||||
async function handleToggleStatus(ticket: FeedbackTicket) {
|
||||
@@ -551,6 +562,11 @@ export default function TicketsPage() {
|
||||
onClick={() => {
|
||||
setUserPicked(true)
|
||||
setView(v)
|
||||
try {
|
||||
sessionStorage.setItem('tickets-view', v)
|
||||
} catch {
|
||||
/* ignorieren */
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t.filters[v]}
|
||||
|
||||
Reference in New Issue
Block a user