From e921862a7f553bb9a44b9176eb972e4f9c6cad32 Mon Sep 17 00:00:00 2001 From: filipriec Date: Thu, 17 Apr 2025 14:41:09 +0200 Subject: [PATCH] compiled, still not working for canvas --- client/src/components/admin/add_table.rs | 161 +++++++++++++----- .../modes/navigation/add_table_nav.rs | 20 ++- client/src/modes/handlers/event.rs | 5 +- 3 files changed, 136 insertions(+), 50 deletions(-) diff --git a/client/src/components/admin/add_table.rs b/client/src/components/admin/add_table.rs index 33d1d2a..5c0fe28 100644 --- a/client/src/components/admin/add_table.rs +++ b/client/src/components/admin/add_table.rs @@ -1,28 +1,37 @@ // src/components/admin/add_table.rs use crate::config::colors::themes::Theme; +use crate::state::app::highlight::HighlightState; +use crate::state::app::state::AppState; +use crate::state::pages::add_table::{AddTableFocus, AddTableState}; +use crate::state::pages::canvas_state::CanvasState; use ratatui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, - style::{Style, Stylize}, + style::{Modifier, Style, Stylize}, text::{Line, Span}, widgets::{Block, BorderType, Borders, Paragraph}, Frame, }; -use crate::state::app::state::AppState; -use crate::state::app::highlight::HighlightState; -use crate::state::pages::canvas_state::CanvasState; +// Assuming render_canvas exists and works like in register.rs use crate::components::handlers::canvas::render_canvas; -use crate::state::pages::add_table::AddTableState; -/// Renders a placeholder page for adding tables. +/// Renders the Add New Table page layout. pub fn render_add_table( f: &mut Frame, area: Rect, theme: &Theme, - _app_state: &AppState, + app_state: &AppState, // Changed back from _app_state as it's needed for focus_outside_canvas check potentially add_table_state: &mut AddTableState, - is_edit_mode: bool, + is_edit_mode: bool, // This comes from the main event loop based on AppMode highlight_state: &HighlightState, ) { + // Determine if focus is on canvas inputs vs other elements based on AddTableState + let focus_on_canvas_inputs = matches!( + add_table_state.current_focus, + AddTableFocus::InputTableName + | AddTableFocus::InputColumnName + | AddTableFocus::InputColumnType + ); + // Main block for the whole page let main_block = Block::default() .title(" Add New Table ") @@ -51,17 +60,24 @@ pub fn render_add_table( .constraints([ Constraint::Length(3), // Profile & Table Name header Constraint::Min(5), // Columns section (expandable) - Constraint::Length(1), // Separator + Constraint::Length(1), // Separator (placeholder for now) Constraint::Min(3), // Indexes section (expandable) - Constraint::Length(1), // Separator + Constraint::Length(1), // Separator (placeholder for now) Constraint::Min(3), // Links section (expandable) ].as_ref()) .split(left_pane); - // Profile & Table Name section + // --- Left Pane Rendering --- + // Profile & Table Name section (Displays current state) let profile_text = Paragraph::new(vec![ - Line::from(Span::styled("profile: default", theme.fg)), // Placeholder - Line::from(Span::styled("table name: [tablename]", theme.fg)), // Placeholder + Line::from(Span::styled( + format!("profile: {}", add_table_state.profile_name), // Use actual profile + theme.fg, + )), + Line::from(Span::styled( + format!("table name: {}", add_table_state.table_name), // Use actual table name (from input) + theme.fg, + )), ]) .block( Block::default() @@ -70,36 +86,67 @@ pub fn render_add_table( ); f.render_widget(profile_text, left_vertical_chunks[0]); - // Columns section - let columns_text = Paragraph::new(vec![ + // --- Columns Table --- + let columns_focused = + add_table_state.current_focus == AddTableFocus::ColumnsTable; + let columns_border_style = if columns_focused { + Style::default().fg(theme.highlight) + } else { + Style::default().fg(theme.secondary) + }; + // TODO: Replace this Paragraph with a Table widget rendering add_table_state.columns + let columns_content = Paragraph::new(vec![ Line::from(Span::styled("Name Type", theme.accent)), // Header + Line::from("... Column list placeholder ..."), // Placeholder content ]) - .block(Block::default().title(Span::styled(" Columns ", theme.fg))); - f.render_widget(columns_text, left_vertical_chunks[1]); + .block( + Block::default() + .title(Span::styled(" Columns ", theme.fg)) + .borders(Borders::TOP) // Separator from Profile/Name + .border_style(columns_border_style), // Indicate focus + ); + f.render_widget(columns_content, left_vertical_chunks[1]); - // Indexes section - let indexes_text = Paragraph::new(vec![ + // --- Indexes Table --- + let indexes_focused = + add_table_state.current_focus == AddTableFocus::IndexesTable; + let indexes_border_style = if indexes_focused { + Style::default().fg(theme.highlight) + } else { + Style::default().fg(theme.secondary) + }; + // TODO: Replace this Paragraph with a Table/List widget for add_table_state.indexes + let indexes_content = Paragraph::new(vec![ Line::from(Span::styled("Column name", theme.accent)), // Header + Line::from("... Index list placeholder ..."), ]) .block( Block::default() .title(Span::styled(" Indexes ", theme.fg)) .borders(Borders::TOP) // Separator from Columns - .border_style(Style::default().fg(theme.secondary)), + .border_style(indexes_border_style), // Indicate focus ); - f.render_widget(indexes_text, left_vertical_chunks[3]); + f.render_widget(indexes_content, left_vertical_chunks[3]); - // Links section - let links_text = Paragraph::new(vec![ + // --- Links Table --- + let links_focused = add_table_state.current_focus == AddTableFocus::LinksTable; + let links_border_style = if links_focused { + Style::default().fg(theme.highlight) + } else { + Style::default().fg(theme.secondary) + }; + // TODO: Replace this Paragraph with a Table widget for add_table_state.links + let links_content = Paragraph::new(vec![ Line::from(Span::styled("Linked table Required", theme.accent)), // Header + Line::from("... Link list placeholder ..."), ]) .block( Block::default() .title(Span::styled(" Links ", theme.fg)) .borders(Borders::TOP) // Separator from Indexes - .border_style(Style::default().fg(theme.secondary)), + .border_style(links_border_style), // Indicate focus ); - f.render_widget(links_text, left_vertical_chunks[5]); + f.render_widget(links_content, left_vertical_chunks[5]); // --- Right Pane --- let right_vertical_chunks = Layout::default() @@ -117,31 +164,58 @@ pub fn render_add_table( let bottom_buttons_area = right_vertical_chunks[3]; // --- Use render_canvas for Inputs --- + // Pass is_edit_mode determined by the main loop based on AppMode + // Only show edit styling if AppMode is Edit AND focus is on one of the canvas inputs let _active_field_rect = render_canvas( f, canvas_area, - add_table_state, - &[ - "Table name", - "Name", - "Type", - ], + add_table_state, // Implements CanvasState + &add_table_state.fields(), // Get field names from state &add_table_state.current_field(), - &add_table_state.inputs().iter().map(|s| *s).collect::>(), + &add_table_state.inputs(), // Get inputs from state theme, - is_edit_mode, + is_edit_mode && focus_on_canvas_inputs, // Only truly edit mode if focus is on canvas highlight_state, ); - // Add Button (Placeholder) + // --- Buttons --- + // Helper to get style based on focus + let get_button_style = |button_focus: AddTableFocus| { + let is_focused = add_table_state.current_focus == button_focus; + // Base style: secondary color, unless focused then highlight color + let mut style = Style::default().fg(if is_focused { + theme.highlight + } else { + theme.secondary + }); + // Apply bold and reverse if focused + if is_focused { + style = style + .add_modifier(Modifier::BOLD) + .add_modifier(Modifier::REVERSED); + } + style + }; + // Helper to get border style based on focus + let get_button_border_style = |button_focus: AddTableFocus| { + if add_table_state.current_focus == button_focus { + Style::default().fg(theme.highlight) // Highlight border when focused + } else { + Style::default().fg(theme.secondary) // Dim border otherwise + } + }; + + // Add Button let add_button = Paragraph::new(" Add ") - .style(Style::default().fg(theme.secondary)) + .style(get_button_style(AddTableFocus::AddColumnButton)) .alignment(Alignment::Center) .block( Block::default() .borders(Borders::ALL) .border_type(BorderType::Rounded) - .border_style(Style::default().fg(theme.secondary)), + .border_style(get_button_border_style( + AddTableFocus::AddColumnButton, + )), ); f.render_widget(add_button, add_button_area); @@ -154,27 +228,30 @@ pub fn render_add_table( ].as_ref()) .split(bottom_buttons_area); - // Save Button (Placeholder) + // Save Button let save_button = Paragraph::new(" Save table ") - .style(Style::default().fg(theme.secondary)) + .style(get_button_style(AddTableFocus::SaveButton)) .alignment(Alignment::Center) .block( Block::default() .borders(Borders::ALL) .border_type(BorderType::Rounded) - .border_style(Style::default().fg(theme.secondary)), + .border_style(get_button_border_style(AddTableFocus::SaveButton)), ); f.render_widget(save_button, bottom_button_chunks[0]); - // Cancel Button (Placeholder) + // Cancel Button let cancel_button = Paragraph::new(" Cancel ") - .style(Style::default().fg(theme.secondary)) + .style(get_button_style(AddTableFocus::CancelButton)) .alignment(Alignment::Center) .block( Block::default() .borders(Borders::ALL) .border_type(BorderType::Rounded) - .border_style(Style::default().fg(theme.secondary)), + .border_style(get_button_border_style( + AddTableFocus::CancelButton, + )), ); f.render_widget(cancel_button, bottom_button_chunks[1]); } + diff --git a/client/src/functions/modes/navigation/add_table_nav.rs b/client/src/functions/modes/navigation/add_table_nav.rs index a0e1cbd..184c412 100644 --- a/client/src/functions/modes/navigation/add_table_nav.rs +++ b/client/src/functions/modes/navigation/add_table_nav.rs @@ -12,7 +12,7 @@ use ratatui::widgets::TableState; pub fn handle_add_table_navigation( key: KeyEvent, config: &Config, - _app_state: &AppState, + app_state: &mut AppState, add_table_state: &mut AddTableState, command_message: &mut String, ) -> bool { @@ -25,9 +25,11 @@ pub fn handle_add_table_navigation( let is_left_pane_focus = matches!(current_focus, AddTableFocus::ColumnsTable | AddTableFocus::IndexesTable | AddTableFocus::LinksTable ); - let is_right_pane_focus = matches!(current_focus, - AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType | - AddTableFocus::AddColumnButton | AddTableFocus::SaveButton | AddTableFocus::CancelButton + let is_right_pane_general_focus = matches!(current_focus, // Non-canvas elements in right pane + AddTableFocus::AddColumnButton | AddTableFocus::SaveButton | AddTableFocus::CancelButton + ); + let is_canvas_input_focus = matches!(current_focus, + AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType ); match action.as_deref() { @@ -95,7 +97,7 @@ pub fn handle_add_table_navigation( AddTableFocus::LinksTable => AddTableFocus::SaveButton, _ => current_focus, // Should not happen based on is_left_pane_focus }; - } else if is_right_pane_focus { + } else if is_right_pane_general_focus || is_canvas_input_focus { // If already in right pane, maybe wrap Save -> Cancel or stay? Let's handle Save->Cancel only. if current_focus == AddTableFocus::SaveButton { new_focus = AddTableFocus::CancelButton; @@ -103,7 +105,7 @@ pub fn handle_add_table_navigation( } } Some("previous_option") => { // 'h' or Left: Move from Right Pane to Left Pane - if is_right_pane_focus { + if is_right_pane_general_focus { new_focus = match current_focus { // Map right pane items back to left pane items (approximate vertical alignment) AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType | AddTableFocus::AddColumnButton => AddTableFocus::ColumnsTable, // Go to top of left pane @@ -196,6 +198,12 @@ pub fn handle_add_table_navigation( add_table_state.current_focus = new_focus; *command_message = format!("Focus set to {:?}", add_table_state.current_focus); + let new_is_canvas_input_focus = matches!(new_focus, + AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType + ); + app_state.ui.focus_outside_canvas = !new_is_canvas_input_focus; + + // Select first item when focusing a table match add_table_state.current_focus { AddTableFocus::ColumnsTable if add_table_state.column_table_state.selected().is_none() && !add_table_state.columns.is_empty() => { diff --git a/client/src/modes/handlers/event.rs b/client/src/modes/handlers/event.rs index ab43874..88d0fe8 100644 --- a/client/src/modes/handlers/event.rs +++ b/client/src/modes/handlers/event.rs @@ -274,7 +274,7 @@ impl EventHandler { return Ok(EventOutcome::Ok(self.command_message.clone())); } // Check for entering edit mode (before cursor) - else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_edit_mode_before") + else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_before") && ModeManager::can_enter_edit_mode(current_mode) { self.is_edit_mode = true; self.edit_mode_cooldown = true; @@ -283,7 +283,7 @@ impl EventHandler { return Ok(EventOutcome::Ok(self.command_message.clone())); } // Check for entering edit mode (after cursor) - else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_edit_mode_after") + else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_after") && ModeManager::can_enter_edit_mode(current_mode) { let current_input = if app_state.ui.show_login || app_state.ui.show_register{ login_state.get_current_input() @@ -307,6 +307,7 @@ impl EventHandler { } self.is_edit_mode = true; self.edit_mode_cooldown = true; + app_state.ui.focus_outside_canvas = false; self.command_message = "Edit mode (after cursor)".to_string(); terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?; return Ok(EventOutcome::Ok(self.command_message.clone()));