Skip to content

Commit 42846a0

Browse files
authored
Merge pull request #1678 from bluewave-labs/fix/fe/infra-details-refactor
fix: fe/infra details refactor
2 parents 8df0767 + f218b60 commit 42846a0

File tree

21 files changed

+838
-808
lines changed

21 files changed

+838
-808
lines changed

Client/src/Components/StatusBoxes/index.jsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ import SkeletonLayout from "./skeleton";
44
// Utils
55
import { useTheme } from "@mui/material/styles";
66
import PropTypes from "prop-types";
7-
const StatusBoxes = ({ shouldRender, children }) => {
7+
const StatusBoxes = ({ shouldRender, flexWrap = "nowrap", children }) => {
88
const theme = useTheme();
99
if (!shouldRender) {
10-
return <SkeletonLayout numBoxes={children?.length ?? 1} />;
10+
return (
11+
<SkeletonLayout
12+
numBoxes={children?.length ?? 1}
13+
flexWrap={flexWrap}
14+
/>
15+
);
1116
}
1217

1318
return (
1419
<Stack
1520
direction="row"
21+
flexWrap={flexWrap}
1622
gap={theme.spacing(8)}
1723
>
1824
{children}

Client/src/Components/StatusBoxes/skeleton.jsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
import { Stack, Skeleton } from "@mui/material";
22
import { useTheme } from "@emotion/react";
33
import PropTypes from "prop-types";
4-
const SkeletonLayout = ({ numBoxes }) => {
4+
const SkeletonLayout = ({ numBoxes, flexWrap }) => {
55
const theme = useTheme();
66
return (
77
<Stack
88
direction="row"
9+
flexWrap={flexWrap}
910
gap={theme.spacing(4)}
1011
mt={theme.spacing(4)}
1112
>
1213
{Array.from({ length: numBoxes }).map((_, index) => {
13-
const width = `${100 / numBoxes}%`;
14+
const width = `${200 / numBoxes}%`;
1415
return (
1516
<Skeleton
1617
variant="rounded"
1718
width={width}
18-
height={50}
19+
height={100}
1920
key={index}
2021
/>
2122
);
@@ -25,6 +26,7 @@ const SkeletonLayout = ({ numBoxes }) => {
2526
};
2627

2728
SkeletonLayout.propTypes = {
29+
flexWrap: PropTypes.string,
2830
numBoxes: PropTypes.number,
2931
};
3032

Client/src/Pages/Infrastructure/Create/Components/CustomThreshold/index.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ CustomThreshold.propTypes = {
117117
fieldName: PropTypes.string,
118118
fieldValue: PropTypes.string.isRequired,
119119
onFieldChange: PropTypes.func.isRequired,
120-
onFieldBlur: PropTypes.func.isRequired,
120+
onFieldBlur: PropTypes.func,
121121
alertUnit: PropTypes.string.isRequired,
122122
infrastructureMonitor: PropTypes.object.isRequired,
123123
errors: PropTypes.object.isRequired,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Components
2+
import { Typography } from "@mui/material";
3+
import BaseContainer from "../BaseContainer";
4+
import AreaChart from "../../../../../Components/Charts/AreaChart";
5+
// Utils
6+
import { useTheme } from "@emotion/react";
7+
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
8+
const InfraAreaChart = ({ config }) => {
9+
const theme = useTheme();
10+
const { getDimensions } = useHardwareUtils();
11+
return (
12+
<BaseContainer>
13+
<Typography
14+
component="h2"
15+
padding={theme.spacing(8)}
16+
>
17+
{config.heading}
18+
</Typography>
19+
<AreaChart
20+
height={getDimensions().areaChartHeight}
21+
data={config.data}
22+
dataKeys={config.dataKeys}
23+
xKey="_id"
24+
yDomain={config.yDomain}
25+
customTooltip={config.toolTip}
26+
xTick={config.xTick}
27+
yTick={config.yTick}
28+
strokeColor={config.strokeColor}
29+
gradient={true}
30+
gradientStartColor={config.gradientStartColor}
31+
gradientEndColor="#ffffff"
32+
/>
33+
</BaseContainer>
34+
);
35+
};
36+
37+
export default InfraAreaChart;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Components
2+
import { Stack } from "@mui/material";
3+
import InfraAreaChart from "./InfraAreaChart";
4+
import SkeletonLayout from "./skeleton";
5+
6+
// Utils
7+
import {
8+
PercentTick,
9+
TzTick,
10+
InfrastructureTooltip,
11+
TemperatureTooltip,
12+
} from "../../../../../Components/Charts/Utils/chartUtils";
13+
import { useTheme } from "@emotion/react";
14+
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
15+
const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
16+
const theme = useTheme();
17+
const { buildTemps } = useHardwareUtils();
18+
19+
if (!shouldRender) {
20+
return <SkeletonLayout />;
21+
}
22+
23+
const { stats } = monitor ?? {};
24+
const { checks } = stats;
25+
26+
let latestCheck = checks[0];
27+
const { temps, tempKeys } = buildTemps(checks);
28+
29+
const configs = [
30+
{
31+
type: "memory",
32+
data: checks,
33+
dataKeys: ["avgMemoryUsage"],
34+
heading: "Memory usage",
35+
strokeColor: theme.palette.accent.main, // CAIO_REVIEW
36+
gradientStartColor: theme.palette.accent.main, // CAIO_REVIEW
37+
yLabel: "Memory usage",
38+
yDomain: [0, 1],
39+
yTick: <PercentTick />,
40+
xTick: <TzTick dateRange={dateRange} />,
41+
toolTip: (
42+
<InfrastructureTooltip
43+
dotColor={theme.palette.primary.main}
44+
yKey={"avgMemoryUsage"}
45+
yLabel={"Memory usage"}
46+
dateRange={dateRange}
47+
/>
48+
),
49+
},
50+
{
51+
type: "cpu",
52+
data: checks,
53+
dataKeys: ["avgCpuUsage"],
54+
heading: "CPU usage",
55+
strokeColor: theme.palette.success.main,
56+
gradientStartColor: theme.palette.success.main,
57+
yLabel: "CPU usage",
58+
yDomain: [0, 1],
59+
yTick: <PercentTick />,
60+
xTick: <TzTick dateRange={dateRange} />,
61+
toolTip: (
62+
<InfrastructureTooltip
63+
dotColor={theme.palette.success.main}
64+
yKey={"avgCpuUsage"}
65+
yLabel={"CPU usage"}
66+
dateRange={dateRange}
67+
/>
68+
),
69+
},
70+
{
71+
type: "temperature",
72+
data: temps,
73+
dataKeys: tempKeys,
74+
strokeColor: theme.palette.error.main,
75+
gradientStartColor: theme.palette.error.main,
76+
heading: "CPU Temperature",
77+
yLabel: "Temperature",
78+
xTick: <TzTick dateRange={dateRange} />,
79+
yDomain: [
80+
0,
81+
Math.max(Math.max(...temps.flatMap((t) => tempKeys.map((k) => t[k]))) * 1.1, 200),
82+
],
83+
toolTip: (
84+
<TemperatureTooltip
85+
keys={tempKeys}
86+
dotColor={theme.palette.error.main}
87+
dateRange={dateRange}
88+
/>
89+
),
90+
},
91+
...(latestCheck?.disks?.map((disk, idx) => ({
92+
type: "disk",
93+
data: checks,
94+
diskIndex: idx,
95+
dataKeys: [`disks[${idx}].usagePercent`],
96+
heading: `Disk${idx} usage`,
97+
strokeColor: theme.palette.warning.main,
98+
gradientStartColor: theme.palette.warning.main,
99+
yLabel: "Disk Usage",
100+
yDomain: [0, 1],
101+
yTick: <PercentTick />,
102+
xTick: <TzTick dateRange={dateRange} />,
103+
toolTip: (
104+
<InfrastructureTooltip
105+
dotColor={theme.palette.warning.main}
106+
yKey={`disks.usagePercent`}
107+
yLabel={"Disc usage"}
108+
yIdx={idx}
109+
dateRange={dateRange}
110+
/>
111+
),
112+
})) || []),
113+
];
114+
115+
return (
116+
<Stack
117+
direction={"row"}
118+
// height={chartContainerHeight} // FE team HELP! Possibly no longer needed?
119+
gap={theme.spacing(8)} // FE team HELP!
120+
flexWrap="wrap" // //FE team HELP! Better way to do this?
121+
sx={{
122+
"& > *": {
123+
flexBasis: `calc(50% - ${theme.spacing(8)})`,
124+
maxWidth: `calc(50% - ${theme.spacing(8)})`,
125+
},
126+
}}
127+
>
128+
{configs.map((config) => (
129+
<InfraAreaChart
130+
key={`${config.type}-${config.diskIndex ?? ""}`}
131+
config={config}
132+
/>
133+
))}
134+
</Stack>
135+
);
136+
};
137+
138+
export default AreaChartBoxes;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Stack, Skeleton } from "@mui/material";
2+
import { useTheme } from "@emotion/react";
3+
const SkeletonLayout = () => {
4+
const theme = useTheme();
5+
return (
6+
<Stack
7+
direction="row"
8+
flexWrap="wrap"
9+
gap={theme.spacing(8)}
10+
>
11+
<Skeleton
12+
height={"33vh"}
13+
sx={{
14+
flex: 1,
15+
}}
16+
/>
17+
<Skeleton
18+
height={"33vh"}
19+
sx={{ flex: 1 }}
20+
/>
21+
</Stack>
22+
);
23+
};
24+
25+
export default SkeletonLayout;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Renders a base box with consistent styling
3+
* @param {Object} props - Component properties
4+
* @param {React.ReactNode} props.children - Child components to render inside the box
5+
* @param {Object} props.sx - Additional styling for the box
6+
* @returns {React.ReactElement} Styled box component
7+
*/
8+
9+
// Components
10+
import { Box } from "@mui/material";
11+
12+
// Utils
13+
import { useTheme } from "@emotion/react";
14+
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
15+
import PropTypes from "prop-types";
16+
17+
const BaseContainer = ({ children, sx = {} }) => {
18+
const theme = useTheme();
19+
const { getDimensions } = useHardwareUtils();
20+
return (
21+
<Box
22+
sx={{
23+
padding: `${theme.spacing(getDimensions().baseBoxPaddingVertical)} ${theme.spacing(getDimensions().baseBoxPaddingHorizontal)}`,
24+
minWidth: 200,
25+
width: 225,
26+
backgroundColor: theme.palette.primary.main,
27+
border: 1,
28+
borderStyle: "solid",
29+
borderColor: theme.palette.primary.lowContrast,
30+
...sx,
31+
}}
32+
>
33+
{children}
34+
</Box>
35+
);
36+
};
37+
38+
BaseContainer.propTypes = {
39+
children: PropTypes.node.isRequired,
40+
sx: PropTypes.object,
41+
};
42+
43+
export default BaseContainer;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Components
2+
import CustomGauge from "../../../../../Components/Charts/CustomGauge";
3+
import BaseContainer from "../BaseContainer";
4+
import { Stack, Typography, Box } from "@mui/material";
5+
// Utils
6+
import { useTheme } from "@emotion/react";
7+
import PropTypes from "prop-types";
8+
9+
const Gauge = ({ value, heading, metricOne, valueOne, metricTwo, valueTwo }) => {
10+
const theme = useTheme();
11+
12+
return (
13+
<BaseContainer>
14+
<Stack
15+
direction="column"
16+
gap={theme.spacing(2)}
17+
alignItems="center"
18+
>
19+
<CustomGauge
20+
progress={value}
21+
radius={100}
22+
color={theme.palette.primary.main}
23+
/>
24+
<Typography component="h2">{heading}</Typography>
25+
<Box
26+
sx={{
27+
width: "100%",
28+
borderTop: `1px solid ${theme.palette.primary.lowContrast}`,
29+
}}
30+
>
31+
<Stack
32+
justifyContent={"space-between"}
33+
direction="row"
34+
gap={theme.spacing(2)}
35+
>
36+
<Typography>{metricOne}</Typography>
37+
<Typography>{valueOne}</Typography>
38+
</Stack>
39+
<Stack
40+
justifyContent={"space-between"}
41+
direction="row"
42+
gap={theme.spacing(2)}
43+
>
44+
<Typography>{metricTwo}</Typography>
45+
<Typography>{valueTwo}</Typography>
46+
</Stack>
47+
</Box>
48+
</Stack>
49+
</BaseContainer>
50+
);
51+
};
52+
53+
Gauge.propTypes = {
54+
value: PropTypes.number,
55+
heading: PropTypes.string,
56+
metricOne: PropTypes.string,
57+
valueOne: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
58+
metricTwo: PropTypes.string,
59+
valueTwo: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
60+
};
61+
62+
export default Gauge;

0 commit comments

Comments
 (0)