@prefecthq/prefect-ui-library
Version:
This library is the Vue and Typescript component library for [Prefect 2](https://github.com/PrefectHQ/prefect) and [Prefect Cloud 2](https://www.prefect.io/cloud/). _The components and utilities in this project are not meant to be used independently_.
127 lines (104 loc) • 3.56 kB
text/typescript
import { toPluralString } from '@prefecthq/prefect-design'
import { fromZonedTime } from 'date-fns-tz'
import { ISchedule } from '@/models'
import { IntervalScheduleResponse } from '@/models/api/ScheduleResponse'
import { secondsInMinute, minutesInHour, dateFormat, timeNumericFormat } from '@/utilities/dates'
import { floor } from '@/utilities/math'
import { formatDateInTimezone } from '@/utilities/timezone'
export type Intervals = {
seconds: number,
minutes: number,
hours: number,
days: number,
}
export interface IIntervalSchedule extends ISchedule {
interval: number,
timezone: string | null,
anchorDate: Date | null,
getIntervals?: () => Intervals,
}
export class IntervalSchedule implements IIntervalSchedule {
public timezone: string | null
public interval: number
public anchorDate: Date | null
public constructor(schedule: Pick<IIntervalSchedule, 'interval' | 'timezone' | 'anchorDate'>) {
this.timezone = schedule.timezone
this.interval = schedule.interval
this.anchorDate = schedule.anchorDate
}
public get raw(): number {
return this.interval
}
public getIntervals(): Intervals {
let remainder = this.interval
const intervals = {
seconds: 0,
minutes: 0,
hours: 0,
days: 0,
}
intervals.seconds = remainder % secondsInMinute
remainder = floor(remainder / secondsInMinute)
intervals.minutes = remainder % minutesInHour
remainder = floor(remainder / minutesInHour)
intervals.hours = remainder % 24
remainder = floor(remainder / 24)
intervals.days = remainder
return intervals
}
public toString({ verbose = false, neat = true }: { neat?: boolean, verbose?: boolean } = {}): string {
const { seconds, minutes, hours, days } = this.getIntervals()
const strings: string[] = []
if (seconds) {
if (neat && seconds === 1 && !minutes && !hours && !days) {
strings.push('second')
} else {
strings.push(`${seconds} ${toPluralString('second', seconds)}`)
}
}
if (minutes) {
if (neat && minutes === 1 && !seconds && !hours && !days) {
strings.push('minute')
} else {
strings.push(`${minutes} ${toPluralString('minute', minutes)}`)
}
}
if (hours) {
if (neat && hours === 1 && !seconds && !minutes && !days) {
strings.push('Hourly')
} else {
strings.push(`${hours} ${toPluralString('hour', hours)}`)
}
}
if (days) {
if (neat && days === 1 && !seconds && !minutes && !hours) {
strings.push('Daily')
} else {
strings.push(`${days} ${toPluralString('day', days)}`)
}
}
let str = strings.reverse().join(', ')
if (!str.includes('Every') && !str.includes('Daily') && !str.includes('Hourly')) {
str = `Every ${str}`
}
if (this.anchorDate && verbose) {
const date = formatDateInTimezone(this.anchorDate, dateFormat, this.timezone ?? 'UTC')
const time = formatDateInTimezone(this.anchorDate, timeNumericFormat, this.timezone ?? 'UTC')
str += ` using ${date} at ${time} (${this.timezone ?? 'UTC'}) as the anchor date`
}
if (str == '') {
str = 'None'
}
return str
}
public toResponse(): IntervalScheduleResponse {
const date = this.anchorDate ?? new Date()
const timezone = this.timezone ?? 'UTC'
const utcDate = fromZonedTime(date, timezone).toISOString()
return {
'interval': this.interval,
'anchor_date': utcDate,
'timezone': timezone,
}
}
}