dify
/
web
/app
/components
/header
/account-setting
/model-provider-page
/model-selector
/index.tsx
import type { FC } from 'react' | |
import { useState } from 'react' | |
import type { | |
DefaultModel, | |
Model, | |
ModelItem, | |
} from '../declarations' | |
import { useCurrentProviderAndModel } from '../hooks' | |
import ModelTrigger from './model-trigger' | |
import EmptyTrigger from './empty-trigger' | |
import DeprecatedModelTrigger from './deprecated-model-trigger' | |
import Popup from './popup' | |
import { | |
PortalToFollowElem, | |
PortalToFollowElemContent, | |
PortalToFollowElemTrigger, | |
} from '@/app/components/base/portal-to-follow-elem' | |
type ModelSelectorProps = { | |
defaultModel?: DefaultModel | |
modelList: Model[] | |
triggerClassName?: string | |
popupClassName?: string | |
onSelect?: (model: DefaultModel) => void | |
readonly?: boolean | |
} | |
const ModelSelector: FC<ModelSelectorProps> = ({ | |
defaultModel, | |
modelList, | |
triggerClassName, | |
popupClassName, | |
onSelect, | |
readonly, | |
}) => { | |
const [open, setOpen] = useState(false) | |
const { | |
currentProvider, | |
currentModel, | |
} = useCurrentProviderAndModel( | |
modelList, | |
defaultModel, | |
) | |
const handleSelect = (provider: string, model: ModelItem) => { | |
setOpen(false) | |
if (onSelect) | |
onSelect({ provider, model: model.model }) | |
} | |
const handleToggle = () => { | |
if (readonly) | |
return | |
setOpen(v => !v) | |
} | |
return ( | |
<PortalToFollowElem | |
open={open} | |
onOpenChange={setOpen} | |
placement='bottom-start' | |
offset={4} | |
> | |
<div className='relative'> | |
<PortalToFollowElemTrigger | |
onClick={handleToggle} | |
className='block' | |
> | |
{ | |
currentModel && currentProvider && ( | |
<ModelTrigger | |
open={open} | |
provider={currentProvider} | |
model={currentModel} | |
className={triggerClassName} | |
readonly={readonly} | |
/> | |
) | |
} | |
{ | |
!currentModel && defaultModel && ( | |
<DeprecatedModelTrigger | |
modelName={defaultModel?.model || ''} | |
providerName={defaultModel?.provider || ''} | |
className={triggerClassName} | |
/> | |
) | |
} | |
{ | |
!defaultModel && ( | |
<EmptyTrigger | |
open={open} | |
className={triggerClassName} | |
/> | |
) | |
} | |
</PortalToFollowElemTrigger> | |
<PortalToFollowElemContent className={`z-[1002] ${popupClassName}`}> | |
<Popup | |
defaultModel={defaultModel} | |
modelList={modelList} | |
onSelect={handleSelect} | |
/> | |
</PortalToFollowElemContent> | |
</div> | |
</PortalToFollowElem> | |
) | |
} | |
export default ModelSelector | |