@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
309 lines (308 loc) • 12.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getChildData = exports.getSummariesData = exports.getData = void 0;
const parseurl_1 = __importDefault(require("parseurl"));
const UserReports_1 = require("../../types/UserReports");
const ReportQuery_1 = __importDefault(require("../../types/ReportQuery"));
const CollatedSummaryBuilder_1 = __importDefault(require("../CollatedSummaryBuilder/CollatedSummaryBuilder"));
const utils_1 = __importDefault(require("../../components/_reports/report-pagination/utils"));
const utils_2 = __importDefault(require("../../components/_reports/report-totals/utils"));
const utils_3 = __importDefault(require("../../components/_filters/utils"));
const utils_4 = __importDefault(require("../../components/_reports/report-columns-form/utils"));
const utils_5 = __importDefault(require("../../components/_reports/report-actions/utils"));
const utils_6 = __importDefault(require("../../components/user-reports/utils"));
const localsHelper_1 = __importDefault(require("../localsHelper"));
const utils_7 = __importDefault(require("../../components/_reports/report-data-table/utils"));
const getData = async ({ res, req, services, token, userId, }) => {
const { definitionsPath: definitionPath } = localsHelper_1.default.getValues(res);
const { reportId, variantId, id, tableId } = req.params;
const reportVariantId = variantId || id;
// Get the definition
const definition = await services.reportingService.getDefinition(token, reportId, reportVariantId, definitionPath);
// Get the request data
const requestData = await services.requestedReportService.getReportByTableId(tableId, userId);
// Get the reportData
const { reportData, reportQuery } = await getReportData(definition, services, token, req, res);
// Get the summary data, if applicable
const summariesData = !definition.variant.summaries
? []
: await (0, exports.getSummariesData)(definition, services, token, req, res);
// Get the child data, if applicable
const childData = !definition.variant.childVariants
? []
: await (0, exports.getChildData)(definition, services, token, req, res, requestData);
return {
definition,
requestData,
reportData,
summariesData,
childData,
reportQuery,
};
};
exports.getData = getData;
const getReportData = async (reportDefinition, services, token, req, res) => {
const { definitionsPath } = localsHelper_1.default.getValues(res);
const { reportId, variantId, id, tableId } = req.params;
const reportVariantId = variantId || id;
const { variant } = reportDefinition;
const { specification } = variant;
const reportQuery = new ReportQuery_1.default({
fields: specification.fields,
template: specification.template,
queryParams: req.query,
definitionsPath,
});
const reportData = await services.reportingService.getAsyncReport(token, reportId, reportVariantId, tableId, reportQuery.toRecordWithFilterPrefix(true));
return {
reportData,
reportQuery,
};
};
const getSummariesData = async (reportDefinition, services, token, req, res) => {
const { reportId, variantId, id, tableId } = req.params;
const { definitionsPath: dataProductDefinitionsPath } = localsHelper_1.default.getValues(res);
const reportVariantId = variantId || id;
return Promise.all(reportDefinition.variant.summaries.map(async (summary) => {
const summaryReport = await services.reportingService.getAsyncSummaryReport(token, reportId, reportVariantId, tableId, summary.id, {
dataProductDefinitionsPath,
});
return {
...summary,
data: summaryReport,
};
}));
};
exports.getSummariesData = getSummariesData;
const getChildData = async (reportDefinition, services, token, req, res, requestData) => {
const { definitionsPath: dataProductDefinitionsPath } = localsHelper_1.default.getValues(res);
const { reportId } = req.params;
return Promise.all(reportDefinition.variant.childVariants.map(async (childVariant) => {
const { specification } = childVariant;
const query = new ReportQuery_1.default({
fields: specification.fields,
template: reportDefinition.variant.specification.template,
queryParams: req.query,
definitionsPath: dataProductDefinitionsPath,
}).toRecordWithFilterPrefix(true);
const { tableId: childTableId } = requestData.childExecutionData.find((e) => e.variantId === childVariant.id);
const childReport = await services.reportingService.getAsyncReport(token, reportId, childVariant.id, childTableId, query);
return {
id: childVariant.id,
data: childReport,
};
}));
};
exports.getChildData = getChildData;
/**
* Entry point function to render the report
*
* @param {AsyncReportUtilsParams} { req, res, services }
* @return {*}
*/
const renderReport = async ({ req, res, services }) => {
const { token, userId } = localsHelper_1.default.getValues(res);
// Get the report data
const { definition, requestData, reportData, childData, summariesData, reportQuery } = await (0, exports.getData)({
req,
res,
services,
token,
userId,
});
// Get the columns
const columns = utils_4.default.getColumns(definition.variant.specification, req.query.columns);
// Get the data table
const dataTable = utils_7.default.createDataTable(definition, columns, reportData, childData, summariesData, reportQuery);
// Get the template data
const templateData = await getTemplateData(req, res, services, definition, requestData, summariesData, dataTable, columns, reportQuery);
const renderData = {
...templateData,
dataTable,
};
if (Object.keys(requestData).length) {
utils_6.default.updateLastViewed({
req,
services,
reportStateData: requestData,
userId,
search: renderData.search,
href: renderData.pathname,
filters: templateData.filterData.filters,
});
}
return { renderData };
};
const getTemplateData = async (req, res, services, definition, requestData, summariesData, dataTable, columns, reportQuery) => {
const url = (0, parseurl_1.default)(req);
const urls = setUrls(url);
const definitionData = extractDataFromDefinition(definition);
const { fields, specification } = definitionData;
const requestedData = extractDataFromRequest(requestData);
const count = await getCount(definition, requestData, services, res, reportQuery);
const interactive = true;
const filterData = await utils_3.default.getFilters({
fields,
req,
interactive,
});
const features = await setFeatures(services, res, requestData, definition, columns, count, urls);
const meta = setMetaData(definition, res);
let reportSummaries;
if (summariesData.length) {
const collatedSummaryBuilder = new CollatedSummaryBuilder_1.default(specification, summariesData);
reportSummaries = collatedSummaryBuilder.collatePageSummaries();
}
let pagination;
let totals;
if (meta.template === 'list') {
pagination = utils_1.default.getPaginationData(url, count);
const { pageSize, currentPage, totalRows } = pagination;
totals = utils_2.default.getTotals(pageSize, currentPage, totalRows, dataTable[0].rowCount);
}
return {
...(showColumns(specification) && { columns }),
filterData,
count,
...meta,
...features,
...requestedData,
...urls,
...(pagination && { pagination }),
...(totals && { totals }),
...(reportSummaries && { reportSummaries }),
};
};
const showColumns = (specification) => {
const { template } = specification;
return !['row-section', 'row-section-child', 'summary', 'summary-section'].includes(template);
};
const setMetaData = (definition, res) => {
const { classification } = definition.variant;
const { template } = definition.variant.specification;
const { csrfToken } = localsHelper_1.default.getValues(res);
return {
csrfToken,
classification,
template,
loadType: UserReports_1.LoadType.ASYNC,
type: UserReports_1.ReportType.REPORT,
};
};
const setUrls = (url) => {
const { search, pathname } = url;
const reportUrl = pathname.replace('/download-disabled', '').replace('/download-disabled?', '');
const reportSearch = search;
const encodedSearch = search ? encodeURIComponent(search) : undefined;
return {
reportUrl,
reportSearch,
encodedSearch,
search,
pathname,
};
};
const setFeatures = async (services, res, requestData, definition, columns, count, urls) => {
const { csrfToken, userId, bookmarkingEnabled, downloadingEnabled } = localsHelper_1.default.getValues(res);
const { reportId } = requestData;
const id = requestData.variantId || requestData.id;
const { variant } = definition;
let canDownload;
if (downloadingEnabled) {
canDownload = await services.downloadPermissionService.downloadEnabled(userId, reportId, id);
}
let bookmarked;
if (bookmarkingEnabled) {
bookmarked = await services.bookmarkService.isBookmarked(id, reportId, userId);
}
const actions = setActions(csrfToken, variant, requestData, columns, canDownload, count, urls.pathname, urls.search);
const { printable } = variant;
return {
actions,
canDownload,
bookmarked,
printable,
};
};
const getCount = async (definition, requestData, services, res, reportQuery) => {
const { token } = localsHelper_1.default.getValues(res);
const { tableId, reportId } = requestData;
const id = requestData.variantId || requestData.id;
return !definition.variant.interactive
? services.reportingService.getAsyncCount(token, tableId)
: services.reportingService.getAsyncInteractiveCount(token, tableId, reportId, id, reportQuery);
};
const extractDataFromDefinition = (definition) => {
const { variant } = definition;
const { classification, printable, specification } = variant;
const { template, fields } = specification;
const { interactive } = variant;
return {
classification,
printable,
specification,
template,
interactive,
fields,
variant,
};
};
const extractDataFromRequest = (requestData) => {
return {
reportName: requestData.reportName,
name: requestData.name,
description: requestData.description,
requestedTimestamp: new Date(requestData.timestamp.requested).toLocaleString(),
reportId: requestData.reportId,
tableId: requestData.tableId,
id: requestData.variantId || requestData.id,
executionId: requestData.executionId,
querySummary: requestData.query.summary,
requestUrl: requestData.url.request,
defaultQuery: requestData.url.report.default,
dataProductDefinitionsPath: requestData.dataProductDefinitionsPath,
};
};
const setActions = (csrfToken, variant, requestData, columns, canDownload, count, currentUrl, currentQueryParams) => {
const { reportName, name, id, variantId, reportId, tableId, executionId, dataProductDefinitionsPath, url } = requestData;
const requestUrl = url.request.fullUrl;
const { printable } = variant;
const ID = variantId || id;
const downloadConfig = {
enabled: count > 0 && canDownload !== undefined,
name,
reportName,
csrfToken,
reportId,
id: ID,
tableId,
columns: columns.value,
definitionPath: dataProductDefinitionsPath,
loadType: UserReports_1.LoadType.ASYNC,
canDownload,
currentUrl,
currentQueryParams,
};
const shareConfig = {
reportName,
name,
url: requestUrl,
};
const refreshConfig = {
url: requestUrl,
executionId,
};
return utils_5.default.getActions({
download: downloadConfig,
print: { enabled: printable },
share: shareConfig,
refresh: refreshConfig,
copy: { url: requestUrl },
});
};
exports.default = {
renderReport,
};