remove unused

This commit is contained in:
Alex Holliday committed 2026-01-26 02:55:52 +00:00
1 parent 64de01437e
commit 174665e70a
15 files changed
+11 -918

No files matched your search

@@ -84,7 +84,6 @@ export const HistogramDetails = ({
checks: GroupedCheck[];
range: string;
}) => {
console.log(range);
const theme = useTheme();
const uiTimezone = useSelector((state: RootState) => state.ui.timezone);
return (
@@ -75,7 +75,7 @@ export const HistogramStatus = ({
if (!active || !payload?.length) return null;
const d = payload[0]?.payload;
const avg = d?.avgResponseTime ?? 0;
const titleText = t("common.charts.labels.averageRepsonseTime");
const titleText = t("common.charts.labels.averageResponseTime");
const fmt = range === "30d" ? "MMM D, YYYY" : "ddd, MMM D, YYYY, h:mm A";
let dateLabel = "";
if (d?._id) {
@@ -1,160 +0,0 @@
// Components
import { Stack, Typography, Box } from "@mui/material";
import ChartBox from "@/Components/v1/Charts/ChartBox/index.jsx";
import Icon from "@/Components/v1/Icon";
import UpBarChart from "../Charts/UpBarChart.jsx";
import DownBarChart from "../Charts/DownBarChart.jsx";
import ResponseGaugeChart from "../Charts/ResponseGaugeChart.jsx";
import SkeletonLayout from "./skeleton.jsx";
// Utils
import { formatDateWithTz } from "../../../../../Utils/timeUtilsLegacy.js";
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
import { useState } from "react";
const ChartBoxes = ({
isLoading = false,
monitorData,
dateRange,
uiTimezone,
dateFormat,
}) => {
// Local state
const [hoveredUptimeData, setHoveredUptimeData] = useState(null);
const [hoveredIncidentsData, setHoveredIncidentsData] = useState(null);
const theme = useTheme();
if (isLoading) {
return <SkeletonLayout />;
}
const noIncidentsMessage = "Great. No Incidents, yet!";
return (
<Stack
direction="row"
flexWrap="wrap"
gap={theme.spacing(8)}
>
<ChartBox
icon={
<Icon
name="Activity"
size={20}
/>
}
header="Uptime"
isEmpty={monitorData?.groupedUpChecks?.length === 0}
>
<Stack
width={"100%"}
justifyContent="space-between"
direction="row"
>
<Box position="relative">
<Typography>Total Checks</Typography>
<Typography component="span">
{hoveredUptimeData !== null
? hoveredUptimeData.totalChecks
: (monitorData?.groupedUpChecks?.reduce((count, checkGroup) => {
return count + checkGroup.totalChecks;
}, 0) ?? 0)}
</Typography>
{hoveredUptimeData !== null && hoveredUptimeData.time !== null && (
<Typography
component="h5"
position="absolute"
top="100%"
fontSize={11}
color={theme.palette.primary.contrastTextTertiary}
>
{formatDateWithTz(hoveredUptimeData._id, dateFormat, uiTimezone)}
</Typography>
)}
</Box>
<Box>
<Typography>
{hoveredUptimeData !== null ? "Avg Response Time" : "Uptime Percentage"}
</Typography>
<Typography component="span">
{hoveredUptimeData !== null
? Math.floor(hoveredUptimeData?.originalAvgResponseTime ?? 0)
: Math.floor((monitorData?.groupedUptimePercentage ?? 0) * 100)}
<Typography component="span">
{hoveredUptimeData !== null ? " ms" : " %"}
</Typography>
</Typography>
</Box>
</Stack>
<UpBarChart
groupedUpChecks={monitorData?.groupedUpChecks}
type={dateRange}
onBarHover={setHoveredUptimeData}
/>
</ChartBox>
<ChartBox
icon={
<Icon
name="AlertTriangle"
size={20}
/>
}
header="Incidents"
noDataMessage={noIncidentsMessage}
isEmpty={monitorData?.groupedDownChecks?.length === 0}
>
<Stack width={"100%"}>
<Box position="relative">
<Typography component="span">
{hoveredIncidentsData !== null
? hoveredIncidentsData.totalChecks
: (monitorData?.groupedDownChecks?.reduce((count, checkGroup) => {
return count + checkGroup.totalChecks;
}, 0) ?? 0)}
</Typography>
{hoveredIncidentsData !== null && hoveredIncidentsData.time !== null && (
<Typography
component="h5"
position="absolute"
top="100%"
fontSize={11}
color={theme.palette.primary.contrastTextTertiary}
>
{formatDateWithTz(hoveredIncidentsData._id, dateFormat, uiTimezone)}
</Typography>
)}
</Box>
</Stack>
<DownBarChart
groupedDownChecks={monitorData?.groupedDownChecks}
type={dateRange}
onBarHover={setHoveredIncidentsData}
/>
</ChartBox>
<ChartBox
icon={
<Icon
name="BarChart3"
size={20}
/>
}
header="Average Response Time"
>
<ResponseGaugeChart avgResponseTime={monitorData?.groupedAvgResponseTime ?? 0} />
</ChartBox>
</Stack>
);
};
export default ChartBoxes;
ChartBoxes.propTypes = {
isLoading: PropTypes.bool,
monitorData: PropTypes.object,
dateRange: PropTypes.string.isRequired,
uiTimezone: PropTypes.string.isRequired,
dateFormat: PropTypes.string.isRequired,
hoveredUptimeData: PropTypes.object,
setHoveredUptimeData: PropTypes.func,
hoveredIncidentsData: PropTypes.object,
setHoveredIncidentsData: PropTypes.func,
};
@@ -1,30 +0,0 @@
import { Skeleton, Stack } from "@mui/material";
import { useTheme } from "@emotion/react";
const SkeletonLayout = () => {
const theme = useTheme();
return (
<Stack
direction="row"
gap={theme.spacing(8)}
>
<Skeleton
variant="rounded"
width="100%"
height={300}
/>
<Skeleton
variant="rounded"
width="100%"
height={300}
/>
<Skeleton
variant="rounded"
width="100%"
height={300}
/>
</Stack>
);
};
export default SkeletonLayout;
@@ -1,42 +0,0 @@
import PropTypes from "prop-types";
import { useSelector } from "react-redux";
import { formatDateWithTz } from "../../../../../Utils/timeUtilsLegacy.js";
const CustomLabels = ({ x, width, height, firstDataPoint, lastDataPoint, type }) => {
const uiTimezone = useSelector((state) => state.ui.timezone);
const dateFormat = type === "day" ? "MMM D, h:mm A" : "MMM D";
return (
<>
<text
x={x}
y={height}
dy={-3}
textAnchor="start"
fontSize={11}
>
{formatDateWithTz(firstDataPoint._id, dateFormat, uiTimezone)}
</text>
<text
x={width}
y={height}
dy={-3}
textAnchor="end"
fontSize={11}
>
{formatDateWithTz(lastDataPoint._id, dateFormat, uiTimezone)}
</text>
</>
);
};
CustomLabels.propTypes = {
x: PropTypes.number.isRequired,
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
firstDataPoint: PropTypes.object,
lastDataPoint: PropTypes.object,
type: PropTypes.string.isRequired,
};
export default CustomLabels;
@@ -1,90 +0,0 @@
import { memo, useState } from "react";
import { useTheme } from "@mui/material";
import { ResponsiveContainer, BarChart, XAxis, Bar, Cell } from "recharts";
import PropTypes from "prop-types";
import CustomLabels from "./CustomLabels.jsx";
const DownBarChart = memo(({ groupedDownChecks = [], type, onBarHover }) => {
const theme = useTheme();
const [chartHovered, setChartHovered] = useState(false);
const [hoveredBarIndex, setHoveredBarIndex] = useState(null);
return (
<ResponsiveContainer
width="100%"
minWidth={250}
height={155}
>
<BarChart
width="100%"
height="100%"
data={groupedDownChecks}
onMouseEnter={() => {
setChartHovered(true);
onBarHover({ time: null, totalChecks: 0 });
}}
onMouseLeave={() => {
setChartHovered(false);
setHoveredBarIndex(null);
onBarHover(null);
}}
>
<XAxis
stroke={theme.palette.primary.lowContrast}
height={15}
tick={false}
label={
<CustomLabels
x={0}
y={0}
width="100%"
height="100%"
firstDataPoint={groupedDownChecks?.[0] ?? {}}
lastDataPoint={groupedDownChecks?.[groupedDownChecks?.length - 1] ?? {}}
type={type}
/>
}
/>
<Bar
dataKey="avgResponseTime"
maxBarSize={7}
background={{ fill: "transparent" }}
>
{groupedDownChecks?.map((entry, index) => {
return (
<Cell
key={`cell-${entry.time}`}
fill={
hoveredBarIndex === index
? theme.palette.error.main
: chartHovered
? theme.palette.error.light // CAIO_REVIEW
: theme.palette.error.main
}
onMouseEnter={() => {
setHoveredBarIndex(index);
onBarHover(entry);
}}
onMouseLeave={() => {
setHoveredBarIndex(null);
onBarHover({ time: null, totalChecks: 0 });
}}
/>
);
})}
</Bar>
</BarChart>
</ResponsiveContainer>
);
});
DownBarChart.displayName = "DownBarChart";
DownBarChart.propTypes = {
monitor: PropTypes.shape({
groupedDownChecks: PropTypes.arrayOf(PropTypes.object),
}),
type: PropTypes.string,
onBarHover: PropTypes.func,
};
export default DownBarChart;
@@ -1,118 +0,0 @@
import PropTypes from "prop-types";
import { useTheme } from "@mui/material";
import { ResponsiveContainer, RadialBarChart, RadialBar, Cell } from "recharts";
import { useTranslation } from "react-i18next";
const ResponseGaugeChart = ({ avgResponseTime }) => {
const theme = useTheme();
const { t } = useTranslation();
let max = 1000; // max ms
const data = [
{ response: max, fill: "transparent", background: false },
{ response: avgResponseTime, background: true },
];
let responseTime = Math.floor(avgResponseTime);
let responseProps =
responseTime <= 200
? {
category: "Excellent",
main: theme.palette.success.main,
bg: theme.palette.success.lowContrast,
}
: responseTime <= 500
? {
category: "Fair",
main: theme.palette.success.main,
bg: theme.palette.success.lowContrast,
}
: responseTime <= 600
? {
category: "Acceptable",
main: theme.palette.warning.main,
bg: theme.palette.warning.lowContrast,
}
: {
category: "Poor",
main: theme.palette.error.main,
bg: theme.palette.error.lowContrast,
};
return (
<ResponsiveContainer
width="100%"
minWidth={210}
height={155}
>
<RadialBarChart
width="100%"
height="100%"
cy="89%"
data={data}
startAngle={180}
endAngle={0}
innerRadius={100}
outerRadius={150}
>
<text
x={0}
y="100%"
dx="5%"
dy={-2}
textAnchor="start"
fontSize={11}
>
{t("low")}
</text>
<text
x="100%"
y="100%"
dx="-3%"
dy={-2}
textAnchor="end"
fontSize={11}
>
{t("high")}
</text>
<text
x="50%"
y="45%"
textAnchor="middle"
dominantBaseline="middle"
fontSize={18}
fontWeight={400}
>
{responseProps.category}
</text>
<text
x="50%"
y="70%"
textAnchor="middle"
alignmentBaseline="hanging"
fontSize={25}
>
<tspan fontWeight={600}>{responseTime}</tspan> <tspan opacity={0.8}>ms</tspan>
</text>
<RadialBar
background={{ fill: responseProps.bg }}
clockWise
dataKey="response"
stroke="none"
>
<Cell
fill="transparent"
background={false}
barSize={0}
/>
<Cell fill={responseProps.main} />
</RadialBar>
</RadialBarChart>
</ResponsiveContainer>
);
};
ResponseGaugeChart.propTypes = {
avgResponseTime: PropTypes.number.isRequired,
};
export default ResponseGaugeChart;
@@ -1,36 +0,0 @@
import ChartBox from "@/Components/v1/Charts/ChartBox/index.jsx";
import MonitorDetailsAreaChart from "@/Components/v1/Charts/MonitorDetailsAreaChart/index.jsx";
import Icon from "@/Components/v1/Icon";
import SkeletonLayout from "./ResponseTimeChartSkeleton.jsx";
import PropTypes from "prop-types";
const ResponseTImeChart = ({ isLoading = false, groupedChecks = [], dateRange }) => {
if (isLoading) {
return <SkeletonLayout />;
}
return (
<ChartBox
icon={
<Icon
name="TrendingUp"
size={20}
/>
}
header="Response Times"
>
<MonitorDetailsAreaChart
checks={groupedChecks}
dateRange={dateRange}
/>
</ChartBox>
);
};
ResponseTImeChart.propTypes = {
isLoading: PropTypes.bool,
groupedChecks: PropTypes.array,
dateRange: PropTypes.string,
};
export default ResponseTImeChart;
@@ -1,12 +0,0 @@
import { Skeleton } from "@mui/material";
const ResponseTimeChartSkeleton = () => {
return (
<Skeleton
variant="rounded"
width="100%"
height={300}
/>
);
};
export default ResponseTimeChartSkeleton;
@@ -1,107 +0,0 @@
import { memo, useState } from "react";
import { useTheme } from "@mui/material";
import { ResponsiveContainer, BarChart, XAxis, Bar, Cell } from "recharts";
import PropTypes from "prop-types";
import CustomLabels from "./CustomLabels.jsx";
const getThemeColor = (responseTime) => {
if (responseTime < 200) {
return "success";
} else if (responseTime < 300) {
return "warning";
} else {
return "error";
}
};
const UpBarChart = memo(({ groupedUpChecks = [], type, onBarHover }) => {
const theme = useTheme();
const [chartHovered, setChartHovered] = useState(false);
const [hoveredBarIndex, setHoveredBarIndex] = useState(null);
return (
<ResponsiveContainer
width="100%"
minWidth={210}
height={155}
>
<BarChart
width="100%"
height="100%"
data={groupedUpChecks}
onMouseEnter={() => {
setChartHovered(true);
onBarHover({ time: null, totalChecks: 0, originalAvgResponseTime: 0 });
}}
onMouseLeave={() => {
setChartHovered(false);
setHoveredBarIndex(null);
onBarHover(null);
}}
>
<XAxis
stroke={theme.palette.primary.lowContrast}
height={15}
tick={false}
label={
<CustomLabels
x={0}
y={0}
width="100%"
height="100%"
firstDataPoint={groupedUpChecks?.[0]}
lastDataPoint={groupedUpChecks?.[groupedUpChecks?.length - 1]}
type={type}
/>
}
/>
<Bar
dataKey="avgResponseTime"
maxBarSize={7}
background={{ fill: "transparent" }}
>
{groupedUpChecks?.map((entry, index) => {
const themeColor = getThemeColor(entry.originalAvgResponseTime);
return (
<Cell
key={`cell-${entry.time}`}
fill={
hoveredBarIndex === index
? theme.palette[themeColor].main
: chartHovered
? theme.palette[themeColor].light
: theme.palette[themeColor].main
}
onMouseEnter={() => {
setHoveredBarIndex(index);
onBarHover(entry);
}}
onMouseLeave={() => {
setHoveredBarIndex(null);
onBarHover({
time: null,
totalChecks: 0,
groupUptimePercentage: 0,
});
}}
/>
);
})}
</Bar>
</BarChart>
</ResponsiveContainer>
);
});
// Add display name for the component
UpBarChart.displayName = "UpBarChart";
// Validate props using PropTypes
UpBarChart.propTypes = {
monitor: PropTypes.shape({
groupedUpChecks: PropTypes.array,
}),
type: PropTypes.string,
onBarHover: PropTypes.func,
};
export default UpBarChart;
@@ -20,7 +20,7 @@ const getHeaders = (t: Function, uiTimezone: string) => {
},
{
id: "date",
content: t("checks.table.headers.dateTime"),
content: t("pages.checks.table.headers.dateTime"),
render: (row) => {
return formatDateWithTz(row.createdAt, "ddd, MMMM D, YYYY, HH:mm A", uiTimezone);
},
@@ -34,7 +34,7 @@ const getHeaders = (t: Function, uiTimezone: string) => {
},
{
id: "statusCode",
content: t("checks.table.headers.statusCode"),
content: t("pages.checks.table.headers.statusCode"),
render: (row) => {
return row.statusCode || "N/A";
},
@@ -1,222 +0,0 @@
import ChartBox from "@/Components/v1/Charts/ChartBox/index.jsx";
import PropTypes from "prop-types";
import Icon from "@/Components/v1/Icon";
import Table from "@/Components/v1/Table/index.jsx";
import TablePagination from "@/Components/v1/Table/TablePagination/index.jsx";
import { StatusLabel } from "@/Components/v1/Label/index.jsx";
import { useTranslation } from "react-i18next";
import { formatDateWithTz } from "../../../../../Utils/timeUtilsLegacy.js";
import SkeletonLayout from "./skeleton.jsx";
import Tooltip from "@mui/material/Tooltip";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import Stack from "@mui/material/Stack";
import { lighten, useTheme } from "@mui/material";
/**
* Creates tooltip content with detailed timing breakdown
* Following the pattern from IncidentTable's GetTooltip function
* @param {Object} timings - Timing object (guaranteed to have phases by caller)
* @param {Object} theme - MUI theme object
* @param {Function} t - Translation function
* @returns {JSX.Element} Tooltip content
*/
const GetTooltip = (timings, theme, t) => {
const phases = timings.phases;
const timingDetails = [
{ label: t("dnsLookup"), value: phases.dns },
{ label: t("tcpConnection"), value: phases.tcp },
{ label: t("tlsHandshake"), value: phases.tls },
{ label: t("waitTime"), value: phases.wait },
{ label: t("timeToFirstByte"), value: phases.firstByte },
{ label: t("download"), value: phases.download },
{ label: t("total"), value: phases.total },
].filter((item) => item.value > 0);
return (
<Stack
sx={{
py: theme.spacing(2),
px: theme.spacing(4),
}}
>
<Typography
variant="body2"
sx={{
fontWeight: 600,
marginBottom: theme.spacing(1),
color: theme.palette.primary.contrastText,
}}
>
{t("responseTimeBreakdown")}
</Typography>
{timingDetails.map((detail, index, array) => (
<Box
key={index}
sx={{
display: "flex",
justifyContent: "space-between",
gap: theme.spacing(4),
marginBottom: index < array.length - 1 ? theme.spacing(0.5) : 0,
}}
>
<Typography
variant="body2"
sx={{ color: theme.palette.primary.contrastText }}
>
{detail.label}:
</Typography>
<Typography
variant="body2"
sx={{
fontWeight: index === array.length - 1 ? 600 : 400,
color: theme.palette.primary.contrastText,
}}
>
{Math.round(detail.value)} ms
</Typography>
</Box>
))}
</Stack>
);
};
const ResponseTable = ({
isLoading = false,
checks = [],
checksCount,
uiTimezone,
page,
setPage,
rowsPerPage,
setRowsPerPage,
}) => {
const { t } = useTranslation();
const theme = useTheme();
if (isLoading) {
return <SkeletonLayout />;
}
const headers = [
{
id: "status",
content: t("status"),
render: (row) => {
const status = row.status === true ? "up" : "down";
return (
<StatusLabel
status={status}
text={status}
customStyles={{ textTransform: "capitalize" }}
/>
);
},
},
{
id: "date",
content: t("date&Time"),
render: (row) =>
formatDateWithTz(row.createdAt, "ddd, MMMM D, YYYY, HH:mm A", uiTimezone),
},
{
id: "statusCode",
content: t("statusCode"),
render: (row) => (row.statusCode ? row.statusCode : "N/A"),
},
{
id: "message",
content: t("message"),
render: (row) => row.message,
},
{
id: "responseTime",
content: t("responseTime"),
render: (row) => {
const hasTimings = row.timings && row.timings.phases;
const responseTime = row.responseTime;
const responseTimeDisplay =
responseTime !== null && responseTime !== undefined
? `${Math.round(responseTime)} ms`
: "N/A";
if (!hasTimings) {
return responseTimeDisplay;
}
return (
<Tooltip
title={GetTooltip(row.timings, theme, t)}
placement="top"
arrow
enterDelay={300}
enterNextDelay={300}
slotProps={{
tooltip: {
sx: {
backgroundColor: lighten(theme.palette.primary.main, 0.1),
border: `1px solid ${theme.palette.primary.lowContrast}`,
borderRadius: theme.shape.borderRadius,
"& .MuiTooltip-arrow": {
color: lighten(theme.palette.primary.main, 0.1),
"&::before": {
border: `1px solid ${theme.palette.primary.lowContrast}`,
},
},
},
},
}}
>
<Box
sx={{
cursor: "help",
display: "inline-block",
}}
>
{responseTimeDisplay}
</Box>
</Tooltip>
);
},
},
];
return (
<ChartBox
icon={
<Icon
name="History"
size={20}
/>
}
header="Response Times"
height="100%"
>
<Table
headers={headers}
data={checks}
/>
<TablePagination
page={page}
handleChangePage={setPage}
rowsPerPage={rowsPerPage}
handleChangeRowsPerPage={setRowsPerPage}
itemCount={checksCount}
/>
</ChartBox>
);
};
ResponseTable.propTypes = {
isLoading: PropTypes.bool,
checks: PropTypes.array,
checksCount: PropTypes.number,
uiTimezone: PropTypes.string.isRequired,
page: PropTypes.number.isRequired,
setPage: PropTypes.func.isRequired,
rowsPerPage: PropTypes.number.isRequired,
setRowsPerPage: PropTypes.func.isRequired,
};
export default ResponseTable;
@@ -1,13 +0,0 @@
import { Skeleton } from "@mui/material";
const SkeletonLayout = () => {
return (
<Skeleton
variant="rounded"
width="100%"
height={300}
/>
);
};
export default SkeletonLayout;
@@ -1,84 +0,0 @@
import StatusBoxes from "@/Components/v1/StatusBoxes/index.jsx";
import StatBox from "@/Components/v1/StatBox/index.jsx";
import PropTypes from "prop-types";
import { getHumanReadableDuration } from "../../../../../Utils/timeUtilsLegacy.js";
import { useTheme } from "@mui/material/styles";
import { Typography } from "@mui/material";
import { useMonitorUtils } from "../../../../../Hooks/useMonitorUtils.js";
const UptimeStatusBoxes = ({
isLoading = false,
monitor,
monitorStats,
certificateExpiry,
}) => {
const theme = useTheme();
const { determineState } = useMonitorUtils();
// Determine time since last failure
const timeOfLastFailure = monitorStats?.timeOfLastFailure;
const timeSinceLastFailure =
timeOfLastFailure > 0
? Date.now() - timeOfLastFailure
: Date.now() - new Date(monitorStats?.createdAt);
// Determine time since last check
const timeOfLastCheck = monitorStats?.lastCheckTimestamp;
const timeSinceLastCheck = Date.now() - timeOfLastCheck;
const streakTime = getHumanReadableDuration(timeSinceLastFailure);
const lastCheckTime = getHumanReadableDuration(timeSinceLastCheck);
return (
<StatusBoxes shouldRender={!isLoading}>
<StatBox
gradient={true}
status={determineState(monitor)}
heading={"active for"}
subHeading={streakTime}
/>
<StatBox
heading="last check"
subHeading={
<>
{lastCheckTime}
<Typography component="span">{"ago"}</Typography>
</>
}
/>
<StatBox
heading="last response time"
subHeading={
<>
{monitorStats?.lastResponseTime}
<Typography component="span">{"ms"}</Typography>
</>
}
/>
{monitor?.type === "http" && (
<StatBox
heading="certificate expiry"
subHeading={
<Typography
component="span"
fontSize={13}
color={theme.palette.primary.contrastText}
>
{certificateExpiry}
</Typography>
}
/>
)}
</StatusBoxes>
);
};
UptimeStatusBoxes.propTypes = {
isLoading: PropTypes.bool,
monitor: PropTypes.object,
monitorStats: PropTypes.object,
certificateExpiry: PropTypes.string,
};
export default UptimeStatusBoxes;
+8
View File
@@ -208,6 +208,14 @@
"placeholder": "Search monitors..."
}
}
},
"checks": {
"table": {
"headers": {
"dateTime": "Date & time",
"statusCode": "Status code"
}
}
}
},
"distributedUptimeStatusCreateStatusPage": "status page",