From 52d630a2e52ebca6006fda947458c7b7b31d0eb8 Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Wed, 22 Oct 2025 21:27:11 +0200 Subject: [PATCH] Remove legacy indexed disk metrics parsing Eliminate duplicate storage entries by removing old disk_count dependency. Dashboard now uses pure auto-discovery of disk_{pool}_usage_percent metrics. Fixes multiple storage instances (Storage 0, Storage 1, Storage root) showing only proper tree structure format. --- dashboard/src/ui/mod.rs | 77 +++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/dashboard/src/ui/mod.rs b/dashboard/src/ui/mod.rs index e6439c5..2b2412b 100644 --- a/dashboard/src/ui/mod.rs +++ b/dashboard/src/ui/mod.rs @@ -432,31 +432,6 @@ impl TuiApp { } if let Some(ref hostname) = self.current_host { - // Get storage pool count (renamed from disk_count in new architecture) - let pool_count = - if let Some(count_metric) = metric_store.get_metric(hostname, "disk_count") { - count_metric.value.as_i64().unwrap_or(0) as usize - } else { - 0 - }; - - if pool_count == 0 { - // No storage pools found - show error/waiting message - let content_chunks = ratatui::layout::Layout::default() - .direction(Direction::Vertical) - .constraints([Constraint::Length(1), Constraint::Min(0)]) - .split(area); - - let storage_title = Paragraph::new("Storage:").style(Typography::widget_title()); - frame.render_widget(storage_title, content_chunks[0]); - - let no_storage_spans = - StatusIcons::create_status_spans(Status::Unknown, "No storage pools detected"); - let no_storage_para = Paragraph::new(ratatui::text::Line::from(no_storage_spans)); - frame.render_widget(no_storage_para, content_chunks[1]); - return; - } - // Discover storage pools from metrics (look for disk_{pool}_usage_percent patterns) let mut storage_pools: std::collections::HashMap> = std::collections::HashMap::new(); @@ -498,6 +473,24 @@ impl TuiApp { } } + // Check if we found any storage pools + if storage_pools.is_empty() { + // No storage pools found - show error/waiting message + let content_chunks = ratatui::layout::Layout::default() + .direction(Direction::Vertical) + .constraints([Constraint::Length(1), Constraint::Min(0)]) + .split(area); + + let storage_title = Paragraph::new("Storage:").style(Typography::widget_title()); + frame.render_widget(storage_title, content_chunks[0]); + + let no_storage_spans = + StatusIcons::create_status_spans(Status::Unknown, "No storage pools detected"); + let no_storage_para = Paragraph::new(ratatui::text::Line::from(no_storage_spans)); + frame.render_widget(no_storage_para, content_chunks[1]); + return; + } + let available_lines = area.height as usize; let mut constraints = Vec::new(); let mut pools_to_show = Vec::new(); @@ -507,19 +500,30 @@ impl TuiApp { let mut sorted_pools: Vec<_> = storage_pools.iter().collect(); sorted_pools.sort_by_key(|(pool_name, _)| pool_name.as_str()); + // Add section title if we have pools + let mut title_added = false; + for (pool_name, drives) in sorted_pools { - // Calculate lines needed: title + usage + 1 line per drive - let lines_for_this_pool = 2 + drives.len(); + // Calculate lines needed: pool header + drives + usage line (+ section title if first) + let section_title_lines = if !title_added { 1 } else { 0 }; + let lines_for_this_pool = section_title_lines + 1 + drives.len() + 1; + if current_line + lines_for_this_pool <= available_lines { pools_to_show.push((pool_name.clone(), drives.clone())); - // Add constraints for this pool - constraints.push(Constraint::Length(1)); // Pool title - constraints.push(Constraint::Length(1)); // Pool usage line - for _ in 0..drives.len() { - constraints.push(Constraint::Length(1)); // Drive line (health/temp/wear) + // Add section title constraint if this is the first pool + if !title_added { + constraints.push(Constraint::Length(1)); // "Storage:" section title + title_added = true; } + // Add constraints for this pool + constraints.push(Constraint::Length(1)); // Pool header with status + for _ in 0..drives.len() { + constraints.push(Constraint::Length(1)); // Drive line with tree symbol + } + constraints.push(Constraint::Length(1)); // Usage line with end tree symbol + current_line += lines_for_this_pool; } else { break; // Can't fit more pools @@ -538,6 +542,13 @@ impl TuiApp { let mut chunk_index = 0; + // Render "Storage:" section title if we have pools + if !pools_to_show.is_empty() { + let storage_title = Paragraph::new("Storage:").style(Typography::widget_title()); + frame.render_widget(storage_title, content_chunks[chunk_index]); + chunk_index += 1; + } + // Display each storage pool with tree structure for (pool_name, drives) in &pools_to_show { // Pool header with status icon and type @@ -558,7 +569,7 @@ impl TuiApp { // Create pool header with status icon let pool_status_icon = StatusIcons::get_icon(pool_status); let pool_status_color = Theme::status_color(pool_status); - let pool_header_text = format!("Storage {} ({}):", pool_display_name, pool_type); + let pool_header_text = format!("{} ({}):", pool_display_name, pool_type); let pool_header_spans = vec![ ratatui::text::Span::styled(