From 7c1c2b390d5f5c84feb38f759508dd48ffd93d02 Mon Sep 17 00:00:00 2001 From: StyxX65 <150797939+StyxX65@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:35:04 +0200 Subject: [PATCH] Keep selected card in view when opening preview Opening the preview panel narrows .grid-area and reflows the auto-fill grid to fewer columns, moving the clicked card to a new row. The single-frame scrollIntoView ran while the browser's scroll-anchoring re-adjusted scrollTop mid-reflow, so the card scrolled out of view. Disable scroll anchoring on .grid-area (overflow-anchor:none) and defer the scroll by two animation frames against the settled layout, centring the card (block:'center'). Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 2 ++ static/js/results.js | 6 +++++- static/style.css | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a66503e..766987c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ Version numbers follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html ### Fixed +- **Selected card scrolled out of view when opening the preview** — opening the preview panel narrows `.grid-area`, which reflows the `auto-fill` grid to fewer columns and moves every card to a new row. The single-frame `scrollIntoView` ran while the browser's scroll-anchoring re-adjusted `scrollTop` mid-reflow, fighting the scroll so the clicked card ended up off-screen. Fixed by disabling scroll anchoring on `.grid-area` (`overflow-anchor: none`) and deferring the scroll by two animation frames so it runs against the settled layout; the card is now centred (`block: 'center'`) instead of `'nearest'` so it stays clearly visible. + - **Cards not shown after browser refresh** — when the browser reconnected to the SSE stream after a completed scan, the `scan_phase` events in the replay buffer temporarily set `S._m365ScanRunning = true` (all running flags start at `false` after a page reload). The watchdog's `loadHistorySession` call fired in this window and bailed on the stale flag; once `scan_done` cleared the flag, `_initialStatusChecked` was already `true` so `loadHistorySession` was never retried. Fixed by having the `sse_replay_done` handler retry `loadHistorySession(null)` when no scan is running and `S._historyRefScanId` is still `null` after replay. - **Settings modal too narrow for seven tabs** — widened from 640 px to 720 px so all tab labels fit on one line without wrapping. diff --git a/static/js/results.js b/static/js/results.js index f45da36..3b142c6 100644 --- a/static/js/results.js +++ b/static/js/results.js @@ -118,7 +118,11 @@ async function openPreview(f) { panel.classList.remove('hidden'); const _savedW = sessionStorage.getItem('gdpr_preview_width'); if (_savedW) panel.style.width = _savedW + 'px'; - if (cardEl) requestAnimationFrame(() => cardEl.scrollIntoView({ behavior: 'smooth', block: 'nearest' })); + // Opening the panel narrows .grid-area and reflows the grid to fewer columns, + // moving the selected card to a new row. Defer the scroll by two frames so it + // runs against the settled layout, and centre the card so it stays visible. + if (cardEl) requestAnimationFrame(() => requestAnimationFrame(() => + cardEl.scrollIntoView({ behavior: 'smooth', block: 'center' }))); title.textContent = f.name; frame.style.display = 'none'; loading.style.display = 'flex'; diff --git a/static/style.css b/static/style.css index a817811..4b6a99d 100644 --- a/static/style.css +++ b/static/style.css @@ -197,7 +197,7 @@ .filter-clear:hover { border-color: var(--danger); color: var(--danger); } /* Grid */ - .grid-area { flex: 1; overflow-y: auto; padding: 24px; min-width: 0; scrollbar-width: thin; scrollbar-color: var(--border) transparent; } + .grid-area { flex: 1; overflow-y: auto; overflow-anchor: none; padding: 24px; min-width: 0; scrollbar-width: thin; scrollbar-color: var(--border) transparent; } .grid-area::-webkit-scrollbar { width: 4px; } .grid-area::-webkit-scrollbar-track { background: transparent; } .grid-area::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }