import { History, Moon, Sun } from "lucide-react" import { useMemo, useState } from "react" import { CanvasStage } from "@/components/canvas/canvas-stage" import { CompareDialog } from "@/components/canvas/compare-dialog" import { VersionStrip } from "@/components/canvas/version-strip" import { VersionsProvider } from "@/components/canvas/versions-context" import { AppToaster } from "@/components/workspace/app-toaster" import { useDictionary } from "@/hooks/use-dictionary" import type { DrawioSource } from "@/lib/drawio/drawio-config" import { cn } from "@/lib/utils" import { useSettingsStore } from "@/stores/settings-store" import { useNodeVersions } from "./node-versions-source" import type { ShellConfig } from "./runtime-config" import { setDark } from "./theme" import { useMcpSync } from "./use-mcp-sync" import { VersionsPanel } from "./versions-panel" const iconButton = "inline-flex size-8 shrink-0 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-accent hover:text-foreground [&_svg]:size-4" /** * The MCP preview: the web app's canvas without the chat. A slim bar names * the session and the sync state; the versions strip, the version cards * (from the server's History) and Compare come from the shared canvas * components. */ export function CanvasShell({ config }: { config: ShellConfig }) { const dict = useDictionary() const isDark = useSettingsStore((s) => s.isDark) const { status, sync } = useMcpSync(config) const versions = useNodeVersions(sync) const [panelOpen, setPanelOpen] = useState(true) const drawioSource = useMemo( () => ({ editorUrl: config.drawioBaseUrl, ui: config.drawioUi || undefined, lang: config.drawioLang || undefined, }), [config], ) const hasVersions = versions.versions.length > 0 const showPanel = panelOpen && hasVersions return (
Next AI Draw.io {config.sessionId && ( {config.sessionId.slice(-8)} )} {dict.shell[status]} {hasVersions && ( )}
{/* With the cards open, one version alone adds nothing to its card */}
{showPanel && ( )}
) }