1use actix_web::{
4 delete, get, patch, post,
5 web::{Json, Path},
6 HttpResponse, Result,
7};
8use uuid::Uuid;
9
10use crate::{
11 config::{
12 auth::user_info::UserInfo,
13 data::{SharedBroadcaster, SharedPool},
14 },
15 model::dto::{
16 actions::{Action, ActionType, UpdateDrawingNotesActionPayload},
17 core::ActionDtoWrapper,
18 drawings::{DrawingDto, UpdateDrawingsDto},
19 },
20 service::{
21 self,
22 map_access_control::{check_permissions, AccessRights},
23 },
24};
25
26#[utoipa::path(
32 context_path = "/api/maps/{map_id}/drawings",
33 params(
34 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
35 ),
36 responses(
37 (status = 200, description = "Find drawings", body = Vec<DrawingDto>)
38 ),
39 security(
40 ("oauth2" = [])
41 )
42)]
43#[get("")]
44pub async fn find(
45 map_id: Path<i32>,
46 pool: SharedPool,
47 user_info: UserInfo,
48) -> Result<HttpResponse> {
49 let id = map_id.into_inner();
50 check_permissions(id, &pool, user_info, AccessRights::Read).await?;
51 let response = service::drawings::find(id, &pool).await?;
52 Ok(HttpResponse::Ok().json(response))
53}
54
55#[utoipa::path(
61 context_path = "/api/maps/{map_id}/drawings",
62 params(
63 ("map_id" = i32, Path, description = "The id of the map"),
64 ),
65 request_body = ActionDtoWrapperNewPlantings,
66 responses(
67 (status = 201, description = "Create plantings", body = Vec<DrawingDto>)
68 ),
69 security(
70 ("oauth2" = [])
71 )
72)]
73#[post("")]
74pub async fn create(
75 path: Path<i32>,
76 new_drawings: Json<ActionDtoWrapper<Vec<DrawingDto>>>,
77 pool: SharedPool,
78 broadcaster: SharedBroadcaster,
79 user_info: UserInfo,
80) -> Result<HttpResponse> {
81 let map_id = path.into_inner();
82 let id = user_info.id;
83 check_permissions(map_id, &pool, user_info, AccessRights::Write).await?;
84
85 let ActionDtoWrapper { action_id, dto } = new_drawings.into_inner();
86
87 let created_drawings = service::drawings::create(dto, &pool).await?;
88
89 broadcaster
90 .broadcast(
91 map_id,
92 Action {
93 action_id,
94 user_id: id,
95 action: ActionType::CreateDrawing(created_drawings.clone()),
96 },
97 )
98 .await;
99
100 Ok(HttpResponse::Created().json(created_drawings))
101}
102
103#[utoipa::path(
109 context_path = "/api/maps/{map_id}/drawings",
110 params(
111 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
112 ),
113 request_body = ActionDtoWrapperUpdatePlantings,
114 responses(
115 (status = 200, description = "Update plantings", body = Vec<DrawingDto>)
116 ),
117 security(
118 ("oauth2" = [])
119 )
120)]
121#[patch("")]
122pub async fn update(
123 path: Path<i32>,
124 update_drawings: Json<ActionDtoWrapper<UpdateDrawingsDto>>,
125 pool: SharedPool,
126 broadcaster: SharedBroadcaster,
127 user_info: UserInfo,
128) -> Result<HttpResponse> {
129 let map_id = path.into_inner();
130 let id = user_info.id;
131 check_permissions(map_id, &pool, user_info, AccessRights::Write).await?;
132 let ActionDtoWrapper { action_id, dto } = update_drawings.into_inner();
133
134 let updated = service::drawings::update(dto.clone(), &pool).await?;
135
136 let action = match &dto {
137 UpdateDrawingsDto::Update(_) => ActionType::UpdateDrawing(updated.clone()),
138 UpdateDrawingsDto::UpdateAddDate(_) => ActionType::UpdateDrawingAddDate(updated.clone()),
139 UpdateDrawingsDto::UpdateRemoveDate(_) => {
140 ActionType::UpdateDrawingRemoveDate(updated.clone())
141 }
142 UpdateDrawingsDto::UpdateNotes(_) => ActionType::UpdateDrawingNotes(
143 updated
144 .clone()
145 .into_iter()
146 .map(UpdateDrawingNotesActionPayload::new)
147 .collect(),
148 ),
149 };
150
151 broadcaster
152 .broadcast(
153 map_id,
154 Action {
155 action_id,
156 user_id: id,
157 action,
158 },
159 )
160 .await;
161
162 Ok(HttpResponse::Ok().json(updated))
163}
164
165#[utoipa::path(
171 context_path = "/api/maps/{map_id}/drawings",
172 params(
173 ("map_id" = i32, Path, description = "The id of the map"),
174 ),
175 request_body = ActionDtoWrapperDeleteDrawings,
176 responses(
177 (status = 200, description = "Drawings have been deleted")
178 ),
179 security(
180 ("oauth2" = [])
181 )
182)]
183#[delete("")]
184pub async fn delete(
185 path: Path<i32>,
186 delete_drawings: Json<ActionDtoWrapper<Vec<Uuid>>>,
187 pool: SharedPool,
188 broadcaster: SharedBroadcaster,
189 user_info: UserInfo,
190) -> Result<HttpResponse> {
191 let map_id = path.into_inner();
192 let id = user_info.id;
193 check_permissions(map_id, &pool, user_info, AccessRights::Write).await?;
194 let ActionDtoWrapper { action_id, dto } = delete_drawings.into_inner();
195
196 service::drawings::delete_by_ids(dto.clone(), &pool).await?;
197
198 broadcaster
199 .broadcast(
200 map_id,
201 Action {
202 action_id,
203 user_id: id,
204 action: ActionType::DeleteDrawing(dto),
205 },
206 )
207 .await;
208
209 Ok(HttpResponse::Ok().finish())
210}