defensive checks

This commit is contained in:
Alex Holliday committed 2025-12-31 20:51:30 +00:00
1 parent 86cfc89545
commit 7f15811fdf
11 files changed
+57 -20

No files matched your search

@@ -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 (
<BaseBox
@@ -37,8 +36,14 @@ export const StatusLabel = ({
...sx,
}}
>
<Box width={7} height={7} bgcolor={theme.palette[palette].light} borderRadius="50%" marginRight="5px" />
{transformedText}
<Box
width={7}
height={7}
bgcolor={theme.palette[palette].light}
borderRadius="50%"
marginRight="5px"
/>
<Typography textTransform={"capitalize"}>{status}</Typography>
</BaseBox>
);
};
@@ -70,7 +75,13 @@ export const ValueLabel = ({
: "rgba(0, 0, 0, 0.08)",
}}
>
<Box width={7} height={7} bgcolor={theme.palette[palette].light} borderRadius="50%" marginRight="5px" />
<Box
width={7}
height={7}
bgcolor={theme.palette[palette].light}
borderRadius="50%"
marginRight="5px"
/>
{transformedText}
</BaseBox>
);
@@ -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 (
<BaseBox sx={{ py: theme.spacing(2), px: theme.spacing(4) }}>
<Typography>
{formatDateWithTz(String(label), fmt, uiTimezone)}
</Typography>
<Typography>{`${value}%`}</Typography>
</BaseBox>
);
};
return (
<BaseChart
@@ -78,6 +97,7 @@ export const HistogramDockerPercentage = ({
tick={{ fontSize: isSmall ? 10 : 11 }}
tickMargin={4}
/>
<Tooltip content={<PercentTooltip />} cursor={false} />
<Area
dataKey={dataKey}
stroke={theme.palette.primary.main}
@@ -45,7 +45,7 @@ export const HistogramPageSpeed = ({
status: MonitorStatus;
}) => {
const theme = useTheme();
const scores = processData(checks);
const scores = processData(checks ?? []);
const color = getStatusColor(status, theme);
return (
<Stack
@@ -23,13 +23,16 @@ export const StatusPageRow = ({ monitor }: { monitor: IMonitor }) => {
alignItems={"center"}
justifyContent={"flex-end"}
>
<StatusLabel status={monitor?.status} sx={{ py: 1 }} />
<StatusLabel
status={(monitor?.status as any) ?? "initializing"}
sx={{ py: 1 }}
/>
</Grid>
<Grid size={12} marginTop={theme.spacing(2)}>
{type === "heatmap" && (
<HeatmapResponseTime
gap={{ xs: theme.spacing(0.5), md: theme.spacing(2) }}
checks={monitor?.latestChecks}
checks={monitor?.latestChecks ?? []}
availabilityCellSx={{
borderRadius: {
xs: theme.spacing(0.5),
@@ -46,7 +49,7 @@ export const StatusPageRow = ({ monitor }: { monitor: IMonitor }) => {
)}
{type === "histogram" && (
<HistogramResponseTime
checks={monitor?.latestChecks}
checks={monitor?.latestChecks ?? []}
height={{ xs: 50, md: 100 }}
gap={{ xs: 0.5, md: theme.spacing(4) }}
/>
+1 -1
View File
@@ -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
@@ -106,7 +106,9 @@ export const DockerMonitorsTable = ({
{t("common.table.headers.status")}
</Typography>
),
render: (row) => <StatusLabel status={row.status} />,
render: (row) => (
<StatusLabel status={(row.status as any) ?? ("initializing" as any)} />
),
},
{
id: "runningContainers",
@@ -116,7 +118,6 @@ export const DockerMonitorsTable = ({
</Typography>
),
render: (row) => {
console.log(row);
const containerCount = (
row.latestChecks?.[0]?.dockerContainers || []
).filter((c: any) => c?.running).length;
@@ -193,7 +193,9 @@ export const InfraMonitorsTable = ({
</Typography>
),
render: (row) => {
return <StatusLabel status={row.status} />;
return (
<StatusLabel status={(row.status as any) ?? ("initializing" as any)} />
);
},
},
{
@@ -204,7 +204,7 @@ export const PageSpeedMonitorTable = ({
return (
<Stack alignItems={"center"}>
<HistogramPageSpeed
checks={row.latestChecks}
checks={row.latestChecks ?? []}
status={row.status}
/>
</Stack>
@@ -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) || [];
@@ -16,7 +16,7 @@ const GLOBAL_REFRESH = config.GLOBAL_REFRESH;
const StatusPages = () => {
const theme = useTheme();
const { id } = useParams();
const { response } = useGet<ApiResponse<IStatusPageWithMonitors>>(
const { response, loading } = useGet<ApiResponse<IStatusPageWithMonitors>>(
`/status-pages/${id}`,
{},
{ refreshInterval: GLOBAL_REFRESH, keepPreviousData: true }
@@ -29,7 +29,7 @@ const StatusPages = () => {
}
return (
<BasePage alignItems={"center"}>
<BasePage alignItems={"center"} loading={loading}>
<Stack minWidth={"66vw"} spacing={theme.spacing(8)}>
<NameHeader statusPage={statusPage} />
<StatusHeader statusPage={statusPage} />
@@ -206,9 +206,9 @@ export const MonitorTable = ({
content: t("monitors.uptime.table.headers.responseTime"),
render: (row) => {
if (chartType === "histogram") {
return <HistogramResponseTime checks={row.latestChecks} />;
return <HistogramResponseTime checks={row.latestChecks ?? []} />;
} else {
return <HeatmapResponseTime checks={row.latestChecks} />;
return <HeatmapResponseTime checks={row.latestChecks ?? []} />;
}
},
},