@ministryofjustice/hmpps-digital-prison-reporting-frontend 4.26.2 → 4.26.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 (45) hide show
  1. package/dpr/all.scss +118 -15
  2. package/dpr/components/_catalogue/catalogue-list/styles.scss +1 -1
  3. package/dpr/components/_reports/report/view.njk +2 -2
  4. package/dpr/components/_reports/report-data-table/style.scss +94 -2
  5. package/dpr/components/_reports/report-data-table/view.njk +2 -2
  6. package/dpr/components/_reports/report-data-table-wrapper/view.njk +3 -3
  7. package/dpr/components/_reports/report-heading/styles.scss +12 -3
  8. package/dpr/components/_reports/report-summary-table/styles.scss +0 -1
  9. package/dpr/components/_reports/report-totals/style.scss +1 -1
  10. package/dpr/components/_reports/report-wrapper/view.njk +1 -1
  11. package/dpr/components/report-list/style.scss +10 -7
  12. package/dpr/routes/journeys/request-report/controller.js +1 -1
  13. package/dpr/routes/journeys/request-report/controller.js.map +2 -2
  14. package/dpr/routes/journeys/request-report/controller.ts +5 -4
  15. package/dpr/routes/journeys/request-report/filters/controller.js +1 -1
  16. package/dpr/routes/journeys/request-report/filters/controller.js.map +2 -2
  17. package/dpr/routes/journeys/request-report/filters/controller.ts +4 -3
  18. package/dpr/routes/journeys/request-report/status/controller.js +1 -1
  19. package/dpr/routes/journeys/request-report/status/controller.js.map +2 -2
  20. package/dpr/routes/journeys/request-report/status/controller.ts +1 -0
  21. package/dpr/routes/journeys/view-report/async/controller.js +1 -1
  22. package/dpr/routes/journeys/view-report/async/controller.js.map +2 -2
  23. package/dpr/routes/journeys/view-report/async/controller.ts +2 -2
  24. package/dpr/routes/journeys/view-report/async/dashboard/controller.js +1 -1
  25. package/dpr/routes/journeys/view-report/async/dashboard/controller.js.map +2 -2
  26. package/dpr/routes/journeys/view-report/async/dashboard/controller.ts +1 -0
  27. package/dpr/routes/journeys/view-report/async/report/controller.js +1 -1
  28. package/dpr/routes/journeys/view-report/async/report/controller.js.map +2 -2
  29. package/dpr/routes/journeys/view-report/async/report/controller.ts +1 -0
  30. package/dpr/routes/journeys/view-report/async/report/tests.cy.js +1 -1
  31. package/dpr/routes/journeys/view-report/async/report/tests.cy.js.map +3 -3
  32. package/dpr/routes/journeys/view-report/async/report/tests.cy.ts +841 -841
  33. package/dpr/routes/journeys/view-report/controller.js +1 -1
  34. package/dpr/routes/journeys/view-report/controller.js.map +2 -2
  35. package/dpr/routes/journeys/view-report/controller.ts +2 -2
  36. package/dpr/routes/journeys/view-report/sync/dashboard/controller.js +1 -1
  37. package/dpr/routes/journeys/view-report/sync/dashboard/controller.js.map +2 -2
  38. package/dpr/routes/journeys/view-report/sync/dashboard/controller.ts +1 -0
  39. package/dpr/routes/journeys/view-report/sync/report/controller.js +1 -1
  40. package/dpr/routes/journeys/view-report/sync/report/controller.js.map +2 -2
  41. package/dpr/routes/journeys/view-report/sync/report/controller.ts +3 -2
  42. package/dpr/utils/DataTableBuilder/DataTableBuilder.js +1 -1
  43. package/dpr/utils/DataTableBuilder/DataTableBuilder.js.map +3 -3
  44. package/dpr/utils/DataTableBuilder/DataTableBuilder.ts +10 -2
  45. package/package.json +3 -4
@@ -1,2 +1,2 @@
1
- "use strict";var c=Object.create;var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var y=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 u(r))!f.call(o,t)&&t!==e&&s(o,t,{get:()=>r[t],enumerable:!(a=d(r,t))||a.enumerable});return o};var l=(o,r,e)=>(e=o!=null?c(y(o)):{},n(r||!o||!o.__esModule?s(e,"default",{value:o,enumerable:!0}):e,o)),v=o=>n(s({},"__esModule",{value:!0}),o);var H={};h(H,{ViewReportController:()=>i,default:()=>g});module.exports=v(H);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.params,error:t,params:r.params})}}var g=i;0&&(module.exports={ViewReportController});
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.error).formatError()\n\n res.render(`dpr/routes/journeys/view-report/error`, {\n layoutPath: this.layoutPath,\n ...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,KAAK,KAAK,EAAE,YAAY,EAE3DC,EAAI,OAAO,wCAAyC,CAClD,WAAY,KAAK,WACjB,GAAGD,EAAI,KACP,GAAGA,EAAI,OACP,MAAAI,EACA,OAAQJ,EAAI,MACd,CAAC,CACH,CACF,CAGA,IAAON,EAAQD",
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.error).formatError()
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})},l=(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)):{},l(r||!e||!e.__esModule?a(t,"default",{value:e,enumerable:!0}):t,e)),v=e=>l(a({},"__esModule",{value:!0}),e);var D={};f(D,{ViewSyncDashboardController:()=>n,default:()=>w});module.exports=v(D);var d=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.title="Dashboard Failed",r.body.errorDescription="We were unable to show this dashboard for the following reason:",r.body.error=new d.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});
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 w=(t,e)=>{for(var r in e)a(t,r,{get:e[r],enumerable:!0})},y=(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)):{},y(e||!t||!t.__esModule?a(r,"default",{value:t,enumerable:!0}):r,t)),b=t=>y(a({},"__esModule",{value:!0}),t);var F={};w(F,{ViewSyncReportController:()=>u,default:()=>E});module.exports=b(F);var l=i(require("../../../../../utils/ErrorHandler")),d=i(require("./utils")),n=require("../../../../../components/_filters/filtersTypeEnum"),c=i(require("../../../../../utils/Personalisation/personalisationUtils")),p=i(require("../../utils"));class u{layoutPath;services;constructor(e,r){this.layoutPath=e,this.services=r}GET=async(e,r,s)=>{try{const o=await d.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.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},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},s()}};applyFilters=async(e,r,s)=>{await p.default.applyReportInteractiveQuery(e,r,this.services,"filters")};applyColumns=async(e,r,s)=>{await p.default.applyReportInteractiveQuery(e,r,this.services,"columns")}}var E=u;0&&(module.exports={ViewSyncReportController});
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,GAAGL,EAAI,IACT,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,GAAGL,EAAI,IACT,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",
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 m=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)m(i,t,{get:e[t],enumerable:!0})},d=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of b(e))!C.call(i,a)&&a!==t&&m(i,a,{get:()=>e[a],enumerable:!(r=D(e,a))||r.enumerable});return i};var h=(i,e,t)=>(t=i!=null?g(S(i)):{},d(e||!i||!i.__esModule?m(t,"default",{value:i,enumerable:!0}):t,i)),v=i=>d(m({},"__esModule",{value:!0}),i);var K={};w(K,{DataTableBuilder:()=>u,default:()=>F});module.exports=v(K);var p=h(require("../urlHelper")),y=h(require("../DateMapper/DateMapper"));class u{fields;sortData;columns=[];reportSummaries={};reportQuery=null;currentQueryParams=null;dateMapper=new y.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="",r=[]){return this.fields.filter(a=>this.columns.includes(a.name)).map(a=>{const o=r.find(n=>n.name===a.name)??a;return this.mapCell(o,e,t)})}mapCell(e,t,r=""){const a=this.mapCellValue(e,t[e.name]);let s="string",o=r;e.wordWrap&&(o+=` data-table-cell-wrap-${e.wordWrap.toLowerCase()}`),e.header&&(o+=" govuk-table__header"),(e.type==="double"||e.type==="long")&&(s="numeric");const n=e.type==="HTML";return{fieldName:e.name,...n?{html:a}:{text:a},format:s,classes:o.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(r=>this.columns.includes(r.name)).map(r=>{if(this.reportQuery&&!e&&r.sortable){let a="none",s=(0,p.default)(this.currentQueryParams||{},{sortColumn:r.name,sortedAsc:"true"},this.fields);return r.name===this.reportQuery.sortColumn&&(a=this.reportQuery.sortedAsc?"ascending":"descending",this.reportQuery.sortedAsc&&(s=(0,p.default)(this.currentQueryParams||{},{sortColumn:r.name,sortedAsc:"false"},this.fields))),{html:`<a data-column="${r.name}" class="data-table-header-button data-table-header-button-sort-${a}" href="${s}">${r.display}</a>`,...t&&{classes:t}}}return{text:r.display,...t&&{classes:t}}})}mapData(e){const t=this.mapSummary("table-header"),r=this.mergeCells(e.map(s=>this.mapRow(s))),a=this.mapSummary("table-footer");return t.concat(r).concat(a)}mergeCells(e){const t=this.fields.filter(a=>a.mergeRows).map(a=>a.name);if(t.length===0)return e;const r={};return t.forEach(a=>{r[a]=e.reduce((s,o)=>{const n=this.getCellByFieldName(o,a);let l="";return n&&(l=n.text||n.html||""),{...s,[l]:(s[l]??0)+1}},{})}),e.map(a=>{let s=[...a];return t.forEach(o=>{const n=this.getCellByFieldName(a,o);let l,c;if(n&&r[o])switch(l=n.text||n.html||"",c=r[o][l],c){case-1:s=s.filter(f=>f.fieldName!==o);break;case 1:break;default:n.rowspan=c,r[o][l]=-1}}),s})}getCellByFieldName(e,t){return e.find(r=>r.fieldName===t)}mapSummary(e){return this.reportSummaries[e]?this.reportSummaries[e].flatMap(t=>t.data.map(r=>this.mapRow(r,`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 r=e.sortKey,a=t.sortKey;return r===a?0:r<a?-1:1}}appendSortKeyToData(e,t=null){const r=t||this.fields;return e.map(a=>{const s=this.getSortKey(a,r);return{...a,sortKey:s}})}mapNamesToFields(e){return e.map(t=>this.fields.find(r=>r.name===t)).filter(t=>t!==void 0)}getSortKey(e,t){return t.map(r=>{const a=e[r.name];return a&&this.dateMapper.isDate(a)?this.dateMapper.toDateString(a,"iso"):this.mapCellValue(r,a)}).join("-").toLowerCase()}convertDataTableToHtml(e){const r=(e.head||[]).map(s=>`<th scope='col' class='govuk-table__header'>${s.html??s.text}</th>`),a=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'>${r.join("")}</thead><tbody class='govuk-table__body'>${a.join("")}</tbody></table>`}withHeaderOptions({reportQuery:e,columns:t,interactive:r}){return r&&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});
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": "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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", "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 textValue = this.mapCellValue(field, rowData[field.name])
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.2",
4
+ "version": "4.26.4",
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.2.3",
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
+ }