diff --git a/package.json b/package.json index d7c1cb909..fda9b519e 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@apollo/client": "^3.5.4", - "@formatjs/intl-relativetimeformat": "^6.0.2", + "@formatjs/intl-relativetimeformat": "^11.2.14", "@mapbox/geo-viewport": "^0.4.0", "@nivo/bar": "^0.79.1", "@nivo/core": "^0.79.0", @@ -28,7 +28,7 @@ "@turf/nearest-point-on-line": "^6.0.2", "autoprefixer": "^10.4.19", "classnames": "^2.2.5", - "date-fns": "^1.29.0", + "date-fns": "^3.6.0", "downshift": "^5.4.3", "file-saver": "^2.0.2", "fontsource-bungee": "^3.1.5", diff --git a/src/components/ActivityListing/ActivityTime.js b/src/components/ActivityListing/ActivityTime.js index a7a73a2ee..f74fe476f 100644 --- a/src/components/ActivityListing/ActivityTime.js +++ b/src/components/ActivityListing/ActivityTime.js @@ -3,12 +3,10 @@ import PropTypes from 'prop-types' import classNames from 'classnames' import { injectIntl, - FormattedRelativeTime, FormattedDate, FormattedTime } from 'react-intl' -import { selectUnit } from '@formatjs/intl-utils' -import parse from 'date-fns/parse' +import { parseISO, formatDistanceToNow } from 'date-fns' /** * Displays the timestamp for an activity entry, either relative or exact @@ -17,20 +15,10 @@ import parse from 'date-fns/parse' * @author [Neil Rotstan](https://github.com/nrotstan) */ export const ActivityTime = props => { - const timestamp = parse(props.entry.created) + const timestamp = parseISO(props.entry.created) const created = `${props.intl.formatDate(timestamp)} ${props.intl.formatTime(timestamp)}` - const selectedUnit = selectUnit(timestamp, Date.now(), - { - second: 30, - minute: 60, - hour: 24, - day: 30 - }) - if (selectedUnit.unit === "second" || - selectedUnit.unit === "minute" || - selectedUnit.unit === "hour") { - selectedUnit.updateIntervalInSeconds = 30 - } + + const distanceToNow = formatDistanceToNow(timestamp, { addSuffix: true }); return (
{ )} title={created} > - {(props.showExactDates || selectedUnit.unit === "year")? + {props.showExactDates ? : - + {distanceToNow} }
) diff --git a/src/components/ActivityMap/ActivityMap.js b/src/components/ActivityMap/ActivityMap.js index ae2c53b4c..69d727f26 100644 --- a/src/components/ActivityMap/ActivityMap.js +++ b/src/components/ActivityMap/ActivityMap.js @@ -4,8 +4,7 @@ import { FormattedMessage, injectIntl } from 'react-intl' import { ZoomControl, CircleMarker, Popup } from 'react-leaflet' import { getCoord } from '@turf/invariant' import centroid from '@turf/centroid' -import parse from 'date-fns/parse' -import differenceInHours from 'date-fns/difference_in_hours' +import { differenceInHours, parseISO } from 'date-fns' import _isString from 'lodash/isString' import _get from 'lodash/get' import _map from 'lodash/map' @@ -42,7 +41,7 @@ export const ActivityMap = props => { JSON.parse(entry.task.location) : entry.task.location const center = getCoord(centroid(geojson)) - const hoursOld = differenceInHours(Date.now(), parse(entry.created)) + const hoursOld = differenceInHours(Date.now(), parseISO(entry.created)) return ( parse(value[0]).getTime()) + _sortBy(groupedByDate, (value) => parseISO(value[0]).getTime()) ) // Build timeline entries for each day, showing each (non-zero) type of @@ -43,7 +43,7 @@ export class ChallengeActivityTimeline extends Component { const isoDate = entriesByDate[0] const statusEntries = entriesByDate[1] - const formattedDate = this.props.intl.formatDate(parse(isoDate), + const formattedDate = this.props.intl.formatDate(parseISO(isoDate), {month: 'long', day: 'numeric'}) const statuses = _compact(_map(statusEntries, entry => { if (entry.count === 0) { diff --git a/src/components/ActivityTimeline/UserActivityTimeline/UserActivityTimelineWidget.js b/src/components/ActivityTimeline/UserActivityTimeline/UserActivityTimelineWidget.js index 09873f109..ecd71046c 100644 --- a/src/components/ActivityTimeline/UserActivityTimeline/UserActivityTimelineWidget.js +++ b/src/components/ActivityTimeline/UserActivityTimeline/UserActivityTimelineWidget.js @@ -9,8 +9,7 @@ import _isNumber from 'lodash/isNumber' import _reverse from 'lodash/reverse' import _sortBy from 'lodash/sortBy' import _compact from 'lodash/compact' -import parse from 'date-fns/parse' -import startOfDay from 'date-fns/start_of_day' +import { startOfDay, parseISO, format } from 'date-fns' import { ActivityItemType, typeLabels, keysByType } @@ -68,7 +67,7 @@ export default class UserActivityTimelineWidget extends Component { challengeNames.set(entry.parentId, entry.parentName) return Object.assign({}, entry, { - normalizedISODate: this.props.startOfDay(parse(entry.created)), + normalizedISODate: this.props.startOfDay(parseISO(entry.created)), challengeId: entry.parentId, description: `${localizedActionLabels[keysByAction[entry.action]]} ` + localizedTypeLabels[keysByType[entry.typeId]] + @@ -104,7 +103,7 @@ export default class UserActivityTimelineWidget extends Component { // Sort date groups in descending date order. const latestEntries = _reverse(_sortBy( groupedByDate, - pairs => parse(pairs[0]).getTime() + pairs => parseISO(pairs[0]).getTime() )) // Build timeline entries for each day, showing each unique type of activity @@ -140,7 +139,7 @@ export default class UserActivityTimelineWidget extends Component { return (
  • - {this.props.intl.formatDate(parse(entriesByDate[0]), + {this.props.intl.formatDate(parseISO(format(entriesByDate[0], "yyyy-MM-dd'T'HH:mm:ssxxx")), {month: 'long', day: 'numeric'})}

      diff --git a/src/components/AdminPane/HOCs/WithChallengeMetrics/WithChallengeMetrics.js b/src/components/AdminPane/HOCs/WithChallengeMetrics/WithChallengeMetrics.js index cd4c172b0..7292e39a7 100644 --- a/src/components/AdminPane/HOCs/WithChallengeMetrics/WithChallengeMetrics.js +++ b/src/components/AdminPane/HOCs/WithChallengeMetrics/WithChallengeMetrics.js @@ -17,7 +17,7 @@ import _pickBy from 'lodash/pickBy' import _values from 'lodash/values' import _indexOf from 'lodash/indexOf' import _isEqual from 'lodash/isEqual' -import parse from 'date-fns/parse' +import { parseISO } from 'date-fns' import WithComputedMetrics from '../../HOCs/WithComputedMetrics/WithComputedMetrics' import WithDashboardEntityFilter from '../../HOCs/WithDashboardEntityFilter/WithDashboardEntityFilter' @@ -134,7 +134,7 @@ const WithChallengeMetrics = function(WrappedComponent, applyFilters = false) { // Calculate metrics for each day let totalRemaining = tasksAvailable dailyMetrics = _map(groupedByDate, dailyEntries => { - const day = parse(dailyEntries[0]) + const day = parseISO(dailyEntries[0]) const dayActivity = dailyEntries[1] const completedToday = _sumBy(dayActivity, entry => diff --git a/src/components/AdminPane/Manage/CalendarHeatmap/CalendarHeatmap.js b/src/components/AdminPane/Manage/CalendarHeatmap/CalendarHeatmap.js index 66ab0cb74..8db693adb 100644 --- a/src/components/AdminPane/Manage/CalendarHeatmap/CalendarHeatmap.js +++ b/src/components/AdminPane/Manage/CalendarHeatmap/CalendarHeatmap.js @@ -6,8 +6,7 @@ import Calendar from 'react-calendar-heatmap' import _map from 'lodash/map' import _compact from 'lodash/compact' import _reverse from 'lodash/reverse' -import format from 'date-fns/format' -import subMonths from 'date-fns/sub_months' +import { subMonths, format } from 'date-fns' import messages from './Messages' import './CalendarHeatmap.scss' @@ -36,7 +35,7 @@ export default class CalendarHeatmap extends Component { _compact(_map(_reverse(this.props.dailyMetrics), metrics => metrics.value === 0 ? null : ({ - date: format(metrics.day, 'YYYY-MM-DD'), + date: format(metrics.day, 'yyyy-MM-dd'), count: metrics.value, }) )) diff --git a/src/components/AdminPane/Manage/ChallengeDashboard/ChallengeDashboard.js b/src/components/AdminPane/Manage/ChallengeDashboard/ChallengeDashboard.js index 4c607aa00..338b514e4 100644 --- a/src/components/AdminPane/Manage/ChallengeDashboard/ChallengeDashboard.js +++ b/src/components/AdminPane/Manage/ChallengeDashboard/ChallengeDashboard.js @@ -1,7 +1,7 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; import { FormattedMessage, FormattedDate, injectIntl } from "react-intl"; -import parse from "date-fns/parse"; +import { parseISO } from "date-fns"; import { Link } from "react-router-dom"; import _get from "lodash/get"; import { @@ -136,7 +136,7 @@ export class ChallengeDashboard extends Component {
      {" "} {this.props.challenge.created && - }
      @@ -116,7 +116,7 @@ export default class ChallengeOverviewWidget extends Component {
      {this.props.challenge.lastTaskRefresh && - }
      @@ -129,7 +129,7 @@ export default class ChallengeOverviewWidget extends Component {
      {this.props.challenge.dataOriginDate && - }
      diff --git a/src/components/CardChallenge/CardChallenge.js b/src/components/CardChallenge/CardChallenge.js index 998a6ea0a..7c4c0d953 100644 --- a/src/components/CardChallenge/CardChallenge.js +++ b/src/components/CardChallenge/CardChallenge.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types' import { FormattedMessage, FormattedDate } from 'react-intl' import { Link } from 'react-router-dom' import classNames from 'classnames' -import parse from 'date-fns/parse' +import { parseISO } from 'date-fns' import _isUndefined from 'lodash/isUndefined' import _noop from 'lodash/noop' import _get from 'lodash/get' @@ -137,7 +137,7 @@ export class CardChallenge extends Component { : diff --git a/src/components/ChallengeDetail/ChallengeDetail.js b/src/components/ChallengeDetail/ChallengeDetail.js index c94473e48..3a9a20b4e 100644 --- a/src/components/ChallengeDetail/ChallengeDetail.js +++ b/src/components/ChallengeDetail/ChallengeDetail.js @@ -9,7 +9,7 @@ import _merge from "lodash/merge"; import _uniqBy from "lodash/uniqBy"; import _differenceBy from "lodash/differenceBy"; import { Popup } from 'react-leaflet' -import parse from "date-fns/parse"; +import { parseISO } from "date-fns"; import MapPane from "../EnhancedMap/MapPane/MapPane"; import TaskClusterMap from "../TaskClusterMap/TaskClusterMap"; import { messagesByDifficulty } from "../../services/Challenge/ChallengeDifficulty/ChallengeDifficulty"; @@ -420,10 +420,10 @@ export class ChallengeDetail extends Component { ? null : this.props.intl.formatMessage(messages.dataOriginDateLabel, { refreshDate: this.props.intl.formatDate( - parse(challenge.lastTaskRefresh) + parseISO(challenge.lastTaskRefresh) ), sourceDate: this.props.intl.formatDate( - parse(challenge.dataOriginDate) + parseISO(challenge.dataOriginDate) ), }); @@ -563,7 +563,7 @@ export class ChallengeDetail extends Component { : {" "} { it("doesn't break if only required props are provided", () => { @@ -25,8 +26,8 @@ describe("ChallengeDetail", () => { browsedChallenge={{ id: 1, parent: { id: 2 }, - lastTaskRefresh: new Date(), - dataOriginDate: new Date(), + lastTaskRefresh: format(new Date(), "yyyy-MM-dd'T'HH:mm:ss.SSSxxx"), + dataOriginDate: format(new Date(), "yyyy-MM-dd'T'HH:mm:ss.SSSxxx").slice(0, 10), }} intl={{ formatMessage: () => '', @@ -54,8 +55,8 @@ describe("ChallengeDetail", () => { browsedChallenge={{ id: 1, parent: { id: 2 }, - lastTaskRefresh: new Date(), - dataOriginDate: new Date(), + lastTaskRefresh: format(new Date(), "yyyy-MM-dd'T'HH:mm:ss.SSSxxx"), + dataOriginDate: format(new Date(), "yyyy-MM-dd'T'HH:mm:ss.SSSxxx").slice(0, 10), enabled: true, }} intl={{ diff --git a/src/components/CommentList/CommentList.js b/src/components/CommentList/CommentList.js index 56f2195f8..18ab1b89c 100644 --- a/src/components/CommentList/CommentList.js +++ b/src/components/CommentList/CommentList.js @@ -5,7 +5,7 @@ import { FormattedMessage, FormattedDate, FormattedTime } from 'react-intl' import { Link } from 'react-router-dom' -import parse from 'date-fns/parse' +import { parseISO } from 'date-fns' import _map from 'lodash/map' import _isObject from 'lodash/isObject' import _sortBy from 'lodash/sortBy' @@ -41,7 +41,7 @@ export default class CommentList extends Component { if (this.props.comments?.length !== 0) { commentDates = new Map() _each(this.props.comments, (comment) => - commentDates.set(comment.id, parse(comment.created)) + commentDates.set(comment.id, parseISO(comment.created)) ) // Show in descending order, with the most recent comment first. @@ -54,7 +54,7 @@ export default class CommentList extends Component { } else { commentDates = new Map() _each(this.props.taskComments, (comment) => - commentDates.set(comment.id, parse(comment.created)) + commentDates.set(comment.id, parseISO(comment.created)) ) // Show in descending order, with the most recent comment first. diff --git a/src/components/HOCs/WithFilterCriteria/WithFilterCriteria.js b/src/components/HOCs/WithFilterCriteria/WithFilterCriteria.js index bc5c20846..3c8f2607a 100644 --- a/src/components/HOCs/WithFilterCriteria/WithFilterCriteria.js +++ b/src/components/HOCs/WithFilterCriteria/WithFilterCriteria.js @@ -11,7 +11,7 @@ import _toInteger from 'lodash/toInteger' import _each from 'lodash/each' import _isUndefined from 'lodash/isUndefined' import _debounce from 'lodash/debounce' -import format from 'date-fns/format' +import { format } from 'date-fns' import { fromLatLngBounds, GLOBAL_MAPBOUNDS } from '../../../services/MapBounds/MapBounds' import { buildSearchCriteriafromURL, buildSearchURL } from '../../../services/SearchCriteria/SearchCriteria' @@ -135,7 +135,7 @@ export const WithFilterCriteria = function(WrappedComponent, ignoreURL = true, if (searchCriteria.filters.reviewedAt && typeof searchCriteria.filters.reviewedAt === "object") { searchCriteria.filters.reviewedAt = - format(searchCriteria.filters.reviewedAt, 'YYYY-MM-DD') + format(searchCriteria.filters.reviewedAt, 'yyyy-MM-dd') } return buildSearchURL(searchCriteria) diff --git a/src/components/HOCs/WithReviewTasks/WithReviewTasks.js b/src/components/HOCs/WithReviewTasks/WithReviewTasks.js index 443906e2e..2eefb7ebe 100644 --- a/src/components/HOCs/WithReviewTasks/WithReviewTasks.js +++ b/src/components/HOCs/WithReviewTasks/WithReviewTasks.js @@ -1,6 +1,6 @@ import React, { Component } from 'react' import { connect } from 'react-redux' -import format from 'date-fns/format' +import { format } from 'date-fns' import _omit from 'lodash/omit' import _get from 'lodash/get' import _merge from 'lodash/merge' @@ -154,7 +154,7 @@ export const WithReviewTasks = function(WrappedComponent) { if (searchCriteria.filters.reviewedAt && typeof searchCriteria.filters.reviewedAt === "object") { searchCriteria.filters.reviewedAt = - format(searchCriteria.filters.reviewedAt, 'YYYY-MM-DD') + format(searchCriteria.filters.reviewedAt, 'yyyy-MM-dd') } // The criteria filters use 'project' but on the url it can also be diff --git a/src/components/HOCs/WithUserMetrics/WithUserMetrics.js b/src/components/HOCs/WithUserMetrics/WithUserMetrics.js index c0d889c48..48d0a8641 100644 --- a/src/components/HOCs/WithUserMetrics/WithUserMetrics.js +++ b/src/components/HOCs/WithUserMetrics/WithUserMetrics.js @@ -1,4 +1,4 @@ -import format from 'date-fns/format' +import { format } from 'date-fns' import React, { Component } from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' @@ -45,22 +45,22 @@ export const WithUserMetrics = function(WrappedComponent, userProp) { _get(this.props[userProp], 'id') === _get(this.props.currentUser, 'userId')) { const startDate = _get(this.state.tasksCompletedDateRange, 'length', 0) === 2 ? - format(this.state.tasksCompletedDateRange[0], 'YYYY-MM-DD') : null + format(this.state.tasksCompletedDateRange[0], 'yyyy-MM-dd') : null const endDate = _get(this.state.tasksCompletedDateRange, 'length', 0) === 2 ? - format(this.state.tasksCompletedDateRange[1], 'YYYY-MM-DD') : null + format(this.state.tasksCompletedDateRange[1], 'yyyy-MM-dd') : null const reviewStart = _get(this.state.tasksReviewedDateRange, 'length', 0) === 2 ? - format(this.state.tasksReviewedDateRange[0], 'YYYY-MM-DD') : null + format(this.state.tasksReviewedDateRange[0], 'yyyy-MM-dd') : null const reviewEnd = _get(this.state.tasksReviewedDateRange, 'length', 0) === 2 ? - format(this.state.tasksReviewedDateRange[1], 'YYYY-MM-DD') : null + format(this.state.tasksReviewedDateRange[1], 'yyyy-MM-dd') : null const reviewerStart = _get(this.state.tasksReviewerDateRange, 'length', 0) === 2 ? - format(this.state.tasksReviewerDateRange[0], 'YYYY-MM-DD') : null + format(this.state.tasksReviewerDateRange[0], 'yyyy-MM-dd') : null const reviewerEnd = _get(this.state.tasksReviewerDateRange, 'length', 0) === 2 ? - format(this.state.tasksReviewerDateRange[1], 'YYYY-MM-DD') : null + format(this.state.tasksReviewerDateRange[1], 'yyyy-MM-dd') : null fetchUserMetrics(this.props[userProp].id, this.state.tasksCompletedMonthsPast, diff --git a/src/components/IntlDatePicker/IntlDatePicker.js b/src/components/IntlDatePicker/IntlDatePicker.js index 61f3516d4..5f20a02ee 100644 --- a/src/components/IntlDatePicker/IntlDatePicker.js +++ b/src/components/IntlDatePicker/IntlDatePicker.js @@ -1,6 +1,6 @@ import React, { Component } from 'react' import DatePicker from 'react-datepicker' -import subYears from 'date-fns/sub_years' +import { subYears } from 'date-fns' /** diff --git a/src/components/OSMElementHistory/OSMElementHistory.js b/src/components/OSMElementHistory/OSMElementHistory.js index 0002ded1b..f3aa8e177 100644 --- a/src/components/OSMElementHistory/OSMElementHistory.js +++ b/src/components/OSMElementHistory/OSMElementHistory.js @@ -2,8 +2,7 @@ import React, { useState, useEffect } from 'react' import PropTypes from 'prop-types' import { FormattedMessage, FormattedTime, FormattedDate, injectIntl } from 'react-intl' -import parse from 'date-fns/parse' -import isAfter from 'date-fns/is_after' +import { isAfter, parseISO } from 'date-fns' import _map from 'lodash/map' import _compact from 'lodash/compact' import _isEmpty from 'lodash/isEmpty' @@ -177,8 +176,8 @@ OSMElementHistory.propTypes = { } const HistoryEntry = props => { - const timestamp = parse(props.timestamp) - const sourceDate = props.sourceDate ? parse(props.sourceDate) : new Date() + const timestamp = parseISO(props.timestamp) + const sourceDate = props.sourceDate ? parseISO(props.sourceDate) : new Date() const changesetComment = _find( _get(props, 'changeset.tag', []), tag => tag.k === "comment" diff --git a/src/components/OpenStreetCamViewer/OpenStreetCamViewer.js b/src/components/OpenStreetCamViewer/OpenStreetCamViewer.js index 184b93e37..47edd3ddf 100644 --- a/src/components/OpenStreetCamViewer/OpenStreetCamViewer.js +++ b/src/components/OpenStreetCamViewer/OpenStreetCamViewer.js @@ -1,7 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import parse from 'date-fns/parse' -import format from 'date-fns/format' +import { parseISO,format } from 'date-fns' import _findIndex from 'lodash/findIndex' import External from '../External/External' import Modal from '../Modal/Modal' @@ -109,7 +108,7 @@ export default class OpenStreetCamViewer extends Component { @{currentImage.username}
      - {format(parse(currentImage.shotDate), 'YYYY-MM-DD')} + {format(parseISO(currentImage.shotDate), 'yyyy-MM-dd')}
      } diff --git a/src/components/ProjectDetail/ProjectDetail.js b/src/components/ProjectDetail/ProjectDetail.js index 58f722468..e82ed114d 100644 --- a/src/components/ProjectDetail/ProjectDetail.js +++ b/src/components/ProjectDetail/ProjectDetail.js @@ -6,7 +6,7 @@ import { FormattedMessage, FormattedDate, injectIntl } import _isObject from 'lodash/isObject' import _get from 'lodash/get' import _filter from 'lodash/filter' -import parse from 'date-fns/parse' +import { parseISO } from 'date-fns' import messages from './Messages' import BusySpinner from '../BusySpinner/BusySpinner' import ChallengeProgress from '../ChallengeProgress/ChallengeProgress' @@ -121,7 +121,7 @@ export class ProjectDetail extends Component { /> : {' '} -
    1. @@ -131,7 +131,7 @@ export class ProjectDetail extends Component { /> : {' '} -
    2. {/* Disable Link tell project leaderboard page is reimplemented */} diff --git a/src/components/TaskAnalysisTable/TaskAnalysisTable.js b/src/components/TaskAnalysisTable/TaskAnalysisTable.js index c6ef3e1b9..4947a56d0 100644 --- a/src/components/TaskAnalysisTable/TaskAnalysisTable.js +++ b/src/components/TaskAnalysisTable/TaskAnalysisTable.js @@ -23,8 +23,7 @@ import _split from 'lodash/split' import _isEmpty from 'lodash/isEmpty' import _merge from 'lodash/merge' import _pick from 'lodash/pick' -import parse from 'date-fns/parse' -import differenceInSeconds from 'date-fns/difference_in_seconds' +import { parseISO,differenceInSeconds } from 'date-fns' import { messagesByStatus, keysByStatus } from '../../services/Task/TaskStatus/TaskStatus' @@ -193,7 +192,7 @@ export class TaskAnalysisTableInternal extends Component { if (!t.reviewedAt || !t.reviewStartedAt) { return 0 } - return differenceInSeconds(parse(t.reviewedAt), parse(t.reviewStartedAt)) + return differenceInSeconds(parseISO(t.reviewedAt), parseISO(t.reviewStartedAt)) }) } else { @@ -556,8 +555,8 @@ const setupColumnTypes = (props, taskBaseRoute, manager, data, openComments) => if (!row._original.reviewedAt || !row._original.reviewStartedAt) return null - const seconds = differenceInSeconds(parse(row._original.reviewedAt), - parse(row._original.reviewStartedAt)) + const seconds = differenceInSeconds(parseISO(row._original.reviewedAt), + parseISO(row._original.reviewStartedAt)) return ( {Math.floor(seconds / 60)}m {seconds % 60}s diff --git a/src/components/TopUserChallenges/TopUserChallengesWidget.js b/src/components/TopUserChallenges/TopUserChallengesWidget.js index 69528d14e..2bc466e7c 100644 --- a/src/components/TopUserChallenges/TopUserChallengesWidget.js +++ b/src/components/TopUserChallenges/TopUserChallengesWidget.js @@ -9,7 +9,7 @@ import { FormattedMessage } from 'react-intl' // import _isPlainObject from 'lodash/isPlainObject' // import { Link } from 'react-router-dom' // Disable till TopUserChallengesWidget is reimplemented -// import subMonths from 'date-fns/sub_months' +// import { subMonths } from 'date-fns' import { WidgetDataTarget, registerWidgetType } from '../../services/Widget/Widget' import QuickWidget from '../QuickWidget/QuickWidget' diff --git a/src/interactions/Challenge/AsManageableChallenge.js b/src/interactions/Challenge/AsManageableChallenge.js index 3c23d1a7b..e60b5a20f 100644 --- a/src/interactions/Challenge/AsManageableChallenge.js +++ b/src/interactions/Challenge/AsManageableChallenge.js @@ -4,7 +4,7 @@ import _isFinite from 'lodash/isFinite' import _get from 'lodash/get' import _filter from 'lodash/filter' import _maxBy from 'lodash/maxBy' -import parse from 'date-fns/parse' +import { parseISO } from 'date-fns' import { ChallengeStatus } from '../../services/Challenge/ChallengeStatus/ChallengeStatus' import { isCompletionStatus } @@ -76,12 +76,12 @@ export class AsManageableChallenge { } return _maxBy(this.completionActivity(), - entry => parse(entry.date).getTime()) + entry => parseISO(entry.date).getTime()) } mostRecentCompletionActivityDate() { const entry = this.mostRecentCompletionActivityEntry() - return _isObject(entry) ? parse(entry.date) : null + return _isObject(entry) ? parseISO(entry.date) : null } } diff --git a/src/pages/Review/TasksReview/TasksReviewTable.js b/src/pages/Review/TasksReview/TasksReviewTable.js index ad22b2ad7..050401bcd 100644 --- a/src/pages/Review/TasksReview/TasksReviewTable.js +++ b/src/pages/Review/TasksReview/TasksReviewTable.js @@ -2,7 +2,7 @@ import React, { Component } from 'react' import classNames from 'classnames' import { FormattedMessage, FormattedDate, FormattedTime } from 'react-intl' -import parse from 'date-fns/parse' +import { parseISO } from 'date-fns' import _get from 'lodash/get' import _each from 'lodash/each' import _map from 'lodash/map' @@ -941,7 +941,7 @@ export const setupColumnTypes = (props, openComments, data, criteria) => { let mappedOn = _get(criteria, 'filters.mappedOn') if (typeof mappedOn === "string" && mappedOn !== "") { - mappedOn = parse(mappedOn) + mappedOn = parseISO(mappedOn) } const clearFilter = () => props.setFiltered("mappedOn", null) @@ -989,7 +989,7 @@ export const setupColumnTypes = (props, openComments, data, criteria) => { Filter: () => { let reviewedAt = _get(criteria, 'filters.reviewedAt') if (typeof reviewedAt === "string" && reviewedAt !== "") { - reviewedAt = parse(reviewedAt) + reviewedAt = parseISO(reviewedAt) } const clearFilter = () => props.setFiltered("reviewedAt", null) diff --git a/src/pages/Social/Social.js b/src/pages/Social/Social.js index 8b887be7e..9cc06b34a 100644 --- a/src/pages/Social/Social.js +++ b/src/pages/Social/Social.js @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react' import { FormattedMessage, FormattedDate, injectIntl } from 'react-intl' import { CopyToClipboard } from 'react-copy-to-clipboard' import { Link } from 'react-router-dom' -import parse from 'date-fns/parse' +import { parseISO } from 'date-fns' import _isEmpty from 'lodash/isEmpty' import _map from 'lodash/map' import { fetchSocialChallenges } from '../../services/Challenge/Challenge' @@ -118,7 +118,7 @@ const ChallengeItem = props => { {props.challenge.name}
      - +
      diff --git a/src/services/Challenge/Challenge.js b/src/services/Challenge/Challenge.js index 63aee3bb0..210dc10d0 100644 --- a/src/services/Challenge/Challenge.js +++ b/src/services/Challenge/Challenge.js @@ -18,8 +18,7 @@ import _fromPairs from "lodash/fromPairs"; import _isUndefined from "lodash/isUndefined"; import _groupBy from "lodash/groupBy"; import _join from "lodash/join"; -import parse from "date-fns/parse"; -import format from "date-fns/format"; +import { parseISO, format, startOfDay } from "date-fns"; import { defaultRoutes as api, isSecurityError } from "../Server/Server"; import Endpoint from "../Server/Endpoint"; import RequestStatus from "../Server/RequestStatus"; @@ -44,7 +43,6 @@ import { generateSearchParametersString, PARAMS_MAP, } from "../Search/Search"; -import startOfDay from "date-fns/start_of_day"; import geojsontoosm from 'geojsontoosm'; /** @@ -197,7 +195,7 @@ export const receiveChallenges = function ( ) { _each(normalizedEntities.challenges, (c) => { if (c.dataOriginDate) { - c.dataOriginDate = format(parse(c.dataOriginDate), "YYYY-MM-DD"); + c.dataOriginDate = format(parseISO(c.dataOriginDate), "yyyy-MM-dd"); } }); @@ -1032,7 +1030,7 @@ export const fetchChallenges = function ( if (challengeData.dataOriginDate) { // Set the timestamp on the dataOriginDate so we get proper timezone info. - challengeData.dataOriginDate = parse( + challengeData.dataOriginDate = parseISO( challengeData.dataOriginDate ).toISOString(); } @@ -1168,7 +1166,7 @@ export const uploadChallengeGeoJSON = function ( if (dataOriginDate) { // Set the timestamp on the dataOriginDate so we get proper timezone info. - dataOriginDate = parse(dataOriginDate).toISOString(); + dataOriginDate = parseISO(dataOriginDate).toISOString(); } return new Endpoint(api.challenge.uploadGeoJSON, { diff --git a/src/services/FundraisingNotices/FundraisingNotices.js b/src/services/FundraisingNotices/FundraisingNotices.js index 7761ae6e0..5470d115a 100644 --- a/src/services/FundraisingNotices/FundraisingNotices.js +++ b/src/services/FundraisingNotices/FundraisingNotices.js @@ -1,7 +1,6 @@ import _isEmpty from 'lodash/isEmpty' import _isArray from 'lodash/isArray' -import parse from 'date-fns/parse' -import isFuture from 'date-fns/is_future' +import { isFuture, parseISO } from 'date-fns' const NOTICES_URL = process.env.REACT_APP_FUNDRAISING_NOTICES_URL @@ -20,7 +19,7 @@ export const fetchActiveFundraisingNotices = async function () { return fundraisingNotices.notices .map((notice) => { // add Date instance for expiration timestamp - notice.expirationDate = parse(notice.expirationTimestamp) + notice.expirationDate = parseISO(notice.expirationTimestamp) return notice }) .filter((notice) => isFuture(notice.expirationDate)) diff --git a/src/services/Leaderboard/Leaderboard.js b/src/services/Leaderboard/Leaderboard.js index d2643817b..0a5fcbaa5 100644 --- a/src/services/Leaderboard/Leaderboard.js +++ b/src/services/Leaderboard/Leaderboard.js @@ -1,8 +1,7 @@ import { defaultRoutes as api } from '../Server/Server' import _isArray from 'lodash/isArray' import Endpoint from '../Server/Endpoint' -import startOfMonth from 'date-fns/start_of_month' -import endOfDay from 'date-fns/end_of_day' +import { startOfMonth, endOfDay } from 'date-fns' import { CHALLENGE_INCLUDE_LOCAL } from '../Challenge/Challenge' import { setupCustomCache } from '../../utils/setupCustomCache' import { addError } from '../Error/Error' diff --git a/src/services/OSMCha/OSMCha.js b/src/services/OSMCha/OSMCha.js index cd679bb1d..cacab70ef 100644 --- a/src/services/OSMCha/OSMCha.js +++ b/src/services/OSMCha/OSMCha.js @@ -1,4 +1,4 @@ -import format from 'date-fns/format' +import { format } from 'date-fns' /** * View changesets in OSMCha. Sets up filters for given bbox, the given start @@ -23,7 +23,7 @@ export const buildOSMChaUrl = (bboxArray, earliestDate, participantUsernames) => // Setup start-date filter if (earliestDate) { - const startDate = format(earliestDate, "YYYY-MM-DD") + const startDate = format(earliestDate, "yyyy-MM-dd") filterParams.push(`"date__gte":[{"label":"${startDate}","value":"${startDate}"}]`) } else { diff --git a/src/services/Overpass/Overpass.js b/src/services/Overpass/Overpass.js index dba438415..531f789a0 100644 --- a/src/services/Overpass/Overpass.js +++ b/src/services/Overpass/Overpass.js @@ -1,5 +1,4 @@ -import addMinutes from 'date-fns/add_minutes' -import isAfter from 'date-fns/is_after' +import { addMinutes, isAfter } from 'date-fns' import { isJosmEditor, sendJOSMCommand } from '../Editor/Editor' import { fromLatLngBounds } from '../MapBounds/MapBounds' import _get from 'lodash/get' diff --git a/src/services/Project/Project.js b/src/services/Project/Project.js index b061eac05..b53bbb1b0 100644 --- a/src/services/Project/Project.js +++ b/src/services/Project/Project.js @@ -6,7 +6,7 @@ import _find from "lodash/find"; import _map from "lodash/map"; import _isFinite from "lodash/isFinite"; import _isUndefined from "lodash/isUndefined"; -import startOfDay from "date-fns/start_of_day"; +import { startOfDay } from 'date-fns' import { defaultRoutes as api, isSecurityError } from "../Server/Server"; import Endpoint from "../Server/Endpoint"; import RequestStatus from "../Server/RequestStatus"; diff --git a/src/services/Search/Search.js b/src/services/Search/Search.js index 43f3f51e4..888edc28a 100644 --- a/src/services/Search/Search.js +++ b/src/services/Search/Search.js @@ -1,4 +1,4 @@ -import format from 'date-fns/format' +import { format } from 'date-fns' import _uniqueId from 'lodash/uniqueId' import _cloneDeep from 'lodash/cloneDeep' import _clone from 'lodash/clone' @@ -272,11 +272,11 @@ export const generateSearchParametersString = (filters, boundingBox, savedChalle } } if (filters.reviewedAt) { - searchParameters.startDate = format(filters.reviewedAt, 'YYYY-MM-DD') - searchParameters.endDate = format(filters.reviewedAt, 'YYYY-MM-DD') + searchParameters.startDate = format(filters.reviewedAt, 'yyyy-MM-dd') + searchParameters.endDate = format(filters.reviewedAt, 'yyyy-MM-dd') } if (filters.mappedOn) { - searchParameters.mo = format(filters.mappedOn, 'YYYY-MM-DD') + searchParameters.mo = format(filters.mappedOn, 'yyyy-MM-dd') } if (filters.id) { diff --git a/src/services/SystemNotices/SystemNotices.js b/src/services/SystemNotices/SystemNotices.js index a11629ba9..1f2d7765c 100644 --- a/src/services/SystemNotices/SystemNotices.js +++ b/src/services/SystemNotices/SystemNotices.js @@ -1,6 +1,5 @@ import _isArray from 'lodash/isArray' -import parse from 'date-fns/parse' -import isFuture from 'date-fns/is_future' +import { isFuture, parseISO } from 'date-fns' import Endpoint from '../Server/Endpoint' import { defaultRoutes as api } from "../Server/Server"; @@ -39,7 +38,7 @@ export const fetchActiveSystemNotices = () => { if (_isArray(systemNotices)) { return systemNotices.map(notice => { // add Date instance for expiration timestamp - notice.expirationDate = parse(notice.expirationTimestamp) + notice.expirationDate = parseISO(notice.expirationTimestamp) return notice }).filter(notice => isFuture(notice.expirationDate)) } diff --git a/src/services/User/User.js b/src/services/User/User.js index 5b7b7b4f0..bdb7bc3dd 100644 --- a/src/services/User/User.js +++ b/src/services/User/User.js @@ -14,8 +14,7 @@ import _toPairs from 'lodash/toPairs' import _omit from 'lodash/omit' import _sortBy from 'lodash/sortBy' import _reverse from 'lodash/reverse' -import subMonths from 'date-fns/sub_months' -import startOfDay from 'date-fns/start_of_day' +import { subMonths, startOfDay } from 'date-fns' import { defaultRoutes as api, isSecurityError, credentialsPolicy, websocketClient } from '../Server/Server' import { resetCache } from '../Server/RequestCache' diff --git a/src/services/VirtualChallenge/VirtualChallenge.js b/src/services/VirtualChallenge/VirtualChallenge.js index cdc53f8b4..30f1430b5 100644 --- a/src/services/VirtualChallenge/VirtualChallenge.js +++ b/src/services/VirtualChallenge/VirtualChallenge.js @@ -4,7 +4,7 @@ import _isFinite from 'lodash/isFinite' import _map from 'lodash/map' import _omit from 'lodash/omit' import _head from 'lodash/head' -import addHours from 'date-fns/add_hours' +import { addHours } from 'date-fns' import { defaultRoutes as api, isSecurityError } from '../Server/Server' import Endpoint from '../Server/Endpoint' import RequestStatus from '../Server/RequestStatus' diff --git a/yarn.lock b/yarn.lock index f8d0fa2a4..c64477f76 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1397,6 +1397,14 @@ dependencies: tslib "^2.0.1" +"@formatjs/ecma402-abstract@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz#39197ab90b1c78b7342b129a56a7acdb8f512e17" + integrity sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g== + dependencies: + "@formatjs/intl-localematcher" "0.5.4" + tslib "^2.4.0" + "@formatjs/fast-memoize@2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz#33bd616d2e486c3e8ef4e68c99648c196887802b" @@ -1446,6 +1454,13 @@ dependencies: tslib "^2.4.0" +"@formatjs/intl-localematcher@0.5.4": + version "0.5.4" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz#caa71f2e40d93e37d58be35cfffe57865f2b366f" + integrity sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g== + dependencies: + tslib "^2.4.0" + "@formatjs/intl-numberformat@^5.5.2": version "5.7.6" resolved "https://registry.yarnpkg.com/@formatjs/intl-numberformat/-/intl-numberformat-5.7.6.tgz#630206bb0acefd2d508ccf4f82367c6875cad611" @@ -1454,19 +1469,14 @@ "@formatjs/ecma402-abstract" "1.4.0" tslib "^2.0.1" -"@formatjs/intl-relativetimeformat@^6.0.2": - version "6.2.4" - resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-6.2.4.tgz#d6d9fe5c0c7fa1b227bf87384a4a79149bc2fdca" - integrity sha512-bhxHRPL6xQIF7XOD1HDYfC3Ip45Ccf2G4viMLyIXDaHPeVgRHM5jZ23FXdg01MQEZ/thb20hoeX56m76+IjI0Q== +"@formatjs/intl-relativetimeformat@^11.2.14": + version "11.2.14" + resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-11.2.14.tgz#acc2aa3d59cc9a414d285d1159ae87ed286287da" + integrity sha512-g1tor23+Z8DUzT9VAlMHzdeNxyhnD6sgaFRFxti6+4cODdaG4mudo77Th8ONg8Z3El2Ienf+CXcCNzJpOG1E7A== dependencies: - "@formatjs/intl-utils" "^3.8.1" - -"@formatjs/intl-utils@^3.8.1": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-3.8.4.tgz#291baac91001db428fc3275c515a3e40fbe95945" - integrity sha512-j5C6NyfKevIxsfLK8KwO1C0vvP7k1+h4A9cFpc+cr6mEwCc1sPkr17dzh0Ke6k9U5pQccAQoXdcNBl3IYa4+ZQ== - dependencies: - emojis-list "^3.0.0" + "@formatjs/ecma402-abstract" "2.0.0" + "@formatjs/intl-localematcher" "0.5.4" + tslib "^2.4.0" "@formatjs/intl@2.9.9": version "2.9.9" @@ -5672,11 +5682,6 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -date-fns@^1.29.0: - version "1.30.1" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" - integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== - date-fns@^2.0.1: version "2.30.0" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" @@ -5684,6 +5689,11 @@ date-fns@^2.0.1: dependencies: "@babel/runtime" "^7.21.0" +date-fns@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf" + integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww== + debug@2.6.9, debug@^2.1.3, debug@^2.6.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"