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};
22
23#[utoipa::path(
28 context_path = "/api/maps/{map_id}/drawings",
29 params(
30 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
31 ),
32 responses(
33 (status = 200, description = "Find drawings", body = Vec<DrawingDto>)
34 ),
35 security(
36 ("oauth2" = [])
37 )
38)]
39#[get("")]
40pub async fn find(map_id: Path<i32>, pool: SharedPool) -> Result<HttpResponse> {
41 let response = service::drawings::find(map_id.into_inner(), &pool).await?;
42 Ok(HttpResponse::Ok().json(response))
43}
44
45#[utoipa::path(
50 context_path = "/api/maps/{map_id}/drawings",
51 params(
52 ("map_id" = i32, Path, description = "The id of the map"),
53 ),
54 request_body = ActionDtoWrapperNewPlantings,
55 responses(
56 (status = 201, description = "Create plantings", body = Vec<DrawingDto>)
57 ),
58 security(
59 ("oauth2" = [])
60 )
61)]
62#[post("")]
63pub async fn create(
64 path: Path<i32>,
65 new_drawings: Json<ActionDtoWrapper<Vec<DrawingDto>>>,
66 pool: SharedPool,
67 broadcaster: SharedBroadcaster,
68 user_info: UserInfo,
69) -> Result<HttpResponse> {
70 let map_id = path.into_inner();
71
72 let ActionDtoWrapper { action_id, dto } = new_drawings.into_inner();
73
74 let created_drawings = service::drawings::create(dto, &pool).await?;
75
76 broadcaster
77 .broadcast(
78 map_id,
79 Action {
80 action_id,
81 user_id: user_info.id,
82 action: ActionType::CreateDrawing(created_drawings.clone()),
83 },
84 )
85 .await;
86
87 Ok(HttpResponse::Created().json(created_drawings))
88}
89
90#[utoipa::path(
95 context_path = "/api/maps/{map_id}/drawings",
96 params(
97 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
98 ),
99 request_body = ActionDtoWrapperUpdatePlantings,
100 responses(
101 (status = 200, description = "Update plantings", body = Vec<DrawingDto>)
102 ),
103 security(
104 ("oauth2" = [])
105 )
106)]
107#[patch("")]
108pub async fn update(
109 path: Path<i32>,
110 update_drawings: Json<ActionDtoWrapper<UpdateDrawingsDto>>,
111 pool: SharedPool,
112 broadcaster: SharedBroadcaster,
113 user_info: UserInfo,
114) -> Result<HttpResponse> {
115 let map_id = path.into_inner();
116
117 let ActionDtoWrapper { action_id, dto } = update_drawings.into_inner();
118
119 let updated = service::drawings::update(dto.clone(), &pool).await?;
120
121 let action = match &dto {
122 UpdateDrawingsDto::Update(_) => ActionType::UpdateDrawing(updated.clone()),
123 UpdateDrawingsDto::UpdateAddDate(_) => ActionType::UpdateDrawingAddDate(updated.clone()),
124 UpdateDrawingsDto::UpdateRemoveDate(_) => {
125 ActionType::UpdateDrawingRemoveDate(updated.clone())
126 }
127 UpdateDrawingsDto::UpdateNotes(_) => ActionType::UpdateDrawingNotes(
128 updated
129 .clone()
130 .into_iter()
131 .map(UpdateDrawingNotesActionPayload::new)
132 .collect(),
133 ),
134 };
135
136 broadcaster
137 .broadcast(
138 map_id,
139 Action {
140 action_id,
141 user_id: user_info.id,
142 action,
143 },
144 )
145 .await;
146
147 Ok(HttpResponse::Ok().json(updated))
148}
149
150#[utoipa::path(
155 context_path = "/api/maps/{map_id}/drawings",
156 params(
157 ("map_id" = i32, Path, description = "The id of the map"),
158 ),
159 request_body = ActionDtoWrapperDeleteDrawings,
160 responses(
161 (status = 200, description = "Drawings have been deleted")
162 ),
163 security(
164 ("oauth2" = [])
165 )
166)]
167#[delete("")]
168pub async fn delete(
169 path: Path<i32>,
170 delete_drawings: Json<ActionDtoWrapper<Vec<Uuid>>>,
171 pool: SharedPool,
172 broadcaster: SharedBroadcaster,
173 user_info: UserInfo,
174) -> Result<HttpResponse> {
175 let map_id = path.into_inner();
176
177 let ActionDtoWrapper { action_id, dto } = delete_drawings.into_inner();
178
179 service::drawings::delete_by_ids(dto.clone(), &pool).await?;
180
181 broadcaster
182 .broadcast(
183 map_id,
184 Action {
185 action_id,
186 user_id: user_info.id,
187 action: ActionType::DeleteDrawing(dto),
188 },
189 )
190 .await;
191
192 Ok(HttpResponse::Ok().finish())
193}