fix: ui issues
This commit is contained in:
@@ -42,10 +42,7 @@ const AccessToken = () => {
|
||||
rules={[
|
||||
{
|
||||
required: false,
|
||||
message: getRuleMessage(
|
||||
'input',
|
||||
intl.formatMessage({ id: 'providers.form.tokens.title' })
|
||||
)
|
||||
message: getRuleMessage('input', 'providers.form.tokens.title')
|
||||
}
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -4,12 +4,15 @@ import useAppUtils from '@/hooks/use-app-utils';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import ProviderLogo from '../components/provider-logo';
|
||||
import { maasProviderOptions } from '../config/providers';
|
||||
import { maasProviderOptions, ProviderEnum } from '../config/providers';
|
||||
import { FormData } from '../config/types';
|
||||
|
||||
const Basic = () => {
|
||||
const Basic: React.FC<{
|
||||
onAPIKeyBlur?: (e: any) => void;
|
||||
}> = ({ onAPIKeyBlur }) => {
|
||||
const intl = useIntl();
|
||||
const form = Form.useFormInstance<FormData>();
|
||||
const providerType = Form.useWatch(['config', 'type'], form);
|
||||
const { getRuleMessage } = useAppUtils();
|
||||
|
||||
const optionRender = (option: any) => {
|
||||
@@ -30,7 +33,17 @@ const Basic = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item<FormData> name="name" data-field="name">
|
||||
<Form.Item<FormData>
|
||||
name="name"
|
||||
data-field="name"
|
||||
required
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: getRuleMessage('input', 'common.table.name')
|
||||
}
|
||||
]}
|
||||
>
|
||||
<SealInput.Input
|
||||
required
|
||||
label={intl.formatMessage({
|
||||
@@ -43,10 +56,7 @@ const Basic = () => {
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: getRuleMessage(
|
||||
'select',
|
||||
intl.formatMessage({ id: 'common.table.type' })
|
||||
)
|
||||
message: getRuleMessage('select', 'common.table.type')
|
||||
}
|
||||
]}
|
||||
>
|
||||
@@ -63,6 +73,16 @@ const Basic = () => {
|
||||
})}
|
||||
/>
|
||||
</Form.Item>
|
||||
{providerType === ProviderEnum.OPENAI && (
|
||||
<Form.Item<FormData> name={['config', 'openaiCustomUrl']}>
|
||||
<SealInput.Input
|
||||
placeholder="http://<your-inference-server>/v1"
|
||||
label={intl.formatMessage({
|
||||
id: 'providers.form.custombeckendUrl'
|
||||
})}
|
||||
/>
|
||||
</Form.Item>
|
||||
)}
|
||||
<Form.Item<FormData>
|
||||
name="api_key"
|
||||
rules={[
|
||||
@@ -74,6 +94,7 @@ const Basic = () => {
|
||||
>
|
||||
<SealInput.Password
|
||||
required
|
||||
onBlur={onAPIKeyBlur}
|
||||
label={intl.formatMessage({
|
||||
id: 'providers.form.tokens.title'
|
||||
})}
|
||||
|
||||
@@ -107,7 +107,9 @@ const ProviderForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
api_key: currentData.api_tokens?.[0] || '',
|
||||
api_tokens: currentData.api_tokens?.slice(1) || [],
|
||||
proxy_enabled: !!currentData.proxy_url,
|
||||
custom_config: json2Yaml(_.omit(currentData.config, ['type']) || {})
|
||||
custom_config: json2Yaml(
|
||||
_.omit(currentData.config, ['type', 'openaiCustomUrl']) || {}
|
||||
)
|
||||
});
|
||||
}
|
||||
}, [form, currentData, action]);
|
||||
|
||||
@@ -3,8 +3,8 @@ import SealSelect from '@/components/seal-form/seal-select';
|
||||
import { categoryOptions } from '@/pages/llmodels/config';
|
||||
import {
|
||||
CheckCircleFilled,
|
||||
CloseCircleFilled,
|
||||
LoadingOutlined
|
||||
LoadingOutlined,
|
||||
WarningFilled
|
||||
} from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Form, Tooltip } from 'antd';
|
||||
@@ -27,9 +27,15 @@ const SelectWrapper = styled.div`
|
||||
`;
|
||||
|
||||
interface ModelItemProps {
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
onChange: (data: ProviderModel) => void;
|
||||
providerModelList: Global.BaseOption<string>[];
|
||||
providerModelList: Global.BaseOption<
|
||||
string,
|
||||
{
|
||||
category: string;
|
||||
accessible: boolean;
|
||||
}
|
||||
>[];
|
||||
selectedModelList: ProviderModel[];
|
||||
item: ProviderModel;
|
||||
loading?: boolean;
|
||||
@@ -63,10 +69,9 @@ const ModelItem: React.FC<ModelItemProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
const handleOnChange = (value: string) => {
|
||||
const handleOnChange = (value: string, option: any) => {
|
||||
onChange({
|
||||
...item,
|
||||
accessible: null,
|
||||
...option,
|
||||
name: value
|
||||
});
|
||||
};
|
||||
@@ -79,20 +84,26 @@ const ModelItem: React.FC<ModelItemProps> = ({
|
||||
};
|
||||
|
||||
const renderSuffixIcon = () => {
|
||||
console.log(
|
||||
'testLoading',
|
||||
testLoading,
|
||||
item.accessible,
|
||||
item.accessible === false
|
||||
);
|
||||
if (testLoading) {
|
||||
return <LoadingOutlined />;
|
||||
}
|
||||
if (item.accessible === true) {
|
||||
return (
|
||||
<CheckCircleFilled
|
||||
style={{ color: 'var(--ant-color-success)', fontSize: 16 }}
|
||||
style={{ color: 'var(--ant-color-success)', fontSize: 14 }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (item.accessible === false) {
|
||||
return (
|
||||
<CloseCircleFilled
|
||||
style={{ color: 'var(--ant-color-error)', fontSize: 16 }}
|
||||
<WarningFilled
|
||||
style={{ color: 'var(--ant-color-error)', fontSize: 14 }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import MetadataList from '@/components/metadata-list';
|
||||
import useAppUtils from '@/hooks/use-app-utils';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import { useRef } from 'react';
|
||||
import { FormData, ProviderModel } from '../config/types';
|
||||
import { useQueryProviderModels } from '../hooks/use-query-provider-models';
|
||||
import ModelItem from './model-item';
|
||||
@@ -11,15 +13,26 @@ const SupportedModels = () => {
|
||||
useQueryProviderModels();
|
||||
const form = Form.useFormInstance<FormData>();
|
||||
const modelList = Form.useWatch('models', form) || [];
|
||||
const prevAPIKeyRef = useRef<string>('');
|
||||
const { getRuleMessage } = useAppUtils();
|
||||
|
||||
const handleOpenChange = async (open: boolean) => {
|
||||
try {
|
||||
await form.validateFields(['api_key']);
|
||||
|
||||
if (open && providerModelList.length === 0) {
|
||||
const currentAPIKey = form.getFieldValue('api_key') || '';
|
||||
|
||||
// Avoid repeated requests with the same API key
|
||||
if (
|
||||
open &&
|
||||
providerModelList.length === 0 &&
|
||||
prevAPIKeyRef.current !== currentAPIKey &&
|
||||
currentAPIKey
|
||||
) {
|
||||
prevAPIKeyRef.current = currentAPIKey;
|
||||
fetchProviderModels({
|
||||
data: {
|
||||
api_token: form.getFieldValue('api_key') || '',
|
||||
api_token: currentAPIKey,
|
||||
config: {
|
||||
type: form.getFieldValue(['config', 'type']) || ''
|
||||
}
|
||||
@@ -55,7 +68,33 @@ const SupportedModels = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item name="models" data-field="supportedModels">
|
||||
<Form.Item
|
||||
name="models"
|
||||
data-field="supportedModels"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
validator: async (_, value) => {
|
||||
if (!value || value.length === 0) {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
getRuleMessage('input', 'providers.form.rules.models')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (value.some((item: ProviderModel) => !item.name)) {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
getRuleMessage('select', 'providers.form.rules.model')
|
||||
)
|
||||
);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
]}
|
||||
>
|
||||
<MetadataList
|
||||
styles={{
|
||||
wrapper: {
|
||||
|
||||
Reference in New Issue
Block a user