Skip to content

Commit 210231d

Browse files
committed
feat: add todo list enable checkbox to provider advanced settings
- Add todoListEnabled field to provider settings types - Create TodoListSettingsControl component similar to DiffSettingsControl - Integrate todo list control into ApiOptions advanced settings - Add translation keys for the new setting - Add comprehensive unit tests for the new component - Update ApiOptions tests to include VSCodeCheckbox mock
1 parent 2eb586b commit 210231d

File tree

6 files changed

+148
-0
lines changed

6 files changed

+148
-0
lines changed

packages/types/src/provider-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export const DEFAULT_CONSECUTIVE_MISTAKE_LIMIT = 3
6161
const baseProviderSettingsSchema = z.object({
6262
includeMaxTokens: z.boolean().optional(),
6363
diffEnabled: z.boolean().optional(),
64+
todoListEnabled: z.boolean().optional(),
6465
fuzzyMatchThreshold: z.number().optional(),
6566
modelTemperature: z.number().nullish(),
6667
rateLimitSeconds: z.number().optional(),

webview-ui/src/components/settings/ApiOptions.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import { ModelInfoView } from "./ModelInfoView"
7878
import { ApiErrorMessage } from "./ApiErrorMessage"
7979
import { ThinkingBudget } from "./ThinkingBudget"
8080
import { DiffSettingsControl } from "./DiffSettingsControl"
81+
import { TodoListSettingsControl } from "./TodoListSettingsControl"
8182
import { TemperatureControl } from "./TemperatureControl"
8283
import { RateLimitSecondsControl } from "./RateLimitSecondsControl"
8384
import { ConsecutiveMistakeLimitControl } from "./ConsecutiveMistakeLimitControl"
@@ -564,6 +565,10 @@ const ApiOptions = ({
564565
<span className="font-medium">{t("settings:advancedSettings.title")}</span>
565566
</CollapsibleTrigger>
566567
<CollapsibleContent className="space-y-3">
568+
<TodoListSettingsControl
569+
todoListEnabled={apiConfiguration.todoListEnabled}
570+
onChange={(field, value) => setApiConfigurationField(field, value)}
571+
/>
567572
<DiffSettingsControl
568573
diffEnabled={apiConfiguration.diffEnabled}
569574
fuzzyMatchThreshold={apiConfiguration.fuzzyMatchThreshold}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { useCallback } from "react"
2+
import { useAppTranslation } from "@/i18n/TranslationContext"
3+
import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
4+
5+
interface TodoListSettingsControlProps {
6+
todoListEnabled?: boolean
7+
onChange: (field: "todoListEnabled", value: any) => void
8+
}
9+
10+
export const TodoListSettingsControl: React.FC<TodoListSettingsControlProps> = ({
11+
todoListEnabled = true,
12+
onChange,
13+
}) => {
14+
const { t } = useAppTranslation()
15+
16+
const handleTodoListEnabledChange = useCallback(
17+
(e: any) => {
18+
onChange("todoListEnabled", e.target.checked)
19+
},
20+
[onChange],
21+
)
22+
23+
return (
24+
<div className="flex flex-col gap-1">
25+
<div>
26+
<VSCodeCheckbox checked={todoListEnabled} onChange={handleTodoListEnabledChange}>
27+
<span className="font-medium">{t("settings:advanced.todoList.label")}</span>
28+
</VSCodeCheckbox>
29+
<div className="text-vscode-descriptionForeground text-sm">
30+
{t("settings:advanced.todoList.description")}
31+
</div>
32+
</div>
33+
</div>
34+
)
35+
}

webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ vi.mock("@vscode/webview-ui-toolkit/react", () => ({
2121
VSCodeRadio: ({ value, checked }: any) => <input type="radio" value={value} checked={checked} />,
2222
VSCodeRadioGroup: ({ children }: any) => <div>{children}</div>,
2323
VSCodeButton: ({ children }: any) => <div>{children}</div>,
24+
VSCodeCheckbox: ({ children, checked, onChange }: any) => (
25+
<label>
26+
<input
27+
type="checkbox"
28+
checked={checked}
29+
onChange={(e) => onChange && onChange({ target: { checked: e.target.checked } })}
30+
/>
31+
{children}
32+
</label>
33+
),
2434
}))
2535

2636
// Mock other components
@@ -173,6 +183,22 @@ vi.mock("../DiffSettingsControl", () => ({
173183
),
174184
}))
175185

186+
// Mock TodoListSettingsControl for tests
187+
vi.mock("../TodoListSettingsControl", () => ({
188+
TodoListSettingsControl: ({ todoListEnabled, onChange }: any) => (
189+
<div data-testid="todo-list-settings-control">
190+
<label>
191+
Enable todo list tool
192+
<input
193+
type="checkbox"
194+
checked={todoListEnabled}
195+
onChange={(e) => onChange("todoListEnabled", e.target.checked)}
196+
/>
197+
</label>
198+
</div>
199+
),
200+
}))
201+
176202
// Mock ThinkingBudget component
177203
vi.mock("../ThinkingBudget", () => ({
178204
ThinkingBudget: ({ modelInfo }: any) => {
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import React from "react"
2+
import { render, screen, fireEvent } from "@testing-library/react"
3+
import { describe, it, expect, vi } from "vitest"
4+
import { TodoListSettingsControl } from "../TodoListSettingsControl"
5+
6+
// Mock the translation hook
7+
vi.mock("@/i18n/TranslationContext", () => ({
8+
useAppTranslation: () => ({
9+
t: (key: string) => {
10+
const translations: Record<string, string> = {
11+
"settings:advanced.todoList.label": "Enable todo list tool",
12+
"settings:advanced.todoList.description":
13+
"When enabled, Roo can create and manage todo lists to track task progress. This helps organize complex tasks into manageable steps.",
14+
}
15+
return translations[key] || key
16+
},
17+
}),
18+
}))
19+
20+
// Mock VSCodeCheckbox
21+
vi.mock("@vscode/webview-ui-toolkit/react", () => ({
22+
VSCodeCheckbox: ({ children, onChange, checked, ...props }: any) => (
23+
<label>
24+
<input
25+
type="checkbox"
26+
checked={checked}
27+
onChange={(e) => onChange({ target: { checked: e.target.checked } })}
28+
{...props}
29+
/>
30+
{children}
31+
</label>
32+
),
33+
}))
34+
35+
describe("TodoListSettingsControl", () => {
36+
it("renders with default props", () => {
37+
const onChange = vi.fn()
38+
render(<TodoListSettingsControl onChange={onChange} />)
39+
40+
const checkbox = screen.getByRole("checkbox")
41+
const label = screen.getByText("Enable todo list tool")
42+
const description = screen.getByText(/When enabled, Roo can create and manage todo lists/)
43+
44+
expect(checkbox).toBeInTheDocument()
45+
expect(checkbox).toBeChecked() // Default is true
46+
expect(label).toBeInTheDocument()
47+
expect(description).toBeInTheDocument()
48+
})
49+
50+
it("renders with todoListEnabled set to false", () => {
51+
const onChange = vi.fn()
52+
render(<TodoListSettingsControl todoListEnabled={false} onChange={onChange} />)
53+
54+
const checkbox = screen.getByRole("checkbox")
55+
expect(checkbox).not.toBeChecked()
56+
})
57+
58+
it("calls onChange when checkbox is clicked", () => {
59+
const onChange = vi.fn()
60+
render(<TodoListSettingsControl todoListEnabled={true} onChange={onChange} />)
61+
62+
const checkbox = screen.getByRole("checkbox")
63+
fireEvent.click(checkbox)
64+
65+
expect(onChange).toHaveBeenCalledWith("todoListEnabled", false)
66+
})
67+
68+
it("toggles from unchecked to checked", () => {
69+
const onChange = vi.fn()
70+
render(<TodoListSettingsControl todoListEnabled={false} onChange={onChange} />)
71+
72+
const checkbox = screen.getByRole("checkbox")
73+
fireEvent.click(checkbox)
74+
75+
expect(onChange).toHaveBeenCalledWith("todoListEnabled", true)
76+
})
77+
})

webview-ui/src/i18n/locales/en/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,10 @@
577577
"label": "Match precision",
578578
"description": "This slider controls how precisely code sections must match when applying diffs. Lower values allow more flexible matching but increase the risk of incorrect replacements. Use values below 100% with extreme caution."
579579
}
580+
},
581+
"todoList": {
582+
"label": "Enable todo list tool",
583+
"description": "When enabled, Roo can create and manage todo lists to track task progress. This helps organize complex tasks into manageable steps."
580584
}
581585
},
582586
"experimental": {

0 commit comments

Comments
 (0)