From 7297edf16fa55cedd372543b34199d2ed576e31f Mon Sep 17 00:00:00 2001 From: MacRimi Date: Sun, 5 Oct 2025 15:44:19 +0200 Subject: [PATCH] Update AppImage --- AppImage/components/network-metrics.tsx | 437 +++++++++++------------ AppImage/components/virtual-machines.tsx | 63 +--- 2 files changed, 223 insertions(+), 277 deletions(-) diff --git a/AppImage/components/network-metrics.tsx b/AppImage/components/network-metrics.tsx index cc153ea..4169270 100644 --- a/AppImage/components/network-metrics.tsx +++ b/AppImage/components/network-metrics.tsx @@ -4,7 +4,7 @@ import { useState } from "react" import { Card, CardContent, CardHeader, CardTitle } from "./ui/card" import { Badge } from "./ui/badge" import { Dialog, DialogContent, DialogHeader, DialogTitle } from "./ui/dialog" -import { Wifi, Activity, Network, Router, AlertCircle, Zap } from "lucide-react" +import { Wifi, Activity, Network, Router, AlertCircle, Zap, Shield } from "lucide-react" import useSWR from "swr" interface NetworkData { @@ -214,6 +214,36 @@ export function NetworkMetrics() { + + + Firewall Status + + + +
Active
+ + Protected + +

System protected

+
+
+ + + + Packets + + + +
{packetsRecvK}K
+ + Received + +

No packet loss

+
+
+ + + {networkData.physical_interfaces && networkData.physical_interfaces.length > 0 && ( @@ -238,7 +268,7 @@ export function NetworkMetrics() { {/* First row: Icon, Name, Type Badge, Status */}
-
+
{interface_.name}
{typeBadge.label} @@ -297,208 +327,208 @@ export function NetworkMetrics() {
+ )} - {networkData.bridge_interfaces && networkData.bridge_interfaces.length > 0 && ( - - - - - Bridge Interfaces - - {networkData.bridge_active_count ?? 0} / {networkData.bridge_total_count ?? 0} Active - - - - -
- {networkData.bridge_interfaces.map((interface_, index) => { - const typeBadge = getInterfaceTypeBadge(interface_.type) + {networkData.bridge_interfaces && networkData.bridge_interfaces.length > 0 && ( + + + + + Bridge Interfaces + + {networkData.bridge_active_count ?? 0} / {networkData.bridge_total_count ?? 0} Active + + + + +
+ {networkData.bridge_interfaces.map((interface_, index) => { + const typeBadge = getInterfaceTypeBadge(interface_.type) - return ( -
setSelectedInterface(interface_)} - > - {/* First row: Icon, Name, Type Badge, Physical Interface, Status */} -
- -
-
{interface_.name}
- - {typeBadge.label} - - {interface_.bridge_physical_interface && ( -
- → {interface_.bridge_physical_interface} - {interface_.bridge_physical_interface.startsWith("bond") && - networkData.physical_interfaces && ( - <> - {(() => { - const bondInterface = networkData.physical_interfaces.find( - (iface) => iface.name === interface_.bridge_physical_interface, + return ( +
setSelectedInterface(interface_)} + > + {/* First row: Icon, Name, Type Badge, Physical Interface, Status */} +
+ +
+
{interface_.name}
+ + {typeBadge.label} + + {interface_.bridge_physical_interface && ( +
+ → {interface_.bridge_physical_interface} + {interface_.bridge_physical_interface.startsWith("bond") && + networkData.physical_interfaces && ( + <> + {(() => { + const bondInterface = networkData.physical_interfaces.find( + (iface) => iface.name === interface_.bridge_physical_interface, + ) + if (bondInterface?.bond_slaves && bondInterface.bond_slaves.length > 0) { + return ( + + ({bondInterface.bond_slaves.join(", ")}) + ) - if (bondInterface?.bond_slaves && bondInterface.bond_slaves.length > 0) { - return ( - - ({bondInterface.bond_slaves.join(", ")}) - - ) - } - return null - })()} - - )} - {interface_.bridge_bond_slaves && interface_.bridge_bond_slaves.length > 0 && ( - - ({interface_.bridge_bond_slaves.join(", ")}) - + } + return null + })()} + )} -
- )} -
- - {interface_.status.toUpperCase()} - -
- - {/* Second row: Details - Responsive layout */} -
-
-
IP Address
-
- {interface_.addresses.length > 0 ? interface_.addresses[0].ip : "N/A"} -
-
- -
-
Speed
-
- - {formatSpeed(interface_.speed)} -
-
- -
-
Traffic
-
- ↓ {formatBytes(interface_.bytes_recv)} - {" / "} - ↑ {formatBytes(interface_.bytes_sent)} -
-
- - {interface_.mac_address && ( -
-
MAC
-
- {interface_.mac_address} -
+ {interface_.bridge_bond_slaves && interface_.bridge_bond_slaves.length > 0 && ( + + ({interface_.bridge_bond_slaves.join(", ")}) + + )}
)}
+ + {interface_.status.toUpperCase()} +
- ) - })} -
- - - )} - {networkData.vm_lxc_interfaces && networkData.vm_lxc_interfaces.length > 0 && ( - - - - - VM & LXC Network Interfaces - - {networkData.vm_lxc_active_count ?? 0} / {networkData.vm_lxc_total_count ?? 0} Active - - - - -
- {networkData.vm_lxc_interfaces.map((interface_, index) => { - const vmTypeBadge = getVMTypeBadge(interface_.vm_type) - - return ( -
setSelectedInterface(interface_)} - > - {/* First row: Icon, Name, VM/LXC Badge, VM Name, Status */} -
- -
-
{interface_.name}
- - {vmTypeBadge.label} - - {interface_.vm_name && ( -
→ {interface_.vm_name}
- )} + {/* Second row: Details - Responsive layout */} +
+
+
IP Address
+
+ {interface_.addresses.length > 0 ? interface_.addresses[0].ip : "N/A"}
- - {interface_.status.toUpperCase()} -
- {/* Second row: Details - Responsive layout */} -
-
-
VMID
-
{interface_.vmid ?? "N/A"}
+
+
Speed
+
+ + {formatSpeed(interface_.speed)}
+
-
-
Speed
-
- - {formatSpeed(interface_.speed)} -
+
+
Traffic
+
+ ↓ {formatBytes(interface_.bytes_recv)} + {" / "} + ↑ {formatBytes(interface_.bytes_sent)}
+
+ {interface_.mac_address && (
-
Traffic
-
- ↓ {formatBytes(interface_.bytes_recv)} - {" / "} - ↑ {formatBytes(interface_.bytes_sent)} +
MAC
+
+ {interface_.mac_address}
+ )} +
+
+ ) + })} +
+ + + )} - {interface_.mac_address && ( -
-
MAC
-
- {interface_.mac_address} -
-
+ {networkData.vm_lxc_interfaces && networkData.vm_lxc_interfaces.length > 0 && ( + + + + + VM & LXC Network Interfaces + + {networkData.vm_lxc_active_count ?? 0} / {networkData.vm_lxc_total_count ?? 0} Active + + + + +
+ {networkData.vm_lxc_interfaces.map((interface_, index) => { + const vmTypeBadge = getVMTypeBadge(interface_.vm_type) + + return ( +
setSelectedInterface(interface_)} + > + {/* First row: Icon, Name, VM/LXC Badge, VM Name, Status */} +
+ +
+
{interface_.name}
+ + {vmTypeBadge.label} + + {interface_.vm_name && ( +
→ {interface_.vm_name}
)}
+ + {interface_.status.toUpperCase()} +
- ) - })} -
- - - )} -
+ + {/* Second row: Details - Responsive layout */} +
+
+
VMID
+
{interface_.vmid ?? "N/A"}
+
+ +
+
Speed
+
+ + {formatSpeed(interface_.speed)} +
+
+ +
+
Traffic
+
+ ↓ {formatBytes(interface_.bytes_recv)} + {" / "} + ↑ {formatBytes(interface_.bytes_sent)} +
+
+ + {interface_.mac_address && ( +
+
MAC
+
+ {interface_.mac_address} +
+
+ )} +
+
+ ) + })} +
+ + + )} {/* Interface Details Modal */} setSelectedInterface(null)}> @@ -532,51 +562,6 @@ export function NetworkMetrics() {
{selectedInterface.bridge_physical_interface}
- {selectedInterface.bridge_physical_interface.startsWith("bond") && - networkData?.physical_interfaces && ( - <> - {(() => { - const bondInterface = networkData.physical_interfaces.find( - (iface) => iface.name === selectedInterface.bridge_physical_interface, - ) - if (bondInterface?.bond_slaves && bondInterface.bond_slaves.length > 0) { - return ( -
-
Bond Slave Interfaces
-
- {bondInterface.bond_slaves.map((slave, idx) => ( - - {slave} - - ))} -
-
- ) - } - return null - })()} - - )} - {selectedInterface.bridge_bond_slaves && selectedInterface.bridge_bond_slaves.length > 0 && ( -
-
Bond Slave Interfaces
-
- {selectedInterface.bridge_bond_slaves.map((slave, idx) => ( - - {slave} - - ))} -
-
- )}
)} {selectedInterface.type === "vm_lxc" && selectedInterface.vm_name && ( diff --git a/AppImage/components/virtual-machines.tsx b/AppImage/components/virtual-machines.tsx index b0b2cdc..75abecd 100644 --- a/AppImage/components/virtual-machines.tsx +++ b/AppImage/components/virtual-machines.tsx @@ -19,7 +19,6 @@ import { RotateCcw, StopCircle, AlertTriangle, - CheckCircle, } from "lucide-react" import useSWR from "swr" @@ -38,7 +37,6 @@ interface VMData { netout?: number diskread?: number diskwrite?: number - ipaddress?: string } interface VMConfig { @@ -253,32 +251,6 @@ export function VirtualMachines() { return false }, [totalAllocatedMemoryGB, physicalMemoryGB]) - const getMemoryOvercommitBadge = () => { - if (!physicalMemoryGB) return null - - const allocated = Number.parseFloat(totalAllocatedMemoryGB) - const physical = Number.parseFloat(physicalMemoryGB) - const overcommitPercent = ((allocated / physical) * 100).toFixed(0) - - if (allocated > physical) { - return { - color: "bg-yellow-500/10 text-yellow-500 border-yellow-500/20", - icon: , - label: "Overcommit", - message: `${overcommitPercent}% de memoria física`, - } - } - - return { - color: "bg-green-500/10 text-green-500 border-green-500/20", - icon: , - label: "Normal", - message: `${overcommitPercent}% de memoria física`, - } - } - - const memoryBadge = getMemoryOvercommitBadge() - if (isLoading) { return (
@@ -334,20 +306,22 @@ export function VirtualMachines() { Total Memory - +
+ {isMemoryOvercommit && } + +
{totalAllocatedMemoryGB} GB
- {memoryBadge && ( -
- - {memoryBadge.icon} - {memoryBadge.label} - -

{memoryBadge.message}

-
+ {isMemoryOvercommit ? ( +

+ + Overcommit: Excede memoria física ({physicalMemoryGB} GB) +

+ ) : ( +

Allocated RAM

)}
@@ -422,13 +396,6 @@ export function VirtualMachines() {
- {vm.ipaddress && ( -
-
IP Address
-
{vm.ipaddress}
-
- )} -
CPU Usage
@@ -529,12 +496,6 @@ export function VirtualMachines() {
VMID
{selectedVM.vmid}
- {selectedVM.ipaddress && ( -
-
IP Address
-
{selectedVM.ipaddress}
-
- )}
CPU Usage
Uptime
-
{formatUptime(selectedVM.uptime)}
+
{formatUptime(selectedVM.uptime)}
Disk I/O