feat: allow manual Node.js path configuration (#1577)
Add ability to manually configure Node.js path for users who have Node.js installed but not in their system PATH. Features: - Browse and select custom Node.js installation folder - Visual status indicator showing Node.js version or "Not found" - Reset to system default PATH option - Manual configuration option in setup banner - Real-time Node.js status checking closes #1050 <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds manual Node.js path configuration so the app works even when Node isn’t on PATH, fulfilling #1050. Users can browse to their install, reset to default, and see real-time status in Settings and during setup. - New Features - Settings: NodePathSelector to browse a Node.js folder, show version/“Not found” status, and reset to system PATH (persists customNodePath). - Setup banner: manual config flow with a folder picker if Node is already installed. - IPC: select-node-folder, set-node-path, get-node-path; reloads env and prepends custom path to PATH. - Real-time Node.js status check with visual indicator (CheckCircle on valid). - E2E tests for browse, reset, and valid-status display. <!-- End of auto-generated description by cubic. -->
This commit is contained in:
committed by
GitHub
parent
cc435d1ed4
commit
b1095b7951
@@ -8,6 +8,7 @@ import {
|
||||
XCircle,
|
||||
Loader2,
|
||||
Settings,
|
||||
Folder,
|
||||
} from "lucide-react";
|
||||
import { providerSettingsRoute } from "@/routes/settings/providers/$provider";
|
||||
|
||||
@@ -30,6 +31,8 @@ import { useScrollAndNavigateTo } from "@/hooks/useScrollAndNavigateTo";
|
||||
// @ts-ignore
|
||||
import logo from "../../assets/logo.svg";
|
||||
import { OnboardingBanner } from "./home/OnboardingBanner";
|
||||
import { showError } from "@/lib/toast";
|
||||
import { useSettings } from "@/hooks/useSettings";
|
||||
|
||||
type NodeInstallStep =
|
||||
| "install"
|
||||
@@ -60,6 +63,32 @@ export function SetupBanner() {
|
||||
setNodeCheckError(true);
|
||||
}
|
||||
}, [setNodeSystemInfo, setNodeCheckError]);
|
||||
const [showManualConfig, setShowManualConfig] = useState(false);
|
||||
const [isSelectingPath, setIsSelectingPath] = useState(false);
|
||||
const { updateSettings } = useSettings();
|
||||
|
||||
// Add handler for manual path selection
|
||||
const handleManualNodeConfig = useCallback(async () => {
|
||||
setIsSelectingPath(true);
|
||||
try {
|
||||
const result = await IpcClient.getInstance().selectNodeFolder();
|
||||
if (result.path) {
|
||||
await updateSettings({ customNodePath: result.path });
|
||||
await IpcClient.getInstance().reloadEnvPath();
|
||||
await checkNode();
|
||||
setNodeInstallStep("finished-checking");
|
||||
setShowManualConfig(false);
|
||||
} else if (result.path === null && result.canceled === false) {
|
||||
showError(
|
||||
`Could not find Node.js at the path "${result.selectedPath}"`,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
showError("Error setting Node.js path:" + error);
|
||||
} finally {
|
||||
setIsSelectingPath(false);
|
||||
}
|
||||
}, [checkNode]);
|
||||
|
||||
useEffect(() => {
|
||||
checkNode();
|
||||
@@ -222,6 +251,38 @@ export function SetupBanner() {
|
||||
handleNodeInstallClick={handleNodeInstallClick}
|
||||
finishNodeInstall={finishNodeInstall}
|
||||
/>
|
||||
|
||||
<div className="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
|
||||
<button
|
||||
onClick={() => setShowManualConfig(!showManualConfig)}
|
||||
className="text-sm text-blue-600 dark:text-blue-400 hover:underline"
|
||||
>
|
||||
Node.js already installed? Configure path manually →
|
||||
</button>
|
||||
|
||||
{showManualConfig && (
|
||||
<div className="mt-3 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg">
|
||||
<Button
|
||||
onClick={handleManualNodeConfig}
|
||||
disabled={isSelectingPath}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
>
|
||||
{isSelectingPath ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
Selecting...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Folder className="mr-2 h-4 w-4" />
|
||||
Browse for Node.js folder
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<NodeJsHelpCallout />
|
||||
|
||||
Reference in New Issue
Block a user