diff --git a/Cargo.lock b/Cargo.lock index 0e23ab66..89574163 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1722,6 +1722,7 @@ dependencies = [ "jirs-data", "js-sys", "lazy_static", + "num-traits", "seed", "serde", "syntect", diff --git a/jirs-client/Cargo.toml b/jirs-client/Cargo.toml index 693aeae6..0b93e208 100644 --- a/jirs-client/Cargo.toml +++ b/jirs-client/Cargo.toml @@ -31,6 +31,7 @@ uuid = { version = "0.8.1", features = ["serde"] } futures = "^0.1.26" comrak = "*" wee_alloc = "*" +num-traits = { version = "*" } lazy_static = "*" syntect = { version = "*", default-features = false, features = ["html", "regex-fancy", "dump-load-rs"] } diff --git a/jirs-client/js/css/styledDateTimeInput.css b/jirs-client/js/css/styledDateTimeInput.css index bd0a4c67..16a0a734 100644 --- a/jirs-client/js/css/styledDateTimeInput.css +++ b/jirs-client/js/css/styledDateTimeInput.css @@ -7,19 +7,11 @@ .dateTimeTooltip { padding: 15px; position: absolute; - top: 0; - width: 100%; -} - -@media (max-width: 1100px) { - .dateTimeTooltip { - padding: 15px; - position: absolute; - top: -50px; + top: -50px; left: 110px; - width: 610px; - min-width: 610px; - max-width: 610px; + width: 610px; + min-width: 610px; + max-width: 610px; } .dateTimeTooltip:before { @@ -35,6 +27,19 @@ z-index: -1; border-left: 1px solid rgba(9, 30, 66, 0.25); border-bottom: 1px solid rgba(9, 30, 66, 0.25); +} + +@media (max-width: 1100px) { + .dateTimeTooltip { + padding: 15px; + position: absolute; + top: 0; + left: 0; + width: 100%; + } + + .dateTimeTooltip:before { + display: none; } } @@ -45,11 +50,8 @@ font-size: 1.1rem; } -.dateTimeTooltip > .actions { - display: flex; - justify-content: space-between; - height: 2rem; - line-height: 2rem; +.dateTimeTooltip > h2 > .headerText { + line-height: 34px; } .dateTimeTooltip > .calendar { @@ -57,16 +59,6 @@ .dateTimeTooltip > .calendar > .week { display: flex; - border-left: 1px solid var(--textDarkest); - border-right: 1px solid var(--textDarkest); -} - -.dateTimeTooltip > .calendar > .week:first-child { - border-top: 1px solid var(--textDarkest); -} - -.dateTimeTooltip > .calendar > .week:last-child { - border-bottom: 1px solid var(--textDarkest); } .dateTimeTooltip > .calendar > .week.weekHeader { diff --git a/jirs-client/js/css/styledModal.css b/jirs-client/js/css/styledModal.css index a201e694..cab2813c 100644 --- a/jirs-client/js/css/styledModal.css +++ b/jirs-client/js/css/styledModal.css @@ -10,6 +10,11 @@ -webkit-overflow-scrolling: touch; } +.modal > .clickableOverlay { + min-height: 100%; + background: rgba(9, 30, 66, 0.54); +} + .modal > .clickableOverlay.center { display: flex; justify-content: center; diff --git a/jirs-client/src/shared/styled_date_time_input.rs b/jirs-client/src/shared/styled_date_time_input.rs index 6a230ec3..0583a97c 100644 --- a/jirs-client/src/shared/styled_date_time_input.rs +++ b/jirs-client/src/shared/styled_date_time_input.rs @@ -9,7 +9,9 @@ use { use crate::shared::styled_button::StyledButton; use crate::shared::styled_icon::Icon; +use crate::shared::styled_select::StyledSelect; use crate::shared::styled_tooltip::StyledTooltip; +use crate::shared::ToChild; use crate::{shared::ToNode, FieldId, Msg}; #[derive(Debug)] @@ -165,86 +167,113 @@ fn render(values: StyledDateTimeInput) -> Node { weeks.push(div![C!["week"], current_week]); } - let close_tooltip = { + 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() - .icon(Icon::Close) - .on_click(mouse_ev(Ev::Click, move |ev| { - ev.prevent_default(); - Some(Msg::StyledDateTimeInputChanged( - field_id, - 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 month_select = { + use num_traits::FromPrimitive; + let field_id = values.field_id.clone(); + let selected_month = Month::from_u32(current.month()).unwrap_or_else(|| Month::January); - 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], - ] + StyledSelect::build() + .options( + vec![ + Month::January, + Month::February, + Month::March, + Month::April, + Month::May, + Month::June, + Month::July, + Month::August, + Month::September, + Month::October, + Month::November, + Month::December, + ] + .into_iter() + .map(|month| (month.name().to_string(), month.number_from_month()).to_child()) + .collect(), + ) + .selected(vec![( + selected_month.name().to_string(), + selected_month.number_from_month(), + ) + .to_child()]) + .build(field_id) + .into_node() }; - let header_text = current.format("%B %Y").to_string(); + let year_select = { + let field_id = values.field_id.clone(); + let selected_year = current.year(); + StyledSelect::build() + .options( + (1980..=Utc::today().year()) + .into_iter() + .map(|i| (i as u32).to_child()) + .collect(), + ) + .selected(vec![(selected_year as u32).to_child()]) + .build(field_id) + .into_node() + }; let tooltip = StyledTooltip::build() .visible(values.popup_visible) .date_time_picker() - .add_child(h2![span![" "], span![header_text], close_tooltip]) - .add_child(actions) + .add_child(h2![ + left_action, + span![C!["headerText"], month_select, year_select], + right_action + ]) .add_child(div![ C!["calendar"], div![