214 lines
10 KiB
Rust
214 lines
10 KiB
Rust
// src/functions/modes/navigation/admin_nav.rs
|
|
|
|
use crate::config::binds::config::Config;
|
|
use crate::state::{
|
|
app::state::AppState,
|
|
pages::admin::{AdminFocus, AdminState},
|
|
};
|
|
use crossterm::event::KeyEvent;
|
|
use crate::state::app::buffer::AppView;
|
|
use crate::state::app::buffer::BufferState;
|
|
use crate::state::pages::add_table::AddTableState;
|
|
|
|
/// Handles navigation events specifically for the Admin Panel view.
|
|
/// Returns true if the event was handled, false otherwise.
|
|
pub fn handle_admin_navigation(
|
|
key: KeyEvent,
|
|
config: &Config,
|
|
app_state: &mut AppState,
|
|
admin_state: &mut AdminState,
|
|
buffer_state: &mut BufferState,
|
|
command_message: &mut String,
|
|
) -> bool {
|
|
let action = config.get_general_action(key.code, key.modifiers);
|
|
let current_focus = admin_state.current_focus;
|
|
let profile_count = app_state.profile_tree.profiles.len();
|
|
|
|
match action {
|
|
// --- Vertical Navigation (Up/Down) ---
|
|
Some("move_up") => {
|
|
match current_focus {
|
|
AdminFocus::Profiles => {
|
|
if profile_count > 0 {
|
|
// Updates navigation state, resets table state
|
|
admin_state.previous_profile(profile_count);
|
|
*command_message = "Navigated profiles".to_string();
|
|
}
|
|
}
|
|
AdminFocus::Tables => {
|
|
// Updates table navigation state
|
|
if let Some(nav_profile_idx) = admin_state.profile_list_state.selected() {
|
|
if let Some(profile) = app_state.profile_tree.profiles.get(nav_profile_idx) {
|
|
let table_count = profile.tables.len();
|
|
if table_count > 0 {
|
|
admin_state.previous_table(table_count);
|
|
*command_message = "Navigated tables".to_string();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
AdminFocus::Button1 | AdminFocus::Button2 | AdminFocus::Button3 => {}
|
|
}
|
|
true // Event handled
|
|
}
|
|
Some("move_down") => {
|
|
match current_focus {
|
|
AdminFocus::Profiles => {
|
|
if profile_count > 0 {
|
|
// Updates navigation state, resets table state
|
|
admin_state.next_profile(profile_count);
|
|
*command_message = "Navigated profiles".to_string();
|
|
}
|
|
}
|
|
AdminFocus::Tables => {
|
|
if let Some(nav_profile_idx) = admin_state.profile_list_state.selected() {
|
|
if let Some(profile) = app_state.profile_tree.profiles.get(nav_profile_idx) {
|
|
let table_count = profile.tables.len();
|
|
if table_count > 0 {
|
|
admin_state.next_table(table_count);
|
|
*command_message = "Navigated tables".to_string();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
AdminFocus::Button1 | AdminFocus::Button2 | AdminFocus::Button3 => {}
|
|
}
|
|
true // Event handled
|
|
}
|
|
|
|
// --- Horizontal Navigation (Focus Change) ---
|
|
Some("next_option") | Some("previous_option") => {
|
|
let old_focus = admin_state.current_focus;
|
|
let is_next = action == Some("next_option"); // Check if 'l' or 'h'
|
|
|
|
admin_state.current_focus = match old_focus {
|
|
AdminFocus::Profiles => if is_next { AdminFocus::Tables } else { AdminFocus::Button3 }, // P -> T (l) or P -> B3 (h)
|
|
AdminFocus::Tables => if is_next { AdminFocus::Button1 } else { AdminFocus::Profiles }, // T -> B1 (l) or T -> P (h)
|
|
AdminFocus::Button1 => if is_next { AdminFocus::Button2 } else { AdminFocus::Tables }, // B1 -> B2 (l) or B1 -> T (h)
|
|
AdminFocus::Button2 => if is_next { AdminFocus::Button3 } else { AdminFocus::Button1 }, // B2 -> B3 (l) or B2 -> B1 (h)
|
|
AdminFocus::Button3 => if is_next { AdminFocus::Profiles } else { AdminFocus::Button2 }, // B3 -> P (l) or B3 -> B2 (h)
|
|
};
|
|
|
|
let new_focus = admin_state.current_focus;
|
|
*command_message = format!("Focus set to {:?}", new_focus);
|
|
// Auto-select first item only when moving from Profiles to Tables via 'l'
|
|
if old_focus == AdminFocus::Profiles && new_focus == AdminFocus::Tables && is_next {
|
|
if let Some(profile_idx) = admin_state.profile_list_state.selected() {
|
|
if let Some(profile) = app_state.profile_tree.profiles.get(profile_idx) {
|
|
if !profile.tables.is_empty() {
|
|
admin_state.table_list_state.select(Some(0));
|
|
} else {
|
|
admin_state.table_list_state.select(None);
|
|
}
|
|
} else {
|
|
admin_state.table_list_state.select(None);
|
|
}
|
|
} else {
|
|
admin_state.table_list_state.select(None);
|
|
}
|
|
}
|
|
// Clear table nav selection if moving away from Tables
|
|
if old_focus == AdminFocus::Tables && new_focus != AdminFocus::Tables {
|
|
admin_state.table_list_state.select(None);
|
|
}
|
|
// Clear profile nav selection if moving away from Profiles
|
|
if old_focus == AdminFocus::Profiles && new_focus != AdminFocus::Profiles {
|
|
// Maybe keep profile nav highlight? Let's try clearing it.
|
|
// admin_state.profile_list_state.select(None); // Optional: clear profile nav highlight
|
|
}
|
|
|
|
true // Event handled
|
|
}
|
|
|
|
// --- Selection ---
|
|
Some("select") => {
|
|
match current_focus {
|
|
AdminFocus::Profiles => {
|
|
// Set the persistent selection to the currently navigated item
|
|
if let Some(nav_idx) = admin_state.profile_list_state.selected() {
|
|
admin_state.selected_profile_index = Some(nav_idx); // Set persistent selection
|
|
|
|
// Move focus to Tables (like pressing 'l')
|
|
admin_state.current_focus = AdminFocus::Tables;
|
|
|
|
// Select the first table for navigation highlight
|
|
admin_state.table_list_state.select(None); // Clear table nav first
|
|
admin_state.selected_table_index = None; // Clear persistent table selection
|
|
if let Some(profile) = app_state.profile_tree.profiles.get(nav_idx) {
|
|
if !profile.tables.is_empty() {
|
|
// Set table nav highlight
|
|
admin_state.table_list_state.select(Some(0));
|
|
}
|
|
}
|
|
|
|
*command_message = format!("Selected profile idx {}, focus on Tables", nav_idx);
|
|
} else {
|
|
*command_message = "No profile selected".to_string();
|
|
}
|
|
}
|
|
AdminFocus::Tables => {
|
|
// Set the persistent selection to the currently navigated item
|
|
if let Some(nav_idx) = admin_state.table_list_state.selected() {
|
|
admin_state.selected_table_index = Some(nav_idx); // Set persistent selection
|
|
*command_message = format!("Selected table index {}", nav_idx);
|
|
} else {
|
|
*command_message = "No table highlighted".to_string();
|
|
}
|
|
// We don't change focus here for now.
|
|
}
|
|
AdminFocus::Button1 => {
|
|
*command_message = "Action: Add Logic (Not Implemented)".to_string();
|
|
// TODO: Trigger action for Button 1
|
|
}
|
|
AdminFocus::Button2 => {
|
|
// --- Prepare AddTableState based on persistent selections ---
|
|
if let Some(p_idx) = admin_state.selected_profile_index {
|
|
if let Some(profile) = app_state.profile_tree.profiles.get(p_idx) {
|
|
let selected_profile_name = profile.name.clone();
|
|
|
|
|
|
// Create and populate the new AddTableState
|
|
let new_add_table_state = AddTableState {
|
|
profile_name: selected_profile_name,
|
|
// Reset other fields to defaults for a fresh start
|
|
..AddTableState::default()
|
|
};
|
|
|
|
// Assign the prepared state
|
|
admin_state.add_table_state = new_add_table_state;
|
|
|
|
// Switch view
|
|
buffer_state.update_history(AppView::AddTable);
|
|
app_state.ui.focus_outside_canvas = false;
|
|
*command_message = format!(
|
|
"Navigating to Add Table for profile '{}'...",
|
|
admin_state.add_table_state.profile_name
|
|
);
|
|
|
|
} else {
|
|
*command_message = "Error: Selected profile index out of bounds.".to_string();
|
|
}
|
|
} else {
|
|
*command_message = "Please select a profile ([*]) first.".to_string();
|
|
}
|
|
// --- End preparation ---
|
|
}
|
|
AdminFocus::Button3 => {
|
|
*command_message = "Action: Change Table (Not Implemented)".to_string();
|
|
// TODO: Trigger action for Button 3
|
|
}
|
|
}
|
|
true // Event handled
|
|
}
|
|
|
|
// --- Other General Keys (Ignore for admin nav) ---
|
|
Some("toggle_sidebar") | Some("toggle_buffer_list") | Some("next_field") | Some("prev_field") => {
|
|
// These are handled globally or not applicable here.
|
|
false
|
|
}
|
|
|
|
// --- No matching action ---
|
|
_ => false, // Event not handled by admin navigation
|
|
}
|
|
}
|