Repository navigation
Replace native datalist with custom dropdown for inspect field - #87
Merged
Merged
Conversation
… detached The asset-focus inspect field used `<input list=...>` paired with a `<datalist>` sibling. When a visualization tab is detached into a popup window via DetachableTabHost, its overlay subtree is physically relocated across documents via appendChild. With tied zoom mirroring state changes between windows, the native datalist dropdown stopped appearing in the main window while still showing in the detached popup — a browser-level quirk of cross-document datalist lookups. Replace the native datalist with a small custom suggestions dropdown rendered as a plain absolutely-positioned sibling of the input. The dropdown now lives in whatever DOM subtree its owning overlay lives in, so it renders reliably in either window regardless of tied state. Add two regression tests: one locks the inspect field off the native <datalist>+list pattern, and the other exercises the custom dropdown rendering path.
The standalone interface exposes a "💡 Make a first guess" button when the Selected Actions panel is empty — it opens the Manual Selection search so the user can start exploring actions without first having to run a full analysis. The React frontend was missing this entry point, leaving users on the empty state with only the italic "Select an action manually…" hint. Mirror the standalone behavior in ActionFeed: when selectedEntries is empty, render the dashed-border "Make a first guess" button alongside the hint and wire it to the existing handleOpenSearch callback. Add three regression tests: the button appears in the empty state, clicking it opens the manual search dropdown, and the button is hidden once any action is selected.
Before this fix, a user's manually added ("first guess") action would
disappear from the Selected Actions section once the analysis was run
and displayed — especially the overlap case, where the same action
was ALSO returned by the recommender. Two issues were at play:
1. `handleRunAnalysis` called the full `clearContingencyState`, which
wiped `result`, `selectedActionIds` and `manuallyAddedIds` before
the stream even started, so the manual action was gone by the time
the results came back.
2. `handleDisplayPrioritizedActions` preserved manual actions by
looking them up via `selectedActionIds.has(id)` — but with that
set already cleared, nothing was preserved, and for the overlap
case the plain recommender entry (missing `is_manual: true`)
replaced the manual one.
Mirror the standalone interface's behavior:
- Add a narrower `resetForAnalysisRun` in App.tsx and wire
`wrappedRunAnalysis` to it. It filters `result.actions` down to the
`is_manual=true` subset (clearing pdf / lines_overloaded so the UI
still shows the in-progress state), trims `selectedActionIds` down
to the manually-added ids, and leaves `manuallyAddedIds` intact.
- Make `handleDisplayPrioritizedActions` preserve actions flagged
`is_manual` directly (not only those in `selectedActionIds`) and
re-apply `is_manual: true` on the preserved entries so the overlap
case keeps the user's manual flag and lands back in the Selected
bucket. Manual entries now win over their analysis-suggested twins
in the merged result.
Regression tests:
- useAnalysis: the overlap case — manual action survives
`handleDisplayPrioritizedActions` with an empty selected set, keeps
`is_manual=true`, and coexists with the other recommender entries.
- ActionFeed: when a manually added action is also present in
`actionScores`, it stays rendered in Selected and the yellow
"also recommended" warning fires with the overlapping id.
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
Replaces the native HTML
<input list>+<datalist>pattern with a custom-rendered suggestions dropdown component in the inspect search field. This fixes a reliability issue where the datalist dropdown would appear in the wrong window or not at all when a detached tab shares inspect state with the main window.Key Changes
New
InspectSearchFieldcomponent: A custom React component that renders an input field with a manually-managed suggestions dropdown, replacing the unreliable native datalist approachonMouseDownon suggestion items to ensure selection registers before the input'sonBlureventUpdated
VisualizationPanel: Replaced the inline<input list>+<datalist>markup with the newInspectSearchFieldcomponentAdded regression tests: Two new test cases verify:
<datalist>elements exist in the rendered outputImplementation Details
The custom dropdown solves the core issue by ensuring the suggestion list lives in the same DOM subtree as the input field. When
DetachableTabHostphysically relocates the overlay to a popup window, the dropdown moves with it, avoiding the Chromium bug where native datalists can render in the wrong window context.https://claude.ai/code/session_01YKKksRnZEYAehHndPxAXkA