Skip to content

Commit

Permalink
chore(date): Migrate Date (#3766)
Browse files Browse the repository at this point in the history
  • Loading branch information
greg-in-a-box authored Dec 5, 2024
1 parent f8cdfff commit d400d6c
Show file tree
Hide file tree
Showing 8 changed files with 363 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
/**
* @flow
* @file Function to render the date table cell
* @author Box
*/

import * as React from 'react';
import { injectIntl, FormattedMessage } from 'react-intl';
import type { IntlShape } from 'react-intl';
import { FormattedMessage, useIntl} from 'react-intl';
import { isToday, isYesterday } from '../../../utils/datetime';
import messages from '../messages';
import './DateField.scss';

type Props = {
capitalize?: boolean,
date: string,
dateFormat?: Object,
intl: IntlShape,
dateFormat?: any,
omitCommas?: boolean,
relative?: boolean,
relative?: boolean
};

const DEFAULT_DATE_FORMAT = {
Expand All @@ -31,10 +23,10 @@ const DateField = ({
date,
dateFormat = DEFAULT_DATE_FORMAT,
omitCommas = false,
intl,
relative = true,
capitalize = false,
}: Props) => {
const { formatDate } = useIntl();
const d = new Date(date);
const isTodaysDate = isToday(d);
const isYesterdaysDate = isYesterday(d);
Expand All @@ -52,9 +44,9 @@ const DateField = ({
return Message;
}

let formattedDate = intl.formatDate(d, dateFormat);
let formattedDate = formatDate(d, dateFormat);
formattedDate = omitCommas ? formattedDate.replace(/,/g, '') : formattedDate;
return formattedDate;
};

export default injectIntl(DateField);
export default DateField;
53 changes: 53 additions & 0 deletions src/elements/common/date/DateField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as React from 'react';
import { FormatDateOptions, FormattedMessage, useIntl } from 'react-intl';
import { isToday, isYesterday } from '../../../utils/datetime';

import messages from '../messages';
import './DateField.scss';

const DEFAULT_DATE_FORMAT = {
weekday: 'short',
month: 'short',
year: 'numeric',
day: 'numeric',
} as const;

export interface DateFieldProps {
capitalize?: boolean;
date: string;
dateFormat?: FormatDateOptions;
omitCommas?: boolean;
relative?: boolean;
}

const DateField = ({
date,
dateFormat = DEFAULT_DATE_FORMAT,
omitCommas = false,
relative = true,
capitalize = false,
}: DateFieldProps): React.ReactNode | string => {
const { formatDate } = useIntl();
const d = new Date(date);
const isTodaysDate = isToday(d);
const isYesterdaysDate = isYesterday(d);

if (relative && (isTodaysDate || isYesterdaysDate)) {
let Message = <FormattedMessage {...messages.today} />;
if (isYesterdaysDate) {
Message = <FormattedMessage {...messages.yesterday} />;
}

if (capitalize) {
return <span className="be-date-capitalize">{Message}</span>;
}

return Message;
}

let formattedDate = formatDate(d, dateFormat);
formattedDate = omitCommas ? formattedDate.replace(/,/g, '') : formattedDate;
return formattedDate;
};

export default DateField;
48 changes: 48 additions & 0 deletions src/elements/common/date/__tests__/DateField.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as React from 'react';
import { render, screen } from '../../../../test-utils/testing-library';

import DateField, { DateFieldProps } from '../DateField';

describe('elements/common/date/DateField', () => {
const renderComponent = (props: Partial<DateFieldProps> = {}) => {
render(<DateField date="2023-10-10T10:00:00Z" {...props} />);
};
test('renders formatted date', () => {
renderComponent();
expect(screen.getByText('Tue, Oct 10, 2023')).toBeInTheDocument();
});

test("renders today message for today's date", () => {
renderComponent({ date: new Date().toISOString(), relative: true });
expect(screen.getByText('today')).toBeInTheDocument();
});

test("renders yesterday message for yesterday's date", () => {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
renderComponent({ date: yesterday.toISOString(), relative: true });
expect(screen.getByText('yesterday')).toBeInTheDocument();
});

test('renders formatted date without commas', () => {
renderComponent({ omitCommas: true });
expect(screen.getByText('Tue Oct 10 2023')).toBeInTheDocument();
});

test('renders capitalized today message', () => {
renderComponent({ date: new Date().toISOString(), relative: true, capitalize: true });
expect(screen.getByText('today')).toHaveClass('be-date-capitalize');
});

test('renders capitalized yesterday message', () => {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
renderComponent({ date: yesterday.toISOString(), relative: true, capitalize: true });
expect(screen.getByText('yesterday')).toHaveClass('be-date-capitalize');
});

test('renders formatted date with custom format', () => {
renderComponent({ dateFormat: { year: '2-digit', month: '2-digit', day: '2-digit' } });
expect(screen.getByText('10/10/23')).toBeInTheDocument();
});
});
1 change: 1 addition & 0 deletions src/elements/common/date/index.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {default} from './DateField';
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
// @flow
export { default } from './DateField';
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ describe('utils/datetime', () => {
['2019-01-01T09:41:56-07:00', true],
['some random string', false],
['', false],
])('should interpret %s as a %p date', (dateString, expected) => {
])('should interpret %s as a %p date', (dateString: string, expected: boolean) => {
const date = new Date(dateString);
expect(isValidDate(date)).toBe(expected);
});
Expand All @@ -151,7 +151,7 @@ describe('utils/datetime', () => {
const TEN_MIN_IN_MS = 600000;
const date = new Date('1995-12-17T03:24:00');
const result = addTime(date, TEN_MIN_IN_MS);
expect(result.getMinutes()).toBe(34);
expect((result as Date).getMinutes()).toBe(34);
});

test('should correctly add time if the date Value is a number', () => {
Expand All @@ -168,7 +168,7 @@ describe('utils/datetime', () => {
['2018-06-13T01:00:00.000+01:00', '2018-06-13T07:00:00.000Z'],
['2018-06-12T23:00:00.000-0100', '2018-06-13T07:00:00.000Z'],
['2018-06-13T02:00:00.000+02', '2018-06-13T07:00:00.000Z'],
])('should correctly convert from %s to %s', (originDateTime, expectedDateTime) => {
])('should correctly convert from %s to %s', (originDateTime: string, expectedDateTime: string) => {
const result = convertISOStringToUTCDate(originDateTime);
expect(result.toISOString()).toBe(expectedDateTime);
});
Expand Down Expand Up @@ -202,7 +202,7 @@ describe('utils/datetime', () => {
// Null-conversion examples
['2018-06-13T00:00:00.000-05:45', '2018-06-13T00:00:00.000-05:45'],
['2018-06-13T00:00:00.000+34', '2018-06-13T00:00:00.000+34'],
])('should convert %s to %s correctly', (from, to) => {
])('should convert %s to %s correctly', (from: string, to: string) => {
const input = convertISOStringtoRFC3339String(from);
expect(input).toEqual(to);
});
Expand Down
5 changes: 0 additions & 5 deletions src/utils/datetime.js → src/utils/datetime.js.flow
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* @flow
* @file Date and time utilities
* @author Box
*/
import isNaN from 'lodash/isNaN';

const MILLISECONDS_PER_SECOND = 1000;
Expand Down
Loading

0 comments on commit d400d6c

Please sign in to comment.