Refactor FE to use new query

This commit is contained in:
Alex Holliday committed 2024-12-31 20:00:22 -08:00
1 parent a3518e4462
commit f176768b54
3 files changed
+113 -57

No files matched your search

@@ -17,7 +17,6 @@ import { Box, Stack, Typography } from "@mui/material";
*/
export const TzTick = ({ x, y, payload, index }) => {
const theme = useTheme();
const uiTimezone = useSelector((state) => state.ui.timezone);
return (
<Text
@@ -163,7 +162,7 @@ export const InfrastructureTooltip = ({
>
{yIdx >= 0
? `${yLabel} ${getFormattedPercentage(payload[0].payload[hardwareType][yIdx][metric])}`
: `${yLabel} ${getFormattedPercentage(payload[0].payload[hardwareType][metric])}`}
: `${yLabel} ${getFormattedPercentage(payload[0].payload[yKey])}`}
</Typography>
</Stack>
</Box>
@@ -1,7 +1,7 @@
import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import Breadcrumbs from "../../../Components/Breadcrumbs";
import { Stack, Box, Typography } from "@mui/material";
import { Button, ButtonGroup, Stack, Box, Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
import CustomGauge from "../../../Components/Charts/CustomGauge";
import AreaChart from "../../../Components/Charts/AreaChart";
@@ -185,9 +185,11 @@ GaugeBox.propTypes = {
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
heading: PropTypes.string.isRequired,
metricOne: PropTypes.string.isRequired,
valueOne: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
valueOne: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.element])
.isRequired,
metricTwo: PropTypes.string.isRequired,
valueTwo: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
valueTwo: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.element])
.isRequired,
};
/**
@@ -217,8 +219,9 @@ const InfrastructureDetails = () => {
(chartContainerHeight - totalChartContainerPadding - totalTypographyPadding) * 0.95;
// end height calculations
const buildStatBoxes = (checks, uptime) => {
let latestCheck = checks[0] ?? null;
const buildStatBoxes = (stats, uptime) => {
if (Object.keys(stats).length === 0) return [];
let latestCheck = stats.aggregateData.latestCheck ?? null;
if (latestCheck === null) return [];
// Extract values from latest check
@@ -311,8 +314,10 @@ const InfrastructureDetails = () => {
];
};
const buildGaugeBoxConfigs = (checks) => {
let latestCheck = checks[0] ?? null;
const buildGaugeBoxConfigs = (stats) => {
if (Object.keys(stats).length === 0) return [];
let latestCheck = stats.aggregateData.latestCheck ?? null;
if (latestCheck === null) return [];
// Extract values from latest check
@@ -359,27 +364,27 @@ const InfrastructureDetails = () => {
if (checks === null) return { temps: [], tempKeys: [] };
for (const check of checks) {
if (check?.cpu?.temperature?.length > numCores) {
numCores = check.cpu.temperature.length;
if (check?.avgTemperature?.length > numCores) {
numCores = check.avgTemperature.length;
break;
}
}
const temps = checks.map((check) => {
// If there's no data, set the temperature to 0
if (
check?.cpu?.temperature?.length === 0 ||
check?.cpu?.temperature === undefined ||
check?.cpu?.temperature === null
check?.avgTemperature?.length === 0 ||
check?.avgTemperature === undefined ||
check?.avgTemperature === null
) {
check.cpu.temperature = Array(numCores).fill(0);
check.avgTemperature = Array(numCores).fill(0);
}
const res = check?.cpu?.temperature?.reduce(
const res = check?.avgTemperature?.reduce(
(acc, cur, idx) => {
acc[`core${idx + 1}`] = cur;
return acc;
},
{
createdAt: check.createdAt,
_id: check._id,
}
);
return res;
@@ -389,7 +394,7 @@ const InfrastructureDetails = () => {
}
return {
tempKeys: Object.keys(temps[0] || {}).filter((key) => key !== "createdAt"),
tempKeys: Object.keys(temps[0] || {}).filter((key) => key !== "_id"),
temps,
};
};
@@ -397,13 +402,12 @@ const InfrastructureDetails = () => {
const buildAreaChartConfigs = (checks) => {
let latestCheck = checks[0] ?? null;
if (latestCheck === null) return [];
const reversedChecks = checks.toReversed();
const tempData = buildTemps(reversedChecks);
const { temps, tempKeys } = buildTemps(checks);
return [
{
type: "memory",
data: reversedChecks,
dataKeys: ["memory.usage_percent"],
data: checks,
dataKeys: ["avgMemoryUsage"],
heading: "Memory usage",
strokeColor: theme.palette.primary.main,
gradientStartColor: theme.palette.primary.main,
@@ -414,15 +418,15 @@ const InfrastructureDetails = () => {
toolTip: (
<InfrastructureTooltip
dotColor={theme.palette.primary.main}
yKey={"memory.usage_percent"}
yKey={"avgMemoryUsage"}
yLabel={"Memory usage"}
/>
),
},
{
type: "cpu",
data: reversedChecks,
dataKeys: ["cpu.usage_percent"],
data: checks,
dataKeys: ["avgCpuUsage"],
heading: "CPU usage",
strokeColor: theme.palette.success.main,
gradientStartColor: theme.palette.success.main,
@@ -433,15 +437,15 @@ const InfrastructureDetails = () => {
toolTip: (
<InfrastructureTooltip
dotColor={theme.palette.success.main}
yKey={"cpu.usage_percent"}
yKey={"avgCpuUsage"}
yLabel={"CPU usage"}
/>
),
},
{
type: "temperature",
data: tempData.temps,
dataKeys: tempData.tempKeys,
data: temps,
dataKeys: tempKeys,
strokeColor: theme.palette.error.main,
gradientStartColor: theme.palette.error.main,
heading: "CPU Temperature",
@@ -450,24 +454,22 @@ const InfrastructureDetails = () => {
yDomain: [
0,
Math.max(
Math.max(
...tempData.temps.flatMap((t) => tempData.tempKeys.map((k) => t[k]))
) * 1.1,
Math.max(...temps.flatMap((t) => tempKeys.map((k) => t[k]))) * 1.1,
200
),
],
toolTip: (
<TemperatureTooltip
keys={tempData.tempKeys}
keys={tempKeys}
dotColor={theme.palette.error.main}
/>
),
},
...(latestCheck?.disk?.map((disk, idx) => ({
...(latestCheck?.disks?.map((disk, idx) => ({
type: "disk",
data: reversedChecks,
data: checks,
diskIndex: idx,
dataKeys: [`disk[${idx}].usage_percent`],
dataKeys: [`disks[${idx}].usagePercent`],
heading: `Disk${idx} usage`,
strokeColor: theme.palette.warning.main,
gradientStartColor: theme.palette.warning.main,
@@ -478,7 +480,7 @@ const InfrastructureDetails = () => {
toolTip: (
<InfrastructureTooltip
dotColor={theme.palette.warning.main}
yKey={`disk.usage_percent`}
yKey={`disks.usagePercent`}
yLabel={"Disc usage"}
yIdx={idx}
/>
@@ -491,15 +493,12 @@ const InfrastructureDetails = () => {
useEffect(() => {
const fetchData = async () => {
try {
const response = await networkService.getStatsByMonitorId({
const response = await networkService.getHardwareDetailsByMonitorId({
authToken: authToken,
monitorId: monitorId,
sortOrder: null,
limit: null,
dateRange: dateRange,
numToDisplay: 50,
normalize: false,
});
response.data.data;
setMonitor(response.data.data);
} catch (error) {
navigate("/not-found", { replace: true });
@@ -510,16 +509,16 @@ const InfrastructureDetails = () => {
}, [authToken, monitorId, dateRange, navigate]);
const statBoxConfigs = buildStatBoxes(
monitor?.checks ?? [],
monitor?.stats ?? {},
monitor?.uptimePercentage ?? "Unknown"
);
const gaugeBoxConfigs = buildGaugeBoxConfigs(monitor?.checks ?? []);
const areaChartConfigs = buildAreaChartConfigs(monitor?.checks ?? []);
const gaugeBoxConfigs = buildGaugeBoxConfigs(monitor?.stats ?? {});
const areaChartConfigs = buildAreaChartConfigs(monitor?.stats?.checks ?? []);
return (
<Box>
<Breadcrumbs list={navList} />
{monitor?.checks?.length > 0 ? (
{monitor?.stats.checks?.length > 0 ? (
<Stack
direction="column"
gap={theme.spacing(10)}
@@ -549,6 +548,7 @@ const InfrastructureDetails = () => {
{formatDurationSplit(monitor?.lastChecked).format} ago
</Typography>
</Stack>
<Stack
direction="row"
flexWrap="wrap"
@@ -561,21 +561,64 @@ const InfrastructureDetails = () => {
/>
))}
</Stack>
<Stack
direction="row"
gap={theme.spacing(8)}
>
{gaugeBoxConfigs.map((config) => (
<GaugeBox
key={`${config.type}-${config.diskIndex ?? ""}`}
value={config.value}
heading={config.heading}
metricOne={config.metricOne}
valueOne={config.valueOne}
metricTwo={config.metricTwo}
valueTwo={config.valueTwo}
/>
))}
{gaugeBoxConfigs.map((config) => {
return (
<GaugeBox
key={`${config.type}-${config.diskIndex ?? ""}`}
value={config.value}
heading={config.heading}
metricOne={config.metricOne}
valueOne={config.valueOne}
metricTwo={config.metricTwo}
valueTwo={config.valueTwo}
/>
);
})}
</Stack>
<Stack
direction="row"
justifyContent="space-between"
alignItems="flex-end"
gap={theme.spacing(8)}
mb={theme.spacing(8)}
>
<Typography variant="body2">
Showing statistics for past{" "}
{dateRange === "day"
? "24 hours"
: dateRange === "week"
? "7 days"
: "30 days"}
.
</Typography>
<ButtonGroup sx={{ height: 32 }}>
<Button
variant="group"
filled={(dateRange === "day").toString()}
onClick={() => setDateRange("day")}
>
Day
</Button>
<Button
variant="group"
filled={(dateRange === "week").toString()}
onClick={() => setDateRange("week")}
>
Week
</Button>
<Button
variant="group"
filled={(dateRange === "month").toString()}
onClick={() => setDateRange("month")}
>
Month
</Button>
</ButtonGroup>
</Stack>
<Stack
direction={"row"}
@@ -602,7 +645,7 @@ const InfrastructureDetails = () => {
height={areaChartHeight}
data={config.data}
dataKeys={config.dataKeys}
xKey="createdAt"
xKey="_id"
yDomain={config.yDomain}
customTooltip={config.toolTip}
xTick={config.xTick}
+14
View File
@@ -242,6 +242,20 @@ class NetworkService {
);
}
async getHardwareDetailsByMonitorId(config) {
const params = new URLSearchParams();
if (config.dateRange) params.append("dateRange", config.dateRange);
return this.axiosInstance.get(
`/monitors/hardware/details/${config.monitorId}?${params.toString()}`,
{
headers: {
Authorization: `Bearer ${config.authToken}`,
},
}
);
}
/**
* ************************************
* Updates a single monitor