diff --git a/client/src/Components/monitors/charts/HistogramPageSpeedDetails.tsx b/client/src/Components/monitors/charts/HistogramPageSpeedDetails.tsx index 8df491197..f89994437 100644 --- a/client/src/Components/monitors/charts/HistogramPageSpeedDetails.tsx +++ b/client/src/Components/monitors/charts/HistogramPageSpeedDetails.tsx @@ -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 = ({ > ( { const { monitorId } = useParams(); const isAdmin = useIsAdmin(); const theme = useTheme(); + const [dateRange, setDateRange] = useState("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( - 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} /> + { + 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 ?? [], }; }; diff --git a/server/src/service/business/monitorService.ts b/server/src/service/business/monitorService.ts index a0591a74f..2005a4a5d 100644 --- a/server/src/service/business/monitorService.ts +++ b/server/src/service/business/monitorService.ts @@ -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, }; diff --git a/server/src/types/check.ts b/server/src/types/check.ts index c02b03099..6c4c26445 100644 --- a/server/src/types/check.ts +++ b/server/src/types/check.ts @@ -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; groupedChecks: GroupedCheck[]; diff --git a/server/src/types/monitor.ts b/server/src/types/monitor.ts index a196aaae6..ac7ca02d0 100644 --- a/server/src/types/monitor.ts +++ b/server/src/types/monitor.ts @@ -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; }