mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-18 07:28:31 -05:00
Merge pull request #3325 from bluewave-labs/feat/pagespeed-date-range
feat: pagespeed date range
This commit is contained in:
@@ -12,7 +12,7 @@ import {
|
||||
import { HistogramPageSpeedScoresTooltip } from "@/Components/monitors";
|
||||
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import type { CheckSnapshot } from "@/Types/Check";
|
||||
import type { PageSpeedGroupedCheck } from "@/Types/Check";
|
||||
import type { Palette } from "@mui/material/styles";
|
||||
type PaletteColorKey = Extract<
|
||||
keyof Palette,
|
||||
@@ -52,7 +52,7 @@ export const HistogramPageSpeedDetails = ({
|
||||
checks,
|
||||
range,
|
||||
}: {
|
||||
checks: CheckSnapshot[];
|
||||
checks: PageSpeedGroupedCheck[];
|
||||
range: string;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
@@ -73,7 +73,7 @@ export const HistogramPageSpeedDetails = ({
|
||||
>
|
||||
<AreaChart data={checks}>
|
||||
<XAxis
|
||||
dataKey={"createdAt"}
|
||||
dataKey={"bucketDate"}
|
||||
tick={(props) => (
|
||||
<XTick
|
||||
{...props}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { BasePage } from "@/Components/design-elements";
|
||||
import { HeaderTimeRange } from "@/Components/common";
|
||||
import type { PageSpeedDetailsResponse } from "@/Types/Monitor";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import {
|
||||
@@ -13,23 +14,36 @@ import { useIsAdmin } from "@/Hooks/useIsAdmin";
|
||||
import { useGet } from "@/Hooks/UseApi";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useTheme } from "@mui/material";
|
||||
import { useState, useMemo } from "react";
|
||||
|
||||
const PageSpeedDetails = () => {
|
||||
const { monitorId } = useParams();
|
||||
const isAdmin = useIsAdmin();
|
||||
const theme = useTheme();
|
||||
const [dateRange, setDateRange] = useState<string>("day");
|
||||
|
||||
const monitorDetailsUrl = useMemo(() => {
|
||||
if (!monitorId) {
|
||||
return null;
|
||||
}
|
||||
const params = new URLSearchParams();
|
||||
params.append("dateRange", dateRange);
|
||||
return `/monitors/pagespeed/details/${monitorId}?${params.toString()}`;
|
||||
}, [monitorId, dateRange]);
|
||||
|
||||
const {
|
||||
data: monitorData,
|
||||
isLoading,
|
||||
error,
|
||||
refetch,
|
||||
} = useGet<PageSpeedDetailsResponse>(
|
||||
monitorId ? `/monitors/pagespeed/details/${monitorId}?dateRange=day` : null,
|
||||
monitorDetailsUrl,
|
||||
{},
|
||||
{ keepPreviousData: true, refreshInterval: 30000 }
|
||||
);
|
||||
|
||||
const monitor = monitorData?.monitor;
|
||||
const monitor = monitorData?.monitorData?.monitor;
|
||||
const groupedChecks = monitorData?.monitorData?.groupedChecks || [];
|
||||
const monitorStats = monitorData?.monitorStats || null;
|
||||
|
||||
return (
|
||||
@@ -47,9 +61,15 @@ const PageSpeedDetails = () => {
|
||||
monitor={monitor}
|
||||
monitorStats={monitorStats}
|
||||
/>
|
||||
<HeaderTimeRange
|
||||
isLoading={isLoading}
|
||||
hasDateRange={true}
|
||||
dateRange={dateRange}
|
||||
setDateRange={setDateRange}
|
||||
/>
|
||||
<HistogramPageSpeedDetails
|
||||
checks={monitor?.recentChecks || []}
|
||||
range="day"
|
||||
checks={groupedChecks}
|
||||
range={dateRange}
|
||||
/>
|
||||
<Stack
|
||||
direction={{ xs: "column", md: "row" }}
|
||||
|
||||
@@ -151,6 +151,15 @@ export interface GroupedCheck {
|
||||
totalChecks: number;
|
||||
}
|
||||
|
||||
export interface PageSpeedGroupedCheck {
|
||||
bucketDate: string;
|
||||
performance: number;
|
||||
accessibility: number;
|
||||
bestPractices: number;
|
||||
seo: number;
|
||||
totalChecks: number;
|
||||
}
|
||||
|
||||
export interface LatestCheck {
|
||||
status: boolean;
|
||||
responseTime: number;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { GroupedCheck, CheckSnapshot } from "@/Types/Check";
|
||||
import type { PageSpeedGroupedCheck } from "@/Types/Check";
|
||||
|
||||
export const MonitorTypes = [
|
||||
"http",
|
||||
@@ -112,7 +113,10 @@ export interface MonitorDetailsResponse {
|
||||
}
|
||||
|
||||
export interface PageSpeedDetailsResponse {
|
||||
monitor: MonitorWithChecks;
|
||||
monitorData: {
|
||||
monitor: Monitor;
|
||||
groupedChecks: PageSpeedGroupedCheck[];
|
||||
};
|
||||
monitorStats: MonitorStats | null;
|
||||
}
|
||||
|
||||
|
||||
@@ -378,7 +378,7 @@ class MongoChecksRepository implements IChecksRepository {
|
||||
return this.findHardwareDateRangeChecks(monitorObjectId, startDate, endDate, dateString);
|
||||
}
|
||||
if (options?.type === "pagespeed") {
|
||||
return this.findPageSpeedDateRangeChecks(monitorObjectId, startDate, endDate);
|
||||
return this.findPageSpeedDateRangeChecks(monitorObjectId, startDate, endDate, dateString);
|
||||
}
|
||||
return this.findUptimeDateRangeChecks(options?.type ?? "http", monitorObjectId, startDate, endDate, dateString);
|
||||
};
|
||||
@@ -572,16 +572,50 @@ class MongoChecksRepository implements IChecksRepository {
|
||||
};
|
||||
};
|
||||
|
||||
private findPageSpeedDateRangeChecks = async (monitorObjectId: mongoose.Types.ObjectId, startDate: Date, endDate: Date) => {
|
||||
private findPageSpeedDateRangeChecks = async (monitorObjectId: mongoose.Types.ObjectId, startDate: Date, endDate: Date, dateString: string) => {
|
||||
const matchStage = {
|
||||
"metadata.monitorId": monitorObjectId,
|
||||
createdAt: { $gte: startDate, $lte: endDate },
|
||||
};
|
||||
|
||||
const checks = await CheckModel.find(matchStage).sort({ createdAt: -1 }).limit(25).lean();
|
||||
const [result] = await CheckModel.aggregate([
|
||||
{ $match: matchStage },
|
||||
{ $sort: { createdAt: 1 } },
|
||||
{
|
||||
$facet: {
|
||||
groupedChecks: [
|
||||
{
|
||||
$group: {
|
||||
_id: {
|
||||
$dateToString: { format: dateString, date: "$createdAt" },
|
||||
},
|
||||
avgPerformance: { $avg: "$performance" },
|
||||
avgAccessibility: { $avg: "$accessibility" },
|
||||
avgBestPractices: { $avg: "$bestPractices" },
|
||||
avgSeo: { $avg: "$seo" },
|
||||
totalChecks: { $sum: 1 },
|
||||
},
|
||||
},
|
||||
{ $sort: { _id: 1 } },
|
||||
{
|
||||
$project: {
|
||||
bucketDate: "$_id",
|
||||
performance: "$avgPerformance",
|
||||
accessibility: "$avgAccessibility",
|
||||
bestPractices: "$avgBestPractices",
|
||||
seo: "$avgSeo",
|
||||
totalChecks: 1,
|
||||
_id: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
return {
|
||||
monitorType: "pagespeed" as const,
|
||||
checks: this.mapDocuments(checks),
|
||||
groupedChecks: result?.groupedChecks ?? [],
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -308,9 +308,9 @@ export class MonitorService implements IMonitorService {
|
||||
const monitorStats = await this.monitorStatsRepository.findByMonitorId(monitor.id);
|
||||
|
||||
return {
|
||||
monitor: {
|
||||
...monitor,
|
||||
checks: checksData.checks,
|
||||
monitorData: {
|
||||
monitor,
|
||||
groupedChecks: checksData.groupedChecks,
|
||||
},
|
||||
monitorStats,
|
||||
};
|
||||
|
||||
@@ -124,7 +124,7 @@ export interface ChecksQueryResult {
|
||||
|
||||
export interface PageSpeedChecksResult {
|
||||
monitorType: "pagespeed";
|
||||
checks: Check[];
|
||||
groupedChecks: PageSpeedGroupedCheck[];
|
||||
}
|
||||
|
||||
export interface HardwareChecksResult {
|
||||
@@ -170,6 +170,15 @@ export interface GroupedCheck {
|
||||
totalChecks: number;
|
||||
}
|
||||
|
||||
export interface PageSpeedGroupedCheck {
|
||||
bucketDate: string;
|
||||
performance: number;
|
||||
accessibility: number;
|
||||
bestPractices: number;
|
||||
seo: number;
|
||||
totalChecks: number;
|
||||
}
|
||||
|
||||
export interface UptimeChecksResult {
|
||||
monitorType: Exclude<MonitorType, "hardware" | "pagespeed">;
|
||||
groupedChecks: GroupedCheck[];
|
||||
|
||||
@@ -125,8 +125,9 @@ export interface HardwareDetailsResult {
|
||||
}
|
||||
|
||||
export interface PageSpeedDetailsResult {
|
||||
monitor: Monitor & {
|
||||
checks: import("./check.js").Check[];
|
||||
monitorData: {
|
||||
monitor: Monitor;
|
||||
groupedChecks: import("./check.js").PageSpeedGroupedCheck[];
|
||||
};
|
||||
monitorStats: import("./monitorStats.js").MonitorStats | null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user