@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
163 lines (162 loc) • 7.98 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const DataTableBuilder_1 = __importDefault(require("../DataTableBuilder/DataTableBuilder"));
const arrayUtils_1 = require("../arrayUtils");
const logger_1 = __importDefault(require("../logger"));
const SectionedDataTableBuilder_1 = __importDefault(require("../SectionedDataTableBuilder/SectionedDataTableBuilder"));
class ParentChildDataTableBuilder extends SectionedDataTableBuilder_1.default {
constructor(variant) {
const { specification } = variant;
const { sections, template } = specification;
super(specification);
this.childData = [];
this.sections = sections;
this.template = template;
this.variant = variant;
}
createParentChildTable(parentData, header) {
let sectionedParentChildData = {};
// Get the parent-child joins definition data
const joinFields = this.mapNamesToFields(this.variant.childVariants.flatMap((c) => c.joinFields).reduce(arrayUtils_1.distinct, []));
// Create the section keys and
const parentChildKeys = this.calculateParentChildKeys(parentData, joinFields);
parentChildKeys.forEach((parentKey) => {
sectionedParentChildData[parentKey.sortKey] = {
parent: [],
};
});
sectionedParentChildData = this.splitParentDataIntoSections(sectionedParentChildData, parentData, joinFields);
sectionedParentChildData = this.splitChildDataIntoSections(parentChildKeys, sectionedParentChildData);
const childDataTableBuilders = this.createChildDataTableBuilders();
const parentChildTable = parentChildKeys.flatMap((key) => {
const sectionData = sectionedParentChildData[key.sortKey];
const parentSectionData = sectionData.parent;
return [header].concat(parentSectionData.map((r) => this.mapRow(r, 'dpr-parent-cell'))).concat(this.variant.childVariants
.filter((childVariant) => sectionData[childVariant.id])
.map((childVariant) => {
const dataTable = childDataTableBuilders[childVariant.id].buildTable(sectionData[childVariant.id]);
return [
{
classes: 'dpr-child-report-cell',
format: 'string',
html: `<div class='dpr-child-report'><h3 class="govuk-heading-s">${childVariant.name}</h3><div class="dpr-child-report_table">${this.convertDataTableToHtml(dataTable)}</div></div>`,
colspan: this.columns.length,
},
];
}));
});
return parentChildTable;
}
createParentChildSectionRows(parentData, header) {
const sectionsDetails = this.mapSections(parentData);
const sectionedData = sectionsDetails.sectionedData;
const sectionedParentChildSectionedRows = [];
Object.keys(sectionedData).forEach((sectionDescription) => {
const data = sectionedData[sectionDescription];
sectionedParentChildSectionedRows.push({
sectionDescription,
...this.getSectionCount(sectionedData, sectionDescription),
rows: this.createParentChildTable(data, header),
});
});
const rows = sectionedParentChildSectionedRows.flatMap((section, index) => {
const sectionHeader = this.createSectionHeader(section.sectionDescription, index, section.count, section.countDescription);
return [...sectionHeader, ...section.rows];
});
return rows;
}
mapParentChildData(parentData, header) {
var _a;
if ((_a = this.sections) === null || _a === void 0 ? void 0 : _a.length) {
return this.createParentChildSectionRows(parentData, header);
}
return this.createParentChildTable(parentData, header);
}
createChildDataTableBuilders() {
const childDataTables = this.variant.childVariants.reduce((previousValue, childVariant) => {
const fieldNamesToDisplay = childVariant.specification.fields
.filter((f) => f.visible || f.mandatory)
.map((f) => f.name);
const dataTableBuilder = new DataTableBuilder_1.default(childVariant.specification.fields)
.withNoHeaderOptions(fieldNamesToDisplay)
.withSortedData();
return {
...previousValue,
[childVariant.id]: dataTableBuilder,
};
}, {});
return childDataTables;
}
calculateParentChildKeys(parentData, joinFields) {
return parentData
.map((rowData) => ({
sortKey: this.getSortKey(rowData, joinFields),
childSortKeys: this.variant.childVariants.reduce((previousValue, childVariant) => {
return {
...previousValue,
[childVariant.id]: this.getSortKey(rowData, this.mapNamesToFields(childVariant.joinFields)),
};
}, {}),
}))
.reduce((previousValue, sortKey) => {
if (previousValue.find((v) => v.sortKey === sortKey.sortKey)) {
return previousValue;
}
return previousValue.concat(sortKey);
}, []);
}
splitParentDataIntoSections(sectionedParentChildData, parentData, joinFields) {
return parentData.reduce((previousValue, rowData) => {
const parentKey = this.getSortKey(rowData, joinFields);
const previousParentValue = previousValue[parentKey].parent;
const newParentValue = {
parent: previousParentValue.concat(rowData),
};
return {
...previousValue,
[parentKey]: newParentValue,
};
}, sectionedParentChildData);
}
splitChildDataIntoSections(parentKeys, sectionedParentChildData) {
const sectionedParentChildDataWithChildren = { ...sectionedParentChildData };
this.variant.childVariants.forEach((childVariant) => {
const childFields = this.mapNamesToFields(childVariant.joinFields);
logger_1.default.info('DPR-Parent-child-template-debugging splitChildDataIntoSections', JSON.stringify({
childFields,
parentKeys,
}));
const matchingChildData = this.childData.find((d) => d.id === childVariant.id);
const data = matchingChildData ? matchingChildData.data : [];
data
.filter((rowData) => {
const sortKey = this.getSortKey(rowData, childFields);
return parentKeys.find((p) => p.childSortKeys[childVariant.id] === sortKey);
})
.forEach((rowData) => {
var _a;
const sortKey = this.getSortKey(rowData, childFields);
const parentSortKey = parentKeys.find((p) => p.childSortKeys[childVariant.id] === sortKey).sortKey;
const existingChildData = (_a = sectionedParentChildDataWithChildren[parentSortKey][childVariant.id]) !== null && _a !== void 0 ? _a : [];
sectionedParentChildDataWithChildren[parentSortKey][childVariant.id] = existingChildData.concat(rowData);
});
});
return sectionedParentChildDataWithChildren;
}
withChildData(childData) {
this.childData = childData;
return this;
}
buildTable(data) {
return {
head: null,
rows: this.mapParentChildData(data, this.mapHeader(true, 'govuk-table__header')),
rowCount: data.length,
colCount: this.columns.length,
};
}
}
exports.default = ParentChildDataTableBuilder;