import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import modelService from '../api/services/modelService'; import Arrow2 from '../assets/dropdown-arrow.svg'; import RoundedTick from '../assets/rounded-tick.svg'; import { selectAvailableModels, selectSelectedModel, setAvailableModels, setModelsLoading, setSelectedModel, } from '../preferences/preferenceSlice'; import type { Model } from '../models/types'; export default function DropdownModel() { const dispatch = useDispatch(); const selectedModel = useSelector(selectSelectedModel); const availableModels = useSelector(selectAvailableModels); const dropdownRef = React.useRef(null); const [isOpen, setIsOpen] = React.useState(false); useEffect(() => { const loadModels = async () => { if ((availableModels?.length ?? 0) > 0) { return; } dispatch(setModelsLoading(true)); try { const response = await modelService.getModels(null); if (!response.ok) { throw new Error(`API error: ${response.status}`); } const data = await response.json(); const models = data.models || []; const transformed = modelService.transformModels(models); dispatch(setAvailableModels(transformed)); if (!selectedModel && transformed.length > 0) { const defaultModel = transformed.find((m) => m.id === data.default_model_id) || transformed[0]; dispatch(setSelectedModel(defaultModel)); } else if (selectedModel && transformed.length > 0) { const isValid = transformed.find((m) => m.id === selectedModel.id); if (!isValid) { const defaultModel = transformed.find((m) => m.id === data.default_model_id) || transformed[0]; dispatch(setSelectedModel(defaultModel)); } } } catch (error) { console.error('Failed to load models:', error); } finally { dispatch(setModelsLoading(false)); } }; loadModels(); }, [availableModels?.length, dispatch, selectedModel]); const handleClickOutside = (event: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) ) { setIsOpen(false); } }; useEffect(() => { document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, []); return (
setIsOpen(!isOpen)} > {selectedModel?.display_name ? (

{selectedModel.display_name}

) : (

Select Model

)} arrow
{isOpen && (
{availableModels && (availableModels?.length ?? 0) > 0 ? ( availableModels.map((model: Model) => (
{ dispatch(setSelectedModel(model)); setIsOpen(false); }} className={`border-gray-3000/75 dark:border-purple-taupe/50 hover:bg-gray-3000/75 dark:hover:bg-purple-taupe flex h-10 w-full cursor-pointer items-center justify-between border-t`} >

{model.display_name}

{model.id === selectedModel?.id ? ( selected ) : null}
)) ) : (

No models available

)}
)}
); }