From 3b130e9208fb76a0957e1c97f6fbaeed87ea9b5c Mon Sep 17 00:00:00 2001 From: filipriec Date: Mon, 1 Sep 2025 16:30:57 +0200 Subject: [PATCH] add_table fixing --- client/src/modes/handlers/event.rs | 18 +++++ .../src/pages/admin_panel/add_table/event.rs | 71 ++++++++++++++----- client/src/ui/handlers/ui.rs | 10 +-- 3 files changed, 75 insertions(+), 24 deletions(-) diff --git a/client/src/modes/handlers/event.rs b/client/src/modes/handlers/event.rs index ceb597e..2070c72 100644 --- a/client/src/modes/handlers/event.rs +++ b/client/src/modes/handlers/event.rs @@ -532,6 +532,24 @@ impl EventHandler { } if let Page::AddTable(add_table_state) = &mut router.current { + // Allow ":" (enter_command_mode) even when inside AddTable canvas + if let Some(action) = + config.get_general_action(key_event.code, key_event.modifiers) + { + if action == "enter_command_mode" + && !self.command_mode + && !app_state.ui.show_search_palette + && !self.navigation_state.active + { + self.command_mode = true; + self.command_input.clear(); + self.command_message.clear(); + self.key_sequence_tracker.reset(); + app_state.ui.focus_outside_canvas = true; + return Ok(EventOutcome::Ok(String::new())); + } + } + let client_clone = self.grpc_client.clone(); let sender_clone = self.save_table_result_sender.clone(); let outcome = crate::pages::admin_panel::add_table::event::handle_add_table_event( diff --git a/client/src/pages/admin_panel/add_table/event.rs b/client/src/pages/admin_panel/add_table/event.rs index 935146d..6842019 100644 --- a/client/src/pages/admin_panel/add_table/event.rs +++ b/client/src/pages/admin_panel/add_table/event.rs @@ -8,9 +8,10 @@ use crate::pages::admin_panel::add_table::logic::{ }; use crate::pages::admin_panel::add_table::nav::SaveTableResultSender; use crate::pages::admin_panel::add_table::state::{AddTableFocus, AddTableFormState}; -use crate::services::GrpcClient; +use crate::services::grpc_client::GrpcClient; use crate::state::app::state::AppState; use crate::modes::handlers::event::EventOutcome; +use canvas::{AppMode as CanvasMode, DataProvider}; use crossterm::event::KeyEvent; /// Focus traversal order for AddTable (outside canvas) @@ -24,11 +25,13 @@ const ADD_TABLE_FOCUS_ORDER: [AddTableFocus; 7] = [ AddTableFocus::CancelButton, ]; -/// Unified AddTable event handler (like AddLogic) +/// Handles all AddTable page-specific events. +/// Return a non-empty Ok(message) only when the page actually consumed the key, +/// otherwise return Ok("") to let global handling proceed. pub fn handle_add_table_event( key_event: KeyEvent, movement: Option, - _config: &Config, + config: &Config, app_state: &mut AppState, page: &mut AddTableFormState, mut grpc_client: GrpcClient, @@ -43,6 +46,36 @@ pub fn handle_add_table_event( ); if inside_canvas_inputs { + // Disable global shortcuts while typing + app_state.ui.focus_outside_canvas = false; + + // Special case: allow ":" to enter command mode even inside canvas + if let Some(action) = config.get_general_action(key_event.code, key_event.modifiers) { + if action == "enter_command_mode" + && !app_state.ui.show_search_palette + && !app_state.ui.dialog.dialog_show + { + app_state.ui.focus_outside_canvas = true; + return Ok(EventOutcome::Ok(String::new())); + } + } + + // Only allow leaving the canvas with Down/Next when in ReadOnly mode + let in_edit_mode = page.editor.mode() == CanvasMode::Edit; + if !in_edit_mode { + if let Some(ma) = movement { + let last_idx = page.editor.data_provider().field_count().saturating_sub(1); + let at_last = page.editor.current_field() >= last_idx; + if at_last && matches!(ma, MovementAction::Down | MovementAction::Next) { + page.state.last_canvas_field = last_idx; + page.set_current_focus(AddTableFocus::AddColumnButton); + app_state.ui.focus_outside_canvas = true; + return Ok(EventOutcome::Ok("Moved to Add button".to_string())); + } + } + } + + // Let the FormEditor handle typing match page.editor.handle_key_event(key_event) { canvas::keymap::KeyEventOutcome::Consumed(Some(msg)) => { page.sync_from_editor(); @@ -61,8 +94,19 @@ pub fn handle_add_table_event( } } - // 2) Movement outside canvas + // 2) Outside canvas if let Some(ma) = movement { + // First let the AddTable state's own movement handler process + if page.state.handle_movement(ma) { + app_state.ui.focus_outside_canvas = !matches!( + page.current_focus(), + AddTableFocus::InputTableName + | AddTableFocus::InputColumnName + | AddTableFocus::InputColumnType + ); + return Ok(EventOutcome::Ok(String::new())); + } + let mut current = page.current_focus(); if move_focus(&ADD_TABLE_FOCUS_ORDER, &mut current, ma) { page.set_current_focus(current); @@ -80,10 +124,7 @@ pub fn handle_add_table_event( MovementAction::Select => match page.current_focus() { AddTableFocus::AddColumnButton => { if let Some(focus_after_add) = - crate::pages::admin_panel::add_table::logic::handle_add_column_action( - &mut page.state, - &mut String::new(), - ) + handle_add_column_action(&mut page.state, &mut String::new()) { page.set_current_focus(focus_after_add); return Ok(EventOutcome::Ok("Column added".into())); @@ -100,25 +141,17 @@ pub fn handle_add_table_event( let state_clone = page.state.clone(); let sender_clone = save_result_sender.clone(); tokio::spawn(async move { - let result = - crate::pages::admin_panel::add_table::logic::handle_save_table_action( - &mut grpc_client, - &state_clone, - ) - .await; + let result = handle_save_table_action(&mut grpc_client, &state_clone).await; let _ = sender_clone.send(result).await; }); return Ok(EventOutcome::Ok("Saving table...".into())); } AddTableFocus::DeleteSelectedButton => { - let msg = - crate::pages::admin_panel::add_table::logic::handle_delete_selected_columns( - &mut page.state, - ); + let msg = handle_delete_selected_columns(&mut page.state); return Ok(EventOutcome::Ok(msg)); } AddTableFocus::CancelButton => { - return Ok(EventOutcome::Ok("Cancelled Add Table".into())); + return Ok(EventOutcome::Ok("Cancelled Add Table".to_string())); } _ => {} }, diff --git a/client/src/ui/handlers/ui.rs b/client/src/ui/handlers/ui.rs index 9ff930b..33e0aac 100644 --- a/client/src/ui/handlers/ui.rs +++ b/client/src/ui/handlers/ui.rs @@ -426,14 +426,14 @@ pub async fn run_ui() -> Result<()> { router.navigate(Page::Admin(admin_state.clone())); } AppView::AddTable => { - router.navigate(Page::AddTable( + if let Page::AddTable(_) = &router.current { + } else { + let mut page = add_table::state::AddTableFormState::from_state( admin_state.add_table_state.clone(), - ), - )); - if let Page::AddTable(page) = &mut router.current { - // Ensure keymap is set once + ); page.editor.set_keymap(config.build_canvas_keymap()); + router.navigate(Page::AddTable(page)); } } AppView::AddLogic => {