event.rs and ui.rs refactor for the forms page(moved logic to the forms page dir and just calling it now)
This commit is contained in:
@@ -82,8 +82,6 @@ impl TableDependencyGraph {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ... (NavigationState struct and its new(), activate_*, deactivate(), add_char(), remove_char(), move_*, autocomplete_selected(), get_display_input() methods are unchanged) ...
|
||||
pub struct NavigationState {
|
||||
pub active: bool,
|
||||
pub input: String,
|
||||
|
||||
@@ -36,6 +36,7 @@ use crate::pages::register::RegisterResult;
|
||||
use crate::pages::routing::{Router, Page};
|
||||
use crate::movement::MovementAction;
|
||||
use crate::dialog;
|
||||
use crate::pages::forms;
|
||||
use crate::pages::forms::FormState;
|
||||
use crate::pages::forms::logic::{save, revert, SaveOutcome};
|
||||
use crate::search::state::SearchState;
|
||||
@@ -384,6 +385,14 @@ impl EventHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Page::Form(path) = &router.current {
|
||||
// NEW: Delegate Form event handling
|
||||
return forms::event::handle_form_event(
|
||||
event,
|
||||
app_state,
|
||||
path,
|
||||
&mut self.ideal_cursor_column
|
||||
);
|
||||
}
|
||||
}
|
||||
if toggle_sidebar(
|
||||
@@ -858,25 +867,14 @@ impl EventHandler {
|
||||
&mut self.auth_client,
|
||||
app_state,
|
||||
)
|
||||
.await?;
|
||||
.await?;
|
||||
Ok(EventOutcome::Ok(message))
|
||||
} else {
|
||||
let save_outcome = if let Page::Form(path) = &router.current {
|
||||
save(
|
||||
app_state,
|
||||
path,
|
||||
&mut self.grpc_client,
|
||||
)
|
||||
.await?
|
||||
if let Page::Form(path) = &router.current {
|
||||
forms::event::save_form(app_state, path, &mut self.grpc_client).await
|
||||
} else {
|
||||
SaveOutcome::NoChange
|
||||
};
|
||||
let message = match save_outcome {
|
||||
SaveOutcome::NoChange => "No changes to save.".to_string(),
|
||||
SaveOutcome::UpdatedExisting => "Entry updated.".to_string(),
|
||||
SaveOutcome::CreatedNew(_) => "New entry created.".to_string(),
|
||||
};
|
||||
Ok(EventOutcome::DataSaved(save_outcome, message))
|
||||
Ok(EventOutcome::Ok("Nothing to save".to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
"force_quit" => {
|
||||
@@ -898,19 +896,18 @@ impl EventHandler {
|
||||
&mut self.auth_client,
|
||||
app_state,
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
let save_outcome = if let Page::Form(path) = &router.current {
|
||||
save(app_state, path, &mut self.grpc_client).await?
|
||||
} else {
|
||||
SaveOutcome::NoChange
|
||||
};
|
||||
match save_outcome {
|
||||
SaveOutcome::NoChange => "No changes to save.".to_string(),
|
||||
SaveOutcome::UpdatedExisting => "Entry updated.".to_string(),
|
||||
SaveOutcome::CreatedNew(_) => "New entry created.".to_string(),
|
||||
.await?
|
||||
} else if let Page::Form(path) = &router.current {
|
||||
let save_result = forms::event::save_form(app_state, path, &mut self.grpc_client).await?;
|
||||
match save_result {
|
||||
EventOutcome::DataSaved(_, msg) => msg,
|
||||
EventOutcome::Ok(msg) => msg,
|
||||
_ => "Saved".to_string(),
|
||||
}
|
||||
} else {
|
||||
"No changes to save.".to_string()
|
||||
};
|
||||
|
||||
if let Page::Form(path) = &router.current {
|
||||
if let Some(editor) = app_state.editor_for_path(path) {
|
||||
editor.cleanup_cursor()?;
|
||||
@@ -918,8 +915,8 @@ impl EventHandler {
|
||||
}
|
||||
terminal.cleanup()?;
|
||||
Ok(EventOutcome::Exit(format!(
|
||||
"{}. Exiting application.",
|
||||
message
|
||||
"{}. Exiting application.",
|
||||
message
|
||||
)))
|
||||
}
|
||||
"revert" => {
|
||||
@@ -933,7 +930,7 @@ impl EventHandler {
|
||||
.await
|
||||
} else {
|
||||
if let Page::Form(path) = &router.current {
|
||||
revert(app_state, path, &mut self.grpc_client).await?
|
||||
return forms::event::revert_form(app_state, path, &mut self.grpc_client).await;
|
||||
} else {
|
||||
"Nothing to revert".to_string()
|
||||
}
|
||||
|
||||
62
client/src/pages/forms/event.rs
Normal file
62
client/src/pages/forms/event.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
// src/pages/forms/event.rs
|
||||
|
||||
use anyhow::Result;
|
||||
use crossterm::event::Event;
|
||||
use canvas::keymap::KeyEventOutcome;
|
||||
use crate::{
|
||||
state::app::state::AppState,
|
||||
pages::forms::{FormState, logic},
|
||||
modes::handlers::event::EventOutcome,
|
||||
};
|
||||
|
||||
pub fn handle_form_event(
|
||||
event: Event,
|
||||
app_state: &mut AppState,
|
||||
path: &str,
|
||||
ideal_cursor_column: &mut usize,
|
||||
) -> Result<EventOutcome> {
|
||||
if let Event::Key(key_event) = event {
|
||||
if let Some(editor) = app_state.editor_for_path(path) {
|
||||
match editor.handle_key_event(key_event) {
|
||||
KeyEventOutcome::Consumed(Some(msg)) => {
|
||||
return Ok(EventOutcome::Ok(msg));
|
||||
}
|
||||
KeyEventOutcome::Consumed(None) => {
|
||||
return Ok(EventOutcome::Ok("Form input updated".into()));
|
||||
}
|
||||
KeyEventOutcome::Pending => {
|
||||
return Ok(EventOutcome::Ok("Waiting for next key...".into()));
|
||||
}
|
||||
KeyEventOutcome::NotMatched => {
|
||||
// fall through to navigation / save / revert
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(EventOutcome::Ok(String::new()))
|
||||
}
|
||||
|
||||
// Save wrapper
|
||||
pub async fn save_form(
|
||||
app_state: &mut AppState,
|
||||
path: &str,
|
||||
grpc_client: &mut crate::services::grpc_client::GrpcClient,
|
||||
) -> Result<EventOutcome> {
|
||||
let outcome = logic::save(app_state, path, grpc_client).await?;
|
||||
let message = match outcome {
|
||||
logic::SaveOutcome::NoChange => "No changes to save.".to_string(),
|
||||
logic::SaveOutcome::UpdatedExisting => "Entry updated.".to_string(),
|
||||
logic::SaveOutcome::CreatedNew(_) => "New entry created.".to_string(),
|
||||
};
|
||||
Ok(EventOutcome::DataSaved(outcome, message))
|
||||
}
|
||||
|
||||
pub async fn revert_form(
|
||||
app_state: &mut AppState,
|
||||
path: &str,
|
||||
grpc_client: &mut crate::services::grpc_client::GrpcClient,
|
||||
) -> Result<EventOutcome> {
|
||||
let message = logic::revert(app_state, path, grpc_client).await?;
|
||||
Ok(EventOutcome::Ok(message))
|
||||
}
|
||||
39
client/src/pages/forms/loader.rs
Normal file
39
client/src/pages/forms/loader.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
// src/pages/forms/loader.rs
|
||||
use anyhow::{Context, Result};
|
||||
use crate::{
|
||||
state::app::state::AppState,
|
||||
services::grpc_client::GrpcClient,
|
||||
services::ui_service::UiService, // ✅ import UiService
|
||||
config::binds::Config,
|
||||
pages::forms::FormState,
|
||||
};
|
||||
|
||||
pub async fn ensure_form_loaded_and_count(
|
||||
grpc_client: &mut GrpcClient,
|
||||
app_state: &mut AppState,
|
||||
config: &Config,
|
||||
profile: &str,
|
||||
table: &str,
|
||||
) -> Result<()> {
|
||||
let path = format!("{}/{}", profile, table);
|
||||
|
||||
app_state.ensure_form_editor(&path, config, || {
|
||||
FormState::new(profile.to_string(), table.to_string(), vec![])
|
||||
});
|
||||
|
||||
if let Some(form_state) = app_state.form_state_for_path(&path) {
|
||||
UiService::fetch_and_set_table_count(grpc_client, form_state)
|
||||
.await
|
||||
.context("Failed to fetch table count")?;
|
||||
|
||||
if form_state.total_count > 0 {
|
||||
UiService::load_table_data_by_position(grpc_client, form_state)
|
||||
.await
|
||||
.context("Failed to load table data")?;
|
||||
} else {
|
||||
form_state.reset_to_empty();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -3,7 +3,11 @@
|
||||
pub mod ui;
|
||||
pub mod state;
|
||||
pub mod logic;
|
||||
pub mod event;
|
||||
pub mod loader;
|
||||
|
||||
pub use ui::*;
|
||||
pub use state::*;
|
||||
pub use logic::*;
|
||||
pub use event::*;
|
||||
pub use loader::*;
|
||||
|
||||
@@ -16,6 +16,7 @@ use crate::pages::admin::AdminState;
|
||||
use crate::pages::admin::AdminFocus;
|
||||
use crate::pages::intro::IntroState;
|
||||
use crate::pages::forms::{FormState, FieldDefinition};
|
||||
use crate::pages::forms;
|
||||
use crate::pages::routing::{Router, Page};
|
||||
use crate::buffer::state::BufferState;
|
||||
use crate::buffer::state::AppView;
|
||||
@@ -459,7 +460,7 @@ pub async fn run_ui() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
if let Page::Form(current_path) = &router.current {
|
||||
if let Page::Form(_current_path) = &router.current {
|
||||
let current_view_profile = app_state.current_view_profile_name.clone();
|
||||
let current_view_table = app_state.current_view_table_name.clone();
|
||||
|
||||
@@ -475,52 +476,16 @@ pub async fn run_ui() -> Result<()> {
|
||||
);
|
||||
needs_redraw = true;
|
||||
|
||||
match UiService::load_table_view(
|
||||
// DELEGATE to the forms loader
|
||||
match forms::loader::ensure_form_loaded_and_count(
|
||||
&mut grpc_client,
|
||||
&mut app_state,
|
||||
&config,
|
||||
prof_name,
|
||||
tbl_name,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(new_form_state) => {
|
||||
// Set the new form state and fetch count
|
||||
let path = format!("{}/{}", prof_name, tbl_name);
|
||||
app_state.ensure_form_editor(&path, &config, || new_form_state);
|
||||
|
||||
if let Some(form_state) = app_state.form_state_for_path(&path) {
|
||||
if let Err(e) = UiService::fetch_and_set_table_count(
|
||||
&mut grpc_client,
|
||||
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,
|
||||
form_state,
|
||||
)
|
||||
.await
|
||||
{
|
||||
app_state.update_dialog_content(
|
||||
&format!("Error loading data: {}", e),
|
||||
vec!["OK".to_string()],
|
||||
DialogPurpose::LoginFailed,
|
||||
);
|
||||
} else {
|
||||
app_state.hide_dialog();
|
||||
}
|
||||
} else {
|
||||
form_state.reset_to_empty();
|
||||
app_state.hide_dialog();
|
||||
}
|
||||
}
|
||||
|
||||
).await {
|
||||
Ok(()) => {
|
||||
app_state.hide_dialog();
|
||||
prev_view_profile_name = current_view_profile;
|
||||
prev_view_table_name = current_view_table;
|
||||
table_just_switched = true;
|
||||
@@ -531,10 +496,9 @@ pub async fn run_ui() -> Result<()> {
|
||||
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();
|
||||
// Reset to previous state on error
|
||||
app_state.current_view_profile_name = prev_view_profile_name.clone();
|
||||
app_state.current_view_table_name = prev_view_table_name.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user