feat: submit api key and add language to Configuration and fetch llm factory list on UserSettingModel mount (#121)

* feat: fetch llm factory list on UserSettingModel mount

* feat: add language to Configuration

* feat: submit api key
This commit is contained in:
balibabu
2024-03-12 18:58:09 +08:00
committed by GitHub
parent 0feb085c88
commit 2ca0dc0fc5
8 changed files with 422 additions and 35 deletions

View File

@@ -0,0 +1,78 @@
import { IModalManagerChildrenProps } from '@/components/modal-manager';
import { Form, Input, Modal } from 'antd';
import { useEffect } from 'react';
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
loading: boolean;
initialValue: string;
onOk: (name: string) => void;
showModal?(): void;
}
type FieldType = {
api_key?: string;
};
const ApiKeyModal = ({
visible,
hideModal,
loading,
initialValue,
onOk,
}: IProps) => {
const [form] = Form.useForm();
const handleOk = async () => {
const ret = await form.validateFields();
return onOk(ret.api_key);
};
const handleCancel = () => {
hideModal();
};
const onFinish = (values: any) => {
console.log('Success:', values);
};
const onFinishFailed = (errorInfo: any) => {
console.log('Failed:', errorInfo);
};
useEffect(() => {
form.setFieldValue('api_key', initialValue);
}, [initialValue, form]);
return (
<Modal
title="Modify"
open={visible}
onOk={handleOk}
onCancel={handleCancel}
okButtonProps={{ loading }}
confirmLoading={loading}
>
<Form
name="basic"
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
style={{ maxWidth: 600 }}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
form={form}
>
<Form.Item<FieldType>
label="Api key"
name="api_key"
rules={[{ required: true, message: 'Please input api key!' }]}
>
<Input />
</Form.Item>
</Form>
</Modal>
);
};
export default ApiKeyModal;

View File

@@ -0,0 +1,50 @@
import { useSetModalState } from '@/hooks/commonHooks';
import { IApiKeySavingParams, useSaveApiKey } from '@/hooks/llmHooks';
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
import { useCallback, useState } from 'react';
type SavingParamsState = Omit<IApiKeySavingParams, 'api_key'>;
export const useSubmitApiKey = () => {
const [savingParams, setSavingParams] = useState<SavingParamsState>(
{} as SavingParamsState,
);
const saveApiKey = useSaveApiKey();
const {
visible: apiKeyVisible,
hideModal: hideApiKeyModal,
showModal: showApiKeyModal,
} = useSetModalState();
const onApiKeySavingOk = useCallback(
async (apiKey: string) => {
const ret = await saveApiKey({ ...savingParams, api_key: apiKey });
if (ret.retcode === 0) {
hideApiKeyModal();
}
},
[hideApiKeyModal, saveApiKey, savingParams],
);
const onShowApiKeyModal = useCallback(
(savingParams: SavingParamsState) => {
setSavingParams(savingParams);
showApiKeyModal();
},
[showApiKeyModal, setSavingParams],
);
const loading = useOneNamespaceEffectsLoading('settingModel', [
'set_api_key',
]);
return {
saveApiKeyLoading: loading,
initialApiKey: '',
onApiKeySavingOk,
apiKeyVisible,
hideApiKeyModal,
showApiKeyModal: onShowApiKeyModal,
};
};

View File

@@ -0,0 +1,6 @@
.modelWrapper {
width: 100%;
.factoryOperationWrapper {
text-align: right;
}
}

View File

@@ -1,5 +1,132 @@
import {
useFetchLlmFactoryListOnMount,
useFetchMyLlmListOnMount,
} from '@/hooks/llmHooks';
import { SettingOutlined } from '@ant-design/icons';
import {
Avatar,
Button,
Card,
Col,
Divider,
Flex,
List,
Row,
Space,
Tag,
} from 'antd';
import SettingTitle from '../components/setting-title';
import ApiKeyModal from './api-key-modal';
import { useSubmitApiKey } from './hooks';
import styles from './index.less';
const UserSettingModel = () => {
return <div>UserSettingModel</div>;
const factoryList = useFetchLlmFactoryListOnMount();
const llmList = useFetchMyLlmListOnMount();
const {
saveApiKeyLoading,
initialApiKey,
onApiKeySavingOk,
apiKeyVisible,
hideApiKeyModal,
showApiKeyModal,
} = useSubmitApiKey();
const handleApiKeyClick = (llmFactory: string) => () => {
showApiKeyModal({ llm_factory: llmFactory });
};
return (
<>
<section className={styles.modelWrapper}>
<SettingTitle
title="Model Setting"
description="Manage your account settings and preferences here."
></SettingTitle>
<Divider></Divider>
<List
grid={{ gutter: 16, column: 1 }}
dataSource={llmList}
renderItem={(item) => (
<List.Item>
<Card>
<Row align={'middle'}>
<Col span={12}>
<Flex gap={'middle'} align="center">
<Avatar shape="square" size="large" src={item.logo} />
<Flex vertical gap={'small'}>
<b>{item.name}</b>
<div>
{item.tags.split(',').map((x) => (
<Tag key={x}>{x}</Tag>
))}
</div>
</Flex>
</Flex>
</Col>
<Col span={12} className={styles.factoryOperationWrapper}>
<Space size={'middle'}>
<Button onClick={handleApiKeyClick(item.name)}>
API-Key
<SettingOutlined />
</Button>
<Button>
Show more models
<SettingOutlined />
</Button>
</Space>
</Col>
</Row>
<List
size="small"
dataSource={item.llm}
renderItem={(item) => <List.Item>{item.name}</List.Item>}
/>
</Card>
</List.Item>
)}
/>
<p>Models to be added</p>
<List
grid={{
gutter: 16,
xs: 1,
sm: 2,
md: 3,
lg: 4,
xl: 4,
xxl: 8,
}}
dataSource={factoryList}
renderItem={(item) => (
<List.Item>
<Card>
<Flex vertical gap={'large'}>
<Avatar shape="square" size="large" src={item.logo} />
<Flex vertical gap={'middle'}>
<b>{item.name}</b>
<Space wrap>
{item.tags.split(',').map((x) => (
<Tag key={x}>{x}</Tag>
))}
</Space>
</Flex>
</Flex>
</Card>
</List.Item>
)}
/>
</section>
<ApiKeyModal
visible={apiKeyVisible}
hideModal={hideApiKeyModal}
loading={saveApiKeyLoading}
initialValue={initialApiKey}
onOk={onApiKeySavingOk}
></ApiKeyModal>
</>
);
};
export default UserSettingModel;