//! Saved view types and DTOs. //! //! Saved views are user-defined filter/sort configurations that can be pinned //! to the sidebar for quick access. Each view targets a specific domain //! (tasks, emails, or events) and stores its filter criteria as JSON. use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use strum_macros::EnumString; use crate::id_types::{SavedViewId, UserId, ProjectId}; use super::shared::{DbValue, ParseableEnum, SortDirection}; // ============ Saved Views ============ /// Type of view for saved filters. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, EnumString)] #[serde(rename_all = "lowercase")] pub enum ViewType { /// Task list view. #[default] #[strum(serialize = "tasks")] Tasks, /// Email list view. #[strum(serialize = "emails")] Emails, /// Event list view. #[strum(serialize = "events")] Events, } impl ViewType { /// Returns a human-readable display string. pub fn as_str(&self) -> &'static str { match self { ViewType::Tasks => "Tasks", ViewType::Emails => "Emails", ViewType::Events => "Events", } } } impl ParseableEnum for ViewType {} impl DbValue for ViewType { fn db_value(&self) -> &'static str { match self { ViewType::Tasks => "tasks", ViewType::Emails => "emails", ViewType::Events => "events", } } } /// Column to sort saved view results by. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum SortField { /// Sort by calculated urgency score (tasks only). Urgency, /// Sort by due date (tasks) or received date (emails). Nulls sort last. Due, /// Sort by creation timestamp. CreatedAt, /// Sort alphabetically by description (tasks) or subject (emails) or title (events). Description, /// Sort by priority level (High > Medium > Low, tasks only). Priority, /// Sort alphabetically by associated project name. Nulls sort last. Project, } /// Filter criteria stored as JSON. #[derive(Debug, Clone, Serialize, Deserialize, Default)] #[serde(rename_all = "camelCase")] pub struct ViewFilters { /// Filter by status. #[serde(skip_serializing_if = "Option::is_none")] pub status: Option>, /// Filter by project ID. #[serde(skip_serializing_if = "Option::is_none")] pub project_id: Option, /// Filter by tags (all must match). #[serde(skip_serializing_if = "Option::is_none")] pub tags: Option>, /// Filter by priority. #[serde(skip_serializing_if = "Option::is_none")] pub priority: Option>, /// Filter by due date range start. #[serde(skip_serializing_if = "Option::is_none")] pub due_from: Option>, /// Filter by due date range end. #[serde(skip_serializing_if = "Option::is_none")] pub due_to: Option>, /// Filter by read/unread status (emails only). #[serde(skip_serializing_if = "Option::is_none")] pub is_read: Option, /// Filter by archived status. #[serde(skip_serializing_if = "Option::is_none")] pub is_archived: Option, /// Show only snoozed items. #[serde(skip_serializing_if = "Option::is_none")] pub is_snoozed: Option, /// Show only items waiting for response. #[serde(skip_serializing_if = "Option::is_none")] pub is_waiting: Option, } /// A saved view / filter configuration. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SavedView { /// Unique view ID. pub id: SavedViewId, /// User who owns this view. #[serde(skip_serializing)] pub user_id: UserId, /// Display name for the view. pub name: String, /// Type of view (tasks, emails, events). pub view_type: ViewType, /// Filter criteria. pub filters: ViewFilters, /// Sort field. pub sort_by: Option, /// Sort order. pub sort_order: SortDirection, /// Whether to show in sidebar. pub is_pinned: bool, /// Position in sidebar. pub position: i32, /// When the view was created. pub created_at: DateTime, /// When the view was last modified. pub updated_at: DateTime, } // ============ Saved View DTOs ============ /// Data for creating a new saved view. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NewSavedView { /// Display name for the view. pub name: String, /// Type of view (tasks, emails, events). pub view_type: ViewType, /// Filter criteria. pub filters: ViewFilters, /// Sort field. pub sort_by: Option, /// Sort order. pub sort_order: Option, /// Whether to pin to sidebar. pub is_pinned: Option, }