add table movement adjustements
This commit is contained in:
@@ -12,11 +12,32 @@ use crate::services::GrpcClient;
|
||||
use tokio::sync::mpsc;
|
||||
use anyhow::Result;
|
||||
|
||||
// Define a type for the save result channel
|
||||
pub type SaveTableResultSender = mpsc::Sender<Result<String>>;
|
||||
|
||||
/// Handles navigation events specifically for the Add Table view.
|
||||
/// Returns true if the event was handled, false otherwise.
|
||||
fn navigate_table_up(table_state: &mut TableState, item_count: usize) -> bool {
|
||||
if item_count == 0 { return false; }
|
||||
let current_selection = table_state.selected();
|
||||
match current_selection {
|
||||
Some(index) => {
|
||||
if index > 0 { table_state.select(Some(index - 1)); true }
|
||||
else { false }
|
||||
}
|
||||
None => { table_state.select(Some(0)); true }
|
||||
}
|
||||
}
|
||||
|
||||
fn navigate_table_down(table_state: &mut TableState, item_count: usize) -> bool {
|
||||
if item_count == 0 { return false; }
|
||||
let current_selection = table_state.selected();
|
||||
match current_selection {
|
||||
Some(index) => {
|
||||
if index < item_count - 1 { table_state.select(Some(index + 1)); true }
|
||||
else { false }
|
||||
}
|
||||
None => { table_state.select(Some(0)); true }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_add_table_navigation(
|
||||
key: KeyEvent,
|
||||
config: &Config,
|
||||
@@ -28,61 +49,52 @@ pub fn handle_add_table_navigation(
|
||||
) -> bool {
|
||||
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
|
||||
let mut new_focus = current_focus; // Initialize new_focus
|
||||
let mut handled = true;
|
||||
let mut new_focus = current_focus;
|
||||
|
||||
if matches!(current_focus, AddTableFocus::InsideColumnsTable | AddTableFocus::InsideIndexesTable | AddTableFocus::InsideLinksTable) {
|
||||
if matches!(action.as_deref(), Some("next_option") | Some("previous_option")) {
|
||||
*command_message = "Press Esc to exit table item navigation first.".to_string();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
match action.as_deref() {
|
||||
// --- Handle Exiting Table Scroll Mode ---
|
||||
Some("exit_table_scroll") => {
|
||||
match current_focus {
|
||||
AddTableFocus::InsideColumnsTable => {
|
||||
add_table_state.column_table_state.select(None);
|
||||
new_focus = AddTableFocus::ColumnsTable;
|
||||
*command_message = "Exited Columns Table".to_string();
|
||||
// *command_message = "Exited Columns Table".to_string(); // Minimal change: remove message
|
||||
}
|
||||
AddTableFocus::InsideIndexesTable => {
|
||||
add_table_state.index_table_state.select(None);
|
||||
new_focus = AddTableFocus::IndexesTable;
|
||||
*command_message = "Exited Indexes Table".to_string();
|
||||
// *command_message = "Exited Indexes Table".to_string();
|
||||
}
|
||||
AddTableFocus::InsideLinksTable => {
|
||||
add_table_state.link_table_state.select(None);
|
||||
new_focus = AddTableFocus::LinksTable;
|
||||
*command_message = "Exited Links Table".to_string();
|
||||
}
|
||||
_ => {
|
||||
// Action triggered but not applicable in this focus state
|
||||
handled = false;
|
||||
// *command_message = "Exited Links Table".to_string();
|
||||
}
|
||||
_ => handled = false,
|
||||
}
|
||||
// If handled (i.e., focus changed), handled remains true.
|
||||
// If not handled, handled becomes false.
|
||||
}
|
||||
|
||||
// --- Vertical Navigation (Up/Down) ---
|
||||
Some("move_up") => {
|
||||
match current_focus {
|
||||
AddTableFocus::InputTableName => new_focus = AddTableFocus::CancelButton,
|
||||
AddTableFocus::InputTableName => {
|
||||
// MINIMAL CHANGE: Do nothing, new_focus remains current_focus
|
||||
// *command_message = "At top of form.".to_string(); // Remove message
|
||||
}
|
||||
AddTableFocus::InputColumnName => new_focus = AddTableFocus::InputTableName,
|
||||
AddTableFocus::InputColumnType => new_focus = AddTableFocus::InputColumnName,
|
||||
AddTableFocus::AddColumnButton => new_focus = AddTableFocus::InputColumnType,
|
||||
// Navigate between blocks when focus is on the table block itself
|
||||
AddTableFocus::ColumnsTable => new_focus = AddTableFocus::AddColumnButton, // Move up to right pane
|
||||
AddTableFocus::ColumnsTable => new_focus = AddTableFocus::AddColumnButton,
|
||||
AddTableFocus::IndexesTable => new_focus = AddTableFocus::ColumnsTable,
|
||||
AddTableFocus::LinksTable => new_focus = AddTableFocus::IndexesTable,
|
||||
// Scroll inside the table when focus is internal
|
||||
AddTableFocus::InsideColumnsTable => {
|
||||
navigate_table_up(&mut add_table_state.column_table_state, add_table_state.columns.len());
|
||||
// Stay inside the table, don't change new_focus
|
||||
}
|
||||
AddTableFocus::InsideIndexesTable => {
|
||||
navigate_table_up(&mut add_table_state.index_table_state, add_table_state.indexes.len());
|
||||
// Stay inside the table
|
||||
}
|
||||
AddTableFocus::InsideLinksTable => {
|
||||
navigate_table_up(&mut add_table_state.link_table_state, add_table_state.links.len());
|
||||
// Stay inside the table
|
||||
}
|
||||
AddTableFocus::InsideColumnsTable => { navigate_table_up(&mut add_table_state.column_table_state, add_table_state.columns.len()); }
|
||||
AddTableFocus::InsideIndexesTable => { navigate_table_up(&mut add_table_state.index_table_state, add_table_state.indexes.len()); }
|
||||
AddTableFocus::InsideLinksTable => { navigate_table_up(&mut add_table_state.link_table_state, add_table_state.links.len()); }
|
||||
AddTableFocus::SaveButton => new_focus = AddTableFocus::LinksTable,
|
||||
AddTableFocus::DeleteSelectedButton => new_focus = AddTableFocus::SaveButton,
|
||||
AddTableFocus::CancelButton => new_focus = AddTableFocus::DeleteSelectedButton,
|
||||
@@ -94,304 +106,97 @@ pub fn handle_add_table_navigation(
|
||||
AddTableFocus::InputColumnName => new_focus = AddTableFocus::InputColumnType,
|
||||
AddTableFocus::InputColumnType => new_focus = AddTableFocus::AddColumnButton,
|
||||
AddTableFocus::AddColumnButton => new_focus = AddTableFocus::ColumnsTable,
|
||||
// Navigate between blocks when focus is on the table block itself
|
||||
AddTableFocus::ColumnsTable => new_focus = AddTableFocus::IndexesTable,
|
||||
AddTableFocus::IndexesTable => new_focus = AddTableFocus::LinksTable,
|
||||
AddTableFocus::LinksTable => new_focus = AddTableFocus::SaveButton, // Move down to right pane
|
||||
// Scroll inside the table when focus is internal
|
||||
AddTableFocus::InsideColumnsTable => {
|
||||
navigate_table_down(&mut add_table_state.column_table_state, add_table_state.columns.len());
|
||||
// Stay inside the table
|
||||
}
|
||||
AddTableFocus::InsideIndexesTable => {
|
||||
navigate_table_down(&mut add_table_state.index_table_state, add_table_state.indexes.len());
|
||||
// Stay inside the table
|
||||
}
|
||||
AddTableFocus::InsideLinksTable => {
|
||||
navigate_table_down(&mut add_table_state.link_table_state, add_table_state.links.len());
|
||||
// Stay inside the table
|
||||
}
|
||||
AddTableFocus::LinksTable => new_focus = AddTableFocus::SaveButton,
|
||||
AddTableFocus::InsideColumnsTable => { navigate_table_down(&mut add_table_state.column_table_state, add_table_state.columns.len()); }
|
||||
AddTableFocus::InsideIndexesTable => { navigate_table_down(&mut add_table_state.index_table_state, add_table_state.indexes.len()); }
|
||||
AddTableFocus::InsideLinksTable => { navigate_table_down(&mut add_table_state.link_table_state, add_table_state.links.len()); }
|
||||
AddTableFocus::SaveButton => new_focus = AddTableFocus::DeleteSelectedButton,
|
||||
AddTableFocus::DeleteSelectedButton => new_focus = AddTableFocus::CancelButton,
|
||||
AddTableFocus::CancelButton => new_focus = AddTableFocus::InputTableName,
|
||||
AddTableFocus::CancelButton => {
|
||||
// MINIMAL CHANGE: Do nothing, new_focus remains current_focus
|
||||
// *command_message = "At bottom of form.".to_string(); // Remove message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Horizontal Navigation (Left/Right) ---
|
||||
Some("next_option") => { // 'l' or Right: Move from Left Pane to Right Pane
|
||||
// Horizontal nav within bottom buttons
|
||||
if current_focus == AddTableFocus::SaveButton {
|
||||
new_focus = AddTableFocus::DeleteSelectedButton;
|
||||
} else if current_focus == AddTableFocus::DeleteSelectedButton {
|
||||
new_focus = AddTableFocus::CancelButton;
|
||||
}
|
||||
Some("next_option") => { // This logic should already be non-wrapping
|
||||
match current_focus {
|
||||
AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType =>
|
||||
{ new_focus = AddTableFocus::AddColumnButton; }
|
||||
AddTableFocus::AddColumnButton => new_focus = AddTableFocus::ColumnsTable,
|
||||
AddTableFocus::ColumnsTable => new_focus = AddTableFocus::IndexesTable,
|
||||
AddTableFocus::IndexesTable => new_focus = AddTableFocus::LinksTable,
|
||||
AddTableFocus::LinksTable => new_focus = AddTableFocus::SaveButton,
|
||||
AddTableFocus::SaveButton => new_focus = AddTableFocus::DeleteSelectedButton,
|
||||
AddTableFocus::DeleteSelectedButton => new_focus = AddTableFocus::CancelButton,
|
||||
AddTableFocus::CancelButton => { /* *command_message = "At last focusable area.".to_string(); */ } // No change in focus
|
||||
_ => handled = false,
|
||||
}
|
||||
}
|
||||
Some("previous_option") => { // 'h' or Left: Move from Right Pane to Left Pane
|
||||
// Horizontal nav within bottom buttons
|
||||
if current_focus == AddTableFocus::CancelButton {
|
||||
new_focus = AddTableFocus::DeleteSelectedButton;
|
||||
} else if current_focus == AddTableFocus::DeleteSelectedButton {
|
||||
new_focus = AddTableFocus::SaveButton;
|
||||
}
|
||||
Some("previous_option") => { // This logic should already be non-wrapping
|
||||
match current_focus {
|
||||
AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType =>
|
||||
{ /* *command_message = "At first focusable area.".to_string(); */ } // No change in focus
|
||||
AddTableFocus::AddColumnButton => new_focus = AddTableFocus::InputColumnType,
|
||||
AddTableFocus::ColumnsTable => new_focus = AddTableFocus::AddColumnButton,
|
||||
AddTableFocus::IndexesTable => new_focus = AddTableFocus::ColumnsTable,
|
||||
AddTableFocus::LinksTable => new_focus = AddTableFocus::IndexesTable,
|
||||
AddTableFocus::SaveButton => new_focus = AddTableFocus::LinksTable,
|
||||
AddTableFocus::DeleteSelectedButton => new_focus = AddTableFocus::SaveButton,
|
||||
AddTableFocus::CancelButton => new_focus = AddTableFocus::DeleteSelectedButton,
|
||||
_ => handled = false,
|
||||
}
|
||||
}
|
||||
|
||||
// --- Tab / Shift+Tab Navigation (Keep as vertical cycle) ---
|
||||
Some("next_field") => { // Tab
|
||||
Some("next_field") => {
|
||||
new_focus = match current_focus {
|
||||
AddTableFocus::InputTableName => AddTableFocus::InputColumnName,
|
||||
AddTableFocus::InputColumnName => AddTableFocus::InputColumnType,
|
||||
AddTableFocus::InputColumnType => AddTableFocus::AddColumnButton,
|
||||
AddTableFocus::AddColumnButton => AddTableFocus::ColumnsTable,
|
||||
// Treat Inside* same as block focus for tabbing out
|
||||
AddTableFocus::ColumnsTable | AddTableFocus::InsideColumnsTable => AddTableFocus::IndexesTable,
|
||||
AddTableFocus::IndexesTable | AddTableFocus::InsideIndexesTable => AddTableFocus::LinksTable,
|
||||
AddTableFocus::LinksTable | AddTableFocus::InsideLinksTable => AddTableFocus::SaveButton,
|
||||
AddTableFocus::SaveButton => AddTableFocus::DeleteSelectedButton,
|
||||
AddTableFocus::DeleteSelectedButton => AddTableFocus::CancelButton,
|
||||
AddTableFocus::CancelButton => AddTableFocus::InputTableName, // Wrap
|
||||
AddTableFocus::InputTableName => AddTableFocus::InputColumnName, AddTableFocus::InputColumnName => AddTableFocus::InputColumnType, AddTableFocus::InputColumnType => AddTableFocus::AddColumnButton, AddTableFocus::AddColumnButton => AddTableFocus::ColumnsTable,
|
||||
AddTableFocus::ColumnsTable | AddTableFocus::InsideColumnsTable => AddTableFocus::IndexesTable, AddTableFocus::IndexesTable | AddTableFocus::InsideIndexesTable => AddTableFocus::LinksTable, AddTableFocus::LinksTable | AddTableFocus::InsideLinksTable => AddTableFocus::SaveButton,
|
||||
AddTableFocus::SaveButton => AddTableFocus::DeleteSelectedButton, AddTableFocus::DeleteSelectedButton => AddTableFocus::CancelButton, AddTableFocus::CancelButton => AddTableFocus::InputTableName,
|
||||
};
|
||||
}
|
||||
Some("prev_field") => { // Shift+Tab
|
||||
Some("prev_field") => {
|
||||
new_focus = match current_focus {
|
||||
AddTableFocus::InputTableName => AddTableFocus::CancelButton, // Wrap
|
||||
AddTableFocus::InputColumnName => AddTableFocus::InputTableName,
|
||||
AddTableFocus::InputColumnType => AddTableFocus::InputColumnName,
|
||||
AddTableFocus::AddColumnButton => AddTableFocus::InputColumnType,
|
||||
// Treat Inside* same as block focus for tabbing out
|
||||
AddTableFocus::ColumnsTable | AddTableFocus::InsideColumnsTable => AddTableFocus::AddColumnButton,
|
||||
AddTableFocus::IndexesTable | AddTableFocus::InsideIndexesTable => AddTableFocus::ColumnsTable,
|
||||
AddTableFocus::LinksTable | AddTableFocus::InsideLinksTable => AddTableFocus::IndexesTable,
|
||||
AddTableFocus::SaveButton => AddTableFocus::LinksTable,
|
||||
AddTableFocus::DeleteSelectedButton => AddTableFocus::SaveButton,
|
||||
AddTableFocus::CancelButton => AddTableFocus::DeleteSelectedButton,
|
||||
AddTableFocus::InputTableName => AddTableFocus::CancelButton, AddTableFocus::InputColumnName => AddTableFocus::InputTableName, AddTableFocus::InputColumnType => AddTableFocus::InputColumnName, AddTableFocus::AddColumnButton => AddTableFocus::InputColumnType,
|
||||
AddTableFocus::ColumnsTable | AddTableFocus::InsideColumnsTable => AddTableFocus::AddColumnButton, AddTableFocus::IndexesTable | AddTableFocus::InsideIndexesTable => AddTableFocus::ColumnsTable, AddTableFocus::LinksTable | AddTableFocus::InsideLinksTable => AddTableFocus::IndexesTable,
|
||||
AddTableFocus::SaveButton => AddTableFocus::LinksTable, AddTableFocus::DeleteSelectedButton => AddTableFocus::SaveButton, AddTableFocus::CancelButton => AddTableFocus::DeleteSelectedButton,
|
||||
};
|
||||
}
|
||||
|
||||
// --- Selection ---
|
||||
Some("select") => {
|
||||
match current_focus {
|
||||
// --- Enter/Exit Table Focus ---
|
||||
AddTableFocus::ColumnsTable => {
|
||||
new_focus = AddTableFocus::InsideColumnsTable;
|
||||
// Select first item if none selected when entering
|
||||
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));
|
||||
}
|
||||
*command_message = "Entered Columns Table (Scroll with Up/Down, Select to exit)".to_string();
|
||||
}
|
||||
AddTableFocus::IndexesTable => {
|
||||
new_focus = AddTableFocus::InsideIndexesTable;
|
||||
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));
|
||||
}
|
||||
*command_message = "Entered Indexes Table (Scroll with Up/Down, Select to exit)".to_string();
|
||||
}
|
||||
AddTableFocus::LinksTable => {
|
||||
new_focus = AddTableFocus::InsideLinksTable;
|
||||
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));
|
||||
}
|
||||
*command_message = "Entered Links Table (Scroll with Up/Down, Select to toggle/exit)".to_string();
|
||||
}
|
||||
AddTableFocus::InsideColumnsTable => {
|
||||
// Toggle selection when pressing select *inside* the columns table
|
||||
if let Some(index) = add_table_state.column_table_state.selected() {
|
||||
if let Some(col) = add_table_state.columns.get_mut(index) {
|
||||
col.selected = !col.selected;
|
||||
add_table_state.has_unsaved_changes = true;
|
||||
*command_message = format!(
|
||||
"Toggled selection for column: {} to {}",
|
||||
col.name, col.selected
|
||||
);
|
||||
}
|
||||
} else {
|
||||
*command_message = "No column highlighted to toggle selection".to_string();
|
||||
}
|
||||
}
|
||||
AddTableFocus::InsideIndexesTable => {
|
||||
// Select does nothing here anymore, only Esc exits.
|
||||
if let Some(index) = add_table_state.index_table_state.selected() {
|
||||
if let Some(idx_def) = add_table_state.indexes.get_mut(index) {
|
||||
idx_def.selected = !idx_def.selected;
|
||||
add_table_state.has_unsaved_changes = true;
|
||||
*command_message = format!(
|
||||
"Toggled selection for index: {} to {}",
|
||||
idx_def.name, idx_def.selected
|
||||
);
|
||||
} else {
|
||||
*command_message = "Error: Selected index out of bounds".to_string();
|
||||
}
|
||||
} else {
|
||||
*command_message = "No index selected (Press Esc to exit scroll mode)".to_string();
|
||||
}
|
||||
}
|
||||
AddTableFocus::InsideLinksTable => {
|
||||
// Toggle selection when pressing select *inside* the links table
|
||||
if let Some(index) = add_table_state.link_table_state.selected() {
|
||||
if let Some(link) = add_table_state.links.get_mut(index) {
|
||||
link.selected = !link.selected; // Toggle the selected state
|
||||
add_table_state.has_unsaved_changes = true; // Mark changes
|
||||
*command_message = format!(
|
||||
"Toggled selection for link: {} to {}",
|
||||
link.linked_table_name, link.selected
|
||||
);
|
||||
} else {
|
||||
*command_message = "Error: Selected link index out of bounds".to_string();
|
||||
}
|
||||
} else {
|
||||
*command_message = "No link selected to toggle".to_string();
|
||||
}
|
||||
// Stay inside the links table after toggling
|
||||
new_focus = AddTableFocus::InsideLinksTable;
|
||||
// Alternative: Exit after toggle:
|
||||
// new_focus = AddTableFocus::LinksTable;
|
||||
// *command_message = format!("{} - Exited Links Table", command_message);
|
||||
}
|
||||
// --- Other Select Actions ---
|
||||
AddTableFocus::AddColumnButton => {
|
||||
if let Some(focus_after_add) = handle_add_column_action(add_table_state, command_message) {
|
||||
new_focus = focus_after_add;
|
||||
}
|
||||
}
|
||||
AddTableFocus::SaveButton => {
|
||||
// --- Initiate Async Save ---
|
||||
if add_table_state.table_name.is_empty() {
|
||||
*command_message = "Cannot save: Table name is empty.".to_string();
|
||||
} else if add_table_state.columns.is_empty() {
|
||||
*command_message = "Cannot save: No columns defined.".to_string();
|
||||
} else {
|
||||
*command_message = "Saving table...".to_string();
|
||||
app_state.show_loading_dialog("Saving", "Please wait...");
|
||||
|
||||
let mut client_clone = grpc_client.clone();
|
||||
let state_clone = add_table_state.clone();
|
||||
let sender_clone = save_result_sender.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let result = handle_save_table_action(&mut client_clone, &state_clone).await;
|
||||
let _ = sender_clone.send(result).await; // Send result back
|
||||
});
|
||||
}
|
||||
// --- End Initiate Async Save ---
|
||||
}
|
||||
AddTableFocus::DeleteSelectedButton => {
|
||||
// --- Show Confirmation Dialog ---
|
||||
// Collect tuples of (index, name, type) for selected columns
|
||||
let columns_to_delete: Vec<(usize, String, String)> = add_table_state
|
||||
.columns
|
||||
.iter()
|
||||
.enumerate() // Get index along with the column
|
||||
.filter(|(_index, col)| col.selected) // Filter based on selection
|
||||
.map(|(index, col)| (index, col.name.clone(), col.data_type.clone())) // Map to (index, name, type)
|
||||
.collect();
|
||||
|
||||
if columns_to_delete.is_empty() {
|
||||
*command_message = "No columns selected for deletion.".to_string();
|
||||
} else {
|
||||
// Format the message to include index, name, and type
|
||||
let column_details: String = columns_to_delete
|
||||
.iter()
|
||||
// Add 1 to index for 1-based numbering for user display
|
||||
.map(|(index, name, dtype)| format!("{}. {} ({})", index + 1, name, dtype))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
|
||||
// Use the formatted column_details string in the message
|
||||
let message = format!(
|
||||
"Delete the following columns?\n\n{}",
|
||||
column_details
|
||||
);
|
||||
let buttons = vec!["Confirm".to_string(), "Cancel".to_string()];
|
||||
app_state.show_dialog(
|
||||
"Confirm Deletion",
|
||||
&message,
|
||||
buttons,
|
||||
DialogPurpose::ConfirmDeleteColumns,
|
||||
);
|
||||
}
|
||||
}
|
||||
AddTableFocus::CancelButton => {
|
||||
*command_message = "Action: Cancel Add Table".to_string();
|
||||
// TODO: Implement logic
|
||||
}
|
||||
_ => { // Input fields
|
||||
*command_message = format!("Select on {:?}", current_focus);
|
||||
handled = false; // Let main loop handle edit mode toggle maybe
|
||||
}
|
||||
AddTableFocus::ColumnsTable => { new_focus = AddTableFocus::InsideColumnsTable; 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)); } /* Message removed */ }
|
||||
AddTableFocus::IndexesTable => { new_focus = AddTableFocus::InsideIndexesTable; 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)); } /* Message removed */ }
|
||||
AddTableFocus::LinksTable => { new_focus = AddTableFocus::InsideLinksTable; 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)); } /* Message removed */ }
|
||||
AddTableFocus::InsideColumnsTable => { if let Some(index) = add_table_state.column_table_state.selected() { if let Some(col) = add_table_state.columns.get_mut(index) { col.selected = !col.selected; add_table_state.has_unsaved_changes = true; /* Message removed */ }} /* else { Message removed } */ }
|
||||
AddTableFocus::InsideIndexesTable => { if let Some(index) = add_table_state.index_table_state.selected() { if let Some(idx_def) = add_table_state.indexes.get_mut(index) { idx_def.selected = !idx_def.selected; add_table_state.has_unsaved_changes = true; /* Message removed */ }} /* else { Message removed } */ }
|
||||
AddTableFocus::InsideLinksTable => { if let Some(index) = add_table_state.link_table_state.selected() { if let Some(link) = add_table_state.links.get_mut(index) { link.selected = !link.selected; add_table_state.has_unsaved_changes = true; /* Message removed */ }} /* else { Message removed } */ }
|
||||
AddTableFocus::AddColumnButton => { if let Some(focus_after_add) = handle_add_column_action(add_table_state, command_message) { new_focus = focus_after_add; } else { /* Message already set by handle_add_column_action */ }}
|
||||
AddTableFocus::SaveButton => { if add_table_state.table_name.is_empty() { *command_message = "Cannot save: Table name is empty.".to_string(); } else if add_table_state.columns.is_empty() { *command_message = "Cannot save: No columns defined.".to_string(); } else { *command_message = "Saving table...".to_string(); app_state.show_loading_dialog("Saving", "Please wait..."); let mut client_clone = grpc_client.clone(); let state_clone = add_table_state.clone(); let sender_clone = save_result_sender.clone(); tokio::spawn(async move { let result = handle_save_table_action(&mut client_clone, &state_clone).await; let _ = sender_clone.send(result).await; }); }}
|
||||
AddTableFocus::DeleteSelectedButton => { let columns_to_delete: Vec<(usize, String, String)> = add_table_state.columns.iter().enumerate().filter(|(_, col)| col.selected).map(|(index, col)| (index, col.name.clone(), col.data_type.clone())).collect(); if columns_to_delete.is_empty() { *command_message = "No columns selected for deletion.".to_string(); } else { let column_details: String = columns_to_delete.iter().map(|(index, name, dtype)| format!("{}. {} ({})", index + 1, name, dtype)).collect::<Vec<String>>().join("\n"); let message = format!("Delete the following columns?\n\n{}", column_details); app_state.show_dialog("Confirm Deletion", &message, vec!["Confirm".to_string(), "Cancel".to_string()], DialogPurpose::ConfirmDeleteColumns); }}
|
||||
AddTableFocus::CancelButton => { *command_message = "Action: Cancel Add Table (Not Implemented)".to_string(); }
|
||||
_ => { handled = false; }
|
||||
}
|
||||
// Keep handled = true for select actions unless specifically set to false
|
||||
}
|
||||
|
||||
// --- Other General Keys ---
|
||||
Some("toggle_sidebar") | Some("toggle_buffer_list") => {
|
||||
handled = false;
|
||||
}
|
||||
|
||||
// --- No matching action ---
|
||||
_ => handled = false,
|
||||
}
|
||||
|
||||
// Update focus state if it changed and was handled
|
||||
if handled && current_focus != new_focus {
|
||||
add_table_state.current_focus = new_focus;
|
||||
// Avoid overwriting specific messages set during 'select' handling
|
||||
if command_message.is_empty() || command_message.starts_with("Focus set to") {
|
||||
*command_message = format!("Focus set to {:?}", add_table_state.current_focus);
|
||||
// Minimal change: Command message update logic can be simplified or removed if not desired
|
||||
// For now, let's keep it minimal and only update if it was truly a focus change,
|
||||
// and not a boundary message.
|
||||
if !command_message.starts_with("At ") && current_focus != new_focus { // Avoid overwriting boundary messages
|
||||
// *command_message = format!("Focus: {:?}", add_table_state.current_focus); // Optional: restore if needed
|
||||
}
|
||||
|
||||
// Check if the *new* focus target is one of the canvas input fields
|
||||
|
||||
let new_is_canvas_input_focus = matches!(new_focus,
|
||||
AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType
|
||||
);
|
||||
// Focus is outside canvas if it's not an input field
|
||||
app_state.ui.focus_outside_canvas = !new_is_canvas_input_focus;
|
||||
} else if !handled {
|
||||
// command_message.clear(); // Optional: Clear message if not handled here
|
||||
}
|
||||
// If not handled, command_message remains as it was (e.g., from a deeper function call or previous event)
|
||||
// or can be cleared if that's the desired default. For minimal change, we leave it.
|
||||
|
||||
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 TableState, item_count: usize) -> bool {
|
||||
if item_count == 0 { return false; }
|
||||
let current_selection = table_state.selected();
|
||||
match current_selection {
|
||||
Some(index) => {
|
||||
if index > 0 {
|
||||
table_state.select(Some(index - 1));
|
||||
true // Navigation happened
|
||||
} else {
|
||||
false // Was at the top
|
||||
}
|
||||
}
|
||||
None => { // No item selected, select the last one
|
||||
table_state.select(Some(item_count - 1));
|
||||
true // Navigation happened (selection set)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 TableState, item_count: usize) -> bool {
|
||||
if item_count == 0 { return false; }
|
||||
let current_selection = table_state.selected();
|
||||
match current_selection {
|
||||
Some(index) => {
|
||||
if index < item_count - 1 {
|
||||
table_state.select(Some(index + 1));
|
||||
true // Navigation happened
|
||||
} else {
|
||||
false // Was at the bottom
|
||||
}
|
||||
}
|
||||
None => { // No item selected, select the first one
|
||||
table_state.select(Some(0));
|
||||
true // Navigation happened (selection set)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user