mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Co-authored-by: Daniel Riccio <ricciodaniel98@gmail.com>
This commit is contained in:
parent
000a9e5268
commit
904e956179
21 changed files with 209 additions and 1 deletions
|
|
@ -33,6 +33,7 @@ import RooTips from "@src/components/welcome/RooTips"
|
|||
import { StandardTooltip } from "@src/components/ui"
|
||||
|
||||
import TelemetryBanner from "../common/TelemetryBanner"
|
||||
import VersionIndicator from "../common/VersionIndicator"
|
||||
import { useTaskSearch } from "../history/useTaskSearch"
|
||||
import HistoryPreview from "../history/HistoryPreview"
|
||||
import Announcement from "./Announcement"
|
||||
|
|
@ -151,6 +152,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
const [wasStreaming, setWasStreaming] = useState<boolean>(false)
|
||||
const [showCheckpointWarning, setShowCheckpointWarning] = useState<boolean>(false)
|
||||
const [isCondensing, setIsCondensing] = useState<boolean>(false)
|
||||
const [showAnnouncementModal, setShowAnnouncementModal] = useState(false)
|
||||
const everVisibleMessagesTsRef = useRef<LRUCache<number, boolean>>(
|
||||
new LRUCache({
|
||||
max: 250,
|
||||
|
|
@ -1365,7 +1367,21 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
|
||||
return (
|
||||
<div className={isHidden ? "hidden" : "fixed top-0 left-0 right-0 bottom-0 flex flex-col overflow-hidden"}>
|
||||
{showAnnouncement && <Announcement hideAnnouncement={hideAnnouncement} />}
|
||||
{/* Version indicator in top-right corner */}
|
||||
<VersionIndicator onClick={() => setShowAnnouncementModal(true)} className="absolute top-2 right-3 z-10" />
|
||||
|
||||
{(showAnnouncement || showAnnouncementModal) && (
|
||||
<Announcement
|
||||
hideAnnouncement={() => {
|
||||
if (showAnnouncementModal) {
|
||||
setShowAnnouncementModal(false)
|
||||
}
|
||||
if (showAnnouncement) {
|
||||
hideAnnouncement()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{task ? (
|
||||
<>
|
||||
<TaskHeader
|
||||
|
|
|
|||
|
|
@ -61,6 +61,55 @@ vi.mock("../AutoApproveMenu", () => ({
|
|||
default: () => null,
|
||||
}))
|
||||
|
||||
vi.mock("@src/components/common/VersionIndicator", () => ({
|
||||
default: function MockVersionIndicator({ onClick, className }: { onClick: () => void; className?: string }) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const React = require("react")
|
||||
return React.createElement(
|
||||
"button",
|
||||
{
|
||||
onClick,
|
||||
className,
|
||||
"aria-label": "chat:versionIndicator.ariaLabel",
|
||||
"data-testid": "version-indicator",
|
||||
},
|
||||
"v3.21.5",
|
||||
)
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock("@src/components/modals/Announcement", () => ({
|
||||
default: function MockAnnouncement({ hideAnnouncement }: { hideAnnouncement: () => void }) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const React = require("react")
|
||||
return React.createElement(
|
||||
"div",
|
||||
{ "data-testid": "announcement-modal" },
|
||||
React.createElement("div", null, "What's New"),
|
||||
React.createElement("button", { onClick: hideAnnouncement }, "Close"),
|
||||
)
|
||||
},
|
||||
}))
|
||||
|
||||
// Mock i18n
|
||||
vi.mock("react-i18next", () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string, options?: any) => {
|
||||
if (key === "chat:versionIndicator.ariaLabel" && options?.version) {
|
||||
return `Version ${options.version}`
|
||||
}
|
||||
return key
|
||||
},
|
||||
}),
|
||||
initReactI18next: {
|
||||
type: "3rdParty",
|
||||
init: () => {},
|
||||
},
|
||||
Trans: ({ i18nKey, children }: { i18nKey: string; children?: React.ReactNode }) => {
|
||||
return <>{children || i18nKey}</>
|
||||
},
|
||||
}))
|
||||
|
||||
interface ChatTextAreaProps {
|
||||
onSend: (value: string) => void
|
||||
inputValue?: string
|
||||
|
|
@ -1068,3 +1117,69 @@ describe("ChatView - Focus Grabbing Tests", () => {
|
|||
expect(mockFocus).toHaveBeenCalledTimes(FOCUS_CALLS_ON_INIT)
|
||||
})
|
||||
})
|
||||
|
||||
describe("ChatView - Version Indicator Tests", () => {
|
||||
beforeEach(() => vi.clearAllMocks())
|
||||
|
||||
it("displays version indicator button", () => {
|
||||
const { getByLabelText } = renderChatView()
|
||||
|
||||
// First hydrate state
|
||||
mockPostMessage({
|
||||
clineMessages: [],
|
||||
})
|
||||
|
||||
// Check that version indicator is displayed
|
||||
const versionButton = getByLabelText(/version/i)
|
||||
expect(versionButton).toBeInTheDocument()
|
||||
expect(versionButton).toHaveTextContent(/^v\d+\.\d+\.\d+/)
|
||||
})
|
||||
|
||||
it("opens announcement modal when version indicator is clicked", () => {
|
||||
const { container } = renderChatView()
|
||||
|
||||
// First hydrate state
|
||||
mockPostMessage({
|
||||
clineMessages: [],
|
||||
})
|
||||
|
||||
// Find version indicator
|
||||
const versionButton = container.querySelector('button[aria-label*="version"]') as HTMLButtonElement
|
||||
expect(versionButton).toBeTruthy()
|
||||
|
||||
// Click should trigger modal - we'll just verify the button exists and is clickable
|
||||
// The actual modal rendering is handled by the component state
|
||||
expect(versionButton.onclick).toBeDefined()
|
||||
})
|
||||
|
||||
it("version indicator has correct styling classes", () => {
|
||||
const { getByTestId } = renderChatView()
|
||||
|
||||
// First hydrate state
|
||||
mockPostMessage({
|
||||
clineMessages: [],
|
||||
})
|
||||
|
||||
// Check styling classes - the VersionIndicator component receives className prop
|
||||
const versionButton = getByTestId("version-indicator")
|
||||
expect(versionButton).toBeInTheDocument()
|
||||
// The className is passed as a prop to VersionIndicator
|
||||
expect(versionButton.className).toContain("absolute top-2 right-3 z-10")
|
||||
})
|
||||
|
||||
it("version indicator has proper accessibility attributes", () => {
|
||||
const { container } = renderChatView()
|
||||
|
||||
// First hydrate state
|
||||
mockPostMessage({
|
||||
clineMessages: [],
|
||||
})
|
||||
|
||||
// Check accessibility - find button by its content
|
||||
const versionButton = container.querySelector('button[aria-label*="version"]')
|
||||
expect(versionButton).toBeTruthy()
|
||||
expect(versionButton).toHaveAttribute("aria-label")
|
||||
// The mock returns the key, so we check for that
|
||||
expect(versionButton?.getAttribute("aria-label")).toBe("chat:versionIndicator.ariaLabel")
|
||||
})
|
||||
})
|
||||
|
|
|
|||
23
webview-ui/src/components/common/VersionIndicator.tsx
Normal file
23
webview-ui/src/components/common/VersionIndicator.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import React from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { Package } from "@roo/package"
|
||||
|
||||
interface VersionIndicatorProps {
|
||||
onClick: () => void
|
||||
className?: string
|
||||
}
|
||||
|
||||
const VersionIndicator: React.FC<VersionIndicatorProps> = ({ onClick, className = "" }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className={`text-xs text-vscode-descriptionForeground hover:text-vscode-foreground transition-colors cursor-pointer px-2 py-1 rounded border border-vscode-panel-border hover:border-vscode-focusBorder ${className}`}
|
||||
aria-label={t("chat:versionIndicator.ariaLabel", { version: Package.version })}>
|
||||
v{Package.version}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
export default VersionIndicator
|
||||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Indexat",
|
||||
"error": "Error d'índex",
|
||||
"status": "Estat de l'índex"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Versió {{version}} - Feu clic per veure les notes de llançament"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Indiziert",
|
||||
"error": "Index-Fehler",
|
||||
"status": "Index-Status"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Version {{version}} - Klicken Sie, um die Versionshinweise anzuzeigen"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Indexed",
|
||||
"error": "Index error",
|
||||
"status": "Index status"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Version {{version}} - Click to view release notes"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Indexado",
|
||||
"error": "Error de índice",
|
||||
"status": "Estado del índice"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Versión {{version}} - Haz clic para ver las notas de la versión"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Indexé",
|
||||
"error": "Erreur d'index",
|
||||
"status": "Statut de l'index"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Version {{version}} - Cliquez pour voir les notes de version"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "इंडेक्स किया गया",
|
||||
"error": "इंडेक्स त्रुटि",
|
||||
"status": "इंडेक्स स्थिति"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "संस्करण {{version}} - रिलीज़ नोट्स देखने के लिए क्लिक करें"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,5 +316,8 @@
|
|||
"indexed": "Terindeks",
|
||||
"error": "Error indeks",
|
||||
"status": "Status indeks"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Versi {{version}} - Klik untuk melihat catatan rilis"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Indicizzato",
|
||||
"error": "Errore indice",
|
||||
"status": "Stato indice"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Versione {{version}} - Clicca per visualizzare le note di rilascio"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "インデックス作成済み",
|
||||
"error": "インデックスエラー",
|
||||
"status": "インデックス状態"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "バージョン {{version}} - クリックしてリリースノートを表示"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "인덱싱 완료",
|
||||
"error": "인덱스 오류",
|
||||
"status": "인덱스 상태"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "버전 {{version}} - 릴리스 노트를 보려면 클릭하세요"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Geïndexeerd",
|
||||
"error": "Index fout",
|
||||
"status": "Index status"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Versie {{version}} - Klik om release notes te bekijken"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Zaindeksowane",
|
||||
"error": "Błąd indeksu",
|
||||
"status": "Status indeksu"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Wersja {{version}} - Kliknij, aby wyświetlić informacje o wydaniu"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Indexado",
|
||||
"error": "Erro do índice",
|
||||
"status": "Status do índice"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Versão {{version}} - Clique para ver as notas de lançamento"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Проиндексировано",
|
||||
"error": "Ошибка индекса",
|
||||
"status": "Статус индекса"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Версия {{version}} - Нажмите, чтобы просмотреть примечания к выпуску"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "İndekslendi",
|
||||
"error": "İndeks hatası",
|
||||
"status": "İndeks durumu"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Sürüm {{version}} - Sürüm notlarını görüntülemek için tıklayın"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "Đã lập chỉ mục",
|
||||
"error": "Lỗi chỉ mục",
|
||||
"status": "Trạng thái chỉ mục"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "Phiên bản {{version}} - Nhấp để xem ghi chú phát hành"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "已索引",
|
||||
"error": "索引错误",
|
||||
"status": "索引状态"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "版本 {{version}} - 点击查看发布说明"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,5 +310,8 @@
|
|||
"indexed": "已索引",
|
||||
"error": "索引錯誤",
|
||||
"status": "索引狀態"
|
||||
},
|
||||
"versionIndicator": {
|
||||
"ariaLabel": "版本 {{version}} - 點擊查看發布說明"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue