@ministryofjustice/hmpps-digital-prison-reporting-frontend 4.2.2 → 4.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dpr/all.mjs +7 -7
  2. package/dpr/assets/js/all.mjs +7 -7
  3. package/dpr/components/_reports/report-actions/view.njk +1 -1
  4. package/dpr/components/download-feeback-form/view.njk +1 -1
  5. package/dpr/middleware/setUpDprResources.js +86 -0
  6. package/dpr/middleware/setUpDprResources.ts +102 -0
  7. package/dpr/routes/DprEmbeddedReports.js +10 -5
  8. package/dpr/routes/DprEmbeddedReports.ts +18 -6
  9. package/dpr/routes/asyncReports.js +12 -50
  10. package/dpr/routes/asyncReports.ts +20 -56
  11. package/dpr/routes/bookmarks.js +5 -5
  12. package/dpr/routes/bookmarks.ts +6 -6
  13. package/dpr/routes/download.js +11 -8
  14. package/dpr/routes/download.ts +12 -9
  15. package/dpr/routes/recentlyViewed.js +5 -5
  16. package/dpr/routes/recentlyViewed.ts +6 -6
  17. package/dpr/routes/syncReports.js +10 -7
  18. package/dpr/routes/syncReports.ts +11 -8
  19. package/dpr/types/DprConfig.js +2 -0
  20. package/dpr/types/DprConfig.ts +4 -0
  21. package/dpr/utils/embeddedRouteUtils.js +1 -1
  22. package/dpr/utils/embeddedRouteUtils.ts +1 -1
  23. package/dpr/utils/localsHelper.js +2 -0
  24. package/dpr/utils/localsHelper.ts +2 -0
  25. package/dpr/utils/reportListsHelper.js +3 -3
  26. package/dpr/utils/reportListsHelper.ts +3 -3
  27. package/dpr/utils/urlHelper.js +13 -1
  28. package/dpr/utils/urlHelper.ts +13 -0
  29. package/package.json +1 -1
  30. package/package.zip +0 -0
  31. package/dpr/middleware/populateDefinitions.js +0 -45
  32. package/dpr/middleware/populateDefinitions.ts +0 -65
  33. package/dpr/middleware/populateRequestedReports.js +0 -44
  34. package/dpr/middleware/populateRequestedReports.ts +0 -48
package/dpr/all.mjs CHANGED
@@ -276,7 +276,7 @@ class BookmarkToggle extends DprClientClass {
276
276
  }
277
277
 
278
278
  async toggleBookmark(type, id, reportId, reportType, csrfToken) {
279
- const endpoint = type === 'add' ? '/addBookmark/' : '/removeBookmark/';
279
+ const endpoint = type === 'add' ? '/dpr/addBookmark/' : '/dpr/removeBookmark/';
280
280
  await fetch(endpoint, {
281
281
  method: 'post',
282
282
  headers: {
@@ -1065,7 +1065,7 @@ class DprPollingStatusClass extends DprClientClass {
1065
1065
  }
1066
1066
 
1067
1067
  async getRequestStatus(metaData, csrfToken) {
1068
- return this.getStatus('/getStatus/', metaData, csrfToken)
1068
+ return this.getStatus('/dpr/getStatus/', metaData, csrfToken)
1069
1069
  }
1070
1070
 
1071
1071
  async getExpiredStatus(endpoint, metaData, csrfToken) {
@@ -1161,7 +1161,7 @@ class DprAsyncPolling extends DprPollingStatusClass {
1161
1161
  const csrfToken = this.cancelRequestButton.getAttribute('data-csrf-token');
1162
1162
 
1163
1163
  this.cancelRequestButton.addEventListener('click', async () => {
1164
- await fetch('/cancelRequest/', {
1164
+ await fetch('/dpr/cancelRequest/', {
1165
1165
  method: 'post',
1166
1166
  headers: {
1167
1167
  Accept: 'application/json',
@@ -1851,7 +1851,7 @@ class DprAsyncRequestList extends DprPollingStatusClass {
1851
1851
  await Promise.all(
1852
1852
  JSON.parse(this.requestData).map(async (metaData) => {
1853
1853
  if (!this.EXPIRED_END_STATUSES.includes(metaData.status)) {
1854
- const response = await this.getExpiredStatus('/getRequestedExpiredStatus/', metaData, this.csrfToken);
1854
+ const response = await this.getExpiredStatus('/dpr/getRequestedExpiredStatus/', metaData, this.csrfToken);
1855
1855
 
1856
1856
  if (response && response.isExpired) {
1857
1857
  clearInterval(this.expiredInterval);
@@ -1891,7 +1891,7 @@ class DprAsyncRequestList extends DprPollingStatusClass {
1891
1891
 
1892
1892
  async removeItemFromList(executionId) {
1893
1893
  let response;
1894
- await fetch('/removeRequestedItem/', {
1894
+ await fetch('/dpr/removeRequestedItem/', {
1895
1895
  method: 'post',
1896
1896
  headers: {
1897
1897
  Accept: 'application/json',
@@ -1945,7 +1945,7 @@ class DprRecentlyViewedList extends DprPollingStatusClass {
1945
1945
  await Promise.all(
1946
1946
  JSON.parse(this.viewedReportData).map(async (metaData) => {
1947
1947
  if (metaData.status !== 'EXPIRED') {
1948
- const response = await this.getExpiredStatus('/getExpiredStatus/', metaData, this.csrfToken);
1948
+ const response = await this.getExpiredStatus('/dpr/getExpiredStatus/', metaData, this.csrfToken);
1949
1949
  if (response && response.isExpired) {
1950
1950
  window.location.reload();
1951
1951
  clearInterval(this.expiredViewedInterval);
@@ -1967,7 +1967,7 @@ class DprRecentlyViewedList extends DprPollingStatusClass {
1967
1967
 
1968
1968
  async removeItemFromList(executionId) {
1969
1969
  let response;
1970
- await fetch('/removeViewedItem/', {
1970
+ await fetch('/dpr/removeViewedItem/', {
1971
1971
  method: 'post',
1972
1972
  headers: {
1973
1973
  Accept: 'application/json',
@@ -249,7 +249,7 @@ class BookmarkToggle extends DprClientClass {
249
249
  }
250
250
 
251
251
  async toggleBookmark(type, id, reportId, reportType, csrfToken) {
252
- const endpoint = type === 'add' ? '/addBookmark/' : '/removeBookmark/';
252
+ const endpoint = type === 'add' ? '/dpr/addBookmark/' : '/dpr/removeBookmark/';
253
253
  await fetch(endpoint, {
254
254
  method: 'post',
255
255
  headers: {
@@ -1038,7 +1038,7 @@ class DprPollingStatusClass extends DprClientClass {
1038
1038
  }
1039
1039
 
1040
1040
  async getRequestStatus(metaData, csrfToken) {
1041
- return this.getStatus('/getStatus/', metaData, csrfToken)
1041
+ return this.getStatus('/dpr/getStatus/', metaData, csrfToken)
1042
1042
  }
1043
1043
 
1044
1044
  async getExpiredStatus(endpoint, metaData, csrfToken) {
@@ -1134,7 +1134,7 @@ class DprAsyncPolling extends DprPollingStatusClass {
1134
1134
  const csrfToken = this.cancelRequestButton.getAttribute('data-csrf-token');
1135
1135
 
1136
1136
  this.cancelRequestButton.addEventListener('click', async () => {
1137
- await fetch('/cancelRequest/', {
1137
+ await fetch('/dpr/cancelRequest/', {
1138
1138
  method: 'post',
1139
1139
  headers: {
1140
1140
  Accept: 'application/json',
@@ -1824,7 +1824,7 @@ class DprAsyncRequestList extends DprPollingStatusClass {
1824
1824
  await Promise.all(
1825
1825
  JSON.parse(this.requestData).map(async (metaData) => {
1826
1826
  if (!this.EXPIRED_END_STATUSES.includes(metaData.status)) {
1827
- const response = await this.getExpiredStatus('/getRequestedExpiredStatus/', metaData, this.csrfToken);
1827
+ const response = await this.getExpiredStatus('/dpr/getRequestedExpiredStatus/', metaData, this.csrfToken);
1828
1828
 
1829
1829
  if (response && response.isExpired) {
1830
1830
  clearInterval(this.expiredInterval);
@@ -1864,7 +1864,7 @@ class DprAsyncRequestList extends DprPollingStatusClass {
1864
1864
 
1865
1865
  async removeItemFromList(executionId) {
1866
1866
  let response;
1867
- await fetch('/removeRequestedItem/', {
1867
+ await fetch('/dpr/removeRequestedItem/', {
1868
1868
  method: 'post',
1869
1869
  headers: {
1870
1870
  Accept: 'application/json',
@@ -1918,7 +1918,7 @@ class DprRecentlyViewedList extends DprPollingStatusClass {
1918
1918
  await Promise.all(
1919
1919
  JSON.parse(this.viewedReportData).map(async (metaData) => {
1920
1920
  if (metaData.status !== 'EXPIRED') {
1921
- const response = await this.getExpiredStatus('/getExpiredStatus/', metaData, this.csrfToken);
1921
+ const response = await this.getExpiredStatus('/dpr/getExpiredStatus/', metaData, this.csrfToken);
1922
1922
  if (response && response.isExpired) {
1923
1923
  window.location.reload();
1924
1924
  clearInterval(this.expiredViewedInterval);
@@ -1940,7 +1940,7 @@ class DprRecentlyViewedList extends DprPollingStatusClass {
1940
1940
 
1941
1941
  async removeItemFromList(executionId) {
1942
1942
  let response;
1943
- await fetch('/removeViewedItem/', {
1943
+ await fetch('/dpr/removeViewedItem/', {
1944
1944
  method: 'post',
1945
1945
  headers: {
1946
1946
  Accept: 'application/json',
@@ -20,7 +20,7 @@
20
20
  } %}
21
21
 
22
22
  {% if not button.disabled %}
23
- <form id="download-report-form" action="/downloadReport/" method="post">
23
+ <form id="download-report-form" action="/dpr/downloadReport/" method="post">
24
24
  <input type="hidden" name="dataProductDefinitionsPath" value="{{ button.attributes.definitionPath }}">
25
25
  <input type="hidden" name="_csrf" value="{{ button.attributes.csrfToken }}">
26
26
  <input type="hidden" name="reportId" value="{{ button.attributes.reportId }}">
@@ -23,7 +23,7 @@
23
23
 
24
24
  <div class="dpr-download-feedback-form-wrapper" data-dpr-module="download-feedback-form">
25
25
 
26
- <form action="/submitFeedback/" method="post" id="download-feedback-form" class="download-feedback-form--hidden">
26
+ <form action="/dpr/submitFeedback/" method="post" id="download-feedback-form" class="download-feedback-form--hidden">
27
27
 
28
28
  <p>To enable downloads for this report (<strong>{{ reportName}} - {{ variantName }}</strong>), take a few moments to fill out this request form.</p><p>Once you have submitted the form you the download button will be enabled immediately.</p>
29
29
 
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.populateRequestedReports = exports.populateDefinitions = exports.setRoutePrefix = void 0;
7
+ const definitionUtils_1 = __importDefault(require("../utils/definitionUtils"));
8
+ const urlHelper_1 = require("../utils/urlHelper");
9
+ const getQueryParamAsString = (query, name) => (query[name] ? query[name].toString() : null);
10
+ const getDefinitionsPath = (query) => getQueryParamAsString(query, 'dataProductDefinitionsPath');
11
+ const deriveDefinitionsPath = (query) => {
12
+ const definitionsPath = getDefinitionsPath(query);
13
+ if (definitionsPath) {
14
+ return definitionsPath;
15
+ }
16
+ return null;
17
+ };
18
+ exports.default = (services, config) => {
19
+ return async (req, res, next) => {
20
+ try {
21
+ await (0, exports.populateDefinitions)(services, req, res, config);
22
+ await (0, exports.populateRequestedReports)(services, res);
23
+ (0, exports.setRoutePrefix)(res, config);
24
+ return next();
25
+ }
26
+ catch (error) {
27
+ return next(error);
28
+ }
29
+ };
30
+ };
31
+ const setRoutePrefix = async (res, config) => {
32
+ res.locals.routePrefix = (0, urlHelper_1.getRoutePrefix)(config);
33
+ };
34
+ exports.setRoutePrefix = setRoutePrefix;
35
+ const populateDefinitions = async (services, req, res, config) => {
36
+ // Get the DPD path from the query
37
+ const dpdPathFromQuery = deriveDefinitionsPath(req.query);
38
+ const dpdPathFromBody = req.body.dataProductDefinitionsPath;
39
+ const definitionsPathFromQuery = dpdPathFromQuery || dpdPathFromBody;
40
+ if (definitionsPathFromQuery) {
41
+ res.locals.dpdPathFromQuery = true;
42
+ }
43
+ // Get the DPD path from the config
44
+ const dpdPathFromConfig = config === null || config === void 0 ? void 0 : config.dataProductDefinitionsPath;
45
+ if (dpdPathFromConfig) {
46
+ res.locals.dpdPathFromConfig = true;
47
+ }
48
+ // query takes presedence over config
49
+ res.locals.definitionsPath = definitionsPathFromQuery || dpdPathFromConfig;
50
+ res.locals.pathSuffix = `?dataProductDefinitionsPath=${res.locals.definitionsPath}`;
51
+ if (res.locals.user.token && services.reportingService) {
52
+ res.locals.definitions = await services.reportingService.getDefinitions(res.locals.user.token, res.locals.definitionsPath);
53
+ }
54
+ };
55
+ exports.populateDefinitions = populateDefinitions;
56
+ const populateRequestedReports = async (services, res) => {
57
+ if (res.locals.user) {
58
+ const { uuid: userId } = res.locals.user;
59
+ const { definitions, definitionsPath } = res.locals;
60
+ const requested = await services.requestedReportService.getAllReports(userId);
61
+ res.locals.requestedReports = !definitionsPath
62
+ ? requested
63
+ : requested.filter((report) => {
64
+ return definitionUtils_1.default.getCurrentVariantDefinition(definitions, report.reportId, report.id);
65
+ });
66
+ const recent = await services.recentlyViewedService.getAllReports(userId);
67
+ res.locals.recentlyViewedReports = !definitionsPath
68
+ ? recent
69
+ : recent.filter((report) => {
70
+ return definitionUtils_1.default.getCurrentVariantDefinition(definitions, report.reportId, report.id);
71
+ });
72
+ if (services.bookmarkService) {
73
+ res.locals.bookmarkingEnabled = true;
74
+ const bookmarks = await services.bookmarkService.getAllBookmarks(userId);
75
+ res.locals.bookmarks = !definitionsPath
76
+ ? bookmarks
77
+ : bookmarks.filter((bookmark) => {
78
+ return definitionUtils_1.default.getCurrentVariantDefinition(definitions, bookmark.reportId, bookmark.id);
79
+ });
80
+ }
81
+ if (services.downloadPermissionService) {
82
+ res.locals.downloadingEnabled = true;
83
+ }
84
+ }
85
+ };
86
+ exports.populateRequestedReports = populateRequestedReports;
@@ -0,0 +1,102 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { RequestHandler, Response, Request } from 'express'
3
+ import type { ParsedQs } from 'qs'
4
+ import { Services } from '../types/Services'
5
+ import { RequestedReport, StoredReportData } from '../types/UserReports'
6
+ import DefinitionUtils from '../utils/definitionUtils'
7
+ import { BookmarkStoreData } from '../types/Bookmark'
8
+ import { getRoutePrefix } from '../utils/urlHelper'
9
+ import { DprConfig } from '../types/DprConfig'
10
+
11
+ const getQueryParamAsString = (query: ParsedQs, name: string) => (query[name] ? query[name].toString() : null)
12
+ const getDefinitionsPath = (query: ParsedQs) => getQueryParamAsString(query, 'dataProductDefinitionsPath')
13
+
14
+ const deriveDefinitionsPath = (query: ParsedQs): string | null => {
15
+ const definitionsPath = getDefinitionsPath(query)
16
+ if (definitionsPath) {
17
+ return definitionsPath
18
+ }
19
+
20
+ return null
21
+ }
22
+
23
+ export default (services: Services, config?: DprConfig): RequestHandler => {
24
+ return async (req, res, next) => {
25
+ try {
26
+ await populateDefinitions(services, req, res, config)
27
+ await populateRequestedReports(services, res)
28
+ setRoutePrefix(res, config)
29
+ return next()
30
+ } catch (error) {
31
+ return next(error)
32
+ }
33
+ }
34
+ }
35
+
36
+ export const setRoutePrefix = async (res: Response, config?: DprConfig) => {
37
+ res.locals.routePrefix = getRoutePrefix(config)
38
+ }
39
+
40
+ export const populateDefinitions = async (services: Services, req: Request, res: Response, config?: DprConfig) => {
41
+ // Get the DPD path from the query
42
+ const dpdPathFromQuery = deriveDefinitionsPath(req.query)
43
+ const dpdPathFromBody = req.body.dataProductDefinitionsPath
44
+ const definitionsPathFromQuery = dpdPathFromQuery || dpdPathFromBody
45
+
46
+ if (definitionsPathFromQuery) {
47
+ res.locals.dpdPathFromQuery = true
48
+ }
49
+
50
+ // Get the DPD path from the config
51
+ const dpdPathFromConfig = config?.dataProductDefinitionsPath
52
+ if (dpdPathFromConfig) {
53
+ res.locals.dpdPathFromConfig = true
54
+ }
55
+
56
+ // query takes presedence over config
57
+ res.locals.definitionsPath = definitionsPathFromQuery || dpdPathFromConfig
58
+ res.locals.pathSuffix = `?dataProductDefinitionsPath=${res.locals.definitionsPath}`
59
+
60
+ if (res.locals.user.token && services.reportingService) {
61
+ res.locals.definitions = await services.reportingService.getDefinitions(
62
+ res.locals.user.token,
63
+ res.locals.definitionsPath,
64
+ )
65
+ }
66
+ }
67
+
68
+ export const populateRequestedReports = async (services: Services, res: Response) => {
69
+ if (res.locals.user) {
70
+ const { uuid: userId } = res.locals.user
71
+ const { definitions, definitionsPath } = res.locals
72
+
73
+ const requested = await services.requestedReportService.getAllReports(userId)
74
+ res.locals.requestedReports = !definitionsPath
75
+ ? requested
76
+ : requested.filter((report: RequestedReport) => {
77
+ return DefinitionUtils.getCurrentVariantDefinition(definitions, report.reportId, report.id)
78
+ })
79
+
80
+ const recent = await services.recentlyViewedService.getAllReports(userId)
81
+ res.locals.recentlyViewedReports = !definitionsPath
82
+ ? recent
83
+ : recent.filter((report: StoredReportData) => {
84
+ return DefinitionUtils.getCurrentVariantDefinition(definitions, report.reportId, report.id)
85
+ })
86
+
87
+ if (services.bookmarkService) {
88
+ res.locals.bookmarkingEnabled = true
89
+
90
+ const bookmarks = await services.bookmarkService.getAllBookmarks(userId)
91
+ res.locals.bookmarks = !definitionsPath
92
+ ? bookmarks
93
+ : bookmarks.filter((bookmark: BookmarkStoreData) => {
94
+ return DefinitionUtils.getCurrentVariantDefinition(definitions, bookmark.reportId, bookmark.id)
95
+ })
96
+ }
97
+
98
+ if (services.downloadPermissionService) {
99
+ res.locals.downloadingEnabled = true
100
+ }
101
+ }
102
+ }
@@ -10,16 +10,21 @@ const download_1 = __importDefault(require("./download"));
10
10
  const recentlyViewed_1 = __importDefault(require("./recentlyViewed"));
11
11
  const syncReports_1 = __importDefault(require("./syncReports"));
12
12
  const logger_1 = __importDefault(require("../utils/logger"));
13
+ const urlHelper_1 = require("../utils/urlHelper");
13
14
  function routes(routeImportParams) {
14
15
  logger_1.default.info('Initialiasing DPR Embedded reports routes...');
15
- (0, asyncReports_1.default)(routeImportParams);
16
- (0, recentlyViewed_1.default)(routeImportParams);
17
- (0, syncReports_1.default)(routeImportParams);
16
+ const params = {
17
+ ...routeImportParams,
18
+ prefix: (0, urlHelper_1.getRoutePrefix)(routeImportParams === null || routeImportParams === void 0 ? void 0 : routeImportParams.config),
19
+ };
20
+ (0, asyncReports_1.default)(params);
21
+ (0, recentlyViewed_1.default)(params);
22
+ (0, syncReports_1.default)(params);
18
23
  const { bookmarkService, downloadPermissionService } = routeImportParams.services;
19
24
  if (bookmarkService) {
20
- (0, bookmarks_1.default)(routeImportParams);
25
+ (0, bookmarks_1.default)(params);
21
26
  }
22
27
  if (downloadPermissionService) {
23
- (0, download_1.default)(routeImportParams);
28
+ (0, download_1.default)(params);
24
29
  }
25
30
  }
@@ -7,21 +7,33 @@ import addSyncRoutes from './syncReports'
7
7
 
8
8
  import type { Services } from '../types/Services'
9
9
  import logger from '../utils/logger'
10
+ import { getRoutePrefix } from '../utils/urlHelper'
11
+ import { DprConfig } from '../types/DprConfig'
10
12
 
11
- export default function routes(routeImportParams: { router: Router; services: Services; layoutPath: string }) {
13
+ export default function routes(routeImportParams: {
14
+ router: Router
15
+ services: Services
16
+ layoutPath: string
17
+ config?: DprConfig
18
+ }) {
12
19
  logger.info('Initialiasing DPR Embedded reports routes...')
13
20
 
14
- addAsyncReportingRoutes(routeImportParams)
15
- addRecentlyViewedRoutes(routeImportParams)
16
- addSyncRoutes(routeImportParams)
21
+ const params = {
22
+ ...routeImportParams,
23
+ prefix: getRoutePrefix(routeImportParams?.config),
24
+ }
25
+
26
+ addAsyncReportingRoutes(params)
27
+ addRecentlyViewedRoutes(params)
28
+ addSyncRoutes(params)
17
29
 
18
30
  const { bookmarkService, downloadPermissionService } = routeImportParams.services
19
31
 
20
32
  if (bookmarkService) {
21
- addBookmarkingRoutes(routeImportParams)
33
+ addBookmarkingRoutes(params)
22
34
  }
23
35
 
24
36
  if (downloadPermissionService) {
25
- addDownloadRoutes(routeImportParams)
37
+ addDownloadRoutes(params)
26
38
  }
27
39
  }
@@ -14,7 +14,7 @@ const localsHelper_1 = __importDefault(require("../utils/localsHelper"));
14
14
  const utils_7 = __importDefault(require("../components/_async/async-report/utils"));
15
15
  const logger_1 = __importDefault(require("../utils/logger"));
16
16
  const UserReports_1 = require("../types/UserReports");
17
- function routes({ router, services, layoutPath, }) {
17
+ function routes({ router, services, layoutPath, prefix, }) {
18
18
  logger_1.default.info('Initialiasing routes: Async reports');
19
19
  /** * * * * * * * * * * * * * * *
20
20
  * *
@@ -90,7 +90,7 @@ function routes({ router, services, layoutPath, }) {
90
90
  });
91
91
  res.render(`dpr/views/async-request`, {
92
92
  layoutPath,
93
- postEndpoint: '/requestReport/',
93
+ postEndpoint: '/dpr/requestReport/',
94
94
  ...requestRenderData,
95
95
  });
96
96
  }
@@ -306,59 +306,21 @@ function routes({ router, services, layoutPath, }) {
306
306
  })),
307
307
  });
308
308
  };
309
- /**
310
- * NOTE:
311
- * - The async route paths have been made more generic with the introduction of `type`, to allow other report types (e.g dashboard) to follow the async path
312
- * - All requests will be made to the this new route.
313
- *
314
- * - Previously stored requested and viewed reports in Redis will have the old route path. Which is redirected to the new path.
315
- * - As requests expire after 24hrs, eventually the old route will dissapear from the requested and viewed store and only include the new route.
316
- * - At this point we can consider removing this route all together
317
- */
318
309
  // 1 - REQUEST
319
- router.get('/async/:type/:reportId/:id/request', isAuthorisedToViewReport, renderRequestHandler, asyncErrorHandler);
320
- router.post('/requestReport/', asyncRequestHandler, asyncErrorHandler);
310
+ router.get(`${prefix}/async/:type/:reportId/:id/request`, isAuthorisedToViewReport, renderRequestHandler, asyncErrorHandler);
311
+ router.post('/dpr/requestReport/', asyncRequestHandler, asyncErrorHandler);
321
312
  // 2 - POLLING
322
- router.get('/async/:type/:reportId/:id/request/:executionId', pollingHandler, asyncErrorHandler);
323
- router.post('/getStatus/', getStatusHandler);
324
- router.post('/cancelRequest/', cancelRequestHandler, asyncErrorHandler);
313
+ router.get(`${prefix}/async/:type/:reportId/:id/request/:executionId`, pollingHandler, asyncErrorHandler);
314
+ router.post('/dpr/getStatus/', getStatusHandler);
315
+ router.post('/dpr/cancelRequest/', cancelRequestHandler, asyncErrorHandler);
325
316
  // 3 - VIEw REPORT
326
317
  const viewReportPaths = [
327
- '/async/:type/:reportId/:id/request/:tableId/report',
328
- '/async/:type/:reportId/:id/request/:tableId/report/:download',
318
+ `${prefix}/async/:type/:reportId/:id/request/:tableId/report`,
319
+ `${prefix}/async/:type/:reportId/:id/request/:tableId/report/:download`,
329
320
  ];
330
321
  router.get(viewReportPaths, isAuthorisedToViewReport, viewReportHandler, asyncErrorHandler);
331
322
  // Homepage widget routes
332
- router.post('/removeRequestedItem/', removeRequestedItemHandler, asyncErrorHandler);
333
- router.post('/getRequestedExpiredStatus/', getExpiredStatus);
334
- router.get('/async-reports/requested', listingHandler);
335
- // REDIRECTS
336
- const setQueryParams = (req, url) => {
337
- const queryString = new URLSearchParams(req.query).toString();
338
- if (queryString.length) {
339
- return `${url}?${queryString}`;
340
- }
341
- return url;
342
- };
343
- // Request
344
- router.get('/async-reports/:reportId/:variantId/request', async (req, res, next) => {
345
- const { reportId, variantId: id } = req.params;
346
- let url = `/async/report/${reportId}/${id}/request`;
347
- url = setQueryParams(req, url);
348
- res.redirect(url);
349
- });
350
- // POLLING
351
- router.get('/async-reports/:reportId/:variantId/request/:executionId', async (req, res, next) => {
352
- const { reportId, variantId: id, executionId } = req.params;
353
- let url = `/async/report/${reportId}/${id}/request/${executionId}`;
354
- url = setQueryParams(req, url);
355
- res.redirect(url);
356
- });
357
- // REPORT
358
- router.get('/async-reports/:reportId/:variantId/request/:tableId/report', async (req, res, next) => {
359
- const { reportId, variantId: id, tableId } = req.params;
360
- let url = `/async/report/${reportId}/${id}/request/${tableId}/report`;
361
- url = setQueryParams(req, url);
362
- res.redirect(url);
363
- });
323
+ router.post('/dpr/removeRequestedItem/', removeRequestedItemHandler, asyncErrorHandler);
324
+ router.post('/dpr/getRequestedExpiredStatus/', getExpiredStatus);
325
+ router.get(`${prefix}/async-reports/requested`, listingHandler);
364
326
  }
@@ -1,4 +1,5 @@
1
- import type { RequestHandler, Router, Request } from 'express'
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import type { RequestHandler, Router } from 'express'
2
3
  import AsyncPollingUtils from '../components/_async/async-polling/utils'
3
4
  import AsyncRequestListUtils from '../components/user-reports/requested/utils'
4
5
  import UserReportsListUtils from '../components/user-reports/utils'
@@ -18,10 +19,12 @@ export default function routes({
18
19
  router,
19
20
  services,
20
21
  layoutPath,
22
+ prefix,
21
23
  }: {
22
24
  router: Router
23
25
  services: Services
24
26
  layoutPath: string
27
+ prefix: string
25
28
  }) {
26
29
  logger.info('Initialiasing routes: Async reports')
27
30
 
@@ -104,7 +107,7 @@ export default function routes({
104
107
 
105
108
  res.render(`dpr/views/async-request`, {
106
109
  layoutPath,
107
- postEndpoint: '/requestReport/',
110
+ postEndpoint: '/dpr/requestReport/',
108
111
  ...requestRenderData,
109
112
  })
110
113
  } catch (error) {
@@ -327,68 +330,29 @@ export default function routes({
327
330
  })
328
331
  }
329
332
 
330
- /**
331
- * NOTE:
332
- * - The async route paths have been made more generic with the introduction of `type`, to allow other report types (e.g dashboard) to follow the async path
333
- * - All requests will be made to the this new route.
334
- *
335
- * - Previously stored requested and viewed reports in Redis will have the old route path. Which is redirected to the new path.
336
- * - As requests expire after 24hrs, eventually the old route will dissapear from the requested and viewed store and only include the new route.
337
- * - At this point we can consider removing this route all together
338
- */
339
-
340
333
  // 1 - REQUEST
341
- router.get('/async/:type/:reportId/:id/request', isAuthorisedToViewReport, renderRequestHandler, asyncErrorHandler)
342
- router.post('/requestReport/', asyncRequestHandler, asyncErrorHandler)
334
+ router.get(
335
+ `${prefix}/async/:type/:reportId/:id/request`,
336
+ isAuthorisedToViewReport,
337
+ renderRequestHandler,
338
+ asyncErrorHandler,
339
+ )
340
+ router.post('/dpr/requestReport/', asyncRequestHandler, asyncErrorHandler)
343
341
 
344
342
  // 2 - POLLING
345
- router.get('/async/:type/:reportId/:id/request/:executionId', pollingHandler, asyncErrorHandler)
346
- router.post('/getStatus/', getStatusHandler)
347
- router.post('/cancelRequest/', cancelRequestHandler, asyncErrorHandler)
343
+ router.get(`${prefix}/async/:type/:reportId/:id/request/:executionId`, pollingHandler, asyncErrorHandler)
344
+ router.post('/dpr/getStatus/', getStatusHandler)
345
+ router.post('/dpr/cancelRequest/', cancelRequestHandler, asyncErrorHandler)
348
346
 
349
347
  // 3 - VIEw REPORT
350
348
  const viewReportPaths = [
351
- '/async/:type/:reportId/:id/request/:tableId/report',
352
- '/async/:type/:reportId/:id/request/:tableId/report/:download',
349
+ `${prefix}/async/:type/:reportId/:id/request/:tableId/report`,
350
+ `${prefix}/async/:type/:reportId/:id/request/:tableId/report/:download`,
353
351
  ]
354
352
  router.get(viewReportPaths, isAuthorisedToViewReport, viewReportHandler, asyncErrorHandler)
355
353
 
356
354
  // Homepage widget routes
357
- router.post('/removeRequestedItem/', removeRequestedItemHandler, asyncErrorHandler)
358
- router.post('/getRequestedExpiredStatus/', getExpiredStatus)
359
- router.get('/async-reports/requested', listingHandler)
360
-
361
- // REDIRECTS
362
-
363
- const setQueryParams = (req: Request, url: string) => {
364
- const queryString = new URLSearchParams(req.query as unknown as URLSearchParams).toString()
365
- if (queryString.length) {
366
- return `${url}?${queryString}`
367
- }
368
- return url
369
- }
370
-
371
- // Request
372
- router.get('/async-reports/:reportId/:variantId/request', async (req, res, next) => {
373
- const { reportId, variantId: id } = req.params
374
- let url = `/async/report/${reportId}/${id}/request`
375
- url = setQueryParams(req, url)
376
- res.redirect(url)
377
- })
378
-
379
- // POLLING
380
- router.get('/async-reports/:reportId/:variantId/request/:executionId', async (req, res, next) => {
381
- const { reportId, variantId: id, executionId } = req.params
382
- let url = `/async/report/${reportId}/${id}/request/${executionId}`
383
- url = setQueryParams(req, url)
384
- res.redirect(url)
385
- })
386
-
387
- // REPORT
388
- router.get('/async-reports/:reportId/:variantId/request/:tableId/report', async (req, res, next) => {
389
- const { reportId, variantId: id, tableId } = req.params
390
- let url = `/async/report/${reportId}/${id}/request/${tableId}/report`
391
- url = setQueryParams(req, url)
392
- res.redirect(url)
393
- })
355
+ router.post('/dpr/removeRequestedItem/', removeRequestedItemHandler, asyncErrorHandler)
356
+ router.post('/dpr/getRequestedExpiredStatus/', getExpiredStatus)
357
+ router.get(`${prefix}/async-reports/requested`, listingHandler)
394
358
  }
@@ -6,23 +6,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = routes;
7
7
  const utils_1 = __importDefault(require("../components/user-reports/bookmarks/utils"));
8
8
  const logger_1 = __importDefault(require("../utils/logger"));
9
- function routes({ router, services, layoutPath, templatePath = 'dpr/views/', }) {
9
+ function routes({ router, services, layoutPath, prefix, }) {
10
10
  logger_1.default.info('Initialiasing routes: Bookmarks');
11
- router.post('/addBookmark/', async (req, res) => {
11
+ router.post('/dpr/addBookmark/', async (req, res) => {
12
12
  var _a;
13
13
  const userId = ((_a = res.locals.user) === null || _a === void 0 ? void 0 : _a.uuid) ? res.locals.user.uuid : 'userId';
14
14
  const { reportId, id, reportType } = req.body;
15
15
  await services.bookmarkService.addBookmark(userId, reportId, id, reportType);
16
16
  res.end();
17
17
  });
18
- router.post('/removeBookmark/', async (req, res) => {
18
+ router.post('/dpr/removeBookmark/', async (req, res) => {
19
19
  var _a;
20
20
  const userId = ((_a = res.locals.user) === null || _a === void 0 ? void 0 : _a.uuid) ? res.locals.user.uuid : 'userId';
21
21
  await services.bookmarkService.removeBookmark(userId, req.body.id);
22
22
  res.end();
23
23
  });
24
- router.get('/async-reports/bookmarks', async (req, res) => {
25
- res.render(`${templatePath}/async-reports`, {
24
+ router.get(`${prefix}/async-reports/bookmarks`, async (req, res) => {
25
+ res.render(`dpr/views/async-reports`, {
26
26
  title: 'Requested Reports',
27
27
  layoutPath,
28
28
  ...(await utils_1.default.renderBookmarkList({ services, res, req })),