fixed form state removed, but not won, aint working yet

This commit is contained in:
Priec
2025-08-22 00:27:23 +02:00
parent 3dd6808ea2
commit 4ed8e7b421
7 changed files with 275 additions and 252 deletions

View File

@@ -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())
}