From e28ad181066edece29f98aa717c01fc9f347e33a Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Fri, 6 Mar 2026 08:59:10 -0800 Subject: [PATCH] Inline pending approvals in composer header Co-authored-by: codex --- apps/web/src/components/ChatView.tsx | 150 ++++++++++++++------------- 1 file changed, 76 insertions(+), 74 deletions(-) diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx index f80a0553e3f02fcbc5c0501805b85b47fad69adc..1380a8b9d4b3175b46a9e6b9f5f44cef0a7118e8 100644 --- a/apps/web/src/components/ChatView.tsx +++ b/apps/web/src/components/ChatView.tsx @@ -122,7 +122,7 @@ import { } from "../keybindings"; import ChatMarkdown from "./ChatMarkdown"; import ThreadTerminalDrawer from "./ThreadTerminalDrawer"; -import { Alert, AlertAction, AlertDescription, AlertTitle } from "./ui/alert"; +import { Alert, AlertDescription, AlertTitle } from "./ui/alert"; import { BotIcon, ChevronDownIcon, @@ -134,7 +134,6 @@ import { DiffIcon, EllipsisIcon, FolderClosedIcon, - InfoIcon, LockIcon, LockOpenIcon, Undo2Icon, @@ -891,8 +890,11 @@ export default function ChatView({ threadId }: ChatViewProps) { interactionMode === "plan" && latestTurnSettled && activeProposedPlan !== null; + const activePendingApproval = pendingApprovals[0] ?? null; const hasComposerHeader = - pendingUserInputs.length > 0 || (showPlanFollowUpPrompt && activeProposedPlan !== null); + activePendingApproval !== null || + pendingUserInputs.length > 0 || + (showPlanFollowUpPrompt && activeProposedPlan !== null); useEffect(() => { if (!activePendingProgress) { return; @@ -3315,11 +3317,6 @@ export default function ChatView({ threadId }: ChatViewProps) { {/* Error banner */} - {/* Messages */} @@ -3379,7 +3376,16 @@ export default function ChatView({ threadId }: ChatViewProps) { onDragLeave={onComposerDragLeave} onDrop={onComposerDrop} > - {pendingUserInputs.length > 0 ? ( + {activePendingApproval ? ( +
+ +
+ ) : pendingUserInputs.length > 0 ? (
Promise; } -const PendingApprovalsPanel = memo(function PendingApprovalsPanel({ - pendingApprovals, - respondingRequestIds, +const ComposerPendingApprovalPanel = memo(function ComposerPendingApprovalPanel({ + approval, + pendingCount, + isResponding, onRespondToApproval, -}: PendingApprovalsPanelProps) { - if (pendingApprovals.length === 0) return null; - return ( -
- {pendingApprovals.map((approval) => { - const isResponding = respondingRequestIds.includes(approval.requestId); +}: ComposerPendingApprovalPanelProps) { + const approvalSummary = + approval.requestKind === "command" + ? "Command approval requested" + : approval.requestKind === "file-read" + ? "File-read approval requested" + : "File-change approval requested"; - return ( - - - - {approval.requestKind === "command" - ? "Command approval requested" - : approval.requestKind === "file-read" - ? "File-read approval requested" - : "File-change approval requested"} - - - {approval.detail} - - - - - - - - - ); - })} + return ( +
+
+ PENDING APPROVAL + {approvalSummary} + {pendingCount > 1 ? ( + 1/{pendingCount} + ) : null} +
+

+ {approval.detail} +

+
+ + + + +
); }); -- 2.54.0