@ministryofjustice/hmpps-digital-prison-reporting-frontend 4.28.8 → 4.29.0
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.
- package/dpr/all.js +6 -8
- package/dpr/all.js.map +3 -3
- package/dpr/all.scss +296 -414
- package/dpr/all.ts +6 -11
- package/dpr/components/_catalogue/catalogue-list/utils.test.ts +1 -1
- package/dpr/components/_charts/chart/clientClass.js +1 -0
- package/dpr/components/_charts/chart/clientClass.js.map +2 -2
- package/dpr/components/_charts/chart/clientClass.ts +1 -0
- package/dpr/components/_reports/{report-actions → report-heading/report-actions}/actionsTemplate.js.map +1 -1
- package/dpr/components/_reports/{report-actions → report-heading/report-actions}/clientClass.js +1 -1
- package/dpr/components/_reports/report-heading/report-actions/clientClass.js.map +7 -0
- package/dpr/components/_reports/{report-actions → report-heading/report-actions}/clientClass.ts +1 -1
- package/dpr/components/_reports/report-heading/report-actions/types.d.js.map +7 -0
- package/dpr/components/_reports/{report-actions → report-heading/report-actions}/types.d.ts +1 -1
- package/dpr/components/_reports/{report-actions → report-heading/report-actions}/utils.js.map +1 -1
- package/dpr/components/_reports/{report-actions → report-heading/report-actions}/utils.test.ts +2 -2
- package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/clientClass.js +1 -3
- package/dpr/components/_reports/report-heading/report-columns/report-columns-form/clientClass.js.map +7 -0
- package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/clientClass.ts +1 -3
- package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/types.d.js.map +1 -1
- package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/utils.js +1 -1
- package/dpr/components/_reports/report-heading/report-columns/report-columns-form/utils.js.map +7 -0
- package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/utils.ts +2 -2
- package/dpr/components/_reports/{report-columns → report-heading/report-columns}/view.njk +1 -1
- package/dpr/components/_reports/{report-download-message → report-heading/report-download-message}/clientClass.js +1 -1
- package/dpr/components/_reports/report-heading/report-download-message/clientClass.js.map +7 -0
- package/dpr/components/_reports/{report-download-message → report-heading/report-download-message}/clientClass.ts +1 -1
- package/dpr/components/_reports/{report-filters → report-heading/report-filters}/view.njk +1 -1
- package/dpr/components/_reports/report-heading/view.njk +4 -4
- package/dpr/components/_reports/report-page/report-print-message/view.njk +10 -0
- package/dpr/components/_reports/report-page/report-template/report-no-data-message/styles.scss +8 -0
- package/dpr/components/_reports/report-page/report-template/report-no-data-message/view.njk +11 -0
- package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/clientClass.js +1 -1
- package/dpr/components/_reports/report-page/report-template/report-pagination/clientClass.js.map +7 -0
- package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/clientClass.ts +1 -1
- package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/types.d.js.map +1 -1
- package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/utils.js.map +1 -1
- package/dpr/components/_reports/report-page/report-template/report-section/parent-child-template/styles.scss +88 -0
- package/dpr/components/_reports/report-page/report-template/report-section/parent-child-template/view.njk +29 -0
- package/dpr/components/_reports/{report-data-table → report-page/report-template/report-section/report-data-table}/clientClass.js +17 -10
- package/dpr/components/_reports/report-page/report-template/report-section/report-data-table/clientClass.js.map +7 -0
- package/dpr/components/_reports/{report-data-table → report-page/report-template/report-section/report-data-table}/clientClass.ts +20 -10
- package/dpr/components/_reports/{report-data-table → report-page/report-template/report-section/report-data-table}/style.scss +35 -185
- package/dpr/components/_reports/report-page/report-template/report-section/report-data-table/types.d.js.map +7 -0
- package/dpr/components/_reports/{report-data-table → report-page/report-template/report-section/report-data-table}/types.d.ts +2 -2
- package/dpr/components/_reports/report-page/report-template/report-section/report-data-table/view.njk +27 -0
- package/dpr/components/_reports/report-page/report-template/report-section/styles.scss +33 -0
- package/dpr/components/_reports/report-page/report-template/report-section/view.njk +58 -0
- package/dpr/components/_reports/{report-summary-table → report-page/report-template/report-summary-table}/styles.scss +21 -4
- package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/utils.js.map +1 -1
- package/dpr/components/_reports/report-page/report-template/styles.scss +5 -0
- package/dpr/components/_reports/report-page/report-template/template-config.js +66 -0
- package/dpr/components/_reports/report-page/report-template/template-config.js.map +7 -0
- package/dpr/components/_reports/report-page/report-template/template-config.ts +45 -0
- package/dpr/components/_reports/report-page/report-template/utils.js +82 -0
- package/dpr/components/_reports/report-page/report-template/utils.js.map +7 -0
- package/dpr/components/_reports/report-page/report-template/utils.ts +100 -0
- package/dpr/components/_reports/report-page/report-template/view.njk +61 -0
- package/dpr/components/_reports/{report-wrapper → report-page}/styles.scss +7 -5
- package/dpr/components/_reports/report-page/view.njk +26 -0
- package/dpr/components/card-group/view.njk +0 -4
- package/dpr/components/report-list/utils.js +11 -3
- package/dpr/components/report-list/utils.js.map +2 -2
- package/dpr/components/report-list/utils.ts +11 -1
- package/dpr/components/report-list/view.njk +2 -2
- package/dpr/components/show-more/style.scss +3 -4
- package/dpr/data/reportingClient.js.map +2 -2
- package/dpr/data/reportingClient.ts +4 -4
- package/dpr/routes/journeys/view-report/async/dashboard/utils.js +1 -1
- package/dpr/routes/journeys/view-report/async/dashboard/utils.js.map +1 -1
- package/dpr/routes/journeys/view-report/async/dashboard/utils.ts +1 -1
- package/dpr/routes/journeys/view-report/async/report/controller.js.map +2 -2
- package/dpr/routes/journeys/view-report/async/report/controller.ts +0 -1
- package/dpr/routes/journeys/view-report/async/report/report-variants.cy.js +207 -56
- package/dpr/routes/journeys/view-report/async/report/report-variants.cy.js.map +2 -2
- package/dpr/routes/journeys/view-report/async/report/report-variants.cy.ts +333 -64
- package/dpr/routes/journeys/view-report/async/report/utils.js +9 -17
- package/dpr/routes/journeys/view-report/async/report/utils.js.map +3 -3
- package/dpr/routes/journeys/view-report/async/report/utils.ts +12 -22
- package/dpr/routes/journeys/view-report/report.njk +2 -2
- package/dpr/routes/journeys/view-report/sync/dashboard/utils.js +1 -1
- package/dpr/routes/journeys/view-report/sync/dashboard/utils.js.map +1 -1
- package/dpr/routes/journeys/view-report/sync/dashboard/utils.ts +1 -1
- package/dpr/routes/journeys/view-report/sync/report/utils.js +38 -11
- package/dpr/routes/journeys/view-report/sync/report/utils.js.map +3 -3
- package/dpr/routes/journeys/view-report/sync/report/utils.ts +39 -14
- package/dpr/routes/journeys/view-report/utils.js +1 -1
- package/dpr/routes/journeys/view-report/utils.js.map +1 -1
- package/dpr/routes/journeys/view-report/utils.ts +1 -1
- package/dpr/services/reportingService.js.map +2 -2
- package/dpr/services/reportingService.ts +2 -2
- package/dpr/types/ReportQuery.js +1 -1
- package/dpr/types/ReportQuery.js.map +1 -1
- package/dpr/types/ReportQuery.ts +1 -1
- package/dpr/types/UserReports.js.map +1 -1
- package/dpr/types/UserReports.ts +3 -3
- package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/ParentChildDataBuilder.js +193 -0
- package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/ParentChildDataBuilder.js.map +7 -0
- package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/ParentChildDataBuilder.ts +203 -0
- package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/types.d.js.map +7 -0
- package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/types.d.ts +36 -0
- package/dpr/utils/TemplateBuilder/ReportBuilder/ReportBuilder.js +114 -0
- package/dpr/utils/TemplateBuilder/ReportBuilder/ReportBuilder.js.map +7 -0
- package/dpr/utils/TemplateBuilder/ReportBuilder/ReportBuilder.ts +117 -0
- package/dpr/utils/TemplateBuilder/ReportBuilder/types.d.js.map +7 -0
- package/dpr/utils/TemplateBuilder/ReportBuilder/types.d.ts +6 -0
- package/dpr/utils/TemplateBuilder/SectionedDataHelper/SectionedDataHelper.js +202 -0
- package/dpr/utils/TemplateBuilder/SectionedDataHelper/SectionedDataHelper.js.map +7 -0
- package/dpr/utils/TemplateBuilder/SectionedDataHelper/SectionedDataHelper.ts +246 -0
- package/dpr/utils/TemplateBuilder/SectionedDataHelper/types.js +17 -0
- package/dpr/utils/TemplateBuilder/SectionedDataHelper/types.js.map +7 -0
- package/dpr/utils/TemplateBuilder/SectionedDataHelper/types.ts +41 -0
- package/dpr/utils/{CollatedSummaryBuilder/CollatedSummaryBuilder.js → TemplateBuilder/SummaryDataHelper/SummaryDataHelper.js} +6 -8
- package/dpr/utils/TemplateBuilder/SummaryDataHelper/SummaryDataHelper.js.map +7 -0
- package/dpr/utils/{CollatedSummaryBuilder/CollatedSummaryBuilder.test.ts → TemplateBuilder/SummaryDataHelper/SummaryDataHelper.test.ts} +4 -4
- package/dpr/utils/{CollatedSummaryBuilder/CollatedSummaryBuilder.ts → TemplateBuilder/SummaryDataHelper/SummaryDataHelper.ts} +6 -9
- package/dpr/utils/TemplateBuilder/TemplateBuilder.js +74 -0
- package/dpr/utils/TemplateBuilder/TemplateBuilder.js.map +7 -0
- package/dpr/utils/TemplateBuilder/TemplateBuilder.ts +68 -0
- package/dpr/utils/definitionUtils.js +22 -2
- package/dpr/utils/definitionUtils.js.map +2 -2
- package/dpr/utils/definitionUtils.ts +26 -1
- package/package.json +1 -1
- package/dpr/DprLoadingHelper.js +0 -51
- package/dpr/DprLoadingHelper.js.map +0 -7
- package/dpr/DprLoadingHelper.ts +0 -27
- package/dpr/components/_reports/report/view.njk +0 -40
- package/dpr/components/_reports/report-actions/clientClass.js.map +0 -7
- package/dpr/components/_reports/report-actions/types.d.js.map +0 -7
- package/dpr/components/_reports/report-columns-form/clientClass.js.map +0 -7
- package/dpr/components/_reports/report-columns-form/utils.js.map +0 -7
- package/dpr/components/_reports/report-data-table/clientClass.js.map +0 -7
- package/dpr/components/_reports/report-data-table/types.d.js.map +0 -7
- package/dpr/components/_reports/report-data-table/utils.js +0 -123
- package/dpr/components/_reports/report-data-table/utils.js.map +0 -7
- package/dpr/components/_reports/report-data-table/utils.test.ts +0 -604
- package/dpr/components/_reports/report-data-table/utils.ts +0 -150
- package/dpr/components/_reports/report-data-table/view.njk +0 -24
- package/dpr/components/_reports/report-data-table-wrapper/view.njk +0 -27
- package/dpr/components/_reports/report-download-message/clientClass.js.map +0 -7
- package/dpr/components/_reports/report-no-data-message/styles.scss +0 -4
- package/dpr/components/_reports/report-no-data-message/view.njk +0 -13
- package/dpr/components/_reports/report-pagination/clientClass.js.map +0 -7
- package/dpr/components/_reports/report-print-message/view.njk +0 -8
- package/dpr/components/_reports/report-template/view.njk +0 -44
- package/dpr/components/_reports/report-wrapper/view.njk +0 -19
- package/dpr/components/loading-anim/styles.scss +0 -117
- package/dpr/components/loading-anim/view.njk +0 -18
- package/dpr/utils/CollatedSummaryBuilder/CollatedSummaryBuilder.js.map +0 -7
- package/dpr/utils/ParentChildDataTableBuilder/ParentChildDataTableBuilder.js +0 -202
- package/dpr/utils/ParentChildDataTableBuilder/ParentChildDataTableBuilder.js.map +0 -7
- package/dpr/utils/ParentChildDataTableBuilder/ParentChildDataTableBuilder.test.ts +0 -503
- package/dpr/utils/ParentChildDataTableBuilder/ParentChildDataTableBuilder.ts +0 -224
- package/dpr/utils/ParentChildDataTableBuilder/types.d.js.map +0 -7
- package/dpr/utils/ParentChildDataTableBuilder/types.d.ts +0 -11
- package/dpr/utils/SectionedDataTableBuilder/SectionedDataTableBuilder.js +0 -311
- package/dpr/utils/SectionedDataTableBuilder/SectionedDataTableBuilder.js.map +0 -7
- package/dpr/utils/SectionedDataTableBuilder/SectionedDataTableBuilder.test.ts +0 -492
- package/dpr/utils/SectionedDataTableBuilder/SectionedDataTableBuilder.ts +0 -342
- package/dpr/utils/SectionedDataTableBuilder/types.d.js.map +0 -7
- package/dpr/utils/SectionedDataTableBuilder/types.d.ts +0 -5
- package/dpr/utils/SectionedFieldsTableBuilder/SectionedFieldsTableBuilder.js +0 -146
- package/dpr/utils/SectionedFieldsTableBuilder/SectionedFieldsTableBuilder.js.map +0 -7
- package/dpr/utils/SectionedFieldsTableBuilder/SectionedFieldsTableBuilder.test.ts +0 -140
- package/dpr/utils/SectionedFieldsTableBuilder/SectionedFieldsTableBuilder.ts +0 -150
- /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/actionsTemplate.js +0 -0
- /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/actionsTemplate.ts +0 -0
- /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/style.scss +0 -0
- /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/types.d.js +0 -0
- /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/utils.js +0 -0
- /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/utils.ts +0 -0
- /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/view.njk +0 -0
- /package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/style.scss +0 -0
- /package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/types.d.js +0 -0
- /package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/types.d.ts +0 -0
- /package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/view.njk +0 -0
- /package/dpr/components/_reports/{report-columns → report-heading/report-columns}/styles.scss +0 -0
- /package/dpr/components/_reports/{report-download-message → report-heading/report-download-message}/style.scss +0 -0
- /package/dpr/components/_reports/{report-download-message → report-heading/report-download-message}/view.njk +0 -0
- /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/style.scss +0 -0
- /package/dpr/components/_reports/{report-data-table → report-page/report-template/report-pagination}/types.d.js +0 -0
- /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/types.d.ts +0 -0
- /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/utils.js +0 -0
- /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/utils.test.ts +0 -0
- /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/utils.ts +0 -0
- /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/view.njk +0 -0
- /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-section/report-data-table}/types.d.js +0 -0
- /package/dpr/components/_reports/{report-summary-table → report-page/report-template/report-summary-table}/view.njk +0 -0
- /package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/style.scss +0 -0
- /package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/utils.js +0 -0
- /package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/utils.ts +0 -0
- /package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/view.njk +0 -0
- /package/dpr/utils/{ParentChildDataTableBuilder → TemplateBuilder/ParentChildDataBuilder}/types.d.js +0 -0
- /package/dpr/utils/{SectionedDataTableBuilder → TemplateBuilder/ReportBuilder}/types.d.js +0 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var SectionedDataHelper_exports = {};
|
|
20
|
+
__export(SectionedDataHelper_exports, {
|
|
21
|
+
SectionedDataHelper: () => SectionedDataHelper
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(SectionedDataHelper_exports);
|
|
24
|
+
var import_definitionUtils = require("../../definitionUtils");
|
|
25
|
+
class SectionedDataHelper {
|
|
26
|
+
sections = [];
|
|
27
|
+
data = [];
|
|
28
|
+
fields = [];
|
|
29
|
+
summariesData = [];
|
|
30
|
+
sectionedDataArray = [];
|
|
31
|
+
sectionedData;
|
|
32
|
+
reportQuery;
|
|
33
|
+
createSectionKey(row) {
|
|
34
|
+
const keyObj = this.sections.map((col) => ({
|
|
35
|
+
name: col,
|
|
36
|
+
value: row[col] ?? ""
|
|
37
|
+
}));
|
|
38
|
+
const keyValues = keyObj.map((v) => v.value).join("");
|
|
39
|
+
const key = keyValues !== "" ? JSON.stringify(keyObj) : "mainSection";
|
|
40
|
+
return {
|
|
41
|
+
keyObj: key === "mainSection" ? [] : keyObj,
|
|
42
|
+
key
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
createSectionTitle(keyObj, fields) {
|
|
46
|
+
return keyObj.map((column) => {
|
|
47
|
+
const fieldName = (0, import_definitionUtils.getFieldDisplayName)(fields, column.name);
|
|
48
|
+
return `${fieldName}: ${column.value}`;
|
|
49
|
+
}).join(", ");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Groups the data into sections
|
|
53
|
+
*
|
|
54
|
+
* @return {*} {SectionedData}
|
|
55
|
+
* @memberof SectionedDataBuilder
|
|
56
|
+
*/
|
|
57
|
+
groupBySections(data, fields, summary) {
|
|
58
|
+
const sectionMap = data.reduce((acc, row) => {
|
|
59
|
+
const { key, keyObj } = this.createSectionKey(row);
|
|
60
|
+
const title = this.createSectionTitle(keyObj, fields);
|
|
61
|
+
if (!acc[key]) {
|
|
62
|
+
acc[key] = {
|
|
63
|
+
title,
|
|
64
|
+
count: 0,
|
|
65
|
+
key,
|
|
66
|
+
keyObj,
|
|
67
|
+
summaries: [],
|
|
68
|
+
data: []
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const section = acc[key];
|
|
72
|
+
if (summary) {
|
|
73
|
+
const { id, template } = summary;
|
|
74
|
+
const existingSummary = section.summaries.find((s) => s.template === template);
|
|
75
|
+
if (existingSummary) {
|
|
76
|
+
existingSummary.data.push(row);
|
|
77
|
+
} else {
|
|
78
|
+
section.summaries.push({
|
|
79
|
+
id,
|
|
80
|
+
template,
|
|
81
|
+
fields,
|
|
82
|
+
data: [row]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
section.data.push(row);
|
|
87
|
+
section.count += 1;
|
|
88
|
+
}
|
|
89
|
+
return acc;
|
|
90
|
+
}, {});
|
|
91
|
+
this.sectionedDataArray.push({
|
|
92
|
+
sections: Object.values(sectionMap)
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
createSummarySections() {
|
|
96
|
+
this.summariesData.forEach((summaryData) => {
|
|
97
|
+
const { fields, id, template, data } = summaryData;
|
|
98
|
+
this.groupBySections(data, fields, { id, template });
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
mergeSections() {
|
|
102
|
+
return {
|
|
103
|
+
sections: this.sectionedDataArray.flatMap((input) => input.sections).reduce((acc, section) => {
|
|
104
|
+
const { key, keyObj } = section;
|
|
105
|
+
const existing = acc.find((s) => s.key === key);
|
|
106
|
+
if (!existing) {
|
|
107
|
+
return acc.concat({
|
|
108
|
+
key: section.key || "",
|
|
109
|
+
keyObj: keyObj || [],
|
|
110
|
+
title: section.title || "",
|
|
111
|
+
count: section.count,
|
|
112
|
+
summaries: section.summaries ? [...section.summaries] : [],
|
|
113
|
+
data: section.data ? [...section.data] : []
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
const updated = acc.map(
|
|
117
|
+
(s) => s.key === key ? {
|
|
118
|
+
...s,
|
|
119
|
+
count: s.count + section.count,
|
|
120
|
+
summaries: (s.summaries ?? []).concat(section.summaries ?? []),
|
|
121
|
+
data: (s.data ?? []).concat(section.data ?? [])
|
|
122
|
+
} : s
|
|
123
|
+
);
|
|
124
|
+
return updated;
|
|
125
|
+
}, [])
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
getSortField() {
|
|
129
|
+
const { sortColumn } = this.reportQuery;
|
|
130
|
+
return sortColumn && this.sections.includes(sortColumn) ? [sortColumn] : [];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Sorts sections based on keyObj values using an optional nameOrder override.
|
|
134
|
+
* - nameOrder can be partial; unspecified names fall back to default order
|
|
135
|
+
* - Default order is derived from the first section's keyObj sequence
|
|
136
|
+
*/
|
|
137
|
+
sortSections(sectionedData) {
|
|
138
|
+
const nameOrder = this.getSortField();
|
|
139
|
+
const { sections } = sectionedData;
|
|
140
|
+
if (sections.length === 0) return sectionedData;
|
|
141
|
+
const defaultOrder = sections[0].keyObj.map((k) => k.name);
|
|
142
|
+
const finalOrder = nameOrder.filter((name) => defaultOrder.includes(name)).concat(defaultOrder.filter((name) => !nameOrder.includes(name)));
|
|
143
|
+
const buildMap = (keyObj) => keyObj.reduce((acc, ko) => ({ ...acc, [ko.name]: ko.value }), {});
|
|
144
|
+
const sortedSections = [...sections].sort((a, b) => {
|
|
145
|
+
const aMap = buildMap(a.keyObj);
|
|
146
|
+
const bMap = buildMap(b.keyObj);
|
|
147
|
+
const comparisons = finalOrder.map((name) => {
|
|
148
|
+
const aVal = aMap[name] ?? "";
|
|
149
|
+
const bVal = bMap[name] ?? "";
|
|
150
|
+
return aVal.localeCompare(bVal, void 0, { numeric: true });
|
|
151
|
+
});
|
|
152
|
+
return comparisons.find((x) => x !== 0) ?? 0;
|
|
153
|
+
});
|
|
154
|
+
return {
|
|
155
|
+
sections: sortedSections
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
withSections(sections) {
|
|
159
|
+
this.sections = sections || [];
|
|
160
|
+
return this;
|
|
161
|
+
}
|
|
162
|
+
withFields(fields) {
|
|
163
|
+
this.fields = (0, import_definitionUtils.getFieldsByName)(this.sections, fields);
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
withData(data) {
|
|
167
|
+
this.data = data;
|
|
168
|
+
return this;
|
|
169
|
+
}
|
|
170
|
+
withSummaries(summaryData) {
|
|
171
|
+
this.summariesData = summaryData || [];
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
withReportQuery(reportQuery) {
|
|
175
|
+
this.reportQuery = reportQuery;
|
|
176
|
+
return this;
|
|
177
|
+
}
|
|
178
|
+
build() {
|
|
179
|
+
let sections;
|
|
180
|
+
if (this.sections.length) {
|
|
181
|
+
this.groupBySections(this.data, this.fields);
|
|
182
|
+
this.createSummarySections();
|
|
183
|
+
sections = this.mergeSections();
|
|
184
|
+
sections = this.sortSections(sections);
|
|
185
|
+
} else {
|
|
186
|
+
const singleSection = {
|
|
187
|
+
key: "",
|
|
188
|
+
keyObj: [],
|
|
189
|
+
data: this.data,
|
|
190
|
+
count: this.data.length,
|
|
191
|
+
summaries: this.summariesData
|
|
192
|
+
};
|
|
193
|
+
sections = { sections: [singleSection] };
|
|
194
|
+
}
|
|
195
|
+
return sections;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
199
|
+
0 && (module.exports = {
|
|
200
|
+
SectionedDataHelper
|
|
201
|
+
});
|
|
202
|
+
//# sourceMappingURL=SectionedDataHelper.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../dpr/utils/TemplateBuilder/SectionedDataHelper/SectionedDataHelper.ts"],
|
|
4
|
+
"sourcesContent": ["import ReportQuery from '../../../types/ReportQuery'\nimport { SummaryTemplate } from '../../../types/Templates'\nimport { AsyncSummary } from '../../../types/UserReports'\nimport { components } from '../../../types/api'\nimport { getFieldsByName, getFieldDisplayName } from '../../definitionUtils'\nimport { SectionData, SectionedData, SectionKey } from './types'\n\nexport class SectionedDataHelper {\n sections: Array<string> = []\n\n data: Array<Record<string, string>> = []\n\n fields: components['schemas']['FieldDefinition'][] = []\n\n summariesData: AsyncSummary[] = []\n\n sectionedDataArray: SectionedData[] = []\n\n sectionedData!: SectionedData\n\n reportQuery!: ReportQuery\n\n createSectionKey(row: Record<string, string>): { keyObj: SectionKey[]; key: string } {\n // Build structured entries with column names + values\n const keyObj: SectionKey[] = this.sections.map((col) => ({\n name: col,\n value: row[col] ?? '',\n }))\n const keyValues = keyObj.map((v) => v.value).join('')\n const key = keyValues !== '' ? JSON.stringify(keyObj) : 'mainSection'\n\n return {\n keyObj: key === 'mainSection' ? [] : keyObj,\n key,\n }\n }\n\n createSectionTitle(\n keyObj: SectionKey[],\n fields: components['schemas']['FieldDefinition'][] | components['schemas']['SummaryField'][],\n ) {\n return keyObj\n .map((column) => {\n const fieldName = getFieldDisplayName(fields, column.name)\n return `${fieldName}: ${column.value}`\n })\n .join(', ')\n }\n\n /**\n * Groups the data into sections\n *\n * @return {*} {SectionedData}\n * @memberof SectionedDataBuilder\n */\n groupBySections(\n data: Array<Record<string, string>>,\n fields: components['schemas']['FieldDefinition'][] | components['schemas']['SummaryField'][],\n summary?: {\n template: SummaryTemplate\n id: string\n },\n ) {\n const sectionMap = data.reduce<Record<string, SectionData>>((acc, row) => {\n const { key, keyObj } = this.createSectionKey(row)\n const title = this.createSectionTitle(keyObj, fields)\n\n // Create the section if needed\n if (!acc[key]) {\n acc[key] = {\n title,\n count: 0,\n key,\n keyObj,\n summaries: [],\n data: <Array<Record<string, string>>>[],\n }\n }\n\n const section = acc[key]\n\n if (summary) {\n const { id, template } = summary\n const existingSummary = section.summaries.find((s) => s.template === template)\n if (existingSummary) {\n existingSummary.data.push(row)\n } else {\n section.summaries.push({\n id,\n template,\n fields,\n data: [row],\n })\n }\n } else {\n section.data.push(row)\n section.count += 1\n }\n\n return acc\n }, {})\n\n this.sectionedDataArray.push({\n sections: Object.values(sectionMap),\n })\n }\n\n createSummarySections() {\n this.summariesData.forEach((summaryData) => {\n const { fields, id, template, data } = summaryData\n this.groupBySections(<Array<Record<string, string>>>data, fields, { id, template })\n })\n }\n\n mergeSections(): SectionedData {\n return {\n sections: this.sectionedDataArray\n .flatMap((input) => input.sections)\n .reduce<SectionData[]>((acc, section) => {\n const { key, keyObj } = section\n const existing = acc.find((s) => s.key === key)\n\n // If section doesn't exist yet \u2192 add fresh copy\n if (!existing) {\n return acc.concat({\n key: section.key || '',\n keyObj: keyObj || [],\n title: section.title || '',\n count: section.count,\n summaries: section.summaries ? [...section.summaries] : [],\n data: section.data ? [...section.data] : [],\n })\n }\n\n // If exists \u2192 update it by concatenating data & summaries\n const updated = acc.map((s) =>\n s.key === key\n ? {\n ...s,\n count: s.count + section.count,\n summaries: (s.summaries ?? []).concat(section.summaries ?? []),\n data: (s.data ?? []).concat(section.data ?? []),\n }\n : s,\n )\n\n return updated\n }, []),\n }\n }\n\n getSortField() {\n const { sortColumn } = this.reportQuery\n return sortColumn && this.sections.includes(sortColumn) ? [sortColumn] : []\n }\n\n /**\n * Sorts sections based on keyObj values using an optional nameOrder override.\n * - nameOrder can be partial; unspecified names fall back to default order\n * - Default order is derived from the first section's keyObj sequence\n */\n sortSections(sectionedData: SectionedData): SectionedData {\n const nameOrder = this.getSortField()\n const { sections } = sectionedData\n if (sections.length === 0) return sectionedData\n\n // Default order is the order of the keyObj.name fields in the first section\n const defaultOrder = sections[0].keyObj.map((k) => k.name)\n\n // Merge partial nameOrder with default order\n const finalOrder = nameOrder\n // 1. start with user-specified names\n .filter((name) => defaultOrder.includes(name))\n // 2. append missing names in default order\n .concat(defaultOrder.filter((name) => !nameOrder.includes(name)))\n\n // Build map for fast comparison\n const buildMap = (keyObj: SectionKey[]) =>\n keyObj.reduce<Record<string, string>>((acc, ko) => ({ ...acc, [ko.name]: ko.value }), {})\n\n const sortedSections = [...sections].sort((a, b) => {\n const aMap = buildMap(a.keyObj)\n const bMap = buildMap(b.keyObj)\n\n // Compare using final order\n const comparisons = finalOrder.map((name) => {\n const aVal = aMap[name] ?? ''\n const bVal = bMap[name] ?? ''\n return aVal.localeCompare(bVal, undefined, { numeric: true })\n })\n\n // Return first non-zero comparison\n return comparisons.find((x) => x !== 0) ?? 0\n })\n\n return {\n sections: sortedSections,\n }\n }\n\n withSections(sections: string[]) {\n this.sections = sections || []\n return this\n }\n\n withFields(fields: components['schemas']['FieldDefinition'][]) {\n this.fields = getFieldsByName(this.sections, fields)\n return this\n }\n\n withData(data: Array<Record<string, string>>) {\n this.data = data\n return this\n }\n\n withSummaries(summaryData: Array<AsyncSummary>) {\n this.summariesData = summaryData || []\n return this\n }\n\n withReportQuery(reportQuery: ReportQuery) {\n this.reportQuery = reportQuery\n return this\n }\n\n build(): SectionedData {\n let sections: SectionedData\n if (this.sections.length) {\n this.groupBySections(this.data, this.fields)\n this.createSummarySections()\n sections = this.mergeSections()\n sections = this.sortSections(sections)\n } else {\n const singleSection: SectionData = {\n key: '',\n keyObj: [],\n data: this.data,\n count: this.data.length,\n summaries: this.summariesData,\n }\n sections = { sections: [singleSection] }\n }\n\n return sections\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import ReportQuery from '../../../types/ReportQuery'
|
|
2
|
+
import { SummaryTemplate } from '../../../types/Templates'
|
|
3
|
+
import { AsyncSummary } from '../../../types/UserReports'
|
|
4
|
+
import { components } from '../../../types/api'
|
|
5
|
+
import { getFieldsByName, getFieldDisplayName } from '../../definitionUtils'
|
|
6
|
+
import { SectionData, SectionedData, SectionKey } from './types'
|
|
7
|
+
|
|
8
|
+
export class SectionedDataHelper {
|
|
9
|
+
sections: Array<string> = []
|
|
10
|
+
|
|
11
|
+
data: Array<Record<string, string>> = []
|
|
12
|
+
|
|
13
|
+
fields: components['schemas']['FieldDefinition'][] = []
|
|
14
|
+
|
|
15
|
+
summariesData: AsyncSummary[] = []
|
|
16
|
+
|
|
17
|
+
sectionedDataArray: SectionedData[] = []
|
|
18
|
+
|
|
19
|
+
sectionedData!: SectionedData
|
|
20
|
+
|
|
21
|
+
reportQuery!: ReportQuery
|
|
22
|
+
|
|
23
|
+
createSectionKey(row: Record<string, string>): { keyObj: SectionKey[]; key: string } {
|
|
24
|
+
// Build structured entries with column names + values
|
|
25
|
+
const keyObj: SectionKey[] = this.sections.map((col) => ({
|
|
26
|
+
name: col,
|
|
27
|
+
value: row[col] ?? '',
|
|
28
|
+
}))
|
|
29
|
+
const keyValues = keyObj.map((v) => v.value).join('')
|
|
30
|
+
const key = keyValues !== '' ? JSON.stringify(keyObj) : 'mainSection'
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
keyObj: key === 'mainSection' ? [] : keyObj,
|
|
34
|
+
key,
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
createSectionTitle(
|
|
39
|
+
keyObj: SectionKey[],
|
|
40
|
+
fields: components['schemas']['FieldDefinition'][] | components['schemas']['SummaryField'][],
|
|
41
|
+
) {
|
|
42
|
+
return keyObj
|
|
43
|
+
.map((column) => {
|
|
44
|
+
const fieldName = getFieldDisplayName(fields, column.name)
|
|
45
|
+
return `${fieldName}: ${column.value}`
|
|
46
|
+
})
|
|
47
|
+
.join(', ')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Groups the data into sections
|
|
52
|
+
*
|
|
53
|
+
* @return {*} {SectionedData}
|
|
54
|
+
* @memberof SectionedDataBuilder
|
|
55
|
+
*/
|
|
56
|
+
groupBySections(
|
|
57
|
+
data: Array<Record<string, string>>,
|
|
58
|
+
fields: components['schemas']['FieldDefinition'][] | components['schemas']['SummaryField'][],
|
|
59
|
+
summary?: {
|
|
60
|
+
template: SummaryTemplate
|
|
61
|
+
id: string
|
|
62
|
+
},
|
|
63
|
+
) {
|
|
64
|
+
const sectionMap = data.reduce<Record<string, SectionData>>((acc, row) => {
|
|
65
|
+
const { key, keyObj } = this.createSectionKey(row)
|
|
66
|
+
const title = this.createSectionTitle(keyObj, fields)
|
|
67
|
+
|
|
68
|
+
// Create the section if needed
|
|
69
|
+
if (!acc[key]) {
|
|
70
|
+
acc[key] = {
|
|
71
|
+
title,
|
|
72
|
+
count: 0,
|
|
73
|
+
key,
|
|
74
|
+
keyObj,
|
|
75
|
+
summaries: [],
|
|
76
|
+
data: <Array<Record<string, string>>>[],
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const section = acc[key]
|
|
81
|
+
|
|
82
|
+
if (summary) {
|
|
83
|
+
const { id, template } = summary
|
|
84
|
+
const existingSummary = section.summaries.find((s) => s.template === template)
|
|
85
|
+
if (existingSummary) {
|
|
86
|
+
existingSummary.data.push(row)
|
|
87
|
+
} else {
|
|
88
|
+
section.summaries.push({
|
|
89
|
+
id,
|
|
90
|
+
template,
|
|
91
|
+
fields,
|
|
92
|
+
data: [row],
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
section.data.push(row)
|
|
97
|
+
section.count += 1
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return acc
|
|
101
|
+
}, {})
|
|
102
|
+
|
|
103
|
+
this.sectionedDataArray.push({
|
|
104
|
+
sections: Object.values(sectionMap),
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
createSummarySections() {
|
|
109
|
+
this.summariesData.forEach((summaryData) => {
|
|
110
|
+
const { fields, id, template, data } = summaryData
|
|
111
|
+
this.groupBySections(<Array<Record<string, string>>>data, fields, { id, template })
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
mergeSections(): SectionedData {
|
|
116
|
+
return {
|
|
117
|
+
sections: this.sectionedDataArray
|
|
118
|
+
.flatMap((input) => input.sections)
|
|
119
|
+
.reduce<SectionData[]>((acc, section) => {
|
|
120
|
+
const { key, keyObj } = section
|
|
121
|
+
const existing = acc.find((s) => s.key === key)
|
|
122
|
+
|
|
123
|
+
// If section doesn't exist yet → add fresh copy
|
|
124
|
+
if (!existing) {
|
|
125
|
+
return acc.concat({
|
|
126
|
+
key: section.key || '',
|
|
127
|
+
keyObj: keyObj || [],
|
|
128
|
+
title: section.title || '',
|
|
129
|
+
count: section.count,
|
|
130
|
+
summaries: section.summaries ? [...section.summaries] : [],
|
|
131
|
+
data: section.data ? [...section.data] : [],
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// If exists → update it by concatenating data & summaries
|
|
136
|
+
const updated = acc.map((s) =>
|
|
137
|
+
s.key === key
|
|
138
|
+
? {
|
|
139
|
+
...s,
|
|
140
|
+
count: s.count + section.count,
|
|
141
|
+
summaries: (s.summaries ?? []).concat(section.summaries ?? []),
|
|
142
|
+
data: (s.data ?? []).concat(section.data ?? []),
|
|
143
|
+
}
|
|
144
|
+
: s,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return updated
|
|
148
|
+
}, []),
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
getSortField() {
|
|
153
|
+
const { sortColumn } = this.reportQuery
|
|
154
|
+
return sortColumn && this.sections.includes(sortColumn) ? [sortColumn] : []
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Sorts sections based on keyObj values using an optional nameOrder override.
|
|
159
|
+
* - nameOrder can be partial; unspecified names fall back to default order
|
|
160
|
+
* - Default order is derived from the first section's keyObj sequence
|
|
161
|
+
*/
|
|
162
|
+
sortSections(sectionedData: SectionedData): SectionedData {
|
|
163
|
+
const nameOrder = this.getSortField()
|
|
164
|
+
const { sections } = sectionedData
|
|
165
|
+
if (sections.length === 0) return sectionedData
|
|
166
|
+
|
|
167
|
+
// Default order is the order of the keyObj.name fields in the first section
|
|
168
|
+
const defaultOrder = sections[0].keyObj.map((k) => k.name)
|
|
169
|
+
|
|
170
|
+
// Merge partial nameOrder with default order
|
|
171
|
+
const finalOrder = nameOrder
|
|
172
|
+
// 1. start with user-specified names
|
|
173
|
+
.filter((name) => defaultOrder.includes(name))
|
|
174
|
+
// 2. append missing names in default order
|
|
175
|
+
.concat(defaultOrder.filter((name) => !nameOrder.includes(name)))
|
|
176
|
+
|
|
177
|
+
// Build map for fast comparison
|
|
178
|
+
const buildMap = (keyObj: SectionKey[]) =>
|
|
179
|
+
keyObj.reduce<Record<string, string>>((acc, ko) => ({ ...acc, [ko.name]: ko.value }), {})
|
|
180
|
+
|
|
181
|
+
const sortedSections = [...sections].sort((a, b) => {
|
|
182
|
+
const aMap = buildMap(a.keyObj)
|
|
183
|
+
const bMap = buildMap(b.keyObj)
|
|
184
|
+
|
|
185
|
+
// Compare using final order
|
|
186
|
+
const comparisons = finalOrder.map((name) => {
|
|
187
|
+
const aVal = aMap[name] ?? ''
|
|
188
|
+
const bVal = bMap[name] ?? ''
|
|
189
|
+
return aVal.localeCompare(bVal, undefined, { numeric: true })
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
// Return first non-zero comparison
|
|
193
|
+
return comparisons.find((x) => x !== 0) ?? 0
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
sections: sortedSections,
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
withSections(sections: string[]) {
|
|
202
|
+
this.sections = sections || []
|
|
203
|
+
return this
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
withFields(fields: components['schemas']['FieldDefinition'][]) {
|
|
207
|
+
this.fields = getFieldsByName(this.sections, fields)
|
|
208
|
+
return this
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
withData(data: Array<Record<string, string>>) {
|
|
212
|
+
this.data = data
|
|
213
|
+
return this
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
withSummaries(summaryData: Array<AsyncSummary>) {
|
|
217
|
+
this.summariesData = summaryData || []
|
|
218
|
+
return this
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
withReportQuery(reportQuery: ReportQuery) {
|
|
222
|
+
this.reportQuery = reportQuery
|
|
223
|
+
return this
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
build(): SectionedData {
|
|
227
|
+
let sections: SectionedData
|
|
228
|
+
if (this.sections.length) {
|
|
229
|
+
this.groupBySections(this.data, this.fields)
|
|
230
|
+
this.createSummarySections()
|
|
231
|
+
sections = this.mergeSections()
|
|
232
|
+
sections = this.sortSections(sections)
|
|
233
|
+
} else {
|
|
234
|
+
const singleSection: SectionData = {
|
|
235
|
+
key: '',
|
|
236
|
+
keyObj: [],
|
|
237
|
+
data: this.data,
|
|
238
|
+
count: this.data.length,
|
|
239
|
+
summaries: this.summariesData,
|
|
240
|
+
}
|
|
241
|
+
sections = { sections: [singleSection] }
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return sections
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var types_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(types_exports);
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../dpr/utils/TemplateBuilder/SectionedDataHelper/types.ts"],
|
|
4
|
+
"sourcesContent": ["import { AsyncSummary } from '../../../types/UserReports'\nimport { SummaryTemplate } from '../../../types/Templates'\nimport { ListSectionTableData } from '../ReportBuilder/types'\nimport { ParentChildTableData } from '../ParentChildDataBuilder/types'\nimport { DataTable } from '../../DataTableBuilder/types'\n\nexport interface SectionedData {\n sections: SectionData[]\n}\n\nexport interface ReportTemplateData {\n rowCount: number\n summaries?: Record<string, DataTable[]>\n sections: SectionDataResult[]\n}\n\nexport interface SectionSummary {\n template: SummaryTemplate\n data: ListSectionTableData // TODO: fix this\n}\n\nexport interface SectionKey {\n name: string\n value: string\n}\n\nexport interface SectionData {\n key?: string\n keyObj: SectionKey[]\n title?: string\n count: number\n summaries: AsyncSummary[]\n data: Array<Record<string, string>>\n}\n\nexport interface SectionDataResult {\n title?: string\n count: number\n summaries: Record<string, DataTable[]>\n data: Array<Record<string, string>> | ParentChildTableData[] | ListSectionTableData\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { AsyncSummary } from '../../../types/UserReports'
|
|
2
|
+
import { SummaryTemplate } from '../../../types/Templates'
|
|
3
|
+
import { ListSectionTableData } from '../ReportBuilder/types'
|
|
4
|
+
import { ParentChildTableData } from '../ParentChildDataBuilder/types'
|
|
5
|
+
import { DataTable } from '../../DataTableBuilder/types'
|
|
6
|
+
|
|
7
|
+
export interface SectionedData {
|
|
8
|
+
sections: SectionData[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ReportTemplateData {
|
|
12
|
+
rowCount: number
|
|
13
|
+
summaries?: Record<string, DataTable[]>
|
|
14
|
+
sections: SectionDataResult[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface SectionSummary {
|
|
18
|
+
template: SummaryTemplate
|
|
19
|
+
data: ListSectionTableData // TODO: fix this
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface SectionKey {
|
|
23
|
+
name: string
|
|
24
|
+
value: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SectionData {
|
|
28
|
+
key?: string
|
|
29
|
+
keyObj: SectionKey[]
|
|
30
|
+
title?: string
|
|
31
|
+
count: number
|
|
32
|
+
summaries: AsyncSummary[]
|
|
33
|
+
data: Array<Record<string, string>>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface SectionDataResult {
|
|
37
|
+
title?: string
|
|
38
|
+
count: number
|
|
39
|
+
summaries: Record<string, DataTable[]>
|
|
40
|
+
data: Array<Record<string, string>> | ParentChildTableData[] | ListSectionTableData
|
|
41
|
+
}
|
|
@@ -26,13 +26,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
mod
|
|
27
27
|
));
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
var
|
|
30
|
-
__export(
|
|
31
|
-
CollatedSummaryBuilder: () => CollatedSummaryBuilder
|
|
32
|
-
default: () => CollatedSummaryBuilder_default
|
|
29
|
+
var SummaryDataHelper_exports = {};
|
|
30
|
+
__export(SummaryDataHelper_exports, {
|
|
31
|
+
CollatedSummaryBuilder: () => CollatedSummaryBuilder
|
|
33
32
|
});
|
|
34
|
-
module.exports = __toCommonJS(
|
|
35
|
-
var import_SummaryDataTableBuilder = __toESM(require("
|
|
33
|
+
module.exports = __toCommonJS(SummaryDataHelper_exports);
|
|
34
|
+
var import_SummaryDataTableBuilder = __toESM(require("../../SummaryDataTableBuilder/SummaryDataTableBuilder"));
|
|
36
35
|
class CollatedSummaryBuilder {
|
|
37
36
|
summaries;
|
|
38
37
|
specification;
|
|
@@ -84,9 +83,8 @@ class CollatedSummaryBuilder {
|
|
|
84
83
|
return dataTables;
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
|
-
var CollatedSummaryBuilder_default = CollatedSummaryBuilder;
|
|
88
86
|
// Annotate the CommonJS export names for ESM import in node:
|
|
89
87
|
0 && (module.exports = {
|
|
90
88
|
CollatedSummaryBuilder
|
|
91
89
|
});
|
|
92
|
-
//# sourceMappingURL=
|
|
90
|
+
//# sourceMappingURL=SummaryDataHelper.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../dpr/utils/TemplateBuilder/SummaryDataHelper/SummaryDataHelper.ts"],
|
|
4
|
+
"sourcesContent": ["import Dict = NodeJS.Dict\nimport { AsyncSummary } from '../../../types/UserReports'\nimport { SummaryTemplate } from '../../../types/Templates'\nimport { components } from '../../../types/api'\nimport { DataTable } from '../../DataTableBuilder/types'\nimport SummaryDataTableBuilder from '../../SummaryDataTableBuilder/SummaryDataTableBuilder'\n\nexport class CollatedSummaryBuilder {\n private summaries: Array<AsyncSummary>\n\n private specification: components['schemas']['Specification']\n\n constructor(specification: components['schemas']['Specification'], summaries: Array<AsyncSummary>) {\n this.specification = specification\n this.summaries = summaries\n }\n\n pageSummaryTemplates: Array<SummaryTemplate> = ['page-header', 'page-footer']\n\n dataTableSummaryTemplates: Array<SummaryTemplate> = [\n 'section-footer',\n 'section-header',\n 'table-footer',\n 'table-header',\n ]\n\n collatePageSummaries(): Dict<Array<DataTable>> {\n return this.collateAndMapToDataTable(this.pageSummaryTemplates)\n }\n\n collateDataTableSummaries(): Dict<Array<AsyncSummary>> {\n return this.collate(this.dataTableSummaryTemplates)\n }\n\n collateAndMapToDataTable(summaryTemplates: Array<SummaryTemplate> = []): Dict<Array<DataTable>> {\n const collatedSummaries = this.collate(summaryTemplates)\n\n return this.mapToDataTables(collatedSummaries)\n }\n\n collate(summaryTemplates: Array<SummaryTemplate> = this.pageSummaryTemplates): Dict<Array<AsyncSummary>> {\n const collatedSummaries: Dict<Array<AsyncSummary>> = {}\n if (this.summaries) {\n this.summaries.forEach((summary: AsyncSummary) => {\n const { template } = summary\n if (summaryTemplates.includes(template)) {\n if (!collatedSummaries[template]) {\n collatedSummaries[template] = []\n }\n collatedSummaries[template].push(summary)\n }\n })\n }\n\n return collatedSummaries\n }\n\n private mapToDataTables(summaries: Dict<Array<AsyncSummary>>): Dict<Array<DataTable>> {\n const dataTables: Dict<Array<DataTable>> = {}\n\n Object.keys(summaries).forEach((summaryType) => {\n if (summaries[summaryType]) {\n dataTables[summaryType] = summaries[summaryType].map((summary) => {\n return new SummaryDataTableBuilder(summary, this.specification.sections).buildSummaryTable()\n })\n }\n })\n\n return dataTables\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,qCAAoC;AAE7B,MAAM,uBAAuB;AAAA,EAC1B;AAAA,EAEA;AAAA,EAER,YAAY,eAAuD,WAAgC;AACjG,SAAK,gBAAgB;AACrB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,uBAA+C,CAAC,eAAe,aAAa;AAAA,EAE5E,4BAAoD;AAAA,IAClD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA,uBAA+C;AAC7C,WAAO,KAAK,yBAAyB,KAAK,oBAAoB;AAAA,EAChE;AAAA,EAEA,4BAAuD;AACrD,WAAO,KAAK,QAAQ,KAAK,yBAAyB;AAAA,EACpD;AAAA,EAEA,yBAAyB,mBAA2C,CAAC,GAA2B;AAC9F,UAAM,oBAAoB,KAAK,QAAQ,gBAAgB;AAEvD,WAAO,KAAK,gBAAgB,iBAAiB;AAAA,EAC/C;AAAA,EAEA,QAAQ,mBAA2C,KAAK,sBAAiD;AACvG,UAAM,oBAA+C,CAAC;AACtD,QAAI,KAAK,WAAW;AAClB,WAAK,UAAU,QAAQ,CAAC,YAA0B;AAChD,cAAM,EAAE,SAAS,IAAI;AACrB,YAAI,iBAAiB,SAAS,QAAQ,GAAG;AACvC,cAAI,CAAC,kBAAkB,QAAQ,GAAG;AAChC,8BAAkB,QAAQ,IAAI,CAAC;AAAA,UACjC;AACA,4BAAkB,QAAQ,EAAE,KAAK,OAAO;AAAA,QAC1C;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,gBAAgB,WAA8D;AACpF,UAAM,aAAqC,CAAC;AAE5C,WAAO,KAAK,SAAS,EAAE,QAAQ,CAAC,gBAAgB;AAC9C,UAAI,UAAU,WAAW,GAAG;AAC1B,mBAAW,WAAW,IAAI,UAAU,WAAW,EAAE,IAAI,CAAC,YAAY;AAChE,iBAAO,IAAI,+BAAAA,QAAwB,SAAS,KAAK,cAAc,QAAQ,EAAE,kBAAkB;AAAA,QAC7F,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AACF;",
|
|
6
|
+
"names": ["SummaryDataTableBuilder"]
|
|
7
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { expect } from '@jest/globals'
|
|
2
|
-
import { components } from '
|
|
3
|
-
import CollatedSummaryBuilder from './
|
|
4
|
-
import { AsyncSummary } from '
|
|
5
|
-
import { DataTable } from '
|
|
2
|
+
import { components } from '../../../types/api'
|
|
3
|
+
import { CollatedSummaryBuilder } from './SummaryDataHelper'
|
|
4
|
+
import { AsyncSummary } from '../../../types/UserReports'
|
|
5
|
+
import { DataTable } from '../../DataTableBuilder/types'
|
|
6
6
|
|
|
7
7
|
const activityField: components['schemas']['FieldDefinition'] = {
|
|
8
8
|
header: false,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import Dict = NodeJS.Dict
|
|
2
|
-
import { AsyncSummary } from '
|
|
3
|
-
import { SummaryTemplate } from '
|
|
4
|
-
import { components } from '
|
|
5
|
-
import { DataTable } from '
|
|
6
|
-
import SummaryDataTableBuilder from '
|
|
2
|
+
import { AsyncSummary } from '../../../types/UserReports'
|
|
3
|
+
import { SummaryTemplate } from '../../../types/Templates'
|
|
4
|
+
import { components } from '../../../types/api'
|
|
5
|
+
import { DataTable } from '../../DataTableBuilder/types'
|
|
6
|
+
import SummaryDataTableBuilder from '../../SummaryDataTableBuilder/SummaryDataTableBuilder'
|
|
7
7
|
|
|
8
|
-
class CollatedSummaryBuilder {
|
|
8
|
+
export class CollatedSummaryBuilder {
|
|
9
9
|
private summaries: Array<AsyncSummary>
|
|
10
10
|
|
|
11
11
|
private specification: components['schemas']['Specification']
|
|
@@ -69,6 +69,3 @@ class CollatedSummaryBuilder {
|
|
|
69
69
|
return dataTables
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
|
|
73
|
-
export { CollatedSummaryBuilder }
|
|
74
|
-
export default CollatedSummaryBuilder
|