refactor: improve server status list data display

This commit is contained in:
moonrailgun 2023-11-01 00:39:37 +08:00
parent 5576d8713e
commit 896170836c
3 changed files with 67 additions and 8 deletions

View File

@ -27,7 +27,7 @@ var (
Url = flag.String("url", "", "The http url of tianji, for example: https://tianji.msgbyte.com") Url = flag.String("url", "", "The http url of tianji, for example: https://tianji.msgbyte.com")
WorkspaceId = flag.String("workspace", "", "The workspace id for tianji, this should be a uuid") WorkspaceId = flag.String("workspace", "", "The workspace id for tianji, this should be a uuid")
Name = flag.String("name", "", "The identification name for this machine") Name = flag.String("name", "", "The identification name for this machine")
Interval = flag.Int("interval", 20.0, "Input the INTERVAL") Interval = flag.Int("interval", 10.0, "Input the INTERVAL, seconed")
IsVnstat = flag.Bool("vnstat", false, "Use vnstat for traffic statistics, linux only") IsVnstat = flag.Bool("vnstat", false, "Use vnstat for traffic statistics, linux only")
) )

View File

@ -0,0 +1,17 @@
import { useEffect, useReducer } from 'react';
export function useIntervalUpdate(timeout: number) {
// update list in 10 second
const [inc, update] = useReducer((state) => state + 1, 0);
useEffect(() => {
const timer = window.setInterval(() => {
update();
}, timeout);
return () => {
window.clearInterval(timer);
};
}, []);
return inc;
}

View File

@ -1,12 +1,15 @@
import React, { useEffect, useMemo, useRef, useState } from 'react'; import React, { useEffect, useMemo, useReducer, useRef, useState } from 'react';
import { import {
Badge, Badge,
Button, Button,
Empty,
Form, Form,
Input, Input,
Modal, Modal,
Steps, Steps,
Switch,
Table, Table,
Tooltip,
Typography, Typography,
} from 'antd'; } from 'antd';
import { ColumnsType } from 'antd/es/table'; import { ColumnsType } from 'antd/es/table';
@ -22,9 +25,12 @@ import { useCurrentWorkspaceId } from '../store/user';
import { useWatch } from '../hooks/useWatch'; import { useWatch } from '../hooks/useWatch';
import { Loading } from '../components/Loading'; import { Loading } from '../components/Loading';
import { without } from 'lodash-es'; import { without } from 'lodash-es';
import { useIntervalUpdate } from '../hooks/useIntervalUpdate';
import clsx from 'clsx';
export const Servers: React.FC = React.memo(() => { export const Servers: React.FC = React.memo(() => {
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [hideOfflineServer, setHideOfflineServer] = useState(false);
const handleOk = () => { const handleOk = () => {
setIsModalOpen(false); setIsModalOpen(false);
@ -34,7 +40,15 @@ export const Servers: React.FC = React.memo(() => {
<div> <div>
<div className="h-24 flex items-center"> <div className="h-24 flex items-center">
<div className="text-2xl flex-1">Servers</div> <div className="text-2xl flex-1">Servers</div>
<div> <div className="flex items-center gap-4">
<div className="flex items-center gap-1 text-gray-500">
<Switch
checked={hideOfflineServer}
onChange={setHideOfflineServer}
/>
Hide Offline
</div>
<Button <Button
type="primary" type="primary"
icon={<PlusOutlined />} icon={<PlusOutlined />}
@ -46,7 +60,7 @@ export const Servers: React.FC = React.memo(() => {
</div> </div>
</div> </div>
<ServerList /> <ServerList hideOfflineServer={hideOfflineServer} />
<Modal <Modal
title="Add Server" title="Add Server"
@ -74,10 +88,26 @@ function useServerMap(): Record<string, ServerStatusInfo> {
return serverMap; return serverMap;
} }
export const ServerList: React.FC = React.memo(() => { export const ServerList: React.FC<{
hideOfflineServer: boolean;
}> = React.memo((props) => {
const serverMap = useServerMap(); const serverMap = useServerMap();
const inc = useIntervalUpdate(2 * 1000);
const { hideOfflineServer } = props;
const dataSource = Object.values(serverMap); const dataSource = useMemo(
() =>
Object.values(serverMap)
.sort((info) => (isServerOnline(info) ? -1 : 1))
.filter((info) => {
if (hideOfflineServer) {
return isServerOnline(info);
}
return true;
}), // make online server is up and offline is down
[serverMap, inc, hideOfflineServer]
);
const lastUpdatedAt = max(dataSource.map((d) => d.updatedAt)); const lastUpdatedAt = max(dataSource.map((d) => d.updatedAt));
const columns = useMemo((): ColumnsType<ServerStatusInfo> => { const columns = useMemo((): ColumnsType<ServerStatusInfo> => {
@ -86,10 +116,16 @@ export const ServerList: React.FC = React.memo(() => {
key: 'status', key: 'status',
title: 'Status', title: 'Status',
render: (val, record) => { render: (val, record) => {
return Date.now() - (record.updatedAt + record.timeout) < 0 ? ( return isServerOnline(record) ? (
<Badge status="success" text="online" /> <Badge status="success" text="online" />
) : ( ) : (
<Badge status="error" text="offline" /> <Tooltip
title={`Last online: ${dayjs(record.updatedAt).format(
'YYYY-MM-DD HH:mm:ss'
)}`}
>
<Badge status="error" text="offline" />
</Tooltip>
); );
}, },
}, },
@ -174,6 +210,8 @@ export const ServerList: React.FC = React.memo(() => {
columns={columns} columns={columns}
dataSource={dataSource} dataSource={dataSource}
pagination={false} pagination={false}
locale={{ emptyText: <Empty description="No server online" /> }}
rowClassName={(record) => clsx(!isServerOnline(record) && 'opacity-80')}
/> />
</div> </div>
); );
@ -274,3 +312,7 @@ export const AddServerStep: React.FC = React.memo(() => {
); );
}); });
AddServerStep.displayName = 'AddServerStep'; AddServerStep.displayName = 'AddServerStep';
function isServerOnline(info: ServerStatusInfo): boolean {
return new Date(info.updatedAt).valueOf() + info.timeout * 1000 > Date.now();
}