feat: display the version and backend service status on the page (#848)
### 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)
This commit is contained in:
@@ -4,11 +4,13 @@ import { ReactComponent as PasswordIcon } from '@/assets/svg/password.svg';
|
||||
import { ReactComponent as ProfileIcon } from '@/assets/svg/profile.svg';
|
||||
import { ReactComponent as TeamIcon } from '@/assets/svg/team.svg';
|
||||
import { UserSettingRouteKey } from '@/constants/setting';
|
||||
import { MonitorOutlined } from '@ant-design/icons';
|
||||
|
||||
export const UserSettingIconMap = {
|
||||
[UserSettingRouteKey.Profile]: <ProfileIcon />,
|
||||
[UserSettingRouteKey.Password]: <PasswordIcon />,
|
||||
[UserSettingRouteKey.Model]: <ModelIcon />,
|
||||
[UserSettingRouteKey.System]: <MonitorOutlined style={{ fontSize: 24 }} />,
|
||||
[UserSettingRouteKey.Team]: <TeamIcon />,
|
||||
[UserSettingRouteKey.Logout]: <LogoutIcon />,
|
||||
};
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
.outletWrapper {
|
||||
padding: 32px 32px 0;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.itemDescription {
|
||||
|
||||
20
web/src/pages/user-setting/setting-system/index.less
Normal file
20
web/src/pages/user-setting/setting-system/index.less
Normal file
@@ -0,0 +1,20 @@
|
||||
.systemInfo {
|
||||
width: 100%;
|
||||
.title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.text {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
.badge {
|
||||
:global(.ant-badge-status-dot) {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
94
web/src/pages/user-setting/setting-system/index.tsx
Normal file
94
web/src/pages/user-setting/setting-system/index.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
import SvgIcon from '@/components/svg-icon';
|
||||
import { useFetchSystemStatus } from '@/hooks/userSettingHook';
|
||||
import { ISystemStatus, Minio } from '@/interfaces/database/userSetting';
|
||||
import { Badge, Card, Flex, Spin, Typography } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import lowerCase from 'lodash/lowerCase';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { toFixed } from '@/utils/commonUtil';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
enum Status {
|
||||
'green' = 'success',
|
||||
'red' = 'error',
|
||||
'yellow' = 'warning',
|
||||
}
|
||||
|
||||
const TitleMap = {
|
||||
es: 'Elasticsearch',
|
||||
minio: 'MinIO Object Storage',
|
||||
redis: 'Redis',
|
||||
mysql: 'Mysql',
|
||||
};
|
||||
|
||||
const SystemInfo = () => {
|
||||
const {
|
||||
systemStatus,
|
||||
fetchSystemStatus,
|
||||
loading: statusLoading,
|
||||
} = useFetchSystemStatus();
|
||||
|
||||
useEffect(() => {
|
||||
fetchSystemStatus();
|
||||
}, [fetchSystemStatus]);
|
||||
|
||||
return (
|
||||
<section className={styles.systemInfo}>
|
||||
<Spin spinning={statusLoading}>
|
||||
<Flex gap={16} vertical>
|
||||
{Object.keys(systemStatus).map((key) => {
|
||||
const info = systemStatus[key as keyof ISystemStatus];
|
||||
|
||||
return (
|
||||
<Card
|
||||
type="inner"
|
||||
title={
|
||||
<Flex align="center" gap={10}>
|
||||
<SvgIcon name={key} width={26}></SvgIcon>
|
||||
<span className={styles.title}>
|
||||
{TitleMap[key as keyof typeof TitleMap]}
|
||||
</span>
|
||||
<Badge
|
||||
className={styles.badge}
|
||||
status={Status[info.status as keyof typeof Status]}
|
||||
/>
|
||||
</Flex>
|
||||
}
|
||||
key={key}
|
||||
>
|
||||
{Object.keys(info)
|
||||
.filter((x) => x !== 'status')
|
||||
.map((x) => {
|
||||
return (
|
||||
<Flex
|
||||
key={x}
|
||||
align="center"
|
||||
gap={16}
|
||||
className={styles.text}
|
||||
>
|
||||
<b>{upperFirst(lowerCase(x))}:</b>
|
||||
<Text
|
||||
className={classNames({
|
||||
[styles.error]: x === 'error',
|
||||
})}
|
||||
>
|
||||
{toFixed(info[x as keyof Minio]) as any}
|
||||
{x === 'elapsed' && ' ms'}
|
||||
</Text>
|
||||
</Flex>
|
||||
);
|
||||
})}
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
</Spin>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default SystemInfo;
|
||||
@@ -1,3 +1,6 @@
|
||||
.sideBarWrapper {
|
||||
padding-top: 32px;
|
||||
.version {
|
||||
color: rgb(17, 206, 17);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useSecondPathName } from '@/hooks/routeHook';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { Menu } from 'antd';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Flex, Menu } from 'antd';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { useNavigate } from 'umi';
|
||||
import {
|
||||
UserSettingBaseKey,
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '../constants';
|
||||
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { useLogout } from '@/hooks/userSettingHook';
|
||||
import { useFetchSystemVersion, useLogout } from '@/hooks/userSettingHook';
|
||||
import styles from './index.less';
|
||||
|
||||
type MenuItem = Required<MenuProps>['items'][number];
|
||||
@@ -20,6 +20,11 @@ const SideBar = () => {
|
||||
const pathName = useSecondPathName();
|
||||
const logout = useLogout();
|
||||
const { t } = useTranslate('setting');
|
||||
const { version, fetchSystemVersion } = useFetchSystemVersion();
|
||||
|
||||
useEffect(() => {
|
||||
fetchSystemVersion();
|
||||
}, [fetchSystemVersion]);
|
||||
|
||||
function getItem(
|
||||
label: string,
|
||||
@@ -32,7 +37,14 @@ const SideBar = () => {
|
||||
key,
|
||||
icon,
|
||||
children,
|
||||
label: t(label),
|
||||
label: (
|
||||
<Flex justify={'space-between'}>
|
||||
{t(label)}
|
||||
<span className={styles.version}>
|
||||
{label === 'system' && version}
|
||||
</span>
|
||||
</Flex>
|
||||
),
|
||||
type,
|
||||
} as MenuItem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user