rowboat/apps/rowboat/app/projects/[projectId]/playground/app.tsx

121 lines
4.8 KiB
TypeScript
Raw Normal View History

2025-01-13 15:31:31 +05:30
'use client';
import { useState, useCallback, useRef } from "react";
2025-01-13 15:31:31 +05:30
import { z } from "zod";
import { Message } from "@/app/lib/types/types";
import { Workflow } from "@/app/lib/types/workflow_types";
2025-03-27 18:52:17 +05:30
import { Chat } from "./components/chat";
import { Panel } from "@/components/common/panel-common";
import { Button } from "@/components/ui/button";
2025-04-14 14:29:50 +05:30
import { Tooltip } from "@heroui/react";
import { CheckIcon, CopyIcon, PlusIcon, InfoIcon, BugIcon, BugOffIcon, MessageCircle } from "lucide-react";
2025-01-13 15:31:31 +05:30
export function App({
hidden = false,
projectId,
workflow,
messageSubscriber,
2025-04-14 14:29:50 +05:30
onPanelClick,
2025-07-13 16:45:14 +05:30
triggerCopilotChat,
isLiveWorkflow,
2025-01-13 15:31:31 +05:30
}: {
hidden?: boolean;
projectId: string;
workflow: z.infer<typeof Workflow>;
2025-06-23 08:38:26 +05:30
messageSubscriber?: (messages: z.infer<typeof Message>[]) => void;
2025-04-14 14:29:50 +05:30
onPanelClick?: () => void;
2025-07-13 16:45:14 +05:30
triggerCopilotChat?: (message: string) => void;
isLiveWorkflow: boolean;
2025-01-13 15:31:31 +05:30
}) {
const [counter, setCounter] = useState<number>(0);
2025-05-07 15:56:30 +05:30
const [showDebugMessages, setShowDebugMessages] = useState<boolean>(true);
2025-03-27 18:52:17 +05:30
const [showCopySuccess, setShowCopySuccess] = useState(false);
const getCopyContentRef = useRef<(() => string) | null>(null);
2025-01-13 15:31:31 +05:30
function handleNewChatButtonClick() {
setCounter(counter + 1);
2025-01-13 15:31:31 +05:30
}
const handleCopyJson = useCallback(() => {
if (getCopyContentRef.current) {
try {
const data = getCopyContentRef.current();
navigator.clipboard.writeText(data);
setShowCopySuccess(true);
setTimeout(() => {
setShowCopySuccess(false);
}, 2000);
} catch (error) {
console.error('Error copying:', error);
}
}
}, []);
2025-03-27 18:52:17 +05:30
return (
2025-03-27 18:52:17 +05:30
<>
<Panel
2025-07-23 11:58:50 +05:30
className={`${hidden ? 'hidden' : 'block'}`}
2025-04-14 14:29:50 +05:30
variant="playground"
tourTarget="playground"
icon={<MessageCircle className="w-5 h-5 text-blue-600 dark:text-blue-400" />}
title="Playground"
subtitle="Chat with your assistant"
rightActions={
<div className="flex items-center gap-2">
2025-03-27 18:52:17 +05:30
<Button
variant="primary"
size="sm"
onClick={handleNewChatButtonClick}
className="bg-blue-50 text-blue-700 hover:bg-blue-100"
showHoverContent={true}
hoverContent="New chat"
>
<PlusIcon className="w-4 h-4" />
</Button>
2025-05-07 15:56:30 +05:30
<Button
variant="primary"
size="sm"
onClick={() => setShowDebugMessages(!showDebugMessages)}
className={showDebugMessages ? "bg-blue-50 text-blue-700 hover:bg-blue-100" : "bg-gray-50 text-gray-500 hover:bg-gray-100"}
showHoverContent={true}
hoverContent={showDebugMessages ? "Hide debug messages" : "Show debug messages"}
>
{showDebugMessages ? (
<BugIcon className="w-4 h-4" />
) : (
<BugOffIcon className="w-4 h-4" />
)}
</Button>
2025-03-27 18:52:17 +05:30
<Button
variant="secondary"
size="sm"
onClick={handleCopyJson}
showHoverContent={true}
hoverContent={showCopySuccess ? "Copied" : "Copy JSON"}
>
{showCopySuccess ? (
<CheckIcon className="w-4 h-4" />
) : (
<CopyIcon className="w-4 h-4" />
)}
</Button>
</div>
}
2025-04-14 14:29:50 +05:30
onClick={onPanelClick}
2025-03-27 18:52:17 +05:30
>
<div className="h-full overflow-auto px-4 py-4">
<Chat
key={`chat-${counter}`}
2025-03-27 18:52:17 +05:30
projectId={projectId}
workflow={workflow}
messageSubscriber={messageSubscriber}
onCopyClick={(fn) => { getCopyContentRef.current = fn; }}
2025-05-07 15:56:30 +05:30
showDebugMessages={showDebugMessages}
2025-07-13 16:45:14 +05:30
triggerCopilotChat={triggerCopilotChat}
isLiveWorkflow={isLiveWorkflow}
2025-03-27 18:52:17 +05:30
/>
</div>
</Panel>
</>
);
2025-01-13 15:31:31 +05:30
}