feat(webui): present chats as topics

This commit is contained in:
chengyongru
2026-07-24 10:29:13 +08:00
committed by chengyongru
parent 8bcab8885e
commit 6a9157f477
18 changed files with 233 additions and 233 deletions
+1 -1
View File
@@ -516,7 +516,7 @@ function ChatsFoldFooter({
const { t, i18n } = useTranslation();
const collapsedFallback = i18n.resolvedLanguage?.startsWith("zh")
? `已折叠 ${hiddenCount} 个对话`
: `${hiddenCount} hidden chats`;
: `${hiddenCount} hidden topics`;
return (
<div className="px-2 pb-1 pt-1">
+16 -16
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "Sidebar navigation",
"collapse": "Collapse sidebar",
"newChat": "New chat",
"newChat": "New topic",
"searchAria": "Search",
"searchPlaceholder": "Search",
"searchResults": "Results",
"noSearchResults": "No matching chats.",
"recent": "Recent",
"noSearchResults": "No matching topics.",
"recent": "Recent topics",
"settings": "Settings",
"language": {
"label": "Language",
@@ -819,15 +819,15 @@
}
},
"chat": {
"fallbackTitle": "Chat {{id}}",
"fallbackTitle": "Topic {{id}}",
"forkTitle": "Fork: {{title}}",
"loading": "Loading…",
"noSessions": "No sessions yet.",
"showMore": "Show {{count}} more",
"collapsed": "{{count}} hidden chats",
"collapsed": "{{count}} hidden topics",
"showLess": "Show less",
"actions": "Chat actions for {{title}}",
"newInProject": "Start a new chat in {{project}}",
"actions": "Topic actions for {{title}}",
"newInProject": "Start a new topic in {{project}}",
"activity": {
"running": "Agent running",
"complete": "Agent finished",
@@ -836,9 +836,9 @@
"pin": "Pin",
"unpin": "Unpin",
"rename": "Rename",
"renameTitle": "Rename chat",
"renameDescription": "Choose a local sidebar name for this chat.",
"renamePlaceholder": "Chat name",
"renameTitle": "Rename topic",
"renameDescription": "Choose a local sidebar name for this topic.",
"renamePlaceholder": "Topic name",
"renameProjectTitle": "Rename project",
"renameProjectDescription": "Choose a local sidebar name for this project.",
"renameProjectPlaceholder": "Project name",
@@ -848,10 +848,10 @@
"showArchived": "Show archived",
"hideArchived": "Hide archived",
"delete": "Delete",
"newChat": "New chat",
"newChat": "New topic",
"groups": {
"pinned": "Pinned",
"all": "Chats",
"all": "Topics",
"projects": "Projects",
"today": "Today",
"yesterday": "Yesterday",
@@ -860,7 +860,7 @@
}
},
"deleteConfirm": {
"title": "Delete this chat?",
"title": "Delete this topic?",
"description": "This action cannot be undone.",
"cancel": "Cancel",
"confirm": "Delete",
@@ -954,14 +954,14 @@
},
"header": {
"toggleSidebar": "Toggle sidebar",
"newChat": "Start a new chat",
"newChat": "Start a new topic",
"toggleTheme": "Toggle theme from header",
"settings": "Open settings",
"sessionInfo": "Session details"
},
"sessionInfo": {
"title": "Session",
"untitled": "Untitled chat",
"untitled": "Untitled topic",
"automations": "Automations",
"count": "{{count}}",
"loading": "Loading automations...",
@@ -987,7 +987,7 @@
"composer": {
"placeholderThread": "Type your message…",
"placeholderHero": "Ask anything...",
"placeholderOpening": "Opening a new chat…",
"placeholderOpening": "Opening a new topic…",
"placeholderStreaming": "Model is responding…",
"inputAria": "Message input",
"sendHint": "Enter to send · Shift+Enter for newline",
+15 -15
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "Navegación de la barra lateral",
"collapse": "Contraer barra lateral",
"newChat": "Nuevo chat",
"newChat": "Nuevo tema",
"searchAria": "Buscar",
"searchPlaceholder": "Buscar",
"searchResults": "Resultados",
"noSearchResults": "No hay chats coincidentes.",
"recent": "Recientes",
"noSearchResults": "No hay temas coincidentes.",
"recent": "Temas recientes",
"settings": "Configuración",
"language": {
"label": "Idioma",
@@ -806,15 +806,15 @@
}
},
"chat": {
"fallbackTitle": "Chat {{id}}",
"fallbackTitle": "Tema {{id}}",
"forkTitle": "Bifurcación: {{title}}",
"loading": "Cargando…",
"noSessions": "Todavía no hay sesiones.",
"showMore": "Mostrar {{count}} más",
"collapsed": "{{count}} chats ocultos",
"collapsed": "{{count}} temas ocultos",
"showLess": "Mostrar menos",
"actions": "Acciones del chat {{title}}",
"newInProject": "Iniciar un chat nuevo en {{project}}",
"actions": "Acciones del tema {{title}}",
"newInProject": "Iniciar un tema nuevo en {{project}}",
"activity": {
"running": "Agent running",
"complete": "Agent finished",
@@ -823,9 +823,9 @@
"pin": "Pin",
"unpin": "Unpin",
"rename": "Rename",
"renameTitle": "Rename chat",
"renameDescription": "Choose a local sidebar name for this chat.",
"renamePlaceholder": "Chat name",
"renameTitle": "Renombrar tema",
"renameDescription": "Elige un nombre local de la barra lateral para este tema.",
"renamePlaceholder": "Nombre del tema",
"renameProjectTitle": "Rename project",
"renameProjectDescription": "Choose a local sidebar name for this project.",
"renameProjectPlaceholder": "Project name",
@@ -835,10 +835,10 @@
"showArchived": "Show archived",
"hideArchived": "Hide archived",
"delete": "Eliminar",
"newChat": "Nuevo chat",
"newChat": "Nuevo tema",
"groups": {
"pinned": "Pinned",
"all": "Chats",
"all": "Temas",
"projects": "Projects",
"today": "Today",
"yesterday": "Yesterday",
@@ -941,14 +941,14 @@
},
"header": {
"toggleSidebar": "Mostrar u ocultar la barra lateral",
"newChat": "Iniciar un chat nuevo",
"newChat": "Iniciar un tema nuevo",
"toggleTheme": "Cambiar tema desde el encabezado",
"settings": "Abrir configuración",
"sessionInfo": "Detalles de la sesión"
},
"sessionInfo": {
"title": "Sesión",
"untitled": "Chat sin título",
"untitled": "Tema sin título",
"automations": "Automatizaciones",
"count": "{{count}}",
"loading": "Cargando automatizaciones...",
@@ -974,7 +974,7 @@
"composer": {
"placeholderThread": "Escribe tu mensaje…",
"placeholderHero": "¿Qué tienes en mente?",
"placeholderOpening": "Abriendo un nuevo chat…",
"placeholderOpening": "Abriendo un nuevo tema…",
"placeholderStreaming": "El modelo está respondiendo…",
"inputAria": "Entrada de mensaje",
"sendHint": "Enter para enviar · Shift+Enter para nueva línea",
+15 -15
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "Navigation de la barre latérale",
"collapse": "Réduire la barre latérale",
"newChat": "Nouvelle discussion",
"newChat": "Nouveau sujet",
"searchAria": "Rechercher",
"searchPlaceholder": "Rechercher",
"searchResults": "Résultats",
"noSearchResults": "Aucun chat correspondant.",
"recent": "Récentes",
"noSearchResults": "Aucun sujet correspondant.",
"recent": "Sujets récents",
"settings": "Paramètres",
"language": {
"label": "Langue",
@@ -805,15 +805,15 @@
}
},
"chat": {
"fallbackTitle": "Discussion {{id}}",
"fallbackTitle": "Sujet {{id}}",
"forkTitle": "Branche : {{title}}",
"loading": "Chargement…",
"noSessions": "Aucune session pour le moment.",
"showMore": "Afficher {{count}} de plus",
"collapsed": "{{count}} discussions masquées",
"collapsed": "{{count}} sujets masqués",
"showLess": "Afficher moins",
"actions": "Actions de la discussion {{title}}",
"newInProject": "Démarrer une nouvelle discussion dans {{project}}",
"actions": "Actions du sujet {{title}}",
"newInProject": "Démarrer un nouveau sujet dans {{project}}",
"activity": {
"running": "Agent running",
"complete": "Agent finished",
@@ -822,9 +822,9 @@
"pin": "Pin",
"unpin": "Unpin",
"rename": "Rename",
"renameTitle": "Rename chat",
"renameDescription": "Choose a local sidebar name for this chat.",
"renamePlaceholder": "Chat name",
"renameTitle": "Renommer le sujet",
"renameDescription": "Choisissez un nom local dans la barre latérale pour ce sujet.",
"renamePlaceholder": "Nom du sujet",
"renameProjectTitle": "Rename project",
"renameProjectDescription": "Choose a local sidebar name for this project.",
"renameProjectPlaceholder": "Project name",
@@ -834,10 +834,10 @@
"showArchived": "Show archived",
"hideArchived": "Hide archived",
"delete": "Supprimer",
"newChat": "Nouvelle discussion",
"newChat": "Nouveau sujet",
"groups": {
"pinned": "Pinned",
"all": "Chats",
"all": "Sujets",
"projects": "Projects",
"today": "Today",
"yesterday": "Yesterday",
@@ -940,14 +940,14 @@
},
"header": {
"toggleSidebar": "Afficher ou masquer la barre latérale",
"newChat": "Démarrer un nouveau chat",
"newChat": "Démarrer un nouveau sujet",
"toggleTheme": "Changer le thème depuis len-tête",
"settings": "Ouvrir les paramètres",
"sessionInfo": "Détails de la session"
},
"sessionInfo": {
"title": "Session",
"untitled": "Chat sans titre",
"untitled": "Sujet sans titre",
"automations": "Automatisations",
"count": "{{count}}",
"loading": "Chargement des automatisations...",
@@ -973,7 +973,7 @@
"composer": {
"placeholderThread": "Saisissez votre message…",
"placeholderHero": "Quavez-vous en tête ?",
"placeholderOpening": "Ouverture dune nouvelle discussion…",
"placeholderOpening": "Ouverture dun nouveau sujet…",
"placeholderStreaming": "Le modèle est en train de répondre…",
"inputAria": "Champ de message",
"sendHint": "Entrée pour envoyer · Maj+Entrée pour un retour à la ligne",
+15 -15
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "Navigasi bilah samping",
"collapse": "Ciutkan sidebar",
"newChat": "Obrolan baru",
"newChat": "Topik baru",
"searchAria": "Cari",
"searchPlaceholder": "Cari",
"searchResults": "Hasil",
"noSearchResults": "Tidak ada chat yang cocok.",
"recent": "Terbaru",
"noSearchResults": "Tidak ada topik yang cocok.",
"recent": "Topik terbaru",
"settings": "Pengaturan",
"language": {
"label": "Bahasa",
@@ -805,15 +805,15 @@
}
},
"chat": {
"fallbackTitle": "Obrolan {{id}}",
"fallbackTitle": "Topik {{id}}",
"forkTitle": "Cabang: {{title}}",
"loading": "Memuat…",
"noSessions": "Belum ada sesi.",
"showMore": "Tampilkan {{count}} lagi",
"collapsed": "{{count}} obrolan diciutkan",
"collapsed": "{{count}} topik diciutkan",
"showLess": "Tampilkan lebih sedikit",
"actions": "Aksi obrolan untuk {{title}}",
"newInProject": "Mulai obrolan baru di {{project}}",
"actions": "Aksi topik untuk {{title}}",
"newInProject": "Mulai topik baru di {{project}}",
"activity": {
"running": "Agent running",
"complete": "Agent finished",
@@ -822,9 +822,9 @@
"pin": "Pin",
"unpin": "Unpin",
"rename": "Rename",
"renameTitle": "Rename chat",
"renameDescription": "Choose a local sidebar name for this chat.",
"renamePlaceholder": "Chat name",
"renameTitle": "Ganti nama topik",
"renameDescription": "Pilih nama lokal di bilah sisi untuk topik ini.",
"renamePlaceholder": "Nama topik",
"renameProjectTitle": "Rename project",
"renameProjectDescription": "Choose a local sidebar name for this project.",
"renameProjectPlaceholder": "Project name",
@@ -834,10 +834,10 @@
"showArchived": "Show archived",
"hideArchived": "Hide archived",
"delete": "Hapus",
"newChat": "Obrolan baru",
"newChat": "Topik baru",
"groups": {
"pinned": "Pinned",
"all": "Chats",
"all": "Topik",
"projects": "Projects",
"today": "Today",
"yesterday": "Yesterday",
@@ -940,14 +940,14 @@
},
"header": {
"toggleSidebar": "Tampilkan atau sembunyikan sidebar",
"newChat": "Mulai chat baru",
"newChat": "Mulai topik baru",
"toggleTheme": "Alihkan tema dari header",
"settings": "Buka pengaturan",
"sessionInfo": "Detail sesi"
},
"sessionInfo": {
"title": "Sesi",
"untitled": "Chat tanpa judul",
"untitled": "Topik tanpa judul",
"automations": "Otomasi",
"count": "{{count}}",
"loading": "Memuat otomasi...",
@@ -973,7 +973,7 @@
"composer": {
"placeholderThread": "Ketik pesan Anda…",
"placeholderHero": "Apa yang sedang Anda pikirkan?",
"placeholderOpening": "Membuka obrolan baru…",
"placeholderOpening": "Membuka topik baru…",
"placeholderStreaming": "Model sedang merespons…",
"inputAria": "Input pesan",
"sendHint": "Enter untuk kirim · Shift+Enter untuk baris baru",
+15 -15
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "サイドバーのナビゲーション",
"collapse": "サイドバーを閉じる",
"newChat": "新しいチャット",
"newChat": "新しいトピック",
"searchAria": "検索",
"searchPlaceholder": "検索",
"searchResults": "検索結果",
"noSearchResults": "一致するチャットはありません。",
"recent": "最近のチャット",
"noSearchResults": "一致するトピックはありません。",
"recent": "最近のトピック",
"settings": "設定",
"language": {
"label": "言語",
@@ -805,15 +805,15 @@
}
},
"chat": {
"fallbackTitle": "チャット {{id}}",
"fallbackTitle": "トピック {{id}}",
"forkTitle": "分岐:{{title}}",
"loading": "読み込み中…",
"noSessions": "まだセッションがありません。",
"showMore": "さらに {{count}} 件表示",
"collapsed": "{{count}} 件のチャットを折りたたみ中",
"collapsed": "{{count}} 件のトピックを折りたたみ中",
"showLess": "折りたたむ",
"actions": "「{{title}}」のチャット操作",
"newInProject": "「{{project}}」で新しいチャットを開始",
"actions": "「{{title}}」のトピック操作",
"newInProject": "「{{project}}」で新しいトピックを開始",
"activity": {
"running": "Agent running",
"complete": "Agent finished",
@@ -822,9 +822,9 @@
"pin": "Pin",
"unpin": "Unpin",
"rename": "Rename",
"renameTitle": "Rename chat",
"renameDescription": "Choose a local sidebar name for this chat.",
"renamePlaceholder": "Chat name",
"renameTitle": "トピック名を変更",
"renameDescription": "このトピックのサイドバー表示名を選択します。",
"renamePlaceholder": "トピック名",
"renameProjectTitle": "Rename project",
"renameProjectDescription": "Choose a local sidebar name for this project.",
"renameProjectPlaceholder": "Project name",
@@ -834,10 +834,10 @@
"showArchived": "Show archived",
"hideArchived": "Hide archived",
"delete": "削除",
"newChat": "新しいチャット",
"newChat": "新しいトピック",
"groups": {
"pinned": "Pinned",
"all": "Chats",
"all": "トピック",
"projects": "Projects",
"today": "Today",
"yesterday": "Yesterday",
@@ -940,14 +940,14 @@
},
"header": {
"toggleSidebar": "サイドバーを切り替える",
"newChat": "新しいチャットを開始",
"newChat": "新しいトピックを開始",
"toggleTheme": "ヘッダーからテーマを切り替える",
"settings": "設定を開く",
"sessionInfo": "セッション詳細"
},
"sessionInfo": {
"title": "セッション",
"untitled": "無題のチャット",
"untitled": "無題のトピック",
"automations": "自動タスク",
"count": "{{count}}",
"loading": "自動タスクを読み込み中...",
@@ -973,7 +973,7 @@
"composer": {
"placeholderThread": "メッセージを入力…",
"placeholderHero": "何を考えていますか?",
"placeholderOpening": "新しいチャットを開いています…",
"placeholderOpening": "新しいトピックを開いています…",
"placeholderStreaming": "モデルが応答しています…",
"inputAria": "メッセージ入力欄",
"sendHint": "Enter で送信 · Shift+Enter で改行",
+15 -15
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "사이드바 탐색",
"collapse": "사이드바 접기",
"newChat": "새 채팅",
"newChat": "새 주제",
"searchAria": "검색",
"searchPlaceholder": "검색",
"searchResults": "결과",
"noSearchResults": "일치하는 채팅이 없습니다.",
"recent": "최근 대화",
"noSearchResults": "일치하는 주제가 없습니다.",
"recent": "최근 주제",
"settings": "설정",
"language": {
"label": "언어",
@@ -805,15 +805,15 @@
}
},
"chat": {
"fallbackTitle": "채팅 {{id}}",
"fallbackTitle": "주제 {{id}}",
"forkTitle": "분기: {{title}}",
"loading": "불러오는 중…",
"noSessions": "아직 세션이 없습니다.",
"showMore": "{{count}}개 더 보기",
"collapsed": "{{count}}개 채팅 접힘",
"collapsed": "{{count}}개 주제 접힘",
"showLess": "접기",
"actions": "{{title}} 채팅 작업",
"newInProject": "{{project}}에서 새 채팅 시작",
"actions": "{{title}} 주제 작업",
"newInProject": "{{project}}에서 새 주제 시작",
"activity": {
"running": "Agent running",
"complete": "Agent finished",
@@ -822,9 +822,9 @@
"pin": "Pin",
"unpin": "Unpin",
"rename": "Rename",
"renameTitle": "Rename chat",
"renameDescription": "Choose a local sidebar name for this chat.",
"renamePlaceholder": "Chat name",
"renameTitle": "주제 이름 변경",
"renameDescription": "이 주제에 사용할 사이드바 이름을 선택하세요.",
"renamePlaceholder": "주제 이름",
"renameProjectTitle": "Rename project",
"renameProjectDescription": "Choose a local sidebar name for this project.",
"renameProjectPlaceholder": "Project name",
@@ -834,10 +834,10 @@
"showArchived": "Show archived",
"hideArchived": "Hide archived",
"delete": "삭제",
"newChat": "새 채팅",
"newChat": "새 주제",
"groups": {
"pinned": "Pinned",
"all": "Chats",
"all": "주제",
"projects": "Projects",
"today": "Today",
"yesterday": "Yesterday",
@@ -940,14 +940,14 @@
},
"header": {
"toggleSidebar": "사이드바 전환",
"newChat": "새 채팅 시작",
"newChat": "새 주제 시작",
"toggleTheme": "헤더에서 테마 전환",
"settings": "설정 열기",
"sessionInfo": "세션 세부 정보"
},
"sessionInfo": {
"title": "세션",
"untitled": "제목 없는 채팅",
"untitled": "제목 없는 주제",
"automations": "자동화",
"count": "{{count}}",
"loading": "자동화를 불러오는 중...",
@@ -973,7 +973,7 @@
"composer": {
"placeholderThread": "메시지를 입력하세요…",
"placeholderHero": "무슨 생각을 하고 있나요?",
"placeholderOpening": "새 채팅을 여는 중…",
"placeholderOpening": "새 주제를 여는 중…",
"placeholderStreaming": "모델이 응답 중입니다…",
"inputAria": "메시지 입력",
"sendHint": "Enter로 전송 · Shift+Enter로 줄바꿈",
+15 -15
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "Navegação da barra lateral",
"collapse": "Recolher barra lateral",
"newChat": "Nova conversa",
"newChat": "Novo tópico",
"searchAria": "Buscar",
"searchPlaceholder": "Buscar",
"searchResults": "Resultados",
"noSearchResults": "Nenhuma conversa encontrada.",
"recent": "Recentes",
"noSearchResults": "Nenhum tópico encontrado.",
"recent": "Tópicos recentes",
"settings": "Configurações",
"language": {
"label": "Idioma",
@@ -819,15 +819,15 @@
}
},
"chat": {
"fallbackTitle": "Conversa {{id}}",
"fallbackTitle": "Tópico {{id}}",
"forkTitle": "Fork: {{title}}",
"loading": "Carregando…",
"noSessions": "Nenhuma sessão ainda.",
"showMore": "Mostrar mais {{count}}",
"collapsed": "{{count}} conversas ocultas",
"collapsed": "{{count}} tópicos ocultos",
"showLess": "Mostrar menos",
"actions": "Ações da conversa {{title}}",
"newInProject": "Iniciar uma nova conversa em {{project}}",
"actions": "Ações do tópico {{title}}",
"newInProject": "Iniciar um novo tópico em {{project}}",
"activity": {
"running": "Agente em execução",
"complete": "Agente finalizado",
@@ -836,9 +836,9 @@
"pin": "Fixar",
"unpin": "Desafixar",
"rename": "Renomear",
"renameTitle": "Renomear conversa",
"renameDescription": "Escolha um nome local da barra lateral para esta conversa.",
"renamePlaceholder": "Nome da conversa",
"renameTitle": "Renomear tópico",
"renameDescription": "Escolha um nome local da barra lateral para este tópico.",
"renamePlaceholder": "Nome do tópico",
"renameProjectTitle": "Renomear projeto",
"renameProjectDescription": "Escolha um nome local da barra lateral para este projeto.",
"renameProjectPlaceholder": "Nome do projeto",
@@ -848,10 +848,10 @@
"showArchived": "Mostrar arquivadas",
"hideArchived": "Ocultar arquivadas",
"delete": "Excluir",
"newChat": "Nova conversa",
"newChat": "Novo tópico",
"groups": {
"pinned": "Fixadas",
"all": "Conversas",
"all": "Tópicos",
"projects": "Projetos",
"today": "Hoje",
"yesterday": "Ontem",
@@ -954,14 +954,14 @@
},
"header": {
"toggleSidebar": "Alternar barra lateral",
"newChat": "Iniciar uma nova conversa",
"newChat": "Iniciar um novo tópico",
"toggleTheme": "Alternar tema pelo cabeçalho",
"settings": "Abrir configurações",
"sessionInfo": "Detalhes da sessão"
},
"sessionInfo": {
"title": "Sessão",
"untitled": "Conversa sem título",
"untitled": "Tópico sem título",
"automations": "Automações",
"count": "{{count}}",
"loading": "Carregando automações...",
@@ -987,7 +987,7 @@
"composer": {
"placeholderThread": "Digite sua mensagem…",
"placeholderHero": "Pergunte qualquer coisa...",
"placeholderOpening": "Abrindo uma nova conversa…",
"placeholderOpening": "Abrindo um novo tópico…",
"placeholderStreaming": "O modelo está respondendo…",
"inputAria": "Campo de mensagem",
"sendHint": "Enter para enviar · Shift+Enter para nova linha",
+15 -15
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "Điều hướng thanh bên",
"collapse": "Thu gọn thanh bên",
"newChat": "Cuộc trò chuyện mới",
"newChat": "Chủ đề mới",
"searchAria": "Tìm kiếm",
"searchPlaceholder": "Tìm kiếm",
"searchResults": "Kết quả",
"noSearchResults": "Không có cuộc trò chuyện phù hợp.",
"recent": "Gần đây",
"noSearchResults": "Không có chủ đề phù hợp.",
"recent": "Chủ đề gần đây",
"settings": "Cài đặt",
"language": {
"label": "Ngôn ngữ",
@@ -805,15 +805,15 @@
}
},
"chat": {
"fallbackTitle": "Trò chuyện {{id}}",
"fallbackTitle": "Chủ đề {{id}}",
"forkTitle": "Nhánh: {{title}}",
"loading": "Đang tải…",
"noSessions": "Chưa có phiên nào.",
"showMore": "Hiển thị thêm {{count}}",
"collapsed": "Đã thu gọn {{count}} cuộc trò chuyện",
"collapsed": "Đã thu gọn {{count}} chủ đề",
"showLess": "Thu gọn",
"actions": "Tác vụ cho cuộc trò chuyện {{title}}",
"newInProject": "Bắt đầu cuộc trò chuyện mới trong {{project}}",
"actions": "Tác vụ cho chủ đề {{title}}",
"newInProject": "Bắt đầu chủ đề mới trong {{project}}",
"activity": {
"running": "Agent running",
"complete": "Agent finished",
@@ -822,9 +822,9 @@
"pin": "Pin",
"unpin": "Unpin",
"rename": "Rename",
"renameTitle": "Rename chat",
"renameDescription": "Choose a local sidebar name for this chat.",
"renamePlaceholder": "Chat name",
"renameTitle": "Đổi tên chủ đề",
"renameDescription": "Chọn tên hiển thị trong thanh bên cho chủ đề này.",
"renamePlaceholder": "Tên chủ đề",
"renameProjectTitle": "Rename project",
"renameProjectDescription": "Choose a local sidebar name for this project.",
"renameProjectPlaceholder": "Project name",
@@ -834,10 +834,10 @@
"showArchived": "Show archived",
"hideArchived": "Hide archived",
"delete": "Xóa",
"newChat": "Cuộc trò chuyện mới",
"newChat": "Chủ đề mới",
"groups": {
"pinned": "Pinned",
"all": "Chats",
"all": "Chủ đề",
"projects": "Projects",
"today": "Today",
"yesterday": "Yesterday",
@@ -940,14 +940,14 @@
},
"header": {
"toggleSidebar": "Bật/tắt thanh bên",
"newChat": "Bắt đầu chat mới",
"newChat": "Bắt đầu chủ đề mới",
"toggleTheme": "Chuyển chủ đề từ header",
"settings": "Mở cài đặt",
"sessionInfo": "Chi tiết phiên"
},
"sessionInfo": {
"title": "Phiên",
"untitled": "Chat chưa đặt tên",
"untitled": "Chủ đề chưa đặt tên",
"automations": "Tự động hóa",
"count": "{{count}}",
"loading": "Đang tải tự động hóa...",
@@ -973,7 +973,7 @@
"composer": {
"placeholderThread": "Nhập tin nhắn…",
"placeholderHero": "Bạn đang nghĩ gì?",
"placeholderOpening": "Đang mở cuộc trò chuyện mới…",
"placeholderOpening": "Đang mở chủ đề mới…",
"placeholderStreaming": "Mô hình đang trả lời…",
"inputAria": "Ô nhập tin nhắn",
"sendHint": "Enter để gửi · Shift+Enter để xuống dòng",
+21 -21
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "侧边栏导航",
"collapse": "收起侧边栏",
"newChat": "新建话",
"newChat": "新建话",
"searchAria": "搜索",
"searchPlaceholder": "搜索",
"searchResults": "搜索结果",
"noSearchResults": "没有匹配的话。",
"recent": "最近话",
"noSearchResults": "没有匹配的话。",
"recent": "最近话",
"settings": "设置",
"language": {
"label": "语言",
@@ -819,15 +819,15 @@
}
},
"chat": {
"fallbackTitle": "话 {{id}}",
"fallbackTitle": "话 {{id}}",
"forkTitle": "分叉:{{title}}",
"loading": "加载中…",
"noSessions": "还没有话。",
"noSessions": "还没有话。",
"showMore": "再显示 {{count}} 个",
"collapsed": "已折叠 {{count}} 个话",
"collapsed": "已折叠 {{count}} 个话",
"showLess": "收起",
"actions": "“{{title}}” 的话操作",
"newInProject": "在 {{project}} 中开始新话",
"actions": "“{{title}}” 的话操作",
"newInProject": "在 {{project}} 中开始新话",
"activity": {
"running": "Agent 正在运行",
"complete": "Agent 已完成",
@@ -836,9 +836,9 @@
"pin": "置顶",
"unpin": "取消置顶",
"rename": "重命名",
"renameTitle": "重命名话",
"renameDescription": "为这个话设置一个仅用于 WebUI 侧边栏的名称。",
"renamePlaceholder": "话名称",
"renameTitle": "重命名话",
"renameDescription": "为这个话设置一个仅用于 WebUI 侧边栏的名称。",
"renamePlaceholder": "话名称",
"renameProjectTitle": "重命名项目",
"renameProjectDescription": "为这个项目设置一个仅用于 WebUI 侧边栏的名称。",
"renameProjectPlaceholder": "项目名称",
@@ -848,10 +848,10 @@
"showArchived": "显示归档",
"hideArchived": "隐藏归档",
"delete": "删除",
"newChat": "新建话",
"newChat": "新建话",
"groups": {
"pinned": "置顶",
"all": "话",
"all": "话",
"projects": "项目",
"today": "今天",
"yesterday": "昨天",
@@ -860,11 +860,11 @@
}
},
"deleteConfirm": {
"title": "删除这个话?",
"title": "删除这个话",
"description": "此操作无法撤销。",
"cancel": "取消",
"confirm": "删除",
"automationsDescription": "这个话有关联的自动任务。删除话也会删除这些自动任务。",
"automationsDescription": "这个话有关联的自动任务。删除话也会删除这些自动任务。",
"moreAutomations": "另有 {{count}} 个",
"confirmWithAutomations": "删除",
"schedule": {
@@ -891,7 +891,7 @@
"error": "连接出错"
},
"thread": {
"loadingConversation": "正在加载话…",
"loadingConversation": "正在加载话…",
"empty": {
"greetings": {
"workOn": "我们要一起做点什么?",
@@ -954,14 +954,14 @@
},
"header": {
"toggleSidebar": "切换侧边栏",
"newChat": "从顶部新建话",
"newChat": "从顶部新建话",
"toggleTheme": "从顶部切换主题",
"settings": "打开设置",
"sessionInfo": "会话详情"
},
"sessionInfo": {
"title": "会话",
"untitled": "未命名话",
"untitled": "未命名话",
"automations": "自动任务",
"count": "{{count}}",
"loading": "正在加载自动任务...",
@@ -987,7 +987,7 @@
"composer": {
"placeholderThread": "输入消息…",
"placeholderHero": "问任何问题...",
"placeholderOpening": "正在打开新话…",
"placeholderOpening": "正在打开新话…",
"placeholderStreaming": "模型正在回复…",
"inputAria": "消息输入框",
"sendHint": "Enter 发送 · Shift+Enter 换行",
@@ -1065,8 +1065,8 @@
},
"commands": {
"new": {
"title": "新建话",
"description": "重置当前话,并开始一个新的话。"
"title": "新建话",
"description": "重置当前话,并开始一个新的话。"
},
"stop": {
"title": "停止当前任务",
+21 -21
View File
@@ -43,12 +43,12 @@
"sidebar": {
"navigation": "側邊欄導覽",
"collapse": "收合側邊欄",
"newChat": "新增話",
"newChat": "新增話",
"searchAria": "搜尋",
"searchPlaceholder": "搜尋",
"searchResults": "搜尋結果",
"noSearchResults": "沒有符合的話。",
"recent": "最近話",
"noSearchResults": "沒有符合的話。",
"recent": "最近話",
"settings": "設定",
"language": {
"label": "語言",
@@ -805,15 +805,15 @@
}
},
"chat": {
"fallbackTitle": "話 {{id}}",
"fallbackTitle": "話 {{id}}",
"forkTitle": "分支:{{title}}",
"loading": "載入中…",
"noSessions": "目前還沒有話。",
"noSessions": "目前還沒有話。",
"showMore": "再顯示 {{count}} 個",
"collapsed": "已隱藏 {{count}} 個話",
"collapsed": "已隱藏 {{count}} 個話",
"showLess": "收起",
"actions": "「{{title}}」的話操作",
"newInProject": "在 {{project}} 中開始新話",
"actions": "「{{title}}」的話操作",
"newInProject": "在 {{project}} 中開始新話",
"activity": {
"running": "Agent 正在執行",
"complete": "Agent 已完成",
@@ -822,9 +822,9 @@
"pin": "置頂",
"unpin": "取消置頂",
"rename": "重新命名",
"renameTitle": "重新命名話",
"renameDescription": "為這個話選擇僅顯示於本機側邊欄的名稱。",
"renamePlaceholder": "話名稱",
"renameTitle": "重新命名話",
"renameDescription": "為這個話選擇僅顯示於本機側邊欄的名稱。",
"renamePlaceholder": "話名稱",
"renameProjectTitle": "重新命名專案",
"renameProjectDescription": "為這個專案選擇僅顯示於本機側邊欄的名稱。",
"renameProjectPlaceholder": "專案名稱",
@@ -834,10 +834,10 @@
"showArchived": "顯示封存",
"hideArchived": "隱藏封存",
"delete": "刪除",
"newChat": "新增話",
"newChat": "新增話",
"groups": {
"pinned": "置頂",
"all": "話",
"all": "話",
"projects": "專案",
"today": "今天",
"yesterday": "昨天",
@@ -846,11 +846,11 @@
}
},
"deleteConfirm": {
"title": "刪除這個話?",
"title": "刪除這個話",
"description": "此操作無法復原。",
"cancel": "取消",
"confirm": "刪除",
"automationsDescription": "這個話含有已排程的自動任務。刪除話時也會一併刪除這些任務。",
"automationsDescription": "這個話含有已排程的自動任務。刪除話時也會一併刪除這些任務。",
"moreAutomations": "另有 {{count}} 個",
"confirmWithAutomations": "刪除",
"schedule": {
@@ -877,7 +877,7 @@
"error": "連線錯誤"
},
"thread": {
"loadingConversation": "正在載入話…",
"loadingConversation": "正在載入話…",
"empty": {
"greetings": {
"workOn": "我們要一起做點什麼?",
@@ -940,14 +940,14 @@
},
"header": {
"toggleSidebar": "切換側邊欄",
"newChat": "開始新話",
"newChat": "開始新話",
"toggleTheme": "切換佈景主題",
"settings": "開啟設定",
"sessionInfo": "對話詳細資料"
},
"sessionInfo": {
"title": "對話",
"untitled": "未命名話",
"untitled": "未命名話",
"automations": "自動任務",
"count": "{{count}}",
"loading": "正在載入自動任務…",
@@ -973,7 +973,7 @@
"composer": {
"placeholderThread": "輸入訊息…",
"placeholderHero": "任何問題都可以問…",
"placeholderOpening": "正在開啟新話…",
"placeholderOpening": "正在開啟新話…",
"placeholderStreaming": "模型正在回覆…",
"inputAria": "訊息輸入框",
"sendHint": "Enter 送出 · Shift+Enter 換行",
@@ -1042,8 +1042,8 @@
"closeHint": "Esc 關閉",
"commands": {
"new": {
"title": "新增話",
"description": "重置目前話,並開始新的話。"
"title": "新增話",
"description": "重置目前話,並開始新的話。"
},
"stop": {
"title": "停止目前任務",
+20 -20
View File
@@ -858,13 +858,13 @@ describe("App layout", () => {
).toBeInTheDocument(),
);
fireEvent.pointerDown(screen.getByLabelText("Chat actions for First chat"), {
fireEvent.pointerDown(screen.getByLabelText("Topic actions for First chat"), {
button: 0,
});
fireEvent.click(await screen.findByRole("menuitem", { name: "Delete" }));
await waitFor(() =>
expect(screen.getByText("Delete this chat?")).toBeInTheDocument(),
expect(screen.getByText("Delete this topic?")).toBeInTheDocument(),
);
fireEvent.click(screen.getByRole("button", { name: "Delete" }));
@@ -876,7 +876,7 @@ describe("App layout", () => {
within(sidebar).getByRole("button", { name: /^Second chat$/ }),
).toBeInTheDocument(),
);
expect(screen.queryByText("Delete this chat?")).not.toBeInTheDocument();
expect(screen.queryByText("Delete this topic?")).not.toBeInTheDocument();
expect(document.body.style.pointerEvents).not.toBe("none");
}, 15_000);
@@ -921,7 +921,7 @@ describe("App layout", () => {
).toBeInTheDocument(),
);
fireEvent.pointerDown(screen.getByLabelText(/First chat.*话操作/), {
fireEvent.pointerDown(screen.getByLabelText(/First chat.*话操作/), {
button: 0,
});
fireEvent.click(await screen.findByRole("menuitem", { name: "删除" }));
@@ -931,7 +931,7 @@ describe("App layout", () => {
);
expect(getSessionAutomationsSpy).toHaveBeenCalledWith("websocket:chat-a");
expect(
screen.getByText("这个话有关联的自动任务。删除话也会删除这些自动任务。"),
screen.getByText("这个话有关联的自动任务。删除话也会删除这些自动任务。"),
).toBeInTheDocument();
expect(
screen.queryByText("This chat has scheduled automations. Deleting it will also delete them."),
@@ -989,7 +989,7 @@ describe("App layout", () => {
);
fireEvent.pointerDown(
within(mobileSidebar).getByLabelText("Chat actions for Existing chat"),
within(mobileSidebar).getByLabelText("Topic actions for Existing chat"),
{ button: 0 },
);
@@ -1000,7 +1000,7 @@ describe("App layout", () => {
fireEvent.click(deleteItem);
await waitFor(() =>
expect(screen.getByText("Delete this chat?")).toBeInTheDocument(),
expect(screen.getByText("Delete this topic?")).toBeInTheDocument(),
);
}, 15_000);
@@ -1143,16 +1143,16 @@ describe("App layout", () => {
await waitFor(() => expect(connectSpy).toHaveBeenCalled());
const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" });
await waitFor(() =>
expect(within(sidebar).getByText("Chats")).toBeInTheDocument(),
expect(within(sidebar).getByText("Topics")).toBeInTheDocument(),
);
const group = within(sidebar).getByText("Chats").closest("section");
const group = within(sidebar).getByText("Topics").closest("section");
expect(group).toBeTruthy();
const labels = within(group as HTMLElement)
.getAllByRole("button")
.map((button) => button.textContent?.trim())
.filter(Boolean);
expect(labels).toEqual(["Alpha plan", "New chat", "Zulu work"]);
expect(labels).toEqual(["Alpha plan", "New topic", "Zulu work"]);
});
it("shows running and completed session indicators in the sidebar", async () => {
@@ -1969,7 +1969,7 @@ describe("App layout", () => {
await waitFor(() => expect(connectSpy).toHaveBeenCalled());
const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" });
fireEvent.click(within(sidebar).getByRole("button", { name: "New chat" }));
fireEvent.click(within(sidebar).getByRole("button", { name: "New topic" }));
await waitFor(() => expect(document.title).toBe("nanobot"));
fireEvent.click(within(sidebar).getByRole("button", { name: "Settings" }));
@@ -2009,7 +2009,7 @@ describe("App layout", () => {
const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" });
expect(within(sidebar).getByText("Q2 roadmap")).toBeInTheDocument();
expect(within(sidebar).getByText("Travel ideas")).toBeInTheDocument();
const newChatButton = within(sidebar).getByRole("button", { name: "New chat" });
const newChatButton = within(sidebar).getByRole("button", { name: "New topic" });
const searchButton = within(sidebar).getByRole("button", { name: "Search" });
expect(
newChatButton.compareDocumentPosition(searchButton) &
@@ -2139,10 +2139,10 @@ describe("App layout", () => {
await waitFor(() => expect(connectSpy).toHaveBeenCalled());
const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" });
const newChatButton = within(sidebar).getByRole("button", { name: "New chat" });
const newChatButton = within(sidebar).getByRole("button", { name: "New topic" });
expect(newChatButton).toHaveAttribute(
"title",
"New chat (Ctrl+Shift+O)",
"New topic (Ctrl+Shift+O)",
);
expect(newChatButton).toHaveAttribute(
"aria-keyshortcuts",
@@ -2157,9 +2157,9 @@ describe("App layout", () => {
await waitFor(() => expect(connectSpy).toHaveBeenCalled());
const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" });
expect(within(sidebar).getByRole("button", { name: "New chat" })).toHaveAttribute(
expect(within(sidebar).getByRole("button", { name: "New topic" })).toHaveAttribute(
"title",
"New chat (⌘⇧O)",
"New topic (⌘⇧O)",
);
});
@@ -2230,9 +2230,9 @@ describe("App layout", () => {
const sidebarAside = container.querySelector("aside.lg\\:block") as HTMLElement;
await waitFor(() => expect(sidebarAside.style.width).toBe("56px"));
expect(screen.queryByRole("button", { name: "Start a new chat" })).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Start a new topic" })).not.toBeInTheDocument();
const rail = screen.getByRole("navigation", { name: "Sidebar navigation" });
expect(within(rail).getByRole("button", { name: "New chat" })).toBeInTheDocument();
expect(within(rail).getByRole("button", { name: "New topic" })).toBeInTheDocument();
expect(within(rail).getByRole("button", { name: "Search" })).toBeInTheDocument();
expect(within(rail).queryByRole("button", { name: "View" })).not.toBeInTheDocument();
expect(within(rail).queryByText("Existing chat")).not.toBeInTheDocument();
@@ -2241,10 +2241,10 @@ describe("App layout", () => {
await waitFor(() => expect(sidebarAside.style.width).toBe("272px"));
const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" });
fireEvent.click(within(sidebar).getByRole("button", { name: "New chat" }));
fireEvent.click(within(sidebar).getByRole("button", { name: "New topic" }));
expect(createChatSpy).not.toHaveBeenCalled();
expect(screen.getByText(HERO_GREETING_PATTERN)).toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Start a new chat" })).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Start a new topic" })).not.toBeInTheDocument();
expect(screen.getByRole("button", { name: "Toggle theme from header" })).toBeInTheDocument();
expect(within(sidebar).getByRole("button", { name: "Settings" })).toBeInTheDocument();
+13 -13
View File
@@ -142,7 +142,7 @@ describe("ChatList", () => {
expect(screen.queryByText("Today")).not.toBeInTheDocument();
});
it("keeps default workspace chats in the Chats section instead of a project folder", () => {
it("keeps default workspace topics in the Topics section instead of a project folder", () => {
const sessions = [
session({
chatId: "default",
@@ -184,7 +184,7 @@ describe("ChatList", () => {
expect(screen.getByRole("region", { name: "nanobot" })).toBeInTheDocument();
expect(screen.queryByRole("region", { name: "workspace" })).not.toBeInTheDocument();
const chatsSection = screen.getByRole("region", { name: "Chats" });
const chatsSection = screen.getByRole("region", { name: "Topics" });
expect(within(chatsSection).getByText("Default workspace chat")).toBeInTheDocument();
expect(within(chatsSection).queryByText("Project chat")).not.toBeInTheDocument();
});
@@ -229,13 +229,13 @@ describe("ChatList", () => {
expect(within(projectSection).queryByText("Alpha task")).not.toBeInTheDocument();
fireEvent.click(
within(projectSection).getByRole("button", { name: "Start a new chat in Photos" }),
within(projectSection).getByRole("button", { name: "Start a new topic in Photos" }),
);
expect(onNewChatInProject).toHaveBeenCalledWith("/Users/me/nanobot", "Photos");
expect(onToggleGroup).toHaveBeenCalledTimes(1);
fireEvent.pointerDown(
within(projectSection).getByLabelText("Chat actions for Photos"),
within(projectSection).getByLabelText("Topic actions for Photos"),
{ button: 0 },
);
fireEvent.click(await screen.findByRole("menuitem", { name: "Rename" }));
@@ -300,13 +300,13 @@ describe("ChatList", () => {
};
const { rerender } = render(<ChatList {...baseProps} />);
const chatsSection = screen.getByRole("region", { name: "Chats" });
const chatsSection = screen.getByRole("region", { name: "Topics" });
expect(within(chatsSection).getByText("Chat 9")).toBeInTheDocument();
expect(within(chatsSection).getByText("Chat 2")).toBeInTheDocument();
expect(within(chatsSection).queryByText("Chat 1")).not.toBeInTheDocument();
expect(within(chatsSection).queryByRole("button", { name: "Show all" })).not.toBeInTheDocument();
fireEvent.click(within(chatsSection).getByRole("button", { name: "2 hidden chats" }));
fireEvent.click(within(chatsSection).getByRole("button", { name: "2 hidden topics" }));
expect(onToggleGroup).toHaveBeenCalledWith("workspace:chats");
@@ -321,7 +321,7 @@ describe("ChatList", () => {
expect(within(chatsSection).getByRole("button", { name: "Show less" })).toBeInTheDocument();
});
it("sorts Chats section among project groups by recency, not always last", () => {
it("sorts Topics section among project groups by recency, not always last", () => {
const sessions = [
session({
chatId: "recent-chat",
@@ -367,8 +367,8 @@ describe("ChatList", () => {
const regionNames = allRegions.map((r) => r.getAttribute("aria-label") ?? r.textContent);
// The most recently updated conversation ("Recent chat" at 12:00) must be
// in the first group — Chats should come before both projects.
const chatsIdx = regionNames.findIndex((n) => n?.includes("Chats"));
// in the first group — Topics should come before both projects.
const chatsIdx = regionNames.findIndex((n) => n?.includes("Topics"));
const projAIdx = regionNames.findIndex((n) => n?.includes("project-a"));
const projBIdx = regionNames.findIndex((n) => n?.includes("project-b"));
@@ -377,7 +377,7 @@ describe("ChatList", () => {
expect(within(allRegions[chatsIdx]).getByText("Recent chat")).toBeInTheDocument();
});
it("keeps one Projects heading when Chats sorts between project groups", () => {
it("keeps one Projects heading when Topics sorts between project groups", () => {
const sessions = [
session({
chatId: "project-a",
@@ -423,11 +423,11 @@ describe("ChatList", () => {
.getAllByRole("region")
.map((r) => r.getAttribute("aria-label") ?? "");
expect(regionNames).toEqual(["project-a", "Chats", "project-b"]);
expect(regionNames).toEqual(["project-a", "Topics", "project-b"]);
expect(screen.getAllByText("Projects")).toHaveLength(1);
});
it("keeps Chats last when its latest conversation is older than all projects", () => {
it("keeps Topics last when its latest conversation is older than all projects", () => {
const sessions = [
session({
chatId: "project-a",
@@ -473,7 +473,7 @@ describe("ChatList", () => {
.getAllByRole("region")
.map((r) => r.getAttribute("aria-label") ?? "");
expect(regionNames).toEqual(["project-a", "project-b", "Chats"]);
expect(regionNames).toEqual(["project-a", "project-b", "Topics"]);
expect(screen.getAllByText("Projects")).toHaveLength(1);
});
});
+1 -1
View File
@@ -445,7 +445,7 @@ describe("webui i18n", () => {
const chat = resources["pt-BR"].common.chat;
expect(sidebar.settings).toBe("Configurações");
expect(chat.newChat).toBe("Nova conversa");
expect(chat.newChat).toBe("Novo tópico");
expect(settings.nav.browser).toBe("Web");
expect(settings.sections.webSearch).toBe("Busca na web");
expect(settings.byok.tabs.webSearch).toBe("Busca na web");
+1 -1
View File
@@ -71,7 +71,7 @@ describe("useSessions", () => {
updatedAt: "2026-04-16T10:00:00Z",
title: "",
preview: "hi",
})).toBe("New chat");
})).toBe("New topic");
expect(sessionTitle({
key: "websocket:chat-work",