@ministryofjustice/hmpps-digital-prison-reporting-frontend 4.26.5 → 4.26.6

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.
@@ -1,2 +1,2 @@
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});
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,t)=>{for(var e in t)c(i,e,{get:t[e],enumerable:!0})},h=(i,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of b(t))!C.call(i,r)&&r!==e&&c(i,r,{get:()=>t[r],enumerable:!(a=D(t,r))||a.enumerable});return i};var y=(i,t,e)=>(e=i!=null?g(S(i)):{},h(t||!i||!i.__esModule?c(e,"default",{value:i,enumerable:!0}):e,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(t,e=!1){this.fields=t,this.sortData=e}mapDate(t){return t?this.dateMapper.toDateString(t,"local-datetime-short-year"):""}mapBoolean(t){return t?t.substring(0,1).toUpperCase()+t.substring(1).toLowerCase():""}mapRow(t,e="",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,t,e)})}mapCell(t,e,a=""){const r=e[t.name],s=this.mapCellValue(t,r);let o="string",n=a;t.wordWrap&&(n+=` data-table-cell-wrap-${t.wordWrap.toLowerCase()}`),t.header&&(n+=" govuk-table__header"),(t.type==="double"||t.type==="long"||typeof r=="number")&&(o="numeric"),o==="string"&&r&&typeof r=="string"&&r.split(" ").length>10&&(n+=" data-table-cell-long-string");const l=t.type==="HTML";return{fieldName:t.name,...l?{html:s}:{text:s},format:o,classes:n.trim()}}mapCellValue(t,e){if(t.calculated)return e;switch(t.type){case"boolean":return this.mapBoolean(e);case"date":case"time":return this.mapDate(e);default:return e||""}}mapHeader(t=!1,e=null){return this.fields.filter(a=>this.columns.includes(a.name)).map(a=>{if(this.reportQuery&&!t&&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>`,...e&&{classes:e}}}return{text:a.display,...e&&{classes:e}}})}mapData(t){const e=this.mapSummary("table-header"),a=this.mergeCells(t.map(s=>this.mapRow(s))),r=this.mapSummary("table-footer");return e.concat(a).concat(r)}mergeCells(t){const e=this.fields.filter(r=>r.mergeRows).map(r=>r.name);if(e.length===0)return t;const a={};return e.forEach(r=>{a[r]=t.reduce((s,o)=>{const n=this.getCellByFieldName(o,r);let l="";return n&&(l=n.text||n.html||""),{...s,[l]:(s[l]??0)+1}},{})}),t.map(r=>{let s=[...r];return e.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(t,e){return t.find(a=>a.fieldName===e)}mapSummary(t){return this.reportSummaries[t]?this.reportSummaries[t].flatMap(e=>e.data.map(a=>this.mapRow(a,`dpr-report-summary-cell dpr-report-summary-cell-${t}`,e.fields))):[]}sort(t){return this.appendSortKeyToData(t).sort(this.sortKeyComparison()).map(e=>({...e}))}sortKeyComparison(){return(t,e)=>{const a=t.sortKey,r=e.sortKey;return a===r?0:a<r?-1:1}}appendSortKeyToData(t,e=null){const a=e||this.fields;return t.map(r=>{const s=this.getSortKey(r,a);return{...r,sortKey:s}})}mapNamesToFields(t){return t.map(e=>this.fields.find(a=>a.name===e)).filter(e=>e!==void 0)}getSortKey(t,e){return e.map(a=>{const r=t[a.name];return r&&this.dateMapper.isDate(r)?this.dateMapper.toDateString(r,"iso"):this.mapCellValue(a,r)}).join("-").toLowerCase()}convertDataTableToHtml(t){const a=(t.head||[]).map(s=>`<th scope='col' class='govuk-table__header'>${s.html??s.text}</th>`),r=t.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:t,columns:e,interactive:a}){return a&&t?this.withHeaderSortOptions(t):this.withNoHeaderOptions(e)}withHeaderSortOptions(t){return this.reportQuery=t,this.columns=t.columns,this.currentQueryParams=this.reportQuery.toRecordWithFilterPrefix(),this}withNoHeaderOptions(t){return this.columns=t,this}buildTable(t){const e=this.mapData(this.sortData?this.sort(t):t);return{head:this.mapHeader(),rows:e,rowCount:t.length,colCount:this.columns.length}}withSummaries(t){return this.reportSummaries=t,this}withSortedData(t=!0){return this.sortData=t,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 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": "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,EAAeN,EAAQI,EAAM,IAAI,EACjCG,EAAY,KAAK,aAAaH,EAAOE,CAAY,EACvD,IAAIE,EAA0B,SAE1BC,EAAUR,EAEVG,EAAM,WACRK,GAAW,yBAAyBL,EAAM,SAAS,YAAY,CAAC,IAG9DA,EAAM,SACRK,GAAW,yBAGTL,EAAM,OAAS,UAAYA,EAAM,OAAS,QAAU,OAAOE,GAAiB,YAC9EE,EAAc,WAGZA,IAAgB,UAAYF,GACZA,EAAa,MAAM,GAAG,EAAE,OAC1B,KACdG,GAAW,gCAIf,MAAMC,EAASN,EAAM,OAAS,OAQ9B,MAPmB,CACjB,UAAWA,EAAM,KACjB,GAAIM,EAAS,CAAE,KAAMH,CAAU,EAAI,CAAE,KAAMA,CAAU,EACrD,OAAQC,EACR,QAASC,EAAQ,KAAK,CACxB,CAGF,CAEU,aAAaL,EAAiDO,EAAmB,CACzF,GAAIP,EAAM,WACR,OAAOO,EAGT,OAAQP,EAAM,KAAM,CAClB,IAAK,UACH,OAAO,KAAK,WAAWO,CAAQ,EAEjC,IAAK,OACL,IAAK,OACH,OAAO,KAAK,QAAQA,CAAQ,EAE9B,QACE,OAAOA,GAAY,EACvB,CACF,CAEU,UAAUC,EAAc,GAAOX,EAA8B,KAAc,CACnF,OAAO,KAAK,OACT,OAAQG,GAAU,KAAK,QAAQ,SAASA,EAAM,IAAI,CAAC,EACnD,IAAKD,GAAM,CACV,GAAI,KAAK,aAAe,CAACS,GACnBT,EAAE,SAAU,CACd,IAAIU,EAAgB,OAChBC,KAAM,EAAAC,SACR,KAAK,oBAAsB,CAAC,EAC5B,CACE,WAAYZ,EAAE,KACd,UAAW,MACb,EACA,KAAK,MACP,EAEA,OAAIA,EAAE,OAAS,KAAK,YAAY,aAC9BU,EAAgB,KAAK,YAAY,UAAY,YAAc,aAEvD,KAAK,YAAY,YACnBC,KAAM,EAAAC,SACJ,KAAK,oBAAsB,CAAC,EAC5B,CACE,WAAYZ,EAAE,KACd,UAAW,OACb,EACA,KAAK,MACP,IAIG,CACL,KACE,mBACgBA,EAAE,IAAI,mEAC2CU,CAAa,WACrEC,CAAG,KACRX,EAAE,OAAO,OACf,GAAIF,GAAgB,CAAE,QAASA,CAAa,CAC9C,CACF,CAEF,MAAO,CACL,KAAME,EAAE,QACR,GAAIF,GAAgB,CAAE,QAASA,CAAa,CAC9C,CACF,CAAC,CACL,CAEU,QAAQe,EAAqC,CACrD,MAAMC,EAAsB,KAAK,WAAW,cAAc,EACpDC,EAAkB,KAAK,WAAWF,EAAK,IAAKhB,GAAY,KAAK,OAAOA,CAAO,CAAC,CAAC,EAC7EmB,EAAsB,KAAK,WAAW,cAAc,EAE1D,OAAOF,EAAoB,OAAOC,CAAe,EAAE,OAAOC,CAAmB,CAC/E,CAEQ,WAAWC,EAA0B,CAC3C,MAAMC,EAAkB,KAAK,OAC1B,OAAQlB,GAA8CA,EAAG,SAAS,EAClE,IAAKA,GAAMA,EAAE,IAAI,EAEpB,GAAIkB,EAAgB,SAAW,EAC7B,OAAOD,EAGT,MAAME,EAAkC,CAAC,EACzC,OAAAD,EAAgB,QAASlB,GAAM,CAC7BmB,EAAYnB,CAAC,EAAIiB,EAAK,OAAO,CAACG,EAA2BC,IAAe,CACtE,MAAMC,EAAc,KAAK,mBAAmBD,EAAYrB,CAAC,EACzD,IAAIuB,EAAY,GAChB,OAAID,IACFC,EAAYD,EAAY,MAAQA,EAAY,MAAQ,IAG/C,CACL,GAAGF,EACH,CAACG,CAAS,GAAIH,EAAYG,CAAS,GAAK,GAAK,CAC/C,CACF,EAAG,CAAC,CAAC,CACP,CAAC,EAEMN,EAAK,IAAKO,GAAQ,CACvB,IAAIC,EAAY,CAAC,GAAGD,CAAG,EAEvB,OAAAN,EAAgB,QAASQ,GAAmB,CAC1C,MAAMC,EAAiB,KAAK,mBAAmBH,EAAKE,CAAc,EAClE,IAAIH,EACAK,EACJ,GAAID,GAAkBR,EAAYO,CAAc,EAI9C,OAHAH,EAAYI,EAAe,MAAQA,EAAe,MAAQ,GAC1DC,EAAqBT,EAAYO,CAAc,EAAEH,CAAS,EAElDK,EAAoB,CAC1B,IAAK,GACHH,EAAYA,EAAU,OAAQI,GAAMA,EAAE,YAAcH,CAAc,EAClE,MAEF,IAAK,GACH,MAEF,QACEC,EAAe,QAAUC,EACzBT,EAAYO,CAAc,EAAEH,CAAS,EAAI,EAC7C,CAEJ,CAAC,EAEME,CACT,CAAC,CACH,CAEQ,mBAAmBD,EAAaM,EAAmB,CACzD,OAAON,EAAI,KAAMK,GAAMA,EAAE,YAAcC,CAAS,CAClD,CAEQ,WAAWC,EAAqC,CACtD,OAAI,KAAK,gBAAgBA,CAAQ,EACxB,KAAK,gBAAgBA,CAAQ,EAAE,QAASC,GAC7CA,EAAc,KAAK,IAAKnC,GACtB,KAAK,OACHA,EACA,mDAAmDkC,CAAQ,GACfC,EAAc,MAC5D,CACF,CACF,EAEK,CAAC,CACV,CAEU,KAAKnB,EAAsC,CACnD,OAAO,KAAK,oBAAoBA,CAAI,EACjC,KAAK,KAAK,kBAAkB,CAAC,EAC7B,IAAKoB,IAAgB,CACpB,GAAGA,CACL,EAAE,CACN,CAEU,mBAAoB,CAC5B,MAAO,CAACC,EAAYC,IAAe,CACjC,MAAMC,EAASF,EAAE,QACXG,EAASF,EAAE,QAEjB,OAAIC,IAAWC,EACN,EAGLD,EAASC,EACJ,GAGF,CACT,CACF,CAEQ,oBACNxB,EACApB,EAA4D,KACjD,CACX,MAAM6C,EAAa7C,GAAU,KAAK,OAElC,OAAOoB,EAAK,IAAKhB,GAAY,CAC3B,MAAM0C,EAAU,KAAK,WAAW1C,EAASyC,CAAU,EAEnD,MAAO,CACL,GAAGzC,EACH,QAAA0C,CACF,CACF,CAAC,CACH,CAEU,iBAAiBC,EAA6D,CACtF,OAAOA,EAAM,IAAKC,GAAM,KAAK,OAAO,KAAMzC,GAAMA,EAAE,OAASyC,CAAC,CAAC,EAAE,OAAQC,GAAMA,IAAM,MAAS,CAC9F,CAEU,WAAW7C,EAA8ByC,EAAwD,CACzG,OAAOA,EACJ,IAAKtC,GAAM,CACV,MAAMJ,EAAQC,EAAQG,EAAE,IAAI,EAC5B,OAAIJ,GAAS,KAAK,WAAW,OAAOA,CAAK,EAChC,KAAK,WAAW,aAAaA,EAAO,KAAK,EAG3C,KAAK,aAAaI,EAAGJ,CAAK,CACnC,CAAC,EACA,KAAK,GAAG,EACR,YAAY,CACjB,CAEU,uBAAuB+C,EAA8B,CAE7D,MAAMC,GADOD,EAAU,MAAQ,CAAC,GACX,IAAKE,GAAM,+CAA+CA,EAAE,MAAQA,EAAE,IAAI,OAAO,EAChG5B,EAAO0B,EAAU,KAAK,IACzBG,GACC,gCAAgCA,EAC7B,IACEjB,GAAM,mDAAmDA,EAAE,MAAM,IAAIA,EAAE,OAAO,KAAKA,EAAE,MAAQA,EAAE,IAAI,OACtG,EACC,KAAK,EAAE,CAAC,OACf,EAEA,MACE,+DACoCe,EAAQ,KAAK,EAAE,CAAC,4CAChB3B,EAAK,KAAK,EAAE,CAAC,kBAGrD,CAEA,kBAAkB,CAChB,YAAA8B,EACA,QAAAC,EACA,YAAAC,CACF,EAIG,CACD,OAAIA,GAAeF,EACV,KAAK,sBAAsBA,CAAW,EAExC,KAAK,oBAAoBC,CAAO,CACzC,CAEA,sBAAsBD,EAA0B,CAC9C,YAAK,YAAcA,EACnB,KAAK,QAAUA,EAAY,QAC3B,KAAK,mBAAqB,KAAK,YAAY,yBAAyB,EAE7D,IACT,CAEA,oBAAoBC,EAAmB,CACrC,YAAK,QAAUA,EACR,IACT,CAEA,WAAWnC,EAAsC,CAC/C,MAAMqC,EAAa,KAAK,QAAQ,KAAK,SAAW,KAAK,KAAKrC,CAAI,EAAIA,CAAI,EAEtE,MAAO,CACL,KAAM,KAAK,UAAU,EACrB,KAAMqC,EACN,SAAUrC,EAAK,OACf,SAAU,KAAK,QAAQ,MACzB,CACF,CAEA,cAAcsC,EAA4C,CACxD,YAAK,gBAAkBA,EAChB,IACT,CAEA,eAAezD,EAAW,GAAM,CAC9B,YAAK,SAAWA,EACT,IACT,CACF,CAGA,IAAON,EAAQD",
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 && typeof displayValue === 'string') {\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
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
  }
@@ -72,7 +72,7 @@ class DataTableBuilder {
72
72
  fieldFormat = 'numeric'
73
73
  }
74
74
 
75
- if (fieldFormat === 'string' && displayValue) {
75
+ if (fieldFormat === 'string' && displayValue && typeof displayValue === 'string') {
76
76
  const wordCount = displayValue.split(' ').length
77
77
  if (wordCount > 10) {
78
78
  classes += ' data-table-cell-long-string'
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.5",
4
+ "version": "4.26.6",
5
5
  "main": "dpr/all.mjs",
6
6
  "sass": "dpr/all.scss",
7
7
  "engines": {
@@ -223,7 +223,7 @@
223
223
  "markdown-it-anchor": "^8.6.7",
224
224
  "mocha-junit-reporter": "^2.2.1",
225
225
  "mockdate": "^3.0.5",
226
- "nock": "^13.3.8",
226
+ "nock": "^14.0.10",
227
227
  "node-html-parser": "^6.1.5",
228
228
  "npm-run-all": "^4.1.5",
229
229
  "openapi-typescript": "^7.8.0",