feat: ai provider component

This commit is contained in:
scarqin
2024-12-25 15:41:20 +08:00
parent f9501d6f60
commit 2ad508ec60
3 changed files with 73 additions and 26 deletions
+1
View File
@@ -42,3 +42,4 @@ fetchData<BasicResponse<{ profile: UserInfoType }>>('account/profile', { method:
}
})
```
14. can't not import new package!
@@ -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<AIProviderSelectProps> = ({ value, onChange, style = { width: 200 } }) => {
const { t } = useTranslation()
const [providers, setProviders] = useState<AIProvider[]>([])
const [loading, setLoading] = useState(false)
const { fetchData } = useFetch()
const AIProviderSelect: React.FC<AIProviderSelectProps> = ({
value,
onChange,
style = { width: 200 },
options = defaultOptions
}) => {
const { t } = useTranslation();
useEffect(() => {
const fetchProviders = async () => {
setLoading(true)
try {
const response = await fetchData<AIProviderResponse>('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 (
<Space className="flex items-center">
@@ -34,10 +62,28 @@ const AIProviderSelect: React.FC<AIProviderSelectProps> = ({
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: (
<Space className="flex items-center">
<span
className="flex items-center h-[20px] w-[20px]"
dangerouslySetInnerHTML={{ __html: provider.logo }}
></span>
<span>{provider.name}</span>
</Space>
),
value: provider.id
}))}
/>
</Space>
);
};
)
}
export default AIProviderSelect;
export default AIProviderSelect
@@ -148,7 +148,7 @@ const KeySettings: React.FC = () => {
{
title: $t('名称'),
dataIndex: 'name',
render: (text: string, record: APIKey) => <Space>{text}</Space>
render: (dom: React.ReactNode, entity: APIKey) => <Space>{entity.name}</Space>
},
{
title: $t('状态'),