import { memo } from "react"; import type { Task, TaskDetail } from "@fusion/core"; import { ClipboardList, GitBranch } from "lucide-react"; import { TaskCard } from "./TaskCard"; import type { ToastType } from "../hooks/useToast"; import type { BlockerFanoutEntry } from "../hooks/useBlockerFanout"; interface WorktreeGroupProps { label: string; activeTasks: Task[]; queuedTasks: Task[]; projectId?: string; onOpenDetail: (task: Task | TaskDetail) => void; addToast: (message: string, type?: ToastType) => void; globalPaused?: boolean; onUpdateTask?: ( id: string, updates: { title?: string; description?: string; dependencies?: string[] } ) => Promise; onRetryTask?: (id: string) => Promise; onOpenDetailWithTab?: (task: Task | TaskDetail, initialTab: "changes" | "retries") => void; /** Project-level stuck task timeout in milliseconds (undefined = disabled) */ taskStuckTimeoutMs?: number; /** Called when user clicks a mission badge on a task card */ onOpenMission?: (missionId: string) => void; /** Timestamp (ms) when task data was last confirmed fresh from the server. Used for freshness-aware stuck detection. */ lastFetchTimeMs?: number; /** Lookup of workflow step IDs to display names, fetched once at board level. */ workflowStepNameLookup?: ReadonlyMap; /** Precomputed blocker fanout keyed by blocker task ID. */ blockerFanoutMap?: ReadonlyMap; } function WorktreeGroupComponent({ label, activeTasks, queuedTasks, projectId, onOpenDetail, addToast, globalPaused, onUpdateTask, onRetryTask, onOpenDetailWithTab, taskStuckTimeoutMs, onOpenMission, lastFetchTimeMs, workflowStepNameLookup, blockerFanoutMap, }: WorktreeGroupProps) { return (
{label === "Up Next" || label === "Unassigned" ? : } {label}
{activeTasks.map((task) => ( ))} {queuedTasks.map((task) => ( ))}
); } export const WorktreeGroup = memo(WorktreeGroupComponent); WorktreeGroup.displayName = "WorktreeGroup";