Add item update functionality

This commit is contained in:
Simon Bruder 2024-07-03 18:47:29 +02:00
parent ac70a4c119
commit f0037b13f8
Signed by: simon
GPG key ID: 347FF8699CDA0776
6 changed files with 94 additions and 4 deletions

View file

@ -2,7 +2,7 @@
// //
// SPDX-License-Identifier: AGPL-3.0-or-later // 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 uuid::Uuid;
use crate::manage; use crate::manage;
@ -10,7 +10,10 @@ use crate::models::*;
use crate::DbPool; use crate::DbPool;
pub fn config(cfg: &mut web::ServiceConfig) { 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")] #[put("/item")]
@ -50,3 +53,20 @@ async fn show(pool: web::Data<DbPool>, path: web::Path<Uuid>) -> actix_web::Resu
Ok(HttpResponse::Ok().json(item)) Ok(HttpResponse::Ok().json(item))
} }
#[post("/item/{id}")]
async fn update(
pool: web::Data<DbPool>,
path: web::Path<Uuid>,
new_item: web::Json<NewItem>,
) -> actix_web::Result<impl Responder> {
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))
}

View file

@ -14,7 +14,9 @@ pub fn config(cfg: &mut web::ServiceConfig) {
cfg.service(show_item) cfg.service(show_item)
.service(list_items) .service(list_items)
.service(add_item) .service(add_item)
.service(add_item_post); .service(add_item_post)
.service(edit_item)
.service(edit_item_post);
} }
#[derive(Template)] #[derive(Template)]
@ -80,3 +82,40 @@ async fn add_item_post(
.map_err(error::ErrorInternalServerError)?; .map_err(error::ErrorInternalServerError)?;
Ok(web::Redirect::to("/item/".to_owned() + &item.id.to_string()).see_other()) 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<DbPool>,
path: web::Path<Uuid>,
) -> actix_web::Result<impl Responder> {
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<DbPool>,
path: web::Path<Uuid>,
data: web::Form<NewItem>,
) -> actix_web::Result<impl Responder> {
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())
}

View file

@ -25,3 +25,10 @@ pub fn get(conn: &mut PgConnection, id: Uuid) -> Result<Item, diesel::result::Er
pub fn get_all(conn: &mut PgConnection) -> Result<Vec<Item>, diesel::result::Error> { pub fn get_all(conn: &mut PgConnection) -> Result<Vec<Item>, diesel::result::Error> {
schema::items::table.select(Item::as_select()).load(conn) schema::items::table.select(Item::as_select()).load(conn)
} }
pub fn update(conn: &mut PgConnection, id: Uuid, modified_item: NewItem) -> Result<Item, diesel::result::Error> {
diesel::update(schema::items::table.filter(schema::items::id.eq(id)))
.set(modified_item)
.returning(Item::as_returning())
.get_result(conn)
}

View file

@ -16,7 +16,7 @@ pub struct Item {
pub name: String, pub name: String,
} }
#[derive(Debug, Insertable, Deserialize)] #[derive(Debug, Insertable, Deserialize, AsChangeset)]
#[diesel(table_name = items)] #[diesel(table_name = items)]
#[diesel(check_for_backend(diesel::pg::Pg))] #[diesel(check_for_backend(diesel::pg::Pg))]
pub struct NewItem { pub struct NewItem {

View file

@ -6,6 +6,9 @@ SPDX-License-Identifier: AGPL-3.0-or-later
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}{% block page_title %}{{ item.name }}{% endblock %} Item Details {{ branding }}{% endblock %} {% block title %}{% block page_title %}{{ item.name }}{% endblock %} Item Details {{ branding }}{% endblock %}
{% block page_actions %}
<a class="btn btn-warning" href="/item/{{ item.id }}/edit">Edit</a>
{% endblock %}
{% block main %} {% block main %}
<table class="table"> <table class="table">
<tbody> <tbody>

21
templates/item_edit.html Normal file
View file

@ -0,0 +1,21 @@
{#
SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
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 %}
<form method="POST">
<div class="mb-3">
<label for="uuid" class="form-label">UUID</label>
<input type="text" class="form-control" id="uuid" disabled required value="{{ item.id }}">
</div>
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" required value="{{ item.name }}">
</div>
<button type="submit" class="btn btn-primary">Edit</button>
</form>
{% endblock %}