Files
komp_ac/client/src/ui/handlers/ui.rs
2025-02-25 23:36:53 +01:00

140 lines
5.4 KiB
Rust

// src/client/ui/handlers/ui.rs
use crate::tui::terminal::AppTerminal;
use crate::config::colors::Theme;
use crate::config::config::Config;
use crate::ui::handlers::{event::EventHandler, form::FormState, render::render_ui};
use crate::state::state::AppState;
pub async fn run_ui() -> Result<(), Box<dyn std::error::Error>> {
let config = Config::load()?;
let mut app_terminal = AppTerminal::new().await?;
let theme = Theme::from_str(&config.colors.theme);
// Fetch table structure at startup (one-time)
// TODO: Later, consider implementing a live update for table structure changes.
let table_structure = app_terminal.get_table_structure().await?;
// Extract the column names from the response
let column_names: Vec<String> = table_structure
.columns
.iter()
.map(|col| col.name.clone())
.collect();
// Initialize FormState with dynamic fields
let mut form_state = FormState::new(column_names);
// The rest of your UI initialization remains the same
let mut event_handler = EventHandler::new();
let mut app_state = AppState::new()?;
// Fetch the total count of Adresar entries
let total_count = app_terminal.get_adresar_count().await?;
app_state.update_total_count(total_count);
app_state.update_current_position(total_count.saturating_add(1)); // Start in new entry mode
form_state.reset_to_empty();
loop {
let total_count = app_terminal.get_adresar_count().await?;
app_state.update_total_count(total_count);
app_terminal.draw(|f| {
render_ui(
f,
&mut form_state,
&theme,
event_handler.is_edit_mode,
app_state.total_count,
app_state.current_position,
&app_state.current_dir,
&event_handler.command_input,
event_handler.command_mode,
&event_handler.command_message,
);
})?;
let event = app_terminal.read_event()?;
let (should_exit, message) = event_handler.handle_event(
event,
&config,
&mut app_terminal,
&mut form_state,
&mut app_state.is_saved,
app_state.total_count,
&mut app_state.current_position,
).await?;
// Handle position changes and update form state
if !event_handler.is_edit_mode {
let current_input = form_state.get_current_input();
let max_cursor_pos = if !current_input.is_empty() {
current_input.len() - 1 // Limit to last character in readonly mode
} else {
0
};
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;
}
if app_state.current_position > total_count {
// New entry - reset form
form_state.reset_to_empty();
form_state.current_field = 0;
} else if app_state.current_position >= 1 && app_state.current_position <= total_count {
// Existing entry - load data
match app_terminal.get_adresar_by_position(app_state.current_position).await {
Ok(response) => {
// Set the ID properly
form_state.id = response.id;
// Update form values dynamically
form_state.values = vec![
response.firma,
response.kz,
response.drc,
response.ulica,
response.psc,
response.mesto,
response.stat,
response.banka,
response.ucet,
response.skladm,
response.ico,
response.kontakt,
response.telefon,
response.skladu,
response.fax,
];
let current_input = form_state.get_current_input();
let max_cursor_pos = if !event_handler.is_edit_mode && !current_input.is_empty() {
current_input.len() - 1 // In readonly mode, limit to last character
} else {
current_input.len()
};
form_state.current_cursor_pos = event_handler.ideal_cursor_column.min(max_cursor_pos);
form_state.has_unsaved_changes = false;
event_handler.command_message = format!("Loaded entry {}", app_state.current_position);
}
Err(e) => {
event_handler.command_message = format!("Error loading entry: {}", e);
}
}
} else {
// Invalid position - reset to first entry
app_state.current_position = 1;
}
}
event_handler.command_message = message;
if should_exit {
return Ok(());
}
}
}