Add overflow handling to system and backup widgets

Restore "... and X more" indicators when panel content doesn't fit:
- System widget: Shows overflow for storage pools when area is too small
- Backup widget: Shows overflow for repository list when area is too small
- Maintains consistent formatting with existing services widget overflow
This commit is contained in:
Christoffer Martinsson 2025-10-23 20:12:01 +02:00
parent ecee256f91
commit 65479c14af
2 changed files with 66 additions and 5 deletions

View File

@ -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);

View File

@ -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);
}
}