@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
206 lines (201 loc) • 8.04 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var dateHelper = require('../dateHelper.js');
var VisualisationOptionalKeysHelper = require('./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 = VisualisationOptionalKeysHelper.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) {
valid = true;
// 3. check keys exist in the defined columns
}
else if (keyColumnsIds.includes(fieldId) && !hasOptionalKeys) {
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) {
return VisualisationOptionalKeysHelper.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: dateHelper.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,
};
exports.default = DatasetHelper;
exports.filterRowsByDisplayColumns = filterRowsByDisplayColumns;
exports.getDatasetRows = getDatasetRows;
exports.getDateValue = getDateValue;
exports.getEarliestDataset = getEarliestDataset;
exports.getGroupKey = getGroupKey;
exports.getLastestDataset = getLastestDataset;
exports.getTimestampColumn = getTimestampColumn;
exports.getTimestampKey = getTimestampKey;
exports.getTimestampMeasure = getTimestampMeasure;
exports.groupRowsBy = groupRowsBy;
exports.groupRowsByKey = groupRowsByKey;
exports.groupRowsByTimestamp = groupRowsByTimestamp;
//# sourceMappingURL=VisualisationDatasetHelper.js.map