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::{DrawingCreateDto, 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.into(), &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<DrawingCreateDto>>>,
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, id).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 Ok(HttpResponse::Created().json(created_drawings))
100}
101
102#[utoipa::path(
108 context_path = "/api/maps/{map_id}/drawings",
109 params(
110 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
111 ),
112 request_body = ActionDtoWrapperUpdatePlantings,
113 responses(
114 (status = 200, description = "Update plantings", body = Vec<DrawingDto>)
115 ),
116 security(
117 ("oauth2" = [])
118 )
119)]
120#[patch("")]
121pub async fn update(
122 path: Path<i32>,
123 update_drawings: Json<ActionDtoWrapper<UpdateDrawingsDto>>,
124 pool: SharedPool,
125 broadcaster: SharedBroadcaster,
126 user_info: UserInfo,
127) -> Result<HttpResponse> {
128 let map_id = path.into_inner();
129 let id = user_info.id;
130 check_permissions(map_id, &pool, user_info, AccessRights::Write).await?;
131 let ActionDtoWrapper { action_id, dto } = update_drawings.into_inner();
132
133 let updated = service::drawings::update(dto.clone(), &pool, id).await?;
134
135 let action = match &dto {
136 UpdateDrawingsDto::Update(_) => ActionType::UpdateDrawing(updated.clone()),
137 UpdateDrawingsDto::UpdateAddDate(_) => ActionType::UpdateDrawingAddDate(updated.clone()),
138 UpdateDrawingsDto::UpdateRemoveDate(_) => {
139 ActionType::UpdateDrawingRemoveDate(updated.clone())
140 }
141 UpdateDrawingsDto::UpdateNotes(_) => ActionType::UpdateDrawingNotes(
142 updated
143 .clone()
144 .into_iter()
145 .map(UpdateDrawingNotesActionPayload::new)
146 .collect(),
147 ),
148 };
149
150 broadcaster
151 .broadcast(
152 map_id,
153 Action {
154 action_id,
155 user_id: id,
156 action,
157 },
158 )
159 .await;
160
161 Ok(HttpResponse::Ok().json(updated))
162}
163
164#[utoipa::path(
170 context_path = "/api/maps/{map_id}/drawings",
171 params(
172 ("map_id" = i32, Path, description = "The id of the map"),
173 ),
174 request_body = ActionDtoWrapperDeleteDrawings,
175 responses(
176 (status = 200, description = "Drawings have been deleted")
177 ),
178 security(
179 ("oauth2" = [])
180 )
181)]
182#[delete("")]
183pub async fn delete(
184 path: Path<i32>,
185 delete_drawings: Json<ActionDtoWrapper<Vec<Uuid>>>,
186 pool: SharedPool,
187 broadcaster: SharedBroadcaster,
188 user_info: UserInfo,
189) -> Result<HttpResponse> {
190 let map_id = path.into_inner();
191 let id = user_info.id;
192 check_permissions(map_id, &pool, user_info, AccessRights::Write).await?;
193 let ActionDtoWrapper { action_id, dto } = delete_drawings.into_inner();
194
195 service::drawings::delete_by_ids(dto.clone(), &pool).await?;
196
197 broadcaster
198 .broadcast(
199 map_id,
200 Action {
201 action_id,
202 user_id: id,
203 action: ActionType::DeleteDrawing(dto),
204 },
205 )
206 .await;
207
208 Ok(HttpResponse::Ok().finish())
209}