@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
166 lines (146 loc) • 4.45 kB
text/typescript
/* eslint-disable no-param-reassign */
import dayjs from 'dayjs'
import { Request } from 'express'
import isBetween from 'dayjs/plugin/isBetween'
import { components } from '../../../types/api'
import { DateFilterValue, DateRange, FilterValue } from '../../_filters/types'
import StartEndDateUtils from '../start-end-date/utils'
import RelativeDateRange, { RelativeOption } from './types'
const dateIsInBounds = (startDate: dayjs.Dayjs | string, endDate: dayjs.Dayjs | string, min: string, max: string) => {
dayjs.extend(isBetween)
const minDate = dayjs(min)
const maxDate = dayjs(max)
const startDateIsBetweenMinAndMax = startDate
? (<dayjs.Dayjs>startDate).isBetween(minDate, maxDate, 'day', '[]')
: true
const endDateIsBetweenMinAndMax = endDate ? (<dayjs.Dayjs>endDate).isBetween(minDate, maxDate, 'day', '[]') : true
return startDateIsBetweenMinAndMax && endDateIsBetweenMinAndMax
}
const calcDates = (durationValue: string) => {
let endDate
let startDate
switch (durationValue) {
case 'none':
endDate = ''
startDate = ''
break
case 'yesterday':
endDate = dayjs()
startDate = endDate.subtract(1, 'day')
break
case 'tomorrow':
startDate = dayjs()
endDate = startDate.add(1, 'day')
break
case 'last-week':
endDate = dayjs()
startDate = endDate.subtract(1, 'week')
break
case 'next-week':
startDate = dayjs()
endDate = startDate.add(1, 'week')
break
case 'last-month':
endDate = dayjs()
startDate = endDate.subtract(1, 'month')
break
case 'next-month':
startDate = dayjs()
endDate = startDate.add(1, 'month')
break
default:
break
}
return {
endDate,
startDate,
}
}
const setValueFromRequest = (filter: FilterValue, req: Request, prefix: string) => {
const start = <string>req.query[`${prefix}${filter.name}.start`]
const end = <string>req.query[`${prefix}${filter.name}.end`]
const relative = <string>req.query[`${prefix}${filter.name}.relative-duration`]
const value = {
start: start || (<DateFilterValue>filter).min,
end: end || (<DateFilterValue>filter).max,
...(relative && { relative }),
} as DateRange
return value
}
const getRelativeDateOptions = (min: string, max: string) => {
if (!min) min = '1977-05-25'
if (!max) max = '9999-01-01'
let options: RelativeOption[] = getRelativeValues()
options.forEach((option: RelativeOption) => {
if (option.value) {
const { endDate, startDate } = calcDates(option.value)
if (!dateIsInBounds(startDate, endDate, min, max)) {
option.disabled = true
}
}
})
if (
options
.filter((opt: RelativeOption) => opt.value !== 'none')
.every((opt: RelativeOption) => {
return opt.value === null || opt.disabled
})
) {
options = []
}
return options
}
const mapRelativeValue = (value: RelativeDateRange) => {
const values = getRelativeValues()
const opt = values.find((v) => v.value === value)
return opt ? opt.text : ''
}
const getRelativeValues = (): {
value: string
text: string
disabled?: boolean
}[] => {
return [
{ value: 'none', text: 'None' },
{ value: 'yesterday', text: 'Yesterday' },
{ value: 'tomorrow', text: 'Tomorrow' },
{ value: 'last-week', text: 'Last week' },
{ value: 'next-week', text: 'Next week' },
{ value: 'last-month', text: 'Last month' },
{ value: 'next-month', text: 'Next month' },
]
}
const getFilterFromDefinition = (filter: components['schemas']['FilterDefinition'], filterData: FilterValue) => {
const value = StartEndDateUtils.getStartAndEndValueFromDefinition(filter)
const relativeOptions = getRelativeDateOptions(filter.min, filter.max)
return {
...filterData,
min: filter.min,
max: filter.max,
relativeOptions,
value,
}
}
const getQueryFromDefinition = (
filter: components['schemas']['FilterDefinition'],
name: string,
filterPrefix: string,
) => {
const dates = filter.defaultValue.split(' - ')
let param
if (dates.length >= 1) {
param = `${filterPrefix}${name}.start=${dates[0]}`
if (dates.length >= 2) {
param = `${param}&${filterPrefix}${name}.end=${dates[1]}`
}
}
return param
}
export default {
calcDates,
getRelativeDateOptions,
getFilterFromDefinition,
setValueFromRequest,
getQueryFromDefinition,
mapRelativeValue,
}