summaryrefslogtreecommitdiff
path: root/makima/frontend/src/routes
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-16 17:59:38 +0000
committerGitHub <noreply@github.com>2026-02-16 17:59:38 +0000
commitb3de779d87450033f1e0361144c621a1d5f1dbf8 (patch)
tree7cb84c2f953bf86f1dd3ec8ff305d70810ac55de /makima/frontend/src/routes
parent7d2079d7c13804766405af8044574bfc93a86897 (diff)
downloadsoryu-b3de779d87450033f1e0361144c621a1d5f1dbf8.tar.gz
soryu-b3de779d87450033f1e0361144c621a1d5f1dbf8.zip
Fix contracts page overflow, remove contract link from orders, add directive name (#65)
* feat: soryu-co/soryu - makima: Add frontend pick-up-orders button and API integration * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Remove contract link from orders and add directive name to order metadata (frontend) * fix: contracts page overflow - use contained scrolling layout Changed the contracts page to use contained scrolling matching the orders/directives pages, preventing the page from growing beyond viewport height. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: resolve completion_task_id FK violation and duplicate button The completion_task_id column has an FK to tasks(id), but claim_directive_for_completion was being called with a placeholder UUID that did not exist in the tasks table, causing FK constraint violations. Fix: Create the task FIRST via create_task_for_owner, then use the real task.id when calling claim_directive_for_completion. Applied in all three locations: phase_completion Part 1 (idle directives), Part 3 (verification tasks), and trigger_completion_task (manual PR creation). Also removes a duplicate "Pick Up Orders" button in DirectiveDetail.tsx. * fix: restore Order type changes lost during rebase conflict resolution Re-apply changes from the orders-refactor commit that were dropped when resolving rebase conflicts with --ours: - Replace contractId with directiveName in Order interface - Make directiveId required in CreateOrderRequest - Remove contractId from UpdateOrderRequest - Change listOrders parameter from contractId to search - Remove linkOrderToContract function - Simplify convertOrderToStep to single argument --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'makima/frontend/src/routes')
-rw-r--r--makima/frontend/src/routes/contracts.tsx23
-rw-r--r--makima/frontend/src/routes/orders.tsx34
2 files changed, 37 insertions, 20 deletions
diff --git a/makima/frontend/src/routes/contracts.tsx b/makima/frontend/src/routes/contracts.tsx
index acb6789..6d838ab 100644
--- a/makima/frontend/src/routes/contracts.tsx
+++ b/makima/frontend/src/routes/contracts.tsx
@@ -524,15 +524,9 @@ function ContractsPageContent() {
return (
<div className="relative z-10 min-h-screen flex flex-col bg-[#0a1628]">
<Masthead showNav />
- <main className="flex-1 flex flex-col p-4 pt-2 gap-4 overflow-hidden">
- {error && (
- <div className="p-3 bg-red-400/10 border border-red-400/30 text-red-400 font-mono text-sm">
- {error}
- </div>
- )}
-
- <div className="flex-1 grid grid-cols-[350px_1fr] gap-4 min-h-0">
- {/* Contract list */}
+ <main className="flex-1 flex overflow-hidden" style={{ height: "calc(100vh - 80px)" }}>
+ {/* Left: Contract list */}
+ <div className="w-[350px] shrink-0 border-r border-dashed border-[rgba(117,170,252,0.2)] overflow-hidden flex flex-col">
<ContractList
contracts={contracts}
loading={loading}
@@ -545,8 +539,18 @@ function ContractsPageContent() {
onDelete={handleContextDelete}
onGoToSupervisor={handleContextGoToSupervisor}
/>
+ </div>
+
+ {/* Right: Detail or Create */}
+ <div className="flex-1 overflow-hidden flex flex-col">
+ {error && (
+ <div className="p-3 bg-red-400/10 border border-red-400/30 text-red-400 font-mono text-sm">
+ {error}
+ </div>
+ )}
{/* Contract detail, creation form, or empty state */}
+ <div className="flex-1 min-h-0 overflow-hidden">
{isCreating ? (
<div className="p-4 max-w-lg overflow-y-auto h-full bg-[#0a1628]">
<h3 className="font-mono text-[10px] text-[#9bc3ff] uppercase tracking-wide mb-4">
@@ -873,6 +877,7 @@ function ContractsPageContent() {
</div>
</div>
)}
+ </div>
</div>
</main>
</div>
diff --git a/makima/frontend/src/routes/orders.tsx b/makima/frontend/src/routes/orders.tsx
index 735c557..deca77f 100644
--- a/makima/frontend/src/routes/orders.tsx
+++ b/makima/frontend/src/routes/orders.tsx
@@ -16,7 +16,7 @@ export default function OrdersPage() {
const [statusFilter, setStatusFilter] = useState<OrderStatus | undefined>(undefined);
const [typeFilter, setTypeFilter] = useState<OrderType | undefined>(undefined);
const { orders, loading: listLoading, create, refresh: refreshList } = useOrders(statusFilter, typeFilter);
- const { order, refresh: refreshDetail, update, remove: removeOrder, linkDirective, linkContract, convertToStep } = useOrder(selectedId);
+ const { order, refresh: refreshDetail, update, remove: removeOrder, linkDirective, convertToStep } = useOrder(selectedId);
const { directives } = useDirectives();
const [showCreate, setShowCreate] = useState(false);
@@ -24,6 +24,7 @@ export default function OrdersPage() {
const [newDesc, setNewDesc] = useState("");
const [newPriority, setNewPriority] = useState<OrderPriority>("medium");
const [newType, setNewType] = useState<OrderType>("feature");
+ const [newDirectiveId, setNewDirectiveId] = useState<string>("");
useEffect(() => {
if (!authLoading && isAuthConfigured && !isAuthenticated) {
@@ -43,19 +44,21 @@ export default function OrdersPage() {
}
const handleCreate = async () => {
- if (!newTitle.trim()) return;
+ if (!newTitle.trim() || !newDirectiveId) return;
try {
const o = await create({
title: newTitle.trim(),
description: newDesc.trim() || undefined,
priority: newPriority,
orderType: newType,
+ directiveId: newDirectiveId,
});
setShowCreate(false);
setNewTitle("");
setNewDesc("");
setNewPriority("medium");
setNewType("feature");
+ setNewDirectiveId("");
navigate(`/orders/${o.id}`);
} catch (e) {
console.error("Failed to create order:", e);
@@ -84,13 +87,8 @@ export default function OrdersPage() {
await refreshList();
};
- const handleLinkContract = async (contractId: string) => {
- await linkContract(contractId);
- await refreshList();
- };
-
- const handleConvertToStep = async (directiveId: string) => {
- await convertToStep(directiveId);
+ const handleConvertToStep = async () => {
+ await convertToStep();
await refreshList();
};
@@ -162,6 +160,21 @@ export default function OrdersPage() {
className="w-full bg-[#0a1628] border border-[rgba(117,170,252,0.2)] rounded px-2 py-1.5 text-[12px] font-mono text-white resize-y"
/>
</div>
+ <div>
+ <label className="text-[10px] font-mono text-[#9bc3ff] uppercase tracking-wide block mb-1">
+ Directive *
+ </label>
+ <select
+ value={newDirectiveId}
+ onChange={(e) => setNewDirectiveId(e.target.value)}
+ className="w-full bg-[#0a1628] border border-[rgba(117,170,252,0.2)] rounded px-2 py-1.5 text-[12px] font-mono text-white"
+ >
+ <option value="">Select directive...</option>
+ {directives.map((d) => (
+ <option key={d.id} value={d.id}>{d.title}</option>
+ ))}
+ </select>
+ </div>
<div className="flex gap-4">
<div className="flex-1">
<label className="text-[10px] font-mono text-[#9bc3ff] uppercase tracking-wide block mb-1">
@@ -196,7 +209,7 @@ export default function OrdersPage() {
<button
type="button"
onClick={handleCreate}
- disabled={!newTitle.trim()}
+ disabled={!newTitle.trim() || !newDirectiveId}
className="text-[11px] font-mono text-emerald-400 hover:text-emerald-300 border border-emerald-800 rounded px-3 py-1 disabled:opacity-50"
>
Create
@@ -218,7 +231,6 @@ export default function OrdersPage() {
onUpdate={handleUpdate}
onDelete={handleDelete}
onLinkDirective={handleLinkDirective}
- onLinkContract={handleLinkContract}
onConvertToStep={handleConvertToStep}
onRefresh={refreshDetail}
/>