needs improvements but at least it looks like it exists

This commit is contained in:
filipriec
2025-04-17 11:53:31 +02:00
parent f34317e504
commit 57f789290d
5 changed files with 323 additions and 140 deletions

View File

@@ -1,134 +1,222 @@
// src/functions/modes/navigation/add_table_nav.rs
use crate::state::pages::add_table::{AddTableFocus, AddTableState};
use crate::state::app::state::AppState; // If needed for list lengths later
use crate::config::binds::config::Config;
use crate::state::{
app::state::AppState,
pages::add_table::{AddTableFocus, AddTableState},
};
use crossterm::event::{KeyEvent};
use ratatui::widgets::TableState; // Import TableState
/// Handles navigation events specifically for the Add Table page.
/// Handles navigation events specifically for the Add Table view.
/// Returns true if the event was handled, false otherwise.
pub fn handle_navigation(
state: &mut AddTableState,
action: &str,
// app_state: &AppState, // Add if needed for list lengths
pub fn handle_add_table_navigation(
key: KeyEvent,
config: &Config,
_app_state: &AppState, // Keep for potential future use (e.g., checking permissions)
add_table_state: &mut AddTableState,
command_message: &mut String,
) -> bool {
let current_focus = state.current_focus;
let mut handled = true; // Assume handled unless proven otherwise
let action = config.get_general_action(key.code, key.modifiers);
let current_focus = add_table_state.current_focus;
let mut handled = true; // Assume handled unless logic determines otherwise
match action {
"move_up" => {
state.current_focus = match current_focus {
AddTableFocus::TableName => AddTableFocus::CancelButton, // Wrap around top
AddTableFocus::ColumnInput => AddTableFocus::TableName,
match action.as_deref() {
// --- Vertical Navigation (Up/Down) ---
Some("move_up") => {
let mut new_focus = current_focus; // Start with current focus
match current_focus {
AddTableFocus::InputTableName => new_focus = AddTableFocus::CancelButton, // Wrap top
AddTableFocus::InputColumnName => new_focus = AddTableFocus::InputTableName,
AddTableFocus::InputColumnType => new_focus = AddTableFocus::InputColumnName,
AddTableFocus::AddColumnButton => new_focus = AddTableFocus::InputColumnType,
AddTableFocus::ColumnsTable => {
// Navigate within table or move focus up
if !navigate_table_up(&mut state.column_table_state, state.columns.len()) {
state.current_focus = AddTableFocus::ColumnInput;
if !navigate_table_up(&mut add_table_state.column_table_state, add_table_state.columns.len()) {
new_focus = AddTableFocus::AddColumnButton; // Move focus up if at table top
}
AddTableFocus::ColumnsTable // Keep focus here while navigating table
// Keep focus on table while navigating within it
}
AddTableFocus::IndexInput => AddTableFocus::ColumnsTable,
AddTableFocus::IndexesTable => {
if !navigate_table_up(&mut state.index_table_state, state.indexes.len()) {
state.current_focus = AddTableFocus::IndexInput;
if !navigate_table_up(&mut add_table_state.index_table_state, add_table_state.indexes.len()) {
new_focus = AddTableFocus::ColumnsTable; // Move focus up
}
AddTableFocus::IndexesTable
}
AddTableFocus::LinkInput => AddTableFocus::IndexesTable,
AddTableFocus::LinksTable => {
if !navigate_table_up(&mut state.link_table_state, state.links.len()) {
state.current_focus = AddTableFocus::LinkInput;
if !navigate_table_up(&mut add_table_state.link_table_state, add_table_state.links.len()) {
new_focus = AddTableFocus::IndexesTable; // Move focus up
}
AddTableFocus::LinksTable
}
AddTableFocus::SaveButton | AddTableFocus::CancelButton => AddTableFocus::LinksTable,
AddTableFocus::SaveButton => new_focus = AddTableFocus::LinksTable,
AddTableFocus::CancelButton => new_focus = AddTableFocus::SaveButton,
}
add_table_state.current_focus = new_focus;
*command_message = format!("Focus set to {:?}", add_table_state.current_focus);
}
"move_down" => {
state.current_focus = match current_focus {
AddTableFocus::TableName => AddTableFocus::ColumnInput,
AddTableFocus::ColumnInput => AddTableFocus::ColumnsTable,
Some("move_down") => {
let mut new_focus = current_focus; // Start with current focus
match current_focus {
AddTableFocus::InputTableName => new_focus = AddTableFocus::InputColumnName,
AddTableFocus::InputColumnName => new_focus = AddTableFocus::InputColumnType,
AddTableFocus::InputColumnType => new_focus = AddTableFocus::AddColumnButton,
AddTableFocus::AddColumnButton => new_focus = AddTableFocus::ColumnsTable,
AddTableFocus::ColumnsTable => {
if !navigate_table_down(&mut state.column_table_state, state.columns.len()) {
state.current_focus = AddTableFocus::IndexInput;
if !navigate_table_down(&mut add_table_state.column_table_state, add_table_state.columns.len()) {
new_focus = AddTableFocus::IndexesTable; // Move focus down if at table bottom
}
AddTableFocus::ColumnsTable
// Keep focus on table while navigating within it
}
AddTableFocus::IndexInput => AddTableFocus::IndexesTable,
AddTableFocus::IndexesTable => {
if !navigate_table_down(&mut state.index_table_state, state.indexes.len()) {
state.current_focus = AddTableFocus::LinkInput;
if !navigate_table_down(&mut add_table_state.index_table_state, add_table_state.indexes.len()) {
new_focus = AddTableFocus::LinksTable; // Move focus down
}
AddTableFocus::IndexesTable
}
AddTableFocus::LinkInput => AddTableFocus::LinksTable,
AddTableFocus::LinksTable => {
if !navigate_table_down(&mut state.link_table_state, state.links.len()) {
// Move to buttons after table
state.current_focus = AddTableFocus::SaveButton;
if !navigate_table_down(&mut add_table_state.link_table_state, add_table_state.links.len()) {
new_focus = AddTableFocus::SaveButton; // Move focus down
}
AddTableFocus::LinksTable
}
AddTableFocus::SaveButton | AddTableFocus::CancelButton => AddTableFocus::TableName, // Wrap around bottom
AddTableFocus::SaveButton => new_focus = AddTableFocus::CancelButton,
AddTableFocus::CancelButton => new_focus = AddTableFocus::InputTableName, // Wrap bottom
}
add_table_state.current_focus = new_focus;
*command_message = format!("Focus set to {:?}", add_table_state.current_focus);
}
"next_option" => { // Typically Tab or Right arrow
state.current_focus = match current_focus {
// Simple vertical flow for now, like move_down
AddTableFocus::TableName => AddTableFocus::ColumnInput,
AddTableFocus::ColumnInput => AddTableFocus::ColumnsTable,
AddTableFocus::ColumnsTable => AddTableFocus::IndexInput,
AddTableFocus::IndexInput => AddTableFocus::IndexesTable,
AddTableFocus::IndexesTable => AddTableFocus::LinkInput,
AddTableFocus::LinkInput => AddTableFocus::LinksTable,
// --- Horizontal Navigation (Left/Right) ---
Some("next_option") => { // 'l' or Right
add_table_state.current_focus = match current_focus {
AddTableFocus::SaveButton => AddTableFocus::CancelButton,
_ => current_focus, // No change for others yet
};
*command_message = format!("Focus set to {:?}", add_table_state.current_focus);
}
Some("previous_option") => { // 'h' or Left
add_table_state.current_focus = match current_focus {
AddTableFocus::CancelButton => AddTableFocus::SaveButton,
_ => current_focus, // No change for others yet
};
*command_message = format!("Focus set to {:?}", add_table_state.current_focus);
}
// --- Tab / Shift+Tab Navigation ---
Some("next_field") => { // Tab
add_table_state.current_focus = match current_focus {
AddTableFocus::InputTableName => AddTableFocus::InputColumnName,
AddTableFocus::InputColumnName => AddTableFocus::InputColumnType,
AddTableFocus::InputColumnType => AddTableFocus::AddColumnButton,
AddTableFocus::AddColumnButton => AddTableFocus::ColumnsTable,
AddTableFocus::ColumnsTable => AddTableFocus::IndexesTable,
AddTableFocus::IndexesTable => AddTableFocus::LinksTable,
AddTableFocus::LinksTable => AddTableFocus::SaveButton,
AddTableFocus::SaveButton => AddTableFocus::CancelButton,
AddTableFocus::CancelButton => AddTableFocus::TableName, // Wrap
}
AddTableFocus::CancelButton => AddTableFocus::InputTableName, // Wrap
};
*command_message = format!("Focus set to {:?}", add_table_state.current_focus);
}
"previous_option" => { // Typically Shift+Tab or Left arrow
state.current_focus = match current_focus {
// Simple vertical flow upwards
AddTableFocus::TableName => AddTableFocus::CancelButton, // Wrap
AddTableFocus::ColumnInput => AddTableFocus::TableName,
AddTableFocus::ColumnsTable => AddTableFocus::ColumnInput,
AddTableFocus::IndexInput => AddTableFocus::ColumnsTable,
AddTableFocus::IndexesTable => AddTableFocus::IndexInput,
AddTableFocus::LinkInput => AddTableFocus::IndexesTable,
AddTableFocus::LinksTable => AddTableFocus::LinkInput,
Some("prev_field") => { // Shift+Tab
add_table_state.current_focus = match current_focus {
AddTableFocus::InputTableName => AddTableFocus::CancelButton, // Wrap
AddTableFocus::InputColumnName => AddTableFocus::InputTableName,
AddTableFocus::InputColumnType => AddTableFocus::InputColumnName,
AddTableFocus::AddColumnButton => AddTableFocus::InputColumnType,
AddTableFocus::ColumnsTable => AddTableFocus::AddColumnButton,
AddTableFocus::IndexesTable => AddTableFocus::ColumnsTable,
AddTableFocus::LinksTable => AddTableFocus::IndexesTable,
AddTableFocus::SaveButton => AddTableFocus::LinksTable,
AddTableFocus::CancelButton => AddTableFocus::SaveButton,
};
*command_message = format!("Focus set to {:?}", add_table_state.current_focus);
}
// --- Selection ---
Some("select") => {
match current_focus {
AddTableFocus::AddColumnButton => {
*command_message = "Action: Add Column (Not Implemented)".to_string();
// TODO: Implement logic to add column based on inputs
// Clear input fields, add to columns list, mark unsaved changes
// add_table_state.add_column(); // Example method call
}
AddTableFocus::SaveButton => {
*command_message = "Action: Save Table (Not Implemented)".to_string();
// TODO: Implement logic to save table (e.g., call API)
// Mark changes as saved
// add_table_state.save_table(); // Example method call
}
AddTableFocus::CancelButton => {
*command_message = "Action: Cancel Add Table".to_string();
// TODO: Implement logic to navigate back (e.g., update AppView history)
// Maybe show a confirmation dialog if there are unsaved changes
// buffer_state.go_back(); // Example call
}
// Selecting input fields usually means entering Edit mode (handled elsewhere)
// Selecting tables might mean focusing on them for editing/deletion (TODO)
AddTableFocus::ColumnsTable => {
if let Some(index) = add_table_state.column_table_state.selected() {
*command_message = format!("Selected column index {}", index);
// TODO: Add logic for editing/deleting selected column
} else {
*command_message = "No column selected".to_string();
}
}
AddTableFocus::IndexesTable => {
if let Some(index) = add_table_state.index_table_state.selected() {
*command_message = format!("Selected index index {}", index);
// TODO: Add logic for editing/deleting selected index
} else {
*command_message = "No index selected".to_string();
}
}
AddTableFocus::LinksTable => {
if let Some(index) = add_table_state.link_table_state.selected() {
*command_message = format!("Selected link index {}", index);
// TODO: Add logic for editing/deleting selected link
} else {
*command_message = "No link selected".to_string();
}
}
_ => {
// For InputTableName, InputColumnName, InputColumnType,
// the main event loop should handle 'select' by potentially
// switching to Edit mode if not already in it.
// We don't need specific logic here for that.
*command_message = format!("Select on {:?}", current_focus);
handled = false; // Let main loop handle edit mode toggle maybe
}
}
}
"select" => {
// TODO: Implement select action based on current_focus
// e.g., Enter edit mode for TableName/Inputs, toggle link required, trigger save/cancel
handled = false; // Mark as not handled for now
// --- Other General Keys (Ignore for add_table nav) ---
Some("toggle_sidebar") | Some("toggle_buffer_list") => {
handled = false; // Let global handler manage these
}
_ => handled = false, // Action not relevant for this navigation
// --- No matching action ---
_ => handled = false, // Event not handled by add_table navigation
}
// If focus changed to a table, select the first row if nothing is selected
if handled && current_focus != state.current_focus {
match state.current_focus {
AddTableFocus::ColumnsTable if state.column_table_state.selected().is_none() && !state.columns.is_empty() => {
state.column_table_state.select(Some(0));
// If focus changed TO a table, select the first row if nothing is selected
if handled && current_focus != add_table_state.current_focus {
match add_table_state.current_focus {
AddTableFocus::ColumnsTable if add_table_state.column_table_state.selected().is_none() && !add_table_state.columns.is_empty() => {
add_table_state.column_table_state.select(Some(0));
}
AddTableFocus::IndexesTable if state.index_table_state.selected().is_none() && !state.indexes.is_empty() => {
state.index_table_state.select(Some(0));
AddTableFocus::IndexesTable if add_table_state.index_table_state.selected().is_none() && !add_table_state.indexes.is_empty() => {
add_table_state.index_table_state.select(Some(0));
}
AddTableFocus::LinksTable if state.link_table_state.selected().is_none() && !state.links.is_empty() => {
state.link_table_state.select(Some(0));
AddTableFocus::LinksTable if add_table_state.link_table_state.selected().is_none() && !add_table_state.links.is_empty() => {
add_table_state.link_table_state.select(Some(0));
}
_ => {} // No action needed for other focus states
}
}
handled
}
// Helper function for navigating up within a table state
// Returns true if navigation happened within the table, false if it reached the top
fn navigate_table_up(table_state: &mut ratatui::widgets::TableState, item_count: usize) -> bool {
fn navigate_table_up(table_state: &mut TableState, item_count: usize) -> bool {
if item_count == 0 { return false; } // Cannot navigate empty table
let current_selection = table_state.selected();
match current_selection {
@@ -141,7 +229,8 @@ fn navigate_table_up(table_state: &mut ratatui::widgets::TableState, item_count:
}
}
None => {
table_state.select(Some(item_count - 1)); // Select last item if nothing selected
// If nothing selected, moving up could select the last item
table_state.select(Some(item_count - 1));
true
}
}
@@ -149,7 +238,7 @@ fn navigate_table_up(table_state: &mut ratatui::widgets::TableState, item_count:
// Helper function for navigating down within a table state
// Returns true if navigation happened within the table, false if it reached the bottom
fn navigate_table_down(table_state: &mut ratatui::widgets::TableState, item_count: usize) -> bool {
fn navigate_table_down(table_state: &mut TableState, item_count: usize) -> bool {
if item_count == 0 { return false; } // Cannot navigate empty table
let current_selection = table_state.selected();
match current_selection {
@@ -162,8 +251,10 @@ fn navigate_table_down(table_state: &mut ratatui::widgets::TableState, item_coun
}
}
None => {
table_state.select(Some(0)); // Select first item if nothing selected
// If nothing selected, moving down could select the first item
table_state.select(Some(0));
true
}
}
}