centralizing logic in the formstate
This commit is contained in:
@@ -82,21 +82,13 @@ pub async fn run_ui() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize AppState and FormState with table data
|
||||
let (initial_profile, initial_table, initial_columns) =
|
||||
let (initial_profile, initial_table, initial_columns_from_service) =
|
||||
UiService::initialize_app_state_and_form(&mut grpc_client, &mut app_state)
|
||||
.await
|
||||
.context("Failed to initialize app state and form")?;
|
||||
|
||||
// Initialize AppState and FormState with table data
|
||||
let (initial_profile, initial_table, initial_columns_from_service) = // Renamed for clarity
|
||||
UiService::initialize_app_state_and_form(&mut grpc_client, &mut app_state)
|
||||
.await
|
||||
.context("Failed to initialize app state and form")?;
|
||||
let filtered_columns = filter_user_columns(initial_columns_from_service);
|
||||
|
||||
// Filter the columns obtained from the service
|
||||
let filtered_columns = filter_user_columns(initial_columns_from_service); // Use the correct variable
|
||||
|
||||
let mut form_state = FormState::new(
|
||||
initial_profile.clone(),
|
||||
initial_table.clone(),
|
||||
@@ -110,7 +102,6 @@ pub async fn run_ui() -> Result<()> {
|
||||
initial_profile, initial_table
|
||||
))?;
|
||||
|
||||
// Load initial data for the form
|
||||
if form_state.total_count > 0 {
|
||||
if let Err(e) = UiService::load_table_data_by_position(&mut grpc_client, &mut form_state).await {
|
||||
event_handler.command_message = format!("Error loading initial data: {}", e);
|
||||
@@ -130,11 +121,9 @@ pub async fn run_ui() -> Result<()> {
|
||||
let mut needs_redraw = true;
|
||||
let mut prev_view_profile_name = app_state.current_view_profile_name.clone();
|
||||
let mut prev_view_table_name = app_state.current_view_table_name.clone();
|
||||
let mut table_just_switched = false;
|
||||
|
||||
loop {
|
||||
// ===================================================================
|
||||
// PROCESS EVENTS & UPDATE STATE
|
||||
// ===================================================================
|
||||
let position_before_event = form_state.current_position;
|
||||
let mut event_processed = false;
|
||||
if crossterm_event::poll(std::time::Duration::from_millis(1))? {
|
||||
@@ -156,7 +145,6 @@ pub async fn run_ui() -> Result<()> {
|
||||
&mut app_state,
|
||||
).await;
|
||||
|
||||
// --- Handle the outcome of the event ---
|
||||
let mut should_exit = false;
|
||||
match event_outcome_result {
|
||||
Ok(outcome) => match outcome {
|
||||
@@ -205,7 +193,6 @@ pub async fn run_ui() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Handle async results from other tasks ---
|
||||
match login_result_receiver.try_recv() {
|
||||
Ok(result) => {
|
||||
if login::handle_login_result(result, &mut app_state, &mut auth_state, &mut login_state) {
|
||||
@@ -255,11 +242,6 @@ pub async fn run_ui() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// STATE-DEPENDENT LOGIC (NOW RUNS AFTER STATE IS UPDATED)
|
||||
// ===================================================================
|
||||
|
||||
// --- Determine which view is active ---
|
||||
if let Some(active_view) = buffer_state.get_active_view() {
|
||||
app_state.ui.show_intro = false;
|
||||
app_state.ui.show_login = false;
|
||||
@@ -307,55 +289,92 @@ pub async fn run_ui() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Handle table change for FormView ---
|
||||
if app_state.ui.show_form {
|
||||
let current_view_profile = app_state.current_view_profile_name.clone();
|
||||
let current_view_table = app_state.current_view_table_name.clone();
|
||||
|
||||
if prev_view_profile_name != current_view_profile || prev_view_table_name != current_view_table {
|
||||
if let (Some(prof_name), Some(tbl_name)) = (current_view_profile.as_ref(), current_view_table.as_ref()) {
|
||||
app_state.show_loading_dialog("Loading Table", &format!("Fetching data for {}.{}...", prof_name, tbl_name));
|
||||
if prev_view_profile_name != current_view_profile
|
||||
|| prev_view_table_name != current_view_table
|
||||
{
|
||||
if let (Some(prof_name), Some(tbl_name)) =
|
||||
(current_view_profile.as_ref(), current_view_table.as_ref())
|
||||
{
|
||||
app_state.show_loading_dialog(
|
||||
"Loading Table",
|
||||
&format!("Fetching data for {}.{}...", prof_name, tbl_name),
|
||||
);
|
||||
needs_redraw = true;
|
||||
|
||||
match grpc_client.get_table_structure(prof_name.clone(), tbl_name.clone()).await {
|
||||
match grpc_client
|
||||
.get_table_structure(prof_name.clone(), tbl_name.clone())
|
||||
.await
|
||||
{
|
||||
Ok(structure_response) => {
|
||||
let new_columns: Vec<String> = structure_response.columns.iter().map(|c| c.name.clone()).collect();
|
||||
let new_columns: Vec<String> = structure_response
|
||||
.columns
|
||||
.iter()
|
||||
.map(|c| c.name.clone())
|
||||
.collect();
|
||||
|
||||
// --- START FIX ---
|
||||
// Apply the same filtering logic here that is used on initial load.
|
||||
let filtered_columns = filter_user_columns(new_columns);
|
||||
form_state = FormState::new(prof_name.clone(), tbl_name.clone(), filtered_columns);
|
||||
// --- END FIX ---
|
||||
form_state = FormState::new(
|
||||
prof_name.clone(),
|
||||
tbl_name.clone(),
|
||||
filtered_columns,
|
||||
);
|
||||
|
||||
if let Err(e) = UiService::fetch_and_set_table_count(&mut grpc_client, &mut form_state).await {
|
||||
app_state.update_dialog_content(&format!("Error fetching count: {}", e), vec!["OK".to_string()], DialogPurpose::LoginFailed);
|
||||
} else {
|
||||
if form_state.total_count > 0 {
|
||||
if let Err(e) = UiService::load_table_data_by_position(&mut grpc_client, &mut form_state).await {
|
||||
app_state.update_dialog_content(&format!("Error loading data: {}", e), vec!["OK".to_string()], DialogPurpose::LoginFailed);
|
||||
} else {
|
||||
app_state.hide_dialog();
|
||||
}
|
||||
if let Err(e) = UiService::fetch_and_set_table_count(
|
||||
&mut grpc_client,
|
||||
&mut form_state,
|
||||
)
|
||||
.await
|
||||
{
|
||||
app_state.update_dialog_content(
|
||||
&format!("Error fetching count: {}", e),
|
||||
vec!["OK".to_string()],
|
||||
DialogPurpose::LoginFailed,
|
||||
);
|
||||
} else if form_state.total_count > 0 {
|
||||
if let Err(e) = UiService::load_table_data_by_position(
|
||||
&mut grpc_client,
|
||||
&mut form_state,
|
||||
)
|
||||
.await
|
||||
{
|
||||
app_state.update_dialog_content(
|
||||
&format!("Error loading data: {}", e),
|
||||
vec!["OK".to_string()],
|
||||
DialogPurpose::LoginFailed,
|
||||
);
|
||||
} else {
|
||||
form_state.reset_to_empty();
|
||||
app_state.hide_dialog();
|
||||
}
|
||||
} else {
|
||||
form_state.reset_to_empty();
|
||||
app_state.hide_dialog();
|
||||
}
|
||||
|
||||
prev_view_profile_name = current_view_profile;
|
||||
prev_view_table_name = current_view_table;
|
||||
table_just_switched = true;
|
||||
}
|
||||
Err(e) => {
|
||||
app_state.update_dialog_content(&format!("Error fetching table structure: {}", e), vec!["OK".to_string()], DialogPurpose::LoginFailed);
|
||||
app_state.current_view_profile_name = prev_view_profile_name.clone();
|
||||
app_state.current_view_table_name = prev_view_table_name.clone();
|
||||
app_state.update_dialog_content(
|
||||
&format!("Error fetching table structure: {}", e),
|
||||
vec!["OK".to_string()],
|
||||
DialogPurpose::LoginFailed,
|
||||
);
|
||||
app_state.current_view_profile_name =
|
||||
prev_view_profile_name.clone();
|
||||
app_state.current_view_table_name =
|
||||
prev_view_table_name.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
prev_view_profile_name = current_view_profile;
|
||||
prev_view_table_name = current_view_table;
|
||||
needs_redraw = true;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Handle pending async fetches ---
|
||||
if let Some((profile_name, table_name)) = app_state.pending_table_structure_fetch.take() {
|
||||
if app_state.ui.show_add_logic {
|
||||
if admin_state.add_logic_state.profile_name == profile_name &&
|
||||
@@ -414,28 +433,17 @@ pub async fn run_ui() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Handle cursor updates based on position changes ---
|
||||
let position_changed = form_state.current_position != position_before_event;
|
||||
let mut position_logic_needs_redraw = false;
|
||||
|
||||
if app_state.ui.show_form {
|
||||
if app_state.ui.show_form && !table_just_switched {
|
||||
if position_changed && !event_handler.is_edit_mode {
|
||||
let current_input_before_load = form_state.get_current_input();
|
||||
let max_cursor_pos_before_load = if !current_input_before_load.is_empty() { current_input_before_load.chars().count() } else { 0 };
|
||||
form_state.current_cursor_pos = event_handler.ideal_cursor_column.min(max_cursor_pos_before_load);
|
||||
position_logic_needs_redraw = true;
|
||||
|
||||
if form_state.total_count > 0 && form_state.current_position > form_state.total_count + 1 {
|
||||
form_state.current_position = form_state.total_count + 1;
|
||||
} else if form_state.total_count == 0 && form_state.current_position > 1 {
|
||||
form_state.current_position = 1;
|
||||
}
|
||||
if form_state.current_position == 0 && form_state.total_count > 0 {
|
||||
form_state.current_position = 1;
|
||||
}
|
||||
|
||||
if (form_state.total_count > 0 && form_state.current_position <= form_state.total_count && form_state.current_position > 0)
|
||||
{
|
||||
if form_state.current_position > form_state.total_count {
|
||||
form_state.reset_to_empty();
|
||||
event_handler.command_message = format!("New entry for {}.{}", form_state.profile_name, form_state.table_name);
|
||||
} else {
|
||||
match UiService::load_table_data_by_position(&mut grpc_client, &mut form_state).await {
|
||||
Ok(load_message) => {
|
||||
if event_handler.command_message.is_empty() || !load_message.starts_with("Error") {
|
||||
@@ -446,27 +454,18 @@ pub async fn run_ui() -> Result<()> {
|
||||
event_handler.command_message = format!("Error loading data: {}", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
form_state.reset_to_empty();
|
||||
event_handler.command_message = format!("New entry for {}.{}", form_state.profile_name, form_state.table_name);
|
||||
}
|
||||
|
||||
let current_input_after_load_str = form_state.get_current_input();
|
||||
let current_input_len_after_load = current_input_after_load_str.chars().count();
|
||||
|
||||
let max_cursor_pos_for_readonly_after_load = if current_input_len_after_load > 0 {
|
||||
let max_cursor_pos = if current_input_len_after_load > 0 {
|
||||
current_input_len_after_load.saturating_sub(1)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
form_state.current_cursor_pos = event_handler.ideal_cursor_column.min(max_cursor_pos);
|
||||
|
||||
if event_handler.is_edit_mode {
|
||||
form_state.current_cursor_pos = event_handler.ideal_cursor_column.min(current_input_len_after_load);
|
||||
} else {
|
||||
form_state.current_cursor_pos = event_handler.ideal_cursor_column.min(max_cursor_pos_for_readonly_after_load);
|
||||
}
|
||||
|
||||
} else if !position_changed && !event_handler.is_edit_mode && app_state.ui.show_form {
|
||||
} else if !position_changed && !event_handler.is_edit_mode {
|
||||
let current_input_str = form_state.get_current_input();
|
||||
let current_input_len = current_input_str.chars().count();
|
||||
let max_cursor_pos = if current_input_len > 0 {
|
||||
@@ -498,9 +497,6 @@ pub async fn run_ui() -> Result<()> {
|
||||
needs_redraw = true;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// STEP 3: DRAW THE UI
|
||||
// ===================================================================
|
||||
if event_processed || needs_redraw || position_changed {
|
||||
let current_mode = ModeManager::derive_mode(&app_state, &event_handler, &admin_state);
|
||||
match current_mode {
|
||||
@@ -543,12 +539,13 @@ pub async fn run_ui() -> Result<()> {
|
||||
needs_redraw = false;
|
||||
}
|
||||
|
||||
// --- FPS calculation ---
|
||||
let now = Instant::now();
|
||||
let frame_duration = now.duration_since(last_frame_time);
|
||||
last_frame_time = now;
|
||||
if frame_duration.as_secs_f64() > 1e-6 {
|
||||
current_fps = 1.0 / frame_duration.as_secs_f64();
|
||||
}
|
||||
|
||||
table_just_switched = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user