Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fe/infra details refactor #1678

Merged
merged 5 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Client/src/Components/StatusBoxes/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ import SkeletonLayout from "./skeleton";
// Utils
import { useTheme } from "@mui/material/styles";
import PropTypes from "prop-types";
const StatusBoxes = ({ shouldRender, children }) => {
const StatusBoxes = ({ shouldRender, flexWrap = "nowrap", children }) => {
const theme = useTheme();
if (!shouldRender) {
return <SkeletonLayout numBoxes={children?.length ?? 1} />;
return (
<SkeletonLayout
numBoxes={children?.length ?? 1}
flexWrap={flexWrap}
/>
);
}

return (
<Stack
direction="row"
flexWrap={flexWrap}
gap={theme.spacing(8)}
>
{children}
Expand Down
8 changes: 5 additions & 3 deletions Client/src/Components/StatusBoxes/skeleton.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { Stack, Skeleton } from "@mui/material";
import { useTheme } from "@emotion/react";
import PropTypes from "prop-types";
const SkeletonLayout = ({ numBoxes }) => {
const SkeletonLayout = ({ numBoxes, flexWrap }) => {
const theme = useTheme();
return (
<Stack
direction="row"
flexWrap={flexWrap}
gap={theme.spacing(4)}
mt={theme.spacing(4)}
>
{Array.from({ length: numBoxes }).map((_, index) => {
const width = `${100 / numBoxes}%`;
const width = `${200 / numBoxes}%`;
return (
<Skeleton
variant="rounded"
width={width}
height={50}
height={100}
key={index}
/>
);
Expand All @@ -25,6 +26,7 @@ const SkeletonLayout = ({ numBoxes }) => {
};

SkeletonLayout.propTypes = {
flexWrap: PropTypes.string,
numBoxes: PropTypes.number,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ CustomThreshold.propTypes = {
fieldName: PropTypes.string,
fieldValue: PropTypes.string.isRequired,
onFieldChange: PropTypes.func.isRequired,
onFieldBlur: PropTypes.func.isRequired,
onFieldBlur: PropTypes.func,
alertUnit: PropTypes.string.isRequired,
infrastructureMonitor: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Components
import { Typography } from "@mui/material";
import BaseContainer from "../BaseContainer";
import AreaChart from "../../../../../Components/Charts/AreaChart";
// Utils
import { useTheme } from "@emotion/react";
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
const InfraAreaChart = ({ config }) => {
const theme = useTheme();
const { getDimensions } = useHardwareUtils();
return (
<BaseContainer>
<Typography
component="h2"
padding={theme.spacing(8)}
>
{config.heading}
</Typography>
<AreaChart
height={getDimensions().areaChartHeight}
data={config.data}
dataKeys={config.dataKeys}
xKey="_id"
yDomain={config.yDomain}
customTooltip={config.toolTip}
xTick={config.xTick}
yTick={config.yTick}
strokeColor={config.strokeColor}
gradient={true}
gradientStartColor={config.gradientStartColor}
gradientEndColor="#ffffff"
/>
</BaseContainer>
);
};

export default InfraAreaChart;
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Components
import { Stack } from "@mui/material";
import InfraAreaChart from "./InfraAreaChart";
import SkeletonLayout from "./skeleton";

// Utils
import {
PercentTick,
TzTick,
InfrastructureTooltip,
TemperatureTooltip,
} from "../../../../../Components/Charts/Utils/chartUtils";
import { useTheme } from "@emotion/react";
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
const theme = useTheme();
const { buildTemps } = useHardwareUtils();

if (!shouldRender) {
return <SkeletonLayout />;
}

const { stats } = monitor ?? {};
const { checks } = stats;

let latestCheck = checks[0];
const { temps, tempKeys } = buildTemps(checks);

const configs = [
{
type: "memory",
data: checks,
dataKeys: ["avgMemoryUsage"],
heading: "Memory usage",
strokeColor: theme.palette.accent.main, // CAIO_REVIEW
gradientStartColor: theme.palette.accent.main, // CAIO_REVIEW
yLabel: "Memory usage",
yDomain: [0, 1],
yTick: <PercentTick />,
xTick: <TzTick dateRange={dateRange} />,
toolTip: (
<InfrastructureTooltip
dotColor={theme.palette.primary.main}
yKey={"avgMemoryUsage"}
yLabel={"Memory usage"}
dateRange={dateRange}
/>
),
},
{
type: "cpu",
data: checks,
dataKeys: ["avgCpuUsage"],
heading: "CPU usage",
strokeColor: theme.palette.success.main,
gradientStartColor: theme.palette.success.main,
yLabel: "CPU usage",
yDomain: [0, 1],
yTick: <PercentTick />,
xTick: <TzTick dateRange={dateRange} />,
toolTip: (
<InfrastructureTooltip
dotColor={theme.palette.success.main}
yKey={"avgCpuUsage"}
yLabel={"CPU usage"}
dateRange={dateRange}
/>
),
},
{
type: "temperature",
data: temps,
dataKeys: tempKeys,
strokeColor: theme.palette.error.main,
gradientStartColor: theme.palette.error.main,
heading: "CPU Temperature",
yLabel: "Temperature",
xTick: <TzTick dateRange={dateRange} />,
yDomain: [
0,
Math.max(Math.max(...temps.flatMap((t) => tempKeys.map((k) => t[k]))) * 1.1, 200),
],
toolTip: (
<TemperatureTooltip
keys={tempKeys}
dotColor={theme.palette.error.main}
dateRange={dateRange}
/>
),
},
...(latestCheck?.disks?.map((disk, idx) => ({
type: "disk",
data: checks,
diskIndex: idx,
dataKeys: [`disks[${idx}].usagePercent`],
heading: `Disk${idx} usage`,
strokeColor: theme.palette.warning.main,
gradientStartColor: theme.palette.warning.main,
yLabel: "Disk Usage",
yDomain: [0, 1],
yTick: <PercentTick />,
xTick: <TzTick dateRange={dateRange} />,
toolTip: (
<InfrastructureTooltip
dotColor={theme.palette.warning.main}
yKey={`disks.usagePercent`}
yLabel={"Disc usage"}
yIdx={idx}
dateRange={dateRange}
/>
),
})) || []),
];

return (
<Stack
direction={"row"}
// height={chartContainerHeight} // FE team HELP! Possibly no longer needed?
gap={theme.spacing(8)} // FE team HELP!
flexWrap="wrap" // //FE team HELP! Better way to do this?
sx={{
"& > *": {
flexBasis: `calc(50% - ${theme.spacing(8)})`,
maxWidth: `calc(50% - ${theme.spacing(8)})`,
},
}}
>
{configs.map((config) => (
<InfraAreaChart
key={`${config.type}-${config.diskIndex ?? ""}`}
config={config}
/>
))}
</Stack>
);
};

export default AreaChartBoxes;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Stack, Skeleton } from "@mui/material";
import { useTheme } from "@emotion/react";
const SkeletonLayout = () => {
const theme = useTheme();
return (
<Stack
direction="row"
flexWrap="wrap"
gap={theme.spacing(8)}
>
<Skeleton
height={"33vh"}
sx={{
flex: 1,
}}
/>
<Skeleton
height={"33vh"}
sx={{ flex: 1 }}
/>
</Stack>
);
};

export default SkeletonLayout;
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Renders a base box with consistent styling
* @param {Object} props - Component properties
* @param {React.ReactNode} props.children - Child components to render inside the box
* @param {Object} props.sx - Additional styling for the box
* @returns {React.ReactElement} Styled box component
*/

// Components
import { Box } from "@mui/material";

// Utils
import { useTheme } from "@emotion/react";
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
import PropTypes from "prop-types";

const BaseContainer = ({ children, sx = {} }) => {
const theme = useTheme();
const { getDimensions } = useHardwareUtils();
return (
<Box
sx={{
padding: `${theme.spacing(getDimensions().baseBoxPaddingVertical)} ${theme.spacing(getDimensions().baseBoxPaddingHorizontal)}`,
minWidth: 200,
width: 225,
backgroundColor: theme.palette.primary.main,
border: 1,
borderStyle: "solid",
borderColor: theme.palette.primary.lowContrast,
...sx,
}}
>
{children}
</Box>
);
};

BaseContainer.propTypes = {
children: PropTypes.node.isRequired,
sx: PropTypes.object,
};

export default BaseContainer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Components
import CustomGauge from "../../../../../Components/Charts/CustomGauge";
import BaseContainer from "../BaseContainer";
import { Stack, Typography, Box } from "@mui/material";
// Utils
import { useTheme } from "@emotion/react";
import PropTypes from "prop-types";

const Gauge = ({ value, heading, metricOne, valueOne, metricTwo, valueTwo }) => {
const theme = useTheme();

return (
<BaseContainer>
<Stack
direction="column"
gap={theme.spacing(2)}
alignItems="center"
>
<CustomGauge
progress={value}
radius={100}
color={theme.palette.primary.main}
/>
<Typography component="h2">{heading}</Typography>
<Box
sx={{
width: "100%",
borderTop: `1px solid ${theme.palette.primary.lowContrast}`,
}}
>
<Stack
justifyContent={"space-between"}
direction="row"
gap={theme.spacing(2)}
>
<Typography>{metricOne}</Typography>
<Typography>{valueOne}</Typography>
</Stack>
<Stack
justifyContent={"space-between"}
direction="row"
gap={theme.spacing(2)}
>
<Typography>{metricTwo}</Typography>
<Typography>{valueTwo}</Typography>
</Stack>
</Box>
</Stack>
</BaseContainer>
);
};

Gauge.propTypes = {
value: PropTypes.number,
heading: PropTypes.string,
metricOne: PropTypes.string,
valueOne: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
metricTwo: PropTypes.string,
valueTwo: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
};

export default Gauge;
Loading