diff options
| author | soryu <soryu@soryu.co> | 2026-03-05 23:25:40 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-03-07 02:28:19 +0000 |
| commit | ae3bc57de7a240c3c8ab15080b405e8ea3e16ccb (patch) | |
| tree | 96562ad1b73efa0f21ea79ae571e1c8674549d31 /makima/frontend/src/components/orders/OrderDetail.tsx | |
| parent | b8ec238084d9d5b210a67bc8c8cbb9a293facf28 (diff) | |
| download | soryu-ae3bc57de7a240c3c8ab15080b405e8ea3e16ccb.tar.gz soryu-ae3bc57de7a240c3c8ab15080b405e8ea3e16ccb.zip | |
WIP: heartbeat checkpointmakima/directive-soryu-co-soryu---makima-19fd3e1d-v1772803139
Diffstat (limited to 'makima/frontend/src/components/orders/OrderDetail.tsx')
| -rw-r--r-- | makima/frontend/src/components/orders/OrderDetail.tsx | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/makima/frontend/src/components/orders/OrderDetail.tsx b/makima/frontend/src/components/orders/OrderDetail.tsx index 9c3ac97..4267725 100644 --- a/makima/frontend/src/components/orders/OrderDetail.tsx +++ b/makima/frontend/src/components/orders/OrderDetail.tsx @@ -6,6 +6,7 @@ import type { OrderType, UpdateOrderRequest, DirectiveSummary, + DirectiveOrderGroup, } from "../../lib/api"; const STATUS_BADGE: Record<OrderStatus, { color: string; label: string }> = { @@ -37,6 +38,7 @@ const STATUS_OPTIONS: OrderStatus[] = ["open", "in_progress", "under_review", "d interface OrderDetailProps { order: Order; directives: DirectiveSummary[]; + dogs: DirectiveOrderGroup[]; onUpdate: (req: UpdateOrderRequest) => Promise<void>; onDelete: () => void; onLinkDirective: (directiveId: string) => Promise<void>; @@ -47,6 +49,7 @@ interface OrderDetailProps { export function OrderDetail({ order, directives, + dogs, onUpdate, onDelete, onLinkDirective, @@ -61,6 +64,7 @@ export function OrderDetail({ const [labelsText, setLabelsText] = useState(order.labels.join(", ")); const [showLinkDirective, setShowLinkDirective] = useState(false); const [directiveSearch, setDirectiveSearch] = useState(""); + const [showDogSelector, setShowDogSelector] = useState(false); const badge = STATUS_BADGE[order.status] || STATUS_BADGE.open; const currentPriority = PRIORITY_OPTIONS.find((p) => p.value === order.priority) || PRIORITY_OPTIONS[4]; @@ -192,6 +196,18 @@ export function OrderDetail({ Step: <span className="text-[#7788aa]">{order.directiveStepId.slice(0, 8)}...</span> </div> )} + {order.directiveId && ( + <div className="text-[10px] font-mono text-[#556677] mb-1"> + DOG:{" "} + {order.dogId ? ( + <span className="text-[#75aafc]"> + {dogs.find((d) => d.id === order.dogId)?.name || order.dogId.slice(0, 8) + "..."} + </span> + ) : ( + <span className="text-[#445566] italic">None</span> + )} + </div> + )} {/* Controls */} <div className="flex flex-wrap gap-2 mt-2"> @@ -501,6 +517,81 @@ export function OrderDetail({ )} </div> + {/* Assign to DOG */} + {order.directiveId && ( + <div> + <div className="flex items-center gap-1.5"> + <button + type="button" + onClick={() => setShowDogSelector(!showDogSelector)} + className="text-[10px] font-mono text-[#75aafc] hover:text-white border border-[rgba(117,170,252,0.3)] rounded px-2 py-1 flex-1 text-left" + > + {order.dogId ? "Change DOG" : "Assign to DOG"} + </button> + {order.dogId && ( + <button + type="button" + onClick={() => onUpdate({ dogId: null })} + className="text-[10px] font-mono text-red-400 hover:text-red-300 border border-red-800 rounded px-2 py-1" + title="Remove DOG assignment" + > + Unlink + </button> + )} + </div> + {showDogSelector && ( + <div className="mt-1 border border-[rgba(117,170,252,0.2)] bg-[#0a1525] rounded"> + <div className="max-h-32 overflow-y-auto"> + {dogs.length === 0 ? ( + <div className="px-3 py-2 text-[10px] font-mono text-[#556677]"> + No DOGs available for this directive + </div> + ) : ( + dogs.map((d) => { + const isAssigned = d.id === order.dogId; + const statusColors: Record<string, string> = { + open: "text-[#75aafc] border-[rgba(117,170,252,0.4)]", + in_progress: "text-yellow-400 border-yellow-800", + done: "text-emerald-400 border-emerald-800", + archived: "text-[#556677] border-[#2a3a5a]", + }; + const sColor = statusColors[d.status] || statusColors.open; + return ( + <button + key={d.id} + type="button" + onClick={async () => { + await onUpdate({ dogId: d.id }); + setShowDogSelector(false); + }} + className={`w-full text-left px-3 py-1.5 text-[10px] font-mono hover:bg-[rgba(117,170,252,0.1)] border-b border-[rgba(117,170,252,0.1)] last:border-b-0 ${ + isAssigned ? "bg-[rgba(117,170,252,0.08)] text-white" : "text-[#9bc3ff]" + }`} + > + <div className="flex items-center gap-1.5"> + <span className={`shrink-0 text-[8px] font-mono ${sColor} border rounded px-1 py-0.5 uppercase`}> + {d.status} + </span> + <span className="truncate">{d.name}</span> + {isAssigned && ( + <span className="shrink-0 text-[8px] text-emerald-400">current</span> + )} + </div> + {d.description && ( + <div className="text-[8px] text-[#556677] truncate mt-0.5"> + {d.description} + </div> + )} + </button> + ); + }) + )} + </div> + </div> + )} + </div> + )} + {/* Convert to Directive Step */} {!order.directiveStepId && order.directiveId && ( <button |
