diff --git a/client/src/Components/v2/DesignElements/StatusLabel.tsx b/client/src/Components/v2/DesignElements/StatusLabel.tsx
index 69b788e96..a314c09b0 100644
--- a/client/src/Components/v2/DesignElements/StatusLabel.tsx
+++ b/client/src/Components/v2/DesignElements/StatusLabel.tsx
@@ -5,7 +5,13 @@ import type { MonitorStatus } from "@/Types/Monitor";
import { getStatusPalette } from "@/Utils/MonitorUtils";
import { useTheme } from "@mui/material/styles";
-export const StatusLabel = ({ status }: { status: MonitorStatus }) => {
+export const StatusLabel = ({
+ status,
+ isActive,
+}: {
+ status: MonitorStatus;
+ isActive?: boolean;
+}) => {
const theme = useTheme();
const palette = getStatusPalette(status);
const transformedText = status.charAt(0).toUpperCase() + status.slice(1).toLowerCase();
@@ -29,7 +35,7 @@ export const StatusLabel = ({ status }: { status: MonitorStatus }) => {
borderRadius="50%"
marginRight="5px"
/>
- {transformedText}
+ {isActive === false ? "Paused" : transformedText}
);
};
diff --git a/client/src/Components/v2/Layouts/Sidebar/Menu.tsx b/client/src/Components/v2/Layouts/Sidebar/Menu.tsx
index 5b3ed705e..f0f99f33a 100644
--- a/client/src/Components/v2/Layouts/Sidebar/Menu.tsx
+++ b/client/src/Components/v2/Layouts/Sidebar/Menu.tsx
@@ -1,12 +1,12 @@
-import Notifications from "@/assets/icons/notifications.svg?react";
+// import Notifications from "@/assets/icons/notifications.svg?react";
import Monitors from "@/assets/icons/monitors.svg?react";
-import PageSpeed from "@/assets/icons/page-speed.svg?react";
-import Integrations from "@/assets/icons/integrations.svg?react";
-import Incidents from "@/assets/icons/incidents.svg?react";
-import StatusPages from "@/assets/icons/status-pages.svg?react";
-import Maintenance from "@/assets/icons/maintenance.svg?react";
-import Logs from "@/assets/icons/logs.svg?react";
-import Settings from "@/assets/icons/settings.svg?react";
+// import PageSpeed from "@/assets/icons/page-speed.svg?react";
+// import Integrations from "@/assets/icons/integrations.svg?react";
+// import Incidents from "@/assets/icons/incidents.svg?react";
+// import StatusPages from "@/assets/icons/status-pages.svg?react";
+// import Maintenance from "@/assets/icons/maintenance.svg?react";
+// import Logs from "@/assets/icons/logs.svg?react";
+// import Settings from "@/assets/icons/settings.svg?react";
import Support from "@/assets/icons/support.svg?react";
import Discussions from "@/assets/icons/discussions.svg?react";
import Docs from "@/assets/icons/docs.svg?react";
@@ -14,25 +14,25 @@ import ChangeLog from "@/assets/icons/changeLog.svg?react";
export const getMenu = (t: Function) => [
{ name: t("menu.uptime"), path: "v2/uptime", icon: },
- { name: t("menu.pagespeed"), path: "pagespeed", icon: },
+ // { name: t("menu.pagespeed"), path: "pagespeed", icon: },
- { name: t("menu.infrastructure"), path: "infrastructure", icon: },
- {
- name: t("menu.notifications"),
- path: "notifications",
- icon: ,
- },
- { name: t("menu.incidents"), path: "incidents", icon: },
+ // { name: t("menu.infrastructure"), path: "infrastructure", icon: },
+ // {
+ // name: t("menu.notifications"),
+ // path: "notifications",
+ // icon: ,
+ // },
+ // { name: t("menu.incidents"), path: "incidents", icon: },
- { name: t("menu.statusPages"), path: "status", icon: },
- { name: t("menu.maintenance"), path: "maintenance", icon: },
- { name: t("menu.logs"), path: "logs", icon: },
+ // { name: t("menu.statusPages"), path: "status", icon: },
+ // { name: t("menu.maintenance"), path: "maintenance", icon: },
+ // { name: t("menu.logs"), path: "logs", icon: },
- {
- name: t("menu.settings"),
- icon: ,
- path: "settings",
- },
+ // {
+ // name: t("menu.settings"),
+ // icon: ,
+ // path: "settings",
+ // },
];
export const getBottomMenu = (t: Function) => [
diff --git a/client/src/Components/v2/Monitors/ChartResponseTime.tsx b/client/src/Components/v2/Monitors/ChartResponseTime.tsx
index 97aef314d..28f40f254 100644
--- a/client/src/Components/v2/Monitors/ChartResponseTime.tsx
+++ b/client/src/Components/v2/Monitors/ChartResponseTime.tsx
@@ -1,6 +1,7 @@
import { BaseChart } from "./HistogramStatus";
import { BaseBox } from "../DesignElements";
import ResponseTimeIcon from "@/assets/icons/response-time-icon.svg?react";
+import { normalizeResponseTimes } from "@/Utils/DataUtils";
import {
AreaChart,
Area,
@@ -68,7 +69,7 @@ const ResponseTimeToolTip: React.FC = ({
if (!active) return null;
const format = tooltipDateFormatLookup(range);
- const responseTime = Math.floor(payload?.[0]?.value || 0);
+ const responseTime = Math.floor(payload?.[0]?.payload?.avgResponseTime || 0);
return (
{formatDateWithTz(label, format, uiTimezone)}
@@ -86,7 +87,10 @@ export const ChartResponseTime = ({
}) => {
const theme = useTheme();
const uiTimezone = useSelector((state: any) => state.ui.timezone);
-
+ const normalized = normalizeResponseTimes(
+ checks,
+ "avgResponseTime"
+ );
return (
}
@@ -96,7 +100,7 @@ export const ChartResponseTime = ({
width="100%"
height={300}
>
-
+
diff --git a/client/src/Components/v2/Monitors/HistogramResponseTime.tsx b/client/src/Components/v2/Monitors/HistogramResponseTime.tsx
index d19ddbf53..1925ac93c 100644
--- a/client/src/Components/v2/Monitors/HistogramResponseTime.tsx
+++ b/client/src/Components/v2/Monitors/HistogramResponseTime.tsx
@@ -3,24 +3,20 @@ import Box from "@mui/material/Box";
import { useTheme } from "@mui/material/styles";
import type { Check } from "@/Types/Check";
import { HistogramResponseTimeTooltip } from "@/Components/v2/Monitors/HistogramResponseTimeTooltip";
+import { normalizeResponseTimes } from "@/Utils/DataUtils";
export const HistogramResponseTime = ({ checks }: { checks: Check[] }) => {
+ const normalChecks = normalizeResponseTimes(checks, "responseTime");
let data = Array();
- data = checks.map((c) => Math.max(c.responseTime, 1));
-
- const logResponses = data.map((r) => Math.log10(r));
- const logMin = Math.min(...logResponses);
- const logMax = Math.max(...logResponses);
-
- if (!checks) {
+ if (!normalChecks || normalChecks.length === 0) {
return null;
}
- if (checks.length !== 25) {
- const placeholders = Array(25 - checks.length).fill("placeholder");
- data = [...checks, ...placeholders];
+ if (normalChecks.length !== 25) {
+ const placeholders = Array(25 - normalChecks.length).fill("placeholder");
+ data = [...normalChecks, ...placeholders];
} else {
- data = checks;
+ data = normalChecks;
}
const theme = useTheme();
@@ -38,14 +34,6 @@ export const HistogramResponseTime = ({ checks }: { checks: Check[] }) => {
}}
>
{data.map((check, index) => {
- const safeResponse = Math.max(check.responseTime, 1);
- const logValue = Math.log10(safeResponse);
- const minHeight = 10;
- const barHeight =
- logMax === logMin
- ? 100
- : Math.max(minHeight, ((logValue - logMin) / (logMax - logMin)) * 100);
-
if (check === "placeholder") {
return (
{
position="absolute"
bottom={0}
width="100%"
- height={`${barHeight}%`}
+ height={`${check.normalResponseTime}%`}
bgcolor={
check.status
? theme.palette.success.lowContrast
diff --git a/client/src/Components/v2/Monitors/HistogramStatus.tsx b/client/src/Components/v2/Monitors/HistogramStatus.tsx
index aeacf31d2..2e10a8042 100644
--- a/client/src/Components/v2/Monitors/HistogramStatus.tsx
+++ b/client/src/Components/v2/Monitors/HistogramStatus.tsx
@@ -9,6 +9,7 @@ import IncidentsIcon from "@/assets/icons/incidents.svg?react";
import type { GroupedCheck } from "@/Types/Check";
import type { MonitorStatus } from "@/Types/Monitor";
+import { normalizeResponseTimes } from "@/Utils/DataUtils";
import { useState } from "react";
import { formatDateWithTz } from "@/Utils/TimeUtils";
import { useSelector } from "react-redux";
@@ -122,8 +123,9 @@ export const HistogramStatus = ({
const theme = useTheme();
const [idx, setIdx] = useState(null);
const dateFormat = range === "1d" || range === "2h" ? "MMM D, h A" : "MMM D";
+ const normalChecks = normalizeResponseTimes(checks, "avgResponseTime");
- if (checks.length === 0) {
+ if (normalChecks.length === 0) {
return (
{
+ const totalChecks = normalChecks.reduce((count, check) => {
return count + check.count;
}, 0);
@@ -161,12 +163,12 @@ export const HistogramStatus = ({
Total checks
{idx ? (
- {checks[idx].count}
+ {normalChecks[idx].count}
- {formatDateWithTz(checks[idx]._id, dateFormat, uiTimezone)}
+ {formatDateWithTz(normalChecks[idx]._id, dateFormat, uiTimezone)}
) : (
@@ -178,26 +180,26 @@ export const HistogramStatus = ({
width="100%"
height={155}
>
-
+
}
/>
- {checks?.map((groupedCheck, idx) => {
- const fillColor = getResponseTimeColor(groupedCheck.avgResponseTime);
+ {normalChecks?.map((groupedCheck, idx) => {
+ const fillColor = getResponseTimeColor(groupedCheck.normalResponseTime);
return (
| setIdx(idx)}
diff --git a/client/src/Pages/v2/Uptime/MonitorTable.tsx b/client/src/Pages/v2/Uptime/MonitorTable.tsx
index a7b1d203f..209784309 100644
--- a/client/src/Pages/v2/Uptime/MonitorTable.tsx
+++ b/client/src/Pages/v2/Uptime/MonitorTable.tsx
@@ -104,7 +104,12 @@ export const MonitorTable = ({
id: "status",
content: t("status"),
render: (row) => {
- return ;
+ return (
+
+ );
},
},
{
diff --git a/client/src/Types/Check.ts b/client/src/Types/Check.ts
index 542507a4b..cccc56f3d 100644
--- a/client/src/Types/Check.ts
+++ b/client/src/Types/Check.ts
@@ -27,6 +27,7 @@ export interface Check {
status: string;
message: string;
responseTime: number;
+ normalResponseTime?: number;
httpStatusCode: number;
ack: boolean;
expiry: string;
diff --git a/client/src/Utils/DataUtils.ts b/client/src/Utils/DataUtils.ts
new file mode 100644
index 000000000..3878d7d6a
--- /dev/null
+++ b/client/src/Utils/DataUtils.ts
@@ -0,0 +1,37 @@
+const MIN_OUT = 10;
+const MAX_OUT = 100;
+
+export const normalizeResponseTimes = , K extends keyof T>(
+ checks: T[],
+ key: K
+): (T & { normalResponseTime: number })[] => {
+ if (!Array.isArray(checks) || checks.length === 0)
+ return checks as (T & {
+ normalResponseTime: number;
+ })[];
+
+ if (checks.length === 1) {
+ return [
+ {
+ ...checks[0],
+ normalResponseTime: 50,
+ },
+ ];
+ }
+
+ const { min, max } = checks.reduce(
+ (acc, check) => {
+ if (check[key] > acc.max) acc.max = check[key];
+ if (check[key] < acc.min) acc.min = check[key];
+ return acc;
+ },
+ { max: -Infinity, min: Infinity }
+ );
+
+ const range = max - min || 1;
+
+ return checks.map((check) => ({
+ ...check,
+ normalResponseTime: MIN_OUT + ((check[key] - min) * (MAX_OUT - MIN_OUT)) / range,
+ }));
+};
|