moving the state from general to each page owning its own state of button or canvas focus
This commit is contained in:
@@ -43,15 +43,29 @@ pub fn handle_admin_navigation(
|
||||
) -> bool {
|
||||
let action = config.get_general_action(key.code, key.modifiers).map(String::from);
|
||||
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
// Check if we're in admin page, but don't borrow mutably yet
|
||||
let is_admin = matches!(&router.current, Page::Admin(_));
|
||||
if !is_admin {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the current focus without borrowing mutably
|
||||
let current_focus = if let Page::Admin(admin_state) = &router.current {
|
||||
admin_state.current_focus
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
let current_focus = admin_state.current_focus;
|
||||
|
||||
let profile_count = app_state.profile_tree.profiles.len();
|
||||
let mut handled = false;
|
||||
|
||||
match current_focus {
|
||||
AdminFocus::ProfilesPane => {
|
||||
// Now we can borrow mutably since we're not reassigning router.current
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
return false;
|
||||
};
|
||||
|
||||
match action.as_deref() {
|
||||
Some("select") => {
|
||||
admin_state.current_focus = AdminFocus::InsideProfilesList;
|
||||
@@ -69,7 +83,6 @@ pub fn handle_admin_navigation(
|
||||
handled = true;
|
||||
}
|
||||
Some("previous_option") | Some("move_up") => {
|
||||
// No wrap-around: Stay on ProfilesPane if trying to go "before" it
|
||||
*command_message = "At first focusable pane.".to_string();
|
||||
handled = true;
|
||||
}
|
||||
@@ -78,6 +91,10 @@ pub fn handle_admin_navigation(
|
||||
}
|
||||
|
||||
AdminFocus::InsideProfilesList => {
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
return false;
|
||||
};
|
||||
|
||||
match action.as_deref() {
|
||||
Some("move_up") => {
|
||||
if profile_count > 0 {
|
||||
@@ -95,11 +112,11 @@ pub fn handle_admin_navigation(
|
||||
}
|
||||
Some("select") => {
|
||||
admin_state.selected_profile_index = admin_state.profile_list_state.selected();
|
||||
admin_state.selected_table_index = None; // Deselect table when profile changes
|
||||
admin_state.selected_table_index = None;
|
||||
if let Some(profile_idx) = admin_state.selected_profile_index {
|
||||
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)); // Auto-select first table for nav
|
||||
admin_state.table_list_state.select(Some(0));
|
||||
} else {
|
||||
admin_state.table_list_state.select(None);
|
||||
}
|
||||
@@ -123,6 +140,10 @@ pub fn handle_admin_navigation(
|
||||
}
|
||||
|
||||
AdminFocus::Tables => {
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
return false;
|
||||
};
|
||||
|
||||
match action.as_deref() {
|
||||
Some("select") => {
|
||||
admin_state.current_focus = AdminFocus::InsideTablesList;
|
||||
@@ -152,7 +173,7 @@ pub fn handle_admin_navigation(
|
||||
} else {
|
||||
*command_message = "No tables in selected profile.".to_string();
|
||||
}
|
||||
admin_state.current_focus = AdminFocus::Tables; // Stay in Tables pane if no tables to enter
|
||||
admin_state.current_focus = AdminFocus::Tables;
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
@@ -171,6 +192,10 @@ pub fn handle_admin_navigation(
|
||||
}
|
||||
|
||||
AdminFocus::InsideTablesList => {
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
return false;
|
||||
};
|
||||
|
||||
match action.as_deref() {
|
||||
Some("move_up") => {
|
||||
let current_profile_idx = admin_state.selected_profile_index
|
||||
@@ -210,7 +235,7 @@ pub fn handle_admin_navigation(
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
Some("select") => { // This is for persistently selecting a table with [*]
|
||||
Some("select") => {
|
||||
admin_state.selected_table_index = admin_state.table_list_state.selected();
|
||||
let table_name = admin_state.selected_profile_index
|
||||
.and_then(|p_idx| app_state.profile_tree.profiles.get(p_idx))
|
||||
@@ -230,10 +255,17 @@ pub fn handle_admin_navigation(
|
||||
|
||||
AdminFocus::Button1 => { // Add Logic Button
|
||||
match action.as_deref() {
|
||||
Some("select") => { // Typically "Enter" key
|
||||
if let Some(p_idx) = admin_state.selected_profile_index {
|
||||
Some("select") => {
|
||||
// Extract needed data first, before any router reassignment
|
||||
let (selected_profile_idx, selected_table_idx) = if let Page::Admin(admin_state) = &router.current {
|
||||
(admin_state.selected_profile_index, admin_state.selected_table_index)
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if let Some(p_idx) = selected_profile_idx {
|
||||
if let Some(profile) = app_state.profile_tree.profiles.get(p_idx) {
|
||||
if let Some(t_idx) = admin_state.selected_table_index {
|
||||
if let Some(t_idx) = selected_table_idx {
|
||||
if let Some(table) = profile.tables.get(t_idx) {
|
||||
// Create AddLogic page with selected profile & table
|
||||
let add_logic_form = AddLogicFormState::new_with_table(
|
||||
@@ -243,16 +275,16 @@ pub fn handle_admin_navigation(
|
||||
table.name.clone(),
|
||||
);
|
||||
|
||||
// Route to AddLogic
|
||||
router.current = Page::AddLogic(add_logic_form);
|
||||
// Store table info for later fetching
|
||||
app_state.pending_table_structure_fetch = Some((
|
||||
profile.name.clone(),
|
||||
table.name.clone(),
|
||||
));
|
||||
|
||||
|
||||
// Now it's safe to reassign router.current
|
||||
router.current = Page::AddLogic(add_logic_form);
|
||||
buffer_state.update_history(AppView::AddLogic);
|
||||
app_state.ui.focus_outside_canvas = false;
|
||||
|
||||
*command_message = format!(
|
||||
"Opening Add Logic for table '{}' in profile '{}'...",
|
||||
table.name, profile.name
|
||||
@@ -272,11 +304,17 @@ pub fn handle_admin_navigation(
|
||||
handled = true;
|
||||
}
|
||||
Some("previous_option") | Some("move_up") => {
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
return false;
|
||||
};
|
||||
admin_state.current_focus = AdminFocus::Tables;
|
||||
*command_message = "Focus: Tables Pane".to_string();
|
||||
handled = true;
|
||||
}
|
||||
Some("next_option") | Some("move_down") => {
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
return false;
|
||||
};
|
||||
admin_state.current_focus = AdminFocus::Button2;
|
||||
*command_message = "Focus: Add Table Button".to_string();
|
||||
handled = true;
|
||||
@@ -288,23 +326,32 @@ pub fn handle_admin_navigation(
|
||||
AdminFocus::Button2 => { // Add Table Button
|
||||
match action.as_deref() {
|
||||
Some("select") => {
|
||||
if let Some(p_idx) = admin_state.selected_profile_index {
|
||||
// Extract needed data first
|
||||
let selected_profile_idx = if let Page::Admin(admin_state) = &router.current {
|
||||
admin_state.selected_profile_index
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if let Some(p_idx) = selected_profile_idx {
|
||||
if let Some(profile) = app_state.profile_tree.profiles.get(p_idx) {
|
||||
let selected_profile_name = profile.name.clone();
|
||||
// Prepare links from the selected profile's existing tables
|
||||
let available_links: Vec<LinkDefinition> = profile.tables.iter()
|
||||
.map(|table| LinkDefinition {
|
||||
linked_table_name: table.name.clone(),
|
||||
is_required: false, // Default, can be changed in AddTable screen
|
||||
is_required: false,
|
||||
selected: false,
|
||||
}).collect();
|
||||
|
||||
// Build decoupled AddTable page and route into it
|
||||
let mut page = AddTableFormState::new(selected_profile_name.clone());
|
||||
page.state.links = available_links;
|
||||
|
||||
// Now safe to reassign router.current
|
||||
router.current = Page::AddTable(page);
|
||||
buffer_state.update_history(AppView::AddTable);
|
||||
app_state.ui.focus_outside_canvas = false;
|
||||
|
||||
*command_message = format!(
|
||||
"Opening Add Table for profile '{}'...",
|
||||
selected_profile_name
|
||||
@@ -320,11 +367,17 @@ pub fn handle_admin_navigation(
|
||||
}
|
||||
}
|
||||
Some("previous_option") | Some("move_up") => {
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
return false;
|
||||
};
|
||||
admin_state.current_focus = AdminFocus::Button1;
|
||||
*command_message = "Focus: Add Logic Button".to_string();
|
||||
handled = true;
|
||||
}
|
||||
Some("next_option") | Some("move_down") => {
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
return false;
|
||||
};
|
||||
admin_state.current_focus = AdminFocus::Button3;
|
||||
*command_message = "Focus: Change Table Button".to_string();
|
||||
handled = true;
|
||||
@@ -336,17 +389,18 @@ pub fn handle_admin_navigation(
|
||||
AdminFocus::Button3 => { // Change Table Button
|
||||
match action.as_deref() {
|
||||
Some("select") => {
|
||||
// Future: Logic to load selected table into AddTableState for editing
|
||||
*command_message = "Action: Change Table (Not Implemented)".to_string();
|
||||
handled = true;
|
||||
}
|
||||
Some("previous_option") | Some("move_up") => {
|
||||
let Page::Admin(admin_state) = &mut router.current else {
|
||||
return false;
|
||||
};
|
||||
admin_state.current_focus = AdminFocus::Button2;
|
||||
*command_message = "Focus: Add Table Button".to_string();
|
||||
handled = true;
|
||||
}
|
||||
Some("next_option") | Some("move_down") => {
|
||||
// No wrap-around: Stay on Button3 if trying to go "after" it
|
||||
*command_message = "At last focusable button.".to_string();
|
||||
handled = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user