Skip to content

Commit

Permalink
Merge pull request #28 from mineralsfree/MEN-6855
Browse files Browse the repository at this point in the history
chore: replaced momentjs with dayjs
  • Loading branch information
mineralsfree committed Sep 6, 2024
2 parents 48c061c + 8a7a1eb commit 0a9f54a
Show file tree
Hide file tree
Showing 31 changed files with 415 additions and 414 deletions.
21 changes: 11 additions & 10 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
"@stripe/stripe-js": "4.1.0",
"axios": "1.7.4",
"copy-to-clipboard": "3.3.3",
"dayjs": "^1.11.13",
"generate-password": "1.7.1",
"jwt-decode": "4.0.0",
"md5": "2.3.0",
"moment": "2.30.1",
"moment-duration-format": "2.3.2",
"msgpack5": "6.0.2",
"pluralize": "8.0.0",
"react": "^18.2.0",
Expand Down Expand Up @@ -99,6 +98,7 @@
"less-loader": "12.2.0",
"lint-staged": "15.2.7",
"mini-css-extract-plugin": "2.9.0",
"mockdate": "^3.0.5",
"msw": "2.3.4",
"postcss": "8.4.40",
"postcss-loader": "8.1.1",
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/js/actions/appActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import moment from 'moment';
import dayjs from 'dayjs';
import durationDayJs from 'dayjs/plugin/duration';
import Cookies from 'universal-cookie';

import GeneralApi from '../api/general-api';
Expand Down Expand Up @@ -50,6 +51,7 @@ import { getReleases } from './releaseActions';
import { getGlobalSettings, getRoles, getUserSettings, saveGlobalSettings, saveUserSettings, setShowStartupNotification } from './userActions';

const cookies = new Cookies();
dayjs.extend(durationDayJs);

export const commonErrorFallback = 'Please check your connection.';
export const commonErrorHandler = (err, errorContext, dispatch, fallback, mightBeAuthRelated = false) => {
Expand Down Expand Up @@ -174,7 +176,7 @@ const interpretAppData = () => (dispatch, getState) => {
const { canManageUsers } = getUserCapabilities(getState());
const { interval, intervalUnit } = getOfflineThresholdSettings(getState());
if (canManageUsers && intervalUnit && intervalUnit !== timeUnits.days) {
const duration = moment.duration(interval, intervalUnit);
const duration = dayjs.duration(interval, intervalUnit);
const days = duration.asDays();
if (days < 1) {
tasks.push(Promise.resolve(setTimeout(() => dispatch(setShowStartupNotification(true)), TIMEOUTS.fiveSeconds)));
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/js/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import { CssBaseline, GlobalStyles, ThemeProvider, createTheme, styled } from '@mui/material';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { makeStyles } from 'tss-react/mui';

import Cookies from 'universal-cookie';
Expand Down Expand Up @@ -221,7 +221,7 @@ export const AppProviders = ({ basename = 'ui' }) => (
<React.StrictMode>
<Provider store={store}>
<CacheProvider value={cache}>
<LocalizationProvider dateAdapter={AdapterMoment}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<ErrorBoundary>
<BrowserRouter basename={basename}>
<AppRoot />
Expand Down
8 changes: 2 additions & 6 deletions frontend/src/js/components/auditlogs/auditlogs.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { Button, TextField } from '@mui/material';
import { makeStyles } from 'tss-react/mui';

import moment from 'moment';
import dayjs from 'dayjs';

import historyImage from '../../../assets/img/history.png';
import { getAuditLogs, getAuditLogsCsvLink, setAuditlogsState } from '../../actions/organizationActions';
Expand Down Expand Up @@ -181,11 +181,7 @@ export const AuditLogs = props => {
const createCsvDownload = () => {
setCsvLoading(true);
dispatch(getAuditLogsCsvLink()).then(address => {
createDownload(
encodeURI(address),
`Mender-AuditLog-${moment(startDate).format(moment.HTML5_FMT.DATE)}-${moment(endDate).format(moment.HTML5_FMT.DATE)}.csv`,
token
);
createDownload(encodeURI(address), `Mender-AuditLog-${dayjs(startDate).format('YYYY-MM-DD')}-${dayjs(endDate).format('YYYY-MM-DD')}.csv`, token);
setCsvLoading(false);
});
};
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/js/components/auditlogs/auditlogs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { MemoryRouter } from 'react-router-dom';

import { ThemeProvider, createTheme } from '@mui/material/styles';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';

import { prettyDOM, screen, render as testingLibRender, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
Expand Down Expand Up @@ -56,7 +56,7 @@ const preloadedStateNoAuditlogs = {
describe('Auditlogs Component', () => {
it('renders correctly', async () => {
const { baseElement } = render(
<LocalizationProvider dateAdapter={AdapterMoment}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<AuditLogs />
</LocalizationProvider>,
{ preloadedState: preloadedStateNoAuditlogs }
Expand All @@ -73,7 +73,7 @@ describe('Auditlogs Component', () => {
let store = getConfiguredStore({ preloadedState });
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
render(
<LocalizationProvider dateAdapter={AdapterMoment}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<Provider store={store}>
<AuditLogs />
</Provider>
Expand All @@ -93,7 +93,7 @@ describe('Auditlogs Component', () => {
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
const theme = createTheme(lightTheme);
const ui = (
<LocalizationProvider dateAdapter={AdapterMoment}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<ThemeProvider theme={theme}>
<MemoryRouter initialEntries={['/auditlog?startDate=2018-01-01']}>
<Provider store={store}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ import { useDispatch, useSelector } from 'react-redux';

import { useTheme } from '@mui/material/styles';

import moment from 'moment';
import momentDurationFormatSetup from 'moment-duration-format';
import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';

import { getDeviceById, getSessionDetails } from '../../../actions/deviceActions';
import { getAuditlogDevice, getIdAttribute, getUserCapabilities } from '../../../selectors';
import Loader from '../../common/loader';
import Time from '../../common/time';
import DeviceDetails, { DetailInformation } from './devicedetails';

momentDurationFormatSetup(moment);
dayjs.extend(duration);

export const PortForward = ({ item, onClose }) => {
const theme = useTheme();
Expand Down Expand Up @@ -53,7 +53,7 @@ export const PortForward = ({ item, onClose }) => {
'Session ID': item.meta.session_id[0],
'Start time': <Time value={sessionDetails.start} />,
'End time': <Time value={sessionDetails.end} />,
'Duration': moment.duration(moment(sessionDetails.end).diff(sessionDetails.start)).format('*hh:*mm:ss:SSS'),
'Duration': dayjs.duration(dayjs(sessionDetails.end).diff(sessionDetails.start)).format('HH:mm:ss:SSS'),
User: item.actor.email
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import { useDispatch, useSelector } from 'react-redux';

import { useTheme } from '@mui/material/styles';

import moment from 'moment';
import momentDurationFormatSetup from 'moment-duration-format';
import dayjs from 'dayjs';
import durationDayJs from 'dayjs/plugin/duration';

import { getDeviceById, getSessionDetails } from '../../../actions/deviceActions';
import { getAuditlogDevice, getCurrentSession, getIdAttribute, getUserCapabilities } from '../../../selectors';
Expand All @@ -26,7 +26,7 @@ import Time from '../../common/time';
import DeviceDetails, { DetailInformation } from './devicedetails';
import TerminalPlayer from './terminalplayer';

momentDurationFormatSetup(moment);
dayjs.extend(durationDayJs);

export const TerminalSession = ({ item, onClose }) => {
const theme = useTheme();
Expand Down Expand Up @@ -55,7 +55,7 @@ export const TerminalSession = ({ item, onClose }) => {
'Session ID': item.meta.session_id[0],
'Start time': <Time value={sessionDetails.start} />,
'End time': <Time value={sessionDetails.end} />,
'Duration': moment.duration(moment(sessionDetails.end).diff(sessionDetails.start)).format('*hh:*mm:ss:SSS'),
'Duration': dayjs.duration(dayjs(sessionDetails.end).diff(sessionDetails.start)).format('HH:mm:ss:SSS'),
User: item.actor.email
};

Expand Down
16 changes: 8 additions & 8 deletions frontend/src/js/components/common/forms/timeframe-picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@ import { Controller, useFormContext } from 'react-hook-form';

import { DatePicker } from '@mui/x-date-pickers/DatePicker';

import moment from 'moment';
import dayjs from 'dayjs';

const ensureStartOfDay = date => {
const momentDate = typeof date === 'string' ? moment(date.replace('Z', '')) : moment(date);
const momentDate = typeof date === 'string' ? dayjs(date.replace('Z', '')) : dayjs(date);
return `${momentDate.format().split('T')[0]}T00:00:00.000`;
};

const ensureEndOfDay = date => {
const momentDate = typeof date === 'string' ? moment(date.replace('Z', '')) : moment(date);
const momentDate = typeof date === 'string' ? dayjs(date.replace('Z', '')) : dayjs(date);
return `${momentDate.format().split('T')[0]}T23:59:59.999`;
};

export const TimeframePicker = ({ tonight: propsTonight }) => {
const [tonight] = useState(moment(propsTonight));
const [tonight] = useState(dayjs(propsTonight));
const [maxStartDate, setMaxStartDate] = useState(tonight);
const [minEndDate, setMinEndDate] = useState(tonight);

Expand All @@ -46,15 +46,15 @@ export const TimeframePicker = ({ tonight: propsTonight }) => {
} else if (currentEndDate > now) {
setValue('endDate', now);
}
setMinEndDate(moment(startDate));
setMinEndDate(dayjs(startDate));
}, [startDate, getValues, setValue]);

useEffect(() => {
let currentStartDate = getValues('startDate');
if (endDate < currentStartDate) {
setValue('startDate', ensureStartOfDay(endDate));
}
setMaxStartDate(moment(endDate));
setMaxStartDate(dayjs(endDate));
}, [endDate, getValues, setValue]);

const handleChangeStartDate = date => ensureStartOfDay(date);
Expand All @@ -74,7 +74,7 @@ export const TimeframePicker = ({ tonight: propsTonight }) => {
label="From"
maxDate={maxStartDate}
onChange={e => onChange(handleChangeStartDate(e))}
value={value ? moment(value) : moment()}
value={value ? dayjs(value) : dayjs()}
/>
)}
/>
Expand All @@ -88,7 +88,7 @@ export const TimeframePicker = ({ tonight: propsTonight }) => {
label="To"
minDate={minEndDate}
onChange={e => onChange(handleChangeEndDate(e))}
value={value ? moment(value) : moment()}
value={value ? dayjs(value) : dayjs()}
/>
)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import React from 'react';
import { FormProvider, useForm } from 'react-hook-form';

import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';

import { screen } from '@testing-library/react';

Expand All @@ -35,7 +35,7 @@ const testRender = ui => {
describe('TimeframePicker Component', () => {
it('renders correctly', async () => {
const { baseElement } = formRenderWrapper(
<LocalizationProvider dateAdapter={AdapterMoment}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<TimeframePicker tonight={new Date().toISOString()} />
</LocalizationProvider>
);
Expand All @@ -45,7 +45,7 @@ describe('TimeframePicker Component', () => {
});
it('works in different timezones correctly', async () => {
testRender(
<LocalizationProvider dateAdapter={AdapterMoment}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<TimeframePicker tonight={new Date().toISOString()} />
</LocalizationProvider>
);
Expand Down
18 changes: 10 additions & 8 deletions frontend/src/js/components/common/time.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,21 @@ import React, { useEffect, useState } from 'react';

import { Tooltip } from '@mui/material';

import moment from 'moment';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import pluralize from 'pluralize';

const defaultDateFormat = 'YYYY-MM-DD';
const defaultTimeFormat = `${defaultDateFormat} HH:mm`;

// based on react-time - https://github.com/andreypopp/react-time - which unfortunately is no longer maintained
dayjs.extend(relativeTime);

export const Time = ({ value, relative, format = defaultTimeFormat, valueFormat, titleFormat = defaultTimeFormat, Component = 'time', ...remainingProps }) => {
if (!value) {
value = moment();
value = dayjs();
}
value = moment(value, valueFormat, true);
value = dayjs(value, valueFormat, true);

const machineReadable = value.format('YYYY-MM-DDTHH:mm:ssZ');
const humanReadable = relative ? value.fromNow() : value.format(format);
Expand All @@ -46,11 +48,11 @@ export const RelativeTime = ({ className, shouldCount = 'both', updateTime }) =>
const [updatedTime, setUpdatedTime] = useState();

useEffect(() => {
setUpdatedTime(updatedTime => (updateTime !== updatedTime ? moment(updateTime) : updatedTime));
setUpdatedTime(updatedTime => (updateTime !== updatedTime ? dayjs(updateTime) : updatedTime));
}, [updateTime]);

let timeDisplay = <MaybeTime className={className} value={updatedTime} />;
const diffSeconds = updatedTime ? updatedTime.diff(moment(), 'seconds') : 0;
const diffSeconds = updatedTime ? updatedTime.diff(dayjs(), 'seconds') : 0;
if (
updatedTime &&
diffSeconds > cutoff &&
Expand All @@ -63,7 +65,7 @@ export const RelativeTime = ({ className, shouldCount = 'both', updateTime }) =>
);
}
return (
<Tooltip title={updatedTime ? updatedTime.toLocaleString() : ''} arrow enterDelay={500}>
<Tooltip title={updatedTime ? updatedTime.toDate().toString().slice(0, 33) : ''} arrow enterDelay={500}>
<span>{timeDisplay}</span>
</Tooltip>
);
Expand All @@ -74,10 +76,10 @@ export const ApproximateRelativeDate = ({ className, updateTime }) => {
const [updatedTime, setUpdatedTime] = useState();

useEffect(() => {
setUpdatedTime(updatedTime => (updateTime !== updatedTime ? moment(updateTime, defaultDateFormat) : updatedTime));
setUpdatedTime(updatedTime => (updateTime !== updatedTime ? dayjs(updateTime, defaultDateFormat) : updatedTime));
}, [updateTime]);

const diff = updatedTime ? Math.abs(updatedTime.diff(moment(), 'days')) : 0;
const diff = updatedTime ? Math.abs(updatedTime.diff(dayjs(), 'days')) : 0;
if (updatedTime && diff <= cutoffDays) {
return (
<time className={className} dateTime={updatedTime.format(defaultDateFormat)}>
Expand Down
Loading

0 comments on commit 0a9f54a

Please sign in to comment.