diff --git a/frontend/.windsurfrules b/frontend/.windsurfrules index 77504d2e..baa0cc3e 100644 --- a/frontend/.windsurfrules +++ b/frontend/.windsurfrules @@ -42,3 +42,4 @@ fetchData>('account/profile', { method: } }) ``` +14. can't not import new package! diff --git a/frontend/packages/core/src/components/AIProviderSelect/index.tsx b/frontend/packages/core/src/components/AIProviderSelect/index.tsx index 2c568c4d..d0690cd5 100644 --- a/frontend/packages/core/src/components/AIProviderSelect/index.tsx +++ b/frontend/packages/core/src/components/AIProviderSelect/index.tsx @@ -1,31 +1,59 @@ -import React from 'react'; -import { Select, Space } from 'antd'; -import { useTranslation } from 'react-i18next'; +import { STATUS_CODE } from '@common/const/const' +import { useFetch } from '@common/hooks/http' +import { Select, Space, message } from 'antd' +import React, { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' -export interface AIProviderOption { - label: string; - value: string; +interface AIProvider { + id: string + name: string + logo: string + configured: boolean + status: string +} + +interface AIProviderResponse { + code: number + msg: string + data: { + providers: AIProvider[] + backup: string + } + msg_zh: string } interface AIProviderSelectProps { - value?: string; - onChange?: (value: string) => void; - style?: React.CSSProperties; - options?: AIProviderOption[]; + value?: string + onChange?: (value: string) => void + style?: React.CSSProperties } -const defaultOptions: AIProviderOption[] = [ - { label: 'OpenAI', value: 'openai' }, - { label: 'Anthropic', value: 'anthropic' } -]; +const AIProviderSelect: React.FC = ({ value, onChange, style = { width: 200 } }) => { + const { t } = useTranslation() + const [providers, setProviders] = useState([]) + const [loading, setLoading] = useState(false) + const { fetchData } = useFetch() -const AIProviderSelect: React.FC = ({ - value, - onChange, - style = { width: 200 }, - options = defaultOptions -}) => { - const { t } = useTranslation(); + useEffect(() => { + const fetchProviders = async () => { + setLoading(true) + try { + const response = await fetchData('simple/ai/providers', { method: 'GET' }) + const { code, data, msg } = response + if (code === STATUS_CODE.SUCCESS) { + setProviders(data.providers) + } else { + message.error(msg || t('Failed to fetch AI providers')) + } + } catch (error) { + message.error(t('Failed to fetch AI providers')) + } finally { + setLoading(false) + } + } + + fetchProviders() + }, []) return ( @@ -34,10 +62,28 @@ const AIProviderSelect: React.FC = ({ value={value} onChange={onChange} style={style} - options={options} + loading={loading} + showSearch + filterOption={(input, option) => { + const label = option?.label as React.ReactElement + const nameSpan = label.props.children[1] as React.ReactElement + return nameSpan.props.children.toLowerCase().includes(input.toLowerCase()) + }} + options={providers.map((provider) => ({ + label: ( + + + {provider.name} + + ), + value: provider.id + }))} /> - ); -}; + ) +} -export default AIProviderSelect; +export default AIProviderSelect diff --git a/frontend/packages/core/src/pages/keySettings/index.tsx b/frontend/packages/core/src/pages/keySettings/index.tsx index 2ac1f396..c2acbad4 100644 --- a/frontend/packages/core/src/pages/keySettings/index.tsx +++ b/frontend/packages/core/src/pages/keySettings/index.tsx @@ -148,7 +148,7 @@ const KeySettings: React.FC = () => { { title: $t('名称'), dataIndex: 'name', - render: (text: string, record: APIKey) => {text} + render: (dom: React.ReactNode, entity: APIKey) => {entity.name} }, { title: $t('状态'),