From fbbb4a4cfb834f2d33c34e9dce91cdc3d46bc1b4 Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Wed, 26 Nov 2025 18:10:08 +0100 Subject: [PATCH] Add subnet compression for IP address display Compress IPv4 addresses from same subnet to save space. Shows first IP in full (192.168.30.1) and subsequent IPs in same subnet with only last octet (100, 142). Version bump to 0.1.163 --- Cargo.lock | 6 ++--- agent/Cargo.toml | 2 +- dashboard/Cargo.toml | 2 +- dashboard/src/ui/widgets/system.rs | 42 +++++++++++++++++++++++++++--- shared/Cargo.toml | 2 +- 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a648fa5..45033f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cm-dashboard" -version = "0.1.162" +version = "0.1.163" dependencies = [ "anyhow", "chrono", @@ -301,7 +301,7 @@ dependencies = [ [[package]] name = "cm-dashboard-agent" -version = "0.1.162" +version = "0.1.163" dependencies = [ "anyhow", "async-trait", @@ -324,7 +324,7 @@ dependencies = [ [[package]] name = "cm-dashboard-shared" -version = "0.1.162" +version = "0.1.163" dependencies = [ "chrono", "serde", diff --git a/agent/Cargo.toml b/agent/Cargo.toml index 4ac864a..2280dd7 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-agent" -version = "0.1.162" +version = "0.1.163" edition = "2021" [dependencies] diff --git a/dashboard/Cargo.toml b/dashboard/Cargo.toml index 8a93d04..979564f 100644 --- a/dashboard/Cargo.toml +++ b/dashboard/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard" -version = "0.1.162" +version = "0.1.163" edition = "2021" [dependencies] diff --git a/dashboard/src/ui/widgets/system.rs b/dashboard/src/ui/widgets/system.rs index 9e46bf5..786e99b 100644 --- a/dashboard/src/ui/widgets/system.rs +++ b/dashboard/src/ui/widgets/system.rs @@ -580,6 +580,42 @@ impl SystemWidget { lines } + /// Compress IPv4 addresses from same subnet + /// Example: "192.168.30.1, 192.168.30.100" -> "192.168.30.1, 100" + fn compress_ipv4_addresses(addresses: &[String]) -> String { + if addresses.is_empty() { + return String::new(); + } + + if addresses.len() == 1 { + return addresses[0].clone(); + } + + let mut result = Vec::new(); + let mut last_prefix = String::new(); + + for addr in addresses { + let parts: Vec<&str> = addr.split('.').collect(); + if parts.len() == 4 { + let prefix = format!("{}.{}.{}", parts[0], parts[1], parts[2]); + + if prefix == last_prefix { + // Same subnet, show only last octet + result.push(parts[3].to_string()); + } else { + // Different subnet, show full IP + result.push(addr.clone()); + last_prefix = prefix; + } + } else { + // Invalid IP format, show as-is + result.push(addr.clone()); + } + } + + result.join(", ") + } + /// Render network section for display fn render_network(&self) -> Vec> { let mut lines = Vec::new(); @@ -595,12 +631,12 @@ impl SystemWidget { // Show interface name let mut interface_text = format!("{}: ", interface.name); - // Add IPv4 addresses + // Add compressed IPv4 addresses if !interface.ipv4_addresses.is_empty() { - interface_text.push_str(&interface.ipv4_addresses.join(", ")); + interface_text.push_str(&Self::compress_ipv4_addresses(&interface.ipv4_addresses)); } - // Add IPv6 addresses + // Add IPv6 addresses (no compression for now) if !interface.ipv6_addresses.is_empty() { if !interface.ipv4_addresses.is_empty() { interface_text.push_str(", "); diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 0aabbe6..f087439 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-shared" -version = "0.1.162" +version = "0.1.163" edition = "2021" [dependencies]