1use crate::ctx::Ctx;
2use crate::model::ModelManager;
3use crate::model::Result;
4use crate::model::member::{Member, MemberBmc};
5use crate::model::panel::{Panel, PanelBmc, PanelFilter};
6use crate::model::panel_element::{PanelElement, PanelElementBmc};
7use crate::model::user::{User, UserBmc};
8use modql::filter::{ListOptions, OrderBy, OrderBys};
9use serde::{Deserialize, Serialize};
10use std::collections::{HashMap, hash_map::Entry};
11use tracing::debug;
12
13#[derive(Serialize, Deserialize, Debug, Clone, Default)]
14pub struct ViewPanel {
15 pub id: i32,
16 pub name: Option<String>,
17 pub description: Option<String>,
18 pub application: Option<i32>,
19 #[serde(rename = "createdAt")]
20 pub created_at: chrono::DateTime<chrono::Utc>,
21 #[serde(rename = "createdBy")]
22 pub created_by: i32,
23 #[serde(rename = "isArchived")]
24 pub is_archived: bool,
25 #[serde(rename = "isFluorophore")]
26 pub is_fluorophore: bool,
27 #[serde(rename = "isLocked")]
28 pub is_locked: bool,
29 #[serde(rename = "updatedAt")]
30 pub updated_at: chrono::DateTime<chrono::Utc>,
31 pub user: User,
32 pub elements: Vec<PanelElement>,
33}
34
35pub struct ViewPanelBmc;
36
37impl ViewPanelBmc {
38 pub async fn get(ctx: &Ctx, mm: &ModelManager, id: i32) -> Result<ViewPanel> {
39 let mut element_map = HashMap::new();
40 let element_options = ListOptions {
41 limit: Some(1_000_000),
42 offset: None,
43 order_bys: Some(OrderBys::new(vec![OrderBy::Desc("id".into())])),
44 };
45 let elements: Vec<PanelElement> =
46 PanelElementBmc::list(ctx, mm, None, Some(element_options)).await?;
47 for element in elements {
48 let toi = match element_map.entry(element.panel_id) {
49 Entry::Occupied(o) => o.into_mut(),
50 Entry::Vacant(v) => v.insert(vec![]),
51 };
52 toi.push(element);
53 }
54
55 let mut member_map = HashMap::new();
56 let members: Vec<Member> = MemberBmc::list(ctx, mm, None, None).await?;
57 for member in members {
58 member_map.insert(member.id, member);
59 }
60
61 let mut user_map = HashMap::new();
62 let users: Vec<User> = UserBmc::list(ctx, mm, None, None).await?;
63 for user in users {
64 user_map.insert(user.id, user);
65 }
66
67 let item: Panel = PanelBmc::get(ctx, mm, id).await?;
68 let elements = match element_map.get(&(item.id as i32)) {
69 Some(v) => v.clone(),
70 None => vec![],
71 };
72
73 let member = match member_map.get(&(item.created_by as i32)) {
74 Some(v) => v.clone(),
75 None => Member::default(),
76 };
77 debug!("member: {:?}", member);
78
79 let user = match user_map.get(&(member.user_id as i32)) {
80 Some(v) => v.clone(),
81 None => User::default(),
82 };
83 debug!("user: {:?}", user);
84
85 let ret = ViewPanel {
86 id: item.id,
87 name: item.name,
88 application: item.application,
89 created_at: item.created_at,
90 created_by: item.created_by,
91 description: item.description,
92 is_archived: item.is_archived,
93 is_fluorophore: item.is_fluorophore,
94 updated_at: item.updated_at,
95 is_locked: item.is_locked,
96 elements,
97 user,
98 };
99
100 Ok(ret)
101 }
102 pub async fn list(
103 ctx: &Ctx,
104 mm: &ModelManager,
105 filters: Option<Vec<PanelFilter>>,
106 list_options: Option<ListOptions>,
107 ) -> Result<Vec<ViewPanel>> {
108 let mut element_map = HashMap::new();
109 let element_options = ListOptions {
110 limit: Some(1_000_000),
111 offset: None,
112 order_bys: Some(OrderBys::new(vec![OrderBy::Desc("id".into())])),
113 };
114 let elements: Vec<PanelElement> =
115 PanelElementBmc::list(ctx, mm, None, Some(element_options)).await?;
116 for element in elements {
117 let toi = match element_map.entry(element.panel_id) {
118 Entry::Occupied(o) => o.into_mut(),
119 Entry::Vacant(v) => v.insert(vec![]),
120 };
121 toi.push(element);
122 }
123
124 let mut member_map = HashMap::new();
125 let members: Vec<Member> = MemberBmc::list(ctx, mm, None, None).await?;
126 for member in members {
127 member_map.insert(member.id, member);
128 }
129
130 let mut user_map = HashMap::new();
131 let users: Vec<User> = UserBmc::list(ctx, mm, None, None).await?;
132 for user in users {
133 user_map.insert(user.id, user);
134 }
135
136 let panels: Vec<Panel> = PanelBmc::list(ctx, mm, filters, list_options).await?;
137 let mut returns = vec![];
138 for item in panels {
139 let elements = match element_map.get(&{ item.id }) {
140 Some(v) => v.clone(),
141 None => vec![],
142 };
143
144 let member = match member_map.get(&{ item.created_by }) {
145 Some(v) => v.clone(),
146 None => Member::default(),
147 };
148
149 let user = match user_map.get(&{ member.user_id }) {
150 Some(v) => v.clone(),
151 None => User::default(),
152 };
153
154 returns.push(ViewPanel {
155 id: item.id,
156 name: item.name,
157 application: item.application,
158 created_at: item.created_at,
159 created_by: item.created_by,
160 description: item.description,
161 is_archived: item.is_archived,
162 is_fluorophore: item.is_fluorophore,
163 updated_at: item.updated_at,
164 is_locked: item.is_locked,
165 elements,
166 user,
167 });
168 }
169
170 Ok(returns)
171 }
172}
173
174#[cfg(test)]
175mod tests {
176 use super::*;
177 use anyhow::Result;
178
179 #[ignore]
180 #[tokio::test]
181 async fn test_view_panel_list_all_ok() -> Result<()> {
182 let mm = ModelManager::new().await?;
183 let ctx = Ctx::root_ctx();
184
185 let panels = ViewPanelBmc::list(&ctx, &mm, None, None).await?;
186
187 let _panels: Vec<ViewPanel> = panels
188 .into_iter()
189 .filter(|t| {
190 t.name
191 .as_ref()
192 .unwrap_or(&String::new())
193 .starts_with("test_list_all_ok-panel")
194 })
195 .collect();
196
197 Ok(())
198 }
199}