From c82b62f72be2149cd4a6dcf655496510ddb32eca Mon Sep 17 00:00:00 2001 From: filipriec Date: Mon, 31 Mar 2025 13:22:08 +0200 Subject: [PATCH] moving modes/canvas/common.rs into the functions --- client/src/tui/functions/common.rs | 2 + client/src/tui/functions/common/form.rs | 180 ++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 client/src/tui/functions/common/form.rs diff --git a/client/src/tui/functions/common.rs b/client/src/tui/functions/common.rs index 98b0ff7..b6774ad 100644 --- a/client/src/tui/functions/common.rs +++ b/client/src/tui/functions/common.rs @@ -1,4 +1,6 @@ // src/tui/functions/common.rs pub mod commands; +pub mod form; pub use commands::*; +pub use form::*; diff --git a/client/src/tui/functions/common/form.rs b/client/src/tui/functions/common/form.rs new file mode 100644 index 0000000..b8d6e68 --- /dev/null +++ b/client/src/tui/functions/common/form.rs @@ -0,0 +1,180 @@ +// src/tui/functions/common/form.rs + +use crate::config::binds::config::Config; +use crate::tui::terminal::core::TerminalCore; +use crate::state::pages::form::FormState; +use crate::state::state::AppState; +use crate::services::grpc_client::GrpcClient; + +use common::proto::multieko2::adresar::{PostAdresarRequest, PutAdresarRequest}; + +/// Main handler for common core actions that can be shared across different components +pub async fn handle_core_action( + action: &str, + form_state: &mut FormState, + grpc_client: &mut GrpcClient, + terminal: &mut TerminalCore, + app_state: &mut AppState, + current_position: &mut u64, + total_count: u64, +) -> Result<(bool, String), Box> { + match action { + "save" => { + let message = save( + form_state, + grpc_client, + &mut app_state.ui.is_saved, + current_position, + total_count, + ).await?; + Ok((false, message)) + }, + "force_quit" => { + terminal.cleanup()?; + Ok((true, "Force exiting without saving.".to_string())) + }, + "save_and_quit" => { + let message = save( + form_state, + grpc_client, + &mut app_state.ui.is_saved, + current_position, + total_count, + ).await?; + terminal.cleanup()?; + Ok((true, format!("{}. Exiting application.", message))) + }, + "revert" => { + let message = revert( + form_state, + grpc_client, + current_position, + total_count, + ).await?; + Ok((false, message)) + }, + // We should never hit this case with proper filtering + _ => Ok((false, format!("Core action not handled: {}", action))), + } +} + +/// Helper function to check if a key event should trigger a core action +pub fn is_core_action(config: &Config, key_code: crossterm::event::KeyCode, modifiers: crossterm::event::KeyModifiers) -> Option { + // Check for core application actions (save, quit, etc.) + if let Some(action) = config.get_action_for_key_in_mode( + &config.keybindings.common, + key_code, + modifiers + ) { + match action { + "save" | "force_quit" | "save_and_quit" | "revert" => { + return Some(action.to_string()) + }, + _ => {} // Other actions are handled by their respective mode handlers + } + } + None +} + +/// Shared logic for saving the current form state +pub async fn save( + form_state: &mut FormState, + grpc_client: &mut GrpcClient, + is_saved: &mut bool, + current_position: &mut u64, + total_count: u64, +) -> Result> { + let is_new = *current_position == total_count + 1; + + let message = if is_new { + let post_request = PostAdresarRequest { + firma: form_state.values[0].clone(), + kz: form_state.values[1].clone(), + drc: form_state.values[2].clone(), + ulica: form_state.values[3].clone(), + psc: form_state.values[4].clone(), + mesto: form_state.values[5].clone(), + stat: form_state.values[6].clone(), + banka: form_state.values[7].clone(), + ucet: form_state.values[8].clone(), + skladm: form_state.values[9].clone(), + ico: form_state.values[10].clone(), + kontakt: form_state.values[11].clone(), + telefon: form_state.values[12].clone(), + skladu: form_state.values[13].clone(), + fax: form_state.values[14].clone(), + }; + let response = grpc_client.post_adresar(post_request).await?; + let new_total = grpc_client.get_adresar_count().await?; + *current_position = new_total; + form_state.id = response.into_inner().id; + "New entry created".to_string() + } else { + let put_request = PutAdresarRequest { + id: form_state.id, + firma: form_state.values[0].clone(), + kz: form_state.values[1].clone(), + drc: form_state.values[2].clone(), + ulica: form_state.values[3].clone(), + psc: form_state.values[4].clone(), + mesto: form_state.values[5].clone(), + stat: form_state.values[6].clone(), + banka: form_state.values[7].clone(), + ucet: form_state.values[8].clone(), + skladm: form_state.values[9].clone(), + ico: form_state.values[10].clone(), + kontakt: form_state.values[11].clone(), + telefon: form_state.values[12].clone(), + skladu: form_state.values[13].clone(), + fax: form_state.values[14].clone(), + }; + let _ = grpc_client.put_adresar(put_request).await?; + "Entry updated".to_string() + }; + + *is_saved = true; + form_state.has_unsaved_changes = false; + Ok(message) +} + +/// Discard changes since last save +pub async fn revert( + form_state: &mut FormState, + grpc_client: &mut GrpcClient, + current_position: &mut u64, + total_count: u64, +) -> Result> { + let is_new = *current_position == total_count + 1; + + if is_new { + // Clear all fields for new entries + form_state.values.iter_mut().for_each(|v| *v = String::new()); + form_state.has_unsaved_changes = false; + return Ok("New entry cleared".to_string()); + } + + let data = grpc_client.get_adresar_by_position(*current_position).await?; + + // Update form fields with saved values + form_state.values = vec![ + data.firma, + data.kz, + data.drc, + data.ulica, + data.psc, + data.mesto, + data.stat, + data.banka, + data.ucet, + data.skladm, + data.ico, + data.kontakt, + data.telefon, + data.skladu, + data.fax, + ]; + + form_state.has_unsaved_changes = false; + Ok("Changes discarded, reloaded last saved version".to_string()) +} +