mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Add search field to dropdown
This commit is contained in:
@@ -1,25 +1,26 @@
|
|||||||
import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react"
|
import React, { useMemo, useState, useRef, useEffect, memo } from "react"
|
||||||
import React, { useMemo } from "react"
|
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
|
||||||
import { useMount } from "react-use"
|
import styled from "styled-components"
|
||||||
import { useExtensionState } from "../../context/ExtensionStateContext"
|
import { useExtensionState } from "../../context/ExtensionStateContext"
|
||||||
|
import { useMount } from "react-use"
|
||||||
import { vscode } from "../../utils/vscode"
|
import { vscode } from "../../utils/vscode"
|
||||||
import { ModelInfoView, normalizeApiConfiguration } from "./ApiOptions"
|
import { ModelInfoView, normalizeApiConfiguration } from "./ApiOptions"
|
||||||
import { memo, useEffect } from "react"
|
|
||||||
import { useRemark } from "react-remark"
|
import { useRemark } from "react-remark"
|
||||||
import styled from "styled-components"
|
|
||||||
|
|
||||||
interface OpenRouterModelPickerProps {}
|
const OpenRouterModelPicker: React.FC = () => {
|
||||||
|
|
||||||
const OpenRouterModelPicker: React.FC<OpenRouterModelPickerProps> = () => {
|
|
||||||
const { apiConfiguration, setApiConfiguration, openRouterModels } = useExtensionState()
|
const { apiConfiguration, setApiConfiguration, openRouterModels } = useExtensionState()
|
||||||
|
const [searchTerm, setSearchTerm] = useState("")
|
||||||
|
const [isDropdownVisible, setIsDropdownVisible] = useState(false)
|
||||||
|
const dropdownRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
const handleModelChange = (event: any) => {
|
const handleModelChange = (newModelId: string) => {
|
||||||
const newModelId = event.target.value
|
|
||||||
setApiConfiguration({
|
setApiConfiguration({
|
||||||
...apiConfiguration,
|
...apiConfiguration,
|
||||||
openRouterModelId: newModelId,
|
openRouterModelId: newModelId,
|
||||||
openRouterModelInfo: openRouterModels[newModelId],
|
openRouterModelInfo: openRouterModels[newModelId],
|
||||||
})
|
})
|
||||||
|
setSearchTerm(newModelId)
|
||||||
|
setIsDropdownVisible(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { selectedModelId, selectedModelInfo } = useMemo(() => {
|
const { selectedModelId, selectedModelInfo } = useMemo(() => {
|
||||||
@@ -30,36 +31,52 @@ const OpenRouterModelPicker: React.FC<OpenRouterModelPickerProps> = () => {
|
|||||||
vscode.postMessage({ type: "refreshOpenRouterModels" })
|
vscode.postMessage({ type: "refreshOpenRouterModels" })
|
||||||
})
|
})
|
||||||
|
|
||||||
const modelIds = useMemo(() => {
|
const filteredModelIds = useMemo(() => {
|
||||||
return Object.keys(openRouterModels).sort((a, b) => a.localeCompare(b))
|
return Object.keys(openRouterModels)
|
||||||
}, [openRouterModels])
|
.filter((modelId) => modelId.toLowerCase().includes(searchTerm.toLowerCase()))
|
||||||
|
.sort((a, b) => a.localeCompare(b))
|
||||||
|
}, [openRouterModels, searchTerm])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
||||||
|
setIsDropdownVisible(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("mousedown", handleClickOutside)
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("mousedown", handleClickOutside)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="dropdown-container">
|
<DropdownWrapper ref={dropdownRef}>
|
||||||
<label htmlFor="model-id">
|
<label htmlFor="model-search">
|
||||||
<span style={{ fontWeight: 500 }}>Model</span>
|
<span style={{ fontWeight: 500 }}>Model</span>
|
||||||
</label>
|
</label>
|
||||||
<VSCodeDropdown
|
<VSCodeTextField
|
||||||
id="model-id"
|
id="model-search"
|
||||||
value={selectedModelId}
|
placeholder="Search and select a model..."
|
||||||
onChange={handleModelChange}
|
value={searchTerm}
|
||||||
style={{ width: "100%" }}>
|
onChange={(e) => {
|
||||||
<VSCodeOption value="">Select a model...</VSCodeOption>
|
setSearchTerm((e.target as HTMLInputElement).value)
|
||||||
{modelIds.map((modelId) => (
|
setIsDropdownVisible(true)
|
||||||
<VSCodeOption
|
}}
|
||||||
key={modelId}
|
onFocus={() => setIsDropdownVisible(true)}
|
||||||
value={modelId}
|
style={{ width: "100%", zIndex: 1001 }}
|
||||||
style={{
|
/>
|
||||||
whiteSpace: "normal",
|
{isDropdownVisible && (
|
||||||
wordWrap: "break-word",
|
<DropdownList>
|
||||||
maxWidth: "100%",
|
{filteredModelIds.map((modelId) => (
|
||||||
}}>
|
<DropdownItem key={modelId} onClick={() => handleModelChange(modelId)}>
|
||||||
{modelId}
|
{modelId}
|
||||||
</VSCodeOption>
|
</DropdownItem>
|
||||||
))}
|
))}
|
||||||
</VSCodeDropdown>
|
</DropdownList>
|
||||||
</div>
|
)}
|
||||||
|
</DropdownWrapper>
|
||||||
|
|
||||||
<ModelInfoView selectedModelId={selectedModelId} modelInfo={selectedModelInfo} />
|
<ModelInfoView selectedModelId={selectedModelId} modelInfo={selectedModelInfo} />
|
||||||
</>
|
</>
|
||||||
@@ -68,6 +85,37 @@ const OpenRouterModelPicker: React.FC<OpenRouterModelPickerProps> = () => {
|
|||||||
|
|
||||||
export default OpenRouterModelPicker
|
export default OpenRouterModelPicker
|
||||||
|
|
||||||
|
// Dropdown
|
||||||
|
|
||||||
|
const DropdownWrapper = styled.div`
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
`
|
||||||
|
|
||||||
|
const DropdownList = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% - 3px);
|
||||||
|
left: 0;
|
||||||
|
width: calc(100% - 2px);
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
background-color: var(--vscode-dropdown-background);
|
||||||
|
border: 1px solid var(--vscode-list-activeSelectionBackground);
|
||||||
|
z-index: 1000;
|
||||||
|
border-bottom-left-radius: 3px;
|
||||||
|
border-bottom-right-radius: 3px;
|
||||||
|
`
|
||||||
|
|
||||||
|
const DropdownItem = styled.div`
|
||||||
|
padding: 5px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--vscode-list-activeSelectionBackground);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// Markdown
|
||||||
|
|
||||||
const StyledMarkdown = styled.div`
|
const StyledMarkdown = styled.div`
|
||||||
font-family: var(--vscode-font-family), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
|
font-family: var(--vscode-font-family), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
|
||||||
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||||
|
|||||||
Reference in New Issue
Block a user