diff --git a/client/src/services/ui_service.rs b/client/src/services/ui_service.rs index befffc9..53f463e 100644 --- a/client/src/services/ui_service.rs +++ b/client/src/services/ui_service.rs @@ -10,6 +10,63 @@ use anyhow::{Context, Result}; pub struct UiService; impl UiService { + pub async fn initialize_add_logic_table_data( + grpc_client: &mut GrpcClient, + add_logic_state: &mut AddLogicState, + profile_tree: &common::proto::multieko2::table_definition::ProfileTreeResponse, + ) -> Result { + let profile_name_clone_opt = Some(add_logic_state.profile_name.clone()); + let table_name_opt_clone = add_logic_state.selected_table_name.clone(); + + // Collect all table names from all profiles + let all_table_names: Vec = profile_tree.profiles + .iter() + .flat_map(|profile| profile.tables.iter()) + .map(|table| table.name.clone()) + .collect(); + + // Set all table names for autocomplete + add_logic_state.set_all_table_names(all_table_names.clone()); + + if let (Some(profile_name_clone), Some(table_name_clone)) = (profile_name_clone_opt, table_name_opt_clone) { + match grpc_client.get_table_structure(profile_name_clone.clone(), table_name_clone.clone()).await { + Ok(response) => { + let column_names: Vec = response.columns + .into_iter() + .map(|col| col.name) + .collect(); + + add_logic_state.set_table_columns(column_names.clone()); + + Ok(format!( + "Loaded {} columns for table '{}' and {} total tables for autocomplete", + column_names.len(), + table_name_clone, + all_table_names.len() + )) + } + Err(e) => { + tracing::warn!( + "Failed to fetch table structure for {}.{}: {}", + profile_name_clone, + table_name_clone, + e + ); + Ok(format!( + "Warning: Could not load table structure for '{}'. Autocomplete will use basic suggestions with {} tables.", + table_name_clone, + all_table_names.len() + )) + } + } + } else { + Ok(format!( + "No table selected for Add Logic. Loaded {} tables for autocomplete.", + all_table_names.len() + )) + } + } + pub async fn initialize_app_state( grpc_client: &mut GrpcClient, app_state: &mut AppState, @@ -38,49 +95,6 @@ impl UiService { Ok(column_names) } - pub async fn initialize_add_logic_table_data( - grpc_client: &mut GrpcClient, - add_logic_state: &mut AddLogicState, - ) -> Result { - let profile_name_clone_opt = Some(add_logic_state.profile_name.clone()); - let table_name_opt_clone = add_logic_state.selected_table_name.clone(); - - if let (Some(profile_name_clone), Some(table_name_clone)) = (profile_name_clone_opt, table_name_opt_clone) { - match grpc_client.get_table_structure(profile_name_clone.clone(), table_name_clone.clone()).await { - Ok(response) => { - let column_names: Vec = response.columns - .into_iter() - .map(|col| col.name) - .collect(); - - // This mutable borrow is now fine - add_logic_state.set_table_columns(column_names.clone()); - - Ok(format!( - "Loaded {} columns for table '{}' in profile '{}'", - column_names.len(), - table_name_clone, // Use cloned value - profile_name_clone // Use cloned value - )) - } - Err(e) => { - tracing::warn!( - "Failed to fetch table structure for {}.{}: {}", - profile_name_clone, // Use cloned value - table_name_clone, // Use cloned value - e - ); - Ok(format!( - "Warning: Could not load table structure for '{}'. Autocomplete will use basic suggestions.", - table_name_clone // Use cloned value - )) - } - } - } else { - Ok("No table selected or profile name missing for Add Logic".to_string()) - } - } - pub async fn initialize_adresar_count( grpc_client: &mut GrpcClient, app_state: &mut AppState, diff --git a/client/src/state/pages/add_logic.rs b/client/src/state/pages/add_logic.rs index eed8b45..993a7f6 100644 --- a/client/src/state/pages/add_logic.rs +++ b/client/src/state/pages/add_logic.rs @@ -48,6 +48,7 @@ pub struct AddLogicState { pub script_editor_suggestions: Vec, pub script_editor_selected_suggestion_index: Option, pub script_editor_trigger_position: Option<(usize, usize)>, // (line, column) + pub all_table_names: Vec, pub script_editor_filter_text: String, } @@ -82,6 +83,7 @@ impl AddLogicState { script_editor_suggestions: Vec::new(), script_editor_selected_suggestion_index: None, script_editor_trigger_position: None, + all_table_names: Vec::new(), script_editor_filter_text: String::new(), } } @@ -132,15 +134,18 @@ impl AddLogicState { /// Updates script editor suggestions based on current filter text pub fn update_script_editor_suggestions(&mut self) { let mut suggestions = vec!["sql".to_string()]; - - // Add actual table name if available + + // Add actual table name if available (current table) if let Some(ref table_name) = self.selected_table_name { suggestions.push(table_name.clone()); } - - // Add column names from the table + + // Add column names from the current table suggestions.extend(self.table_columns_for_suggestions.clone()); + // Add all table names from all profiles + suggestions.extend(self.all_table_names.clone()); + if self.script_editor_filter_text.is_empty() { self.script_editor_suggestions = suggestions; } else { @@ -173,6 +178,11 @@ impl AddLogicState { } } + /// Sets all available table names for autocomplete suggestions + pub fn set_all_table_names(&mut self, table_names: Vec) { + self.all_table_names = table_names; + } + /// Deactivates script editor autocomplete and clears related state pub fn deactivate_script_editor_autocomplete(&mut self) { self.script_editor_autocomplete_active = false; diff --git a/client/src/ui/handlers/ui.rs b/client/src/ui/handlers/ui.rs index 38057c2..02aeed3 100644 --- a/client/src/ui/handlers/ui.rs +++ b/client/src/ui/handlers/ui.rs @@ -163,22 +163,21 @@ pub async fn run_ui() -> Result<()> { // Ensure admin_state.add_logic_state matches the pending fetch if admin_state.add_logic_state.profile_name == profile_name && admin_state.add_logic_state.selected_table_name.as_deref() == Some(table_name.as_str()) { - + info!("Fetching table structure for {}.{}", profile_name, table_name); let fetch_message = UiService::initialize_add_logic_table_data( &mut grpc_client, &mut admin_state.add_logic_state, + &app_state.profile_tree, // Pass the profile tree ).await.unwrap_or_else(|e| { error!("Error initializing add_logic_table_data: {}", e); format!("Error fetching table structure: {}", e) }); - + if !fetch_message.contains("Error") && !fetch_message.contains("Warning") { info!("{}", fetch_message); - // Optionally update command message on success if desired - // event_handler.command_message = fetch_message; } else { - event_handler.command_message = fetch_message; // Show error/warning to user + event_handler.command_message = fetch_message; } needs_redraw = true; } else { @@ -188,15 +187,12 @@ pub async fn run_ui() -> Result<()> { admin_state.add_logic_state.profile_name, admin_state.add_logic_state.selected_table_name ); - // Cleared by .take(), no need to set to None explicitly unless re-queueing } } else { warn!( "Pending table structure fetch for {}.{} but AddLogic view is not active. Fetch ignored.", profile_name, table_name ); - // If you need to re-queue: - // app_state.pending_table_structure_fetch = Some((profile_name, table_name)); } }