balibabu
commited on
Commit
·
d80b399
1
Parent(s):
7ccbbf8
feat: generate select options for SystemModelSettingModal grouped by type and add llm icon and add upgrade button to UserSettingTeam and replace the icon in the sidebar of the user settings page (#128)
Browse files* feat: generate select options for SystemModelSettingModal grouped by type
* feat: add llm icon
* feat: add upgrade button to UserSettingTeam
* feat: replace the icon in the sidebar of the user settings page
- web/src/assets/svg/logout.svg +5 -0
- web/src/assets/svg/model-providers.svg +5 -0
- web/src/assets/svg/password.svg +5 -0
- web/src/assets/svg/profile.svg +5 -0
- web/src/assets/svg/team.svg +5 -0
- web/src/hooks/llmHooks.ts +49 -4
- web/src/hooks/userSettingHook.ts +8 -3
- web/src/icons/moonshot.svg +31 -0
- web/src/icons/openai.svg +6 -0
- web/src/icons/tongyi.svg +7 -0
- web/src/icons/wenxin.svg +11 -0
- web/src/icons/zhipu.svg +12 -0
- web/src/layouts/components/user/index.tsx +14 -44
- web/src/layouts/index.less +4 -0
- web/src/pages/setting/model.ts +1 -20
- web/src/pages/user-setting/constants.tsx +10 -10
- web/src/pages/user-setting/setting-model/hooks.ts +14 -5
- web/src/pages/user-setting/setting-model/index.tsx +54 -15
- web/src/pages/user-setting/setting-model/system-model-setting-modal/index.tsx +10 -8
- web/src/pages/user-setting/setting-team/index.less +6 -0
- web/src/pages/user-setting/setting-team/index.tsx +17 -1
- web/src/pages/user-setting/sidebar/index.tsx +7 -1
web/src/assets/svg/logout.svg
ADDED
|
web/src/assets/svg/model-providers.svg
ADDED
|
web/src/assets/svg/password.svg
ADDED
|
web/src/assets/svg/profile.svg
ADDED
|
web/src/assets/svg/team.svg
ADDED
|
web/src/hooks/llmHooks.ts
CHANGED
@@ -7,7 +7,10 @@ import {
|
|
7 |
import { useCallback, useEffect, useMemo } from 'react';
|
8 |
import { useDispatch, useSelector } from 'umi';
|
9 |
|
10 |
-
export const useFetchLlmList = (
|
|
|
|
|
|
|
11 |
const dispatch = useDispatch();
|
12 |
|
13 |
const fetchLlmList = useCallback(() => {
|
@@ -18,15 +21,25 @@ export const useFetchLlmList = (modelType?: LlmModelType) => {
|
|
18 |
}, [dispatch, modelType]);
|
19 |
|
20 |
useEffect(() => {
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
|
|
23 |
};
|
24 |
|
25 |
-
export const
|
26 |
const llmInfo: IThirdOAIModelCollection = useSelector(
|
27 |
(state: any) => state.settingModel.llmInfo,
|
28 |
);
|
29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
const embeddingModelOptions = useMemo(() => {
|
31 |
return Object.entries(llmInfo).map(([key, value]) => {
|
32 |
return {
|
@@ -43,6 +56,38 @@ export const useSelectLlmOptions = () => {
|
|
43 |
return embeddingModelOptions;
|
44 |
};
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
export const useSelectLlmFactoryList = () => {
|
47 |
const factoryList: IFactory[] = useSelector(
|
48 |
(state: any) => state.settingModel.factoryList,
|
|
|
7 |
import { useCallback, useEffect, useMemo } from 'react';
|
8 |
import { useDispatch, useSelector } from 'umi';
|
9 |
|
10 |
+
export const useFetchLlmList = (
|
11 |
+
isOnMountFetching: boolean = true,
|
12 |
+
modelType?: LlmModelType,
|
13 |
+
) => {
|
14 |
const dispatch = useDispatch();
|
15 |
|
16 |
const fetchLlmList = useCallback(() => {
|
|
|
21 |
}, [dispatch, modelType]);
|
22 |
|
23 |
useEffect(() => {
|
24 |
+
if (isOnMountFetching) {
|
25 |
+
fetchLlmList();
|
26 |
+
}
|
27 |
+
}, [fetchLlmList, isOnMountFetching]);
|
28 |
+
|
29 |
+
return fetchLlmList;
|
30 |
};
|
31 |
|
32 |
+
export const useSelectLlmInfo = () => {
|
33 |
const llmInfo: IThirdOAIModelCollection = useSelector(
|
34 |
(state: any) => state.settingModel.llmInfo,
|
35 |
);
|
36 |
|
37 |
+
return llmInfo;
|
38 |
+
};
|
39 |
+
|
40 |
+
export const useSelectLlmOptions = () => {
|
41 |
+
const llmInfo: IThirdOAIModelCollection = useSelectLlmInfo();
|
42 |
+
|
43 |
const embeddingModelOptions = useMemo(() => {
|
44 |
return Object.entries(llmInfo).map(([key, value]) => {
|
45 |
return {
|
|
|
56 |
return embeddingModelOptions;
|
57 |
};
|
58 |
|
59 |
+
export const useSelectLlmOptionsByModelType = () => {
|
60 |
+
const llmInfo: IThirdOAIModelCollection = useSelectLlmInfo();
|
61 |
+
|
62 |
+
const groupOptionsByModelType = (modelType: LlmModelType) => {
|
63 |
+
return Object.entries(llmInfo)
|
64 |
+
.filter(([, value]) =>
|
65 |
+
modelType ? value.some((x) => x.model_type === modelType) : true,
|
66 |
+
)
|
67 |
+
.map(([key, value]) => {
|
68 |
+
return {
|
69 |
+
label: key,
|
70 |
+
options: value
|
71 |
+
.filter((x) => (modelType ? x.model_type === modelType : true))
|
72 |
+
.map((x) => ({
|
73 |
+
label: x.llm_name,
|
74 |
+
value: x.llm_name,
|
75 |
+
disabled: !x.available,
|
76 |
+
})),
|
77 |
+
};
|
78 |
+
});
|
79 |
+
};
|
80 |
+
|
81 |
+
return {
|
82 |
+
[LlmModelType.Chat]: groupOptionsByModelType(LlmModelType.Chat),
|
83 |
+
[LlmModelType.Embedding]: groupOptionsByModelType(LlmModelType.Embedding),
|
84 |
+
[LlmModelType.Image2text]: groupOptionsByModelType(LlmModelType.Image2text),
|
85 |
+
[LlmModelType.Speech2text]: groupOptionsByModelType(
|
86 |
+
LlmModelType.Speech2text,
|
87 |
+
),
|
88 |
+
};
|
89 |
+
};
|
90 |
+
|
91 |
export const useSelectLlmFactoryList = () => {
|
92 |
const factoryList: IFactory[] = useSelector(
|
93 |
(state: any) => state.settingModel.factoryList,
|
web/src/hooks/userSettingHook.ts
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
import { ITenantInfo } from '@/interfaces/database/knowledge';
|
2 |
import { IUserInfo } from '@/interfaces/database/userSetting';
|
|
|
3 |
import { useCallback, useEffect, useMemo } from 'react';
|
4 |
-
import { useDispatch, useSelector } from 'umi';
|
5 |
|
6 |
export const useFetchUserInfo = () => {
|
7 |
const dispatch = useDispatch();
|
@@ -68,8 +69,12 @@ export const useSelectParserList = (): Array<{
|
|
68 |
export const useLogout = () => {
|
69 |
const dispatch = useDispatch(); // TODO: clear redux state
|
70 |
|
71 |
-
const logout = useCallback(()
|
72 |
-
|
|
|
|
|
|
|
|
|
73 |
}, [dispatch]);
|
74 |
|
75 |
return logout;
|
|
|
1 |
import { ITenantInfo } from '@/interfaces/database/knowledge';
|
2 |
import { IUserInfo } from '@/interfaces/database/userSetting';
|
3 |
+
import authorizationUtil from '@/utils/authorizationUtil';
|
4 |
import { useCallback, useEffect, useMemo } from 'react';
|
5 |
+
import { history, useDispatch, useSelector } from 'umi';
|
6 |
|
7 |
export const useFetchUserInfo = () => {
|
8 |
const dispatch = useDispatch();
|
|
|
69 |
export const useLogout = () => {
|
70 |
const dispatch = useDispatch(); // TODO: clear redux state
|
71 |
|
72 |
+
const logout = useCallback(async () => {
|
73 |
+
const retcode = await dispatch<any>({ type: 'loginModel/logout' });
|
74 |
+
if (retcode === 0) {
|
75 |
+
authorizationUtil.removeAll();
|
76 |
+
history.push('/login');
|
77 |
+
}
|
78 |
}, [dispatch]);
|
79 |
|
80 |
return logout;
|
web/src/icons/moonshot.svg
ADDED
|
web/src/icons/openai.svg
ADDED
|
web/src/icons/tongyi.svg
ADDED
|
web/src/icons/wenxin.svg
ADDED
|
web/src/icons/zhipu.svg
ADDED
|
web/src/layouts/components/user/index.tsx
CHANGED
@@ -1,59 +1,29 @@
|
|
1 |
-
import {
|
2 |
-
|
3 |
-
|
4 |
-
useSelectUserInfo,
|
5 |
-
} from '@/hooks/userSettingHook';
|
6 |
-
import authorizationUtil from '@/utils/authorizationUtil';
|
7 |
-
import type { MenuProps } from 'antd';
|
8 |
-
import { Avatar, Button, Dropdown } from 'antd';
|
9 |
-
import React, { useCallback, useMemo } from 'react';
|
10 |
-
import { useTranslation } from 'react-i18next';
|
11 |
import { history } from 'umi';
|
12 |
|
|
|
|
|
13 |
const App: React.FC = () => {
|
14 |
-
const { t } = useTranslation();
|
15 |
const userInfo = useSelectUserInfo();
|
16 |
-
const logout = useLogout();
|
17 |
-
|
18 |
-
const handleLogout = useCallback(async () => {
|
19 |
-
const retcode = await logout();
|
20 |
-
if (retcode === 0) {
|
21 |
-
authorizationUtil.removeAll();
|
22 |
-
history.push('/login');
|
23 |
-
}
|
24 |
-
}, [logout]);
|
25 |
|
26 |
const toSetting = () => {
|
27 |
history.push('/user-setting');
|
28 |
};
|
29 |
|
30 |
-
const items: MenuProps['items'] = useMemo(() => {
|
31 |
-
return [
|
32 |
-
{
|
33 |
-
key: '1',
|
34 |
-
onClick: handleLogout,
|
35 |
-
label: <Button type="text">{t('header.logout')}</Button>,
|
36 |
-
},
|
37 |
-
{
|
38 |
-
key: '2',
|
39 |
-
onClick: toSetting,
|
40 |
-
label: <Button type="text">{t('header.setting')}</Button>,
|
41 |
-
},
|
42 |
-
];
|
43 |
-
}, [t, handleLogout]);
|
44 |
-
|
45 |
useFetchUserInfo();
|
46 |
|
47 |
return (
|
48 |
-
<
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
);
|
58 |
};
|
59 |
|
|
|
1 |
+
import { useFetchUserInfo, useSelectUserInfo } from '@/hooks/userSettingHook';
|
2 |
+
import { Avatar } from 'antd';
|
3 |
+
import React from 'react';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import { history } from 'umi';
|
5 |
|
6 |
+
import styles from '../../index.less';
|
7 |
+
|
8 |
const App: React.FC = () => {
|
|
|
9 |
const userInfo = useSelectUserInfo();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
const toSetting = () => {
|
12 |
history.push('/user-setting');
|
13 |
};
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
useFetchUserInfo();
|
16 |
|
17 |
return (
|
18 |
+
<Avatar
|
19 |
+
size={32}
|
20 |
+
onClick={toSetting}
|
21 |
+
className={styles.clickAvailable}
|
22 |
+
src={
|
23 |
+
userInfo.avatar ??
|
24 |
+
'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
|
25 |
+
}
|
26 |
+
/>
|
27 |
);
|
28 |
};
|
29 |
|
web/src/layouts/index.less
CHANGED
@@ -21,3 +21,7 @@ body {
|
|
21 |
.divider {
|
22 |
margin: 0;
|
23 |
}
|
|
|
|
|
|
|
|
|
|
21 |
.divider {
|
22 |
margin: 0;
|
23 |
}
|
24 |
+
|
25 |
+
.clickAvailable {
|
26 |
+
cursor: pointer;
|
27 |
+
}
|
web/src/pages/setting/model.ts
CHANGED
@@ -11,9 +11,6 @@ import { Nullable } from 'typings';
|
|
11 |
import { DvaModel } from 'umi';
|
12 |
|
13 |
export interface SettingModelState {
|
14 |
-
isShowPSwModal: boolean;
|
15 |
-
isShowTntModal: boolean;
|
16 |
-
isShowSSModal: boolean;
|
17 |
llm_factory: string;
|
18 |
tenantIfo: Nullable<ITenantInfo>;
|
19 |
llmInfo: IThirdAiModelCollection;
|
@@ -25,9 +22,6 @@ export interface SettingModelState {
|
|
25 |
const model: DvaModel<SettingModelState> = {
|
26 |
namespace: 'settingModel',
|
27 |
state: {
|
28 |
-
isShowPSwModal: false,
|
29 |
-
isShowTntModal: false,
|
30 |
-
isShowSSModal: false,
|
31 |
llm_factory: '',
|
32 |
tenantIfo: null,
|
33 |
llmInfo: {},
|
@@ -55,12 +49,6 @@ const model: DvaModel<SettingModelState> = {
|
|
55 |
const { retcode } = data;
|
56 |
if (retcode === 0) {
|
57 |
message.success('Modified!');
|
58 |
-
yield put({
|
59 |
-
type: 'updateState',
|
60 |
-
payload: {
|
61 |
-
isShowPSwModal: false,
|
62 |
-
},
|
63 |
-
});
|
64 |
yield put({
|
65 |
type: 'getUserInfo',
|
66 |
});
|
@@ -101,15 +89,8 @@ const model: DvaModel<SettingModelState> = {
|
|
101 |
*set_tenant_info({ payload = {} }, { call, put }) {
|
102 |
const { data } = yield call(userService.set_tenant_info, payload);
|
103 |
const { retcode } = data;
|
104 |
-
// llm_id 对应chat_id
|
105 |
-
// asr_id 对应speech2txt
|
106 |
if (retcode === 0) {
|
107 |
-
|
108 |
-
type: 'updateState',
|
109 |
-
payload: {
|
110 |
-
isShowSSModal: false,
|
111 |
-
},
|
112 |
-
});
|
113 |
yield put({
|
114 |
type: 'getTenantInfo',
|
115 |
});
|
|
|
11 |
import { DvaModel } from 'umi';
|
12 |
|
13 |
export interface SettingModelState {
|
|
|
|
|
|
|
14 |
llm_factory: string;
|
15 |
tenantIfo: Nullable<ITenantInfo>;
|
16 |
llmInfo: IThirdAiModelCollection;
|
|
|
22 |
const model: DvaModel<SettingModelState> = {
|
23 |
namespace: 'settingModel',
|
24 |
state: {
|
|
|
|
|
|
|
25 |
llm_factory: '',
|
26 |
tenantIfo: null,
|
27 |
llmInfo: {},
|
|
|
49 |
const { retcode } = data;
|
50 |
if (retcode === 0) {
|
51 |
message.success('Modified!');
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
yield put({
|
53 |
type: 'getUserInfo',
|
54 |
});
|
|
|
89 |
*set_tenant_info({ payload = {} }, { call, put }) {
|
90 |
const { data } = yield call(userService.set_tenant_info, payload);
|
91 |
const { retcode } = data;
|
|
|
|
|
92 |
if (retcode === 0) {
|
93 |
+
message.success('Modified!');
|
|
|
|
|
|
|
|
|
|
|
94 |
yield put({
|
95 |
type: 'getTenantInfo',
|
96 |
});
|
web/src/pages/user-setting/constants.tsx
CHANGED
@@ -1,16 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import { UserSettingRouteKey } from '@/constants/setting';
|
2 |
-
import {
|
3 |
-
ContainerOutlined,
|
4 |
-
DesktopOutlined,
|
5 |
-
PieChartOutlined,
|
6 |
-
} from '@ant-design/icons';
|
7 |
|
8 |
export const UserSettingIconMap = {
|
9 |
-
[UserSettingRouteKey.Profile]: <
|
10 |
-
[UserSettingRouteKey.Password]: <
|
11 |
-
[UserSettingRouteKey.Model]: <
|
12 |
-
[UserSettingRouteKey.Team]: <
|
13 |
-
[UserSettingRouteKey.Logout]: <
|
14 |
};
|
15 |
|
16 |
export * from '@/constants/setting';
|
|
|
1 |
+
import { ReactComponent as LogoutIcon } from '@/assets/svg/logout.svg';
|
2 |
+
import { ReactComponent as ModelIcon } from '@/assets/svg/model-providers.svg';
|
3 |
+
import { ReactComponent as PasswordIcon } from '@/assets/svg/password.svg';
|
4 |
+
import { ReactComponent as ProfileIcon } from '@/assets/svg/profile.svg';
|
5 |
+
import { ReactComponent as TeamIcon } from '@/assets/svg/team.svg';
|
6 |
import { UserSettingRouteKey } from '@/constants/setting';
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
export const UserSettingIconMap = {
|
9 |
+
[UserSettingRouteKey.Profile]: <ProfileIcon />,
|
10 |
+
[UserSettingRouteKey.Password]: <PasswordIcon />,
|
11 |
+
[UserSettingRouteKey.Model]: <ModelIcon />,
|
12 |
+
[UserSettingRouteKey.Team]: <TeamIcon />,
|
13 |
+
[UserSettingRouteKey.Logout]: <LogoutIcon />,
|
14 |
};
|
15 |
|
16 |
export * from '@/constants/setting';
|
web/src/pages/user-setting/setting-model/hooks.ts
CHANGED
@@ -5,13 +5,14 @@ import {
|
|
5 |
useFetchLlmList,
|
6 |
useSaveApiKey,
|
7 |
useSaveTenantInfo,
|
|
|
8 |
} from '@/hooks/llmHooks';
|
9 |
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
10 |
import {
|
11 |
useFetchTenantInfo,
|
12 |
useSelectTenantInfo,
|
13 |
} from '@/hooks/userSettingHook';
|
14 |
-
import { useCallback, useState } from 'react';
|
15 |
|
16 |
type SavingParamsState = Omit<IApiKeySavingParams, 'api_key'>;
|
17 |
|
@@ -97,10 +98,18 @@ export const useSubmitSystemModelSetting = () => {
|
|
97 |
};
|
98 |
};
|
99 |
|
100 |
-
export const useFetchSystemModelSettingOnMount = () => {
|
101 |
const systemSetting = useSelectTenantInfo();
|
102 |
-
|
103 |
-
|
|
|
104 |
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
};
|
|
|
5 |
useFetchLlmList,
|
6 |
useSaveApiKey,
|
7 |
useSaveTenantInfo,
|
8 |
+
useSelectLlmOptionsByModelType,
|
9 |
} from '@/hooks/llmHooks';
|
10 |
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
11 |
import {
|
12 |
useFetchTenantInfo,
|
13 |
useSelectTenantInfo,
|
14 |
} from '@/hooks/userSettingHook';
|
15 |
+
import { useCallback, useEffect, useState } from 'react';
|
16 |
|
17 |
type SavingParamsState = Omit<IApiKeySavingParams, 'api_key'>;
|
18 |
|
|
|
98 |
};
|
99 |
};
|
100 |
|
101 |
+
export const useFetchSystemModelSettingOnMount = (visible: boolean) => {
|
102 |
const systemSetting = useSelectTenantInfo();
|
103 |
+
const allOptions = useSelectLlmOptionsByModelType();
|
104 |
+
const fetchLlmList = useFetchLlmList();
|
105 |
+
const fetchTenantInfo = useFetchTenantInfo();
|
106 |
|
107 |
+
useEffect(() => {
|
108 |
+
if (visible) {
|
109 |
+
fetchLlmList();
|
110 |
+
fetchTenantInfo();
|
111 |
+
}
|
112 |
+
}, [fetchLlmList, fetchTenantInfo, visible]);
|
113 |
+
|
114 |
+
return { systemSetting, allOptions };
|
115 |
};
|
web/src/pages/user-setting/setting-model/index.tsx
CHANGED
@@ -5,12 +5,19 @@ import {
|
|
5 |
useFetchLlmFactoryListOnMount,
|
6 |
useFetchMyLlmListOnMount,
|
7 |
} from '@/hooks/llmHooks';
|
8 |
-
import {
|
|
|
|
|
|
|
|
|
|
|
9 |
import {
|
10 |
Avatar,
|
11 |
Button,
|
12 |
Card,
|
13 |
Col,
|
|
|
|
|
14 |
Divider,
|
15 |
Flex,
|
16 |
List,
|
@@ -26,6 +33,23 @@ import SystemModelSettingModal from './system-model-setting-modal';
|
|
26 |
|
27 |
import styles from './index.less';
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
const { Text } = Typography;
|
30 |
interface IModelCardProps {
|
31 |
item: LlmItem;
|
@@ -49,7 +73,7 @@ const ModelCard = ({ item, clickApiKey }: IModelCardProps) => {
|
|
49 |
<Row align={'middle'}>
|
50 |
<Col span={12}>
|
51 |
<Flex gap={'middle'} align="center">
|
52 |
-
<
|
53 |
<Flex vertical gap={'small'}>
|
54 |
<b>{item.name}</b>
|
55 |
<Text>{item.tags}</Text>
|
@@ -114,16 +138,11 @@ const UserSettingModel = () => {
|
|
114 |
handleApiKeyClick(llmFactory);
|
115 |
};
|
116 |
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
description="Manage your account settings and preferences here."
|
123 |
-
showRightButton
|
124 |
-
clickButton={showSystemSettingModal}
|
125 |
-
></SettingTitle>
|
126 |
-
<Divider></Divider>
|
127 |
<List
|
128 |
grid={{ gutter: 16, column: 1 }}
|
129 |
dataSource={llmList}
|
@@ -131,10 +150,15 @@ const UserSettingModel = () => {
|
|
131 |
<ModelCard item={item} clickApiKey={handleApiKeyClick}></ModelCard>
|
132 |
)}
|
133 |
/>
|
134 |
-
|
|
|
|
|
|
|
|
|
|
|
135 |
<List
|
136 |
grid={{
|
137 |
-
gutter:
|
138 |
xs: 1,
|
139 |
sm: 2,
|
140 |
md: 3,
|
@@ -147,7 +171,7 @@ const UserSettingModel = () => {
|
|
147 |
<List.Item>
|
148 |
<Card className={styles.toBeAddedCard}>
|
149 |
<Flex vertical gap={'large'}>
|
150 |
-
<
|
151 |
<Flex vertical gap={'middle'}>
|
152 |
<b>{item.name}</b>
|
153 |
<Text>{item.tags}</Text>
|
@@ -161,6 +185,21 @@ const UserSettingModel = () => {
|
|
161 |
</List.Item>
|
162 |
)}
|
163 |
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
</section>
|
165 |
<ApiKeyModal
|
166 |
visible={apiKeyVisible}
|
|
|
5 |
useFetchLlmFactoryListOnMount,
|
6 |
useFetchMyLlmListOnMount,
|
7 |
} from '@/hooks/llmHooks';
|
8 |
+
import { ReactComponent as MoonshotIcon } from '@/icons/moonshot.svg';
|
9 |
+
import { ReactComponent as OpenAiIcon } from '@/icons/openai.svg';
|
10 |
+
import { ReactComponent as TongYiIcon } from '@/icons/tongyi.svg';
|
11 |
+
import { ReactComponent as WenXinIcon } from '@/icons/wenxin.svg';
|
12 |
+
import { ReactComponent as ZhiPuIcon } from '@/icons/zhipu.svg';
|
13 |
+
import { SettingOutlined, UserOutlined } from '@ant-design/icons';
|
14 |
import {
|
15 |
Avatar,
|
16 |
Button,
|
17 |
Card,
|
18 |
Col,
|
19 |
+
Collapse,
|
20 |
+
CollapseProps,
|
21 |
Divider,
|
22 |
Flex,
|
23 |
List,
|
|
|
33 |
|
34 |
import styles from './index.less';
|
35 |
|
36 |
+
const IconMap = {
|
37 |
+
通义千问: TongYiIcon,
|
38 |
+
Moonshot: MoonshotIcon,
|
39 |
+
OpenAI: OpenAiIcon,
|
40 |
+
智谱AI: ZhiPuIcon,
|
41 |
+
文心一言: WenXinIcon,
|
42 |
+
};
|
43 |
+
|
44 |
+
const LlmIcon = ({ name }: { name: string }) => {
|
45 |
+
const Icon = IconMap[name as keyof typeof IconMap];
|
46 |
+
return Icon ? (
|
47 |
+
<Icon width={48} height={48}></Icon>
|
48 |
+
) : (
|
49 |
+
<Avatar shape="square" size="large" icon={<UserOutlined />} />
|
50 |
+
);
|
51 |
+
};
|
52 |
+
|
53 |
const { Text } = Typography;
|
54 |
interface IModelCardProps {
|
55 |
item: LlmItem;
|
|
|
73 |
<Row align={'middle'}>
|
74 |
<Col span={12}>
|
75 |
<Flex gap={'middle'} align="center">
|
76 |
+
<LlmIcon name={item.name} />
|
77 |
<Flex vertical gap={'small'}>
|
78 |
<b>{item.name}</b>
|
79 |
<Text>{item.tags}</Text>
|
|
|
138 |
handleApiKeyClick(llmFactory);
|
139 |
};
|
140 |
|
141 |
+
const items: CollapseProps['items'] = [
|
142 |
+
{
|
143 |
+
key: '1',
|
144 |
+
label: 'Added models',
|
145 |
+
children: (
|
|
|
|
|
|
|
|
|
|
|
146 |
<List
|
147 |
grid={{ gutter: 16, column: 1 }}
|
148 |
dataSource={llmList}
|
|
|
150 |
<ModelCard item={item} clickApiKey={handleApiKeyClick}></ModelCard>
|
151 |
)}
|
152 |
/>
|
153 |
+
),
|
154 |
+
},
|
155 |
+
{
|
156 |
+
key: '2',
|
157 |
+
label: 'Models to be added',
|
158 |
+
children: (
|
159 |
<List
|
160 |
grid={{
|
161 |
+
gutter: 24,
|
162 |
xs: 1,
|
163 |
sm: 2,
|
164 |
md: 3,
|
|
|
171 |
<List.Item>
|
172 |
<Card className={styles.toBeAddedCard}>
|
173 |
<Flex vertical gap={'large'}>
|
174 |
+
<LlmIcon name={item.name} />
|
175 |
<Flex vertical gap={'middle'}>
|
176 |
<b>{item.name}</b>
|
177 |
<Text>{item.tags}</Text>
|
|
|
185 |
</List.Item>
|
186 |
)}
|
187 |
/>
|
188 |
+
),
|
189 |
+
},
|
190 |
+
];
|
191 |
+
|
192 |
+
return (
|
193 |
+
<>
|
194 |
+
<section className={styles.modelWrapper}>
|
195 |
+
<SettingTitle
|
196 |
+
title="Model Setting"
|
197 |
+
description="Manage your account settings and preferences here."
|
198 |
+
showRightButton
|
199 |
+
clickButton={showSystemSettingModal}
|
200 |
+
></SettingTitle>
|
201 |
+
<Divider></Divider>
|
202 |
+
<Collapse defaultActiveKey={['1']} ghost items={items} />
|
203 |
</section>
|
204 |
<ApiKeyModal
|
205 |
visible={apiKeyVisible}
|
web/src/pages/user-setting/setting-model/system-model-setting-modal/index.tsx
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
|
|
2 |
import { ISystemModelSettingSavingParams } from '@/hooks/llmHooks';
|
3 |
import { Form, Modal, Select } from 'antd';
|
4 |
import { useEffect } from 'react';
|
@@ -18,7 +19,8 @@ const SystemModelSettingModal = ({
|
|
18 |
loading,
|
19 |
}: IProps) => {
|
20 |
const [form] = Form.useForm();
|
21 |
-
const initialValues =
|
|
|
22 |
|
23 |
const handleOk = async () => {
|
24 |
const values = await form.validateFields();
|
@@ -33,7 +35,7 @@ const SystemModelSettingModal = ({
|
|
33 |
|
34 |
return (
|
35 |
<Modal
|
36 |
-
title="
|
37 |
open={visible}
|
38 |
onOk={handleOk}
|
39 |
onCancel={hideModal}
|
@@ -41,17 +43,17 @@ const SystemModelSettingModal = ({
|
|
41 |
confirmLoading={loading}
|
42 |
>
|
43 |
<Form form={form} onValuesChange={onFormLayoutChange} layout={'vertical'}>
|
44 |
-
<Form.Item label="
|
45 |
-
<Select options={[
|
46 |
</Form.Item>
|
47 |
<Form.Item label="Embedding model" name="embd_id">
|
48 |
-
<Select options={[
|
49 |
</Form.Item>
|
50 |
-
<Form.Item label="
|
51 |
-
<Select options={[
|
52 |
</Form.Item>
|
53 |
<Form.Item label="Chat model" name="llm_id">
|
54 |
-
<Select options={[
|
55 |
</Form.Item>
|
56 |
</Form>
|
57 |
</Modal>
|
|
|
1 |
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
2 |
+
import { LlmModelType } from '@/constants/knowledge';
|
3 |
import { ISystemModelSettingSavingParams } from '@/hooks/llmHooks';
|
4 |
import { Form, Modal, Select } from 'antd';
|
5 |
import { useEffect } from 'react';
|
|
|
19 |
loading,
|
20 |
}: IProps) => {
|
21 |
const [form] = Form.useForm();
|
22 |
+
const { systemSetting: initialValues, allOptions } =
|
23 |
+
useFetchSystemModelSettingOnMount(visible);
|
24 |
|
25 |
const handleOk = async () => {
|
26 |
const values = await form.validateFields();
|
|
|
35 |
|
36 |
return (
|
37 |
<Modal
|
38 |
+
title="System Model Settings"
|
39 |
open={visible}
|
40 |
onOk={handleOk}
|
41 |
onCancel={hideModal}
|
|
|
43 |
confirmLoading={loading}
|
44 |
>
|
45 |
<Form form={form} onValuesChange={onFormLayoutChange} layout={'vertical'}>
|
46 |
+
<Form.Item label="Sequence2txt model" name="asr_id">
|
47 |
+
<Select options={allOptions[LlmModelType.Speech2text]} />
|
48 |
</Form.Item>
|
49 |
<Form.Item label="Embedding model" name="embd_id">
|
50 |
+
<Select options={allOptions[LlmModelType.Embedding]} />
|
51 |
</Form.Item>
|
52 |
+
<Form.Item label="Img2txt model" name="img2txt_id">
|
53 |
+
<Select options={allOptions[LlmModelType.Image2text]} />
|
54 |
</Form.Item>
|
55 |
<Form.Item label="Chat model" name="llm_id">
|
56 |
+
<Select options={allOptions[LlmModelType.Chat]} />
|
57 |
</Form.Item>
|
58 |
</Form>
|
59 |
</Modal>
|
web/src/pages/user-setting/setting-team/index.less
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.teamWrapper {
|
2 |
+
width: 100%;
|
3 |
+
.teamCard {
|
4 |
+
// width: 100%;
|
5 |
+
}
|
6 |
+
}
|
web/src/pages/user-setting/setting-team/index.tsx
CHANGED
@@ -1,5 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
1 |
const UserSettingTeam = () => {
|
2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
};
|
4 |
|
5 |
export default UserSettingTeam;
|
|
|
1 |
+
import { Button, Card, Flex } from 'antd';
|
2 |
+
|
3 |
+
import { useSelectUserInfo } from '@/hooks/userSettingHook';
|
4 |
+
import styles from './index.less';
|
5 |
+
|
6 |
const UserSettingTeam = () => {
|
7 |
+
const userInfo = useSelectUserInfo();
|
8 |
+
|
9 |
+
return (
|
10 |
+
<div className={styles.teamWrapper}>
|
11 |
+
<Card className={styles.teamCard}>
|
12 |
+
<Flex align="center" justify={'space-between'}>
|
13 |
+
<span>{userInfo.nickname} Workspace</span>
|
14 |
+
<Button type="primary">Upgrade</Button>
|
15 |
+
</Flex>
|
16 |
+
</Card>
|
17 |
+
</div>
|
18 |
+
);
|
19 |
};
|
20 |
|
21 |
export default UserSettingTeam;
|
web/src/pages/user-setting/sidebar/index.tsx
CHANGED
@@ -10,6 +10,7 @@ import {
|
|
10 |
UserSettingRouteMap,
|
11 |
} from '../constants';
|
12 |
|
|
|
13 |
import styles from './index.less';
|
14 |
|
15 |
type MenuItem = Required<MenuProps>['items'][number];
|
@@ -37,9 +38,14 @@ const items: MenuItem[] = Object.values(UserSettingRouteKey).map((value) =>
|
|
37 |
const SideBar = () => {
|
38 |
const navigate = useNavigate();
|
39 |
const pathName = useSecondPathName();
|
|
|
40 |
|
41 |
const handleMenuClick: MenuProps['onClick'] = ({ key }) => {
|
42 |
-
|
|
|
|
|
|
|
|
|
43 |
};
|
44 |
|
45 |
const selectedKeys = useMemo(() => {
|
|
|
10 |
UserSettingRouteMap,
|
11 |
} from '../constants';
|
12 |
|
13 |
+
import { useLogout } from '@/hooks/userSettingHook';
|
14 |
import styles from './index.less';
|
15 |
|
16 |
type MenuItem = Required<MenuProps>['items'][number];
|
|
|
38 |
const SideBar = () => {
|
39 |
const navigate = useNavigate();
|
40 |
const pathName = useSecondPathName();
|
41 |
+
const logout = useLogout();
|
42 |
|
43 |
const handleMenuClick: MenuProps['onClick'] = ({ key }) => {
|
44 |
+
if (key === UserSettingRouteKey.Logout) {
|
45 |
+
logout();
|
46 |
+
} else {
|
47 |
+
navigate(`/${UserSettingBaseKey}/${key}`);
|
48 |
+
}
|
49 |
};
|
50 |
|
51 |
const selectedKeys = useMemo(() => {
|