add ready state

This commit is contained in:
2023-08-29 21:34:00 +02:00
parent b38c11b86f
commit 199e4abc97
5 changed files with 404 additions and 231 deletions

View File

@@ -230,6 +230,14 @@ async fn main() -> Result<(), StartError> {
.route(
"/:id/items/:id/unpack",
get(trip_item_set_unpack).post(trip_item_set_unpack_htmx),
)
.route(
"/:id/items/:id/ready",
get(trip_item_set_ready).post(trip_item_set_ready_htmx),
)
.route(
"/:id/items/:id/unready",
get(trip_item_set_unready).post(trip_item_set_unready_htmx),
),
)
.nest(
@@ -856,6 +864,82 @@ async fn trip_item_set_unpack_htmx(
Ok((headers, trip_row(&state, trip_id, item_id).await?))
}
async fn trip_item_set_ready(
State(state): State<AppState>,
Path((trip_id, item_id)): Path<(Uuid, Uuid)>,
headers: HeaderMap,
) -> Result<Redirect, Error> {
Ok::<_, Error>(
trip_item_set_state(
&state,
trip_id,
item_id,
models::trips::TripItemStateKey::Ready,
true,
)
.await?,
)
.map(|_| -> Result<Redirect, Error> { Ok(Redirect::to(get_referer(&headers)?)) })?
}
async fn trip_item_set_ready_htmx(
State(state): State<AppState>,
Path((trip_id, item_id)): Path<(Uuid, Uuid)>,
) -> Result<impl IntoResponse, Error> {
trip_item_set_state(
&state,
trip_id,
item_id,
models::trips::TripItemStateKey::Ready,
true,
)
.await?;
let mut headers = HeaderMap::new();
headers.insert::<HeaderName>(
HtmxResponseHeaders::Trigger.into(),
HtmxEvents::TripItemEdited.into(),
);
Ok((headers, trip_row(&state, trip_id, item_id).await?))
}
async fn trip_item_set_unready(
State(state): State<AppState>,
Path((trip_id, item_id)): Path<(Uuid, Uuid)>,
headers: HeaderMap,
) -> Result<Redirect, Error> {
Ok::<_, Error>(
trip_item_set_state(
&state,
trip_id,
item_id,
models::trips::TripItemStateKey::Ready,
false,
)
.await?,
)
.map(|_| -> Result<Redirect, Error> { Ok(Redirect::to(get_referer(&headers)?)) })?
}
async fn trip_item_set_unready_htmx(
State(state): State<AppState>,
Path((trip_id, item_id)): Path<(Uuid, Uuid)>,
) -> Result<impl IntoResponse, Error> {
trip_item_set_state(
&state,
trip_id,
item_id,
models::trips::TripItemStateKey::Ready,
false,
)
.await?;
let mut headers = HeaderMap::new();
headers.insert::<HeaderName>(
HtmxResponseHeaders::Trigger.into(),
HtmxEvents::TripItemEdited.into(),
);
Ok((headers, trip_row(&state, trip_id, item_id).await?))
}
async fn trip_total_weight_htmx(
State(state): State<AppState>,
Path(trip_id): Path<Uuid>,

View File

@@ -91,6 +91,7 @@ impl std::convert::TryFrom<&str> for TripState {
pub enum TripItemStateKey {
Pick,
Pack,
Ready,
}
impl fmt::Display for TripItemStateKey {
@@ -101,6 +102,7 @@ impl fmt::Display for TripItemStateKey {
match self {
Self::Pick => "pick",
Self::Pack => "pack",
Self::Ready => "ready",
},
)
}
@@ -146,6 +148,7 @@ impl TripCategory {
inner.item_weight AS item_weight,
inner.item_is_picked AS item_is_picked,
inner.item_is_packed AS item_is_packed,
inner.item_is_ready AS item_is_ready,
inner.item_is_new AS item_is_new
FROM inventory_items_categories AS category
LEFT JOIN (
@@ -160,6 +163,7 @@ impl TripCategory {
item.weight as item_weight,
trip.pick as item_is_picked,
trip.pack as item_is_packed,
trip.ready as item_is_ready,
trip.new as item_is_new
FROM trips_items as trip
INNER JOIN inventory_items as item
@@ -209,6 +213,7 @@ impl TripCategory {
},
picked: row.item_is_picked.unwrap(),
packed: row.item_is_packed.unwrap(),
ready: row.item_is_ready.unwrap(),
new: row.item_is_new.unwrap(),
};
@@ -237,18 +242,20 @@ pub struct TripItem {
pub item: inventory::Item,
pub picked: bool,
pub packed: bool,
pub ready: bool,
pub new: bool,
}
pub(crate) struct DbTripsItemsRow {
pub(crate) picked: bool,
pub(crate) packed: bool,
pub(crate) new: bool,
pub(crate) id: String,
pub(crate) name: String,
pub(crate) weight: i64,
pub(crate) description: Option<String>,
pub(crate) category_id: String,
pub struct DbTripsItemsRow {
pub picked: bool,
pub packed: bool,
pub ready: bool,
pub new: bool,
pub id: String,
pub name: String,
pub weight: i64,
pub description: Option<String>,
pub category_id: String,
}
impl TryFrom<DbTripsItemsRow> for TripItem {
@@ -258,6 +265,7 @@ impl TryFrom<DbTripsItemsRow> for TripItem {
Ok(TripItem {
picked: row.picked,
packed: row.packed,
ready: row.ready,
new: row.new,
item: inventory::Item {
id: Uuid::try_parse(&row.id)?,
@@ -285,6 +293,7 @@ impl TripItem {
t_item.item_id AS id,
t_item.pick AS picked,
t_item.pack AS packed,
t_item.ready AS ready,
t_item.new AS new,
i_item.name AS name,
i_item.description AS description,
@@ -738,14 +747,16 @@ impl Trip {
trip_id,
pick,
pack,
ready,
new
)
VALUES (?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?)
",
item_id,
trip_id,
false,
false,
false,
mark_as_new,
)
.execute(pool)
@@ -775,6 +786,7 @@ impl Trip {
inner.item_weight AS item_weight,
inner.item_is_picked AS item_is_picked,
inner.item_is_packed AS item_is_packed,
inner.item_is_ready AS item_is_ready,
inner.item_is_new AS item_is_new
FROM inventory_items_categories AS category
LEFT JOIN (
@@ -789,6 +801,7 @@ impl Trip {
item.weight as item_weight,
trip.pick as item_is_picked,
trip.pack as item_is_packed,
trip.ready as item_is_ready,
trip.new as item_is_new
FROM trips_items as trip
INNER JOIN inventory_items as item
@@ -832,6 +845,7 @@ impl Trip {
},
picked: row.item_is_picked.unwrap(),
packed: row.item_is_packed.unwrap(),
ready: row.item_is_ready.unwrap(),
new: row.item_is_new.unwrap(),
};

View File

@@ -1032,6 +1032,7 @@ impl TripItemList {
{
thead ."bg-gray-200" {
tr ."h-10" {
th ."border" ."p-2" {}
th ."border" ."p-2" {}
th ."border" ."p-2" {}
th ."border" ."p-2" ."w-1/2" { "Name" }
@@ -1099,6 +1100,61 @@ impl TripItemListRow {
}
}
}
td
."border"
."p-0"
{
@if item.picked {
a
href={
"/trips/" (trip_id)
"/items/" (item.item.id)
"/" (if item.ready { "unready" } else { "ready" }) }
hx-post={
"/trips/" (trip_id)
"/items/" (item.item.id)
"/" (if item.ready { "unready" } else { "ready" }) }
hx-target="closest tr"
hx-swap="outerHTML"
."inline-block"
."p-2"
."m-0"
."w-full"
."justify-center"
."content-center"
."flex"
."bg-green-200"[item.ready]
."hover:bg-green-100"[!item.ready]
{
@if item.ready {
span
."mdi"
."mdi-wardrobe-outline"
."text-2xl"
{}
} @else {
span
."mdi"
."mdi-map-marker-question-outline"
."text-2xl"
{}
}
}
} @else {
div
."flex"
."justify-center"
."items-center"
{
span
."mdi"
."mdi-wardrobe-outline"
."text-2xl"
."text-gray-300"
{}
}
}
}
td
."border"
."p-0"