dashboard: hide selection bar outside SW4RM tab (closes #596)

The sticky bulk-action bar (#443) was visible on every tab whenever the
selection was non-empty. On Y3R C4LL / SYST3M / SCH3DUL3S the operator
sees a floating bar without the agent cards next to it for cross-
reference — which is what mara called out in #596.

Fix: gate the bar on `document.body.dataset.activeTab === 'swarm'` in
addition to the existing non-empty-selection check. Selection state
itself stays in memory, so the bar reappears on return to SW4RM if any
agents are still ticked. The `activateTab` hook now sets the data
attribute and re-runs `renderSelectionBar` so the toggle takes effect
on hashchange without waiting for the next SSE update.
This commit is contained in:
iris 2026-05-29 19:35:30 +02:00
commit 1ae939499c

View file

@ -788,7 +788,13 @@ window.marked = marked;
if (!countSpan || !namesSpan || !actions) return;
const selected = containers.filter((c) => selectionState.has(c.name));
if (!selected.length) {
// #596: the bar's actions only make sense on the SW4RM tab — that's
// where the agent cards are visible to cross-reference against the
// selection. On other tabs the operator just sees a floating bar
// with no context, so hide it. Selection state persists in-memory
// and the bar reappears on return to SW4RM if still non-empty.
const onSwarmTab = (document.body.dataset.activeTab || 'swarm') === 'swarm';
if (!selected.length || !onSwarmTab) {
bar.hidden = true;
document.body.classList.remove('has-selection');
return;
@ -3055,6 +3061,12 @@ window.marked = marked;
if (tab) tab.classList.toggle('active', t === target);
if (pane) pane.classList.toggle('tab-pane-active', t === target);
}
// #596: track active tab on the body so renderSelectionBar can
// gate visibility (bar only belongs on SW4RM where agent cards
// live). Re-render the bar so the toggle takes effect immediately
// on hashchange without waiting for the next SSE update.
document.body.dataset.activeTab = target;
renderSelectionBar(Array.from(containersState.values()));
// #459: schedules pane has no SSE channel yet (PR C follow-up), so
// re-fetch on activation so the operator never lands on stale data.
if (target === 'schedules') refreshSchedules();