From fc481a72cfeef565cd30115cdf80c7b3a9c3bd62 Mon Sep 17 00:00:00 2001 From: morgmart <98432065+morgmart@users.noreply.github.com> Date: Tue, 14 Apr 2026 21:49:01 -0700 Subject: [PATCH] fix: update 7 files --- .../features/sidebar/ui/SidebarChatRow.tsx | 14 ++++++- .../sidebar/ui/SidebarProjectsSection.tsx | 1 + .../ui/__tests__/SidebarChatRow.test.tsx | 37 +++++++++++++++++++ .../src/shared/i18n/locales/es/sidebar.json | 2 +- ui/goose2/src/shared/styles/globals.css | 10 +++++ .../ui/SessionActivityIndicator.test.tsx | 16 +++++--- .../shared/ui/SessionActivityIndicator.tsx | 16 +++++--- 7 files changed, 84 insertions(+), 12 deletions(-) diff --git a/ui/goose2/src/features/sidebar/ui/SidebarChatRow.tsx b/ui/goose2/src/features/sidebar/ui/SidebarChatRow.tsx index d005ab5366..b1f13cba12 100644 --- a/ui/goose2/src/features/sidebar/ui/SidebarChatRow.tsx +++ b/ui/goose2/src/features/sidebar/ui/SidebarChatRow.tsx @@ -28,6 +28,7 @@ interface SidebarChatRowProps { isActive: boolean; isRunning?: boolean; hasUnread?: boolean; + reserveActivitySpace?: boolean; className?: string; onSelect?: (id: string) => void; onRename?: (id: string, nextTitle: string) => void; @@ -42,6 +43,7 @@ export function SidebarChatRow({ isActive, isRunning = false, hasUnread = false, + reserveActivitySpace = false, className, onSelect, onRename, @@ -64,6 +66,9 @@ export function SidebarChatRow({ t("common:session.defaultTitle"), ); const [draftTitle, setDraftTitle] = useState(editableTitle); + const showActivityIndicator = isRunning || hasUnread; + const shouldReserveActivitySpace = + reserveActivitySpace || showActivityIndicator; useEffect(() => { setDraftTitle(editableTitle); @@ -186,10 +191,17 @@ export function SidebarChatRow({ isActive ? ACTIVE_CHAT_ROW_CLASS : INACTIVE_CHAT_ROW_CLASS, )} > + {shouldReserveActivitySpace && ( + + + + )} {displayTitle} - diff --git a/ui/goose2/src/features/sidebar/ui/SidebarProjectsSection.tsx b/ui/goose2/src/features/sidebar/ui/SidebarProjectsSection.tsx index ab41a2f7f5..77fc99cfdc 100644 --- a/ui/goose2/src/features/sidebar/ui/SidebarProjectsSection.tsx +++ b/ui/goose2/src/features/sidebar/ui/SidebarProjectsSection.tsx @@ -493,6 +493,7 @@ export function SidebarProjectsSection({ isActive={isActive} isRunning={session.isRunning ?? false} hasUnread={session.hasUnread ?? false} + reserveActivitySpace={false} onSelect={onSelectSession} onRename={onRenameChat} onArchive={onArchiveChat} diff --git a/ui/goose2/src/features/sidebar/ui/__tests__/SidebarChatRow.test.tsx b/ui/goose2/src/features/sidebar/ui/__tests__/SidebarChatRow.test.tsx index bd81f815de..cbb0a8c7be 100644 --- a/ui/goose2/src/features/sidebar/ui/__tests__/SidebarChatRow.test.tsx +++ b/ui/goose2/src/features/sidebar/ui/__tests__/SidebarChatRow.test.tsx @@ -108,6 +108,43 @@ describe("SidebarChatRow", () => { expect(screen.getByLabelText(/unread messages/i)).toBeInTheDocument(); }); + it("does not reserve activity space by default when idle", () => { + const { container } = render( + , + ); + + expect( + container.querySelector(".h-3.w-3.shrink-0.items-center.justify-center"), + ).toBeNull(); + }); + + it("does not reserve activity space for recents until activity exists", () => { + const { container, rerender } = render( + , + ); + + expect( + container.querySelector(".h-3.w-3.shrink-0.items-center.justify-center"), + ).toBeNull(); + + rerender( + , + ); + + expect(screen.getByLabelText(/unread messages/i)).toBeInTheDocument(); + }); + it("keeps the localized default title in rename mode without persisting it", async () => { const user = userEvent.setup(); const onRename = vi.fn(); diff --git a/ui/goose2/src/shared/i18n/locales/es/sidebar.json b/ui/goose2/src/shared/i18n/locales/es/sidebar.json index a34114c2e8..c468bfecc7 100644 --- a/ui/goose2/src/shared/i18n/locales/es/sidebar.json +++ b/ui/goose2/src/shared/i18n/locales/es/sidebar.json @@ -18,7 +18,7 @@ }, "search": { "error": "La búsqueda de mensajes falló. Mostrando solo coincidencias de metadatos.", - "placeholder": "Busca chats por título, persona, proyecto o mensaje...", + "placeholder": "Buscar conversaciones", "searching": "Buscando chats..." }, "sections": { diff --git a/ui/goose2/src/shared/styles/globals.css b/ui/goose2/src/shared/styles/globals.css index 1b5aca120a..77f03716ea 100644 --- a/ui/goose2/src/shared/styles/globals.css +++ b/ui/goose2/src/shared/styles/globals.css @@ -32,6 +32,7 @@ --color-blue-100: #7cacff; --color-blue-200: #5c98f9; + --color-blue-300: #0090ff; --color-green-100: #a3d795; --color-green-200: #91cb80; @@ -98,6 +99,7 @@ --background-danger: var(--color-red-200); --background-success: var(--color-green-200); --background-info: var(--color-blue-200); + --background-info-strong: var(--color-blue-300); --background-warning: var(--color-yellow-200); /* Semantic borders */ @@ -111,6 +113,7 @@ --border-success: var(--color-green-300); --border-warning: var(--color-yellow-200); --border-info: var(--color-blue-200); + --border-info-strong: var(--color-blue-300); /* Semantic text */ --text-default: var(--color-gray-900); @@ -123,6 +126,7 @@ --text-success: var(--color-green-300); --text-warning: var(--color-yellow-200); --text-info: var(--color-blue-200); + --text-info-strong: var(--color-blue-300); --ring: color-mix(in srgb, var(--border-strong) 20%, transparent); @@ -281,6 +285,7 @@ --background-danger: var(--color-red-100); --background-success: var(--color-green-100); --background-info: var(--color-blue-100); + --background-info-strong: var(--color-blue-300); --background-warning: var(--color-yellow-100); /* semantic borders */ @@ -294,6 +299,7 @@ --border-success: var(--color-green-200); --border-warning: var(--color-yellow-200); --border-info: var(--color-blue-200); + --border-info-strong: var(--color-blue-300); /* semantic text */ --text-default: var(--color-white); @@ -306,6 +312,7 @@ --text-success: var(--color-green-100); --text-warning: var(--color-yellow-100); --text-info: var(--color-blue-100); + --text-info-strong: var(--color-blue-300); --ring: color-mix(in srgb, var(--border-strong) 20%, transparent); @@ -381,6 +388,7 @@ --color-background-danger: var(--background-danger); --color-background-success: var(--background-success); --color-background-info: var(--background-info); + --color-background-info-strong: var(--background-info-strong); --color-background-warning: var(--background-warning); --color-background-accent: var(--background-accent); @@ -398,6 +406,7 @@ --color-border-success: var(--border-success); --color-border-warning: var(--border-warning); --color-border-info: var(--border-info); + --color-border-info-strong: var(--border-info-strong); /* semantic text */ --color-text-default: var(--text-default); @@ -410,6 +419,7 @@ --color-text-success: var(--text-success); --color-text-warning: var(--text-warning); --color-text-info: var(--text-info); + --color-text-info-strong: var(--text-info-strong); /* alpha variants */ --color-dark-10: var(--dark-10); diff --git a/ui/goose2/src/shared/ui/SessionActivityIndicator.test.tsx b/ui/goose2/src/shared/ui/SessionActivityIndicator.test.tsx index 2999424bc9..3e5eb8e35c 100644 --- a/ui/goose2/src/shared/ui/SessionActivityIndicator.test.tsx +++ b/ui/goose2/src/shared/ui/SessionActivityIndicator.test.tsx @@ -3,16 +3,20 @@ import { describe, expect, it } from "vitest"; import { SessionActivityIndicator } from "./SessionActivityIndicator"; describe("SessionActivityIndicator", () => { - it("renders a brand-colored inline spinner for running sessions", () => { + it("renders a strong-info inline spinner for running sessions", () => { render(); - expect(screen.getByLabelText(/chat active/i)).toHaveClass("text-brand"); + expect(screen.getByLabelText(/chat active/i)).toHaveClass( + "text-[var(--color-text-info-strong)]", + ); }); - it("renders a brand-colored inline dot for unread sessions", () => { + it("renders a strong-info inline dot for unread sessions", () => { render(); - expect(screen.getByLabelText(/unread messages/i)).toHaveClass("bg-brand"); + expect(screen.getByLabelText(/unread messages/i)).toHaveClass( + "bg-[var(--color-background-info-strong)]", + ); }); it("renders an overlay spinner variant for running sessions", () => { @@ -21,7 +25,9 @@ describe("SessionActivityIndicator", () => { ); expect(screen.getByLabelText(/chat active/i)).toBeInTheDocument(); - expect(container.querySelector(".text-brand")).toBeTruthy(); + expect( + container.querySelector(".text-\\[var\\(--color-text-info-strong\\)\\]"), + ).toBeTruthy(); }); it("renders nothing when the session is idle and read", () => { diff --git a/ui/goose2/src/shared/ui/SessionActivityIndicator.tsx b/ui/goose2/src/shared/ui/SessionActivityIndicator.tsx index a18a1b1094..d45afe338d 100644 --- a/ui/goose2/src/shared/ui/SessionActivityIndicator.tsx +++ b/ui/goose2/src/shared/ui/SessionActivityIndicator.tsx @@ -21,13 +21,13 @@ export function SessionActivityIndicator({ role="status" aria-label="Chat active" className={cn( - "absolute -right-1 -top-1 flex h-3.5 w-3.5 items-center justify-center rounded-full border border-background bg-background shadow-sm", + "absolute -right-1 -top-1 flex h-3.5 w-3.5 items-center justify-center rounded-full border border-background bg-background shadow-sm transition-opacity duration-200 ease-out animate-in fade-in-0", className, )} >