Skip to content

Commit

Permalink
Merge pull request #1188 from bluewave-labs/feat/fe/details-empty-views
Browse files Browse the repository at this point in the history
add safety checks and simple empty view for details page, addresses #1187
  • Loading branch information
ajhollid authored Nov 25, 2024
2 parents dd82201 + 15345e3 commit b9a1d28
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 14 deletions.
37 changes: 37 additions & 0 deletions Client/src/Pages/Infrastructure/Details/empty.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useTheme } from "@emotion/react";
import PlaceholderLight from "../../../assets/Images/data_placeholder.svg?react";
import PlaceholderDark from "../../../assets/Images/data_placeholder_dark.svg?react";
import { Box, Typography, Stack } from "@mui/material";
import PropTypes from "prop-types";
import { useSelector } from "react-redux";
const Empty = ({ styles }) => {
const theme = useTheme();
const mode = useSelector((state) => state.ui.mode);
return (
<Box sx={{ ...styles, marginTop: theme.spacing(24) }}>
<Stack
direction="column"
gap={theme.spacing(8)}
alignItems="center"
>
{mode === "light" ? <PlaceholderLight /> : <PlaceholderDark />}

<Typography variant="h2">Your infrastructure dashboard will show here</Typography>
<Typography
textAlign="center"
color={theme.palette.text.secondary}
>
Hang tight! When we receive data, we'll show it here. Please check back in a few
minutes.
</Typography>
</Stack>
</Box>
);
};

Empty.propTypes = {
styles: PropTypes.object,
mode: PropTypes.string,
};

export default Empty;
62 changes: 48 additions & 14 deletions Client/src/Pages/Infrastructure/Details/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { useSelector } from "react-redux";
import { networkService } from "../../../main";
import PulseDot from "../../../Components/Animated/PulseDot";
import useUtils from "../../Monitors/utils";
import { useNavigate } from "react-router-dom";
import Empty from "./empty";
import { logger } from "../../../Utils/Logger";
import { formatDurationRounded, formatDurationSplit } from "../../../Utils/timeUtils";
import {
Expand All @@ -27,6 +29,7 @@ const TYPOGRAPHY_PADDING = 8;
* @returns {number} Converted value in gigabytes
*/
const formatBytes = (bytes) => {
if (bytes === undefined || bytes === null) return "0 GB";
if (typeof bytes !== "number") return "0 GB";
if (bytes === 0) return "0 GB";

Expand All @@ -40,6 +43,22 @@ const formatBytes = (bytes) => {
}
};

/**
* Converts a decimal value to a percentage
*
* @function decimalToPercentage
* @param {number} value - Decimal value to convert
* @returns {number} Percentage representation
*
* @example
* decimalToPercentage(0.75) // Returns 75
* decimalToPercentage(null) // Returns 0
*/
const decimalToPercentage = (value) => {
if (value === null || value === undefined) return 0;
return value * 100;
};

/**
* Renders a base box with consistent styling
* @param {Object} props - Component properties
Expand Down Expand Up @@ -107,6 +126,7 @@ StatBox.propTypes = {
*/
const GaugeBox = ({ value, heading, metricOne, valueOne, metricTwo, valueTwo }) => {
const theme = useTheme();

return (
<BaseBox>
<Stack
Expand Down Expand Up @@ -162,6 +182,7 @@ GaugeBox.propTypes = {
* @returns {React.ReactElement} Infrastructure details page component
*/
const InfrastructureDetails = () => {
const navigate = useNavigate();
const theme = useTheme();
const { monitorId } = useParams();
const navList = [
Expand Down Expand Up @@ -196,19 +217,22 @@ const InfrastructureDetails = () => {
numToDisplay: 50,
normalize: false,
});

setMonitor(response.data.data);
} catch (error) {
logger.error(error);
navigate("/not-found", { replace: true });
logger.error(error);
}
};
fetchData();
}, [dateRange, monitorId, authToken]);
}, [authToken, monitorId, dateRange]);


const statBoxConfigs = [
{
id: 0,
heading: "CPU",
subHeading: `${monitor?.checks[0]?.cpu?.physical_core} cores`,
subHeading: `${monitor?.checks[0]?.cpu?.physical_core ?? 0} cores`,
},
{
id: 1,
Expand All @@ -231,7 +255,7 @@ const InfrastructureDetails = () => {
const gaugeBoxConfigs = [
{
type: "memory",
value: monitor?.checks[0]?.memory?.usage_percent * 100,
value: decimalToPercentage(monitor?.checks[0]?.memory?.usage_percent),
heading: "Memory Usage",
metricOne: "Used",
valueOne: formatBytes(monitor?.checks[0]?.memory?.used_bytes),
Expand All @@ -240,17 +264,17 @@ const InfrastructureDetails = () => {
},
{
type: "cpu",
value: monitor?.checks[0]?.cpu?.usage_percent * 100,
value: decimalToPercentage(monitor?.checks[0]?.cpu?.usage_percent),
heading: "CPU Usage",
metricOne: "Cores",
valueOne: monitor?.checks[0]?.cpu?.physical_core,
valueOne: monitor?.checks[0]?.cpu?.physical_core ?? 0,
metricTwo: "Frequency",
valueTwo: `${(monitor?.checks[0]?.cpu?.frequency / 1000).toFixed(2)} Ghz`,
valueTwo: `${(monitor?.checks[0]?.cpu?.frequency ?? 0 / 1000).toFixed(2)} Ghz`,
},
...(monitor?.checks[0]?.disk ?? []).map((disk, idx) => ({
...(monitor?.checks?.[0]?.disk ?? []).map((disk, idx) => ({
type: "disk",
diskIndex: idx,
value: disk.usage_percent * 100,
value: decimalToPercentage(disk.usage_percent),
heading: `Disk${idx} usage`,
metricOne: "Used",
valueOne: formatBytes(disk.total_bytes - disk.free_bytes),
Expand Down Expand Up @@ -285,9 +309,9 @@ const InfrastructureDetails = () => {
];

return (
monitor && (
<Box>
<Breadcrumbs list={navList} />
<Box>
<Breadcrumbs list={navList} />
{monitor?.checks?.length > 0 ? (
<Stack
direction="column"
gap={theme.spacing(10)}
Expand Down Expand Up @@ -393,8 +417,18 @@ const InfrastructureDetails = () => {
))}
</Stack>
</Stack>
</Box>
)
) : (
<Empty
styles={{
border: 1,
borderColor: theme.palette.border.light,
borderRadius: theme.shape.borderRadius,
backgroundColor: theme.palette.background.main,
p: theme.spacing(30),
}}
/>
)}
</Box>
);
};

Expand Down

0 comments on commit b9a1d28

Please sign in to comment.