fix: update 7 files

This commit is contained in:
morgmart
2026-04-14 21:49:01 -07:00
parent 311518b473
commit fc481a72cf
7 changed files with 84 additions and 12 deletions
@@ -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 && (
<span className="flex h-3 w-3 shrink-0 items-center justify-center">
<SessionActivityIndicator
isRunning={isRunning}
hasUnread={hasUnread}
/>
</span>
)}
<span className="flex-1 min-w-0 truncate text-left">
{displayTitle}
</span>
<SessionActivityIndicator isRunning={isRunning} hasUnread={hasUnread} />
</Button>
<DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}>
@@ -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}
@@ -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(
<SidebarChatRow id="session-1" title="Idle Chat" isActive={false} />,
);
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(
<SidebarChatRow
id="session-1"
title="Recent Chat"
isActive={false}
reserveActivitySpace={false}
/>,
);
expect(
container.querySelector(".h-3.w-3.shrink-0.items-center.justify-center"),
).toBeNull();
rerender(
<SidebarChatRow
id="session-1"
title="Recent Chat"
isActive={false}
hasUnread
reserveActivitySpace={false}
/>,
);
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();
@@ -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": {
+10
View File
@@ -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);
@@ -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(<SessionActivityIndicator isRunning />);
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(<SessionActivityIndicator hasUnread />);
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", () => {
@@ -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,
)}
>
<Loader2
aria-hidden="true"
className="h-2.5 w-2.5 animate-spin text-brand"
className="h-2.5 w-2.5 animate-spin text-[var(--color-text-info-strong)]"
/>
</span>
);
@@ -37,7 +37,10 @@ export function SessionActivityIndicator({
<Loader2
role="status"
aria-label="Chat active"
className={cn("h-3 w-3 shrink-0 animate-spin text-brand", className)}
className={cn(
"h-3 w-3 shrink-0 animate-in fade-in-0 animate-spin text-[var(--color-text-info-strong)] duration-200 ease-out",
className,
)}
/>
);
}
@@ -52,7 +55,7 @@ export function SessionActivityIndicator({
role="status"
aria-label="Unread messages"
className={cn(
"absolute -right-0.5 -top-0.5 h-2.5 w-2.5 shrink-0 rounded-full border border-background bg-brand",
"absolute -right-0.5 -top-0.5 h-2 w-2 shrink-0 rounded-full border border-background bg-[var(--color-background-info-strong)] transition-opacity duration-200 ease-out animate-in fade-in-0",
className,
)}
/>
@@ -63,7 +66,10 @@ export function SessionActivityIndicator({
<span
role="status"
aria-label="Unread messages"
className={cn("h-2 w-2 shrink-0 rounded-full bg-brand", className)}
className={cn(
"h-1.5 w-1.5 shrink-0 rounded-full bg-[var(--color-background-info-strong)] transition-opacity duration-200 ease-out animate-in fade-in-0",
className,
)}
/>
);
}