Decouple item (class) form from model
This makes it possible to introduce form-only fields without affecting the model.
This commit is contained in:
parent
e3cb717087
commit
7defae7931
|
@ -7,6 +7,7 @@ use std::collections::HashMap;
|
||||||
use actix_identity::Identity;
|
use actix_identity::Identity;
|
||||||
use actix_web::{error, get, post, web, Responder};
|
use actix_web::{error, get, post, web, Responder};
|
||||||
use maud::html;
|
use maud::html;
|
||||||
|
use serde::Deserialize;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -263,10 +264,28 @@ async fn list(pool: web::Data<PgPool>, user: Identity) -> actix_web::Result<impl
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct NewItemForm {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub parent: Option<Uuid>,
|
||||||
|
pub class: Uuid,
|
||||||
|
pub original_packaging: Option<Uuid>,
|
||||||
|
pub description: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct NewItemFormPrefilled {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub parent: Option<Uuid>,
|
||||||
|
pub class: Option<Uuid>,
|
||||||
|
pub original_packaging: Option<Uuid>,
|
||||||
|
pub description: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/items/add")]
|
#[get("/items/add")]
|
||||||
async fn add_form(
|
async fn add_form(
|
||||||
pool: web::Data<PgPool>,
|
pool: web::Data<PgPool>,
|
||||||
form: web::Query<NewItemForm>,
|
form: web::Query<NewItemFormPrefilled>,
|
||||||
user: Identity,
|
user: Identity,
|
||||||
) -> actix_web::Result<impl Responder> {
|
) -> actix_web::Result<impl Responder> {
|
||||||
let datalist_items = datalist::items(&pool)
|
let datalist_items = datalist::items(&pool)
|
||||||
|
@ -340,13 +359,23 @@ async fn add_form(
|
||||||
|
|
||||||
#[post("/items/add")]
|
#[post("/items/add")]
|
||||||
async fn add_post(
|
async fn add_post(
|
||||||
data: web::Form<NewItem>,
|
data: web::Form<NewItemForm>,
|
||||||
pool: web::Data<PgPool>,
|
pool: web::Data<PgPool>,
|
||||||
_user: Identity,
|
_user: Identity,
|
||||||
) -> actix_web::Result<impl Responder> {
|
) -> actix_web::Result<impl Responder> {
|
||||||
let item = manage::item::add(&pool, data.into_inner())
|
let data = data.into_inner();
|
||||||
.await
|
let item = manage::item::add(
|
||||||
.map_err(error::ErrorInternalServerError)?;
|
&pool,
|
||||||
|
NewItem {
|
||||||
|
name: data.name,
|
||||||
|
class: data.class,
|
||||||
|
parent: data.parent,
|
||||||
|
original_packaging: data.original_packaging,
|
||||||
|
description: data.description,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.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())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
use actix_identity::Identity;
|
use actix_identity::Identity;
|
||||||
use actix_web::{error, get, post, web, Responder};
|
use actix_web::{error, get, post, web, Responder};
|
||||||
use maud::html;
|
use maud::html;
|
||||||
|
use serde::Deserialize;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -230,10 +231,24 @@ async fn list(pool: web::Data<PgPool>, user: Identity) -> actix_web::Result<impl
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct NewItemClassForm {
|
||||||
|
pub name: String,
|
||||||
|
pub parent: Option<Uuid>,
|
||||||
|
pub description: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct NewItemClassFormPrefilled {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub parent: Option<Uuid>,
|
||||||
|
pub description: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/item-classes/add")]
|
#[get("/item-classes/add")]
|
||||||
async fn add_form(
|
async fn add_form(
|
||||||
pool: web::Data<PgPool>,
|
pool: web::Data<PgPool>,
|
||||||
form: web::Query<NewItemClassForm>,
|
form: web::Query<NewItemClassFormPrefilled>,
|
||||||
user: Identity,
|
user: Identity,
|
||||||
) -> actix_web::Result<impl Responder> {
|
) -> actix_web::Result<impl Responder> {
|
||||||
let datalist_item_classes = datalist::item_classes(&pool)
|
let datalist_item_classes = datalist::item_classes(&pool)
|
||||||
|
@ -285,13 +300,21 @@ async fn add_form(
|
||||||
|
|
||||||
#[post("/item-classes/add")]
|
#[post("/item-classes/add")]
|
||||||
async fn add(
|
async fn add(
|
||||||
data: web::Form<NewItemClass>,
|
data: web::Form<NewItemClassForm>,
|
||||||
pool: web::Data<PgPool>,
|
pool: web::Data<PgPool>,
|
||||||
_user: Identity,
|
_user: Identity,
|
||||||
) -> actix_web::Result<impl Responder> {
|
) -> actix_web::Result<impl Responder> {
|
||||||
let item = manage::item_class::add(&pool, data.into_inner())
|
let data = data.into_inner();
|
||||||
.await
|
let item = manage::item_class::add(
|
||||||
.map_err(error::ErrorInternalServerError)?;
|
&pool,
|
||||||
|
NewItemClass {
|
||||||
|
name: data.name,
|
||||||
|
parent: data.parent,
|
||||||
|
description: data.description,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(error::ErrorInternalServerError)?;
|
||||||
Ok(web::Redirect::to("/item-class/".to_owned() + &item.id.to_string()).see_other())
|
Ok(web::Redirect::to("/item-class/".to_owned() + &item.id.to_string()).see_other())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,21 +36,6 @@ pub struct NewItem {
|
||||||
pub description: String,
|
pub description: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Its structure is not how it could ideally be
|
|
||||||
// (doubly nested Options where the original struct already has an Option>)
|
|
||||||
// because the intended usage (in a GET request parameter) does not allow such fine-grained types.
|
|
||||||
// TODO: this can be automated from NewItem with derive macro
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct NewItemForm {
|
|
||||||
#[serde(default)]
|
|
||||||
pub name: Option<String>,
|
|
||||||
#[serde(default)]
|
|
||||||
pub parent: Option<Uuid>,
|
|
||||||
pub class: Option<Uuid>,
|
|
||||||
pub original_packaging: Option<Uuid>,
|
|
||||||
pub description: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
pub struct ItemClass {
|
pub struct ItemClass {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
|
@ -69,12 +54,3 @@ pub struct NewItemClass {
|
||||||
pub parent: Option<Uuid>,
|
pub parent: Option<Uuid>,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// see NewItemForm
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct NewItemClassForm {
|
|
||||||
pub name: Option<String>,
|
|
||||||
#[serde(default)]
|
|
||||||
pub parent: Option<Uuid>,
|
|
||||||
pub description: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue