Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion webview-ui/src/components/settings/About.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const About = ({ telemetrySetting, setTelemetrySetting, className, ...pro
</SectionHeader>

<Section>
<div>
<div data-setting-id="telemetrySetting">
<VSCodeCheckbox
checked={telemetrySetting === "enabled"}
onChange={(e: any) => {
Expand Down
22 changes: 11 additions & 11 deletions webview-ui/src/components/settings/AutoApproveSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export const AutoApproveSettings = ({
<span className="codicon codicon-eye" />
<div>{t("settings:autoApprove.readOnly.label")}</div>
</div>
<div>
<div data-setting-id="alwaysAllowReadOnlyOutsideWorkspace">
<VSCodeCheckbox
checked={alwaysAllowReadOnlyOutsideWorkspace}
onChange={(e: any) =>
Expand All @@ -185,7 +185,7 @@ export const AutoApproveSettings = ({
<span className="codicon codicon-edit" />
<div>{t("settings:autoApprove.write.label")}</div>
</div>
<div>
<div data-setting-id="alwaysAllowWriteOutsideWorkspace">
<VSCodeCheckbox
checked={alwaysAllowWriteOutsideWorkspace}
onChange={(e: any) =>
Expand All @@ -200,7 +200,7 @@ export const AutoApproveSettings = ({
{t("settings:autoApprove.write.outsideWorkspace.description")}
</div>
</div>
<div>
<div data-setting-id="alwaysAllowWriteProtected">
<VSCodeCheckbox
checked={alwaysAllowWriteProtected}
onChange={(e: any) =>
Expand All @@ -222,7 +222,7 @@ export const AutoApproveSettings = ({
<span className="codicon codicon-refresh" />
<div>{t("settings:autoApprove.retry.label")}</div>
</div>
<div>
<div data-setting-id="requestDelaySeconds">
<div className="flex items-center gap-2">
<Slider
min={5}
Expand All @@ -247,7 +247,7 @@ export const AutoApproveSettings = ({
<span className="codicon codicon-question" />
<div>{t("settings:autoApprove.followupQuestions.label")}</div>
</div>
<div>
<div data-setting-id="followupAutoApproveTimeoutMs">
<div className="flex items-center gap-2">
<Slider
min={1000}
Expand Down Expand Up @@ -275,12 +275,12 @@ export const AutoApproveSettings = ({
<div>{t("settings:autoApprove.execute.label")}</div>
</div>

<div>
<div data-setting-id="allowedCommands">
<label className="block font-medium mb-1" data-testid="allowed-commands-heading">
{t("settings:autoApprove.execute.allowedCommands")}
{t("settings:autoApprove.execute.allowedCommands.label")}
</label>
<div className="text-vscode-descriptionForeground text-sm mt-1">
{t("settings:autoApprove.execute.allowedCommandsDescription")}
{t("settings:autoApprove.execute.allowedCommands.description")}
</div>
</div>

Expand Down Expand Up @@ -323,12 +323,12 @@ export const AutoApproveSettings = ({
</div>

{/* Denied Commands Section */}
<div className="mt-6">
<div className="mt-6" data-setting-id="deniedCommands">
<label className="block font-medium mb-1" data-testid="denied-commands-heading">
{t("settings:autoApprove.execute.deniedCommands")}
{t("settings:autoApprove.execute.deniedCommands.label")}
</label>
<div className="text-vscode-descriptionForeground text-sm mt-1">
{t("settings:autoApprove.execute.deniedCommandsDescription")}
{t("settings:autoApprove.execute.deniedCommands.description")}
</div>
</div>

Expand Down
1 change: 1 addition & 0 deletions webview-ui/src/components/settings/AutoApproveToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export const AutoApproveToggle = ({ onToggle, ...props }: AutoApproveToggleProps
aria-label={t(labelKey)}
aria-pressed={!!props[key]}
data-testid={testId}
data-setting-id={key}
className={cn(" aspect-square h-[80px]", !props[key] && "opacity-50")}>
<span className={cn("flex flex-col items-center gap-1")}>
<span className={`codicon codicon-${icon}`} />
Expand Down
10 changes: 5 additions & 5 deletions webview-ui/src/components/settings/BrowserSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const BrowserSettings = ({
</SectionHeader>

<Section>
<div>
<div data-setting-id="browserToolEnabled">
<VSCodeCheckbox
checked={browserToolEnabled}
onChange={(e: any) => setCachedStateField("browserToolEnabled", e.target.checked)}>
Expand All @@ -126,7 +126,7 @@ export const BrowserSettings = ({

{browserToolEnabled && (
<div className="flex flex-col gap-3 pl-3 border-l-2 border-vscode-button-background">
<div>
<div data-setting-id="browserViewportSize">
<label className="block font-medium mb-1">{t("settings:browser.viewport.label")}</label>
<Select
value={browserViewportSize}
Expand All @@ -149,7 +149,7 @@ export const BrowserSettings = ({
</div>
</div>

<div>
<div data-setting-id="screenshotQuality">
<label className="block font-medium mb-1">
{t("settings:browser.screenshotQuality.label")}
</label>
Expand All @@ -168,7 +168,7 @@ export const BrowserSettings = ({
</div>
</div>

<div>
<div data-setting-id="remoteBrowserEnabled">
<VSCodeCheckbox
checked={remoteBrowserEnabled}
onChange={(e: any) => {
Expand All @@ -189,7 +189,7 @@ export const BrowserSettings = ({

{remoteBrowserEnabled && (
<>
<div className="flex items-center gap-2">
<div className="flex items-center gap-2" data-setting-id="remoteBrowserHost">
<VSCodeTextField
value={remoteBrowserHost ?? ""}
onChange={(e: any) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const CheckpointSettings = ({ enableCheckpoints, setCachedStateField, ...
</SectionHeader>

<Section>
<div>
<div data-setting-id="enableCheckpoints">
<VSCodeCheckbox
checked={enableCheckpoints}
onChange={(e: any) => {
Expand Down
28 changes: 15 additions & 13 deletions webview-ui/src/components/settings/ContextManagementSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const ContextManagementSettings = ({
</SectionHeader>

<Section>
<div>
<div data-setting-id="maxOpenTabsContext">
<span className="block font-medium mb-1">{t("settings:contextManagement.openTabs.label")}</span>
<div className="flex items-center gap-2">
<Slider
Expand All @@ -116,7 +116,7 @@ export const ContextManagementSettings = ({
</div>
</div>

<div>
<div data-setting-id="maxWorkspaceFiles">
<span className="block font-medium mb-1">
{t("settings:contextManagement.workspaceFiles.label")}
</span>
Expand All @@ -136,7 +136,7 @@ export const ContextManagementSettings = ({
</div>
</div>

<div>
<div data-setting-id="maxConcurrentFileReads">
<span className="block font-medium mb-1">
{t("settings:contextManagement.maxConcurrentFileReads.label")}
</span>
Expand All @@ -156,7 +156,7 @@ export const ContextManagementSettings = ({
</div>
</div>

<div>
<div data-setting-id="showRooIgnoredFiles">
<VSCodeCheckbox
checked={showRooIgnoredFiles}
onChange={(e: any) => setCachedStateField("showRooIgnoredFiles", e.target.checked)}
Expand All @@ -170,7 +170,7 @@ export const ContextManagementSettings = ({
</div>
</div>

<div>
<div data-setting-id="maxReadFileLine">
<div className="flex flex-col gap-2">
<span className="font-medium">{t("settings:contextManagement.maxReadFile.label")}</span>
<div className="flex items-center gap-4">
Expand Down Expand Up @@ -296,19 +296,21 @@ export const ContextManagementSettings = ({
</div>
</Section>
<Section className="pt-2">
<VSCodeCheckbox
checked={autoCondenseContext}
onChange={(e: any) => setCachedStateField("autoCondenseContext", e.target.checked)}
data-testid="auto-condense-context-checkbox">
<span className="font-medium">{t("settings:contextManagement.autoCondenseContext.name")}</span>
</VSCodeCheckbox>
<div data-setting-id="autoCondenseContext">
<VSCodeCheckbox
checked={autoCondenseContext}
onChange={(e: any) => setCachedStateField("autoCondenseContext", e.target.checked)}
data-testid="auto-condense-context-checkbox">
<span className="font-medium">{t("settings:contextManagement.autoCondenseContext.name")}</span>
</VSCodeCheckbox>
</div>
{autoCondenseContext && (
<div className="flex flex-col gap-3 pl-3 border-l-2 border-vscode-button-background">
<div className="flex items-center gap-4 font-bold">
<FoldVertical size={16} />
<div>{t("settings:contextManagement.condensingThreshold.label")}</div>
</div>
<div>
<div data-setting-id="condensingApiConfigId">
<Select
value={selectedThresholdProfile || "default"}
onValueChange={(value) => {
Expand Down Expand Up @@ -353,7 +355,7 @@ export const ContextManagementSettings = ({
</div>

{/* Threshold Slider */}
<div>
<div data-setting-id="autoCondenseContextPercent">
<div className="flex items-center gap-2">
<Slider
min={10}
Expand Down
34 changes: 19 additions & 15 deletions webview-ui/src/components/settings/LanguageSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,25 @@ export const LanguageSettings = ({ language, setCachedStateField, className, ...
</SectionHeader>

<Section>
<Select value={language} onValueChange={(value) => setCachedStateField("language", value as Language)}>
<SelectTrigger className="w-full">
<SelectValue placeholder={t("settings:common.select")} />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{Object.entries(LANGUAGES).map(([code, name]) => (
<SelectItem key={code} value={code}>
{name}
<span className="text-muted-foreground">({code})</span>
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
<div data-setting-id="language">
<Select
value={language}
onValueChange={(value) => setCachedStateField("language", value as Language)}>
<SelectTrigger className="w-full">
<SelectValue placeholder={t("settings:common.select")} />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{Object.entries(LANGUAGES).map(([code, name]) => (
<SelectItem key={code} value={code}>
{name}
<span className="text-muted-foreground">({code})</span>
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</div>
</Section>
</div>
)
Expand Down
8 changes: 4 additions & 4 deletions webview-ui/src/components/settings/NotificationSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const NotificationSettings = ({
</SectionHeader>

<Section>
<div>
<div data-setting-id="ttsEnabled">
<VSCodeCheckbox
checked={ttsEnabled}
onChange={(e: any) => setCachedStateField("ttsEnabled", e.target.checked)}
Expand All @@ -49,7 +49,7 @@ export const NotificationSettings = ({

{ttsEnabled && (
<div className="flex flex-col gap-3 pl-3 border-l-2 border-vscode-button-background">
<div>
<div data-setting-id="ttsSpeed">
<label className="block font-medium mb-1">
{t("settings:notifications.tts.speedLabel")}
</label>
Expand All @@ -68,7 +68,7 @@ export const NotificationSettings = ({
</div>
)}

<div>
<div data-setting-id="soundEnabled">
<VSCodeCheckbox
checked={soundEnabled}
onChange={(e: any) => setCachedStateField("soundEnabled", e.target.checked)}
Expand All @@ -82,7 +82,7 @@ export const NotificationSettings = ({

{soundEnabled && (
<div className="flex flex-col gap-3 pl-3 border-l-2 border-vscode-button-background">
<div>
<div data-setting-id="soundVolume">
<label className="block font-medium mb-1">
{t("settings:notifications.sound.volumeLabel")}
</label>
Expand Down
55 changes: 55 additions & 0 deletions webview-ui/src/components/settings/SearchHighlight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from "react"

export const highlightText = (text: string, query: string): React.ReactNode => {
if (!query.trim()) return text

// Escape special regex characters to prevent regex injection
const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
const parts = text.split(new RegExp(`(${escapedQuery})`, "gi"))
return parts.map((part, index) =>
part.toLowerCase() === query.toLowerCase() ? (
<mark key={index} className="bg-vscode-editor-findMatchHighlightBackground text-inherit">
{part}
</mark>
) : (
part
),
)
}

interface SearchHighlightProps {
text: string
searchQuery: string
className?: string
}

export const SearchHighlight: React.FC<SearchHighlightProps> = ({ text, searchQuery, className }) => {
return <span className={className}>{highlightText(text, searchQuery)}</span>
}

interface SettingHighlightWrapperProps {
settingId: string
searchQuery: string
matches: Array<{ settingId: string }>
children: React.ReactNode
}

export const SettingHighlightWrapper: React.FC<SettingHighlightWrapperProps> = ({
settingId,
searchQuery,
matches,
children,
}) => {
const isHighlighted = matches.some((match) => match.settingId === settingId)

if (!searchQuery || !isHighlighted) {
return <>{children}</>
}

return (
<div className="relative">
<div className="absolute -left-2 top-0 bottom-0 w-1 bg-vscode-editor-findMatchHighlightBackground rounded" />
{children}
</div>
)
}
Loading