Wire BlockedTriageModal to UnifiedShell and TopBar

- Add import for BlockedTriageModal in unified-shell.tsx
- Add blockedTriageOpen state and handlers
- Pass onOpenBlockedTriage prop to TopBar
- Render BlockedTriageModal at end of UnifiedShell
- Add onOpenBlockedTriage prop to TopBarProps interface
- Update blocked items button onClick to use onOpenBlockedTriage
This commit is contained in:
zenchantlive 2026-03-01 21:19:11 -08:00
parent 29eefaf7ec
commit 842f931f71
2 changed files with 45 additions and 26 deletions

View file

@ -18,6 +18,7 @@ export interface TopBarProps {
actor?: string; actor?: string;
onActorChange?: (name: string) => void; onActorChange?: (name: string) => void;
onLaunchSwarm?: () => void; onLaunchSwarm?: () => void;
onOpenBlockedTriage?: () => void;
} }
interface MetricTileProps { interface MetricTileProps {
@ -87,6 +88,7 @@ export function TopBar({
actor = '', actor = '',
onActorChange, onActorChange,
onLaunchSwarm, onLaunchSwarm,
onOpenBlockedTriage,
}: TopBarProps) { }: TopBarProps) {
const { leftPanel, toggleLeftPanel, rightPanel, toggleRightPanel, blockedOnly, toggleBlockedOnly } = useUrlState(); const { leftPanel, toggleLeftPanel, rightPanel, toggleRightPanel, blockedOnly, toggleBlockedOnly } = useUrlState();
const { isDesktop } = useResponsive(); const { isDesktop } = useResponsive();
@ -126,9 +128,9 @@ export function TopBar({
<div className="mr-3 flex items-center gap-2"> <div className="mr-3 flex items-center gap-2">
{children ?? ( {children ?? (
<> <>
<button <button
type="button" type="button"
onClick={toggleBlockedOnly} onClick={onOpenBlockedTriage}
aria-pressed={blockedOnly} aria-pressed={blockedOnly}
className="inline-flex items-center gap-2 rounded-xl border px-3 py-2 text-xs font-semibold uppercase tracking-[0.11em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--accent-info)]" className="inline-flex items-center gap-2 rounded-xl border px-3 py-2 text-xs font-semibold uppercase tracking-[0.11em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--accent-info)]"
style={{ style={{

View file

@ -5,6 +5,7 @@ import { X } from 'lucide-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import type { BeadIssue } from '../../lib/types'; import type { BeadIssue } from '../../lib/types';
import type { ProjectScopeOption } from '../../lib/project-scope'; import type { ProjectScopeOption } from '../../lib/project-scope';
import { buildProjectContext } from '../../lib/project-context';
import { TopBar } from './top-bar'; import { TopBar } from './top-bar';
import { LeftPanel, type LeftPanelFilters } from './left-panel'; import { LeftPanel, type LeftPanelFilters } from './left-panel';
import { RightPanel } from './right-panel'; import { RightPanel } from './right-panel';
@ -22,6 +23,7 @@ import { TelemetryStrip } from './telemetry-strip';
import { useSwarmList } from '../../hooks/use-swarm-list'; import { useSwarmList } from '../../hooks/use-swarm-list';
import { useBeadsSubscription } from '../../hooks/use-beads-subscription'; import { useBeadsSubscription } from '../../hooks/use-beads-subscription';
import { useBdHealth } from '../../hooks/use-bd-health'; import { useBdHealth } from '../../hooks/use-bd-health';
import { BlockedTriageModal } from './blocked-triage-modal';
export interface UnifiedShellProps { export interface UnifiedShellProps {
issues: BeadIssue[]; issues: BeadIssue[];
@ -69,13 +71,19 @@ export function UnifiedShell({
const [assignMode, setAssignMode] = useState(false); const [assignMode, setAssignMode] = useState(false);
const [selectedAssignIssue, setSelectedAssignIssue] = useState<BeadIssue | null>(null); const [selectedAssignIssue, setSelectedAssignIssue] = useState<BeadIssue | null>(null);
// Remember last non-telemetry state for minimize button // Remember last non-telemetry state for minimize button
const [lastTaskId, setLastTaskId] = useState<string | null>(null); const [lastTaskId, setLastTaskId] = useState<string | null>(null);
const [lastAssignMode, setLastAssignMode] = useState(false); const [lastAssignMode, setLastAssignMode] = useState(false);
const socialCards = useMemo(() => buildSocialCards(issues), [issues]); // Blocked triage modal state
const [blockedTriageOpen, setBlockedTriageOpen] = useState(false);
const handleOpenBlockedTriage = useCallback(() => setBlockedTriageOpen(true), []);
const handleCloseBlockedTriage = useCallback(() => setBlockedTriageOpen(false), []);
const socialCards = useMemo(() => buildSocialCards(issues), [issues]);
const { swarms: swarmCards } = useSwarmList(projectRoot); const { swarms: swarmCards } = useSwarmList(projectRoot);
const bdHealth = useBdHealth(projectRoot); const bdHealth = useBdHealth(projectRoot);
const projectContext = useMemo(() => buildProjectContext(projectRoot), [projectRoot]);
const selectedSocialCard = taskId ? socialCards.find(c => c.id === taskId) : null; const selectedSocialCard = taskId ? socialCards.find(c => c.id === taskId) : null;
const selectedSwarmCard = swarmId ? swarmCards.find(c => c.swarmId === swarmId) : null; const selectedSwarmCard = swarmId ? swarmCards.find(c => c.swarmId === swarmId) : null;
@ -238,7 +246,7 @@ export function UnifiedShell({
return ( return (
<div className="flex flex-col h-screen bg-[var(--surface-backdrop)]" data-testid="unified-shell"> <div className="flex flex-col h-screen bg-[var(--surface-backdrop)]" data-testid="unified-shell">
{/* TOP BAR: 3rem fixed */} {/* TOP BAR: 3rem fixed */}
<TopBar <TopBar
totalTasks={issues.filter(i => i.issue_type !== 'epic').length} totalTasks={issues.filter(i => i.issue_type !== 'epic').length}
criticalAlerts={issues.filter(i => i.status === 'blocked').length} criticalAlerts={issues.filter(i => i.status === 'blocked').length}
busyCount={issues.filter(i => i.status === 'in_progress').length} busyCount={issues.filter(i => i.status === 'in_progress').length}
@ -246,6 +254,7 @@ export function UnifiedShell({
actor={actor} actor={actor}
onActorChange={handleActorChange} onActorChange={handleActorChange}
onLaunchSwarm={() => { setTaskId(null); setAssignMode(true); }} onLaunchSwarm={() => { setTaskId(null); setAssignMode(true); }}
onOpenBlockedTriage={handleOpenBlockedTriage}
/> />
{!bdHealth.loading && !bdHealth.healthy ? ( {!bdHealth.loading && !bdHealth.healthy ? (
<div className="border-b border-amber-500/35 bg-amber-500/12 px-4 py-2 text-xs text-amber-100"> <div className="border-b border-amber-500/35 bg-amber-500/12 px-4 py-2 text-xs text-amber-100">
@ -319,8 +328,16 @@ export function UnifiedShell({
</div> </div>
) : null} ) : null}
{/* MOBILE NAV: Bottom tab bar */} {/* MOBILE NAV: Bottom tab bar */}
<MobileNav /> <MobileNav />
{/* BLOCKED TRIAGE MODAL */}
<BlockedTriageModal
isOpen={blockedTriageOpen}
onClose={handleCloseBlockedTriage}
issues={issues}
projectRoot={projectContext}
/>
</div> </div>
); );
} }