UNPKG

@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
/* 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, }