@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
301 lines (297 loc) • 11.7 kB
JavaScript
;
var sessionHelper = require('../utils/sessionHelper.js');
var urlHelper = require('../utils/urlHelper.js');
var queryMappers = require('../utils/queryMappers.js');
var UserReports = require('../types/UserReports.js');
var localsHelper = require('../utils/localsHelper.js');
var definitionUtils = require('../utils/definitionUtils.js');
var filtersTypeEnum = require('../components/_filters/filtersTypeEnum.js');
var personalisationUtils = require('../utils/Personalisation/personalisationUtils.js');
var utils = require('../components/my-reports/my-reports-list-item/my-reports-list-item-actions/utils.js');
const storeActiveReportSessionData = ({ services, loadType = UserReports.LoadType.ASYNC }) => async (req, res, next) => {
if (!req.session) {
return next(new Error('Session not initialized'));
}
if (req.method !== 'GET') {
return next();
}
// --- Initialise Session Namespace -------------------------------------
if (!req.session.activeReport) {
req.session.activeReport = {};
}
const store = req.session.activeReport;
// --- Build Key Variants & Data configurataions -------------------------
const { baseKey, execKey, tableKey } = buildKeyVariants(req);
const { baseData, execData, tableData } = await buildDataConfiguration(req, res, services, loadType);
// --- Write Base Key (always updated) ----------------------------------
store[baseKey] = {
...(store[baseKey] ?? {}),
...baseData,
};
// --- Write Exec Key (async loading) -----------------------------------
if (execKey && execData) {
store[execKey] = {
...(store[execKey] ?? {}),
...execData,
};
}
// --- Write Table Key (final async state) ------------------------------
if (tableKey && tableData) {
store[tableKey] = {
...(store[tableKey] ?? {}),
...tableData,
};
}
return next();
};
/**
* Creates the active report data configuration
*
* @param {Request} req
* @param {Response} res
* @param {Services} services
* @return {*}
*/
const buildDataConfiguration = async (req, res, services, loadType) => {
// Normalise Express params (string | string[])
const asString = (v) => (Array.isArray(v) ? v[0] : v);
const p = req.params;
// -------------- Get static values -------------------
// - values that dont change during the active report journey
const id = asString(p['id']);
const reportId = asString(p['reportId']);
const executionId = asString(p['executionId']);
const tableId = asString(p['tableId']);
const reportType = asString(p['type']);
const { definitionsPath, dprUser } = localsHelper.default.getValues(res);
const { token } = dprUser;
const fields = res.locals['fields'] ??
(await definitionUtils.getDefinitionByType(reportType, services, token, reportId, id, definitionsPath)).fields ??
[];
const definitionDefaults = await setUpDefaultsFromDefinition(fields);
// -------------- Fetch Dynamic Values -------------------
// values that are subject to change during the journey
const reportIsBookmarked = await setUpBookmark(req, res, services.bookmarkService);
const subscriptionData = await setUpSubsrcription(req, res, services.subscriptionStoreService);
const downloadEnabled = await setUpDownloadConfig(req, res, services.downloadPermissionService);
const feedbackSubmissionFormPath = setupDownloadFeedbackPaths(req, res);
const reportUrls = setUpReportUrls(req);
const savedDefaults = await setupSavedDefaults(req, res, services.defaultFilterValuesService, fields);
// -------------- Prepare Data Payloads -------------------
const baseData = {
id,
reportId,
reportIsBookmarked,
downloadEnabled,
loadType,
...definitionDefaults,
...savedDefaults,
...subscriptionData,
};
// Sync: these values never change → store them under baseKey
if (loadType === UserReports.LoadType.SYNC) {
Object.assign(baseData, {
feedbackSubmissionFormPath,
...reportUrls,
});
}
const execData = executionId ? { executionId } : undefined;
const tableData = tableId
? {
tableId,
...(executionId && { executionId }),
...(feedbackSubmissionFormPath && { feedbackSubmissionFormPath }),
...reportUrls,
}
: undefined;
return {
baseData,
execData,
tableData,
};
};
/**
* initialises the active report keys
*
* @param {Request} req
* @return {*}
*/
const buildKeyVariants = (req) => {
const { id, reportId } = req.params;
const { executionId, tableId } = req.params;
const baseKey = sessionHelper.buildJourneyKey({ reportId, id });
const execKey = executionId ? sessionHelper.buildJourneyKey({ reportId, id, executionId }) : undefined;
const tableKey = tableId ? sessionHelper.buildJourneyKey({ reportId, id, tableId }) : undefined;
return {
baseKey,
execKey,
tableKey,
};
};
/**
* Sets up the active report journey URLS
*
* @param {Request} req
* @return {*}
*/
const setUpReportUrls = (req) => {
let currentReportPathname;
let currentReportSearch;
let currentReportUrl;
let currentReportFiltersSearch;
let currentReportColumnsSearch;
let currentPageSizeSearch;
let currentSortSearch;
if (req.originalUrl.includes('view-report')) {
const url = new URL(req.originalUrl, `${req.protocol}://${req.get('host')}`);
currentReportPathname = url.pathname;
currentReportSearch = url.search;
currentReportUrl = req.originalUrl;
}
if (currentReportSearch !== undefined) {
// Create the current filters string
const filterQueryObject = queryMappers.qsToQueryObject(currentReportSearch, 'filters.');
currentReportFiltersSearch = queryMappers.queryObjectToQs(filterQueryObject);
// Create the current columns string
const columnsQueryObject = queryMappers.qsToQueryObject(currentReportSearch, 'columns');
currentReportColumnsSearch = queryMappers.queryObjectToQs(columnsQueryObject);
// Create the current paging string
const pageSizeQueryObject = queryMappers.qsToQueryObject(currentReportSearch, 'pageSize');
currentPageSizeSearch = queryMappers.queryObjectToQs(pageSizeQueryObject);
// Create the current sort string
const pageSortQueryObject = queryMappers.qsToQueryObject(currentReportSearch, 'sort');
currentSortSearch = queryMappers.queryObjectToQs(pageSortQueryObject);
}
return {
...(currentReportPathname && { currentReportPathname }),
...(currentReportSearch !== undefined && { currentReportSearch }),
...(currentReportUrl && { currentReportUrl }),
...(currentReportFiltersSearch !== undefined && { currentReportFiltersSearch }),
...(currentReportColumnsSearch !== undefined && { currentReportColumnsSearch }),
...(currentPageSizeSearch !== undefined && { currentPageSizeSearch }),
...(currentSortSearch !== undefined && { currentSortSearch }),
};
};
/**
* Sets up the default query strings from the definition
*
* @param {Request} req
* @param {Response} res
* @param {ReportingService} service
* @return {*}
*/
const setUpDefaultsFromDefinition = async (fields) => {
const filtersQueryStrings = definitionUtils.getDefaultFiltersQueryString(fields);
const defaultColumnsSearch = definitionUtils.getDefaultColumnsQueryString(fields);
const defaultSortQueryString = definitionUtils.getDefaultSortQueryString(fields);
return {
...filtersQueryStrings,
defaultColumnsSearch,
defaultSortQueryString,
};
};
/**
* Sets up the bookmark configuration for the active report
*
* @param {Request} req
* @param {Response} res
* @param {BookmarkService} service
* @return {*}
*/
const setUpBookmark = async (req, res, service) => {
const { reportId, id } = req.params;
const userId = res.locals['dprUser'].id;
let reportIsBookmarked = false;
if (reportId && id && userId) {
reportIsBookmarked = (await service.isBookmarked(id, reportId, userId)) || false;
}
return reportIsBookmarked;
};
/**
* Sets up the subscription config for the active report
*
* @param {Request} req
* @param {Response} res
* @param {SubscriptionStoreService} service
* @return {*}
*/
const setUpSubsrcription = async (req, res, service) => {
const { reportId, id } = req.params;
const userId = res.locals['dprUser'].id;
let subscribed = false;
let subscriptionUrl;
if (reportId && id && userId) {
subscribed = (await service.isSubscribed(reportId, id, userId)) || false;
if (subscribed) {
const subscribedReport = await service.getSubscription(reportId, id, userId);
subscriptionUrl = subscribedReport ? utils.buildReportPageAction(res, req, subscribedReport).href : '/';
}
}
return {
subscribed,
subscriptionUrl,
};
};
/**
* Sets up the download configuration for the active report
*
* @param {Request} req
* @param {Response} res
* @param {DownloadPermissionService} service
* @return {*}
*/
const setUpDownloadConfig = async (req, res, service) => {
const { reportId, id } = req.params;
const userId = res.locals['dprUser'].id;
let downloadEnabled = false;
if (reportId && id && userId) {
downloadEnabled = await service.downloadEnabledForReport(userId, reportId, id);
}
return downloadEnabled;
};
/**
* Sets up the feedback configuration for the active report
*
* @param {Request} req
* @param {Response} res
* @return {*}
*/
const setupDownloadFeedbackPaths = (req, res) => {
const { reportId, id, tableId } = req.params;
const { nestedBaseUrl } = localsHelper.default.getRouteLocals(res);
let feedbackSubmissionFormPath;
if (reportId && id) {
feedbackSubmissionFormPath = tableId
? `/dpr/download-report/request-download/${reportId}/${id}/tableId/${tableId}/form`
: `/dpr/download-report/request-download/${reportId}/${id}/form`;
feedbackSubmissionFormPath = urlHelper.setNestedPath(feedbackSubmissionFormPath, nestedBaseUrl);
}
return feedbackSubmissionFormPath;
};
/**
* Sets up the saved defaults as query strings
*
* @param {Request} req
* @param {Response} res
* @param {DefaultFilterValuesService} service
* @return {*}
*/
const setupSavedDefaults = async (req, res, service, fields) => {
const { reportId, id } = req.params;
const userId = res.locals['dprUser'].id;
const savedRequestFilterValues = await service.get(userId, reportId, id, filtersTypeEnum.FiltersType.REQUEST);
const savedInteractiveFilterValues = await service.get(userId, reportId, id, filtersTypeEnum.FiltersType.INTERACTIVE);
const savedRequestDefaultsSearch = savedRequestFilterValues && savedRequestFilterValues.length
? personalisationUtils.createQsFromSavedDefaults(savedRequestFilterValues, fields)
: '';
const savedInteractiveDefaultsSearch = savedInteractiveFilterValues && savedInteractiveFilterValues.length
? personalisationUtils.createQsFromSavedDefaults(savedInteractiveFilterValues, fields)
: '';
return {
savedRequestDefaultsSearch,
savedInteractiveDefaultsSearch,
};
};
exports.buildKeyVariants = buildKeyVariants;
exports.storeActiveReportSessionData = storeActiveReportSessionData;
//# sourceMappingURL=setUpActiveReport.js.map