@ministryofjustice/hmpps-digital-prison-reporting-frontend 3.10.2 → 3.10.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 (32) hide show
  1. package/dpr/assets/js/all.mjs +3 -2
  2. package/dpr/components/async-filters/utils.js +15 -0
  3. package/dpr/components/async-filters/utils.ts +17 -0
  4. package/dpr/components/async-polling/utils.js +31 -35
  5. package/dpr/components/async-polling/utils.ts +38 -43
  6. package/dpr/components/async-report-list/utils.js +14 -24
  7. package/dpr/components/async-report-list/utils.ts +45 -54
  8. package/dpr/components/async-reports-list/utils/asyncReportsUtils.js +12 -4
  9. package/dpr/components/async-reports-list/utils/asyncReportsUtils.ts +17 -4
  10. package/dpr/components/async-reports-list/utils/index.js +3 -2
  11. package/dpr/components/async-reports-list/utils/index.ts +9 -2
  12. package/dpr/components/async-reports-list/utils/recentlyViewedUtils.js +11 -2
  13. package/dpr/components/async-reports-list/utils/recentlyViewedUtils.ts +14 -2
  14. package/dpr/components/async-reports-list/view.njk +4 -3
  15. package/dpr/components/content-slide/view.njk +9 -4
  16. package/dpr/components/filter-input/view.njk +12 -9
  17. package/dpr/components/pagination/utils.js +13 -10
  18. package/dpr/components/pagination/utils.ts +14 -11
  19. package/dpr/components/table-card-group/types.d.ts +6 -1
  20. package/dpr/components/table-card-group/view.njk +2 -2
  21. package/dpr/routes/asyncReports.js +88 -36
  22. package/dpr/routes/asyncReports.ts +92 -36
  23. package/dpr/views/async-error.njk +7 -3
  24. package/dpr/views/async-reports.njk +18 -0
  25. package/package.json +1 -1
  26. package/package.zip +0 -0
  27. package/dpr/components/table-card-group/utils/asyncReportsUtils.js +0 -134
  28. package/dpr/components/table-card-group/utils/asyncReportsUtils.ts +0 -147
  29. package/dpr/components/table-card-group/utils/index.js +0 -10
  30. package/dpr/components/table-card-group/utils/index.ts +0 -4
  31. package/dpr/components/table-card-group/utils/recentlyViewedUtils.js +0 -73
  32. package/dpr/components/table-card-group/utils/recentlyViewedUtils.ts +0 -121
@@ -937,7 +937,8 @@ class AsyncDataTable extends DprClientClass {
937
937
  const classificationContent = `<b>${classification}</b>`;
938
938
  const currentRangeStart = (selectedPage - 1) * pageSize;
939
939
  const currentRangeEnd = currentRangeStart + rowLength;
940
- const totalsContent = `${currentRangeStart + 1}-${currentRangeEnd} of ${totalRowCount}`;
940
+ const totalsContent =
941
+ totalRowCount > 0 ? `${currentRangeStart + 1}-${currentRangeEnd} of ${totalRowCount}` : `0-0 of 0`;
941
942
 
942
943
  // Headers
943
944
  const header = this.table.createTHead();
@@ -973,7 +974,7 @@ class dprAsyncPolling extends DprClientClass {
973
974
 
974
975
  async initialise () {
975
976
  this.POLLING_STATUSES = ['SUBMITTED', 'STARTED', 'PICKED'];
976
- this.POLLING_FREQUENCY = '2000'; // 2 seconds
977
+ this.POLLING_FREQUENCY = '500'; // 2 seconds
977
978
 
978
979
  this.statusSection = document.getElementById('async-request-polling-status');
979
980
  this.retryRequestButton = document.getElementById('retry-async-request');
@@ -136,4 +136,19 @@ exports.default = {
136
136
  }
137
137
  return redirect;
138
138
  },
139
+ handleError: (error, req) => {
140
+ const filters = Object.keys(req.body)
141
+ .filter((attr) => attr.includes('filters.'))
142
+ .filter((attr) => !!req.body[attr])
143
+ .map((attr) => {
144
+ return { name: attr, value: req.body[attr] };
145
+ });
146
+ return {
147
+ title: 'Request Failed',
148
+ description: 'Your report has failed to generate. The issue has been reported to admin staff',
149
+ retry: true,
150
+ error: error.data,
151
+ filters,
152
+ };
153
+ },
139
154
  };
@@ -1,3 +1,4 @@
1
+ import { Request } from 'express'
1
2
  import Dict = NodeJS.Dict
2
3
  import { components } from '../../types/api'
3
4
  import FilterUtils from '../filters/utils'
@@ -161,4 +162,20 @@ export default {
161
162
 
162
163
  return redirect
163
164
  },
165
+
166
+ handleError: (error: Dict<string>, req: Request) => {
167
+ const filters = Object.keys(req.body)
168
+ .filter((attr) => attr.includes('filters.'))
169
+ .filter((attr) => !!req.body[attr])
170
+ .map((attr) => {
171
+ return { name: attr, value: req.body[attr] }
172
+ })
173
+ return {
174
+ title: 'Request Failed',
175
+ description: 'Your report has failed to generate. The issue has been reported to admin staff',
176
+ retry: true,
177
+ error: error.data,
178
+ filters,
179
+ }
180
+ },
164
181
  }
@@ -17,6 +17,8 @@ const getStatus = async (token, reportId, variantId, executionId, currentStatus,
17
17
  errorMessage = data.userMessage;
18
18
  status = currentStatus === AsyncReport_1.RequestStatus.FINISHED ? AsyncReport_1.RequestStatus.EXPIRED : AsyncReport_1.RequestStatus.FAILED;
19
19
  }
20
+ if (typeof status === 'number')
21
+ status = AsyncReport_1.RequestStatus.FAILED;
20
22
  const res = {
21
23
  status,
22
24
  ...(errorMessage && { errorMessage }),
@@ -42,43 +44,37 @@ exports.default = {
42
44
  getStatus,
43
45
  renderPolling: async ({ req, res, dataSources, asyncReportsStore, next }) => {
44
46
  var _a;
45
- try {
46
- const { token } = res.locals.user || 'token';
47
- const { reportId, variantId, executionId } = req.params;
48
- let reportData = await asyncReportsStore.getReportByExecutionId(executionId);
49
- let statusResponse;
50
- if ((0, exports.timeoutRequest)(reportData.timestamp.requested)) {
51
- statusResponse = {
52
- status: AsyncReport_1.RequestStatus.FAILED,
53
- errorMessage: 'Request taking too long. Request Halted',
54
- };
55
- }
56
- else {
57
- statusResponse = await getStatus(token, reportId, variantId, executionId, reportData.status, dataSources, asyncReportsStore, reportData.dataProductDefinitionsPath);
58
- }
59
- const { status, errorMessage } = statusResponse;
60
- if (statusResponse.reportData)
61
- reportData = statusResponse.reportData;
62
- return {
63
- pollingRenderData: {
64
- reportName: reportData.reportName,
65
- variantName: reportData.name,
66
- variantDescription: reportData.description,
67
- executionId,
68
- reportId,
69
- variantId,
70
- status,
71
- tableId: reportData.tableId,
72
- querySummary: reportData.query.summary,
73
- ...(((_a = reportData.url.report) === null || _a === void 0 ? void 0 : _a.fullUrl) && { reportUrl: reportData.url.report.fullUrl }),
74
- ...(reportData.url.request.fullUrl && { requestUrl: reportData.url.request.fullUrl }),
75
- ...(errorMessage && { errorMessage }),
76
- },
47
+ const { token } = res.locals.user || 'token';
48
+ const { reportId, variantId, executionId } = req.params;
49
+ let reportData = await asyncReportsStore.getReportByExecutionId(executionId);
50
+ let statusResponse;
51
+ if ((0, exports.timeoutRequest)(reportData.timestamp.requested)) {
52
+ statusResponse = {
53
+ status: AsyncReport_1.RequestStatus.FAILED,
54
+ errorMessage: 'Request taking too long. Request Halted',
77
55
  };
78
56
  }
79
- catch (error) {
80
- next(error);
81
- return false;
57
+ else {
58
+ statusResponse = await getStatus(token, reportId, variantId, executionId, reportData.status, dataSources, asyncReportsStore, reportData.dataProductDefinitionsPath);
82
59
  }
60
+ const { status, errorMessage } = statusResponse;
61
+ if (statusResponse.reportData)
62
+ reportData = statusResponse.reportData;
63
+ return {
64
+ pollingRenderData: {
65
+ reportName: reportData.reportName,
66
+ variantName: reportData.name,
67
+ variantDescription: reportData.description,
68
+ executionId,
69
+ reportId,
70
+ variantId,
71
+ status,
72
+ tableId: reportData.tableId,
73
+ querySummary: reportData.query.summary,
74
+ ...(((_a = reportData.url.report) === null || _a === void 0 ? void 0 : _a.fullUrl) && { reportUrl: reportData.url.report.fullUrl }),
75
+ ...(reportData.url.request.fullUrl && { requestUrl: reportData.url.request.fullUrl }),
76
+ ...(errorMessage && { errorMessage }),
77
+ },
78
+ };
83
79
  },
84
80
  };
@@ -35,6 +35,7 @@ const getStatus = async (
35
35
  status = currentStatus === RequestStatus.FINISHED ? RequestStatus.EXPIRED : RequestStatus.FAILED
36
36
  }
37
37
 
38
+ if (typeof status === 'number') status = RequestStatus.FAILED
38
39
  const res: GetStatusUtilsResponse = {
39
40
  status,
40
41
  ...(errorMessage && { errorMessage }),
@@ -57,7 +58,6 @@ export const timeoutRequest = (requestTime: Date) => {
57
58
  const diffMins = Math.round(((diffMs % 86400000) % 3600000) / 60000)
58
59
  return diffMins >= TIMEOUT_MINS_MAX
59
60
  }
60
-
61
61
  interface GetStatusUtilsResponse {
62
62
  status: RequestStatus
63
63
  errorMessage: string
@@ -67,51 +67,46 @@ interface GetStatusUtilsResponse {
67
67
  export default {
68
68
  getStatus,
69
69
  renderPolling: async ({ req, res, dataSources, asyncReportsStore, next }: AsyncReportUtilsParams) => {
70
- try {
71
- const { token } = res.locals.user || 'token'
72
- const { reportId, variantId, executionId } = req.params
73
- let reportData = await asyncReportsStore.getReportByExecutionId(executionId)
70
+ const { token } = res.locals.user || 'token'
71
+ const { reportId, variantId, executionId } = req.params
72
+ let reportData = await asyncReportsStore.getReportByExecutionId(executionId)
74
73
 
75
- let statusResponse
76
- if (timeoutRequest(reportData.timestamp.requested)) {
77
- statusResponse = {
78
- status: RequestStatus.FAILED,
79
- errorMessage: 'Request taking too long. Request Halted',
80
- }
81
- } else {
82
- statusResponse = await getStatus(
83
- token,
84
- reportId,
85
- variantId,
86
- executionId,
87
- reportData.status,
88
- dataSources,
89
- asyncReportsStore,
90
- reportData.dataProductDefinitionsPath,
91
- )
74
+ let statusResponse
75
+ if (timeoutRequest(reportData.timestamp.requested)) {
76
+ statusResponse = {
77
+ status: RequestStatus.FAILED,
78
+ errorMessage: 'Request taking too long. Request Halted',
92
79
  }
93
- const { status, errorMessage } = statusResponse
94
- if (statusResponse.reportData) reportData = statusResponse.reportData
80
+ } else {
81
+ statusResponse = await getStatus(
82
+ token,
83
+ reportId,
84
+ variantId,
85
+ executionId,
86
+ reportData.status,
87
+ dataSources,
88
+ asyncReportsStore,
89
+ reportData.dataProductDefinitionsPath,
90
+ )
91
+ }
92
+ const { status, errorMessage } = statusResponse
93
+ if (statusResponse.reportData) reportData = statusResponse.reportData
95
94
 
96
- return {
97
- pollingRenderData: {
98
- reportName: reportData.reportName,
99
- variantName: reportData.name,
100
- variantDescription: reportData.description,
101
- executionId,
102
- reportId,
103
- variantId,
104
- status,
105
- tableId: reportData.tableId,
106
- querySummary: reportData.query.summary,
107
- ...(reportData.url.report?.fullUrl && { reportUrl: reportData.url.report.fullUrl }),
108
- ...(reportData.url.request.fullUrl && { requestUrl: reportData.url.request.fullUrl }),
109
- ...(errorMessage && { errorMessage }),
110
- },
111
- }
112
- } catch (error) {
113
- next(error)
114
- return false
95
+ return {
96
+ pollingRenderData: {
97
+ reportName: reportData.reportName,
98
+ variantName: reportData.name,
99
+ variantDescription: reportData.description,
100
+ executionId,
101
+ reportId,
102
+ variantId,
103
+ status,
104
+ tableId: reportData.tableId,
105
+ querySummary: reportData.query.summary,
106
+ ...(reportData.url.report?.fullUrl && { reportUrl: reportData.url.report.fullUrl }),
107
+ ...(reportData.url.request.fullUrl && { requestUrl: reportData.url.request.fullUrl }),
108
+ ...(errorMessage && { errorMessage }),
109
+ },
115
110
  }
116
111
  },
117
112
  }
@@ -11,25 +11,19 @@ const utils_2 = __importDefault(require("../async-columns/utils"));
11
11
  const utils_3 = __importDefault(require("../pagination/utils"));
12
12
  const utils_4 = __importDefault(require("../icon-button-list/utils"));
13
13
  const initDataSources = ({ req, res, next, asyncReportsStore, dataSources }) => {
14
- try {
15
- const { token } = res.locals.user || 'token';
16
- const { reportId, reportVariantId, tableId } = req.params;
17
- const { selectedPage = 1, pageSize = 10 } = req.query;
18
- const dataProductDefinitionsPath = req.query.dataProductDefinitionsPath;
19
- const reportDefinitionPromise = dataSources.getDefinition(token, reportId, reportVariantId, dataProductDefinitionsPath);
20
- const reportDataPromise = dataSources.getAsyncReport(token, reportId, reportVariantId, tableId, {
21
- selectedPage: +selectedPage,
22
- pageSize: +pageSize,
23
- dataProductDefinitionsPath,
24
- });
25
- const reportDataCountPromise = dataSources.getAsyncCount(token, tableId);
26
- const stateDataPromise = asyncReportsStore.getReportByTableId(tableId);
27
- return [reportDefinitionPromise, reportDataPromise, reportDataCountPromise, stateDataPromise];
28
- }
29
- catch (error) {
30
- next(error);
31
- return false;
32
- }
14
+ const { token } = res.locals.user || 'token';
15
+ const { reportId, reportVariantId, tableId } = req.params;
16
+ const { selectedPage = 1, pageSize = 10 } = req.query;
17
+ const dataProductDefinitionsPath = req.query.dataProductDefinitionsPath;
18
+ const reportDefinitionPromise = dataSources.getDefinition(token, reportId, reportVariantId, dataProductDefinitionsPath);
19
+ const reportDataPromise = dataSources.getAsyncReport(token, reportId, reportVariantId, tableId, {
20
+ selectedPage: +selectedPage,
21
+ pageSize: +pageSize,
22
+ dataProductDefinitionsPath,
23
+ });
24
+ const reportDataCountPromise = dataSources.getAsyncCount(token, tableId);
25
+ const stateDataPromise = asyncReportsStore.getReportByTableId(tableId);
26
+ return [reportDefinitionPromise, reportDataPromise, reportDataCountPromise, stateDataPromise];
33
27
  };
34
28
  exports.initDataSources = initDataSources;
35
29
  const renderReport = async ({ req, res, next, asyncReportsStore, recentlyViewedStoreService, dataSources, }) => {
@@ -38,8 +32,7 @@ const renderReport = async ({ req, res, next, asyncReportsStore, recentlyViewedS
38
32
  let renderData = {};
39
33
  let reportStateData;
40
34
  if (dataPromises) {
41
- await Promise.all(dataPromises)
42
- .then((resolvedData) => {
35
+ await Promise.all(dataPromises).then((resolvedData) => {
43
36
  const definition = resolvedData[0];
44
37
  const reportData = resolvedData[1];
45
38
  const count = resolvedData[2];
@@ -65,9 +58,6 @@ const renderReport = async ({ req, res, next, asyncReportsStore, recentlyViewedS
65
58
  appliedFilters: query.summary,
66
59
  classification,
67
60
  };
68
- })
69
- .catch((err) => {
70
- next(err);
71
61
  });
72
62
  }
73
63
  if (Object.keys(renderData).length && Object.keys(reportStateData).length) {
@@ -11,30 +11,25 @@ import { AsyncReportUtilsParams } from '../../types/AsyncReportUtils'
11
11
  import { AsyncReportData } from '../../types/AsyncReport'
12
12
 
13
13
  export const initDataSources = ({ req, res, next, asyncReportsStore, dataSources }: AsyncReportUtilsParams) => {
14
- try {
15
- const { token } = res.locals.user || 'token'
16
- const { reportId, reportVariantId, tableId } = req.params
17
- const { selectedPage = 1, pageSize = 10 } = req.query
18
- const dataProductDefinitionsPath = <string>req.query.dataProductDefinitionsPath
19
- const reportDefinitionPromise = dataSources.getDefinition(
20
- token,
21
- reportId,
22
- reportVariantId,
23
- dataProductDefinitionsPath,
24
- )
25
- const reportDataPromise = dataSources.getAsyncReport(token, reportId, reportVariantId, tableId, {
26
- selectedPage: +selectedPage,
27
- pageSize: +pageSize,
28
- dataProductDefinitionsPath,
29
- })
30
- const reportDataCountPromise = dataSources.getAsyncCount(token, tableId)
31
- const stateDataPromise = asyncReportsStore.getReportByTableId(tableId)
14
+ const { token } = res.locals.user || 'token'
15
+ const { reportId, reportVariantId, tableId } = req.params
16
+ const { selectedPage = 1, pageSize = 10 } = req.query
17
+ const dataProductDefinitionsPath = <string>req.query.dataProductDefinitionsPath
18
+ const reportDefinitionPromise = dataSources.getDefinition(
19
+ token,
20
+ reportId,
21
+ reportVariantId,
22
+ dataProductDefinitionsPath,
23
+ )
24
+ const reportDataPromise = dataSources.getAsyncReport(token, reportId, reportVariantId, tableId, {
25
+ selectedPage: +selectedPage,
26
+ pageSize: +pageSize,
27
+ dataProductDefinitionsPath,
28
+ })
29
+ const reportDataCountPromise = dataSources.getAsyncCount(token, tableId)
30
+ const stateDataPromise = asyncReportsStore.getReportByTableId(tableId)
32
31
 
33
- return [reportDefinitionPromise, reportDataPromise, reportDataCountPromise, stateDataPromise]
34
- } catch (error) {
35
- next(error)
36
- return false
37
- }
32
+ return [reportDefinitionPromise, reportDataPromise, reportDataCountPromise, stateDataPromise]
38
33
  }
39
34
 
40
35
  export const renderReport = async ({
@@ -52,40 +47,36 @@ export const renderReport = async ({
52
47
  let renderData = {}
53
48
  let reportStateData: AsyncReportData
54
49
  if (dataPromises) {
55
- await Promise.all(dataPromises)
56
- .then((resolvedData) => {
57
- const definition = resolvedData[0] as unknown as components['schemas']['SingleVariantReportDefinition']
58
- const reportData = <Array<Dict<string>>>resolvedData[1]
59
- const count = <number>resolvedData[2]
60
- reportStateData = <AsyncReportData>resolvedData[3]
50
+ await Promise.all(dataPromises).then((resolvedData) => {
51
+ const definition = resolvedData[0] as unknown as components['schemas']['SingleVariantReportDefinition']
52
+ const reportData = <Array<Dict<string>>>resolvedData[1]
53
+ const count = <number>resolvedData[2]
54
+ reportStateData = <AsyncReportData>resolvedData[3]
61
55
 
62
- const fieldDefinition = definition.variant.specification.fields
63
- const { classification } = definition.variant
56
+ const fieldDefinition = definition.variant.specification.fields
57
+ const { classification } = definition.variant
64
58
 
65
- const columns = ColumnUtils.getColumns(fieldDefinition, <string[]>reqColumns)
66
- const url = parseUrl(req)
67
- const pagination = PaginationUtils.getPaginationData(url, count)
68
- const actions = ReportActionsUtils.initReportActions(definition.variant, reportStateData)
69
- const rows = DataTableUtils.mapData(reportData, fieldDefinition, columns.value)
70
- const head = DataTableUtils.mapAsyncHeader(fieldDefinition, columns.value)
71
- const { reportName, name: variantName, query, description } = reportStateData
59
+ const columns = ColumnUtils.getColumns(fieldDefinition, <string[]>reqColumns)
60
+ const url = parseUrl(req)
61
+ const pagination = PaginationUtils.getPaginationData(url, count)
62
+ const actions = ReportActionsUtils.initReportActions(definition.variant, reportStateData)
63
+ const rows = DataTableUtils.mapData(reportData, fieldDefinition, columns.value)
64
+ const head = DataTableUtils.mapAsyncHeader(fieldDefinition, columns.value)
65
+ const { reportName, name: variantName, query, description } = reportStateData
72
66
 
73
- renderData = {
74
- variantName,
75
- reportName,
76
- description,
77
- rows,
78
- head,
79
- columns,
80
- pagination,
81
- actions,
82
- appliedFilters: query.summary,
83
- classification,
84
- }
85
- })
86
- .catch((err) => {
87
- next(err)
88
- })
67
+ renderData = {
68
+ variantName,
69
+ reportName,
70
+ description,
71
+ rows,
72
+ head,
73
+ columns,
74
+ pagination,
75
+ actions,
76
+ appliedFilters: query.summary,
77
+ classification,
78
+ }
79
+ })
89
80
  }
90
81
 
91
82
  if (Object.keys(renderData).length && Object.keys(reportStateData).length) {
@@ -61,8 +61,7 @@ const setDataFromStatus = (status, requestedReportsData) => {
61
61
  let href;
62
62
  switch (status) {
63
63
  case AsyncReport_1.RequestStatus.FAILED: {
64
- const retryParam = `&retryId=${requestedReportsData.executionId}`;
65
- href = `${requestedReportsData.url.request.fullUrl}${retryParam}`;
64
+ href = `${requestedReportsData.url.polling.fullUrl}`;
66
65
  timestamp = `Failed at: ${new Date(requestedReportsData.timestamp.failed).toLocaleString()}`;
67
66
  break;
68
67
  }
@@ -135,19 +134,28 @@ const formatTable = (cardData) => {
135
134
  };
136
135
  };
137
136
  exports.default = {
138
- renderAsyncReportsList: async ({ asyncReportsStore, dataSources, res, }) => {
137
+ renderAsyncReportsList: async ({ asyncReportsStore, dataSources, res, maxRows, }) => {
139
138
  const { token } = res.locals.user || 'token';
140
- const cardData = await formatCards(asyncReportsStore, dataSources, token);
139
+ let cardData = await formatCards(asyncReportsStore, dataSources, token);
141
140
  const head = {
142
141
  title: 'Requested Reports',
143
142
  icon: 'hourglass',
144
143
  id: 'requested-reports',
144
+ ...(cardData.length && { href: './async-reports/requested' }),
145
145
  ...(!cardData.length && { emptyMessage: 'You have 0 requested reports' }),
146
146
  };
147
+ const total = {
148
+ amount: cardData.length,
149
+ shown: cardData.length > maxRows ? maxRows : cardData.length,
150
+ max: maxRows,
151
+ };
152
+ if (maxRows)
153
+ cardData = cardData.slice(0, maxRows);
147
154
  return {
148
155
  head,
149
156
  cardData,
150
157
  tableData: formatTable(cardData),
158
+ total,
151
159
  };
152
160
  },
153
161
  };
@@ -58,8 +58,7 @@ const setDataFromStatus = (status: RequestStatus, requestedReportsData: AsyncRep
58
58
  let href
59
59
  switch (status) {
60
60
  case RequestStatus.FAILED: {
61
- const retryParam = `&retryId=${requestedReportsData.executionId}`
62
- href = `${requestedReportsData.url.request.fullUrl}${retryParam}`
61
+ href = `${requestedReportsData.url.polling.fullUrl}`
63
62
  timestamp = `Failed at: ${new Date(requestedReportsData.timestamp.failed).toLocaleString()}`
64
63
  break
65
64
  }
@@ -149,19 +148,33 @@ export default {
149
148
  asyncReportsStore,
150
149
  dataSources,
151
150
  res,
152
- }: AsyncReportUtilsParams): Promise<RenderTableListResponse> => {
151
+ maxRows,
152
+ }: { maxRows?: number } & AsyncReportUtilsParams): Promise<RenderTableListResponse> => {
153
153
  const { token } = res.locals.user || 'token'
154
- const cardData = await formatCards(asyncReportsStore, dataSources, token)
154
+
155
+ let cardData = await formatCards(asyncReportsStore, dataSources, token)
156
+
155
157
  const head = {
156
158
  title: 'Requested Reports',
157
159
  icon: 'hourglass',
158
160
  id: 'requested-reports',
161
+ ...(cardData.length && { href: './async-reports/requested' }),
159
162
  ...(!cardData.length && { emptyMessage: 'You have 0 requested reports' }),
160
163
  }
164
+
165
+ const total = {
166
+ amount: cardData.length,
167
+ shown: cardData.length > maxRows ? maxRows : cardData.length,
168
+ max: maxRows,
169
+ }
170
+
171
+ if (maxRows) cardData = cardData.slice(0, maxRows)
172
+
161
173
  return {
162
174
  head,
163
175
  cardData,
164
176
  tableData: formatTable(cardData),
177
+ total,
165
178
  }
166
179
  },
167
180
  }
@@ -9,10 +9,10 @@ exports.AsyncCardGroupUtils = asyncReportsUtils_1.default;
9
9
  const recentlyViewedUtils_1 = __importDefault(require("./recentlyViewedUtils"));
10
10
  exports.RecentlyViewedCardGroupUtils = recentlyViewedUtils_1.default;
11
11
  exports.default = {
12
- renderList: async ({ asyncReportsStore, recentlyViewedStoreService, dataSources, res }) => {
12
+ renderList: async ({ asyncReportsStore, recentlyViewedStoreService, dataSources, res, maxRows = 6, }) => {
13
13
  return {
14
14
  requestedReports: {
15
- ...(await asyncReportsUtils_1.default.renderAsyncReportsList({ asyncReportsStore, dataSources, res })),
15
+ ...(await asyncReportsUtils_1.default.renderAsyncReportsList({ asyncReportsStore, dataSources, res, maxRows })),
16
16
  },
17
17
  viewedReports: {
18
18
  ...(await recentlyViewedUtils_1.default.renderRecentlyViewedList({
@@ -20,6 +20,7 @@ exports.default = {
20
20
  asyncReportsStore,
21
21
  dataSources,
22
22
  res,
23
+ maxRows,
23
24
  })),
24
25
  },
25
26
  };
@@ -5,10 +5,16 @@ import RecentlyViewedCardGroupUtils from './recentlyViewedUtils'
5
5
  export { AsyncCardGroupUtils, RecentlyViewedCardGroupUtils }
6
6
 
7
7
  export default {
8
- renderList: async ({ asyncReportsStore, recentlyViewedStoreService, dataSources, res }: AsyncReportUtilsParams) => {
8
+ renderList: async ({
9
+ asyncReportsStore,
10
+ recentlyViewedStoreService,
11
+ dataSources,
12
+ res,
13
+ maxRows = 6,
14
+ }: { maxRows: number } & AsyncReportUtilsParams) => {
9
15
  return {
10
16
  requestedReports: {
11
- ...(await AsyncCardGroupUtils.renderAsyncReportsList({ asyncReportsStore, dataSources, res })),
17
+ ...(await AsyncCardGroupUtils.renderAsyncReportsList({ asyncReportsStore, dataSources, res, maxRows })),
12
18
  },
13
19
  viewedReports: {
14
20
  ...(await RecentlyViewedCardGroupUtils.renderRecentlyViewedList({
@@ -16,6 +22,7 @@ export default {
16
22
  asyncReportsStore,
17
23
  dataSources,
18
24
  res,
25
+ maxRows,
19
26
  })),
20
27
  },
21
28
  }
@@ -56,18 +56,27 @@ const formatTableData = (card) => {
56
56
  ];
57
57
  };
58
58
  exports.default = {
59
- renderRecentlyViewedList: async ({ recentlyViewedStoreService, asyncReportsStore, dataSources, res, }) => {
59
+ renderRecentlyViewedList: async ({ recentlyViewedStoreService, asyncReportsStore, dataSources, res, maxRows, }) => {
60
60
  const { token } = res.locals.user || 'token';
61
- const cardData = await formatCards(recentlyViewedStoreService, asyncReportsStore, dataSources, token);
61
+ let cardData = await formatCards(recentlyViewedStoreService, asyncReportsStore, dataSources, token);
62
+ const total = {
63
+ amount: cardData.length,
64
+ shown: cardData.length > maxRows ? maxRows : cardData.length,
65
+ max: maxRows,
66
+ };
67
+ if (maxRows)
68
+ cardData = cardData.slice(0, maxRows);
62
69
  return {
63
70
  head: {
64
71
  title: 'Recently Viewed',
65
72
  icon: 'viewed',
66
73
  id: 'recently-viewed',
74
+ ...(cardData.length && { href: '/async-reports/recently-viewed' }),
67
75
  ...(!cardData.length && { emptyMessage: 'You have 0 recently viewed reports' }),
68
76
  },
69
77
  cardData,
70
78
  tableData: formatTable(cardData),
79
+ total,
71
80
  };
72
81
  },
73
82
  };
@@ -104,18 +104,30 @@ export default {
104
104
  asyncReportsStore,
105
105
  dataSources,
106
106
  res,
107
- }: AsyncReportUtilsParams): Promise<RenderTableListResponse> => {
107
+ maxRows,
108
+ }: { maxRows?: number } & AsyncReportUtilsParams): Promise<RenderTableListResponse> => {
108
109
  const { token } = res.locals.user || 'token'
109
- const cardData = await formatCards(recentlyViewedStoreService, asyncReportsStore, dataSources, token)
110
+ let cardData = await formatCards(recentlyViewedStoreService, asyncReportsStore, dataSources, token)
111
+
112
+ const total = {
113
+ amount: cardData.length,
114
+ shown: cardData.length > maxRows ? maxRows : cardData.length,
115
+ max: maxRows,
116
+ }
117
+
118
+ if (maxRows) cardData = cardData.slice(0, maxRows)
119
+
110
120
  return {
111
121
  head: {
112
122
  title: 'Recently Viewed',
113
123
  icon: 'viewed',
114
124
  id: 'recently-viewed',
125
+ ...(cardData.length && { href: '/async-reports/recently-viewed' }),
115
126
  ...(!cardData.length && { emptyMessage: 'You have 0 recently viewed reports' }),
116
127
  },
117
128
  cardData,
118
129
  tableData: formatTable(cardData),
130
+ total,
119
131
  }
120
132
  },
121
133
  }
@@ -1,17 +1,18 @@
1
1
  {% from "../table-card-group/view.njk" import dprTableCardGroup %}
2
2
 
3
3
  {% macro dprAsyncReportsList(requestedReports, viewedReports) %}
4
-
5
4
  {{ dprTableCardGroup(
6
5
  requestedReports.head,
7
6
  requestedReports.cardData,
8
- requestedReports.tableData
7
+ requestedReports.tableData,
8
+ requestedReports.total
9
9
  )}}
10
10
 
11
11
  {{ dprTableCardGroup(
12
12
  viewedReports.head,
13
13
  viewedReports.cardData,
14
- viewedReports.tableData
14
+ viewedReports.tableData,
15
+ viewedReports.total
15
16
  ) }}
16
17
 
17
18
  {% endmacro %}