feat: add clear offlline node button
This commit is contained in:
parent
c41994879a
commit
b6846b0419
@ -1,11 +1,13 @@
|
||||
import React, { useEffect, useMemo, useReducer, useRef, useState } from 'react';
|
||||
import React, { useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Divider,
|
||||
Empty,
|
||||
Form,
|
||||
Input,
|
||||
Modal,
|
||||
Popconfirm,
|
||||
Steps,
|
||||
Switch,
|
||||
Table,
|
||||
@ -28,15 +30,31 @@ import { Loading } from '../components/Loading';
|
||||
import { without } from 'lodash-es';
|
||||
import { useIntervalUpdate } from '../hooks/useIntervalUpdate';
|
||||
import clsx from 'clsx';
|
||||
import { isServerOnline } from '../../shared';
|
||||
import { defaultErrorHandler, trpc } from '../api/trpc';
|
||||
import { useEvent } from '../hooks/useEvent';
|
||||
import { useRequest } from '../hooks/useRequest';
|
||||
|
||||
export const Servers: React.FC = React.memo(() => {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [hideOfflineServer, setHideOfflineServer] = useState(false);
|
||||
const workspaceId = useCurrentWorkspaceId();
|
||||
|
||||
const handleOk = () => {
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
|
||||
const clearOfflineNodeMutation =
|
||||
trpc.serverStatus.clearOfflineServerStatus.useMutation({
|
||||
onError: defaultErrorHandler,
|
||||
});
|
||||
|
||||
const [{ loading }, handleClearOfflineNode] = useRequest(async (e) => {
|
||||
await clearOfflineNodeMutation.mutateAsync({
|
||||
workspaceId,
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="h-24 flex items-center">
|
||||
@ -50,6 +68,21 @@ export const Servers: React.FC = React.memo(() => {
|
||||
Hide Offline
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Popconfirm
|
||||
title="Clear Offline Node"
|
||||
description="Are you sure to clear all offline node?"
|
||||
disabled={loading}
|
||||
onConfirm={handleClearOfflineNode}
|
||||
>
|
||||
<Button size="large" loading={loading}>
|
||||
Clear Offline
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
|
||||
<Divider type="vertical" />
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
@ -151,10 +184,10 @@ export const ServerList: React.FC<{
|
||||
dataIndex: 'hostname',
|
||||
title: 'Host Name',
|
||||
},
|
||||
{
|
||||
dataIndex: ['payload', 'system'],
|
||||
title: 'System',
|
||||
},
|
||||
// {
|
||||
// dataIndex: ['payload', 'system'],
|
||||
// title: 'System',
|
||||
// },
|
||||
{
|
||||
dataIndex: ['payload', 'uptime'],
|
||||
title: 'Uptime',
|
||||
@ -351,7 +384,3 @@ export const AddServerStep: React.FC = React.memo(() => {
|
||||
);
|
||||
});
|
||||
AddServerStep.displayName = 'AddServerStep';
|
||||
|
||||
function isServerOnline(info: ServerStatusInfo): boolean {
|
||||
return new Date(info.updatedAt).valueOf() + info.timeout * 1000 > Date.now();
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
import dayjs from 'dayjs';
|
||||
import { ServerStatusInfo } from '../../types';
|
||||
import { createSubscribeInitializer, subscribeEventBus } from '../ws/shared';
|
||||
import _ from 'lodash';
|
||||
import { isServerOnline } from '../../shared';
|
||||
|
||||
const serverMap: Record<
|
||||
string, // workspaceId
|
||||
@ -47,3 +50,28 @@ export function recordServerStatus(info: ServerStatusInfo) {
|
||||
serverMap[workspaceId]
|
||||
);
|
||||
}
|
||||
|
||||
export function clearOfflineServerStatus(workspaceId: string) {
|
||||
if (!serverMap[workspaceId]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const offlineNode: string[] = [];
|
||||
Object.entries(serverMap[workspaceId]).forEach(([key, info]) => {
|
||||
if (!isServerOnline(info)) {
|
||||
offlineNode.push(key);
|
||||
}
|
||||
});
|
||||
|
||||
for (const node of offlineNode) {
|
||||
delete serverMap[workspaceId][node];
|
||||
}
|
||||
|
||||
subscribeEventBus.emit(
|
||||
'onServerStatusUpdate',
|
||||
workspaceId,
|
||||
serverMap[workspaceId]
|
||||
);
|
||||
|
||||
return serverMap[workspaceId];
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import { monitorRouter } from './monitor';
|
||||
import { userRouter } from './user';
|
||||
import { workspaceRouter } from './workspace';
|
||||
import { globalRouter } from './global';
|
||||
import { serverStatusRouter } from './serverStatus';
|
||||
|
||||
export const appRouter = router({
|
||||
global: globalRouter,
|
||||
@ -13,6 +14,7 @@ export const appRouter = router({
|
||||
website: websiteRouter,
|
||||
notification: notificationRouter,
|
||||
monitor: monitorRouter,
|
||||
serverStatus: serverStatusRouter,
|
||||
});
|
||||
|
||||
export type AppRouter = typeof appRouter;
|
||||
|
12
src/server/trpc/routers/serverStatus.ts
Normal file
12
src/server/trpc/routers/serverStatus.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { router, workspaceOwnerProcedure } from '../trpc';
|
||||
import { clearOfflineServerStatus } from '../../model/serverStatus';
|
||||
|
||||
export const serverStatusRouter = router({
|
||||
clearOfflineServerStatus: workspaceOwnerProcedure.mutation(
|
||||
async ({ input }) => {
|
||||
const workspaceId = input.workspaceId;
|
||||
|
||||
return clearOfflineServerStatus(workspaceId);
|
||||
}
|
||||
),
|
||||
});
|
@ -1 +1,2 @@
|
||||
export * from './date';
|
||||
export * from './server';
|
||||
|
5
src/shared/server.ts
Normal file
5
src/shared/server.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { ServerStatusInfo } from '../types';
|
||||
|
||||
export function isServerOnline(info: ServerStatusInfo): boolean {
|
||||
return new Date(info.updatedAt).valueOf() + info.timeout * 1000 > Date.now();
|
||||
}
|
Loading…
Reference in New Issue
Block a user