@ministryofjustice/hmpps-digital-prison-reporting-frontend 3.23.0 → 3.23.2

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.
@@ -752,8 +752,8 @@ class DprPollingStatusClass extends DprClientClass {
752
752
  return this.getStatus('/getStatus/', metaData, csrfToken)
753
753
  }
754
754
 
755
- async getExpiredStatus(metaData, csrfToken) {
756
- return this.getStatus('/getExpiredStatus/', metaData, csrfToken)
755
+ async getExpiredStatus(endpoint, metaData, csrfToken) {
756
+ return this.getStatus(endpoint, metaData, csrfToken)
757
757
  }
758
758
 
759
759
  async getStatus(endpoint, body, csrfToken) {
@@ -922,7 +922,8 @@ class BookmarkToggle extends DprClientClass {
922
922
  }
923
923
 
924
924
  initToggles() {
925
- document.querySelectorAll('.bookmark-input[type=checkbox]').forEach((bookmarkToggle) => {
925
+ const element = this.getElement();
926
+ element.querySelectorAll('.bookmark-input[type=checkbox]').forEach((bookmarkToggle) => {
926
927
  const csrfToken = bookmarkToggle.getAttribute('data-csrf-token');
927
928
  const reportId = bookmarkToggle.getAttribute('data-report-id');
928
929
  const variantId = bookmarkToggle.getAttribute('data-variant-id');
@@ -1092,7 +1093,7 @@ class DprAsyncRequestList extends DprPollingStatusClass {
1092
1093
  await Promise.all(
1093
1094
  meta.map(async (metaData) => {
1094
1095
  if (metaData.status !== 'EXPIRED') {
1095
- const response = await this.getExpiredStatus(metaData, this.csrfToken);
1096
+ const response = await this.getExpiredStatus('/getRequestedExpiredStatus/', metaData, this.csrfToken);
1096
1097
  if (response.isExpired) {
1097
1098
  window.location.reload();
1098
1099
  }
@@ -1100,7 +1101,7 @@ class DprAsyncRequestList extends DprPollingStatusClass {
1100
1101
  }),
1101
1102
  );
1102
1103
  }
1103
- }, 60000); // 1 minute
1104
+ }, '60000'); // 1 minute
1104
1105
  }
1105
1106
 
1106
1107
  initStatusPollingStatus() {
@@ -1127,7 +1128,8 @@ class DprAsyncRequestList extends DprPollingStatusClass {
1127
1128
  initItemActions() {
1128
1129
  this.removeActions.forEach((button) => {
1129
1130
  const id = button.getAttribute('data-execution-id');
1130
- button.addEventListener('click', async () => {
1131
+ button.addEventListener('click', async (e) => {
1132
+ e.preventDefault();
1131
1133
  await this.removeItemFromList(id);
1132
1134
  });
1133
1135
  });
@@ -1182,7 +1184,7 @@ class DprRecentlyViewedList extends DprPollingStatusClass {
1182
1184
  await Promise.all(
1183
1185
  meta.map(async (metaData) => {
1184
1186
  if (metaData.status !== 'EXPIRED') {
1185
- const response = await this.getExpiredStatus(metaData, this.csrfToken);
1187
+ const response = await this.getExpiredStatus('/getExpiredStatus/', metaData, this.csrfToken);
1186
1188
  if (response.isExpired) {
1187
1189
  window.location.reload();
1188
1190
  }
@@ -1196,7 +1198,8 @@ class DprRecentlyViewedList extends DprPollingStatusClass {
1196
1198
  initItemActions() {
1197
1199
  this.removeActions.forEach((button) => {
1198
1200
  const id = button.getAttribute('data-execution-id');
1199
- button.addEventListener('click', async () => {
1201
+ button.addEventListener('click', async (e) => {
1202
+ e.preventDefault();
1200
1203
  await this.removeItemFromList(id);
1201
1204
  });
1202
1205
  });
@@ -105,6 +105,13 @@ exports.default = {
105
105
  }
106
106
  return response;
107
107
  },
108
+ getExpiredStatus: async ({ req, res, services }) => {
109
+ const report = await (0, reportStatusHelper_1.getExpiredStatus)({ req, res, services });
110
+ if (report.isExpired) {
111
+ await services.asyncReportsStore.setToExpired(report.executionId);
112
+ }
113
+ return report.isExpired;
114
+ },
108
115
  renderList: async ({ services, res, maxRows, }) => {
109
116
  const csrfToken = res.locals.csrfToken || 'csrfToken';
110
117
  const requestedReportsData = await services.asyncReportsStore.getAllReports();
@@ -1,7 +1,7 @@
1
1
  import { CardData, RenderTableListResponse } from '../table-card-group/types'
2
2
  import { AsyncReportUtilsParams } from '../../types/AsyncReportUtils'
3
3
  import { AsyncReportData, RequestStatus } from '../../types/AsyncReport'
4
- import { getStatus } from '../../utils/reportStatusHelper'
4
+ import { getStatus, getExpiredStatus } from '../../utils/reportStatusHelper'
5
5
  import * as ReportListHelper from '../../utils/reportsListHelper'
6
6
 
7
7
  export const formatCardData = (requestedReportsData: AsyncReportData): CardData => {
@@ -101,6 +101,14 @@ export default {
101
101
  return response
102
102
  },
103
103
 
104
+ getExpiredStatus: async ({ req, res, services }: AsyncReportUtilsParams) => {
105
+ const report = await getExpiredStatus({ req, res, services })
106
+ if (report.isExpired) {
107
+ await services.asyncReportsStore.setToExpired(report.executionId)
108
+ }
109
+ return report.isExpired
110
+ },
111
+
104
112
  renderList: async ({
105
113
  services,
106
114
  res,
@@ -4,14 +4,12 @@
4
4
  {% macro dprReportsList(head, rows, id = 'reports-search') %}
5
5
 
6
6
  {% set tableHtml %}
7
- <div data-dpr-module="bookmark-toggle">
8
7
  {{ govukTable({
9
8
  captionClasses: "govuk-table__caption--m",
10
9
  head: head,
11
10
  rows: rows,
12
11
  classes: "dpr-search-table"
13
12
  }) }}
14
- </div>
15
13
  {% endset %}
16
14
 
17
15
  {{ dprSearch(id, tableHtml) }}
@@ -131,6 +131,15 @@ function routes({ router, services, layoutPath, templatePath = 'dpr/views/', })
131
131
  res.send({ status: 'FAILED' });
132
132
  }
133
133
  };
134
+ const getExpiredStatus = async (req, res, next) => {
135
+ try {
136
+ const response = await utils_3.default.getExpiredStatus({ req, res, services });
137
+ res.send({ isExpired: response });
138
+ }
139
+ catch (error) {
140
+ res.send({ status: 'FAILED' });
141
+ }
142
+ };
134
143
  const pollingHandler = async (req, res, next) => {
135
144
  try {
136
145
  const pollingRenderData = await utils_2.default.renderPolling({
@@ -177,6 +186,7 @@ function routes({ router, services, layoutPath, templatePath = 'dpr/views/', })
177
186
  router.post('/cancelRequest/', cancelRequestHandler, asyncErrorHandler);
178
187
  router.post('/removeRequestedItem/', removeRequestedItemHandler, asyncErrorHandler);
179
188
  router.post('/getStatus/', getStatusHandler);
189
+ router.post('/getRequestedExpiredStatus/', getExpiredStatus);
180
190
  router.get('/async-reports/:reportId/:variantId/request/:executionId', pollingHandler, asyncErrorHandler);
181
191
  router.get('/async-reports/:reportId/:variantId/request/:tableId/report', getReportHandler, asyncErrorHandler);
182
192
  router.get('/async-reports/requested', async (req, res) => {
@@ -119,6 +119,15 @@ export default function routes({
119
119
  }
120
120
  }
121
121
 
122
+ const getExpiredStatus: RequestHandler = async (req, res, next) => {
123
+ try {
124
+ const response = await AsyncRequestListUtils.getExpiredStatus({ req, res, services })
125
+ res.send({ isExpired: response })
126
+ } catch (error) {
127
+ res.send({ status: 'FAILED' })
128
+ }
129
+ }
130
+
122
131
  const pollingHandler: RequestHandler = async (req, res, next) => {
123
132
  try {
124
133
  const pollingRenderData = await AsyncPollingUtils.renderPolling({
@@ -165,6 +174,7 @@ export default function routes({
165
174
  router.post('/cancelRequest/', cancelRequestHandler, asyncErrorHandler)
166
175
  router.post('/removeRequestedItem/', removeRequestedItemHandler, asyncErrorHandler)
167
176
  router.post('/getStatus/', getStatusHandler)
177
+ router.post('/getRequestedExpiredStatus/', getExpiredStatus)
168
178
  router.get('/async-reports/:reportId/:variantId/request/:executionId', pollingHandler, asyncErrorHandler)
169
179
  router.get('/async-reports/:reportId/:variantId/request/:tableId/report', getReportHandler, asyncErrorHandler)
170
180
  router.get('/async-reports/requested', async (req, res) => {
@@ -51,7 +51,7 @@ class BookmarkService extends userStoreService_1.default {
51
51
  createBookMarkToggleHtml(reportId, variantId, csrfToken, id) {
52
52
  const checked = this.isBookmarked(variantId) ? 'checked' : null;
53
53
  const tooltip = !checked ? 'Add Bookmark' : 'Remove Bookmark';
54
- return `<div class='dpr-bookmark dpr-bookmark-tooltip dpr-bookmark-table' tooltip="${tooltip}">
54
+ return `<div class='dpr-bookmark dpr-bookmark-tooltip dpr-bookmark-table' tooltip="${tooltip}" data-dpr-module="bookmark-toggle">
55
55
  <input class="bookmark-input" aria-label="bookmark toggle" type='checkbox' id='${reportId}-${variantId}-${id}' data-report-id='${reportId}' data-variant-id='${variantId}' data-csrf-token='${csrfToken}' ${checked} />
56
56
  <label id="${variantId}-${reportId}-bookmark-label" for='${reportId}-${variantId}-${id}'><span class="dpr-visually-hidden">Bookmark toggle</span></label>
57
57
  </div>`;
@@ -59,7 +59,7 @@ export default class BookmarkService extends UserStoreService {
59
59
  createBookMarkToggleHtml(reportId: string, variantId: string, csrfToken: string, id: string) {
60
60
  const checked = this.isBookmarked(variantId) ? 'checked' : null
61
61
  const tooltip = !checked ? 'Add Bookmark' : 'Remove Bookmark'
62
- return `<div class='dpr-bookmark dpr-bookmark-tooltip dpr-bookmark-table' tooltip="${tooltip}">
62
+ return `<div class='dpr-bookmark dpr-bookmark-tooltip dpr-bookmark-table' tooltip="${tooltip}" data-dpr-module="bookmark-toggle">
63
63
  <input class="bookmark-input" aria-label="bookmark toggle" type='checkbox' id='${reportId}-${variantId}-${id}' data-report-id='${reportId}' data-variant-id='${variantId}' data-csrf-token='${csrfToken}' ${checked} />
64
64
  <label id="${variantId}-${reportId}-bookmark-label" for='${reportId}-${variantId}-${id}'><span class="dpr-visually-hidden">Bookmark toggle</span></label>
65
65
  </div>`
@@ -130,6 +130,23 @@ class AsyncReportStoreService extends userStoreService_1.default {
130
130
  this.requestedReports[index] = report;
131
131
  await this.saveRequestedReportState();
132
132
  }
133
+ async setToExpired(id) {
134
+ await this.getRequestedReportsState();
135
+ const index = this.findIndexByExecutionId(id, this.requestedReports);
136
+ let report = this.requestedReports[index];
137
+ if (report) {
138
+ report = {
139
+ ...report,
140
+ status: AsyncReport_1.RequestStatus.EXPIRED,
141
+ timestamp: {
142
+ ...report.timestamp,
143
+ expired: new Date(),
144
+ },
145
+ };
146
+ }
147
+ this.requestedReports[index] = report;
148
+ await this.saveRequestedReportState();
149
+ }
133
150
  updateDataByStatus(report, status, errorMessage) {
134
151
  const ts = new Date();
135
152
  const { tableId } = report;
@@ -166,6 +166,24 @@ export default class AsyncReportStoreService extends UserStoreService {
166
166
  await this.saveRequestedReportState()
167
167
  }
168
168
 
169
+ async setToExpired(id: string) {
170
+ await this.getRequestedReportsState()
171
+ const index = this.findIndexByExecutionId(id, this.requestedReports)
172
+ let report: AsyncReportData = this.requestedReports[index]
173
+ if (report) {
174
+ report = {
175
+ ...report,
176
+ status: RequestStatus.EXPIRED,
177
+ timestamp: {
178
+ ...report.timestamp,
179
+ expired: new Date(),
180
+ },
181
+ }
182
+ }
183
+ this.requestedReports[index] = report
184
+ await this.saveRequestedReportState()
185
+ }
186
+
169
187
  updateDataByStatus(report: AsyncReportData, status?: RequestStatus | undefined, errorMessage?: string) {
170
188
  const ts = new Date()
171
189
  const { tableId } = report
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ministryofjustice/hmpps-digital-prison-reporting-frontend",
3
3
  "description": "The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.",
4
- "version": "3.23.0",
4
+ "version": "3.23.2",
5
5
  "main": "dpr/assets/js/all.mjs",
6
6
  "sass": "dpr/all.scss",
7
7
  "engines": {
package/package.zip CHANGED
Binary file