Description
While a query is running, the "running" spinner is not tied to the tab that launched the query — it follows whichever tab is currently active. Switch to another tab mid-run and the spinner jumps to that tab, even though a different tab owns the running query. The same spinner also appears on the SQL Editor header bar for whatever tab you're viewing.
Steps to reproduce
- Open two query tabs (A and B) on a connection.
- Run a slow-ish query on Tab A.
- While it's running, switch to Tab B.
Expected: the spinner stays on Tab A's status glyph; Tab B (which isn't running anything) shows no spinner, and its editor header bar shows no spinner.
Actual: the spinner moves to Tab B's glyph and Tab B's header bar — it "follows" the active tab.
Root cause
Execution state is a single global isExecuting boolean, and every indicator is gated on the active tab rather than the launching tab:
- Tab glyph —
src/components/layout/MainContent.tsx: const tabIsExecuting = activeTabId === tab.id && isExecuting;
- Header bar —
src/components/editor/QueryEditor.tsx: the editor renders for the active tab only and receives the global isExecuting prop.
- Results-panel loading and the psql window use the same global flag.
The query does internally know which tab started it (currentTabId), but the UI discards that. So all three indicators are really the same boolean painted in different places — none of them point at the owning tab.
Fix (prepared locally)
Introduce an executingTabId state recording which tab launched the run (set when execution starts; cleared in the finally, on cancel, and on supersession). The tab glyph keys off executingTabId === tab.id; the editor header / psql window / results-panel loading use isExecuting && executingTabId === activeTabId so they only show "running" when the active tab is the executing one. The top toolbar Run/Cancel control stays global (QueryDen runs one query at a time and you can cancel it from any tab).
PR to follow.
Environment
Affects all platforms / DB engines (the indicators are engine-agnostic frontend state).
Description
While a query is running, the "running" spinner is not tied to the tab that launched the query — it follows whichever tab is currently active. Switch to another tab mid-run and the spinner jumps to that tab, even though a different tab owns the running query. The same spinner also appears on the SQL Editor header bar for whatever tab you're viewing.
Steps to reproduce
Expected: the spinner stays on Tab A's status glyph; Tab B (which isn't running anything) shows no spinner, and its editor header bar shows no spinner.
Actual: the spinner moves to Tab B's glyph and Tab B's header bar — it "follows" the active tab.
Root cause
Execution state is a single global
isExecutingboolean, and every indicator is gated on the active tab rather than the launching tab:src/components/layout/MainContent.tsx:const tabIsExecuting = activeTabId === tab.id && isExecuting;src/components/editor/QueryEditor.tsx: the editor renders for the active tab only and receives the globalisExecutingprop.The query does internally know which tab started it (
currentTabId), but the UI discards that. So all three indicators are really the same boolean painted in different places — none of them point at the owning tab.Fix (prepared locally)
Introduce an
executingTabIdstate recording which tab launched the run (set when execution starts; cleared in thefinally, on cancel, and on supersession). The tab glyph keys offexecutingTabId === tab.id; the editor header / psql window / results-panel loading useisExecuting && executingTabId === activeTabIdso they only show "running" when the active tab is the executing one. The top toolbar Run/Cancel control stays global (QueryDen runs one query at a time and you can cancel it from any tab).PR to follow.
Environment
Affects all platforms / DB engines (the indicators are engine-agnostic frontend state).