airlab_lib/model/
view_panel.rs

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}