@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
JavaScript
;
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);
},
};