@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
152 lines (128 loc) • 5.14 kB
text/typescript
import type { RequestHandler, Router } from 'express'
import { Services } from '../types/Services'
import logger from '../utils/logger'
import DownloadUtils from '../utils/downloadUtils'
import { LoadType } from '../types/UserReports'
import { components } from '../types/api'
import LocalsHelper from '../utils/localsHelper'
/**
* DOWNLOAD PROCESS
*
* 1. User clicks download button on the report for the first time.
* 2. The users download permissions are checked.
* 3. No permission is found - redirect to report with disabled message - leave feedback to download
* 4. Fill feedback form and submit - POST to submission handler
* 5. Log feedback, add download permission for report to user config
* 6. User navigates back to the report
* 7. Clicks download - POST to download handler
* 8. Check if user has permission - permission is present
* 9. Handler gets report data, converts to CSV, saves to file, download the file and clears up
*/
export default function routes({
router,
layoutPath,
services,
prefix,
}: {
router: Router
layoutPath: string
services: Services
prefix: string
}) {
logger.info('Initialiasing routes: Download')
const feedbackFormHandler: RequestHandler = async (req, res, next) => {
const { token, csrfToken, definitionsPath } = LocalsHelper.getValues(res)
const { reportId, variantId, tableId } = req.params
const loadType = tableId ? LoadType.ASYNC : LoadType.SYNC
const { reportSearch, reportUrl } = req.query
let queryString
let dataProductDefinitionsPath
if (reportSearch) {
queryString = decodeURIComponent(<string>reportSearch)
const params = new URLSearchParams(queryString)
dataProductDefinitionsPath = params.get('dataProductDefinitionsPath') || definitionsPath
}
const variantData: components['schemas']['SingleVariantReportDefinition'] =
await services.reportingService.getDefinition(token, reportId, variantId, dataProductDefinitionsPath)
try {
res.render(`dpr/views/feedback-form`, {
title: 'Download request form',
user: res.locals.user,
report: {
reportId,
reportName: variantData.name,
variantId,
variantName: variantData.variant.name,
tableId,
loadType,
reportUrl,
reportSearch: reportSearch || undefined,
time: new Date().toDateString(),
},
csrfToken,
layoutPath,
postEndpoint: '/dpr/submitFeedback/',
})
} catch (error) {
next()
}
}
const feedbackSubmitHandler: RequestHandler = async (req, res, next) => {
const { body } = req
const { reportId, variantId, reportName, variantName, reportUrl, reportSearch } = body
logger.info('Download Feedback Submission:', `${JSON.stringify(body)}`)
let queryParams
queryParams = `?reportName=${reportName}&variantName=${variantName}&reportUrl=${reportUrl}`
if (reportSearch) {
const encodedSearch = encodeURIComponent(reportSearch)
queryParams = `${queryParams}&reportSearch=${encodedSearch}`
}
const redirect = `/download/${reportId}/${variantId}/feedback/submitted${queryParams}`
res.redirect(redirect)
}
const feedbackSuccessHandler: RequestHandler = async (req, res, next) => {
const userId = res.locals.user?.uuid ? res.locals.user.uuid : 'userId'
const { reportId, variantId } = req.params
const { reportName, variantName, reportUrl, reportSearch } = req.query
let decodedReportSearch
if (reportSearch) {
decodedReportSearch = decodeURIComponent(<string>reportSearch)
}
const reportHref = reportSearch ? `${reportUrl}${decodedReportSearch}` : `${reportUrl}`
await services.downloadPermissionService.saveDownloadPermissionData(userId, reportId, variantId)
res.render(`dpr/views/feedback-form-success`, {
title: 'success',
layoutPath,
report: {
reportName,
variantName,
reportHref,
},
})
}
const downloadRequestHandler: RequestHandler = async (req, res, next) => {
const userId = res.locals.user?.uuid ? res.locals.user.uuid : 'userId'
const { reportId, id, loadType, currentUrl, currentQueryParams } = req.body
let redirect = `${currentUrl}/download-disabled`
redirect = currentQueryParams ? `${redirect}${currentQueryParams}` : redirect
const canDownload = await services.downloadPermissionService.downloadEnabled(userId, reportId, id)
if (canDownload) {
await DownloadUtils.downloadReport({ req, res, services, redirect, loadType })
} else {
res.redirect(redirect)
}
}
router.get(
[`${prefix}/download/:reportId/:variantId/:tableId/feedback`, `${prefix}/download/:reportId/:variantId/feedback`],
feedbackFormHandler,
)
router.post('/dpr/submitFeedback/', feedbackSubmitHandler)
router.get(
[
`${prefix}/download/:reportId/:variantId/:tableId/feedback/submitted`,
`${prefix}/download/:reportId/:variantId/feedback/submitted`,
],
feedbackSuccessHandler,
)
router.post('/dpr/downloadReport/', downloadRequestHandler)
}