diff options
Diffstat (limited to 'makima/frontend/src/components/directives/OrchestratorStepNode.tsx')
| -rw-r--r-- | makima/frontend/src/components/directives/OrchestratorStepNode.tsx | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/makima/frontend/src/components/directives/OrchestratorStepNode.tsx b/makima/frontend/src/components/directives/OrchestratorStepNode.tsx new file mode 100644 index 0000000..9c8e95e --- /dev/null +++ b/makima/frontend/src/components/directives/OrchestratorStepNode.tsx @@ -0,0 +1,161 @@ +export type OrchestratorStepType = + | "planning" + | "replanning" + | "plan-orders" + | "pr" + | "pr-update" + | "cleanup" + | "verification"; + +export type OrchestratorStepStatus = "running" | "completed" | "failed" | "pending"; + +export interface OrchestratorStepNodeProps { + type: OrchestratorStepType; + taskId: string; + status: OrchestratorStepStatus; + label: string; + hasQuestions?: boolean; +} + +const TYPE_COLORS: Record< + OrchestratorStepType, + { accent: string; bg: string; border: string; text: string; dot: string } +> = { + planning: { + accent: "#75aafc", + bg: "bg-[#0d1a30]", + border: "border-[#75aafc]", + text: "text-[#75aafc]", + dot: "bg-[#75aafc]", + }, + replanning: { + accent: "#75aafc", + bg: "bg-[#0d1a30]", + border: "border-[#75aafc]", + text: "text-[#75aafc]", + dot: "bg-[#75aafc]", + }, + "plan-orders": { + accent: "#c084fc", + bg: "bg-[#1a0d30]", + border: "border-[#c084fc]", + text: "text-[#c084fc]", + dot: "bg-[#c084fc]", + }, + pr: { + accent: "#34d399", + bg: "bg-[#0a1a14]", + border: "border-[#34d399]", + text: "text-[#34d399]", + dot: "bg-[#34d399]", + }, + "pr-update": { + accent: "#34d399", + bg: "bg-[#0a1a14]", + border: "border-[#34d399]", + text: "text-[#34d399]", + dot: "bg-[#34d399]", + }, + cleanup: { + accent: "#7788aa", + bg: "bg-[#141a24]", + border: "border-[#7788aa]", + text: "text-[#7788aa]", + dot: "bg-[#7788aa]", + }, + verification: { + accent: "#7788aa", + bg: "bg-[#141a24]", + border: "border-[#7788aa]", + text: "text-[#7788aa]", + dot: "bg-[#7788aa]", + }, +}; + +const TYPE_LABELS: Record<OrchestratorStepType, string> = { + planning: "PLANNING", + replanning: "REPLANNING", + "plan-orders": "PLAN ORDERS", + pr: "PR", + "pr-update": "PR UPDATE", + cleanup: "CLEANUP", + verification: "VERIFICATION", +}; + +const STATUS_LABELS: Record<OrchestratorStepStatus, string> = { + pending: "PENDING", + running: "RUNNING", + completed: "DONE", + failed: "FAILED", +}; + +export function OrchestratorStepNode({ + type, + taskId, + status, + label, + hasQuestions, +}: OrchestratorStepNodeProps) { + const colors = TYPE_COLORS[type]; + const typeLabel = TYPE_LABELS[type]; + const statusLabel = STATUS_LABELS[status]; + + return ( + <div + className={`${colors.bg} ${colors.border} border border-dashed rounded px-3 py-2 min-w-[160px] max-w-[220px] relative`} + > + {/* Type badge */} + <div className="flex items-center justify-between gap-2 mb-1"> + <div className="flex items-center gap-1.5 min-w-0"> + {/* Status dot */} + {status === "running" && ( + <span + className={`inline-block w-2 h-2 rounded-full ${colors.dot} animate-pulse shrink-0`} + /> + )} + {status === "completed" && ( + <span className="inline-block w-2 h-2 rounded-full bg-emerald-400 shrink-0" /> + )} + {status === "failed" && ( + <span className="inline-block w-2 h-2 rounded-full bg-red-400 shrink-0" /> + )} + {status === "pending" && ( + <span className="inline-block w-2 h-2 rounded-full bg-[#556677] shrink-0" /> + )} + <span className={`text-[9px] font-mono ${colors.text} uppercase shrink-0`}> + {typeLabel} + </span> + </div> + <div className="flex items-center gap-1 shrink-0"> + {hasQuestions && ( + <span className="inline-block w-2 h-2 rounded-full bg-purple-400 animate-pulse" title="Has pending questions" /> + )} + <span + className={`text-[9px] font-mono uppercase ${ + status === "completed" + ? "text-emerald-400" + : status === "failed" + ? "text-red-400" + : colors.text + }`} + > + {statusLabel} + </span> + </div> + </div> + + {/* Label */} + <span className="text-[11px] font-mono text-white truncate block font-medium mb-1"> + {label} + </span> + + {/* Task link */} + <a + href={`/mesh/${taskId}`} + className={`text-[9px] font-mono text-[#556677] hover:${colors.text} underline block`} + > + {status === "running" ? "View running task" : "View task"} + </a> + </div> + ); +} |
