Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0430998
feat: move slash commands to settings tab with gear icon for discover…
roomote Sep 15, 2025
46ae66c
feat: simplify slash commands popover and add settings navigation
roomote Sep 15, 2025
bd9a499
ux: Makes text area buttons appear only when there's text (#7987)
brunobergher Sep 15, 2025
a1f8b7d
Removes SlashCommand icon from textarea
brunobergher Sep 15, 2025
f4ab67a
Reorders settings for slash commands
brunobergher Sep 15, 2025
620cf3d
Ensures the gear icon in slash commands goes to the right place in se…
brunobergher Sep 15, 2025
d0ce642
Visual tweaks to make the settings cog work in the slashcommands popo…
brunobergher Sep 15, 2025
690f680
Makes the intro copy for slash commands only appear when there's no s…
brunobergher Sep 15, 2025
6173797
test: add comprehensive test coverage for SlashCommandItemSimple and …
roomote Sep 15, 2025
8801439
fix: corrected C# tree-sitter query (#7813)
mubeen-zulfiqar Sep 15, 2025
05540da
Removes unused components
brunobergher Sep 15, 2025
8041639
Adds translations (including old stuff which had never been localized)
brunobergher Sep 15, 2025
c5df5e4
Merge remote-tracking branch 'origin/main' into feat/slash-commands-s…
mrubens Sep 15, 2025
a09893c
Update webview-ui/src/i18n/locales/ca/chat.json
mrubens Sep 15, 2025
9e86f9a
Update webview-ui/src/i18n/locales/fr/settings.json
mrubens Sep 15, 2025
3eac654
Update webview-ui/src/i18n/locales/ja/chat.json
mrubens Sep 15, 2025
4752dfd
Update webview-ui/src/i18n/locales/nl/chat.json
mrubens Sep 15, 2025
365c817
Update webview-ui/src/i18n/locales/zh-TW/chat.json
mrubens Sep 15, 2025
bb43eb2
Delete webview-ui/src/__tests__/SettingsTabNavigation.spec.tsx
mrubens Sep 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2776,7 +2776,12 @@ export const webviewMessageHandler = async (
TelemetryService.instance.captureTabShown(message.tab)
}

await provider.postMessageToWebview({ type: "action", action: "switchTab", tab: message.tab })
await provider.postMessageToWebview({
type: "action",
action: "switchTab",
tab: message.tab,
values: message.values,
})
}
break
}
Expand Down
4 changes: 4 additions & 0 deletions src/i18n/locales/ca/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/de/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -215,5 +215,9 @@
"preventCompletionWithOpenTodos": {
"description": "Prevent task completion when there are incomplete todos in the todo list"
}
},
"docsLink": {
"label": "Docs",
"url": "https://docs.roocode.com"
}
}
4 changes: 4 additions & 0 deletions src/i18n/locales/es/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/fr/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/hi/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/id/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/it/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/ja/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/ko/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/nl/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/pl/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/pt-BR/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/ru/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/tr/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/vi/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/zh-CN/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/i18n/locales/zh-TW/common.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion webview-ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ const App = () => {
if (message.action === "switchTab" && message.tab) {
const targetTab = message.tab as Tab
switchTab(targetTab)
setCurrentSection(undefined)
// Extract targetSection from values if provided
const targetSection = message.values?.section as string | undefined
setCurrentSection(targetSection)
setCurrentMarketplaceTab(undefined)
} else {
// Handle other actions using the mapping
Expand Down
150 changes: 150 additions & 0 deletions webview-ui/src/__tests__/SettingsTabNavigation.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import React from "react"
import { render, waitFor } from "@testing-library/react"
import { vi } from "vitest"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"

import App from "../App"
import TranslationProvider from "../i18n/TranslationContext"

// Mock vscode API
const mockPostMessage = vi.fn()
vi.mock("../utils/vscode", () => ({
vscode: {
postMessage: (message: any) => mockPostMessage(message),
},
}))

// Mock extension state
const mockExtensionState = {
Copy link
Collaborator

@mrubens mrubens Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I try to avoid these mockExtensionState tests, since you always need to maintain them when you add new things to extension state. Is there a way to write this test without it? If not I might just cut the test.

didHydrateState: true,
showWelcome: false,
shouldShowAnnouncement: false,
telemetrySetting: "off" as const,
telemetryKey: undefined,
machineId: "test-machine-id",
cloudUserInfo: null,
cloudIsAuthenticated: false,
cloudApiUrl: undefined,
renderContext: "editor" as const,
mdmCompliant: true,
currentApiConfigName: "test-config",
listApiConfigMeta: [],
apiConfiguration: {},
experiments: {},
customModes: [],
mode: { slug: "code", name: "Code" },
clineMessages: [],
taskHistory: [],
version: "1.0.0",
writeDelayMs: 100,
requestDelaySeconds: 1,
enableCheckpoints: false,
maxOpenTabsContext: 10,
maxWorkspaceFiles: 100,
showRooIgnoredFiles: false,
maxReadFileLine: 1000,
maxImageFileSize: 5,
maxTotalImageSize: 20,
mcpEnabled: false,
enableMcpServerCreation: false,
sharingEnabled: false,
organizationAllowList: {
enabled: false,
allowed: [],
providers: {},
},
autoCondenseContext: false,
autoCondenseContextPercent: 50,
profileThresholds: {},
hasOpenedModeSelector: false,
remoteControlEnabled: false,
taskSyncEnabled: false,
featureRoomoteControlEnabled: false,
// Add missing properties required by ChatView components
openedTabs: [],
filePaths: [],
commands: [],
gitCommits: [],
browserToolEnabled: false,
mcpServers: [],
}

vi.mock("../context/ExtensionStateContext", () => ({
ExtensionStateContextProvider: ({ children }: { children: React.ReactNode }) => children,
useExtensionState: () => mockExtensionState,
}))

describe("Settings Tab Navigation", () => {
let queryClient: QueryClient

beforeEach(() => {
queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
})
mockPostMessage.mockClear()
})

it("should navigate to slash commands section when handleSettingsClick is called", async () => {
const { container } = render(
<QueryClientProvider client={queryClient}>
<TranslationProvider>
<App />
</TranslationProvider>
</QueryClientProvider>,
)

// Simulate message from ContextMenu to switch to settings tab with targetSection
const messageEvent = new MessageEvent("message", {
data: {
type: "action",
action: "switchTab",
tab: "settings",
values: { section: "slashCommands" },
},
})
window.dispatchEvent(messageEvent)

// Wait for the settings view to render
await waitFor(() => {
const slashCommandsTab = container.querySelector('[data-testid="tab-slashCommands"]')
expect(slashCommandsTab).toBeTruthy()
})

// Verify the slash commands tab is active
const slashCommandsTab = container.querySelector('[data-testid="tab-slashCommands"]')
expect(slashCommandsTab?.getAttribute("aria-selected")).toBe("true")
})

it("should switch to settings tab without a specific section", async () => {
const { container } = render(
<QueryClientProvider client={queryClient}>
<TranslationProvider>
<App />
</TranslationProvider>
</QueryClientProvider>,
)

// Simulate message to switch to settings tab without targetSection
const messageEvent = new MessageEvent("message", {
data: {
type: "action",
action: "switchTab",
tab: "settings",
},
})
window.dispatchEvent(messageEvent)

// Wait for the settings view to render
await waitFor(() => {
const providersTab = container.querySelector('[data-testid="tab-providers"]')
expect(providersTab).toBeTruthy()
})

// Verify the default providers tab is active
const providersTab = container.querySelector('[data-testid="tab-providers"]')
expect(providersTab?.getAttribute("aria-selected")).toBe("true")
})
})
2 changes: 0 additions & 2 deletions webview-ui/src/components/chat/ChatTextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import { AutoApproveDropdown } from "./AutoApproveDropdown"
import { MAX_IMAGES_PER_MESSAGE } from "./ChatView"
import ContextMenu from "./ContextMenu"
import { IndexingStatusBadge } from "./IndexingStatusBadge"
import { SlashCommandsPopover } from "./SlashCommandsPopover"
import { usePromptHistory } from "./hooks/usePromptHistory"

interface ChatTextAreaProps {
Expand Down Expand Up @@ -1232,7 +1231,6 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
</button>
</StandardTooltip>
)}
{!isEditMode ? <SlashCommandsPopover /> : null}
{!isEditMode ? <IndexingStatusBadge /> : null}
<StandardTooltip content={t("chat:addImages")}>
<button
Expand Down
Loading
Loading