diff options
Diffstat (limited to 'makima/frontend/src')
| -rw-r--r-- | makima/frontend/src/components/directives/DirectiveDetail.tsx | 16 | ||||
| -rw-r--r-- | makima/frontend/src/hooks/useDirectives.ts | 8 | ||||
| -rw-r--r-- | makima/frontend/src/lib/api.ts | 6 | ||||
| -rw-r--r-- | makima/frontend/src/routes/directives.tsx | 3 |
4 files changed, 32 insertions, 1 deletions
diff --git a/makima/frontend/src/components/directives/DirectiveDetail.tsx b/makima/frontend/src/components/directives/DirectiveDetail.tsx index 9305e20..c8da7a0 100644 --- a/makima/frontend/src/components/directives/DirectiveDetail.tsx +++ b/makima/frontend/src/components/directives/DirectiveDetail.tsx @@ -27,6 +27,7 @@ interface DirectiveDetailProps { onRefresh: () => void; onCleanupTasks: () => void; onPickUpOrders: () => Promise<{ message: string; orderCount: number; taskId: string | null } | null>; + onCreatePR: () => Promise<void>; } export function DirectiveDetail({ @@ -43,12 +44,14 @@ export function DirectiveDetail({ onRefresh, onCleanupTasks, onPickUpOrders, + onCreatePR, }: DirectiveDetailProps) { const [editingGoal, setEditingGoal] = useState(false); const [goalText, setGoalText] = useState(directive.goal); const [visibleTaskIds, setVisibleTaskIds] = useState<Set<string> | null>(null); const [pickingUpOrders, setPickingUpOrders] = useState(false); const [pickUpResult, setPickUpResult] = useState<string | null>(null); + const [creatingPR, setCreatingPR] = useState(false); // Sync goalText and reset editing state when directive changes useEffect(() => { @@ -333,6 +336,19 @@ export function DirectiveDetail({ Clean up tasks </button> )} + {completedSteps > 0 && !directive.completionTaskId && ( + <button + type="button" + onClick={async () => { + setCreatingPR(true); + try { await onCreatePR(); } catch (e) { console.error("Failed to create PR:", e); } finally { setCreatingPR(false); } + }} + disabled={creatingPR} + className="text-[10px] font-mono text-emerald-400 hover:text-emerald-300 border border-emerald-800 rounded px-2 py-1 disabled:opacity-50" + > + {creatingPR ? "Creating..." : directive.prUrl ? "Update PR" : "Create PR"} + </button> + )} <button type="button" onClick={handlePickUpOrders} diff --git a/makima/frontend/src/hooks/useDirectives.ts b/makima/frontend/src/hooks/useDirectives.ts index 7e26ec4..18544da 100644 --- a/makima/frontend/src/hooks/useDirectives.ts +++ b/makima/frontend/src/hooks/useDirectives.ts @@ -21,6 +21,7 @@ import { updateDirectiveGoal, cleanupDirectiveTasks, pickUpOrders as pickUpOrdersApi, + createDirectivePR, } from "../lib/api"; export function useDirectives() { @@ -185,6 +186,12 @@ export function useDirective(id: string | undefined) { return result; }, [id, refresh]); + const createPR = useCallback(async () => { + if (!id) return; + await createDirectivePR(id); + await refresh(); + }, [id, refresh]); + return { directive, loading, error, refresh, update, addStep, removeStep, @@ -192,5 +199,6 @@ export function useDirective(id: string | undefined) { completeStep, failStep, skipStep, updateGoal, cleanupTasks, pickUpOrders: pickUpOrdersFn, + createPR, }; } diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts index 467ee22..a496412 100644 --- a/makima/frontend/src/lib/api.ts +++ b/makima/frontend/src/lib/api.ts @@ -3262,6 +3262,12 @@ export interface PickUpOrdersResponse { taskId: string | null; } +export async function createDirectivePR(id: string): Promise<DirectiveWithSteps> { + const res = await authFetch(`${API_BASE}/api/v1/directives/${id}/create-pr`, { method: "POST" }); + if (!res.ok) throw new Error(`Failed to create PR: ${res.statusText}`); + return res.json(); +} + export async function pickUpOrders(directiveId: string): Promise<PickUpOrdersResponse> { const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/pick-up-orders`, { method: "POST", diff --git a/makima/frontend/src/routes/directives.tsx b/makima/frontend/src/routes/directives.tsx index b4ed0cc..2bb673c 100644 --- a/makima/frontend/src/routes/directives.tsx +++ b/makima/frontend/src/routes/directives.tsx @@ -12,7 +12,7 @@ export default function DirectivesPage() { const navigate = useNavigate(); const { id: selectedId } = useParams<{ id: string }>(); const { directives, loading: listLoading, create, remove } = useDirectives(); - const { directive, refresh: refreshDetail, update, start, pause, advance, completeStep, failStep, skipStep, updateGoal, cleanupTasks, pickUpOrders } = useDirective(selectedId); + const { directive, refresh: refreshDetail, update, start, pause, advance, completeStep, failStep, skipStep, updateGoal, cleanupTasks, pickUpOrders, createPR } = useDirective(selectedId); const [showCreate, setShowCreate] = useState(false); const [newTitle, setNewTitle] = useState(""); @@ -212,6 +212,7 @@ export default function DirectivesPage() { onRefresh={refreshDetail} onCleanupTasks={cleanupTasks} onPickUpOrders={pickUpOrders} + onCreatePR={createPR} /> ) : ( <div className="flex-1 flex items-center justify-center h-full"> |
