UNPKG

@stackoverfloweth/prefect-design

Version:

A collection of low-level Vue components.

97 lines (81 loc) 3.33 kB
import { addSeconds, differenceInSeconds, endOfToday, startOfToday, subSeconds } from 'date-fns' import { secondsInDay, secondsInHour, secondsInMinute } from 'date-fns/constants' import { DateRangeSelectAroundUnit, DateRangeSelectAroundValue, DateRangeSelectPeriodValue, DateRangeSelectRangeValue, DateRangeSelectSpanValue, DateRangeSelectValue } from '@/types/dateRange' function nowWithoutMilliseconds(): Date { const now = new Date() now.setMilliseconds(0) return now } export type DateRangeWithTimeSpan = { startDate: Date, endDate: Date, timeSpanInSeconds: number, } function mapDateRangeSelectRangeValueToDateRange({ startDate, endDate }: DateRangeSelectRangeValue): DateRangeWithTimeSpan { const timeSpanInSeconds = differenceInSeconds(endDate, startDate) return { startDate, endDate, timeSpanInSeconds } } function mapDateRangeSelectSpanValueToDateRange({ seconds }: DateRangeSelectSpanValue): DateRangeWithTimeSpan { const now = nowWithoutMilliseconds() const then = addSeconds(now, seconds) const [startDate, endDate] = [now, then].sort((dateA, dateB) => dateA.getTime() - dateB.getTime()) const timeSpanInSeconds = Math.abs(seconds) return { startDate, endDate, timeSpanInSeconds } } function mapDateRangeSelectAroundValueToDateRange({ date, quantity, unit }: DateRangeSelectAroundValue): DateRangeWithTimeSpan { const multiplier = getMultiplierForUnit(unit) const seconds = Math.abs(quantity * multiplier) const startDate = subSeconds(date, seconds) const endDate = addSeconds(date, seconds) const timeSpanInSeconds = differenceInSeconds(endDate, startDate) return { startDate, endDate, timeSpanInSeconds } } function getMultiplierForUnit(unit: DateRangeSelectAroundUnit): number { switch (unit) { case 'second': return 1 case 'minute': return secondsInMinute case 'hour': return secondsInHour case 'day': return secondsInDay default: const exhaustive: never = unit throw new Error(`Failed get multiplier for unit because unit is not supported: ${exhaustive}`) } } function mapDateRangeSelectPeriodToDateRange({ period }: DateRangeSelectPeriodValue): DateRangeWithTimeSpan { // I want a condition for each value so that the exhaustive check below works correctly // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (period === 'Today') { const startDate = startOfToday() const endDate = endOfToday() const timeSpanInSeconds = differenceInSeconds(endDate, startDate) return { startDate, endDate, timeSpanInSeconds, } } const exhaustive: never = period throw new Error(`No handler for period: ${exhaustive}`) } export function mapDateRangeSelectValueToDateRange(source: DateRangeSelectValue): DateRangeWithTimeSpan | null { if (!source) { return null } switch (source.type) { case 'range': return mapDateRangeSelectRangeValueToDateRange(source) case 'span': return mapDateRangeSelectSpanValueToDateRange(source) case 'around': return mapDateRangeSelectAroundValueToDateRange(source) case 'period': return mapDateRangeSelectPeriodToDateRange(source) default: const exhaustive: never = source throw new Error(`No handler for DateRangeSelectValue.type: ${exhaustive}`) } }