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:
parent
29eefaf7ec
commit
842f931f71
2 changed files with 45 additions and 26 deletions
|
|
@ -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={{
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,9 @@
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { X } from 'lucide-react';
|
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';
|
||||||
|
|
@ -18,10 +19,11 @@ import { SocialPage } from '../social/social-page';
|
||||||
import { buildSocialCards } from '../../lib/social-cards';
|
import { buildSocialCards } from '../../lib/social-cards';
|
||||||
import { ContextualRightPanel } from '../activity/contextual-right-panel';
|
import { ContextualRightPanel } from '../activity/contextual-right-panel';
|
||||||
import { AssignmentPanel } from '../graph/assignment-panel';
|
import { AssignmentPanel } from '../graph/assignment-panel';
|
||||||
import { TelemetryStrip } from './telemetry-strip';
|
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);
|
||||||
|
|
||||||
|
// 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 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,15 +246,16 @@ 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}
|
||||||
idleCount={0}
|
idleCount={0}
|
||||||
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">
|
||||||
<span className="font-semibold">BD setup issue:</span> {bdHealth.message}
|
<span className="font-semibold">BD setup issue:</span> {bdHealth.message}
|
||||||
|
|
@ -319,8 +328,16 @@ export function UnifiedShell({
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{/* MOBILE NAV: Bottom tab bar */}
|
{/* MOBILE NAV: Bottom tab bar */}
|
||||||
<MobileNav />
|
<MobileNav />
|
||||||
</div>
|
|
||||||
|
{/* BLOCKED TRIAGE MODAL */}
|
||||||
|
<BlockedTriageModal
|
||||||
|
isOpen={blockedTriageOpen}
|
||||||
|
onClose={handleCloseBlockedTriage}
|
||||||
|
issues={issues}
|
||||||
|
projectRoot={projectContext}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue