From 46149c09db7dd28083c78885500e18a545b5ff2a Mon Sep 17 00:00:00 2001 From: filipriec Date: Sat, 30 Aug 2025 16:42:04 +0200 Subject: [PATCH] event.rs and ui.rs refactor for the forms page(moved logic to the forms page dir and just calling it now) --- .../src/modes/general/command_navigation.rs | 2 - client/src/modes/handlers/event.rs | 57 ++++++++--------- client/src/pages/forms/event.rs | 62 +++++++++++++++++++ client/src/pages/forms/loader.rs | 39 ++++++++++++ client/src/pages/forms/mod.rs | 4 ++ client/src/ui/handlers/ui.rs | 58 ++++------------- 6 files changed, 143 insertions(+), 79 deletions(-) create mode 100644 client/src/pages/forms/event.rs create mode 100644 client/src/pages/forms/loader.rs diff --git a/client/src/modes/general/command_navigation.rs b/client/src/modes/general/command_navigation.rs index e484af2..1d01729 100644 --- a/client/src/modes/general/command_navigation.rs +++ b/client/src/modes/general/command_navigation.rs @@ -82,8 +82,6 @@ impl TableDependencyGraph { } } - -// ... (NavigationState struct and its new(), activate_*, deactivate(), add_char(), remove_char(), move_*, autocomplete_selected(), get_display_input() methods are unchanged) ... pub struct NavigationState { pub active: bool, pub input: String, diff --git a/client/src/modes/handlers/event.rs b/client/src/modes/handlers/event.rs index d22e332..9654927 100644 --- a/client/src/modes/handlers/event.rs +++ b/client/src/modes/handlers/event.rs @@ -36,6 +36,7 @@ use crate::pages::register::RegisterResult; use crate::pages::routing::{Router, Page}; use crate::movement::MovementAction; use crate::dialog; +use crate::pages::forms; use crate::pages::forms::FormState; use crate::pages::forms::logic::{save, revert, SaveOutcome}; use crate::search::state::SearchState; @@ -384,6 +385,14 @@ impl EventHandler { } } } + } else if let Page::Form(path) = &router.current { + // NEW: Delegate Form event handling + return forms::event::handle_form_event( + event, + app_state, + path, + &mut self.ideal_cursor_column + ); } } if toggle_sidebar( @@ -858,25 +867,14 @@ impl EventHandler { &mut self.auth_client, app_state, ) - .await?; + .await?; Ok(EventOutcome::Ok(message)) } else { - let save_outcome = if let Page::Form(path) = &router.current { - save( - app_state, - path, - &mut self.grpc_client, - ) - .await? + if let Page::Form(path) = &router.current { + forms::event::save_form(app_state, path, &mut self.grpc_client).await } else { - SaveOutcome::NoChange - }; - let message = match save_outcome { - SaveOutcome::NoChange => "No changes to save.".to_string(), - SaveOutcome::UpdatedExisting => "Entry updated.".to_string(), - SaveOutcome::CreatedNew(_) => "New entry created.".to_string(), - }; - Ok(EventOutcome::DataSaved(save_outcome, message)) + Ok(EventOutcome::Ok("Nothing to save".to_string())) + } } } "force_quit" => { @@ -898,19 +896,18 @@ impl EventHandler { &mut self.auth_client, app_state, ) - .await? - } else { - let save_outcome = if let Page::Form(path) = &router.current { - save(app_state, path, &mut self.grpc_client).await? - } else { - SaveOutcome::NoChange - }; - match save_outcome { - SaveOutcome::NoChange => "No changes to save.".to_string(), - SaveOutcome::UpdatedExisting => "Entry updated.".to_string(), - SaveOutcome::CreatedNew(_) => "New entry created.".to_string(), + .await? + } else if let Page::Form(path) = &router.current { + let save_result = forms::event::save_form(app_state, path, &mut self.grpc_client).await?; + match save_result { + EventOutcome::DataSaved(_, msg) => msg, + EventOutcome::Ok(msg) => msg, + _ => "Saved".to_string(), } + } else { + "No changes to save.".to_string() }; + if let Page::Form(path) = &router.current { if let Some(editor) = app_state.editor_for_path(path) { editor.cleanup_cursor()?; @@ -918,8 +915,8 @@ impl EventHandler { } terminal.cleanup()?; Ok(EventOutcome::Exit(format!( - "{}. Exiting application.", - message + "{}. Exiting application.", + message ))) } "revert" => { @@ -933,7 +930,7 @@ impl EventHandler { .await } else { if let Page::Form(path) = &router.current { - revert(app_state, path, &mut self.grpc_client).await? + return forms::event::revert_form(app_state, path, &mut self.grpc_client).await; } else { "Nothing to revert".to_string() } diff --git a/client/src/pages/forms/event.rs b/client/src/pages/forms/event.rs new file mode 100644 index 0000000..2a63e04 --- /dev/null +++ b/client/src/pages/forms/event.rs @@ -0,0 +1,62 @@ +// src/pages/forms/event.rs + +use anyhow::Result; +use crossterm::event::Event; +use canvas::keymap::KeyEventOutcome; +use crate::{ + state::app::state::AppState, + pages::forms::{FormState, logic}, + modes::handlers::event::EventOutcome, +}; + +pub fn handle_form_event( + event: Event, + app_state: &mut AppState, + path: &str, + ideal_cursor_column: &mut usize, +) -> Result { + if let Event::Key(key_event) = event { + if let Some(editor) = app_state.editor_for_path(path) { + match editor.handle_key_event(key_event) { + KeyEventOutcome::Consumed(Some(msg)) => { + return Ok(EventOutcome::Ok(msg)); + } + KeyEventOutcome::Consumed(None) => { + return Ok(EventOutcome::Ok("Form input updated".into())); + } + KeyEventOutcome::Pending => { + return Ok(EventOutcome::Ok("Waiting for next key...".into())); + } + KeyEventOutcome::NotMatched => { + // fall through to navigation / save / revert + } + } + } + } + + Ok(EventOutcome::Ok(String::new())) +} + +// Save wrapper +pub async fn save_form( + app_state: &mut AppState, + path: &str, + grpc_client: &mut crate::services::grpc_client::GrpcClient, +) -> Result { + let outcome = logic::save(app_state, path, grpc_client).await?; + let message = match outcome { + logic::SaveOutcome::NoChange => "No changes to save.".to_string(), + logic::SaveOutcome::UpdatedExisting => "Entry updated.".to_string(), + logic::SaveOutcome::CreatedNew(_) => "New entry created.".to_string(), + }; + Ok(EventOutcome::DataSaved(outcome, message)) +} + +pub async fn revert_form( + app_state: &mut AppState, + path: &str, + grpc_client: &mut crate::services::grpc_client::GrpcClient, +) -> Result { + let message = logic::revert(app_state, path, grpc_client).await?; + Ok(EventOutcome::Ok(message)) +} diff --git a/client/src/pages/forms/loader.rs b/client/src/pages/forms/loader.rs new file mode 100644 index 0000000..5836578 --- /dev/null +++ b/client/src/pages/forms/loader.rs @@ -0,0 +1,39 @@ +// src/pages/forms/loader.rs +use anyhow::{Context, Result}; +use crate::{ + state::app::state::AppState, + services::grpc_client::GrpcClient, + services::ui_service::UiService, // ✅ import UiService + config::binds::Config, + pages::forms::FormState, +}; + +pub async fn ensure_form_loaded_and_count( + grpc_client: &mut GrpcClient, + app_state: &mut AppState, + config: &Config, + profile: &str, + table: &str, +) -> Result<()> { + let path = format!("{}/{}", profile, table); + + app_state.ensure_form_editor(&path, config, || { + FormState::new(profile.to_string(), table.to_string(), vec![]) + }); + + if let Some(form_state) = app_state.form_state_for_path(&path) { + UiService::fetch_and_set_table_count(grpc_client, form_state) + .await + .context("Failed to fetch table count")?; + + if form_state.total_count > 0 { + UiService::load_table_data_by_position(grpc_client, form_state) + .await + .context("Failed to load table data")?; + } else { + form_state.reset_to_empty(); + } + } + + Ok(()) +} diff --git a/client/src/pages/forms/mod.rs b/client/src/pages/forms/mod.rs index 1afcdce..de211a6 100644 --- a/client/src/pages/forms/mod.rs +++ b/client/src/pages/forms/mod.rs @@ -3,7 +3,11 @@ pub mod ui; pub mod state; pub mod logic; +pub mod event; +pub mod loader; pub use ui::*; pub use state::*; pub use logic::*; +pub use event::*; +pub use loader::*; diff --git a/client/src/ui/handlers/ui.rs b/client/src/ui/handlers/ui.rs index 244b0a6..9a14c75 100644 --- a/client/src/ui/handlers/ui.rs +++ b/client/src/ui/handlers/ui.rs @@ -16,6 +16,7 @@ use crate::pages::admin::AdminState; use crate::pages::admin::AdminFocus; use crate::pages::intro::IntroState; use crate::pages::forms::{FormState, FieldDefinition}; +use crate::pages::forms; use crate::pages::routing::{Router, Page}; use crate::buffer::state::BufferState; use crate::buffer::state::AppView; @@ -459,7 +460,7 @@ pub async fn run_ui() -> Result<()> { } } - if let Page::Form(current_path) = &router.current { + if let Page::Form(_current_path) = &router.current { let current_view_profile = app_state.current_view_profile_name.clone(); let current_view_table = app_state.current_view_table_name.clone(); @@ -475,52 +476,16 @@ pub async fn run_ui() -> Result<()> { ); needs_redraw = true; - match UiService::load_table_view( + // DELEGATE to the forms loader + match forms::loader::ensure_form_loaded_and_count( &mut grpc_client, &mut app_state, + &config, prof_name, tbl_name, - ) - .await - { - Ok(new_form_state) => { - // Set the new form state and fetch count - let path = format!("{}/{}", prof_name, tbl_name); - app_state.ensure_form_editor(&path, &config, || new_form_state); - - if let Some(form_state) = app_state.form_state_for_path(&path) { - if let Err(e) = UiService::fetch_and_set_table_count( - &mut grpc_client, - form_state, - ) - .await - { - app_state.update_dialog_content( - &format!("Error fetching count: {}", e), - vec!["OK".to_string()], - DialogPurpose::LoginFailed, - ); - } else if form_state.total_count > 0 { - if let Err(e) = UiService::load_table_data_by_position( - &mut grpc_client, - form_state, - ) - .await - { - app_state.update_dialog_content( - &format!("Error loading data: {}", e), - vec!["OK".to_string()], - DialogPurpose::LoginFailed, - ); - } else { - app_state.hide_dialog(); - } - } else { - form_state.reset_to_empty(); - app_state.hide_dialog(); - } - } - + ).await { + Ok(()) => { + app_state.hide_dialog(); prev_view_profile_name = current_view_profile; prev_view_table_name = current_view_table; table_just_switched = true; @@ -531,10 +496,9 @@ pub async fn run_ui() -> Result<()> { vec!["OK".to_string()], DialogPurpose::LoginFailed, ); - app_state.current_view_profile_name = - prev_view_profile_name.clone(); - app_state.current_view_table_name = - prev_view_table_name.clone(); + // Reset to previous state on error + app_state.current_view_profile_name = prev_view_profile_name.clone(); + app_state.current_view_table_name = prev_view_table_name.clone(); } } }