UNPKG

@ministryofjustice/hmpps-digital-prison-reporting-frontend

Version:

The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.

189 lines (186 loc) 6.63 kB
import DatasetHelper, { getTimestampColumn, getDateValue } from '../../../utils/Dashboards/VisualisationDatasetHelper.js'; import ListSchemas from './validate.js'; import { apiDateToUi } from '../../../utils/dateHelper.js'; const createList = (listDefinition, dashboardData) => { ListSchemas.ListSchema.parse(listDefinition); const { columns, options } = listDefinition; const { measures, keys } = columns; const listOptions = options; const columnsAsList = listOptions?.columnsAsList; const showAllData = (!measures && !keys) || (!measures.length && !keys); let datasetData = [...dashboardData]; if (listOptions?.showLatest ?? true) { const dateColumn = DatasetHelper.getTimestampColumn(columns); datasetData = DatasetHelper.getLastestDataset(datasetData, dateColumn); } let head; let rows; let ts; if (showAllData) { ({ head, rows, ts } = createFullList(listDefinition, datasetData)); } else if (columnsAsList) { ({ head, rows, ts } = createListFromColumns(listDefinition, datasetData)); } else { ({ head, rows, ts } = creatListFromRows(listDefinition, datasetData)); } if (rows.length && measures) rows = sumColumns(rows, measures); return { table: { head, rows, }, ts, }; }; const createListFromColumns = (listDefinition, dashboardData) => { const { columns } = listDefinition; const { keys, measures } = columns; const groupKey = DatasetHelper.getGroupKey(dashboardData, keys || []); const dateColumn = getTimestampColumn(columns); const dateData = getDateValue(dashboardData, dateColumn); const ts = dateData?.value ? `${dateData.value}` : ''; const head = []; head.push({ html: '<p class="govuk-visually-hidden">list values</p>', }); dashboardData.forEach(row => { head.push({ text: groupKey ? `${row[groupKey.id].raw}` : '', }); }); const rows = []; measures.forEach(measure => { rows.push([{ text: measure.display }]); }); measures.forEach((measure, index) => { dashboardData.forEach(row => { rows[index].push({ text: `${row[measure.id].raw}` }); }); }); return { rows, head, ts, }; }; /** * Creates the table rows for a dashboard list visualisation * - If no measures are passed in it will present the full data * * @param {DashboardDataResponse[]} data * @param {components['schemas']['DashboardVisualisationColumnDefinition'][]} [measures] * @return {*} {MoJTableRow[][]} */ const createTableRows = (data, measures) => { if (!data || data.length === 0 || !data[0]) { return []; } // Set the list data using the measure if (measures && measures.length) { return data.map(dataRow => { const row = Array.from({ length: measures.length }, () => ({ text: '' })); Object.keys(dataRow).forEach(key => { const headIndex = measures.findIndex(m => m.id === key); if (headIndex === -1) { return; } const measure = measures[headIndex]; const raw = dataRow[key]?.raw; if (raw == null) { return; } let cellContent = String(raw); const { type } = measure; if (type === 'date' || type === 'timestamp') { cellContent = apiDateToUi(cellContent) || cellContent; } const cell = measure.type === 'HTML' ? { html: cellContent } : { text: cellContent }; row[headIndex] = cell; }); return row; }); } // Return the data unfiltered by measures return data.map(dataRow => { const row = Array(Object.keys(data[0]).length); Object.keys(dataRow).forEach((key, index) => { const text = dataRow[key].raw; row.splice(index, 1, { text }); }); return row; }); }; const creatListFromRows = (listDefinition, dashboardData) => { const { columns } = listDefinition; const { measures } = columns; const head = measures.map(column => { return { text: column.display || '' }; }); const dataSetRows = DatasetHelper.getDatasetRows(listDefinition, dashboardData); const displayRows = DatasetHelper.filterRowsByDisplayColumns(listDefinition, dataSetRows); const rows = createTableRows(displayRows, measures); const dateColumn = getTimestampColumn(columns); const dateData = getDateValue(dataSetRows, dateColumn); const ts = dateData?.value ? `${dateData.value}` : ''; return { head, rows, ts, }; }; const createFullList = (listDefinition, dashboardData) => { if (!dashboardData || dashboardData.length === 0 || !dashboardData[0]) { return { head: [], rows: [], ts: '', }; } const { columns } = listDefinition; const firstRow = dashboardData[0]; const head = Object.keys(firstRow).map(key => { return { text: key || '' }; }); const rows = createTableRows(dashboardData); const dateColumn = getTimestampColumn(columns); const latestData = DatasetHelper.getLastestDataset(dashboardData, dateColumn); const dateData = getDateValue(latestData, dateColumn); const ts = dateData?.value ? `${dateData.value}` : ''; return { head, rows, ts, }; }; const sumColumns = (rowsData, measures) => { const sumColumnIndexes = measures.flatMap((col, idx) => (col.aggregate ? [idx] : [])); if (sumColumnIndexes.length) { const sumRow = [{ html: `<strong>Total<strong>` }]; for (let index = 1; index < measures.length; index += 1) { sumRow[index] = { text: '' }; } rowsData.push(sumRow); sumColumnIndexes.forEach(index => { const total = rowsData.reduce((acc, row) => { const rowIndex = row[index]; if (rowIndex && rowIndex.text) { acc += Number(rowIndex.text); } return acc; }, 0); rowsData[rowsData.length - 1][index] = { html: `<strong>${total}<strong>`, }; }); } return rowsData; }; var DashboardListUtils = { createList, createTableRows, }; export { createList, createTableRows, DashboardListUtils as default }; //# sourceMappingURL=utils.js.map