fix(ui): switch to react-day-picker for silence modal

This commit is contained in:
Łukasz Mierzwa
2020-06-15 13:15:00 +01:00
committed by Łukasz Mierzwa
parent a22ccb1937
commit eaae762d6d
9 changed files with 909 additions and 755 deletions

50
ui/package-lock.json generated
View File

@@ -8386,6 +8386,7 @@
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz",
"integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==",
"dev": true,
"requires": {
"gud": "^1.0.0",
"warning": "^4.0.3"
@@ -8768,11 +8769,6 @@
}
}
},
"date-fns": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.14.0.tgz",
"integrity": "sha512-1zD+68jhFgDIM0rF05rcwYO8cExdNqxjq4xP1QKM60Q45mnO6zaMWB4tOzrIr4M4GSLntsKeE4c9Bdl2jhL/yw=="
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@@ -11633,7 +11629,8 @@
"gud": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==",
"dev": true
},
"gzip-size": {
"version": "5.1.1",
@@ -17123,7 +17120,8 @@
"popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
"dev": true
},
"portfinder": {
"version": "1.0.26",
@@ -18655,32 +18653,12 @@
"@babel/runtime": "^7.0.0"
}
},
"react-datepicker": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-3.0.0.tgz",
"integrity": "sha512-Yrxan1tERAiWS0EzitpiaiXOIz0APTUtV75uWbaS+jSaKoGCR6wUN2FDwr1ACGlnEoGhR9QQ2Vq3odnWtgJsOA==",
"react-day-picker": {
"version": "7.4.8",
"resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-7.4.8.tgz",
"integrity": "sha512-pp0hnxFVoRuBQcRdR1Hofw4CQtOCGVmzCNrscyvS0Q8NEc+UiYLEDqE5dk37bf0leSnBW4lheIt0CKKhuKzDVw==",
"requires": {
"classnames": "^2.2.6",
"date-fns": "^2.0.1",
"prop-types": "^15.7.2",
"react-onclickoutside": "^6.9.0",
"react-popper": "^1.3.4"
},
"dependencies": {
"react-popper": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.7.tgz",
"integrity": "sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww==",
"requires": {
"@babel/runtime": "^7.1.2",
"create-react-context": "^0.3.0",
"deep-equal": "^1.1.1",
"popper.js": "^1.14.4",
"prop-types": "^15.6.1",
"typed-styles": "^0.0.7",
"warning": "^4.0.2"
}
}
"prop-types": "^15.6.2"
}
},
"react-dev-utils": {
@@ -19170,11 +19148,6 @@
"resolved": "https://registry.npmjs.org/react-moment/-/react-moment-0.9.7.tgz",
"integrity": "sha512-ifzUrUGF6KRsUN2pRG5k56kO0mJBr8kRkWb0wNvtFIsBIxOuPxhUpL1YlXwpbQCbHq23hUu6A0VEk64HsFxk9g=="
},
"react-onclickoutside": {
"version": "6.9.0",
"resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.9.0.tgz",
"integrity": "sha512-8ltIY3bC7oGhj2nPAvWOGi+xGFybPNhJM0V1H8hY/whNcXgmDeaeoCMPPd8VatrpTsUWjb/vGzrmu6SrXVty3A=="
},
"react-popper": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.3.tgz",
@@ -22071,7 +22044,8 @@
"typed-styles": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
"integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
"integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==",
"dev": true
},
"typedarray": {
"version": "0.0.6",

View File

@@ -38,7 +38,7 @@
"react": "16.13.1",
"react-app-polyfill": "1.0.6",
"react-autosuggest": "10.0.2",
"react-datepicker": "3.0.0",
"react-day-picker": "7.4.8",
"react-dom": "16.13.1",
"react-highlighter": "0.4.3",
"react-hotkeys": "2.0.0",

View File

@@ -5,7 +5,8 @@ import { useObserver } from "mobx-react-lite";
import moment from "moment";
import DatePicker from "react-datepicker";
import DayPicker from "react-day-picker";
import "react-day-picker/lib/style.css";
import { SilenceFormStore } from "Stores/SilenceFormStore";
import { Duration } from "./Duration";
@@ -57,15 +58,31 @@ const TabContentStart = ({ silenceFormStore }) => {
return useObserver(() => (
<div className="d-flex flex-sm-row flex-column justify-content-around mx-3 mt-2">
<div className="d-flex justify-content-center align-items-center">
<DatePicker
inline
todayButton={"Today"}
minDate={moment().second(0).toDate()}
selected={silenceFormStore.data.startsAt.toDate()}
onChange={(val) => {
silenceFormStore.data.startsAt = moment(val);
<DayPicker
className="components-date-range"
month={silenceFormStore.data.startsAt.toDate()}
disabledDays={{
before: moment().second(0).toDate(),
}}
todayButton="Today"
onDayClick={(val, ...mod) => {
const startsAt = moment(val);
startsAt.set({
hour: silenceFormStore.data.startsAt.hour(),
minute: silenceFormStore.data.startsAt.minute(),
second: 0,
});
silenceFormStore.data.startsAt = startsAt;
silenceFormStore.data.verifyStarEnd();
}}
selectedDays={{
from: silenceFormStore.data.startsAt.toDate(),
to: silenceFormStore.data.endsAt.toDate(),
}}
modifiers={{
start: silenceFormStore.data.startsAt.toDate(),
end: silenceFormStore.data.endsAt.toDate(),
}}
/>
</div>
<HourMinute
@@ -83,15 +100,31 @@ const TabContentEnd = ({ silenceFormStore }) => {
return useObserver(() => (
<div className="d-flex flex-sm-row flex-column justify-content-around mx-3 mt-2">
<div className="d-flex justify-content-center align-items-center">
<DatePicker
inline
todayButton={"Today"}
minDate={moment().second(0).add(1, "minutes").toDate()}
selected={silenceFormStore.data.endsAt.toDate()}
onChange={(val) => {
silenceFormStore.data.endsAt = moment(val);
<DayPicker
className="components-date-range"
month={silenceFormStore.data.endsAt.toDate()}
disabledDays={{
before: moment().second(0).add(1, "minutes").toDate(),
}}
todayButton="Today"
onDayClick={(val) => {
const endsAt = moment(val);
endsAt.set({
hour: silenceFormStore.data.endsAt.hour(),
minute: silenceFormStore.data.endsAt.minute(),
second: 0,
});
silenceFormStore.data.endsAt = endsAt;
silenceFormStore.data.verifyStarEnd();
}}
selectedDays={{
from: silenceFormStore.data.startsAt.toDate(),
to: silenceFormStore.data.endsAt.toDate(),
}}
modifiers={{
start: silenceFormStore.data.startsAt.toDate(),
end: silenceFormStore.data.endsAt.toDate(),
}}
/>
</div>
<HourMinute
@@ -179,7 +212,7 @@ const DateTimeSelect = ({ silenceFormStore, openTab }) => {
};
}, [updateTimeNow]);
return (
return useObserver(() => (
<React.Fragment>
<ul className="nav nav-tabs nav-fill">
<Tab
@@ -237,7 +270,7 @@ const DateTimeSelect = ({ silenceFormStore, openTab }) => {
) : null}
</div>
</React.Fragment>
);
));
};
DateTimeSelect.propTypes = {
silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired,

View File

@@ -184,12 +184,12 @@ const MountedTabContentStart = () => {
};
describe("<TabContentStart />", () => {
it("selecting date on DatePicker updates startsAt", () => {
it("selecting date on DayPicker updates startsAt", () => {
const tree = MountedTabContentStart();
expect(silenceFormStore.data.startsAt.toISOString()).toBe(
moment([2060, 1, 1, 0, 0, 0]).toISOString()
);
tree.find("div.react-datepicker__day--018").simulate("click");
tree.find('div[aria-label="Wed Feb 18 2060"]').simulate("click");
expect(silenceFormStore.data.startsAt.toISOString()).toBe(
moment([2060, 1, 18, 0, 0, 0]).toISOString()
);
@@ -297,12 +297,12 @@ const MountedTabContentEnd = () => {
};
describe("<TabContentEnd />", () => {
it("Selecting date on DatePicker updates endsAt", () => {
it("Selecting date on DayPicker updates endsAt", () => {
const tree = MountedTabContentEnd();
expect(silenceFormStore.data.endsAt.toISOString()).toBe(
moment([2061, 1, 1, 0, 0, 0]).toISOString()
);
tree.find("div.react-datepicker__day--024").simulate("click");
tree.find('div[aria-label="Thu Feb 24 2061"]').simulate("click");
expect(silenceFormStore.data.endsAt.toISOString()).toBe(
moment([2061, 1, 24, 0, 0, 0]).toISOString()
);

View File

@@ -4,6 +4,8 @@ import fetchMock from "fetch-mock";
import { storiesOf } from "@storybook/react";
import moment from "moment";
import { MockSilence } from "__mocks__/Alerts";
import { AlertStore } from "Stores/AlertStore";
import { Settings } from "Stores/Settings";
@@ -101,7 +103,10 @@ storiesOf("SilenceModal", module)
silenceFormStore.data.addEmptyMatcher();
silenceFormStore.data.author = "john@example.com";
silenceFormStore.data.comment = "fake silence";
silenceFormStore.data.resetStartEnd();
silenceFormStore.data.silenceID = "1234567890";
silenceFormStore.data.startsAt = moment();
silenceFormStore.data.endsAt = moment().add(2, "hour").add(10, "day");
silenceFormStore.tab.current = SilenceTabNames.Editor;

View File

@@ -1,28 +1,65 @@
@import "~react-datepicker/src/stylesheets/datepicker.scss";
.react-datepicker {
background-color: $datepicker__background-color;
}
.react-datepicker__week {
& > .react-datepicker__day:hover:not(.react-datepicker__day--disabled) {
color: $datepicker__day-hover-color;
border-color: $datepicker__border-color;
.components-date-range.DayPicker {
.DayPicker-wrapper {
outline: none;
}
& > .react-datepicker__day:not(.react-datepicker__day--disabled) {
border-width: 1px;
border-style: solid;
border-color: transparent;
.DayPicker-Weekday {
font-weight: 600;
}
.DayPicker-Month {
border-collapse: inherit;
border-spacing: 0 1px;
}
.DayPicker-Day {
&:not(.DayPicker-Day--disabled):not(.DayPicker-Day--outside):not(.DayPicker-Day--selected):hover {
background-color: $light;
border-radius: 50%;
}
&.DayPicker-Day--today {
color: $dark;
}
&.DayPicker-Day--disabled {
color: $secondary;
}
&.DayPicker-Day--selected {
border-radius: 0;
&.DayPicker-Day--start {
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
font-weight: 600;
}
&.DayPicker-Day--end {
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
font-weight: 600;
}
&.DayPicker-Day--start:not(.DayPicker-Day--outside),
&.DayPicker-Day--end:not(.DayPicker-Day--outside) {
background-color: $primary;
color: $white;
}
&:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside) {
background-color: $light;
color: $components-date-range-sub-color;
}
}
}
.DayPicker-TodayButton {
color: $components-date-range-today-color;
font-weight: 600;
}
.DayPicker-Footer {
display: flex;
justify-content: space-around;
}
}
.react-datepicker__day-names {
& > .react-datepicker__day-name {
color: $datepicker__day-name-color;
}
}
.react-datepicker__today-button {
border-bottom-left-radius: $datepicker__border-radius;
border-bottom-right-radius: $datepicker__border-radius;
}

View File

@@ -85,19 +85,8 @@ $filterinput-border: $navbar-dark-color;
$grid-swimlane-bg: lighten($dark, 2%);
$bg-focused: darken($blue, 5%);
$datepicker__background-color: $gray-700;
$datepicker__border-color: $gray-800;
$datepicker__highlighted-color: $white;
$datepicker__muted-color: $gray-600;
$datepicker__selected-color: $primary;
$datepicker__text-color: $gray-300;
$datepicker__header-color: $white;
$datepicker__navigation-disabled-color: $gray-500;
$datepicker__font-size: $font-size-base;
$datepicker__font-family: $font-family-sans-serif;
$datepicker__border-radius: 0.25rem;
$datepicker__day-name-color: $white;
$datepicker__day-hover-color: $white;
$components-date-range-today-color: $white;
$components-date-range-sub-color: $white;
$input-range-neutral-color: $gray-300;
$input-range-neutral-light-color: $secondary;

View File

@@ -67,19 +67,8 @@ $filterinput-border: $navbar-dark-color;
$grid-swimlane-bg: lighten($dark, 2%);
$bg-focused: lighten($blue, 5%);
$datepicker__background-color: $white;
$datepicker__border-color: $gray-300;
$datepicker__highlighted-color: $secondary;
$datepicker__muted-color: $gray-600;
$datepicker__selected-color: $primary;
$datepicker__text-color: $black;
$datepicker__header-color: $black;
$datepicker__navigation-disabled-color: $gray-600;
$datepicker__font-size: $font-size-base;
$datepicker__font-family: $font-family-sans-serif;
$datepicker__border-radius: 0.25rem;
$datepicker__day-name-color: $black;
$datepicker__day-hover-color: $black;
$components-date-range-today-color: $black;
$components-date-range-sub-color: $black;
$input-range-neutral-color: $dark;
$input-range-neutral-light-color: $gray-400;