Created now function and refactored intervalToDateRange

This commit is contained in:
Alejandro Celaya 2022-12-05 17:18:00 +01:00
parent 7d83e434e6
commit 1654784471
10 changed files with 38 additions and 50 deletions

View file

@ -9,6 +9,7 @@ import {
intervalToDateRange, intervalToDateRange,
rangeIsInterval, rangeIsInterval,
dateRangeIsEmpty, dateRangeIsEmpty,
ALL,
} from '../helpers/dateIntervals'; } from '../helpers/dateIntervals';
import { DateRangeRow } from './DateRangeRow'; import { DateRangeRow } from './DateRangeRow';
import { DateIntervalDropdownItems } from './DateIntervalDropdownItems'; import { DateIntervalDropdownItems } from './DateIntervalDropdownItems';
@ -31,7 +32,7 @@ export const DateRangeSelector = (
const [activeDateRange, setActiveDateRange] = useState(initialIntervalIsRange ? undefined : initialDateRange); const [activeDateRange, setActiveDateRange] = useState(initialIntervalIsRange ? undefined : initialDateRange);
const updateDateRange = (dateRange: DateRange) => { const updateDateRange = (dateRange: DateRange) => {
setActiveInterval(dateRangeIsEmpty(dateRange) ? 'all' : undefined); setActiveInterval(dateRangeIsEmpty(dateRange) ? ALL : undefined);
setActiveDateRange(dateRange); setActiveDateRange(dateRange);
onDatesChange(dateRange); onDatesChange(dateRange);
}; };

View file

@ -1,5 +1,5 @@
import { parseISO, format as formatDate, getUnixTime, formatDistance } from 'date-fns'; import { parseISO, format as formatDate, getUnixTime, formatDistance } from 'date-fns';
import { isDateObject, STANDARD_DATE_AND_TIME_FORMAT } from '../helpers/date'; import { isDateObject, now, STANDARD_DATE_AND_TIME_FORMAT } from '../helpers/date';
export interface TimeProps { export interface TimeProps {
date: Date | string; date: Date | string;
@ -12,7 +12,7 @@ export const Time = ({ date, format = STANDARD_DATE_AND_TIME_FORMAT, relative =
return ( return (
<time dateTime={`${getUnixTime(dateObject)}000`}> <time dateTime={`${getUnixTime(dateObject)}000`}>
{relative ? `${formatDistance(new Date(), dateObject)} ago` : formatDate(dateObject, format)} {relative ? `${formatDistance(now(), dateObject)} ago` : formatDate(dateObject, format)}
</time> </time>
); );
}; };

View file

@ -9,6 +9,8 @@ export type DateOrString = Date | string;
type NullableDate = DateOrString | null; type NullableDate = DateOrString | null;
export const now = () => new Date();
export const isDateObject = (date: DateOrString): date is Date => typeof date !== 'string'; export const isDateObject = (date: DateOrString): date is Date => typeof date !== 'string';
const formatDateFromFormat = (date?: NullableDate, theFormat?: string): OptionalString => { const formatDateFromFormat = (date?: NullableDate, theFormat?: string): OptionalString => {
@ -28,7 +30,7 @@ export const formatIsoDate = (date?: NullableDate) => formatDateFromFormat(date,
export const formatInternational = formatDate(); export const formatInternational = formatDate();
export const parseDate = (date: string, theFormat: string) => parse(date, theFormat, new Date()); export const parseDate = (date: string, theFormat: string) => parse(date, theFormat, now());
export const parseISO = (date: DateOrString): Date => (isDateObject(date) ? date : stdParseISO(date)); export const parseISO = (date: DateOrString): Date => (isDateObject(date) ? date : stdParseISO(date));

View file

@ -1,13 +1,13 @@
import { subDays, startOfDay, endOfDay } from 'date-fns'; import { subDays, startOfDay, endOfDay } from 'date-fns';
import { cond, filter, isEmpty, T } from 'ramda'; import { cond, filter, isEmpty, T } from 'ramda';
import { dateOrNull, DateOrString, formatInternational, isBeforeOrEqual, parseISO } from './date'; import { dateOrNull, DateOrString, formatInternational, isBeforeOrEqual, now, parseISO } from './date';
export interface DateRange { export interface DateRange {
startDate?: Date | null; startDate?: Date | null;
endDate?: Date | null; endDate?: Date | null;
} }
const ALL = 'all'; export const ALL = 'all';
const INTERVAL_TO_STRING_MAP = { const INTERVAL_TO_STRING_MAP = {
today: 'Today', today: 'Today',
yesterday: 'Yesterday', yesterday: 'Yesterday',
@ -64,39 +64,25 @@ export const rangeOrIntervalToString = (range?: DateRange | DateInterval): strin
return INTERVAL_TO_STRING_MAP[range]; return INTERVAL_TO_STRING_MAP[range];
}; };
const startOfDaysAgo = (daysAgo: number) => startOfDay(subDays(new Date(), daysAgo)); const startOfDaysAgo = (daysAgo: number) => startOfDay(subDays(now(), daysAgo));
const endingToday = (startDate: Date): DateRange => ({ startDate, endDate: endOfDay(new Date()) }); const endingToday = (startDate: Date): DateRange => ({ startDate, endDate: endOfDay(now()) });
export const intervalToDateRange = (dateInterval?: DateInterval): DateRange => { export const intervalToDateRange = cond<[DateInterval | undefined], DateRange>([
if (!dateInterval || dateInterval === ALL) { [(dateInterval) => dateInterval === 'today', () => endingToday(startOfDay(now()))],
return {}; [(dateInterval) => dateInterval === 'yesterday', () => ({ startDate: startOfDaysAgo(1), endDate: endOfDay(subDays(now(), 1)) })],
} [(dateInterval) => dateInterval === 'last7Days', () => endingToday(startOfDaysAgo(7))],
[(dateInterval) => dateInterval === 'last30Days', () => endingToday(startOfDaysAgo(30))],
switch (dateInterval) { [(dateInterval) => dateInterval === 'last90Days', () => endingToday(startOfDaysAgo(90))],
case 'today': [(dateInterval) => dateInterval === 'last180Days', () => endingToday(startOfDaysAgo(180))],
return endingToday(startOfDay(new Date())); [(dateInterval) => dateInterval === 'last365Days', () => endingToday(startOfDaysAgo(365))],
case 'yesterday': [T, () => ({})],
return { startDate: startOfDaysAgo(1), endDate: endOfDay(subDays(new Date(), 1)) }; ]);
case 'last7Days':
return endingToday(startOfDaysAgo(7));
case 'last30Days':
return endingToday(startOfDaysAgo(30));
case 'last90Days':
return endingToday(startOfDaysAgo(90));
case 'last180Days':
return endingToday(startOfDaysAgo(180));
case 'last365Days':
return endingToday(startOfDaysAgo(365));
}
return {};
};
export const dateToMatchingInterval = (date: DateOrString): DateInterval => { export const dateToMatchingInterval = (date: DateOrString): DateInterval => {
const theDate: Date = parseISO(date); const theDate = parseISO(date);
return cond<never, DateInterval>([ return cond<never, DateInterval>([
[() => isBeforeOrEqual(startOfDay(new Date()), theDate), () => 'today'], [() => isBeforeOrEqual(startOfDay(now()), theDate), () => 'today'],
[() => isBeforeOrEqual(startOfDaysAgo(1), theDate), () => 'yesterday'], [() => isBeforeOrEqual(startOfDaysAgo(1), theDate), () => 'yesterday'],
[() => isBeforeOrEqual(startOfDaysAgo(7), theDate), () => 'last7Days'], [() => isBeforeOrEqual(startOfDaysAgo(7), theDate), () => 'last7Days'],
[() => isBeforeOrEqual(startOfDaysAgo(30), theDate), () => 'last30Days'], [() => isBeforeOrEqual(startOfDaysAgo(30), theDate), () => 'last30Days'],

View file

@ -8,11 +8,10 @@ import {
rangeOrIntervalToString, rangeOrIntervalToString,
toDateRange, toDateRange,
} from '../../../src/utils/helpers/dateIntervals'; } from '../../../src/utils/helpers/dateIntervals';
import { parseDate } from '../../../src/utils/helpers/date'; import { parseDate, now } from '../../../src/utils/helpers/date';
describe('date-types', () => { describe('date-types', () => {
const now = () => new Date(); const daysBack = (days: number) => subDays(now(), days);
const daysBack = (days: number) => subDays(new Date(), days);
describe('dateRangeIsEmpty', () => { describe('dateRangeIsEmpty', () => {
it.each([ it.each([
@ -26,9 +25,9 @@ describe('date-types', () => {
[{ startDate: undefined, endDate: undefined }, true], [{ startDate: undefined, endDate: undefined }, true],
[{ startDate: undefined, endDate: null }, true], [{ startDate: undefined, endDate: null }, true],
[{ startDate: null, endDate: undefined }, true], [{ startDate: null, endDate: undefined }, true],
[{ startDate: new Date() }, false], [{ startDate: now() }, false],
[{ endDate: new Date() }, false], [{ endDate: now() }, false],
[{ startDate: new Date(), endDate: new Date() }, false], [{ startDate: now(), endDate: now() }, false],
])('returns proper result', (dateRange, expectedResult) => { ])('returns proper result', (dateRange, expectedResult) => {
expect(dateRangeIsEmpty(dateRange)).toEqual(expectedResult); expect(dateRangeIsEmpty(dateRange)).toEqual(expectedResult);
}); });

View file

@ -197,12 +197,12 @@ describe('domainVisitsReducer', () => {
it.each([ it.each([
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 20)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 20)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last30Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last30Days' },
3, 3,
], ],
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 100)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 100)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last180Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last180Days' },
3, 3,
], ],

View file

@ -177,12 +177,12 @@ describe('nonOrphanVisitsReducer', () => {
it.each([ it.each([
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 5)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 5)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last7Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last7Days' },
3, 3,
], ],
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 200)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 200)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last365Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last365Days' },
3, 3,
], ],

View file

@ -175,12 +175,12 @@ describe('orphanVisitsReducer', () => {
it.each([ it.each([
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 5)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 5)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last7Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last7Days' },
3, 3,
], ],
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 200)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 200)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last365Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last365Days' },
3, 3,
], ],

View file

@ -219,12 +219,12 @@ describe('shortUrlVisitsReducer', () => {
it.each([ it.each([
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 5)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 5)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last7Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last7Days' },
3, 3,
], ],
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 200)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 200)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last365Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last365Days' },
3, 3,
], ],

View file

@ -193,12 +193,12 @@ describe('tagVisitsReducer', () => {
it.each([ it.each([
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 20)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 20)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last30Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last30Days' },
3, 3,
], ],
[ [
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 100)) })], [Mock.of<Visit>({ date: formatISO(subDays(now, 100)) })],
{ type: fallbackToIntervalAction.toString(), payload: 'last180Days' }, { type: fallbackToIntervalAction.toString(), payload: 'last180Days' },
3, 3,
], ],