162 lines
6.1 KiB
Rust
162 lines
6.1 KiB
Rust
// src/ui/handlers/ui.rs
|
|
|
|
use crate::tui::terminal::TerminalCore;
|
|
use crate::tui::terminal::GrpcClient;
|
|
use crate::tui::controls::CommandHandler;
|
|
use crate::tui::terminal::EventReader;
|
|
use crate::config::colors::themes::Theme;
|
|
use crate::config::binds::config::Config;
|
|
use crate::ui::handlers::render::render_ui;
|
|
use crate::state::pages::form::FormState;
|
|
use crate::state::pages::auth::AuthState;
|
|
use crate::modes::handlers::event::EventHandler;
|
|
use crate::state::state::AppState;
|
|
|
|
pub async fn run_ui() -> Result<(), Box<dyn std::error::Error>> {
|
|
let config = Config::load()?;
|
|
let mut terminal = TerminalCore::new()?;
|
|
let mut grpc_client = GrpcClient::new().await?;
|
|
let mut command_handler = CommandHandler::new();
|
|
let theme = Theme::from_str(&config.colors.theme);
|
|
let mut auth_state = AuthState::default();
|
|
|
|
// 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;
|
|
|
|
// Fetch table structure at startup (one-time)
|
|
let table_structure = grpc_client.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 event_reader = EventReader::new();
|
|
|
|
// Fetch the total count of Adresar entries
|
|
let total_count = grpc_client.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 = grpc_client.get_adresar_count().await?;
|
|
app_state.update_total_count(total_count);
|
|
|
|
terminal.draw(|f| {
|
|
render_ui(
|
|
f,
|
|
&mut form_state,
|
|
&mut auth_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,
|
|
&app_state,
|
|
);
|
|
})?;
|
|
|
|
let total_count = app_state.total_count;
|
|
let mut current_position = app_state.current_position;
|
|
|
|
let event = event_reader.read_event()?;
|
|
let (should_exit, message) = event_handler.handle_event(
|
|
event,
|
|
&config,
|
|
&mut terminal,
|
|
&mut grpc_client,
|
|
&mut command_handler,
|
|
&mut form_state,
|
|
&mut app_state,
|
|
total_count,
|
|
&mut current_position,
|
|
).await?;
|
|
|
|
app_state.current_position = current_position;
|
|
|
|
// 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 grpc_client.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(());
|
|
}
|
|
}
|
|
}
|