From 7f15811fdf985b10f3786b3daa22bceb3a667fa4 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 31 Dec 2025 20:51:30 +0000 Subject: [PATCH] defensive checks --- .../design-elements/StatusLabel.tsx | 23 ++++++++++++++----- .../monitors/HistogramDockerPercentage.tsx | 20 ++++++++++++++++ .../monitors/HistogramPageSpeed.tsx | 2 +- .../components/status-pages/StatusPageRow.tsx | 9 +++++--- client/src/pages/docker/DockerDetails.tsx | 2 +- .../src/pages/docker/DockerMonitorsTable.tsx | 5 ++-- .../infrastructure/InfraMonitorsTable.tsx | 4 +++- .../pages/pagespeed/PageSpeedMonitorTable.tsx | 2 +- .../pages/status-page/StatusPageConfig.tsx | 2 +- .../pages/status-page/StatusPageDetails.tsx | 4 ++-- .../src/pages/uptime/UptimeMonitorsTable.tsx | 4 ++-- 11 files changed, 57 insertions(+), 20 deletions(-) diff --git a/client/src/components/design-elements/StatusLabel.tsx b/client/src/components/design-elements/StatusLabel.tsx index 9d454ba47..cea057aa0 100644 --- a/client/src/components/design-elements/StatusLabel.tsx +++ b/client/src/components/design-elements/StatusLabel.tsx @@ -1,8 +1,9 @@ import Box from "@mui/material/Box"; import { BaseBox } from "@/components/design-elements"; +import Typography from "@mui/material/Typography"; + import type { MonitorStatus } from "@/types/monitor"; import type { SxProps } from "@mui/material/styles"; - import { getStatusPalette, getValuePalette } from "@/utils/MonitorUtils"; import { useTheme } from "@mui/material/styles"; @@ -18,8 +19,6 @@ export const StatusLabel = ({ }) => { const theme = useTheme(); const palette = getStatusPalette(status); - const transformedText = - status.charAt(0).toUpperCase() + status.slice(1).toLowerCase(); return ( - - {transformedText} + + {status} ); }; @@ -70,7 +75,13 @@ export const ValueLabel = ({ : "rgba(0, 0, 0, 0.08)", }} > - + {transformedText} ); diff --git a/client/src/components/monitors/HistogramDockerPercentage.tsx b/client/src/components/monitors/HistogramDockerPercentage.tsx index 819ff3b15..61a3eccc6 100644 --- a/client/src/components/monitors/HistogramDockerPercentage.tsx +++ b/client/src/components/monitors/HistogramDockerPercentage.tsx @@ -8,10 +8,14 @@ import { XAxis, YAxis, CartesianGrid, + Tooltip, } from "recharts"; import { XTick } from "@/components/monitors/ChartResponseTime"; import { useTheme } from "@mui/material/styles"; import useMediaQuery from "@mui/material/useMediaQuery"; +import { BaseBox } from "@/components/design-elements"; +import { useAppSelector } from "@/hooks/AppHooks"; +import { formatDateWithTz, tooltipDateFormatLookup } from "@/utils/TimeUtils"; export const HistogramDockerPercentage = ({ data, @@ -29,6 +33,21 @@ export const HistogramDockerPercentage = ({ const theme = useTheme(); const isSmall = useMediaQuery(theme.breakpoints.down("sm")); const hasData = Array.isArray(data) && data.length > 0; + const uiTimezone = useAppSelector((state: any) => state.ui.timezone); + + const PercentTooltip = ({ active, payload, label }: any) => { + if (!active || !payload || !label) return null; + const fmt = tooltipDateFormatLookup(range); + const value = payload?.[0]?.payload?.[dataKey] ?? 0; + return ( + + + {formatDateWithTz(String(label), fmt, uiTimezone)} + + {`${value}%`} + + ); + }; return ( + } cursor={false} /> { const theme = useTheme(); - const scores = processData(checks); + const scores = processData(checks ?? []); const color = getStatusColor(status, theme); return ( { alignItems={"center"} justifyContent={"flex-end"} > - + {type === "heatmap" && ( { )} {type === "histogram" && ( diff --git a/client/src/pages/docker/DockerDetails.tsx b/client/src/pages/docker/DockerDetails.tsx index f7338cdff..7a9d0eeb4 100644 --- a/client/src/pages/docker/DockerDetails.tsx +++ b/client/src/pages/docker/DockerDetails.tsx @@ -39,7 +39,7 @@ const DockerDetailsPage = () => { const monitor = response?.data?.monitor; const stats = response?.data?.stats; const checks = (response?.data?.checks || []) as any; - const snapshot = monitor?.latestChecks?.[0].dockerContainers || []; + const snapshot = monitor?.latestChecks?.[0]?.dockerContainers ?? []; const palette = getStatusPalette(monitor?.status || "initializing"); const streakDuration = stats?.currentStreakStartedAt diff --git a/client/src/pages/docker/DockerMonitorsTable.tsx b/client/src/pages/docker/DockerMonitorsTable.tsx index c794099dc..6cf82cc5f 100644 --- a/client/src/pages/docker/DockerMonitorsTable.tsx +++ b/client/src/pages/docker/DockerMonitorsTable.tsx @@ -106,7 +106,9 @@ export const DockerMonitorsTable = ({ {t("common.table.headers.status")} ), - render: (row) => , + render: (row) => ( + + ), }, { id: "runningContainers", @@ -116,7 +118,6 @@ export const DockerMonitorsTable = ({ ), render: (row) => { - console.log(row); const containerCount = ( row.latestChecks?.[0]?.dockerContainers || [] ).filter((c: any) => c?.running).length; diff --git a/client/src/pages/infrastructure/InfraMonitorsTable.tsx b/client/src/pages/infrastructure/InfraMonitorsTable.tsx index 674867337..e55cb5866 100644 --- a/client/src/pages/infrastructure/InfraMonitorsTable.tsx +++ b/client/src/pages/infrastructure/InfraMonitorsTable.tsx @@ -193,7 +193,9 @@ export const InfraMonitorsTable = ({ ), render: (row) => { - return ; + return ( + + ); }, }, { diff --git a/client/src/pages/pagespeed/PageSpeedMonitorTable.tsx b/client/src/pages/pagespeed/PageSpeedMonitorTable.tsx index 5d2d0fb1c..57262c452 100644 --- a/client/src/pages/pagespeed/PageSpeedMonitorTable.tsx +++ b/client/src/pages/pagespeed/PageSpeedMonitorTable.tsx @@ -204,7 +204,7 @@ export const PageSpeedMonitorTable = ({ return ( diff --git a/client/src/pages/status-page/StatusPageConfig.tsx b/client/src/pages/status-page/StatusPageConfig.tsx index 4ca29a775..294f93f71 100644 --- a/client/src/pages/status-page/StatusPageConfig.tsx +++ b/client/src/pages/status-page/StatusPageConfig.tsx @@ -20,7 +20,7 @@ const StatusPageConfigPage = () => { ); const monitors = response?.data || []; - const initialData = statusPageResponse?.data; + const initialData = statusPageResponse?.data || {}; initialData.monitors = initialData?.monitors?.map((monitor: IMonitor) => monitor?._id) || []; diff --git a/client/src/pages/status-page/StatusPageDetails.tsx b/client/src/pages/status-page/StatusPageDetails.tsx index 335fb646f..993f92fd0 100644 --- a/client/src/pages/status-page/StatusPageDetails.tsx +++ b/client/src/pages/status-page/StatusPageDetails.tsx @@ -16,7 +16,7 @@ const GLOBAL_REFRESH = config.GLOBAL_REFRESH; const StatusPages = () => { const theme = useTheme(); const { id } = useParams(); - const { response } = useGet>( + const { response, loading } = useGet>( `/status-pages/${id}`, {}, { refreshInterval: GLOBAL_REFRESH, keepPreviousData: true } @@ -29,7 +29,7 @@ const StatusPages = () => { } return ( - + diff --git a/client/src/pages/uptime/UptimeMonitorsTable.tsx b/client/src/pages/uptime/UptimeMonitorsTable.tsx index aafe76902..d507f0690 100644 --- a/client/src/pages/uptime/UptimeMonitorsTable.tsx +++ b/client/src/pages/uptime/UptimeMonitorsTable.tsx @@ -206,9 +206,9 @@ export const MonitorTable = ({ content: t("monitors.uptime.table.headers.responseTime"), render: (row) => { if (chartType === "histogram") { - return ; + return ; } else { - return ; + return ; } }, },