From a0f1e1fa95d227ec3ec0f9beb6b63949b7d0d2a5 Mon Sep 17 00:00:00 2001 From: balibabu Date: Fri, 15 Mar 2024 19:35:59 +0800 Subject: [PATCH] feat: add SystemModelSettingModal (#127) * feat: add the model * feat: add SystemModelSettingModal --- web/src/assets/svg/more-model.svg | 14 ++ web/src/hooks/commonHooks.ts | 6 +- web/src/hooks/llmHooks.ts | 44 ++++-- web/src/pages/setting/model.ts | 4 +- .../components/setting-title/index.tsx | 27 +++- .../setting-model/api-key-modal/index.tsx | 2 +- .../pages/user-setting/setting-model/hooks.ts | 60 +++++++- .../user-setting/setting-model/index.less | 17 +++ .../user-setting/setting-model/index.tsx | 142 ++++++++++++------ .../system-model-setting-modal/index.tsx | 61 ++++++++ 10 files changed, 311 insertions(+), 66 deletions(-) create mode 100644 web/src/assets/svg/more-model.svg create mode 100644 web/src/pages/user-setting/setting-model/system-model-setting-modal/index.tsx diff --git a/web/src/assets/svg/more-model.svg b/web/src/assets/svg/more-model.svg new file mode 100644 index 000000000..c54f885c0 --- /dev/null +++ b/web/src/assets/svg/more-model.svg @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/web/src/hooks/commonHooks.ts b/web/src/hooks/commonHooks.ts index 6cbf10e89..21e6641e1 100644 --- a/web/src/hooks/commonHooks.ts +++ b/web/src/hooks/commonHooks.ts @@ -11,7 +11,11 @@ export const useSetModalState = () => { setVisible(false); }; - return { visible, showModal, hideModal }; + const switchVisible = () => { + setVisible(!visible); + }; + + return { visible, showModal, hideModal, switchVisible }; }; export const useDeepCompareEffect = ( diff --git a/web/src/hooks/llmHooks.ts b/web/src/hooks/llmHooks.ts index eed420c8e..74363b21a 100644 --- a/web/src/hooks/llmHooks.ts +++ b/web/src/hooks/llmHooks.ts @@ -7,7 +7,7 @@ import { import { useCallback, useEffect, useMemo } from 'react'; import { useDispatch, useSelector } from 'umi'; -export const useFetchLlmList = (modelType: LlmModelType) => { +export const useFetchLlmList = (modelType?: LlmModelType) => { const dispatch = useDispatch(); const fetchLlmList = useCallback(() => { @@ -85,19 +85,20 @@ export const useFetchLlmFactoryListOnMount = () => { return list; }; +export type LlmItem = { name: string; logo: string } & IMyLlmValue; + export const useFetchMyLlmListOnMount = () => { const dispatch = useDispatch(); const llmList = useSelectMyLlmList(); const factoryList = useSelectLlmFactoryList(); - const list: Array<{ name: string; logo: string } & IMyLlmValue> = - useMemo(() => { - return Object.entries(llmList).map(([key, value]) => ({ - name: key, - logo: factoryList.find((x) => x.name === key)?.logo ?? '', - ...value, - })); - }, [llmList, factoryList]); + const list: Array = useMemo(() => { + return Object.entries(llmList).map(([key, value]) => ({ + name: key, + logo: factoryList.find((x) => x.name === key)?.logo ?? '', + ...value, + })); + }, [llmList, factoryList]); const fetchMyLlmList = useCallback(() => { dispatch({ @@ -135,3 +136,28 @@ export const useSaveApiKey = () => { return saveApiKey; }; + +export interface ISystemModelSettingSavingParams { + tenant_id: string; + name?: string; + asr_id: string; + embd_id: string; + img2txt_id: string; + llm_id: string; +} + +export const useSaveTenantInfo = () => { + const dispatch = useDispatch(); + + const saveTenantInfo = useCallback( + (savingParams: ISystemModelSettingSavingParams) => { + return dispatch({ + type: 'settingModel/set_tenant_info', + payload: savingParams, + }); + }, + [dispatch], + ); + + return saveTenantInfo; +}; diff --git a/web/src/pages/setting/model.ts b/web/src/pages/setting/model.ts index 79f1e92bc..3157f896b 100644 --- a/web/src/pages/setting/model.ts +++ b/web/src/pages/setting/model.ts @@ -142,7 +142,7 @@ const model: DvaModel = { } }, *my_llm({ payload = {} }, { call, put }) { - const { data } = yield call(userService.my_llm, payload); + const { data } = yield call(userService.my_llm); const { retcode, data: res } = data; if (retcode === 0) { yield put({ @@ -158,6 +158,8 @@ const model: DvaModel = { const { retcode } = data; if (retcode === 0) { message.success('Modified!'); + yield put({ type: 'my_llm' }); + yield put({ type: 'factories_list' }); yield put({ type: 'updateState', }); diff --git a/web/src/pages/user-setting/components/setting-title/index.tsx b/web/src/pages/user-setting/components/setting-title/index.tsx index 1996d5077..8ad153f3a 100644 --- a/web/src/pages/user-setting/components/setting-title/index.tsx +++ b/web/src/pages/user-setting/components/setting-title/index.tsx @@ -1,18 +1,33 @@ -import { Typography } from 'antd'; +import { SettingOutlined } from '@ant-design/icons'; +import { Button, Flex, Typography } from 'antd'; const { Title, Paragraph } = Typography; interface IProps { title: string; description: string; + showRightButton?: boolean; + clickButton?: () => void; } -const SettingTitle = ({ title, description }: IProps) => { +const SettingTitle = ({ + title, + description, + clickButton, + showRightButton = false, +}: IProps) => { return ( -
- {title} - {description} -
+ +
+ {title} + {description} +
+ {showRightButton && ( + + )} +
); }; diff --git a/web/src/pages/user-setting/setting-model/api-key-modal/index.tsx b/web/src/pages/user-setting/setting-model/api-key-modal/index.tsx index 62b403ab9..3829cef99 100644 --- a/web/src/pages/user-setting/setting-model/api-key-modal/index.tsx +++ b/web/src/pages/user-setting/setting-model/api-key-modal/index.tsx @@ -64,7 +64,7 @@ const ApiKeyModal = ({ form={form} > - label="Api key" + label="Api-Key" name="api_key" rules={[{ required: true, message: 'Please input api key!' }]} > diff --git a/web/src/pages/user-setting/setting-model/hooks.ts b/web/src/pages/user-setting/setting-model/hooks.ts index 725f6328d..b0e70f290 100644 --- a/web/src/pages/user-setting/setting-model/hooks.ts +++ b/web/src/pages/user-setting/setting-model/hooks.ts @@ -1,6 +1,16 @@ import { useSetModalState } from '@/hooks/commonHooks'; -import { IApiKeySavingParams, useSaveApiKey } from '@/hooks/llmHooks'; +import { + IApiKeySavingParams, + ISystemModelSettingSavingParams, + useFetchLlmList, + useSaveApiKey, + useSaveTenantInfo, +} from '@/hooks/llmHooks'; import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; +import { + useFetchTenantInfo, + useSelectTenantInfo, +} from '@/hooks/userSettingHook'; import { useCallback, useState } from 'react'; type SavingParamsState = Omit; @@ -20,7 +30,7 @@ export const useSubmitApiKey = () => { async (apiKey: string) => { const ret = await saveApiKey({ ...savingParams, api_key: apiKey }); - if (ret.retcode === 0) { + if (ret === 0) { hideApiKeyModal(); } }, @@ -48,3 +58,49 @@ export const useSubmitApiKey = () => { showApiKeyModal: onShowApiKeyModal, }; }; + +export const useSubmitSystemModelSetting = () => { + const systemSetting = useSelectTenantInfo(); + const loading = useOneNamespaceEffectsLoading('settingModel', [ + 'set_tenant_info', + ]); + const saveSystemModelSetting = useSaveTenantInfo(); + const { + visible: systemSettingVisible, + hideModal: hideSystemSettingModal, + showModal: showSystemSettingModal, + } = useSetModalState(); + + const onSystemSettingSavingOk = useCallback( + async ( + payload: Omit, + ) => { + const ret = await saveSystemModelSetting({ + tenant_id: systemSetting.tenant_id, + name: systemSetting.name, + ...payload, + }); + + if (ret === 0) { + hideSystemSettingModal(); + } + }, + [hideSystemSettingModal, saveSystemModelSetting, systemSetting], + ); + + return { + saveSystemModelSettingLoading: loading, + onSystemSettingSavingOk, + systemSettingVisible, + hideSystemSettingModal, + showSystemSettingModal, + }; +}; + +export const useFetchSystemModelSettingOnMount = () => { + const systemSetting = useSelectTenantInfo(); + useFetchLlmList(); + useFetchTenantInfo(); + + return systemSetting; +}; diff --git a/web/src/pages/user-setting/setting-model/index.less b/web/src/pages/user-setting/setting-model/index.less index d91b0c01d..128c5df85 100644 --- a/web/src/pages/user-setting/setting-model/index.less +++ b/web/src/pages/user-setting/setting-model/index.less @@ -3,4 +3,21 @@ .factoryOperationWrapper { text-align: right; } + .modelItem { + } + .llmList { + padding-top: 10px; + } + .toBeAddedCard { + border-radius: 24px; + border: 1px solid #eaecf0; + background: #e3f0ff; + box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05); + } + .addedCard { + border-radius: 18px; + border: 1px solid #eaecf0; + background: #e6e7eb; + box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05); + } } diff --git a/web/src/pages/user-setting/setting-model/index.tsx b/web/src/pages/user-setting/setting-model/index.tsx index 451d23341..8ce57d9ed 100644 --- a/web/src/pages/user-setting/setting-model/index.tsx +++ b/web/src/pages/user-setting/setting-model/index.tsx @@ -1,4 +1,7 @@ +import { ReactComponent as MoreModelIcon } from '@/assets/svg/more-model.svg'; +import { useSetModalState } from '@/hooks/commonHooks'; import { + LlmItem, useFetchLlmFactoryListOnMount, useFetchMyLlmListOnMount, } from '@/hooks/llmHooks'; @@ -13,14 +16,74 @@ import { List, Row, Space, - Tag, + Typography, } from 'antd'; +import { useCallback } from 'react'; import SettingTitle from '../components/setting-title'; import ApiKeyModal from './api-key-modal'; -import { useSubmitApiKey } from './hooks'; +import { useSubmitApiKey, useSubmitSystemModelSetting } from './hooks'; +import SystemModelSettingModal from './system-model-setting-modal'; import styles from './index.less'; +const { Text } = Typography; +interface IModelCardProps { + item: LlmItem; + clickApiKey: (llmFactory: string) => void; +} + +const ModelCard = ({ item, clickApiKey }: IModelCardProps) => { + const { visible, switchVisible } = useSetModalState(); + + const handleApiKeyClick = () => { + clickApiKey(item.name); + }; + + const handleShowMoreClick = () => { + switchVisible(); + }; + + return ( + + + + + + + + {item.name} + {item.tags} + + + + + + + + + + + {visible && ( + {item.name}} + /> + )} + + + ); +}; + const UserSettingModel = () => { const factoryList = useFetchLlmFactoryListOnMount(); const llmList = useFetchMyLlmListOnMount(); @@ -32,9 +95,23 @@ const UserSettingModel = () => { hideApiKeyModal, showApiKeyModal, } = useSubmitApiKey(); + const { + saveSystemModelSettingLoading, + onSystemSettingSavingOk, + systemSettingVisible, + hideSystemSettingModal, + showSystemSettingModal, + } = useSubmitSystemModelSetting(); - const handleApiKeyClick = (llmFactory: string) => () => { - showApiKeyModal({ llm_factory: llmFactory }); + const handleApiKeyClick = useCallback( + (llmFactory: string) => { + showApiKeyModal({ llm_factory: llmFactory }); + }, + [showApiKeyModal], + ); + + const handleAddModel = (llmFactory: string) => () => { + handleApiKeyClick(llmFactory); }; return ( @@ -43,48 +120,15 @@ const UserSettingModel = () => { ( - - - - - - - - {item.name} -
- {item.tags.split(',').map((x) => ( - {x} - ))} -
-
-
- - - - - - - -
- {item.name}} - /> -
-
+ )} />

Models to be added

@@ -101,18 +145,18 @@ const UserSettingModel = () => { dataSource={factoryList} renderItem={(item) => ( - + {item.name} - - {item.tags.split(',').map((x) => ( - {x} - ))} - + {item.tags} + + )} @@ -125,6 +169,12 @@ const UserSettingModel = () => { initialValue={initialApiKey} onOk={onApiKeySavingOk} > + ); }; diff --git a/web/src/pages/user-setting/setting-model/system-model-setting-modal/index.tsx b/web/src/pages/user-setting/setting-model/system-model-setting-modal/index.tsx new file mode 100644 index 000000000..1edd60479 --- /dev/null +++ b/web/src/pages/user-setting/setting-model/system-model-setting-modal/index.tsx @@ -0,0 +1,61 @@ +import { IModalManagerChildrenProps } from '@/components/modal-manager'; +import { ISystemModelSettingSavingParams } from '@/hooks/llmHooks'; +import { Form, Modal, Select } from 'antd'; +import { useEffect } from 'react'; +import { useFetchSystemModelSettingOnMount } from '../hooks'; + +interface IProps extends Omit { + loading: boolean; + onOk: ( + payload: Omit, + ) => void; +} + +const SystemModelSettingModal = ({ + visible, + hideModal, + onOk, + loading, +}: IProps) => { + const [form] = Form.useForm(); + const initialValues = useFetchSystemModelSettingOnMount(); + + const handleOk = async () => { + const values = await form.validateFields(); + onOk(values); + }; + + useEffect(() => { + form.setFieldsValue(initialValues); + }, [form, initialValues]); + + const onFormLayoutChange = () => {}; + + return ( + +
+ + sample }]} /> + + + sample }]} /> + +
+
+ ); +}; + +export default SystemModelSettingModal;