[web-console] Implement bi-directional search bar for logs tab and profiler metrics#6681
[web-console] Implement bi-directional search bar for logs tab and profiler metrics#6681Karakatiza666 wants to merge 1 commit into
Conversation
mythical-fred
left a comment
There was a problem hiding this comment.
Nicely done. The SearchProgress single-source-of-truth pattern is the right shape — counter, highlight, and nav all derive from results, and editing/clearing/closing all funnel through onclear. Test coverage is thorough: the shared SearchBar component gets its own spec, lookup.test.ts locks down the coordinator contract, metricsSearch.test.ts exercises the tiered matcher, and the MonitoringPanel spec was updated to drive the popup end-to-end (including the Ctrl+F → Esc → Ctrl+F reopen flow).
A few small non-blocking observations:
-
Two
useShortcuthandlers race forisFindShortcutinSupportBundleViewerLayout. Both are window-capture keydown listeners registered in order. When the graph is focused, the first callspreventDefault; the second still runs, returnsfalse, and no-ops. When the graph is not focused, the first returnsfalse(native find remains theoretically available for a brief moment before the second listener), and the second opens the search bar withpreventDefault. The current behavior is correct because Chrome fires the browser find only after all listeners resolve, so a laterpreventDefaultstill cancels it. Still, one combineduseShortcutwith a branch (if diagram focused → node search, else → tab search) would be less subtle and easier to reason about six months from now. -
matchCursorandsearchQueryinMetricsVieware plainlet, not$state. They're only read/written insiderunSearch, which is invoked imperatively via the lookup coordinator — so no reactivity is needed and this is fine. A one-liner comment (// imperative — no$stateon purpose) would prevent a well-meaning future contributor from "fixing" them. -
ProfilerDiagram.isFocused()usespointerOnGraphas a proxy for focus because the visualizer swallows its own pointer events. Comment already explains it; nothing to change. Just note that a keyboard-only user who tabs into the graph area cannot use Ctrl+F to focus "Search node" — they'd land on the tab search instead. Very niche; a11y-wise the graph isn't really keyboard-navigable today anyway. -
PR title typo — "bi-directinal" → "bi-directional". Worth fixing in the squash commit message.
-
Two nested destructurings got reformatted in
MetricsView.svelteandIssuesTab.svelte(prettier wrap width). Purely cosmetic, no behavior change — fine.
Everything I looked at holds together. Approving.
…filer metrics Switch what search bar Ctrl+F focuses in profiler based on context Extend search to include top nodes, global profile stats Signed-off-by: Karakatiza666 <bulakh.96@gmail.com>
mythical-fred
left a comment
There was a problem hiding this comment.
Re-review at b9b49a23c039f6b55e7af7cdb3fc4e76c66be5a5. Substantive changes since my earlier APPROVE at 0cd79fea (not a rebase-only update):
- New shared
common-ui/SearchBar.sveltepopup (icon toggle + input +"x of X"/"No results"counter + prev/next/close). Presentational only — host owns the query and drives the search. - New
common-ui/useShortcut.svelte.ts— capture-phase windowkeydownscoped to anisActivegetter.SupportBundleViewerLayoutnow uses one handler that routes Ctrl/Cmd-F to the graph's "Search node" input when the diagram is focused and to the tab'sSearchBarotherwise, collapsing the two prioruseShortcutcalls into a single context-switching path. - New
metricsSearch.ts(buildSearchTargets+matchTargets) with three-tier title → labels → keys ranking and dedup. Metrics search now covers the overview "Global stats" tile and every "Top nodes" table row (each row carries adata-block-id="top-node-<i>"anchor), on top of the per-node metric blocks. advanceSearch(state, next, direction: 'next'|'prev')for bi-directional stepping;findOccurrencestill wraps modulo count.LookupCoordinator.executereturnsSearchProgress— each tab handler (BundleLogsView,TriageResultsView,MetricsView) now reports{current, total}so the layout drives the counter and enables/disables the nav buttons off a single source of truth.LogListdropsonSearchShortcut(the host owns Ctrl/Cmd-F viauseShortcutnow) and exposesonMatchCountChangefrom a$derivedcountOccurrences.MonitoringPanelswaps the ad-hoc<input>for<SearchBar>, wiresuseShortcut(isFindShortcut, ..., () => currentTab === 'Logs'), and derivessearchResultsfromlogSearch+logMatchCount.- Explicit
// Imperative — no $state on purposecomment on thematchCursor/searchQuerypair inMetricsView(the intentionality note I asked about last round). - Node search input on the graph panel now blurs on Escape.
- PR title typo fixed (
bi-directional) — the commit subject still saysbi-directinal, but GitHub's squash uses the PR title.
Test coverage matches the growth: metricsSearch.test.ts (buildSearchTargets shapes + matchTargets three-tier ranking / dedup), the previously-added SearchBar.svelte.spec.ts, the extended MonitoringPanel.svelte.spec.ts (Ctrl+F popup, edit-invalidates-results, Esc close returns focus), logSearch.svelte.spec.ts (countOccurrences, isFindShortcut, advanceSearch direction cases), and lookup.test.ts for the coordinator contract.
Every non-blocking note from my previous review was folded in. LGTM.
One tiny nit for a future pass (not blocking): TriageResultsView.runSearch computes matches.indexOf(idx) + 1 after already scanning to build matches. For triage-sized inputs this is nothing, but if it ever grows tracking the cursor position during the filter pass would drop the extra O(n).
This adds a re-usable searchbar implementation
Switch what search bar Ctrl+F focuses in profiler based on context
The new search bar can be opened with a dedicated button or Ctrl+F and has buttons for forward and backward navigation, and responds to Enter and Shift+Enter shortcuts
Extend search to include top nodes, global profile stats
#6508
Screencast.From.2026-07-20.14-49-47.webm