Generalize PageAction to allow dropdown

This commit is contained in:
Simon Bruder 2024-07-14 16:37:07 +02:00
parent a528b9fe44
commit b15a2e2885
Signed by: simon
GPG key ID: 347FF8699CDA0776
4 changed files with 97 additions and 46 deletions

View file

@ -10,7 +10,7 @@ use maud::html;
use sqlx::PgPool; use sqlx::PgPool;
use uuid::Uuid; use uuid::Uuid;
use super::templates::helpers::{Colour, ItemName, PageAction, PageActionMethod}; use super::templates::helpers::{Colour, ItemName, PageAction, PageActionGroup, PageActionMethod};
use super::templates::{self, datalist, forms, TemplateConfig}; use super::templates::{self, datalist, forms, TemplateConfig};
use crate::manage; use crate::manage;
use crate::models::*; use crate::models::*;
@ -74,22 +74,28 @@ async fn show(
title: Some(&title), title: Some(&title),
page_title: Some(Box::new(item_name.clone())), page_title: Some(Box::new(item_name.clone())),
page_actions: vec![ page_actions: vec![
(PageAction { (PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get, method: PageActionMethod::Get,
target: format!("/items/add?parent={}", item.id), target: format!("/items/add?parent={}", item.id),
name: "Add Child".to_string(), name: "Add Child".to_string(),
},
colour: Colour::Success, colour: Colour::Success,
}), }),
(PageAction { (PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get, method: PageActionMethod::Get,
target: format!("/item/{}/edit", item.id), target: format!("/item/{}/edit", item.id),
name: "Edit".to_string(), name: "Edit".to_string(),
},
colour: Colour::Warning, colour: Colour::Warning,
}), }),
(PageAction { (PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Post, method: PageActionMethod::Post,
target: format!("/item/{}/delete", item.id), target: format!("/item/{}/delete", item.id),
name: "Delete".to_string(), name: "Delete".to_string(),
},
colour: Colour::Danger, colour: Colour::Danger,
}), }),
], ],
@ -201,10 +207,12 @@ async fn list(pool: web::Data<PgPool>, user: Identity) -> actix_web::Result<impl
title: Some("Item List"), title: Some("Item List"),
page_title: Some(Box::new("Item List")), page_title: Some(Box::new("Item List")),
page_actions: vec![ page_actions: vec![
(PageAction { (PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get, method: PageActionMethod::Get,
target: "/items/add".to_string(), target: "/items/add".to_string(),
name: "Add".to_string(), name: "Add".to_string(),
},
colour: Colour::Success, colour: Colour::Success,
}), }),
], ],

View file

@ -8,7 +8,7 @@ use maud::html;
use sqlx::PgPool; use sqlx::PgPool;
use uuid::Uuid; use uuid::Uuid;
use super::templates::helpers::{Colour, ItemName, PageAction, PageActionMethod}; use super::templates::helpers::{Colour, ItemName, PageAction, PageActionGroup, PageActionMethod};
use super::templates::{self, datalist, forms, TemplateConfig}; use super::templates::{self, datalist, forms, TemplateConfig};
use crate::manage; use crate::manage;
use crate::models::*; use crate::models::*;
@ -56,31 +56,39 @@ async fn show(
title.push_str(" Item Details"); title.push_str(" Item Details");
let mut page_actions = vec![ let mut page_actions = vec![
(PageAction { (PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get, method: PageActionMethod::Get,
target: format!("/items/add?class={}", item_class.id), target: format!("/items/add?class={}", item_class.id),
name: "Add Item".to_string(), name: "Add Item".to_string(),
},
colour: Colour::Success, colour: Colour::Success,
}), }),
]; ];
if item_class.parent.is_none() { if item_class.parent.is_none() {
page_actions.push(PageAction { page_actions.push(PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get, method: PageActionMethod::Get,
target: format!("/item-classes/add?parent={}", item_class.id), target: format!("/item-classes/add?parent={}", item_class.id),
name: "Add Child".to_string(), name: "Add Child".to_string(),
},
colour: Colour::Primary, colour: Colour::Primary,
}); });
} }
page_actions.push(PageAction { page_actions.push(PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get, method: PageActionMethod::Get,
target: format!("/item-class/{}/edit", item_class.id), target: format!("/item-class/{}/edit", item_class.id),
name: "Edit".to_string(), name: "Edit".to_string(),
},
colour: Colour::Warning, colour: Colour::Warning,
}); });
page_actions.push(PageAction { page_actions.push(PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Post, method: PageActionMethod::Post,
target: format!("/item-class/{}/delete", item_class.id), target: format!("/item-class/{}/delete", item_class.id),
name: "Delete".to_string(), name: "Delete".to_string(),
},
colour: Colour::Danger, colour: Colour::Danger,
}); });
@ -159,10 +167,12 @@ async fn list(pool: web::Data<PgPool>, user: Identity) -> actix_web::Result<impl
title: Some("Item Class List"), title: Some("Item Class List"),
page_title: Some(Box::new("Item Class List")), page_title: Some(Box::new("Item Class List")),
page_actions: vec![ page_actions: vec![
(PageAction { (PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get, method: PageActionMethod::Get,
target: "/item-classes/add".to_string(), target: "/item-classes/add".to_string(),
name: "Add".to_string(), name: "Add".to_string(),
},
colour: Colour::Success, colour: Colour::Success,
}), }),
], ],

View file

@ -137,23 +137,56 @@ pub enum PageActionMethod {
Post, Post,
} }
pub enum PageActionGroup {
Button {
action: PageAction,
colour: Colour,
},
Dropdown {
name: String,
actions: Vec<PageAction>,
colour: Colour,
},
}
pub struct PageAction { pub struct PageAction {
pub method: PageActionMethod, pub method: PageActionMethod,
pub target: String, pub target: String,
pub name: String, pub name: String,
pub colour: Colour,
} }
impl Render for PageAction { impl Render for PageActionGroup {
fn render(&self) -> Markup { fn render(&self) -> Markup {
html! { html! {
@match self.method { @match self {
PageActionMethod::Get => a .btn.btn-primary.(self.colour.button()) href=(self.target) { (self.name) }, Self::Button { action, colour } => {
PageActionMethod::Post => form action=(self.target) method="POST" { @match action.method {
button .btn.btn-primary.(self.colour.button()) type="submit" { (self.name) } PageActionMethod::Get => a .btn.btn-primary.(colour.button()) href=(action.target) { (action.name) },
PageActionMethod::Post => form action=(action.target) method="POST" {
button .btn.btn-primary.(colour.button()) type="submit" { (action.name) }
}, },
} }
} }
Self::Dropdown { name, actions, colour } => {
div .btn-group {
button .btn.(colour.button()).dropdown-toggle type="button" data-bs-toggle="dropdown" { (name) }
ul .dropdown-menu {
@for action in actions {
li {
@match action.method {
PageActionMethod::Get => a .dropdown-item href=(action.target) { (action.name) },
PageActionMethod::Post => form action=(action.target) method="POST" {
button .dropdown-item type="submit" { (action.name) }
},
}
}
}
}
}
}
}
}
} }
} }

View file

@ -69,7 +69,7 @@ pub struct TemplateConfig<'a> {
pub path: &'a str, pub path: &'a str,
pub title: Option<&'a str>, pub title: Option<&'a str>,
pub page_title: Option<Box<dyn Render>>, pub page_title: Option<Box<dyn Render>>,
pub page_actions: Vec<PageAction>, pub page_actions: Vec<PageActionGroup>,
pub extra_css: Vec<Css<'a>>, pub extra_css: Vec<Css<'a>>,
pub extra_js: Vec<Js<'a>>, pub extra_js: Vec<Js<'a>>,
pub datalists: Vec<&'a Datalist>, pub datalists: Vec<&'a Datalist>,