From 8d18cc81ac3a631eacd6d03c031c3d829d8d9765 Mon Sep 17 00:00:00 2001 From: Andy <119136210+AndyMik90@users.noreply.github.com> Date: Tue, 27 Jan 2026 20:13:02 +0100 Subject: [PATCH] auto-claude: subtask-1-1 - Remove Popover wrapper and related functionality from ClaudeCodeStatusBadge (#1566) - Remove Popover, PopoverContent, PopoverTrigger wrappers - Remove AlertDialog components for update/rollback/path change warnings - Remove version selector (Select component) and installation selector - Remove all popover-related state (isOpen, showUpdateWarning, showRollbackWarning, etc.) - Remove unused imports (Button, Download, RefreshCw, ExternalLink, FolderOpen, Select, AlertDialog) - Remove install/update functions and related state (isInstalling, availableVersions, etc.) - Keep only the status badge display with colored indicator - Keep Tooltip for hover information - Keep version checking for status indicator - Add new i18n key upToDateWithVersion for showing version in tooltip Co-authored-by: Claude Opus 4.5 --- .../components/ClaudeCodeStatusBadge.tsx | 673 ++---------------- .../shared/i18n/locales/en/navigation.json | 1 + .../shared/i18n/locales/fr/navigation.json | 1 + 3 files changed, 59 insertions(+), 616 deletions(-) diff --git a/apps/frontend/src/renderer/components/ClaudeCodeStatusBadge.tsx b/apps/frontend/src/renderer/components/ClaudeCodeStatusBadge.tsx index 8fd34ee3..c438df6c 100644 --- a/apps/frontend/src/renderer/components/ClaudeCodeStatusBadge.tsx +++ b/apps/frontend/src/renderer/components/ClaudeCodeStatusBadge.tsx @@ -6,33 +6,10 @@ import { AlertTriangle, X, Loader2, - Download, - RefreshCw, - ExternalLink, - FolderOpen, } from "lucide-react"; -import { Button } from "./ui/button"; -import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover"; import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip"; -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, -} from "./ui/alert-dialog"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "./ui/select"; import { cn } from "../lib/utils"; -import type { ClaudeCodeVersionInfo, ClaudeInstallationInfo } from "../../shared/types/cli"; +import type { ClaudeCodeVersionInfo } from "../../shared/types/cli"; interface ClaudeCodeStatusBadgeProps { className?: string; @@ -42,36 +19,15 @@ type StatusType = "loading" | "installed" | "outdated" | "not-found" | "error"; // Check every 24 hours const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; -// Delay before re-checking version after install/update -const VERSION_RECHECK_DELAY_MS = 5000; /** * Claude Code CLI status badge for the sidebar. - * Shows installation status and provides quick access to install/update. + * Shows installation status with a tooltip on hover. */ export function ClaudeCodeStatusBadge({ className }: ClaudeCodeStatusBadgeProps) { const { t } = useTranslation(["common", "navigation"]); const [status, setStatus] = useState("loading"); const [versionInfo, setVersionInfo] = useState(null); - const [isInstalling, setIsInstalling] = useState(false); - const [lastChecked, setLastChecked] = useState(null); - const [isOpen, setIsOpen] = useState(false); - const [showUpdateWarning, setShowUpdateWarning] = useState(false); - - // Version rollback state - const [availableVersions, setAvailableVersions] = useState([]); - const [isLoadingVersions, setIsLoadingVersions] = useState(false); - const [versionsError, setVersionsError] = useState(null); - const [selectedVersion, setSelectedVersion] = useState(null); - const [showRollbackWarning, setShowRollbackWarning] = useState(false); - const [installError, setInstallError] = useState(null); - - // CLI path selection state - const [installations, setInstallations] = useState([]); - const [isLoadingInstallations, setIsLoadingInstallations] = useState(false); - const [installationsError, setInstallationsError] = useState(null); - const [selectedInstallation, setSelectedInstallation] = useState(null); - const [showPathChangeWarning, setShowPathChangeWarning] = useState(false); // Check Claude Code version const checkVersion = useCallback(async () => { @@ -85,7 +41,6 @@ export function ClaudeCodeStatusBadge({ className }: ClaudeCodeStatusBadgeProps) if (result.success && result.data) { setVersionInfo(result.data); - setLastChecked(new Date()); if (!result.data.installed) { setStatus("not-found"); @@ -97,60 +52,11 @@ export function ClaudeCodeStatusBadge({ className }: ClaudeCodeStatusBadgeProps) } else { setStatus("error"); } - } catch (err) { - console.error("Failed to check Claude Code version:", err); + } catch { setStatus("error"); } }, []); - // Fetch available versions - const fetchVersions = useCallback(async () => { - if (!window.electronAPI?.getClaudeCodeVersions) { - return; - } - - setIsLoadingVersions(true); - setVersionsError(null); - - try { - const result = await window.electronAPI.getClaudeCodeVersions(); - if (result.success && result.data) { - setAvailableVersions(result.data.versions); - } else { - setVersionsError(result.error || "Failed to load versions"); - } - } catch (err) { - console.error("Failed to fetch versions:", err); - setVersionsError("Failed to load versions"); - } finally { - setIsLoadingVersions(false); - } - }, []); - - // Fetch CLI installations - const fetchInstallations = useCallback(async () => { - if (!window.electronAPI?.getClaudeCodeInstallations) { - return; - } - - setIsLoadingInstallations(true); - setInstallationsError(null); - - try { - const result = await window.electronAPI.getClaudeCodeInstallations(); - if (result.success && result.data) { - setInstallations(result.data.installations); - } else { - setInstallationsError(result.error || "Failed to load installations"); - } - } catch (err) { - console.error("Failed to fetch installations:", err); - setInstallationsError("Failed to load installations"); - } finally { - setIsLoadingInstallations(false); - } - }, []); - // Initial check and periodic re-check useEffect(() => { checkVersion(); @@ -163,155 +69,6 @@ export function ClaudeCodeStatusBadge({ className }: ClaudeCodeStatusBadgeProps) return () => clearInterval(interval); }, [checkVersion]); - // Fetch versions when popover opens and Claude is installed - useEffect(() => { - if (isOpen && versionInfo?.installed && availableVersions.length === 0) { - fetchVersions(); - } - }, [isOpen, versionInfo?.installed, availableVersions.length, fetchVersions]); - - // Fetch installations when popover opens - useEffect(() => { - if (isOpen && installations.length === 0) { - fetchInstallations(); - } - }, [isOpen, installations.length, fetchInstallations]); - - // Perform the actual install/update - const performInstall = async () => { - setIsInstalling(true); - setShowUpdateWarning(false); - setInstallError(null); - try { - if (!window.electronAPI?.installClaudeCode) { - setInstallError("Installation not available"); - return; - } - - const result = await window.electronAPI.installClaudeCode(); - - if (result.success) { - // Re-check after a delay - setTimeout(() => { - checkVersion(); - }, VERSION_RECHECK_DELAY_MS); - } else { - setInstallError(result.error || "Installation failed"); - } - } catch (err) { - console.error("Failed to install Claude Code:", err); - setInstallError(err instanceof Error ? err.message : "Installation failed"); - } finally { - setIsInstalling(false); - } - }; - - // Perform version rollback/switch - const performVersionSwitch = async () => { - if (!selectedVersion) return; - - setIsInstalling(true); - setShowRollbackWarning(false); - setInstallError(null); - - try { - if (!window.electronAPI?.installClaudeCodeVersion) { - setInstallError("Version switching not available"); - return; - } - - const result = await window.electronAPI.installClaudeCodeVersion(selectedVersion); - - if (result.success) { - // Re-check after a delay - setTimeout(() => { - checkVersion(); - }, VERSION_RECHECK_DELAY_MS); - } else { - setInstallError(result.error || "Failed to switch version"); - } - } catch (err) { - console.error("Failed to switch Claude Code version:", err); - setInstallError(err instanceof Error ? err.message : "Failed to switch version"); - } finally { - setIsInstalling(false); - setSelectedVersion(null); - } - }; - - // Perform CLI path switch - const performPathSwitch = async () => { - if (!selectedInstallation) return; - - setIsInstalling(true); - setShowPathChangeWarning(false); - setInstallError(null); - - try { - if (!window.electronAPI?.setClaudeCodeActivePath) { - setInstallError("Path switching not available"); - return; - } - - const result = await window.electronAPI.setClaudeCodeActivePath(selectedInstallation); - - if (result.success) { - // Re-check version and refresh installations - setTimeout(() => { - checkVersion(); - fetchInstallations(); - }, VERSION_RECHECK_DELAY_MS); - } else { - setInstallError(result.error || "Failed to switch CLI path"); - } - } catch (err) { - console.error("Failed to switch Claude CLI path:", err); - setInstallError(err instanceof Error ? err.message : "Failed to switch CLI path"); - } finally { - setIsInstalling(false); - setSelectedInstallation(null); - } - }; - - // Handle install/update button click - const handleInstall = () => { - if (status === "outdated") { - // Show warning for updates since it will close running Claude sessions - setShowUpdateWarning(true); - } else { - // Fresh install - no warning needed - performInstall(); - } - }; - - // Handle installation selection - const handleInstallationSelect = (cliPath: string) => { - // Don't do anything if it's the currently active installation - const installation = installations.find(i => i.path === cliPath); - if (installation?.isActive) { - return; - } - setInstallError(null); - setSelectedInstallation(cliPath); - setShowPathChangeWarning(true); - }; - - // Normalize version string by removing 'v' prefix for comparison - const normalizeVersion = (v: string) => v.replace(/^v/, ''); - - // Handle version selection - const handleVersionSelect = (version: string) => { - // Don't do anything if it's the currently installed version (normalize both for comparison) - const normalizedSelected = normalizeVersion(version); - const normalizedInstalled = versionInfo?.installed ? normalizeVersion(versionInfo.installed) : ''; - if (normalizedSelected === normalizedInstalled) { - return; - } - setInstallError(null); - setSelectedVersion(version); - setShowRollbackWarning(true); - }; - // Get status indicator color const getStatusColor = () => { switch (status) { @@ -327,29 +84,17 @@ export function ClaudeCodeStatusBadge({ className }: ClaudeCodeStatusBadgeProps) } }; - // Get status icon - const getStatusIcon = () => { - switch (status) { - case "loading": - return ; - case "installed": - return ; - case "outdated": - return ; - case "not-found": - return ; - case "error": - return ; - } - }; - // Get tooltip text const getTooltipText = () => { switch (status) { case "loading": return t("navigation:claudeCode.checking", "Checking Claude Code..."); case "installed": - return t("navigation:claudeCode.upToDate", "Claude Code is up to date"); + return versionInfo?.installed + ? t("navigation:claudeCode.upToDateWithVersion", "Claude Code {{version}} installed", { + version: versionInfo.installed, + }) + : t("navigation:claudeCode.upToDate", "Claude Code is up to date"); case "outdated": return t("navigation:claudeCode.updateAvailable", "Claude Code update available"); case "not-found": @@ -359,366 +104,62 @@ export function ClaudeCodeStatusBadge({ className }: ClaudeCodeStatusBadgeProps) } }; + // Get status icon for the badge + const getStatusIcon = () => { + switch (status) { + case "loading": + return ; + case "installed": + return ; + case "outdated": + return ; + case "not-found": + case "error": + return ; + } + }; + return ( - - - - - - - - {getTooltipText()} - - - -
- {/* Header */} -
-
- -
-
-

Claude Code CLI

-

- {getStatusIcon()} - {status === "installed" && t("navigation:claudeCode.installed", "Installed")} - {status === "outdated" && t("navigation:claudeCode.outdated", "Update available")} - {status === "not-found" && t("navigation:claudeCode.missing", "Not installed")} - {status === "loading" && t("navigation:claudeCode.checking", "Checking...")} - {status === "error" && t("navigation:claudeCode.error", "Error")} -

-
+ />
- - {/* Version info */} - {versionInfo && status !== "loading" && ( -
- {versionInfo.installed && ( -
- - {t("navigation:claudeCode.current", "Current")}: - - {versionInfo.installed} -
- )} - {versionInfo.latest && versionInfo.latest !== "unknown" && ( -
- - {t("navigation:claudeCode.latest", "Latest")}: - - {versionInfo.latest} -
- )} - {versionInfo.path && ( -
- - - {t("navigation:claudeCode.path", "Path")}: - - - {versionInfo.path} - -
- )} - {lastChecked && ( -
- {t("navigation:claudeCode.lastChecked", "Last checked")}: - {lastChecked.toLocaleTimeString()} -
- )} -
+ Claude Code + {status === "outdated" && ( + + {getStatusIcon()} + {t("common:update", "Update")} + )} - - {/* Actions */} -
- {(status === "not-found" || status === "outdated") && ( - - )} - -
- - {/* Install/Update error display */} - {installError && ( -
- - {installError} -
+ {status === "not-found" && ( + + {getStatusIcon()} + {t("common:install", "Install")} + )} - - {/* Version selector - only show when Claude is installed */} - {versionInfo?.installed && ( -
- - -
+ {status === "installed" && ( + + {getStatusIcon()} + )} - - {/* CLI Installation selector - show when multiple installations are found */} - {installations.length > 1 && ( -
- - -
- )} - - {/* Learn more link */} - - - {/* Changelog link */} -
-
- - {/* Update warning dialog */} - - - - - {t("navigation:claudeCode.updateWarningTitle", "Update Claude Code?")} - - - {t( - "navigation:claudeCode.updateWarningDescription", - "Updating will close all running Claude Code sessions. Any unsaved work in those sessions may be lost. Make sure to save your work before proceeding." - )} - - {t( - "navigation:claudeCode.updateWarningTerminalNote", - "A terminal window will open to run the installation command. Please wait for the installation to complete before continuing." - )} - - - - - {t("common:cancel", "Cancel")} - - {t("navigation:claudeCode.updateAnyway", "Open Terminal & Update")} - - - - - - {/* Version rollback warning dialog */} - - - - - {t("navigation:claudeCode.rollbackWarningTitle", "Switch to version {{version}}?", { - version: selectedVersion, - })} - - - {t( - "navigation:claudeCode.rollbackWarningDescription", - "Switching versions will close all running Claude Code sessions. Any unsaved work in those sessions may be lost. Make sure to save your work before proceeding." - )} - - {t( - "navigation:claudeCode.rollbackWarningTerminalNote", - "A terminal window will open to run the installation command. Please wait for the installation to complete before continuing." - )} - - - - - setSelectedVersion(null)}> - {t("common:cancel", "Cancel")} - - - {t("navigation:claudeCode.switchAnyway", "Open Terminal & Switch")} - - - - - - {/* Path change warning dialog */} - - - - - {t("navigation:claudeCode.pathChangeWarningTitle", "Switch CLI installation?")} - - - {t( - "navigation:claudeCode.pathChangeWarningDescription", - "Switching CLI installations will use a different Claude Code binary. Any running sessions will continue using the previous installation until restarted." - )} - - {selectedInstallation} - - - - - setSelectedInstallation(null)}> - {t("common:cancel", "Cancel")} - - - {t("navigation:claudeCode.switchInstallationConfirm", "Switch")} - - - - -
+ + {getTooltipText()} + ); } diff --git a/apps/frontend/src/shared/i18n/locales/en/navigation.json b/apps/frontend/src/shared/i18n/locales/en/navigation.json index 50483700..9e9db1cc 100644 --- a/apps/frontend/src/shared/i18n/locales/en/navigation.json +++ b/apps/frontend/src/shared/i18n/locales/en/navigation.json @@ -44,6 +44,7 @@ "claudeCode": { "checking": "Checking Claude Code...", "upToDate": "Claude Code is up to date", + "upToDateWithVersion": "Claude Code {{version}} installed", "updateAvailable": "Claude Code update available", "notInstalled": "Claude Code not installed", "error": "Error checking Claude Code", diff --git a/apps/frontend/src/shared/i18n/locales/fr/navigation.json b/apps/frontend/src/shared/i18n/locales/fr/navigation.json index db779e10..55e1a450 100644 --- a/apps/frontend/src/shared/i18n/locales/fr/navigation.json +++ b/apps/frontend/src/shared/i18n/locales/fr/navigation.json @@ -44,6 +44,7 @@ "claudeCode": { "checking": "Vérification de Claude Code...", "upToDate": "Claude Code est à jour", + "upToDateWithVersion": "Claude Code {{version}} installé", "updateAvailable": "Mise à jour Claude Code disponible", "notInstalled": "Claude Code non installé", "error": "Erreur de vérification de Claude Code",