1use actix_web::{
4 delete, get, post, put,
5 web::{Json, Path, Query},
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},
17 core::{
18 ActionDtoWrapper, ActionDtoWrapperDeleteLayer, ActionDtoWrapperNewLayer,
19 ActionDtoWrapperUpdateLayer,
20 },
21 layers::LayerSearchParameters,
22 },
23 service::{
24 layer,
25 map_access_control::{check_permissions, AccessRights},
26 },
27};
28
29#[utoipa::path(
36 context_path = "/api/maps/{map_id}/layers",
37 params(
38 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
39 LayerSearchParameters,
40 ),
41 responses(
42 (status = 200, description = "Search layers", body = VecLayerDto)
43 ),
44 security(
45 ("oauth2" = [])
46 )
47)]
48#[get("")]
49pub async fn find(
50 search_query: Query<LayerSearchParameters>,
51 map_id: Path<i32>,
52 pool: SharedPool,
53 user_info: UserInfo,
54) -> Result<HttpResponse> {
55 let mut search_params = search_query.into_inner();
56 let id = map_id.into_inner();
57 search_params.map_id = Some(id);
58
59 check_permissions(id, &pool, user_info, AccessRights::Read).await?;
60
61 let response = layer::find(search_params, &pool).await?;
62 Ok(HttpResponse::Ok().json(response))
63}
64
65#[utoipa::path(
70 context_path = "/api/maps/{map_id}/layers",
71 params(
72 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
73 ),
74 responses(
75 (status = 200, description = "Fetch layer by id", body = LayerDto)
76 ),
77 security(
78 ("oauth2" = [])
79 )
80)]
81#[get("/{id}")]
82pub async fn find_by_id(path: Path<(i32, Uuid)>, pool: SharedPool) -> Result<HttpResponse> {
83 let (_, id) = path.into_inner();
84 let response = layer::find_by_id(id, &pool).await?;
85 Ok(HttpResponse::Ok().json(response))
86}
87
88#[utoipa::path(
94 context_path = "/api/maps/{map_id}/layers",
95 params(
96 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
97 ),
98 request_body = ActionDtoWrapperUpdateLayer,
99 responses(
100 (status = 201, description = "Create a plant layer", body = LayerDto)
101 ),
102 security(
103 ("oauth2" = [])
104 )
105)]
106#[post("")]
107pub async fn create(
108 path: Path<i32>,
109 new_layer: Json<ActionDtoWrapperNewLayer>,
110 pool: SharedPool,
111 broadcaster: SharedBroadcaster,
112 user_info: UserInfo,
113) -> Result<HttpResponse> {
114 let ActionDtoWrapper { action_id, dto } = new_layer.into_inner();
115 let map_id = path.into_inner();
116 let user_id = user_info.id;
117
118 check_permissions(map_id, &pool, user_info, AccessRights::Write).await?;
119
120 let dto = layer::create(map_id, dto, &pool).await?;
121
122 broadcaster
123 .broadcast(
124 map_id,
125 Action {
126 action_id,
127 user_id,
128 action: ActionType::CreateLayer(dto.clone()),
129 },
130 )
131 .await;
132
133 Ok(HttpResponse::Created().json(dto))
134}
135
136#[utoipa::path(
142 context_path = "/api/maps/{map_id}/layers",
143 params(
144 ("map_id" = i32, Path, description = "The id of the map"),
145 ),
146 request_body = ActionDtoWrapperUpdateLayer,
147 responses(
148 (status = 200, description = "Layers have been reordered")
149 ),
150 security(
151 ("oauth2" = [])
152 )
153)]
154#[put("")]
155pub async fn update(
156 path: Path<i32>,
157 update: Json<ActionDtoWrapperUpdateLayer>,
158 pool: SharedPool,
159 broadcaster: SharedBroadcaster,
160 user_info: UserInfo,
161) -> Result<HttpResponse> {
162 let ActionDtoWrapper { action_id, dto } = update.into_inner();
163 let map_id = path.into_inner();
164 let user_id = user_info.id;
165
166 check_permissions(map_id, &pool, user_info, AccessRights::Write).await?;
167
168 let action = layer::update(map_id, dto.clone(), &pool).await?;
169
170 broadcaster
171 .broadcast(
172 map_id,
173 Action {
174 action_id,
175 user_id,
176 action,
177 },
178 )
179 .await;
180
181 Ok(HttpResponse::Ok().finish())
182}
183
184#[utoipa::path(
191 context_path = "/api/maps/{map_id}/layers",
192 params(
193 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
194 ),
195 request_body = ActionDtoWrapperDeleteLayer,
196 responses(
197 (status = 200, description = "Delete a layer")
198 ),
199 security(
200 ("oauth2" = [])
201 )
202)]
203#[delete("")]
204pub async fn delete(
205 path: Path<i32>,
206 delete_layer: Json<ActionDtoWrapperDeleteLayer>,
207 pool: SharedPool,
208 broadcaster: SharedBroadcaster,
209 user_info: UserInfo,
210) -> Result<HttpResponse> {
211 let ActionDtoWrapper { action_id, dto } = delete_layer.into_inner();
212 let map_id = path.into_inner();
213 let user_id = user_info.id;
214 let layer_id = dto.id;
215
216 check_permissions(map_id, &pool, user_info, AccessRights::Write).await?;
217
218 layer::delete_by_id(map_id, layer_id, &pool).await?;
219
220 broadcaster
221 .broadcast(
222 map_id,
223 Action {
224 action_id,
225 user_id,
226 action: ActionType::DeleteLayer(layer_id),
227 },
228 )
229 .await;
230
231 Ok(HttpResponse::Ok().finish())
232}