diff --git a/client/src/components/admin/admin_panel.rs b/client/src/components/admin/admin_panel.rs index 150d726..10986e7 100644 --- a/client/src/components/admin/admin_panel.rs +++ b/client/src/components/admin/admin_panel.rs @@ -60,9 +60,8 @@ impl AdminPanelState { // Title let title = Line::from(Span::styled("Admin Panel", Style::default().fg(theme.highlight))); - Paragraph::new(title) - .alignment(Alignment::Center) - .render(f, chunks[0]); + let title_widget = Paragraph::new(title).alignment(Alignment::Center); + f.render_widget(title_widget, chunks[0]); // Content let content_chunks = Layout::default() @@ -74,17 +73,18 @@ impl AdminPanelState { let items: Vec = self.profiles.iter() .map(|p| ListItem::new(Line::from(vec![ Span::styled( - if Some(p) == selected_profile { "✓ " } else { " " }, + if Some(p) == selected_profile.as_ref() { "✓ " } else { " " }, Style::default().fg(theme.accent) ), Span::styled(p, Style::default().fg(theme.fg)), ]))) .collect(); - List::new(items) + let list = List::new(items) .block(Block::default().title("Profiles")) - .highlight_style(Style::default().bg(theme.highlight).fg(theme.bg)) - .render_stateful(f, content_chunks[0], &mut self.list_state); + .highlight_style(Style::default().bg(theme.highlight).fg(theme.bg)); + + f.render_stateful_widget(list, content_chunks[0], &mut self.list_state); // Profile details if let Some(profile) = self.list_state.selected() @@ -110,9 +110,9 @@ impl AdminPanelState { text.lines.push(Line::from(line)); } - Paragraph::new(text) - .block(Block::default().title("Details")) - .render(f, content_chunks[1]); + let details_widget = Paragraph::new(text) + .block(Block::default().title("Details")); + f.render_widget(details_widget, content_chunks[1]); } } } diff --git a/client/src/state/state.rs b/client/src/state/state.rs index 8311e94..e734747 100644 --- a/client/src/state/state.rs +++ b/client/src/state/state.rs @@ -32,6 +32,7 @@ impl AppState { total_count: 0, current_position: 0, profile_tree: ProfileTreeResponse::default(), + selected_profile: None, ui: UiState::default(), }) } diff --git a/client/src/ui/handlers/render.rs b/client/src/ui/handlers/render.rs index 8c63846..07c1f09 100644 --- a/client/src/ui/handlers/render.rs +++ b/client/src/ui/handlers/render.rs @@ -44,7 +44,13 @@ pub fn render_ui( if app_state.ui.show_intro { intro_state.render(f, main_content_area, theme); } else if app_state.ui.show_admin { - admin_panel_state.render(f, main_content_area, theme); + admin_panel_state.render( + f, + main_content_area, + theme, + &app_state.profile_tree, + &app_state.selected_profile, + ); } else { let (sidebar_area, form_area) = calculate_sidebar_layout( app_state.ui.show_sidebar, @@ -52,7 +58,13 @@ pub fn render_ui( ); if let Some(sidebar_rect) = sidebar_area { - sidebar::render_sidebar(f, sidebar_rect, theme, &app_state.profile_tree); + sidebar::render_sidebar( + f, + sidebar_rect, + theme, + &app_state.profile_tree, + &app_state.selected_profile // Remove trailing comma + ); } // This change makes the form stay stationary when toggling sidebar diff --git a/client/src/ui/handlers/ui.rs b/client/src/ui/handlers/ui.rs index 7f89f9c..b4094ec 100644 --- a/client/src/ui/handlers/ui.rs +++ b/client/src/ui/handlers/ui.rs @@ -1,4 +1,4 @@ -// src/client/ui/handlers/ui.rs +// src/ui/handlers/ui.rs use crate::tui::terminal::TerminalCore; use crate::tui::terminal::GrpcClient; @@ -19,10 +19,22 @@ pub async fn run_ui() -> Result<(), Box> { let mut command_handler = CommandHandler::new(); let theme = Theme::from_str(&config.colors.theme); let mut intro_state = IntroState::new(); - let admin_panel_state = AdminPanelState::new(); + + // Initialize app_state first + let mut app_state = AppState::new()?; + + // Fetch profile tree and table structure + let profile_tree = grpc_client.get_profile_tree().await?; + app_state.profile_tree = profile_tree; + + // Now create admin panel with profiles from app_state + let profiles = app_state.profile_tree.profiles + .iter() + .map(|p| p.name.clone()) + .collect(); + let admin_panel_state = AdminPanelState::new(profiles); // Fetch table structure at startup (one-time) - // TODO: Later, consider implementing a live update for table structure changes. let table_structure = grpc_client.get_table_structure().await?; // Extract the column names from the response @@ -35,13 +47,9 @@ pub async fn run_ui() -> Result<(), Box> { // Initialize FormState with dynamic fields let mut form_state = FormState::new(column_names); - // Fetch profile tree and table structure - let profile_tree = grpc_client.get_profile_tree().await?; // The rest of your UI initialization remains the same let mut event_handler = EventHandler::new(); let event_reader = EventReader::new(); - let mut app_state = AppState::new()?; - app_state.profile_tree = profile_tree; // Fetch the total count of Adresar entries let total_count = grpc_client.get_adresar_count().await?; @@ -100,7 +108,6 @@ pub async fn run_ui() -> Result<(), Box> { }; form_state.current_cursor_pos = event_handler.ideal_cursor_column.min(max_cursor_pos); - // Ensure position never exceeds total_count + 1 if app_state.current_position > total_count + 1 { app_state.current_position = total_count + 1;