diff --git a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx
index 343f7681b..7aad494ab 100644
--- a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx
+++ b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx
@@ -9,6 +9,7 @@ import {
InfrastructureTooltip,
} from "../../../../../Components/Charts/Utils/chartUtils";
import { useTheme } from "@emotion/react";
+import { useTranslation } from "react-i18next";
const getFormattedNetworkMetric = (value) => {
if (typeof value !== "number" || isNaN(value)) return "0";
@@ -20,22 +21,23 @@ const getFormattedNetworkMetric = (value) => {
const NetworkCharts = ({ eth0Data, dateRange }) => {
const theme = useTheme();
+ const { t } = useTranslation();
const configs = [
{
type: "network-bytes",
data: eth0Data,
dataKeys: ["bytesPerSec"],
- heading: "Bytes per second",
+ heading: t("bytesPerSecond"),
strokeColor: theme.palette.info.main,
gradientStartColor: theme.palette.info.main,
- yLabel: "Bytes per second",
+ yLabel: t("bytesPerSecond"),
xTick: ,
toolTip: (
@@ -45,16 +47,16 @@ const NetworkCharts = ({ eth0Data, dateRange }) => {
type: "network-packets",
data: eth0Data,
dataKeys: ["packetsPerSec"],
- heading: "Packets per second",
+ heading: t("packetsPerSecond"),
strokeColor: theme.palette.success.main,
gradientStartColor: theme.palette.success.main,
- yLabel: "Packets per second",
+ yLabel: t("packetsPerSecond"),
xTick: ,
toolTip: (
Math.round(value).toLocaleString()}
/>
@@ -64,16 +66,16 @@ const NetworkCharts = ({ eth0Data, dateRange }) => {
type: "network-errors",
data: eth0Data,
dataKeys: ["errors"],
- heading: "Errors",
+ heading: t("errors"),
strokeColor: theme.palette.error.main,
gradientStartColor: theme.palette.error.main,
- yLabel: "Errors",
+ yLabel: t("errors"),
xTick: ,
toolTip: (
Math.round(value).toLocaleString()}
/>
@@ -83,16 +85,16 @@ const NetworkCharts = ({ eth0Data, dateRange }) => {
type: "network-drops",
data: eth0Data,
dataKeys: ["drops"],
- heading: "Drops",
+ heading: t("drops"),
strokeColor: theme.palette.warning.main,
gradientStartColor: theme.palette.warning.main,
- yLabel: "Drops",
+ yLabel: t("drops"),
xTick: ,
toolTip: (
Math.round(value).toLocaleString()}
/>
diff --git a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkStatBoxes.jsx b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkStatBoxes.jsx
index b2f2f7841..3125e86a9 100644
--- a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkStatBoxes.jsx
+++ b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkStatBoxes.jsx
@@ -3,6 +3,7 @@ import PropTypes from "prop-types";
import StatusBoxes from "../../../../../Components/StatusBoxes";
import StatBox from "../../../../../Components/StatBox";
import { Typography } from "@mui/material";
+import { useTranslation } from "react-i18next";
function formatBytes(bytes) {
if (bytes === 0 || bytes == null) return "0 B";
@@ -18,11 +19,12 @@ function formatNumber(num) {
}
const NetworkStatBoxes = ({ shouldRender, net }) => {
+ const { t } = useTranslation();
const filtered =
net?.filter((iface) => iface.name === "en0" || iface.name === "wlan0") || [];
if (!net?.length) {
- return No network stats available.;
+ return {t("noNetworkStatsAvailable")};
}
return (
@@ -34,32 +36,32 @@ const NetworkStatBoxes = ({ shouldRender, net }) => {
.map((iface) => [
,
,
,
,
,
,
])
diff --git a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx
index 6b8ccb85a..03e0c019d 100644
--- a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx
+++ b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx
@@ -37,101 +37,62 @@ export default Network;
/* ---------- Helper functions ---------- */
function getEth0TimeSeries(checks) {
- console.log(`[NetworkStats] Processing ${checks?.length || 0} checks`);
- if (checks && checks.length > 0) {
- console.log("[NetworkStats] First check _id:", checks[0]._id);
- console.log("[NetworkStats] Last check _id:", checks[checks.length - 1]._id);
- console.log(
- "[NetworkStats] Sample check structure:",
- JSON.stringify(checks[0], null, 2)
- );
- }
-
const sorted = [...(checks || [])].sort((a, b) => new Date(a._id) - new Date(b._id));
const series = [];
let prev = null;
for (const check of sorted) {
- console.log(`[NetworkStats] Processing check: ${check._id}`);
const eth = (check.net || []).find((iface) => iface.name === "en0");
if (!eth) {
- console.log("[NetworkStats] No en0 interface found in check:", check._id);
prev = check;
continue;
}
- console.log(`[NetworkStats] Found en0 interface in check ${check._id}:`, eth);
-
if (prev) {
- console.log(`[NetworkStats] Have previous check: ${prev._id}`);
const prevEth = (prev.net || []).find((iface) => iface.name === "en0");
const t1 = new Date(check._id);
const t0 = new Date(prev._id);
- console.log(`[NetworkStats] Time difference: ${t1 - t0}ms`);
if (!prevEth || isNaN(t1) || isNaN(t0)) {
- console.log("[NetworkStats] Skipping - invalid prev data or time");
prev = check;
continue;
}
const dt = (t1 - t0) / 1000;
- console.log(`[NetworkStats] Delta time: ${dt}s`);
if (dt > 0) {
const bytesField = eth.avgBytesSent;
const prevBytesField = prevEth.avgBytesSent;
- console.log(`[NetworkStats] Bytes comparison:`, {
- current: bytesField,
- previous: prevBytesField,
- diff: bytesField - prevBytesField,
- });
-
if (bytesField !== undefined && prevBytesField !== undefined) {
const dataPoint = {
- _id: check._id, // Use _id instead of time to match AreaChartBoxes
+ _id: check._id,
bytesPerSec: (bytesField - prevBytesField) / dt,
packetsPerSec: (eth.avgPacketsSent - prevEth.avgPacketsSent) / dt,
errors: (eth.avgErrIn ?? 0) + (eth.avgErrOut ?? 0),
- drops: 0, // Skip drops for now since we don't have avgDropIn/Out
+ drops: 0,
};
- console.log(`[NetworkStats] Adding data point:`, dataPoint);
series.push(dataPoint);
- } else {
- console.warn("[NetworkStats] Missing bytes fields:", { eth, prevEth });
}
- } else {
- console.log("[NetworkStats] Skipping - zero or negative time delta");
}
- } else {
- console.log("[NetworkStats] No previous check yet, setting as prev");
}
prev = check;
}
- console.log(`[NetworkStats] Generated ${series.length} time series data points`);
-
// If we only have one check, create a single data point with absolute values
if (series.length === 0 && sorted.length === 1) {
const check = sorted[0];
const eth = (check.net || []).find((iface) => iface.name === "en0");
if (eth) {
- console.log(
- "[NetworkStats] Only one data point available, showing absolute values"
- );
series.push({
- _id: check._id, // Use _id instead of time to match AreaChartBoxes
- bytesPerSec: eth.avgBytesSent || 0, // Show absolute value instead of rate
- packetsPerSec: eth.avgPacketsSent || 0, // Show absolute value instead of rate
+ _id: check._id,
+ bytesPerSec: eth.avgBytesSent || 0,
+ packetsPerSec: eth.avgPacketsSent || 0,
errors: (eth.avgErrIn ?? 0) + (eth.avgErrOut ?? 0),
drops: 0,
});
}
}
- if (series.length > 0) {
- console.log("[NetworkStats] Sample series data:", series[0]);
- }
return series;
}
diff --git a/client/src/Pages/Infrastructure/Details/index.jsx b/client/src/Pages/Infrastructure/Details/index.jsx
index 78b78fa78..72f384101 100644
--- a/client/src/Pages/Infrastructure/Details/index.jsx
+++ b/client/src/Pages/Infrastructure/Details/index.jsx
@@ -25,7 +25,6 @@ const BREADCRUMBS = [
{ name: "details", path: "" },
];
const InfrastructureDetails = () => {
-
// Local state
const [dateRange, setDateRange] = useState("recent");
const [trigger, setTrigger] = useState(false);
@@ -96,11 +95,11 @@ const InfrastructureDetails = () => {
onChange={(e, v) => setTab(v)}
>
diff --git a/client/src/locales/en.json b/client/src/locales/en.json
index 230637474..bf949ea45 100644
--- a/client/src/locales/en.json
+++ b/client/src/locales/en.json
@@ -201,6 +201,9 @@
"avgCpuTemperature": "Average CPU Temperature",
"bar": "Bar",
"basicInformation": "Basic Information",
+ "bytesPerSecond": "Bytes per second",
+ "bytesReceived": "Bytes Received",
+ "bytesSent": "Bytes Sent",
"bulkImport": {
"fallbackPage": "Import a file to upload a list of servers in bulk",
"invalidFileType": "Invalid file type",
@@ -332,6 +335,11 @@
},
"disk": "Disk",
"diskUsage": "Disk Usage",
+ "drops": "Drops",
+ "errors": "Errors",
+ "errorsIn": "Errors In",
+ "errorsOut": "Errors Out",
+ "details": "Details",
"displayName": "Display name",
"distributedRightCategoryTitle": "Monitor",
"distributedStatusHeaderText": "Real-time, real-device coverage",
@@ -632,7 +640,9 @@
},
"ms": "ms",
"navControls": "Controls",
+ "network": "Network",
"nextWindow": "Next window",
+ "noNetworkStatsAvailable": "No network stats available.",
"notFoundButton": "Go to the main dashboard",
"notificationConfig": {
"description": "Select the notifications channels you want to use",
@@ -744,6 +754,9 @@
"passwordRequirements": "New password must contain at least 8 characters and must have at least one uppercase letter, one lowercase letter, one number and one special character.",
"saving": "Saving..."
},
+ "packetsPerSecond": "Packets per second",
+ "packetsReceived": "Packets Received",
+ "packetsSent": "Packets Sent",
"pause": "Pause",
"pingMonitoring": "Ping monitoring",
"pingMonitoringDescription": "Check whether your server is available or not.",