From 50c01d5a40aef734b74962b4c4c70525d364569f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Thu, 28 Mar 2024 08:40:44 +0100 Subject: [PATCH] Change: Update datepicker to use current version of react-datepicker react-datepicker > 1.8.0 dropped the usage of moment.js and requires native JS Date objects as inputs. Therefore we didn't update it for a long time. This change adjusts our own datepicker component to still use moment.js dates and passes the wrapped JS Date objects to react-datepicker. Because native Date objects don't know anything about timezone the datepicker component requires a timezone prop now to be able to convert the native Date object into a timezone aware moment.js date. This change might also fix a small issue with out datepicker component on initial creation. The datepicker created a moment.js date having possibly the wrong timezone information. Also with updating react-datepicker to the latest release all blockers for updating to React 18 are resolved. --- package-lock.json | 180 ++++++++---------- package.json | 2 +- src/web/components/form/datepicker.js | 47 ++--- .../performance/startendtimeselection.js | 2 + src/web/pages/schedules/dialog.js | 1 + src/web/wizard/advancedtaskwizard.js | 1 + src/web/wizard/modifytaskwizard.js | 1 + 7 files changed, 115 insertions(+), 119 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5472dfdf3c..537a9f7a00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "qs": "^6.11.2", "react": "^16.14.0", "react-beautiful-dnd": "^13.1.1", - "react-datepicker": "^1.8.0", + "react-datepicker": "^6.0.0", "react-dom": "^16.14.0", "react-redux": "^8.1.3", "react-router-dom": "^5.2.0", @@ -2591,6 +2591,54 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.10", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.10.tgz", + "integrity": "sha512-sh6f9gVvWQdEzLObrWbJ97c0clJObiALsFe0LiR/kb3tDRKwEhObASEH2QyfdoO/ZBPzwxa9j+nYFo+sqgbioA==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@floating-ui/utils": "^0.2.0", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -2624,20 +2672,6 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "license": "BSD-3-Clause" }, - "node_modules/@hypnosphi/create-react-context": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz", - "integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==", - "license": "MIT", - "dependencies": { - "gud": "^1.0.0", - "warning": "^4.0.3" - }, - "peerDependencies": { - "prop-types": "^15.0.0", - "react": ">=0.14.0" - } - }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -7099,6 +7133,14 @@ "node": ">=12" } }, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -8144,6 +8186,15 @@ "node": ">=12" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -10444,12 +10495,6 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "license": "MIT" }, - "node_modules/gud": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", - "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==", - "license": "MIT" - }, "node_modules/gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", @@ -16565,16 +16610,6 @@ "semver-compare": "^1.0.0" } }, - "node_modules/popper.js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", - "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", - "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, "node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -18220,20 +18255,19 @@ } }, "node_modules/react-datepicker": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-1.8.0.tgz", - "integrity": "sha512-N4LdVTtqJCsZyKXBQ/AqSEcH6FyhgsY1gD07zECNu60nGt5s4ngRlhYdHoE34VNFO+ZY+pvljZRLwSC8LS9RxQ==", - "license": "MIT", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-6.6.0.tgz", + "integrity": "sha512-ERC0/Q4pPC9bNIcGUpdCbHc+oCxhkU3WI3UOGHkyJ3A9fqALCYpEmLc5S5xvAd7DuCDdbsyW97oRPM6pWWwjww==", "dependencies": { - "classnames": "^2.2.5", - "prop-types": "^15.6.0", - "react-onclickoutside": "^6.7.1", - "react-popper": "^1.0.2" + "@floating-ui/react": "^0.26.2", + "clsx": "^2.1.0", + "date-fns": "^3.3.1", + "prop-types": "^15.7.2", + "react-onclickoutside": "^6.13.0" }, "peerDependencies": { - "moment": "^2.20.0", - "react": "^16.0.0", - "react-dom": "^16.0.0" + "react": "^16.9.0 || ^17 || ^18", + "react-dom": "^16.9.0 || ^17 || ^18" } }, "node_modules/react-dev-utils": { @@ -18308,10 +18342,9 @@ "license": "MIT" }, "node_modules/react-onclickoutside": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.12.2.tgz", - "integrity": "sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA==", - "license": "MIT", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz", + "integrity": "sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A==", "funding": { "type": "individual", "url": "https://github.com/Pomax/react-onclickoutside/blob/master/FUNDING.md" @@ -18321,41 +18354,6 @@ "react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x" } }, - "node_modules/react-popper": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz", - "integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.1.2", - "@hypnosphi/create-react-context": "^0.3.1", - "deep-equal": "^1.1.1", - "popper.js": "^1.14.4", - "prop-types": "^15.6.1", - "typed-styles": "^0.0.7", - "warning": "^4.0.2" - }, - "peerDependencies": { - "react": "0.14.x || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/react-popper/node_modules/deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "license": "MIT", - "dependencies": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/react-redux": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", @@ -21582,6 +21580,11 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "license": "MIT" }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "node_modules/tailwindcss": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.7.tgz", @@ -22011,12 +22014,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typed-styles": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", - "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==", - "license": "MIT" - }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -22337,15 +22334,6 @@ "makeerror": "1.0.12" } }, - "node_modules/warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/package.json b/package.json index 61b8079f4d..ba7dd57e51 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "qs": "^6.11.2", "react": "^16.14.0", "react-beautiful-dnd": "^13.1.1", - "react-datepicker": "^1.8.0", + "react-datepicker": "^6.0.0", "react-dom": "^16.14.0", "react-redux": "^8.1.3", "react-router-dom": "^5.2.0", diff --git a/src/web/components/form/datepicker.js b/src/web/components/form/datepicker.js index 455b0d340c..4820690a81 100644 --- a/src/web/components/form/datepicker.js +++ b/src/web/components/form/datepicker.js @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import React from 'react'; +import React, {useCallback} from 'react'; import styled from 'styled-components'; @@ -73,32 +73,34 @@ InputField.propTypes = { onClick: PropTypes.func, }; -const DatePickerComponent = props => { - const handleChange = value => { - const {name, onChange} = props; - - if (isDefined(onChange)) { - onChange(value, name); - } - }; - - const { - disabled, - minDate = date(), - name, - width, - value = date(), - ...restProps - } = props; - +const DatePickerComponent = ({ + disabled, + timezone, + minDate = date().tz(timezone), + name, + width, + value = date().tz(timezone), + onChange, + ...restProps +}) => { + const handleChange = useCallback( + newValue => { + if (isDefined(onChange)) { + onChange(date(newValue).tz(timezone), name); + } + }, + [name, onChange, timezone], + ); return ( } - minDate={minDate === false ? undefined : minDate} - maxDate={date().add(3, 'years')} - selected={value} + minDate={ + minDate === false || !isDefined(minDate) ? undefined : minDate.toDate() + } + maxDate={date().add(3, 'years').toDate()} + selected={value.toDate()} todayButton={_('Today')} locale={getLocale()} onChange={handleChange} @@ -110,6 +112,7 @@ DatePickerComponent.propTypes = { disabled: PropTypes.bool, minDate: PropTypes.oneOfType([PropTypes.date, PropTypes.oneOf([false])]), name: PropTypes.string, + timezone: PropTypes.string.isRequired, value: PropTypes.date.isRequired, width: PropTypes.string, onChange: PropTypes.func, diff --git a/src/web/pages/performance/startendtimeselection.js b/src/web/pages/performance/startendtimeselection.js index 1f928764d8..8deeb91d15 100644 --- a/src/web/pages/performance/startendtimeselection.js +++ b/src/web/pages/performance/startendtimeselection.js @@ -118,6 +118,7 @@ class StartTimeSelection extends React.Component { @@ -149,6 +150,7 @@ class StartTimeSelection extends React.Component { diff --git a/src/web/pages/schedules/dialog.js b/src/web/pages/schedules/dialog.js index 3b4372b312..e0ac9b1850 100644 --- a/src/web/pages/schedules/dialog.js +++ b/src/web/pages/schedules/dialog.js @@ -435,6 +435,7 @@ class ScheduleDialog extends React.Component { diff --git a/src/web/wizard/modifytaskwizard.js b/src/web/wizard/modifytaskwizard.js index 77619c2ebb..6f0783d44c 100644 --- a/src/web/wizard/modifytaskwizard.js +++ b/src/web/wizard/modifytaskwizard.js @@ -152,6 +152,7 @@ const ModifyTaskWizard = ({