use crate::azure::models::{Application, CreatedSecret, KeyVault, UserInfo}; use crate::state::async_operations::AsyncOperations; use crate::ui::BackgroundRenderer; use std::sync::Arc; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum AuthStatus { NotAuthenticated, Authenticating, Authenticated, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ViewState { Login, AppList, CreateSecret, SelectKeyVault, } pub struct AppState { // Authentication pub auth_status: AuthStatus, pub user_info: Option, // Data pub applications: Vec, pub selected_app: Option, pub key_vaults: Vec, pub selected_keyvault: Option, // Created secret (temporary, should be saved to vault ASAP) pub created_secret: Option, // Async operations pub operations: AsyncOperations, // UI State pub current_view: ViewState, pub error_message: Option, pub success_message: Option, // Form inputs pub secret_description: String, pub secret_name_for_vault: String, pub app_search_filter: String, pub vault_search_filter: String, // Background rendering pub background_renderer: Option>, } impl AppState { pub fn new() -> Self { Self { auth_status: AuthStatus::NotAuthenticated, user_info: None, applications: Vec::new(), selected_app: None, key_vaults: Vec::new(), selected_keyvault: None, created_secret: None, operations: AsyncOperations::new(), current_view: ViewState::Login, error_message: None, success_message: None, secret_description: String::new(), secret_name_for_vault: String::new(), app_search_filter: String::new(), vault_search_filter: String::new(), background_renderer: None, } } pub fn clear_messages(&mut self) { self.error_message = None; self.success_message = None; } pub fn set_error(&mut self, error: String) { self.error_message = Some(error); self.success_message = None; } pub fn set_success(&mut self, message: String) { self.success_message = Some(message); self.error_message = None; } pub fn filtered_applications(&self) -> Vec { if self.app_search_filter.is_empty() { return self.applications.clone(); } let filter_lower = self.app_search_filter.to_lowercase(); self.applications .iter() .filter(|app| { app.display_name.to_lowercase().contains(&filter_lower) || app.app_id.to_lowercase().contains(&filter_lower) }) .cloned() .collect() } pub fn filtered_vaults(&self) -> Vec { if self.vault_search_filter.is_empty() { return self.key_vaults.clone(); } let filter_lower = self.vault_search_filter.to_lowercase(); self.key_vaults .iter() .filter(|vault| { vault.name.to_lowercase().contains(&filter_lower) || vault.location.to_lowercase().contains(&filter_lower) }) .cloned() .collect() } pub fn reset_for_new_secret(&mut self) { self.secret_description.clear(); self.secret_name_for_vault.clear(); self.created_secret = None; self.selected_app = None; self.selected_keyvault = None; // Clear the selected keyvault for next secret self.clear_messages(); } } impl Default for AppState { fn default() -> Self { Self::new() } }