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.

309 lines (308 loc) 12.7 kB
"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, };