feat: monitor allow edit notifications
This commit is contained in:
parent
0346dc21d9
commit
0c1c72ccab
@ -3,6 +3,7 @@ import type { Monitor } from '@prisma/client';
|
|||||||
import { Button, Form, Input, InputNumber, Select } from 'antd';
|
import { Button, Form, Input, InputNumber, Select } from 'antd';
|
||||||
import { monitorProviders } from './provider';
|
import { monitorProviders } from './provider';
|
||||||
import { useEvent } from '../../../hooks/useEvent';
|
import { useEvent } from '../../../hooks/useEvent';
|
||||||
|
import { NotificationPicker } from '../../notification/NotificationPicker';
|
||||||
|
|
||||||
export type MonitorInfoEditorValues = Omit<
|
export type MonitorInfoEditorValues = Omit<
|
||||||
Monitor,
|
Monitor,
|
||||||
@ -10,6 +11,7 @@ export type MonitorInfoEditorValues = Omit<
|
|||||||
> & {
|
> & {
|
||||||
id?: string;
|
id?: string;
|
||||||
payload: Record<string, any>;
|
payload: Record<string, any>;
|
||||||
|
notificationIds?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultValues: Omit<MonitorInfoEditorValues, 'payload'> = {
|
const defaultValues: Omit<MonitorInfoEditorValues, 'payload'> = {
|
||||||
@ -82,6 +84,10 @@ export const MonitorInfoEditor: React.FC<MonitorInfoEditorProps> = React.memo(
|
|||||||
|
|
||||||
{formEl}
|
{formEl}
|
||||||
|
|
||||||
|
<Form.Item label="Notification" name="notificationIds">
|
||||||
|
<NotificationPicker allowClear={true} mode="multiple" />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
<Button type="primary" htmlType="submit">
|
<Button type="primary" htmlType="submit">
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -56,12 +56,12 @@ export const MonitorList: React.FC = React.memo(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="p-2">
|
||||||
{monitors.map((monitor) => (
|
{monitors.map((monitor) => (
|
||||||
<div
|
<div
|
||||||
key={monitor.name}
|
key={monitor.name}
|
||||||
className={clsx(
|
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
|
selectedMonitorId === monitor.id
|
||||||
? 'bg-green-500 bg-opacity-20'
|
? 'bg-green-500 bg-opacity-20'
|
||||||
: 'bg-green-500 bg-opacity-0 hover:bg-opacity-10'
|
: 'bg-green-500 bg-opacity-0 hover:bg-opacity-10'
|
||||||
|
27
src/client/components/notification/NotificationPicker.tsx
Normal file
27
src/client/components/notification/NotificationPicker.tsx
Normal 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';
|
@ -31,7 +31,12 @@ export const MonitorEdit: React.FC = React.memo(() => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<MonitorInfoEditor
|
<MonitorInfoEditor
|
||||||
initialValues={monitor as MonitorInfoEditorValues}
|
initialValues={
|
||||||
|
{
|
||||||
|
...monitor,
|
||||||
|
notificationIds: monitor.notifications.map((n) => n.id),
|
||||||
|
} as MonitorInfoEditorValues
|
||||||
|
}
|
||||||
onSave={async (value) => {
|
onSave={async (value) => {
|
||||||
const monitor = await mutation.mutateAsync({
|
const monitor = await mutation.mutateAsync({
|
||||||
...value,
|
...value,
|
||||||
|
@ -8,7 +8,12 @@ import dayjs from 'dayjs';
|
|||||||
export type MonitorUpsertData = Pick<
|
export type MonitorUpsertData = Pick<
|
||||||
Monitor,
|
Monitor,
|
||||||
'workspaceId' | 'name' | 'type' | 'interval'
|
'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[] };
|
type MonitorWithNotification = Monitor & { notifications: Notification[] };
|
||||||
|
|
||||||
@ -21,13 +26,19 @@ class MonitorManager {
|
|||||||
*/
|
*/
|
||||||
async upsert(data: MonitorUpsertData): Promise<MonitorWithNotification> {
|
async upsert(data: MonitorUpsertData): Promise<MonitorWithNotification> {
|
||||||
let monitor: MonitorWithNotification;
|
let monitor: MonitorWithNotification;
|
||||||
if (data.id) {
|
const { id, notificationIds = [], ...others } = data;
|
||||||
|
if (id) {
|
||||||
// update
|
// update
|
||||||
monitor = await prisma.monitor.update({
|
monitor = await prisma.monitor.update({
|
||||||
where: {
|
where: {
|
||||||
id: data.id,
|
id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
...others,
|
||||||
|
notifications: {
|
||||||
|
set: notificationIds.map((id) => ({ id })),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data: { ...data },
|
|
||||||
include: {
|
include: {
|
||||||
notifications: true,
|
notifications: true,
|
||||||
},
|
},
|
||||||
@ -37,7 +48,12 @@ class MonitorManager {
|
|||||||
} else {
|
} else {
|
||||||
// create
|
// create
|
||||||
monitor = await prisma.monitor.create({
|
monitor = await prisma.monitor.create({
|
||||||
data: { ...data },
|
data: {
|
||||||
|
...others,
|
||||||
|
notifications: {
|
||||||
|
connect: notificationIds.map((id) => ({ id })),
|
||||||
|
},
|
||||||
|
},
|
||||||
include: {
|
include: {
|
||||||
notifications: true,
|
notifications: true,
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,7 @@ import { router, workspaceOwnerProcedure, workspaceProcedure } from '../trpc';
|
|||||||
import { prisma } from '../../model/_client';
|
import { prisma } from '../../model/_client';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { monitorManager } from '../../model/monitor';
|
import { monitorManager } from '../../model/monitor';
|
||||||
import { MonitorInfo } from '../../../types';
|
import { MonitorInfoWithNotificationIds } from '../../../types';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
export const monitorRouter = router({
|
export const monitorRouter = router({
|
||||||
@ -12,9 +12,16 @@ export const monitorRouter = router({
|
|||||||
where: {
|
where: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
},
|
},
|
||||||
|
include: {
|
||||||
|
notifications: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return monitors as MonitorInfo[];
|
return monitors as MonitorInfoWithNotificationIds[];
|
||||||
}),
|
}),
|
||||||
get: workspaceProcedure
|
get: workspaceProcedure
|
||||||
.input(
|
.input(
|
||||||
@ -29,9 +36,16 @@ export const monitorRouter = router({
|
|||||||
id,
|
id,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
},
|
},
|
||||||
|
include: {
|
||||||
|
notifications: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return monitor as MonitorInfo;
|
return monitor as MonitorInfoWithNotificationIds;
|
||||||
}),
|
}),
|
||||||
upsert: workspaceOwnerProcedure
|
upsert: workspaceOwnerProcedure
|
||||||
.input(
|
.input(
|
||||||
@ -41,11 +55,21 @@ export const monitorRouter = router({
|
|||||||
type: z.string(),
|
type: z.string(),
|
||||||
active: z.boolean().default(true),
|
active: z.boolean().default(true),
|
||||||
interval: z.number().int().default(20),
|
interval: z.number().int().default(20),
|
||||||
|
notificationIds: z.array(z.string()).default([]),
|
||||||
payload: z.object({}).passthrough(),
|
payload: z.object({}).passthrough(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.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({
|
const monitor = await monitorManager.upsert({
|
||||||
id,
|
id,
|
||||||
@ -54,6 +78,7 @@ export const monitorRouter = router({
|
|||||||
type,
|
type,
|
||||||
active,
|
active,
|
||||||
interval,
|
interval,
|
||||||
|
notificationIds,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -7,3 +7,7 @@ export type MonitorInfo = ExactType<
|
|||||||
payload: Record<string, any>;
|
payload: Record<string, any>;
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
export type MonitorInfoWithNotificationIds = MonitorInfo & {
|
||||||
|
notifications: { id: string }[];
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user