aboutsummaryrefslogtreecommitdiff
path: root/src/core/data/data_loader.rs
diff options
context:
space:
mode:
authorUMTS at Teleco <crt@teleco.ch>2025-12-13 02:51:15 +0100
committerUMTS at Teleco <crt@teleco.ch>2025-12-13 02:51:15 +0100
commit8323fdd73272a2882781aba3c499ba0be3dff2a6 (patch)
treeffbf86473933e69cfaeef30d5c6ea7e5b494856c /src/core/data/data_loader.rs
committing to insanityHEADmaster
Diffstat (limited to 'src/core/data/data_loader.rs')
-rw-r--r--src/core/data/data_loader.rs99
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)
+ }
+}