Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed overnight datetime formatting #323

Merged
merged 1 commit into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function ReservationDetails({
let reservationTime = '';

if (selectedTime) {
reservationTime = formatDetailsDatetimes(selectedTime.begin, selectedTime.end, t('common.unit.time.day.short'));
reservationTime = formatDetailsDatetimes(selectedTime.begin, selectedTime.end, t, t('common.unit.time.day.short'));
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class ReservationListItem extends Component {
beginFormat={beginFormat}
end={reservation.end}
endFormat={endFormat}
isMultiday={isReservationMultiday}
/>
</div>
<ReservationAccessCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ describe('pages/user-reservations/reservation-list/ReservationListItem', () => {
expect(timeRange.prop('end')).toBe(props.reservation.end);
expect(timeRange.prop('beginFormat')).toBe('dddd, LLL');
expect(timeRange.prop('endFormat')).toBe('LT');
expect(timeRange.prop('isMultiday')).toBe(false);
});
});

Expand All @@ -105,6 +106,7 @@ describe('pages/user-reservations/reservation-list/ReservationListItem', () => {
expect(timeRange.prop('end')).toBe(reservationA.end);
expect(timeRange.prop('beginFormat')).toBe('D.M.YYYY HH:mm');
expect(timeRange.prop('endFormat')).toBe('D.M.YYYY HH:mm');
expect(timeRange.prop('isMultiday')).toBe(true);
});
});

Expand Down
1 change: 1 addition & 0 deletions app/shared/modals/reservation-info/ReservationEditForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ class UnconnectedReservationEditForm extends Component {
beginFormat={beginFormat}
end={reservation.end}
endFormat={endFormat}
isMultiday={isReservationMultiday}
/>
);
return this.renderInfoRow(t('common.reservationTimeLabel'), staticReservationTime);
Expand Down
8 changes: 4 additions & 4 deletions app/shared/overnight-calendar/OvernightCalendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,25 +234,25 @@ function OvernightCalendar({
{!isEditing && (
<OvernightSummary
duration={selectedDuration}
endDatetime={getOvernightDatetime(endDate, overnightEndTime)}
endDatetime={getOvernightDatetime(endDate, overnightEndTime, t)}
handleSelectDatetimes={handleSelectDatetimes}
isDurationBelowMin={isDurBelowMin}
minDuration={minPeriod}
selected={selected}
startDatetime={getOvernightDatetime(startDate, overnightStartTime)}
startDatetime={getOvernightDatetime(startDate, overnightStartTime, t)}
/>
)}
{isEditing && (
<OvernightEditSummary
datesSameAsInitial={datesSameAsInitial}
duration={selectedDuration}
endDatetime={getOvernightDatetime(endDate, overnightEndTime)}
endDatetime={getOvernightDatetime(endDate, overnightEndTime, t)}
isDurationBelowMin={isDurBelowMin}
minDuration={minPeriod}
onCancel={onEditCancel}
onConfirm={handleSelectDatetimes}
selected={selected}
startDatetime={getOvernightDatetime(startDate, overnightStartTime)}
startDatetime={getOvernightDatetime(startDate, overnightStartTime, t)}
/>
)}
</div>
Expand Down
7 changes: 5 additions & 2 deletions app/shared/overnight-calendar/overnightUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import moment from 'moment';

import { formatDatetimeToString } from '../../utils/timeUtils';

/**
* Handles setting the start and end dates when selecting a date range.
* @param {Object} params
Expand Down Expand Up @@ -339,13 +341,14 @@ export function setDatesTime(date, time) {
* Combines date and time into a datetime string and returns it.
* @param {Date} date
* @param {string} time e.g. "12:00:00"
* @param {function} t
* @returns {string} datetime string e.g. "2018-02-01T12:00:00Z"
* or empty string if date or time is missing
*/
export function getOvernightDatetime(date, time) {
export function getOvernightDatetime(date, time, t) {
if (date && time) {
const momentDate = setDatesTime(date, time);
return momentDate.format('D.M.YYYY HH:mm');
return formatDatetimeToString(momentDate, t);
}
return '';
}
Expand Down
4 changes: 2 additions & 2 deletions app/shared/overnight-calendar/tests/OvernightCalendar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,13 @@ describe('app/shared/overnight-calendar/OvernightCalendar', () => {
expect(editSummary).toHaveLength(1);
expect(editSummary.prop('datesSameAsInitial')).toBe(true);
expect(editSummary.prop('duration')).toBeDefined();
expect(editSummary.prop('endDatetime')).toBe('19.2.2024 09:00');
expect(editSummary.prop('endDatetime')).toBe('19.2.2024 TimeSlots.selectedTime');
expect(editSummary.prop('isDurationBelowMin')).toBe(false);
expect(editSummary.prop('minDuration')).toBe(defaultProps.resource.minPeriod);
expect(editSummary.prop('onCancel')).toBe(defaultProps.onEditCancel);
expect(editSummary.prop('onConfirm')).toBeDefined();
expect(editSummary.prop('selected')).toBe(selected);
expect(editSummary.prop('startDatetime')).toBe('18.2.2024 11:00');
expect(editSummary.prop('startDatetime')).toBe('18.2.2024 TimeSlots.selectedTime');
});
});
});
Expand Down
11 changes: 6 additions & 5 deletions app/shared/overnight-calendar/tests/overnightUtils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,16 +533,17 @@ describe('app/shared/overnight-calendar/overnightUtils', () => {
});

describe('getOvernightDatetime', () => {
const t = (str, timeObj) => `${str} ${timeObj.time}`;
test('returns correct datetime string', () => {
const date = moment('2024-04-23').toDate();
const time = '10:30:00';
const result = getOvernightDatetime(date, time);
expect(result).toBe('23.4.2024 10:30');
const result = getOvernightDatetime(date, time, t);
expect(result).toBe('23.4.2024 TimeSlots.selectedTime 10:30');
});
test('returns empty string when date or time is missing', () => {
expect(getOvernightDatetime(null, null)).toBe('');
expect(getOvernightDatetime(null, '10:30:00')).toBe('');
expect(getOvernightDatetime(moment('2024-04-23').toDate(), null)).toBe('');
expect(getOvernightDatetime(null, null, t)).toBe('');
expect(getOvernightDatetime(null, '10:30:00', t)).toBe('');
expect(getOvernightDatetime(moment('2024-04-23').toDate(), null, t)).toBe('');
});
});

Expand Down
6 changes: 3 additions & 3 deletions app/shared/reservation-date/ReservationOvernightDate.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import moment from 'moment';

import iconClock from 'assets/icons/clock-o.svg';
import iconCalendar from 'assets/icons/calendar.svg';
import { getPrettifiedDuration } from 'utils/timeUtils';
import { getPrettifiedDuration, formatDatetimeToString } from 'utils/timeUtils';
import injectT from '../../i18n/injectT';

function ReservationOvernightDate({ beginDate, endDate, t }) {
Expand All @@ -14,8 +14,8 @@ function ReservationOvernightDate({ beginDate, endDate, t }) {

const reservationBegin = moment(beginDate);
const reservationEnd = moment(endDate);
const begin = reservationBegin.format('D.M.YYYY HH:mm');
const end = reservationEnd.format('D.M.YYYY HH:mm');
const begin = formatDatetimeToString(reservationBegin, t);
const end = formatDatetimeToString(reservationEnd, t);
const duration = getPrettifiedDuration(reservationBegin, reservationEnd, t('common.unit.time.day.short'));

return (
Expand Down
4 changes: 2 additions & 2 deletions app/shared/reservation-date/ReservationOvernightDate.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ describe('shared/reservation-date/ReservationOvernightDate', () => {
test('renders time texts', () => {
const texts = wrapper.find('p.reservation-date__time');
expect(texts.length).toBe(3);
expect(texts.at(0).text()).toBe('common.time.begin: 29.1.2018 13:00');
expect(texts.at(1).text()).toBe('common.time.end: 31.1.2018 09:00');
expect(texts.at(0).text()).toBe('common.time.begin: 29.1.2018 TimeSlots.selectedTime');
expect(texts.at(1).text()).toBe('common.time.end: 31.1.2018 TimeSlots.selectedTime');
expect(texts.at(2).text()).toBe('common.time.duration: 1common.unit.time.day.short 20h');
});

Expand Down
17 changes: 15 additions & 2 deletions app/shared/time-range/TimeRange.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@ import moment from 'moment';
import PropTypes from 'prop-types';
import React from 'react';

import { formatDatetimeToString } from '../../utils/timeUtils';
import injectT from '../../i18n/injectT';

function TimeRange(props) {
const {
begin,
className,
beginFormat,
end,
endFormat,
isMultiday,
t,
} = props;
const beginMoment = moment(begin);
const endMoment = moment(end);
const rangeString = `${beginMoment.format(beginFormat)} \u2013 ${endMoment.format(endFormat)}`;
let rangeString = '';
if (isMultiday) {
rangeString = `${formatDatetimeToString(beginMoment, t)} \u2013 ${formatDatetimeToString(endMoment, t)}`;
} else {
rangeString = `${beginMoment.format(beginFormat)} \u2013 ${endMoment.format(endFormat)}`;
}
const ISORangeString = `${begin}/${end}`;

return (
Expand All @@ -29,11 +39,14 @@ TimeRange.propTypes = {
className: PropTypes.string,
end: PropTypes.string.isRequired,
endFormat: PropTypes.string,
isMultiday: PropTypes.bool,
t: PropTypes.func.isRequired,
};

TimeRange.defaultProps = {
beginFormat: 'dddd, LLL',
endFormat: 'LT',
isMultiday: false,
};

export default TimeRange;
export default injectT(TimeRange);
12 changes: 10 additions & 2 deletions app/shared/time-range/TimeRange.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { shallow } from 'enzyme';
import moment from 'moment';
import React from 'react';

import { shallowWithIntl } from 'utils/testUtils';
import TimeRange from './TimeRange';

describe('shared/time-range/TimeRange', () => {
Expand All @@ -14,7 +14,7 @@ describe('shared/time-range/TimeRange', () => {
};

function getWrapper(extraProps) {
return shallow(<TimeRange {...defaultProps} {...extraProps} />);
return shallowWithIntl(<TimeRange {...defaultProps} {...extraProps} />);
}

test('renders a time element', () => {
Expand Down Expand Up @@ -45,5 +45,13 @@ describe('shared/time-range/TimeRange', () => {
const expected = moment(defaultProps.end).format(defaultProps.endFormat);
expect(rangeString).toContain(expected);
});

describe('when time range is multiday', () => {
test('display correct range string', () => {
const timeElement = getWrapper({ isMultiday: true, end: '2015-10-12T14:00:00Z' });
expect(timeElement).toHaveLength(1);
expect(timeElement.text()).toBe('11.10.2015 TimeSlots.selectedTime – 12.10.2015 TimeSlots.selectedTime');
});
});
});
});
16 changes: 13 additions & 3 deletions app/utils/__tests__/timeUtils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import {
formatTime,
formatDateTime,
formatDetailsDatetimes,
isMultiday
isMultiday,
formatDatetimeToString
} from 'utils/timeUtils';

const moment = extendMoment(Moment);
Expand Down Expand Up @@ -883,9 +884,18 @@ describe('Utils: timeUtils', () => {
describe('formatDetailsDatetimes', () => {
test.each([
['2023-11-01T15:00:00Z', '2023-11-01T16:00:00Z', '1.11.2023 17:00–18:00 (1h)'],
['2023-11-01T15:00:00Z', '2023-11-03T13:00:00Z', '1.11.2023 17:00 - 3.11.2023 15:00 (1d 22h)'],
['2023-11-01T15:00:00Z', '2023-11-03T13:00:00Z', '1.11.2023 TimeSlots.selectedTime 17:00 - 3.11.2023 TimeSlots.selectedTime 15:00 (1d 22h)'],
])('returns correctly formatted datetime string with given params', (begin, end, expected) => {
expect(formatDetailsDatetimes(begin, end)).toBe(expected);
const t = (str, timeObj) => `${str} ${timeObj.time}`;
expect(formatDetailsDatetimes(begin, end, t)).toBe(expected);
});
});

describe('formatDatetimeToString', () => {
const t = (str, timeObj) => `${str} ${timeObj.time}`;
test('returns correct string', () => {
expect(formatDatetimeToString('2023-11-01T15:00:00Z', t)).toBe('1.11.2023 TimeSlots.selectedTime 17:00');
expect(formatDatetimeToString(moment('2023-11-01T15:00:00Z'), t)).toBe('1.11.2023 TimeSlots.selectedTime 17:00');
});
});

Expand Down
21 changes: 18 additions & 3 deletions app/utils/timeUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,13 @@ function formatDateTime(datetime, targetFormat) {
* D.M.YYYY HH:mm–HH:mm (1h 30min) or D.M.YYYY HH:mm - D.M.YYYY HH:mm (2d 5h)
* @param {string} begin datetime
* @param {string} end datetime
* @param {function} t
* @returns {string} formatted datetime string
*/
function formatDetailsDatetimes(begin, end, dayUnit = 'd') {
function formatDetailsDatetimes(begin, end, t, dayUnit = 'd') {
if (isMultiday(begin, end)) {
const beginText = moment(begin).format('D.M.YYYY HH:mm');
const endText = moment(end).format('D.M.YYYY HH:mm');
const beginText = formatDatetimeToString(begin, t);
const endText = formatDatetimeToString(end, t);
const duration = getPrettifiedDuration(begin, end, dayUnit);
return `${beginText} - ${endText} (${duration})`;
}
Expand All @@ -369,6 +370,19 @@ function formatDetailsDatetimes(begin, end, dayUnit = 'd') {
return `${beginText}–${endText} (${duration})`;
}

/**
* Formats datetime to string
* @param {object|string} datetime any moment parsable format
* @param {function} t
* @returns {string} formatted datetime string e.g 20.10.2010 11:00
*/
function formatDatetimeToString(datetime, t) {
const momentDatetime = moment(datetime);
const formattedDate = momentDatetime.format('D.M.YYYY');
const formattedTime = t('TimeSlots.selectedTime', { time: momentDatetime.format('HH:mm') });
return `${formattedDate} ${formattedTime}`;
}

/**
* Check whether begin and end are on different days
* @param {string} begin datetime
Expand Down Expand Up @@ -403,4 +417,5 @@ export {
formatDateTime,
formatDetailsDatetimes,
isMultiday,
formatDatetimeToString,
};
Loading