"use client"; import React, { useMemo, useState } from 'react'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from '@/components/ui/dialog'; import { deriveBlockedIds, buildBlockedByTree, type BlockedTreeNode } from '../../lib/kanban'; import { useArchetypePicker } from '../../hooks/use-archetype-picker'; import type { BeadIssue } from '../../lib/types'; import type { ProjectContext } from '../../lib/types'; import { Blocks, ChevronRight, UserPlus } from 'lucide-react'; import { cn } from '@/lib/utils'; export interface BlockedTriageModalProps { isOpen: boolean; onClose: () => void; issues: BeadIssue[]; projectRoot: ProjectContext; } export function BlockedTriageModal({ isOpen, onClose, issues, projectRoot, }: BlockedTriageModalProps) { const blockedIdsSet = useMemo(() => deriveBlockedIds(issues), [issues]); const blockedTasks = useMemo(() => { return issues.filter((issue) => { const isExplicitlyBlocked = issue.status === 'blocked'; const isDerivedBlocked = blockedIdsSet.has(issue.id); return isExplicitlyBlocked || isDerivedBlocked; }); }, [issues, blockedIdsSet]); const [expandedRow, setExpandedRow] = useState(null); const archetypePicker = useArchetypePicker(); const toggleRow = (issueId: string) => { setExpandedRow((prev) => (prev === issueId ? null : issueId)); }; const handleAssign = async (issueId: string) => { await archetypePicker.handleAssign(issueId); if (archetypePicker.assignSuccess) { setExpandedRow(null); archetypePicker.resetAssignState(); } }; return ( !open && onClose()}> Blocked Tasks Triage {blockedTasks.length} blocked task{blockedTasks.length !== 1 ? 's' : ''} require attention. Click on a row to see the blocker chain and assign an archetype.
{blockedTasks.length === 0 ? (
No blocked tasks found.
) : ( blockedTasks.map((issue) => { const blockerChain = buildBlockedByTree(issues, issue.id); const isExpanded = expandedRow === issue.id; return (
{isExpanded && (
{blockerChain.nodes.length > 0 ? (

Blocked by:

{blockerChain.nodes.map((node: BlockedTreeNode) => ( {node.title} ))} {blockerChain.total > blockerChain.nodes.length && ( +{blockerChain.total - blockerChain.nodes.length} more )}
) : (

No blocker chain found.

)}
{archetypePicker.assignError && (

{archetypePicker.assignError}

)} {archetypePicker.assignSuccess && (

Assigned successfully!

)}
)}
); }) )}
); }