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.

287 lines (286 loc) 11.6 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.setDataFromStatus = void 0; const dayjs_1 = __importDefault(require("dayjs")); const UserReports_1 = require("../../types/UserReports"); const requestStatusHelper_1 = require("../../utils/requestStatusHelper"); const utils_1 = __importDefault(require("../_filters/filters-selected/utils")); const reportListsHelper_1 = require("../../utils/reportListsHelper"); const utils_2 = __importDefault(require("./requested/utils")); const utils_3 = __importDefault(require("./viewed/utils")); const utils_4 = __importDefault(require("./bookmarks/utils")); const localsHelper_1 = __importDefault(require("../../utils/localsHelper")); const DateMapper_1 = __importDefault(require("../../utils/DateMapper/DateMapper")); const UserStoreItemBuilder_1 = __importDefault(require("../../utils/UserStoreItemBuilder")); const formatData = (reportData) => { const reportDataCopy = JSON.parse(JSON.stringify(reportData)); const { executionId, tableId, variantName, name, reportId, variantId, id, description, query, interactiveQuery, status, timestamp, reportName, dataProductDefinitionsPath, type: reportType, } = reportDataCopy; let summary = []; if (query) { summary = query.summary; } let interactiveSummary = []; if (interactiveQuery) { interactiveSummary = interactiveQuery.summary; } const type = reportType || UserReports_1.ReportType.REPORT; return { id: executionId, text: name || variantName, reportName, description, tag: 'MIS', summary, interactiveSummary, timestamp, status, type, ...(0, exports.setDataFromStatus)(status, reportDataCopy), meta: { reportId, id: variantId || id, executionId, tableId, status, type, dataProductDefinitionsPath, }, }; }; const formatTable = (data, type) => { const rows = data.map((card) => { return formatTableRow(card, type); }); return { rows, head: [ { text: 'Product', classes: 'dpr-req-product-head' }, { text: 'Filters', classes: 'dpr-req-filters-head' }, { text: 'Status', classes: 'dpr-req-status-head' }, { text: 'Actions', classes: 'dpr-req-actions-head' }, ], }; }; const formatTableRow = (data, type) => { let statusClass; let itemActions = ''; const { href, id, reportName, text, timestamp, type: reportType, status } = data; switch (status) { case UserReports_1.RequestStatus.FAILED: statusClass = 'govuk-tag--red'; itemActions = (0, reportListsHelper_1.itemActionsHtml)(href, id, type, status); break; case UserReports_1.RequestStatus.EXPIRED: statusClass = 'govuk-tag--grey'; itemActions = (0, reportListsHelper_1.itemActionsHtml)(href, id, type, status); break; case UserReports_1.RequestStatus.ABORTED: statusClass = 'govuk-tag--orange'; itemActions = (0, reportListsHelper_1.itemActionsHtml)(href, id, type, status); break; case UserReports_1.RequestStatus.READY: case UserReports_1.RequestStatus.FINISHED: itemActions = `<a class='govuk-link govuk-link--no-visited-state' href="${href}">Go to ${reportType}</a>`; statusClass = 'govuk-tag--green'; break; case UserReports_1.RequestStatus.PICKED: case UserReports_1.RequestStatus.SUBMITTED: case UserReports_1.RequestStatus.STARTED: itemActions = `<a class='govuk-link govuk-link--no-visited-state' href="${href}">Go to status</a>`; break; default: break; } let filtersSummary = ''; if (data.summary || data.interactiveSummary) { filtersSummary = createSummaryHtml(data); } return [ { html: (0, reportListsHelper_1.createListItemProduct)(reportName, text, reportType, timestamp), }, { html: filtersSummary }, { html: `<strong class="govuk-tag dpr-request-status-tag ${statusClass}">${status}</strong>`, classes: 'dpr-req-cell dpr-req-cell__status', }, { html: `${itemActions}`, classes: 'dpr-req-cell dpr-req-cell__status', }, ]; }; const getTotals = (formattedCount, maxRows) => { return { amount: formattedCount, shown: formattedCount > maxRows ? maxRows : formattedCount, max: maxRows, }; }; const createSummaryHtml = (data) => { const summaryHtml = data.summary .map((item) => `<li class="govuk-body-s dpr-query-summary"><strong>${item.name}</strong>: ${item.value}</li>`) .join(''); const interactiveSummaryHtml = data.interactiveSummary .map((item) => `<li class="govuk-body-s dpr-interactive-query-summary"><strong>${item.name}</strong>: ${item.value}</li>`) .join(''); return `<ul class="dpr-card-group__item__filters-list govuk-!-margin-top-0 govuk-!-margin-bottom-0">${summaryHtml}${interactiveSummaryHtml}</ul>`; }; const getMeta = (formattedData) => { return formattedData.map((d) => { return { reportId: d.meta.reportId, id: d.meta.id, executionId: d.meta.executionId, tableId: d.meta.tableId, status: d.meta.status, requestedAt: d.meta.requestedAt, type: d.meta.type, dataProductDefinitionsPath: d.meta.dataProductDefinitionsPath, }; }); }; const setDataFromStatus = (status, reportsData) => { let timestamp; let href; let formattedDate; const { url, timestamp: time } = reportsData; const dateMapper = new DateMapper_1.default(); switch (status) { case UserReports_1.RequestStatus.FAILED: { formattedDate = time.failed ? dateMapper.toDateString(time.failed, 'local-date') : (0, dayjs_1.default)().format('DD/MM/YYYY'); href = `${url.polling.fullUrl}`; timestamp = `Failed at: ${formattedDate}`; break; } case UserReports_1.RequestStatus.ABORTED: { href = `${url.request.fullUrl}`; formattedDate = dateMapper.toDateString(time.aborted, 'local-date'); timestamp = `Aborted at: ${formattedDate}`; break; } case UserReports_1.RequestStatus.FINISHED: href = url.report.fullUrl; formattedDate = dateMapper.toDateString(time.completed, 'local-date'); timestamp = `Ready at: ${formattedDate}`; break; case UserReports_1.RequestStatus.EXPIRED: { href = `${url.request.fullUrl}`; formattedDate = dateMapper.toDateString(time.expired, 'local-date'); timestamp = `Expired at: ${formattedDate}`; break; } case UserReports_1.RequestStatus.READY: { href = `${url.report.fullUrl}`; formattedDate = dateMapper.toDateString(time.lastViewed, 'local-date'); timestamp = `Last viewed: ${formattedDate}`; break; } case UserReports_1.RequestStatus.SUBMITTED: case UserReports_1.RequestStatus.STARTED: case UserReports_1.RequestStatus.PICKED: href = url.polling.fullUrl; formattedDate = dateMapper.toDateString(time.requested, 'local-date'); timestamp = `Requested at: ${formattedDate}`; break; default: formattedDate = dateMapper.toDateString(time.lastViewed, 'local-date'); timestamp = `Last viewed: ${formattedDate}`; break; } return { timestamp, href, }; }; exports.setDataFromStatus = setDataFromStatus; const renderList = async ({ res, reportsData, maxRows, filterFunction, type, }) => { const { csrfToken } = localsHelper_1.default.getValues(res); let formatted = reportsData.filter(filterFunction).map(formatData); const formattedCount = formatted.length; if (maxRows) formatted = formatted.slice(0, maxRows); const tableData = formatTable(formatted, type); const head = { ...(formatted.length && { href: `./async-reports/${type}` }), ...(!formatted.length && { emptyMessage: `You have 0 ${type} reports` }), }; const result = { head, tableData, total: getTotals(formattedCount, maxRows), meta: getMeta(formatted), csrfToken, maxRows, }; return result; }; exports.default = { renderList, getExpiredStatus: async ({ req, res, services, storeService, }) => { const { userId } = localsHelper_1.default.getValues(res); const report = await (0, requestStatusHelper_1.getExpiredStatus)({ req, res, services }); if (report && report.isExpired) { await storeService.setToExpired(report.executionId, userId); } return report ? report.isExpired : false; }, init: async ({ services, res, req, maxRows = 6, }) => { const { requestedReports, recentlyViewedReports, bookmarkingEnabled } = localsHelper_1.default.getValues(res); const requestedReportsList = await renderList({ res, reportsData: requestedReports, filterFunction: utils_2.default.filterReports, maxRows, type: 'requested', }); const viewedReportsList = await renderList({ res, reportsData: recentlyViewedReports, filterFunction: utils_3.default.filterReports, maxRows, type: 'viewed', }); let bookmarks; if (bookmarkingEnabled) { bookmarks = await utils_4.default.renderBookmarkList({ res, req, services, maxRows, }); } return { requestedReports: requestedReportsList, viewedReports: viewedReportsList, bookmarks, }; }, updateLastViewed: async ({ req, services, reportStateData, userId, filters, }) => { const { type, reportId, reportName, description, id, name, executionId, tableId, query, url } = reportStateData; const reportData = { type, reportId, reportName, description, id, name }; const executionData = { executionId, tableId }; const queryData = query ? { query: query.data, querySummary: query.summary } : { query: {}, querySummary: [] }; const interactiveQueryData = { query: req.query, querySummary: utils_1.default.getQuerySummary(req, filters), }; const recentlyViewedData = new UserStoreItemBuilder_1.default() .addReportData(reportData) .addExecutionData(executionData) .addQuery(queryData) .addInteractiveQuery(interactiveQueryData) .addStatus(UserReports_1.RequestStatus.READY) .addTimestamp() .addAsyncUrls(url) .addReportUrls(req) .build(); await services.requestedReportService.updateLastViewed(reportStateData.executionId, userId); await services.recentlyViewedService.setRecentlyViewed(recentlyViewedData, userId); }, };