diff --git a/rdmo/core/assets/js/hooks/index.js b/rdmo/core/assets/js/hooks/index.js index 35876244a8..589ce241d6 100644 --- a/rdmo/core/assets/js/hooks/index.js +++ b/rdmo/core/assets/js/hooks/index.js @@ -1,3 +1,2 @@ -export { default as useFormattedDateTime } from './useFormattedDateTime' export { default as useModal } from './useModal' export { default as useScrollToTop } from './useScrollToTop' diff --git a/rdmo/core/assets/js/hooks/useFormattedDateTime.js b/rdmo/core/assets/js/hooks/useFormattedDateTime.js deleted file mode 100644 index 82a2e732af..0000000000 --- a/rdmo/core/assets/js/hooks/useFormattedDateTime.js +++ /dev/null @@ -1,26 +0,0 @@ -import { format, parseISO } from 'date-fns' -import { de, enUS } from 'date-fns/locale' - -const getLocaleObject = (language) => { - return language === 'de' ? de : enUS -} - -const FORMAT_STRINGS = { - dateTime: { - en: 'MMM d, yyyy, h:mm a', - de: 'd. MMM yyyy, H:mm', - }, - dateOnly: { - en: 'MMM d, yyyy', - de: 'd. MMM yyyy', - }, -} - -export const useFormattedDateTime = (date, language, formatType = 'dateTime') => { - const locale = getLocaleObject(language) - const formatString = FORMAT_STRINGS[formatType][language] ?? FORMAT_STRINGS[formatType].en - - return format(parseISO(date), formatString, { locale }) -} - -export default useFormattedDateTime diff --git a/rdmo/core/assets/js/utils/date.js b/rdmo/core/assets/js/utils/date.js index acbfb5ecd9..3c1b0c4469 100644 --- a/rdmo/core/assets/js/utils/date.js +++ b/rdmo/core/assets/js/utils/date.js @@ -1,7 +1,7 @@ -import { parse, set } from 'date-fns' +import { format, parse, parseISO, set } from 'date-fns' import { de, enGB, es, fr, it } from 'date-fns/locale' -import lang from 'rdmo/core/assets/js/utils/lang' +import { language as lang } from 'rdmo/core/assets/js/utils' export const getLocale = () => { switch (lang) { @@ -18,7 +18,20 @@ export const getLocale = () => { } } -export const getDateFormat = () => { +export const getDateFormat = (formatType = 'short') => { + if (formatType === 'long') { + switch (lang) { + case 'de': + return 'd. MMM yyyy' + case 'it': + case 'es': + case 'fr': + return 'd MMM yyyy' + default: + return 'MMM d, yyyy' + } + } + switch (lang) { case 'de': return 'dd.MM.yyyy' @@ -33,6 +46,10 @@ export const getDateFormat = () => { } } +export const getDateTimeFormat = (formatType = 'short') => { + return `${getDateFormat(formatType)}, ${lang === 'en' ? 'h:mm a' : 'H:mm'}` +} + export const parseDate = (value, end = false) => { if (!value) return null @@ -46,3 +63,19 @@ export const parseDate = (value, end = false) => { return parse(value, getDateFormat(), new Date()) } } + +export const formatDate = (value, formatType = 'short') => { + if (!value) return '' + + return format(parseISO(value), getDateFormat(formatType), { + locale: getLocale() + }) +} + +export const formatDateTime = (value, formatType = 'short') => { + if (!value) return '' + + return format(parseISO(value), getDateTimeFormat(formatType), { + locale: getLocale() + }) +} diff --git a/rdmo/core/assets/js/utils/lang.js b/rdmo/core/assets/js/utils/lang.js deleted file mode 100644 index 24bce4d468..0000000000 --- a/rdmo/core/assets/js/utils/lang.js +++ /dev/null @@ -1,2 +0,0 @@ -// take the baseurl from the of the django template -export default document.querySelector('html').getAttribute('lang') diff --git a/rdmo/projects/assets/js/project/components/areas/Dashboard.js b/rdmo/projects/assets/js/project/components/areas/Dashboard.js index 56241327c9..6ab443a10e 100644 --- a/rdmo/projects/assets/js/project/components/areas/Dashboard.js +++ b/rdmo/projects/assets/js/project/components/areas/Dashboard.js @@ -2,10 +2,9 @@ import React, { useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import * as configActions from 'rdmo/core/assets/js/actions/configActions' -import { useFormattedDateTime } from 'rdmo/core/assets/js/hooks' -import { language } from 'rdmo/core/assets/js/utils' import { navigateDashboard, updateProjectTask } from '../../actions/projectActions' +import { renderIssueDate } from '../../utils/renderIssueDate' import { Tile } from '../helper' import IssueModal from './dashboard/IssueModal' @@ -20,15 +19,6 @@ const Dashboard = () => { /* Show only issues that resolve */ const issues = allIssues.filter((issue) => issue.resolve === true) - // Mock dates for testing - // issues.forEach((issue) => { - // issue.dates = [ - // ['2017-04-03', '2017-12-31'], - // ['2017-04-03'], - // ['2017-04-04'], - // ] - // }) - const { showClosedTasks, showClosedRecommendations } = config const [selectedIssue, setSelectedIssue] = useState(null) @@ -60,10 +50,6 @@ const Dashboard = () => { })) } - const renderDate = (date) => ( - date.map((dateValue) => useFormattedDateTime(dateValue, language, 'dateOnly')).join(' - ') - ) - const renderVisibleIssues = (visibleIssues) => (
{ @@ -100,7 +86,7 @@ const Dashboard = () => { issue.dates?.length > 0 && (
- {renderDate(issue.dates[0])} + {renderIssueDate(issue.dates[0])}
) } diff --git a/rdmo/projects/assets/js/project/components/areas/dashboard/IssueModal.js b/rdmo/projects/assets/js/project/components/areas/dashboard/IssueModal.js index c8a48b3758..fb49469f63 100644 --- a/rdmo/projects/assets/js/project/components/areas/dashboard/IssueModal.js +++ b/rdmo/projects/assets/js/project/components/areas/dashboard/IssueModal.js @@ -2,13 +2,12 @@ import React from 'react' import PropTypes from 'prop-types' import { Modal } from 'rdmo/core/assets/js/_bs53/components' -import { useFormattedDateTime } from 'rdmo/core/assets/js/hooks' -import { language } from 'rdmo/core/assets/js/utils' import { baseUrl } from 'rdmo/core/assets/js/utils/meta' import Select from 'rdmo/core/assets/js/components/forms/Select' import { projectId } from '../../../utils/meta' +import { renderIssueDate } from '../../../utils/renderIssueDate' const IssueModal = ({ canChangeIssue = false, @@ -23,10 +22,6 @@ const IssueModal = ({ { value: 'in_progress', label: gettext('In progress') }, ] - const renderDate = (date) => ( - date.map((dateValue) => useFormattedDateTime(dateValue, language, 'dateOnly')).join(' - ') - ) - return ( (
- {renderDate(date)} + {renderIssueDate(date)}
)) } diff --git a/rdmo/projects/assets/js/project/components/areas/snapshots/SnapshotTable.js b/rdmo/projects/assets/js/project/components/areas/snapshots/SnapshotTable.js index 201f670911..9380d3534b 100644 --- a/rdmo/projects/assets/js/project/components/areas/snapshots/SnapshotTable.js +++ b/rdmo/projects/assets/js/project/components/areas/snapshots/SnapshotTable.js @@ -3,9 +3,8 @@ import PropTypes from 'prop-types' import { useDispatch, useSelector } from 'react-redux' import { Link } from 'rdmo/core/assets/js/components' -import { useFormattedDateTime } from 'rdmo/core/assets/js/hooks' import { useModal } from 'rdmo/core/assets/js/hooks' -import { language } from 'rdmo/core/assets/js/utils' +import { formatDateTime } from 'rdmo/core/assets/js/utils/date' import { navigateDashboard } from '../../../actions/projectActions' import { buildPath } from '../../../utils/location' @@ -63,7 +62,7 @@ const SnapshotTable = ({ snapshots }) => { {snapshot.description} - {useFormattedDateTime(snapshot.created, language)} + {formatDateTime(snapshot.created, 'long')}
diff --git a/rdmo/projects/assets/js/project/utils/renderIssueDate.js b/rdmo/projects/assets/js/project/utils/renderIssueDate.js new file mode 100644 index 0000000000..b7710cb4de --- /dev/null +++ b/rdmo/projects/assets/js/project/utils/renderIssueDate.js @@ -0,0 +1,15 @@ +import { formatDate } from 'rdmo/core/assets/js/utils/date' + +export const renderIssueDate = (date) => { + const { start_date: startDate, end_date: endDate } = date + + if (startDate && endDate) { + return `${formatDate(startDate, 'long')} - ${formatDate(endDate, 'long')}` + } + + return startDate ? ( + `${gettext('Start date')}: ${formatDate(startDate, 'long')}` + ) : `${gettext('End date')}: ${formatDate(endDate, 'long')}` +} + +export default renderIssueDate diff --git a/rdmo/projects/assets/js/projects/components/Main.js b/rdmo/projects/assets/js/projects/components/Main.js index da76d9d98f..085bcb1c55 100644 --- a/rdmo/projects/assets/js/projects/components/Main.js +++ b/rdmo/projects/assets/js/projects/components/Main.js @@ -5,8 +5,8 @@ import { get, isEmpty } from 'lodash' import { Modal } from 'rdmo/core/assets/js/_bs53/components' import * as configActions from 'rdmo/core/assets/js/actions/configActions' import { Link, SearchField } from 'rdmo/core/assets/js/components' -import { useFormattedDateTime, useModal, useScrollToTop } from 'rdmo/core/assets/js/hooks' -import { language } from 'rdmo/core/assets/js/utils' +import { useModal, useScrollToTop } from 'rdmo/core/assets/js/hooks' +import { formatDateTime } from 'rdmo/core/assets/js/utils/date' import { baseUrl } from 'rdmo/core/assets/js/utils/meta' import * as projectsActions from '../actions/projectsActions' @@ -267,8 +267,8 @@ const Main = () => { ), progress: (_content, row) => getProgressString(row), - created: content => useFormattedDateTime(content, language), - last_changed: content => useFormattedDateTime(content, language), + created: content => formatDateTime(content, 'long'), + last_changed: content => formatDateTime(content, 'long'), actions: (_content, row) => { const perms = row.permissions || {} return ( diff --git a/rdmo/projects/models/issue.py b/rdmo/projects/models/issue.py index da7341170a..e391d0ec1a 100644 --- a/rdmo/projects/models/issue.py +++ b/rdmo/projects/models/issue.py @@ -89,11 +89,18 @@ def dates(self): end_date = None if start_date and end_date: - dates.append((start_date - days_before, end_date + days_after)) + dates.append({ + "start_date": start_date - days_before, + "end_date": end_date + days_after, + }) elif start_date: - dates.append((start_date - days_before + days_after, )) + dates.append({ + "start_date": start_date - days_before + days_after, + }) elif end_date: - dates.append((end_date - days_before + days_after, )) + dates.append({ + "end_date": end_date - days_before + days_after, + }) return dates