2026-03-10 21:06:10 -05:00
|
|
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
2026-02-23 14:41:21 -06:00
|
|
|
import { useQuery } from "@tanstack/react-query";
|
2026-02-26 16:33:29 -06:00
|
|
|
import { BookOpen, Moon, Sun } from "lucide-react";
|
2026-03-02 16:44:03 -06:00
|
|
|
import { Outlet, useLocation, useNavigate, useParams } from "@/lib/router";
|
2026-02-23 14:41:21 -06:00
|
|
|
import { CompanyRail } from "./CompanyRail";
|
2026-02-16 13:32:04 -06:00
|
|
|
import { Sidebar } from "./Sidebar";
|
2026-02-23 14:41:21 -06:00
|
|
|
import { SidebarNavItem } from "./SidebarNavItem";
|
Add shared UI primitives, contexts, and reusable components
Add shadcn components: avatar, breadcrumb, checkbox, collapsible,
command, dialog, dropdown-menu, label, popover, scroll-area, sheet,
skeleton, tabs, textarea, tooltip. Add shared components: BreadcrumbBar,
CommandPalette, CompanySwitcher, CommentThread, EmptyState, EntityRow,
FilterBar, InlineEditor, MetricCard, PageSkeleton, PriorityIcon,
PropertiesPanel, StatusIcon, SidebarNavItem/Section. Add contexts for
breadcrumbs, dialogs, and side panels. Add keyboard shortcut hook and
utility helpers. Update layout, sidebar, and main app shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:00 -06:00
|
|
|
import { BreadcrumbBar } from "./BreadcrumbBar";
|
|
|
|
|
import { PropertiesPanel } from "./PropertiesPanel";
|
|
|
|
|
import { CommandPalette } from "./CommandPalette";
|
|
|
|
|
import { NewIssueDialog } from "./NewIssueDialog";
|
2026-02-17 10:53:20 -06:00
|
|
|
import { NewProjectDialog } from "./NewProjectDialog";
|
2026-02-20 13:12:39 -06:00
|
|
|
import { NewGoalDialog } from "./NewGoalDialog";
|
Build out agent management UI: detail page, create dialog, list view
Add NewAgentDialog for creating agents with adapter config. Expand
AgentDetail page with tabbed view (overview, runs, config, logs),
run history timeline, and live status. Enhance Agents list page with
richer cards and filtering. Update AgentProperties panel, API client,
query keys, and utility helpers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 12:33:04 -06:00
|
|
|
import { NewAgentDialog } from "./NewAgentDialog";
|
2026-02-20 13:47:13 -06:00
|
|
|
import { ToastViewport } from "./ToastViewport";
|
2026-02-23 16:08:24 -06:00
|
|
|
import { MobileBottomNav } from "./MobileBottomNav";
|
Add shared UI primitives, contexts, and reusable components
Add shadcn components: avatar, breadcrumb, checkbox, collapsible,
command, dialog, dropdown-menu, label, popover, scroll-area, sheet,
skeleton, tabs, textarea, tooltip. Add shared components: BreadcrumbBar,
CommandPalette, CompanySwitcher, CommentThread, EmptyState, EntityRow,
FilterBar, InlineEditor, MetricCard, PageSkeleton, PriorityIcon,
PropertiesPanel, StatusIcon, SidebarNavItem/Section. Add contexts for
breadcrumbs, dialogs, and side panels. Add keyboard shortcut hook and
utility helpers. Update layout, sidebar, and main app shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:00 -06:00
|
|
|
import { useDialog } from "../context/DialogContext";
|
|
|
|
|
import { usePanel } from "../context/PanelContext";
|
2026-02-17 13:24:33 -06:00
|
|
|
import { useCompany } from "../context/CompanyContext";
|
2026-02-20 10:32:32 -06:00
|
|
|
import { useSidebar } from "../context/SidebarContext";
|
2026-02-26 16:33:29 -06:00
|
|
|
import { useTheme } from "../context/ThemeContext";
|
Add shared UI primitives, contexts, and reusable components
Add shadcn components: avatar, breadcrumb, checkbox, collapsible,
command, dialog, dropdown-menu, label, popover, scroll-area, sheet,
skeleton, tabs, textarea, tooltip. Add shared components: BreadcrumbBar,
CommandPalette, CompanySwitcher, CommentThread, EmptyState, EntityRow,
FilterBar, InlineEditor, MetricCard, PageSkeleton, PriorityIcon,
PropertiesPanel, StatusIcon, SidebarNavItem/Section. Add contexts for
breadcrumbs, dialogs, and side panels. Add keyboard shortcut hook and
utility helpers. Update layout, sidebar, and main app shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:00 -06:00
|
|
|
import { useKeyboardShortcuts } from "../hooks/useKeyboardShortcuts";
|
2026-02-23 14:47:54 -06:00
|
|
|
import { useCompanyPageMemory } from "../hooks/useCompanyPageMemory";
|
2026-02-23 14:41:21 -06:00
|
|
|
import { healthApi } from "../api/health";
|
|
|
|
|
import { queryKeys } from "../lib/queryKeys";
|
Add shared UI primitives, contexts, and reusable components
Add shadcn components: avatar, breadcrumb, checkbox, collapsible,
command, dialog, dropdown-menu, label, popover, scroll-area, sheet,
skeleton, tabs, textarea, tooltip. Add shared components: BreadcrumbBar,
CommandPalette, CompanySwitcher, CommentThread, EmptyState, EntityRow,
FilterBar, InlineEditor, MetricCard, PageSkeleton, PriorityIcon,
PropertiesPanel, StatusIcon, SidebarNavItem/Section. Add contexts for
breadcrumbs, dialogs, and side panels. Add keyboard shortcut hook and
utility helpers. Update layout, sidebar, and main app shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:00 -06:00
|
|
|
import { cn } from "../lib/utils";
|
2026-03-10 16:38:46 -05:00
|
|
|
import { NotFoundPage } from "../pages/NotFound";
|
2026-02-26 16:33:29 -06:00
|
|
|
import { Button } from "@/components/ui/button";
|
2026-02-16 13:32:04 -06:00
|
|
|
|
|
|
|
|
export function Layout() {
|
2026-02-20 10:32:32 -06:00
|
|
|
const { sidebarOpen, setSidebarOpen, toggleSidebar, isMobile } = useSidebar();
|
2026-02-17 13:24:33 -06:00
|
|
|
const { openNewIssue, openOnboarding } = useDialog();
|
2026-03-03 12:07:01 -06:00
|
|
|
const { togglePanelVisible } = usePanel();
|
2026-03-10 16:38:46 -05:00
|
|
|
const {
|
|
|
|
|
companies,
|
|
|
|
|
loading: companiesLoading,
|
|
|
|
|
selectedCompany,
|
|
|
|
|
selectedCompanyId,
|
|
|
|
|
setSelectedCompanyId,
|
|
|
|
|
} = useCompany();
|
2026-02-26 16:33:29 -06:00
|
|
|
const { theme, toggleTheme } = useTheme();
|
2026-03-02 16:44:03 -06:00
|
|
|
const { companyPrefix } = useParams<{ companyPrefix: string }>();
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
const location = useLocation();
|
2026-02-17 13:24:33 -06:00
|
|
|
const onboardingTriggered = useRef(false);
|
2026-02-23 16:08:24 -06:00
|
|
|
const lastMainScrollTop = useRef(0);
|
|
|
|
|
const [mobileNavVisible, setMobileNavVisible] = useState(true);
|
2026-02-26 16:33:29 -06:00
|
|
|
const nextTheme = theme === "dark" ? "light" : "dark";
|
2026-03-10 16:38:46 -05:00
|
|
|
const matchedCompany = useMemo(() => {
|
|
|
|
|
if (!companyPrefix) return null;
|
|
|
|
|
const requestedPrefix = companyPrefix.toUpperCase();
|
|
|
|
|
return companies.find((company) => company.issuePrefix.toUpperCase() === requestedPrefix) ?? null;
|
|
|
|
|
}, [companies, companyPrefix]);
|
|
|
|
|
const hasUnknownCompanyPrefix =
|
|
|
|
|
Boolean(companyPrefix) && !companiesLoading && companies.length > 0 && !matchedCompany;
|
2026-02-23 14:41:21 -06:00
|
|
|
const { data: health } = useQuery({
|
|
|
|
|
queryKey: queryKeys.health,
|
|
|
|
|
queryFn: () => healthApi.get(),
|
|
|
|
|
retry: false,
|
|
|
|
|
});
|
2026-02-17 13:24:33 -06:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (companiesLoading || onboardingTriggered.current) return;
|
2026-02-23 14:41:21 -06:00
|
|
|
if (health?.deploymentMode === "authenticated") return;
|
2026-02-17 13:24:33 -06:00
|
|
|
if (companies.length === 0) {
|
|
|
|
|
onboardingTriggered.current = true;
|
|
|
|
|
openOnboarding();
|
|
|
|
|
}
|
2026-02-23 14:41:21 -06:00
|
|
|
}, [companies, companiesLoading, openOnboarding, health?.deploymentMode]);
|
Add shared UI primitives, contexts, and reusable components
Add shadcn components: avatar, breadcrumb, checkbox, collapsible,
command, dialog, dropdown-menu, label, popover, scroll-area, sheet,
skeleton, tabs, textarea, tooltip. Add shared components: BreadcrumbBar,
CommandPalette, CompanySwitcher, CommentThread, EmptyState, EntityRow,
FilterBar, InlineEditor, MetricCard, PageSkeleton, PriorityIcon,
PropertiesPanel, StatusIcon, SidebarNavItem/Section. Add contexts for
breadcrumbs, dialogs, and side panels. Add keyboard shortcut hook and
utility helpers. Update layout, sidebar, and main app shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:00 -06:00
|
|
|
|
2026-03-02 16:44:03 -06:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (!companyPrefix || companiesLoading || companies.length === 0) return;
|
|
|
|
|
|
2026-03-10 16:38:46 -05:00
|
|
|
if (!matchedCompany) {
|
|
|
|
|
const fallback = (selectedCompanyId ? companies.find((company) => company.id === selectedCompanyId) : null)
|
|
|
|
|
?? companies[0]
|
|
|
|
|
?? null;
|
|
|
|
|
if (fallback && selectedCompanyId !== fallback.id) {
|
|
|
|
|
setSelectedCompanyId(fallback.id, { source: "route_sync" });
|
|
|
|
|
}
|
2026-03-02 16:44:03 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-10 16:38:46 -05:00
|
|
|
if (companyPrefix !== matchedCompany.issuePrefix) {
|
2026-03-02 16:44:03 -06:00
|
|
|
const suffix = location.pathname.replace(/^\/[^/]+/, "");
|
2026-03-10 16:38:46 -05:00
|
|
|
navigate(`/${matchedCompany.issuePrefix}${suffix}${location.search}`, { replace: true });
|
2026-03-02 16:44:03 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-10 16:38:46 -05:00
|
|
|
if (selectedCompanyId !== matchedCompany.id) {
|
|
|
|
|
setSelectedCompanyId(matchedCompany.id, { source: "route_sync" });
|
2026-03-02 16:44:03 -06:00
|
|
|
}
|
|
|
|
|
}, [
|
|
|
|
|
companyPrefix,
|
|
|
|
|
companies,
|
|
|
|
|
companiesLoading,
|
2026-03-10 16:38:46 -05:00
|
|
|
matchedCompany,
|
2026-03-02 16:44:03 -06:00
|
|
|
location.pathname,
|
|
|
|
|
location.search,
|
|
|
|
|
navigate,
|
|
|
|
|
selectedCompanyId,
|
|
|
|
|
setSelectedCompanyId,
|
|
|
|
|
]);
|
|
|
|
|
|
2026-03-03 12:07:01 -06:00
|
|
|
const togglePanel = togglePanelVisible;
|
Add shared UI primitives, contexts, and reusable components
Add shadcn components: avatar, breadcrumb, checkbox, collapsible,
command, dialog, dropdown-menu, label, popover, scroll-area, sheet,
skeleton, tabs, textarea, tooltip. Add shared components: BreadcrumbBar,
CommandPalette, CompanySwitcher, CommentThread, EmptyState, EntityRow,
FilterBar, InlineEditor, MetricCard, PageSkeleton, PriorityIcon,
PropertiesPanel, StatusIcon, SidebarNavItem/Section. Add contexts for
breadcrumbs, dialogs, and side panels. Add keyboard shortcut hook and
utility helpers. Update layout, sidebar, and main app shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:00 -06:00
|
|
|
|
2026-02-23 14:47:54 -06:00
|
|
|
useCompanyPageMemory();
|
|
|
|
|
|
Add shared UI primitives, contexts, and reusable components
Add shadcn components: avatar, breadcrumb, checkbox, collapsible,
command, dialog, dropdown-menu, label, popover, scroll-area, sheet,
skeleton, tabs, textarea, tooltip. Add shared components: BreadcrumbBar,
CommandPalette, CompanySwitcher, CommentThread, EmptyState, EntityRow,
FilterBar, InlineEditor, MetricCard, PageSkeleton, PriorityIcon,
PropertiesPanel, StatusIcon, SidebarNavItem/Section. Add contexts for
breadcrumbs, dialogs, and side panels. Add keyboard shortcut hook and
utility helpers. Update layout, sidebar, and main app shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:00 -06:00
|
|
|
useKeyboardShortcuts({
|
|
|
|
|
onNewIssue: () => openNewIssue(),
|
|
|
|
|
onToggleSidebar: toggleSidebar,
|
|
|
|
|
onTogglePanel: togglePanel,
|
|
|
|
|
});
|
Overhaul UI with shadcn components and new pages
Add shadcn/ui components (badge, button, card, input, select,
separator). Add company context provider. New pages: Activity,
Approvals, Companies, Costs, Org chart. Restyle existing pages
(Dashboard, Agents, Issues, Goals, Projects) with shadcn components
and dark theme. Update layout, sidebar navigation, and routing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:32 -06:00
|
|
|
|
2026-02-23 16:08:24 -06:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (!isMobile) {
|
|
|
|
|
setMobileNavVisible(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
lastMainScrollTop.current = 0;
|
|
|
|
|
setMobileNavVisible(true);
|
|
|
|
|
}, [isMobile]);
|
|
|
|
|
|
2026-02-25 21:43:49 -06:00
|
|
|
// Swipe gesture to open/close sidebar on mobile
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!isMobile) return;
|
|
|
|
|
|
|
|
|
|
const EDGE_ZONE = 30; // px from left edge to start open-swipe
|
|
|
|
|
const MIN_DISTANCE = 50; // minimum horizontal swipe distance
|
|
|
|
|
const MAX_VERTICAL = 75; // max vertical drift before we ignore
|
|
|
|
|
|
|
|
|
|
let startX = 0;
|
|
|
|
|
let startY = 0;
|
|
|
|
|
|
|
|
|
|
const onTouchStart = (e: TouchEvent) => {
|
|
|
|
|
const t = e.touches[0]!;
|
|
|
|
|
startX = t.clientX;
|
|
|
|
|
startY = t.clientY;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onTouchEnd = (e: TouchEvent) => {
|
|
|
|
|
const t = e.changedTouches[0]!;
|
|
|
|
|
const dx = t.clientX - startX;
|
|
|
|
|
const dy = Math.abs(t.clientY - startY);
|
|
|
|
|
|
|
|
|
|
if (dy > MAX_VERTICAL) return; // vertical scroll, ignore
|
|
|
|
|
|
|
|
|
|
// Swipe right from left edge → open
|
|
|
|
|
if (!sidebarOpen && startX < EDGE_ZONE && dx > MIN_DISTANCE) {
|
|
|
|
|
setSidebarOpen(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Swipe left when open → close
|
|
|
|
|
if (sidebarOpen && dx < -MIN_DISTANCE) {
|
|
|
|
|
setSidebarOpen(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
|
|
|
document.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
document.removeEventListener("touchstart", onTouchStart);
|
|
|
|
|
document.removeEventListener("touchend", onTouchEnd);
|
|
|
|
|
};
|
|
|
|
|
}, [isMobile, sidebarOpen, setSidebarOpen]);
|
|
|
|
|
|
2026-03-10 21:06:10 -05:00
|
|
|
const updateMobileNavVisibility = useCallback((currentTop: number) => {
|
|
|
|
|
const delta = currentTop - lastMainScrollTop.current;
|
2026-02-23 16:08:24 -06:00
|
|
|
|
2026-03-10 21:06:10 -05:00
|
|
|
if (currentTop <= 24) {
|
|
|
|
|
setMobileNavVisible(true);
|
|
|
|
|
} else if (delta > 8) {
|
|
|
|
|
setMobileNavVisible(false);
|
|
|
|
|
} else if (delta < -8) {
|
|
|
|
|
setMobileNavVisible(true);
|
|
|
|
|
}
|
2026-02-23 16:08:24 -06:00
|
|
|
|
2026-03-10 21:06:10 -05:00
|
|
|
lastMainScrollTop.current = currentTop;
|
|
|
|
|
}, []);
|
2026-02-23 16:08:24 -06:00
|
|
|
|
2026-03-10 21:06:10 -05:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (!isMobile) {
|
|
|
|
|
setMobileNavVisible(true);
|
|
|
|
|
lastMainScrollTop.current = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onScroll = () => {
|
|
|
|
|
updateMobileNavVisibility(window.scrollY || document.documentElement.scrollTop || 0);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onScroll();
|
|
|
|
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
window.removeEventListener("scroll", onScroll);
|
|
|
|
|
};
|
|
|
|
|
}, [isMobile, updateMobileNavVisibility]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const previousOverflow = document.body.style.overflow;
|
|
|
|
|
|
|
|
|
|
document.body.style.overflow = isMobile ? "visible" : "hidden";
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
document.body.style.overflow = previousOverflow;
|
|
|
|
|
};
|
|
|
|
|
}, [isMobile]);
|
2026-02-23 16:08:24 -06:00
|
|
|
|
2026-02-16 13:32:04 -06:00
|
|
|
return (
|
2026-03-10 21:06:10 -05:00
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
"bg-background text-foreground pt-[env(safe-area-inset-top)]",
|
|
|
|
|
isMobile ? "min-h-dvh" : "flex h-dvh overflow-hidden",
|
|
|
|
|
)}
|
|
|
|
|
>
|
2026-03-02 16:44:03 -06:00
|
|
|
<a
|
|
|
|
|
href="#main-content"
|
|
|
|
|
className="sr-only focus:not-sr-only focus:fixed focus:left-3 focus:top-3 focus:z-[200] focus:rounded-md focus:bg-background focus:px-3 focus:py-2 focus:text-sm focus:font-medium focus:shadow-lg focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
|
|
|
>
|
|
|
|
|
Skip to Main Content
|
|
|
|
|
</a>
|
2026-02-20 10:32:32 -06:00
|
|
|
{/* Mobile backdrop */}
|
|
|
|
|
{isMobile && sidebarOpen && (
|
2026-03-02 16:44:03 -06:00
|
|
|
<button
|
|
|
|
|
type="button"
|
2026-02-20 10:32:32 -06:00
|
|
|
className="fixed inset-0 z-40 bg-black/50"
|
|
|
|
|
onClick={() => setSidebarOpen(false)}
|
2026-03-02 16:44:03 -06:00
|
|
|
aria-label="Close sidebar"
|
2026-02-20 10:32:32 -06:00
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
|
2026-02-23 14:41:21 -06:00
|
|
|
{/* Combined sidebar area: company rail + inner sidebar + docs bar */}
|
2026-02-20 10:32:32 -06:00
|
|
|
{isMobile ? (
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
2026-03-02 16:44:03 -06:00
|
|
|
"fixed inset-y-0 left-0 z-50 flex flex-col overflow-hidden pt-[env(safe-area-inset-top)] transition-transform duration-100 ease-out",
|
2026-02-20 10:32:32 -06:00
|
|
|
sidebarOpen ? "translate-x-0" : "-translate-x-full"
|
|
|
|
|
)}
|
|
|
|
|
>
|
2026-02-25 21:36:06 -06:00
|
|
|
<div className="flex flex-1 min-h-0 overflow-hidden">
|
|
|
|
|
<CompanyRail />
|
|
|
|
|
<Sidebar />
|
|
|
|
|
</div>
|
|
|
|
|
<div className="border-t border-r border-border px-3 py-2 bg-background">
|
2026-02-26 16:33:29 -06:00
|
|
|
<div className="flex items-center gap-1">
|
|
|
|
|
<SidebarNavItem
|
|
|
|
|
to="/docs"
|
|
|
|
|
label="Documentation"
|
|
|
|
|
icon={BookOpen}
|
|
|
|
|
className="flex-1 min-w-0"
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
type="button"
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon-sm"
|
|
|
|
|
className="text-muted-foreground shrink-0"
|
|
|
|
|
onClick={toggleTheme}
|
|
|
|
|
aria-label={`Switch to ${nextTheme} mode`}
|
|
|
|
|
title={`Switch to ${nextTheme} mode`}
|
|
|
|
|
>
|
|
|
|
|
{theme === "dark" ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
2026-02-23 14:41:21 -06:00
|
|
|
</div>
|
2026-02-20 10:32:32 -06:00
|
|
|
</div>
|
|
|
|
|
) : (
|
2026-02-23 14:41:21 -06:00
|
|
|
<div className="flex flex-col shrink-0 h-full">
|
|
|
|
|
<div className="flex flex-1 min-h-0">
|
|
|
|
|
<CompanyRail />
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
2026-03-02 16:44:03 -06:00
|
|
|
"overflow-hidden transition-[width] duration-100 ease-out",
|
2026-02-23 14:41:21 -06:00
|
|
|
sidebarOpen ? "w-60" : "w-0"
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
<Sidebar />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="border-t border-r border-border px-3 py-2">
|
2026-02-26 16:33:29 -06:00
|
|
|
<div className="flex items-center gap-1">
|
|
|
|
|
<SidebarNavItem
|
|
|
|
|
to="/docs"
|
|
|
|
|
label="Documentation"
|
|
|
|
|
icon={BookOpen}
|
|
|
|
|
className="flex-1 min-w-0"
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
type="button"
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon-sm"
|
|
|
|
|
className="text-muted-foreground shrink-0"
|
|
|
|
|
onClick={toggleTheme}
|
|
|
|
|
aria-label={`Switch to ${nextTheme} mode`}
|
|
|
|
|
title={`Switch to ${nextTheme} mode`}
|
|
|
|
|
>
|
|
|
|
|
{theme === "dark" ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
2026-02-23 14:41:21 -06:00
|
|
|
</div>
|
2026-02-20 10:32:32 -06:00
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* Main content */}
|
2026-03-10 21:06:10 -05:00
|
|
|
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "h-full flex-1")}>
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
isMobile && "sticky top-0 z-20 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/85",
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
<BreadcrumbBar />
|
|
|
|
|
</div>
|
|
|
|
|
<div className={cn(isMobile ? "block" : "flex flex-1 min-h-0")}>
|
2026-02-23 16:08:24 -06:00
|
|
|
<main
|
2026-03-02 16:44:03 -06:00
|
|
|
id="main-content"
|
|
|
|
|
tabIndex={-1}
|
2026-03-10 21:06:10 -05:00
|
|
|
className={cn(
|
|
|
|
|
"flex-1 p-4 md:p-6",
|
|
|
|
|
isMobile ? "overflow-visible pb-[calc(5rem+env(safe-area-inset-bottom))]" : "overflow-auto",
|
|
|
|
|
)}
|
2026-02-23 16:08:24 -06:00
|
|
|
>
|
2026-03-10 16:38:46 -05:00
|
|
|
{hasUnknownCompanyPrefix ? (
|
|
|
|
|
<NotFoundPage
|
|
|
|
|
scope="invalid_company_prefix"
|
|
|
|
|
requestedPrefix={companyPrefix ?? selectedCompany?.issuePrefix}
|
|
|
|
|
/>
|
|
|
|
|
) : (
|
|
|
|
|
<Outlet />
|
|
|
|
|
)}
|
Add shared UI primitives, contexts, and reusable components
Add shadcn components: avatar, breadcrumb, checkbox, collapsible,
command, dialog, dropdown-menu, label, popover, scroll-area, sheet,
skeleton, tabs, textarea, tooltip. Add shared components: BreadcrumbBar,
CommandPalette, CompanySwitcher, CommentThread, EmptyState, EntityRow,
FilterBar, InlineEditor, MetricCard, PageSkeleton, PriorityIcon,
PropertiesPanel, StatusIcon, SidebarNavItem/Section. Add contexts for
breadcrumbs, dialogs, and side panels. Add keyboard shortcut hook and
utility helpers. Update layout, sidebar, and main app shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:00 -06:00
|
|
|
</main>
|
|
|
|
|
<PropertiesPanel />
|
|
|
|
|
</div>
|
Overhaul UI with shadcn components and new pages
Add shadcn/ui components (badge, button, card, input, select,
separator). Add company context provider. New pages: Activity,
Approvals, Companies, Costs, Org chart. Restyle existing pages
(Dashboard, Agents, Issues, Goals, Projects) with shadcn components
and dark theme. Update layout, sidebar navigation, and routing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:32 -06:00
|
|
|
</div>
|
2026-02-23 16:08:24 -06:00
|
|
|
{isMobile && <MobileBottomNav visible={mobileNavVisible} />}
|
Add shared UI primitives, contexts, and reusable components
Add shadcn components: avatar, breadcrumb, checkbox, collapsible,
command, dialog, dropdown-menu, label, popover, scroll-area, sheet,
skeleton, tabs, textarea, tooltip. Add shared components: BreadcrumbBar,
CommandPalette, CompanySwitcher, CommentThread, EmptyState, EntityRow,
FilterBar, InlineEditor, MetricCard, PageSkeleton, PriorityIcon,
PropertiesPanel, StatusIcon, SidebarNavItem/Section. Add contexts for
breadcrumbs, dialogs, and side panels. Add keyboard shortcut hook and
utility helpers. Update layout, sidebar, and main app shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:00 -06:00
|
|
|
<CommandPalette />
|
|
|
|
|
<NewIssueDialog />
|
2026-02-17 10:53:20 -06:00
|
|
|
<NewProjectDialog />
|
2026-02-20 13:12:39 -06:00
|
|
|
<NewGoalDialog />
|
Build out agent management UI: detail page, create dialog, list view
Add NewAgentDialog for creating agents with adapter config. Expand
AgentDetail page with tabbed view (overview, runs, config, logs),
run history timeline, and live status. Enhance Agents list page with
richer cards and filtering. Update AgentProperties panel, API client,
query keys, and utility helpers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 12:33:04 -06:00
|
|
|
<NewAgentDialog />
|
2026-02-20 13:47:13 -06:00
|
|
|
<ToastViewport />
|
2026-02-16 13:32:04 -06:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|