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

View file

@ -8,7 +8,7 @@ use maud::html;
use sqlx::PgPool;
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 crate::manage;
use crate::models::*;
@ -56,31 +56,39 @@ async fn show(
title.push_str(" Item Details");
let mut page_actions = vec![
(PageAction {
(PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get,
target: format!("/items/add?class={}", item_class.id),
name: "Add Item".to_string(),
},
colour: Colour::Success,
}),
];
if item_class.parent.is_none() {
page_actions.push(PageAction {
page_actions.push(PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get,
target: format!("/item-classes/add?parent={}", item_class.id),
name: "Add Child".to_string(),
},
colour: Colour::Primary,
});
}
page_actions.push(PageAction {
page_actions.push(PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get,
target: format!("/item-class/{}/edit", item_class.id),
name: "Edit".to_string(),
},
colour: Colour::Warning,
});
page_actions.push(PageAction {
page_actions.push(PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Post,
target: format!("/item-class/{}/delete", item_class.id),
name: "Delete".to_string(),
},
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"),
page_title: Some(Box::new("Item Class List")),
page_actions: vec![
(PageAction {
(PageActionGroup::Button {
action: PageAction {
method: PageActionMethod::Get,
target: "/item-classes/add".to_string(),
name: "Add".to_string(),
},
colour: Colour::Success,
}),
],

View file

@ -137,23 +137,56 @@ pub enum PageActionMethod {
Post,
}
pub enum PageActionGroup {
Button {
action: PageAction,
colour: Colour,
},
Dropdown {
name: String,
actions: Vec<PageAction>,
colour: Colour,
},
}
pub struct PageAction {
pub method: PageActionMethod,
pub target: String,
pub name: String,
pub colour: Colour,
}
impl Render for PageAction {
impl Render for PageActionGroup {
fn render(&self) -> Markup {
html! {
@match self.method {
PageActionMethod::Get => a .btn.btn-primary.(self.colour.button()) href=(self.target) { (self.name) },
PageActionMethod::Post => form action=(self.target) method="POST" {
button .btn.btn-primary.(self.colour.button()) type="submit" { (self.name) }
@match self {
Self::Button { action, colour } => {
@match action.method {
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 title: Option<&'a str>,
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_js: Vec<Js<'a>>,
pub datalists: Vec<&'a Datalist>,