From e542f0d7a6aa0b912aefe69e8b5abc1dc928987a Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Fri, 17 Jul 2026 16:22:38 -0400 Subject: [PATCH] fix: collapse git panel by default (#1744) Co-authored-by: Ramon Nogueira <270434257+ramon-langchain@users.noreply.github.com> Co-authored-by: open-swe[bot] (cherry picked from commit 3e8089c36995cccaeee3694599cf58857b06e557) Co-authored-by: Ramon Nogueira --- .../agents/components/AgentGitPanel.tsx | 20 ------- .../agents/components/AgentThreadView.tsx | 6 +- .../agents/lib/gitPanelPreferences.test.ts | 58 +++++++++++++++++++ .../agents/lib/gitPanelPreferences.ts | 20 +++++++ 4 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 ui/src/features/agents/lib/gitPanelPreferences.test.ts create mode 100644 ui/src/features/agents/lib/gitPanelPreferences.ts diff --git a/ui/src/features/agents/components/AgentGitPanel.tsx b/ui/src/features/agents/components/AgentGitPanel.tsx index 540b0d9f..12bfe404 100644 --- a/ui/src/features/agents/components/AgentGitPanel.tsx +++ b/ui/src/features/agents/components/AgentGitPanel.tsx @@ -88,9 +88,6 @@ function commonDirPrefix(paths: Array): string { } const PANEL_STORAGE_WIDTH = "open-swe.gitpanel.width" -const PANEL_STORAGE_COLLAPSED = "open-swe.gitpanel.collapsed" -const COLLAPSED_STATE_TRUE = "1" -const COLLAPSED_STATE_FALSE = "0" const PANEL_DEFAULT_WIDTH = 420 const PANEL_MIN_WIDTH = 320 // Keep at least this much room for the chat so the panel can grow to nearly the @@ -119,23 +116,6 @@ function readStoredPanelWidth(): number { return clampPanelWidth(parsed) } -export function readStoredPanelCollapsed(): boolean { - if (typeof window === "undefined") return true - // Default to collapsed until the user opens it once. - return ( - window.localStorage.getItem(PANEL_STORAGE_COLLAPSED) !== - COLLAPSED_STATE_FALSE - ) -} - -export function writeStoredPanelCollapsed(collapsed: boolean): void { - if (typeof window === "undefined") return - window.localStorage.setItem( - PANEL_STORAGE_COLLAPSED, - collapsed ? COLLAPSED_STATE_TRUE : COLLAPSED_STATE_FALSE - ) -} - function PanelResizeHandle({ width, onResize, diff --git a/ui/src/features/agents/components/AgentThreadView.tsx b/ui/src/features/agents/components/AgentThreadView.tsx index c1b3fb9a..ce3e8b91 100644 --- a/ui/src/features/agents/components/AgentThreadView.tsx +++ b/ui/src/features/agents/components/AgentThreadView.tsx @@ -12,10 +12,12 @@ import type { ModelSelection } from "@/features/agents/lib/provider/useModelOpti import { AgentGitPanel, PANEL_MIN_CHAT_WIDTH, - readStoredPanelCollapsed, - writeStoredPanelCollapsed, } from "@/features/agents/components/AgentGitPanel" import { AgentPromptBar } from "@/features/agents/components/AgentPromptBar" +import { + readStoredPanelCollapsed, + writeStoredPanelCollapsed, +} from "@/features/agents/lib/gitPanelPreferences" import { Messages } from "@/features/agents/components/messages" import { streamMessagesToUi } from "@/features/agents/lib/streamMessagesToUi" import { messageArrivalTimestamp } from "@/features/agents/lib/messageTimestamps" diff --git a/ui/src/features/agents/lib/gitPanelPreferences.test.ts b/ui/src/features/agents/lib/gitPanelPreferences.test.ts new file mode 100644 index 00000000..2baead28 --- /dev/null +++ b/ui/src/features/agents/lib/gitPanelPreferences.test.ts @@ -0,0 +1,58 @@ +/** @vitest-environment jsdom */ + +import { beforeEach, describe, expect, it, vi } from "vitest" + +import { + readStoredPanelCollapsed, + writeStoredPanelCollapsed, +} from "./gitPanelPreferences" + +function mockViewport(matches: boolean): void { + Object.defineProperty(window, "matchMedia", { + configurable: true, + writable: true, + value: vi.fn().mockImplementation((query: string) => ({ + matches, + media: query, + onchange: null, + addListener: vi.fn(), + removeListener: vi.fn(), + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + }) +} + +beforeEach(() => { + window.localStorage.clear() + mockViewport(false) +}) + +describe("git panel collapsed preference", () => { + it("defaults to collapsed before really wide screens", () => { + mockViewport(false) + + expect(readStoredPanelCollapsed()).toBe(true) + }) + + it("defaults to expanded on really wide screens", () => { + mockViewport(true) + + expect(readStoredPanelCollapsed()).toBe(false) + }) + + it("keeps an explicit collapsed preference on really wide screens", () => { + mockViewport(true) + writeStoredPanelCollapsed(true) + + expect(readStoredPanelCollapsed()).toBe(true) + }) + + it("keeps an explicit expanded preference before really wide screens", () => { + mockViewport(false) + writeStoredPanelCollapsed(false) + + expect(readStoredPanelCollapsed()).toBe(false) + }) +}) diff --git a/ui/src/features/agents/lib/gitPanelPreferences.ts b/ui/src/features/agents/lib/gitPanelPreferences.ts new file mode 100644 index 00000000..baded01a --- /dev/null +++ b/ui/src/features/agents/lib/gitPanelPreferences.ts @@ -0,0 +1,20 @@ +const PANEL_STORAGE_COLLAPSED = "open-swe.gitpanel.collapsed" +const COLLAPSED_STATE_TRUE = "1" +const COLLAPSED_STATE_FALSE = "0" +const PANEL_DEFAULT_EXPANDED_MEDIA_QUERY = "(min-width: 1536px)" + +export function readStoredPanelCollapsed(): boolean { + if (typeof window === "undefined") return true + const stored = window.localStorage.getItem(PANEL_STORAGE_COLLAPSED) + if (stored === COLLAPSED_STATE_TRUE) return true + if (stored === COLLAPSED_STATE_FALSE) return false + return !window.matchMedia(PANEL_DEFAULT_EXPANDED_MEDIA_QUERY).matches +} + +export function writeStoredPanelCollapsed(collapsed: boolean): void { + if (typeof window === "undefined") return + window.localStorage.setItem( + PANEL_STORAGE_COLLAPSED, + collapsed ? COLLAPSED_STATE_TRUE : COLLAPSED_STATE_FALSE + ) +}