From e1409a80451e5189990b6e4c511eb5d0d672d066 Mon Sep 17 00:00:00 2001 From: MacRimi Date: Tue, 18 Nov 2025 21:27:24 +0100 Subject: [PATCH] Update AppImage --- .../components/interface-details-modal.tsx | 60 ---------- AppImage/components/metrics-dialog.tsx | 33 ++---- AppImage/components/network-card.tsx | 27 +---- AppImage/components/network-metrics.tsx | 25 ++-- AppImage/components/network-traffic-chart.tsx | 67 +++++------ AppImage/components/settings.tsx | 107 ++++++++---------- AppImage/components/system-overview.tsx | 105 ++++++++--------- AppImage/components/virtual-machines.tsx | 68 +++-------- AppImage/lib/network-utils.ts | 50 -------- 9 files changed, 170 insertions(+), 372 deletions(-) delete mode 100644 AppImage/components/interface-details-modal.tsx delete mode 100644 AppImage/lib/network-utils.ts diff --git a/AppImage/components/interface-details-modal.tsx b/AppImage/components/interface-details-modal.tsx deleted file mode 100644 index 2d63210..0000000 --- a/AppImage/components/interface-details-modal.tsx +++ /dev/null @@ -1,60 +0,0 @@ -"use client" -import { useState, useEffect } from "react" -import { Dialog, DialogContent } from "@radix-ui/react-dialog" -import { getUnitsSettings, formatNetworkTraffic, getNetworkLabel } from "@/lib/network-utils" - -export function InterfaceDetailsModal({ interface_, onClose, timeframe }: InterfaceDetailsModalProps) { - const [metricsData, setMetricsData] = useState([]) - const [loading, setLoading] = useState(false) - const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes") - - useEffect(() => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - - const handleSettingsChange = () => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - } - - window.addEventListener('storage', handleSettingsChange) - window.addEventListener('unitsSettingsChanged', handleSettingsChange) - - return () => { - window.removeEventListener('storage', handleSettingsChange) - window.removeEventListener('unitsSettingsChanged', handleSettingsChange) - } - }, []) - - const totalReceived = metricsData.length > 0 - ? Math.max(0, (metricsData[metricsData.length - 1].netin || 0) - (metricsData[0].netin || 0)) - : 0 - - const totalSent = metricsData.length > 0 - ? Math.max(0, (metricsData[metricsData.length - 1].netout || 0) - (metricsData[0].netout || 0)) - : 0 - - return ( - - - -
-

- Network Traffic Statistics (Last 24 Hours) -

-
-
-

{getNetworkLabel(networkUnit, "received")}

-

{formatNetworkTraffic(totalReceived, networkUnit)}

-
-
-

{getNetworkLabel(networkUnit, "sent")}

-

{formatNetworkTraffic(totalSent, networkUnit)}

-
-
- -
-
-
- ) -} diff --git a/AppImage/components/metrics-dialog.tsx b/AppImage/components/metrics-dialog.tsx index 90e7395..ce201a6 100644 --- a/AppImage/components/metrics-dialog.tsx +++ b/AppImage/components/metrics-dialog.tsx @@ -3,10 +3,9 @@ import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" -import { ArrowLeft, Loader2 } from 'lucide-react' +import { ArrowLeft, Loader2 } from "lucide-react" import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from "recharts" import { fetchApi } from "@/lib/api-config" -import { getUnitsSettings, formatNetworkTraffic } from "@/lib/network-utils" interface MetricsViewProps { vmid: number @@ -85,7 +84,6 @@ const CustomDiskTooltip = ({ active, payload, label }: any) => { const CustomNetworkTooltip = ({ active, payload, label }: any) => { if (active && payload && payload.length) { - const unit = networkUnit === "Bits" ? "Mb" : "MB" return (

{label}

@@ -94,7 +92,7 @@ const CustomNetworkTooltip = ({ active, payload, label }: any) => {
{entry.name}: - {entry.value} {unit} + {entry.value} MB
))}
@@ -111,20 +109,10 @@ export function MetricsView({ vmid, vmName, vmType, onBack }: MetricsViewProps) const [error, setError] = useState(null) const [hiddenDiskLines, setHiddenDiskLines] = useState([]) const [hiddenNetworkLines, setHiddenNetworkLines] = useState([]) - const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes") useEffect(() => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - - const handleStorageChange = () => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - } - - window.addEventListener('storage', handleStorageChange) - return () => window.removeEventListener('storage', handleStorageChange) - }, []) + fetchMetrics() + }, [vmid, timeframe]) const fetchMetrics = async () => { setLoading(true) @@ -169,9 +157,6 @@ export function MetricsView({ vmid, vmName, vmType, onBack }: MetricsViewProps) }) } - const netinValue = item.netin ? (item.netin / 1024 / 1024) : 0 - const netoutValue = item.netout ? (item.netout / 1024 / 1024) : 0 - return { time: timeLabel, timestamp: item.time, @@ -179,8 +164,8 @@ export function MetricsView({ vmid, vmName, vmType, onBack }: MetricsViewProps) memory: item.mem ? Number(((item.mem / item.maxmem) * 100).toFixed(2)) : 0, memoryGB: item.mem ? Number((item.mem / 1024 / 1024 / 1024).toFixed(2)) : 0, maxMemoryGB: item.maxmem ? Number((item.maxmem / 1024 / 1024 / 1024).toFixed(2)) : 0, - netin: networkUnit === "Bits" ? Number((netinValue * 8).toFixed(2)) : Number(netinValue.toFixed(2)), - netout: networkUnit === "Bits" ? Number((netoutValue * 8).toFixed(2)) : Number(netoutValue.toFixed(2)), + netin: item.netin ? Number((item.netin / 1024 / 1024).toFixed(2)) : 0, + netout: item.netout ? Number((item.netout / 1024 / 1024).toFixed(2)) : 0, diskread: item.diskread ? Number((item.diskread / 1024 / 1024).toFixed(2)) : 0, diskwrite: item.diskwrite ? Number((item.diskwrite / 1024 / 1024).toFixed(2)) : 0, } @@ -194,10 +179,6 @@ export function MetricsView({ vmid, vmName, vmType, onBack }: MetricsViewProps) } } - useEffect(() => { - fetchMetrics() - }, [vmid, timeframe]) - const formatXAxisTick = (tick: any) => { return tick } @@ -378,7 +359,7 @@ export function MetricsView({ vmid, vmName, vmType, onBack }: MetricsViewProps) stroke="currentColor" className="text-foreground" tick={{ fill: "currentColor" }} - label={{ value: networkUnit === "Bits" ? "Mb" : "MB", angle: -90, position: "insideLeft", fill: "currentColor" }} + label={{ value: "MB", angle: -90, position: "insideLeft", fill: "currentColor" }} domain={[0, "dataMax"]} /> } /> diff --git a/AppImage/components/network-card.tsx b/AppImage/components/network-card.tsx index 16a6d7f..06f8f95 100644 --- a/AppImage/components/network-card.tsx +++ b/AppImage/components/network-card.tsx @@ -2,10 +2,9 @@ import { Card, CardContent } from "./ui/card" import { Badge } from "./ui/badge" -import { Wifi, Zap } from 'lucide-react' +import { Wifi, Zap } from "lucide-react" import { useState, useEffect } from "react" import { fetchApi } from "../lib/api-config" -import { getUnitsSettings, formatNetworkTraffic } from "../lib/network-utils" interface NetworkCardProps { interface_: { @@ -88,31 +87,11 @@ export function NetworkCard({ interface_, timeframe, onClick }: NetworkCardProps const typeBadge = getInterfaceTypeBadge(interface_.type) const vmTypeBadge = interface_.vm_type ? getVMTypeBadge(interface_.vm_type) : null - const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes") - const [trafficData, setTrafficData] = useState<{ received: number; sent: number }>({ received: 0, sent: 0, }) - useEffect(() => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - - const handleSettingsChange = () => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - } - - window.addEventListener('storage', handleSettingsChange) - window.addEventListener('unitsSettingsChanged', handleSettingsChange) - - return () => { - window.removeEventListener('storage', handleSettingsChange) - window.removeEventListener('unitsSettingsChanged', handleSettingsChange) - } - }, []) - useEffect(() => { const fetchTrafficData = async () => { try { @@ -228,9 +207,9 @@ export function NetworkCard({ interface_, timeframe, onClick }: NetworkCardProps
{interface_.status.toLowerCase() === "up" && interface_.vm_type !== "vm" ? ( <> - ↓ {formatNetworkTraffic(trafficData.received, networkUnit)} + ↓ {formatStorage(trafficData.received * 1024 * 1024 * 1024)} {" / "} - ↑ {formatNetworkTraffic(trafficData.sent, networkUnit)} + ↑ {formatStorage(trafficData.sent * 1024 * 1024 * 1024)} ) : ( <> diff --git a/AppImage/components/network-metrics.tsx b/AppImage/components/network-metrics.tsx index f2793a1..ff67ef7 100644 --- a/AppImage/components/network-metrics.tsx +++ b/AppImage/components/network-metrics.tsx @@ -133,10 +133,10 @@ const fetcher = async (url: string): Promise => { } const getUnitsSettings = (): "Bytes" | "Bits" => { - const raw = localStorage.getItem("proxmenux-network-unit"); - const networkUnit = raw && raw.toLowerCase() === "bits" ? "Bits" : "Bytes"; - return networkUnit; -}; + if (typeof window === "undefined") return "Bytes" + const raw = localStorage.getItem("proxmenux-network-unit") + return raw && raw.toLowerCase() === "bits" ? "Bits" : "Bytes" +} export function NetworkMetrics() { const { @@ -154,13 +154,19 @@ export function NetworkMetrics() { const [modalTimeframe, setModalTimeframe] = useState<"hour" | "day" | "week" | "month" | "year">("day") const [networkTotals, setNetworkTotals] = useState<{ received: number; sent: number }>({ received: 0, sent: 0 }) const [interfaceTotals, setInterfaceTotals] = useState<{ received: number; sent: number }>({ received: 0, sent: 0 }) - - const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes"); + + const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes") useEffect(() => { - const networkUnitSetting = getUnitsSettings(); - setNetworkUnit(networkUnitSetting); - }, []); + setNetworkUnit(getUnitsSettings()) + + const handleUnitChange = (e: CustomEvent) => { + setNetworkUnit(e.detail === "Bits" ? "Bits" : "Bytes") + } + + window.addEventListener("networkUnitChanged" as any, handleUnitChange) + return () => window.removeEventListener("networkUnitChanged" as any, handleUnitChange) + }, []) const { data: modalNetworkData } = useSWR(selectedInterface ? "/api/network" : null, fetcher, { refreshInterval: 17000, @@ -905,7 +911,6 @@ export function NetworkMetrics() { interfaceName={displayInterface.name} onTotalsCalculated={setInterfaceTotals} refreshInterval={60000} - networkUnit={networkUnit} />
diff --git a/AppImage/components/network-traffic-chart.tsx b/AppImage/components/network-traffic-chart.tsx index e34ddea..e3a6c8e 100644 --- a/AppImage/components/network-traffic-chart.tsx +++ b/AppImage/components/network-traffic-chart.tsx @@ -17,7 +17,29 @@ interface NetworkTrafficChartProps { interfaceName?: string onTotalsCalculated?: (totals: { received: number; sent: number }) => void refreshInterval?: number // En milisegundos, por defecto 60000 (60 segundos) - networkUnit?: string // Added networkUnit prop with default value + networkUnit?: "Bytes" | "Bits" // Added networkUnit prop +} + +const CustomNetworkTooltip = ({ active, payload, label, networkUnit }: any) => { + if (active && payload && payload.length) { + return ( +
+

{label}

+
+ {payload.map((entry: any, index: number) => ( +
+
+ {entry.name}: + + {entry.value.toFixed(3)} {networkUnit === "Bits" ? "Gb" : "GB"} + +
+ ))} +
+
+ ) + } + return null } export function NetworkTrafficChart({ @@ -25,7 +47,7 @@ export function NetworkTrafficChart({ interfaceName, onTotalsCalculated, refreshInterval = 60000, - networkUnit = "Bytes", // Added networkUnit prop with default value + networkUnit = "Bytes", // Default to Bytes }: NetworkTrafficChartProps) { const [data, setData] = useState([]) const [loading, setLoading] = useState(true) @@ -39,7 +61,7 @@ export function NetworkTrafficChart({ useEffect(() => { setIsInitialLoad(true) fetchMetrics() - }, [timeframe, interfaceName]) + }, [timeframe, interfaceName, networkUnit]) // Added networkUnit to dependencies useEffect(() => { if (refreshInterval > 0) { @@ -49,7 +71,7 @@ export function NetworkTrafficChart({ return () => clearInterval(interval) } - }, [timeframe, interfaceName, refreshInterval]) + }, [timeframe, interfaceName, refreshInterval, networkUnit]) // Added networkUnit to dependencies const fetchMetrics = async () => { if (isInitialLoad) { @@ -121,16 +143,14 @@ export function NetworkTrafficChart({ const netOutBytes = (item.netout || 0) * intervalSeconds if (networkUnit === "Bits") { - // Convert to Gigabits: bytes * 8 / 1024^3 return { time: timeLabel, timestamp: item.time, - netIn: Number((netInBytes * 8 / 1024 / 1024 / 1024).toFixed(4)), - netOut: Number((netOutBytes * 8 / 1024 / 1024 / 1024).toFixed(4)), + netIn: Number(((netInBytes * 8) / 1024 / 1024 / 1024).toFixed(4)), + netOut: Number(((netOutBytes * 8) / 1024 / 1024 / 1024).toFixed(4)), } } - // Default: Convert to Gigabytes return { time: timeLabel, timestamp: item.time, @@ -190,28 +210,6 @@ export function NetworkTrafficChart({ ) } - const CustomNetworkTooltip = ({ active, payload, label }: any) => { - if (active && payload && payload.length) { - return ( -
-

{label}

-
- {payload.map((entry: any, index: number) => ( -
-
- {entry.name}: - - {entry.value.toFixed(3)} {networkUnit === "Bits" ? "Gb" : "GB"} - -
- ))} -
-
- ) - } - return null - } - if (loading && isInitialLoad) { return (
@@ -255,10 +253,15 @@ export function NetworkTrafficChart({ stroke="currentColor" className="text-foreground" tick={{ fill: "currentColor", fontSize: 12 }} - label={{ value: networkUnit === "Bits" ? "Gb" : "GB", angle: -90, position: "insideLeft", fill: "currentColor" }} + label={{ + value: networkUnit === "Bits" ? "Gb" : "GB", // Dynamic label based on unit + angle: -90, + position: "insideLeft", + fill: "currentColor", + }} domain={[0, "auto"]} /> - } /> + } /> // Pass networkUnit to tooltip { checkAuthStatus() loadProxmenuxTools() - getUnitsSettings(); // Load network unit settings on mount + getUnitsSettings() // Load units settings on mount }, []) - const changeNetworkUnit = (unit: string) => { - const settings = { networkUnit: unit } - localStorage.setItem('unitsSettings', JSON.stringify(settings)) - localStorage.setItem("proxmenux-network-unit", unit); // Keep legacy for backwards compatibility - setNetworkUnitSettings(unit); - - // Dispatch custom event to notify other components - window.dispatchEvent(new CustomEvent('unitsSettingsChanged', { detail: settings })) - window.dispatchEvent(new Event('storage')) - }; - - const getUnitsSettings = () => { - const networkUnit = - localStorage.getItem("proxmenux-network-unit") || "Bytes"; - setNetworkUnitSettings(networkUnit); - setLoadingUnitSettings(false); - }; - const checkAuthStatus = async () => { try { const response = await fetch(getApiUrl("/api/auth/status")) @@ -370,6 +353,19 @@ export function Settings() { })) } + const changeNetworkUnit = (unit: string) => { + localStorage.setItem("proxmenux-network-unit", unit) + setNetworkUnitSettings(unit) + // Dispatch custom event to notify other components + window.dispatchEvent(new CustomEvent("networkUnitChanged", { detail: unit })) + } + + const getUnitsSettings = () => { + const networkUnit = localStorage.getItem("proxmenux-network-unit") || "Bytes" + setNetworkUnitSettings(networkUnit) + setLoadingUnitSettings(false) + } + return (
@@ -671,6 +667,37 @@ export function Settings() { + {/* Network Units Settings */} + + +
+ + Network Units +
+ Change how network traffic is displayed +
+ + {loadingUnitSettings ? ( +
+
+
+ ) : ( +
+
Network Unit Display
+ +
+ )} + + + {/* API Access Tokens */} {authEnabled && ( @@ -864,42 +891,6 @@ export function Settings() { )} - {/* ProxMenux Unit Settings */} - - -
- - ProxMenux Unit Settings -
- Change settings related to units -
- - {loadingUnitSettings ? ( -
-
-
- ) : ( -
-
- Network Unit Display -
- -
- )} - - - {/* ProxMenux Optimizations */} diff --git a/AppImage/components/system-overview.tsx b/AppImage/components/system-overview.tsx index 26cca48..1cf67d5 100644 --- a/AppImage/components/system-overview.tsx +++ b/AppImage/components/system-overview.tsx @@ -9,7 +9,6 @@ import { NodeMetricsCharts } from "./node-metrics-charts" import { NetworkTrafficChart } from "./network-traffic-chart" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select" import { fetchApi } from "../lib/api-config" -import { getUnitsSettings } from "../lib/network-utils" interface SystemData { cpu_usage: number @@ -147,6 +146,12 @@ const fetchProxmoxStorageData = async (): Promise => } } +const getUnitsSettings = (): "Bytes" | "Bits" => { + if (typeof window === "undefined") return "Bytes" + const raw = window.localStorage.getItem("proxmenux-network-unit") + return raw && raw.toLowerCase() === "bits" ? "Bits" : "Bytes" +} + export function SystemOverview() { const [systemData, setSystemData] = useState(null) const [vmData, setVmData] = useState([]) @@ -162,25 +167,7 @@ export function SystemOverview() { const [error, setError] = useState(null) const [networkTimeframe, setNetworkTimeframe] = useState("day") const [networkTotals, setNetworkTotals] = useState<{ received: number; sent: number }>({ received: 0, sent: 0 }) - const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes") - - useEffect(() => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - - const handleSettingsChange = () => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - } - - window.addEventListener('storage', handleSettingsChange) - window.addEventListener('unitsSettingsChanged', handleSettingsChange) - - return () => { - window.removeEventListener('storage', handleSettingsChange) - window.removeEventListener('unitsSettingsChanged', handleSettingsChange) - } - }, []) + const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes") // Added networkUnit state useEffect(() => { const fetchAllData = async () => { @@ -235,11 +222,20 @@ export function SystemOverview() { if (data) setNetworkData(data) }, 59000) + setNetworkUnit(getUnitsSettings()) // Load initial setting + + const handleUnitChange = (e: CustomEvent) => { + setNetworkUnit(e.detail === "Bits" ? "Bits" : "Bytes") + } + + window.addEventListener("networkUnitChanged" as any, handleUnitChange) + return () => { clearInterval(systemInterval) clearInterval(vmInterval) clearInterval(storageInterval) clearInterval(networkInterval) + window.removeEventListener("networkUnitChanged" as any, handleUnitChange) } }, []) @@ -318,13 +314,21 @@ export function SystemOverview() { return (bytes / 1024 ** 3).toFixed(2) } - const formatStorage = (sizeInGB: number): string => { - if (sizeInGB < 1) { - return `${(sizeInGB * 1024).toFixed(1)} MB` - } else if (sizeInGB > 999) { - return `${(sizeInGB / 1024).toFixed(2)} TB` + const formatStorage = (sizeInGB: number, unit: "Bytes" | "Bits" = "Bytes"): string => { + let size = sizeInGB + let suffix = "B" + + if (unit === "Bits") { + size = size * 8 + suffix = "b" + } + + if (size < 1) { + return `${(size * 1024).toFixed(1)} M${suffix}` + } else if (size > 999) { + return `${(size / 1024).toFixed(2)} T${suffix}` } else { - return `${sizeInGB.toFixed(2)} GB` + return `${size.toFixed(2)} G${suffix}` } } @@ -467,11 +471,9 @@ export function SystemOverview() { - - - - Temperature - + + Temperature +
@@ -621,29 +623,18 @@ export function SystemOverview() { Network Overview
-
- - -
+
@@ -700,21 +691,21 @@ export function SystemOverview() {
Received: - ↓ {formatNetworkTraffic(networkTotals.received, networkUnit)} + ↓ {formatStorage(networkTotals.received, networkUnit)} ({getTimeframeLabel(networkTimeframe)})
Sent: - ↑ {formatNetworkTraffic(networkTotals.sent, networkUnit)} + ↑ {formatStorage(networkTotals.sent, networkUnit)} ({getTimeframeLabel(networkTimeframe)})
- +
) : ( diff --git a/AppImage/components/virtual-machines.tsx b/AppImage/components/virtual-machines.tsx index a4ff3fd..6687b2a 100644 --- a/AppImage/components/virtual-machines.tsx +++ b/AppImage/components/virtual-machines.tsx @@ -28,41 +28,6 @@ import { MetricsView } from "./metrics-dialog" import { formatStorage } from "@/lib/utils" // Import formatStorage utility import { fetchApi } from "../lib/api-config" -const getUnitsSettings = () => { - if (typeof window === 'undefined') return { networkUnit: 'Bytes' as const } - - try { - const settings = localStorage.getItem('unitsSettings') - if (settings) { - const parsed = JSON.parse(settings) - return { networkUnit: parsed.networkUnit || 'Bytes' } - } - } catch (e) { - console.error('[v0] Error reading units settings:', e) - } - - return { networkUnit: 'Bytes' as const } -} - -const formatBytes = (bytes: number | undefined, unit: "Bytes" | "Bits" = "Bytes"): string => { - if (!bytes || bytes === 0) return unit === "Bits" ? "0 b" : "0 B" - - if (unit === "Bits") { - // Convert bytes to bits (*8) - const bits = bytes * 8 - const k = 1000 // Use decimal for bits (networking standard) - const sizes = ["b", "Kb", "Mb", "Gb", "Tb"] - const i = Math.floor(Math.log(bits) / Math.log(k)) - return `${(bits / Math.pow(k, i)).toFixed(2)} ${sizes[i]}` - } else { - // Bytes mode (existing behavior) - const k = 1024 - const sizes = ["B", "KB", "MB", "GB", "TB"] - const i = Math.floor(Math.log(bytes) / Math.log(k)) - return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}` - } -} - interface VMData { vmid: number name: string @@ -172,6 +137,13 @@ const fetcher = async (url: string) => { return fetchApi(url) } +const formatBytes = (bytes: number | undefined): string => { + if (!bytes || bytes === 0) return "0 B" + const k = 1024 + const sizes = ["B", "KB", "MB", "GB", "TB"] + const i = Math.floor(Math.log(bytes) / Math.log(k)) + return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}` +} const formatUptime = (seconds: number) => { const days = Math.floor(seconds / 86400) @@ -300,20 +272,6 @@ export function VirtualMachines() { const [selectedMetric, setSelectedMetric] = useState(null) const [ipsLoaded, setIpsLoaded] = useState(false) const [loadingIPs, setLoadingIPs] = useState(false) - const [networkUnit, setNetworkUnit] = useState<"Bytes" | "Bits">("Bytes") - - useEffect(() => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - - const handleStorageChange = () => { - const settings = getUnitsSettings() - setNetworkUnit(settings.networkUnit as "Bytes" | "Bits") - } - - window.addEventListener('storage', handleStorageChange) - return () => window.removeEventListener('storage', handleStorageChange) - }, []) useEffect(() => { const fetchLXCIPs = async () => { @@ -980,11 +938,11 @@ export function VirtualMachines() {
- ↓ {formatBytes(vm.netin, networkUnit)} + ↓ {formatBytes(vm.netin)}
- ↑ {formatBytes(vm.netout, networkUnit)} + ↑ {formatBytes(vm.netout)}
@@ -1194,11 +1152,11 @@ export function VirtualMachines() {
- {formatBytes(selectedVM.diskread || 0, "Bytes")} + {((selectedVM.diskread || 0) / 1024 ** 2).toFixed(2)} MB
- {formatBytes(selectedVM.diskwrite || 0, "Bytes")} + {((selectedVM.diskwrite || 0) / 1024 ** 2).toFixed(2)} MB
@@ -1209,11 +1167,11 @@ export function VirtualMachines() {
- {formatBytes(selectedVM.netin || 0, networkUnit)} + {((selectedVM.netin || 0) / 1024 ** 2).toFixed(2)} MB
- {formatBytes(selectedVM.netout || 0, networkUnit)} + {((selectedVM.netout || 0) / 1024 ** 2).toFixed(2)} MB
diff --git a/AppImage/lib/network-utils.ts b/AppImage/lib/network-utils.ts deleted file mode 100644 index 1b603cd..0000000 --- a/AppImage/lib/network-utils.ts +++ /dev/null @@ -1,50 +0,0 @@ -export const getUnitsSettings = () => { - if (typeof window === 'undefined') return { networkUnit: 'Bytes' as const } - - try { - const settings = localStorage.getItem('unitsSettings') - if (settings) { - const parsed = JSON.parse(settings) - return { networkUnit: parsed.networkUnit || 'Bytes' } - } - } catch (e) { - console.error('[v0] Error reading units settings:', e) - } - - return { networkUnit: 'Bytes' as const } -} - -export const formatNetworkTraffic = (sizeInGB: number, unit: "Bytes" | "Bits" = "Bytes"): string => { - if (unit === "Bits") { - const sizeInGb = sizeInGB * 8 // Convert gigabytes to gigabits - - // Use decimal (base 1000) for bits - if (sizeInGb < 0.001) { - return `${(sizeInGb * 1000 * 1000).toFixed(2)} Mb` - } else if (sizeInGb < 1) { - return `${(sizeInGb * 1000).toFixed(2)} Mb` - } else if (sizeInGb < 1000) { - return `${sizeInGb.toFixed(1)} Gb` - } else if (sizeInGb < 1000000) { - return `${(sizeInGb / 1000).toFixed(2)} Tb` - } else { - return `${(sizeInGb / 1000000).toFixed(2)} Pb` - } - } else { - // Bytes mode - use binary base (1024) - if (sizeInGB < 1) { - return `${(sizeInGB * 1024).toFixed(1)} MB` - } else if (sizeInGB < 1024) { - return `${sizeInGB.toFixed(1)} GB` - } else { - return `${(sizeInGB / 1024).toFixed(1)} TB` - } - } -} - -export const getNetworkLabel = (unit: "Bytes" | "Bits", type: "received" | "sent"): string => { - if (unit === "Bits") { - return type === "received" ? "Bits Received" : "Bits Sent" - } - return type === "received" ? "Bytes Received" : "Bytes Sent" -}