diff options
| author | soryu <soryu@soryu.co> | 2026-02-08 16:18:13 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-02-08 16:18:13 +0000 |
| commit | c0f220582cd61f0d88e42dfbc29d55b3be1e3b19 (patch) | |
| tree | 5105fe5ffb6e80d3e82f806411628b0587c0685c /makima/frontend/src/components/directives/DirectiveDetail.tsx | |
| parent | 62d411f61893486680ded5921a8b86b483ee1144 (diff) | |
| download | soryu-c0f220582cd61f0d88e42dfbc29d55b3be1e3b19.tar.gz soryu-c0f220582cd61f0d88e42dfbc29d55b3be1e3b19.zip | |
Fix directive deletion and stop local only on contracts
Diffstat (limited to 'makima/frontend/src/components/directives/DirectiveDetail.tsx')
| -rw-r--r-- | makima/frontend/src/components/directives/DirectiveDetail.tsx | 188 |
1 files changed, 42 insertions, 146 deletions
diff --git a/makima/frontend/src/components/directives/DirectiveDetail.tsx b/makima/frontend/src/components/directives/DirectiveDetail.tsx index 06d8ba2..6bdf5aa 100644 --- a/makima/frontend/src/components/directives/DirectiveDetail.tsx +++ b/makima/frontend/src/components/directives/DirectiveDetail.tsx @@ -3,8 +3,6 @@ import { useNavigate } from "react-router"; import type { DirectiveWithChains, DirectiveStatus, - ChainWithSteps, - ChainStep, ContractPhase, } from "../../lib/api"; import { getDirective } from "../../lib/api"; @@ -32,122 +30,6 @@ const statusColors: Record<DirectiveStatus, string> = { failed: "text-red-400", }; -const stepStatusColors: Record<string, string> = { - pending: "text-[#888]", - running: "text-yellow-400", - passed: "text-green-400", - failed: "text-red-400", -}; - -const stepStatusIcons: Record<string, string> = { - pending: "\u25CB", // ○ - running: "\u25D4", // ◔ - passed: "\u25CF", // ● - failed: "\u2715", // ✕ -}; - -function StepRow({ step }: { step: ChainStep }) { - const navigate = useNavigate(); - const color = stepStatusColors[step.status] || "text-[#888]"; - const icon = stepStatusIcons[step.status] || "\u25CB"; - const summary = step.contractSummary; - - return ( - <div className="flex items-start gap-2 py-1.5 px-2 hover:bg-[rgba(117,170,252,0.05)]"> - <span className={`font-mono text-[11px] ${color} mt-px`}>{icon}</span> - <div className="flex-1 min-w-0"> - <div className="flex items-center gap-2"> - <span className="font-mono text-[11px] text-[#dbe7ff] truncate"> - {step.name} - </span> - <span className={`font-mono text-[9px] uppercase ${color}`}> - {step.status} - </span> - </div> - {summary && ( - <div className="flex items-center gap-2 mt-0.5"> - <PhaseProgressBarCompact - currentPhase={summary.phase as ContractPhase} - /> - <span className="font-mono text-[9px] text-[#7788aa]"> - {summary.tasksDone}/{summary.taskCount} tasks - </span> - {step.contractId && ( - <button - onClick={(e) => { - e.stopPropagation(); - navigate(`/contracts/${step.contractId}`); - }} - className="font-mono text-[9px] text-[#75aafc] hover:text-white transition-colors" - > - contract → - </button> - )} - </div> - )} - {!summary && step.contractId && ( - <button - onClick={() => navigate(`/contracts/${step.contractId}`)} - className="font-mono text-[9px] text-[#75aafc] hover:text-white transition-colors mt-0.5" - > - contract → - </button> - )} - {step.description && ( - <p className="font-mono text-[10px] text-[#7788aa] truncate mt-0.5"> - {step.description} - </p> - )} - </div> - </div> - ); -} - -function ChainCard({ chainWithSteps }: { chainWithSteps: ChainWithSteps }) { - const chain = chainWithSteps; - const steps = chainWithSteps.steps || []; - - return ( - <div className="border border-dashed border-[rgba(117,170,252,0.25)] bg-[rgba(117,170,252,0.03)]"> - <div className="p-3"> - <div className="flex items-center justify-between mb-1"> - <span className="font-mono text-xs text-[#dbe7ff]"> - {chain.name} - </span> - <span className="font-mono text-[10px] text-[#7788aa] uppercase"> - gen {chain.generation} · {chain.status} - </span> - </div> - {chain.description && ( - <p className="font-mono text-[11px] text-[#7788aa] mb-1"> - {chain.description} - </p> - )} - <div className="flex gap-3 font-mono text-[10px] text-[#7788aa]"> - <span> - {chain.completedSteps}/{chain.totalSteps} steps - </span> - {chain.failedSteps > 0 && ( - <span className="text-red-400">{chain.failedSteps} failed</span> - )} - {chain.currentConfidence != null && ( - <span> - confidence: {(chain.currentConfidence * 100).toFixed(0)}% - </span> - )} - </div> - </div> - {steps.length > 0 && ( - <div className="border-t border-dashed border-[rgba(117,170,252,0.15)]"> - {steps.map((step) => ( - <StepRow key={step.id} step={step} /> - ))} - </div> - )} - </div> - ); -} - function JsonSection({ label, data, @@ -484,39 +366,53 @@ export function DirectiveDetail({ {activeTab === "chain" && ( <div className="space-y-4"> - {/* Step diagram */} - {directive.chains.length > 0 && ( - <div> - <h4 className="font-mono text-[10px] text-[#75aafc] uppercase tracking-wider mb-2"> - Step Dependencies - </h4> - <StepDiagram - steps={directive.chains.flatMap((c) => c.steps)} - /> - </div> - )} - - {/* Chain cards */} - <div> - <h4 className="font-mono text-[10px] text-[#75aafc] uppercase tracking-wider mb-2"> - Chains ({directive.chains.length}) - </h4> - {directive.chains.length === 0 ? ( - <p className="font-mono text-xs text-[#7788aa]"> + {directive.chains.length === 0 ? ( + <div className="flex flex-col items-center justify-center py-12"> + <div className="font-mono text-[40px] text-[#333] mb-3"> + {directive.status === "planning" ? "\u2699" : "\u25CB"} + </div> + <p className="font-mono text-xs text-[#7788aa] text-center max-w-[300px]"> {directive.status === "planning" - ? "Planning in progress... chains will appear when the planner completes." + ? "Planning in progress... the chain will appear when the planner submits a plan." : directive.status === "draft" ? "No chains yet. Start the directive to begin planning." : "No chains created for this directive."} </p> - ) : ( - <div className="space-y-2"> - {directive.chains.map((cws) => ( - <ChainCard key={cws.id} chainWithSteps={cws} /> - ))} - </div> - )} - </div> + </div> + ) : ( + <> + {/* Chain metadata header */} + {directive.chains.map((chain) => ( + <div key={chain.id} className="space-y-3"> + <div className="flex items-center gap-3 pb-2 border-b border-dashed border-[rgba(117,170,252,0.15)]"> + <span className="font-mono text-xs text-[#dbe7ff]"> + {chain.name} + </span> + <span className="font-mono text-[10px] text-[#7788aa] uppercase"> + gen {chain.generation} + </span> + <span className={`font-mono text-[10px] uppercase ${ + chain.status === "completed" ? "text-green-400" : + chain.status === "failed" ? "text-red-400" : + chain.status === "running" ? "text-yellow-400" : + "text-[#7788aa]" + }`}> + {chain.status} + </span> + <span className="font-mono text-[10px] text-[#7788aa] ml-auto"> + {chain.completedSteps}/{chain.totalSteps} steps + {chain.failedSteps > 0 && ( + <span className="text-red-400 ml-1"> + ({chain.failedSteps} failed) + </span> + )} + </span> + </div> + <StepDiagram steps={chain.steps} /> + </div> + ))} + </> + )} </div> )} |
