diff --git a/src/api/v1/item.rs b/src/api/v1/item.rs index e11e1e8..4051cd5 100644 --- a/src/api/v1/item.rs +++ b/src/api/v1/item.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: AGPL-3.0-or-later -use actix_web::{error, get, put, web, HttpResponse, Responder}; +use actix_web::{error, get, post, put, web, HttpResponse, Responder}; use uuid::Uuid; use crate::manage; @@ -10,7 +10,10 @@ use crate::models::*; use crate::DbPool; pub fn config(cfg: &mut web::ServiceConfig) { - cfg.service(add).service(list).service(show); + cfg.service(add) + .service(list) + .service(show) + .service(update); } #[put("/item")] @@ -50,3 +53,20 @@ async fn show(pool: web::Data, path: web::Path) -> actix_web::Resu Ok(HttpResponse::Ok().json(item)) } + +#[post("/item/{id}")] +async fn update( + pool: web::Data, + path: web::Path, + new_item: web::Json, +) -> actix_web::Result { + let id = path.into_inner(); + + let item = web::block(move || { + manage::item::update(&mut pool.get().unwrap(), id, new_item.into_inner()) + }) + .await? + .map_err(error::ErrorInternalServerError)?; + + Ok(HttpResponse::Ok().json(item)) +} diff --git a/src/frontend/item.rs b/src/frontend/item.rs index b902e81..e0e6f83 100644 --- a/src/frontend/item.rs +++ b/src/frontend/item.rs @@ -14,7 +14,9 @@ pub fn config(cfg: &mut web::ServiceConfig) { cfg.service(show_item) .service(list_items) .service(add_item) - .service(add_item_post); + .service(add_item_post) + .service(edit_item) + .service(edit_item_post); } #[derive(Template)] @@ -80,3 +82,40 @@ async fn add_item_post( .map_err(error::ErrorInternalServerError)?; Ok(web::Redirect::to("/item/".to_owned() + &item.id.to_string()).see_other()) } + +#[derive(Template)] +#[template(path = "item_edit.html")] +struct ItemEditForm { + req: HttpRequest, + item: Item, +} + +#[get("/item/{id}/edit")] +async fn edit_item( + req: HttpRequest, + pool: web::Data, + path: web::Path, +) -> actix_web::Result { + let id = path.into_inner(); + + let item = web::block(move || manage::item::get(&mut pool.get().unwrap(), id)) + .await? + .map_err(error::ErrorInternalServerError)?; + + Ok(ItemEditForm { req, item }) +} + +#[post("/item/{id}/edit")] +async fn edit_item_post( + pool: web::Data, + path: web::Path, + data: web::Form, +) -> actix_web::Result { + let id = path.into_inner(); + + let item = web::block(move || manage::item::update(&mut pool.get().unwrap(), id, data.into_inner())) + .await? + .map_err(error::ErrorInternalServerError)?; + + Ok(web::Redirect::to("/item/".to_owned() + &item.id.to_string()).see_other()) +} diff --git a/src/manage/item.rs b/src/manage/item.rs index 755bc52..81b386b 100644 --- a/src/manage/item.rs +++ b/src/manage/item.rs @@ -25,3 +25,10 @@ pub fn get(conn: &mut PgConnection, id: Uuid) -> Result Result, diesel::result::Error> { schema::items::table.select(Item::as_select()).load(conn) } + +pub fn update(conn: &mut PgConnection, id: Uuid, modified_item: NewItem) -> Result { + diesel::update(schema::items::table.filter(schema::items::id.eq(id))) + .set(modified_item) + .returning(Item::as_returning()) + .get_result(conn) +} diff --git a/src/models.rs b/src/models.rs index 3733c5e..24827e4 100644 --- a/src/models.rs +++ b/src/models.rs @@ -16,7 +16,7 @@ pub struct Item { pub name: String, } -#[derive(Debug, Insertable, Deserialize)] +#[derive(Debug, Insertable, Deserialize, AsChangeset)] #[diesel(table_name = items)] #[diesel(check_for_backend(diesel::pg::Pg))] pub struct NewItem { diff --git a/templates/item_details.html b/templates/item_details.html index 6b902b8..bb1b888 100644 --- a/templates/item_details.html +++ b/templates/item_details.html @@ -6,6 +6,9 @@ SPDX-License-Identifier: AGPL-3.0-or-later {% extends "base.html" %} {% block title %}{% block page_title %}{{ item.name }}{% endblock %} – Item Details – {{ branding }}{% endblock %} +{% block page_actions %} +Edit +{% endblock %} {% block main %} diff --git a/templates/item_edit.html b/templates/item_edit.html new file mode 100644 index 0000000..13c2d6f --- /dev/null +++ b/templates/item_edit.html @@ -0,0 +1,21 @@ +{# +SPDX-FileCopyrightText: 2024 Simon Bruder + +SPDX-License-Identifier: AGPL-3.0-or-later +#} + +{% extends "base.html" %} +{% block title %}{% block page_title %}{{ item.name }}{% endblock %} – Edit Item – {{ branding }}{% endblock %} +{% block main %} +
+
+ + +
+
+ + +
+ + +{% endblock %}