diff options
Diffstat (limited to 'makima/frontend/src/components/orders/OrderDetail.tsx')
| -rw-r--r-- | makima/frontend/src/components/orders/OrderDetail.tsx | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/makima/frontend/src/components/orders/OrderDetail.tsx b/makima/frontend/src/components/orders/OrderDetail.tsx index 338cc60..ebc8124 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,11 @@ export function OrderDetail({ step:{order.directiveStepId.slice(0, 8)} </span> )} + {order.directiveId && ( + <span className="text-[10px] font-mono text-[#75aafc] border border-[rgba(117,170,252,0.3)] rounded px-1.5 py-0.5 truncate max-w-[120px]"> + DOG: {order.dogId ? (dogs.find((d) => d.id === order.dogId)?.name || order.dogId.slice(0, 8) + "...") : "None"} + </span> + )} <button type="button" onClick={onDelete} @@ -498,6 +507,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 |
