Add date time input (needs style and handle time)

This commit is contained in:
Adrian Woźniak 2020-08-19 22:53:10 +02:00
parent 5c98e51a10
commit 7e4afa19bc
14 changed files with 233 additions and 86 deletions

View File

@ -4,7 +4,27 @@
/* TOOLTIP */
.dateTimeTooltip {
padding: 15px;
position: absolute;
top: 0;
width: 720px;
min-width: 720px;
max-width: 720px;
}
.dateTimeTooltip > h2 {
display: flex;
justify-content: space-between;
margin-bottom: 15px;
font-size: 1.1rem;
}
.dateTimeTooltip > .actions {
display: flex;
justify-content: space-between;
height: 2rem;
line-height: 2rem;
}
.dateTimeTooltip > .calendar {
@ -31,8 +51,8 @@
.dateTimeTooltip > .calendar > .week > .day {
width: calc(100% / 7);
text-align: center;
height: 3rem;
line-height: 3rem;
height: 2rem;
line-height: 2rem;
cursor: pointer;
}
@ -50,12 +70,11 @@
color: var(--textLight);
}
/*.styledDateTimeInput > .calendar > .week > .day > .weekday {*/
/* font-family: var(--font-bold);*/
/* line-height: 1.5rem;*/
/* font-size: 1rem;*/
/* cursor: pointer;*/
/*}*/
.dateTimeTooltip > .calendar > .week > .day.inCurrentMonth.selected,
.dateTimeTooltip > .calendar > .week > .day.outCurrentMonth.selected {
color: var(--primary);
background: var(--asideIcon);
}
.dateTimeTooltip > .calendar > .week > .day {
font-family: var(--font-medium);

View File

@ -376,3 +376,11 @@ i.styledIcon.listing-dots:before {
i.styledIcon.listing-number:before {
content: "\ef76";
}
i.styledIcon.double-left:before {
content: "\ea7b";
}
i.styledIcon.double-right:before {
content: "\ea7c";
}

View File

@ -8,9 +8,9 @@ pub use fields::*;
use jirs_data::*;
use crate::model::{ModalType, Model, Page};
use crate::shared::styled_date_time_input::DateTimeMsg;
use crate::shared::styled_date_time_input::StyledDateTimeChanged;
use crate::shared::styled_rte::RteMsg;
use crate::shared::styled_select::StyledSelectChange;
use crate::shared::styled_select::StyledSelectChanged;
use crate::shared::styled_tooltip::{Variant as StyledTooltip, Variant};
use crate::shared::{go_to_board, go_to_login, styled_tooltip};
use crate::ws::{flush_queue, open_socket, read_incoming, send_ws_msg};
@ -50,8 +50,8 @@ pub enum Msg {
UserChanged(Option<User>),
ProjectChanged(Option<Project>),
StyledSelectChanged(FieldId, StyledSelectChange),
StyledDateTimeInputChanged(FieldId, DateTimeMsg),
StyledSelectChanged(FieldId, StyledSelectChanged),
StyledDateTimeInputChanged(FieldId, StyledDateTimeChanged),
InternalFailure(String),
ToggleTooltip(StyledTooltip),
@ -195,6 +195,7 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
}
styled_tooltip::Variant::CodeBuilder => {}
Variant::TableBuilder => {}
Variant::DateTimeBuilder => {}
},
_ => (),
}

View File

@ -13,7 +13,7 @@ use crate::{
styled_input::StyledInput,
styled_modal::{StyledModal, Variant as ModalVariant},
styled_select::StyledSelect,
styled_select::StyledSelectChange,
styled_select::StyledSelectChanged,
styled_select_child::{StyledSelectChild, StyledSelectChildBuilder},
styled_textarea::StyledTextarea,
ToChild, ToNode,
@ -180,7 +180,7 @@ pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orde
// ReporterAddIssueModal
Msg::StyledSelectChanged(
FieldId::AddIssueModal(IssueFieldId::Reporter),
StyledSelectChange::Changed(id),
StyledSelectChanged::Changed(id),
) => {
modal.reporter_id = id.map(|n| n as UserId);
}
@ -188,7 +188,7 @@ pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orde
// AssigneesAddIssueModal
Msg::StyledSelectChanged(
FieldId::AddIssueModal(IssueFieldId::Assignees),
StyledSelectChange::Changed(Some(id)),
StyledSelectChanged::Changed(Some(id)),
) => {
let id = *id as UserId;
if !modal.user_ids.contains(&id) {
@ -197,7 +197,7 @@ pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orde
}
Msg::StyledSelectChanged(
FieldId::AddIssueModal(IssueFieldId::Assignees),
StyledSelectChange::RemoveMulti(id),
StyledSelectChanged::RemoveMulti(id),
) => {
let id = *id as i32;
let mut old: Vec<i32> = vec![];
@ -212,7 +212,7 @@ pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orde
// IssuePriorityAddIssueModal
Msg::StyledSelectChanged(
FieldId::AddIssueModal(IssueFieldId::Priority),
StyledSelectChange::Changed(Some(id)),
StyledSelectChanged::Changed(Some(id)),
) => {
modal.priority = (*id).into();
}
@ -240,14 +240,26 @@ pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
Type::Epic => {
let name_field = name_field(modal);
let starts = StyledDateTimeInput::build()
.state(&modal.epic_starts_at_state)
.build(FieldId::AddIssueModal(IssueFieldId::EpicStartsAt))
let starts = StyledField::build()
.input(
StyledDateTimeInput::build()
.state(&modal.epic_starts_at_state)
.build(FieldId::AddIssueModal(IssueFieldId::EpicStartsAt))
.into_node(),
)
.label("Starts at")
.build()
.into_node();
let end = StyledDateTimeInput::build()
.state(&modal.epic_ends_at_state)
.build(FieldId::AddIssueModal(IssueFieldId::EpicEndsAt))
let end = StyledField::build()
.input(
StyledDateTimeInput::build()
.state(&modal.epic_ends_at_state)
.build(FieldId::AddIssueModal(IssueFieldId::EpicEndsAt))
.into_node(),
)
.label("Ends at")
.build()
.into_node();
form.add_field(name_field).add_field(starts).add_field(end)

View File

@ -12,7 +12,7 @@ use crate::{
styled_field::StyledField,
styled_icon::Icon,
styled_input::StyledInput,
styled_select::{StyledSelect, StyledSelectChange},
styled_select::{StyledSelect, StyledSelectChanged},
styled_textarea::StyledTextarea,
tracking_widget::tracking_link,
ToChild, ToNode,
@ -34,7 +34,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Type)),
StyledSelectChange::Changed(Some(value)),
StyledSelectChanged::Changed(Some(value)),
) => {
modal.payload.issue_type = (*value).into();
send_ws_msg(
@ -49,7 +49,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::IssueStatusId)),
StyledSelectChange::Changed(Some(value)),
StyledSelectChanged::Changed(Some(value)),
) => {
modal.payload.issue_status_id = *value as IssueStatusId;
send_ws_msg(
@ -64,7 +64,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Reporter)),
StyledSelectChange::Changed(Some(value)),
StyledSelectChanged::Changed(Some(value)),
) => {
modal.payload.reporter_id = *value as i32;
send_ws_msg(
@ -79,7 +79,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Assignees)),
StyledSelectChange::Changed(Some(value)),
StyledSelectChanged::Changed(Some(value)),
) => {
modal.payload.user_ids.push(*value as i32);
send_ws_msg(
@ -94,7 +94,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Assignees)),
StyledSelectChange::RemoveMulti(value),
StyledSelectChanged::RemoveMulti(value),
) => {
let mut old = vec![];
std::mem::swap(&mut old, &mut modal.payload.user_ids);
@ -116,7 +116,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Priority)),
StyledSelectChange::Changed(Some(value)),
StyledSelectChanged::Changed(Some(value)),
) => {
modal.payload.priority = (*value).into();
send_ws_msg(
@ -185,7 +185,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::TimeSpent)),
StyledSelectChange::Changed(..),
StyledSelectChanged::Changed(..),
) => {
modal.payload.time_spent = modal.time_spent_select.values.get(0).map(|n| *n as i32);
send_ws_msg(
@ -216,7 +216,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::TimeRemaining)),
StyledSelectChange::Changed(..),
StyledSelectChanged::Changed(..),
) => {
modal.payload.time_remaining =
modal.time_remaining_select.values.get(0).map(|n| *n as i32);
@ -248,7 +248,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Estimate)),
StyledSelectChange::Changed(..),
StyledSelectChanged::Changed(..),
) => {
modal.payload.estimate = modal.estimate_select.values.get(0).map(|n| *n as i32);
send_ws_msg(
@ -263,7 +263,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::EpicName)),
StyledSelectChange::Changed(v),
StyledSelectChanged::Changed(v),
) => {
send_ws_msg(
WsMsg::IssueUpdate(

View File

@ -4,7 +4,7 @@ use web_sys::FormData;
use jirs_data::{ProjectId, UsersFieldId, WsMsg};
use crate::model::{Model, Page, PageContent, ProfilePage};
use crate::shared::styled_select::StyledSelectChange;
use crate::shared::styled_select::StyledSelectChanged;
use crate::ws::{board_load, send_ws_msg};
use crate::{FieldId, Msg, PageChanged, ProfilePageChange, WebSocketChanged};
@ -69,7 +69,7 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
}
Msg::StyledSelectChanged(
FieldId::Profile(UsersFieldId::CurrentProject),
StyledSelectChange::Changed(Some(id)),
StyledSelectChanged::Changed(Some(id)),
) => {
if let Some(up) = model
.user_projects

View File

@ -3,7 +3,7 @@ use seed::prelude::Orders;
use jirs_data::{Issue, IssueFieldId, WsMsg};
use crate::model::{ModalType, Model, Page, PageContent, ProjectPage};
use crate::shared::styled_select::StyledSelectChange;
use crate::shared::styled_select::StyledSelectChanged;
use crate::ws::{board_load, send_ws_msg};
use crate::{BoardPageChange, EditIssueModalSection, FieldId, Msg, PageChanged, WebSocketChanged};
@ -57,7 +57,7 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
}
Msg::StyledSelectChanged(
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Type)),
StyledSelectChange::Text(text),
StyledSelectChanged::Text(text),
) => {
let modal = model
.modals

View File

@ -6,7 +6,7 @@ use seed::prelude::Orders;
use jirs_data::{IssueStatus, IssueStatusId, ProjectFieldId, UpdateProjectPayload, WsMsg};
use crate::model::{Model, Page, PageContent, ProjectSettingsPage};
use crate::shared::styled_select::StyledSelectChange;
use crate::shared::styled_select::StyledSelectChanged;
use crate::ws::{board_load, send_ws_msg};
use crate::FieldChange::TabChanged;
use crate::{FieldId, Msg, PageChanged, ProjectPageChange, WebSocketChanged};
@ -68,7 +68,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::ProjectSettings(ProjectFieldId::Category),
StyledSelectChange::Changed(Some(value)),
StyledSelectChanged::Changed(Some(value)),
) => {
let category = value.into();
page.payload.category = Some(category);

View File

@ -13,7 +13,7 @@ use crate::shared::styled_tooltip::StyledTooltip;
use crate::{shared::ToNode, FieldId, Msg};
#[derive(Debug)]
pub enum DateTimeMsg {
pub enum StyledDateTimeChanged {
MonthChanged(Option<NaiveDateTime>),
DayChanged(Option<NaiveDateTime>),
PopupVisibilityChanged(bool),
@ -35,22 +35,35 @@ impl StyledDateTimeInputState {
}
}
pub fn reset(&mut self) {
self.timestamp = None;
self.popup_visible = false;
}
pub fn update(&mut self, msg: &Msg, _orders: &mut impl Orders<Msg>) {
match msg {
Msg::StyledDateTimeInputChanged(field_id, DateTimeMsg::MonthChanged(new_date))
if field_id == &self.field_id =>
{
Msg::StyledDateTimeInputChanged(
field_id,
StyledDateTimeChanged::MonthChanged(new_date),
) if field_id == &self.field_id => {
self.timestamp = *new_date;
}
Msg::StyledDateTimeInputChanged(field_id, DateTimeMsg::DayChanged(new_date))
if field_id == &self.field_id =>
{
Msg::StyledDateTimeInputChanged(
field_id,
StyledDateTimeChanged::DayChanged(new_date),
) if field_id == &self.field_id => {
self.timestamp = *new_date;
self.popup_visible = false;
}
Msg::StyledDateTimeInputChanged(field_id, DateTimeMsg::PopupVisibilityChanged(b))
if field_id == &self.field_id =>
{
self.popup_visible = *b;
Msg::StyledDateTimeInputChanged(
field_id,
StyledDateTimeChanged::PopupVisibilityChanged(b),
) if field_id == &self.field_id => {
if *b {
self.popup_visible = true;
} else {
self.reset();
}
}
_ => {}
}
@ -100,10 +113,10 @@ impl StyledDateTimeInputBuilder {
}
fn render(values: StyledDateTimeInput) -> Node<Msg> {
let current = values
let timestamp = values
.timestamp
.unwrap_or_else(|| chrono::Utc::now().naive_utc());
let start = current.with_day0(0).unwrap().date();
let start = timestamp.with_day0(0).unwrap();
let end = (start + Duration::days(32)).with_day0(0).unwrap();
let calendar_start = match start.weekday() {
@ -139,7 +152,12 @@ fn render(values: StyledDateTimeInput) -> Node<Msg> {
current_week = vec![];
}
current_week.push(day_cell(&current, &current_month_range));
current_week.push(day_cell(
&values.field_id,
&timestamp,
&current,
&current_month_range,
));
current += Duration::days(1);
}
@ -156,22 +174,77 @@ fn render(values: StyledDateTimeInput) -> Node<Msg> {
ev.prevent_default();
Some(Msg::StyledDateTimeInputChanged(
field_id,
DateTimeMsg::PopupVisibilityChanged(false),
StyledDateTimeChanged::PopupVisibilityChanged(false),
))
}))
.build()
.into_node()
};
let actions = {
let left_action = {
let field_id = values.field_id.clone();
let current = timestamp;
let on_click_left = mouse_ev(Ev::Click, move |ev| {
ev.stop_propagation();
ev.prevent_default();
let last_day_of_prev_month = current.with_day0(0).unwrap() - Duration::days(1);
let date = last_day_of_prev_month
.with_day0(timestamp.day0())
.unwrap_or_else(|| last_day_of_prev_month);
Msg::StyledDateTimeInputChanged(
field_id,
StyledDateTimeChanged::MonthChanged(Some(date)),
)
});
StyledButton::build()
.on_click(on_click_left)
.icon(Icon::DoubleLeft)
.empty()
.build()
.into_node()
};
let right_action = {
let field_id = values.field_id.clone();
let current = timestamp;
let on_click_right = mouse_ev(Ev::Click, move |ev| {
ev.stop_propagation();
ev.prevent_default();
let first_day_of_next_month = (current + Duration::days(32)).with_day0(0).unwrap();
let last_day_of_next_month = (first_day_of_next_month + Duration::days(32))
.with_day0(0)
.unwrap()
- Duration::days(1);
let date = first_day_of_next_month
.with_day0(timestamp.day0())
.unwrap_or_else(|| last_day_of_next_month);
Msg::StyledDateTimeInputChanged(
field_id,
StyledDateTimeChanged::MonthChanged(Some(date)),
)
});
StyledButton::build()
.on_click(on_click_right)
.icon(Icon::DoubleRight)
.empty()
.build()
.into_node()
};
div![
C!["actions"],
button![C!["prev"], left_action],
button![C!["next"], right_action],
]
};
let header_text = current.format("%B %Y").to_string();
let tooltip = StyledTooltip::build()
.visible(values.popup_visible)
.add_class("dateTimeTooltip")
.add_child(h2![span!["Add table"], close_tooltip])
.add_child(div![
C!["actions"],
button![C!["prev"], "Prev"],
button![C!["next"], "Next"],
])
.date_time_picker()
.add_child(h2![span![" "], span![header_text], close_tooltip])
.add_child(actions)
.add_child(div![
C!["calendar"],
div![
@ -194,17 +267,20 @@ fn render(values: StyledDateTimeInput) -> Node<Msg> {
let on_focus = ev(Ev::Click, move |ev| {
ev.prevent_default();
ev.stop_propagation();
Msg::StyledDateTimeInputChanged(field_id, DateTimeMsg::PopupVisibilityChanged(true))
Msg::StyledDateTimeInputChanged(
field_id,
StyledDateTimeChanged::PopupVisibilityChanged(true),
)
});
let text = values
.timestamp
.map(|d| format!("{}", d))
.unwrap_or_default();
.unwrap_or_else(|| Utc::now().naive_utc())
.date()
.format("%d/%m/%Y")
.to_string();
StyledButton::build()
.add_class("")
.on_click(on_focus)
.text(text)
.active(true)
.empty()
.build()
.into_node()
@ -218,7 +294,27 @@ fn render(values: StyledDateTimeInput) -> Node<Msg> {
]
}
fn day_cell(current: &NaiveDate, current_month_range: &RangeInclusive<NaiveDate>) -> Node<Msg> {
fn day_cell(
field_id: &FieldId,
timestamp: &NaiveDateTime,
current: &NaiveDateTime,
current_month_range: &RangeInclusive<NaiveDateTime>,
) -> Node<Msg> {
let selected_day_class = if *timestamp == *current {
"selected"
} else {
""
};
let on_click = {
let field_id = field_id.clone();
let date = *current;
ev(Ev::Click, move |ev| {
ev.stop_propagation();
ev.prevent_default();
Msg::StyledDateTimeInputChanged(field_id, StyledDateTimeChanged::DayChanged(Some(date)))
})
};
div![
C!["day"],
attrs![At::Class => format!("{}", current.weekday())],
@ -227,6 +323,8 @@ fn day_cell(current: &NaiveDate, current_month_range: &RangeInclusive<NaiveDate>
} else {
C!["outCurrentMonth"]
},
C![selected_day_class],
format!("{}", current.day()).as_str(),
on_click,
]
}

View File

@ -15,6 +15,9 @@ pub enum Icon {
Story,
Epic,
DoubleLeft,
DoubleRight,
ArrowDown,
ArrowLeftCircle,
ArrowUp,
@ -196,6 +199,9 @@ impl std::fmt::Display for Icon {
Icon::ListingDots => "listing-dots",
Icon::ListingNumber => "listing-number",
Icon::Epic => "epic",
Icon::DoubleLeft => "double-left",
Icon::DoubleRight => "double-right",
};
f.write_str(code)
}

View File

@ -1075,7 +1075,7 @@ fn code_tooltip(values: &StyledRte) -> Node<Msg> {
let languages = values.code_tooltip.languages();
let options: Vec<(String, u32)> = languages
.into_iter()
.iter()
.enumerate()
.map(|(idx, label)| (label.to_string(), idx as u32))
.collect();
@ -1146,7 +1146,3 @@ fn code_tooltip(values: &StyledRte) -> Node<Msg> {
.build()
.into_node()
}
// pub fn code_to_tag(code: &str) -> Node<Msg> {
// custom!["jirs-code-view", code]
// }

View File

@ -6,7 +6,7 @@ use crate::shared::ToNode;
use crate::{FieldId, Msg};
#[derive(Clone, Debug, PartialEq)]
pub enum StyledSelectChange {
pub enum StyledSelectChanged {
Text(String),
DropDownVisibility(bool),
Changed(Option<u32>),
@ -63,7 +63,7 @@ impl StyledSelectState {
pub fn update(&mut self, msg: &Msg, _orders: &mut impl Orders<Msg>) {
let ref id = self.field_id;
match msg {
Msg::StyledSelectChanged(field_id, StyledSelectChange::DropDownVisibility(b))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::DropDownVisibility(b))
if field_id == id =>
{
self.opened = *b;
@ -71,22 +71,22 @@ impl StyledSelectState {
self.text_filter.clear();
}
}
Msg::StyledSelectChanged(field_id, StyledSelectChange::Text(text))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::Text(text))
if field_id == id =>
{
self.text_filter = text.clone();
}
Msg::StyledSelectChanged(field_id, StyledSelectChange::Changed(Some(v)))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::Changed(Some(v)))
if field_id == id =>
{
self.values = vec![*v];
}
Msg::StyledSelectChanged(field_id, StyledSelectChange::Changed(None))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::Changed(None))
if field_id == id =>
{
self.values.clear();
}
Msg::StyledSelectChanged(field_id, StyledSelectChange::RemoveMulti(v))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::RemoveMulti(v))
if field_id == id =>
{
let mut old = vec![];
@ -256,14 +256,14 @@ pub fn render(values: StyledSelect) -> Node<Msg> {
let on_text = {
let field_id = id.clone();
input_ev(Ev::KeyUp, move |value| {
Msg::StyledSelectChanged(field_id, StyledSelectChange::Text(value))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::Text(value))
})
};
let on_handler = {
let field_id = id.clone();
mouse_ev(Ev::Click, move |_| {
Msg::StyledSelectChanged(field_id, StyledSelectChange::DropDownVisibility(!opened))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::DropDownVisibility(!opened))
})
};
@ -282,7 +282,7 @@ pub fn render(values: StyledSelect) -> Node<Msg> {
mouse_ev(Ev::Click, move |ev| {
ev.stop_propagation();
ev.prevent_default();
Msg::StyledSelectChanged(field_id, StyledSelectChange::Changed(None))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::Changed(None))
})
};
StyledIcon::build(Icon::Close)
@ -310,7 +310,7 @@ pub fn render(values: StyledSelect) -> Node<Msg> {
let on_change = {
let field_id = id.clone();
mouse_ev(Ev::Click, move |_| {
Msg::StyledSelectChanged(field_id, StyledSelectChange::Changed(Some(value)))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::Changed(Some(value)))
})
};
div![
@ -403,7 +403,7 @@ fn into_multi_value(opt: StyledSelectChildBuilder, id: FieldId) -> Node<Msg> {
let field_id = id.clone();
mouse_ev(Ev::Click, move |ev| {
ev.stop_propagation();
Msg::StyledSelectChanged(field_id, StyledSelectChange::RemoveMulti(value))
Msg::StyledSelectChanged(field_id, StyledSelectChanged::RemoveMulti(value))
})
};

View File

@ -9,6 +9,7 @@ pub enum Variant {
Messages,
TableBuilder,
CodeBuilder,
DateTimeBuilder,
}
impl Default for Variant {
@ -24,6 +25,7 @@ impl std::fmt::Display for Variant {
Variant::Messages => f.write_str("messages"),
Variant::TableBuilder => f.write_str("tableTooltip"),
Variant::CodeBuilder => f.write_str("codeTooltip"),
Variant::DateTimeBuilder => f.write_str("dateTimeTooltip"),
}
}
}
@ -94,6 +96,11 @@ impl StyledTooltipBuilder {
self
}
pub fn date_time_picker(mut self) -> Self {
self.variant = Variant::DateTimeBuilder;
self
}
pub fn build(self) -> StyledTooltip {
StyledTooltip {
visible: self.visible,

View File

@ -3,7 +3,7 @@ use seed::prelude::Orders;
use jirs_data::{InvitationState, UserRole, UsersFieldId, WsMsg};
use crate::model::{InvitationFormState, Model, Page, PageContent, UsersPage};
use crate::shared::styled_select::StyledSelectChange;
use crate::shared::styled_select::StyledSelectChanged;
use crate::ws::{invitation_load, send_ws_msg};
use crate::{FieldId, Msg, PageChanged, UsersPageChange, WebSocketChanged};
@ -74,7 +74,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::StyledSelectChanged(
FieldId::Users(UsersFieldId::UserRole),
StyledSelectChange::Changed(Some(role)),
StyledSelectChanged::Changed(Some(role)),
) => {
page.user_role = role.into();
}