use actix_web::{
delete, get, post, put,
web::{Json, Path, Query},
HttpResponse, Result,
};
use uuid::Uuid;
use crate::{
config::{
auth::user_info::UserInfo,
data::{SharedBroadcaster, SharedPool},
},
model::dto::{
actions::{Action, ActionType},
core::{
ActionDtoWrapper, ActionDtoWrapperDeleteLayer, ActionDtoWrapperNewLayer,
ActionDtoWrapperUpdateLayer,
},
layers::LayerSearchParameters,
},
service::layer,
};
#[utoipa::path(
context_path = "/api/maps/{map_id}/layers",
params(
("map_id" = i32, Path, description = "The id of the map the layer is on"),
LayerSearchParameters,
),
responses(
(status = 200, description = "Search layers", body = VecLayerDto)
),
security(
("oauth2" = [])
)
)]
#[get("")]
pub async fn find(
search_query: Query<LayerSearchParameters>,
map_id: Path<i32>,
pool: SharedPool,
) -> Result<HttpResponse> {
let mut search_params = search_query.into_inner();
search_params.map_id = Some(map_id.into_inner());
let response = layer::find(search_params, &pool).await?;
Ok(HttpResponse::Ok().json(response))
}
#[utoipa::path(
context_path = "/api/maps/{map_id}/layers",
params(
("map_id" = i32, Path, description = "The id of the map the layer is on"),
),
responses(
(status = 200, description = "Fetch layer by id", body = LayerDto)
),
security(
("oauth2" = [])
)
)]
#[get("/{id}")]
pub async fn find_by_id(path: Path<(i32, Uuid)>, pool: SharedPool) -> Result<HttpResponse> {
let (_, id) = path.into_inner();
let response = layer::find_by_id(id, &pool).await?;
Ok(HttpResponse::Ok().json(response))
}
#[utoipa::path(
context_path = "/api/maps/{map_id}/layers",
params(
("map_id" = i32, Path, description = "The id of the map the layer is on"),
),
request_body = ActionDtoWrapperUpdateLayer,
responses(
(status = 201, description = "Create a plant layer", body = LayerDto)
),
security(
("oauth2" = [])
)
)]
#[post("")]
pub async fn create(
path: Path<i32>,
new_layer: Json<ActionDtoWrapperNewLayer>,
pool: SharedPool,
broadcaster: SharedBroadcaster,
user_info: UserInfo,
) -> Result<HttpResponse> {
let ActionDtoWrapper { action_id, dto } = new_layer.into_inner();
let map_id = path.into_inner();
let user_id = user_info.id;
let dto = layer::create(map_id, dto, &pool).await?;
broadcaster
.broadcast(
map_id,
Action {
action_id,
user_id,
action: ActionType::CreateLayer(dto.clone()),
},
)
.await;
Ok(HttpResponse::Created().json(dto))
}
#[utoipa::path(
context_path = "/api/maps/{map_id}/layers",
params(
("map_id" = i32, Path, description = "The id of the map"),
),
request_body = ActionDtoWrapperUpdateLayer,
responses(
(status = 200, description = "Layers have been reordered")
),
security(
("oauth2" = [])
)
)]
#[put("")]
pub async fn update(
path: Path<i32>,
update: Json<ActionDtoWrapperUpdateLayer>,
pool: SharedPool,
broadcaster: SharedBroadcaster,
user_info: UserInfo,
) -> Result<HttpResponse> {
let ActionDtoWrapper { action_id, dto } = update.into_inner();
let map_id = path.into_inner();
let user_id = user_info.id;
let action = layer::update(map_id, dto.clone(), &pool).await?;
broadcaster
.broadcast(
map_id,
Action {
action_id,
user_id,
action,
},
)
.await;
Ok(HttpResponse::Ok().finish())
}
#[utoipa::path(
context_path = "/api/maps/{map_id}/layers",
params(
("map_id" = i32, Path, description = "The id of the map the layer is on"),
),
request_body = ActionDtoWrapperDeleteLayer,
responses(
(status = 200, description = "Delete a layer")
),
security(
("oauth2" = [])
)
)]
#[delete("")]
pub async fn delete(
path: Path<i32>,
delete_layer: Json<ActionDtoWrapperDeleteLayer>,
pool: SharedPool,
broadcaster: SharedBroadcaster,
user_info: UserInfo,
) -> Result<HttpResponse> {
let ActionDtoWrapper { action_id, dto } = delete_layer.into_inner();
let map_id = path.into_inner();
let user_id = user_info.id;
let layer_id = dto.id;
layer::delete_by_id(map_id, layer_id, &pool).await?;
broadcaster
.broadcast(
map_id,
Action {
action_id,
user_id,
action: ActionType::DeleteLayer(layer_id),
},
)
.await;
Ok(HttpResponse::Ok().finish())
}