// src/modes/canvas/common.rs use crossterm::event::{KeyEvent}; use crate::config::binds::config::Config; use crate::tui::terminal::grpc_client::GrpcClient; use crate::tui::terminal::core::TerminalCore; use crate::tui::controls::commands::CommandHandler; use crate::state::pages::form::FormState; use crate::state::state::AppState; use common::proto::multieko2::adresar::{PostAdresarRequest, PutAdresarRequest}; /// Main handler for common core actions pub async fn handle_core_action( action: &str, form_state: &mut FormState, grpc_client: &mut GrpcClient, command_handler: &mut CommandHandler, 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()) }