diff --git a/client/src/Components/common/charts/HeatmapResponseTimeTooltip.tsx b/client/src/Components/common/charts/HeatmapResponseTimeTooltip.tsx
index 38ad25b9f..66c502f72 100644
--- a/client/src/Components/common/charts/HeatmapResponseTimeTooltip.tsx
+++ b/client/src/Components/common/charts/HeatmapResponseTimeTooltip.tsx
@@ -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 = ({
{t("common.labels.responseTime")}:{" "}
- {check?.responseTime
- ? prettyMilliseconds(check.responseTime, { compact: true })
- : "N/A"}
+ {check?.responseTime ? formatMs(check.responseTime) : "N/A"}
Status:{" "}
diff --git a/client/src/Components/common/charts/HistogramResponseTime.tsx b/client/src/Components/common/charts/HistogramResponseTime.tsx
index eca798011..e2924d29f 100644
--- a/client/src/Components/common/charts/HistogramResponseTime.tsx
+++ b/client/src/Components/common/charts/HistogramResponseTime.tsx
@@ -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") && (
-
+
-
- {t("common.charts.histogram.avg", { value: stats.avg })}
-
-
- {t("common.charts.histogram.max", { value: stats.max })}
-
-
- );
+ {t("common.charts.histogram.avg", { value: stats.avg })}
+
+
+ {t("common.charts.histogram.max", { value: stats.max })}
+
+
+ );
return (
{
const theme = useTheme();
const isSmall = useMediaQuery(theme.breakpoints.down("md"));
@@ -52,7 +52,7 @@ export const MonitorStatus = ({ monitor }: { monitor: Monitor }) => {
<>
- Checking every {prettyMilliseconds(monitor?.interval, { verbose: true })}
+ Checking every {formatDuration(monitor?.interval, true)}
>
)}
diff --git a/client/src/Components/monitors/GeoChecksMap.tsx b/client/src/Components/monitors/GeoChecksMap.tsx
index e013f2235..ab5bfc3ab 100644
--- a/client/src/Components/monitors/GeoChecksMap.tsx
+++ b/client/src/Components/monitors/GeoChecksMap.tsx
@@ -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:
{" "}
- {formatResponseTime(selectedCheck.timings.total)}
+ {formatMs(selectedCheck.timings.total)}
{monitor?.type === "http" && (
diff --git a/client/src/Components/monitors/charts/HistogramDetails.tsx b/client/src/Components/monitors/charts/HistogramDetails.tsx
index f0d501327..a9af6d117 100644
--- a/client/src/Components/monitors/charts/HistogramDetails.tsx
+++ b/client/src/Components/monitors/charts/HistogramDetails.tsx
@@ -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 (
{formatDateWithTz(String(label), format, uiTimezone)}
{t("common.charts.histogram.responseTime", {
- value: prettyMilliseconds(responseTime, {
- formatSubMilliseconds: true,
- compact: true,
- }),
+ value: formatMs(responseTime),
})}
@@ -94,7 +90,7 @@ const TimingPhasesToolTip = ({
{formatDateWithTz(bucket.bucketDate, format, uiTimezone)}
- {t("common.charts.histogram.total", { value: prettyMilliseconds(total) })}
+ {t("common.charts.histogram.total", { value: formatMs(total) })}
{PHASE_KEYS.map((key) => (
- {t(PHASE_LABEL_KEYS[key])}:{" "}
- {prettyMilliseconds(bucket[key], {
- formatSubMilliseconds: true,
- compact: true,
- })}
+ {t(PHASE_LABEL_KEYS[key])}: {formatMs(bucket[key])}
))}
diff --git a/client/src/Components/monitors/charts/HistogramStatus.tsx b/client/src/Components/monitors/charts/HistogramStatus.tsx
index 44f6bea97..846510e09 100644
--- a/client/src/Components/monitors/charts/HistogramStatus.tsx
+++ b/client/src/Components/monitors/charts/HistogramStatus.tsx
@@ -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 = ({
) : null}
{titleText}
- {Math.floor(avg)} ms
+ {formatMs(avg)}
);
};
diff --git a/client/src/Components/monitors/charts/RadialAvgResponse.tsx b/client/src/Components/monitors/charts/RadialAvgResponse.tsx
index dccb18984..98864b48e 100644
--- a/client/src/Components/monitors/charts/RadialAvgResponse.tsx
+++ b/client/src/Components/monitors/charts/RadialAvgResponse.tsx
@@ -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 }) =>
{`${avg?.toFixed()}ms`}
+ >
+ {formatMs(avg)}
+
diff --git a/client/src/Pages/Incidents/utils.ts b/client/src/Pages/Incidents/utils.ts
index 6ff518a18..3407c40b4 100644
--- a/client/src/Pages/Incidents/utils.ts
+++ b/client/src/Pages/Incidents/utils.ts
@@ -1,5 +1,5 @@
import type { Incident, IncidentSummaryItem } from "@/Types/Incident";
-import prettyMilliseconds from "pretty-ms";
+import { formatDuration } from "@/Utils/TimeUtils";
type IncidentLike = Pick;
@@ -24,8 +24,5 @@ export const getIncidentsDuration = (incident: IncidentLike | IncidentSummaryIte
return "-";
}
- return prettyMilliseconds(durationMs, {
- secondsDecimalDigits: 0,
- millisecondsDecimalDigits: 0,
- });
+ return formatDuration(durationMs);
};
diff --git a/client/src/Pages/Logs/components/Stats.tsx b/client/src/Pages/Logs/components/Stats.tsx
index 9fe04fa9d..d76aa7443 100644
--- a/client/src/Pages/Logs/components/Stats.tsx
+++ b/client/src/Pages/Logs/components/Stats.tsx
@@ -2,10 +2,10 @@ import Box from "@mui/material/Box";
import { StatBox } from "@/Components/design-elements";
import prettyBytes from "pretty-bytes";
-import prettyMilliseconds from "pretty-ms";
import { useTheme } from "@mui/material";
import { useTranslation } from "react-i18next";
import type { Diagnostics } from "@/Types/Diagnostics";
+import { formatDuration, formatMs } from "@/Utils/TimeUtils";
interface StatsProps {
diagnostics: Diagnostics | null;
@@ -18,13 +18,9 @@ export const Stats = ({ diagnostics }: StatsProps) => {
const theme = useTheme();
const eventLoopDelay = diagnostics
- ? prettyMilliseconds(diagnostics.eventLoopDelayMs ?? 0, {
- millisecondsDecimalDigits: 2,
- })
- : PLACEHOLDER;
- const uptime = diagnostics
- ? prettyMilliseconds(diagnostics.uptimeMs ?? 0, { hideSeconds: true })
+ ? formatMs(diagnostics.eventLoopDelayMs ?? 0)
: PLACEHOLDER;
+ const uptime = diagnostics ? formatDuration(diagnostics.uptimeMs ?? 0) : PLACEHOLDER;
const usedHeap = diagnostics
? prettyBytes(diagnostics.v8HeapStats?.usedHeapSizeBytes ?? 0)
: PLACEHOLDER;
@@ -37,10 +33,10 @@ export const Stats = ({ diagnostics }: StatsProps) => {
return (
*": { width: "100% !important" },
}}
>
diff --git a/client/src/Pages/Logs/components/TableJobs.tsx b/client/src/Pages/Logs/components/TableJobs.tsx
index 26fe62bb3..c8c287a9e 100644
--- a/client/src/Pages/Logs/components/TableJobs.tsx
+++ b/client/src/Pages/Logs/components/TableJobs.tsx
@@ -1,7 +1,6 @@
import { Table, Pagination } from "@/Components/design-elements";
import { Typography, useTheme } from "@mui/material";
-import prettyMilliseconds from "pretty-ms";
-import { formatTimestamp } from "@/Utils/TimeUtils";
+import { formatDuration, formatTimestamp } from "@/Utils/TimeUtils";
import { useTranslation } from "react-i18next";
import type { QueueJobFailure, QueueJobSummary, QueueMetrics } from "@/Types/Queue";
@@ -84,7 +83,7 @@ export const TableJobs = ({
id: "interval",
content: t("common.table.headers.interval"),
render: (row) => (
- {prettyMilliseconds(row.monitorInterval ?? 0)}
+ {formatDuration(row.monitorInterval ?? 0)}
),
},
{
diff --git a/client/src/Pages/Maintenance/MaintenanceWindowTable.tsx b/client/src/Pages/Maintenance/MaintenanceWindowTable.tsx
index 6dadb5a9c..7cd543007 100644
--- a/client/src/Pages/Maintenance/MaintenanceWindowTable.tsx
+++ b/client/src/Pages/Maintenance/MaintenanceWindowTable.tsx
@@ -4,7 +4,6 @@ import { Pagination } from "@/Components/design-elements/Table";
import { ActionsMenu } from "@/Components/actions-menu";
import { DialogInput } from "@/Components/inputs/Dialog";
-import prettyMilliseconds from "pretty-ms";
import { useTheme } from "@mui/material";
import type { Header } from "@/Components/design-elements/Table";
import type { ActionMenuItem } from "@/Components/actions-menu";
@@ -18,6 +17,7 @@ import { setRowsPerPage } from "@/Features/UI/uiSlice";
import dayjs from "dayjs";
import { useState } from "react";
import { useDelete, usePatch } from "@/Hooks/UseApi";
+import { formatDuration } from "@/Utils/TimeUtils";
interface MaintenanceWindowTableProps {
maintenanceWindows: MaintenanceWindow[];
@@ -51,7 +51,7 @@ const getTimeToNextWindow = (
// Window is in the future
if (start.isAfter(now)) {
- return prettyMilliseconds(start.diff(now), { unitCount: 2, hideSeconds: true });
+ return formatDuration(start.diff(now));
}
return "N/A";
@@ -152,9 +152,7 @@ export const MaintenanceWindowTable = ({
id: "repeat",
content: t("pages.maintenanceWindow.table.headers.repeat"),
render: (row) =>
- row.repeat === 0
- ? t("common.labels.na")
- : prettyMilliseconds(row.repeat, { verbose: true }),
+ row.repeat === 0 ? t("common.labels.na") : formatDuration(row.repeat),
},
{
id: "actions",
diff --git a/client/src/Pages/StatusPage/Status/themes/shared/ThemedChartTooltip.tsx b/client/src/Pages/StatusPage/Status/themes/shared/ThemedChartTooltip.tsx
index 597000b17..bc3def0d4 100644
--- a/client/src/Pages/StatusPage/Status/themes/shared/ThemedChartTooltip.tsx
+++ b/client/src/Pages/StatusPage/Status/themes/shared/ThemedChartTooltip.tsx
@@ -1,8 +1,7 @@
import type { CheckSnapshot } from "@/Types/Check";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
-import prettyMilliseconds from "pretty-ms";
-import { formatDateWithTz } from "@/Utils/TimeUtils";
+import { formatDateWithTz, formatMs } from "@/Utils/TimeUtils";
import { useStatusPageTheme } from "@/Pages/StatusPage/Status/themes/StatusPageThemeProvider";
import { useTranslation } from "react-i18next";
@@ -16,7 +15,7 @@ export const ThemedChartTooltip = ({ check }: { check: CheckSnapshot }) => {
fontWeight={600}
>
{check.status
- ? `${prettyMilliseconds(check.responseTime, { compact: true })}`
+ ? formatMs(check.responseTime)
: t("pages.statusPages.monitorsList.chart.downTooltip")}
{
>
);
diff --git a/client/src/Pages/StatusPage/Status/themes/shared/ThemedHistogram.tsx b/client/src/Pages/StatusPage/Status/themes/shared/ThemedHistogram.tsx
index c83010e7d..a5c0b71f1 100644
--- a/client/src/Pages/StatusPage/Status/themes/shared/ThemedHistogram.tsx
+++ b/client/src/Pages/StatusPage/Status/themes/shared/ThemedHistogram.tsx
@@ -7,6 +7,7 @@ import { useTranslation } from "react-i18next";
import type { CheckSnapshot } from "@/Types/Check";
import { MAX_RECENT_CHECKS } from "@/Types/Monitor";
import { computeBarHeights } from "@/Utils/DataUtils";
+import { formatMs } from "@/Utils/TimeUtils";
import { ThemedChartTooltip } from "@/Pages/StatusPage/Status/themes/shared/ThemedChartTooltip";
const CELLS = MAX_RECENT_CHECKS;
const MIN_HEIGHT_PCT = 6;
@@ -41,11 +42,11 @@ export const ThemedHistogram = ({
];
const heights = computeBarHeights(source);
const valid = out.filter((c): c is CheckSnapshot => c !== null && c.responseTime > 0);
- const maxRt = valid.length ? Math.max(...valid.map((c) => c.responseTime)) : 1;
+ const maxRt = valid.length ? Math.max(...valid.map((c) => c.responseTime)) : 0;
const avgRt = valid.length
- ? Math.round(valid.reduce((s, c) => s + c.responseTime, 0) / valid.length)
+ ? valid.reduce((s, c) => s + c.responseTime, 0) / valid.length
: 0;
- return { padded: out, heights, avg: avgRt, peak: maxRt };
+ return { padded: out, heights, avg: formatMs(avgRt), peak: formatMs(maxRt) };
}, [checks]);
return (
@@ -71,7 +72,7 @@ export const ThemedHistogram = ({
>
);
diff --git a/client/src/Pages/Uptime/Details/Components/GeoChecksTable.tsx b/client/src/Pages/Uptime/Details/Components/GeoChecksTable.tsx
index 373e09da2..2144c8769 100644
--- a/client/src/Pages/Uptime/Details/Components/GeoChecksTable.tsx
+++ b/client/src/Pages/Uptime/Details/Components/GeoChecksTable.tsx
@@ -8,10 +8,9 @@ import Box from "@mui/material/Box";
import type { Header } from "@/Components/design-elements";
import type { FlatGeoCheck } from "@/Types/GeoCheck";
import { useTranslation } from "react-i18next";
-import { formatDateWithTz } from "@/Utils/TimeUtils";
+import { formatDateWithTz, formatMs } from "@/Utils/TimeUtils";
import type { RootState } from "@/Types/state";
import { useSelector } from "react-redux";
-import prettyMilliseconds from "pretty-ms";
export const GeoChecksTable = ({
geoChecks,
@@ -69,7 +68,7 @@ export const GeoChecksTable = ({
content: t("common.table.headers.responseTime"),
render: (row) => {
if (!row.timings?.total) return "N/A";
- return prettyMilliseconds(row.timings.total, { compact: true });
+ return formatMs(row.timings.total);
},
},
];
diff --git a/client/src/Utils/TimeUtils.ts b/client/src/Utils/TimeUtils.ts
index 5b63de87e..4112967ab 100644
--- a/client/src/Utils/TimeUtils.ts
+++ b/client/src/Utils/TimeUtils.ts
@@ -3,6 +3,7 @@ import duration from "dayjs/plugin/duration";
import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone";
import customParseFormat from "dayjs/plugin/customParseFormat";
+import prettyMilliseconds from "pretty-ms";
dayjs.extend(utc);
dayjs.extend(timezone);
@@ -77,3 +78,45 @@ export const formatTimestamp = (timestamp: string | number | null): string => {
const date = new Date(timestamp);
return date.toLocaleString();
};
+
+const DISPLAY_UNITS = [MS_PER_DAY, MS_PER_HOUR, MS_PER_MINUTE, MS_PER_SECOND];
+
+// pretty-ms floors seconds-and-above and truncates fractional ms, so values
+// must be rounded to their display unit first to land on the nearest whole
+// unit (53.6 → "54 ms", 1937 → "2 s", 59500 → "1 m").
+const roundToDisplayUnit = (ms: number): number => {
+ for (const unit of DISPLAY_UNITS) {
+ if (ms >= unit) return Math.round(ms / unit) * unit;
+ }
+ return ms >= 1 ? Math.round(ms) : ms;
+};
+
+export const formatMs = (ms: number, hasSpace: boolean = true): string => {
+ const formatted = prettyMilliseconds(roundToDisplayUnit(ms), {
+ compact: true,
+ formatSubMilliseconds: true,
+ secondsDecimalDigits: 0,
+ });
+
+ if (hasSpace) {
+ return formatted.replace(/^(\d+)(\D+)$/, "$1 $2");
+ }
+ return formatted;
+};
+
+export const formatDuration = (ms: number, verbose: boolean = false, hasSpace = true) => {
+ if (verbose) {
+ return prettyMilliseconds(ms, { verbose: true });
+ }
+
+ const formatted = prettyMilliseconds(ms, {
+ unitCount: 2,
+ secondsDecimalDigits: 0,
+ millisecondsDecimalDigits: 0,
+ });
+
+ if (hasSpace) {
+ return formatted.replace(/^(\d+)(\D+)$/, "$1 $2");
+ }
+ return formatted;
+};
diff --git a/client/src/locales/ar.json b/client/src/locales/ar.json
index 6e315bd9a..55f34650d 100644
--- a/client/src/locales/ar.json
+++ b/client/src/locales/ar.json
@@ -58,8 +58,8 @@
"uptime": "وقت التشغيل"
},
"histogram": {
- "avg": "المتوسط: {{value}} مللي ثانية",
- "max": "الحد الأقصى: {{value}} مللي ثانية"
+ "avg": "المتوسط: {{value}}",
+ "max": "الحد الأقصى: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "وقت الاستجابة"
},
"chart": {
- "avg": "متوسط {{value}} مللي ثانية",
+ "avg": "متوسط {{value}}",
"downTooltip": "متوقف",
"heatmapAria": "خريطة حرارية لزمن الاستجابة",
- "max": "أقصى {{value}} مللي ثانية"
+ "max": "أقصى {{value}}"
},
"status": {
"breached": "تم تجاوز الحد",
diff --git a/client/src/locales/ca.json b/client/src/locales/ca.json
index 3c1a29613..7e39eca86 100644
--- a/client/src/locales/ca.json
+++ b/client/src/locales/ca.json
@@ -58,8 +58,8 @@
"uptime": "Temps en línia"
},
"histogram": {
- "avg": "Mitjana: {{value}} ms",
- "max": "Màx: {{value}} ms"
+ "avg": "Mitjana: {{value}}",
+ "max": "Màx: {{value}}"
}
},
"dialogs": {
@@ -1346,8 +1346,8 @@
"initializing": "Inicialitzant"
},
"chart": {
- "avg": "mitj {{value}}ms",
- "max": "màx {{value}}ms",
+ "avg": "mitj {{value}}",
+ "max": "màx {{value}}",
"downTooltip": "Caigut",
"heatmapAria": "Mapa de calor del temps de resposta"
},
diff --git a/client/src/locales/cs.json b/client/src/locales/cs.json
index ae683aefe..d04b9b23b 100644
--- a/client/src/locales/cs.json
+++ b/client/src/locales/cs.json
@@ -58,8 +58,8 @@
"uptime": "Dostupnost"
},
"histogram": {
- "avg": "Prům.: {{value}} ms",
- "max": "Max: {{value}} ms"
+ "avg": "Prům.: {{value}}",
+ "max": "Max: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Doba odezvy"
},
"chart": {
- "avg": "průměr {{value}}ms",
+ "avg": "průměr {{value}}",
"downTooltip": "Mimo provoz",
"heatmapAria": "Tepelná mapa doby odezvy",
- "max": "max {{value}}ms"
+ "max": "max {{value}}"
},
"status": {
"breached": "Překročen limit",
diff --git a/client/src/locales/de.json b/client/src/locales/de.json
index 7b2e64945..d43d5d52a 100644
--- a/client/src/locales/de.json
+++ b/client/src/locales/de.json
@@ -58,8 +58,8 @@
"uptime": "Verfügbarkeit"
},
"histogram": {
- "avg": "Durchschn.: {{value}} ms",
- "max": "Max.: {{value}} ms"
+ "avg": "Durchschn.: {{value}}",
+ "max": "Max.: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Antwortzeit"
},
"chart": {
- "avg": "Ø {{value}}ms",
+ "avg": "Ø {{value}}",
"downTooltip": "Ausgefallen",
"heatmapAria": "Heatmap der Antwortzeit",
- "max": "max. {{value}}ms"
+ "max": "max. {{value}}"
},
"status": {
"breached": "Schwellenwert überschritten",
diff --git a/client/src/locales/en.json b/client/src/locales/en.json
index ce7f74dfb..955e9727f 100644
--- a/client/src/locales/en.json
+++ b/client/src/locales/en.json
@@ -74,8 +74,8 @@
"uptime": "Uptime"
},
"histogram": {
- "avg": "Avg: {{value}} ms",
- "max": "Max: {{value}} ms",
+ "avg": "Avg: {{value}}",
+ "max": "Max: {{value}}",
"responseTime": "Response time: {{value}}",
"total": "Total: {{value}}"
},
@@ -1455,8 +1455,8 @@
"initializing": "Initializing"
},
"chart": {
- "avg": "avg {{value}}ms",
- "max": "max {{value}}ms",
+ "avg": "avg {{value}}",
+ "max": "max {{value}}",
"downTooltip": "Down",
"heatmapAria": "Response time heatmap"
},
diff --git a/client/src/locales/es.json b/client/src/locales/es.json
index 1c45ecad4..589399a83 100644
--- a/client/src/locales/es.json
+++ b/client/src/locales/es.json
@@ -58,8 +58,8 @@
"uptime": "Tiempo de actividad"
},
"histogram": {
- "avg": "Prom: {{value}} ms",
- "max": "Máx: {{value}} ms"
+ "avg": "Prom: {{value}}",
+ "max": "Máx: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Tiempo de respuesta"
},
"chart": {
- "avg": "prom {{value}}ms",
+ "avg": "prom {{value}}",
"downTooltip": "Caído",
"heatmapAria": "Mapa de calor del tiempo de respuesta",
- "max": "máx {{value}}ms"
+ "max": "máx {{value}}"
},
"status": {
"breached": "Umbral superado",
diff --git a/client/src/locales/fi.json b/client/src/locales/fi.json
index 3ca1de82a..030698d44 100644
--- a/client/src/locales/fi.json
+++ b/client/src/locales/fi.json
@@ -58,8 +58,8 @@
"uptime": "Käytettävyys"
},
"histogram": {
- "avg": "Keskim.: {{value}} ms",
- "max": "Maks.: {{value}} ms"
+ "avg": "Keskim.: {{value}}",
+ "max": "Maks.: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Vasteaika"
},
"chart": {
- "avg": "ka {{value}}ms",
+ "avg": "ka {{value}}",
"downTooltip": "Alhaalla",
"heatmapAria": "Vasteajan lämpökartta",
- "max": "max {{value}}ms"
+ "max": "max {{value}}"
},
"status": {
"breached": "Kynnys ylittyi",
diff --git a/client/src/locales/fr.json b/client/src/locales/fr.json
index 9b3e983a6..1e0a6b096 100644
--- a/client/src/locales/fr.json
+++ b/client/src/locales/fr.json
@@ -58,8 +58,8 @@
"uptime": "Disponibilité"
},
"histogram": {
- "avg": "Moy : {{value}} ms",
- "max": "Max : {{value}} ms"
+ "avg": "Moy : {{value}}",
+ "max": "Max : {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Temps de réponse"
},
"chart": {
- "avg": "moy {{value}}ms",
+ "avg": "moy {{value}}",
"downTooltip": "Hors service",
"heatmapAria": "Carte thermique des temps de réponse",
- "max": "max {{value}}ms"
+ "max": "max {{value}}"
},
"status": {
"breached": "Seuil dépassé",
diff --git a/client/src/locales/it.json b/client/src/locales/it.json
index cabeb94ef..3d6d1ea16 100644
--- a/client/src/locales/it.json
+++ b/client/src/locales/it.json
@@ -71,8 +71,8 @@
"uptime": "Uptime"
},
"histogram": {
- "avg": "Media: {{value}} ms",
- "max": "Max: {{value}} ms"
+ "avg": "Media: {{value}}",
+ "max": "Max: {{value}}"
}
},
"dialogs": {
@@ -1442,8 +1442,8 @@
"initializing": "Inizializzazione"
},
"chart": {
- "avg": "media {{value}}ms",
- "max": "max {{value}}ms",
+ "avg": "media {{value}}",
+ "max": "max {{value}}",
"downTooltip": "Non attivo",
"heatmapAria": "Heatmap del tempo di risposta"
},
diff --git a/client/src/locales/ja.json b/client/src/locales/ja.json
index 031350b20..16e2ec641 100644
--- a/client/src/locales/ja.json
+++ b/client/src/locales/ja.json
@@ -58,8 +58,8 @@
"uptime": "稼働時間"
},
"histogram": {
- "avg": "平均: {{value}} ms",
- "max": "最大: {{value}} ms"
+ "avg": "平均: {{value}}",
+ "max": "最大: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "応答時間"
},
"chart": {
- "avg": "平均 {{value}}ms",
+ "avg": "平均 {{value}}",
"downTooltip": "ダウン",
"heatmapAria": "応答時間のヒートマップ",
- "max": "最大 {{value}}ms"
+ "max": "最大 {{value}}"
},
"status": {
"breached": "しきい値超過",
diff --git a/client/src/locales/pl.json b/client/src/locales/pl.json
index 9a74b6cdb..81509ee6f 100644
--- a/client/src/locales/pl.json
+++ b/client/src/locales/pl.json
@@ -53,8 +53,8 @@
},
"charts": {
"histogram": {
- "avg": "Średnia: {{value}} ms",
- "max": "Maks: {{value}} ms"
+ "avg": "Średnia: {{value}}",
+ "max": "Maks: {{value}}"
},
"labels": {
"averageResponseTime": "Średni czas odpowiedzi",
@@ -1542,10 +1542,10 @@
},
"monitorsList": {
"chart": {
- "avg": "śr. {{value}}ms",
+ "avg": "śr. {{value}}",
"downTooltip": "Niedostępny",
"heatmapAria": "Heatmapa czasu odpowiedzi",
- "max": "maks. {{value}}ms"
+ "max": "maks. {{value}}"
},
"chartTypeHeatmap": "Heatmapa",
"chartTypeHistogram": "Histogram",
diff --git a/client/src/locales/pt-BR.json b/client/src/locales/pt-BR.json
index 0286f2857..c75ead3ef 100644
--- a/client/src/locales/pt-BR.json
+++ b/client/src/locales/pt-BR.json
@@ -58,8 +58,8 @@
"uptime": "Uptime"
},
"histogram": {
- "avg": "Média: {{value}} ms",
- "max": "Máx: {{value}} ms"
+ "avg": "Média: {{value}}",
+ "max": "Máx: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Tempo de resposta"
},
"chart": {
- "avg": "méd {{value}}ms",
+ "avg": "méd {{value}}",
"downTooltip": "Fora do ar",
"heatmapAria": "Mapa de calor do tempo de resposta",
- "max": "máx {{value}}ms"
+ "max": "máx {{value}}"
},
"status": {
"breached": "Limite excedido",
diff --git a/client/src/locales/ru.json b/client/src/locales/ru.json
index 50226037a..cf5e486f7 100644
--- a/client/src/locales/ru.json
+++ b/client/src/locales/ru.json
@@ -58,8 +58,8 @@
"uptime": "Аптайм"
},
"histogram": {
- "avg": "Сред: {{value}} мс",
- "max": "Макс: {{value}} мс"
+ "avg": "Сред: {{value}}",
+ "max": "Макс: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Время ответа"
},
"chart": {
- "avg": "ср {{value}}мс",
+ "avg": "ср {{value}}",
"downTooltip": "Не работает",
"heatmapAria": "Тепловая карта времени отклика",
- "max": "макс {{value}}мс"
+ "max": "макс {{value}}"
},
"status": {
"breached": "Превышен порог",
diff --git a/client/src/locales/th.json b/client/src/locales/th.json
index c0889a72f..66d354adc 100644
--- a/client/src/locales/th.json
+++ b/client/src/locales/th.json
@@ -58,8 +58,8 @@
"uptime": "อัปไทม์"
},
"histogram": {
- "avg": "เฉลี่ย: {{value}} ms",
- "max": "สูงสุด: {{value}} ms"
+ "avg": "เฉลี่ย: {{value}}",
+ "max": "สูงสุด: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "เวลาตอบสนอง"
},
"chart": {
- "avg": "เฉลี่ย {{value}}ms",
+ "avg": "เฉลี่ย {{value}}",
"downTooltip": "ไม่พร้อมใช้งาน",
"heatmapAria": "แผนที่ความร้อนของเวลาตอบสนอง",
- "max": "สูงสุด {{value}}ms"
+ "max": "สูงสุด {{value}}"
},
"status": {
"breached": "เกินขีดจำกัด",
diff --git a/client/src/locales/tr.json b/client/src/locales/tr.json
index c82091a83..26f8aace0 100644
--- a/client/src/locales/tr.json
+++ b/client/src/locales/tr.json
@@ -58,8 +58,8 @@
"uptime": "Çalışma süresi"
},
"histogram": {
- "avg": "Ort: {{value}} ms",
- "max": "Maks: {{value}} ms"
+ "avg": "Ort: {{value}}",
+ "max": "Maks: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Yanıt süresi"
},
"chart": {
- "avg": "ort {{value}}ms",
+ "avg": "ort {{value}}",
"downTooltip": "Çalışmıyor",
"heatmapAria": "Yanıt süresi ısı haritası",
- "max": "maks {{value}}ms"
+ "max": "maks {{value}}"
},
"status": {
"breached": "Eşik aşıldı",
diff --git a/client/src/locales/uk.json b/client/src/locales/uk.json
index 6c3b47b66..d1cb983d1 100644
--- a/client/src/locales/uk.json
+++ b/client/src/locales/uk.json
@@ -58,8 +58,8 @@
"uptime": "Час роботи"
},
"histogram": {
- "avg": "Сер: {{value}} мс",
- "max": "Макс: {{value}} мс"
+ "avg": "Сер: {{value}}",
+ "max": "Макс: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Час відповіді"
},
"chart": {
- "avg": "сер {{value}}мс",
+ "avg": "сер {{value}}",
"downTooltip": "Не працює",
"heatmapAria": "Теплова карта часу відгуку",
- "max": "макс {{value}}мс"
+ "max": "макс {{value}}"
},
"status": {
"breached": "Перевищено поріг",
diff --git a/client/src/locales/vi.json b/client/src/locales/vi.json
index 72c933601..81da1c6fc 100644
--- a/client/src/locales/vi.json
+++ b/client/src/locales/vi.json
@@ -58,8 +58,8 @@
"uptime": "Thời gian hoạt động"
},
"histogram": {
- "avg": "TB: {{value}} ms",
- "max": "Tối đa: {{value}} ms"
+ "avg": "TB: {{value}}",
+ "max": "Tối đa: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "Thời gian phản hồi"
},
"chart": {
- "avg": "TB {{value}}ms",
+ "avg": "TB {{value}}",
"downTooltip": "Ngừng hoạt động",
"heatmapAria": "Bản đồ nhiệt thời gian phản hồi",
- "max": "tối đa {{value}}ms"
+ "max": "tối đa {{value}}"
},
"status": {
"breached": "Vượt ngưỡng",
diff --git a/client/src/locales/zh-CN.json b/client/src/locales/zh-CN.json
index 4499dd5fb..bef6bebde 100644
--- a/client/src/locales/zh-CN.json
+++ b/client/src/locales/zh-CN.json
@@ -58,8 +58,8 @@
"uptime": "正常运行时间"
},
"histogram": {
- "avg": "平均: {{value}} ms",
- "max": "最大: {{value}} ms"
+ "avg": "平均: {{value}}",
+ "max": "最大: {{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "响应时间"
},
"chart": {
- "avg": "平均 {{value}}ms",
+ "avg": "平均 {{value}}",
"downTooltip": "宕机",
"heatmapAria": "响应时间热图",
- "max": "最大 {{value}}ms"
+ "max": "最大 {{value}}"
},
"status": {
"breached": "超出阈值",
diff --git a/client/src/locales/zh-TW.json b/client/src/locales/zh-TW.json
index 7b560ae7d..a15a2a2bb 100644
--- a/client/src/locales/zh-TW.json
+++ b/client/src/locales/zh-TW.json
@@ -58,8 +58,8 @@
"uptime": "正常運行時間"
},
"histogram": {
- "avg": "平均:{{value}} ms",
- "max": "最大:{{value}} ms"
+ "avg": "平均:{{value}}",
+ "max": "最大:{{value}}"
}
},
"dialogs": {
@@ -1352,10 +1352,10 @@
"responseTime": "回應時間"
},
"chart": {
- "avg": "平均 {{value}}ms",
+ "avg": "平均 {{value}}",
"downTooltip": "停機",
"heatmapAria": "回應時間熱圖",
- "max": "最大 {{value}}ms"
+ "max": "最大 {{value}}"
},
"status": {
"breached": "超過閾值",