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::{layer, map_access_control::check_permissions},
24};
25
26#[utoipa::path(
32 context_path = "/api/maps/{map_id}/layers",
33 params(
34 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
35 LayerSearchParameters,
36 ),
37 responses(
38 (status = 200, description = "Search layers", body = VecLayerDto)
39 ),
40 security(
41 ("oauth2" = [])
42 )
43)]
44#[get("")]
45pub async fn find(
46 search_query: Query<LayerSearchParameters>,
47 map_id: Path<i32>,
48 pool: SharedPool,
49 user_info: UserInfo,
50) -> Result<HttpResponse> {
51 let mut search_params = search_query.into_inner();
52 let id = map_id.into_inner();
53 search_params.map_id = Some(id);
54
55 check_permissions(id, &pool, user_info).await?;
56
57 let response = layer::find(search_params, &pool).await?;
58 Ok(HttpResponse::Ok().json(response))
59}
60
61#[utoipa::path(
66 context_path = "/api/maps/{map_id}/layers",
67 params(
68 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
69 ),
70 responses(
71 (status = 200, description = "Fetch layer by id", body = LayerDto)
72 ),
73 security(
74 ("oauth2" = [])
75 )
76)]
77#[get("/{id}")]
78pub async fn find_by_id(path: Path<(i32, Uuid)>, pool: SharedPool) -> Result<HttpResponse> {
79 let (_, id) = path.into_inner();
80 let response = layer::find_by_id(id, &pool).await?;
81 Ok(HttpResponse::Ok().json(response))
82}
83
84#[utoipa::path(
89 context_path = "/api/maps/{map_id}/layers",
90 params(
91 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
92 ),
93 request_body = ActionDtoWrapperUpdateLayer,
94 responses(
95 (status = 201, description = "Create a plant layer", body = LayerDto)
96 ),
97 security(
98 ("oauth2" = [])
99 )
100)]
101#[post("")]
102pub async fn create(
103 path: Path<i32>,
104 new_layer: Json<ActionDtoWrapperNewLayer>,
105 pool: SharedPool,
106 broadcaster: SharedBroadcaster,
107 user_info: UserInfo,
108) -> Result<HttpResponse> {
109 let ActionDtoWrapper { action_id, dto } = new_layer.into_inner();
110 let map_id = path.into_inner();
111 let user_id = user_info.id;
112
113 check_permissions(map_id, &pool, user_info).await?;
114
115 let dto = layer::create(map_id, dto, &pool).await?;
116
117 broadcaster
118 .broadcast(
119 map_id,
120 Action {
121 action_id,
122 user_id,
123 action: ActionType::CreateLayer(dto.clone()),
124 },
125 )
126 .await;
127
128 Ok(HttpResponse::Created().json(dto))
129}
130
131#[utoipa::path(
136 context_path = "/api/maps/{map_id}/layers",
137 params(
138 ("map_id" = i32, Path, description = "The id of the map"),
139 ),
140 request_body = ActionDtoWrapperUpdateLayer,
141 responses(
142 (status = 200, description = "Layers have been reordered")
143 ),
144 security(
145 ("oauth2" = [])
146 )
147)]
148#[put("")]
149pub async fn update(
150 path: Path<i32>,
151 update: Json<ActionDtoWrapperUpdateLayer>,
152 pool: SharedPool,
153 broadcaster: SharedBroadcaster,
154 user_info: UserInfo,
155) -> Result<HttpResponse> {
156 let ActionDtoWrapper { action_id, dto } = update.into_inner();
157 let map_id = path.into_inner();
158 let user_id = user_info.id;
159
160 check_permissions(map_id, &pool, user_info).await?;
161
162 let action = layer::update(map_id, dto.clone(), &pool).await?;
163
164 broadcaster
165 .broadcast(
166 map_id,
167 Action {
168 action_id,
169 user_id,
170 action,
171 },
172 )
173 .await;
174
175 Ok(HttpResponse::Ok().finish())
176}
177
178#[utoipa::path(
184 context_path = "/api/maps/{map_id}/layers",
185 params(
186 ("map_id" = i32, Path, description = "The id of the map the layer is on"),
187 ),
188 request_body = ActionDtoWrapperDeleteLayer,
189 responses(
190 (status = 200, description = "Delete a layer")
191 ),
192 security(
193 ("oauth2" = [])
194 )
195)]
196#[delete("")]
197pub async fn delete(
198 path: Path<i32>,
199 delete_layer: Json<ActionDtoWrapperDeleteLayer>,
200 pool: SharedPool,
201 broadcaster: SharedBroadcaster,
202 user_info: UserInfo,
203) -> Result<HttpResponse> {
204 let ActionDtoWrapper { action_id, dto } = delete_layer.into_inner();
205 let map_id = path.into_inner();
206 let user_id = user_info.id;
207 let layer_id = dto.id;
208
209 check_permissions(map_id, &pool, user_info).await?;
210
211 layer::delete_by_id(map_id, layer_id, &pool).await?;
212
213 broadcaster
214 .broadcast(
215 map_id,
216 Action {
217 action_id,
218 user_id,
219 action: ActionType::DeleteLayer(layer_id),
220 },
221 )
222 .await;
223
224 Ok(HttpResponse::Ok().finish())
225}