automcomplete running and working now
This commit is contained in:
@@ -5,26 +5,27 @@ use crate::state::pages::{
|
||||
auth::{LoginState, RegisterState},
|
||||
canvas_state::CanvasState,
|
||||
};
|
||||
use crate::state::pages::add_logic::AddLogicState;
|
||||
use crate::state::pages::form::FormState;
|
||||
use crate::state::pages::add_table::AddTableState;
|
||||
use crate::state::pages::form::FormState; // <<< ADD THIS LINE
|
||||
// AddLogicState is already imported
|
||||
// AddTableState is already imported
|
||||
use crate::state::pages::admin::AdminState;
|
||||
use crate::modes::handlers::event::EventOutcome;
|
||||
use crate::functions::modes::edit::{add_logic_e, auth_e, form_e, add_table_e};
|
||||
use crate::state::app::state::AppState;
|
||||
use anyhow::Result;
|
||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
||||
use crossterm::event::KeyEvent; // Removed KeyCode, KeyModifiers as they were unused
|
||||
use tracing::debug;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum EditEventOutcome {
|
||||
Message(String), // Return a message, stay in Edit mode
|
||||
ExitEditMode, // Signal to exit Edit mode
|
||||
Message(String),
|
||||
ExitEditMode,
|
||||
}
|
||||
|
||||
pub async fn handle_edit_event(
|
||||
key: KeyEvent,
|
||||
config: &Config,
|
||||
form_state: &mut FormState,
|
||||
form_state: &mut FormState, // Now FormState is in scope
|
||||
login_state: &mut LoginState,
|
||||
register_state: &mut RegisterState,
|
||||
admin_state: &mut AdminState,
|
||||
@@ -34,17 +35,20 @@ pub async fn handle_edit_event(
|
||||
grpc_client: &mut GrpcClient,
|
||||
app_state: &AppState,
|
||||
) -> Result<EditEventOutcome> {
|
||||
// Global command mode check (should ideally be handled before calling this function)
|
||||
// --- Global command mode check ---
|
||||
if let Some("enter_command_mode") = config.get_action_for_key_in_mode(
|
||||
&config.keybindings.global,
|
||||
&config.keybindings.global, // Assuming command mode can be entered globally
|
||||
key.code,
|
||||
key.modifiers,
|
||||
) {
|
||||
// This check might be redundant if EventHandler already prevents entering Edit mode
|
||||
// when command_mode is true. However, it's a safeguard.
|
||||
return Ok(EditEventOutcome::Message(
|
||||
"Command mode entry handled globally.".to_string(),
|
||||
"Cannot enter command mode from edit mode here.".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
// --- Common actions (save, revert) ---
|
||||
if let Some(action) = config.get_action_for_key_in_mode(
|
||||
&config.keybindings.common,
|
||||
key.code,
|
||||
@@ -52,261 +56,197 @@ pub async fn handle_edit_event(
|
||||
).as_deref() {
|
||||
if matches!(action, "save" | "revert") {
|
||||
let message_string: String = if app_state.ui.show_login {
|
||||
auth_e::execute_common_action(
|
||||
action,
|
||||
login_state,
|
||||
grpc_client,
|
||||
current_position,
|
||||
total_count,
|
||||
)
|
||||
.await?
|
||||
auth_e::execute_common_action(action, login_state, grpc_client, current_position, total_count).await?
|
||||
} else if app_state.ui.show_register {
|
||||
auth_e::execute_common_action(
|
||||
action,
|
||||
register_state,
|
||||
grpc_client,
|
||||
current_position,
|
||||
total_count,
|
||||
)
|
||||
.await?
|
||||
auth_e::execute_common_action(action, register_state, grpc_client, current_position, total_count).await?
|
||||
} else if app_state.ui.show_add_table {
|
||||
format!(
|
||||
"Action '{}' not fully implemented for Add Table view here.",
|
||||
action
|
||||
)
|
||||
// TODO: Implement common actions for AddTable if needed
|
||||
format!("Action '{}' not implemented for Add Table in edit mode.", action)
|
||||
} else if app_state.ui.show_add_logic {
|
||||
format!(
|
||||
"Action '{}' not fully implemented for Add Logic view here.",
|
||||
action
|
||||
)
|
||||
} else {
|
||||
let outcome = form_e::execute_common_action(
|
||||
action,
|
||||
form_state,
|
||||
grpc_client,
|
||||
current_position,
|
||||
total_count,
|
||||
)
|
||||
.await?;
|
||||
// TODO: Implement common actions for AddLogic if needed
|
||||
format!("Action '{}' not implemented for Add Logic in edit mode.", action)
|
||||
} else { // Assuming Form view
|
||||
let outcome = form_e::execute_common_action(action, form_state, grpc_client, current_position, total_count).await?;
|
||||
match outcome {
|
||||
EventOutcome::Ok(msg) => msg,
|
||||
EventOutcome::DataSaved(_, msg) => msg,
|
||||
_ => format!(
|
||||
"Unexpected outcome from common action: {:?}",
|
||||
outcome
|
||||
),
|
||||
EventOutcome::Ok(msg) | EventOutcome::DataSaved(_, msg) => msg,
|
||||
_ => format!("Unexpected outcome from common action: {:?}", outcome),
|
||||
}
|
||||
};
|
||||
return Ok(EditEventOutcome::Message(message_string));
|
||||
}
|
||||
}
|
||||
|
||||
// Edit-specific actions
|
||||
if let Some(action) =
|
||||
config.get_edit_action_for_key(key.code, key.modifiers)
|
||||
.as_deref() {
|
||||
// Handle enter_decider first
|
||||
if action == "enter_decider" {
|
||||
// --- Edit-specific actions ---
|
||||
if let Some(action_str) = config.get_edit_action_for_key(key.code, key.modifiers).as_deref() {
|
||||
// --- Handle "enter_decider" (Enter key) ---
|
||||
if action_str == "enter_decider" {
|
||||
let effective_action = if app_state.ui.show_register
|
||||
&& register_state.in_suggestion_mode
|
||||
&& register_state.current_field() == 4 {
|
||||
&& register_state.current_field() == 4 { // Role field
|
||||
"select_suggestion"
|
||||
} else if app_state.ui.show_add_logic
|
||||
&& admin_state.add_logic_state.in_target_column_suggestion_mode
|
||||
&& admin_state.add_logic_state.current_field() == 1 { // Target Column field
|
||||
"select_suggestion"
|
||||
} else {
|
||||
"next_field"
|
||||
"next_field" // Default action for Enter
|
||||
};
|
||||
|
||||
let msg = if app_state.ui.show_login {
|
||||
auth_e::execute_edit_action(
|
||||
effective_action,
|
||||
key,
|
||||
login_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
auth_e::execute_edit_action(effective_action, key, login_state, ideal_cursor_column).await?
|
||||
} else if app_state.ui.show_add_table {
|
||||
add_table_e::execute_edit_action(
|
||||
effective_action,
|
||||
key,
|
||||
&mut admin_state.add_table_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
add_table_e::execute_edit_action(effective_action, key, &mut admin_state.add_table_state, ideal_cursor_column).await?
|
||||
} else if app_state.ui.show_add_logic {
|
||||
add_logic_e::execute_edit_action(
|
||||
effective_action,
|
||||
key,
|
||||
&mut admin_state.add_logic_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
add_logic_e::execute_edit_action(effective_action, key, &mut admin_state.add_logic_state, ideal_cursor_column).await?
|
||||
} else if app_state.ui.show_register {
|
||||
auth_e::execute_edit_action(
|
||||
effective_action,
|
||||
key,
|
||||
register_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
form_e::execute_edit_action(
|
||||
effective_action,
|
||||
key,
|
||||
form_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
auth_e::execute_edit_action(effective_action, key, register_state, ideal_cursor_column).await?
|
||||
} else { // Form view
|
||||
form_e::execute_edit_action(effective_action, key, form_state, ideal_cursor_column).await?
|
||||
};
|
||||
return Ok(EditEventOutcome::Message(msg));
|
||||
}
|
||||
|
||||
if action == "exit" {
|
||||
// --- Handle "exit" (Escape key) ---
|
||||
if action_str == "exit" {
|
||||
if app_state.ui.show_register && register_state.in_suggestion_mode {
|
||||
let msg = auth_e::execute_edit_action(
|
||||
"exit_suggestion_mode",
|
||||
key,
|
||||
register_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?;
|
||||
let msg = auth_e::execute_edit_action("exit_suggestion_mode", key, register_state, ideal_cursor_column).await?;
|
||||
return Ok(EditEventOutcome::Message(msg));
|
||||
} else if app_state.ui.show_add_logic && admin_state.add_logic_state.in_target_column_suggestion_mode {
|
||||
admin_state.add_logic_state.in_target_column_suggestion_mode = false;
|
||||
admin_state.add_logic_state.show_target_column_suggestions = false;
|
||||
admin_state.add_logic_state.selected_target_column_suggestion_index = None;
|
||||
return Ok(EditEventOutcome::Message("Exited column suggestions".to_string()));
|
||||
} else {
|
||||
return Ok(EditEventOutcome::ExitEditMode);
|
||||
}
|
||||
}
|
||||
|
||||
// Special handling for role field suggestions (Register view only)
|
||||
if app_state.ui.show_register && register_state.current_field() == 4 {
|
||||
if !register_state.in_suggestion_mode
|
||||
&& key.code == KeyCode::Tab
|
||||
&& key.modifiers == KeyModifiers::NONE
|
||||
{
|
||||
register_state.update_role_suggestions();
|
||||
if !register_state.role_suggestions.is_empty() {
|
||||
register_state.in_suggestion_mode = true;
|
||||
register_state.selected_suggestion_index = Some(0);
|
||||
return Ok(EditEventOutcome::Message(
|
||||
"Suggestions shown".to_string(),
|
||||
));
|
||||
} else {
|
||||
return Ok(EditEventOutcome::Message(
|
||||
"No suggestions available".to_string(),
|
||||
));
|
||||
// --- Autocomplete for AddLogicState Target Column ---
|
||||
if app_state.ui.show_add_logic && admin_state.add_logic_state.current_field() == 1 { // Target Column field
|
||||
if action_str == "suggestion_down" { // "Tab" is mapped to suggestion_down
|
||||
if !admin_state.add_logic_state.in_target_column_suggestion_mode {
|
||||
// Attempt to open suggestions
|
||||
if let Some(profile_name) = admin_state.add_logic_state.profile_name.clone().into() {
|
||||
if let Some(table_name) = admin_state.add_logic_state.selected_table_name.clone() {
|
||||
debug!("Fetching table structure for autocomplete: Profile='{}', Table='{}'", profile_name, table_name);
|
||||
match grpc_client.get_table_structure(profile_name, table_name).await {
|
||||
Ok(ts_response) => {
|
||||
admin_state.add_logic_state.table_columns_for_suggestions =
|
||||
ts_response.columns.into_iter().map(|c| c.name).collect();
|
||||
admin_state.add_logic_state.update_target_column_suggestions();
|
||||
if !admin_state.add_logic_state.target_column_suggestions.is_empty() {
|
||||
admin_state.add_logic_state.in_target_column_suggestion_mode = true;
|
||||
// update_target_column_suggestions handles initial selection
|
||||
return Ok(EditEventOutcome::Message("Column suggestions shown".to_string()));
|
||||
} else {
|
||||
return Ok(EditEventOutcome::Message("No column suggestions for current input".to_string()));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("Error fetching table structure: {}", e);
|
||||
admin_state.add_logic_state.table_columns_for_suggestions.clear(); // Clear old data on error
|
||||
admin_state.add_logic_state.update_target_column_suggestions();
|
||||
return Ok(EditEventOutcome::Message(format!("Error fetching columns: {}", e)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Ok(EditEventOutcome::Message("No table selected for column suggestions".to_string()));
|
||||
}
|
||||
} else { // Should not happen if AddLogic is properly initialized
|
||||
return Ok(EditEventOutcome::Message("Profile name missing for column suggestions".to_string()));
|
||||
}
|
||||
} else { // Already in suggestion mode, navigate down
|
||||
let msg = add_logic_e::execute_edit_action(action_str, key, &mut admin_state.add_logic_state, ideal_cursor_column).await?;
|
||||
return Ok(EditEventOutcome::Message(msg));
|
||||
}
|
||||
}
|
||||
if register_state.in_suggestion_mode
|
||||
&& matches!(
|
||||
action,
|
||||
"suggestion_down" | "suggestion_up"
|
||||
)
|
||||
{
|
||||
let msg = auth_e::execute_edit_action(
|
||||
action,
|
||||
key,
|
||||
register_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?;
|
||||
} else if admin_state.add_logic_state.in_target_column_suggestion_mode && action_str == "suggestion_up" {
|
||||
let msg = add_logic_e::execute_edit_action(action_str, key, &mut admin_state.add_logic_state, ideal_cursor_column).await?;
|
||||
return Ok(EditEventOutcome::Message(msg));
|
||||
}
|
||||
}
|
||||
|
||||
// Execute other edit actions based on the current view
|
||||
// --- Autocomplete for RegisterState Role Field ---
|
||||
if app_state.ui.show_register && register_state.current_field() == 4 { // Role field
|
||||
if !register_state.in_suggestion_mode && action_str == "suggestion_down" { // Tab
|
||||
register_state.update_role_suggestions();
|
||||
if !register_state.role_suggestions.is_empty() {
|
||||
register_state.in_suggestion_mode = true;
|
||||
// update_role_suggestions should handle initial selection
|
||||
return Ok(EditEventOutcome::Message("Role suggestions shown".to_string()));
|
||||
} else {
|
||||
// If Tab doesn't open suggestions, it might fall through to "next_field"
|
||||
// or you might want specific behavior. For now, let it fall through.
|
||||
}
|
||||
}
|
||||
if register_state.in_suggestion_mode && matches!(action_str, "suggestion_down" | "suggestion_up") {
|
||||
let msg = auth_e::execute_edit_action(action_str, key, register_state, ideal_cursor_column).await?;
|
||||
return Ok(EditEventOutcome::Message(msg));
|
||||
}
|
||||
}
|
||||
|
||||
// --- Dispatch other edit actions ---
|
||||
let msg = if app_state.ui.show_login {
|
||||
auth_e::execute_edit_action(
|
||||
action,
|
||||
key,
|
||||
login_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
auth_e::execute_edit_action(action_str, key, login_state, ideal_cursor_column).await?
|
||||
} else if app_state.ui.show_add_table {
|
||||
add_table_e::execute_edit_action(
|
||||
action,
|
||||
key,
|
||||
&mut admin_state.add_table_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
add_table_e::execute_edit_action(action_str, key, &mut admin_state.add_table_state, ideal_cursor_column).await?
|
||||
} else if app_state.ui.show_add_logic {
|
||||
add_logic_e::execute_edit_action(
|
||||
action,
|
||||
key,
|
||||
&mut admin_state.add_logic_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
// If not a suggestion action handled above for AddLogic
|
||||
if !(admin_state.add_logic_state.in_target_column_suggestion_mode && matches!(action_str, "suggestion_down" | "suggestion_up")) {
|
||||
add_logic_e::execute_edit_action(action_str, key, &mut admin_state.add_logic_state, ideal_cursor_column).await?
|
||||
} else { String::new() /* Already handled */ }
|
||||
} else if app_state.ui.show_register {
|
||||
auth_e::execute_edit_action(
|
||||
action,
|
||||
key,
|
||||
register_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
form_e::execute_edit_action(
|
||||
action,
|
||||
key,
|
||||
form_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
if !(register_state.in_suggestion_mode && matches!(action_str, "suggestion_down" | "suggestion_up")) {
|
||||
auth_e::execute_edit_action(action_str, key, register_state, ideal_cursor_column).await?
|
||||
} else { String::new() /* Already handled */ }
|
||||
} else { // Form view
|
||||
form_e::execute_edit_action(action_str, key, form_state, ideal_cursor_column).await?
|
||||
};
|
||||
return Ok(EditEventOutcome::Message(msg));
|
||||
}
|
||||
|
||||
// --- Character insertion ---
|
||||
// If character insertion happens while in suggestion mode, exit suggestion mode first.
|
||||
let mut exited_suggestion_mode_for_typing = false;
|
||||
if app_state.ui.show_register && register_state.in_suggestion_mode {
|
||||
register_state.in_suggestion_mode = false;
|
||||
register_state.show_role_suggestions = false;
|
||||
register_state.selected_suggestion_index = None;
|
||||
exited_suggestion_mode_for_typing = true;
|
||||
}
|
||||
if app_state.ui.show_add_logic && admin_state.add_logic_state.in_target_column_suggestion_mode {
|
||||
admin_state.add_logic_state.in_target_column_suggestion_mode = false;
|
||||
admin_state.add_logic_state.show_target_column_suggestions = false;
|
||||
admin_state.add_logic_state.selected_target_column_suggestion_index = None;
|
||||
exited_suggestion_mode_for_typing = true;
|
||||
}
|
||||
|
||||
let msg = if app_state.ui.show_login {
|
||||
auth_e::execute_edit_action(
|
||||
"insert_char",
|
||||
key,
|
||||
login_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
let mut char_insert_msg = if app_state.ui.show_login {
|
||||
auth_e::execute_edit_action("insert_char", key, login_state, ideal_cursor_column).await?
|
||||
} else if app_state.ui.show_add_table {
|
||||
add_table_e::execute_edit_action(
|
||||
"insert_char",
|
||||
key,
|
||||
&mut admin_state.add_table_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
add_table_e::execute_edit_action("insert_char", key, &mut admin_state.add_table_state, ideal_cursor_column).await?
|
||||
} else if app_state.ui.show_add_logic {
|
||||
add_logic_e::execute_edit_action(
|
||||
"insert_char",
|
||||
key,
|
||||
&mut admin_state.add_logic_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
add_logic_e::execute_edit_action("insert_char", key, &mut admin_state.add_logic_state, ideal_cursor_column).await?
|
||||
} else if app_state.ui.show_register {
|
||||
auth_e::execute_edit_action(
|
||||
"insert_char",
|
||||
key,
|
||||
register_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
form_e::execute_edit_action(
|
||||
"insert_char",
|
||||
key,
|
||||
form_state,
|
||||
ideal_cursor_column,
|
||||
)
|
||||
.await?
|
||||
auth_e::execute_edit_action("insert_char", key, register_state, ideal_cursor_column).await?
|
||||
} else { // Form view
|
||||
form_e::execute_edit_action("insert_char", key, form_state, ideal_cursor_column).await?
|
||||
};
|
||||
|
||||
// After character insertion, update suggestions if applicable
|
||||
if app_state.ui.show_register && register_state.current_field() == 4 {
|
||||
register_state.update_role_suggestions();
|
||||
// If we just exited suggestion mode by typing, don't immediately show them again unless Tab is pressed.
|
||||
// However, update_role_suggestions will set show_role_suggestions if matches are found.
|
||||
// This is fine, as the render logic checks in_suggestion_mode.
|
||||
}
|
||||
if app_state.ui.show_add_logic && admin_state.add_logic_state.current_field() == 1 {
|
||||
admin_state.add_logic_state.update_target_column_suggestions();
|
||||
}
|
||||
|
||||
return Ok(EditEventOutcome::Message(msg));
|
||||
if exited_suggestion_mode_for_typing && char_insert_msg.is_empty() {
|
||||
char_insert_msg = "Suggestions hidden".to_string();
|
||||
}
|
||||
|
||||
|
||||
Ok(EditEventOutcome::Message(char_insert_msg))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user