Skip to content

Commit fbed0da

Browse files
committed
feat: improve unlimited diagnostics UI with integrated slider design
- Replace separate unlimited checkbox with intuitive slider design - Slider maximum position (100) now represents 'unlimited' value - Internal value of -1 is set when slider is at maximum position - Display 'Unlimited' text when slider is at max position - Update all 18 language translations for the new UI text - Update tests to reflect the new integrated design approach This provides a cleaner, more intuitive interface for setting diagnostic limits without the need for a separate checkbox control.
1 parent 5084ccc commit fbed0da

File tree

20 files changed

+120
-52
lines changed

20 files changed

+120
-52
lines changed

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

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,22 @@ export const ContextManagementSettings = ({
272272
min={1}
273273
max={100}
274274
step={1}
275-
value={[maxDiagnosticMessages ?? 50]}
276-
onValueChange={([value]) => setCachedStateField("maxDiagnosticMessages", value)}
275+
value={[
276+
maxDiagnosticMessages !== undefined && maxDiagnosticMessages <= 0
277+
? 100
278+
: (maxDiagnosticMessages ?? 50),
279+
]}
280+
onValueChange={([value]) => {
281+
// When slider reaches 100, set to -1 (unlimited)
282+
setCachedStateField("maxDiagnosticMessages", value === 100 ? -1 : value)
283+
}}
277284
data-testid="max-diagnostic-messages-slider"
278-
disabled={maxDiagnosticMessages === -1}
279285
/>
280-
<span className="w-10">
281-
{maxDiagnosticMessages === -1 ? "∞" : (maxDiagnosticMessages ?? 50)}
286+
<span className="w-20 text-sm font-medium">
287+
{(maxDiagnosticMessages !== undefined && maxDiagnosticMessages <= 0) ||
288+
maxDiagnosticMessages === 100
289+
? t("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel") || "Unlimited"
290+
: (maxDiagnosticMessages ?? 50)}
282291
</span>
283292
<Button
284293
variant="ghost"
@@ -290,18 +299,12 @@ export const ContextManagementSettings = ({
290299
<span className="codicon codicon-discard" />
291300
</Button>
292301
</div>
293-
<div className="flex items-center gap-2 mt-2">
294-
<VSCodeCheckbox
295-
checked={maxDiagnosticMessages === -1}
296-
onChange={(e: any) =>
297-
setCachedStateField("maxDiagnosticMessages", e.target.checked ? -1 : 50)
298-
}
299-
data-testid="max-diagnostic-messages-unlimited-checkbox">
300-
{t("settings:contextManagement.diagnostics.maxMessages.unlimited")}
301-
</VSCodeCheckbox>
302-
</div>
303302
<div className="text-vscode-descriptionForeground text-sm mt-1">
304-
{t("settings:contextManagement.diagnostics.maxMessages.description")}
303+
{(maxDiagnosticMessages !== undefined && maxDiagnosticMessages <= 0) ||
304+
maxDiagnosticMessages === 100
305+
? t("settings:contextManagement.diagnostics.maxMessages.unlimitedDescription") ||
306+
"All diagnostic messages will be included. Use with caution as this may significantly increase token usage."
307+
: t("settings:contextManagement.diagnostics.maxMessages.description")}
305308
</div>
306309
</div>
307310
</Section>

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

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
import { render, screen, fireEvent, waitFor } from "@/utils/test-utils"
44
import { ContextManagementSettings } from "../ContextManagementSettings"
55

6+
// Mock the translation hook
7+
vi.mock("@/hooks/useAppTranslation", () => ({
8+
useAppTranslation: () => ({
9+
t: (key: string) => {
10+
// Return specific translations for our test cases
11+
if (key === "settings:contextManagement.diagnostics.maxMessages.unlimitedLabel") {
12+
return "Unlimited"
13+
}
14+
return key
15+
},
16+
}),
17+
}))
18+
619
// Mock the UI components
720
vi.mock("@/components/ui", () => ({
821
...vi.importActual("@/components/ui"),
@@ -122,7 +135,7 @@ describe("ContextManagementSettings", () => {
122135
fireEvent.change(slider, { target: { value: "100" } })
123136

124137
await waitFor(() => {
125-
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", 100)
138+
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", -1)
126139
})
127140
})
128141

@@ -142,9 +155,17 @@ describe("ContextManagementSettings", () => {
142155

143156
expect(screen.getByText("25")).toBeInTheDocument()
144157

145-
// Update value
158+
// Update value - 100 should display as "Unlimited"
146159
rerender(<ContextManagementSettings {...defaultProps} maxDiagnosticMessages={100} />)
147-
expect(screen.getByText("100")).toBeInTheDocument()
160+
expect(
161+
screen.getByText("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel"),
162+
).toBeInTheDocument()
163+
164+
// Test unlimited value (-1) displays as "Unlimited"
165+
rerender(<ContextManagementSettings {...defaultProps} maxDiagnosticMessages={-1} />)
166+
expect(
167+
screen.getByText("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel"),
168+
).toBeInTheDocument()
148169
})
149170

150171
it("renders other context management settings", () => {
@@ -161,7 +182,7 @@ describe("ContextManagementSettings", () => {
161182
})
162183

163184
describe("Edge cases for maxDiagnosticMessages", () => {
164-
it("handles zero value correctly", async () => {
185+
it("handles zero value as unlimited", async () => {
165186
const setCachedStateField = vi.fn()
166187
render(
167188
<ContextManagementSettings
@@ -171,13 +192,17 @@ describe("ContextManagementSettings", () => {
171192
/>,
172193
)
173194

174-
expect(screen.getByText("0")).toBeInTheDocument()
195+
// Zero is now treated as unlimited
196+
expect(
197+
screen.getByText("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel"),
198+
).toBeInTheDocument()
175199

176200
const slider = screen.getByTestId("max-diagnostic-messages-slider")
177-
expect(slider).toHaveValue("0")
201+
// Zero should map to slider position 100 (unlimited)
202+
expect(slider).toHaveValue("100")
178203
})
179204

180-
it("handles negative values by displaying them", async () => {
205+
it("handles negative values as unlimited", async () => {
181206
const setCachedStateField = vi.fn()
182207
render(
183208
<ContextManagementSettings
@@ -187,11 +212,14 @@ describe("ContextManagementSettings", () => {
187212
/>,
188213
)
189214

190-
// Component displays the actual negative value in the text span
191-
expect(screen.getByText("-10")).toBeInTheDocument()
215+
// Component displays "Unlimited" for any negative value
216+
expect(
217+
screen.getByText("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel"),
218+
).toBeInTheDocument()
192219

193-
// Note: The actual slider behavior with negative values depends on the implementation
194-
// In this case, we're just verifying the component renders without errors
220+
// Slider should be at max position (100) for negative values
221+
const slider = screen.getByTestId("max-diagnostic-messages-slider")
222+
expect(slider).toHaveValue("100")
195223
})
196224

197225
it("handles very large numbers by capping at maximum", async () => {
@@ -223,32 +251,33 @@ describe("ContextManagementSettings", () => {
223251
fireEvent.change(slider, { target: { value: "150" } })
224252

225253
await waitFor(() => {
226-
// Should be capped at 100 (the slider's max)
227-
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", 100)
254+
// Should be capped at 100, which maps to -1 (unlimited)
255+
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", -1)
228256
})
229257
})
230258

231-
it("handles boundary value at minimum (0)", async () => {
259+
it("handles boundary value at minimum (1)", async () => {
232260
const setCachedStateField = vi.fn()
233261
render(<ContextManagementSettings {...defaultProps} setCachedStateField={setCachedStateField} />)
234262

235263
const slider = screen.getByTestId("max-diagnostic-messages-slider")
236-
fireEvent.change(slider, { target: { value: "0" } })
264+
fireEvent.change(slider, { target: { value: "1" } })
237265

238266
await waitFor(() => {
239-
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", 0)
267+
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", 1)
240268
})
241269
})
242270

243-
it("handles boundary value at maximum (100)", async () => {
271+
it("handles boundary value at maximum (100) as unlimited (-1)", async () => {
244272
const setCachedStateField = vi.fn()
245273
render(<ContextManagementSettings {...defaultProps} setCachedStateField={setCachedStateField} />)
246274

247275
const slider = screen.getByTestId("max-diagnostic-messages-slider")
248276
fireEvent.change(slider, { target: { value: "100" } })
249277

250278
await waitFor(() => {
251-
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", 100)
279+
// When slider is at 100, it should set the value to -1 (unlimited)
280+
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", -1)
252281
})
253282
})
254283

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,9 @@
475475
"label": "Màxim de missatges de diagnòstic",
476476
"description": "Nombre màxim de missatges de diagnòstic a incloure per fitxer. Aquest límit s'aplica tant a la inclusió automàtica (quan la casella està activada) com a les mencions manuals de @problems. Valors més alts proporcionen més context però augmenten l'ús de tokens.",
477477
"resetTooltip": "Restablir al valor per defecte (50)",
478-
"unlimited": "Missatges de diagnòstic il·limitats"
478+
"unlimited": "Missatges de diagnòstic il·limitats",
479+
"unlimitedLabel": "Il·limitat",
480+
"unlimitedDescription": "S'inclouran tots els missatges de diagnòstic. Utilitzeu amb precaució ja que això pot augmentar significativament l'ús de tokens."
479481
}
480482
},
481483
"condensingThreshold": {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,9 @@
475475
"label": "Maximale Anzahl von Diagnosenachrichten",
476476
"description": "Maximale Anzahl von Diagnosenachrichten, die pro Datei eingeschlossen werden. Dieses Limit gilt sowohl für die automatische Einbeziehung (wenn das Kontrollkästchen aktiviert ist) als auch für manuelle @problems-Erwähnungen. Höhere Werte bieten mehr Kontext, erhöhen aber den Token-Verbrauch.",
477477
"resetTooltip": "Auf Standardwert zurücksetzen (50)",
478-
"unlimited": "Unbegrenzte Diagnosenachrichten"
478+
"unlimited": "Unbegrenzte Diagnosenachrichten",
479+
"unlimitedLabel": "Unbegrenzt",
480+
"unlimitedDescription": "Alle Diagnosenachrichten werden einbezogen. Mit Vorsicht verwenden, da dies den Token-Verbrauch erheblich erhöhen kann."
479481
}
480482
},
481483
"condensingThreshold": {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,9 @@
475475
"label": "Maximum diagnostic messages",
476476
"description": "Maximum number of diagnostic messages to include per file. This limit applies to both automatic inclusion (when checkbox is enabled) and manual @problems mentions. Higher values provide more context but increase token usage.",
477477
"resetTooltip": "Reset to default value (50)",
478-
"unlimited": "Unlimited diagnostic messages"
478+
"unlimited": "Unlimited diagnostic messages",
479+
"unlimitedLabel": "Unlimited",
480+
"unlimitedDescription": "All diagnostic messages will be included. Use with caution as this may significantly increase token usage."
479481
}
480482
},
481483
"condensingThreshold": {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,9 @@
475475
"label": "Máximo de mensajes de diagnóstico",
476476
"description": "Número máximo de mensajes de diagnóstico a incluir por archivo. Este límite se aplica tanto a la inclusión automática (cuando la casilla está habilitada) como a las menciones manuales de @problems. Valores más altos proporcionan más contexto pero aumentan el uso de tokens.",
477477
"resetTooltip": "Restablecer al valor predeterminado (50)",
478-
"unlimited": "Mensajes de diagnóstico ilimitados"
478+
"unlimited": "Mensajes de diagnóstico ilimitados",
479+
"unlimitedLabel": "Ilimitado",
480+
"unlimitedDescription": "Se incluirán todos los mensajes de diagnóstico. Úselo con precaución ya que esto puede aumentar significativamente el uso de tokens."
479481
}
480482
},
481483
"condensingThreshold": {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,9 @@
475475
"label": "Nombre maximum de messages de diagnostic",
476476
"description": "Nombre maximum de messages de diagnostic à inclure par fichier. Cette limite s'applique à la fois à l'inclusion automatique (lorsque la case est cochée) et aux mentions manuelles @problems. Des valeurs plus élevées fournissent plus de contexte mais augmentent l'utilisation des jetons.",
477477
"resetTooltip": "Réinitialiser à la valeur par défaut (50)",
478-
"unlimited": "Messages de diagnostic illimités"
478+
"unlimited": "Messages de diagnostic illimités",
479+
"unlimitedLabel": "Illimité",
480+
"unlimitedDescription": "Tous les messages de diagnostic seront inclus. Utilisez avec prudence car cela peut augmenter considérablement l'utilisation des jetons."
479481
}
480482
},
481483
"condensingThreshold": {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,9 @@
475475
"label": "अधिकतम नैदानिक ​​संदेश",
476476
"description": "प्रति फ़ाइल शामिल किए जाने वाले नैदानिक ​​संदेशों की अधिकतम संख्या। यह सीमा स्वचालित समावेशन (जब चेकबॉक्स सक्षम है) और मैन्युअल @problems उल्लेख दोनों पर लागू होती है। उच्च मान अधिक संदर्भ प्रदान करते हैं लेकिन टोकन उपयोग बढ़ाते हैं।",
477477
"resetTooltip": "डिफ़ॉल्ट मान पर रीसेट करें (50)",
478-
"unlimited": "असीमित डायग्नोस्टिक संदेश"
478+
"unlimited": "असीमित डायग्नोस्टिक संदेश",
479+
"unlimitedLabel": "असीमित",
480+
"unlimitedDescription": "सभी डायग्नोस्टिक संदेश शामिल किए जाएंगे। सावधानी से उपयोग करें क्योंकि यह टोकन उपयोग को काफी बढ़ा सकता है।"
479481
}
480482
},
481483
"condensingThreshold": {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,9 @@
457457
"label": "Pesan diagnostik maksimum",
458458
"description": "Jumlah maksimum pesan diagnostik yang akan disertakan per file. Batas ini berlaku untuk penyertaan otomatis (ketika checkbox diaktifkan) dan penyebutan manual @problems. Nilai yang lebih tinggi memberikan lebih banyak konteks tetapi meningkatkan penggunaan token.",
459459
"resetTooltip": "Reset ke nilai default (50)",
460-
"unlimited": "Pesan diagnostik tidak terbatas"
460+
"unlimited": "Pesan diagnostik tidak terbatas",
461+
"unlimitedLabel": "Tak terbatas",
462+
"unlimitedDescription": "Semua pesan diagnostik akan disertakan. Gunakan dengan hati-hati karena ini dapat meningkatkan penggunaan token secara signifikan."
461463
}
462464
},
463465
"condensingThreshold": {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,9 @@
475475
"label": "Numero massimo di messaggi diagnostici",
476476
"description": "Numero massimo di messaggi diagnostici da includere per file. Questo limite si applica sia all'inclusione automatica (quando la casella è abilitata) che alle menzioni manuali di @problems. Valori più alti forniscono più contesto ma aumentano l'utilizzo dei token.",
477477
"resetTooltip": "Ripristina al valore predefinito (50)",
478-
"unlimited": "Messaggi diagnostici illimitati"
478+
"unlimited": "Messaggi diagnostici illimitati",
479+
"unlimitedLabel": "Illimitato",
480+
"unlimitedDescription": "Verranno inclusi tutti i messaggi diagnostici. Usare con cautela poiché questo può aumentare significativamente l'utilizzo dei token."
479481
}
480482
},
481483
"condensingThreshold": {

0 commit comments

Comments
 (0)