balibabu
commited on
Commit
·
bf1e3ff
1
Parent(s):
d219eb3
feat: display the version and backend service status on the page (#848)
Browse files### What problem does this PR solve?
#643 feat: display the version and backend service status on the page
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- web/src/assets/svg/es.svg +24 -0
- web/src/assets/svg/minio.svg +10 -0
- web/src/assets/svg/mysql.svg +9 -0
- web/src/assets/svg/redis.svg +6 -0
- web/src/constants/setting.ts +2 -0
- web/src/hooks/userSettingHook.ts +41 -2
- web/src/interfaces/database/userSetting.ts +28 -0
- web/src/locales/en.ts +1 -0
- web/src/locales/zh-traditional.ts +1 -0
- web/src/locales/zh.ts +1 -0
- web/src/pages/user-setting/constants.tsx +2 -0
- web/src/pages/user-setting/index.less +2 -0
- web/src/pages/user-setting/setting-system/index.less +20 -0
- web/src/pages/user-setting/setting-system/index.tsx +94 -0
- web/src/pages/user-setting/sidebar/index.less +3 -0
- web/src/pages/user-setting/sidebar/index.tsx +16 -4
- web/src/routes.ts +4 -0
- web/src/services/userService.ts +10 -0
- web/src/utils/api.ts +4 -0
- web/src/utils/commonUtil.ts +7 -0
- web/src/utils/registerServer.ts +1 -1
web/src/assets/svg/es.svg
ADDED
|
web/src/assets/svg/minio.svg
ADDED
|
web/src/assets/svg/mysql.svg
ADDED
|
web/src/assets/svg/redis.svg
ADDED
|
web/src/constants/setting.ts
CHANGED
@@ -4,6 +4,7 @@ export enum UserSettingRouteKey {
|
|
4 |
Profile = 'profile',
|
5 |
Password = 'password',
|
6 |
Model = 'model',
|
|
|
7 |
Team = 'team',
|
8 |
Logout = 'logout',
|
9 |
}
|
@@ -12,6 +13,7 @@ export const UserSettingRouteMap = {
|
|
12 |
[UserSettingRouteKey.Profile]: 'Profile',
|
13 |
[UserSettingRouteKey.Password]: 'Password',
|
14 |
[UserSettingRouteKey.Model]: 'Model Providers',
|
|
|
15 |
[UserSettingRouteKey.Team]: 'Team',
|
16 |
[UserSettingRouteKey.Logout]: 'Log out',
|
17 |
};
|
|
|
4 |
Profile = 'profile',
|
5 |
Password = 'password',
|
6 |
Model = 'model',
|
7 |
+
System = 'system',
|
8 |
Team = 'team',
|
9 |
Logout = 'logout',
|
10 |
}
|
|
|
13 |
[UserSettingRouteKey.Profile]: 'Profile',
|
14 |
[UserSettingRouteKey.Password]: 'Password',
|
15 |
[UserSettingRouteKey.Model]: 'Model Providers',
|
16 |
+
[UserSettingRouteKey.System]: 'System Version',
|
17 |
[UserSettingRouteKey.Team]: 'Team',
|
18 |
[UserSettingRouteKey.Logout]: 'Log out',
|
19 |
};
|
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 authorizationUtil from '@/utils/authorizationUtil';
|
4 |
-
import { useCallback, useEffect, useMemo } from 'react';
|
5 |
import { history, useDispatch, useSelector } from 'umi';
|
6 |
|
7 |
export const useFetchUserInfo = () => {
|
@@ -92,3 +93,41 @@ export const useSaveSetting = () => {
|
|
92 |
|
93 |
return saveSetting;
|
94 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import { ITenantInfo } from '@/interfaces/database/knowledge';
|
2 |
+
import { ISystemStatus, IUserInfo } from '@/interfaces/database/userSetting';
|
3 |
+
import userService from '@/services/userService';
|
4 |
import authorizationUtil from '@/utils/authorizationUtil';
|
5 |
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
6 |
import { history, useDispatch, useSelector } from 'umi';
|
7 |
|
8 |
export const useFetchUserInfo = () => {
|
|
|
93 |
|
94 |
return saveSetting;
|
95 |
};
|
96 |
+
|
97 |
+
export const useFetchSystemVersion = () => {
|
98 |
+
const [version, setVersion] = useState('');
|
99 |
+
const [loading, setLoading] = useState(false);
|
100 |
+
|
101 |
+
const fetchSystemVersion = useCallback(async () => {
|
102 |
+
setLoading(true);
|
103 |
+
const { data } = await userService.getSystemVersion();
|
104 |
+
if (data.retcode === 0) {
|
105 |
+
setVersion(data.data);
|
106 |
+
setLoading(false);
|
107 |
+
}
|
108 |
+
}, []);
|
109 |
+
|
110 |
+
return { fetchSystemVersion, version, loading };
|
111 |
+
};
|
112 |
+
|
113 |
+
export const useFetchSystemStatus = () => {
|
114 |
+
const [systemStatus, setSystemStatus] = useState<ISystemStatus>(
|
115 |
+
{} as ISystemStatus,
|
116 |
+
);
|
117 |
+
const [loading, setLoading] = useState(false);
|
118 |
+
|
119 |
+
const fetchSystemStatus = useCallback(async () => {
|
120 |
+
setLoading(true);
|
121 |
+
const { data } = await userService.getSystemStatus();
|
122 |
+
if (data.retcode === 0) {
|
123 |
+
setSystemStatus(data.data);
|
124 |
+
setLoading(false);
|
125 |
+
}
|
126 |
+
}, []);
|
127 |
+
|
128 |
+
return {
|
129 |
+
systemStatus,
|
130 |
+
fetchSystemStatus,
|
131 |
+
loading,
|
132 |
+
};
|
133 |
+
};
|
web/src/interfaces/database/userSetting.ts
CHANGED
@@ -19,3 +19,31 @@ export interface IUserInfo {
|
|
19 |
update_date: string;
|
20 |
update_time: number;
|
21 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
update_date: string;
|
20 |
update_time: number;
|
21 |
}
|
22 |
+
|
23 |
+
export interface ISystemStatus {
|
24 |
+
es: Es;
|
25 |
+
minio: Minio;
|
26 |
+
mysql: Minio;
|
27 |
+
redis: Redis;
|
28 |
+
}
|
29 |
+
|
30 |
+
interface Redis {
|
31 |
+
status: string;
|
32 |
+
elapsed: number;
|
33 |
+
error: string;
|
34 |
+
pending: number;
|
35 |
+
}
|
36 |
+
|
37 |
+
export interface Minio {
|
38 |
+
status: string;
|
39 |
+
elapsed: number;
|
40 |
+
error: string;
|
41 |
+
}
|
42 |
+
|
43 |
+
interface Es {
|
44 |
+
status: string;
|
45 |
+
elapsed: number;
|
46 |
+
error: string;
|
47 |
+
number_of_nodes: number;
|
48 |
+
active_shards: number;
|
49 |
+
}
|
web/src/locales/en.ts
CHANGED
@@ -393,6 +393,7 @@ export default {
|
|
393 |
model: 'Model Providers',
|
394 |
modelDescription: 'Set the model parameter and API Key here.',
|
395 |
team: 'Team',
|
|
|
396 |
logout: 'Log out',
|
397 |
username: 'Username',
|
398 |
usernameMessage: 'Please input your username!',
|
|
|
393 |
model: 'Model Providers',
|
394 |
modelDescription: 'Set the model parameter and API Key here.',
|
395 |
team: 'Team',
|
396 |
+
system: 'System',
|
397 |
logout: 'Log out',
|
398 |
username: 'Username',
|
399 |
usernameMessage: 'Please input your username!',
|
web/src/locales/zh-traditional.ts
CHANGED
@@ -364,6 +364,7 @@ export default {
|
|
364 |
modelDescription: '在此設置模型參數和 API Key。',
|
365 |
team: '團隊',
|
366 |
logout: '登出',
|
|
|
367 |
username: '使用者名稱',
|
368 |
usernameMessage: '請輸入用戶名',
|
369 |
photo: '頭像',
|
|
|
364 |
modelDescription: '在此設置模型參數和 API Key。',
|
365 |
team: '團隊',
|
366 |
logout: '登出',
|
367 |
+
system: '系統',
|
368 |
username: '使用者名稱',
|
369 |
usernameMessage: '請輸入用戶名',
|
370 |
photo: '頭像',
|
web/src/locales/zh.ts
CHANGED
@@ -380,6 +380,7 @@ export default {
|
|
380 |
model: '模型提供商',
|
381 |
modelDescription: '在此设置模型参数和 API Key。',
|
382 |
team: '团队',
|
|
|
383 |
logout: '登出',
|
384 |
username: '用户名',
|
385 |
usernameMessage: '请输入用户名',
|
|
|
380 |
model: '模型提供商',
|
381 |
modelDescription: '在此设置模型参数和 API Key。',
|
382 |
team: '团队',
|
383 |
+
system: '系统',
|
384 |
logout: '登出',
|
385 |
username: '用户名',
|
386 |
usernameMessage: '请输入用户名',
|
web/src/pages/user-setting/constants.tsx
CHANGED
@@ -4,11 +4,13 @@ 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 |
};
|
|
|
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 |
+
import { MonitorOutlined } from '@ant-design/icons';
|
8 |
|
9 |
export const UserSettingIconMap = {
|
10 |
[UserSettingRouteKey.Profile]: <ProfileIcon />,
|
11 |
[UserSettingRouteKey.Password]: <PasswordIcon />,
|
12 |
[UserSettingRouteKey.Model]: <ModelIcon />,
|
13 |
+
[UserSettingRouteKey.System]: <MonitorOutlined style={{ fontSize: 24 }} />,
|
14 |
[UserSettingRouteKey.Team]: <TeamIcon />,
|
15 |
[UserSettingRouteKey.Logout]: <LogoutIcon />,
|
16 |
};
|
web/src/pages/user-setting/index.less
CHANGED
@@ -3,6 +3,8 @@
|
|
3 |
|
4 |
.outletWrapper {
|
5 |
padding: 32px 32px 0;
|
|
|
|
|
6 |
}
|
7 |
|
8 |
.itemDescription {
|
|
|
3 |
|
4 |
.outletWrapper {
|
5 |
padding: 32px 32px 0;
|
6 |
+
height: 100%;
|
7 |
+
overflow-y: auto;
|
8 |
}
|
9 |
|
10 |
.itemDescription {
|
web/src/pages/user-setting/setting-system/index.less
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.systemInfo {
|
2 |
+
width: 100%;
|
3 |
+
.title {
|
4 |
+
font-size: 20px;
|
5 |
+
font-weight: 600;
|
6 |
+
}
|
7 |
+
.text {
|
8 |
+
height: 26px;
|
9 |
+
line-height: 26px;
|
10 |
+
}
|
11 |
+
.badge {
|
12 |
+
:global(.ant-badge-status-dot) {
|
13 |
+
width: 10px;
|
14 |
+
height: 10px;
|
15 |
+
}
|
16 |
+
}
|
17 |
+
.error {
|
18 |
+
color: red;
|
19 |
+
}
|
20 |
+
}
|
web/src/pages/user-setting/setting-system/index.tsx
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import SvgIcon from '@/components/svg-icon';
|
2 |
+
import { useFetchSystemStatus } from '@/hooks/userSettingHook';
|
3 |
+
import { ISystemStatus, Minio } from '@/interfaces/database/userSetting';
|
4 |
+
import { Badge, Card, Flex, Spin, Typography } from 'antd';
|
5 |
+
import classNames from 'classnames';
|
6 |
+
import lowerCase from 'lodash/lowerCase';
|
7 |
+
import upperFirst from 'lodash/upperFirst';
|
8 |
+
import { useEffect } from 'react';
|
9 |
+
|
10 |
+
import { toFixed } from '@/utils/commonUtil';
|
11 |
+
import styles from './index.less';
|
12 |
+
|
13 |
+
const { Text } = Typography;
|
14 |
+
|
15 |
+
enum Status {
|
16 |
+
'green' = 'success',
|
17 |
+
'red' = 'error',
|
18 |
+
'yellow' = 'warning',
|
19 |
+
}
|
20 |
+
|
21 |
+
const TitleMap = {
|
22 |
+
es: 'Elasticsearch',
|
23 |
+
minio: 'MinIO Object Storage',
|
24 |
+
redis: 'Redis',
|
25 |
+
mysql: 'Mysql',
|
26 |
+
};
|
27 |
+
|
28 |
+
const SystemInfo = () => {
|
29 |
+
const {
|
30 |
+
systemStatus,
|
31 |
+
fetchSystemStatus,
|
32 |
+
loading: statusLoading,
|
33 |
+
} = useFetchSystemStatus();
|
34 |
+
|
35 |
+
useEffect(() => {
|
36 |
+
fetchSystemStatus();
|
37 |
+
}, [fetchSystemStatus]);
|
38 |
+
|
39 |
+
return (
|
40 |
+
<section className={styles.systemInfo}>
|
41 |
+
<Spin spinning={statusLoading}>
|
42 |
+
<Flex gap={16} vertical>
|
43 |
+
{Object.keys(systemStatus).map((key) => {
|
44 |
+
const info = systemStatus[key as keyof ISystemStatus];
|
45 |
+
|
46 |
+
return (
|
47 |
+
<Card
|
48 |
+
type="inner"
|
49 |
+
title={
|
50 |
+
<Flex align="center" gap={10}>
|
51 |
+
<SvgIcon name={key} width={26}></SvgIcon>
|
52 |
+
<span className={styles.title}>
|
53 |
+
{TitleMap[key as keyof typeof TitleMap]}
|
54 |
+
</span>
|
55 |
+
<Badge
|
56 |
+
className={styles.badge}
|
57 |
+
status={Status[info.status as keyof typeof Status]}
|
58 |
+
/>
|
59 |
+
</Flex>
|
60 |
+
}
|
61 |
+
key={key}
|
62 |
+
>
|
63 |
+
{Object.keys(info)
|
64 |
+
.filter((x) => x !== 'status')
|
65 |
+
.map((x) => {
|
66 |
+
return (
|
67 |
+
<Flex
|
68 |
+
key={x}
|
69 |
+
align="center"
|
70 |
+
gap={16}
|
71 |
+
className={styles.text}
|
72 |
+
>
|
73 |
+
<b>{upperFirst(lowerCase(x))}:</b>
|
74 |
+
<Text
|
75 |
+
className={classNames({
|
76 |
+
[styles.error]: x === 'error',
|
77 |
+
})}
|
78 |
+
>
|
79 |
+
{toFixed(info[x as keyof Minio]) as any}
|
80 |
+
{x === 'elapsed' && ' ms'}
|
81 |
+
</Text>
|
82 |
+
</Flex>
|
83 |
+
);
|
84 |
+
})}
|
85 |
+
</Card>
|
86 |
+
);
|
87 |
+
})}
|
88 |
+
</Flex>
|
89 |
+
</Spin>
|
90 |
+
</section>
|
91 |
+
);
|
92 |
+
};
|
93 |
+
|
94 |
+
export default SystemInfo;
|
web/src/pages/user-setting/sidebar/index.less
CHANGED
@@ -1,3 +1,6 @@
|
|
1 |
.sideBarWrapper {
|
2 |
padding-top: 32px;
|
|
|
|
|
|
|
3 |
}
|
|
|
1 |
.sideBarWrapper {
|
2 |
padding-top: 32px;
|
3 |
+
.version {
|
4 |
+
color: rgb(17, 206, 17);
|
5 |
+
}
|
6 |
}
|
web/src/pages/user-setting/sidebar/index.tsx
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import { useSecondPathName } from '@/hooks/routeHook';
|
2 |
import type { MenuProps } from 'antd';
|
3 |
-
import { Menu } from 'antd';
|
4 |
-
import React, { useMemo } from 'react';
|
5 |
import { useNavigate } from 'umi';
|
6 |
import {
|
7 |
UserSettingBaseKey,
|
@@ -10,7 +10,7 @@ import {
|
|
10 |
} from '../constants';
|
11 |
|
12 |
import { useTranslate } from '@/hooks/commonHooks';
|
13 |
-
import { useLogout } from '@/hooks/userSettingHook';
|
14 |
import styles from './index.less';
|
15 |
|
16 |
type MenuItem = Required<MenuProps>['items'][number];
|
@@ -20,6 +20,11 @@ const SideBar = () => {
|
|
20 |
const pathName = useSecondPathName();
|
21 |
const logout = useLogout();
|
22 |
const { t } = useTranslate('setting');
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
function getItem(
|
25 |
label: string,
|
@@ -32,7 +37,14 @@ const SideBar = () => {
|
|
32 |
key,
|
33 |
icon,
|
34 |
children,
|
35 |
-
label:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
type,
|
37 |
} as MenuItem;
|
38 |
}
|
|
|
1 |
import { useSecondPathName } from '@/hooks/routeHook';
|
2 |
import type { MenuProps } from 'antd';
|
3 |
+
import { Flex, Menu } from 'antd';
|
4 |
+
import React, { useEffect, useMemo } from 'react';
|
5 |
import { useNavigate } from 'umi';
|
6 |
import {
|
7 |
UserSettingBaseKey,
|
|
|
10 |
} from '../constants';
|
11 |
|
12 |
import { useTranslate } from '@/hooks/commonHooks';
|
13 |
+
import { useFetchSystemVersion, useLogout } from '@/hooks/userSettingHook';
|
14 |
import styles from './index.less';
|
15 |
|
16 |
type MenuItem = Required<MenuProps>['items'][number];
|
|
|
20 |
const pathName = useSecondPathName();
|
21 |
const logout = useLogout();
|
22 |
const { t } = useTranslate('setting');
|
23 |
+
const { version, fetchSystemVersion } = useFetchSystemVersion();
|
24 |
+
|
25 |
+
useEffect(() => {
|
26 |
+
fetchSystemVersion();
|
27 |
+
}, [fetchSystemVersion]);
|
28 |
|
29 |
function getItem(
|
30 |
label: string,
|
|
|
37 |
key,
|
38 |
icon,
|
39 |
children,
|
40 |
+
label: (
|
41 |
+
<Flex justify={'space-between'}>
|
42 |
+
{t(label)}
|
43 |
+
<span className={styles.version}>
|
44 |
+
{label === 'system' && version}
|
45 |
+
</span>
|
46 |
+
</Flex>
|
47 |
+
),
|
48 |
type,
|
49 |
} as MenuItem;
|
50 |
}
|
web/src/routes.ts
CHANGED
@@ -78,6 +78,10 @@ const routes = [
|
|
78 |
path: '/user-setting/team',
|
79 |
component: '@/pages/user-setting/setting-team',
|
80 |
},
|
|
|
|
|
|
|
|
|
81 |
],
|
82 |
},
|
83 |
{
|
|
|
78 |
path: '/user-setting/team',
|
79 |
component: '@/pages/user-setting/setting-team',
|
80 |
},
|
81 |
+
{
|
82 |
+
path: '/user-setting/system',
|
83 |
+
component: '@/pages/user-setting/setting-system',
|
84 |
+
},
|
85 |
],
|
86 |
},
|
87 |
{
|
web/src/services/userService.ts
CHANGED
@@ -16,6 +16,8 @@ const {
|
|
16 |
set_tenant_info,
|
17 |
add_llm,
|
18 |
delete_llm,
|
|
|
|
|
19 |
} = api;
|
20 |
|
21 |
const methods = {
|
@@ -71,6 +73,14 @@ const methods = {
|
|
71 |
url: delete_llm,
|
72 |
method: 'post',
|
73 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
} as const;
|
75 |
|
76 |
const userService = registerServer<keyof typeof methods>(methods, request);
|
|
|
16 |
set_tenant_info,
|
17 |
add_llm,
|
18 |
delete_llm,
|
19 |
+
getSystemStatus,
|
20 |
+
getSystemVersion,
|
21 |
} = api;
|
22 |
|
23 |
const methods = {
|
|
|
73 |
url: delete_llm,
|
74 |
method: 'post',
|
75 |
},
|
76 |
+
getSystemStatus: {
|
77 |
+
url: getSystemStatus,
|
78 |
+
method: 'get',
|
79 |
+
},
|
80 |
+
getSystemVersion: {
|
81 |
+
url: getSystemVersion,
|
82 |
+
method: 'get',
|
83 |
+
},
|
84 |
} as const;
|
85 |
|
86 |
const userService = registerServer<keyof typeof methods>(methods, request);
|
web/src/utils/api.ts
CHANGED
@@ -77,4 +77,8 @@ export default {
|
|
77 |
createFolder: `${api_host}/file/create`,
|
78 |
connectFileToKnowledge: `${api_host}/file2document/convert`,
|
79 |
getFile: `${api_host}/file/get`,
|
|
|
|
|
|
|
|
|
80 |
};
|
|
|
77 |
createFolder: `${api_host}/file/create`,
|
78 |
connectFileToKnowledge: `${api_host}/file2document/convert`,
|
79 |
getFile: `${api_host}/file/get`,
|
80 |
+
|
81 |
+
// system
|
82 |
+
getSystemVersion: `${api_host}/system/version`,
|
83 |
+
getSystemStatus: `${api_host}/system/status`,
|
84 |
};
|
web/src/utils/commonUtil.ts
CHANGED
@@ -65,3 +65,10 @@ export const filterOptionsByInput = (
|
|
65 |
input: string,
|
66 |
option: { label: string; value: string } | undefined,
|
67 |
) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
input: string,
|
66 |
option: { label: string; value: string } | undefined,
|
67 |
) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase());
|
68 |
+
|
69 |
+
export const toFixed = (value: unknown, fixed = 2) => {
|
70 |
+
if (typeof value === 'number') {
|
71 |
+
return value.toFixed(fixed);
|
72 |
+
}
|
73 |
+
return value;
|
74 |
+
};
|
web/src/utils/registerServer.ts
CHANGED
@@ -9,7 +9,7 @@ const registerServer = <T extends string>(
|
|
9 |
) => {
|
10 |
const server: Service<T> = {} as Service<T>;
|
11 |
for (let key in opt) {
|
12 |
-
server[key] = (params
|
13 |
let url = opt[key].url;
|
14 |
const requestOptions = opt[key];
|
15 |
if (urlAppendix) {
|
|
|
9 |
) => {
|
10 |
const server: Service<T> = {} as Service<T>;
|
11 |
for (let key in opt) {
|
12 |
+
server[key] = (params?: any, urlAppendix?: string) => {
|
13 |
let url = opt[key].url;
|
14 |
const requestOptions = opt[key];
|
15 |
if (urlAppendix) {
|