// src/components/handlers/sidebar.rs use ratatui::{ widgets::{Block, List, ListItem}, layout::{Rect, Direction, Layout, Constraint}, style::Style, Frame, }; use crate::config::colors::themes::Theme; use common::proto::multieko2::table_definition::{ProfileTreeResponse}; use ratatui::text::{Span, Line}; // Reduced sidebar width const SIDEBAR_WIDTH: u16 = 12; pub fn calculate_sidebar_layout(show_sidebar: bool, main_content_area: Rect) -> (Option, Rect) { if show_sidebar { let chunks = Layout::default() .direction(Direction::Horizontal) .constraints([ Constraint::Length(SIDEBAR_WIDTH), Constraint::Min(0), ]) .split(main_content_area); (Some(chunks[0]), chunks[1]) } else { (None, main_content_area) } } pub fn render_sidebar( f: &mut Frame, area: Rect, theme: &Theme, profile_tree: &ProfileTreeResponse, selected_profile: &Option, ) { let sidebar_block = Block::default().style(Style::default().bg(theme.bg)); let mut items = Vec::new(); if let Some(profile_name) = selected_profile { // Existing code for when a profile is selected... } else { // Show full profile tree when no profile is selected (compact version) for (profile_idx, profile) in profile_tree.profiles.iter().enumerate() { // Profile header - more compact items.push(ListItem::new(Line::from(vec![ Span::styled("◆", Style::default().fg(theme.accent)), Span::styled(&profile.name, Style::default().fg(theme.highlight)), ]))); // Tables with compact prefixes for (table_idx, table) in profile.tables.iter().enumerate() { let is_last_table = table_idx == profile.tables.len() - 1; let is_last_profile = profile_idx == profile_tree.profiles.len() - 1; // Shorter prefix characters let prefix = match (is_last_profile, is_last_table) { (true, true) => " └", (true, false) => " ├", (false, true) => "│└", (false, false) => "│├", }; // Get table name without year prefix to save space let display_name = if table.name.starts_with("2025_") { &table.name[5..] // Skip "2025_" prefix } else { &table.name }; let mut line = vec![ Span::styled(prefix, Style::default().fg(theme.fg)), Span::styled(display_name, Style::default().fg(theme.fg)), ]; // Show a simple indicator for dependencies instead of listing them if !table.depends_on.is_empty() { line.push(Span::styled( "→", Style::default().fg(theme.secondary) )); } items.push(ListItem::new(Line::from(line))); } // Compact separator between profiles if profile_idx < profile_tree.profiles.len() - 1 { items.push(ListItem::new(Line::from( Span::styled("│", Style::default().fg(theme.secondary)) ))); } } if profile_tree.profiles.is_empty() { items.push(ListItem::new(Span::styled( "No profiles", Style::default().fg(theme.secondary) ))); } } let list = List::new(items) .block(sidebar_block) .highlight_style(Style::default().fg(theme.highlight)) .highlight_symbol(">"); f.render_widget(list, area); }