forked from farhoodlabs/paperclip
adca44849a
Add live ActiveAgentsPanel with real-time transcript feed, SidebarContext for responsive sidebar state, agent config form with reasoning effort, improved inbox with failed run alerts, enriched issue detail with project picker, and various component refinements across pages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import { useCallback, useEffect, useRef } from "react";
|
|
import { Outlet } from "react-router-dom";
|
|
import { Sidebar } from "./Sidebar";
|
|
import { BreadcrumbBar } from "./BreadcrumbBar";
|
|
import { PropertiesPanel } from "./PropertiesPanel";
|
|
import { CommandPalette } from "./CommandPalette";
|
|
import { NewIssueDialog } from "./NewIssueDialog";
|
|
import { NewProjectDialog } from "./NewProjectDialog";
|
|
import { NewAgentDialog } from "./NewAgentDialog";
|
|
import { OnboardingWizard } from "./OnboardingWizard";
|
|
import { useDialog } from "../context/DialogContext";
|
|
import { usePanel } from "../context/PanelContext";
|
|
import { useCompany } from "../context/CompanyContext";
|
|
import { useSidebar } from "../context/SidebarContext";
|
|
import { useKeyboardShortcuts } from "../hooks/useKeyboardShortcuts";
|
|
import { cn } from "../lib/utils";
|
|
|
|
export function Layout() {
|
|
const { sidebarOpen, setSidebarOpen, toggleSidebar, isMobile } = useSidebar();
|
|
const { openNewIssue, openOnboarding } = useDialog();
|
|
const { panelContent, closePanel } = usePanel();
|
|
const { companies, loading: companiesLoading } = useCompany();
|
|
const onboardingTriggered = useRef(false);
|
|
|
|
useEffect(() => {
|
|
if (companiesLoading || onboardingTriggered.current) return;
|
|
if (companies.length === 0) {
|
|
onboardingTriggered.current = true;
|
|
openOnboarding();
|
|
}
|
|
}, [companies, companiesLoading, openOnboarding]);
|
|
|
|
const togglePanel = useCallback(() => {
|
|
if (panelContent) closePanel();
|
|
}, [panelContent, closePanel]);
|
|
|
|
useKeyboardShortcuts({
|
|
onNewIssue: () => openNewIssue(),
|
|
onToggleSidebar: toggleSidebar,
|
|
onTogglePanel: togglePanel,
|
|
});
|
|
|
|
return (
|
|
<div className="flex h-screen bg-background text-foreground overflow-hidden">
|
|
{/* Mobile backdrop */}
|
|
{isMobile && sidebarOpen && (
|
|
<div
|
|
className="fixed inset-0 z-40 bg-black/50"
|
|
onClick={() => setSidebarOpen(false)}
|
|
/>
|
|
)}
|
|
|
|
{/* Sidebar */}
|
|
{isMobile ? (
|
|
<div
|
|
className={cn(
|
|
"fixed inset-y-0 left-0 z-50 w-60 transition-transform duration-200 ease-in-out",
|
|
sidebarOpen ? "translate-x-0" : "-translate-x-full"
|
|
)}
|
|
>
|
|
<Sidebar />
|
|
</div>
|
|
) : (
|
|
<div
|
|
className={cn(
|
|
"shrink-0 h-full overflow-hidden transition-all duration-200 ease-in-out",
|
|
sidebarOpen ? "w-60" : "w-0"
|
|
)}
|
|
>
|
|
<Sidebar />
|
|
</div>
|
|
)}
|
|
|
|
{/* Main content */}
|
|
<div className="flex-1 flex flex-col min-w-0 h-full">
|
|
<BreadcrumbBar />
|
|
<div className="flex flex-1 min-h-0">
|
|
<main className="flex-1 overflow-auto p-4 md:p-6">
|
|
<Outlet />
|
|
</main>
|
|
<PropertiesPanel />
|
|
</div>
|
|
</div>
|
|
<CommandPalette />
|
|
<NewIssueDialog />
|
|
<NewProjectDialog />
|
|
<NewAgentDialog />
|
|
<OnboardingWizard />
|
|
</div>
|
|
);
|
|
}
|