feat: monitor add trending mode

This commit is contained in:
moonrailgun 2024-05-02 16:31:38 +08:00
parent f6fc210b65
commit d77e1321f4
8 changed files with 53 additions and 13 deletions

View File

@ -8,6 +8,11 @@ export function useMonitorUpsert() {
workspaceId: data.workspaceId, workspaceId: data.workspaceId,
}); });
utils.monitor.get.refetch({
workspaceId: data.workspaceId,
monitorId: data.id,
});
defaultSuccessHandler(); defaultSuccessHandler();
}, },
onError: defaultErrorHandler, onError: defaultErrorHandler,

View File

@ -1,7 +1,7 @@
import { AreaConfig, Area } from '@ant-design/charts'; import { AreaConfig, Area } from '@ant-design/charts';
import { Select } from 'antd'; import { Select } from 'antd';
import dayjs, { Dayjs } from 'dayjs'; import dayjs, { Dayjs } from 'dayjs';
import { uniqBy } from 'lodash-es'; import { max, min, uniqBy } from 'lodash-es';
import React, { useState, useMemo } from 'react'; import React, { useState, useMemo } from 'react';
import { useSocketSubscribeList } from '../../api/socketio'; import { useSocketSubscribeList } from '../../api/socketio';
import { trpc } from '../../api/trpc'; import { trpc } from '../../api/trpc';
@ -97,6 +97,16 @@ export const MonitorDataChart: React.FC<{ monitorId: string }> = React.memo(
}, [_recentData, _data, subscribedDataList]); }, [_recentData, _data, subscribedDataList]);
const config = useMemo<AreaConfig>(() => { const config = useMemo<AreaConfig>(() => {
const values = data.map((d) => d.value);
const maxValue = max(values) ?? 0;
const minValue = min(values) ?? 0;
const isTrendingMode = monitorInfo?.trendingMode ?? false; // if true, y axis not start from 0
const yMin = isTrendingMode
? Math.max(minValue - (maxValue - minValue) / 10, 0)
: 0;
return { return {
data, data,
height: 200, height: 200,
@ -104,6 +114,9 @@ export const MonitorDataChart: React.FC<{ monitorId: string }> = React.memo(
yField: 'value', yField: 'value',
smooth: true, smooth: true,
meta: { meta: {
value: {
min: yMin,
},
time: { time: {
formatter(value) { formatter(value) {
return dayjs(value).format( return dayjs(value).format(
@ -112,6 +125,10 @@ export const MonitorDataChart: React.FC<{ monitorId: string }> = React.memo(
}, },
}, },
}, },
// need explore how to display null data
// xAxis: {
// type: 'time',
// },
color: 'rgb(34 197 94 / 0.8)', color: 'rgb(34 197 94 / 0.8)',
areaStyle: () => { areaStyle: () => {
return { return {

View File

@ -1,6 +1,6 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import type { Monitor } from '../../../server/types/prisma'; import type { Monitor } from '../../../server/types/prisma';
import { Button, Form, Input, InputNumber, Select } from 'antd'; import { Button, Form, Input, InputNumber, Select, Switch } from 'antd';
import { getMonitorProvider, monitorProviders } from './provider'; import { getMonitorProvider, monitorProviders } from './provider';
import { useEventWithLoading } from '../../hooks/useEvent'; import { useEventWithLoading } from '../../hooks/useEvent';
import { NotificationPicker } from '../notification/NotificationPicker'; import { NotificationPicker } from '../notification/NotificationPicker';
@ -12,6 +12,7 @@ export type MonitorInfoEditorValues = Omit<
> & { > & {
id?: string; id?: string;
payload: Record<string, any>; payload: Record<string, any>;
trendingMode: boolean;
notificationIds?: string[]; notificationIds?: string[];
}; };
@ -21,6 +22,7 @@ const defaultValues: Omit<MonitorInfoEditorValues, 'payload'> = {
active: true, active: true,
interval: 60, interval: 60,
maxRetries: 0, maxRetries: 0,
trendingMode: false,
}; };
interface MonitorInfoEditorProps { interface MonitorInfoEditorProps {
@ -105,6 +107,15 @@ export const MonitorInfoEditor: React.FC<MonitorInfoEditorProps> = React.memo(
{formEl} {formEl}
<Form.Item
label={t('Trending Mode')}
name="trendingMode"
valuePropName="checked"
tooltip={t('Y Axis will not start from zero')}
>
<Switch />
</Form.Item>
<Form.Item label={t('Notification')} name="notificationIds"> <Form.Item label={t('Notification')} name="notificationIds">
<NotificationPicker allowClear={true} mode="multiple" /> <NotificationPicker allowClear={true} mode="multiple" />
</Form.Item> </Form.Item>

View File

@ -5,7 +5,7 @@ import { logger } from '../../utils/logger';
export type MonitorUpsertData = Pick< export type MonitorUpsertData = Pick<
Monitor, Monitor,
'workspaceId' | 'name' | 'type' | 'interval' | 'maxRetries' 'workspaceId' | 'name' | 'type' | 'interval' | 'maxRetries' | 'trendingMode'
> & { > & {
id?: string; id?: string;
active?: boolean; active?: boolean;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Monitor" ADD COLUMN "trendingMode" BOOLEAN NOT NULL DEFAULT false;

View File

@ -284,20 +284,21 @@ model Notification {
} }
model Monitor { model Monitor {
id String @id() @default(cuid()) @db.VarChar(30) id String @id() @default(cuid()) @db.VarChar(30)
workspaceId String @db.VarChar(30) workspaceId String @db.VarChar(30)
name String @db.VarChar(100) name String @db.VarChar(100)
type String @db.VarChar(100) type String @db.VarChar(100)
active Boolean @default(true) @db.Boolean active Boolean @default(true) @db.Boolean
interval Int @default(20) @db.Integer interval Int @default(20) @db.Integer
maxRetries Int @default(0) @db.Integer maxRetries Int @default(0) @db.Integer
// TODO // TODO
// retryInterval Int @default(0) @db.Integer // retryInterval Int @default(0) @db.Integer
/// [CommonPayload] /// [CommonPayload]
/// @zod.custom(imports.CommonPayloadSchema) /// @zod.custom(imports.CommonPayloadSchema)
payload Json @db.Json payload Json @db.Json
createdAt DateTime @default(now()) @db.Timestamptz(6) trendingMode Boolean @default(false) @db.Boolean
updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6) createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
workspace Workspace @relation(fields: [workspaceId], references: [id]) workspace Workspace @relation(fields: [workspaceId], references: [id])

View File

@ -20,6 +20,7 @@ export const MonitorModelSchema = z.object({
* [CommonPayload] * [CommonPayload]
*/ */
payload: imports.CommonPayloadSchema, payload: imports.CommonPayloadSchema,
trendingMode: z.boolean(),
createdAt: z.date(), createdAt: z.date(),
updatedAt: z.date(), updatedAt: z.date(),
}) })

View File

@ -128,6 +128,7 @@ export const monitorRouter = router({
active: z.boolean().default(true), active: z.boolean().default(true),
interval: z.number().int().min(5).max(10000).default(20), interval: z.number().int().min(5).max(10000).default(20),
maxRetries: z.number().int().min(0).max(10).default(0), maxRetries: z.number().int().min(0).max(10).default(0),
trendingMode: z.boolean().default(false),
notificationIds: z.array(z.string()).default([]), notificationIds: z.array(z.string()).default([]),
payload: z.object({}).passthrough(), payload: z.object({}).passthrough(),
}) })
@ -142,6 +143,7 @@ export const monitorRouter = router({
active, active,
interval, interval,
maxRetries, maxRetries,
trendingMode,
notificationIds, notificationIds,
payload, payload,
} = input; } = input;
@ -154,6 +156,7 @@ export const monitorRouter = router({
active, active,
interval, interval,
maxRetries, maxRetries,
trendingMode,
notificationIds, notificationIds,
payload, payload,
}); });