Refactor FE to use new query
This commit is contained in:
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}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user