@ministryofjustice/hmpps-digital-prison-reporting-frontend 4.26.2 → 4.26.3
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.
- package/dpr/all.scss +22 -4
- package/dpr/components/_catalogue/catalogue-list/styles.scss +1 -1
- package/dpr/components/_reports/report/view.njk +2 -2
- package/dpr/components/_reports/report-data-table/style.scss +21 -2
- package/dpr/components/_reports/report-data-table/view.njk +2 -2
- package/dpr/components/_reports/report-data-table-wrapper/view.njk +3 -3
- package/dpr/components/_reports/report-summary-table/styles.scss +0 -1
- package/dpr/routes/journeys/request-report/controller.js +1 -1
- package/dpr/routes/journeys/request-report/controller.js.map +2 -2
- package/dpr/routes/journeys/request-report/controller.ts +5 -4
- package/dpr/routes/journeys/request-report/filters/controller.js +1 -1
- package/dpr/routes/journeys/request-report/filters/controller.js.map +2 -2
- package/dpr/routes/journeys/request-report/filters/controller.ts +4 -3
- package/dpr/routes/journeys/request-report/status/controller.js +1 -1
- package/dpr/routes/journeys/request-report/status/controller.js.map +2 -2
- package/dpr/routes/journeys/request-report/status/controller.ts +1 -0
- package/dpr/routes/journeys/view-report/async/controller.js +1 -1
- package/dpr/routes/journeys/view-report/async/controller.js.map +2 -2
- package/dpr/routes/journeys/view-report/async/controller.ts +2 -2
- package/dpr/routes/journeys/view-report/async/dashboard/controller.js +1 -1
- package/dpr/routes/journeys/view-report/async/dashboard/controller.js.map +2 -2
- package/dpr/routes/journeys/view-report/async/dashboard/controller.ts +1 -0
- package/dpr/routes/journeys/view-report/async/report/controller.js +1 -1
- package/dpr/routes/journeys/view-report/async/report/controller.js.map +2 -2
- package/dpr/routes/journeys/view-report/async/report/controller.ts +1 -0
- package/dpr/routes/journeys/view-report/async/report/tests.cy.js +1 -1
- package/dpr/routes/journeys/view-report/async/report/tests.cy.js.map +3 -3
- package/dpr/routes/journeys/view-report/async/report/tests.cy.ts +841 -841
- package/dpr/routes/journeys/view-report/controller.js +1 -1
- package/dpr/routes/journeys/view-report/controller.js.map +2 -2
- package/dpr/routes/journeys/view-report/controller.ts +2 -2
- package/dpr/routes/journeys/view-report/sync/dashboard/controller.js +1 -1
- package/dpr/routes/journeys/view-report/sync/dashboard/controller.js.map +2 -2
- package/dpr/routes/journeys/view-report/sync/dashboard/controller.ts +1 -0
- package/dpr/routes/journeys/view-report/sync/report/controller.js +1 -1
- package/dpr/routes/journeys/view-report/sync/report/controller.js.map +2 -2
- package/dpr/routes/journeys/view-report/sync/report/controller.ts +3 -2
- package/dpr/utils/DataTableBuilder/DataTableBuilder.js +1 -1
- package/dpr/utils/DataTableBuilder/DataTableBuilder.js.map +3 -3
- package/dpr/utils/DataTableBuilder/DataTableBuilder.ts +10 -2
- package/package.json +3 -4
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.create;var s=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var h=(o,r)=>{for(var e in r)s(o,e,{get:r[e],enumerable:!0})},n=(o,r,e,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of c(r))!f.call(o,t)&&t!==e&&s(o,t,{get:()=>r[t],enumerable:!(a=y(r,t))||a.enumerable});return o};var l=(o,r,e)=>(e=o!=null?d(u(o)):{},n(r||!o||!o.__esModule?s(e,"default",{value:o,enumerable:!0}):e,o)),v=o=>n(s({},"__esModule",{value:!0}),o);var b={};h(b,{ViewReportController:()=>i,default:()=>g});module.exports=v(b);var m=l(require("../../../utils/ErrorHandler")),p=l(require("../../../utils/logger"));class i{layoutPath;services;constructor(r,e){this.layoutPath=r,this.services=e}errorHandler=async(r,e,a)=>{p.default.error(`Error: ${JSON.stringify(r.body)}`);const t=new m.default(r.body?.error||{}).formatError();e.render("dpr/routes/journeys/view-report/error",{layoutPath:this.layoutPath,...r.body&&{...r.body},...r.params,error:t,params:r.params})}}var g=i;0&&(module.exports={ViewReportController});
|
|
2
2
|
//# sourceMappingURL=controller.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/dpr/routes/journeys/view-report/controller.ts"],
|
|
4
|
-
"sourcesContent": ["import { RequestHandler } from 'express'\nimport ErrorHandler from '../../../utils/ErrorHandler'\nimport { Services } from '../../../types/Services'\nimport logger from '../../../utils/logger'\n\nclass ViewReportController {\n layoutPath: string\n\n services: Services\n\n constructor(layoutPath: string, services: Services) {\n this.layoutPath = layoutPath\n this.services = services\n }\n\n errorHandler: RequestHandler = async (req, res, _next) => {\n logger.error(`Error: ${JSON.stringify(req.body)}`)\n const error = new ErrorHandler(req.body
|
|
5
|
-
"mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GACA,IAAAK,EAAyB,0CAEzBC,EAAmB,oCAEnB,MAAMJ,CAAqB,CACzB,WAEA,SAEA,YAAYK,EAAoBC,EAAoB,CAClD,KAAK,WAAaD,EAClB,KAAK,SAAWC,CAClB,CAEA,aAA+B,MAAOC,EAAKC,EAAKC,IAAU,CACxD,EAAAC,QAAO,MAAM,UAAU,KAAK,UAAUH,EAAI,IAAI,CAAC,EAAE,EACjD,MAAMI,EAAQ,IAAI,EAAAC,QAAaL,EAAI,
|
|
4
|
+
"sourcesContent": ["import { RequestHandler } from 'express'\nimport ErrorHandler from '../../../utils/ErrorHandler'\nimport { Services } from '../../../types/Services'\nimport logger from '../../../utils/logger'\n\nclass ViewReportController {\n layoutPath: string\n\n services: Services\n\n constructor(layoutPath: string, services: Services) {\n this.layoutPath = layoutPath\n this.services = services\n }\n\n errorHandler: RequestHandler = async (req, res, _next) => {\n logger.error(`Error: ${JSON.stringify(req.body)}`)\n const error = new ErrorHandler(req.body?.error || {}).formatError()\n\n res.render(`dpr/routes/journeys/view-report/error`, {\n layoutPath: this.layoutPath,\n ...(req.body && { ...req.body }),\n ...req.params,\n error,\n params: req.params,\n })\n }\n}\n\nexport { ViewReportController }\nexport default ViewReportController\n"],
|
|
5
|
+
"mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GACA,IAAAK,EAAyB,0CAEzBC,EAAmB,oCAEnB,MAAMJ,CAAqB,CACzB,WAEA,SAEA,YAAYK,EAAoBC,EAAoB,CAClD,KAAK,WAAaD,EAClB,KAAK,SAAWC,CAClB,CAEA,aAA+B,MAAOC,EAAKC,EAAKC,IAAU,CACxD,EAAAC,QAAO,MAAM,UAAU,KAAK,UAAUH,EAAI,IAAI,CAAC,EAAE,EACjD,MAAMI,EAAQ,IAAI,EAAAC,QAAaL,EAAI,MAAM,OAAS,CAAC,CAAC,EAAE,YAAY,EAElEC,EAAI,OAAO,wCAAyC,CAClD,WAAY,KAAK,WACjB,GAAID,EAAI,MAAQ,CAAE,GAAGA,EAAI,IAAK,EAC9B,GAAGA,EAAI,OACP,MAAAI,EACA,OAAQJ,EAAI,MACd,CAAC,CACH,CACF,CAGA,IAAON,EAAQD",
|
|
6
6
|
"names": ["controller_exports", "__export", "ViewReportController", "controller_default", "__toCommonJS", "import_ErrorHandler", "import_logger", "layoutPath", "services", "req", "res", "_next", "logger", "error", "ErrorHandler"]
|
|
7
7
|
}
|
|
@@ -15,11 +15,11 @@ class ViewReportController {
|
|
|
15
15
|
|
|
16
16
|
errorHandler: RequestHandler = async (req, res, _next) => {
|
|
17
17
|
logger.error(`Error: ${JSON.stringify(req.body)}`)
|
|
18
|
-
const error = new ErrorHandler(req.body
|
|
18
|
+
const error = new ErrorHandler(req.body?.error || {}).formatError()
|
|
19
19
|
|
|
20
20
|
res.render(`dpr/routes/journeys/view-report/error`, {
|
|
21
21
|
layoutPath: this.layoutPath,
|
|
22
|
-
...req.body,
|
|
22
|
+
...(req.body && { ...req.body }),
|
|
23
23
|
...req.params,
|
|
24
24
|
error,
|
|
25
25
|
params: req.params,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var y=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var b=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var f=(e,r)=>{for(var t in r)a(e,t,{get:r[t],enumerable:!0})},
|
|
1
|
+
"use strict";var y=Object.create;var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var b=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var f=(e,r)=>{for(var t in r)a(e,t,{get:r[t],enumerable:!0})},d=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of u(r))!m.call(e,o)&&o!==t&&a(e,o,{get:()=>r[o],enumerable:!(s=p(r,o))||s.enumerable});return e};var i=(e,r,t)=>(t=e!=null?y(b(e)):{},d(r||!e||!e.__esModule?a(t,"default",{value:e,enumerable:!0}):t,e)),v=e=>d(a({},"__esModule",{value:!0}),e);var D={};f(D,{ViewSyncDashboardController:()=>n,default:()=>w});module.exports=v(D);var l=i(require("../../../../../utils/ErrorHandler")),c=i(require("./utils")),h=i(require("../../utils"));class n{layoutPath;services;constructor(r,t){this.layoutPath=r,this.services=t}GET=async(r,t,s)=>{try{const o=await c.default.renderSyncDashboard({req:r,res:t,services:this.services});t.render("dpr/routes/journeys/view-report/dashboard",{layoutPath:this.layoutPath,...o})}catch(o){r.body??={},r.body.title="Dashboard Failed",r.body.errorDescription="We were unable to show this dashboard for the following reason:",r.body.error=new l.default(o).formatError(),s()}};applyFilters=async(r,t,s)=>{await h.default.applyDashboardInteractiveQuery(r,t,this.services,"filters")}}var w=n;0&&(module.exports={ViewSyncDashboardController});
|
|
2
2
|
//# sourceMappingURL=controller.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/dpr/routes/journeys/view-report/sync/dashboard/controller.ts"],
|
|
4
|
-
"sourcesContent": ["import { RequestHandler } from 'express'\nimport ErrorHandler from '../../../../../utils/ErrorHandler'\nimport { Services } from '../../../../../types/Services'\nimport SyncDashboardUtils from './utils'\nimport ViewReportUtils from '../../utils'\n\nclass ViewSyncDashboardController {\n layoutPath: string\n\n services: Services\n\n constructor(layoutPath: string, services: Services) {\n this.layoutPath = layoutPath\n this.services = services\n }\n\n GET: RequestHandler = async (req, res, next) => {\n try {\n const renderData = await SyncDashboardUtils.renderSyncDashboard({ req, res, services: this.services })\n\n res.render(`dpr/routes/journeys/view-report/dashboard`, {\n layoutPath: this.layoutPath,\n ...renderData,\n })\n } catch (error) {\n req.body.title = `Dashboard Failed`\n req.body.errorDescription = 'We were unable to show this dashboard for the following reason:'\n req.body.error = new ErrorHandler(error).formatError()\n next()\n }\n }\n\n applyFilters: RequestHandler = async (req, res, _next) => {\n await ViewReportUtils.applyDashboardInteractiveQuery(req, res, this.services, 'filters')\n }\n}\n\nexport { ViewSyncDashboardController }\nexport default ViewSyncDashboardController\n"],
|
|
5
|
-
"mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iCAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GACA,IAAAK,EAAyB,gDAEzBC,EAA+B,sBAC/BA,EAA4B,0BAE5B,MAAMJ,CAA4B,CAChC,WAEA,SAEA,YAAYK,EAAoBC,EAAoB,CAClD,KAAK,WAAaD,EAClB,KAAK,SAAWC,CAClB,CAEA,IAAsB,MAAOC,EAAKC,EAAKC,IAAS,CAC9C,GAAI,CACF,MAAMC,EAAa,MAAM,EAAAC,QAAmB,oBAAoB,CAAE,IAAAJ,EAAK,IAAAC,EAAK,SAAU,KAAK,QAAS,CAAC,EAErGA,EAAI,OAAO,4CAA6C,CACtD,WAAY,KAAK,WACjB,GAAGE,CACL,CAAC,CACH,OAASE,EAAO,CACdL,EAAI,KAAK,MAAQ,mBACjBA,EAAI,KAAK,iBAAmB,kEAC5BA,EAAI,KAAK,MAAQ,IAAI,EAAAM,QAAaD,CAAK,EAAE,YAAY,EACrDH,EAAK,CACP,CACF,EAEA,aAA+B,MAAOF,EAAKC,EAAKM,IAAU,CACxD,MAAM,EAAAC,QAAgB,+BAA+BR,EAAKC,EAAK,KAAK,SAAU,SAAS,CACzF,CACF,CAGA,IAAOP,EAAQD",
|
|
4
|
+
"sourcesContent": ["import { RequestHandler } from 'express'\nimport ErrorHandler from '../../../../../utils/ErrorHandler'\nimport { Services } from '../../../../../types/Services'\nimport SyncDashboardUtils from './utils'\nimport ViewReportUtils from '../../utils'\n\nclass ViewSyncDashboardController {\n layoutPath: string\n\n services: Services\n\n constructor(layoutPath: string, services: Services) {\n this.layoutPath = layoutPath\n this.services = services\n }\n\n GET: RequestHandler = async (req, res, next) => {\n try {\n const renderData = await SyncDashboardUtils.renderSyncDashboard({ req, res, services: this.services })\n\n res.render(`dpr/routes/journeys/view-report/dashboard`, {\n layoutPath: this.layoutPath,\n ...renderData,\n })\n } catch (error) {\n req.body ??= {}\n req.body.title = `Dashboard Failed`\n req.body.errorDescription = 'We were unable to show this dashboard for the following reason:'\n req.body.error = new ErrorHandler(error).formatError()\n next()\n }\n }\n\n applyFilters: RequestHandler = async (req, res, _next) => {\n await ViewReportUtils.applyDashboardInteractiveQuery(req, res, this.services, 'filters')\n }\n}\n\nexport { ViewSyncDashboardController }\nexport default ViewSyncDashboardController\n"],
|
|
5
|
+
"mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iCAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GACA,IAAAK,EAAyB,gDAEzBC,EAA+B,sBAC/BA,EAA4B,0BAE5B,MAAMJ,CAA4B,CAChC,WAEA,SAEA,YAAYK,EAAoBC,EAAoB,CAClD,KAAK,WAAaD,EAClB,KAAK,SAAWC,CAClB,CAEA,IAAsB,MAAOC,EAAKC,EAAKC,IAAS,CAC9C,GAAI,CACF,MAAMC,EAAa,MAAM,EAAAC,QAAmB,oBAAoB,CAAE,IAAAJ,EAAK,IAAAC,EAAK,SAAU,KAAK,QAAS,CAAC,EAErGA,EAAI,OAAO,4CAA6C,CACtD,WAAY,KAAK,WACjB,GAAGE,CACL,CAAC,CACH,OAASE,EAAO,CACdL,EAAI,OAAS,CAAC,EACdA,EAAI,KAAK,MAAQ,mBACjBA,EAAI,KAAK,iBAAmB,kEAC5BA,EAAI,KAAK,MAAQ,IAAI,EAAAM,QAAaD,CAAK,EAAE,YAAY,EACrDH,EAAK,CACP,CACF,EAEA,aAA+B,MAAOF,EAAKC,EAAKM,IAAU,CACxD,MAAM,EAAAC,QAAgB,+BAA+BR,EAAKC,EAAK,KAAK,SAAU,SAAS,CACzF,CACF,CAGA,IAAOP,EAAQD",
|
|
6
6
|
"names": ["controller_exports", "__export", "ViewSyncDashboardController", "controller_default", "__toCommonJS", "import_ErrorHandler", "import_utils", "layoutPath", "services", "req", "res", "next", "renderData", "SyncDashboardUtils", "error", "ErrorHandler", "_next", "ViewReportUtils"]
|
|
7
7
|
}
|
|
@@ -23,6 +23,7 @@ class ViewSyncDashboardController {
|
|
|
23
23
|
...renderData,
|
|
24
24
|
})
|
|
25
25
|
} catch (error) {
|
|
26
|
+
req.body ??= {}
|
|
26
27
|
req.body.title = `Dashboard Failed`
|
|
27
28
|
req.body.errorDescription = 'We were unable to show this dashboard for the following reason:'
|
|
28
29
|
req.body.error = new ErrorHandler(error).formatError()
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var m=Object.create;var a=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var h=Object.getPrototypeOf,R=Object.prototype.hasOwnProperty;var
|
|
1
|
+
"use strict";var m=Object.create;var a=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var h=Object.getPrototypeOf,R=Object.prototype.hasOwnProperty;var b=(t,e)=>{for(var r in e)a(t,r,{get:e[r],enumerable:!0})},p=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of v(e))!R.call(t,o)&&o!==r&&a(t,o,{get:()=>e[o],enumerable:!(s=f(e,o))||s.enumerable});return t};var i=(t,e,r)=>(r=t!=null?m(h(t)):{},p(e||!t||!t.__esModule?a(r,"default",{value:t,enumerable:!0}):r,t)),w=t=>p(a({},"__esModule",{value:!0}),t);var F={};b(F,{ViewSyncReportController:()=>d,default:()=>E});module.exports=w(F);var l=i(require("../../../../../utils/ErrorHandler")),u=i(require("./utils")),n=require("../../../../../components/_filters/filtersTypeEnum"),c=i(require("../../../../../utils/Personalisation/personalisationUtils")),y=i(require("../../utils"));class d{layoutPath;services;constructor(e,r){this.layoutPath=e,this.services=r}GET=async(e,r,s)=>{try{const o=await u.default.getReport({req:e,res:r,services:this.services});r.render("dpr/routes/journeys/view-report/report",{layoutPath:this.layoutPath,...o})}catch(o){e.body??={},e.body.title="Report Failed",e.body.errorDescription="We were unable to show this report for the following reason:",e.body.error=new l.default(o).formatError(),s()}};saveDefaultFilterValues=async(e,r,s)=>{try{c.default.saveDefaults(n.FiltersType.INTERACTIVE,r,e,this.services),r.redirect(`${e.baseUrl}?defaultsSaved=true`)}catch(o){e.body={title:"Failed to save defaults",error:new l.default(o).formatError(),...e.body&&{...e.body}},s()}};removeDefaultFilterValues=async(e,r,s)=>{try{c.default.removeDefaults(n.FiltersType.INTERACTIVE,r,e,this.services),r.redirect(e.baseUrl)}catch(o){e.body={title:"Failed to remove defaults",error:new l.default(o).formatError(),...e.body&&{...e.body}},s()}};applyFilters=async(e,r,s)=>{await y.default.applyReportInteractiveQuery(e,r,this.services,"filters")};applyColumns=async(e,r,s)=>{await y.default.applyReportInteractiveQuery(e,r,this.services,"columns")}}var E=d;0&&(module.exports={ViewSyncReportController});
|
|
2
2
|
//# sourceMappingURL=controller.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/dpr/routes/journeys/view-report/sync/report/controller.ts"],
|
|
4
|
-
"sourcesContent": ["import { RequestHandler } from 'express'\nimport ErrorHandler from '../../../../../utils/ErrorHandler'\nimport { Services } from '../../../../../types/Services'\nimport SyncReportUtils from './utils'\nimport { FiltersType } from '../../../../../components/_filters/filtersTypeEnum'\nimport PersonalisationUtils from '../../../../../utils/Personalisation/personalisationUtils'\nimport ViewReportUtils from '../../utils'\n\nclass ViewSyncReportController {\n layoutPath: string\n\n services: Services\n\n constructor(layoutPath: string, services: Services) {\n this.layoutPath = layoutPath\n this.services = services\n }\n\n GET: RequestHandler = async (req, res, next) => {\n try {\n const renderData = await SyncReportUtils.getReport({ req, res, services: this.services })\n res.render(`dpr/routes/journeys/view-report/report`, {\n layoutPath: this.layoutPath,\n ...renderData,\n })\n } catch (error) {\n req.body.title = `Report Failed`\n req.body.errorDescription = 'We were unable to show this report for the following reason:'\n req.body.error = new ErrorHandler(error).formatError()\n next()\n }\n }\n\n saveDefaultFilterValues: RequestHandler = async (req, res, next) => {\n try {\n PersonalisationUtils.saveDefaults(FiltersType.INTERACTIVE, res, req, this.services)\n res.redirect(`${req.baseUrl}?defaultsSaved=true`)\n } catch (error) {\n req.body = {\n title: 'Failed to save defaults',\n error: new ErrorHandler(error).formatError(),\n ...req.body,\n }\n next()\n }\n }\n\n removeDefaultFilterValues: RequestHandler = async (req, res, next) => {\n try {\n PersonalisationUtils.removeDefaults(FiltersType.INTERACTIVE, res, req, this.services)\n res.redirect(req.baseUrl)\n } catch (error) {\n req.body = {\n title: 'Failed to remove defaults',\n error: new ErrorHandler(error).formatError(),\n ...req.body,\n }\n next()\n }\n }\n\n applyFilters: RequestHandler = async (req, res, _next) => {\n await ViewReportUtils.applyReportInteractiveQuery(req, res, this.services, 'filters')\n }\n\n applyColumns: RequestHandler = async (req, res, _next) => {\n await ViewReportUtils.applyReportInteractiveQuery(req, res, this.services, 'columns')\n }\n}\n\nexport { ViewSyncReportController }\nexport default ViewSyncReportController\n"],
|
|
5
|
-
"mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,8BAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GACA,IAAAK,EAAyB,gDAEzBC,EAA4B,sBAC5BC,EAA4B,8DAC5BC,EAAiC,wEACjCF,EAA4B,0BAE5B,MAAMJ,CAAyB,CAC7B,WAEA,SAEA,YAAYO,EAAoBC,EAAoB,CAClD,KAAK,WAAaD,EAClB,KAAK,SAAWC,CAClB,CAEA,IAAsB,MAAOC,EAAKC,EAAKC,IAAS,CAC9C,GAAI,CACF,MAAMC,EAAa,MAAM,EAAAC,QAAgB,UAAU,CAAE,IAAAJ,EAAK,IAAAC,EAAK,SAAU,KAAK,QAAS,CAAC,EACxFA,EAAI,OAAO,yCAA0C,CACnD,WAAY,KAAK,WACjB,GAAGE,CACL,CAAC,CACH,OAASE,EAAO,CACdL,EAAI,KAAK,MAAQ,gBACjBA,EAAI,KAAK,iBAAmB,+DAC5BA,EAAI,KAAK,MAAQ,IAAI,EAAAM,QAAaD,CAAK,EAAE,YAAY,EACrDH,EAAK,CACP,CACF,EAEA,wBAA0C,MAAOF,EAAKC,EAAKC,IAAS,CAClE,GAAI,CACF,EAAAK,QAAqB,aAAa,cAAY,YAAaN,EAAKD,EAAK,KAAK,QAAQ,EAClFC,EAAI,SAAS,GAAGD,EAAI,OAAO,qBAAqB,CAClD,OAASK,EAAO,CACdL,EAAI,KAAO,CACT,MAAO,0BACP,MAAO,IAAI,EAAAM,QAAaD,CAAK,EAAE,YAAY,EAC3C,
|
|
4
|
+
"sourcesContent": ["import { RequestHandler } from 'express'\nimport ErrorHandler from '../../../../../utils/ErrorHandler'\nimport { Services } from '../../../../../types/Services'\nimport SyncReportUtils from './utils'\nimport { FiltersType } from '../../../../../components/_filters/filtersTypeEnum'\nimport PersonalisationUtils from '../../../../../utils/Personalisation/personalisationUtils'\nimport ViewReportUtils from '../../utils'\n\nclass ViewSyncReportController {\n layoutPath: string\n\n services: Services\n\n constructor(layoutPath: string, services: Services) {\n this.layoutPath = layoutPath\n this.services = services\n }\n\n GET: RequestHandler = async (req, res, next) => {\n try {\n const renderData = await SyncReportUtils.getReport({ req, res, services: this.services })\n res.render(`dpr/routes/journeys/view-report/report`, {\n layoutPath: this.layoutPath,\n ...renderData,\n })\n } catch (error) {\n req.body ??= {}\n req.body.title = `Report Failed`\n req.body.errorDescription = 'We were unable to show this report for the following reason:'\n req.body.error = new ErrorHandler(error).formatError()\n next()\n }\n }\n\n saveDefaultFilterValues: RequestHandler = async (req, res, next) => {\n try {\n PersonalisationUtils.saveDefaults(FiltersType.INTERACTIVE, res, req, this.services)\n res.redirect(`${req.baseUrl}?defaultsSaved=true`)\n } catch (error) {\n req.body = {\n title: 'Failed to save defaults',\n error: new ErrorHandler(error).formatError(),\n ...(req.body && { ...req.body }),\n }\n next()\n }\n }\n\n removeDefaultFilterValues: RequestHandler = async (req, res, next) => {\n try {\n PersonalisationUtils.removeDefaults(FiltersType.INTERACTIVE, res, req, this.services)\n res.redirect(req.baseUrl)\n } catch (error) {\n req.body = {\n title: 'Failed to remove defaults',\n error: new ErrorHandler(error).formatError(),\n ...(req.body && { ...req.body }),\n }\n next()\n }\n }\n\n applyFilters: RequestHandler = async (req, res, _next) => {\n await ViewReportUtils.applyReportInteractiveQuery(req, res, this.services, 'filters')\n }\n\n applyColumns: RequestHandler = async (req, res, _next) => {\n await ViewReportUtils.applyReportInteractiveQuery(req, res, this.services, 'columns')\n }\n}\n\nexport { ViewSyncReportController }\nexport default ViewSyncReportController\n"],
|
|
5
|
+
"mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,8BAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GACA,IAAAK,EAAyB,gDAEzBC,EAA4B,sBAC5BC,EAA4B,8DAC5BC,EAAiC,wEACjCF,EAA4B,0BAE5B,MAAMJ,CAAyB,CAC7B,WAEA,SAEA,YAAYO,EAAoBC,EAAoB,CAClD,KAAK,WAAaD,EAClB,KAAK,SAAWC,CAClB,CAEA,IAAsB,MAAOC,EAAKC,EAAKC,IAAS,CAC9C,GAAI,CACF,MAAMC,EAAa,MAAM,EAAAC,QAAgB,UAAU,CAAE,IAAAJ,EAAK,IAAAC,EAAK,SAAU,KAAK,QAAS,CAAC,EACxFA,EAAI,OAAO,yCAA0C,CACnD,WAAY,KAAK,WACjB,GAAGE,CACL,CAAC,CACH,OAASE,EAAO,CACdL,EAAI,OAAS,CAAC,EACdA,EAAI,KAAK,MAAQ,gBACjBA,EAAI,KAAK,iBAAmB,+DAC5BA,EAAI,KAAK,MAAQ,IAAI,EAAAM,QAAaD,CAAK,EAAE,YAAY,EACrDH,EAAK,CACP,CACF,EAEA,wBAA0C,MAAOF,EAAKC,EAAKC,IAAS,CAClE,GAAI,CACF,EAAAK,QAAqB,aAAa,cAAY,YAAaN,EAAKD,EAAK,KAAK,QAAQ,EAClFC,EAAI,SAAS,GAAGD,EAAI,OAAO,qBAAqB,CAClD,OAASK,EAAO,CACdL,EAAI,KAAO,CACT,MAAO,0BACP,MAAO,IAAI,EAAAM,QAAaD,CAAK,EAAE,YAAY,EAC3C,GAAIL,EAAI,MAAQ,CAAE,GAAGA,EAAI,IAAK,CAChC,EACAE,EAAK,CACP,CACF,EAEA,0BAA4C,MAAOF,EAAKC,EAAKC,IAAS,CACpE,GAAI,CACF,EAAAK,QAAqB,eAAe,cAAY,YAAaN,EAAKD,EAAK,KAAK,QAAQ,EACpFC,EAAI,SAASD,EAAI,OAAO,CAC1B,OAASK,EAAO,CACdL,EAAI,KAAO,CACT,MAAO,4BACP,MAAO,IAAI,EAAAM,QAAaD,CAAK,EAAE,YAAY,EAC3C,GAAIL,EAAI,MAAQ,CAAE,GAAGA,EAAI,IAAK,CAChC,EACAE,EAAK,CACP,CACF,EAEA,aAA+B,MAAOF,EAAKC,EAAKO,IAAU,CACxD,MAAM,EAAAC,QAAgB,4BAA4BT,EAAKC,EAAK,KAAK,SAAU,SAAS,CACtF,EAEA,aAA+B,MAAOD,EAAKC,EAAKO,IAAU,CACxD,MAAM,EAAAC,QAAgB,4BAA4BT,EAAKC,EAAK,KAAK,SAAU,SAAS,CACtF,CACF,CAGA,IAAOT,EAAQD",
|
|
6
6
|
"names": ["controller_exports", "__export", "ViewSyncReportController", "controller_default", "__toCommonJS", "import_ErrorHandler", "import_utils", "import_filtersTypeEnum", "import_personalisationUtils", "layoutPath", "services", "req", "res", "next", "renderData", "SyncReportUtils", "error", "ErrorHandler", "PersonalisationUtils", "_next", "ViewReportUtils"]
|
|
7
7
|
}
|
|
@@ -24,6 +24,7 @@ class ViewSyncReportController {
|
|
|
24
24
|
...renderData,
|
|
25
25
|
})
|
|
26
26
|
} catch (error) {
|
|
27
|
+
req.body ??= {}
|
|
27
28
|
req.body.title = `Report Failed`
|
|
28
29
|
req.body.errorDescription = 'We were unable to show this report for the following reason:'
|
|
29
30
|
req.body.error = new ErrorHandler(error).formatError()
|
|
@@ -39,7 +40,7 @@ class ViewSyncReportController {
|
|
|
39
40
|
req.body = {
|
|
40
41
|
title: 'Failed to save defaults',
|
|
41
42
|
error: new ErrorHandler(error).formatError(),
|
|
42
|
-
...req.body,
|
|
43
|
+
...(req.body && { ...req.body }),
|
|
43
44
|
}
|
|
44
45
|
next()
|
|
45
46
|
}
|
|
@@ -53,7 +54,7 @@ class ViewSyncReportController {
|
|
|
53
54
|
req.body = {
|
|
54
55
|
title: 'Failed to remove defaults',
|
|
55
56
|
error: new ErrorHandler(error).formatError(),
|
|
56
|
-
...req.body,
|
|
57
|
+
...(req.body && { ...req.body }),
|
|
57
58
|
}
|
|
58
59
|
next()
|
|
59
60
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var g=Object.create;var
|
|
1
|
+
"use strict";var g=Object.create;var c=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var S=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty;var w=(i,e)=>{for(var t in e)c(i,t,{get:e[t],enumerable:!0})},h=(i,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of b(e))!C.call(i,r)&&r!==t&&c(i,r,{get:()=>e[r],enumerable:!(a=D(e,r))||a.enumerable});return i};var y=(i,e,t)=>(t=i!=null?g(S(i)):{},h(e||!i||!i.__esModule?c(t,"default",{value:i,enumerable:!0}):t,i)),v=i=>h(c({},"__esModule",{value:!0}),i);var K={};w(K,{DataTableBuilder:()=>u,default:()=>F});module.exports=v(K);var p=y(require("../urlHelper")),f=y(require("../DateMapper/DateMapper"));class u{fields;sortData;columns=[];reportSummaries={};reportQuery=null;currentQueryParams=null;dateMapper=new f.default;constructor(e,t=!1){this.fields=e,this.sortData=t}mapDate(e){return e?this.dateMapper.toDateString(e,"local-datetime-short-year"):""}mapBoolean(e){return e?e.substring(0,1).toUpperCase()+e.substring(1).toLowerCase():""}mapRow(e,t="",a=[]){return this.fields.filter(r=>this.columns.includes(r.name)).map(r=>{const o=a.find(n=>n.name===r.name)??r;return this.mapCell(o,e,t)})}mapCell(e,t,a=""){const r=t[e.name],s=this.mapCellValue(e,r);let o="string",n=a;e.wordWrap&&(n+=` data-table-cell-wrap-${e.wordWrap.toLowerCase()}`),e.header&&(n+=" govuk-table__header"),(e.type==="double"||e.type==="long"||typeof r=="number")&&(o="numeric"),o==="string"&&r&&r.split(" ").length>10&&(n+=" data-table-cell-long-string");const l=e.type==="HTML";return{fieldName:e.name,...l?{html:s}:{text:s},format:o,classes:n.trim()}}mapCellValue(e,t){if(e.calculated)return t;switch(e.type){case"boolean":return this.mapBoolean(t);case"date":case"time":return this.mapDate(t);default:return t||""}}mapHeader(e=!1,t=null){return this.fields.filter(a=>this.columns.includes(a.name)).map(a=>{if(this.reportQuery&&!e&&a.sortable){let r="none",s=(0,p.default)(this.currentQueryParams||{},{sortColumn:a.name,sortedAsc:"true"},this.fields);return a.name===this.reportQuery.sortColumn&&(r=this.reportQuery.sortedAsc?"ascending":"descending",this.reportQuery.sortedAsc&&(s=(0,p.default)(this.currentQueryParams||{},{sortColumn:a.name,sortedAsc:"false"},this.fields))),{html:`<a data-column="${a.name}" class="data-table-header-button data-table-header-button-sort-${r}" href="${s}">${a.display}</a>`,...t&&{classes:t}}}return{text:a.display,...t&&{classes:t}}})}mapData(e){const t=this.mapSummary("table-header"),a=this.mergeCells(e.map(s=>this.mapRow(s))),r=this.mapSummary("table-footer");return t.concat(a).concat(r)}mergeCells(e){const t=this.fields.filter(r=>r.mergeRows).map(r=>r.name);if(t.length===0)return e;const a={};return t.forEach(r=>{a[r]=e.reduce((s,o)=>{const n=this.getCellByFieldName(o,r);let l="";return n&&(l=n.text||n.html||""),{...s,[l]:(s[l]??0)+1}},{})}),e.map(r=>{let s=[...r];return t.forEach(o=>{const n=this.getCellByFieldName(r,o);let l,m;if(n&&a[o])switch(l=n.text||n.html||"",m=a[o][l],m){case-1:s=s.filter(d=>d.fieldName!==o);break;case 1:break;default:n.rowspan=m,a[o][l]=-1}}),s})}getCellByFieldName(e,t){return e.find(a=>a.fieldName===t)}mapSummary(e){return this.reportSummaries[e]?this.reportSummaries[e].flatMap(t=>t.data.map(a=>this.mapRow(a,`dpr-report-summary-cell dpr-report-summary-cell-${e}`,t.fields))):[]}sort(e){return this.appendSortKeyToData(e).sort(this.sortKeyComparison()).map(t=>({...t}))}sortKeyComparison(){return(e,t)=>{const a=e.sortKey,r=t.sortKey;return a===r?0:a<r?-1:1}}appendSortKeyToData(e,t=null){const a=t||this.fields;return e.map(r=>{const s=this.getSortKey(r,a);return{...r,sortKey:s}})}mapNamesToFields(e){return e.map(t=>this.fields.find(a=>a.name===t)).filter(t=>t!==void 0)}getSortKey(e,t){return t.map(a=>{const r=e[a.name];return r&&this.dateMapper.isDate(r)?this.dateMapper.toDateString(r,"iso"):this.mapCellValue(a,r)}).join("-").toLowerCase()}convertDataTableToHtml(e){const a=(e.head||[]).map(s=>`<th scope='col' class='govuk-table__header'>${s.html??s.text}</th>`),r=e.rows.map(s=>`<tr class='govuk-table__row'>${s.map(o=>`<td class='govuk-table__cell govuk-table__cell--${o.format} ${o.classes}'>${o.html??o.text}</td>`).join("")}</tr>`);return`<table class='govuk-table'><thead class='govuk-table__head'>${a.join("")}</thead><tbody class='govuk-table__body'>${r.join("")}</tbody></table>`}withHeaderOptions({reportQuery:e,columns:t,interactive:a}){return a&&e?this.withHeaderSortOptions(e):this.withNoHeaderOptions(t)}withHeaderSortOptions(e){return this.reportQuery=e,this.columns=e.columns,this.currentQueryParams=this.reportQuery.toRecordWithFilterPrefix(),this}withNoHeaderOptions(e){return this.columns=e,this}buildTable(e){const t=this.mapData(this.sortData?this.sort(e):e);return{head:this.mapHeader(),rows:t,rowCount:e.length,colCount:this.columns.length}}withSummaries(e){return this.reportSummaries=e,this}withSortedData(e=!0){return this.sortData=e,this}}var F=u;0&&(module.exports={DataTableBuilder});
|
|
2
2
|
//# sourceMappingURL=DataTableBuilder.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/dpr/utils/DataTableBuilder/DataTableBuilder.ts"],
|
|
4
|
-
"sourcesContent": ["import Dict = NodeJS.Dict\nimport ReportQuery from '../../types/ReportQuery'\nimport { Cell, CellFormat, DataTable, SortKey } from './types'\nimport createUrlForParameters from '../urlHelper'\nimport type { SummaryTemplate } from '../../types/Templates'\nimport { AsyncSummary } from '../../types/UserReports'\nimport DateMapper from '../DateMapper/DateMapper'\nimport { components } from '../../types/api'\n\nclass DataTableBuilder {\n protected fields: components['schemas']['FieldDefinition'][]\n\n private sortData: boolean\n\n protected columns: Array<string> = []\n\n protected reportSummaries: Dict<Array<AsyncSummary>> = {}\n\n // Sortable headers only\n private reportQuery: ReportQuery | null = null\n\n private currentQueryParams: NodeJS.Dict<string | Array<string>> | null = null\n\n private dateMapper = new DateMapper()\n\n constructor(fields: components['schemas']['FieldDefinition'][], sortData = false) {\n this.fields = fields\n this.sortData = sortData\n }\n\n private mapDate(isoDate?: string) {\n if (!isoDate) return ''\n\n return this.dateMapper.toDateString(isoDate, 'local-datetime-short-year')\n }\n\n private mapBoolean(value?: string) {\n if (!value) return ''\n return value.substring(0, 1).toUpperCase() + value.substring(1).toLowerCase()\n }\n\n protected mapRow(\n rowData: NodeJS.Dict<string>,\n extraClasses = '',\n overrideFields: components['schemas']['FieldDefinition'][] = [],\n ): Cell[] {\n return this.fields\n .filter((f) => this.columns.includes(f.name))\n .map((f) => {\n const overrideField = overrideFields.find((o) => o.name === f.name)\n const field = overrideField ?? f\n return this.mapCell(field, rowData, extraClasses)\n })\n }\n\n private mapCell(field: components['schemas']['FieldDefinition'], rowData: NodeJS.Dict<string>, extraClasses = '') {\n const textValue = this.mapCellValue(field, rowData[field.name])\n let fieldFormat: CellFormat = 'string'\n\n let classes = extraClasses\n\n if (field.wordWrap) {\n classes += ` data-table-cell-wrap-${field.wordWrap.toLowerCase()}`\n }\n\n if (field.header) {\n classes += ' govuk-table__header'\n }\n\n if (field.type === 'double' || field.type === 'long') {\n fieldFormat = 'numeric'\n }\n\n const isHtml = field.type === 'HTML'\n const cell: Cell = {\n fieldName: field.name,\n ...(isHtml ? { html: textValue } : { text: textValue }),\n format: fieldFormat,\n classes: classes.trim(),\n }\n\n return cell\n }\n\n protected mapCellValue(field: components['schemas']['FieldDefinition'], cellData?: string) {\n if (field.calculated) {\n return cellData\n }\n\n switch (field.type) {\n case 'boolean':\n return this.mapBoolean(cellData)\n\n case 'date':\n case 'time':\n return this.mapDate(cellData)\n\n default:\n return cellData || ''\n }\n }\n\n protected mapHeader(disableSort = false, extraClasses: string | null = null): Cell[] {\n return this.fields\n .filter((field) => this.columns.includes(field.name))\n .map((f) => {\n if (this.reportQuery && !disableSort) {\n if (f.sortable) {\n let sortDirection = 'none'\n let url = createUrlForParameters(\n this.currentQueryParams || {},\n {\n sortColumn: f.name,\n sortedAsc: 'true',\n },\n this.fields,\n )\n\n if (f.name === this.reportQuery.sortColumn) {\n sortDirection = this.reportQuery.sortedAsc ? 'ascending' : 'descending'\n\n if (this.reportQuery.sortedAsc) {\n url = createUrlForParameters(\n this.currentQueryParams || {},\n {\n sortColumn: f.name,\n sortedAsc: 'false',\n },\n this.fields,\n )\n }\n }\n\n return {\n html:\n `<a ` +\n `data-column=\"${f.name}\" ` +\n `class=\"data-table-header-button data-table-header-button-sort-${sortDirection}\" ` +\n `href=\"${url}\"` +\n `>${f.display}</a>`,\n ...(extraClasses && { classes: extraClasses }),\n }\n }\n }\n return {\n text: f.display,\n ...(extraClasses && { classes: extraClasses }),\n }\n })\n }\n\n protected mapData(data: Array<Dict<string>>): Cell[][] {\n const mappedHeaderSummary = this.mapSummary('table-header')\n const mappedTableData = this.mergeCells(data.map((rowData) => this.mapRow(rowData)))\n const mappedFooterSummary = this.mapSummary('table-footer')\n\n return mappedHeaderSummary.concat(mappedTableData).concat(mappedFooterSummary)\n }\n\n private mergeCells(rows: Cell[][]): Cell[][] {\n const mergeFieldNames = this.fields\n .filter((f) => (<components['schemas']['SummaryField']>f).mergeRows)\n .map((f) => f.name)\n\n if (mergeFieldNames.length === 0) {\n return rows\n }\n\n const occurrences: Dict<Dict<number>> = {}\n mergeFieldNames.forEach((f) => {\n occurrences[f] = rows.reduce((accumulator: Dict<number>, currentRow) => {\n const currentCell = this.getCellByFieldName(currentRow, f)\n let cellValue = ''\n if (currentCell) {\n cellValue = currentCell.text || currentCell.html || ''\n }\n\n return {\n ...accumulator,\n [cellValue]: (accumulator[cellValue] ?? 0) + 1,\n }\n }, {})\n })\n\n return rows.map((row) => {\n let mergedRow = [...row]\n\n mergeFieldNames.forEach((mergeFieldName) => {\n const currentRowCell = this.getCellByFieldName(row, mergeFieldName)\n let cellValue\n let occurrencesOfValue\n if (currentRowCell && occurrences[mergeFieldName]) {\n cellValue = currentRowCell.text || currentRowCell.html || ''\n occurrencesOfValue = occurrences[mergeFieldName][cellValue]\n\n switch (occurrencesOfValue) {\n case -1:\n mergedRow = mergedRow.filter((c) => c.fieldName !== mergeFieldName)\n break\n\n case 1:\n break\n\n default:\n currentRowCell.rowspan = occurrencesOfValue\n occurrences[mergeFieldName][cellValue] = -1\n }\n }\n })\n\n return mergedRow\n })\n }\n\n private getCellByFieldName(row: Cell[], fieldName: string) {\n return row.find((c) => c.fieldName === fieldName)\n }\n\n private mapSummary(template: SummaryTemplate): Cell[][] {\n if (this.reportSummaries[template]) {\n return this.reportSummaries[template].flatMap((reportSummary) =>\n reportSummary.data.map((rowData) =>\n this.mapRow(\n rowData,\n `dpr-report-summary-cell dpr-report-summary-cell-${template}`,\n <components['schemas']['FieldDefinition'][]>reportSummary.fields,\n ),\n ),\n )\n }\n return []\n }\n\n protected sort(data: Dict<string>[]): Dict<string>[] {\n return this.appendSortKeyToData(data)\n .sort(this.sortKeyComparison())\n .map((d: SortKey) => ({\n ...d,\n }))\n }\n\n protected sortKeyComparison() {\n return (a: SortKey, b: SortKey) => {\n const aValue = a.sortKey\n const bValue = b.sortKey\n\n if (aValue === bValue) {\n return 0\n }\n\n if (aValue < bValue) {\n return -1\n }\n\n return 1\n }\n }\n\n private appendSortKeyToData(\n data: Dict<string>[],\n fields: components['schemas']['FieldDefinition'][] | null = null,\n ): SortKey[] {\n const sortFields = fields || this.fields\n\n return data.map((rowData) => {\n const sortKey = this.getSortKey(rowData, sortFields)\n\n return {\n ...rowData,\n sortKey,\n }\n })\n }\n\n protected mapNamesToFields(names: string[]): components['schemas']['FieldDefinition'][] {\n return names.map((s) => this.fields.find((f) => f.name === s)).filter((n) => n !== undefined)\n }\n\n protected getSortKey(rowData: NodeJS.Dict<string>, sortFields: components['schemas']['FieldDefinition'][]) {\n return sortFields\n .map((f) => {\n const value = rowData[f.name]\n if (value && this.dateMapper.isDate(value)) {\n return this.dateMapper.toDateString(value, 'iso')\n }\n\n return this.mapCellValue(f, value)\n })\n .join('-')\n .toLowerCase()\n }\n\n protected convertDataTableToHtml(dataTable: DataTable): string {\n const head = dataTable.head || []\n const headers = head.map((h) => `<th scope='col' class='govuk-table__header'>${h.html ?? h.text}</th>`)\n const rows = dataTable.rows.map(\n (r) =>\n `<tr class='govuk-table__row'>${r\n .map(\n (c) => `<td class='govuk-table__cell govuk-table__cell--${c.format} ${c.classes}'>${c.html ?? c.text}</td>`,\n )\n .join('')}</tr>`,\n )\n\n return (\n \"<table class='govuk-table'>\" +\n `<thead class='govuk-table__head'>${headers.join('')}</thead>` +\n `<tbody class='govuk-table__body'>${rows.join('')}</tbody>` +\n '</table>'\n )\n }\n\n withHeaderOptions({\n reportQuery,\n columns,\n interactive,\n }: {\n reportQuery?: ReportQuery\n columns: string[]\n interactive: boolean\n }) {\n if (interactive && reportQuery) {\n return this.withHeaderSortOptions(reportQuery)\n }\n return this.withNoHeaderOptions(columns)\n }\n\n withHeaderSortOptions(reportQuery: ReportQuery) {\n this.reportQuery = reportQuery\n this.columns = reportQuery.columns\n this.currentQueryParams = this.reportQuery.toRecordWithFilterPrefix()\n\n return this\n }\n\n withNoHeaderOptions(columns: string[]) {\n this.columns = columns\n return this\n }\n\n buildTable(data: Array<Dict<string>>): DataTable {\n const mappedData = this.mapData(this.sortData ? this.sort(data) : data)\n\n return {\n head: this.mapHeader(),\n rows: mappedData,\n rowCount: data.length,\n colCount: this.columns.length,\n }\n }\n\n withSummaries(reportSummaries: Dict<Array<AsyncSummary>>) {\n this.reportSummaries = reportSummaries\n return this\n }\n\n withSortedData(sortData = true) {\n this.sortData = sortData\n return this\n }\n}\n\nexport { DataTableBuilder }\nexport default DataTableBuilder\n"],
|
|
5
|
-
"mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GAGA,IAAAK,EAAmC,2BAGnCC,EAAuB,uCAGvB,MAAMJ,CAAiB,CACX,OAEF,SAEE,QAAyB,CAAC,EAE1B,gBAA6C,CAAC,EAGhD,YAAkC,KAElC,mBAAiE,KAEjE,WAAa,IAAI,EAAAK,QAEzB,YAAYC,EAAoDC,EAAW,GAAO,CAChF,KAAK,OAASD,EACd,KAAK,SAAWC,CAClB,CAEQ,QAAQC,EAAkB,CAChC,OAAKA,EAEE,KAAK,WAAW,aAAaA,EAAS,2BAA2B,EAFnD,EAGvB,CAEQ,WAAWC,EAAgB,CACjC,OAAKA,EACEA,EAAM,UAAU,EAAG,CAAC,EAAE,YAAY,EAAIA,EAAM,UAAU,CAAC,EAAE,YAAY,EADzD,EAErB,CAEU,OACRC,EACAC,EAAe,GACfC,EAA6D,CAAC,EACtD,CACR,OAAO,KAAK,OACT,OAAQC,GAAM,KAAK,QAAQ,SAASA,EAAE,IAAI,CAAC,EAC3C,IAAKA,GAAM,CAEV,MAAMC,EADgBF,EAAe,KAAMG,GAAMA,EAAE,OAASF,EAAE,IAAI,GACnCA,EAC/B,OAAO,KAAK,QAAQC,EAAOJ,EAASC,CAAY,CAClD,CAAC,CACL,CAEQ,QAAQG,EAAiDJ,EAA8BC,EAAe,GAAI,CAChH,MAAMK,
|
|
6
|
-
"names": ["DataTableBuilder_exports", "__export", "DataTableBuilder", "DataTableBuilder_default", "__toCommonJS", "import_urlHelper", "import_DateMapper", "DateMapper", "fields", "sortData", "isoDate", "value", "rowData", "extraClasses", "overrideFields", "f", "field", "o", "textValue", "fieldFormat", "classes", "isHtml", "cellData", "disableSort", "sortDirection", "url", "createUrlForParameters", "data", "mappedHeaderSummary", "mappedTableData", "mappedFooterSummary", "rows", "mergeFieldNames", "occurrences", "accumulator", "currentRow", "currentCell", "cellValue", "row", "mergedRow", "mergeFieldName", "currentRowCell", "occurrencesOfValue", "c", "fieldName", "template", "reportSummary", "d", "a", "b", "aValue", "bValue", "sortFields", "sortKey", "names", "s", "n", "dataTable", "headers", "h", "r", "reportQuery", "columns", "interactive", "mappedData", "reportSummaries"]
|
|
4
|
+
"sourcesContent": ["import Dict = NodeJS.Dict\nimport ReportQuery from '../../types/ReportQuery'\nimport { Cell, CellFormat, DataTable, SortKey } from './types'\nimport createUrlForParameters from '../urlHelper'\nimport type { SummaryTemplate } from '../../types/Templates'\nimport { AsyncSummary } from '../../types/UserReports'\nimport DateMapper from '../DateMapper/DateMapper'\nimport { components } from '../../types/api'\n\nclass DataTableBuilder {\n protected fields: components['schemas']['FieldDefinition'][]\n\n private sortData: boolean\n\n protected columns: Array<string> = []\n\n protected reportSummaries: Dict<Array<AsyncSummary>> = {}\n\n // Sortable headers only\n private reportQuery: ReportQuery | null = null\n\n private currentQueryParams: NodeJS.Dict<string | Array<string>> | null = null\n\n private dateMapper = new DateMapper()\n\n constructor(fields: components['schemas']['FieldDefinition'][], sortData = false) {\n this.fields = fields\n this.sortData = sortData\n }\n\n private mapDate(isoDate?: string) {\n if (!isoDate) return ''\n\n return this.dateMapper.toDateString(isoDate, 'local-datetime-short-year')\n }\n\n private mapBoolean(value?: string) {\n if (!value) return ''\n return value.substring(0, 1).toUpperCase() + value.substring(1).toLowerCase()\n }\n\n protected mapRow(\n rowData: NodeJS.Dict<string>,\n extraClasses = '',\n overrideFields: components['schemas']['FieldDefinition'][] = [],\n ): Cell[] {\n return this.fields\n .filter((f) => this.columns.includes(f.name))\n .map((f) => {\n const overrideField = overrideFields.find((o) => o.name === f.name)\n const field = overrideField ?? f\n return this.mapCell(field, rowData, extraClasses)\n })\n }\n\n private mapCell(field: components['schemas']['FieldDefinition'], rowData: NodeJS.Dict<string>, extraClasses = '') {\n const displayValue = rowData[field.name]\n const textValue = this.mapCellValue(field, displayValue)\n let fieldFormat: CellFormat = 'string'\n\n let classes = extraClasses\n\n if (field.wordWrap) {\n classes += ` data-table-cell-wrap-${field.wordWrap.toLowerCase()}`\n }\n\n if (field.header) {\n classes += ' govuk-table__header'\n }\n\n if (field.type === 'double' || field.type === 'long' || typeof displayValue === 'number') {\n fieldFormat = 'numeric'\n }\n\n if (fieldFormat === 'string' && displayValue) {\n const wordCount = displayValue.split(' ').length\n if (wordCount > 10) {\n classes += ' data-table-cell-long-string'\n }\n }\n\n const isHtml = field.type === 'HTML'\n const cell: Cell = {\n fieldName: field.name,\n ...(isHtml ? { html: textValue } : { text: textValue }),\n format: fieldFormat,\n classes: classes.trim(),\n }\n\n return cell\n }\n\n protected mapCellValue(field: components['schemas']['FieldDefinition'], cellData?: string) {\n if (field.calculated) {\n return cellData\n }\n\n switch (field.type) {\n case 'boolean':\n return this.mapBoolean(cellData)\n\n case 'date':\n case 'time':\n return this.mapDate(cellData)\n\n default:\n return cellData || ''\n }\n }\n\n protected mapHeader(disableSort = false, extraClasses: string | null = null): Cell[] {\n return this.fields\n .filter((field) => this.columns.includes(field.name))\n .map((f) => {\n if (this.reportQuery && !disableSort) {\n if (f.sortable) {\n let sortDirection = 'none'\n let url = createUrlForParameters(\n this.currentQueryParams || {},\n {\n sortColumn: f.name,\n sortedAsc: 'true',\n },\n this.fields,\n )\n\n if (f.name === this.reportQuery.sortColumn) {\n sortDirection = this.reportQuery.sortedAsc ? 'ascending' : 'descending'\n\n if (this.reportQuery.sortedAsc) {\n url = createUrlForParameters(\n this.currentQueryParams || {},\n {\n sortColumn: f.name,\n sortedAsc: 'false',\n },\n this.fields,\n )\n }\n }\n\n return {\n html:\n `<a ` +\n `data-column=\"${f.name}\" ` +\n `class=\"data-table-header-button data-table-header-button-sort-${sortDirection}\" ` +\n `href=\"${url}\"` +\n `>${f.display}</a>`,\n ...(extraClasses && { classes: extraClasses }),\n }\n }\n }\n return {\n text: f.display,\n ...(extraClasses && { classes: extraClasses }),\n }\n })\n }\n\n protected mapData(data: Array<Dict<string>>): Cell[][] {\n const mappedHeaderSummary = this.mapSummary('table-header')\n const mappedTableData = this.mergeCells(data.map((rowData) => this.mapRow(rowData)))\n const mappedFooterSummary = this.mapSummary('table-footer')\n\n return mappedHeaderSummary.concat(mappedTableData).concat(mappedFooterSummary)\n }\n\n private mergeCells(rows: Cell[][]): Cell[][] {\n const mergeFieldNames = this.fields\n .filter((f) => (<components['schemas']['SummaryField']>f).mergeRows)\n .map((f) => f.name)\n\n if (mergeFieldNames.length === 0) {\n return rows\n }\n\n const occurrences: Dict<Dict<number>> = {}\n mergeFieldNames.forEach((f) => {\n occurrences[f] = rows.reduce((accumulator: Dict<number>, currentRow) => {\n const currentCell = this.getCellByFieldName(currentRow, f)\n let cellValue = ''\n if (currentCell) {\n cellValue = currentCell.text || currentCell.html || ''\n }\n\n return {\n ...accumulator,\n [cellValue]: (accumulator[cellValue] ?? 0) + 1,\n }\n }, {})\n })\n\n return rows.map((row) => {\n let mergedRow = [...row]\n\n mergeFieldNames.forEach((mergeFieldName) => {\n const currentRowCell = this.getCellByFieldName(row, mergeFieldName)\n let cellValue\n let occurrencesOfValue\n if (currentRowCell && occurrences[mergeFieldName]) {\n cellValue = currentRowCell.text || currentRowCell.html || ''\n occurrencesOfValue = occurrences[mergeFieldName][cellValue]\n\n switch (occurrencesOfValue) {\n case -1:\n mergedRow = mergedRow.filter((c) => c.fieldName !== mergeFieldName)\n break\n\n case 1:\n break\n\n default:\n currentRowCell.rowspan = occurrencesOfValue\n occurrences[mergeFieldName][cellValue] = -1\n }\n }\n })\n\n return mergedRow\n })\n }\n\n private getCellByFieldName(row: Cell[], fieldName: string) {\n return row.find((c) => c.fieldName === fieldName)\n }\n\n private mapSummary(template: SummaryTemplate): Cell[][] {\n if (this.reportSummaries[template]) {\n return this.reportSummaries[template].flatMap((reportSummary) =>\n reportSummary.data.map((rowData) =>\n this.mapRow(\n rowData,\n `dpr-report-summary-cell dpr-report-summary-cell-${template}`,\n <components['schemas']['FieldDefinition'][]>reportSummary.fields,\n ),\n ),\n )\n }\n return []\n }\n\n protected sort(data: Dict<string>[]): Dict<string>[] {\n return this.appendSortKeyToData(data)\n .sort(this.sortKeyComparison())\n .map((d: SortKey) => ({\n ...d,\n }))\n }\n\n protected sortKeyComparison() {\n return (a: SortKey, b: SortKey) => {\n const aValue = a.sortKey\n const bValue = b.sortKey\n\n if (aValue === bValue) {\n return 0\n }\n\n if (aValue < bValue) {\n return -1\n }\n\n return 1\n }\n }\n\n private appendSortKeyToData(\n data: Dict<string>[],\n fields: components['schemas']['FieldDefinition'][] | null = null,\n ): SortKey[] {\n const sortFields = fields || this.fields\n\n return data.map((rowData) => {\n const sortKey = this.getSortKey(rowData, sortFields)\n\n return {\n ...rowData,\n sortKey,\n }\n })\n }\n\n protected mapNamesToFields(names: string[]): components['schemas']['FieldDefinition'][] {\n return names.map((s) => this.fields.find((f) => f.name === s)).filter((n) => n !== undefined)\n }\n\n protected getSortKey(rowData: NodeJS.Dict<string>, sortFields: components['schemas']['FieldDefinition'][]) {\n return sortFields\n .map((f) => {\n const value = rowData[f.name]\n if (value && this.dateMapper.isDate(value)) {\n return this.dateMapper.toDateString(value, 'iso')\n }\n\n return this.mapCellValue(f, value)\n })\n .join('-')\n .toLowerCase()\n }\n\n protected convertDataTableToHtml(dataTable: DataTable): string {\n const head = dataTable.head || []\n const headers = head.map((h) => `<th scope='col' class='govuk-table__header'>${h.html ?? h.text}</th>`)\n const rows = dataTable.rows.map(\n (r) =>\n `<tr class='govuk-table__row'>${r\n .map(\n (c) => `<td class='govuk-table__cell govuk-table__cell--${c.format} ${c.classes}'>${c.html ?? c.text}</td>`,\n )\n .join('')}</tr>`,\n )\n\n return (\n \"<table class='govuk-table'>\" +\n `<thead class='govuk-table__head'>${headers.join('')}</thead>` +\n `<tbody class='govuk-table__body'>${rows.join('')}</tbody>` +\n '</table>'\n )\n }\n\n withHeaderOptions({\n reportQuery,\n columns,\n interactive,\n }: {\n reportQuery?: ReportQuery\n columns: string[]\n interactive: boolean\n }) {\n if (interactive && reportQuery) {\n return this.withHeaderSortOptions(reportQuery)\n }\n return this.withNoHeaderOptions(columns)\n }\n\n withHeaderSortOptions(reportQuery: ReportQuery) {\n this.reportQuery = reportQuery\n this.columns = reportQuery.columns\n this.currentQueryParams = this.reportQuery.toRecordWithFilterPrefix()\n\n return this\n }\n\n withNoHeaderOptions(columns: string[]) {\n this.columns = columns\n return this\n }\n\n buildTable(data: Array<Dict<string>>): DataTable {\n const mappedData = this.mapData(this.sortData ? this.sort(data) : data)\n\n return {\n head: this.mapHeader(),\n rows: mappedData,\n rowCount: data.length,\n colCount: this.columns.length,\n }\n }\n\n withSummaries(reportSummaries: Dict<Array<AsyncSummary>>) {\n this.reportSummaries = reportSummaries\n return this\n }\n\n withSortedData(sortData = true) {\n this.sortData = sortData\n return this\n }\n}\n\nexport { DataTableBuilder }\nexport default DataTableBuilder\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["DataTableBuilder_exports", "__export", "DataTableBuilder", "DataTableBuilder_default", "__toCommonJS", "import_urlHelper", "import_DateMapper", "DateMapper", "fields", "sortData", "isoDate", "value", "rowData", "extraClasses", "overrideFields", "f", "field", "o", "displayValue", "textValue", "fieldFormat", "classes", "isHtml", "cellData", "disableSort", "sortDirection", "url", "createUrlForParameters", "data", "mappedHeaderSummary", "mappedTableData", "mappedFooterSummary", "rows", "mergeFieldNames", "occurrences", "accumulator", "currentRow", "currentCell", "cellValue", "row", "mergedRow", "mergeFieldName", "currentRowCell", "occurrencesOfValue", "c", "fieldName", "template", "reportSummary", "d", "a", "b", "aValue", "bValue", "sortFields", "sortKey", "names", "s", "n", "dataTable", "headers", "h", "r", "reportQuery", "columns", "interactive", "mappedData", "reportSummaries"]
|
|
7
7
|
}
|
|
@@ -54,7 +54,8 @@ class DataTableBuilder {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
private mapCell(field: components['schemas']['FieldDefinition'], rowData: NodeJS.Dict<string>, extraClasses = '') {
|
|
57
|
-
const
|
|
57
|
+
const displayValue = rowData[field.name]
|
|
58
|
+
const textValue = this.mapCellValue(field, displayValue)
|
|
58
59
|
let fieldFormat: CellFormat = 'string'
|
|
59
60
|
|
|
60
61
|
let classes = extraClasses
|
|
@@ -67,10 +68,17 @@ class DataTableBuilder {
|
|
|
67
68
|
classes += ' govuk-table__header'
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
if (field.type === 'double' || field.type === 'long') {
|
|
71
|
+
if (field.type === 'double' || field.type === 'long' || typeof displayValue === 'number') {
|
|
71
72
|
fieldFormat = 'numeric'
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
if (fieldFormat === 'string' && displayValue) {
|
|
76
|
+
const wordCount = displayValue.split(' ').length
|
|
77
|
+
if (wordCount > 10) {
|
|
78
|
+
classes += ' data-table-cell-long-string'
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
74
82
|
const isHtml = field.type === 'HTML'
|
|
75
83
|
const cell: Cell = {
|
|
76
84
|
fieldName: field.name,
|
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": "4.26.
|
|
4
|
+
"version": "4.26.3",
|
|
5
5
|
"main": "dpr/all.mjs",
|
|
6
6
|
"sass": "dpr/all.scss",
|
|
7
7
|
"engines": {
|
|
@@ -191,7 +191,6 @@
|
|
|
191
191
|
"audit-ci": "^6.6.1",
|
|
192
192
|
"autoprefixer": "^10.4.15",
|
|
193
193
|
"axe-core": "^4.9.0",
|
|
194
|
-
"body-parser": "^1.20.2",
|
|
195
194
|
"cssnano": "^6.0.1",
|
|
196
195
|
"cypress": "^14.5.4",
|
|
197
196
|
"cypress-axe": "^1.6.0",
|
|
@@ -233,7 +232,7 @@
|
|
|
233
232
|
"require-dir": "^1.2.0",
|
|
234
233
|
"sass": "^1.66.1",
|
|
235
234
|
"serve": "^14.2.4",
|
|
236
|
-
"superagent": "^10.
|
|
235
|
+
"superagent": "^10.3.0",
|
|
237
236
|
"ts-jest": "^29.1.1",
|
|
238
237
|
"ts-node": "^10.9.2",
|
|
239
238
|
"tsconfig-paths": "^4.2.0",
|
|
@@ -244,4 +243,4 @@
|
|
|
244
243
|
"peerDependencies": {
|
|
245
244
|
"jquery": "^3.7.1"
|
|
246
245
|
}
|
|
247
|
-
}
|
|
246
|
+
}
|