diff options
| author | soryu <soryu@soryu.co> | 2026-02-17 00:40:32 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-17 00:40:32 +0000 |
| commit | b67b3f8e8d63361d9ff19f87fd608c03bfa3fd43 (patch) | |
| tree | d5429658a90c4be9a2984617118d2c843cadfdf6 /makima/frontend/src/components | |
| parent | 4bd40f047a6f4703945c6db2811d8feda27241d6 (diff) | |
| download | soryu-b67b3f8e8d63361d9ff19f87fd608c03bfa3fd43.tar.gz soryu-b67b3f8e8d63361d9ff19f87fd608c03bfa3fd43.zip | |
soryu-co/soryu - makima (#67)
* feat: soryu-co/soryu - makima: Fix contracts page scrolling overflow
* WIP: heartbeat checkpoint
* WIP: heartbeat checkpoint
* WIP: heartbeat checkpoint
* WIP: heartbeat checkpoint
* feat: soryu-co/soryu - makima: Remove contract association from orders and make directive mandatory in UI
* feat: soryu-co/soryu - makima: Add directive name to order metadata for searchability
* feat: soryu-co/soryu - makima: Change directive link in orders to use search interface
* feat: soryu-co/soryu - makima: Name directive PRs based on content not directive title
* feat: soryu-co/soryu - makima: Add orderId to step creation and auto-link orders to steps
* feat: soryu-co/soryu - makima: Add under_review status and auto-complete orders in plan flow
Diffstat (limited to 'makima/frontend/src/components')
| -rw-r--r-- | makima/frontend/src/components/orders/OrderDetail.tsx | 117 | ||||
| -rw-r--r-- | makima/frontend/src/components/orders/OrderList.tsx | 5 |
2 files changed, 95 insertions, 27 deletions
diff --git a/makima/frontend/src/components/orders/OrderDetail.tsx b/makima/frontend/src/components/orders/OrderDetail.tsx index 9d4c00c..1b8d76e 100644 --- a/makima/frontend/src/components/orders/OrderDetail.tsx +++ b/makima/frontend/src/components/orders/OrderDetail.tsx @@ -11,6 +11,7 @@ import type { const STATUS_BADGE: Record<OrderStatus, { color: string; label: string }> = { open: { color: "text-[#75aafc] border-[rgba(117,170,252,0.4)]", label: "OPEN" }, in_progress: { color: "text-yellow-400 border-yellow-800", label: "IN PROGRESS" }, + under_review: { color: "text-amber-400 border-amber-800", label: "UNDER REVIEW" }, done: { color: "text-emerald-400 border-emerald-800", label: "DONE" }, archived: { color: "text-[#556677] border-[#2a3a5a]", label: "ARCHIVED" }, }; @@ -31,7 +32,7 @@ const TYPE_OPTIONS: { value: OrderType; color: string; label: string }[] = [ { value: "improvement", color: "text-emerald-400", label: "Improvement" }, ]; -const STATUS_OPTIONS: OrderStatus[] = ["open", "in_progress", "done", "archived"]; +const STATUS_OPTIONS: OrderStatus[] = ["open", "in_progress", "under_review", "done", "archived"]; interface OrderDetailProps { order: Order; @@ -59,6 +60,7 @@ export function OrderDetail({ const [editingLabels, setEditingLabels] = useState(false); const [labelsText, setLabelsText] = useState(order.labels.join(", ")); const [showLinkDirective, setShowLinkDirective] = useState(false); + const [directiveSearch, setDirectiveSearch] = useState(""); const badge = STATUS_BADGE[order.status] || STATUS_BADGE.open; const currentPriority = PRIORITY_OPTIONS.find((p) => p.value === order.priority) || PRIORITY_OPTIONS[4]; @@ -405,31 +407,96 @@ export function OrderDetail({ <div className="flex flex-col gap-2"> {/* Link to Directive */} <div> - <button - type="button" - onClick={() => setShowLinkDirective(!showLinkDirective)} - className="text-[10px] font-mono text-[#75aafc] hover:text-white border border-[rgba(117,170,252,0.3)] rounded px-2 py-1 w-full text-left" - > - Link to Directive - </button> + <div className="flex items-center gap-1.5"> + <button + type="button" + onClick={() => { + setShowLinkDirective(!showLinkDirective); + setDirectiveSearch(""); + }} + 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.directiveId ? "Change Directive" : "Link to Directive"} + </button> + {order.directiveId && ( + <button + type="button" + onClick={() => onUpdate({ directiveId: null, directiveStepId: null })} + className="text-[10px] font-mono text-red-400 hover:text-red-300 border border-red-800 rounded px-2 py-1" + title="Unlink directive" + > + Unlink + </button> + )} + </div> {showLinkDirective && ( - <div className="mt-1 border border-[rgba(117,170,252,0.2)] bg-[#0a1525] max-h-32 overflow-y-auto rounded"> - {directives.length === 0 ? ( - <div className="px-3 py-2 text-[10px] font-mono text-[#556677]"> - No directives available - </div> - ) : ( - directives.map((d) => ( - <button - key={d.id} - type="button" - onClick={() => handleLinkDirective(d.id)} - className="w-full text-left px-3 py-1.5 text-[10px] font-mono text-[#9bc3ff] hover:bg-[rgba(117,170,252,0.1)] border-b border-[rgba(117,170,252,0.1)] last:border-b-0" - > - {d.title} - </button> - )) - )} + <div className="mt-1 border border-[rgba(117,170,252,0.2)] bg-[#0a1525] rounded"> + <div className="px-2 py-1.5 border-b border-[rgba(117,170,252,0.1)]"> + <input + type="text" + value={directiveSearch} + onChange={(e) => setDirectiveSearch(e.target.value)} + placeholder="Search directives..." + autoFocus + className="w-full bg-transparent border-none outline-none text-[10px] font-mono text-[#75aafc] placeholder-[#556677]" + /> + </div> + <div className="max-h-32 overflow-y-auto"> + {directives.length === 0 ? ( + <div className="px-3 py-2 text-[10px] font-mono text-[#556677]"> + No directives available + </div> + ) : ( + (() => { + const filtered = directives.filter((d) => + d.title.toLowerCase().includes(directiveSearch.toLowerCase()) + ); + if (filtered.length === 0) { + return ( + <div className="px-3 py-2 text-[10px] font-mono text-[#556677]"> + No matching directives + </div> + ); + } + return filtered.map((d) => { + const isLinked = d.id === order.directiveId; + const statusColors: Record<string, string> = { + draft: "text-[#556677] border-[#2a3a5a]", + active: "text-emerald-400 border-emerald-800", + idle: "text-[#7788aa] border-[#2a3a5a]", + paused: "text-yellow-400 border-yellow-800", + archived: "text-[#556677] border-[#2a3a5a]", + }; + const sColor = statusColors[d.status] || statusColors.draft; + return ( + <button + key={d.id} + type="button" + onClick={() => handleLinkDirective(d.id)} + 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 ${ + isLinked ? "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.title}</span> + {isLinked && ( + <span className="shrink-0 text-[8px] text-emerald-400">●</span> + )} + </div> + {d.repositoryUrl && ( + <div className="text-[8px] text-[#556677] truncate mt-0.5"> + {d.repositoryUrl} + </div> + )} + </button> + ); + }); + })() + )} + </div> </div> )} </div> diff --git a/makima/frontend/src/components/orders/OrderList.tsx b/makima/frontend/src/components/orders/OrderList.tsx index 1d279f7..3d63c54 100644 --- a/makima/frontend/src/components/orders/OrderList.tsx +++ b/makima/frontend/src/components/orders/OrderList.tsx @@ -4,6 +4,7 @@ import type { Order, OrderStatus, OrderPriority, OrderType } from "../../lib/api const STATUS_BADGE: Record<OrderStatus, { color: string; label: string }> = { open: { color: "text-[#75aafc] border-[rgba(117,170,252,0.4)]", label: "OPEN" }, in_progress: { color: "text-yellow-400 border-yellow-800", label: "IN PROGRESS" }, + under_review: { color: "text-amber-400 border-amber-800", label: "REVIEW" }, done: { color: "text-emerald-400 border-emerald-800", label: "DONE" }, archived: { color: "text-[#556677] border-[#2a3a5a]", label: "ARCHIVED" }, }; @@ -35,7 +36,7 @@ interface OrderListProps { onTypeFilter: (t: OrderType | undefined) => void; } -const STATUS_OPTIONS: (OrderStatus | "all")[] = ["all", "open", "in_progress", "done", "archived"]; +const STATUS_OPTIONS: (OrderStatus | "all")[] = ["all", "open", "in_progress", "under_review", "done", "archived"]; const TYPE_OPTIONS: (OrderType | "all")[] = ["all", "feature", "bug", "spike", "chore", "improvement"]; export function OrderList({ @@ -105,7 +106,7 @@ export function OrderList({ : "text-[#556677] hover:text-[#7788aa] border border-transparent" }`} > - {s === "all" ? "ALL" : s === "in_progress" ? "WIP" : s.toUpperCase()} + {s === "all" ? "ALL" : s === "in_progress" ? "WIP" : s === "under_review" ? "REVIEW" : s.toUpperCase()} </button> ))} </div> |
