diff options
Diffstat (limited to 'makima/frontend/src/components/mesh/TaskDetail.tsx')
| -rw-r--r-- | makima/frontend/src/components/mesh/TaskDetail.tsx | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/makima/frontend/src/components/mesh/TaskDetail.tsx b/makima/frontend/src/components/mesh/TaskDetail.tsx index 8e853e7..efe26a8 100644 --- a/makima/frontend/src/components/mesh/TaskDetail.tsx +++ b/makima/frontend/src/components/mesh/TaskDetail.tsx @@ -32,6 +32,8 @@ interface TaskDetailProps { onCreatePR?: (title: string, body: string, draft: boolean) => Promise<void>; onAutoMerge?: () => Promise<void>; fetchSubtasks?: (taskId: string) => Promise<TaskSummary[]>; + /** For supervisor tasks: all tasks in the contract (excluding the supervisor itself) */ + contractTasks?: TaskSummary[]; } function formatDate(dateStr: string): string { @@ -114,6 +116,7 @@ export function TaskDetail({ onCreatePR, onAutoMerge, fetchSubtasks, + contractTasks, }: TaskDetailProps) { const [isEditing, setIsEditing] = useState(false); const [editName, setEditName] = useState(task.name); @@ -149,10 +152,18 @@ export function TaskDetail({ // Show continue for supervisors (always) or terminal states for other tasks const canContinue = isSupervisor || isTaskTerminal; - // Calculate subtask statistics + // Determine which tasks to show: for supervisors, show contractTasks; for regular tasks, show subtasks + const displayTasks = useMemo(() => { + if (isSupervisor && contractTasks) { + return contractTasks; + } + return task.subtasks; + }, [isSupervisor, contractTasks, task.subtasks]); + + // Calculate task statistics for progress bar const subtaskStats = useMemo( - () => calculateTreeStats(task.subtasks), - [task.subtasks] + () => calculateTreeStats(displayTasks), + [displayTasks] ); // Check if task can create PR @@ -645,14 +656,14 @@ export function TaskDetail({ </div> )} - {/* Subtasks */} + {/* Subtasks / Contract Tasks (for supervisors) */} <div className="space-y-2"> <div className="flex items-center justify-between"> <div className="flex items-center gap-3"> <div className="font-mono text-xs text-[#9bc3ff] tracking-wide uppercase"> - Subtasks ({task.subtasks.length}) + {isSupervisor ? `Contract Tasks (${displayTasks.length})` : `Subtasks (${displayTasks.length})`} </div> - {task.subtasks.length > 0 && ( + {displayTasks.length > 0 && ( <button onClick={() => setUseTreeView(!useTreeView)} className="font-mono text-[9px] text-[#555] hover:text-[#75aafc]" @@ -661,41 +672,41 @@ export function TaskDetail({ </button> )} </div> - {/* Disable adding subtasks at max depth (2 = sub-subtask, cannot have children) */} - {task.depth < 2 ? ( + {/* Disable adding subtasks for supervisors and at max depth (2 = sub-subtask, cannot have children) */} + {!isSupervisor && task.depth < 2 ? ( <button onClick={onCreateSubtask} className="px-2 py-1 font-mono text-[10px] text-[#9bc3ff] border border-[rgba(117,170,252,0.25)] hover:border-[#3f6fb3] transition-colors uppercase" > + Add Subtask </button> - ) : ( + ) : !isSupervisor ? ( <span className="px-2 py-1 font-mono text-[10px] text-[#555] border border-[#333]" title="Maximum depth reached"> Max depth </span> - )} + ) : null} </div> - {/* Progress bar for subtasks */} - {task.subtasks.length > 0 && ( + {/* Progress bar for tasks */} + {displayTasks.length > 0 && ( <SubtaskProgressBar stats={subtaskStats} /> )} - {task.subtasks.length === 0 ? ( + {displayTasks.length === 0 ? ( <div className="text-[#555] font-mono text-xs py-4 text-center"> - No subtasks yet + {isSupervisor ? "No tasks in contract yet" : "No subtasks yet"} </div> ) : useTreeView ? ( <div className="border border-[rgba(117,170,252,0.15)]"> <SubtaskTree - subtasks={task.subtasks} + subtasks={displayTasks} onSelect={onSelectSubtask} fetchSubtasks={fetchSubtasks} /> </div> ) : ( <div className="divide-y divide-[rgba(117,170,252,0.15)] border border-[rgba(117,170,252,0.15)]"> - {task.subtasks.map((subtask: TaskSummary) => { + {displayTasks.map((subtask: TaskSummary) => { const isRunning = subtask.status === "running" || subtask.status === "initializing" || subtask.status === "starting"; const isViewingOutput = viewingSubtaskId === subtask.id; const isExpanded = expandedSubtaskId === subtask.id; |
