Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 88 additions & 6 deletions apps/code/src/renderer/components/permissions/PlanContent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Box } from "@radix-ui/themes";
import { useEffect, useRef } from "react";
import { ArrowsIn, ArrowsOut, ListChecks, X } from "@phosphor-icons/react";
import { Box, Flex, IconButton, Text } from "@radix-ui/themes";
import { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

Expand All @@ -12,6 +14,7 @@ interface PlanContentProps {

export function PlanContent({ id, plan }: PlanContentProps) {
const scrollRef = useRef<HTMLDivElement>(null);
const [isFullscreen, setIsFullscreen] = useState(false);

useEffect(() => {
const el = scrollRef.current;
Expand All @@ -33,14 +36,93 @@ export function PlanContent({ id, plan }: PlanContentProps) {
};
}, [id]);
Comment thread
charlesvien marked this conversation as resolved.

useEffect(() => {
if (!isFullscreen) return;
const handler = (e: KeyboardEvent) => {
if (e.key === "Escape") {
setIsFullscreen(false);
}
};
window.addEventListener("keydown", handler);
return () => window.removeEventListener("keydown", handler);
}, [isFullscreen]);

const markdown = (
<ReactMarkdown remarkPlugins={[remarkGfm]}>{plan}</ReactMarkdown>
);

if (isFullscreen) {
const portalTarget = document.getElementById("fullscreen-portal");
if (portalTarget) {
return (
<>
<Flex justify="end" className="py-0.5">
<IconButton
size="1"
variant="ghost"
color="gray"
onClick={() => setIsFullscreen(false)}
title="Exit fullscreen"
>
<ArrowsIn size={12} />
</IconButton>
</Flex>

{createPortal(
<Box className="pointer-events-auto absolute inset-0 flex flex-col bg-gray-1">
<Flex
align="center"
justify="between"
className="border-gray-6 border-b px-4 py-2"
>
<Flex align="center" gap="2">
<ListChecks size={14} className="text-gray-11" />
<Text size="2" className="text-gray-11">
Plan
</Text>
</Flex>
<IconButton
size="1"
variant="ghost"
color="gray"
onClick={() => setIsFullscreen(false)}
title="Exit fullscreen (Escape)"
>
<X size={14} />
</IconButton>
</Flex>

<Box
ref={scrollRef}
className="plan-markdown flex-1 overflow-y-auto p-6"
>
{markdown}
</Box>
</Box>,
portalTarget,
)}
</>
);
}
}

return (
<Box
ref={scrollRef}
className="max-h-[50vh] max-w-[750px] overflow-y-auto rounded-lg border-2 border-blue-6 bg-blue-2 p-4"
className="relative max-h-[50vh] max-w-[750px] overflow-y-auto rounded-lg border-2 border-blue-6 bg-blue-2 p-4"
>
<Box className="plan-markdown text-blue-12">
<ReactMarkdown remarkPlugins={[remarkGfm]}>{plan}</ReactMarkdown>
</Box>
<IconButton
size="1"
variant="ghost"
color="gray"
className="sticky top-0 z-10 float-right"
onClick={() => setIsFullscreen(true)}
title="Expand to fullscreen"
>
<ArrowsOut size={12} />
</IconButton>

<Box className="plan-markdown text-blue-12">{markdown}</Box>
</Box>
);
}
81 changes: 41 additions & 40 deletions apps/code/src/renderer/features/mcp-apps/components/McpAppHost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,50 +198,51 @@ export function McpAppHost({
</Flex>
);

const portalTarget = document.getElementById("mcp-fullscreen-portal");
if (displayMode === "fullscreen") {
const portalTarget = document.getElementById("fullscreen-portal");
if (portalTarget) {
return (
<>
{fullscreenToggle}

if (displayMode === "fullscreen" && portalTarget) {
return (
<>
{fullscreenToggle}

{createPortal(
<Box
className="pointer-events-auto absolute inset-0 flex flex-col bg-gray-1"
style={{
transition: "opacity 150ms ease",
}}
>
<Flex
align="center"
justify="between"
className="border-gray-6 border-b px-4 py-2"
{createPortal(
<Box
className="pointer-events-auto absolute inset-0 flex flex-col bg-gray-1"
style={{
transition: "opacity 150ms ease",
}}
>
<Flex align="center" gap="2">
<Plugs size={14} className="text-gray-11" />
<Text size="2" className="text-gray-11">
{serverName} - {toolName}
</Text>
</Flex>
<IconButton
size="1"
variant="ghost"
color="gray"
onClick={() => {
setDisplayMode("inline");
}}
title="Exit fullscreen (Escape)"
<Flex
align="center"
justify="between"
className="border-gray-6 border-b px-4 py-2"
>
<X size={14} />
</IconButton>
</Flex>
<Flex align="center" gap="2">
<Plugs size={14} className="text-gray-11" />
<Text size="2" className="text-gray-11">
{serverName} - {toolName}
</Text>
</Flex>
<IconButton
size="1"
variant="ghost"
color="gray"
onClick={() => {
setDisplayMode("inline");
}}
title="Exit fullscreen (Escape)"
>
<X size={14} />
</IconButton>
</Flex>

<Box className="flex-1 overflow-hidden p-4">{iframeElement}</Box>
</Box>,
portalTarget,
)}
</>
);
<Box className="flex-1 overflow-hidden p-4">{iframeElement}</Box>
</Box>,
portalTarget,
)}
</>
);
}
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export function ConversationView({
return (
<div className="relative flex-1">
<div
id="mcp-fullscreen-portal"
id="fullscreen-portal"
className="pointer-events-none absolute inset-0 z-20"
/>

Expand Down
Loading