Merge branch 'develop' into fix/fe/uptime-details-empty-views

This commit is contained in:
Alex Holliday committed 2025-01-31 10:12:08 -08:00
commit d7905e1246
10 files changed
+83 -38

No files matched your search

@@ -3,7 +3,7 @@ import { useTheme } from "@emotion/react";
import { useNavigate } from "react-router-dom";
import SettingsIcon from "../../../assets/icons/settings-bold.svg?react";
import PropTypes from "prop-types";
const ConfigButton = ({ shouldRender, monitorId }) => {
const ConfigButton = ({ shouldRender = true, monitorId, path }) => {
const theme = useTheme();
const navigate = useNavigate();
@@ -14,7 +14,7 @@ const ConfigButton = ({ shouldRender, monitorId }) => {
<Button
variant="contained"
color="secondary"
onClick={() => navigate(`/uptime/configure/${monitorId}`)}
onClick={() => navigate(`/${path}/configure/${monitorId}`)}
sx={{
px: theme.spacing(5),
"& svg": {
@@ -34,7 +34,8 @@ const ConfigButton = ({ shouldRender, monitorId }) => {
ConfigButton.propTypes = {
shouldRender: PropTypes.bool,
monitorId: PropTypes.string,
monitorId: PropTypes.string.isRequired,
path: PropTypes.string.isRequired,
};
export default ConfigButton;
@@ -8,7 +8,7 @@ import ConfigButton from "./ConfigButton";
import SkeletonLayout from "./skeleton";
import PropTypes from "prop-types";
const MonitorStatusHeader = ({ shouldRender = true, isAdmin, monitor }) => {
const MonitorStatusHeader = ({ path, shouldRender = true, isAdmin, monitor }) => {
const theme = useTheme();
const { statusColor, statusMsg, determineState } = useUtils();
if (!shouldRender) {
@@ -38,6 +38,7 @@ const MonitorStatusHeader = ({ shouldRender = true, isAdmin, monitor }) => {
</Stack>
</Stack>
<ConfigButton
path={path}
shouldRender={isAdmin}
monitorId={monitor?._id}
/>
@@ -46,6 +47,7 @@ const MonitorStatusHeader = ({ shouldRender = true, isAdmin, monitor }) => {
};
MonitorStatusHeader.propTypes = {
path: PropTypes.string.isRequired,
shouldRender: PropTypes.bool,
isAdmin: PropTypes.bool,
monitor: PropTypes.object,
@@ -3,25 +3,22 @@ import { useTheme } from "@emotion/react";
import SkeletonLayout from "./skeleton";
import PropTypes from "prop-types";
const TimeFramePicker = ({ shouldRender = true, dateRange, setDateRange }) => {
const MonitorTimeFrameHeader = ({
shouldRender = true,
hasDateRange = true,
dateRange,
setDateRange,
}) => {
const theme = useTheme();
if (!shouldRender) {
return <SkeletonLayout />;
}
return (
<Stack
direction="row"
justifyContent="space-between"
alignItems="flex-end"
gap={theme.spacing(4)}
mb={theme.spacing(8)}
>
<Typography variant="body2">
Showing statistics for past{" "}
{dateRange === "day" ? "24 hours" : dateRange === "week" ? "7 days" : "30 days"}.
</Typography>
let timeFramePicker = null;
if (hasDateRange) {
timeFramePicker = (
<ButtonGroup sx={{ height: 32 }}>
<Button
variant="group"
@@ -45,14 +42,31 @@ const TimeFramePicker = ({ shouldRender = true, dateRange, setDateRange }) => {
Month
</Button>
</ButtonGroup>
);
}
return (
<Stack
direction="row"
justifyContent="space-between"
alignItems="flex-end"
gap={theme.spacing(4)}
mb={theme.spacing(8)}
>
<Typography variant="body2">
Showing statistics for past{" "}
{dateRange === "day" ? "24 hours" : dateRange === "week" ? "7 days" : "30 days"}.
</Typography>
{timeFramePicker}
</Stack>
);
};
TimeFramePicker.propTypes = {
MonitorTimeFrameHeader.propTypes = {
shouldRender: PropTypes.bool,
hasDateRange: PropTypes.bool,
dateRange: PropTypes.string,
setDateRange: PropTypes.func,
};
export default TimeFramePicker;
export default MonitorTimeFrameHeader;
Whitespace-only changes.
+27 -7
View File
@@ -1,10 +1,12 @@
// Components
import { Stack, Typography, Skeleton } from "@mui/material";
import { Stack, Typography } from "@mui/material";
import Breadcrumbs from "../../../Components/Breadcrumbs";
import MonitorTimeFrameHeader from "../../../Components/MonitorTimeFrameHeader";
import MonitorStatusHeader from "../../../Components/MonitorStatusHeader";
import PageSpeedStatusBoxes from "./Components/PageSpeedStatusBoxes";
import PageSpeedAreaChart from "./Components/PageSpeedAreaChart";
import PerformanceReport from "./Components/PerformanceReport";
import GenericFallback from "../../../Components/GenericFallback";
// Utils
import { useTheme } from "@emotion/react";
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
@@ -41,10 +43,28 @@ const PageSpeedDetails = () => {
setMetrics((prev) => ({ ...prev, [id]: !prev[id] }));
};
// Empty view, displayed when loading is complete and there are no checks
if (!isLoading && monitor?.checks?.length === 0) {
return (
<Stack gap={theme.spacing(10)}>
<Breadcrumbs list={BREADCRUMBS} />
<MonitorStatusHeader
path={"pagespeed"}
isAdmin={isAdmin}
monitor={monitor}
/>
<GenericFallback>
<Typography>There is no history for this monitor yet.</Typography>
</GenericFallback>
</Stack>
);
}
return (
<Stack gap={theme.spacing(10)}>
<Breadcrumbs list={BREADCRUMBS} />
<MonitorStatusHeader
path={"pagespeed"}
isAdmin={isAdmin}
shouldRender={!isLoading}
monitor={monitor}
@@ -53,12 +73,12 @@ const PageSpeedDetails = () => {
shouldRender={!isLoading}
monitor={monitor}
/>
<Typography
variant="body2"
my={theme.spacing(8)}
>
Showing statistics for past 24 hours.
</Typography>
<MonitorTimeFrameHeader
shouldRender={!isLoading}
dateRange={"day"}
hasDateRange={false}
/>
<PageSpeedAreaChart
shouldRender={!isLoading}
monitor={monitor}
+3 -2
View File
@@ -1,7 +1,7 @@
// Components
import Breadcrumbs from "../../../Components/Breadcrumbs";
import MonitorStatusHeader from "../../../Components/MonitorStatusHeader";
import TimeFramePicker from "./Components/TimeFramePicker";
import MonitorTimeFrameHeader from "../../../Components/MonitorTimeFrameHeader";
import ChartBoxes from "./Components/ChartBoxes";
import ResponseTimeChart from "./Components/Charts/ResponseTimeChart";
import ResponseTable from "./Components/ResponseTable";
@@ -110,8 +110,9 @@ const UptimeDetails = () => {
monitor={monitor}
certificateExpiry={certificateExpiry}
/>
<TimeFramePicker
<MonitorTimeFrameHeader
shouldRender={!monitorIsLoading}
hasDateRange={true}
dateRange={dateRange}
setDateRange={setDateRange}
/>
+6 -2
View File
@@ -123,8 +123,12 @@ const getChecksByMonitor = async (req) => {
},
{
$project: {
checksCount: { $arrayElemAt: ["$summary.checksCount", 0] },
checks: "$checks",
checksCount: {
$ifNull: [{ $arrayElemAt: ["$summary.checksCount", 0] }, 0],
},
checks: {
$ifNull: ["$checks", []],
},
},
},
]);
+1
View File
@@ -340,6 +340,7 @@ const getUptimeDetailsById = async (req) => {
};
const dateString = formatLookup[dateRange];
const results = await Check.aggregate(
buildUptimeDetailsPipeline(monitor, dates, dateString)
);
@@ -218,18 +218,20 @@ const buildUptimeDetailsPipeline = (monitor, dates, dateString) => {
{
$project: {
uptimeStreak: {
$cond: [
{ $eq: [{ $size: { $first: "$uptimeStreak.streak.checks" } }, 0] },
0,
{
$subtract: [
new Date(),
$let: {
vars: {
checks: { $ifNull: [{ $first: "$uptimeStreak.streak.checks" }, []] },
},
in: {
$cond: [
{ $eq: [{ $size: "$$checks" }, 0] },
0,
{
$last: { $first: "$uptimeStreak.streak.checks.createdAt" },
$subtract: [new Date(), { $last: "$$checks.createdAt" }],
},
],
},
],
},
},
avgResponseTime: {
$arrayElemAt: ["$aggregateData.avgResponseTime", 0],