diff --git a/client/src/components/admin.rs b/client/src/components/admin.rs index 46bccbe..cf826ee 100644 --- a/client/src/components/admin.rs +++ b/client/src/components/admin.rs @@ -1,10 +1,6 @@ // src/components/admin.rs -pub mod admin_panel; -pub mod admin_panel_admin; pub mod add_table; pub mod add_logic; -pub use admin_panel::*; -pub use admin_panel_admin::*; pub use add_table::*; pub use add_logic::*; diff --git a/client/src/components/admin/admin_panel.rs b/client/src/components/admin/admin_panel.rs deleted file mode 100644 index f3b5eff..0000000 --- a/client/src/components/admin/admin_panel.rs +++ /dev/null @@ -1,131 +0,0 @@ -// src/components/admin/admin_panel.rs - -use crate::config::colors::themes::Theme; -use crate::state::pages::auth::AuthState; -use crate::state::app::state::AppState; -use crate::pages::admin::AdminState; -use common::proto::komp_ac::table_definition::ProfileTreeResponse; -use ratatui::{ - layout::{Constraint, Direction, Layout, Rect}, - style::Style, - text::{Line, Span, Text}, - widgets::{Block, BorderType, Borders, List, ListItem, Paragraph, Wrap}, - Frame, -}; -use super::admin_panel_admin::render_admin_panel_admin; - -pub fn render_admin_panel( - f: &mut Frame, - app_state: &AppState, - auth_state: &AuthState, - admin_state: &mut AdminState, - area: Rect, - theme: &Theme, - profile_tree: &ProfileTreeResponse, - selected_profile: &Option, -) { - let block = Block::default() - .borders(Borders::ALL) - .border_type(BorderType::Rounded) - .border_style(Style::default().fg(theme.accent)) - .style(Style::default().bg(theme.bg)); - - let inner_area = block.inner(area); - f.render_widget(block, area); - - let chunks = Layout::default() - .direction(Direction::Vertical) - .constraints([Constraint::Length(3), Constraint::Min(1)]) - .split(inner_area); - - // Content - let content_chunks = Layout::default() - .direction(Direction::Horizontal) - .constraints([Constraint::Percentage(30), Constraint::Percentage(70)]) - .split(chunks[1]); - - if auth_state.role.as_deref() != Some("admin") { - render_admin_panel_non_admin( - f, - admin_state, - &content_chunks, - theme, - profile_tree, - selected_profile, - ); - } else { - render_admin_panel_admin( - f, - chunks[1], - app_state, - admin_state, - theme, - ); - } -} - -/// Renders the view for non-admin users (profile list and details). -fn render_admin_panel_non_admin( - f: &mut Frame, - admin_state: &AdminState, - content_chunks: &[Rect], - theme: &Theme, - profile_tree: &ProfileTreeResponse, - selected_profile: &Option, -) { - // Profile list - Use data from admin_state - let items: Vec = admin_state - .profiles - .iter() - .map(|p| { - ListItem::new(Line::from(vec![ - Span::styled( - if Some(p) == selected_profile.as_ref() { "✓ " } else { " " }, - Style::default().fg(theme.accent), - ), - Span::styled(p, Style::default().fg(theme.fg)), - ])) - }) - .collect(); - - let list = List::new(items) - .block(Block::default().title("Profiles")) - .highlight_style(Style::default().bg(theme.highlight).fg(theme.bg)); - - let mut profile_list_state_clone = admin_state.profile_list_state.clone(); - f.render_stateful_widget(list, content_chunks[0], &mut profile_list_state_clone); - - // Profile details - Use selection info from admin_state - if let Some(profile) = admin_state - .get_selected_index() - .and_then(|i| profile_tree.profiles.get(i)) - { - let mut text = Text::default(); - text.lines.push(Line::from(vec![ - Span::styled("Profile: ", Style::default().fg(theme.accent)), - Span::styled(&profile.name, Style::default().fg(theme.highlight)), - ])); - - text.lines.push(Line::from("")); - text.lines.push(Line::from(Span::styled( - "Tables:", - Style::default().fg(theme.accent), - ))); - - for table in &profile.tables { - let mut line = vec![Span::styled(format!("├─ {}", table.name), theme.fg)]; - if !table.depends_on.is_empty() { - line.push(Span::styled( - format!(" → {}", table.depends_on.join(", ")), - Style::default().fg(theme.secondary), - )); - } - text.lines.push(Line::from(line)); - } - - let details_widget = Paragraph::new(text) - .block(Block::default().title("Details")) - .wrap(Wrap { trim: true }); - f.render_widget(details_widget, content_chunks[1]); - } -} diff --git a/client/src/components/admin/admin_panel_admin.rs b/client/src/components/admin/admin_panel_admin.rs deleted file mode 100644 index 6e3d431..0000000 --- a/client/src/components/admin/admin_panel_admin.rs +++ /dev/null @@ -1,180 +0,0 @@ -// src/components/admin/admin_panel_admin.rs - -use crate::config::colors::themes::Theme; -use crate::pages::admin::{AdminFocus, AdminState}; -use crate::state::app::state::AppState; -use ratatui::{ - layout::{Alignment, Constraint, Direction, Layout, Rect}, - style::Style, - text::{Line, Span, Text}, - widgets::{Block, BorderType, Borders, List, ListItem, Paragraph}, - Frame, -}; - -pub fn render_admin_panel_admin( - f: &mut Frame, - area: Rect, - app_state: &AppState, - admin_state: &mut AdminState, - theme: &Theme, -) { - let main_chunks = Layout::default() - .direction(Direction::Vertical) - .constraints([Constraint::Min(0), Constraint::Length(1)].as_ref()) - .split(area); - let panes_area = main_chunks[0]; - let buttons_area = main_chunks[1]; - - let pane_chunks = Layout::default() - .direction(Direction::Horizontal) - .constraints([ - Constraint::Percentage(25), // Profiles - Constraint::Percentage(40), // Tables - Constraint::Percentage(35), // Dependencies - ].as_ref()) - .split(panes_area); - - let profiles_pane = pane_chunks[0]; - let tables_pane = pane_chunks[1]; - let deps_pane = pane_chunks[2]; - - // --- Profiles Pane (Left) --- - let profile_pane_has_focus = matches!(admin_state.current_focus, AdminFocus::ProfilesPane | AdminFocus::InsideProfilesList); - let profile_border_style = if profile_pane_has_focus { - Style::default().fg(theme.highlight) - } else { - Style::default().fg(theme.border) - }; - let profiles_block = Block::default().title(" Profiles ").borders(Borders::ALL).border_type(BorderType::Rounded).border_style(profile_border_style); - let profiles_inner_area = profiles_block.inner(profiles_pane); - f.render_widget(profiles_block, profiles_pane); - let profile_list_items: Vec = app_state.profile_tree.profiles.iter().enumerate().map(|(idx, profile)| { - let is_persistently_selected = admin_state.selected_profile_index == Some(idx); - let is_nav_highlighted = admin_state.profile_list_state.selected() == Some(idx) && admin_state.current_focus == AdminFocus::InsideProfilesList; - let prefix = if is_persistently_selected { "[*] " } else { "[ ] " }; - let item_style = if is_nav_highlighted { Style::default().fg(theme.highlight).add_modifier(ratatui::style::Modifier::BOLD) } - else if is_persistently_selected { Style::default().fg(theme.accent) } - else { Style::default().fg(theme.fg) }; - ListItem::new(Line::from(vec![Span::styled(prefix, item_style), Span::styled(&profile.name, item_style)])) - }).collect(); - let profile_list = List::new(profile_list_items) - .highlight_style(if admin_state.current_focus == AdminFocus::InsideProfilesList { Style::default().add_modifier(ratatui::style::Modifier::REVERSED) } else { Style::default() }) - .highlight_symbol(if admin_state.current_focus == AdminFocus::InsideProfilesList { "> " } else { " " }); - f.render_stateful_widget(profile_list, profiles_inner_area, &mut admin_state.profile_list_state); - - - // --- Tables Pane (Middle) --- - let table_pane_has_focus = matches!(admin_state.current_focus, AdminFocus::Tables | AdminFocus::InsideTablesList); - let table_border_style = if table_pane_has_focus { Style::default().fg(theme.highlight) } else { Style::default().fg(theme.border) }; - - let profile_to_display_tables_for_idx: Option; - if admin_state.current_focus == AdminFocus::InsideProfilesList { - profile_to_display_tables_for_idx = admin_state.profile_list_state.selected(); - } else { - profile_to_display_tables_for_idx = admin_state.selected_profile_index - .or_else(|| admin_state.profile_list_state.selected()); - } - let tables_pane_title_profile_name = profile_to_display_tables_for_idx - .and_then(|idx| app_state.profile_tree.profiles.get(idx)) - .map_or("None Selected", |p| p.name.as_str()); - let tables_block = Block::default().title(format!(" Tables (Profile: {}) ", tables_pane_title_profile_name)).borders(Borders::ALL).border_type(BorderType::Rounded).border_style(table_border_style); - let tables_inner_area = tables_block.inner(tables_pane); - f.render_widget(tables_block, tables_pane); - - let table_list_items_for_display: Vec = - if let Some(profile_data_for_tables) = profile_to_display_tables_for_idx - .and_then(|idx| app_state.profile_tree.profiles.get(idx)) { - profile_data_for_tables.tables.iter().enumerate().map(|(idx, table)| { - let is_table_persistently_selected = admin_state.selected_table_index == Some(idx) && - profile_to_display_tables_for_idx == admin_state.selected_profile_index; - let is_table_nav_highlighted = admin_state.table_list_state.selected() == Some(idx) && - admin_state.current_focus == AdminFocus::InsideTablesList; - let prefix = if is_table_persistently_selected { "[*] " } else { "[ ] " }; - let style = if is_table_nav_highlighted { Style::default().fg(theme.highlight).add_modifier(ratatui::style::Modifier::BOLD) } - else if is_table_persistently_selected { Style::default().fg(theme.accent) } - else { Style::default().fg(theme.fg) }; - ListItem::new(Line::from(vec![Span::styled(prefix, style), Span::styled(&table.name, style)])) - }).collect() - } else { - vec![ListItem::new("Select a profile to see tables")] - }; - let table_list = List::new(table_list_items_for_display) - .highlight_style(if admin_state.current_focus == AdminFocus::InsideTablesList { Style::default().add_modifier(ratatui::style::Modifier::REVERSED) } else { Style::default() }) - .highlight_symbol(if admin_state.current_focus == AdminFocus::InsideTablesList { "> " } else { " " }); - f.render_stateful_widget(table_list, tables_inner_area, &mut admin_state.table_list_state); - - - // --- Dependencies Pane (Right) --- - let mut deps_pane_title_table_name = "N/A".to_string(); - let dependencies_to_display: Vec; - - if admin_state.current_focus == AdminFocus::InsideTablesList { - // If navigating tables, show dependencies for the '>' highlighted table. - // The profile context is `profile_to_display_tables_for_idx` (from Tables pane logic). - if let Some(p_idx_for_current_tables) = profile_to_display_tables_for_idx { - if let Some(current_profile_showing_tables) = app_state.profile_tree.profiles.get(p_idx_for_current_tables) { - if let Some(table_nav_idx) = admin_state.table_list_state.selected() { // The '>' highlighted table - if let Some(navigated_table) = current_profile_showing_tables.tables.get(table_nav_idx) { - deps_pane_title_table_name = navigated_table.name.clone(); - dependencies_to_display = navigated_table.depends_on.clone(); - } else { - dependencies_to_display = Vec::new(); // Navigated table index out of bounds - } - } else { - dependencies_to_display = Vec::new(); // No table navigated with '>' - } - } else { - dependencies_to_display = Vec::new(); // Profile for tables out of bounds - } - } else { - dependencies_to_display = Vec::new(); // No profile active for table display - } - } else { - // Otherwise, show dependencies for the '[*]' persistently selected table & profile. - if let Some(p_idx) = admin_state.selected_profile_index { // Must be a persistently selected profile - if let Some(selected_profile) = app_state.profile_tree.profiles.get(p_idx) { - if let Some(t_idx) = admin_state.selected_table_index { // Must be a persistently selected table - if let Some(selected_table) = selected_profile.tables.get(t_idx) { - deps_pane_title_table_name = selected_table.name.clone(); - dependencies_to_display = selected_table.depends_on.clone(); - } else { dependencies_to_display = Vec::new(); } - } else { dependencies_to_display = Vec::new(); } - } else { dependencies_to_display = Vec::new(); } - } else { dependencies_to_display = Vec::new(); } - } - - let deps_block = Block::default() - .title(format!(" Dependencies (Table: {}) ", deps_pane_title_table_name)) - .borders(Borders::ALL) - .border_type(BorderType::Rounded) - .border_style(Style::default().fg(theme.border)); - let deps_inner_area = deps_block.inner(deps_pane); - f.render_widget(deps_block, deps_pane); - - let mut deps_content = Text::default(); - deps_content.lines.push(Line::from(Span::styled( - "Depends On:", - Style::default().fg(theme.accent), - ))); - - if !dependencies_to_display.is_empty() { - for dep in dependencies_to_display { - deps_content.lines.push(Line::from(Span::styled(format!("- {}", dep), theme.fg))); - } - } else { - deps_content.lines.push(Line::from(Span::styled(" None", theme.secondary))); - } - let deps_paragraph = Paragraph::new(deps_content); - f.render_widget(deps_paragraph, deps_inner_area); - - // --- Buttons Row --- - let button_chunks = Layout::default().direction(Direction::Horizontal).constraints([Constraint::Percentage(33), Constraint::Percentage(34), Constraint::Percentage(33)].as_ref()).split(buttons_area); - let btn_base_style = Style::default().fg(theme.secondary); - let get_btn_style = |button_focus: AdminFocus| { if admin_state.current_focus == button_focus { btn_base_style.add_modifier(ratatui::style::Modifier::REVERSED) } else { btn_base_style } }; - let btn1 = Paragraph::new("Add Logic").style(get_btn_style(AdminFocus::Button1)).alignment(Alignment::Center); - let btn2 = Paragraph::new("Add Table").style(get_btn_style(AdminFocus::Button2)).alignment(Alignment::Center); - let btn3 = Paragraph::new("Change Table").style(get_btn_style(AdminFocus::Button3)).alignment(Alignment::Center); - f.render_widget(btn1, button_chunks[0]); - f.render_widget(btn2, button_chunks[1]); - f.render_widget(btn3, button_chunks[2]); -} diff --git a/client/src/functions/modes/navigation.rs b/client/src/functions/modes/navigation.rs index d963419..441c299 100644 --- a/client/src/functions/modes/navigation.rs +++ b/client/src/functions/modes/navigation.rs @@ -1,5 +1,4 @@ // src/functions/modes/navigation.rs -pub mod admin_nav; pub mod add_table_nav; pub mod add_logic_nav; diff --git a/client/src/functions/modes/navigation/admin_nav.rs b/client/src/functions/modes/navigation/admin_nav.rs deleted file mode 100644 index cfecae4..0000000 --- a/client/src/functions/modes/navigation/admin_nav.rs +++ /dev/null @@ -1,351 +0,0 @@ -// src/functions/modes/navigation/admin_nav.rs -use crate::pages::admin::{AdminFocus, AdminState}; -use crate::state::app::state::AppState; -use crate::config::binds::config::Config; -use crate::buffer::state::{BufferState, AppView}; -use crate::state::pages::add_table::{AddTableState, LinkDefinition}; -use ratatui::widgets::ListState; -use crate::state::pages::add_logic::{AddLogicState, AddLogicFocus}; // Added AddLogicFocus import - -// Helper functions list_select_next and list_select_previous remain the same -fn list_select_next(list_state: &mut ListState, item_count: usize) { - if item_count == 0 { - list_state.select(None); - return; - } - let i = match list_state.selected() { - Some(i) => if i >= item_count - 1 { 0 } else { i + 1 }, - None => 0, - }; - list_state.select(Some(i)); -} - -fn list_select_previous(list_state: &mut ListState, item_count: usize) { - if item_count == 0 { - list_state.select(None); - return; - } - let i = match list_state.selected() { - Some(i) => if i == 0 { item_count - 1 } else { i - 1 }, - None => if item_count > 0 { item_count - 1 } else { 0 }, - }; - list_state.select(Some(i)); -} - -pub fn handle_admin_navigation( - key: crossterm::event::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).map(String::from); - 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 => { - match action.as_deref() { - Some("select") => { - admin_state.current_focus = AdminFocus::InsideProfilesList; - if !app_state.profile_tree.profiles.is_empty() { - if admin_state.profile_list_state.selected().is_none() { - admin_state.profile_list_state.select(Some(0)); - } - } - *command_message = "Navigating profiles. Use Up/Down. Esc to exit.".to_string(); - handled = true; - } - Some("next_option") | Some("move_down") => { - admin_state.current_focus = AdminFocus::Tables; - *command_message = "Focus: Tables Pane".to_string(); - 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; - } - _ => handled = false, - } - } - - AdminFocus::InsideProfilesList => { - match action.as_deref() { - Some("move_up") => { - if profile_count > 0 { - list_select_previous(&mut admin_state.profile_list_state, profile_count); - *command_message = "".to_string(); - handled = true; - } - } - Some("move_down") => { - if profile_count > 0 { - list_select_next(&mut admin_state.profile_list_state, profile_count); - *command_message = "".to_string(); - handled = true; - } - } - Some("select") => { - admin_state.selected_profile_index = admin_state.profile_list_state.selected(); - admin_state.selected_table_index = None; // Deselect table when profile changes - 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 - } else { - admin_state.table_list_state.select(None); - } - } - } else { - admin_state.table_list_state.select(None); - } - *command_message = format!( - "Profile '{}' set as active.", - admin_state.get_selected_profile_name().unwrap_or(&"N/A".to_string()) - ); - handled = true; - } - Some("exit_table_scroll") => { - admin_state.current_focus = AdminFocus::ProfilesPane; - *command_message = "Focus: Profiles Pane".to_string(); - handled = true; - } - _ => handled = false, - } - } - - AdminFocus::Tables => { - match action.as_deref() { - Some("select") => { - admin_state.current_focus = AdminFocus::InsideTablesList; - let current_profile_idx = admin_state.selected_profile_index - .or_else(|| admin_state.profile_list_state.selected()); - if let Some(profile_idx) = current_profile_idx { - if let Some(profile) = app_state.profile_tree.profiles.get(profile_idx) { - if !profile.tables.is_empty() { - if admin_state.table_list_state.selected().is_none() { - 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); - *command_message = "Select a profile first to view its tables.".to_string(); - } - if admin_state.current_focus == AdminFocus::InsideTablesList && !admin_state.table_list_state.selected().is_none() { - *command_message = "Navigating tables. Use Up/Down. Esc to exit.".to_string(); - } else if admin_state.table_list_state.selected().is_none() { - if current_profile_idx.is_none() { - *command_message = "No profile selected to view tables.".to_string(); - } 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 - } - handled = true; - } - Some("previous_option") | Some("move_up") => { - admin_state.current_focus = AdminFocus::ProfilesPane; - *command_message = "Focus: Profiles Pane".to_string(); - handled = true; - } - Some("next_option") | Some("move_down") => { - admin_state.current_focus = AdminFocus::Button1; - *command_message = "Focus: Add Logic Button".to_string(); - handled = true; - } - _ => handled = false, - } - } - - AdminFocus::InsideTablesList => { - match action.as_deref() { - Some("move_up") => { - let current_profile_idx = admin_state.selected_profile_index - .or_else(|| admin_state.profile_list_state.selected()); - if let Some(p_idx) = current_profile_idx { - if let Some(profile) = app_state.profile_tree.profiles.get(p_idx) { - if !profile.tables.is_empty() { - list_select_previous(&mut admin_state.table_list_state, profile.tables.len()); - *command_message = "".to_string(); - handled = true; - } else { - *command_message = "No tables to navigate.".to_string(); - handled = true; - } - } - } else { - *command_message = "No active profile for tables.".to_string(); - handled = true; - } - } - Some("move_down") => { - let current_profile_idx = admin_state.selected_profile_index - .or_else(|| admin_state.profile_list_state.selected()); - if let Some(p_idx) = current_profile_idx { - if let Some(profile) = app_state.profile_tree.profiles.get(p_idx) { - if !profile.tables.is_empty() { - list_select_next(&mut admin_state.table_list_state, profile.tables.len()); - *command_message = "".to_string(); - handled = true; - } else { - *command_message = "No tables to navigate.".to_string(); - handled = true; - } - } - } else { - *command_message = "No active profile for tables.".to_string(); - handled = true; - } - } - Some("select") => { // This is for persistently selecting a table with [*] - 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)) - .and_then(|p| admin_state.selected_table_index.and_then(|t_idx| p.tables.get(t_idx))) - .map_or("N/A", |t| t.name.as_str()); - *command_message = format!("Table '{}' set as active.", table_name); - handled = true; - } - Some("exit_table_scroll") => { - admin_state.current_focus = AdminFocus::Tables; - *command_message = "Focus: Tables Pane".to_string(); - handled = true; - } - _ => handled = false, - } - } - - AdminFocus::Button1 => { // Add Logic Button - match action.as_deref() { - Some("select") => { // Typically "Enter" key - if let Some(p_idx) = admin_state.selected_profile_index { - 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(table) = profile.tables.get(t_idx) { - // Both profile and table are selected, proceed - admin_state.add_logic_state = AddLogicState { - profile_name: profile.name.clone(), - selected_table_name: Some(table.name.clone()), - selected_table_id: Some(table.id), // If you have table IDs - editor_keybinding_mode: config.editor.keybinding_mode.clone(), - current_focus: AddLogicFocus::default(), - ..AddLogicState::default() - }; - - // Store table info for later fetching - app_state.pending_table_structure_fetch = Some(( - profile.name.clone(), - table.name.clone() - )); - - 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 - ); - } else { - *command_message = "Error: Selected table data not found.".to_string(); - } - } else { - *command_message = "Select a table first!".to_string(); - } - } else { - *command_message = "Error: Selected profile data not found.".to_string(); - } - } else { - *command_message = "Select a profile first!".to_string(); - } - handled = true; - } - Some("previous_option") | Some("move_up") => { - admin_state.current_focus = AdminFocus::Tables; - *command_message = "Focus: Tables Pane".to_string(); - handled = true; - } - Some("next_option") | Some("move_down") => { - admin_state.current_focus = AdminFocus::Button2; - *command_message = "Focus: Add Table Button".to_string(); - handled = true; - } - _ => handled = false, - } - } - - AdminFocus::Button2 => { // Add Table Button - match action.as_deref() { - Some("select") => { - 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(); - // Prepare links from the selected profile's existing tables - let available_links: Vec = profile.tables.iter() - .map(|table| LinkDefinition { - linked_table_name: table.name.clone(), - is_required: false, // Default, can be changed in AddTable screen - selected: false, - }).collect(); - - admin_state.add_table_state = AddTableState { - profile_name: selected_profile_name, - links: available_links, - ..AddTableState::default() // Reset other fields - }; - buffer_state.update_history(AppView::AddTable); - app_state.ui.focus_outside_canvas = false; - *command_message = format!("Opening Add Table for profile '{}'...", admin_state.add_table_state.profile_name); - handled = true; - } else { - *command_message = "Error: Selected profile index out of bounds.".to_string(); - handled = true; - } - } else { - *command_message = "Please select a profile ([*]) first to add a table.".to_string(); - handled = true; - } - } - Some("previous_option") | Some("move_up") => { - admin_state.current_focus = AdminFocus::Button1; - *command_message = "Focus: Add Logic Button".to_string(); - handled = true; - } - Some("next_option") | Some("move_down") => { - admin_state.current_focus = AdminFocus::Button3; - *command_message = "Focus: Change Table Button".to_string(); - handled = true; - } - _ => handled = false, - } - } - - 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") => { - 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; - } - _ => handled = false, - } - } - } - handled -} diff --git a/client/src/modes/handlers/event.rs b/client/src/modes/handlers/event.rs index 56818a3..1260c6e 100644 --- a/client/src/modes/handlers/event.rs +++ b/client/src/modes/handlers/event.rs @@ -7,7 +7,9 @@ use crate::search::event::handle_search_palette_event; use crate::functions::modes::navigation::add_logic_nav; use crate::functions::modes::navigation::add_logic_nav::SaveLogicResultSender; use crate::functions::modes::navigation::add_table_nav::SaveTableResultSender; -use crate::functions::modes::navigation::{add_table_nav, admin_nav}; +use crate::functions::modes::navigation::add_table_nav; +use crate::pages::admin::main::logic::handle_admin_navigation; +use crate::pages::admin::main::tui::handle_admin_selection; use crate::modes::general::command_navigation::{ handle_command_navigation_event, NavigationState, }; @@ -37,7 +39,6 @@ use crate::pages::forms::logic::{save, revert, SaveOutcome}; use crate::search::state::SearchState; use crate::tui::{ terminal::core::TerminalCore, - admin, }; use crate::ui::handlers::context::UiContext; use canvas::KeyEventOutcome; @@ -419,7 +420,7 @@ impl EventHandler { // Optional page-specific handlers (non-movement or rich actions) if let Page::Admin(admin_state) = &mut router.current { if auth_state.role.as_deref() == Some("admin") { - if admin_nav::handle_admin_navigation( + if handle_admin_navigation( key_event, config, app_state, @@ -548,7 +549,7 @@ impl EventHandler { } UiContext::Admin => { if let Page::Admin(admin_state) = &router.current { - admin::handle_admin_selection( + handle_admin_selection( app_state, admin_state, ); diff --git a/client/src/tui/functions.rs b/client/src/tui/functions.rs index ddfd58c..d75cb82 100644 --- a/client/src/tui/functions.rs +++ b/client/src/tui/functions.rs @@ -1,6 +1,3 @@ // src/tui/functions.rs -pub mod admin; pub mod common; - -pub use admin::*; diff --git a/client/src/tui/functions/admin.rs b/client/src/tui/functions/admin.rs deleted file mode 100644 index dfffcf0..0000000 --- a/client/src/tui/functions/admin.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::state::app::state::AppState; -use crate::pages::admin::AdminState; - -pub fn handle_admin_selection(app_state: &mut AppState, admin_state: &AdminState) { - let profiles = &app_state.profile_tree.profiles; - if let Some(selected_index) = admin_state.get_selected_index() { - if let Some(profile) = profiles.get(selected_index) { - app_state.selected_profile = Some(profile.name.clone()); - } - } -} diff --git a/client/src/ui/handlers/render.rs b/client/src/ui/handlers/render.rs index f2ae438..6438dd0 100644 --- a/client/src/ui/handlers/render.rs +++ b/client/src/ui/handlers/render.rs @@ -90,7 +90,7 @@ pub fn render_ui( state, app_state, ), - Page::Admin(state) => crate::components::admin::admin_panel::render_admin_panel( + Page::Admin(state) => crate::pages::admin::main::ui::render_admin_panel( f, app_state, &mut AuthState::default(),