Skip to main content

max / goingson

4.9 KB · 158 lines History Blame Raw
1 //! Saved view types and DTOs.
2 //!
3 //! Saved views are user-defined filter/sort configurations that can be pinned
4 //! to the sidebar for quick access. Each view targets a specific domain
5 //! (tasks, emails, or events) and stores its filter criteria as JSON.
6
7 use chrono::{DateTime, Utc};
8 use serde::{Deserialize, Serialize};
9 use strum_macros::EnumString;
10 use crate::id_types::{SavedViewId, UserId, ProjectId};
11
12 use super::shared::{DbValue, ParseableEnum, SortDirection};
13
14 // ============ Saved Views ============
15
16 /// Type of view for saved filters.
17 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, EnumString)]
18 #[serde(rename_all = "lowercase")]
19 pub enum ViewType {
20 /// Task list view.
21 #[default]
22 #[strum(serialize = "tasks")]
23 Tasks,
24 /// Email list view.
25 #[strum(serialize = "emails")]
26 Emails,
27 /// Event list view.
28 #[strum(serialize = "events")]
29 Events,
30 }
31
32 impl ViewType {
33 /// Returns a human-readable display string.
34 pub fn as_str(&self) -> &'static str {
35 match self {
36 ViewType::Tasks => "Tasks",
37 ViewType::Emails => "Emails",
38 ViewType::Events => "Events",
39 }
40 }
41
42 }
43
44 impl ParseableEnum for ViewType {}
45
46 impl DbValue for ViewType {
47 fn db_value(&self) -> &'static str {
48 match self {
49 ViewType::Tasks => "tasks",
50 ViewType::Emails => "emails",
51 ViewType::Events => "events",
52 }
53 }
54 }
55
56 /// Column to sort saved view results by.
57 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
58 #[serde(rename_all = "snake_case")]
59 pub enum SortField {
60 /// Sort by calculated urgency score (tasks only).
61 Urgency,
62 /// Sort by due date (tasks) or received date (emails). Nulls sort last.
63 Due,
64 /// Sort by creation timestamp.
65 CreatedAt,
66 /// Sort alphabetically by description (tasks) or subject (emails) or title (events).
67 Description,
68 /// Sort by priority level (High > Medium > Low, tasks only).
69 Priority,
70 /// Sort alphabetically by associated project name. Nulls sort last.
71 Project,
72 }
73
74 /// Filter criteria stored as JSON.
75 #[derive(Debug, Clone, Serialize, Deserialize, Default)]
76 #[serde(rename_all = "camelCase")]
77 pub struct ViewFilters {
78 /// Filter by status.
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub status: Option<Vec<crate::models::TaskStatus>>,
81 /// Filter by project ID.
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub project_id: Option<ProjectId>,
84 /// Filter by tags (all must match).
85 #[serde(skip_serializing_if = "Option::is_none")]
86 pub tags: Option<Vec<String>>,
87 /// Filter by priority.
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub priority: Option<Vec<crate::models::Priority>>,
90 /// Filter by due date range start.
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub due_from: Option<DateTime<Utc>>,
93 /// Filter by due date range end.
94 #[serde(skip_serializing_if = "Option::is_none")]
95 pub due_to: Option<DateTime<Utc>>,
96 /// Filter by read/unread status (emails only).
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub is_read: Option<bool>,
99 /// Filter by archived status.
100 #[serde(skip_serializing_if = "Option::is_none")]
101 pub is_archived: Option<bool>,
102 /// Show only snoozed items.
103 #[serde(skip_serializing_if = "Option::is_none")]
104 pub is_snoozed: Option<bool>,
105 /// Show only items waiting for response.
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub is_waiting: Option<bool>,
108 }
109
110 /// A saved view / filter configuration.
111 #[derive(Debug, Clone, Serialize, Deserialize)]
112 #[serde(rename_all = "camelCase")]
113 pub struct SavedView {
114 /// Unique view ID.
115 pub id: SavedViewId,
116 /// User who owns this view.
117 #[serde(skip_serializing)]
118 pub user_id: UserId,
119 /// Display name for the view.
120 pub name: String,
121 /// Type of view (tasks, emails, events).
122 pub view_type: ViewType,
123 /// Filter criteria.
124 pub filters: ViewFilters,
125 /// Sort field.
126 pub sort_by: Option<SortField>,
127 /// Sort order.
128 pub sort_order: SortDirection,
129 /// Whether to show in sidebar.
130 pub is_pinned: bool,
131 /// Position in sidebar.
132 pub position: i32,
133 /// When the view was created.
134 pub created_at: DateTime<Utc>,
135 /// When the view was last modified.
136 pub updated_at: DateTime<Utc>,
137 }
138
139 // ============ Saved View DTOs ============
140
141 /// Data for creating a new saved view.
142 #[derive(Debug, Clone, Serialize, Deserialize)]
143 #[serde(rename_all = "camelCase")]
144 pub struct NewSavedView {
145 /// Display name for the view.
146 pub name: String,
147 /// Type of view (tasks, emails, events).
148 pub view_type: ViewType,
149 /// Filter criteria.
150 pub filters: ViewFilters,
151 /// Sort field.
152 pub sort_by: Option<SortField>,
153 /// Sort order.
154 pub sort_order: Option<SortDirection>,
155 /// Whether to pin to sidebar.
156 pub is_pinned: Option<bool>,
157 }
158