@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
263 lines (262 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.updateStore = void 0;
// Utils
const utils_1 = __importDefault(require("../async-filters-form/utils"));
const localsHelper_1 = __importDefault(require("../../../utils/localsHelper"));
const utils_2 = __importDefault(require("../../_filters/utils"));
const reportStoreHelper_1 = require("../../../utils/reportStoreHelper");
const UserStoreItemBuilder_1 = __importDefault(require("../../../utils/UserStoreItemBuilder"));
const UserReports_1 = require("../../../types/UserReports");
/**
* Updates the store with the request details
*
* @param {Request} req
* @param {Response} res
* @param {Services} services
* @param {SetQueryFromFiltersResult} querySummaryData
* @param {string} executionData
* @return {*} {Promise<string>}
*/
const updateStore = async ({ req, res, services, queryData, executionData, childExecutionData, }) => {
const { search, id, type } = req.body;
const { userId, definitionsPath, dpdPathFromQuery } = localsHelper_1.default.getValues(res);
await (0, reportStoreHelper_1.removeDuplicates)({ storeService: services.requestedReportService, userId, id, search });
await (0, reportStoreHelper_1.removeDuplicates)({ storeService: services.recentlyViewedService, userId, id, search });
const reportData = req.body;
let requestedReportData;
switch (type) {
case UserReports_1.ReportType.REPORT:
requestedReportData = new UserStoreItemBuilder_1.default(reportData)
.addExecutionData(executionData)
.addChildExecutionData(childExecutionData)
.addFilters(queryData.filterData)
.addSortData(queryData.sortData)
.addDefinitionsPath(definitionsPath, dpdPathFromQuery)
.addRequestUrls()
.addQuery(queryData)
.addStatus(UserReports_1.RequestStatus.SUBMITTED)
.addTimestamp()
.build();
break;
case UserReports_1.ReportType.DASHBOARD: {
requestedReportData = new UserStoreItemBuilder_1.default(reportData)
.addExecutionData(executionData)
.addChildExecutionData(childExecutionData)
.addFilters(queryData.filterData)
.addDefinitionsPath(definitionsPath, dpdPathFromQuery)
.addRequestUrls()
.addQuery(queryData)
.addStatus(UserReports_1.RequestStatus.SUBMITTED)
.addTimestamp()
.addMetrics(JSON.parse(req.body.sections))
.build();
break;
}
default:
break;
}
await services.requestedReportService.addReport(userId, requestedReportData);
return requestedReportData.url.polling.pathname;
};
exports.updateStore = updateStore;
async function requestChildReports(childVariants, reportingService, token, reportId, queryData, dataProductDefinitionsPath) {
return Promise.all(childVariants.map((childVariant) => reportingService
.requestAsyncReport(token, reportId, childVariant.id, {
...queryData.query,
dataProductDefinitionsPath,
})
.then((response) => {
const { executionId, tableId } = response;
return { executionId, tableId, variantId: childVariant.id };
})));
}
const requestProduct = async ({ req, res, token, dashboardService, reportingService, }) => {
var _a;
const { definitionsPath: dataProductDefinitionsPath } = localsHelper_1.default.getValues(res);
const { reportId, id, type } = req.body;
let fields;
let queryData;
let executionId;
let tableId;
let definition;
let childVariants = [];
if (type === UserReports_1.ReportType.REPORT) {
definition = await reportingService.getDefinition(token, reportId, id, dataProductDefinitionsPath);
fields = definition ? definition.variant.specification.fields : [];
queryData = utils_1.default.setQueryFromFilters(req, fields);
({ executionId, tableId } = await reportingService.requestAsyncReport(token, reportId, id, {
...queryData.query,
dataProductDefinitionsPath,
}));
childVariants = (_a = definition.variant.childVariants) !== null && _a !== void 0 ? _a : [];
}
if (type === UserReports_1.ReportType.DASHBOARD) {
definition = await dashboardService.getDefinition(token, id, reportId, dataProductDefinitionsPath);
fields = definition ? definition.filterFields : [];
queryData = utils_1.default.setQueryFromFilters(req, fields);
({ executionId, tableId } = await dashboardService.requestAsyncDashboard(token, reportId, id, {
...queryData.query,
dataProductDefinitionsPath,
}));
}
const childExecutionData = await requestChildReports(childVariants, reportingService, token, reportId, queryData, dataProductDefinitionsPath);
return {
executionData: { executionId, tableId },
childExecutionData,
queryData,
};
};
const renderDashboardRequestData = async ({ token, reportId, definitionPath, services, definition, }) => {
const productDefinitions = await services.reportingService.getDefinitions(token, definitionPath);
const productDefinition = productDefinitions.find((def) => def.id === reportId);
const reportName = productDefinition.name;
const { name, description, sections, filterFields: fields } = definition;
return {
reportName,
name,
description,
sections: sections || [],
fields,
};
};
const renderReportRequestData = async (definition) => {
var _a, _b, _c;
return {
definition,
reportName: definition.name,
name: definition.variant.name,
description: definition.variant.description || definition.description,
template: definition.variant.specification,
fields: (_b = (_a = definition === null || definition === void 0 ? void 0 : definition.variant) === null || _a === void 0 ? void 0 : _a.specification) === null || _b === void 0 ? void 0 : _b.fields,
interactive: (_c = definition === null || definition === void 0 ? void 0 : definition.variant) === null || _c === void 0 ? void 0 : _c.interactive,
};
};
const getDefintionByType = async (req, res, next, services) => {
const { token, definitionsPath } = localsHelper_1.default.getValues(res);
const { reportId, id, variantId, type } = req.params;
let definition;
if (type === UserReports_1.ReportType.REPORT) {
definition = await services.reportingService.getDefinition(token, reportId, variantId || id, definitionsPath);
}
if (type === UserReports_1.ReportType.DASHBOARD) {
definition = await services.dashboardService.getDefinition(token, variantId || id, reportId, definitionsPath);
}
return definition;
};
exports.default = {
/**
* Sends the request for the async report
*
* @param {AsyncReportUtilsParams} { req, res, services }
* @return {*}
*/
request: async ({ req, res, services }) => {
const { token } = localsHelper_1.default.getValues(res);
const requestArgs = { req, res, token };
const { executionData, queryData, childExecutionData } = await requestProduct({
...requestArgs,
dashboardService: services.dashboardService,
reportingService: services.reportingService,
});
let redirect = '';
if (executionData) {
redirect = await (0, exports.updateStore)({
req,
res,
services,
queryData,
executionData,
childExecutionData,
});
}
return redirect;
},
cancelRequest: async ({ req, res, services }) => {
const { token, userId, definitionsPath } = localsHelper_1.default.getValues(res);
const { reportId, id, executionId, type } = req.body;
let service;
if (type === UserReports_1.ReportType.REPORT)
service = services.reportingService;
if (type === UserReports_1.ReportType.DASHBOARD)
service = services.dashboardService;
const response = await service.cancelAsyncRequest(token, reportId, id, executionId, definitionsPath);
if (response && response.cancellationSucceeded) {
await services.requestedReportService.updateStatus(executionId, userId, UserReports_1.RequestStatus.ABORTED);
}
},
/**
* Returns the data required for rendering the async filters component
*
* @param {AsyncReportUtilsParams} { req, res, dataSources }
* @return {*}
*/
renderRequest: async ({ req, res, services, next }) => {
try {
const { token, csrfToken, definitionsPath: definitionPath, dpdPathFromQuery } = localsHelper_1.default.getValues(res);
const { reportId, type, id } = req.params;
const { definition } = req.body;
const definitionApiArgs = { token, reportId, definitionPath, services };
let name;
let reportName;
let description;
let template;
let fields;
let sections;
let interactive;
let defaultInteractiveQueryString;
let filtersData;
if (type === UserReports_1.ReportType.REPORT) {
;
({ name, reportName, description, fields, interactive } = await renderReportRequestData(definition));
}
if (type === UserReports_1.ReportType.DASHBOARD) {
;
({ name, reportName, description, sections, fields } = await renderDashboardRequestData({
...definitionApiArgs,
definition,
}));
}
if (fields) {
filtersData = await utils_1.default.renderFilters(fields, interactive);
filtersData.filters = utils_2.default.setFilterValuesFromRequest(filtersData.filters, req);
defaultInteractiveQueryString = utils_2.default.setFilterQueryFromFilterDefinition(fields, true);
}
const reportData = {
reportName,
name,
description,
reportId,
id,
...(dpdPathFromQuery && { definitionPath }),
...((defaultInteractiveQueryString === null || defaultInteractiveQueryString === void 0 ? void 0 : defaultInteractiveQueryString.length) && { defaultInteractiveQueryString }),
csrfToken,
template,
sections,
type: type,
};
return {
title: `Request ${type}`,
filtersDescription: `Customise your ${type} using the filters below and submit your request.`,
filtersData,
reportData,
};
}
catch (error) {
next(error);
return false;
}
},
getFiltersFromReqBody: (req) => {
return Object.keys(req.body)
.filter((attr) => attr.includes('filters.'))
.filter((attr) => !!req.body[attr])
.map((attr) => {
return { name: attr, value: req.body[attr] };
});
},
getDefintionByType,
};