@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
176 lines (173 loc) • 6.42 kB
JavaScript
import dayjs from 'dayjs';
import customParse from '../../../../_virtual/customParseFormat.js';
import isBetween from '../../../../_virtual/isBetween.js';
import StartEndDatetUtils from '../start-end-date/utils.js';
import RelativeDateRange from './types.js';
import { calcDatesForUI, calcDatesForAPI } from '../../../utils/durationCalculator.js';
/* eslint-disable no-param-reassign */
dayjs.extend(customParse);
dayjs.extend(isBetween);
const dateIsInBounds = (startDate, endDate, min, max) => {
const minDate = dayjs(min, 'YYYY-MM-DD').startOf('day');
const maxDate = dayjs(max, 'YYYY-MM-DD').endOf('day');
const isStartValid = !startDate || dayjs(startDate, 'DD/MM/YYYY').isBetween(minDate, maxDate, 'day', '[]');
const isEndValid = !endDate || dayjs(endDate, 'DD/MM/YYYY').isBetween(minDate, maxDate, 'day', '[]');
return isStartValid && isEndValid;
};
const setValueFromRequest = (filter, req, prefix) => {
const { relativeOptions } = filter;
const start = req.query[`${prefix}${filter.name}.start`];
const end = req.query[`${prefix}${filter.name}.end`];
const relative = req.query[`${prefix}${filter.name}.relative-duration`];
let relativeDisabled = false;
if (relative && relativeOptions) {
const option = relativeOptions.find(opt => opt.value === relative);
relativeDisabled = option && option.disabled ? option.disabled : false;
}
const value = {
start,
end,
...(relative && !relativeDisabled && { relative }),
};
return value;
};
const setDefaultValue = (req, name) => {
const dateRangeName = name.split('.')[0];
const dateRangeDefaults = Object.keys(req.body)
.filter(key => key.includes(dateRangeName))
.map(key => {
return { name: key.split('.')[2], value: req.body[key] };
});
const dateRangeValue = { start: '', end: '' };
dateRangeDefaults.forEach(dateRangeDefault => {
if (dateRangeDefault.name.includes('start')) {
dateRangeValue.start = dateRangeDefault.value;
}
if (dateRangeDefault.name.includes('end')) {
dateRangeValue.end = dateRangeDefault.value;
}
if (dateRangeDefault.name.includes('relative-duration')) {
dateRangeValue.relative = dateRangeDefault.value;
}
});
return { value: dateRangeValue, name: dateRangeName };
};
const setFilterValueFromDefault = (defaultValue, filter) => {
const value = { start: '', end: '', relative: '' };
const { start, end, relative } = defaultValue.value;
if (relative) {
value.relative = relative;
}
if (start) {
value.start = dayjs(start, 'D/M/YYYY').format('YYYY-MM-DD').toString();
}
if (end) {
value.end = dayjs(end, 'D/M/YYYY').format('YYYY-MM-DD').toString();
}
return {
...filter,
value,
};
};
const getRelativeDateOptions = (min, max) => {
if (!min)
min = '1977-05-25';
if (!max)
max = '9999-01-01';
let options = getRelativeValues();
options.forEach((option) => {
if (option.value !== RelativeDateRange.NONE) {
const dates = calcDatesForUI(option.value);
if (dates && !dateIsInBounds(dates.start, dates.end, min, max)) {
option.disabled = true;
}
}
});
if (options
.filter((opt) => opt.value !== 'none')
.every((opt) => {
return opt.value === null || opt.disabled;
})) {
options = [];
}
return options;
};
const mapRelativeValue = (value) => {
const values = getRelativeValues();
const opt = values.find(v => v.value === value);
return opt ? opt.text : '';
};
const getRelativeValues = () => {
return [
{ value: RelativeDateRange.NONE, text: 'None' },
{ value: RelativeDateRange.YESTERDAY, text: 'Yesterday' },
{ value: RelativeDateRange.TOMORROW, text: 'Tomorrow' },
{ value: RelativeDateRange.LAST_WEEK, text: 'Last week' },
{ value: RelativeDateRange.NEXT_WEEK, text: 'Next week' },
{ value: RelativeDateRange.LAST_MONTH, text: 'Last month' },
{ value: RelativeDateRange.NEXT_MONTH, text: 'Next month' },
];
};
const getFilterFromDefinition = (filter, filterData) => {
const value = StartEndDatetUtils.getStartAndEndValueFromDefinition(filter);
const relativeOptions = getRelativeDateOptions(filter.min || undefined, filter.max || undefined);
return {
...filterData,
min: filter.min,
max: filter.max,
relativeOptions,
value,
};
};
/**
* Creates and appends the daterange query string
* to an existing URLSearchParams
*
* @param {URLSearchParams} params
* @param {string} fieldName
* @param {string} defaultValue
*/
const appendDateRangeValue = (params, fieldName, value) => {
if (value.start) {
params.append(`filters.${fieldName}.start`, value.start);
}
if (value.end) {
params.append(`filters.${fieldName}.end`, value.end);
}
if (value.relative) {
params.append(`filters.${fieldName}.relative-duration`, value.relative);
}
};
const resolveDateRangeDefaults = (filter) => {
// Case 1: quick filter wins
if (filter.defaultQuickFilterValue) {
const dates = calcDatesForAPI(filter.defaultQuickFilterValue);
return {
relative: filter.defaultQuickFilterValue,
...(dates?.start !== undefined ? { start: dates.start } : {}),
...(dates?.end !== undefined ? { end: dates.end } : {}),
};
}
if (filter.defaultValue) {
const [start, end] = filter.defaultValue
.split(' - ')
.map(v => v.trim())
.filter(Boolean);
return {
...(start !== undefined ? { start } : {}),
...(end !== undefined ? { end } : {}),
};
}
return undefined;
};
var DateRangeInputUtils = {
getRelativeDateOptions,
getFilterFromDefinition,
setValueFromRequest,
mapRelativeValue,
setDefaultValue,
setFilterValueFromDefault,
appendDateRangeValue,
};
export { appendDateRangeValue, dateIsInBounds, DateRangeInputUtils as default, getFilterFromDefinition, getRelativeDateOptions, getRelativeValues, mapRelativeValue, resolveDateRangeDefaults, setDefaultValue, setFilterValueFromDefault, setValueFromRequest };
//# sourceMappingURL=utils.js.map