import React, { useCallback } from "react"; import { Button } from "@/src/components/ui/button"; import { Play, Loader2 } from "lucide-react"; import { ResetPlaygroundButton } from "@/src/features/playground/page/components/ResetPlaygroundButton"; import { useWindowCoordination } from "@/src/features/playground/page/hooks/useWindowCoordination"; import { usePersistedWindowIds } from "@/src/features/playground/page/hooks/usePersistedWindowIds"; import useCommandEnter from "@/src/features/playground/page/hooks/useCommandEnter"; import { type MultiWindowState } from "@/src/features/playground/page/types"; import Page from "@/src/components/layouts/page"; import MultiWindowPlayground from "@/src/features/playground/page/components/MultiWindowPlayground"; import { NoModelConfiguredAlert } from "@/src/features/playground/page/components/NoModelConfiguredAlert"; import useProjectIdFromURL from "@/src/hooks/useProjectIdFromURL"; /** * PlaygroundPage Component * * Main playground page that provides the multi-window playground experience * for prompt testing and comparison. Manages window state at the page level * to enable header controls integration. * * Key Features: * - Multi-window playground for side-by-side comparison * - Integrated header controls for window management * - Global execution controls (Run All, Stop All) * - Window count display and management * - Reset playground functionality for starting fresh * - Persistent window IDs across page refreshes * * Architecture: * - Page-level window state management * - Header integration with multi-window controls * - Global coordination through useWindowCoordination hook * - Clean single-header design */ export default function PlaygroundPage() { const projectId = useProjectIdFromURL(); const { windowIds, isLoaded, addWindowWithCopy, removeWindowId } = usePersistedWindowIds(); // Global coordination hook for managing window actions const { executeAllWindows, getExecutionStatus, isExecutingAll: globalIsExecutingAll, hasAnyModelConfigured, } = useWindowCoordination(); /** * Add a new window to the playground * @param sourceWindowId - Optional source window ID to copy state from. If not provided, copies from the most recent window. */ const addWindow = useCallback( (sourceWindowId?: string) => { const newWindowId = addWindowWithCopy(sourceWindowId); if (newWindowId) { console.log(`Added new window: ${newWindowId}`); } else { console.warn("Failed to add new window"); } }, [addWindowWithCopy], ); /** * Remove a window from the playground */ const removeWindow = useCallback( (windowId: string) => { removeWindowId(windowId); }, [removeWindowId], ); /** * Handle global execution of all windows */ const handleExecuteAll = useCallback(() => { executeAllWindows(); }, [executeAllWindows]); // Handle command+enter for "Run All" button useCommandEnter(!globalIsExecutingAll, async () => { executeAllWindows(); }); // Don't render until window IDs are loaded if (!isLoaded) { return (
); } // Execution status and control states const executionStatus = globalIsExecutingAll ? getExecutionStatus() || `Executing ${windowIds.length} window${windowIds.length === 1 ? "" : "s"}` : getExecutionStatus(); const isRunAllDisabled = globalIsExecutingAll || !hasAnyModelConfigured; const windowState: MultiWindowState = { windowIds, isExecutingAll: globalIsExecutingAll, }; return ( {/* Window Count Display - Hidden on mobile */}
{windowIds.length} window {windowIds.length === 1 ? "" : "s"} {executionStatus && ( <>
{executionStatus}
)}
{/* Multi-Window Controls - Hidden on mobile */} {/* Reset Playground Button */} ), }} >
{!hasAnyModelConfigured && projectId && ( )}
); }