fix(cicd-statistics): date-fns -> luxon
Signed-off-by: Gustaf Räntilä <g.rantila@gmail.com>
This commit is contained in:
@@ -34,8 +34,8 @@ import {
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||
import { formatISO9075, parseISO } from 'date-fns';
|
||||
import { countBy } from 'lodash';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import { Build, FilterStatusType, statusTypes } from '../apis/types';
|
||||
import { labelFormatterWithoutTime, tickFormatterX } from './utils';
|
||||
@@ -56,9 +56,7 @@ export function StatusChart(props: StatusChartProps) {
|
||||
builds.forEach(build => {
|
||||
foundStatuses.add(build.status);
|
||||
|
||||
const dayString = formatISO9075(build.requestedAt, {
|
||||
representation: 'date',
|
||||
});
|
||||
const dayString = DateTime.fromJSDate(build.requestedAt).toISODate();
|
||||
const dayList = buildsByDay.get(dayString);
|
||||
if (dayList) {
|
||||
dayList.push(build);
|
||||
@@ -75,7 +73,7 @@ export function StatusChart(props: StatusChartProps) {
|
||||
),
|
||||
],
|
||||
values: [...buildsByDay.entries()].map(([dayString, buildThisDay]) => ({
|
||||
__epoch: parseISO(dayString).getTime(),
|
||||
__epoch: DateTime.fromISO(dayString).toMillis(),
|
||||
...countBy(buildThisDay, 'status'),
|
||||
})),
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React, { CSSProperties } from 'react';
|
||||
import { formatISO9075, formatDistanceStrict } from 'date-fns';
|
||||
import { DateTime, Duration } from 'luxon';
|
||||
|
||||
const infoText: CSSProperties = { color: 'InfoText' };
|
||||
|
||||
@@ -40,20 +40,25 @@ export function pickElements<T>(arr: ReadonlyArray<T>, num: number): Array<T> {
|
||||
];
|
||||
}
|
||||
|
||||
export function labelFormatter(epoch: number) {
|
||||
return <span style={infoText}>{formatISO9075(new Date(epoch))}</span>;
|
||||
function formatDateShort(milliseconds: number) {
|
||||
return DateTime.fromMillis(milliseconds).toLocaleString(DateTime.DATE_SHORT);
|
||||
}
|
||||
|
||||
export function labelFormatterWithoutTime(epoch: number) {
|
||||
return (
|
||||
<span style={infoText}>
|
||||
{formatISO9075(new Date(epoch), { representation: 'date' })}
|
||||
</span>
|
||||
function formatDateTimeShort(milliseconds: number) {
|
||||
return DateTime.fromMillis(milliseconds).toLocaleString(
|
||||
DateTime.DATETIME_SHORT,
|
||||
);
|
||||
}
|
||||
|
||||
export function labelFormatter(epoch: number) {
|
||||
return <span style={infoText}>{formatDateTimeShort(epoch)}</span>;
|
||||
}
|
||||
|
||||
export function labelFormatterWithoutTime(epoch: number) {
|
||||
return <span style={infoText}>{formatDateShort(epoch)}</span>;
|
||||
}
|
||||
|
||||
export function tickFormatterX(epoch: number) {
|
||||
return formatISO9075(new Date(epoch), { representation: 'date' });
|
||||
return formatDateShort(epoch);
|
||||
}
|
||||
|
||||
export function tickFormatterY(duration: number) {
|
||||
@@ -80,8 +85,32 @@ export function tooltipValueFormatter(duration: number, name: string) {
|
||||
];
|
||||
}
|
||||
|
||||
const baseDate = new Date();
|
||||
const baseEpoch = baseDate.getTime();
|
||||
export function formatDuration(milliseconds: number) {
|
||||
return formatDistanceStrict(baseDate, new Date(baseEpoch + milliseconds));
|
||||
export function formatDuration(millis: number) {
|
||||
let rest = Math.round(millis);
|
||||
const days = Math.floor(rest / (1000 * 60 * 60 * 24));
|
||||
rest -= days * (1000 * 60 * 60 * 24);
|
||||
const hours = Math.floor(rest / (1000 * 60 * 60));
|
||||
rest -= hours * (1000 * 60 * 60);
|
||||
const minutes = Math.floor(rest / (1000 * 60));
|
||||
rest -= minutes * (1000 * 60);
|
||||
const seconds = Math.floor(rest / 1000);
|
||||
rest -= seconds * 1000;
|
||||
const milliseconds = rest;
|
||||
|
||||
if (!days && !hours && !minutes) {
|
||||
if (seconds < 1) {
|
||||
return `${milliseconds}ms`;
|
||||
} else if (seconds < 2) {
|
||||
return `${((milliseconds + seconds * 1000) / 1000).toFixed(1)}s`;
|
||||
}
|
||||
}
|
||||
|
||||
const dur = Duration.fromObject({
|
||||
...(days && { days }),
|
||||
...(hours && { hours }),
|
||||
...(minutes && !days && { minutes }),
|
||||
...(seconds && !days && !hours && { seconds }),
|
||||
});
|
||||
|
||||
return dur.toHuman({ unitDisplay: 'narrow' }).replace(/, /g, '');
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ import {
|
||||
MuiPickersUtilsProvider,
|
||||
KeyboardDatePicker,
|
||||
} from '@material-ui/pickers';
|
||||
import { subMonths, isSameDay } from 'date-fns';
|
||||
import DateFnsUtils from '@date-io/date-fns';
|
||||
import { DateTime } from 'luxon';
|
||||
import LuxonUtils from '@date-io/luxon';
|
||||
|
||||
import {
|
||||
CicdConfiguration,
|
||||
@@ -89,7 +89,9 @@ export function getDefaultChartFilter(
|
||||
): ChartFilter {
|
||||
const toDate = cicdConfiguration.defaults?.timeTo ?? new Date();
|
||||
return {
|
||||
fromDate: cicdConfiguration.defaults?.timeFrom ?? subMonths(toDate, 1),
|
||||
fromDate:
|
||||
cicdConfiguration.defaults?.timeFrom ??
|
||||
DateTime.fromJSDate(toDate).minus({ months: 1 }).toJSDate(),
|
||||
toDate,
|
||||
branch: cicdConfiguration.defaults?.filterType ?? 'branch',
|
||||
status:
|
||||
@@ -104,8 +106,11 @@ function isSameChartFilter(a: ChartFilter, b: ChartFilter): boolean {
|
||||
return (
|
||||
a.branch === b.branch &&
|
||||
[...a.status].sort().join(' ') === [...b.status].sort().join(' ') &&
|
||||
isSameDay(a.fromDate, b.fromDate) &&
|
||||
isSameDay(a.toDate, b.toDate)
|
||||
DateTime.fromJSDate(a.fromDate).hasSame(
|
||||
DateTime.fromJSDate(b.fromDate),
|
||||
'day',
|
||||
) &&
|
||||
DateTime.fromJSDate(a.toDate).hasSame(DateTime.fromJSDate(b.toDate), 'day')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -218,7 +223,7 @@ export function ChartFilters(props: ChartFiltersProps) {
|
||||
|
||||
const toggleUseNowAsDate = useCallback(() => {
|
||||
setUseNowAsToDate(!useNowAsToDate);
|
||||
if (!isSameDay(toDate, new Date())) {
|
||||
if (!DateTime.fromJSDate(toDate).hasSame(DateTime.now(), 'day')) {
|
||||
setToDate(new Date());
|
||||
}
|
||||
}, [useNowAsToDate, toDate]);
|
||||
@@ -248,7 +253,7 @@ export function ChartFilters(props: ChartFiltersProps) {
|
||||
}, [toDate, fromDate, branch, selectedStatus, updateFetchFilter]);
|
||||
|
||||
return (
|
||||
<MuiPickersUtilsProvider utils={DateFnsUtils}>
|
||||
<MuiPickersUtilsProvider utils={LuxonUtils}>
|
||||
<Card className={classes.rootCard}>
|
||||
<CardHeader
|
||||
action={
|
||||
@@ -283,7 +288,7 @@ export function ChartFilters(props: ChartFiltersProps) {
|
||||
format="yyyy-MM-dd"
|
||||
value={fromDate}
|
||||
InputAdornmentProps={{ position: 'start' }}
|
||||
onChange={date => setFromDate(date as any as Date)}
|
||||
onChange={date => setFromDate(date?.toJSDate() ?? new Date())}
|
||||
/>
|
||||
<br />
|
||||
<FormControl component="fieldset">
|
||||
@@ -306,7 +311,7 @@ export function ChartFilters(props: ChartFiltersProps) {
|
||||
format="yyyy-MM-dd"
|
||||
value={toDate}
|
||||
InputAdornmentProps={{ position: 'start' }}
|
||||
onChange={date => setToDate(date as any as Date)}
|
||||
onChange={date => setToDate(date?.toJSDate() ?? new Date())}
|
||||
/>
|
||||
)}
|
||||
</FormGroup>
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
import React, { useCallback, useState, useMemo, useEffect } from 'react';
|
||||
import { Grid, makeStyles, Theme } from '@material-ui/core';
|
||||
import { startOfDay, endOfDay } from 'date-fns';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { useApi, errorApiRef } from '@backstage/core-plugin-api';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import {
|
||||
useCicdStatistics,
|
||||
@@ -58,6 +58,13 @@ const useStyles = makeStyles<Theme>(
|
||||
},
|
||||
);
|
||||
|
||||
function startOfDay(date: Date) {
|
||||
return DateTime.fromJSDate(date).startOf('day').toJSDate();
|
||||
}
|
||||
function endOfDay(date: Date) {
|
||||
return DateTime.fromJSDate(date).endOf('day').toJSDate();
|
||||
}
|
||||
|
||||
interface CicdChartsProps {
|
||||
cicdConfiguration: CicdConfiguration;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user