Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import { useDraggable } from "@dnd-kit/core"; import type { TaskRecord } from "../../types"; import { StatusPill } from "../shared/StatusPill"; /** Presentational card body — reused in DragOverlay */ export function TaskCardContent({ task }: { task: TaskRecord }) { return ( <> <div className="task-card__top"> <span className="task-card__title">{task.title}</span> <StatusPill status={task.run_status} /> </div> <p className="task-card__prompt">{task.prompt}</p> <div className="task-card__meta"> <span>{task.project_dir}</span> <span>{task.session_id ?? "no session"}</span> </div> {task.last_result_summary ? ( <pre className="task-card__summary">{task.last_result_summary}</pre> ) : null} </> ); } export function TaskCard({ task, onEdit, onDelete, onRun, canRun, }: { task: TaskRecord; onEdit: () => void; onDelete: () => void; onRun: () => void; canRun: boolean; }) { const isRunning = task.run_status === "running"; const { attributes, listeners, setNodeRef, isDragging } = useDraggable({ id: task.task_id, disabled: isRunning, data: { taskId: task.task_id, stage: task.stage }, }); return ( <article ref={setNodeRef} className={`task-card${isDragging ? " task-card--dragging" : ""}${isRunning ? " task-card--readonly" : ""}`} > {/* Drag handle — only this region initiates drag */} <div className="task-card__drag-handle" {...listeners} {...attributes}> <TaskCardContent task={task} /> </div> <div className="task-card__actions"> <button type="button" className="btn btn--ghost btn--sm" onClick={onEdit} disabled={isRunning}> Edit </button> {canRun ? ( <button type="button" className="btn btn--ghost btn--sm" onClick={onRun} disabled={isRunning} > Start </button> ) : null} {task.session_id ? ( <a className="btn btn--ghost btn--sm" href={`/sessions/${encodeURIComponent(task.session_id)}`} target="_blank" rel="noopener noreferrer" > Session </a> ) : null} <button type="button" className="btn btn--danger btn--sm" onClick={onDelete} disabled={isRunning}> Delete </button> </div> </article> ); } |