Condensing fixes (#4107)

* Add missing telemetry types

* Give IconButton the pointer cursor when enabled

* Change context condensing to use a Lucide icon

* Mock Lucide icons globally
This commit is contained in:
Matt Rubens 2025-05-29 10:45:13 -04:00 committed by GitHub
parent c03b9f9d25
commit 337b5dac88
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 31 additions and 71 deletions

View file

@ -109,6 +109,8 @@ export const rooCodeTelemetryEventSchema = z.discriminatedUnion("type", [
TelemetryEventName.DIFF_APPLICATION_ERROR,
TelemetryEventName.SHELL_INTEGRATION_ERROR,
TelemetryEventName.CONSECUTIVE_MISTAKE_ERROR,
TelemetryEventName.CONTEXT_CONDENSED,
TelemetryEventName.SLIDING_WINDOW_TRUNCATION,
]),
properties: telemetryPropertiesSchema,
}),

View file

@ -6,7 +6,7 @@ module.exports = {
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
transform: { "^.+\\.(ts|tsx)$": ["ts-jest", { tsconfig: { jsx: "react-jsx", module: "ESNext" } }] },
testMatch: ["<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}", "<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"],
setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"],
setupFilesAfterEnv: ["<rootDir>/src/setupTests.tsx"],
moduleNameMapper: {
"\\.(css|less|scss|sass)$": "identity-obj-proxy",
"^vscrui$": "<rootDir>/src/__mocks__/vscrui.ts",

View file

@ -27,6 +27,7 @@ export const IconButton: React.FC<IconButtonProps> = ({
"hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
"active:bg-[rgba(255,255,255,0.1)]",
!disabled && "cursor-pointer",
disabled &&
"opacity-40 cursor-not-allowed grayscale-[30%] hover:bg-transparent hover:border-[rgba(255,255,255,0.08)] active:bg-transparent",
className,

View file

@ -2,7 +2,7 @@ import { memo, useRef, useState } from "react"
import { useWindowSize } from "react-use"
import { useTranslation } from "react-i18next"
import { VSCodeBadge } from "@vscode/webview-ui-toolkit/react"
import { CloudUpload, CloudDownload } from "lucide-react"
import { CloudUpload, CloudDownload, FoldVertical } from "lucide-react"
import type { ClineMessage } from "@roo-code/types"
@ -19,7 +19,6 @@ import Thumbnails from "../common/Thumbnails"
import { TaskActions } from "./TaskActions"
import { ContextWindowProgress } from "./ContextWindowProgress"
import { Mention } from "./Mention"
import { IconButton } from "./IconButton"
export interface TaskHeaderProps {
task: ClineMessage
@ -108,13 +107,13 @@ const TaskHeader = ({
: undefined
}
/>
<IconButton
iconClass="codicon-fold"
<button
title={t("chat:task.condenseContext")}
disabled={buttonsDisabled}
onClick={() => currentTaskItem && handleCondenseContext(currentTaskItem.id)}
className="shrink-0 min-h-[20px] min-w-[20px] p-[2px]"
/>
className="shrink-0 min-h-[20px] min-w-[20px] p-[2px] cursor-pointer disabled:cursor-not-allowed opacity-85 hover:opacity-100 bg-transparent border-none rounded-md">
<FoldVertical size={16} />
</button>
{!!totalCost && <VSCodeBadge>${totalCost.toFixed(2)}</VSCodeBadge>}
</div>
)}

View file

@ -28,22 +28,6 @@ jest.mock("shiki", () => ({
},
}))
// Mock all lucide-react icons with a proxy to handle any icon requested
jest.mock("lucide-react", () => {
return new Proxy(
{},
{
get: function (_obj, prop) {
// Return a component factory for any icon that's requested
if (prop === "__esModule") {
return true
}
return () => <div data-testid={`${String(prop)}-icon`}>{String(prop)}</div>
},
},
)
})
// Mock the highlighter utility
jest.mock("../../../utils/highlighter", () => {
const mockHighlighter = {

View file

@ -12,22 +12,6 @@ jest.mock("@src/utils/vscode", () => ({
},
}))
// Mock all lucide-react icons with a proxy to handle any icon requested
jest.mock("lucide-react", () => {
return new Proxy(
{},
{
get: function (_obj, prop) {
// Return a component factory for any icon that's requested
if (prop === "__esModule") {
return true
}
return () => <div data-testid={`${String(prop)}-icon`}>{String(prop)}</div>
},
},
)
})
const mockExtensionState = {
customModePrompts: {},
listApiConfigMeta: [

View file

@ -1,7 +1,7 @@
import { HTMLAttributes } from "react"
import { useAppTranslation } from "@/i18n/TranslationContext"
import { VSCodeCheckbox, VSCodeTextArea } from "@vscode/webview-ui-toolkit/react"
import { Database } from "lucide-react"
import { Database, FoldVertical } from "lucide-react"
import { cn } from "@/lib/utils"
import { Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider } from "@/components/ui"
@ -197,7 +197,7 @@ export const ContextManagementSettings = ({
{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">
<span className="codicon codicon-fold" />
<FoldVertical size={16} />
<div>{t("settings:contextManagement.autoCondenseContextPercent.label")}</div>
</div>
<div>

View file

@ -13,20 +13,6 @@ class MockResizeObserver {
global.ResizeObserver = MockResizeObserver
// Mock lucide-react icons - these don't work well in Jest/JSDOM environment
jest.mock("lucide-react", () => {
return {
Database: React.forwardRef((props: any, ref: any) => <div ref={ref} data-testid="database-icon" {...props} />),
ChevronDown: React.forwardRef((props: any, ref: any) => (
<div ref={ref} data-testid="chevron-down-icon" {...props} />
)),
ChevronUp: React.forwardRef((props: any, ref: any) => (
<div ref={ref} data-testid="chevron-up-icon" {...props} />
)),
Check: React.forwardRef((props: any, ref: any) => <div ref={ref} data-testid="check-icon" {...props} />),
}
})
// Mock translation hook to return the key as the translation
jest.mock("@/i18n/TranslationContext", () => ({
useAppTranslation: () => ({

View file

@ -10,22 +10,6 @@ import SettingsView from "../SettingsView"
// Mock vscode API
jest.mock("@src/utils/vscode", () => ({ vscode: { postMessage: jest.fn() } }))
// Mock all lucide-react icons with a proxy to handle any icon requested
jest.mock("lucide-react", () => {
return new Proxy(
{},
{
get: function (_obj, prop) {
// Return a component factory for any icon that's requested
if (prop === "__esModule") {
return true
}
return () => <div data-testid={`${String(prop)}-icon`}>{String(prop)}</div>
},
},
)
})
// Mock ApiConfigManager component
jest.mock("../ApiConfigManager", () => ({
__esModule: true,

View file

@ -30,3 +30,23 @@ Object.defineProperty(window, "matchMedia", {
dispatchEvent: jest.fn(),
})),
})
// Mock lucide-react icons globally using Proxy for dynamic icon handling
jest.mock("lucide-react", () => {
return new Proxy(
{},
{
get: function (_obj, prop) {
// Return a component factory for any icon that's requested
if (prop === "__esModule") {
return true
}
return (props: any) => (
<div {...props} data-testid={`${String(prop)}-icon`}>
{String(prop)}
</div>
)
},
},
)
})