Repository navigation
Fix main window tab switching when action tab is detached - #90
Merged
Merged
Conversation
When the Remedial Action tab is open in a detached popup, clicking a
different action card used to force the main window to switch to the
action tab — which then rendered only the "view is detached" placeholder
over whatever N or N-1 diagram the user was studying. The detached
popup got the new diagram but the main window lost its context.
`handleActionSelect` now checks whether the action tab is currently
detached (via a ref mirror of the detachedTabs map) and, if so, skips
both the `setActiveTab('action')` call on select and the
`setActiveTab('n-1')` fallback on deselect. The popup still re-renders
with the new diagram because the action PZ / React subtree is unaffected.
Adds 5 regression tests covering select/deselect with and without the
action tab detached.
https://claude.ai/code/session_01VSVgi5jnBmHLrjb1XZuM9Y
The N-1 tab used to source overload halos exclusively from `result.lines_overloaded`, which is only populated after running "Analyze & Suggest". As a result, the orange overload highlights stayed invisible from the moment the user picked a contingency until the moment they clicked through a remedial-action simulation — even though the backend already reports the overloaded lines along with the N-1 diagram itself (`n1Diagram.lines_overloaded`). Add a small `computeN1OverloadHighlights` helper that prefers the analysis-result overloads when available and falls back to the N-1 diagram's own overload list otherwise, with the user's selected-overload set further filtering both. Wire `applyHighlightsForTab` to use it for the N-1 tab. This mirrors what the standalone interface has been doing. Tests: - 8 unit tests for `computeN1OverloadHighlights` covering both sources, the override priority, the user-selection filter and the empty edge cases. - 2 integration tests in `App.contingency.test.tsx` verifying that the app's overload state is populated immediately after the N-1 fetch (no analysis run), including across contingency switches. https://claude.ai/code/session_01VSVgi5jnBmHLrjb1XZuM9Y
Clicking a different action card while the Remedial Action tab is detached into a popup used to snap the popup back to the N / N-1 viewBox, losing the zoom the user had on the previous action. The capture + restore pair in handleActionSelect / the action-diagram re-sync effect were both gated on `activeTab === 'action'`, which is FALSE when the tab is detached (the main window is on N or N-1), so the capture fell through to the N-1 viewBox fallback and the restore was skipped entirely. Both paths now treat "action tab shows the action diagram" as either `activeTab === 'action'` OR `detachedTabsRef.current?.action` being truthy, matching the inline behaviour for the detached case. Adds 3 regression tests in useDiagrams.test.ts: - viewBox preserved across action switches when detached; - viewBox preserved across action switches when inline (guards the long-standing attached-case behaviour); - N-1 viewBox fallback still kicks in when there is no prior action-tab viewBox to preserve. https://claude.ai/code/session_01VSVgi5jnBmHLrjb1XZuM9Y
Clicking an asset badge inside an action card used to force the main
window's activeTab to 'action' via handleAssetClick, even when the
action tab was currently detached into a popup. That blanked whatever
N / N-1 view the operator had open and replaced it with the "view is
detached" placeholder — exactly the regression covered by the earlier
handleActionSelect fix, but from a different entry point. The N and
N-1 branches of handleAssetClick had the same symmetric problem for
overload-badge clicks in the OverloadPanel.
handleAssetClick now:
- routes the auto-zoom target through setInspectQueryForTab(tab, …)
so the zoom still lands on the correct (possibly detached) tab
regardless of the main window's activeTab;
- skips the setActiveTab call when the click targets a detached tab
(action, n or n-1). Inline clicks behave exactly as before.
Adds 6 regression tests in useDiagrams.test.ts covering:
- action-card asset click with action tab detached (stays on n-1);
- action-card asset click with action tab inline (still switches);
- n overload badge click with N tab detached (stays on action);
- n-1 overload badge click with N-1 tab detached (stays on action);
- n-1 overload badge click with N-1 tab inline (still switches);
- different-action asset click with action detached still delegates
to handleActionSelectFn (whose own detached guard is tested
separately).
https://claude.ai/code/session_01VSVgi5jnBmHLrjb1XZuM9Y
Fills in the doc gap left by the four fixes shipped for detached-tab interactions: - New "Main window stays steady on detached-tab interactions" section stating the invariant, listing every entry point it covers (handleActionSelect select / deselect, handleAssetClick for action / n / n-1), explaining why zoom still lands on the right tab thanks to setInspectQueryForTab, and showing the ref-mirror implementation pattern. - New "Preserving action-tab zoom across action switches" section walking through the capture + restore pattern in useDiagrams and why both halves had to learn about the detached case. - Feature-summary bullets pointing at both new sections. - Regression-tests section extended with the 14 new useDiagrams tests grouped by describe block. https://claude.ai/code/session_01VSVgi5jnBmHLrjb1XZuM9Y
marota
pushed a commit
that referenced
this pull request
Apr 30, 2026
Reconciliation of section 2 (0.5.0): - Drop misattributed PRs that were actually pre-rebrand: save/reload (#49/#52), MW Start (#62), interaction-logging (#64), SLD highlights (#63), load shedding initial integration (#61). All now properly cited in section 1.5–1.6. - Disambiguate App.tsx refactor history: PR #56 (hooks, 2100 → 800, pre-rebrand) vs PR #74 (components, 1000 → 650, 0.5.0) vs PR #75 (memoization Phase 2, same LoC). - Add accurate 0.5.0 PRs: #66 (vectorization w/ benchmark table), #69/#70/#71 (UI polish), #72 (curtailment), #73 (loads_p/gens_p format + configurable MW), #74/#75 (App.tsx decomposition), #78 (PST tap re-simulation), #84/#86/#87/#90 (detachable tabs). - Add a recap table summarizing what's truly new in 0.5.0. Diagrams added (Mermaid, GitHub-rendered): - Gantt timeline of all 4 phases (top of doc). - High-level architecture (frontend / backend / data). - Two-step analysis sequence diagram (section 1.6). - App.tsx LoC evolution flow (section 2.4). - Backend mixin decomposition before/after PR #104/#106 (section 3). - PyPSA-EUR pipeline flowchart (section 4). https://claude.ai/code/session_01Pg7fuCUG2edfm5PyHS6SbN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When the action tab is detached into a popup window, selecting an action card in the popup should not switch the main window's active tab to 'action'. This prevents the main window from blanking out and showing the "Detached" placeholder every time the user clicks a different action card in the popup.
Key Changes
detachedTabsRefto track the current detached tabs state in a stable ref, allowing callbacks to read the latest detached state without re-bindinghandleActionSelectto check if the action tab is detached before switching the main window's active tabsetActiveTab('action')so the main window stays on its current tab (N or N-1)handleActionSelectto only fall back to 'n-1' when the action tab is inlineImplementation Details
activeTabRefto maintain a stable reference todetachedTabswithout triggering callback re-bindshttps://claude.ai/code/session_01VSVgi5jnBmHLrjb1XZuM9Y