Simmplify

This commit is contained in:
Adrian Woźniak 2021-04-19 10:21:20 +02:00
parent e3e55acd54
commit 1b5ac3c9c3
43 changed files with 582 additions and 739 deletions

View File

@ -1,7 +1,6 @@
use seed::prelude::*; use seed::prelude::*;
use seed::*; use seed::*;
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
#[derive(Debug)] #[derive(Debug)]
@ -75,10 +74,3 @@ impl<'l> Default for StyledAvatar<'l> {
} }
} }
} }
impl<'l> ToNode for StyledAvatar<'l> {
#[inline(always)]
fn into_node(self) -> Node<Msg> {
self.render()
}
}

View File

@ -1,7 +1,6 @@
use seed::prelude::*; use seed::prelude::*;
use seed::*; use seed::*;
use crate::shared::ToNode;
use crate::{ButtonId, Msg}; use crate::{ButtonId, Msg};
#[allow(dead_code)] #[allow(dead_code)]
@ -45,16 +44,13 @@ pub struct StyledButton<'l> {
} }
impl<'l> StyledButton<'l> { impl<'l> StyledButton<'l> {
pub fn secondary_with_text_and_icon<I>(text: &'l str, icon: I) -> Self pub fn secondary_with_text_and_icon(text: &'l str, icon: Node<Msg>) -> Self {
where
I: ToNode,
{
Self { Self {
variant: ButtonVariant::Secondary, variant: ButtonVariant::Secondary,
disabled: false, disabled: false,
active: false, active: false,
text: Some(text), text: Some(text),
icon: Some(icon.into_node()), icon: Some(icon),
on_click: None, on_click: None,
children: vec![], children: vec![],
class_list: "", class_list: "",
@ -128,10 +124,3 @@ impl<'l> StyledButton<'l> {
] ]
} }
} }
impl<'l> ToNode for StyledButton<'l> {
#[inline(always)]
fn into_node(self) -> Node<Msg> {
self.render()
}
}

View File

@ -1,7 +1,6 @@
use seed::prelude::*; use seed::prelude::*;
use seed::*; use seed::*;
use crate::shared::ToNode;
use crate::{FieldId, Msg}; use crate::{FieldId, Msg};
#[derive(Debug)] #[derive(Debug)]
@ -121,12 +120,3 @@ where
] ]
} }
} }
impl<'l, Options> ToNode for StyledCheckbox<'l, Options>
where
Options: Iterator<Item = ChildBuilder<'l>>,
{
fn into_node(self) -> Node<Msg> {
self.render()
}
}

View File

@ -3,7 +3,6 @@ use seed::{EventHandler, *};
use crate::components::styled_button::{ButtonVariant, StyledButton}; use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_modal::StyledModal; use crate::components::styled_modal::StyledModal;
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
const TITLE: &str = "Warning"; const TITLE: &str = "Warning";
@ -63,7 +62,7 @@ impl<'l> StyledConfirmModal<'l> {
class_list: "confirmModal", class_list: "confirmModal",
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
} }
@ -78,9 +77,3 @@ impl<'l> Default for StyledConfirmModal<'l> {
} }
} }
} }
impl<'l> ToNode for StyledConfirmModal<'l> {
fn into_node(self) -> Node<Msg> {
self.render()
}
}

View File

@ -6,9 +6,8 @@ use seed::prelude::*;
use seed::*; use seed::*;
use crate::components::styled_button::{ButtonVariant, StyledButton}; use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_icon::Icon; use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_tooltip::{StyledTooltip, TooltipVariant}; use crate::components::styled_tooltip::{StyledTooltip, TooltipVariant};
use crate::shared::ToNode;
use crate::{FieldId, Msg}; use crate::{FieldId, Msg};
#[derive(Debug)] #[derive(Debug)]
@ -134,11 +133,11 @@ impl StyledDateTimeInput {
}); });
StyledButton { StyledButton {
on_click: Some(on_click_left), on_click: Some(on_click_left),
icon: Some(Icon::DoubleLeft.into_node()), icon: Some(StyledIcon::from(Icon::DoubleLeft).render()),
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
..Default::default() ..Default::default()
} }
.into_node() .render()
}; };
let right_action = { let right_action = {
let field_id = self.field_id.clone(); let field_id = self.field_id.clone();
@ -161,7 +160,7 @@ impl StyledDateTimeInput {
}); });
StyledButton { StyledButton {
on_click: Some(on_click_right), on_click: Some(on_click_right),
icon: Some(Icon::DoubleRight.into_node()), icon: Some(StyledIcon::from(Icon::DoubleRight).render()),
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
..Default::default() ..Default::default()
} }
@ -256,12 +255,6 @@ impl StyledDateTimeInput {
} }
} }
impl ToNode for StyledDateTimeInput {
fn into_node(self) -> Node<Msg> {
self.render()
}
}
pub struct DayCell<'l> { pub struct DayCell<'l> {
field_id: &'l FieldId, field_id: &'l FieldId,
timestamp: &'l NaiveDateTime, timestamp: &'l NaiveDateTime,

View File

@ -2,7 +2,6 @@ use seed::prelude::*;
use seed::*; use seed::*;
use crate::components::styled_textarea::StyledTextarea; use crate::components::styled_textarea::StyledTextarea;
use crate::shared::ToNode;
use crate::{FieldChange, FieldId, Msg}; use crate::{FieldChange, FieldId, Msg};
#[derive(Debug, Clone, PartialOrd, PartialEq, Hash)] #[derive(Debug, Clone, PartialOrd, PartialEq, Hash)]
@ -79,7 +78,7 @@ impl<'l> StyledEditor<'l> {
placeholder: "", placeholder: "",
disable_auto_resize: false, disable_auto_resize: false,
} }
.into_node(); .render();
div![ div![
C!["styledEditor"], C!["styledEditor"],
@ -119,13 +118,6 @@ impl<'l> StyledEditor<'l> {
} }
} }
impl<'l> ToNode for StyledEditor<'l> {
#[inline]
fn into_node(self) -> Node<Msg> {
self.render()
}
}
#[inline] #[inline]
fn click_handler(field_id: FieldId, new_mode: Mode) -> EventHandler<Msg> { fn click_handler(field_id: FieldId, new_mode: Mode) -> EventHandler<Msg> {
mouse_ev(Ev::Click, move |ev| { mouse_ev(Ev::Click, move |ev| {

View File

@ -1,7 +1,6 @@
use seed::prelude::*; use seed::prelude::*;
use seed::*; use seed::*;
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
#[derive(Debug)] #[derive(Debug)]
@ -41,9 +40,3 @@ impl<'l> StyledField<'l> {
] ]
} }
} }
impl<'l> ToNode for StyledField<'l> {
fn into_node(self) -> Node<Msg> {
self.render()
}
}

View File

@ -1,7 +1,6 @@
use seed::prelude::*; use seed::prelude::*;
use seed::*; use seed::*;
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
@ -30,10 +29,3 @@ impl<'l> StyledForm<'l> {
] ]
} }
} }
impl<'l> ToNode for StyledForm<'l> {
#[inline]
fn into_node(self) -> Node<Msg> {
self.render()
}
}

View File

@ -1,10 +1,7 @@
use std::borrow::Cow;
use jirs_data::{IssuePriority, IssueType}; use jirs_data::{IssuePriority, IssueType};
use seed::prelude::*; use seed::prelude::*;
use seed::*; use seed::*;
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
#[allow(dead_code)] #[allow(dead_code)]
@ -102,14 +99,16 @@ pub enum Icon {
} }
impl Icon { impl Icon {
pub fn to_color(&self) -> Option<String> { #[inline(always)]
pub fn to_color(self) -> Option<String> {
match self { match self {
Icon::Bug | Icon::Task | Icon::Story | Icon::Epic => Some(format!("var(--{})", self)), Icon::Bug | Icon::Task | Icon::Story | Icon::Epic => Some(format!("var(--{})", self)),
_ => None, _ => None,
} }
} }
pub fn to_str<'l>(&self) -> &'l str { #[inline(always)]
pub fn to_str<'l>(self) -> &'l str {
match self { match self {
Icon::Bug => "bug", Icon::Bug => "bug",
Icon::Stopwatch => "stopwatch", Icon::Stopwatch => "stopwatch",
@ -209,6 +208,7 @@ impl std::fmt::Display for Icon {
} }
impl From<IssueType> for Icon { impl From<IssueType> for Icon {
#[inline(always)]
fn from(t: IssueType) -> Self { fn from(t: IssueType) -> Self {
use IssueType::*; use IssueType::*;
match t { match t {
@ -220,6 +220,7 @@ impl From<IssueType> for Icon {
} }
impl From<IssuePriority> for Icon { impl From<IssuePriority> for Icon {
#[inline(always)]
fn from(t: IssuePriority) -> Self { fn from(t: IssuePriority) -> Self {
match t { match t {
IssuePriority::Highest => Icon::ArrowUp, IssuePriority::Highest => Icon::ArrowUp,
@ -232,6 +233,7 @@ impl From<IssuePriority> for Icon {
} }
impl<'l> From<Icon> for StyledIcon<'l> { impl<'l> From<Icon> for StyledIcon<'l> {
#[inline(always)]
fn from(icon: Icon) -> StyledIcon<'l> { fn from(icon: Icon) -> StyledIcon<'l> {
StyledIcon { StyledIcon {
icon, icon,
@ -240,42 +242,31 @@ impl<'l> From<Icon> for StyledIcon<'l> {
} }
} }
impl ToNode for Icon {
fn into_node(self) -> Node<Msg> {
let styled: StyledIcon = self.into();
styled.into_node()
}
}
pub struct StyledIcon<'l> { pub struct StyledIcon<'l> {
pub icon: Icon, pub icon: Icon,
pub size: Option<i32>, pub size: Option<i32>,
pub class_list: &'l str, pub class_list: &'l str,
pub style_list: Vec<Cow<'l, str>>, pub style_list: &'l str,
pub color: Option<&'l str>, pub color: Option<&'l str>,
pub on_click: Option<EventHandler<Msg>>, pub on_click: Option<EventHandler<Msg>>,
} }
impl<'l> Default for StyledIcon<'l> { impl<'l> Default for StyledIcon<'l> {
#[inline(always)]
fn default() -> Self { fn default() -> Self {
Self { Self {
icon: Icon::Stopwatch, icon: Icon::Stopwatch,
size: None, size: None,
class_list: "", class_list: "",
style_list: vec![], style_list: "",
color: None, color: None,
on_click: None, on_click: None,
} }
} }
} }
impl<'l> ToNode for StyledIcon<'l> {
fn into_node(self) -> Node<Msg> {
self.render()
}
}
impl<'l> StyledIcon<'l> { impl<'l> StyledIcon<'l> {
#[inline(always)]
pub fn render(self) -> Node<Msg> { pub fn render(self) -> Node<Msg> {
let StyledIcon { let StyledIcon {
icon, icon,
@ -301,19 +292,6 @@ impl<'l> StyledIcon<'l> {
.flatten() .flatten()
.collect(); .collect();
let style_list = style_list.into_iter().fold("".to_string(), |mut mem, s| {
match s {
Cow::Borrowed(s) => {
mem.push_str(s);
}
Cow::Owned(owned) => {
mem.push_str(owned.as_str());
}
}
mem.push(';');
mem
});
i![ i![
C!["styledIcon", class_list, icon.to_str()], C!["styledIcon", class_list, icon.to_str()],
styles, styles,

View File

@ -2,7 +2,6 @@ use seed::prelude::*;
use seed::*; use seed::*;
use web_sys::File; use web_sys::File;
use crate::shared::ToNode;
use crate::{FieldId, Msg}; use crate::{FieldId, Msg};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -37,13 +36,8 @@ pub struct StyledImageInput<'l> {
pub url: Option<&'l str>, pub url: Option<&'l str>,
} }
impl<'l> ToNode for StyledImageInput<'l> {
fn into_node(self) -> Node<Msg> {
self.render()
}
}
impl<'l> StyledImageInput<'l> { impl<'l> StyledImageInput<'l> {
#[inline(always)]
pub fn render(self) -> Node<Msg> { pub fn render(self) -> Node<Msg> {
let StyledImageInput { let StyledImageInput {
id, id,

View File

@ -2,7 +2,6 @@ use seed::prelude::*;
use seed::*; use seed::*;
use crate::components::styled_icon::{Icon, StyledIcon}; use crate::components::styled_icon::{Icon, StyledIcon};
use crate::shared::ToNode;
use crate::{FieldId, Msg}; use crate::{FieldId, Msg};
#[derive(Clone, Debug, PartialOrd, PartialEq)] #[derive(Clone, Debug, PartialOrd, PartialEq)]
@ -160,13 +159,6 @@ impl<'l, 'm: 'l> StyledInput<'l, 'm> {
} }
} }
impl<'l, 'm: 'l> ToNode for StyledInput<'l, 'm> {
#[inline]
fn into_node(self) -> Node<Msg> {
self.render()
}
}
impl<'l, 'm: 'l> StyledInput<'l, 'm> { impl<'l, 'm: 'l> StyledInput<'l, 'm> {
pub fn render(self) -> Node<Msg> { pub fn render(self) -> Node<Msg> {
let StyledInput { let StyledInput {

View File

@ -3,7 +3,6 @@ use std::str::FromStr;
use seed::prelude::*; use seed::prelude::*;
use seed::*; use seed::*;
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
pub struct StyledLink<'l> { pub struct StyledLink<'l> {
@ -12,12 +11,6 @@ pub struct StyledLink<'l> {
pub href: &'l str, pub href: &'l str,
} }
impl<'l> ToNode for StyledLink<'l> {
fn into_node(self) -> Node<Msg> {
self.render()
}
}
impl<'l> StyledLink<'l> { impl<'l> StyledLink<'l> {
pub fn render(self) -> Node<Msg> { pub fn render(self) -> Node<Msg> {
let StyledLink { let StyledLink {
@ -43,7 +36,7 @@ impl<'l> StyledLink<'l> {
a![ a![
C!["styledLink", class_list], C!["styledLink", class_list],
attrs![ At::Href => href, ], attrs![ At::Href => href ],
on_click, on_click,
children, children,
] ]

View File

@ -2,7 +2,6 @@ use seed::prelude::*;
use seed::*; use seed::*;
use crate::components::styled_icon::{Icon, StyledIcon}; use crate::components::styled_icon::{Icon, StyledIcon};
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
#[allow(dead_code)] #[allow(dead_code)]
@ -61,12 +60,6 @@ impl<'l> StyledModal<'l> {
} }
} }
impl<'l> ToNode for StyledModal<'l> {
fn into_node(self) -> Node<Msg> {
self.render()
}
}
impl<'l> StyledModal<'l> { impl<'l> StyledModal<'l> {
#[inline] #[inline]
pub fn render(self) -> Node<Msg> { pub fn render(self) -> Node<Msg> {

View File

@ -1,16 +1,12 @@
use { use seed::prelude::*;
crate::{ use seed::*;
components::{
styled_button::StyledButton, use crate::components::styled_button::StyledButton;
styled_icon::{Icon, StyledIcon}, use crate::components::styled_icon::{Icon, StyledIcon};
styled_select::{StyledSelect, StyledSelectState}, use crate::components::styled_select::{StyledSelect, StyledSelectState};
styled_tooltip::StyledTooltip, use crate::components::styled_tooltip::StyledTooltip;
}, use crate::shared::ToChild;
shared::{ToChild, ToNode}, use crate::{ButtonId, FieldId, Msg, RteField};
ButtonId, FieldId, Msg, RteField,
},
seed::{prelude::*, *},
};
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum HeadingSize { pub enum HeadingSize {
@ -437,12 +433,6 @@ impl<'component> StyledRte<'component> {
} }
} }
impl<'component> ToNode for StyledRte<'component> {
fn into_node(self) -> Node<Msg> {
render(self)
}
}
pub struct StyledRteBuilder<'outer> { pub struct StyledRteBuilder<'outer> {
field_id: FieldId, field_id: FieldId,
value: String, value: String,
@ -639,14 +629,14 @@ pub fn render(values: StyledRte) -> Node<Msg> {
C!["bar"], C!["bar"],
first_row(click_handler.clone()), first_row(click_handler.clone()),
second_row(&values, click_handler, change_handler), second_row(&values, click_handler, change_handler),
// brush_button, /* brush_button,
// color_bucket_button, * color_bucket_button,
// color_picker_button, * color_picker_button,
// link_broken_button, * link_broken_button,
// pin_button, * pin_button,
// save_button, * save_button,
// text_height_button, * text_height_button,
// text_width_button, * text_width_button, */
], ],
div![ div![
C!["editorWrapper"], C!["editorWrapper"],
@ -852,7 +842,7 @@ fn second_row(
})) }))
.empty() .empty()
.build() .build()
.into_node(); .render();
span![C!["headingOption"], button] span![C!["headingOption"], button]
}) })
.collect(); .collect();
@ -880,8 +870,8 @@ fn second_row(
C!["group font"], C!["group font"],
// font_button, // font_button,
heading_button, heading_button,
// small_cap_button, /* small_cap_button,
// all_caps_button * all_caps_button */
] ]
}; };
@ -1000,7 +990,7 @@ fn table_tooltip(
.icon(Icon::Close) .icon(Icon::Close)
.on_click(click_handler.clone()) .on_click(click_handler.clone())
.build() .build()
.into_node(); .render();
let on_submit = click_handler; let on_submit = click_handler;
@ -1036,7 +1026,7 @@ fn table_tooltip(
] ]
}) })
.build() .build()
.into_node() .render()
} }
fn code_tooltip(values: &StyledRte, click_handler: EventHandler<Msg>) -> Node<Msg> { fn code_tooltip(values: &StyledRte, click_handler: EventHandler<Msg>) -> Node<Msg> {
@ -1070,7 +1060,7 @@ fn code_tooltip(values: &StyledRte, click_handler: EventHandler<Msg>) -> Node<Ms
.build(FieldId::Rte(RteField::CodeLang(Box::new( .build(FieldId::Rte(RteField::CodeLang(Box::new(
values.field_id.clone(), values.field_id.clone(),
)))) ))))
.into_node(); .render();
let close_tooltip = StyledButton::build() let close_tooltip = StyledButton::build()
.empty() .empty()
@ -1078,7 +1068,7 @@ fn code_tooltip(values: &StyledRte, click_handler: EventHandler<Msg>) -> Node<Ms
.button_id(ButtonId::RteInsertCode) .button_id(ButtonId::RteInsertCode)
.on_click(click_handler.clone()) .on_click(click_handler.clone())
.build() .build()
.into_node(); .render();
let input = { let input = {
let field_id = values.field_id.clone(); let field_id = values.field_id.clone();
@ -1098,7 +1088,7 @@ fn code_tooltip(values: &StyledRte, click_handler: EventHandler<Msg>) -> Node<Ms
.on_click(click_handler) .on_click(click_handler)
.text("Insert") .text("Insert")
.build() .build()
.into_node(); .render();
div![insert] div![insert]
}; };
@ -1110,7 +1100,7 @@ fn code_tooltip(values: &StyledRte, click_handler: EventHandler<Msg>) -> Node<Ms
.add_child(input) .add_child(input)
.add_child(actions) .add_child(actions)
.build() .build()
.into_node() .render()
} }
fn styled_rte_button( fn styled_rte_button(
@ -1125,6 +1115,6 @@ fn styled_rte_button(
.on_click(handler) .on_click(handler)
.empty() .empty()
.build() .build()
.into_node(); .render();
span![C!["styledRteButton"], attrs![At::Title => title], button] span![C!["styledRteButton"], attrs![At::Title => title], button]
} }

View File

@ -5,7 +5,6 @@ use seed::*;
use crate::components::styled_icon::{Icon, StyledIcon}; use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_select_child::*; use crate::components::styled_select_child::*;
use crate::shared::ToNode;
use crate::{FieldId, Msg}; use crate::{FieldId, Msg};
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -110,7 +109,7 @@ impl StyledSelectState {
pub struct StyledSelect<'l, Options> pub struct StyledSelect<'l, Options>
where where
Options: Iterator<Item = StyledSelectChild<'l>>, Options: Iterator<Item = StyledSelectOption<'l>>,
{ {
pub id: FieldId, pub id: FieldId,
pub variant: SelectVariant, pub variant: SelectVariant,
@ -119,7 +118,7 @@ where
pub valid: bool, pub valid: bool,
pub is_multi: bool, pub is_multi: bool,
pub options: Option<Options>, pub options: Option<Options>,
pub selected: Vec<StyledSelectChild<'l>>, pub selected: Vec<StyledSelectOption<'l>>,
pub text_filter: &'l str, pub text_filter: &'l str,
pub opened: bool, pub opened: bool,
pub clearable: bool, pub clearable: bool,
@ -127,7 +126,7 @@ where
impl<'l, Options> Default for StyledSelect<'l, Options> impl<'l, Options> Default for StyledSelect<'l, Options>
where where
Options: Iterator<Item = StyledSelectChild<'l>>, Options: Iterator<Item = StyledSelectOption<'l>>,
{ {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -146,19 +145,11 @@ where
} }
} }
impl<'l, Options> ToNode for StyledSelect<'l, Options> impl<'l, Options> StyledSelect<'l, Options>
where where
Options: Iterator<Item = StyledSelectChild<'l>>, Options: Iterator<Item = StyledSelectOption<'l>>,
{
fn into_node(self) -> Node<Msg> {
render(self)
}
}
pub fn render<'l, Options>(values: StyledSelect<'l, Options>) -> Node<Msg>
where
Options: Iterator<Item = StyledSelectChild<'l>>,
{ {
pub fn render(self) -> Node<Msg> {
let StyledSelect { let StyledSelect {
id, id,
variant, variant,
@ -171,7 +162,7 @@ where
text_filter, text_filter,
opened, opened,
clearable, clearable,
} = values; } = self;
let on_text = { let on_text = {
let field_id = id.clone(); let field_id = id.clone();
@ -207,14 +198,14 @@ where
on_click: Some(on_click), on_click: Some(on_click),
..Default::default() ..Default::default()
} }
.into_node() .render()
} else if (selected.is_empty() || !is_multi) && variant != SelectVariant::Empty { } else if (selected.is_empty() || !is_multi) && variant != SelectVariant::Empty {
StyledIcon { StyledIcon {
icon: Icon::ChevronDown, icon: Icon::ChevronDown,
class_list: "chevronIcon", class_list: "chevronIcon",
..Default::default() ..Default::default()
} }
.into_node() .render()
} else { } else {
empty![] empty![]
}; };
@ -261,7 +252,7 @@ where
C!["valueMulti"], C!["valueMulti"],
selected selected
.into_iter() .into_iter()
.map(|m| into_multi_value(m, id.clone())) .map(|m| Self::multi_value(m, id.clone()))
.collect::<Vec<Node<Msg>>>(), .collect::<Vec<Node<Msg>>>(),
IF![children.is_empty() => div![C!["placeholder"], "Select"]], IF![children.is_empty() => div![C!["placeholder"], "Select"]],
IF![!children.is_empty() => div![C!["addMore"], StyledIcon::from(Icon::Plus).render(), "Add more"]], IF![!children.is_empty() => div![C!["addMore"], StyledIcon::from(Icon::Plus).render(), "Add more"]],
@ -295,7 +286,7 @@ where
] ]
} }
fn into_multi_value(child: StyledSelectChild, id: FieldId) -> Node<Msg> { fn multi_value(child: StyledSelectOption, id: FieldId) -> Node<Msg> {
let value = child.value(); let value = child.value();
let opt = child.render_multi_value(); let opt = child.render_multi_value();
@ -310,3 +301,4 @@ fn into_multi_value(child: StyledSelectChild, id: FieldId) -> Node<Msg> {
div![C!["valueMultiItem"], opt, handler] div![C!["valueMultiItem"], opt, handler]
} }
}

View File

@ -3,7 +3,6 @@ use seed::*;
use crate::components::styled_icon::{Icon, StyledIcon}; use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_select::SelectVariant; use crate::components::styled_select::SelectVariant;
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq)]
@ -14,7 +13,7 @@ pub enum DisplayType {
SelectMultiValue, SelectMultiValue,
} }
pub struct StyledSelectChild<'l> { pub struct StyledSelectOption<'l> {
pub name: Option<&'l str>, pub name: Option<&'l str>,
pub icon: Option<Node<Msg>>, pub icon: Option<Node<Msg>>,
pub text: Option<&'l str>, pub text: Option<&'l str>,
@ -23,7 +22,7 @@ pub struct StyledSelectChild<'l> {
pub variant: SelectVariant, pub variant: SelectVariant,
} }
impl<'l> Default for StyledSelectChild<'l> { impl<'l> Default for StyledSelectOption<'l> {
fn default() -> Self { fn default() -> Self {
Self { Self {
name: None, name: None,
@ -36,25 +35,25 @@ impl<'l> Default for StyledSelectChild<'l> {
} }
} }
impl<'l> StyledSelectChild<'l> { impl<'l> StyledSelectOption<'l> {
#[inline] #[inline(always)]
pub fn value(&self) -> u32 { pub fn value(&self) -> u32 {
self.value self.value
} }
#[inline(always)] #[inline(always)]
pub fn render_value(self) -> Node<Msg> { pub fn render_value(self) -> Node<Msg> {
render(DisplayType::SelectValue, self) self.render(DisplayType::SelectValue)
} }
#[inline(always)] #[inline(always)]
pub fn render_multi_value(self) -> Node<Msg> { pub fn render_multi_value(self) -> Node<Msg> {
render(DisplayType::SelectMultiValue, self) self.render(DisplayType::SelectMultiValue)
} }
#[inline(always)] #[inline(always)]
pub fn render_option(self) -> Node<Msg> { pub fn render_option(self) -> Node<Msg> {
render(DisplayType::SelectOption, self) self.render(DisplayType::SelectOption)
} }
#[inline(always)] #[inline(always)]
@ -64,18 +63,17 @@ impl<'l> StyledSelectChild<'l> {
.map(|t| t.to_lowercase().contains(text.to_lowercase().as_str())) .map(|t| t.to_lowercase().contains(text.to_lowercase().as_str()))
.unwrap_or(true) .unwrap_or(true)
} }
}
#[inline(always)] #[inline(always)]
pub fn render(display_type: DisplayType, values: StyledSelectChild) -> Node<Msg> { pub fn render(self, display_type: DisplayType) -> Node<Msg> {
let StyledSelectChild { let StyledSelectOption {
name, name,
icon, icon,
text, text,
value: _, value: _,
class_list, class_list,
variant, variant,
} = values; } = self;
let icon_node = match icon { let icon_node = match icon {
Some(icon) => icon, Some(icon) => icon,
@ -91,7 +89,8 @@ pub fn render(display_type: DisplayType, values: StyledSelectChild) -> Node<Msg>
.unwrap_or_default(), .unwrap_or_default(),
match display_type { match display_type {
DisplayType::SelectOption => "optionLabel", DisplayType::SelectOption => "optionLabel",
DisplayType::SelectValue | DisplayType::SelectMultiValue => "selectItemLabel", DisplayType::SelectValue | DisplayType::SelectMultiValue =>
"selectItemLabel",
}, },
class_list class_list
], ],
@ -115,6 +114,7 @@ pub fn render(display_type: DisplayType, values: StyledSelectChild) -> Node<Msg>
IF![display_type == DisplayType::SelectMultiValue => close_icon()] IF![display_type == DisplayType::SelectMultiValue => close_icon()]
] ]
} }
}
#[inline(always)] #[inline(always)]
fn close_icon() -> Node<Msg> { fn close_icon() -> Node<Msg> {
@ -123,5 +123,5 @@ fn close_icon() -> Node<Msg> {
size: Some(14), size: Some(14),
..Default::default() ..Default::default()
} }
.into_node() .render()
} }

View File

@ -1,7 +1,6 @@
use seed::prelude::*; use seed::prelude::*;
use seed::*; use seed::*;
use crate::shared::ToNode;
use crate::{FieldId, Msg}; use crate::{FieldId, Msg};
#[derive(Debug)] #[derive(Debug)]
@ -31,26 +30,14 @@ impl<'l> Default for StyledTextarea<'l> {
} }
} }
impl<'l> ToNode for StyledTextarea<'l> { impl<'l> StyledTextarea<'l> {
fn into_node(self) -> Node<Msg> {
render(self)
}
}
const FONT_SIZE: f64 = 15f64;
const LINE_HEIGHT: f64 = 1.4285;
const LETTER_HEIGHT: f64 = FONT_SIZE * LINE_HEIGHT;
const PADDING_TOP_BOTTOM: f64 = 17f64;
const BORDER_TOP_BOTTOM: f64 = 2f64;
const ADDITIONAL_HEIGHT: f64 = PADDING_TOP_BOTTOM + BORDER_TOP_BOTTOM;
// height = `calc( (${$0.value.split("\n").length}px * ( 15 * 1.4285 )) + 17px + // height = `calc( (${$0.value.split("\n").length}px * ( 15 * 1.4285 )) + 17px +
// 2px)` where: // 2px)` where:
// * 15 is font-size // * 15 is font-size
// * 1.4285 is line-height // * 1.4285 is line-height
// * 17 is padding top + bottom // * 17 is padding top + bottom
// * 2 is border top + bottom // * 2 is border top + bottom
pub fn render(values: StyledTextarea) -> Node<Msg> { pub fn render(self) -> Node<Msg> {
let StyledTextarea { let StyledTextarea {
id, id,
height, height,
@ -60,7 +47,7 @@ pub fn render(values: StyledTextarea) -> Node<Msg> {
update_event, update_event,
placeholder, placeholder,
disable_auto_resize, disable_auto_resize,
} = values; } = self;
let id = id.expect("Text area requires FieldId"); let id = id.expect("Text area requires FieldId");
let mut style_list = vec![]; let mut style_list = vec![];
@ -90,7 +77,8 @@ pub fn render(values: StyledTextarea) -> Node<Msg> {
let target = event.target().unwrap(); let target = event.target().unwrap();
let textarea = seed::to_textarea(&target); let textarea = seed::to_textarea(&target);
let value = textarea.value(); let value = textarea.value();
let min_height = get_min_height(value.as_str(), height as f64, handler_disable_auto_resize); let min_height =
get_min_height(value.as_str(), height as f64, handler_disable_auto_resize);
textarea textarea
.style() .style()
@ -142,6 +130,14 @@ pub fn render(values: StyledTextarea) -> Node<Msg> {
] ]
] ]
} }
}
const FONT_SIZE: f64 = 15f64;
const LINE_HEIGHT: f64 = 1.4285;
const LETTER_HEIGHT: f64 = FONT_SIZE * LINE_HEIGHT;
const PADDING_TOP_BOTTOM: f64 = 17f64;
const BORDER_TOP_BOTTOM: f64 = 2f64;
const ADDITIONAL_HEIGHT: f64 = PADDING_TOP_BOTTOM + BORDER_TOP_BOTTOM;
fn get_min_height(value: &str, min_height: f64, disable_auto_resize: bool) -> f64 { fn get_min_height(value: &str, min_height: f64, disable_auto_resize: bool) -> f64 {
if disable_auto_resize { if disable_auto_resize {

View File

@ -1,7 +1,6 @@
use seed::prelude::*; use seed::prelude::*;
use seed::*; use seed::*;
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@ -59,9 +58,3 @@ impl<'l> StyledTooltip<'l> {
} }
} }
} }
impl<'l> ToNode for StyledTooltip<'l> {
fn into_node(self) -> Node<Msg> {
self.render()
}
}

View File

@ -1,7 +1,6 @@
use jirs_data::CommentId; use jirs_data::CommentId;
use seed::prelude::*; use seed::prelude::*;
use crate::shared::ToNode;
use crate::styled_confirm_modal::StyledConfirmModal; use crate::styled_confirm_modal::StyledConfirmModal;
use crate::{model, Msg}; use crate::{model, Msg};
@ -14,5 +13,5 @@ pub fn view(_model: &model::Model, modal: &super::Model) -> Node<Msg> {
on_confirm: Some(mouse_ev(Ev::Click, move |_| Msg::DeleteComment(comment_id))), on_confirm: Some(mouse_ev(Ev::Click, move |_| Msg::DeleteComment(comment_id))),
..Default::default() ..Default::default()
} }
.into_node() .render()
} }

View File

@ -3,7 +3,6 @@ use seed::*;
use crate::components::styled_modal::StyledModal; use crate::components::styled_modal::StyledModal;
use crate::model::Model; use crate::model::Model;
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
pub fn view(model: &Model) -> Node<Msg> { pub fn view(model: &Model) -> Node<Msg> {
@ -15,5 +14,5 @@ pub fn view(model: &Model) -> Node<Msg> {
children: vec![code], children: vec![code],
..Default::default() ..Default::default()
} }
.into_node() .render()
} }

View File

@ -3,9 +3,8 @@ use seed::prelude::Node;
use crate::components::styled_field::StyledField; use crate::components::styled_field::StyledField;
use crate::components::styled_select::{SelectVariant, StyledSelect}; use crate::components::styled_select::{SelectVariant, StyledSelect};
use crate::components::styled_select_child::StyledSelectChild; use crate::components::styled_select_child::StyledSelectOption;
use crate::model::{IssueModal, Model}; use crate::model::{IssueModal, Model};
use crate::shared::ToNode;
use crate::{FieldId, Msg}; use crate::{FieldId, Msg};
pub fn epic_field<Modal>(model: &Model, modal: &Modal, field_id: FieldId) -> Option<Node<Msg>> pub fn epic_field<Modal>(model: &Model, modal: &Modal, field_id: FieldId) -> Option<Node<Msg>>
@ -31,7 +30,7 @@ where
valid: true, valid: true,
..Default::default() ..Default::default()
} }
.into_node(); .render();
Some( Some(
StyledField { StyledField {
label: "Epic", label: "Epic",
@ -39,12 +38,12 @@ where
input, input,
..Default::default() ..Default::default()
} }
.into_node(), .render(),
) )
} }
fn epic_select_option<'l>(epic: &'l Epic) -> StyledSelectChild<'l> { fn epic_select_option<'l>(epic: &'l Epic) -> StyledSelectOption<'l> {
StyledSelectChild { StyledSelectOption {
value: epic.id as u32, value: epic.id as u32,
text: Some(epic.name.as_str()), text: Some(epic.name.as_str()),
..Default::default() ..Default::default()

View File

@ -6,7 +6,6 @@ use crate::components::styled_confirm_modal::*;
use crate::components::styled_icon::*; use crate::components::styled_icon::*;
use crate::components::styled_modal::*; use crate::components::styled_modal::*;
use crate::modals::epics_delete::Model; use crate::modals::epics_delete::Model;
use crate::shared::ToNode;
use crate::{model, Msg}; use crate::{model, Msg};
pub fn view(model: &model::Model, modal: &Model) -> Node<Msg> { pub fn view(model: &model::Model, modal: &Model) -> Node<Msg> {
@ -22,7 +21,7 @@ pub fn view(model: &model::Model, modal: &Model) -> Node<Msg> {
})), })),
..Default::default() ..Default::default()
} }
.into_node() .render()
} else { } else {
StyledModal { StyledModal {
children: vec![warning(model, modal)], children: vec![warning(model, modal)],
@ -30,7 +29,7 @@ pub fn view(model: &model::Model, modal: &Model) -> Node<Msg> {
class_list: "deleteEpic", class_list: "deleteEpic",
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
} }
@ -40,7 +39,7 @@ fn warning(model: &model::Model, modal: &Model) -> Node<Msg> {
.iter() .iter()
.flat_map(|id| model.issues_by_id.get(id)) .flat_map(|id| model.issues_by_id.get(id))
.map(|issue| { .map(|issue| {
let link = StyledIcon::from(Icon::Link).into_node(); let link = StyledIcon::from(Icon::Link).render();
li![div![ li![div![
C!["relatedIssue"], C!["relatedIssue"],
a![ a![
@ -62,7 +61,7 @@ fn warning(model: &model::Model, modal: &Model) -> Node<Msg> {
variant: ButtonVariant::Secondary, variant: ButtonVariant::Secondary,
..Default::default() ..Default::default()
} }
.into_node(); .render();
section![ section![
h3![C!["header"], "Cannot delete epic"], h3![C!["header"], "Cannot delete epic"],

View File

@ -4,11 +4,10 @@ use seed::*;
use crate::components::styled_button::*; use crate::components::styled_button::*;
use crate::components::styled_checkbox::*; use crate::components::styled_checkbox::*;
use crate::components::styled_icon::Icon; use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_input::*; use crate::components::styled_input::*;
use crate::components::styled_modal::*; use crate::components::styled_modal::*;
use crate::modals::epics_edit::Model; use crate::modals::epics_edit::Model;
use crate::shared::ToNode;
use crate::{model, FieldId, Msg}; use crate::{model, FieldId, Msg};
pub fn view(_model: &model::Model, modal: &Model) -> Node<Msg> { pub fn view(_model: &model::Model, modal: &Model) -> Node<Msg> {
@ -24,10 +23,10 @@ pub fn view(_model: &model::Model, modal: &Model) -> Node<Msg> {
Msg::ModalDropped Msg::ModalDropped
})), })),
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
icon: Some(Icon::Close.into_node()), icon: Some(StyledIcon::from(Icon::Close).render()),
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledModal { StyledModal {
width: Some(600), width: Some(600),
class_list: "editEpic", class_list: "editEpic",
@ -39,12 +38,12 @@ pub fn view(_model: &model::Model, modal: &Model) -> Node<Msg> {
id: Some(FieldId::EditEpic(EpicFieldId::Name)), id: Some(FieldId::EditEpic(EpicFieldId::Name)),
..Default::default() ..Default::default()
} }
.into_node(), .render(),
transform, transform,
], ],
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn transform_into_available(modal: &super::Model) -> Node<Msg> { fn transform_into_available(modal: &super::Model) -> Node<Msg> {
@ -56,7 +55,7 @@ fn transform_into_available(modal: &super::Model) -> Node<Msg> {
), ),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let execute = StyledButton { let execute = StyledButton {
on_click: Some(mouse_ev("click", |ev| { on_click: Some(mouse_ev("click", |ev| {
ev.stop_propagation(); ev.stop_propagation();
@ -66,7 +65,7 @@ fn transform_into_available(modal: &super::Model) -> Node<Msg> {
text: Some("Transform"), text: Some("Transform"),
..Default::default() ..Default::default()
} }
.into_node(); .render();
div![C!["transform available"], div![types], div![execute]] div![C!["transform available"], div![types], div![execute]]
} }

View File

@ -2,7 +2,6 @@ use jirs_data::IssueStatusId;
use seed::prelude::*; use seed::prelude::*;
use crate::components::styled_confirm_modal::StyledConfirmModal; use crate::components::styled_confirm_modal::StyledConfirmModal;
use crate::shared::ToNode;
use crate::{model, Msg}; use crate::{model, Msg};
pub fn view(_model: &model::Model, issue_status_id: IssueStatusId) -> Node<Msg> { pub fn view(_model: &model::Model, issue_status_id: IssueStatusId) -> Node<Msg> {
@ -15,5 +14,5 @@ pub fn view(_model: &model::Model, issue_status_id: IssueStatusId) -> Node<Msg>
Msg::DeleteIssueStatus(issue_status_id) Msg::DeleteIssueStatus(issue_status_id)
})), })),
} }
.into_node() .render()
} }

View File

@ -11,12 +11,11 @@ use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_input::StyledInput; use crate::components::styled_input::StyledInput;
use crate::components::styled_modal::StyledModal; use crate::components::styled_modal::StyledModal;
use crate::components::styled_select::{SelectVariant, StyledSelect}; use crate::components::styled_select::{SelectVariant, StyledSelect};
use crate::components::styled_select_child::StyledSelectChild; use crate::components::styled_select_child::StyledSelectOption;
use crate::components::styled_textarea::StyledTextarea; use crate::components::styled_textarea::StyledTextarea;
use crate::modals::epic_field; use crate::modals::epic_field;
use crate::modals::issues_create::{Model as AddIssueModal, Type}; use crate::modals::issues_create::{Model as AddIssueModal, Type};
use crate::model::Model; use crate::model::Model;
use crate::shared::ToNode;
use crate::{FieldId, Msg}; use crate::{FieldId, Msg};
pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> { pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
@ -45,11 +44,11 @@ pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
popup_visible: modal.epic_starts_at_state.popup_visible, popup_visible: modal.epic_starts_at_state.popup_visible,
timestamp: modal.epic_starts_at_state.timestamp.clone(), timestamp: modal.epic_starts_at_state.timestamp.clone(),
} }
.into_node(), .render(),
label: "Starts at", label: "Starts at",
..Default::default() ..Default::default()
} }
.into_node(); .render();
let end = StyledField { let end = StyledField {
input: StyledDateTimeInput { input: StyledDateTimeInput {
@ -57,11 +56,11 @@ pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
popup_visible: modal.epic_ends_at_state.popup_visible, popup_visible: modal.epic_ends_at_state.popup_visible,
timestamp: modal.epic_ends_at_state.timestamp.clone(), timestamp: modal.epic_ends_at_state.timestamp.clone(),
} }
.into_node(), .render(),
label: "Ends at", label: "Ends at",
..Default::default() ..Default::default()
} }
.into_node(); .render();
form.fields.push(name_field); form.fields.push(name_field);
form.fields.push(starts); form.fields.push(starts);
@ -99,7 +98,7 @@ pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
})), })),
..Default::default() ..Default::default()
} }
.into_node() .render()
}; };
let cancel = StyledButton { let cancel = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
@ -112,7 +111,7 @@ pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
})), })),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let actions = div![attrs![At::Class => "actions"], submit, cancel]; let actions = div![attrs![At::Class => "actions"], submit, cancel];
form.fields.push(actions); form.fields.push(actions);
@ -120,10 +119,10 @@ pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
StyledModal { StyledModal {
class_list: "addIssue", class_list: "addIssue",
width: Some(0), width: Some(0),
children: vec![form.into_node()], children: vec![form.render()],
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn issue_type_field(modal: &AddIssueModal) -> Node<Msg> { fn issue_type_field(modal: &AddIssueModal) -> Node<Msg> {
@ -146,18 +145,18 @@ fn issue_type_field(modal: &AddIssueModal) -> Node<Msg> {
)], )],
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Issue Type", label: "Issue Type",
tip: Some("Start typing to get a list of possible matches."), tip: Some("Start typing to get a list of possible matches."),
input: select_type, input: select_type,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
#[inline(always)] #[inline(always)]
fn type_select_option<'l>(t: Type) -> StyledSelectChild<'l> { fn type_select_option<'l>(t: Type) -> StyledSelectOption<'l> {
let name = match t { let name = match t {
Type::Task => "Task", Type::Task => "Task",
Type::Bug => "Bug", Type::Bug => "Bug",
@ -165,7 +164,7 @@ fn type_select_option<'l>(t: Type) -> StyledSelectChild<'l> {
Type::Epic => "Epic", Type::Epic => "Epic",
}; };
StyledSelectChild { StyledSelectOption {
class_list: name, class_list: name,
text: Some(name), text: Some(name),
icon: Some( icon: Some(
@ -179,7 +178,7 @@ fn type_select_option<'l>(t: Type) -> StyledSelectChild<'l> {
class_list: name, class_list: name,
..Default::default() ..Default::default()
} }
.into_node(), .render(),
), ),
name: Some("type"), name: Some("type"),
value: t.into(), value: t.into(),
@ -195,14 +194,14 @@ fn short_summary_field(modal: &AddIssueModal) -> Node<Msg> {
id: Some(FieldId::AddIssueModal(IssueFieldId::Title)), id: Some(FieldId::AddIssueModal(IssueFieldId::Title)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Short Summary", label: "Short Summary",
tip: Some("Concisely summarize the issue in one or two sentences."), tip: Some("Concisely summarize the issue in one or two sentences."),
input: short_summary, input: short_summary,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn description_field() -> Node<Msg> { fn description_field() -> Node<Msg> {
@ -212,14 +211,14 @@ fn description_field() -> Node<Msg> {
class_list: "textarea", class_list: "textarea",
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Description", label: "Description",
tip: Some("Describe the issue in as much detail as you'd like."), tip: Some("Describe the issue in as much detail as you'd like."),
input: description, input: description,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn reporter_field(model: &Model, modal: &AddIssueModal) -> Node<Msg> { fn reporter_field(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
@ -248,18 +247,18 @@ fn reporter_field(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
valid: true, valid: true,
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
input: reporter, input: reporter,
label: "Reporter", label: "Reporter",
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
#[inline(always)] #[inline(always)]
fn reporter_select_option(user: &User) -> StyledSelectChild { fn reporter_select_option(user: &User) -> StyledSelectOption {
StyledSelectChild { StyledSelectOption {
value: user.id as u32, value: user.id as u32,
icon: Some( icon: Some(
StyledAvatar { StyledAvatar {
@ -268,7 +267,7 @@ fn reporter_select_option(user: &User) -> StyledSelectChild {
avatar_url: user.avatar_url.as_deref(), avatar_url: user.avatar_url.as_deref(),
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node(), .render(),
), ),
text: Some(user.name.as_str()), text: Some(user.name.as_str()),
name: Some("reporter"), name: Some("reporter"),
@ -299,19 +298,19 @@ fn assignees_field(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
valid: true, valid: true,
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
input: assignees, input: assignees,
label: "Assignees", label: "Assignees",
tip: Some(""), tip: Some(""),
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
#[inline(always)] #[inline(always)]
fn assignee_select_option(user: &User) -> StyledSelectChild { fn assignee_select_option(user: &User) -> StyledSelectOption {
StyledSelectChild { StyledSelectOption {
value: user.id as u32, value: user.id as u32,
icon: Some( icon: Some(
StyledAvatar { StyledAvatar {
@ -320,7 +319,7 @@ fn assignee_select_option(user: &User) -> StyledSelectChild {
avatar_url: user.avatar_url.as_deref(), avatar_url: user.avatar_url.as_deref(),
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node(), .render(),
), ),
text: Some(user.name.as_str()), text: Some(user.name.as_str()),
name: Some("assignees"), name: Some("assignees"),
@ -341,25 +340,25 @@ fn issue_priority_field(modal: &AddIssueModal) -> Node<Msg> {
selected: vec![priority_select_option(modal.priority)], selected: vec![priority_select_option(modal.priority)],
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Issue Type", label: "Issue Type",
tip: Some("Priority in relation to other issues."), tip: Some("Priority in relation to other issues."),
input: select_priority, input: select_priority,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn priority_select_option<'l>(priority: IssuePriority) -> StyledSelectChild<'l> { fn priority_select_option<'l>(priority: IssuePriority) -> StyledSelectOption<'l> {
StyledSelectChild { StyledSelectOption {
icon: Some( icon: Some(
StyledIcon { StyledIcon {
icon: priority.clone().into(), icon: priority.clone().into(),
class_list: priority.to_str(), class_list: priority.to_str(),
..Default::default() ..Default::default()
} }
.into_node(), .render(),
), ),
text: Some(priority.to_str()), text: Some(priority.to_str()),
class_list: priority.to_str(), class_list: priority.to_str(),
@ -376,12 +375,12 @@ fn name_field(modal: &AddIssueModal) -> Node<Msg> {
id: Some(FieldId::AddIssueModal(IssueFieldId::Title)), id: Some(FieldId::AddIssueModal(IssueFieldId::Title)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Epic name", label: "Epic name",
tip: Some("Describe upcoming feature."), tip: Some("Describe upcoming feature."),
input: name, input: name,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }

View File

@ -1,7 +1,6 @@
use seed::prelude::*; use seed::prelude::*;
use crate::components::styled_confirm_modal::StyledConfirmModal; use crate::components::styled_confirm_modal::StyledConfirmModal;
use crate::shared::ToNode;
use crate::{model, Msg}; use crate::{model, Msg};
pub fn view(model: &model::Model) -> Node<Msg> { pub fn view(model: &model::Model) -> Node<Msg> {
@ -17,5 +16,5 @@ pub fn view(model: &model::Model) -> Node<Msg> {
cancel_text: "Cancel", cancel_text: "Cancel",
on_confirm: Some(mouse_ev(Ev::Click, move |_| Msg::DeleteIssue(issue_id))), on_confirm: Some(mouse_ev(Ev::Click, move |_| Msg::DeleteIssue(issue_id))),
} }
.into_node() .render()
} }

View File

@ -14,13 +14,12 @@ use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_input::StyledInput; use crate::components::styled_input::StyledInput;
use crate::components::styled_modal::*; use crate::components::styled_modal::*;
use crate::components::styled_select::{SelectVariant, StyledSelect, StyledSelectState}; use crate::components::styled_select::{SelectVariant, StyledSelect, StyledSelectState};
use crate::components::styled_select_child::StyledSelectChild; use crate::components::styled_select_child::StyledSelectOption;
use crate::modals::epic_field; use crate::modals::epic_field;
use crate::modals::issues_edit::Model as EditIssueModal; use crate::modals::issues_edit::Model as EditIssueModal;
use crate::modals::time_tracking::time_tracking_field; use crate::modals::time_tracking::time_tracking_field;
use crate::model::{ModalType, Model}; use crate::model::{ModalType, Model};
use crate::shared::tracking_widget::tracking_link; use crate::shared::tracking_widget::tracking_link;
use crate::shared::ToNode;
use crate::{EditIssueModalSection, FieldChange, FieldId, Msg}; use crate::{EditIssueModalSection, FieldChange, FieldId, Msg};
mod comments; mod comments;
@ -30,7 +29,7 @@ pub fn view(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
.issues_by_id .issues_by_id
.get(&modal.id) .get(&modal.id)
.map(|_issue| { .map(|_issue| {
StyledModal::centered_with_width_and_body(1040, vec![details(model, modal)]).into_node() StyledModal::centered_with_width_and_body(1040, vec![details(model, modal)]).render()
}) })
.unwrap_or(Node::Empty) .unwrap_or(Node::Empty)
} }
@ -96,7 +95,7 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
let copy_button = StyledButton { let copy_button = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
icon: Some(Icon::Link.into_node()), icon: Some(StyledIcon::from(Icon::Link).render()),
on_click: Some(click_handler), on_click: Some(click_handler),
children: vec![span![if *link_copied { children: vec![span![if *link_copied {
"Link Copied" "Link Copied"
@ -105,7 +104,7 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
}]], }]],
..Default::default() ..Default::default()
} }
.into_node(); .render();
let delete_button = StyledButton { let delete_button = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
icon: Some( icon: Some(
@ -114,12 +113,12 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
size: Some(19), size: Some(19),
..Default::default() ..Default::default()
} }
.into_node(), .render(),
), ),
on_click: Some(delete_confirmation_handler), on_click: Some(delete_confirmation_handler),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let close_button = StyledButton { let close_button = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
icon: Some( icon: Some(
@ -128,12 +127,12 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
size: Some(24), size: Some(24),
..Default::default() ..Default::default()
} }
.into_node(), .render(),
), ),
on_click: Some(close_handler), on_click: Some(close_handler),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let issue_type_select = { let issue_type_select = {
let id = modal.id; let id = modal.id;
@ -155,7 +154,7 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
selected: vec![type_select_option(payload.issue_type, &text)], selected: vec![type_select_option(payload.issue_type, &text)],
..Default::default() ..Default::default()
} }
.into_node() .render()
}; };
div![ div![
@ -171,18 +170,18 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
} }
#[inline(always)] #[inline(always)]
fn type_select_option<'l>(t: IssueType, text: &'l str) -> StyledSelectChild<'l> { fn type_select_option<'l>(t: IssueType, text: &'l str) -> StyledSelectOption<'l> {
let name = t.to_label(); let name = t.to_label();
StyledSelectChild { StyledSelectOption {
class_list: name, class_list: name,
text: Some(text), text: Some(text),
icon: Some( icon: Some(
StyledIcon { StyledIcon {
icon: t.clone().into(), icon: t.into(),
class_list: name, class_list: name,
..Default::default() ..Default::default()
} }
.into_node(), .render(),
), ),
value: t.into(), value: t.into(),
name: Some("type"), name: Some("type"),
@ -208,7 +207,7 @@ fn left_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
))), ))),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let description = { let description = {
StyledEditor { StyledEditor {
@ -221,13 +220,13 @@ fn left_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
mode: description_state.mode.clone(), mode: description_state.mode.clone(),
update_event: Ev::Change, update_event: Ev::Change,
} }
.into_node() .render()
}; };
let description_field = StyledField { let description_field = StyledField {
input: description, input: description,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let user_avatar = StyledAvatar { let user_avatar = StyledAvatar {
avatar_url: model.user.as_ref().and_then(|u| u.avatar_url.as_deref()), avatar_url: model.user.as_ref().and_then(|u| u.avatar_url.as_deref()),
@ -235,7 +234,7 @@ fn left_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
class_list: "userAvatar", class_list: "userAvatar",
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node(); .render();
let create_comment = if comment_form.creating && comment_form.id.is_none() { let create_comment = if comment_form.creating && comment_form.id.is_none() {
build_comment_form(comment_form) build_comment_form(comment_form)
@ -320,7 +319,7 @@ fn right_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
input: tracking, input: tracking,
..Default::default() ..Default::default()
} }
.into_node(); .render();
(estimate_field, tracking_field) (estimate_field, tracking_field)
} else { } else {
(Node::Empty, Node::Empty) (Node::Empty, Node::Empty)
@ -364,25 +363,25 @@ fn priorities_select(
selected: vec![priority_select_option(payload.priority)], selected: vec![priority_select_option(payload.priority)],
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Priority", label: "Priority",
input: priority, input: priority,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
#[inline(always)] #[inline(always)]
fn priority_select_option<'l>(ip: IssuePriority) -> StyledSelectChild<'l> { fn priority_select_option<'l>(ip: IssuePriority) -> StyledSelectOption<'l> {
StyledSelectChild { StyledSelectOption {
icon: Some( icon: Some(
StyledIcon { StyledIcon {
icon: ip.clone().into(), icon: ip.clone().into(),
class_list: ip.to_str(), class_list: ip.to_str(),
..Default::default() ..Default::default()
} }
.into_node(), .render(),
), ),
text: Some(ip.to_str()), text: Some(ip.to_str()),
class_list: ip.to_str(), class_list: ip.to_str(),
@ -415,18 +414,18 @@ fn status_select(
valid: true, valid: true,
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Status", label: "Status",
input: status, input: status,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
#[inline(always)] #[inline(always)]
fn issue_status_select_option<'l>(is: &'l IssueStatus) -> StyledSelectChild<'l> { fn issue_status_select_option<'l>(is: &'l IssueStatus) -> StyledSelectOption<'l> {
StyledSelectChild { StyledSelectOption {
value: is.id as u32, value: is.id as u32,
class_list: is.name.as_str(), class_list: is.name.as_str(),
text: Some(is.name.as_str()), text: Some(is.name.as_str()),
@ -456,18 +455,18 @@ fn reporters_select(
.collect(), .collect(),
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Reporter", label: "Reporter",
input: reporter, input: reporter,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
#[inline(always)] #[inline(always)]
fn reporter_select_option<'l>(user: &'l User) -> StyledSelectChild<'l> { fn reporter_select_option<'l>(user: &'l User) -> StyledSelectOption<'l> {
StyledSelectChild { StyledSelectOption {
value: user.id as u32, value: user.id as u32,
icon: Some( icon: Some(
StyledAvatar { StyledAvatar {
@ -476,7 +475,7 @@ fn reporter_select_option<'l>(user: &'l User) -> StyledSelectChild<'l> {
avatar_url: user.avatar_url.as_deref(), avatar_url: user.avatar_url.as_deref(),
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node(), .render(),
), ),
text: Some(user.name.as_str()), text: Some(user.name.as_str()),
name: Some("reporter"), name: Some("reporter"),
@ -506,18 +505,18 @@ fn assignees_select(
.collect(), .collect(),
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
input: assignees, input: assignees,
label: "Assignees", label: "Assignees",
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
#[inline(always)] #[inline(always)]
fn assignee_select_option<'l>(user: &'l User) -> StyledSelectChild<'l> { fn assignee_select_option<'l>(user: &'l User) -> StyledSelectOption<'l> {
StyledSelectChild { StyledSelectOption {
value: user.id as u32, value: user.id as u32,
icon: Some( icon: Some(
StyledAvatar { StyledAvatar {
@ -526,7 +525,7 @@ fn assignee_select_option<'l>(user: &'l User) -> StyledSelectChild<'l> {
avatar_url: user.avatar_url.as_deref(), avatar_url: user.avatar_url.as_deref(),
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node(), .render(),
), ),
text: Some(user.name.as_str()), text: Some(user.name.as_str()),
name: Some("assignees"), name: Some("assignees"),

View File

@ -7,9 +7,9 @@ use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_textarea::StyledTextarea; use crate::components::styled_textarea::StyledTextarea;
use crate::modals::issues_edit::Model as EditIssueModal; use crate::modals::issues_edit::Model as EditIssueModal;
use crate::model::{CommentForm, ModalType, Model}; use crate::model::{CommentForm, ModalType, Model};
use crate::shared::ToNode;
use crate::{EditIssueModalSection, FieldChange, FieldId, Msg}; use crate::{EditIssueModalSection, FieldChange, FieldId, Msg};
#[inline(always)]
pub fn build_comment_form(form: &CommentForm) -> Vec<Node<Msg>> { pub fn build_comment_form(form: &CommentForm) -> Vec<Node<Msg>> {
let submit_comment_form = mouse_ev(Ev::Click, move |ev| { let submit_comment_form = mouse_ev(Ev::Click, move |ev| {
ev.stop_propagation(); ev.stop_propagation();
@ -31,7 +31,7 @@ pub fn build_comment_form(form: &CommentForm) -> Vec<Node<Msg>> {
placeholder: "Add a comment...", placeholder: "Add a comment...",
..Default::default() ..Default::default()
} }
.into_node(); .render();
let submit = StyledButton { let submit = StyledButton {
variant: ButtonVariant::Primary, variant: ButtonVariant::Primary,
@ -39,18 +39,19 @@ pub fn build_comment_form(form: &CommentForm) -> Vec<Node<Msg>> {
text: Some("Save"), text: Some("Save"),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let cancel = StyledButton { let cancel = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
on_click: Some(close_comment_form), on_click: Some(close_comment_form),
text: Some("Cancel"), text: Some("Cancel"),
..Default::default() ..Default::default()
} }
.into_node(); .render();
vec![text_area, div![C!["actions"], submit, cancel]] vec![text_area, div![C!["actions"], submit, cancel]]
} }
#[inline(always)]
pub fn comment(model: &Model, modal: &EditIssueModal, comment: &Comment) -> Option<Node<Msg>> { pub fn comment(model: &Model, modal: &EditIssueModal, comment: &Comment) -> Option<Node<Msg>> {
let show_form = modal.comment_form.creating && modal.comment_form.id == Some(comment.id); let show_form = modal.comment_form.creating && modal.comment_form.id == Some(comment.id);
@ -62,7 +63,7 @@ pub fn comment(model: &Model, modal: &EditIssueModal, comment: &Comment) -> Opti
class_list: "userAvatar", class_list: "userAvatar",
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node(); .render();
let buttons = if model.user.as_ref().map(|u| u.id) == Some(comment.user_id) { let buttons = if model.user.as_ref().map(|u| u.id) == Some(comment.user_id) {
let comment_id = comment.id; let comment_id = comment.id;
@ -82,7 +83,7 @@ pub fn comment(model: &Model, modal: &EditIssueModal, comment: &Comment) -> Opti
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let cancel_button = StyledButton { let cancel_button = StyledButton {
class_list: "deleteButton", class_list: "deleteButton",
@ -91,7 +92,7 @@ pub fn comment(model: &Model, modal: &EditIssueModal, comment: &Comment) -> Opti
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
..Default::default() ..Default::default()
} }
.into_node(); .render();
vec![edit_button, cancel_button] vec![edit_button, cancel_button]
} else { } else {

View File

@ -7,10 +7,9 @@ use crate::components::styled_field::StyledField;
use crate::components::styled_input::{StyledInput, StyledInputState}; use crate::components::styled_input::{StyledInput, StyledInputState};
use crate::components::styled_modal::StyledModal; use crate::components::styled_modal::StyledModal;
use crate::components::styled_select::{StyledSelect, StyledSelectState}; use crate::components::styled_select::{StyledSelect, StyledSelectState};
use crate::components::styled_select_child::StyledSelectChild; use crate::components::styled_select_child::StyledSelectOption;
use crate::model::Model; use crate::model::Model;
use crate::shared::tracking_widget::{fibonacci_value_name, fibonacci_values, tracking_widget}; use crate::shared::tracking_widget::{fibonacci_value_name, fibonacci_values, tracking_widget};
use crate::shared::ToNode;
use crate::{EditIssueModalSection, FieldId, Msg}; use crate::{EditIssueModalSection, FieldId, Msg};
pub fn value_for_time_tracking(v: &Option<i32>, time_tracking_type: &TimeTracking) -> String { pub fn value_for_time_tracking(v: &Option<i32>, time_tracking_type: &TimeTracking) -> String {
@ -69,7 +68,7 @@ pub fn view(model: &Model, modal: &super::Model) -> Node<Msg> {
on_click: Some(mouse_ev(Ev::Click, |_| Msg::ModalDropped)), on_click: Some(mouse_ev(Ev::Click, |_| Msg::ModalDropped)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledModal { StyledModal {
class_list: "timeTrackingModal", class_list: "timeTrackingModal",
@ -77,7 +76,7 @@ pub fn view(model: &Model, modal: &super::Model) -> Node<Msg> {
width: Some(400), width: Some(400),
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
#[inline(always)] #[inline(always)]
@ -110,27 +109,27 @@ pub fn time_tracking_field(
), ),
..Default::default() ..Default::default()
} }
.into_node(), .render(),
TimeTracking::Hourly => StyledInput { TimeTracking::Hourly => StyledInput {
valid: input_state.is_valid(), valid: input_state.is_valid(),
value: input_state.value.as_str(), value: input_state.value.as_str(),
id: Some(field_id), id: Some(field_id),
..Default::default() ..Default::default()
} }
.into_node(), .render(),
}; };
StyledField { StyledField {
input, input,
label, label,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn fibonacci_value_select_option<'l>(value: u32) -> StyledSelectChild<'l> { fn fibonacci_value_select_option<'l>(value: u32) -> StyledSelectOption<'l> {
let name = fibonacci_value_name(value); let name = fibonacci_value_name(value);
StyledSelectChild { StyledSelectOption {
class_list: name, class_list: name,
text: Some(name), text: Some(name),
value, value,

View File

@ -8,7 +8,7 @@ use crate::components::styled_form::StyledForm;
use crate::components::styled_input::StyledInput; use crate::components::styled_input::StyledInput;
use crate::model::{Model, PageContent}; use crate::model::{Model, PageContent};
use crate::pages::invite_page::InvitePage; use crate::pages::invite_page::InvitePage;
use crate::shared::{outer_layout, ToNode}; use crate::shared::outer_layout;
use crate::validations::is_token; use crate::validations::is_token;
use crate::{match_page, FieldId, InvitationPageChange, Msg, PageChanged}; use crate::{match_page, FieldId, InvitationPageChange, Msg, PageChanged};
@ -30,7 +30,7 @@ pub fn view(model: &Model) -> Node<Msg> {
})), })),
fields: vec![token_field, submit_field, error], fields: vec![token_field, submit_field, error],
} }
.into_node(); .render();
outer_layout(model, "invite", vec![form]) outer_layout(model, "invite", vec![form])
} }
@ -41,12 +41,12 @@ fn submit(_page: &InvitePage) -> Node<Msg> {
variant: ButtonVariant::Primary, variant: ButtonVariant::Primary,
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
input: submit, input: submit,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn token_field(page: &InvitePage) -> Node<Msg> { fn token_field(page: &InvitePage) -> Node<Msg> {
@ -56,12 +56,12 @@ fn token_field(page: &InvitePage) -> Node<Msg> {
value: page.token.as_str(), value: page.token.as_str(),
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
input, input,
label: "Your invite token", label: "Your invite token",
..Default::default() ..Default::default()
} }
.into_node() .render()
} }

View File

@ -10,10 +10,10 @@ use crate::components::styled_form::StyledForm;
use crate::components::styled_image_input::StyledImageInput; use crate::components::styled_image_input::StyledImageInput;
use crate::components::styled_input::{InputVariant, StyledInput}; use crate::components::styled_input::{InputVariant, StyledInput};
use crate::components::styled_select::{SelectVariant, StyledSelect}; use crate::components::styled_select::{SelectVariant, StyledSelect};
use crate::components::styled_select_child::StyledSelectChild; use crate::components::styled_select_child::StyledSelectOption;
use crate::model::{Model, PageContent}; use crate::model::{Model, PageContent};
use crate::pages::profile_page::model::ProfilePage; use crate::pages::profile_page::model::ProfilePage;
use crate::shared::{inner_layout, ToNode}; use crate::shared::inner_layout;
use crate::{FieldId, Msg, PageChanged, ProfilePageChange}; use crate::{FieldId, Msg, PageChanged, ProfilePageChange};
pub fn view(model: &Model) -> Node<Msg> { pub fn view(model: &Model) -> Node<Msg> {
@ -27,7 +27,7 @@ pub fn view(model: &Model) -> Node<Msg> {
class_list: "avatar", class_list: "avatar",
url: page.avatar.url.as_deref(), url: page.avatar.url.as_deref(),
} }
.into_node(); .render();
let username = StyledInput { let username = StyledInput {
id: Some(FieldId::Profile(UsersFieldId::Username)), id: Some(FieldId::Profile(UsersFieldId::Username)),
@ -36,13 +36,13 @@ pub fn view(model: &Model) -> Node<Msg> {
variant: InputVariant::Primary, variant: InputVariant::Primary,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let username_field = StyledField { let username_field = StyledField {
label: "Username", label: "Username",
input: username, input: username,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let email = StyledInput { let email = StyledInput {
id: Some(FieldId::Profile(UsersFieldId::Email)), id: Some(FieldId::Profile(UsersFieldId::Email)),
@ -51,13 +51,13 @@ pub fn view(model: &Model) -> Node<Msg> {
variant: InputVariant::Primary, variant: InputVariant::Primary,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let email_field = StyledField { let email_field = StyledField {
label: "E-Mail", label: "E-Mail",
input: email, input: email,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let current_project = build_current_project(model, page); let current_project = build_current_project(model, page);
@ -70,12 +70,12 @@ pub fn view(model: &Model) -> Node<Msg> {
})), })),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let submit_field = StyledField { let submit_field = StyledField {
input: submit, input: submit,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let content = StyledForm { let content = StyledForm {
heading: "Profile", heading: "Profile",
@ -91,7 +91,7 @@ pub fn view(model: &Model) -> Node<Msg> {
submit_field, submit_field,
], ],
} }
.into_node(); .render();
inner_layout(model, "profile", &[content]) inner_layout(model, "profile", &[content])
} }
@ -137,18 +137,18 @@ fn build_current_project(model: &Model, page: &ProfilePage) -> Node<Msg> {
.collect(), .collect(),
..Default::default() ..Default::default()
} }
.into_node() .render()
}; };
StyledField { StyledField {
label: "Current project", label: "Current project",
input: div![C!["project-name"], inner], input: div![C!["project-name"], inner],
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn project_select_option<'l>(project: &'l Project) -> StyledSelectChild<'l> { fn project_select_option<'l>(project: &'l Project) -> StyledSelectOption<'l> {
StyledSelectChild { StyledSelectOption {
text: Some(project.name.as_str()), text: Some(project.name.as_str()),
value: project.id as u32, value: project.id as u32,
..Default::default() ..Default::default()

View File

@ -2,9 +2,9 @@ use seed::prelude::*;
use seed::*; use seed::*;
use crate::components::styled_button::StyledButton; use crate::components::styled_button::StyledButton;
use crate::components::styled_icon::Icon; use crate::components::styled_icon::{Icon, StyledIcon};
use crate::model::Model; use crate::model::Model;
use crate::shared::{inner_layout, ToNode}; use crate::shared::inner_layout;
use crate::Msg; use crate::Msg;
mod board; mod board;
@ -41,7 +41,11 @@ fn header(model: &Model) -> Node<Msg> {
if !model.show_extras { if !model.show_extras {
return Node::Empty; return Node::Empty;
} }
let button = StyledButton::secondary_with_text_and_icon("Repository", Icon::Github).into_node(); let button = StyledButton::secondary_with_text_and_icon(
"Repository",
StyledIcon::from(Icon::Github).render(),
)
.render();
div![ div![
id!["projectBoardHeader"], id!["projectBoardHeader"],
div![id!["boardName"], C!["headerChild"], "Kanban board"], div![id!["boardName"], C!["headerChild"], "Kanban board"],

View File

@ -6,7 +6,6 @@ use crate::components::styled_avatar::*;
use crate::components::styled_button::{ButtonVariant, StyledButton}; use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_icon::*; use crate::components::styled_icon::*;
use crate::model::PageContent; use crate::model::PageContent;
use crate::shared::ToNode;
use crate::{BoardPageChange, Model, Msg, Page, PageChanged}; use crate::{BoardPageChange, Model, Msg, Page, PageChanged};
pub fn project_board_lists(model: &Model) -> Node<Msg> { pub fn project_board_lists(model: &Model) -> Node<Msg> {
@ -37,7 +36,7 @@ pub fn project_board_lists(model: &Model) -> Node<Msg> {
let id = *id; let id = *id;
let edit_button = StyledButton { let edit_button = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
icon: Some(Icon::EditAlt.into_node()), icon: Some(StyledIcon::from(Icon::EditAlt).render()),
on_click: Some(mouse_ev("click", move |ev| { on_click: Some(mouse_ev("click", move |ev| {
ev.stop_propagation(); ev.stop_propagation();
ev.prevent_default(); ev.prevent_default();
@ -49,10 +48,10 @@ pub fn project_board_lists(model: &Model) -> Node<Msg> {
})), })),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let delete_button = StyledButton { let delete_button = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
icon: Some(Icon::DeleteAlt.into_node()), icon: Some(StyledIcon::from(Icon::DeleteAlt).render()),
on_click: Some(mouse_ev("click", move |ev| { on_click: Some(mouse_ev("click", move |ev| {
ev.stop_propagation(); ev.stop_propagation();
ev.prevent_default(); ev.prevent_default();
@ -64,7 +63,7 @@ pub fn project_board_lists(model: &Model) -> Node<Msg> {
})), })),
..Default::default() ..Default::default()
} }
.into_node(); .render();
div![ div![
C!["epicHeader"], C!["epicHeader"],
@ -138,7 +137,7 @@ fn project_issue(model: &Model, issue: &Issue) -> Node<Msg> {
name: &user.name, name: &user.name,
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node() .render()
}) })
.collect(); .collect();
@ -148,7 +147,7 @@ fn project_issue(model: &Model, issue: &Issue) -> Node<Msg> {
color: Some(issue.issue_type.to_str()), color: Some(issue.issue_type.to_str()),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let priority_icon = StyledIcon { let priority_icon = StyledIcon {
icon: issue.priority.into(), icon: issue.priority.into(),
@ -156,7 +155,7 @@ fn project_issue(model: &Model, issue: &Issue) -> Node<Msg> {
color: Some(issue.priority.to_str()), color: Some(issue.priority.to_str()),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let issue_id = issue.id; let issue_id = issue.id;
let drag_started = drag_ev(Ev::DragStart, move |ev| { let drag_started = drag_ev(Ev::DragStart, move |ev| {

View File

@ -6,7 +6,6 @@ use crate::components::styled_button::*;
use crate::components::styled_icon::*; use crate::components::styled_icon::*;
use crate::components::styled_input::*; use crate::components::styled_input::*;
use crate::model::PageContent; use crate::model::PageContent;
use crate::shared::ToNode;
use crate::{FieldId, Model, Msg}; use crate::{FieldId, Model, Msg};
pub fn project_board_filters(model: &Model) -> Node<Msg> { pub fn project_board_filters(model: &Model) -> Node<Msg> {
@ -22,7 +21,7 @@ pub fn project_board_filters(model: &Model) -> Node<Msg> {
icon: Some(Icon::Search), icon: Some(Icon::Search),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let only_my = StyledButton { let only_my = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
@ -32,7 +31,7 @@ pub fn project_board_filters(model: &Model) -> Node<Msg> {
on_click: Some(mouse_ev(Ev::Click, |_| Msg::ProjectToggleOnlyMy)), on_click: Some(mouse_ev(Ev::Click, |_| Msg::ProjectToggleOnlyMy)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let recently_updated = StyledButton { let recently_updated = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
@ -41,7 +40,7 @@ pub fn project_board_filters(model: &Model) -> Node<Msg> {
on_click: Some(mouse_ev(Ev::Click, |_| Msg::ProjectToggleRecentlyUpdated)), on_click: Some(mouse_ev(Ev::Click, |_| Msg::ProjectToggleRecentlyUpdated)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let clear_all = if project_page.only_my_filter let clear_all = if project_page.only_my_filter
|| project_page.recently_updated_filter || project_page.recently_updated_filter
@ -89,7 +88,7 @@ pub fn avatars_filters(model: &Model) -> Node<Msg> {
user_index: idx, user_index: idx,
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node(); .render();
div![ div![
IF![active => C!["isActive"]], IF![active => C!["isActive"]],
C!["avatarIsActiveBorder"], C!["avatarIsActiveBorder"],

View File

@ -12,11 +12,11 @@ use crate::components::styled_form::StyledForm;
use crate::components::styled_icon::{Icon, StyledIcon}; use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_input::{InputVariant, StyledInput}; use crate::components::styled_input::{InputVariant, StyledInput};
use crate::components::styled_select::{SelectVariant, StyledSelect}; use crate::components::styled_select::{SelectVariant, StyledSelect};
use crate::components::styled_select_child::StyledSelectChild; use crate::components::styled_select_child::StyledSelectOption;
use crate::components::styled_textarea::StyledTextarea; use crate::components::styled_textarea::StyledTextarea;
use crate::model::{self, ModalType, Model, PageContent}; use crate::model::{self, ModalType, Model, PageContent};
use crate::pages::project_settings_page::ProjectSettingsPage; use crate::pages::project_settings_page::ProjectSettingsPage;
use crate::shared::{inner_layout, ToNode}; use crate::shared::inner_layout;
use crate::{FieldId, Msg, PageChanged, ProjectFieldId, ProjectPageChange}; use crate::{FieldId, Msg, PageChanged, ProjectFieldId, ProjectPageChange};
// use crate::shared::styled_rte::StyledRte; // use crate::shared::styled_rte::StyledRte;
@ -40,10 +40,10 @@ pub fn view(model: &model::Model) -> Node<Msg> {
// StyledRte::build(FieldId::ProjectSettings(ProjectFieldId:: // StyledRte::build(FieldId::ProjectSettings(ProjectFieldId::
// Description)) .state(&page.description_rte) // Description)) .state(&page.description_rte)
// .build() // .build()
// .into_node(), // .render(),
// ) // )
// .build() // .build()
// .into_node(); // .render();
let category_field = category_field(page); let category_field = category_field(page);
@ -62,7 +62,7 @@ pub fn view(model: &model::Model) -> Node<Msg> {
text: Some("Save changes"), text: Some("Save changes"),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let form = StyledForm { let form = StyledForm {
heading: "Project Details", heading: "Project Details",
@ -83,7 +83,7 @@ pub fn view(model: &model::Model) -> Node<Msg> {
)) ))
})), })),
} }
.into_node(); .render();
let project_section = [div![C!["formContainer"], form]]; let project_section = [div![C!["formContainer"], form]];
@ -100,7 +100,7 @@ fn time_tracking_select(page: &ProjectSettingsPage) -> Node<Msg> {
), ),
class_list: "timeTracking", class_list: "timeTracking",
} }
.into_node(); .render();
let time_tracking_type: TimeTracking = page.time_tracking.value.into(); let time_tracking_type: TimeTracking = page.time_tracking.value.into();
StyledField { StyledField {
input: time_tracking, input: time_tracking,
@ -111,7 +111,7 @@ fn time_tracking_select(page: &ProjectSettingsPage) -> Node<Msg> {
}), }),
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn time_tracking_checkbox_option<'l>( fn time_tracking_checkbox_option<'l>(
@ -151,14 +151,14 @@ fn name_field(page: &ProjectSettingsPage) -> Node<Msg> {
disable_auto_resize: true, disable_auto_resize: true,
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Name", label: "Name",
input: name, input: name,
tip: Some(""), tip: Some(""),
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
/// Build project url input with styled field wrapper /// Build project url input with styled field wrapper
@ -171,14 +171,14 @@ fn url_field(page: &ProjectSettingsPage) -> Node<Msg> {
value: page.payload.url.as_deref().unwrap_or_default(), value: page.payload.url.as_deref().unwrap_or_default(),
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
label: "Url", label: "Url",
input: url, input: url,
tip: Some(""), tip: Some(""),
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
/// Build project description text area with styled field wrapper /// Build project description text area with styled field wrapper
@ -191,14 +191,14 @@ fn description_field(page: &ProjectSettingsPage) -> Node<Msg> {
mode: page.description_mode.clone(), mode: page.description_mode.clone(),
update_event: Ev::Change, update_event: Ev::Change,
} }
.into_node(); .render();
StyledField { StyledField {
label: "Description", label: "Description",
tip: Some("Describe the project in as much detail as you'd like."), tip: Some("Describe the project in as much detail as you'd like."),
input: description, input: description,
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
/// Build project category dropdown with styled field wrapper /// Build project category dropdown with styled field wrapper
@ -219,18 +219,18 @@ fn category_field(page: &ProjectSettingsPage) -> Node<Msg> {
)], )],
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
input: category, input: category,
label: "Project Category", label: "Project Category",
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
#[inline(always)] #[inline(always)]
fn category_select_option<'l>(pc: ProjectCategory) -> StyledSelectChild<'l> { fn category_select_option<'l>(pc: ProjectCategory) -> StyledSelectOption<'l> {
StyledSelectChild { StyledSelectOption {
class_list: pc.to_str(), class_list: pc.to_str(),
text: Some(pc.to_str()), text: Some(pc.to_str()),
value: pc.into(), value: pc.into(),
@ -266,7 +266,7 @@ fn columns_section(model: &Model, page: &ProjectSettingsPage) -> Node<Msg> {
input: columns_section, input: columns_section,
class_list: "columnsField", class_list: "columnsField",
} }
.into_node() .render()
} }
#[inline] #[inline]
@ -300,14 +300,14 @@ fn add_column(page: &ProjectSettingsPage, column_style: &str) -> Node<Msg> {
input_handlers: vec![blur], input_handlers: vec![blur],
..Default::default() ..Default::default()
} }
.into_node(); .render();
div![ div![
C!["columnPreview"], C!["columnPreview"],
div![C!["columnName"], form![on_submit, input]] div![C!["columnName"], form![on_submit, input]]
] ]
} else { } else {
let add_column = StyledIcon::from(Icon::Plus).into_node(); let add_column = StyledIcon::from(Icon::Plus).render();
div![ div![
C!["columnPreview"], C!["columnPreview"],
attrs![At::Style => column_style], attrs![At::Style => column_style],
@ -339,7 +339,7 @@ fn column_preview(
id: Some(FieldId::ProjectSettings(ProjectFieldId::IssueStatusName)), id: Some(FieldId::ProjectSettings(ProjectFieldId::IssueStatusName)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
div![C!["columnPreview"], div![C!["columnName"], input]] div![C!["columnPreview"], div![C!["columnName"], input]]
} else { } else {
@ -391,11 +391,11 @@ fn show_column_preview(
let delete = StyledButton { let delete = StyledButton {
variant: ButtonVariant::Primary, variant: ButtonVariant::Primary,
class_list: "removeColumn", class_list: "removeColumn",
icon: Some(Icon::Trash.into_node()), icon: Some(StyledIcon::from(Icon::Trash).render()),
on_click: Some(on_delete), on_click: Some(on_delete),
..Default::default() ..Default::default()
} }
.into_node(); .render();
div![C!["removeColumn"], delete] div![C!["removeColumn"], delete]
} else { } else {
div![ div![

View File

@ -9,7 +9,7 @@ use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_link::*; use crate::components::styled_link::*;
use crate::model::{Model, PageContent}; use crate::model::{Model, PageContent};
use crate::pages::reports_page::model::ReportsPage; use crate::pages::reports_page::model::ReportsPage;
use crate::shared::{inner_layout, ToNode}; use crate::shared::inner_layout;
use crate::{Msg, PageChanged, ReportsPageChange}; use crate::{Msg, PageChanged, ReportsPageChange};
const SVG_MARGIN_X: u32 = 10; const SVG_MARGIN_X: u32 = 10;
@ -202,9 +202,9 @@ fn issue_list(page: &ReportsPage, project_name: &str, this_month_updated: &[&Iss
let day = date.format("%Y-%m-%d").to_string(); let day = date.format("%Y-%m-%d").to_string();
let type_icon = StyledIcon::from(Icon::from(issue_type.clone())) let type_icon = StyledIcon::from(Icon::from(issue_type.clone()))
.into_node(); .render();
let priority_icon = StyledIcon::from(Icon::from(priority.clone())) let priority_icon = StyledIcon::from(Icon::from(priority.clone()))
.into_node(); .render();
let desc = Node::from_html(None, let desc = Node::from_html(None,
description description
.as_deref() .as_deref()
@ -212,12 +212,12 @@ fn issue_list(page: &ReportsPage, project_name: &str, this_month_updated: &[&Iss
); );
let link = StyledLink { let link = StyledLink {
children: vec![ children: vec![
Icon::Link.into_node(), StyledIcon::from(Icon::Link).render(),
span![format!("{}-{}", project_name, id).as_str()] span![format!("{}-{}", project_name, id).as_str()]
], ],
class_list: "withIcon", class_list: "withIcon",
href: format!("/issues/{}", id).as_str(), href: format!("/issues/{}", id).as_str(),
}.into_node(); }.render();
li![ li![
C!["issue", selection_state.to_str()], C!["issue", selection_state.to_str()],

View File

@ -8,7 +8,7 @@ use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_input::StyledInput; use crate::components::styled_input::StyledInput;
use crate::components::styled_link::StyledLink; use crate::components::styled_link::StyledLink;
use crate::model::{self, PageContent}; use crate::model::{self, PageContent};
use crate::shared::{outer_layout, ToNode}; use crate::shared::outer_layout;
use crate::validations::{is_email, is_token}; use crate::validations::{is_email, is_token};
use crate::{FieldId, Msg, SignInFieldId}; use crate::{FieldId, Msg, SignInFieldId};
@ -24,13 +24,13 @@ pub fn view(model: &model::Model) -> Node<Msg> {
id: Some(FieldId::SignIn(SignInFieldId::Username)), id: Some(FieldId::SignIn(SignInFieldId::Username)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let username_field = StyledField { let username_field = StyledField {
label: "Username", label: "Username",
input: username, input: username,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let email = StyledInput { let email = StyledInput {
value: page.email.as_str(), value: page.email.as_str(),
@ -38,13 +38,13 @@ pub fn view(model: &model::Model) -> Node<Msg> {
id: Some(FieldId::SignIn(SignInFieldId::Email)), id: Some(FieldId::SignIn(SignInFieldId::Email)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let email_field = StyledField { let email_field = StyledField {
label: "E-Mail", label: "E-Mail",
input: email, input: email,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let submit = if page.login_success { let submit = if page.login_success {
StyledButton { StyledButton {
@ -60,18 +60,18 @@ pub fn view(model: &model::Model) -> Node<Msg> {
..Default::default() ..Default::default()
} }
} }
.into_node(); .render();
let register_link = StyledLink { let register_link = StyledLink {
children: vec![span!["Register"]], children: vec![span!["Register"]],
class_list: "signUpLink", class_list: "signUpLink",
href: "/register", href: "/register",
} }
.into_node(); .render();
let submit_field = StyledField { let submit_field = StyledField {
input: div![C!["twoRow"], submit, register_link], input: div![C!["twoRow"], submit, register_link],
..Default::default() ..Default::default()
} }
.into_node(); .render();
let help_icon = StyledIcon { let help_icon = StyledIcon {
icon: Icon::Help, icon: Icon::Help,
@ -79,7 +79,7 @@ pub fn view(model: &model::Model) -> Node<Msg> {
size: Some(22), size: Some(22),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let no_pass_section = div![ let no_pass_section = div![
C!["noPasswordSection"], C!["noPasswordSection"],
@ -97,32 +97,32 @@ pub fn view(model: &model::Model) -> Node<Msg> {
Msg::SignInRequest Msg::SignInRequest
})), })),
} }
.into_node(); .render();
let token = StyledInput::new_with_id_and_value_and_valid( let token = StyledInput::new_with_id_and_value_and_valid(
FieldId::SignIn(SignInFieldId::Token), FieldId::SignIn(SignInFieldId::Token),
&page.token, &page.token,
is_valid_token(page.token_touched, page.token.as_str()), is_valid_token(page.token_touched, page.token.as_str()),
) )
.into_node(); .render();
let token_field = StyledField { let token_field = StyledField {
label: "Single use token", label: "Single use token",
input: token, input: token,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let submit_token = StyledButton { let submit_token = StyledButton {
variant: ButtonVariant::Primary, variant: ButtonVariant::Primary,
text: Some("Authorize"), text: Some("Authorize"),
on_click: Some(mouse_ev(Ev::Click, |_| Msg::BindClientRequest)), on_click: Some(mouse_ev(Ev::Click, |_| Msg::BindClientRequest)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let submit_token_field = StyledField { let submit_token_field = StyledField {
input: submit_token, input: submit_token,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let bind_token_form = StyledForm { let bind_token_form = StyledForm {
on_submit: Some(ev(Ev::Submit, |ev| { on_submit: Some(ev(Ev::Submit, |ev| {
@ -133,7 +133,7 @@ pub fn view(model: &model::Model) -> Node<Msg> {
fields: vec![token_field, submit_token_field], fields: vec![token_field, submit_token_field],
..Default::default() ..Default::default()
} }
.into_node(); .render();
let children = vec![sign_in_form, bind_token_form]; let children = vec![sign_in_form, bind_token_form];
outer_layout(model, "login", children) outer_layout(model, "login", children)

View File

@ -9,7 +9,7 @@ use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_input::StyledInput; use crate::components::styled_input::StyledInput;
use crate::components::styled_link::StyledLink; use crate::components::styled_link::StyledLink;
use crate::model::{self, PageContent}; use crate::model::{self, PageContent};
use crate::shared::{outer_layout, ToNode}; use crate::shared::outer_layout;
use crate::validations::is_email; use crate::validations::is_email;
use crate::{match_page, FieldId, Msg}; use crate::{match_page, FieldId, Msg};
@ -22,13 +22,13 @@ pub fn view(model: &model::Model) -> Node<Msg> {
id: Some(FieldId::SignUp(SignUpFieldId::Username)), id: Some(FieldId::SignUp(SignUpFieldId::Username)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let username_field = StyledField { let username_field = StyledField {
label: "Username", label: "Username",
input: username, input: username,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let email = StyledInput { let email = StyledInput {
value: page.email.as_str(), value: page.email.as_str(),
@ -36,13 +36,13 @@ pub fn view(model: &model::Model) -> Node<Msg> {
id: Some(FieldId::SignUp(SignUpFieldId::Email)), id: Some(FieldId::SignUp(SignUpFieldId::Email)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let email_field = StyledField { let email_field = StyledField {
label: "E-Mail", label: "E-Mail",
input: email, input: email,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let submit = if page.sign_up_success { let submit = if page.sign_up_success {
StyledButton { StyledButton {
@ -58,20 +58,20 @@ pub fn view(model: &model::Model) -> Node<Msg> {
..Default::default() ..Default::default()
} }
} }
.into_node(); .render();
let sign_in_link = StyledLink { let sign_in_link = StyledLink {
children: vec![span!["Sign In"]], children: vec![span!["Sign In"]],
class_list: "signInLink", class_list: "signInLink",
href: "/login", href: "/login",
} }
.into_node(); .render();
let submit_field = StyledField { let submit_field = StyledField {
input: div![C!["twoRow"], submit, sign_in_link], input: div![C!["twoRow"], submit, sign_in_link],
..Default::default() ..Default::default()
} }
.into_node(); .render();
let help_icon = StyledIcon { let help_icon = StyledIcon {
icon: Icon::Help, icon: Icon::Help,
@ -79,7 +79,7 @@ pub fn view(model: &model::Model) -> Node<Msg> {
size: Some(22), size: Some(22),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let no_pass_section = div![ let no_pass_section = div![
C!["noPasswordSection"], C!["noPasswordSection"],
@ -109,7 +109,7 @@ pub fn view(model: &model::Model) -> Node<Msg> {
error_row, error_row,
], ],
} }
.into_node(); .render();
let children = vec![sign_up_form]; let children = vec![sign_up_form];
outer_layout(model, "register", children) outer_layout(model, "register", children)
} }

View File

@ -7,10 +7,10 @@ use crate::components::styled_field::StyledField;
use crate::components::styled_form::StyledForm; use crate::components::styled_form::StyledForm;
use crate::components::styled_input::{InputVariant, StyledInput}; use crate::components::styled_input::{InputVariant, StyledInput};
use crate::components::styled_select::{SelectVariant, StyledSelect}; use crate::components::styled_select::{SelectVariant, StyledSelect};
use crate::components::styled_select_child::StyledSelectChild; use crate::components::styled_select_child::StyledSelectOption;
use crate::model::{InvitationFormState, Model, PageContent}; use crate::model::{InvitationFormState, Model, PageContent};
use crate::pages::users_page::UsersPage; use crate::pages::users_page::UsersPage;
use crate::shared::{inner_layout, ToNode}; use crate::shared::inner_layout;
use crate::validations::is_email; use crate::validations::is_email;
use crate::{FieldId, Msg, PageChanged, UsersPageChange}; use crate::{FieldId, Msg, PageChanged, UsersPageChange};
@ -27,13 +27,13 @@ pub fn view(model: &Model) -> Node<Msg> {
id: Some(FieldId::Users(UsersFieldId::Username)), id: Some(FieldId::Users(UsersFieldId::Username)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let name_field = StyledField { let name_field = StyledField {
label: "Name", label: "Name",
input: name, input: name,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let email = StyledInput { let email = StyledInput {
id: Some(FieldId::Users(UsersFieldId::Email)), id: Some(FieldId::Users(UsersFieldId::Email)),
@ -42,13 +42,13 @@ pub fn view(model: &Model) -> Node<Msg> {
variant: InputVariant::Normal, variant: InputVariant::Normal,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let email_field = StyledField { let email_field = StyledField {
input: email, input: email,
label: "E-Mail", label: "E-Mail",
..Default::default() ..Default::default()
} }
.into_node(); .render();
let user_role_field = user_role_select(page); let user_role_field = user_role_select(page);
@ -59,7 +59,7 @@ pub fn view(model: &Model) -> Node<Msg> {
active: page.form_state != InvitationFormState::Sent, active: page.form_state != InvitationFormState::Sent,
..Default::default() ..Default::default()
} }
.into_node(); .render();
let submit_supplement = match page.form_state { let submit_supplement = match page.form_state {
InvitationFormState::Succeed => StyledButton { InvitationFormState::Succeed => StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
@ -72,7 +72,7 @@ pub fn view(model: &Model) -> Node<Msg> {
button_type: "reset", button_type: "reset",
..Default::default() ..Default::default()
} }
.into_node(), .render(),
InvitationFormState::Failed => div![C!["error"], "There was an error"], InvitationFormState::Failed => div![C!["error"], "There was an error"],
_ => empty![], _ => empty![],
}; };
@ -80,7 +80,7 @@ pub fn view(model: &Model) -> Node<Msg> {
input: div![C!["invitationActions"], submit, submit_supplement], input: div![C!["invitationActions"], submit, submit_supplement],
..Default::default() ..Default::default()
} }
.into_node(); .render();
let form = StyledForm { let form = StyledForm {
heading: "Invite new user", heading: "Invite new user",
@ -90,7 +90,7 @@ pub fn view(model: &Model) -> Node<Msg> {
})), })),
fields: vec![name_field, email_field, user_role_field, submit_field], fields: vec![name_field, email_field, user_role_field, submit_field],
} }
.into_node(); .render();
let users: Vec<Node<Msg>> = page let users: Vec<Node<Msg>> = page
.invited_users .invited_users
@ -104,7 +104,7 @@ pub fn view(model: &Model) -> Node<Msg> {
})), })),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let role = page let role = page
.invitations .invitations
.iter() .iter()
@ -139,13 +139,13 @@ pub fn view(model: &Model) -> Node<Msg> {
on_click: Some(mouse_ev(Ev::Click, move |_| Msg::InviteRevokeRequest(id))), on_click: Some(mouse_ev(Ev::Click, move |_| Msg::InviteRevokeRequest(id))),
..Default::default() ..Default::default()
} }
.into_node(); .render();
// let revoke = StyledButton::build() // let revoke = StyledButton::build()
// .text("Revoke") // .text("Revoke")
// .disabled(invitation.state == InvitationState::Revoked) // .disabled(invitation.state == InvitationState::Revoked)
// .on_click(mouse_ev(Ev::Click, move |_| Msg::InviteRevokeRequest(id))) // .on_click(mouse_ev(Ev::Click, move |_| Msg::InviteRevokeRequest(id)))
// .build() // .build()
// .into_node(); // .render();
li![ li![
C!["invitation", invitation.state.to_str()], C!["invitation", invitation.state.to_str()],
span![invitation.name.as_str()], span![invitation.name.as_str()],
@ -178,19 +178,19 @@ fn user_role_select(page: &UsersPage) -> Node<Msg> {
options: Some(UserRole::default().into_iter().map(user_role_select_option)), options: Some(UserRole::default().into_iter().map(user_role_select_option)),
..Default::default() ..Default::default()
} }
.into_node(); .render();
StyledField { StyledField {
input: user_role, input: user_role,
label: "Role", label: "Role",
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
fn user_role_select_option<'l>(ur: UserRole) -> StyledSelectChild<'l> { fn user_role_select_option<'l>(ur: UserRole) -> StyledSelectOption<'l> {
let name = ur.to_str(); let name = ur.to_str();
StyledSelectChild { StyledSelectOption {
text: Some(name), text: Some(name),
value: ur.into(), value: ur.into(),
class_list: name, class_list: name,

View File

@ -4,7 +4,7 @@ use seed::*;
use crate::components::styled_icon::{Icon, StyledIcon}; use crate::components::styled_icon::{Icon, StyledIcon};
use crate::model::{Model, Page}; use crate::model::{Model, Page};
use crate::shared::{divider, ToNode}; use crate::shared::divider;
use crate::ws::enqueue_ws_msg; use crate::ws::enqueue_ws_msg;
use crate::{Msg, OperationKind, ResourceKind}; use crate::{Msg, OperationKind, ResourceKind};
@ -96,7 +96,7 @@ fn sidebar_link_item(model: &Model, name: &str, icon: Icon, page: Option<Page>)
None None
}; };
let active_flag = page.filter(|p| *p == model.page).map(|_| C!["active"]); let active_flag = page.filter(|p| *p == model.page).map(|_| C!["active"]);
let icon_node = StyledIcon::from(icon).into_node(); let icon_node = StyledIcon::from(icon).render();
let on_click = page.map(|p| { let on_click = page.map(|p| {
mouse_ev("click", move |ev| { mouse_ev("click", move |ev| {
ev.stop_propagation(); ev.stop_propagation();

View File

@ -42,10 +42,6 @@ pub fn go_to(url: &str, orders: &mut impl Orders<Msg>) {
} }
} }
pub trait ToNode {
fn into_node(self) -> Node<Msg>;
}
#[inline] #[inline]
pub fn divider() -> Node<Msg> { pub fn divider() -> Node<Msg> {
div![C!["divider"], ""] div![C!["divider"], ""]

View File

@ -8,7 +8,7 @@ use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_tooltip; use crate::components::styled_tooltip;
use crate::components::styled_tooltip::{StyledTooltip, TooltipVariant}; use crate::components::styled_tooltip::{StyledTooltip, TooltipVariant};
use crate::model::Model; use crate::model::Model;
use crate::shared::{divider, ToNode}; use crate::shared::divider;
use crate::ws::send_ws_msg; use crate::ws::send_ws_msg;
use crate::{Msg, Page}; use crate::{Msg, Page};
@ -29,7 +29,7 @@ impl IntoNavItemIcon for Icon {
size: Some(21), size: Some(21),
..Default::default() ..Default::default()
} }
.into_node() .render()
} }
} }
@ -56,7 +56,7 @@ pub fn render(model: &Model) -> Vec<Node<Msg>> {
name: &user.name, name: &user.name,
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node(); .render();
i![C!["styledIcon"], avatar] i![C!["styledIcon"], avatar]
} }
_ => StyledIcon { _ => StyledIcon {
@ -64,7 +64,7 @@ pub fn render(model: &Model) -> Vec<Node<Msg>> {
size: Some(21), size: Some(21),
..Default::default() ..Default::default()
} }
.into_node(), .render(),
}; };
let messages = if model.messages.is_empty() { let messages = if model.messages.is_empty() {
@ -177,7 +177,7 @@ fn messages_tooltip_popup(model: &Model) -> Node<Msg> {
children: vec![body], children: vec![body],
variant: TooltipVariant::Messages, variant: TooltipVariant::Messages,
} }
.into_node() .render()
} }
fn message_ui(model: &Model, message: &Message) -> Option<Node<Msg>> { fn message_ui(model: &Model, message: &Message) -> Option<Node<Msg>> {
@ -194,7 +194,7 @@ fn message_ui(model: &Model, message: &Message) -> Option<Node<Msg>> {
let hyperlink = if hyper_link.is_empty() && !hyper_link.starts_with('#') { let hyperlink = if hyper_link.is_empty() && !hyper_link.starts_with('#') {
empty![] empty![]
} else { } else {
let link_icon = StyledIcon::from(Icon::Link).into_node(); let link_icon = StyledIcon::from(Icon::Link).render();
div![ div![
C!["hyperlink"], C!["hyperlink"],
a![ a![
@ -209,7 +209,7 @@ fn message_ui(model: &Model, message: &Message) -> Option<Node<Msg>> {
let message_description = parse_description(model, description.as_str()); let message_description = parse_description(model, description.as_str());
let close_button = StyledButton { let close_button = StyledButton {
variant: ButtonVariant::Empty, variant: ButtonVariant::Empty,
icon: Some(Icon::Close.into_node()), icon: Some(StyledIcon::from(Icon::Close).render()),
on_click: Some(mouse_ev(Ev::Click, move |ev| { on_click: Some(mouse_ev(Ev::Click, move |ev| {
ev.stop_propagation(); ev.stop_propagation();
ev.prevent_default(); ev.prevent_default();
@ -217,7 +217,7 @@ fn message_ui(model: &Model, message: &Message) -> Option<Node<Msg>> {
})), })),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let top = div![ let top = div![
C!["top"], C!["top"],
div![C!["summary"], summary], div![C!["summary"], summary],
@ -231,7 +231,7 @@ fn message_ui(model: &Model, message: &Message) -> Option<Node<Msg>> {
variant: ButtonVariant::Primary, variant: ButtonVariant::Primary,
active: true, active: true,
text: Some("Accept"), text: Some("Accept"),
icon: Some(Icon::Check.into_node()), icon: Some(StyledIcon::from(Icon::Check).render()),
on_click: Some(mouse_ev(Ev::Click, move |ev| { on_click: Some(mouse_ev(Ev::Click, move |ev| {
ev.stop_propagation(); ev.stop_propagation();
ev.prevent_default(); ev.prevent_default();
@ -239,12 +239,12 @@ fn message_ui(model: &Model, message: &Message) -> Option<Node<Msg>> {
})), })),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let reject = StyledButton { let reject = StyledButton {
variant: ButtonVariant::Danger, variant: ButtonVariant::Danger,
active: true, active: true,
text: Some("Dismiss"), text: Some("Dismiss"),
icon: Some(Icon::Close.into_node()), icon: Some(StyledIcon::from(Icon::Close).render()),
on_click: Some(mouse_ev(Ev::Click, move |ev| { on_click: Some(mouse_ev(Ev::Click, move |ev| {
ev.stop_propagation(); ev.stop_propagation();
ev.prevent_default(); ev.prevent_default();
@ -252,7 +252,7 @@ fn message_ui(model: &Model, message: &Message) -> Option<Node<Msg>> {
})), })),
..Default::default() ..Default::default()
} }
.into_node(); .render();
div![ div![
C!["message"], C!["message"],
attrs![At::Class => format!("{}", message_type)], attrs![At::Class => format!("{}", message_type)],
@ -283,14 +283,14 @@ fn about_tooltip_popup(model: &Model) -> Node<Msg> {
text: Some("Visit Website"), text: Some("Visit Website"),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let github_repo = StyledButton { let github_repo = StyledButton {
variant: ButtonVariant::Secondary, variant: ButtonVariant::Secondary,
text: Some("Github Repo"), text: Some("Github Repo"),
icon: Some(Icon::Github.into_node()), icon: Some(StyledIcon::from(Icon::Github).render()),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let on_click = mouse_ev(Ev::Click, |_| { let on_click = mouse_ev(Ev::Click, |_| {
Msg::ToggleTooltip(styled_tooltip::TooltipVariant::About) Msg::ToggleTooltip(styled_tooltip::TooltipVariant::About)
@ -339,7 +339,7 @@ fn about_tooltip_popup(model: &Model) -> Node<Msg> {
children: vec![body], children: vec![body],
variant: TooltipVariant::About, variant: TooltipVariant::About,
} }
.into_node() .render()
} }
fn parse_description(model: &Model, desc: &str) -> Node<Msg> { fn parse_description(model: &Model, desc: &str) -> Node<Msg> {
@ -360,7 +360,7 @@ fn parse_description(model: &Model, desc: &str) -> Node<Msg> {
user_index: index, user_index: index,
..StyledAvatar::default() ..StyledAvatar::default()
} }
.into_node(); .render();
span![C!["mention"], avatar, user.name.as_str()] span![C!["mention"], avatar, user.name.as_str()]
}) })
.unwrap_or_else(|| span![word]); .unwrap_or_else(|| span![word]);

View File

@ -6,7 +6,6 @@ use crate::components::styled_icon::{Icon, StyledIcon};
use crate::modals::issues_edit::Model as EditIssueModal; use crate::modals::issues_edit::Model as EditIssueModal;
use crate::modals::time_tracking::value_for_time_tracking; use crate::modals::time_tracking::value_for_time_tracking;
use crate::model::{ModalType, Model}; use crate::model::{ModalType, Model};
use crate::shared::ToNode;
use crate::Msg; use crate::Msg;
#[inline] #[inline]
@ -69,7 +68,7 @@ pub fn tracking_widget(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
size: Some(32), size: Some(32),
..Default::default() ..Default::default()
} }
.into_node(); .render();
let bar_width = calc_bar_width(*estimate, *time_spent, *time_remaining); let bar_width = calc_bar_width(*estimate, *time_spent, *time_remaining);
let spent_text = match (time_spent, time_tracking_type) { let spent_text = match (time_spent, time_tracking_type) {