import { useState, useCallback } from "react"; import type { Task, TaskDetail, TaskCreateInput, Column as ColumnType } from "@hai/core"; import { COLUMN_LABELS, COLUMN_DESCRIPTIONS } from "@hai/core"; import { TaskCard } from "./TaskCard"; import { WorktreeGroup } from "./WorktreeGroup"; import { InlineCreateCard } from "./InlineCreateCard"; import { groupByWorktree } from "../utils/worktreeGrouping"; import type { ToastType } from "../hooks/useToast"; interface ColumnProps { column: ColumnType; tasks: Task[]; allTasks: Task[]; maxConcurrent: number; onMoveTask: (id: string, column: ColumnType) => Promise; onOpenDetail: (task: TaskDetail) => void; addToast: (message: string, type?: ToastType) => void; isCreating?: boolean; onCancelCreate?: () => void; onCreateTask?: (input: TaskCreateInput) => Promise; onNewTask?: () => void; autoMerge?: boolean; onToggleAutoMerge?: () => void; } export function Column({ column, tasks, allTasks, maxConcurrent, onMoveTask, onOpenDetail, addToast, isCreating, onCancelCreate, onCreateTask, onNewTask, autoMerge, onToggleAutoMerge }: ColumnProps) { const [dragOver, setDragOver] = useState(false); const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; setDragOver(true); }, []); const handleDragLeave = useCallback((e: React.DragEvent) => { const el = e.currentTarget as HTMLElement; if (!el.contains(e.relatedTarget as Node)) { setDragOver(false); } }, []); const handleDrop = useCallback(async (e: React.DragEvent) => { e.preventDefault(); setDragOver(false); const taskId = e.dataTransfer.getData("text/plain"); if (!taskId) return; try { await onMoveTask(taskId, column); } catch (err: any) { addToast(err.message, "error"); } }, [column, onMoveTask, addToast]); return (

{COLUMN_LABELS[column]}

{tasks.length} {column === "in-review" && onToggleAutoMerge && ( )} {onNewTask && ( )}

{COLUMN_DESCRIPTIONS[column]}

{column === "triage" && isCreating && onCancelCreate && onCreateTask && ( )} {column === "in-progress" ? ( (() => { const groups = groupByWorktree(tasks, allTasks, maxConcurrent); return groups.length === 0 ? (
No tasks
) : ( groups.map((group) => ( )) ); })() ) : tasks.length === 0 ? (
No tasks
) : ( tasks.map((task) => ( )) )}
); }