feat: monitor allow edit notifications

This commit is contained in:
moonrailgun 2023-10-20 00:48:56 +08:00
parent 0346dc21d9
commit 0c1c72ccab
7 changed files with 95 additions and 12 deletions

View File

@ -3,6 +3,7 @@ import type { Monitor } from '@prisma/client';
import { Button, Form, Input, InputNumber, Select } from 'antd';
import { monitorProviders } from './provider';
import { useEvent } from '../../../hooks/useEvent';
import { NotificationPicker } from '../../notification/NotificationPicker';
export type MonitorInfoEditorValues = Omit<
Monitor,
@ -10,6 +11,7 @@ export type MonitorInfoEditorValues = Omit<
> & {
id?: string;
payload: Record<string, any>;
notificationIds?: string[];
};
const defaultValues: Omit<MonitorInfoEditorValues, 'payload'> = {
@ -82,6 +84,10 @@ export const MonitorInfoEditor: React.FC<MonitorInfoEditorProps> = React.memo(
{formEl}
<Form.Item label="Notification" name="notificationIds">
<NotificationPicker allowClear={true} mode="multiple" />
</Form.Item>
<Button type="primary" htmlType="submit">
Save
</Button>

View File

@ -56,12 +56,12 @@ export const MonitorList: React.FC = React.memo(() => {
}
return (
<div>
<div className="p-2">
{monitors.map((monitor) => (
<div
key={monitor.name}
className={clsx(
'flex rounded-lg py-3 px-4 cursor-pointer',
'flex rounded-lg py-3 px-4 cursor-pointer mb-1',
selectedMonitorId === monitor.id
? 'bg-green-500 bg-opacity-20'
: 'bg-green-500 bg-opacity-0 hover:bg-opacity-10'

View File

@ -0,0 +1,27 @@
import { Select, SelectProps } from 'antd';
import React from 'react';
import { trpc } from '../../api/trpc';
import { useCurrentWorkspaceId } from '../../store/user';
import { ColorTag } from '../ColorTag';
interface NotificationPickerProps extends SelectProps<string> {}
export const NotificationPicker: React.FC<NotificationPickerProps> = React.memo(
(props) => {
const workspaceId = useCurrentWorkspaceId();
const { data: allNotification = [] } = trpc.notification.all.useQuery({
workspaceId,
});
return (
<Select {...props}>
{allNotification.map((m) => (
<Select.Option key={m.id} value={m.id}>
<ColorTag label={m.type} />
{m.name}
</Select.Option>
))}
</Select>
);
}
);
NotificationPicker.displayName = 'NotificationPicker';

View File

@ -31,7 +31,12 @@ export const MonitorEdit: React.FC = React.memo(() => {
return (
<div>
<MonitorInfoEditor
initialValues={monitor as MonitorInfoEditorValues}
initialValues={
{
...monitor,
notificationIds: monitor.notifications.map((n) => n.id),
} as MonitorInfoEditorValues
}
onSave={async (value) => {
const monitor = await mutation.mutateAsync({
...value,

View File

@ -8,7 +8,12 @@ import dayjs from 'dayjs';
export type MonitorUpsertData = Pick<
Monitor,
'workspaceId' | 'name' | 'type' | 'interval'
> & { id?: string; active?: boolean; payload: Record<string, any> };
> & {
id?: string;
active?: boolean;
notificationIds?: string[];
payload: Record<string, any>;
};
type MonitorWithNotification = Monitor & { notifications: Notification[] };
@ -21,13 +26,19 @@ class MonitorManager {
*/
async upsert(data: MonitorUpsertData): Promise<MonitorWithNotification> {
let monitor: MonitorWithNotification;
if (data.id) {
const { id, notificationIds = [], ...others } = data;
if (id) {
// update
monitor = await prisma.monitor.update({
where: {
id: data.id,
id,
},
data: {
...others,
notifications: {
set: notificationIds.map((id) => ({ id })),
},
},
data: { ...data },
include: {
notifications: true,
},
@ -37,7 +48,12 @@ class MonitorManager {
} else {
// create
monitor = await prisma.monitor.create({
data: { ...data },
data: {
...others,
notifications: {
connect: notificationIds.map((id) => ({ id })),
},
},
include: {
notifications: true,
},

View File

@ -2,7 +2,7 @@ import { router, workspaceOwnerProcedure, workspaceProcedure } from '../trpc';
import { prisma } from '../../model/_client';
import { z } from 'zod';
import { monitorManager } from '../../model/monitor';
import { MonitorInfo } from '../../../types';
import { MonitorInfoWithNotificationIds } from '../../../types';
import dayjs from 'dayjs';
export const monitorRouter = router({
@ -12,9 +12,16 @@ export const monitorRouter = router({
where: {
workspaceId,
},
include: {
notifications: {
select: {
id: true,
},
},
},
});
return monitors as MonitorInfo[];
return monitors as MonitorInfoWithNotificationIds[];
}),
get: workspaceProcedure
.input(
@ -29,9 +36,16 @@ export const monitorRouter = router({
id,
workspaceId,
},
include: {
notifications: {
select: {
id: true,
},
},
},
});
return monitor as MonitorInfo;
return monitor as MonitorInfoWithNotificationIds;
}),
upsert: workspaceOwnerProcedure
.input(
@ -41,11 +55,21 @@ export const monitorRouter = router({
type: z.string(),
active: z.boolean().default(true),
interval: z.number().int().default(20),
notificationIds: z.array(z.string()).default([]),
payload: z.object({}).passthrough(),
})
)
.mutation(async ({ input }) => {
const { id, workspaceId, name, type, active, interval, payload } = input;
const {
id,
workspaceId,
name,
type,
active,
interval,
notificationIds,
payload,
} = input;
const monitor = await monitorManager.upsert({
id,
@ -54,6 +78,7 @@ export const monitorRouter = router({
type,
active,
interval,
notificationIds,
payload,
});

View File

@ -7,3 +7,7 @@ export type MonitorInfo = ExactType<
payload: Record<string, any>;
}
>;
export type MonitorInfoWithNotificationIds = MonitorInfo & {
notifications: { id: string }[];
};