From 2f323e24c14ec4f35e135c28acc52ad6698f64a6 Mon Sep 17 00:00:00 2001 From: Xubin Ren <52506698+Re-bin@users.noreply.github.com> Date: Sun, 17 May 2026 23:52:50 +0800 Subject: [PATCH] fix(webui): polish session titles and status --- webui/src/App.tsx | 4 +- webui/src/components/ChatList.tsx | 10 ++-- webui/src/components/ConnectionBadge.tsx | 12 +++-- webui/src/components/Sidebar.tsx | 4 +- webui/src/components/thread/ThreadShell.tsx | 3 +- webui/src/lib/format.ts | 25 ++++++++++ webui/src/lib/nanobot-client.ts | 9 ++-- webui/src/tests/nanobot-client.test.ts | 8 ++- webui/src/tests/thread-shell.test.tsx | 54 +++++++++++++++++++-- webui/src/tests/useSessions.test.tsx | 32 ++++++++++-- 10 files changed, 134 insertions(+), 27 deletions(-) diff --git a/webui/src/App.tsx b/webui/src/App.tsx index fabcff180..591cf4a96 100644 --- a/webui/src/App.tsx +++ b/webui/src/App.tsx @@ -17,6 +17,7 @@ import { loadSavedSecret, saveSecret, } from "@/lib/bootstrap"; +import { deriveTitle } from "@/lib/format"; import { NanobotClient } from "@/lib/nanobot-client"; import { ClientProvider, useClient } from "@/providers/ClientProvider"; import type { ChatSummary } from "@/lib/types"; @@ -391,8 +392,7 @@ function Shell({ const headerTitle = activeSession ? activeSession.title || - activeSession.preview || - t("chat.fallbackTitle", { id: activeSession.chatId.slice(0, 6) }) + deriveTitle(activeSession.preview, t("chat.newChat")) : t("app.brand"); useEffect(() => { diff --git a/webui/src/components/ChatList.tsx b/webui/src/components/ChatList.tsx index fc667883c..a51076519 100644 --- a/webui/src/components/ChatList.tsx +++ b/webui/src/components/ChatList.tsx @@ -7,6 +7,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { deriveTitle } from "@/lib/format"; import { cn } from "@/lib/utils"; import type { ChatSummary } from "@/lib/types"; @@ -64,8 +65,11 @@ export function ChatList({ const fallbackTitle = t("chat.fallbackTitle", { id: s.chatId.slice(0, 6), }); - const rawLabel = (s.title || s.preview)?.trim(); - const title = rawLabel || fallbackTitle; + const generatedTitle = s.title?.trim() || ""; + const title = + generatedTitle || deriveTitle(s.preview, t("chat.newChat")); + const tooltipTitle = + generatedTitle || deriveTitle(s.preview, fallbackTitle); return (
  • onSelect(s.key)} - title={rawLabel || fallbackTitle} + title={tooltipTitle} className="min-w-0 flex-1 overflow-hidden py-1.5 text-left" > {title} diff --git a/webui/src/components/ConnectionBadge.tsx b/webui/src/components/ConnectionBadge.tsx index 7616ddbe5..a09aadd28 100644 --- a/webui/src/components/ConnectionBadge.tsx +++ b/webui/src/components/ConnectionBadge.tsx @@ -36,21 +36,25 @@ export function ConnectionBadge() { status === "connecting" || status === "reconnecting" || status === "error"; + const label = t(`connection.${status}`); return ( - + {pulsing && ( )} - + - {t(`connection.${status}`)} + {label} ); } diff --git a/webui/src/components/Sidebar.tsx b/webui/src/components/Sidebar.tsx index cf21c8865..cd55475fe 100644 --- a/webui/src/components/Sidebar.tsx +++ b/webui/src/components/Sidebar.tsx @@ -117,12 +117,12 @@ export function Sidebar(props: SidebarProps) { />
    -
    +