diff options
Diffstat (limited to 'src/core/data/data_loader.rs')
| -rw-r--r-- | src/core/data/data_loader.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/core/data/data_loader.rs b/src/core/data/data_loader.rs new file mode 100644 index 0000000..7eb4125 --- /dev/null +++ b/src/core/data/data_loader.rs @@ -0,0 +1,99 @@ +use crate::api::ApiClient; +use serde_json::Value; + +/// Loading state management for UI views +#[derive(Default)] +pub struct LoadingState { + pub is_loading: bool, + pub last_error: Option<String>, + pub last_load_time: Option<std::time::Instant>, +} + +impl LoadingState { + pub fn new() -> Self { + Self::default() + } + + pub fn start_loading(&mut self) { + self.is_loading = true; + self.last_error = None; + self.last_load_time = Some(std::time::Instant::now()); + } + + pub fn finish_loading(&mut self, error: Option<String>) { + self.is_loading = false; + self.last_error = error; + } + + pub fn finish_success(&mut self) { + self.finish_loading(None); + } + + pub fn finish_error(&mut self, error: String) { + self.finish_loading(Some(error)); + } + + #[allow(dead_code)] + pub fn has_error(&self) -> bool { + self.last_error.is_some() + } + + pub fn get_error(&self) -> Option<&str> { + self.last_error.as_deref() + } + + #[allow(dead_code)] + pub fn should_auto_retry(&self, retry_after_seconds: u64) -> bool { + if let (Some(error), Some(load_time)) = (&self.last_error, self.last_load_time) { + !error.is_empty() && load_time.elapsed().as_secs() > retry_after_seconds + } else { + false + } + } +} + +/// Data loader for assets +pub struct DataLoader; + +impl DataLoader { + pub fn load_assets( + api_client: &ApiClient, + limit: Option<u32>, + where_clause: Option<Value>, + filter: Option<Value>, + ) -> Result<Vec<Value>, String> { + log::info!( + "Loading inventory assets (limit={:?}, where={:?}, filter={:?})...", + limit, + where_clause, + filter + ); + + // Use select_with_joins to load assets with zone and category data + let response = api_client + .select_with_joins( + "assets", + None, // columns (None = all) + where_clause, + filter, + None, // order_by + limit, + None, // joins (None = use default joins) + ) + .map_err(|e| format!("Failed to load assets: {}", e))?; + + if !response.success { + // Check if this is a database timeout error + if ApiClient::is_database_timeout_error(&response.error) { + log::warn!("Database timeout detected while loading assets"); + } + let error_msg = format!("API error: {:?}", response.error); + log::error!("{}", error_msg); + return Err(error_msg); + } + + let assets = response.data.unwrap_or_default(); + log::info!("Loaded {} assets successfully (with JOINs)", assets.len()); + Ok(assets) + } +} |
