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.

177 lines (174 loc) 6.15 kB
import localsHelper from '../../../utils/localsHelper.js'; import logger from '../../../utils/logger.js'; import { getActiveJourneyValue } from '../../../utils/sessionHelper.js'; import { qsToQueryObject } from '../../../utils/queryMappers.js'; import { validateDefinition, getFields, getField } from '../../../utils/definitionUtils.js'; /** * Streams the download for an Async repoort * * @param {({ * services: Services * token: string * tableId: string * reportId: string * id: string * queryParams: Record<string, string | string[]> * res: Response * })} args * @return {*} */ const streamDownloadAsyncData = async (args) => { const { token, services, tableId, reportId, id, queryParams, res } = args; return services.reportingService.downloadAsyncReport(token, reportId, id, tableId, queryParams, res); }; /** * Streams the download for a sync report * * @param {({ * definition: components['schemas']['SingleVariantReportDefinition'] * services: Services * token: string * queryParams: Record<string, string | string[]> * res: Response * })} args * @return {*} */ const streamDownloadSyncData = async (args) => { const { token, services, queryParams, definition, res } = args; const { variant } = validateDefinition(definition); const { resourceName } = variant; return services.reportingService.downloadSyncReport(token, resourceName, queryParams, res); }; /** * Downloads the report * * @param {{ * req: Request * services: Services * res: Response * redirect: string * }} { * req, * services, * res, * redirect, * } */ const downloadReport = async ({ req, services, res }) => { const { reportId, id, tableId } = req.params; const { token, definitionsPath: dataProductDefinitionsPath } = localsHelper.getValues(res); const definition = await services.reportingService.getDefinition(token, reportId, id, dataProductDefinitionsPath); const queryParams = setQueryForDownload(req, definition, dataProductDefinitionsPath); logger.info(`Initiating streaming...`); if (!tableId) { await streamDownloadSyncData({ definition, services, token, queryParams, res, }); } else { await streamDownloadAsyncData({ services, token, reportId, id, tableId, queryParams, res, }); } }; /** * Initialises the download config in the UI * * @param {Response} res * @param {Request} req * @param {ExtractedDefinitionData} definitionData * @param {LoadType} loadType * @param {ExtractedRequestData} [requestData] * @return {*} {(DownloadActionParams | undefined)} */ const setUpDownload = (res, req) => { const { downloadingEnabled } = localsHelper.getValues(res); let downloadConfig; if (downloadingEnabled) { const { tableId, id, reportId } = req.params; const { csrfToken } = localsHelper.getValues(res); const { downloadActionEndpoint } = localsHelper.getRouteLocals(res); const downloadEnabledForReport = getActiveJourneyValue(req, { id, reportId }, 'downloadEnabled'); const formaction = tableId ? `${downloadActionEndpoint}${reportId}/${id}/tableId/${tableId}` : `${downloadActionEndpoint}${reportId}/${id}`; return { enabled: downloadingEnabled, formAction: formaction, canDownload: Boolean(downloadEnabledForReport), csrfToken, }; } return downloadConfig; }; /** * Sets the query for the download API request * * @param {string} currentReportSearch * @param {components['schemas']['SingleVariantReportDefinition']} definition * @return {*} */ const setQueryForDownload = (req, definition, dataProductDefinitionsPath) => { const { reportId, id, tableId } = req.params; const sessionKey = tableId ? { reportId, id, tableId } : { reportId, id }; const currentReportSearch = getActiveJourneyValue(req, sessionKey, 'currentReportSearch') || ''; // Filters query const filtersQuery = qsToQueryObject(currentReportSearch, 'filters.'); // Sort query let sortQuery = qsToQueryObject(currentReportSearch, 'sort'); if (!sortQuery || Object.keys(sortQuery).length === 0) { // Fall back to default const defaultSortQueryString = getActiveJourneyValue(req, sessionKey, 'defaultSortQueryString') || ''; sortQuery = qsToQueryObject(defaultSortQueryString, 'sort'); } // Columns const columnsQuery = qsToQueryObject(currentReportSearch, 'columns'); const validColumnsQuery = setColumnsForDownload(columnsQuery, definition); return { ...filtersQuery, ...validColumnsQuery, ...sortQuery, ...(dataProductDefinitionsPath && { dataProductDefinitionsPath }), }; }; /** * Gets the columns/fields for the download request * * - Fields with fieldSource of 'specfield' should be discarded * * @param {Columns} columns * @param {ExtractedDefinitionData} definitionData * @return {*} */ const setColumnsForDownload = (query, definition) => { const fields = getFields(definition); const { specification } = definition.variant; // Ensure sections heading are always included in download, if present const sections = specification?.sections || []; // Normalize columns - single column will be a `string`, we need an array const queryColumns = [].concat(query['columns'] ?? []); // master columns list const requestedColumns = [...new Set([...queryColumns, ...sections])]; // Ensure only valid columns are part of download query const validColumns = requestedColumns.filter(fieldName => { const field = getField(fields, fieldName); return field && (field.fieldSource === 'specfield' || field.fieldSource === undefined); }); return { columns: validColumns }; }; var DownloadUtils = { downloadReport, setUpDownload, }; export { DownloadUtils as default, downloadReport, setUpDownload }; //# sourceMappingURL=utils.js.map