use formatMs function to consistently format point times

This commit is contained in:
Alex Holliday committed 2026-07-31 12:40:18 -07:00
1 parent 65c6f567b5
commit 336dbe4de2
32 files changed
+153 -147

No files matched your search

@@ -1,13 +1,12 @@
import Stack from "@mui/material/Stack";
import Tooltip from "@mui/material/Tooltip";
import Typography from "@mui/material/Typography";
import { formatDateWithTz } from "@/Utils/TimeUtils";
import { formatDateWithTz, formatMs } from "@/Utils/TimeUtils";
import type { CheckSnapshot } from "@/Types/Check";
import { useTheme } from "@mui/material/styles";
import { useSelector } from "react-redux";
import type { RootState } from "@/Types/state";
import { useTranslation } from "react-i18next";
import prettyMilliseconds from "pretty-ms";
type HeatmapCheck =
| CheckSnapshot
@@ -59,9 +58,7 @@ export const HeatmapResponseTimeTooltip = ({
</Typography>
<Typography>
{t("common.labels.responseTime")}:{" "}
{check?.responseTime
? prettyMilliseconds(check.responseTime, { compact: true })
: "N/A"}
{check?.responseTime ? formatMs(check.responseTime) : "N/A"}
</Typography>
<Typography textTransform={"capitalize"}>
Status:{" "}
@@ -9,6 +9,7 @@ import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { MAX_RECENT_CHECKS } from "@/Types/Monitor";
import { computeBarHeights } from "@/Utils/DataUtils";
import { formatMs } from "@/Utils/TimeUtils";
interface HistogramResponseTimeProps {
checks: CheckSnapshot[];
@@ -19,25 +20,25 @@ interface HistogramResponseTimeProps {
}
interface ResponseTimeStats {
max: number | string;
avg: number | string;
max: string | null;
avg: string | null;
}
const DEFAULT_HEIGHT = 50;
const calculateResponseTimeStats = (checks: CheckSnapshot[]): ResponseTimeStats => {
if (!Array.isArray(checks) || checks.length === 0) {
return { max: "-", avg: "-" };
return { max: null, avg: null };
}
const validChecks = checks.filter((check) => check.responseTime != null);
if (validChecks.length === 0) {
return { max: "-", avg: "-" };
return { max: null, avg: null };
}
const responseTimes = validChecks.map((check) => check.responseTime);
const max = Math.round(Math.max(...responseTimes));
const avg = Math.round(
const max = formatMs(Math.max(...responseTimes));
const avg = formatMs(
responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length
);
@@ -69,29 +70,28 @@ export const HistogramResponseTime = ({
const chartHeight = typeof height === "number" ? `${height}px` : height;
const gridGap = gap ?? theme.spacing(0.5);
const statsContent = showStats &&
(typeof stats.max === "number" || typeof stats.avg === "number") && (
<Stack
justifyContent="center"
alignItems={statsPosition === "left" ? "flex-end" : "flex-start"}
width={110}
pr={statsPosition === "left" ? theme.spacing(8) : 0}
pl={statsPosition === "right" ? theme.spacing(8) : 0}
const statsContent = showStats && (stats.max !== null || stats.avg !== null) && (
<Stack
justifyContent="center"
alignItems={statsPosition === "left" ? "flex-end" : "flex-start"}
width={110}
pr={statsPosition === "left" ? theme.spacing(8) : 0}
pl={statsPosition === "right" ? theme.spacing(8) : 0}
>
<Typography
variant="body2"
noWrap
>
<Typography
variant="body2"
noWrap
>
{t("common.charts.histogram.avg", { value: stats.avg })}
</Typography>
<Typography
variant="body2"
noWrap
>
{t("common.charts.histogram.max", { value: stats.max })}
</Typography>
</Stack>
);
{t("common.charts.histogram.avg", { value: stats.avg })}
</Typography>
<Typography
variant="body2"
noWrap
>
{t("common.charts.histogram.max", { value: stats.max })}
</Typography>
</Stack>
);
return (
<Stack
@@ -6,6 +6,7 @@ import type { FlatGeoCheck } from "@/Types/GeoCheck";
import { useTranslation } from "react-i18next";
import { formatStatusCode } from "@/Utils/statusCode";
import "maplibre-gl/dist/maplibre-gl.css";
import { formatMs } from "@/Utils/TimeUtils";
interface GeoChecksMapProps {
geoChecks: FlatGeoCheck[];
@@ -83,10 +84,6 @@ export const GeoChecksMap = ({ geoChecks }: GeoChecksMapProps) => {
return status ? theme.palette.success.main : theme.palette.error.main;
};
const formatResponseTime = (timing: number): string => {
return `${timing.toFixed(0)}ms`;
};
return (
<>
{mapPopupStyles}
@@ -186,7 +183,7 @@ export const GeoChecksMap = ({ geoChecks }: GeoChecksMapProps) => {
>
Response Time:
</Typography>{" "}
{formatResponseTime(selectedCheck.timings.total)}
{formatMs(selectedCheck.timings.total)}
</Typography>
<Typography
variant="caption"
@@ -6,6 +6,7 @@ import { useTheme } from "@mui/material/styles";
import type { MonitorStats, Monitor } from "@/Types/Monitor";
import { getStatusPalette } from "@/Utils/MonitorUtils";
import { useTranslation } from "react-i18next";
import { formatMs } from "@/Utils/TimeUtils";
interface MonitorStatBoxesProps {
monitor?: Monitor;
@@ -67,7 +68,7 @@ export const MonitorStatBoxes = ({
/>
<StatBox
title={t("pages.common.monitors.statBoxes.lastResponseTime")}
subtitle={prettyMilliseconds(monitorStats?.lastResponseTime ?? 0)}
subtitle={formatMs(monitorStats?.lastResponseTime ?? 0)}
/>
{monitor?.type === "http" && (
@@ -14,11 +14,10 @@ import {
import type { TooltipProps } from "recharts";
import type { NameType, ValueType } from "recharts/types/component/DefaultTooltipContent";
import Typography from "@mui/material/Typography";
import prettyMilliseconds from "pretty-ms";
import { XTick } from "@/Components/monitors/charts/XTick";
import { useSelector } from "react-redux";
import { useTranslation } from "react-i18next";
import { formatDateWithTz, tooltipDateFormatLookup } from "@/Utils/TimeUtils";
import { formatDateWithTz, formatMs, tooltipDateFormatLookup } from "@/Utils/TimeUtils";
import { useTheme } from "@mui/material/styles";
import type { Theme } from "@mui/material/styles";
import type { GroupedCheck, GroupedUptimeCheck } from "@/Types/Check";
@@ -56,16 +55,13 @@ const ResponseTimeToolTip = ({
if (!active) return null;
const format = tooltipDateFormatLookup(range);
const responseTime = Math.floor(payload[0]?.payload?.avgResponseTime || 0);
const responseTime = payload[0]?.payload?.avgResponseTime ?? 0;
return (
<BaseBox sx={{ py: theme.spacing(2), px: theme.spacing(4) }}>
<Typography>{formatDateWithTz(String(label), format, uiTimezone)}</Typography>
<Typography>
{t("common.charts.histogram.responseTime", {
value: prettyMilliseconds(responseTime, {
formatSubMilliseconds: true,
compact: true,
}),
value: formatMs(responseTime),
})}
</Typography>
</BaseBox>
@@ -94,7 +90,7 @@ const TimingPhasesToolTip = ({
<BaseBox sx={{ py: theme.spacing(2), px: theme.spacing(4) }}>
<Typography>{formatDateWithTz(bucket.bucketDate, format, uiTimezone)}</Typography>
<Typography>
{t("common.charts.histogram.total", { value: prettyMilliseconds(total) })}
{t("common.charts.histogram.total", { value: formatMs(total) })}
</Typography>
{PHASE_KEYS.map((key) => (
<Stack
@@ -108,11 +104,7 @@ const TimingPhasesToolTip = ({
color={theme.palette.chart.phases[PHASE_COLOR_KEYS[key]]}
/>
<Typography>
{t(PHASE_LABEL_KEYS[key])}:{" "}
{prettyMilliseconds(bucket[key], {
formatSubMilliseconds: true,
compact: true,
})}
{t(PHASE_LABEL_KEYS[key])}: {formatMs(bucket[key])}
</Typography>
</Stack>
))}
@@ -3,7 +3,7 @@ import Typography from "@mui/material/Typography";
import { BaseChart } from "@/Components/design-elements";
import { useTheme } from "@mui/material/styles";
import { useSelector } from "react-redux";
import { formatDateWithTz } from "@/Utils/TimeUtils";
import { formatDateWithTz, formatMs } from "@/Utils/TimeUtils";
import { useTranslation } from "react-i18next";
import { ResponsiveContainer, BarChart, XAxis, Bar, Cell, Tooltip } from "recharts";
import { getResponseTimeColor } from "@/Utils/MonitorUtils";
@@ -100,7 +100,7 @@ export const HistogramStatus = ({
</Typography>
) : null}
<Typography variant="caption">{titleText}</Typography>
<Typography variant="body2">{Math.floor(avg)} ms</Typography>
<Typography variant="body2">{formatMs(avg)}</Typography>
</Stack>
);
};
@@ -7,6 +7,7 @@ import { Cell, RadialBarChart, RadialBar, ResponsiveContainer } from "recharts";
import { useTranslation } from "react-i18next";
import { getResponseTimeColor } from "@/Utils/MonitorUtils";
import { useTheme } from "@mui/material/styles";
import { formatMs } from "@/Utils/TimeUtils";
export const RadialAvgResponse = ({ avg, max }: { avg: number; max: number }) => {
const { t } = useTranslation();
@@ -84,7 +85,9 @@ export const RadialAvgResponse = ({ avg, max }: { avg: number; max: number }) =>
<Typography
variant="h1"
textAlign={"center"}
>{`${avg?.toFixed()}ms`}</Typography>
>
{formatMs(avg)}
</Typography>
</Stack>
</Stack>
</BaseChart>