fixed form state removed, but not won, aint working yet
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
// src/tui/functions/common/form.rs
|
||||
|
||||
use crate::services::grpc_client::GrpcClient;
|
||||
use crate::state::app::state::AppState; // NEW: Import AppState
|
||||
use crate::state::pages::form::FormState;
|
||||
use crate::utils::data_converter; // NEW: Import our translator
|
||||
use crate::state::app::state::AppState;
|
||||
use crate::utils::data_converter;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -14,143 +12,137 @@ pub enum SaveOutcome {
|
||||
CreatedNew(i64),
|
||||
}
|
||||
|
||||
// MODIFIED save function signature and logic
|
||||
pub async fn save(
|
||||
app_state: &AppState, // NEW: Pass in AppState
|
||||
form_state: &mut FormState,
|
||||
app_state: &mut AppState,
|
||||
grpc_client: &mut GrpcClient,
|
||||
) -> Result<SaveOutcome> {
|
||||
if !form_state.has_unsaved_changes {
|
||||
return Ok(SaveOutcome::NoChange);
|
||||
}
|
||||
|
||||
// --- NEW: VALIDATION & CONVERSION STEP ---
|
||||
let cache_key =
|
||||
format!("{}.{}", form_state.profile_name, form_state.table_name);
|
||||
let schema = match app_state.schema_cache.get(&cache_key) {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return Err(anyhow!(
|
||||
"Schema for table '{}' not found in cache. Cannot save.",
|
||||
form_state.table_name
|
||||
));
|
||||
if let Some(fs) = app_state.form_state_mut() {
|
||||
if !fs.has_unsaved_changes {
|
||||
return Ok(SaveOutcome::NoChange);
|
||||
}
|
||||
};
|
||||
|
||||
let data_map: HashMap<String, String> = form_state
|
||||
.fields
|
||||
.iter()
|
||||
.zip(form_state.values.iter())
|
||||
.map(|(field_def, value)| (field_def.data_key.clone(), value.clone()))
|
||||
.collect();
|
||||
// Copy out what we need before dropping the mutable borrow
|
||||
let profile_name = fs.profile_name.clone();
|
||||
let table_name = fs.table_name.clone();
|
||||
let fields = fs.fields.clone();
|
||||
let values = fs.values.clone();
|
||||
let id = fs.id;
|
||||
let total_count = fs.total_count;
|
||||
let current_position = fs.current_position;
|
||||
|
||||
// Use our new translator. It returns a user-friendly error on failure.
|
||||
let converted_data =
|
||||
match data_converter::convert_and_validate_data(&data_map, schema) {
|
||||
Ok(data) => data,
|
||||
Err(user_error) => return Err(anyhow!(user_error)),
|
||||
let cache_key = format!("{}.{}", profile_name, table_name);
|
||||
let schema = app_state
|
||||
.schema_cache
|
||||
.get(&cache_key)
|
||||
.ok_or_else(|| {
|
||||
anyhow!(
|
||||
"Schema for table '{}' not found in cache. Cannot save.",
|
||||
table_name
|
||||
)
|
||||
})?;
|
||||
|
||||
let data_map: HashMap<String, String> = fields
|
||||
.iter()
|
||||
.zip(values.iter())
|
||||
.map(|(field_def, value)| (field_def.data_key.clone(), value.clone()))
|
||||
.collect();
|
||||
|
||||
let converted_data =
|
||||
data_converter::convert_and_validate_data(&data_map, schema)
|
||||
.map_err(|user_error| anyhow!(user_error))?;
|
||||
|
||||
let is_new_entry = id == 0
|
||||
|| (total_count > 0 && current_position > total_count)
|
||||
|| (total_count == 0 && current_position == 1);
|
||||
|
||||
let outcome = if is_new_entry {
|
||||
let response = grpc_client
|
||||
.post_table_data(profile_name.clone(), table_name.clone(), converted_data)
|
||||
.await
|
||||
.context("Failed to post new table data")?;
|
||||
|
||||
if response.success {
|
||||
if let Some(fs) = app_state.form_state_mut() {
|
||||
fs.id = response.inserted_id;
|
||||
fs.total_count += 1;
|
||||
fs.current_position = fs.total_count;
|
||||
fs.has_unsaved_changes = false;
|
||||
}
|
||||
SaveOutcome::CreatedNew(response.inserted_id)
|
||||
} else {
|
||||
return Err(anyhow!("Server failed to insert data: {}", response.message));
|
||||
}
|
||||
} else {
|
||||
if id == 0 {
|
||||
return Err(anyhow!(
|
||||
"Cannot update record: ID is 0, but not classified as new entry."
|
||||
));
|
||||
}
|
||||
let response = grpc_client
|
||||
.put_table_data(profile_name.clone(), table_name.clone(), id, converted_data)
|
||||
.await
|
||||
.context("Failed to put (update) table data")?;
|
||||
|
||||
if response.success {
|
||||
if let Some(fs) = app_state.form_state_mut() {
|
||||
fs.has_unsaved_changes = false;
|
||||
}
|
||||
SaveOutcome::UpdatedExisting
|
||||
} else {
|
||||
return Err(anyhow!("Server failed to update data: {}", response.message));
|
||||
}
|
||||
};
|
||||
// --- END OF NEW STEP ---
|
||||
|
||||
let outcome: SaveOutcome;
|
||||
let is_new_entry = form_state.id == 0
|
||||
|| (form_state.total_count > 0
|
||||
&& form_state.current_position > form_state.total_count)
|
||||
|| (form_state.total_count == 0 && form_state.current_position == 1);
|
||||
|
||||
if is_new_entry {
|
||||
let response = grpc_client
|
||||
.post_table_data(
|
||||
form_state.profile_name.clone(),
|
||||
form_state.table_name.clone(),
|
||||
converted_data, // Use the validated & converted data
|
||||
)
|
||||
.await
|
||||
.context("Failed to post new table data")?;
|
||||
|
||||
if response.success {
|
||||
form_state.id = response.inserted_id;
|
||||
form_state.total_count += 1;
|
||||
form_state.current_position = form_state.total_count;
|
||||
outcome = SaveOutcome::CreatedNew(response.inserted_id);
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"Server failed to insert data: {}",
|
||||
response.message
|
||||
));
|
||||
}
|
||||
Ok(outcome)
|
||||
} else {
|
||||
if form_state.id == 0 {
|
||||
return Err(anyhow!(
|
||||
"Cannot update record: ID is 0, but not classified as new entry."
|
||||
));
|
||||
}
|
||||
let response = grpc_client
|
||||
.put_table_data(
|
||||
form_state.profile_name.clone(),
|
||||
form_state.table_name.clone(),
|
||||
form_state.id,
|
||||
converted_data, // Use the validated & converted data
|
||||
)
|
||||
.await
|
||||
.context("Failed to put (update) table data")?;
|
||||
|
||||
if response.success {
|
||||
outcome = SaveOutcome::UpdatedExisting;
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"Server failed to update data: {}",
|
||||
response.message
|
||||
));
|
||||
}
|
||||
Ok(SaveOutcome::NoChange)
|
||||
}
|
||||
|
||||
form_state.has_unsaved_changes = false;
|
||||
Ok(outcome)
|
||||
}
|
||||
|
||||
pub async fn revert(
|
||||
form_state: &mut FormState, // Takes &mut FormState to update it
|
||||
app_state: &mut AppState,
|
||||
grpc_client: &mut GrpcClient,
|
||||
) -> Result<String> {
|
||||
if form_state.id == 0 || (form_state.total_count > 0 && form_state.current_position > form_state.total_count) || (form_state.total_count == 0 && form_state.current_position == 1) {
|
||||
let old_total_count = form_state.total_count; // Preserve for correct new position
|
||||
form_state.reset_to_empty(); // reset_to_empty will clear values and set id=0
|
||||
form_state.total_count = old_total_count; // Restore total_count
|
||||
if form_state.total_count > 0 { // Correctly set current_position for new
|
||||
form_state.current_position = form_state.total_count + 1;
|
||||
} else {
|
||||
form_state.current_position = 1;
|
||||
if let Some(fs) = app_state.form_state_mut() {
|
||||
if fs.id == 0
|
||||
|| (fs.total_count > 0 && fs.current_position > fs.total_count)
|
||||
|| (fs.total_count == 0 && fs.current_position == 1)
|
||||
{
|
||||
let old_total_count = fs.total_count;
|
||||
fs.reset_to_empty();
|
||||
fs.total_count = old_total_count;
|
||||
if fs.total_count > 0 {
|
||||
fs.current_position = fs.total_count + 1;
|
||||
} else {
|
||||
fs.current_position = 1;
|
||||
}
|
||||
return Ok("New entry cleared".to_string());
|
||||
}
|
||||
return Ok("New entry cleared".to_string());
|
||||
}
|
||||
|
||||
if form_state.current_position == 0 || form_state.current_position > form_state.total_count {
|
||||
if form_state.total_count > 0 {
|
||||
form_state.current_position = 1;
|
||||
} else {
|
||||
// No records to revert to, effectively a new entry state.
|
||||
form_state.reset_to_empty();
|
||||
return Ok("No saved data to revert to; form cleared.".to_string());
|
||||
if fs.current_position == 0 || fs.current_position > fs.total_count {
|
||||
if fs.total_count > 0 {
|
||||
fs.current_position = 1;
|
||||
} else {
|
||||
fs.reset_to_empty();
|
||||
return Ok("No saved data to revert to; form cleared.".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let response = grpc_client
|
||||
.get_table_data_by_position(
|
||||
fs.profile_name.clone(),
|
||||
fs.table_name.clone(),
|
||||
fs.current_position as i32,
|
||||
)
|
||||
.await
|
||||
.context(format!(
|
||||
"Failed to get table data by position {} for table {}.{}",
|
||||
fs.current_position, fs.profile_name, fs.table_name
|
||||
))?;
|
||||
|
||||
fs.update_from_response(&response.data, fs.current_position);
|
||||
Ok("Changes discarded, reloaded last saved version".to_string())
|
||||
} else {
|
||||
Ok("Nothing to revert".to_string())
|
||||
}
|
||||
|
||||
let response = grpc_client
|
||||
.get_table_data_by_position(
|
||||
form_state.profile_name.clone(),
|
||||
form_state.table_name.clone(),
|
||||
form_state.current_position as i32,
|
||||
)
|
||||
.await
|
||||
.context(format!(
|
||||
"Failed to get table data by position {} for table {}.{}",
|
||||
form_state.current_position,
|
||||
form_state.profile_name,
|
||||
form_state.table_name
|
||||
))?;
|
||||
|
||||
// FIX: Pass the current position as the second argument
|
||||
form_state.update_from_response(&response.data, form_state.current_position);
|
||||
Ok("Changes discarded, reloaded last saved version".to_string())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user