diff options
Diffstat (limited to 'makima/frontend/src/components/mesh/TaskOutput.tsx')
| -rw-r--r-- | makima/frontend/src/components/mesh/TaskOutput.tsx | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/makima/frontend/src/components/mesh/TaskOutput.tsx b/makima/frontend/src/components/mesh/TaskOutput.tsx index d53429d..7140c8a 100644 --- a/makima/frontend/src/components/mesh/TaskOutput.tsx +++ b/makima/frontend/src/components/mesh/TaskOutput.tsx @@ -2,6 +2,11 @@ import { useRef, useEffect, useState, useCallback } from "react"; import { SimpleMarkdown } from "../SimpleMarkdown"; import type { TaskOutputEvent } from "../../hooks/useTaskSubscription"; import { sendTaskMessage } from "../../lib/api"; +import { + PhaseConfirmationInline, + type PhaseConfirmationData, +} from "../contracts/PhaseConfirmationModal"; +import type { ContractPhase } from "../../lib/api"; interface TaskOutputProps { /** Array of parsed output events from the backend */ @@ -312,6 +317,15 @@ function OutputEntryRenderer({ entry, pendingQuestionIds, onAnswerQuestion }: Ou /> ); + case "phase_confirmation": + return ( + <PhaseConfirmationEntry + entry={entry} + pendingQuestionIds={pendingQuestionIds} + onAnswerQuestion={onAnswerQuestion} + /> + ); + default: return null; } @@ -520,3 +534,55 @@ function AuthRequiredEntry({ entry }: { entry: TaskOutputEvent }) { </div> ); } + +/** Entry for phase transition confirmations */ +function PhaseConfirmationEntry({ + entry, + pendingQuestionIds, + onAnswerQuestion, +}: { + entry: TaskOutputEvent; + pendingQuestionIds?: Set<string>; + onAnswerQuestion?: (questionId: string, response: string) => Promise<void>; +}) { + const questionId = entry.toolInput?.question_id as string; + const currentPhase = entry.toolInput?.current_phase as ContractPhase; + const nextPhase = entry.toolInput?.next_phase as ContractPhase; + const contractId = entry.toolInput?.contract_id as string; + const contractName = entry.toolInput?.contract_name as string | undefined; + const summary = entry.toolInput?.summary as string | undefined; + const deliverables = entry.toolInput?.deliverables as + | Array<{ name: string; completed: boolean }> + | undefined; + + const isPending = pendingQuestionIds?.has(questionId) ?? false; + + const data: PhaseConfirmationData = { + questionId, + contractId, + contractName, + currentPhase, + nextPhase, + summary, + deliverables, + }; + + const handleApprove = async (qId: string) => { + if (!onAnswerQuestion) return; + await onAnswerQuestion(qId, "APPROVE"); + }; + + const handleRequestChanges = async (qId: string, feedback: string) => { + if (!onAnswerQuestion) return; + await onAnswerQuestion(qId, `CHANGES_REQUESTED: ${feedback}`); + }; + + return ( + <PhaseConfirmationInline + data={data} + isPending={isPending} + onApprove={handleApprove} + onRequestChanges={handleRequestChanges} + /> + ); +} |
