From eaae762d6d09fa9527857503cc29ee21cd006fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Mon, 15 Jun 2020 13:15:00 +0100 Subject: [PATCH] fix(ui): switch to react-day-picker for silence modal --- ui/package-lock.json | 50 +- ui/package.json | 2 +- .../__snapshots__/index.test.js.snap | 1413 +++++++++-------- .../SilenceModal/DateTimeSelect/index.js | 67 +- .../SilenceModal/DateTimeSelect/index.test.js | 8 +- .../Components/SilenceModal/index.stories.js | 7 +- ui/src/Styles/Components/DateTimeSelect.scss | 87 +- ui/src/Styles/DarkTheme.scss | 15 +- ui/src/Styles/LightTheme.scss | 15 +- 9 files changed, 909 insertions(+), 755 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index 624d9d209..ec033cde2 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -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", diff --git a/ui/package.json b/ui/package.json index 5355d5420..676b748e4 100644 --- a/ui/package.json +++ b/ui/package.json @@ -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", diff --git a/ui/src/Components/SilenceModal/DateTimeSelect/__snapshots__/index.test.js.snap b/ui/src/Components/SilenceModal/DateTimeSelect/__snapshots__/index.test.js.snap index 6767e15f2..e1b3de4fc 100644 --- a/ui/src/Components/SilenceModal/DateTimeSelect/__snapshots__/index.test.js.snap +++ b/ui/src/Components/SilenceModal/DateTimeSelect/__snapshots__/index.test.js.snap @@ -264,350 +264,408 @@ exports[` 'Ends' tab matches snapshot 1`] = `
-
-
-
-
- - -
-
-
- February 2061 -
-
-
-
-
- Su -
-
- Mo -
-
- Tu -
-
- We -
-
- Th -
-
- Fr -
-
- Sa -
-
-
-
-
-
- 30 -
-
- 31 -
-
- 1 -
-
- 2 -
-
- 3 -
-
- 4 -
-
- 5 + + + +
+
+
+
+
+ February 2061
-
-
+
- 6 -
-
- 7 -
-
- 8 -
-
- 9 -
-
- 10 -
-
- 11 -
-
- 12 +
+ + Su + +
+
+ + Mo + +
+
+ + Tu + +
+
+ + We + +
+
+ + Th + +
+
+ + Fr + +
+
+ + Sa + +
-
-
+
- 13 +
+
+
+
+
+ 1 +
+
+ 2 +
+
+ 3 +
+
+ 4 +
+
+ 5 +
-
- 14 +
+ 6 +
+
+ 7 +
+
+ 8 +
+
+ 9 +
+
+ 10 +
+
+ 11 +
+
+ 12 +
-
- 15 +
+ 13 +
+
+ 14 +
+
+ 15 +
+
+ 16 +
+
+ 17 +
+
+ 18 +
+
+ 19 +
-
- 16 +
+ 20 +
+
+ 21 +
+
+ 22 +
+
+ 23 +
+
+ 24 +
+
+ 25 +
+
+ 26 +
-
- 17 -
-
- 18 -
-
- 19 -
-
-
-
- 20 -
-
- 21 -
-
- 22 -
-
- 23 -
-
- 24 -
-
- 25 -
-
- 26 -
-
-
-
- 27 -
-
- 28 -
-
- 1 -
-
- 2 -
-
- 3 -
-
- 4 -
-
- 5 +
+ 27 +
+
+ 28 +
+
+
+
+
+
+
+
+
+
+
-
- Today +
+
@@ -757,344 +815,413 @@ exports[` 'Starts' tab matches snapshot 1`] = `
-
-
-
-
- -
-
-
- February 2060 -
-
-
-
-
- Su -
-
- Mo -
-
- Tu -
-
- We -
-
- Th -
-
- Fr -
-
- Sa -
-
-
-
+
+
+ -
-
- 1 -
-
- 2 -
-
- 3 -
-
- 4 -
-
- 5 -
-
- 6 -
-
- 7 + + + +
+
+
+
+
+ February 2060
-
-
+
- 8 -
-
- 9 -
-
- 10 -
-
- 11 -
-
- 12 -
-
- 13 -
-
- 14 +
+ + Su + +
+
+ + Mo + +
+
+ + Tu + +
+
+ + We + +
+
+ + Th + +
+
+ + Fr + +
+
+ + Sa + +
-
-
+
- 15 +
+ 1 +
+
+ 2 +
+
+ 3 +
+
+ 4 +
+
+ 5 +
+
+ 6 +
+
+ 7 +
-
- 16 +
+ 8 +
+
+ 9 +
+
+ 10 +
+
+ 11 +
+
+ 12 +
+
+ 13 +
+
+ 14 +
-
- 17 +
+ 15 +
+
+ 16 +
+
+ 17 +
+
+ 18 +
+
+ 19 +
+
+ 20 +
+
+ 21 +
-
- 18 +
+ 22 +
+
+ 23 +
+
+ 24 +
+
+ 25 +
+
+ 26 +
+
+ 27 +
+
+ 28 +
-
- 19 -
-
- 20 -
-
- 21 -
-
-
-
- 22 -
-
- 23 -
-
- 24 -
-
- 25 -
-
- 26 -
-
- 27 -
-
- 28 -
-
-
-
- 29 -
-
- 1 -
-
- 2 -
-
- 3 -
-
- 4 -
-
- 5 -
-
- 6 +
+ 29 +
+
+
+
+
+
+
+
+
+
+
+
+
-
- Today +
+
diff --git a/ui/src/Components/SilenceModal/DateTimeSelect/index.js b/ui/src/Components/SilenceModal/DateTimeSelect/index.js index ae9a4d749..bd7191f28 100644 --- a/ui/src/Components/SilenceModal/DateTimeSelect/index.js +++ b/ui/src/Components/SilenceModal/DateTimeSelect/index.js @@ -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(() => (
- { - silenceFormStore.data.startsAt = moment(val); + { + 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(), + }} />
{ return useObserver(() => (
- { - silenceFormStore.data.endsAt = moment(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(), + }} />
{ }; }, [updateTimeNow]); - return ( + return useObserver(() => (
    { ) : null}
- ); + )); }; DateTimeSelect.propTypes = { silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired, diff --git a/ui/src/Components/SilenceModal/DateTimeSelect/index.test.js b/ui/src/Components/SilenceModal/DateTimeSelect/index.test.js index 3e4e1f46e..e1a0e1b71 100644 --- a/ui/src/Components/SilenceModal/DateTimeSelect/index.test.js +++ b/ui/src/Components/SilenceModal/DateTimeSelect/index.test.js @@ -184,12 +184,12 @@ const MountedTabContentStart = () => { }; describe("", () => { - 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("", () => { - 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() ); diff --git a/ui/src/Components/SilenceModal/index.stories.js b/ui/src/Components/SilenceModal/index.stories.js index 2f42768c3..d8486329f 100644 --- a/ui/src/Components/SilenceModal/index.stories.js +++ b/ui/src/Components/SilenceModal/index.stories.js @@ -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; diff --git a/ui/src/Styles/Components/DateTimeSelect.scss b/ui/src/Styles/Components/DateTimeSelect.scss index 249846403..e18818d1e 100644 --- a/ui/src/Styles/Components/DateTimeSelect.scss +++ b/ui/src/Styles/Components/DateTimeSelect.scss @@ -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; -} diff --git a/ui/src/Styles/DarkTheme.scss b/ui/src/Styles/DarkTheme.scss index c33e2351a..f96d92f89 100644 --- a/ui/src/Styles/DarkTheme.scss +++ b/ui/src/Styles/DarkTheme.scss @@ -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; diff --git a/ui/src/Styles/LightTheme.scss b/ui/src/Styles/LightTheme.scss index 9333f0342..4aafa3900 100644 --- a/ui/src/Styles/LightTheme.scss +++ b/ui/src/Styles/LightTheme.scss @@ -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;