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.

190 lines (187 loc) 7.57 kB
import { apiDateToUi } from '../dateHelper.js'; import { hasOptionalKeys, filterRowsByKeys } from './VisualisationOptionalKeysHelper.js'; /** * Creates the dataset for a single visualisation * - given the visualisation definition will extract the relevant * - rows from the master dataset to produce a visualisation dataset * * @param {components['schemas']['DashboardVisualisationDefinition']} visDefinition * @param {DashboardDataResponse[]} dashboardData * @return {DashboardDataResponse[]} the visualisation dataset */ const getDatasetRows = (visDefinition, dashboardData) => { const { columns } = visDefinition; const { measures, filters, expectNulls } = visDefinition.columns; const { keys } = visDefinition.columns; const displayColumnsIds = measures.map(col => col.id); const keyColumnsIds = keys?.map(col => col.id) || []; let filterColIds = filters?.map(col => col.id) || []; filterColIds = [...new Set(filterColIds)]; const hasOptionalKeys$1 = hasOptionalKeys(keys || []); const dateColumn = getTimestampColumn(columns); const dateData = getDateValue(dashboardData, dateColumn); if (dashboardData.length && dateData) { keyColumnsIds.unshift(dateData.measure.id); } const filtered = dashboardData.filter((datasetRow) => { const validRow = []; Object.keys(datasetRow).forEach(fieldId => { const value = datasetRow[fieldId].raw; // All rows are valid until proven otherwise let valid = true; // 1. check if the column value is equal to a defined column value if (filterColIds.includes(fieldId) && filters) { const filterValues = filters ? filters.filter(f => f.id === fieldId).map(f => f.equals) : []; const validFilters = []; filterValues.forEach(filterValue => { if (filterValue === null) { validFilters.push(value === '' || value === undefined || value === null); } else { validFilters.push(filterValue === value); } }); valid = validFilters.some(Boolean); // 3. check keys exist in the defined columns } else if (keyColumnsIds.includes(fieldId) && hasOptionalKeys$1) { valid = true; // 3. check keys exist in the defined columns } else if (keyColumnsIds.includes(fieldId) && !hasOptionalKeys$1) { valid = value !== '' && value !== undefined && value !== null; // 2. check values exist in the defined columns } else if (displayColumnsIds.includes(fieldId)) { valid = value !== '' && value !== undefined && value !== null; // 3. check that all remaining columns are null. } else if (expectNulls) { valid = value === '' || value === undefined || value === null; } validRow.push(valid); }); return validRow.every(val => val); }); if (hasOptionalKeys$1) { return filterRowsByKeys(filtered, keys || []); } return filtered; }; const getLastestDataset = (dashboardData, dateMeasure) => { if (dateMeasure) { const latestTimestamp = dashboardData[dashboardData.length - 1]?.[dateMeasure.id]?.raw; if (latestTimestamp) { return dashboardData.filter(data => data[dateMeasure.id].raw === latestTimestamp); } } return dashboardData; }; const getEarliestDataset = (dashboardData, dateMeasure) => { if (dateMeasure) { const earliestTimestamp = dashboardData[0]?.[dateMeasure.id]?.raw; if (earliestTimestamp) { return dashboardData.filter(data => data[dateMeasure.id].raw === earliestTimestamp); } } return dashboardData; }; const groupRowsByTimestamp = (dashboardData, dateMeasure) => { const { id } = dateMeasure; const uniqueTimestamps = [...new Set(dashboardData.map(item => item[id].raw))]; return uniqueTimestamps.map(ts => { return dashboardData.filter(d => d[id].raw === ts); }); }; const groupRowsByKey = (dashboardData, key) => { const uniqueKeyValues = [...new Set(dashboardData.map(item => item[key].raw))]; return uniqueKeyValues.map(keyValue => { return dashboardData.filter(d => d[key].raw === keyValue); }); }; const groupRowsBy = (dashboardData, groupIds) => { const grouped = dashboardData.reduce((acc, row) => { // Create a unique composite key from the grouping fields const key = groupIds.map(id => row[id]?.raw ?? '').join('|'); // Build or append to the group acc[key] = acc[key] ? [...acc[key], row] : [row]; return acc; }, {}); // Return the groups as an array of arrays return Object.values(grouped); }; const getGroupKey = (rawData, keys) => { if (!keys || !keys.length || !rawData.length) { return undefined; } const data = rawData[0]; let index = keys.length - 1; let keyFound = false; while (!keyFound) { const k = `${keys[index]?.id}`; if (k && index !== -1 && (!data[k] || !data[k].raw || data[k].raw === '' || data[k].raw === null)) { index -= 1; } else { keyFound = true; } } return index !== -1 ? keys[index] : undefined; }; const filterRowsByDisplayColumns = (listDefinition, dashboardData, includeKeys = false) => { const { keys: keyCols, measures } = listDefinition.columns; const keys = keyCols || []; let displayColumns = [...measures]; if (includeKeys) { displayColumns = [...keys, ...measures]; } const displayColumnsIds = displayColumns.map(col => col.id); return dashboardData.map((datasetRow) => { return Object.keys(datasetRow) .filter(key => displayColumnsIds.includes(key)) .reduce((acc, key) => { acc[key] = datasetRow[key]; return acc; }, {}); }); }; const getDateValue = (dashboardData, dateColumn) => { if (!dateColumn || !dashboardData || !dashboardData.length) return undefined; const { id } = dateColumn; const dateValue = dashboardData[0][id]?.raw; if (!dateValue || typeof dateValue !== 'string') return undefined; return { measure: dateColumn, value: apiDateToUi(dateValue) || dateValue, }; }; const getTimestampColumn = (columns) => { const { measures, keys } = columns; const tsMeasure = getTimestampMeasure(measures); const tsKey = getTimestampKey(keys); return tsKey ?? tsMeasure; }; const getTimestampMeasure = (measures) => { return measures.find(m => m.type === 'timestamp'); }; const getTimestampKey = (keys) => { return keys ? keys.find(m => m.type === 'timestamp') : undefined; }; var DatasetHelper = { getDatasetRows, getLastestDataset, getEarliestDataset, filterRowsByDisplayColumns, groupRowsByTimestamp, groupRowsByKey, groupRowsBy, getGroupKey, getTimestampMeasure, getTimestampKey, getTimestampColumn, getDateValue, }; export { DatasetHelper as default, filterRowsByDisplayColumns, getDatasetRows, getDateValue, getEarliestDataset, getGroupKey, getLastestDataset, getTimestampColumn, getTimestampKey, getTimestampMeasure, groupRowsBy, groupRowsByKey, groupRowsByTimestamp }; //# sourceMappingURL=VisualisationDatasetHelper.js.map