Browse Source

Merge pull request #921 from RooVetGit/welcome_screen_tweaks

Hide custom temp on welcome view and make submit button more intuitive
Matt Rubens 11 months ago
parent
commit
1f07a77ff7

+ 15 - 12
webview-ui/src/components/settings/ApiOptions.tsx

@@ -48,9 +48,10 @@ import { RequestyModelPicker } from "./RequestyModelPicker"
 interface ApiOptionsProps {
 	apiErrorMessage?: string
 	modelIdErrorMessage?: string
+	fromWelcomeView?: boolean
 }
 
-const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) => {
+const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage, fromWelcomeView }: ApiOptionsProps) => {
 	const { apiConfiguration, uriScheme, handleInputChange } = useExtensionState()
 	const [ollamaModels, setOllamaModels] = useState<string[]>([])
 	const [lmStudioModels, setLmStudioModels] = useState<string[]>([])
@@ -1391,17 +1392,19 @@ const ApiOptions = ({ apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) =
 					</>
 				)}
 
-			<div style={{ marginTop: "10px" }}>
-				<TemperatureControl
-					value={apiConfiguration?.modelTemperature}
-					onChange={(value) => {
-						handleInputChange("modelTemperature")({
-							target: { value },
-						})
-					}}
-					maxValue={2}
-				/>
-			</div>
+			{!fromWelcomeView && (
+				<div style={{ marginTop: "10px" }}>
+					<TemperatureControl
+						value={apiConfiguration?.modelTemperature}
+						onChange={(value) => {
+							handleInputChange("modelTemperature")({
+								target: { value },
+							})
+						}}
+						maxValue={2}
+					/>
+				</div>
+			)}
 
 			{modelIdErrorMessage && (
 				<p

+ 67 - 0
webview-ui/src/components/settings/__tests__/ApiOptions.test.tsx

@@ -0,0 +1,67 @@
+import { render, screen } from "@testing-library/react"
+import ApiOptions from "../ApiOptions"
+import { ExtensionStateContextProvider } from "../../../context/ExtensionStateContext"
+
+// Mock VSCode components
+jest.mock("@vscode/webview-ui-toolkit/react", () => ({
+	VSCodeTextField: ({ children, value, onBlur }: any) => (
+		<div>
+			{children}
+			<input type="text" value={value} onChange={onBlur} />
+		</div>
+	),
+	VSCodeLink: ({ children, href }: any) => <a href={href}>{children}</a>,
+	VSCodeRadio: ({ children, value, checked }: any) => <input type="radio" value={value} checked={checked} />,
+	VSCodeRadioGroup: ({ children }: any) => <div>{children}</div>,
+}))
+
+// Mock other components
+jest.mock("vscrui", () => ({
+	Dropdown: ({ children, value, onChange }: any) => (
+		<select value={value} onChange={onChange}>
+			{children}
+		</select>
+	),
+	Checkbox: ({ children, checked, onChange }: any) => (
+		<label>
+			<input type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)} />
+			{children}
+		</label>
+	),
+	Pane: ({ children }: any) => <div>{children}</div>,
+}))
+
+jest.mock("../TemperatureControl", () => ({
+	TemperatureControl: ({ value, onChange }: any) => (
+		<div data-testid="temperature-control">
+			<input
+				type="range"
+				value={value || 0}
+				onChange={(e) => onChange(parseFloat(e.target.value))}
+				min={0}
+				max={2}
+				step={0.1}
+			/>
+		</div>
+	),
+}))
+
+describe("ApiOptions", () => {
+	const renderApiOptions = (props = {}) => {
+		render(
+			<ExtensionStateContextProvider>
+				<ApiOptions {...props} />
+			</ExtensionStateContextProvider>,
+		)
+	}
+
+	it("shows temperature control by default", () => {
+		renderApiOptions()
+		expect(screen.getByTestId("temperature-control")).toBeInTheDocument()
+	})
+
+	it("hides temperature control when fromWelcomeView is true", () => {
+		renderApiOptions({ fromWelcomeView: true })
+		expect(screen.queryByTestId("temperature-control")).not.toBeInTheDocument()
+	})
+})

+ 15 - 12
webview-ui/src/components/welcome/WelcomeView.tsx

@@ -1,5 +1,5 @@
 import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
-import { useEffect, useState } from "react"
+import { useState } from "react"
 import { useExtensionState } from "../../context/ExtensionStateContext"
 import { validateApiConfiguration } from "../../utils/validate"
 import { vscode } from "../../utils/vscode"
@@ -8,18 +8,18 @@ import ApiOptions from "../settings/ApiOptions"
 const WelcomeView = () => {
 	const { apiConfiguration } = useExtensionState()
 
-	const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
-
-	const disableLetsGoButton = apiErrorMessage !== null && apiErrorMessage !== undefined
+	const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined)
 
 	const handleSubmit = () => {
+		const error = validateApiConfiguration(apiConfiguration)
+		if (error) {
+			setErrorMessage(error)
+			return
+		}
+		setErrorMessage(undefined)
 		vscode.postMessage({ type: "apiConfiguration", apiConfiguration })
 	}
 
-	useEffect(() => {
-		setApiErrorMessage(validateApiConfiguration(apiConfiguration))
-	}, [apiConfiguration])
-
 	return (
 		<div style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, padding: "0 20px" }}>
 			<h2>Hi, I'm Roo!</h2>
@@ -33,10 +33,13 @@ const WelcomeView = () => {
 			<b>To get started, this extension needs an API provider.</b>
 
 			<div style={{ marginTop: "10px" }}>
-				<ApiOptions />
-				<VSCodeButton onClick={handleSubmit} disabled={disableLetsGoButton} style={{ marginTop: "3px" }}>
-					Let's go!
-				</VSCodeButton>
+				<ApiOptions fromWelcomeView />
+				<div style={{ display: "flex", flexDirection: "column", gap: "5px" }}>
+					<VSCodeButton onClick={handleSubmit} style={{ marginTop: "3px" }}>
+						Let's go!
+					</VSCodeButton>
+					{errorMessage && <span className="text-destructive">{errorMessage}</span>}
+				</div>
 			</div>
 		</div>
 	)