From 60ab4d4f9ea4ffa6cd75b3ecf2dad489f1dbda3c Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Sun, 30 Nov 2025 12:09:44 +0100 Subject: [PATCH] Fix service panel column width calculation Replace hardcoded terminal width thresholds with dynamic calculation based on actual column requirements. Column visibility now adapts correctly at 58, 52, 43, and 34 character widths instead of the previous arbitrary 80, 60, 45 thresholds. - Add width constants for each column (NAME=23, STATUS=10, etc) - Calculate cumulative widths dynamically for each layout tier - Ensure header and data formatting use consistent width values - Fix service name truncation to respect calculated column width --- Cargo.lock | 6 +-- agent/Cargo.toml | 2 +- dashboard/Cargo.toml | 2 +- dashboard/src/ui/widgets/services.rs | 57 ++++++++++++++++++---------- shared/Cargo.toml | 2 +- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index faa78c3..459526f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cm-dashboard" -version = "0.1.226" +version = "0.1.227" dependencies = [ "anyhow", "chrono", @@ -301,7 +301,7 @@ dependencies = [ [[package]] name = "cm-dashboard-agent" -version = "0.1.226" +version = "0.1.227" dependencies = [ "anyhow", "async-trait", @@ -325,7 +325,7 @@ dependencies = [ [[package]] name = "cm-dashboard-shared" -version = "0.1.226" +version = "0.1.227" dependencies = [ "chrono", "serde", diff --git a/agent/Cargo.toml b/agent/Cargo.toml index 2862ba6..958fe0b 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-agent" -version = "0.1.227" +version = "0.1.228" edition = "2021" [dependencies] diff --git a/dashboard/Cargo.toml b/dashboard/Cargo.toml index a41a5dd..a704050 100644 --- a/dashboard/Cargo.toml +++ b/dashboard/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard" -version = "0.1.227" +version = "0.1.228" edition = "2021" [dependencies] diff --git a/dashboard/src/ui/widgets/services.rs b/dashboard/src/ui/widgets/services.rs index 9607137..8829575 100644 --- a/dashboard/src/ui/widgets/services.rs +++ b/dashboard/src/ui/widgets/services.rs @@ -22,10 +22,25 @@ struct ColumnVisibility { } impl ColumnVisibility { + /// Calculate actual width needed for all columns + const NAME_WIDTH: u16 = 23; + const STATUS_WIDTH: u16 = 10; + const RAM_WIDTH: u16 = 8; + const UPTIME_WIDTH: u16 = 8; + const RESTARTS_WIDTH: u16 = 5; + const COLUMN_SPACING: u16 = 1; // Space between columns + /// Determine which columns to show based on available width + /// Priority order: Name > Status > RAM > Uptime > Restarts fn from_width(width: u16) -> Self { - if width >= 80 { - // Full layout: Name (25) + Status (10) + RAM (8) + Uptime (8) + Restarts (5) = 56 chars + // Calculate cumulative widths for each configuration + let minimal = Self::NAME_WIDTH + Self::COLUMN_SPACING + Self::STATUS_WIDTH; // 34 + let with_ram = minimal + Self::COLUMN_SPACING + Self::RAM_WIDTH; // 43 + let with_uptime = with_ram + Self::COLUMN_SPACING + Self::UPTIME_WIDTH; // 52 + let full = with_uptime + Self::COLUMN_SPACING + Self::RESTARTS_WIDTH; // 58 + + if width >= full { + // Show all columns Self { show_name: true, show_status: true, @@ -33,8 +48,8 @@ impl ColumnVisibility { show_uptime: true, show_restarts: true, } - } else if width >= 60 { - // Hide restarts: Name (25) + Status (10) + RAM (8) + Uptime (8) = 51 chars + } else if width >= with_uptime { + // Hide restarts Self { show_name: true, show_status: true, @@ -42,8 +57,8 @@ impl ColumnVisibility { show_uptime: true, show_restarts: false, } - } else if width >= 45 { - // Hide uptime and restarts: Name (25) + Status (10) + RAM (8) = 43 chars + } else if width >= with_ram { + // Hide uptime and restarts Self { show_name: true, show_status: true, @@ -52,7 +67,7 @@ impl ColumnVisibility { show_restarts: false, } } else { - // Minimal: Name (25) + Status (10) = 35 chars + // Minimal: Name + Status only Self { show_name: true, show_status: true, @@ -130,9 +145,11 @@ impl ServicesWidget { /// Format parent service line - returns text without icon for span formatting fn format_parent_service_line(&self, name: &str, info: &ServiceInfo, columns: ColumnVisibility) -> String { - // Truncate long service names to fit layout (account for icon space) - let short_name = if name.len() > 22 { - format!("{}...", &name[..19]) + // Truncate long service names to fit layout + // NAME_WIDTH - 3 chars for "..." = max displayable chars + let max_name_len = (ColumnVisibility::NAME_WIDTH - 3) as usize; + let short_name = if name.len() > max_name_len { + format!("{}...", &name[..max_name_len.saturating_sub(3)]) } else { name.to_string() }; @@ -185,19 +202,19 @@ impl ServicesWidget { // Build format string based on column visibility let mut parts = Vec::new(); if columns.show_name { - parts.push(format!("{:<23}", short_name)); + parts.push(format!("{: