/* * @Author: ZhaoYing * @Date: 2026-03-07 16:49:59 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-04-17 10:11:54 */ import { type FC, useEffect, useState } from 'react'; import { Select, Flex, Space } from 'antd'; import type { SelectProps } from 'antd/es/select'; import { useTranslation } from 'react-i18next'; import { getModelList } from '@/api/models'; import type { Query, Model } from '@/views/ModelManagement/types'; import { getListLogoUrl } from '@/views/ModelManagement/utils'; import Tag from '@/components/Tag'; /** Extends AntD SelectProps; omits filterOption since it's handled internally */ interface ModelSelectProps extends SelectProps { /** Extra query params passed to getModelList */ params?: Query; placeholder?: string; fontClassName?: string; isAutoFetch?: boolean; initialData?: Model[]; updateOptions?: (options: Model[]) => void; } const ModelSelect: FC = ({ params, placeholder, fontClassName, isAutoFetch = true, initialData = [], updateOptions, ...props }) => { const { t } = useTranslation(); const [options, setOptions] = useState([]); // Fetch active models whenever params change; stringify for stable deep comparison useEffect(() => { if (!isAutoFetch) return getModelList({ ...(params ?? {}), pagesize: 100, is_active: true }).then((res) => { setOptions((res as { items: Model[] }).items ?? []); }); }, [JSON.stringify(params), isAutoFetch]); // Render the selected value inside the trigger with logo + truncated name const labelRender: SelectProps['labelRender'] = ({ value }) => { const item = options.find((o) => o.id === value); if (!item) return undefined; const logo = getListLogoUrl(item.provider, item.logo as string); return ( {logo && {logo}}
{item.name}
); }; useEffect(() => { if (updateOptions) updateOptions([...options, ...initialData]); }, [options, initialData]) return (