diff --git a/dashboard/src/ui/widgets/backup.rs b/dashboard/src/ui/widgets/backup.rs index f34e481..3d2890b 100644 --- a/dashboard/src/ui/widgets/backup.rs +++ b/dashboard/src/ui/widgets/backup.rs @@ -390,15 +390,37 @@ impl Widget for BackupWidget { ratatui::text::Span::styled("Repos:", Typography::widget_title()) ])); - // Repository list + // Repository list with overflow handling + let remaining_space = area.height.saturating_sub(lines.len() as u16); + let mut repo_lines = Vec::new(); + for service in &self.service_metrics { if let (Some(archives), Some(size_gb)) = (service.archive_count, service.repo_size_gb) { let size_str = Self::format_size_with_proper_units(size_gb); let repo_text = format!("{} ({}) {}", service.name, archives, size_str); let repo_spans = StatusIcons::create_status_spans(service.status, &repo_text); - lines.push(ratatui::text::Line::from(repo_spans)); + repo_lines.push(ratatui::text::Line::from(repo_spans)); } } + + if repo_lines.len() <= remaining_space as usize { + // All repos fit + lines.extend(repo_lines); + } else if remaining_space >= 2 { + // Show what we can and add overflow indicator + let lines_to_show = (remaining_space - 1) as usize; // Reserve 1 line for overflow + lines.extend(repo_lines.iter().take(lines_to_show).cloned()); + + let hidden_repos = repo_lines.len() - lines_to_show; + let overflow_text = format!( + "... and {} more repo{}", + hidden_repos, + if hidden_repos == 1 { "" } else { "s" } + ); + lines.push(ratatui::text::Line::from(vec![ + ratatui::text::Span::styled(overflow_text, Typography::muted()) + ])); + } let paragraph = Paragraph::new(ratatui::text::Text::from(lines)); frame.render_widget(paragraph, area); diff --git a/dashboard/src/ui/widgets/system.rs b/dashboard/src/ui/widgets/system.rs index f2e6570..dee28e4 100644 --- a/dashboard/src/ui/widgets/system.rs +++ b/dashboard/src/ui/widgets/system.rs @@ -466,11 +466,50 @@ impl Widget for SystemWidget { Span::styled("Storage:", Typography::widget_title()) ])); - // Storage items - lines.extend(self.render_storage()); + // Storage items with overflow handling + let storage_lines = self.render_storage(); + let remaining_space = area.height.saturating_sub(lines.len() as u16); + + if storage_lines.len() <= remaining_space as usize { + // All storage lines fit + lines.extend(storage_lines); + } else if remaining_space >= 2 { + // Show what we can and add overflow indicator + let lines_to_show = (remaining_space - 1) as usize; // Reserve 1 line for overflow + lines.extend(storage_lines.iter().take(lines_to_show).cloned()); + + // Count hidden pools + let mut hidden_pools = 0; + let mut current_pool = String::new(); + for (i, line) in storage_lines.iter().enumerate() { + if i >= lines_to_show { + // Check if this line represents a new pool (no indentation) + if let Some(first_span) = line.spans.first() { + let text = first_span.content.as_ref(); + if !text.starts_with(" ") && text.contains(':') { + let pool_name = text.split(':').next().unwrap_or("").trim(); + if pool_name != current_pool { + hidden_pools += 1; + current_pool = pool_name.to_string(); + } + } + } + } + } + + if hidden_pools > 0 { + let overflow_text = format!( + "... and {} more pool{}", + hidden_pools, + if hidden_pools == 1 { "" } else { "s" } + ); + lines.push(Line::from(vec![ + Span::styled(overflow_text, Typography::muted()) + ])); + } + } let paragraph = Paragraph::new(Text::from(lines)); - frame.render_widget(paragraph, area); } } \ No newline at end of file