feat: add delete button for monitor

This commit is contained in:
moonrailgun 2023-12-09 00:39:36 +08:00
parent 674952da59
commit e1638de5e8
3 changed files with 104 additions and 42 deletions

View File

@ -1,4 +1,4 @@
import { Button, Card, Space, Spin } from 'antd';
import { Button, Card, Popconfirm, Space, Spin } from 'antd';
import dayjs from 'dayjs';
import React, { useState } from 'react';
import {
@ -41,6 +41,10 @@ export const MonitorInfo: React.FC<MonitorInfoProps> = React.memo((props) => {
onSuccess: defaultSuccessHandler,
onError: defaultErrorHandler,
});
const deleteMutation = trpc.monitor.delete.useMutation({
onSuccess: defaultSuccessHandler,
onError: defaultErrorHandler,
});
const trpcUtils = trpc.useContext();
@ -78,6 +82,17 @@ export const MonitorInfo: React.FC<MonitorInfoProps> = React.memo((props) => {
});
});
const handleDelete = useEvent(async () => {
await deleteMutation.mutateAsync({
workspaceId,
monitorId,
});
trpcUtils.monitor.all.refetch();
navigate('/monitor');
});
if (isInitialLoading) {
return <Loading />;
}
@ -140,6 +155,13 @@ export const MonitorInfo: React.FC<MonitorInfoProps> = React.memo((props) => {
Start
</Button>
)}
<Popconfirm
title="How you sure delete this monitor?"
onConfirm={handleDelete}
>
<Button danger={true}>Delete</Button>
</Popconfirm>
</div>
<Card>

View File

@ -4,6 +4,7 @@ import { prisma } from '../_client';
import { monitorProviders } from './provider';
import { sendNotification } from '../notification';
import dayjs from 'dayjs';
import { logger } from '../../utils/logger';
export type MonitorUpsertData = Pick<
Monitor,
@ -74,6 +75,23 @@ class MonitorManager {
return monitor;
}
async delete(workspaceId: string, monitorId: string) {
const runner = this.getRunner(monitorId);
if (!runner) {
throw new Error('This monitor not found');
}
runner.stopMonitor();
delete this.monitorRunner[monitorId];
return prisma.monitor.delete({
where: {
workspaceId,
id: monitorId,
},
});
}
/**
* Get and start all monitors
*/
@ -148,50 +166,54 @@ class MonitorRunner {
};
const run = async () => {
let value = 0;
try {
value = await provider.run(monitor);
let value = 0;
try {
value = await provider.run(monitor);
} catch (err) {
console.error(err);
value = -1;
}
// check event update
if (value < 0 && currentStatus === 'UP') {
await this.createEvent(
'DOWN',
`Monitor [${monitor.name}] has been down`
);
await this.notify(
`[${monitor.name}] 🔴 Down`,
`[${monitor.name}] 🔴 Down\nTime: ${dayjs().format(
'YYYY-MM-DD HH:mm:ss (z)'
)}`
);
currentStatus = 'DOWN';
} else if (value > 0 && currentStatus === 'DOWN') {
await this.createEvent('UP', `Monitor [${monitor.name}] has been up`);
await this.notify(
`[${monitor.name}] ✅ Up`,
`[${monitor.name}] ✅ Up\nTime: ${dayjs().format(
'YYYY-MM-DD HH:mm:ss (z)'
)}`
);
currentStatus = 'UP';
}
// insert into data
const data = await prisma.monitorData.create({
data: {
monitorId: monitor.id,
value,
},
});
subscribeEventBus.emit('onMonitorReceiveNewData', workspaceId, data);
// Run next loop
nextAction();
} catch (err) {
console.error(err);
value = -1;
logger.error('Run monitor error,', monitor.id, String(err));
}
// check event update
if (value < 0 && currentStatus === 'UP') {
await this.createEvent(
'DOWN',
`Monitor [${monitor.name}] has been down`
);
await this.notify(
`[${monitor.name}] 🔴 Down`,
`[${monitor.name}] 🔴 Down\nTime: ${dayjs().format(
'YYYY-MM-DD HH:mm:ss (z)'
)}`
);
currentStatus = 'DOWN';
} else if (value > 0 && currentStatus === 'DOWN') {
await this.createEvent('UP', `Monitor [${monitor.name}] has been up`);
await this.notify(
`[${monitor.name}] ✅ Up`,
`[${monitor.name}] ✅ Up\nTime: ${dayjs().format(
'YYYY-MM-DD HH:mm:ss (z)'
)}`
);
currentStatus = 'UP';
}
// insert into data
const data = await prisma.monitorData.create({
data: {
monitorId: monitor.id,
value,
},
});
subscribeEventBus.emit('onMonitorReceiveNewData', workspaceId, data);
// Run next loop
nextAction();
};
run();

View File

@ -119,6 +119,24 @@ export const monitorRouter = router({
return monitor;
}),
delete: workspaceOwnerProcedure
.meta(
buildMonitorOpenapi({
method: 'DELETE',
path: '/{monitorId}',
})
)
.input(
z.object({
monitorId: z.string().cuid2(),
})
)
.output(monitorInfoSchema)
.mutation(async ({ input }) => {
const { workspaceId, monitorId } = input;
return monitorManager.delete(workspaceId, monitorId);
}),
data: workspaceProcedure
.meta(
buildMonitorOpenapi({