From 9754c2d7912c769bbcc3d322a47a9d3f5c395f6c Mon Sep 17 00:00:00 2001 From: Johannes du Plessis Date: Thu, 4 Jun 2026 15:24:25 -0700 Subject: [PATCH] fix: make dashboard UI mobile-friendly (#1416) * Make dashboard UI mobile-friendly - Drop the thread title/repo header on the agent chat view. - Expanded sidebar becomes a full-screen overlay on mobile (<768px) instead of a squished column; resize handle hidden. - Default to collapsed on mobile first load so the chat stays visible; navigating a link/thread auto-collapses the overlay. * Fix settings rows and run cards overflowing on small screens - SettingsRow stacks label/control vertically below sm; reduce AppShell padding on mobile. - Truncate long model/repo names in AgentRunCard metadata so cards stay within bounds. * Keep collapsed-sidebar button from overlapping page titles on mobile * Render page titles below the sidebar button on mobile instead of indenting * Don't persist mobile auto-close to localStorage, preserving desktop preference --------- Co-authored-by: open-swe[bot] <215916821+open-swe[bot]@users.noreply.github.com> --- ui/src/components/AppShell.tsx | 6 +-- ui/src/components/AppSidebar.tsx | 2 + ui/src/components/agents/AgentRunCard.tsx | 20 +++++---- ui/src/components/agents/AgentThreadView.tsx | 12 ------ ui/src/components/agents/AgentsSidebar.tsx | 43 +++++++++++++++++--- ui/src/components/sidebar-layout.tsx | 21 ++++++++-- 6 files changed, 73 insertions(+), 31 deletions(-) diff --git a/ui/src/components/AppShell.tsx b/ui/src/components/AppShell.tsx index d7b1634f..a8fc0f4b 100644 --- a/ui/src/components/AppShell.tsx +++ b/ui/src/components/AppShell.tsx @@ -18,7 +18,7 @@ export function AppShell({ user, title, description, backTo, children }: AppShel
-
+
{backTo && ( +
-
{control}
+
{control}
); } diff --git a/ui/src/components/AppSidebar.tsx b/ui/src/components/AppSidebar.tsx index a4752133..84684b18 100644 --- a/ui/src/components/AppSidebar.tsx +++ b/ui/src/components/AppSidebar.tsx @@ -51,6 +51,7 @@ export function AppSidebar({ user }: { user: SessionUser }) {
- - - + + +
@@ -99,10 +116,12 @@ function ThreadGroup({ label, threads, activeThreadId, + onNavigate, }: { label: string; threads: Array; activeThreadId?: string; + onNavigate?: () => void; }) { if (threads.length === 0) return null; @@ -112,13 +131,26 @@ function ThreadGroup({ {label}
{threads.map((thread) => ( - + ))}
); } -function ThreadRow({ thread, isActive }: { thread: AgentThread; isActive: boolean }) { +function ThreadRow({ + thread, + isActive, + onNavigate, +}: { + thread: AgentThread; + isActive: boolean; + onNavigate?: () => void; +}) { const deleteThread = useDeleteAgentThread(); const badge = thread.diffStats && thread.diffStats.additions > 0 @@ -141,6 +173,7 @@ function ThreadRow({ thread, isActive }: { thread: AgentThread; isActive: boolea setCollapsed(!collapsed), [collapsed, setCollapsed]); - return { width, collapsed, setWidth, setCollapsed, toggle }; + const closeOnMobile = useCallback(() => { + if (typeof window === "undefined") return; + // State-only: don't persist, so the desktop collapsed preference is preserved. + if (window.matchMedia("(max-width: 767px)").matches) setCollapsedState(true); + }, []); + + return { width, collapsed, setWidth, setCollapsed, toggle, closeOnMobile }; } interface SidebarFrameProps { @@ -76,10 +85,16 @@ export function SidebarFrame({ return ( ); }