diff --git a/client/src/modes/handlers/event.rs b/client/src/modes/handlers/event.rs index c4c84c8..b9a8b70 100644 --- a/client/src/modes/handlers/event.rs +++ b/client/src/modes/handlers/event.rs @@ -48,7 +48,6 @@ impl EventHandler { total_count: u64, current_position: &mut u64, intro_state: &mut crate::components::intro::intro::IntroState, - admin_state: &mut crate::components::admin::admin_panel::AdminPanelState, ) -> Result<(bool, String), Box> { if app_state.ui.show_intro { if let Event::Key(key) = event { @@ -67,21 +66,99 @@ impl EventHandler { return Ok((false, String::new())); } - if let Event::Key(key) = event { - let key_code = key.code; - let modifiers = key.modifiers; + if let Event::Key(key) = event { + let key_code = key.code; + let modifiers = key.modifiers; - // Handle admin panel first if visible - if app_state.ui.show_admin { - if let Some(action) = config.get_admin_action(key_code, modifiers) { + // Handle admin panel mode + if app_state.ui.show_admin { + if let Some(action) = config.get_admin_action(key_code, modifiers) { + match action { + "move_up" => { + // Handle up movement using app_state directly + app_state.admin_selected_item = app_state.admin_selected_item.saturating_sub(1); + } + "move_down" => { + // Handle down movement using app_state + app_state.admin_selected_item = app_state.admin_selected_item.saturating_add(1); + } + "quit" => app_state.ui.show_admin = false, + _ => {} + } + return Ok((false, format!("Admin: {}", action))); + } + return Ok((false, String::new())); + } + if UiStateHandler::toggle_sidebar( + &mut app_state.ui, + config, + key_code, + modifiers, + ) { + return Ok((false, format!("Sidebar {}", + if app_state.ui.show_sidebar { "shown" } else { "hidden" } + ))); + } + + // Handle edit mode first to allow normal character input + if self.is_edit_mode { + if config.is_exit_edit_mode(key_code, modifiers) { + if form_state.has_unsaved_changes { + self.command_message = "Unsaved changes! Use :w to save or :q! to discard".to_string(); + return Ok((false, self.command_message.clone())); + } + self.is_edit_mode = false; + self.edit_mode_cooldown = true; + self.command_message = "Read-only mode".to_string(); + terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?; + + let current_input = form_state.get_current_input(); + if !current_input.is_empty() && form_state.current_cursor_pos >= current_input.len() { + form_state.current_cursor_pos = current_input.len() - 1; + self.ideal_cursor_column = form_state.current_cursor_pos; + } + return Ok((false, self.command_message.clone())); + } + + let result = edit::handle_edit_event_internal( + key, + config, + form_state, + &mut self.ideal_cursor_column, + &mut self.command_message, + &mut app_state.ui.is_saved, + current_position, + total_count, + grpc_client, + ).await?; + + self.key_sequence_tracker.reset(); + return Ok((false, result)); + } + + // Global command mode activation + let context_action = config.get_action_for_current_context( + self.is_edit_mode, + self.command_mode, + app_state.ui.show_intro, + app_state.ui.show_admin, + key_code, + modifiers + ); + + if let Some("enter_command_mode") = context_action { + self.command_mode = true; + self.command_input.clear(); + self.command_message.clear(); + return Ok((false, String::new())); + } + + if let Some(action) = config.get_action_for_key_in_mode( + &config.keybindings.common, + key_code, + modifiers + ) { match action { - "move_up" => admin_state.previous(), - "move_down" => admin_state.next(), - "select" => { - // Handle selection logic - }, - "quit" => app_state.ui.show_admin = false, - // Handle common actions "save" => { let message = common::save( form_state, @@ -92,6 +169,14 @@ impl EventHandler { ).await?; return Ok((false, message)); }, + "force_quit" => { + let (should_exit, message) = command_handler.handle_command("force_quit", terminal).await?; + return Ok((should_exit, message)); + }, + "save_and_quit" => { + let (should_exit, message) = command_handler.handle_command("save_and_quit", terminal).await?; + return Ok((should_exit, message)); + }, "revert" => { let message = common::revert( form_state, @@ -103,177 +188,72 @@ impl EventHandler { }, _ => {} } - return Ok((false, format!("Admin: {}", action))); } - // Block other keybindings when admin panel is visible - return Ok((false, String::new())); - } - if UiStateHandler::toggle_sidebar( - &mut app_state.ui, - config, - key_code, - modifiers, - ) { - return Ok((false, format!("Sidebar {}", - if app_state.ui.show_sidebar { "shown" } else { "hidden" } - ))); - } + if self.command_mode { + let (should_exit, message, exit_command_mode) = command_mode::handle_command_event( + key, + config, + form_state, + &mut self.command_input, + &mut self.command_message, + grpc_client, + &mut app_state.ui.is_saved, + current_position, + total_count, + ).await?; - // Handle edit mode first to allow normal character input - if self.is_edit_mode { - if config.is_exit_edit_mode(key_code, modifiers) { - if form_state.has_unsaved_changes { - self.command_message = "Unsaved changes! Use :w to save or :q! to discard".to_string(); - return Ok((false, self.command_message.clone())); + if exit_command_mode { + self.command_mode = false; } - self.is_edit_mode = false; + + return Ok((should_exit, message)); + } + + if let Some(action) = config.get_read_only_action_for_key(key_code, modifiers) { + if action == "enter_command_mode" { + self.command_mode = true; + self.command_input.clear(); + self.command_message.clear(); + return Ok((false, String::new())); + } + } + + if config.is_enter_edit_mode_before(key_code, modifiers) { + self.is_edit_mode = true; self.edit_mode_cooldown = true; - self.command_message = "Read-only mode".to_string(); - terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?; - - let current_input = form_state.get_current_input(); - if !current_input.is_empty() && form_state.current_cursor_pos >= current_input.len() { - form_state.current_cursor_pos = current_input.len() - 1; - self.ideal_cursor_column = form_state.current_cursor_pos; - } + self.command_message = "Edit mode".to_string(); + terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?; return Ok((false, self.command_message.clone())); } - let result = edit::handle_edit_event_internal( + if config.is_enter_edit_mode_after(key_code, modifiers) { + let current_input = form_state.get_current_input(); + if !current_input.is_empty() && form_state.current_cursor_pos < current_input.len() { + form_state.current_cursor_pos += 1; + self.ideal_cursor_column = form_state.current_cursor_pos; + } + self.is_edit_mode = true; + self.edit_mode_cooldown = true; + self.command_message = "Edit mode (after cursor)".to_string(); + terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?; + return Ok((false, self.command_message.clone())); + } + + return read_only::handle_read_only_event( key, config, form_state, + &mut self.key_sequence_tracker, + current_position, + total_count, + grpc_client, + &mut self.command_message, + &mut self.edit_mode_cooldown, &mut self.ideal_cursor_column, - &mut self.command_message, - &mut app_state.ui.is_saved, - current_position, - total_count, - grpc_client, - ).await?; - - self.key_sequence_tracker.reset(); - return Ok((false, result)); + ).await; } - // Global command mode activation - let context_action = config.get_action_for_current_context( - self.is_edit_mode, - self.command_mode, - app_state.ui.show_intro, - app_state.ui.show_admin, - key_code, - modifiers - ); - - if let Some("enter_command_mode") = context_action { - self.command_mode = true; - self.command_input.clear(); - self.command_message.clear(); - return Ok((false, String::new())); - } - - if let Some(action) = config.get_action_for_key_in_mode( - &config.keybindings.common, - key_code, - modifiers - ) { - match action { - "save" => { - let message = common::save( - form_state, - grpc_client, - &mut app_state.ui.is_saved, - current_position, - total_count, - ).await?; - return Ok((false, message)); - }, - "force_quit" => { - let (should_exit, message) = command_handler.handle_command("force_quit", terminal).await?; - return Ok((should_exit, message)); - }, - "save_and_quit" => { - let (should_exit, message) = command_handler.handle_command("save_and_quit", terminal).await?; - return Ok((should_exit, message)); - }, - "revert" => { - let message = common::revert( - form_state, - grpc_client, - current_position, - total_count, - ).await?; - return Ok((false, message)); - }, - _ => {} - } - } - - if self.command_mode { - let (should_exit, message, exit_command_mode) = command_mode::handle_command_event( - key, - config, - form_state, - &mut self.command_input, - &mut self.command_message, - grpc_client, - &mut app_state.ui.is_saved, - current_position, - total_count, - ).await?; - - if exit_command_mode { - self.command_mode = false; - } - - return Ok((should_exit, message)); - } - - if let Some(action) = config.get_read_only_action_for_key(key_code, modifiers) { - if action == "enter_command_mode" { - self.command_mode = true; - self.command_input.clear(); - self.command_message.clear(); - return Ok((false, String::new())); - } - } - - if config.is_enter_edit_mode_before(key_code, modifiers) { - self.is_edit_mode = true; - self.edit_mode_cooldown = true; - self.command_message = "Edit mode".to_string(); - terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?; - return Ok((false, self.command_message.clone())); - } - - if config.is_enter_edit_mode_after(key_code, modifiers) { - let current_input = form_state.get_current_input(); - if !current_input.is_empty() && form_state.current_cursor_pos < current_input.len() { - form_state.current_cursor_pos += 1; - self.ideal_cursor_column = form_state.current_cursor_pos; - } - self.is_edit_mode = true; - self.edit_mode_cooldown = true; - self.command_message = "Edit mode (after cursor)".to_string(); - terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?; - return Ok((false, self.command_message.clone())); - } - - return read_only::handle_read_only_event( - key, - config, - form_state, - &mut self.key_sequence_tracker, - current_position, - total_count, - grpc_client, - &mut self.command_message, - &mut self.edit_mode_cooldown, - &mut self.ideal_cursor_column, - ).await; - } - self.edit_mode_cooldown = false; Ok((false, self.command_message.clone())) } diff --git a/client/src/state/state.rs b/client/src/state/state.rs index e734747..834a1d1 100644 --- a/client/src/state/state.rs +++ b/client/src/state/state.rs @@ -17,6 +17,8 @@ pub struct AppState { pub current_position: u64, pub profile_tree: ProfileTreeResponse, pub selected_profile: Option, + pub admin_selected_item: usize, // Tracks selection in admin panel + pub admin_profiles: Vec, // Stores admin panel data // UI preferences pub ui: UiState, @@ -33,6 +35,8 @@ impl AppState { current_position: 0, profile_tree: ProfileTreeResponse::default(), selected_profile: None, + admin_selected_item: 0, + admin_profiles: Vec::new(), ui: UiState::default(), }) } diff --git a/client/src/ui/handlers/render.rs b/client/src/ui/handlers/render.rs index 11a8875..052cadc 100644 --- a/client/src/ui/handlers/render.rs +++ b/client/src/ui/handlers/render.rs @@ -27,7 +27,6 @@ pub fn render_ui( command_message: &str, app_state: &AppState, intro_state: &intro::IntroState, - admin_panel_state: &mut AdminPanelState, ) { render_background(f, f.area(), theme); diff --git a/client/src/ui/handlers/ui.rs b/client/src/ui/handlers/ui.rs index 39a0016..8e1afc0 100644 --- a/client/src/ui/handlers/ui.rs +++ b/client/src/ui/handlers/ui.rs @@ -28,11 +28,14 @@ pub async fn run_ui() -> Result<(), Box> { app_state.profile_tree = profile_tree; // Now create admin panel with profiles from app_state - let profiles = app_state.profile_tree.profiles - .iter() - .map(|p| p.name.clone()) - .collect(); - let mut admin_panel_state = AdminPanelState::new(profiles); + if intro_state.selected_option == 1 { + app_state.ui.show_admin = true; + app_state.admin_profiles = app_state.profile_tree.profiles + .iter() + .map(|p| p.name.clone()) + .collect(); + app_state.admin_selected_item = 0; + } // Fetch table structure at startup (one-time) let table_structure = grpc_client.get_table_structure().await?; @@ -75,7 +78,6 @@ pub async fn run_ui() -> Result<(), Box> { &event_handler.command_message, &app_state, &intro_state, - &mut admin_panel_state, ); })?; @@ -94,7 +96,6 @@ pub async fn run_ui() -> Result<(), Box> { total_count, &mut current_position, &mut intro_state, - &mut admin_panel_state, ).await?; app_state.current_position = current_position;