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

momentjs/date-fns to dayjs #2693

Merged
merged 19 commits into from
Jan 13, 2024
Merged
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"@appsignal/plugin-path-decorator": "^1.0.16",
"@appsignal/plugin-window-events": "^1.0.20",
"@appsignal/react": "^1.0.23",
"@date-io/date-fns": "^2.17.0",
"@date-io/dayjs": "^2.17.0",
"@draft-js-plugins/editor": "^4.1.4",
"@draft-js-plugins/mention": "^5.2.2",
"@emoji-mart/data": "^1.1.2",
Expand All @@ -30,7 +30,7 @@
"apollo-link-token-refresh": "^0.6.1",
"axios": "^1.6.4",
"buffer": "^6.0.3",
"date-fns": "2.30.0",
"dayjs": "^1.11.10",
"draft-js": "^0.11.7",
"emoji-mart": "^5.5.2",
"formik": "^2.4.5",
Expand All @@ -40,7 +40,6 @@
"i18next-browser-languagedetector": "^7.2.0",
"interweave": "^13.1.0",
"interweave-autolink": "^5.1.1",
"moment": "^2.30.1",
"pino": "^8.17.2",
"pino-logflare": "^0.4.2",
"react": "^18.2.0",
Expand Down
7 changes: 3 additions & 4 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import moment from 'moment';
import dayjs from 'dayjs';
import * as Yup from 'yup';

export const SIDE_DRAWER_WIDTH = 233;
Expand All @@ -11,7 +11,7 @@ export const FLOW_STATUS_PUBLISHED = 'published';
export const SIMULATOR_NUMBER_START = '9876543210';
export const GUPSHUP_ENTERPRISE_SHORTCODE = 'gupshup_enterprise';
export const VALID_URL_REGEX =
'https?://(www.)?[-a-zA-Z0-9@:%._+~#=]{2,256}.[a-z]{2,4}([-a-zA-Z0-9@:%_+.~#?&\/=]*)';
'https?://(www.)?[-a-zA-Z0-9@:%._+~#=]{2,256}.[a-z]{2,4}([-a-zA-Z0-9@:%_+.~#?&/=]*)';
// to find variables in message
export const pattern = /[^{}]+(?=})/g;

Expand Down Expand Up @@ -112,8 +112,7 @@ export const setVariables = (
},
});

export const is24HourWindowOver = (time: any) =>
moment.duration(moment(new Date()).diff(moment(time))).asHours() > 24;
export const is24HourWindowOver = (time: any) => dayjs().diff(dayjs(time), 'hours') > 24;

// connection retry attempt configuration
export const CONNECTION_RECONNECT_ATTEMPTS = 5;
Expand Down
7 changes: 3 additions & 4 deletions src/components/UI/Form/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useState } from 'react';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { LocalizationProvider, DatePicker } from '@mui/x-date-pickers';
import 'date-fns';
import { getIn } from 'formik';
import styles from './Calendar.module.css';

Expand All @@ -17,7 +16,7 @@ export interface CalendarProps {
}

export const Calendar = ({
format = 'MM/dd/yyyy',
format = 'MM/DD/YYYY',
field,
disabled = false,
form: { setFieldValue, errors, touched },
Expand All @@ -41,7 +40,7 @@ export const Calendar = ({
};

return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<div className={styles.Calendar} data-testid="date-picker-inline">
<DatePicker
label={placeholder}
Expand Down
19 changes: 12 additions & 7 deletions src/components/UI/Form/DateTimePicker/DateTimePicker.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';

import { DateTimePicker } from './DateTimePicker';
import dayjs from 'dayjs';
import { userEvent } from '@testing-library/user-event';

describe('<DateTimePicker />', () => {
const onChangeMock = vi.fn();
Expand All @@ -25,11 +27,14 @@ describe('<DateTimePicker />', () => {
it('test date change event', async () => {
render(wrapper);
const input = screen.getByRole('textbox');
fireEvent.change(input, { target: { value: '14/05/2021 10:50 AM' } });
expect(input).toHaveValue('14/05/2021 10:50 AM');
userEvent.type(input, '14/05/2021 09:50 am');

await waitFor(() => {
expect(input).toHaveValue('14/05/2021 09:50 am');
});

expect(setFieldMock).toBeCalled();
expect(onChangeMock).toBeCalled();
expect(setFieldMock).toHaveBeenCalled();
expect(onChangeMock).toHaveBeenCalled();
});

it('test date with errors', async () => {
Expand All @@ -43,7 +48,7 @@ describe('<DateTimePicker />', () => {

it('test date default value', async () => {
const props = getProps();
props.field.value = new Date();
props.field.value = dayjs();
render(<DateTimePicker {...props} />);
const input = screen.getByRole('textbox');
expect(input).toHaveValue();
Expand All @@ -55,6 +60,6 @@ describe('<DateTimePicker />', () => {
render(<DateTimePicker {...props} />);
const input = screen.getByRole('textbox');
fireEvent.change(input, { target: { value: '14/05/2021 10:50 AM' } });
expect(onChangeMock).toBeCalledTimes(1);
expect(onChangeMock).toHaveBeenCalled();
});
});
13 changes: 8 additions & 5 deletions src/components/UI/Form/DateTimePicker/DateTimePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { LocalizationProvider, DateTimePicker as Picker } from '@mui/x-date-pickers';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import 'date-fns';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { getIn } from 'formik';

import styles from './DateTimePicker.module.css';
dayjs.extend(utc);

export interface DateTimePickerProps {
variant?: any;
Expand All @@ -17,7 +19,7 @@ export interface DateTimePickerProps {
}

export const DateTimePicker = ({
format = 'dd/MM/yyyy hh:mm a',
format = 'DD/MM/YYYY hh:mm a',
field,
form: { setFieldValue, errors, touched },
placeholder,
Expand All @@ -30,17 +32,18 @@ export const DateTimePicker = ({
const dateValue = field.value ? field.value : null;

const handleDateChange = (date: Date | null | string) => {
const value = date && date.toString() !== 'Invalid Date' ? date : null;
const value = date && date.toString() !== 'Invalid Date' ? dayjs(date) : null;
setFieldValue(field.name, value);
if (onChange) onChange(value);
};

return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<div className={styles.DateTimePicker} data-testid="date-picker-inline">
<Picker
className={styles.Text}
label={placeholder}
timezone="system"
format={format}
value={dateValue}
slotProps={{
Expand Down
2 changes: 1 addition & 1 deletion src/components/UI/Form/TimePicker/TimePicker.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('<TimePicker />', () => {
it('test time change event', async () => {
render(wrapper);
const input = screen.getByRole('textbox');
fireEvent.change(input, { target: { value: '09:00 am' } });
fireEvent.change(input, { target: { value: '09:00 AM' } });
expect(cleanText(input.getAttribute('value'))).toBe('09:00 AM');
});

Expand Down
16 changes: 8 additions & 8 deletions src/components/UI/Form/TimePicker/TimePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useState } from 'react';
import 'date-fns';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { LocalizationProvider, TimePicker as Picker } from '@mui/x-date-pickers';
import moment from 'moment';
import dayjs from 'dayjs';
import { getIn } from 'formik';
import utc from 'dayjs/plugin/utc';

import styles from './TimePicker.module.css';
dayjs.extend(utc);

export interface TimePickerProps {
variant?: any;
Expand All @@ -24,29 +25,28 @@ export const TimePicker = ({
disabled = false,
helperText,
}: TimePickerProps) => {
moment.defaultFormat = 'Thh:mm:ss';
const timeValue = field.value ? moment(field.value, moment.defaultFormat).toDate() : null;
const timeValue = field.value ? field.value : null;
const [open, setOpen] = useState(false);

const errorText = getIn(errors, field.name);
const touchedVal = getIn(touched, field.name);
const hasError = touchedVal && errorText !== undefined;

const handleDateChange = (time: Date | null) => {
const value = time ? moment(time).format('THH:mm:ss') : null;
const value = time ? time : null;
setFieldValue(field.name, value);
};

return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<div className={styles.TimePicker} data-testid="time-picker">
<Picker
className={styles.Picker}
label={placeholder}
open={open}
value={timeValue}
onClose={() => setOpen(false)}
disabled={disabled}
value={timeValue}
onChange={handleDateChange}
slotProps={{
textField: {
Expand Down
12 changes: 6 additions & 6 deletions src/components/UI/Timer/Timer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react';
import moment from 'moment';
import { useTranslation } from 'react-i18next';
import dayjs from 'dayjs';

import ContactOptOutIcon from 'assets/images/icons/ContactOptOut.svg?react';
import Tooltip from 'components/UI/Tooltip/Tooltip';
Expand All @@ -13,7 +13,7 @@
}

export const Timer = (props: TimerProps) => {
const [currentTime, setCurrentTime] = useState(moment(new Date()));
const [currentTime, setCurrentTime] = useState(dayjs());
const { t } = useTranslation();

const link = (
Expand Down Expand Up @@ -41,7 +41,7 @@
let intervalID: any;
useEffect(() => {
intervalID = setInterval(() => {
setCurrentTime(moment(new Date()));
setCurrentTime(dayjs());

Check warning on line 44 in src/components/UI/Timer/Timer.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/UI/Timer/Timer.tsx#L44

Added line #L44 was not covered by tests
}, 60000);

return () => clearInterval(intervalID);
Expand All @@ -68,9 +68,9 @@

let hours: string | number = 0;
if (time) {
const lastMessageTime = moment(time);
const duration = moment.duration(currentTime.diff(lastMessageTime));
hours = Math.floor(duration.asHours());
const lastMessageTime = dayjs(time);
const duration = currentTime.diff(lastMessageTime, "hour")
hours = Math.floor(duration);
if (hours < 0) hours = 0;
hours = hours > 24 ? 0 : 24 - hours;
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/simulator/Simulator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import VideocamIcon from '@mui/icons-material/Videocam';
import CameraAltIcon from '@mui/icons-material/CameraAlt';
import ClearIcon from '@mui/icons-material/Clear';
import axios from 'axios';
import moment from 'moment';
import dayjs from 'dayjs';
import { v4 as uuidv4 } from 'uuid';
import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined';

Expand Down Expand Up @@ -104,7 +104,7 @@ const getStyleForDirection = (
const TimeComponent = ({ direction, insertedAt }: any) => (
<>
<span className={direction === 'received' ? styles.TimeSent : styles.TimeReceived}>
{moment(insertedAt).format(TIME_FORMAT)}
{dayjs(insertedAt).format(TIME_FORMAT)}
{direction === 'send' && <DoneAllIcon sx={{ fontSize: 10, ml: '2px' }} />}
</span>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { fireEvent, render } from '@testing-library/react';
import moment from 'moment';
import dayjs from 'dayjs';
import { MockedProvider } from '@apollo/client/testing';
import { MemoryRouter } from 'react-router-dom';

Expand Down Expand Up @@ -64,7 +64,7 @@ test('it should render the message content correctly', () => {

test('it should render the message date correctly', () => {
const { getByTestId } = render(wrapperContainer(defaultProps));
expect(getByTestId('date')).toHaveTextContent(moment(insertedAt).format(DATE_FORMAT));
expect(getByTestId('date')).toHaveTextContent(dayjs(insertedAt).format(DATE_FORMAT));
});

test('it should call the callback function on click action', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ListItemButton } from '@mui/material';
import { Link } from 'react-router-dom';
import moment from 'moment';
import dayjs from 'dayjs';
import { useApolloClient, useMutation } from '@apollo/client';

import { COMPACT_MESSAGE_LENGTH, DATE_FORMAT } from 'common/constants';
Expand Down Expand Up @@ -233,7 +233,7 @@ const ChatConversation = ({
{isTextType && highlightSearch ? BoldedText(body, highlightSearch) : displayMSG}
</div>
<div className={styles.MessageDate} data-testid="date">
{moment(lastMessage.insertedAt).format(DATE_FORMAT)}
{dayjs(lastMessage.insertedAt).format(DATE_FORMAT)}
</div>
</div>
</ListItemButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
import { List, Container, CircularProgress, Typography } from '@mui/material';
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
import { useApolloClient, useLazyQuery, useQuery } from '@apollo/client';
import moment from 'moment';
import dayjs from 'dayjs';
import { useTranslation } from 'react-i18next';

import Loading from 'components/UI/Layout/Loading/Loading';
Expand Down Expand Up @@ -128,8 +128,8 @@ export const ConversationList = ({
filter.includeLabels = params.includeLabels.map((obj: any) => obj.id);
if (params.dateFrom) {
filter.dateRange = {
from: moment(params.dateFrom).format('YYYY-MM-DD'),
to: moment(params.dateTo).format('YYYY-MM-DD'),
from: dayjs(params.dateFrom).format('YYYY-MM-DD'),
to: dayjs(params.dateTo).format('YYYY-MM-DD'),
};
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { render, fireEvent, waitFor, screen } from '@testing-library/react';
import moment from 'moment';
import dayjs from 'dayjs';
import { MockedProvider } from '@apollo/client/testing';

import { TIME_FORMAT } from 'common/constants';
Expand Down Expand Up @@ -84,7 +84,7 @@ describe('<ChatMessage />', () => {

test('it should render the message date correctly', () => {
const { getByTestId } = render(chatMessageText);
expect(getByTestId('date')).toHaveTextContent(moment(insertedAt).format(TIME_FORMAT));
expect(getByTestId('date')).toHaveTextContent(dayjs(insertedAt).format(TIME_FORMAT));
});

test('it should render "Other" class for the content', () => {
Expand Down
12 changes: 6 additions & 6 deletions src/containers/Chat/ChatMessages/ChatMessage/ChatMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useRef, useState } from 'react';
import { Button, Popper, Fade, Paper } from '@mui/material';
import moment from 'moment';
import dayjs from 'dayjs';
import { useTranslation } from 'react-i18next';

import LabelIcon from 'assets/images/icons/Label/Filled.svg?react';
Expand Down Expand Up @@ -110,7 +110,7 @@ export const ChatMessage = ({
let messageDetails = styles.MessageDetails;
const messageError = errors ? parseTextMethod(errors) : {};
let messageErrorStatus: any = false;
let tooltipTitle: any = moment(insertedAt).format(DATE_FORMAT);
let tooltipTitle: any = dayjs(insertedAt).format(DATE_FORMAT);

// Check if the message has an error after sending the message.
if (Object.prototype.hasOwnProperty.call(messageError, 'payload')) {
Expand Down Expand Up @@ -206,9 +206,9 @@ export const ChatMessage = ({
const sendByLabel = !isSender && sendBy;
let messageFooter;
if (sendByLabel) {
messageFooter = `${sendBy} | ${moment(insertedAt).format(TIME_FORMAT)}`;
messageFooter = `${sendBy} | ${dayjs(insertedAt).format(TIME_FORMAT)}`;
} else {
messageFooter = moment(insertedAt).format(TIME_FORMAT);
messageFooter = dayjs(insertedAt).format(TIME_FORMAT);
}

const dateAndSendBy = messageFooter && (
Expand All @@ -222,7 +222,7 @@ export const ChatMessage = ({
if (daySeparator) {
daySeparatorContent = (
<div className={styles.DaySeparator} data-testid="daySeparator">
<p className={styles.DaySeparatorContent}>{moment(insertedAt).format(DATE_FORMAT)}</p>
<p className={styles.DaySeparatorContent}>{dayjs(insertedAt).format(DATE_FORMAT)}</p>
</div>
);
}
Expand Down Expand Up @@ -296,7 +296,7 @@ export const ChatMessage = ({
id={`search${messageNumber}`}
>
{contextMessage ? (
<Tooltip title={moment(contextMessage.insertedAt).format(DATE_FORMAT)} placement="right">
<Tooltip title={dayjs(contextMessage.insertedAt).format(DATE_FORMAT)} placement="right">
<div
className={styles.ReplyMessage}
onClick={() => jumpToMessage(contextMessage.messageNumber)}
Expand Down
Loading