From cd256318631a4ecdc3e790eb6db6e19828927200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20K=C3=B6rber?= Date: Tue, 30 Apr 2024 09:04:15 +0200 Subject: [PATCH] . --- src/elements/list.rs | 150 ++++++++++++++++++++++++++---------------- src/view/inventory.rs | 34 +++++++--- 2 files changed, 119 insertions(+), 65 deletions(-) diff --git a/src/elements/list.rs b/src/elements/list.rs index fd13576..ea5679a 100644 --- a/src/elements/list.rs +++ b/src/elements/list.rs @@ -13,17 +13,10 @@ pub struct NumberWithBar { pub max_value: i64, } -pub struct Icon { - pub icon: super::Icon, - pub href: String, - pub hx_config: Option, -} - pub enum CellType<'a> { Text(&'a str), Link(Link<'a>), NumberWithBar(NumberWithBar), - Icon(Icon), } pub struct Cell<'a> { @@ -31,7 +24,7 @@ pub struct Cell<'a> { } impl<'a> Cell<'a> { - fn render(self) -> Markup { + fn render(self, is_edit: bool) -> Markup { match self.cell_type { CellType::Text(text) => html!( td @@ -98,38 +91,79 @@ impl<'a> Cell<'a> { {} } ), - CellType::Icon(icon) => html!( - td - ."border-none" - ."p-0" - .(icon.icon.background()) - .(icon.icon.background_hover()) - ."h-full" - ."w-10" - { - a - href=(icon.href) - ."aspect-square" - ."flex" - { - span - ."m-auto" - ."mdi" - ."text-xl" - .(icon.icon.mdi_class()) - {} - } - } - ), } } } +pub struct Button { + pub icon: super::Icon, + pub action: Action, + pub hx_config: Option, +} + +impl Button { + fn render(self) -> Markup { + html!( + td + ."border-none" + ."p-0" + .(self.icon.background()) + .(self.icon.background_hover()) + ."h-full" + ."w-10" + { + @match self.action { + Action::Href(href) => { + a + href=(href) + ."aspect-square" + ."flex" + { + span + ."m-auto" + ."mdi" + ."text-xl" + .(self.icon.mdi_class()) + {} + } + } + Action::Submit(form) => { + button + ."aspect-square" + ."flex" + ."w-full" + ."h-full" + type="submit" + form=(form) + { + span + ."m-auto" + ."mdi" + .(self.icon.mdi_class()) + ."text-xl" + {} + } + } + } + } + ) + } +} + +pub enum Action { + Href(String), + Submit(&'static str), +} + pub struct EditingConfig { - pub edit_href: String, + pub edit_action: Action, pub edit_hx_config: Option, - pub delete_href: String, + pub delete_action: Action, pub delete_hx_config: Option, + pub save_action: Action, + pub save_hx_config: Option, + pub cancel_action: Action, + pub cancel_hx_config: Option, } pub trait Row { @@ -141,10 +175,6 @@ pub trait Row { false } - fn editing_config(&self) -> Option { - None - } - fn cells(&self) -> Vec; } @@ -203,6 +233,7 @@ where tbody { @for row in self.rows.into_iter() { @let active = row.is_active(); + @let is_edit = row.is_edit(); tr ."h-10" ."hover:bg-gray-100" @@ -213,26 +244,35 @@ where ."font-bold"[active] { @for cell in row.cells() { - (cell.render()) + (cell.render(is_edit)) } - } - @if let Some(ref edit_config) = self.editing_config { - @let edit_config = (*edit_config)(row); - (Cell { - cell_type: CellType::Icon(Icon { - icon: super::Icon::Edit, - href: edit_config.edit_href, - hx_config: edit_config.edit_hx_config, - }), - }.render()) - (Cell { - cell_type: CellType::Icon(Icon { - icon: super::Icon::Delete, - href: edit_config.delete_href, - hx_config: edit_config.delete_hx_config, - }), - }.render()) + @if let Some(ref edit_config) = self.editing_config { + @let edit_config = (*edit_config)(row); + @if is_edit { + (Button { + icon: super::Icon::Save, + action: edit_config.save_action, + hx_config: edit_config.save_hx_config, + }.render()) + (Button { + icon: super::Icon::Cancel, + action: edit_config.cancel_action, + hx_config: edit_config.cancel_hx_config, + }.render()) + } @else { + (Button { + icon: super::Icon::Edit, + action: edit_config.edit_action, + hx_config: edit_config.edit_hx_config, + } .render()) + (Button { + icon: super::Icon::Delete, + action: edit_config.delete_action, + hx_config: edit_config.delete_hx_config, + }.render()) + } + } } } } diff --git a/src/view/inventory.rs b/src/view/inventory.rs index deef3f0..dfc4e8e 100644 --- a/src/view/inventory.rs +++ b/src/view/inventory.rs @@ -5,7 +5,7 @@ use crate::ClientState; use crate::{ elements::{ self, - list::{self, List}, + list::{self, Action, List}, }, models::inventory::Item, }; @@ -142,6 +142,7 @@ impl InventoryItemList { struct Row<'a> { item: &'a Item, biggest_item_weight: i64, + edit_item_id: Option, } impl<'a> list::Row for Row<'a> { @@ -162,21 +163,33 @@ impl InventoryItemList { }, ] } - } - fn editing_config(row: Row) -> list::EditingConfig { - list::EditingConfig { - edit_href: format!("?edit_item={id}", id = row.item.id), - edit_hx_config: None, - - delete_href: format!("/inventory/item/{id}/delete", id = row.item.id), - delete_hx_config: None, + fn is_edit(&self) -> bool { + self.edit_item_id.map_or(false, |id| id == self.item.id) } } let table = list::List { id: None, - editing_config: Some(Box::new(editing_config)), + editing_config: Some(Box::new(|row: Row| list::EditingConfig { + edit_action: Action::Href(format!("?edit_item={id}", id = row.item.id)), + edit_hx_config: None, + + delete_action: Action::Href(format!( + "/inventory/item/{id}/delete", + id = row.item.id + )), + delete_hx_config: None, + + save_action: Action::Submit("edit-item"), + save_hx_config: None, + + cancel_action: Action::Href(format!( + "/inventory/item/{id}/cancel", + id = row.item.id + )), + cancel_hx_config: None, + })), header: list::Header { cells: vec![ Some(list::HeaderCell { title: "Name" }), @@ -188,6 +201,7 @@ impl InventoryItemList { .map(|item| Row { item, biggest_item_weight, + edit_item_id, }) .collect(), };