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.

223 lines (205 loc) 5.94 kB
import { NextFunction, Request, RequestHandler, Response } from 'express' import ReportQuery from '../../types/ReportQuery' import { ListDataSources, RenderListWithDataInput, RenderListWithDefinitionInput, CreateRequestHandlerInput, } from './types' import ReportingClient from '../../data/reportingClient' import { ListWithWarnings, Warnings } from '../../data/types' import { components } from '../../types/api' import Dict = NodeJS.Dict import ReportActionsUtils from '../_reports/report-actions/utils' import { Template } from '../../types/Templates' import SyncReportUtils from '../../utils/report/syncReportUtils' import FiltersUtils from '../_filters/utils' import { ReportType } from '../../types/UserReports' function isListWithWarnings(data: Dict<string>[] | ListWithWarnings): data is ListWithWarnings { return (data as ListWithWarnings).data !== undefined } export async function renderList( listData: ListDataSources, variantDefinition: components['schemas']['VariantDefinition'], reportQuery: ReportQuery, request: Request, response: Response, next: NextFunction, title: string, layoutTemplate: string, otherOptions?: NodeJS.Dict<object>, reportName?: string, ) { await Promise.all([listData.data, listData.count]) .then(async (resolvedData) => { let data let warnings: Warnings = {} const { specification, classification, printable, description, name: variantName } = variantDefinition const { template } = specification const count = resolvedData[1] if (isListWithWarnings(resolvedData[0])) { // eslint-disable-next-line prefer-destructuring data = resolvedData[0].data warnings = resolvedData[0].warnings } else { // eslint-disable-next-line prefer-destructuring data = resolvedData[0] } const reportRenderData = await SyncReportUtils.getReportRenderData( request, count, specification, reportQuery, data, ) const actions = ReportActionsUtils.getActions({ print: { enabled: variantDefinition.printable, }, share: { reportName, name: variantDefinition.name, url: reportRenderData.fullUrl, }, copy: { url: reportRenderData.fullUrl, }, }) const renderData = { renderData: { ...reportRenderData, reportName, name: title || variantName, description, count, classification, printable, actions, template, warnings, type: ReportType.REPORT, ...otherOptions, }, layoutTemplate, } response.render(`dpr/components/report-list/list`, renderData) }) .catch((err) => next(err)) } export const renderListWithDefinition = async ({ title, definitionName, variantName, request, response, next, otherOptions, layoutTemplate, token, apiUrl, apiTimeout, definitionsPath, }: RenderListWithDefinitionInput) => { const reportingClient = new ReportingClient({ url: apiUrl, agent: { timeout: apiTimeout, }, }) const { dataProductDefinitionsPath } = request.query const reportDef = <string>dataProductDefinitionsPath || definitionsPath try { const reportDefinition = await reportingClient.getDefinition(token, definitionName, variantName, reportDef) const reportName: string = reportDefinition.name const variantDefinition = reportDefinition.variant const reportQuery = new ReportQuery({ fields: variantDefinition.specification.fields, template: variantDefinition.specification.template as Template, queryParams: request.query, definitionsPath: reportDef, }) if (!FiltersUtils.redirectWithDefaultFilters(reportQuery, variantDefinition, response, request)) { const getListData: ListDataSources = { data: reportingClient.getListWithWarnings(variantDefinition.resourceName, token, reportQuery), count: reportingClient.getCount(variantDefinition.resourceName, token, reportQuery), } await renderList( getListData, variantDefinition, reportQuery, request, response, next, `${variantDefinition.name}`, layoutTemplate, otherOptions, title || `${reportName}`, ) } } catch (error) { next(error) } } export default { renderListWithData: async ({ title, reportName, variantDefinition, request, response, next, getListDataSources, otherOptions, layoutTemplate, }: RenderListWithDataInput) => { const { specification } = variantDefinition const reportQuery = new ReportQuery({ fields: specification.fields, template: specification.template as Template, queryParams: request.query, definitionsPath: <string>request.query.dataProductDefinitionsPath, }) const listData = getListDataSources(reportQuery) await renderList( listData, variantDefinition, reportQuery, request, response, next, title, layoutTemplate, otherOptions, reportName, ) }, createReportListRequestHandler: ({ title, definitionName, variantName, apiUrl, apiTimeout, otherOptions, layoutTemplate, tokenProvider, definitionsPath, }: CreateRequestHandlerInput): RequestHandler => { return (request: Request, response: Response, next: NextFunction) => { renderListWithDefinition({ title, definitionName, variantName, request, response, next, otherOptions, layoutTemplate, token: tokenProvider(request, response, next), apiUrl, apiTimeout, definitionsPath, }) } }, renderListWithDefinition, }