From f509bafd07b82e02c98c437df590f4a9df2e3a24 Mon Sep 17 00:00:00 2001 From: Alex Hancock Date: Thu, 20 Feb 2025 16:39:33 -0500 Subject: [PATCH] fix: fully remove react-router now that it is unused (#1317) --- ui/desktop/eslint.config.js | 2 +- ui/desktop/openapi.json | 2 +- ui/desktop/package-lock.json | 42 ----- ui/desktop/package.json | 1 - ui/desktop/src/App.tsx | 5 +- ui/desktop/src/ChatWindow.tsx | 14 -- ui/desktop/src/ConfigTestingWindow.tsx | 150 ---------------- ui/desktop/src/components/BottomMenu.tsx | 7 +- ui/desktop/src/components/MoreMenu.tsx | 11 +- .../src/components/pages/ConfigPage.tsx | 162 ------------------ .../src/components/settings/Settings.tsx | 32 +--- .../components/settings/models/MoreModels.tsx | 3 - .../welcome_screen/ProviderGrid.tsx | 3 - ui/desktop/src/extensions.tsx | 3 +- ui/desktop/src/renderer.tsx | 5 +- 15 files changed, 11 insertions(+), 431 deletions(-) delete mode 100644 ui/desktop/src/ConfigTestingWindow.tsx delete mode 100644 ui/desktop/src/components/pages/ConfigPage.tsx diff --git a/ui/desktop/eslint.config.js b/ui/desktop/eslint.config.js index ae2080af0..d03560e97 100644 --- a/ui/desktop/eslint.config.js +++ b/ui/desktop/eslint.config.js @@ -26,7 +26,7 @@ const noWindowLocationHref = { ) { context.report({ node, - message: 'Do not use window.location.href directly in Electron apps. Use React Router\'s navigate() instead.' + message: 'Do not use window.location.href directly in Electron apps. Use setView from the project instead' }); } } diff --git a/ui/desktop/openapi.json b/ui/desktop/openapi.json index f3db92438..d597f00c1 100644 --- a/ui/desktop/openapi.json +++ b/ui/desktop/openapi.json @@ -10,7 +10,7 @@ "license": { "name": "Apache-2.0" }, - "version": "1.0.5" + "version": "1.0.7" }, "paths": { "/config": { diff --git a/ui/desktop/package-lock.json b/ui/desktop/package-lock.json index 76171627c..584c0591c 100644 --- a/ui/desktop/package-lock.json +++ b/ui/desktop/package-lock.json @@ -38,7 +38,6 @@ "react-dom": "^18.3.1", "react-icons": "^5.3.0", "react-markdown": "^9.0.1", - "react-router-dom": "^6.28.0", "react-select": "^5.9.0", "react-syntax-highlighter": "^15.6.1", "react-toastify": "^8.0.0", @@ -3925,15 +3924,6 @@ } } }, - "node_modules/@remix-run/router": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.22.0.tgz", - "integrity": "sha512-MBOl8MeOzpK0HQQQshKB7pABXbmyHizdTpqnrIseTbsv0nAepwC2ENZa1aaBExNQcpLoXmWthhak8SABLzvGPw==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.34.6", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz", @@ -13655,38 +13645,6 @@ } } }, - "node_modules/react-router": { - "version": "6.29.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.29.0.tgz", - "integrity": "sha512-DXZJoE0q+KyeVw75Ck6GkPxFak63C4fGqZGNijnWgzB/HzSP1ZfTlBj5COaGWwhrMQ/R8bXiq5Ooy4KG+ReyjQ==", - "license": "MIT", - "dependencies": { - "@remix-run/router": "1.22.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/react-router-dom": { - "version": "6.29.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.29.0.tgz", - "integrity": "sha512-pkEbJPATRJ2iotK+wUwHfy0xs2T59YPEN8BQxVCPeBZvK7kfPESRc/nyxzdcxR17hXgUPYx2whMwl+eo9cUdnQ==", - "license": "MIT", - "dependencies": { - "@remix-run/router": "1.22.0", - "react-router": "6.29.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" - } - }, "node_modules/react-select": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.10.0.tgz", diff --git a/ui/desktop/package.json b/ui/desktop/package.json index ef7478571..f8a6761f2 100644 --- a/ui/desktop/package.json +++ b/ui/desktop/package.json @@ -93,7 +93,6 @@ "react-dom": "^18.3.1", "react-icons": "^5.3.0", "react-markdown": "^9.0.1", - "react-router-dom": "^6.28.0", "react-select": "^5.9.0", "react-syntax-highlighter": "^15.6.1", "react-toastify": "^8.0.0", diff --git a/ui/desktop/src/App.tsx b/ui/desktop/src/App.tsx index ce2bec601..91d02d236 100644 --- a/ui/desktop/src/App.tsx +++ b/ui/desktop/src/App.tsx @@ -1,6 +1,5 @@ import React, { useEffect, useState } from 'react'; import { addExtensionFromDeepLink } from './extensions'; -import { useNavigate } from 'react-router-dom'; import LauncherWindow from './LauncherWindow'; import ChatWindow from './ChatWindow'; import ErrorScreen from './components/ErrorScreen'; @@ -19,7 +18,7 @@ export default function App() { const [isInstalling, setIsInstalling] = useState(false); // Track installation progress const searchParams = new URLSearchParams(window.location.search); const isLauncher = searchParams.get('window') === 'launcher'; - const navigate = useNavigate(); + const navigate = () => console.log('todo - bring back nav'); // Utility function to extract the command from the link function extractCommand(link: string): string { @@ -55,7 +54,7 @@ export default function App() { console.log('Confirming installation for link:', pendingLink); try { - await addExtensionFromDeepLink(pendingLink, navigate); // Proceed with adding the extension + await addExtensionFromDeepLink(pendingLink, navigate); } catch (error) { console.error('Failed to add extension:', error); } finally { diff --git a/ui/desktop/src/ChatWindow.tsx b/ui/desktop/src/ChatWindow.tsx index 9551d58f9..e1de74140 100644 --- a/ui/desktop/src/ChatWindow.tsx +++ b/ui/desktop/src/ChatWindow.tsx @@ -363,12 +363,6 @@ export default function ChatWindow() { setupStoredProvider(); }, []); - // Render everything inside ChatLayout now - // We'll switch views inside the ChatLayout children. - - // If we want to skip showing ChatLayout for the welcome screen, we can do so. - // But let's do exactly what's requested: put all view options under ChatLayout. - return ( {/* Conditionally render based on `view` */} @@ -395,14 +389,6 @@ export default function ChatWindow() { setView={setView} /> )} - {view === 'configPage' && ( - { - setView('chat'); - }} - setView={setView} - /> - )} {view === 'configureProviders' && ( { diff --git a/ui/desktop/src/ConfigTestingWindow.tsx b/ui/desktop/src/ConfigTestingWindow.tsx deleted file mode 100644 index ec0fdc6c6..000000000 --- a/ui/desktop/src/ConfigTestingWindow.tsx +++ /dev/null @@ -1,150 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { Button } from './components/ui/button'; -import { Input } from './components/ui/input'; -import { Label } from './components/ui/label'; -import { Card } from './components/ui/card'; -import { useNavigate } from 'react-router-dom'; -import BackButton from './components/ui/BackButton'; -import { useConfig } from './hooks/useConfig'; - -export default function ConfigPage() { - const [configs, setConfigs] = useState>({}); - const [newKey, setNewKey] = useState(''); - const [newValue, setNewValue] = useState(''); - const navigate = useNavigate(); - - const { loading, error, loadConfigs, addConfig, removeConfig } = useConfig(); - - // Fetch all configs on component mount - useEffect(() => { - const fetchConfigs = async () => { - const result = await loadConfigs(); - setConfigs(result); - }; - fetchConfigs(); - }, [loadConfigs]); - - const handleAddConfig = async () => { - if (!newKey || !newValue) { - return; - } - - let parsedValue = newValue; - // Try to parse as JSON if it looks like JSON - if (newValue.trim().startsWith('{') || newValue.trim().startsWith('[')) { - try { - parsedValue = JSON.parse(newValue); - } catch (e) { - // If parsing fails, use the original string value - console.log('Value is not valid JSON, using as string'); - } - } - - const success = await addConfig(newKey, parsedValue); - if (success) { - setNewKey(''); - setNewValue(''); - const updatedConfigs = await loadConfigs(); - setConfigs(updatedConfigs); - } - }; - - const handleRemoveConfig = async (key: string) => { - const success = await removeConfig(key); - if (success) { - const updatedConfigs = await loadConfigs(); - setConfigs(updatedConfigs); - } - }; - - return ( -
-
- -
-
- navigate('/settings')} /> -

Configuration

-
- -
-
- {/* Add new config form */} - -

Add New Configuration

-
-
- - setNewKey(e.target.value)} - placeholder="Enter config key" - className="mt-1" - /> -
-
- - setNewValue(e.target.value)} - placeholder="Enter config value (string or JSON)" - className="mt-1" - /> -
- -
-
- - {/* Error display */} - {error && ( -
- {error.message} -
- )} - - {/* Config list */} - -

Current Configurations

-
- {loading ? ( -
Loading configurations...
- ) : Object.keys(configs).length === 0 ? ( -
No configurations found
- ) : ( - Object.entries(configs).map(([key, value]) => ( -
-
- {key}:{' '} - - {typeof value === 'object' - ? JSON.stringify(value, null, 2) - : String(value)} - -
- -
- )) - )} -
-
-
-
-
-
- ); -} diff --git a/ui/desktop/src/components/BottomMenu.tsx b/ui/desktop/src/components/BottomMenu.tsx index 0687fdede..bc8e1132d 100644 --- a/ui/desktop/src/components/BottomMenu.tsx +++ b/ui/desktop/src/components/BottomMenu.tsx @@ -3,8 +3,6 @@ import { useModel } from './settings/models/ModelContext'; import { useRecentModels } from './settings/models/RecentModels'; // Hook for recent models import { Sliders } from 'lucide-react'; import { ModelRadioList } from './settings/models/ModelRadioList'; -// Remove react-router-dom usage -// import { useNavigate } from 'react-router-dom'; import { Document, ChevronUp, ChevronDown } from './icons'; import type { View } from '../ChatWindow'; @@ -13,7 +11,7 @@ export default function BottomMenu({ setView, }: { hasMessages: boolean; - setView?: (view: View) => void; + setView: (view: View) => void; }) { const [isModelMenuOpen, setIsModelMenuOpen] = useState(false); const { currentModel } = useModel(); @@ -133,8 +131,7 @@ export default function BottomMenu({ border-t border-borderSubtle mt-2" onClick={() => { setIsModelMenuOpen(false); - // Instead of navigate('/settings'), call setView('settings'). - setView?.('settings'); + setView('settings'); }} > Tools and Settings diff --git a/ui/desktop/src/components/MoreMenu.tsx b/ui/desktop/src/components/MoreMenu.tsx index 328399535..06ece801d 100644 --- a/ui/desktop/src/components/MoreMenu.tsx +++ b/ui/desktop/src/components/MoreMenu.tsx @@ -1,12 +1,6 @@ import { Popover, PopoverContent, PopoverTrigger, PopoverPortal } from '@radix-ui/react-popover'; import React, { useEffect, useState } from 'react'; -import { FaMoon, FaSun } from 'react-icons/fa'; -import VertDots from './ui/VertDots'; -// Removed react-router-dom import -// import { useNavigate } from 'react-router-dom'; import { More } from './icons'; -import { Settings, Grid, MessageSquare } from 'lucide-react'; -import { Button } from './ui/button'; import type { View } from '../../ChatWindow'; interface VersionInfo { @@ -15,7 +9,7 @@ interface VersionInfo { } // Accept setView as a prop from the parent (e.g. ChatContent) -export default function MoreMenu({ setView }: { setView?: (view: View) => void }) { +export default function MoreMenu({ setView }: { setView: (view: View) => void }) { const [open, setOpen] = useState(false); const [versions, setVersions] = useState(null); const [showVersions, setShowVersions] = useState(false); @@ -231,8 +225,7 @@ export default function MoreMenu({ setView }: { setView?: (view: View) => void } - - - - {/* Error display */} - {error && ( -
- {error.message} -
- )} - - {/* Config list */} - -

Current Configurations

-
- {loading ? ( -
Loading configurations...
- ) : Object.keys(configs).length === 0 ? ( -
No configurations found
- ) : ( - Object.entries(configs).map(([key, value]) => ( -
-
- {key}:{' '} - - {typeof value === 'object' - ? JSON.stringify(value, null, 2) - : String(value)} - -
- -
- )) - )} -
-
- - - - - ); -} diff --git a/ui/desktop/src/components/settings/Settings.tsx b/ui/desktop/src/components/settings/Settings.tsx index 17938bbd8..33d7e45b8 100644 --- a/ui/desktop/src/components/settings/Settings.tsx +++ b/ui/desktop/src/components/settings/Settings.tsx @@ -56,7 +56,6 @@ export default function Settings({ onClose: () => void; setView: (view: View) => void; }) { - // We'll read query params from window.location instead of react-router's useLocation const [searchParams] = useState(() => new URLSearchParams(window.location.search)); const [settings, setSettings] = React.useState(() => { @@ -181,8 +180,6 @@ export default function Settings({ return BUILT_IN_EXTENSIONS.some((builtIn) => builtIn.id === extensionId); }; - function navigate(s: string) {} - return (
@@ -190,12 +187,7 @@ export default function Settings({
- { - // Instead of navigate('/chat/1', { replace: true }); - onClose(); - }} - /> + onClose()} />

Settings

@@ -207,7 +199,6 @@ export default function Settings({

Models

- -
-
-

Configuration

-
- -
-
- -
-

- Manage application configuration and settings. You can view, add, edit, and - remove configuration values. -

-
-
diff --git a/ui/desktop/src/components/settings/models/MoreModels.tsx b/ui/desktop/src/components/settings/models/MoreModels.tsx index cb7c3ab3d..14adbe3f0 100644 --- a/ui/desktop/src/components/settings/models/MoreModels.tsx +++ b/ui/desktop/src/components/settings/models/MoreModels.tsx @@ -1,13 +1,10 @@ import React from 'react'; -import { Button } from '../../ui/button'; import { RecentModels } from './RecentModels'; import { ProviderButtons } from './ProviderButtons'; import BackButton from '../../ui/BackButton'; import { SearchBar } from './Search'; import { useModel } from './ModelContext'; import { AddModelInline } from './AddModelInline'; -// Removed react-router-dom usage -// import { useNavigate } from 'react-router-dom'; import { ScrollArea } from '../../ui/scroll-area'; import type { View } from '../../../ChatWindow'; diff --git a/ui/desktop/src/components/welcome_screen/ProviderGrid.tsx b/ui/desktop/src/components/welcome_screen/ProviderGrid.tsx index c5e8f54df..7a9cc8fea 100644 --- a/ui/desktop/src/components/welcome_screen/ProviderGrid.tsx +++ b/ui/desktop/src/components/welcome_screen/ProviderGrid.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { Button } from '../ui/button'; import { supported_providers, required_keys, @@ -15,7 +14,6 @@ import { initializeSystem } from '../../utils/providerUtils'; import { getApiUrl, getSecretKey } from '../../config'; import { toast } from 'react-toastify'; import { getActiveProviders, isSecretKey } from '../settings/api_keys/utils'; -import { useNavigate } from 'react-router-dom'; import { BaseProviderGrid, getProviderDescription } from '../settings/providers/BaseProviderGrid'; interface ProviderGridProps { @@ -28,7 +26,6 @@ export function ProviderGrid({ onSubmit }: ProviderGridProps) { const [showSetupModal, setShowSetupModal] = React.useState(false); const { switchModel } = useModel(); const { addRecentModel } = useRecentModels(); - const navigate = useNavigate(); const providers = React.useMemo(() => { return supported_providers.map((providerName) => { diff --git a/ui/desktop/src/extensions.tsx b/ui/desktop/src/extensions.tsx index aaa7c6f6c..ec5c0d908 100644 --- a/ui/desktop/src/extensions.tsx +++ b/ui/desktop/src/extensions.tsx @@ -1,5 +1,4 @@ import { getApiUrl, getSecretKey } from './config'; -import { NavigateFunction } from 'react-router-dom'; import { toast } from 'react-toastify'; // ExtensionConfig type matching the Rust version @@ -258,7 +257,7 @@ function handleError(message: string, shouldThrow = false): void { } } -export async function addExtensionFromDeepLink(url: string, navigate: NavigateFunction) { +export async function addExtensionFromDeepLink(url: string, navigate: any) { if (!url.startsWith('goose://extension')) { handleError( 'Failed to install extension: Invalid URL: URL must use the goose://extension scheme' diff --git a/ui/desktop/src/renderer.tsx b/ui/desktop/src/renderer.tsx index 6353c4fcc..66cb3cd0f 100644 --- a/ui/desktop/src/renderer.tsx +++ b/ui/desktop/src/renderer.tsx @@ -1,6 +1,5 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import { HashRouter as Router } from 'react-router-dom'; import App from './App'; // Error Boundary Component @@ -72,9 +71,7 @@ window.addEventListener('error', (event) => { ReactDOM.createRoot(document.getElementById('root')!).render( - - - + );