update
All checks were successful
ci/woodpecker/push/test Pipeline was successful

This commit is contained in:
JMARyA 2025-02-23 00:53:33 +01:00
parent 1196f00ca7
commit a79da3d797
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
11 changed files with 84 additions and 76 deletions

View file

@ -52,15 +52,12 @@ pub trait AssetRoutes {
impl AssetRoutes for rocket::Rocket<Build> {
fn mount_assets(self) -> Self {
self.mount(
"/",
routes![
crate::asset::htmx_script_route,
crate::asset::flowbite_css,
crate::asset::flowbite_js,
crate::asset::material_css,
crate::asset::material_font
],
)
self.mount("/", routes![
crate::asset::htmx_script_route,
crate::asset::flowbite_css,
crate::asset::flowbite_js,
crate::asset::material_css,
crate::asset::material_font
])
}
}

View file

@ -1,5 +1,3 @@
use maud::{Markup, Render};
use crate::auth::User;
use crate::ui::primitives::Optional;

View file

@ -4,12 +4,14 @@ use crate::ui::{UIWidget, color::UIColor};
use super::ColorCircle;
#[allow(non_snake_case)]
pub fn Indicator<C: UIColor + 'static>(color: C) -> PreEscaped<String> {
html! {
span class=(format!("flex w-3 h-3 me-3 bg-{} rounded-full", color.color_class())) {};
}
}
#[allow(non_snake_case)]
pub fn IndicatorLegend<C: UIColor + 'static>(color: C, legend: &str) -> PreEscaped<String> {
html! {
span class="flex items-center text-sm font-medium text-gray-900 dark:text-white me-3" {
@ -19,6 +21,7 @@ pub fn IndicatorLegend<C: UIColor + 'static>(color: C, legend: &str) -> PreEscap
}
}
#[allow(non_snake_case)]
pub fn NumberIndicator<T: UIWidget + 'static>(on: T, amount: u32) -> PreEscaped<String> {
html! {
div class="relative items-center max-w-fit" {
@ -28,6 +31,7 @@ pub fn NumberIndicator<T: UIWidget + 'static>(on: T, amount: u32) -> PreEscaped<
}
}
#[allow(non_snake_case)]
pub fn BadgeIndicator<C: UIColor + 'static + ColorCircle>(
color: C,
dark_color: C,

View file

@ -15,7 +15,7 @@ pub mod prelude {
pub use super::appbar::AppBar;
pub use super::avatar::{Avatar, AvatarStack};
pub use super::htmx::{ClickToLoad, InfinityScroll, LazyLoad};
pub use super::icon::MaterialIcon;
pub use super::icon::{ColoredMaterialIcon, MaterialIcon};
pub use super::indicator::{BadgeIndicator, Indicator, IndicatorLegend, NumberIndicator};
pub use super::modal::{Modal, ModalCloseButton, ModalOpenButton};
pub use super::overlay::{
@ -31,6 +31,7 @@ pub mod prelude {
Alignment, BottomNavigation, BottomNavigationTile, Classic, ClassicWidget, FetchToast,
NavBar, Position, Shell, Toast,
};
pub use super::timeline::{ActivityLog, ActivityLogElement, Timeline, TimelineElement};
pub use super::{
Accordion, Alert, Banner, Breadcrumb, Card, Carousel, CarouselMode, ColoredAlert,
ColoredSpinner, CopyText, FetchAlert, FnKey, HelpIcon, HorizontalLine, IconStepper,
@ -56,12 +57,14 @@ pub fn HorizontalLine() -> PreEscaped<String> {
}
}
#[allow(non_snake_case)]
pub fn FnKey(key: &str) -> PreEscaped<String> {
html! {
kbd class="px-2 py-1.5 text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-200 rounded-lg dark:bg-gray-600 dark:text-gray-100 dark:border-gray-500" { (key) };
}
}
#[allow(non_snake_case)]
pub fn ColoredSpinner<T: UIColor + 'static>(color: T) -> PreEscaped<String> {
let col = color.color_class();
html! {
@ -80,6 +83,7 @@ pub fn Spinner() -> PreEscaped<String> {
ColoredSpinner(super::color::Blue::_600)
}
#[allow(non_snake_case)]
pub fn CopyText(txt: &str) -> PreEscaped<String> {
let id = uuid::Uuid::new_v4().to_string();
@ -739,12 +743,14 @@ impl UIWidget for StepperWidget {
pub struct TabWidget {
pub content: Vec<(PreEscaped<String>, String, Box<dyn UIWidget>)>,
pub active: String,
}
#[allow(non_snake_case)]
pub fn Tabs() -> TabWidget {
TabWidget {
content: Vec::new(),
active: String::new(),
}
}
@ -759,6 +765,11 @@ impl TabWidget {
.push((tab.render(), id.to_string(), Box::new(body)));
self
}
pub fn active(mut self, id: &str) -> Self {
self.active = id.to_string();
self
}
}
impl Render for TabWidget {
@ -789,11 +800,11 @@ impl UIWidget for TabWidget {
@for (i, (head, id, _)) in self.content.iter().enumerate() {
li class=(if i == self.content.len() { "" } else { "me-2" }) role="presentation" {
button class="inline-block p-4 border-b-2 rounded-t-lg"
data-tabs-target=(format!("#{id}"))
data-tabs-target=(format!("#{id}"))x
type="button"
role="tab"
aria-controls=(id)
aria-selected="false" { (head) };
aria-selected=(if *id == self.active { "true" } else { "false" }) { (head) };
}
};
}

View file

@ -1,7 +1,8 @@
use maud::{PreEscaped, Render, html};
use maud::{PreEscaped, html};
use crate::ui::UIWidget;
#[allow(non_snake_case)]
pub fn ModalCloseButton<T: UIWidget + 'static>(modal: &str, inner: T) -> PreEscaped<String> {
html! {
button
@ -10,6 +11,7 @@ pub fn ModalCloseButton<T: UIWidget + 'static>(modal: &str, inner: T) -> PreEsca
}
}
#[allow(non_snake_case)]
pub fn ModalOpenButton<T: UIWidget + 'static>(modal: &str, inner: T) -> PreEscaped<String> {
html! {
button
@ -19,6 +21,7 @@ pub fn ModalOpenButton<T: UIWidget + 'static>(modal: &str, inner: T) -> PreEscap
}
}
#[allow(non_snake_case)]
pub fn Modal<T: UIWidget + 'static, E: UIWidget + 'static, F: FnOnce(String) -> E>(
title: &str,
body: T,
@ -26,32 +29,29 @@ pub fn Modal<T: UIWidget + 'static, E: UIWidget + 'static, F: FnOnce(String) ->
) -> (String, PreEscaped<String>) {
let id = uuid::Uuid::new_v4().to_string();
(
format!("modal-{id}"),
html! {
div id=(format!("modal-{id}")) tabindex="-1" aria-hidden="true" class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full" {
div class="relative p-4 w-full max-w-2xl max-h-full" {
(format!("modal-{id}"), html! {
div id=(format!("modal-{id}")) tabindex="-1" aria-hidden="true" class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full" {
div class="relative p-4 w-full max-w-2xl max-h-full" {
div class="relative bg-white rounded-lg shadow dark:bg-gray-700" {
div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600" {
h3 class="text-xl font-semibold text-gray-900 dark:text-white" { (title) }
button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-hide=(format!("modal-{id}")) {
svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14" {
path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" {};
};
span class="sr-only" { "Close modal" };
}
};
div class="p-4 md:p-5 space-y-4" {
(body)
};
div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b dark:border-gray-600" {
(footer(format!("modal-{id}")))
};
div class="relative bg-white rounded-lg shadow dark:bg-gray-700" {
div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600" {
h3 class="text-xl font-semibold text-gray-900 dark:text-white" { (title) }
button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-hide=(format!("modal-{id}")) {
svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14" {
path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" {};
};
span class="sr-only" { "Close modal" };
}
};
}};
},
)
div class="p-4 md:p-5 space-y-4" {
(body)
};
div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b dark:border-gray-600" {
(footer(format!("modal-{id}")))
};
};
}};
})
}

View file

@ -278,13 +278,10 @@ pub fn BottomNavigationTile<T: UIWidget + 'static>(
) -> ClassicWidget<LinkWidget> {
Classic(
"inline-flex flex-col items-center justify-center px-5 hover:bg-gray-50 dark:hover:bg-gray-800 group",
Link(
reference,
html! {
(icon.map(|x| x.render()).unwrap_or_default());
span class="text-sm text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500" { (text) };
},
),
Link(reference, html! {
(icon.map(|x| x.render()).unwrap_or_default());
span class="text-sm text-gray-500 dark:text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-500" { (text) };
}),
)
}

View file

@ -38,8 +38,8 @@ pub mod prelude {
MixBlendMode, Opacity, Saturate, Sepia,
};
pub use super::primitives::flex::{
AlignContent, AlignItems, Direction, DivideStyle, DivideWidth, Flex, FlexBasis, FlexGrow,
Justify, JustifyItems, Order, Strategy, Wrap,
AlignContent, AlignItems, Column, Direction, DivideStyle, DivideWidth, Flex, FlexBasis,
FlexGrow, Justify, JustifyItems, Order, Row, Strategy, Wrap,
};
pub use super::primitives::grid::{
Columns, Grid, GridAmount, GridAutoFlow, GridAutoSize, GridElementColumn, GridElementRow,
@ -53,7 +53,7 @@ pub mod prelude {
Range, Select, TextArea, TextInput, TimePicker, Toggle,
};
pub use super::primitives::link::Link;
pub use super::primitives::list::{OrderedList, UnorderedList};
pub use super::primitives::list::{HorizontalList, ListEntry, OrderedList, UnorderedList};
pub use super::primitives::margin::Margin;
pub use super::primitives::padding::Padding;
pub use super::primitives::position::{
@ -79,7 +79,9 @@ pub mod prelude {
};
pub use super::primitives::visibility::Visibility;
pub use super::primitives::width::{MaxWidth, MinWidth, Width};
pub use super::primitives::{Context, NoBrowserAppearance, Nothing, Side, Size, script};
pub use super::primitives::{
Context, NoBrowserAppearance, Nothing, Optional, Side, Size, script,
};
pub use super::wrapper::{
_2XLScreen, Hover, LargeScreen, MediumScreen, Screen, SmallScreen, XLScreen,
};

View file

@ -274,25 +274,21 @@ impl GridElement {
}
pub fn span(mut self, value: GridElementValue) -> Self {
self.1.push(format!(
"{}-span-{}",
self.2,
match value {
GridElementValue::_1 => "1",
GridElementValue::_2 => "2",
GridElementValue::_3 => "3",
GridElementValue::_4 => "4",
GridElementValue::_5 => "5",
GridElementValue::_6 => "6",
GridElementValue::_7 => "7",
GridElementValue::_8 => "8",
GridElementValue::_9 => "9",
GridElementValue::_10 => "10",
GridElementValue::_11 => "11",
GridElementValue::_12 => "12",
GridElementValue::Auto => "full",
}
));
self.1.push(format!("{}-span-{}", self.2, match value {
GridElementValue::_1 => "1",
GridElementValue::_2 => "2",
GridElementValue::_3 => "3",
GridElementValue::_4 => "4",
GridElementValue::_5 => "5",
GridElementValue::_6 => "6",
GridElementValue::_7 => "7",
GridElementValue::_8 => "8",
GridElementValue::_9 => "9",
GridElementValue::_10 => "10",
GridElementValue::_11 => "11",
GridElementValue::_12 => "12",
GridElementValue::Auto => "full",
}));
self
}

View file

@ -1,6 +1,4 @@
use std::{collections::HashMap, fmt::Write};
use maud::{Markup, PreEscaped, Render, html};
use maud::{Markup, Render, html};
use crate::{
auth::{User, csrf::CSRF},

View file

@ -93,7 +93,7 @@ impl UIWidget for TextInputWidget {
Vec::new()
}
fn render_with_class(&self, class: &str) -> Markup {
fn render_with_class(&self, _: &str) -> Markup {
let mut attrs = self.attrs.clone();
if self.password {
@ -303,6 +303,7 @@ pub struct NumberInputWidget {
buttons: bool,
}
#[allow(non_snake_case)]
pub fn NumberInput() -> NumberInputWidget {
NumberInputWidget {
inner: None,

View file

@ -116,6 +116,7 @@ impl UIWidget for ListWidget {
// TODO : List data backed list + reorderable + add + remove + crud
#[allow(non_snake_case)]
pub fn CheckIconRounded() -> PreEscaped<String> {
html! {
svg class="w-3.5 h-3.5 me-2 text-green-500 dark:text-green-400 shrink-0" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20" {
@ -124,6 +125,7 @@ pub fn CheckIconRounded() -> PreEscaped<String> {
}
}
#[allow(non_snake_case)]
pub fn CheckIconRoundedGray() -> PreEscaped<String> {
html! {
svg class="w-3.5 h-3.5 me-2 text-gray-500 dark:text-gray-400 shrink-0" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20" {
@ -132,6 +134,7 @@ pub fn CheckIconRoundedGray() -> PreEscaped<String> {
}
}
#[allow(non_snake_case)]
pub fn ListEntry<T: UIWidget + 'static, I: UIWidget + 'static>(
icon: I,
inner: T,
@ -144,6 +147,7 @@ pub fn ListEntry<T: UIWidget + 'static, I: UIWidget + 'static>(
}
}
#[allow(non_snake_case)]
pub fn CheckIcon() -> PreEscaped<String> {
html! {
svg class="shrink-0 w-3.5 h-3.5 text-green-500 dark:text-green-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 12" {