diff --git a/client/src/components/admin/add_table.rs b/client/src/components/admin/add_table.rs index d2cfbbe..f29a246 100644 --- a/client/src/components/admin/add_table.rs +++ b/client/src/components/admin/add_table.rs @@ -15,8 +15,7 @@ use ratatui::{ use crate::components::handlers::canvas::render_canvas; /// Renders the Add New Table page layout, structuring the display of table information, -/// input fields, and action buttons, following the provided screenshot layout -/// with profile/table name on one line and a full-width Add button. +/// input fields, and action buttons. Adapts layout based on terminal width. pub fn render_add_table( f: &mut Frame, area: Rect, @@ -26,6 +25,10 @@ pub fn render_add_table( is_edit_mode: bool, // Determines if canvas inputs are in edit mode highlight_state: &HighlightState, // For text highlighting in canvas ) { + // --- Configuration --- + // Threshold width to switch between wide and narrow layouts + const NARROW_LAYOUT_THRESHOLD: u16 = 120; // Adjust this value as needed + // --- State Checks --- let focus_on_canvas_inputs = matches!( add_table_state.current_focus, @@ -35,9 +38,11 @@ pub fn render_add_table( ); // --- Main Page Block --- + // Use a centered title for wide, left for narrow? Or keep consistent? + // Let's keep it consistent for now (centered). let main_block = Block::default() .title(" Add New Table ") - .title_alignment(Alignment::Left) + .title_alignment(Alignment::Center) // Centered title .borders(Borders::ALL) .border_type(BorderType::Rounded) .border_style(Style::default().fg(theme.border)) @@ -45,62 +50,142 @@ pub fn render_add_table( let inner_area = main_block.inner(area); f.render_widget(main_block, area); - // --- Main Vertical Layout --- - let main_chunks = Layout::default() - .direction(Direction::Vertical) - .constraints([ - Constraint::Length(1), // Top: Profile & Committed Table Name (Single Row) - Constraint::Length(5), // Column Definition Input Canvas Area - Constraint::Length(3), // Add Button Area - Constraint::Min(5), // Columns Table Area - Constraint::Min(5), // Indexes & Links Area - Constraint::Length(3), // Bottom: Save/Cancel Buttons + // --- Area Variable Declarations --- + let top_info_area: Rect; + let columns_area: Rect; + let canvas_area: Rect; + let add_button_area: Rect; + let indexes_area: Rect; + let links_area: Rect; + let bottom_buttons_area: Rect; + + // --- Layout Decision --- + if area.width >= NARROW_LAYOUT_THRESHOLD { + // --- WIDE Layout (Based on first screenshot) --- + let main_chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Length(2), // Top Info (Profile/Table Name) + Constraint::Min(10), // Middle Area (Columns | Right Pane) + Constraint::Length(3), // Bottom Buttons + ]) + .split(inner_area); + + top_info_area = main_chunks[0]; + let middle_area = main_chunks[1]; + bottom_buttons_area = main_chunks[2]; + + // Split Middle Horizontally + let middle_chunks = Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage(60), // Left: Columns Table + Constraint::Percentage(40), // Right: Inputs etc. + ]) + .split(middle_area); + + columns_area = middle_chunks[0]; + let right_pane_area = middle_chunks[1]; + + // Split Right Pane Vertically + let right_pane_chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Length(5), // Input Canvas Area + Constraint::Length(3), // Add Button Area + Constraint::Min(5), // Indexes & Links Area + ]) + .split(right_pane_area); + + canvas_area = right_pane_chunks[0]; + add_button_area = right_pane_chunks[1]; + let indexes_links_area = right_pane_chunks[2]; + + // Split Indexes/Links Horizontally + let indexes_links_chunks = Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage(50), // Indexes Table + Constraint::Percentage(50), // Links Table + ]) + .split(indexes_links_area); + indexes_area = indexes_links_chunks[0]; + links_area = indexes_links_chunks[1]; + + // --- Top Info Rendering (Wide - 2 lines) --- + let profile_text = Paragraph::new(vec![ + Line::from(Span::styled( + format!("profile: {}", add_table_state.profile_name), + theme.fg, + )), + Line::from(Span::styled( + format!("table name: {}", add_table_state.table_name), + theme.fg, + )), ]) - .split(inner_area); + .block( + Block::default() // Add bottom border for separation + .borders(Borders::BOTTOM) + .border_style(Style::default().fg(theme.secondary)), + ); + f.render_widget(profile_text, top_info_area); + } else { + // --- NARROW Layout (Based on second screenshot) --- + let main_chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Length(1), // Top: Profile & Table Name (Single Row) + Constraint::Length(5), // Column Definition Input Canvas Area + Constraint::Length(3), // Add Button Area + Constraint::Min(5), // Columns Table Area + Constraint::Min(5), // Indexes & Links Area + Constraint::Length(3), // Bottom: Save/Cancel Buttons + ]) + .split(inner_area); - let top_info_area = main_chunks[0]; - let canvas_area = main_chunks[1]; - let add_button_area = main_chunks[2]; - let columns_area = main_chunks[3]; - let indexes_links_area = main_chunks[4]; - let bottom_buttons_area = main_chunks[5]; + top_info_area = main_chunks[0]; + canvas_area = main_chunks[1]; + add_button_area = main_chunks[2]; + columns_area = main_chunks[3]; + let indexes_links_area = main_chunks[4]; + bottom_buttons_area = main_chunks[5]; - // --- Top Info Rendering (Single Row) --- - let top_info_chunks = Layout::default() - .direction(Direction::Horizontal) - .constraints([ - Constraint::Percentage(50), // Adjust percentage as needed - Constraint::Percentage(50), - ]) - .split(top_info_area); + // Split Indexes/Links Horizontally + let indexes_links_chunks = Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage(50), // Indexes Table + Constraint::Percentage(50), // Links Table + ]) + .split(indexes_links_area); + indexes_area = indexes_links_chunks[0]; + links_area = indexes_links_chunks[1]; - let profile_text = Paragraph::new(Span::styled( - format!("profile: {}", add_table_state.profile_name), - theme.fg, - )) - .alignment(Alignment::Left); // Align left within its chunk - f.render_widget(profile_text, top_info_chunks[0]); + // --- Top Info Rendering (Narrow - 1 line) --- + let top_info_chunks = Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage(50), + Constraint::Percentage(50), + ]) + .split(top_info_area); - let table_name_text = Paragraph::new(Span::styled( - format!("table name: {}", add_table_state.table_name), - theme.fg, - )) - .alignment(Alignment::Left); // Align left within its chunk - f.render_widget(table_name_text, top_info_chunks[1]); + let profile_text = Paragraph::new(Span::styled( + format!("profile: {}", add_table_state.profile_name), + theme.fg, + )) + .alignment(Alignment::Left); + f.render_widget(profile_text, top_info_chunks[0]); - // --- Indexes & Links Layout (Horizontal Split) --- - let indexes_links_chunks = Layout::default() - .direction(Direction::Horizontal) - .constraints([ - Constraint::Percentage(50), // Indexes Table - Constraint::Percentage(50), // Links Table - ]) - .split(indexes_links_area); + let table_name_text = Paragraph::new(Span::styled( + format!("table name: {}", add_table_state.table_name), + theme.fg, + )) + .alignment(Alignment::Left); + f.render_widget(table_name_text, top_info_chunks[1]); + } - let indexes_area = indexes_links_chunks[0]; - let links_area = indexes_links_chunks[1]; - - // --- Widget Rendering --- + // --- Common Widget Rendering (Uses calculated areas) --- // --- Columns Table Rendering --- let columns_focused = @@ -121,6 +206,7 @@ pub fn render_add_table( .style(Style::default().fg(theme.fg)) }) .collect(); + // Use different headers/constraints based on layout? For now, keep consistent. let header_cells = ["Name", "Type"] .iter() .map(|h| Cell::from(*h).style(Style::default().fg(theme.accent))); @@ -134,7 +220,7 @@ pub fn render_add_table( Block::default() .title(Span::styled(" Columns ", theme.fg)) .title_alignment(Alignment::Center) - .borders(Borders::ALL) + .borders(Borders::ALL) // Use ALL borders for consistency .border_type(BorderType::Rounded) .border_style(columns_border_style), ) @@ -167,14 +253,14 @@ pub fn render_add_table( let get_button_style = |button_focus: AddTableFocus, current_focus| { let is_focused = current_focus == button_focus; let base_style = Style::default().fg(if is_focused { - theme.bg + theme.bg // Reversed text color } else { - theme.secondary + theme.secondary // Normal text color }); if is_focused { base_style .add_modifier(Modifier::BOLD) - .bg(theme.highlight) + .bg(theme.highlight) // Reversed background } else { base_style } @@ -187,7 +273,7 @@ pub fn render_add_table( } }; - // --- Add Button Rendering (Full Width) --- + // --- Add Button Rendering --- let add_button = Paragraph::new(" Add ") .style(get_button_style( AddTableFocus::AddColumnButton, @@ -203,8 +289,7 @@ pub fn render_add_table( add_table_state.current_focus, )), ); - // Render directly into the full area for the button row - f.render_widget(add_button, add_button_area); + f.render_widget(add_button, add_button_area); // Render into the calculated area // --- Indexes Table Rendering --- let indexes_focused =