Skip to content

Commit fd7e630

Browse files
committed
chore: replace moment with date-fns
1 parent d044030 commit fd7e630

5 files changed

Lines changed: 59 additions & 59 deletions

File tree

packages/visualizer/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
"@uidotdev/usehooks": "^2.4.1",
2121
"chart.js": "^4.5.0",
2222
"d3": "^7.9.0",
23+
"date-fns": "^4.1.0",
2324
"immer": "^10.1.1",
2425
"lodash": "^4.17.21",
25-
"moment": "^2.30.1",
2626
"motion": "^12.23.0",
2727
"next": "^15.3.4",
2828
"notistack": "^3.0.2",

packages/visualizer/src/components/ReportPickerArea.tsx

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Avatar, Box, Button, CircularProgress, Stack, Typography, alpha, useThe
33
import { motion } from 'motion/react';
44
import { useSnackbar } from 'notistack';
55
import type { PropsWithChildren } from 'react';
6-
import { useRef, useState } from 'react';
6+
import { useCallback, useRef, useState } from 'react';
77
import React, { useMemo } from 'react';
88
import { tss } from 'tss-react/mui';
99

@@ -30,44 +30,47 @@ export default function ReportPickerArea({ children }: ReportPickerAreaProps) {
3030
const [loading, setLoading] = useState(false);
3131
const [reportLoadError, setReportLoadError] = useState<Error | string | null>(null);
3232

33-
const handleFile = (file: File) => {
34-
if (!file || file.type !== 'application/json') {
35-
enqueueSnackbar({
36-
message: 'Please select a valid JSON file.',
37-
variant: 'error',
38-
});
39-
return;
40-
}
33+
const handleFile = useCallback(
34+
(file: File) => {
35+
if (!file || file.type !== 'application/json') {
36+
enqueueSnackbar({
37+
message: 'Please select a valid JSON file.',
38+
variant: 'error',
39+
});
40+
return;
41+
}
4142

42-
const reader = new FileReader();
43+
const reader = new FileReader();
4344

44-
reader.onload = () => {
45-
try {
46-
if (!reader.result) {
47-
throw new Error('File reading error');
48-
}
45+
reader.onload = () => {
46+
try {
47+
if (!reader.result) {
48+
throw new Error('File reading error');
49+
}
4950

50-
const json = JSON.parse(reader.result as string);
51+
const json = JSON.parse(reader.result as string);
5152

52-
setAutoLoadFromServer(false);
53-
setReport(json, file.name);
54-
} catch (error) {
55-
console.error('Error parsing JSON file:', error);
53+
setAutoLoadFromServer(false);
54+
setReport(json, file.name);
55+
} catch (error) {
56+
console.error('Error parsing JSON file:', error);
5657

57-
enqueueSnackbar({
58-
message: 'Failed to parse JSON file. Please ensure it is a valid JSON.',
59-
variant: 'error',
60-
});
58+
enqueueSnackbar({
59+
message: 'Failed to parse JSON file. Please ensure it is a valid JSON.',
60+
variant: 'error',
61+
});
6162

62-
setReportLoadError(error as Error | string);
63-
} finally {
64-
setLoading(false);
65-
}
66-
};
63+
setReportLoadError(error as Error | string);
64+
} finally {
65+
setLoading(false);
66+
}
67+
};
6768

68-
setLoading(true);
69-
reader.readAsText(file);
70-
};
69+
setLoading(true);
70+
reader.readAsText(file);
71+
},
72+
[enqueueSnackbar, setAutoLoadFromServer, setReport],
73+
);
7174

7275
const handleDrop: React.DragEventHandler<HTMLDivElement> = (e) => {
7376
e.preventDefault();
Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,35 @@
11
'use client';
22

33
import { Typography } from '@mui/material';
4-
import moment from 'moment';
4+
import { format, formatDistanceToNow, isSameDay, isWithinInterval } from 'date-fns';
55
import { useEffect, useState } from 'react';
66

77
export type UpdatingHeadingProps = {
88
reportName?: string;
9-
loadedAt?: moment.Moment;
9+
loadedAt?: Date;
1010
};
1111

1212
export function UpdatingHeading({ reportName, loadedAt }: UpdatingHeadingProps) {
13-
const [now, setNow] = useState(() => moment());
13+
const [now, setNow] = useState(() => new Date());
1414

1515
// update time interval
1616
useEffect(() => {
1717
const interval = setInterval(() => {
18-
setNow(moment());
18+
setNow(new Date());
1919
}, 1000);
2020

2121
return () => clearInterval(interval);
2222
}, []);
2323

2424
return (
25-
reportName && (
26-
<Typography variant="caption">
27-
{reportName},{' '}
28-
{loadedAt &&
29-
(loadedAt.isSame(now, 'minute')
30-
? loadedAt.fromNow()
31-
: loadedAt.isSame(now, 'day')
32-
? 'at ' + loadedAt.format('HH:mm')
33-
: 'on ' + loadedAt.format('DD.MM HH:mm'))}
34-
</Typography>
35-
)
25+
<Typography variant="caption">
26+
{reportName ? `${reportName}, ` : ''}loaded{' '}
27+
{loadedAt &&
28+
(isWithinInterval(loadedAt, { start: new Date(now.getTime() - 1000 * 60 * 2), end: now })
29+
? formatDistanceToNow(loadedAt, { addSuffix: true, includeSeconds: true })
30+
: isSameDay(loadedAt, now)
31+
? 'at ' + format(loadedAt, 'HH:mm')
32+
: 'on ' + format(loadedAt, 'dd.MM HH:mm'))}
33+
</Typography>
3634
);
3735
}

packages/visualizer/src/store/visualizerStore.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { Types } from '@callstack/licenses';
2-
import moment from 'moment';
32
import { create } from 'zustand';
43
import { immer } from 'zustand/middleware/immer';
54

@@ -8,7 +7,7 @@ import { DependencyType } from '@/types/DependencyType';
87
type VisualizerStoreState = {
98
report: Types.AggregatedLicensesMapping | null;
109
reportName?: string;
11-
loadedAt?: moment.Moment;
10+
loadedAt?: Date;
1211
visibleDependencyTypes: DependencyType[];
1312
autoLoadFromServer: boolean;
1413
selectedRoot: Types.License | null;
@@ -32,7 +31,7 @@ export const useVisualizerStore = create<VisualizerStore>()(
3231
set((state) => {
3332
state.report = report;
3433
state.reportName = reportName;
35-
state.loadedAt = moment();
34+
state.loadedAt = new Date();
3635
}),
3736

3837
reportName: undefined,

yarn.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4210,14 +4210,14 @@ __metadata:
42104210
"@uidotdev/usehooks": ^2.4.1
42114211
chart.js: ^4.5.0
42124212
d3: ^7.9.0
4213+
date-fns: ^4.1.0
42134214
eslint: ^8.46.0
42144215
eslint-config-prettier: ^10.1.8
42154216
eslint-import-resolver-typescript: ^4.4.4
42164217
eslint-plugin-prettier: ^5.5.4
42174218
eslint-plugin-react-hooks: ^5.2.0
42184219
immer: ^10.1.1
42194220
lodash: ^4.17.21
4220-
moment: ^2.30.1
42214221
motion: ^12.23.0
42224222
next: ^15.3.4
42234223
notistack: ^3.0.2
@@ -11829,6 +11829,13 @@ __metadata:
1182911829
languageName: node
1183011830
linkType: hard
1183111831

11832+
"date-fns@npm:^4.1.0":
11833+
version: 4.1.0
11834+
resolution: "date-fns@npm:4.1.0"
11835+
checksum: fb681b242cccabed45494468f64282a7d375ea970e0adbcc5dcc92dcb7aba49b2081c2c9739d41bf71ce89ed68dd73bebfe06ca35129490704775d091895710b
11836+
languageName: node
11837+
linkType: hard
11838+
1183211839
"dayjs@npm:^1.8.15":
1183311840
version: 1.11.13
1183411841
resolution: "dayjs@npm:1.11.13"
@@ -19539,13 +19546,6 @@ __metadata:
1953919546
languageName: node
1954019547
linkType: hard
1954119548

19542-
"moment@npm:^2.30.1":
19543-
version: 2.30.1
19544-
resolution: "moment@npm:2.30.1"
19545-
checksum: 859236bab1e88c3e5802afcf797fc801acdbd0ee509d34ea3df6eea21eb6bcc2abd4ae4e4e64aa7c986aa6cba563c6e62806218e6412a765010712e5fa121ba6
19546-
languageName: node
19547-
linkType: hard
19548-
1954919549
"motion-dom@npm:^12.22.0":
1955019550
version: 12.22.0
1955119551
resolution: "motion-dom@npm:12.22.0"

0 commit comments

Comments
 (0)