update details page to use new queries
This commit is contained in:
1 parent
9ac563bf8c
commit
3d71e7759b
11 files changed
+131
-81
No files matched your search
@@ -8,10 +8,10 @@ import ConfigButton from "./ConfigButton";
|
||||
import SkeletonLayout from "./skeleton";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const MonitorStatusHeader = ({ path, shouldRender = true, isAdmin, monitor }) => {
|
||||
const MonitorStatusHeader = ({ path, isLoading = false, isAdmin, monitor }) => {
|
||||
const theme = useTheme();
|
||||
const { statusColor, statusMsg, determineState } = useUtils();
|
||||
if (!shouldRender) {
|
||||
const { statusColor, determineState } = useUtils();
|
||||
if (isLoading) {
|
||||
return <SkeletonLayout />;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ const MonitorStatusHeader = ({ path, shouldRender = true, isAdmin, monitor }) =>
|
||||
|
||||
MonitorStatusHeader.propTypes = {
|
||||
path: PropTypes.string.isRequired,
|
||||
shouldRender: PropTypes.bool,
|
||||
isLoading: PropTypes.bool,
|
||||
isAdmin: PropTypes.bool,
|
||||
monitor: PropTypes.object,
|
||||
};
|
||||
|
||||
@@ -4,14 +4,14 @@ import SkeletonLayout from "./skeleton";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const MonitorTimeFrameHeader = ({
|
||||
shouldRender = true,
|
||||
isLoading = false,
|
||||
hasDateRange = true,
|
||||
dateRange,
|
||||
setDateRange,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
if (!shouldRender) {
|
||||
if (isLoading) {
|
||||
return <SkeletonLayout />;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ const MonitorTimeFrameHeader = ({
|
||||
};
|
||||
|
||||
MonitorTimeFrameHeader.propTypes = {
|
||||
shouldRender: PropTypes.bool,
|
||||
isLoading: PropTypes.bool,
|
||||
hasDateRange: PropTypes.bool,
|
||||
dateRange: PropTypes.string,
|
||||
setDateRange: PropTypes.func,
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { networkService } from "../main";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { createToast } from "../Utils/toastUtils";
|
||||
|
||||
export const useFetchUptimeMonitorDetails = ({ monitorId, dateRange }) => {
|
||||
const [networkError, setNetworkError] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [monitor, setMonitor] = useState(undefined);
|
||||
const [monitorStats, setMonitorStats] = useState(undefined);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchMonitors = async () => {
|
||||
try {
|
||||
const res = await networkService.getUptimeDetailsById({
|
||||
monitorId: monitorId,
|
||||
dateRange: dateRange,
|
||||
normalize: true,
|
||||
});
|
||||
const { monitorData, monitorStats } = res?.data?.data ?? {};
|
||||
setMonitor(monitorData);
|
||||
setMonitorStats(monitorStats);
|
||||
} catch (error) {
|
||||
setNetworkError(true);
|
||||
createToast({ body: error.message });
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
fetchMonitors();
|
||||
}, [dateRange, monitorId, navigate]);
|
||||
return [monitor, monitorStats, isLoading, networkError];
|
||||
};
|
||||
|
||||
export default useFetchUptimeMonitorDetails;
|
||||
@@ -27,7 +27,7 @@ const StatusPagesTable = ({ data }) => {
|
||||
row.type === "distributed"
|
||||
? `/status/distributed/public/${row.url}`
|
||||
: `/status/uptime/public/${row.url}`;
|
||||
window.open(url, "_blank", "noopener,noreferrer")
|
||||
window.open(url, "_blank", "noopener,noreferrer");
|
||||
}
|
||||
},
|
||||
render: (row) => {
|
||||
|
||||
@@ -12,29 +12,23 @@ import SkeletonLayout from "./skeleton";
|
||||
import { formatDateWithTz } from "../../../../../Utils/timeUtils";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useState } from "react";
|
||||
|
||||
const ChartBoxes = ({
|
||||
shouldRender = true,
|
||||
monitor,
|
||||
isLoading = false,
|
||||
monitorData,
|
||||
dateRange,
|
||||
uiTimezone,
|
||||
dateFormat,
|
||||
hoveredUptimeData,
|
||||
setHoveredUptimeData,
|
||||
hoveredIncidentsData,
|
||||
setHoveredIncidentsData,
|
||||
}) => {
|
||||
// Local state
|
||||
const [hoveredUptimeData, setHoveredUptimeData] = useState(null);
|
||||
const [hoveredIncidentsData, setHoveredIncidentsData] = useState(null);
|
||||
const theme = useTheme();
|
||||
|
||||
if (!shouldRender) {
|
||||
if (isLoading) {
|
||||
return <SkeletonLayout />;
|
||||
}
|
||||
|
||||
const totalUpChecks = monitor?.upChecks?.totalChecks ?? 0;
|
||||
const totalDownChecks = monitor?.downChecks?.totalChecks ?? 0;
|
||||
const denominator =
|
||||
totalUpChecks + totalDownChecks > 0 ? totalUpChecks + totalDownChecks : 1;
|
||||
const groupedUptimePercentage = (totalUpChecks / denominator) * 100;
|
||||
const noIncidentsMessage = "Great. No Incidents, yet!";
|
||||
|
||||
return (
|
||||
@@ -46,7 +40,7 @@ const ChartBoxes = ({
|
||||
<ChartBox
|
||||
icon={<UptimeIcon />}
|
||||
header="Uptime"
|
||||
isEmpty={monitor?.uptimePercentage === 0 && !monitor?.upChecks?.length}
|
||||
isEmpty={false} // TODO
|
||||
>
|
||||
<Stack
|
||||
width={"100%"}
|
||||
@@ -58,7 +52,7 @@ const ChartBoxes = ({
|
||||
<Typography component="span">
|
||||
{hoveredUptimeData !== null
|
||||
? hoveredUptimeData.totalChecks
|
||||
: (monitor?.groupedUpChecks?.reduce((count, checkGroup) => {
|
||||
: (monitorData?.groupedUpChecks?.reduce((count, checkGroup) => {
|
||||
return count + checkGroup.totalChecks;
|
||||
}, 0) ?? 0)}
|
||||
</Typography>
|
||||
@@ -81,7 +75,7 @@ const ChartBoxes = ({
|
||||
<Typography component="span">
|
||||
{hoveredUptimeData !== null
|
||||
? Math.floor(hoveredUptimeData?.avgResponseTime ?? 0)
|
||||
: Math.floor(groupedUptimePercentage)}
|
||||
: Math.floor(monitorData?.groupedUptimePercentage * 100 ?? 0)}
|
||||
<Typography component="span">
|
||||
{hoveredUptimeData !== null ? " ms" : " %"}
|
||||
</Typography>
|
||||
@@ -89,7 +83,7 @@ const ChartBoxes = ({
|
||||
</Box>
|
||||
</Stack>
|
||||
<UpBarChart
|
||||
monitor={monitor}
|
||||
groupedUpChecks={monitorData?.groupedUpChecks}
|
||||
type={dateRange}
|
||||
onBarHover={setHoveredUptimeData}
|
||||
/>
|
||||
@@ -98,14 +92,14 @@ const ChartBoxes = ({
|
||||
icon={<IncidentsIcon />}
|
||||
header="Incidents"
|
||||
noDataMessage={noIncidentsMessage}
|
||||
isEmpty={monitor?.groupedDownChecks?.length === 0}
|
||||
isEmpty={monitorData?.groupedDownChecks?.length === 0}
|
||||
>
|
||||
<Stack width={"100%"}>
|
||||
<Box position="relative">
|
||||
<Typography component="span">
|
||||
{hoveredIncidentsData !== null
|
||||
? hoveredIncidentsData.totalChecks
|
||||
: (monitor?.groupedDownChecks?.reduce((count, checkGroup) => {
|
||||
: (monitorData?.groupedDownChecks?.reduce((count, checkGroup) => {
|
||||
return count + checkGroup.totalChecks;
|
||||
}, 0) ?? 0)}
|
||||
</Typography>
|
||||
@@ -123,7 +117,7 @@ const ChartBoxes = ({
|
||||
</Box>
|
||||
</Stack>
|
||||
<DownBarChart
|
||||
monitor={monitor}
|
||||
groupedDownChecks={monitorData?.groupedDownChecks}
|
||||
type={dateRange}
|
||||
onBarHover={setHoveredIncidentsData}
|
||||
/>
|
||||
@@ -132,7 +126,7 @@ const ChartBoxes = ({
|
||||
icon={<AverageResponseIcon />}
|
||||
header="Average Response Time"
|
||||
>
|
||||
<ResponseGaugeChart avgResponseTime={monitor?.avgResponseTime ?? 0} />
|
||||
<ResponseGaugeChart avgResponseTime={monitorData?.groupedAvgResponseTime ?? 0} />
|
||||
</ChartBox>
|
||||
</Stack>
|
||||
);
|
||||
@@ -141,8 +135,8 @@ const ChartBoxes = ({
|
||||
export default ChartBoxes;
|
||||
|
||||
ChartBoxes.propTypes = {
|
||||
shouldRender: PropTypes.bool,
|
||||
monitor: PropTypes.object,
|
||||
isLoading: PropTypes.bool,
|
||||
monitorData: PropTypes.object,
|
||||
dateRange: PropTypes.string.isRequired,
|
||||
uiTimezone: PropTypes.string.isRequired,
|
||||
dateFormat: PropTypes.string.isRequired,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ResponsiveContainer, BarChart, XAxis, Bar, Cell } from "recharts";
|
||||
import PropTypes from "prop-types";
|
||||
import CustomLabels from "./CustomLabels";
|
||||
|
||||
const DownBarChart = memo(({ monitor, type, onBarHover }) => {
|
||||
const DownBarChart = memo(({ groupedDownChecks = [], type, onBarHover }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const [chartHovered, setChartHovered] = useState(false);
|
||||
@@ -19,7 +19,7 @@ const DownBarChart = memo(({ monitor, type, onBarHover }) => {
|
||||
<BarChart
|
||||
width="100%"
|
||||
height="100%"
|
||||
data={monitor?.groupedDownChecks}
|
||||
data={groupedDownChecks}
|
||||
onMouseEnter={() => {
|
||||
setChartHovered(true);
|
||||
onBarHover({ time: null, totalChecks: 0 });
|
||||
@@ -40,10 +40,8 @@ const DownBarChart = memo(({ monitor, type, onBarHover }) => {
|
||||
y={0}
|
||||
width="100%"
|
||||
height="100%"
|
||||
firstDataPoint={monitor?.groupedDownChecks?.[0] ?? {}}
|
||||
lastDataPoint={
|
||||
monitor?.groupedDownChecks?.[monitor?.groupedDownChecks?.length - 1] ?? {}
|
||||
}
|
||||
firstDataPoint={groupedDownChecks?.[0] ?? {}}
|
||||
lastDataPoint={groupedDownChecks?.[groupedDownChecks?.length - 1] ?? {}}
|
||||
type={type}
|
||||
/>
|
||||
}
|
||||
@@ -53,7 +51,7 @@ const DownBarChart = memo(({ monitor, type, onBarHover }) => {
|
||||
maxBarSize={7}
|
||||
background={{ fill: "transparent" }}
|
||||
>
|
||||
{monitor?.groupedDownChecks?.map((entry, index) => {
|
||||
{groupedDownChecks?.map((entry, index) => {
|
||||
return (
|
||||
<Cell
|
||||
key={`cell-${entry.time}`}
|
||||
|
||||
@@ -4,8 +4,8 @@ import ResponseTimeIcon from "../../../../../assets/icons/response-time-icon.svg
|
||||
import SkeletonLayout from "./ResponseTimeChartSkeleton";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const ResponseTImeChart = ({ shouldRender = true, monitor, dateRange }) => {
|
||||
if (!shouldRender) {
|
||||
const ResponseTImeChart = ({ isLoading = false, groupedChecks = [], dateRange }) => {
|
||||
if (isLoading) {
|
||||
return <SkeletonLayout />;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ const ResponseTImeChart = ({ shouldRender = true, monitor, dateRange }) => {
|
||||
header="Response Times"
|
||||
>
|
||||
<MonitorDetailsAreaChart
|
||||
checks={monitor?.groupedChecks ?? []}
|
||||
checks={groupedChecks}
|
||||
dateRange={dateRange}
|
||||
/>
|
||||
</ChartBox>
|
||||
@@ -23,8 +23,8 @@ const ResponseTImeChart = ({ shouldRender = true, monitor, dateRange }) => {
|
||||
};
|
||||
|
||||
ResponseTImeChart.propTypes = {
|
||||
shouldRender: PropTypes.bool,
|
||||
monitor: PropTypes.object,
|
||||
isLoading: PropTypes.bool,
|
||||
groupedChecks: PropTypes.array,
|
||||
dateRange: PropTypes.string,
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ const getThemeColor = (responseTime) => {
|
||||
}
|
||||
};
|
||||
|
||||
const UpBarChart = memo(({ monitor, type, onBarHover }) => {
|
||||
const UpBarChart = memo(({ groupedUpChecks = [], type, onBarHover }) => {
|
||||
const theme = useTheme();
|
||||
const [chartHovered, setChartHovered] = useState(false);
|
||||
const [hoveredBarIndex, setHoveredBarIndex] = useState(null);
|
||||
@@ -28,7 +28,7 @@ const UpBarChart = memo(({ monitor, type, onBarHover }) => {
|
||||
<BarChart
|
||||
width="100%"
|
||||
height="100%"
|
||||
data={monitor?.groupedUpChecks}
|
||||
data={groupedUpChecks}
|
||||
onMouseEnter={() => {
|
||||
setChartHovered(true);
|
||||
onBarHover({ time: null, totalChecks: 0, avgResponseTime: 0 });
|
||||
@@ -49,10 +49,8 @@ const UpBarChart = memo(({ monitor, type, onBarHover }) => {
|
||||
y={0}
|
||||
width="100%"
|
||||
height="100%"
|
||||
firstDataPoint={monitor?.groupedUpChecks?.[0]}
|
||||
lastDataPoint={
|
||||
monitor?.groupedUpChecks?.[monitor?.groupedUpChecks?.length - 1]
|
||||
}
|
||||
firstDataPoint={groupedUpChecks?.[0]}
|
||||
lastDataPoint={groupedUpChecks?.[groupedUpChecks?.length - 1]}
|
||||
type={type}
|
||||
/>
|
||||
}
|
||||
@@ -62,7 +60,7 @@ const UpBarChart = memo(({ monitor, type, onBarHover }) => {
|
||||
maxBarSize={7}
|
||||
background={{ fill: "transparent" }}
|
||||
>
|
||||
{monitor?.groupedUpChecks?.map((entry, index) => {
|
||||
{groupedUpChecks?.map((entry, index) => {
|
||||
const themeColor = getThemeColor(entry.avgResponseTime);
|
||||
return (
|
||||
<Cell
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { formatDateWithTz } from "../../../../../Utils/timeUtils";
|
||||
import SkeletonLayout from "./skeleton";
|
||||
const ResponseTable = ({
|
||||
shouldRender = true,
|
||||
isLoading = false,
|
||||
checks = [],
|
||||
checksCount,
|
||||
uiTimezone,
|
||||
@@ -17,8 +17,12 @@ const ResponseTable = ({
|
||||
rowsPerPage,
|
||||
setRowsPerPage,
|
||||
}) => {
|
||||
<<<<<<< Updated upstream
|
||||
const { t } = useTranslation();
|
||||
if (!shouldRender) {
|
||||
=======
|
||||
if (isLoading) {
|
||||
>>>>>>> Stashed changes
|
||||
return <SkeletonLayout />;
|
||||
}
|
||||
|
||||
@@ -78,7 +82,7 @@ const ResponseTable = ({
|
||||
};
|
||||
|
||||
ResponseTable.propTypes = {
|
||||
shouldRender: PropTypes.bool,
|
||||
isLoading: PropTypes.bool,
|
||||
checks: PropTypes.array,
|
||||
checksCount: PropTypes.number,
|
||||
uiTimezone: PropTypes.string.isRequired,
|
||||
|
||||
@@ -1,23 +1,36 @@
|
||||
import StatusBoxes from "../../../../../Components/StatusBoxes";
|
||||
import StatBox from "../../../../../Components/StatBox";
|
||||
|
||||
import PropTypes from "prop-types";
|
||||
import { getHumanReadableDuration } from "../../../../../Utils/timeUtils";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { Typography } from "@mui/material";
|
||||
import useUtils from "../../../Monitors/Hooks/useUtils";
|
||||
|
||||
const UptimeStatusBoxes = ({ shouldRender, monitor, certificateExpiry }) => {
|
||||
const UptimeStatusBoxes = ({
|
||||
isLoading = false,
|
||||
monitor,
|
||||
monitorStats,
|
||||
certificateExpiry,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const { determineState } = useUtils();
|
||||
|
||||
const { time: streakTime, units: streakUnits } = getHumanReadableDuration(
|
||||
monitor?.uptimeStreak
|
||||
);
|
||||
// Determine time since last failure
|
||||
const timeOfLastFailure = monitorStats?.timeOfLastFailure;
|
||||
const timeSinceLastFailure = timeOfLastFailure > 0 ? Date.now() - timeOfLastFailure : 0;
|
||||
|
||||
const { time: lastCheckTime, units: lastCheckUnits } = getHumanReadableDuration(
|
||||
monitor?.timeSinceLastCheck
|
||||
);
|
||||
// Determine time since last check
|
||||
const timeOfLastCheck = monitorStats?.lastCheckTimestamp;
|
||||
const timeSinceLastCheck = Date.now() - timeOfLastCheck;
|
||||
|
||||
const { time: streakTime, units: streakUnits } =
|
||||
getHumanReadableDuration(timeSinceLastFailure);
|
||||
|
||||
const { time: lastCheckTime, units: lastCheckUnits } =
|
||||
getHumanReadableDuration(timeSinceLastCheck);
|
||||
return (
|
||||
<StatusBoxes shouldRender={shouldRender}>
|
||||
<StatusBoxes shouldRender={!isLoading}>
|
||||
<StatBox
|
||||
gradient={true}
|
||||
status={determineState(monitor)}
|
||||
@@ -43,7 +56,7 @@ const UptimeStatusBoxes = ({ shouldRender, monitor, certificateExpiry }) => {
|
||||
heading="last response time"
|
||||
subHeading={
|
||||
<>
|
||||
{monitor?.latestResponseTime}
|
||||
{monitorStats?.lastResponseTime}
|
||||
<Typography component="span">{"ms"}</Typography>
|
||||
</>
|
||||
}
|
||||
@@ -64,4 +77,11 @@ const UptimeStatusBoxes = ({ shouldRender, monitor, certificateExpiry }) => {
|
||||
);
|
||||
};
|
||||
|
||||
UptimeStatusBoxes.propTypes = {
|
||||
shouldRender: PropTypes.bool,
|
||||
monitor: PropTypes.object,
|
||||
monitorStats: PropTypes.object,
|
||||
certificateExpiry: PropTypes.string,
|
||||
};
|
||||
|
||||
export default UptimeStatusBoxes;
|
||||
@@ -16,7 +16,7 @@ import { useParams } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
import useMonitorFetch from "./Hooks/useMonitorFetch";
|
||||
import useFetchUptimeMonitorDetails from "../../../Hooks/useFetchUptimeMonitorDetails";
|
||||
import useCertificateFetch from "./Hooks/useCertificateFetch";
|
||||
import useChecksFetch from "./Hooks/useChecksFetch";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -36,8 +36,7 @@ const UptimeDetails = () => {
|
||||
|
||||
// Local state
|
||||
const [dateRange, setDateRange] = useState("recent");
|
||||
const [hoveredUptimeData, setHoveredUptimeData] = useState(null);
|
||||
const [hoveredIncidentsData, setHoveredIncidentsData] = useState(null);
|
||||
|
||||
const [page, setPage] = useState(0);
|
||||
const [rowsPerPage, setRowsPerPage] = useState(5);
|
||||
|
||||
@@ -49,10 +48,13 @@ const UptimeDetails = () => {
|
||||
const isAdmin = useIsAdmin();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [monitor, monitorIsLoading, monitorNetworkError] = useMonitorFetch({
|
||||
monitorId,
|
||||
dateRange,
|
||||
});
|
||||
const [monitorData, monitorStats, monitorIsLoading, monitorNetworkError] =
|
||||
useFetchUptimeMonitorDetails({
|
||||
monitorId,
|
||||
dateRange,
|
||||
});
|
||||
|
||||
const monitor = monitorData?.monitor;
|
||||
|
||||
const [certificateExpiry, certificateIsLoading] = useCertificateFetch({
|
||||
monitor,
|
||||
@@ -62,7 +64,6 @@ const UptimeDetails = () => {
|
||||
});
|
||||
|
||||
const monitorType = monitor?.type;
|
||||
|
||||
const [checks, checksCount, checksAreLoading, checksNetworkError] = useChecksFetch({
|
||||
monitorId,
|
||||
monitorType,
|
||||
@@ -71,6 +72,8 @@ const UptimeDetails = () => {
|
||||
rowsPerPage,
|
||||
});
|
||||
|
||||
console.log("render");
|
||||
|
||||
// Handlers
|
||||
const handlePageChange = (_, newPage) => {
|
||||
setPage(newPage);
|
||||
@@ -119,38 +122,35 @@ const UptimeDetails = () => {
|
||||
<MonitorStatusHeader
|
||||
path={"uptime"}
|
||||
isAdmin={isAdmin}
|
||||
shouldRender={!monitorIsLoading}
|
||||
isLoading={monitorIsLoading}
|
||||
monitor={monitor}
|
||||
/>
|
||||
<UptimeStatusBoxes
|
||||
shouldRender={!monitorIsLoading}
|
||||
isLoading={monitorIsLoading}
|
||||
monitor={monitor}
|
||||
monitorStats={monitorStats}
|
||||
certificateExpiry={certificateExpiry}
|
||||
/>
|
||||
<MonitorTimeFrameHeader
|
||||
shouldRender={!monitorIsLoading}
|
||||
isLoading={monitorIsLoading}
|
||||
hasDateRange={true}
|
||||
dateRange={dateRange}
|
||||
setDateRange={setDateRange}
|
||||
/>
|
||||
<ChartBoxes
|
||||
shouldRender={!monitorIsLoading}
|
||||
monitor={monitor}
|
||||
isLoading={monitorIsLoading}
|
||||
monitorData={monitorData}
|
||||
uiTimezone={uiTimezone}
|
||||
dateRange={dateRange}
|
||||
dateFormat={dateFormat}
|
||||
hoveredUptimeData={hoveredUptimeData}
|
||||
setHoveredUptimeData={setHoveredUptimeData}
|
||||
hoveredIncidentsData={hoveredIncidentsData}
|
||||
setHoveredIncidentsData={setHoveredIncidentsData}
|
||||
/>
|
||||
<ResponseTimeChart
|
||||
shouldRender={!monitorIsLoading}
|
||||
monitor={monitor}
|
||||
isLoading={monitorIsLoading}
|
||||
groupedChecks={monitorData?.groupedChecks}
|
||||
dateRange={dateRange}
|
||||
/>
|
||||
<ResponseTable
|
||||
shouldRender={!checksAreLoading}
|
||||
isLoading={checksAreLoading}
|
||||
checks={checks}
|
||||
uiTimezone={uiTimezone}
|
||||
page={page}
|
||||
|
||||
Reference in new issue
Block a user