Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## [11.0.0] (IN PROGRESS)

* Package Record - Titlelist Display - Add Column for Tags and few column width adjustments. (UIEH-1449)
* Replace `moment` usage with `dayjs`. (UIEH-1407)

## [11.0.0] (https://github.com/folio-org/ui-eholdings/tree/v11.0.0) (2025-03-13)

Expand Down
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
"husky": "^1.3.1",
"identity-obj-proxy": "^3.0.0",
"lodash": "^4.17.4",
"moment": "^2.24.0",
"moment-range": "^3.0.3",
"qs": "^6.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import {
injectIntl,
} from 'react-intl';

import moment from 'moment';
import isEqual from 'lodash/isEqual';

import {
Datepicker,
RepeatableField,
Col,
Row,
dayjs,
getLocaleDateFormat,
} from '@folio/stripes/components';
import {
BACKEND_DATE_STANDARD,
Expand All @@ -32,7 +33,7 @@ class PackageCoverageFields extends Component {
values?.forEach(({ beginCoverage, endCoverage }) => {
const errors = {};

if (endCoverage && !moment.utc(endCoverage).isAfter(moment.utc(beginCoverage))) {
if (endCoverage && !dayjs.utc(endCoverage).isAfter(dayjs.utc(beginCoverage))) {
errors.beginCoverage = <FormattedMessage id="ui-eholdings.validate.errors.dateRange.startDateBeforeEndDate" />;
}

Expand All @@ -44,11 +45,10 @@ class PackageCoverageFields extends Component {

validateCoverageDate = (value) => {
const { intl } = this.props;
moment.locale(intl.locale);
const dateFormat = moment.localeData()._longDateFormat.L;
const dateFormat = getLocaleDateFormat({ intl });
let errors;

if (value && !moment.utc(value).isValid()) {
if (value && !dayjs.utc(value).isValid()) {
errors = (
<FormattedMessage
id="ui-eholdings.validate.errors.dateRange.format"
Expand Down
52 changes: 25 additions & 27 deletions src/components/resource/_fields/validate-date-range.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import {
FormattedMessage,
} from 'react-intl';
import Moment from 'moment';
import { extendMoment } from 'moment-range';

import { FormattedDate } from '@folio/stripes/components';
import { FormattedMessage } from 'react-intl';

const moment = extendMoment(Moment);
import {
FormattedDate,
dayjs,
DayRange,
getLocaleDateFormat,
} from '@folio/stripes/components';

/**
* Validator to ensure begin date is present and entered dates are valid
* @param {} dateRange - coverage date range to validate
* @returns {} - an error object if errors are found, or `undefined` otherwise
*/
const validateDateFormat = (dateRange, locale) => {
moment.locale(locale);
const dateFormat = moment.localeData()._longDateFormat.L;
const dateFormat = getLocaleDateFormat({ intl: { locale } });
const message = <FormattedMessage id="ui-eholdings.validate.errors.dateRange.format" values={{ dateFormat }} />;

if (!dateRange.beginCoverage || !moment.utc(dateRange.beginCoverage).isValid()) {
if (!dateRange.beginCoverage || !dayjs.utc(dateRange.beginCoverage).isValid()) {
return { beginCoverage: message };
}

Expand All @@ -33,7 +31,7 @@ const validateDateFormat = (dateRange, locale) => {
const validateStartDateBeforeEndDate = (dateRange) => {
const message = <FormattedMessage id="ui-eholdings.validate.errors.dateRange.startDateBeforeEndDate" />;

if (dateRange.endCoverage && moment.utc(dateRange.beginCoverage).isAfter(moment.utc(dateRange.endCoverage))) {
if (dateRange.endCoverage && dayjs.utc(dateRange.beginCoverage).isAfter(dayjs.utc(dateRange.endCoverage))) {
return { beginCoverage: message };
}

Expand All @@ -49,11 +47,11 @@ const validateStartDateBeforeEndDate = (dateRange) => {
* @returns {} - an error object if errors are found, or `undefined` otherwise
*/
const validateNoRangeOverlaps = (dateRange, customCoverages, index) => {
const present = moment.utc('9999-09-09T05:00:00.000Z');
const present = dayjs.utc('9999-09-09T05:00:00.000Z');

const beginCoverageDate = moment.utc(dateRange.beginCoverage);
const endCoverageDate = dateRange.endCoverage ? moment.utc(dateRange.endCoverage) : present;
const coverageRange = moment.range(beginCoverageDate, endCoverageDate);
const beginCoverageDate = dayjs.utc(dateRange.beginCoverage);
const endCoverageDate = dateRange.endCoverage ? dayjs.utc(dateRange.endCoverage) : present;
const coverageRange = new DayRange(beginCoverageDate, endCoverageDate);

for (let overlapIndex = 0, len = customCoverages.length; overlapIndex < len; overlapIndex++) {
const overlapRange = customCoverages[overlapIndex];
Expand All @@ -63,9 +61,9 @@ const validateNoRangeOverlaps = (dateRange, customCoverages, index) => {
continue; // eslint-disable-line no-continue
}

const overlapCoverageBeginDate = moment.utc(overlapRange.beginCoverage);
const overlapCoverageEndDate = overlapRange.endCoverage ? moment.utc(overlapRange.endCoverage) : present;
const overlapCoverageRange = moment.range(overlapCoverageBeginDate, overlapCoverageEndDate);
const overlapCoverageBeginDate = dayjs.utc(overlapRange.beginCoverage);
const overlapCoverageEndDate = overlapRange.endCoverage ? dayjs.utc(overlapRange.endCoverage) : present;
const overlapCoverageRange = new DayRange(overlapCoverageBeginDate, overlapCoverageEndDate);

const startDate =
<FormattedDate
Expand All @@ -89,7 +87,7 @@ const validateNoRangeOverlaps = (dateRange, customCoverages, index) => {
const message = <FormattedMessage id="ui-eholdings.validate.errors.dateRange.overlap" values={{ startDate, endDate }} />;

if (overlapCoverageRange.overlaps(coverageRange)
|| overlapCoverageRange.isEqual(coverageRange)
|| overlapCoverageRange.isSame(coverageRange)
|| overlapCoverageRange.contains(coverageRange)) {
return { beginCoverage: message, endCoverage: message };
}
Expand All @@ -109,16 +107,16 @@ const validateWithinPackageRange = (resourceDateRange, packageDateRange) => {
beginCoverage: packageBeginCoverage,
endCoverage: packageEndCoverage
} = packageDateRange;
// javascript/moment has no mechanism for "infinite", so we
// javascript/dayjs has no mechanism for "infinite", so we
// use an absurd future date to represent the concept of "present"
const present = moment.utc('9999-09-09T05:00:00.000Z');
const present = dayjs.utc('9999-09-09T05:00:00.000Z');
if (packageBeginCoverage) {
const beginCoverageDate = moment.utc(resourceDateRange.beginCoverage);
const endCoverageDate = resourceDateRange.endCoverage ? moment.utc(resourceDateRange.endCoverage) : present;
const beginCoverageDate = dayjs.utc(resourceDateRange.beginCoverage);
const endCoverageDate = resourceDateRange.endCoverage ? dayjs.utc(resourceDateRange.endCoverage) : present;

const packageBeginCoverageDate = moment.utc(packageBeginCoverage);
const packageEndCoverageDate = packageEndCoverage ? moment.utc(packageEndCoverage) : moment.utc();
const packageRange = moment.range(packageBeginCoverageDate, packageEndCoverageDate);
const packageBeginCoverageDate = dayjs.utc(packageBeginCoverage);
const packageEndCoverageDate = packageEndCoverage ? dayjs.utc(packageEndCoverage) : dayjs.utc();
const packageRange = new DayRange(packageBeginCoverageDate, packageEndCoverageDate);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @JohnC-80 this is a very very belated review, apologies for that.
It looks like functions for moment.contains and dayjs.isBetween work differently.
moment returns true if we check dates that are either the beginning or end date, but dayjs will return false.
For example, for when checking if date 2021-01-01 is in range 2021-01-01 to 2021-01-31 moment will return true, but dayjs will return false.
The isBetween plugin has a parameter that defines if begin and end dates should or should not be included: https://day.js.org/docs/en/plugin/is-between

I think since we've been using moment and by default it includes start and end date then we should do the same with dayjs. Do you have any thoughts?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am working on making this PR up-to-date so we can merge it, just need to confirm with you if we should make the date inclusivity a default behaviour or not

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a PR to handle date ranges correctly folio-org/stripes-components#2443


const startDate =
<FormattedDate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ describe('Given EditCoverageSettings', () => {
});
});

describe('when setting incorrect coverage dates', () => {
describe('when setting start coverage date after end coverage date', () => {
it('should show error message', () => {
const {
getByLabelText,
Expand All @@ -165,4 +165,40 @@ describe('Given EditCoverageSettings', () => {
expect(getByText('ui-eholdings.validate.errors.dateRange.startDateBeforeEndDate')).toBeDefined();
});
});

describe('when setting coverage dates are outside of package coverage dates', () => {
it('should show error message', () => {
const {
getByLabelText,
getByText,
} = renderCoverageSettings();

const startDateInput = getByLabelText('ui-eholdings.date.startDate');
const endDateInput = getByLabelText('ui-eholdings.date.endDate');

fireEvent.change(startDateInput, { target: { value: '01/02/2021' } });
fireEvent.change(endDateInput, { target: { value: '02/01/2021' } });
fireEvent.blur(endDateInput);

expect(getByText('ui-eholdings.validate.errors.dateRange.packageRange')).toBeDefined();
});
});

describe('when setting coverage dates are within package coverage dates', () => {
it('should show error message', () => {
const {
getByLabelText,
queryByText,
} = renderCoverageSettings();

const startDateInput = getByLabelText('ui-eholdings.date.startDate');
const endDateInput = getByLabelText('ui-eholdings.date.endDate');

fireEvent.change(startDateInput, { target: { value: '01/01/2021' } });
fireEvent.change(endDateInput, { target: { value: '01/31/2021' } });
fireEvent.blur(endDateInput);

expect(queryByText('ui-eholdings.validate.errors.dateRange.packageRange')).not.toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import {
FormattedMessage,
useIntl,
} from 'react-intl';
import moment from 'moment';

import {
useStripes,
} from '@folio/stripes/core';
import {
Select,
TextField,
dayjs,
} from '@folio/stripes/components';

import SettingsForm from '../settings-form';
Expand Down Expand Up @@ -134,7 +134,7 @@ const SettingsUsageConsolidation = ({

const monthDataOptions = MONTHS.map((month, index) => ({
value: month.toLowerCase().substring(0, 3),
label: moment.months()[index],
label: dayjs.months()[index],
}));

const parseUsageConsolidationId = value => {
Expand Down
14 changes: 8 additions & 6 deletions src/components/utilities.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import moment from 'moment';
import queryString from 'qs';
import {
get,
Expand All @@ -8,7 +7,10 @@ import {
FormattedMessage,
} from 'react-intl';

import { FormattedDate } from '@folio/stripes/components';
import {
FormattedDate,
dayjs,
} from '@folio/stripes/components';

import {
searchTypes,
Expand Down Expand Up @@ -68,7 +70,7 @@ export function formatCoverageYear({ beginCoverage, endCoverage }) {

if (!startYear) {
return endCoverage ? endYear : '';
} else if ((moment.utc(beginCoverage).format('YYYY') === moment.utc(endCoverage).format('YYYY')) || (!endYear)) {
} else if ((dayjs.utc(beginCoverage).format('YYYY') === dayjs.utc(endCoverage).format('YYYY')) || (!endYear)) {
return startYear;
} else {
return <>{startYear}{' - '}{endYear}</>;
Expand All @@ -77,10 +79,10 @@ export function formatCoverageYear({ beginCoverage, endCoverage }) {

export function isValidCoverage(coverageObj) {
if (coverageObj.beginCoverage) {
if (!moment.utc(coverageObj.beginCoverage, 'YYYY-MM-DD').isValid()) { return false; }
if (!dayjs.utc(coverageObj.beginCoverage, 'YYYY-MM-DD').isValid()) { return false; }
}
if (coverageObj.endCoverage) {
if (!moment.utc(coverageObj.endCoverage, 'YYYY-MM-DD').isValid()) { return false; }
if (!dayjs.utc(coverageObj.endCoverage, 'YYYY-MM-DD').isValid()) { return false; }
}
return true;
}
Expand Down Expand Up @@ -274,7 +276,7 @@ export const getFullName = user => {

export const parseDate = value => value;

export const formatDate = value => (value ? moment.utc(value) : '');
export const formatDate = value => (value ? dayjs.utc(value) : '');

export const combineMCLProps = defaultProps => customProps => {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
} from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import moment from 'moment';
import noop from 'lodash/noop';

import { useStripes } from '@folio/stripes/core';
Expand All @@ -13,6 +12,7 @@ import {
Headline,
InfoPopover,
Spinner,
dayjs,
} from '@folio/stripes/components';

import Toaster from '../../../components/toaster';
Expand Down Expand Up @@ -67,7 +67,7 @@ const UsageConsolidationAccordion = ({
const { isLoading: isCostPerUseDataLoading } = costPerUseData;

const filtersInitialState = {
year: moment().year(),
year: dayjs().year(),
platformType: usageConsolidation.data.platformType,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
Form,
Field,
} from 'react-final-form';
import moment from 'moment';
import {
useIntl,
FormattedMessage,
Expand All @@ -19,6 +18,7 @@ import {
Row,
Col,
Button,
dayjs,
} from '@folio/stripes/components';

import { platformTypes } from '../../constants';
Expand All @@ -45,7 +45,7 @@ const UsageConsolidationFilters = ({
}
}, [yearField]);

const currentYear = moment().year();
const currentYear = dayjs().year();
const last5Years = new Array(5)
.fill(currentYear)
.map((year, index) => year - index);
Expand Down
9 changes: 5 additions & 4 deletions src/routes/package-create-route/package-create-route.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Component } from 'react';
import PropTypes from 'prop-types';
import ReactRouterPropTypes from 'react-router-prop-types';
import moment from 'moment';
import { TitleManager } from '@folio/stripes/core';
import { FormattedMessage } from 'react-intl';

import { TitleManager } from '@folio/stripes/core';
import { dayjs } from '@folio/stripes/components';

import View from '../../components/package/create';

import { accessTypesReduxStateShape } from '../../constants';
Expand Down Expand Up @@ -41,9 +42,9 @@ export default class PackageCreateRoute extends Component {
if (values?.customCoverages?.[0]) {
attrs.customCoverage = {
beginCoverage: !values.customCoverages[0].beginCoverage ? '' :
moment.utc(values.customCoverages[0].beginCoverage).format('YYYY-MM-DD'),
dayjs.utc(values.customCoverages[0].beginCoverage).format('YYYY-MM-DD'),
endCoverage: !values.customCoverages[0].endCoverage ? '' :
moment.utc(values.customCoverages[0].endCoverage).format('YYYY-MM-DD')
dayjs.utc(values.customCoverages[0].endCoverage).format('YYYY-MM-DD')
};
}

Expand Down
6 changes: 3 additions & 3 deletions src/routes/package-edit-route/package-edit-route.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Component } from 'react';
import PropTypes from 'prop-types';
import ReactRouterPropTypes from 'react-router-prop-types';
import isEqual from 'lodash/isEqual';
import moment from 'moment';
import { FormattedMessage } from 'react-intl';

import { TitleManager } from '@folio/stripes/core';
import { dayjs } from '@folio/stripes/components';

import View from '../../components/package/package-edit';

Expand Down Expand Up @@ -135,8 +135,8 @@ class PackageEditRoute extends Component {
let endCoverage = '';

if (values.customCoverages[0]) {
beginCoverage = !values.customCoverages[0].beginCoverage ? '' : moment.utc(values.customCoverages[0].beginCoverage).format('YYYY-MM-DD');
endCoverage = !values.customCoverages[0].endCoverage ? '' : moment.utc(values.customCoverages[0].endCoverage).format('YYYY-MM-DD');
beginCoverage = !values.customCoverages[0].beginCoverage ? '' : dayjs.utc(values.customCoverages[0].beginCoverage).format('YYYY-MM-DD');
endCoverage = !values.customCoverages[0].endCoverage ? '' : dayjs.utc(values.customCoverages[0].endCoverage).format('YYYY-MM-DD');
}

model.customCoverage = {
Expand Down
Loading