@ministryofjustice/hmpps-digital-prison-reporting-frontend 4.28.7 → 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.
Files changed (194) hide show
  1. package/dpr/all.js +6 -8
  2. package/dpr/all.js.map +3 -3
  3. package/dpr/all.scss +296 -414
  4. package/dpr/all.ts +6 -11
  5. package/dpr/components/_catalogue/catalogue-list/utils.test.ts +1 -1
  6. package/dpr/components/_charts/chart/clientClass.js +1 -0
  7. package/dpr/components/_charts/chart/clientClass.js.map +2 -2
  8. package/dpr/components/_charts/chart/clientClass.ts +1 -0
  9. package/dpr/components/_reports/{report-actions → report-heading/report-actions}/actionsTemplate.js.map +1 -1
  10. package/dpr/components/_reports/{report-actions → report-heading/report-actions}/clientClass.js +1 -1
  11. package/dpr/components/_reports/report-heading/report-actions/clientClass.js.map +7 -0
  12. package/dpr/components/_reports/{report-actions → report-heading/report-actions}/clientClass.ts +1 -1
  13. package/dpr/components/_reports/report-heading/report-actions/types.d.js.map +7 -0
  14. package/dpr/components/_reports/{report-actions → report-heading/report-actions}/types.d.ts +1 -1
  15. package/dpr/components/_reports/{report-actions → report-heading/report-actions}/utils.js.map +1 -1
  16. package/dpr/components/_reports/{report-actions → report-heading/report-actions}/utils.test.ts +2 -2
  17. package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/clientClass.js +1 -3
  18. package/dpr/components/_reports/report-heading/report-columns/report-columns-form/clientClass.js.map +7 -0
  19. package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/clientClass.ts +1 -3
  20. package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/types.d.js.map +1 -1
  21. package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/utils.js +1 -1
  22. package/dpr/components/_reports/report-heading/report-columns/report-columns-form/utils.js.map +7 -0
  23. package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/utils.ts +2 -2
  24. package/dpr/components/_reports/{report-columns → report-heading/report-columns}/view.njk +1 -1
  25. package/dpr/components/_reports/{report-download-message → report-heading/report-download-message}/clientClass.js +1 -1
  26. package/dpr/components/_reports/report-heading/report-download-message/clientClass.js.map +7 -0
  27. package/dpr/components/_reports/{report-download-message → report-heading/report-download-message}/clientClass.ts +1 -1
  28. package/dpr/components/_reports/{report-filters → report-heading/report-filters}/view.njk +1 -1
  29. package/dpr/components/_reports/report-heading/view.njk +4 -4
  30. package/dpr/components/_reports/report-page/report-print-message/view.njk +10 -0
  31. package/dpr/components/_reports/report-page/report-template/report-no-data-message/styles.scss +8 -0
  32. package/dpr/components/_reports/report-page/report-template/report-no-data-message/view.njk +11 -0
  33. package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/clientClass.js +1 -1
  34. package/dpr/components/_reports/report-page/report-template/report-pagination/clientClass.js.map +7 -0
  35. package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/clientClass.ts +1 -1
  36. package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/types.d.js.map +1 -1
  37. package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/utils.js.map +1 -1
  38. package/dpr/components/_reports/report-page/report-template/report-section/parent-child-template/styles.scss +88 -0
  39. package/dpr/components/_reports/report-page/report-template/report-section/parent-child-template/view.njk +29 -0
  40. package/dpr/components/_reports/{report-data-table → report-page/report-template/report-section/report-data-table}/clientClass.js +17 -10
  41. package/dpr/components/_reports/report-page/report-template/report-section/report-data-table/clientClass.js.map +7 -0
  42. package/dpr/components/_reports/{report-data-table → report-page/report-template/report-section/report-data-table}/clientClass.ts +20 -10
  43. package/dpr/components/_reports/{report-data-table → report-page/report-template/report-section/report-data-table}/style.scss +35 -185
  44. package/dpr/components/_reports/report-page/report-template/report-section/report-data-table/types.d.js.map +7 -0
  45. package/dpr/components/_reports/{report-data-table → report-page/report-template/report-section/report-data-table}/types.d.ts +2 -2
  46. package/dpr/components/_reports/report-page/report-template/report-section/report-data-table/view.njk +27 -0
  47. package/dpr/components/_reports/report-page/report-template/report-section/styles.scss +33 -0
  48. package/dpr/components/_reports/report-page/report-template/report-section/view.njk +58 -0
  49. package/dpr/components/_reports/{report-summary-table → report-page/report-template/report-summary-table}/styles.scss +21 -4
  50. package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/utils.js.map +1 -1
  51. package/dpr/components/_reports/report-page/report-template/styles.scss +5 -0
  52. package/dpr/components/_reports/report-page/report-template/template-config.js +66 -0
  53. package/dpr/components/_reports/report-page/report-template/template-config.js.map +7 -0
  54. package/dpr/components/_reports/report-page/report-template/template-config.ts +45 -0
  55. package/dpr/components/_reports/report-page/report-template/utils.js +82 -0
  56. package/dpr/components/_reports/report-page/report-template/utils.js.map +7 -0
  57. package/dpr/components/_reports/report-page/report-template/utils.ts +100 -0
  58. package/dpr/components/_reports/report-page/report-template/view.njk +61 -0
  59. package/dpr/components/_reports/{report-wrapper → report-page}/styles.scss +7 -5
  60. package/dpr/components/_reports/report-page/view.njk +26 -0
  61. package/dpr/components/card-group/view.njk +0 -4
  62. package/dpr/components/report-list/utils.js +11 -3
  63. package/dpr/components/report-list/utils.js.map +2 -2
  64. package/dpr/components/report-list/utils.ts +11 -1
  65. package/dpr/components/report-list/view.njk +2 -2
  66. package/dpr/components/show-more/style.scss +3 -4
  67. package/dpr/data/reportingClient.js.map +2 -2
  68. package/dpr/data/reportingClient.ts +4 -4
  69. package/dpr/routes/journeys/view-report/async/dashboard/utils.js +1 -1
  70. package/dpr/routes/journeys/view-report/async/dashboard/utils.js.map +1 -1
  71. package/dpr/routes/journeys/view-report/async/dashboard/utils.ts +1 -1
  72. package/dpr/routes/journeys/view-report/async/report/controller.js.map +2 -2
  73. package/dpr/routes/journeys/view-report/async/report/controller.ts +0 -1
  74. package/dpr/routes/journeys/view-report/async/report/report-variants.cy.js +207 -56
  75. package/dpr/routes/journeys/view-report/async/report/report-variants.cy.js.map +2 -2
  76. package/dpr/routes/journeys/view-report/async/report/report-variants.cy.ts +333 -64
  77. package/dpr/routes/journeys/view-report/async/report/utils.js +9 -17
  78. package/dpr/routes/journeys/view-report/async/report/utils.js.map +3 -3
  79. package/dpr/routes/journeys/view-report/async/report/utils.ts +12 -22
  80. package/dpr/routes/journeys/view-report/report.njk +2 -2
  81. package/dpr/routes/journeys/view-report/sync/dashboard/utils.js +2 -2
  82. package/dpr/routes/journeys/view-report/sync/dashboard/utils.js.map +1 -1
  83. package/dpr/routes/journeys/view-report/sync/dashboard/utils.ts +2 -2
  84. package/dpr/routes/journeys/view-report/sync/report/utils.js +38 -11
  85. package/dpr/routes/journeys/view-report/sync/report/utils.js.map +3 -3
  86. package/dpr/routes/journeys/view-report/sync/report/utils.ts +39 -14
  87. package/dpr/routes/journeys/view-report/utils.js +1 -1
  88. package/dpr/routes/journeys/view-report/utils.js.map +1 -1
  89. package/dpr/routes/journeys/view-report/utils.ts +1 -1
  90. package/dpr/services/reportingService.js.map +2 -2
  91. package/dpr/services/reportingService.ts +2 -2
  92. package/dpr/types/ReportQuery.js +1 -1
  93. package/dpr/types/ReportQuery.js.map +1 -1
  94. package/dpr/types/ReportQuery.ts +1 -1
  95. package/dpr/types/UserReports.js.map +1 -1
  96. package/dpr/types/UserReports.ts +3 -3
  97. package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/ParentChildDataBuilder.js +193 -0
  98. package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/ParentChildDataBuilder.js.map +7 -0
  99. package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/ParentChildDataBuilder.ts +203 -0
  100. package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/types.d.js.map +7 -0
  101. package/dpr/utils/TemplateBuilder/ParentChildDataBuilder/types.d.ts +36 -0
  102. package/dpr/utils/TemplateBuilder/ReportBuilder/ReportBuilder.js +114 -0
  103. package/dpr/utils/TemplateBuilder/ReportBuilder/ReportBuilder.js.map +7 -0
  104. package/dpr/utils/TemplateBuilder/ReportBuilder/ReportBuilder.ts +117 -0
  105. package/dpr/utils/TemplateBuilder/ReportBuilder/types.d.js.map +7 -0
  106. package/dpr/utils/TemplateBuilder/ReportBuilder/types.d.ts +6 -0
  107. package/dpr/utils/TemplateBuilder/SectionedDataHelper/SectionedDataHelper.js +202 -0
  108. package/dpr/utils/TemplateBuilder/SectionedDataHelper/SectionedDataHelper.js.map +7 -0
  109. package/dpr/utils/TemplateBuilder/SectionedDataHelper/SectionedDataHelper.ts +246 -0
  110. package/dpr/utils/TemplateBuilder/SectionedDataHelper/types.js +17 -0
  111. package/dpr/utils/TemplateBuilder/SectionedDataHelper/types.js.map +7 -0
  112. package/dpr/utils/TemplateBuilder/SectionedDataHelper/types.ts +41 -0
  113. package/dpr/utils/{CollatedSummaryBuilder/CollatedSummaryBuilder.js → TemplateBuilder/SummaryDataHelper/SummaryDataHelper.js} +6 -8
  114. package/dpr/utils/TemplateBuilder/SummaryDataHelper/SummaryDataHelper.js.map +7 -0
  115. package/dpr/utils/{CollatedSummaryBuilder/CollatedSummaryBuilder.test.ts → TemplateBuilder/SummaryDataHelper/SummaryDataHelper.test.ts} +4 -4
  116. package/dpr/utils/{CollatedSummaryBuilder/CollatedSummaryBuilder.ts → TemplateBuilder/SummaryDataHelper/SummaryDataHelper.ts} +6 -9
  117. package/dpr/utils/TemplateBuilder/TemplateBuilder.js +74 -0
  118. package/dpr/utils/TemplateBuilder/TemplateBuilder.js.map +7 -0
  119. package/dpr/utils/TemplateBuilder/TemplateBuilder.ts +68 -0
  120. package/dpr/utils/definitionUtils.js +22 -2
  121. package/dpr/utils/definitionUtils.js.map +2 -2
  122. package/dpr/utils/definitionUtils.ts +26 -1
  123. package/package.json +1 -1
  124. package/dpr/DprLoadingHelper.js +0 -51
  125. package/dpr/DprLoadingHelper.js.map +0 -7
  126. package/dpr/DprLoadingHelper.ts +0 -27
  127. package/dpr/components/_reports/report/view.njk +0 -40
  128. package/dpr/components/_reports/report-actions/clientClass.js.map +0 -7
  129. package/dpr/components/_reports/report-actions/types.d.js.map +0 -7
  130. package/dpr/components/_reports/report-columns-form/clientClass.js.map +0 -7
  131. package/dpr/components/_reports/report-columns-form/utils.js.map +0 -7
  132. package/dpr/components/_reports/report-data-table/clientClass.js.map +0 -7
  133. package/dpr/components/_reports/report-data-table/types.d.js.map +0 -7
  134. package/dpr/components/_reports/report-data-table/utils.js +0 -123
  135. package/dpr/components/_reports/report-data-table/utils.js.map +0 -7
  136. package/dpr/components/_reports/report-data-table/utils.test.ts +0 -604
  137. package/dpr/components/_reports/report-data-table/utils.ts +0 -150
  138. package/dpr/components/_reports/report-data-table/view.njk +0 -24
  139. package/dpr/components/_reports/report-data-table-wrapper/view.njk +0 -27
  140. package/dpr/components/_reports/report-download-message/clientClass.js.map +0 -7
  141. package/dpr/components/_reports/report-no-data-message/styles.scss +0 -4
  142. package/dpr/components/_reports/report-no-data-message/view.njk +0 -13
  143. package/dpr/components/_reports/report-pagination/clientClass.js.map +0 -7
  144. package/dpr/components/_reports/report-print-message/view.njk +0 -8
  145. package/dpr/components/_reports/report-template/view.njk +0 -44
  146. package/dpr/components/_reports/report-wrapper/view.njk +0 -19
  147. package/dpr/components/loading-anim/styles.scss +0 -117
  148. package/dpr/components/loading-anim/view.njk +0 -18
  149. package/dpr/utils/CollatedSummaryBuilder/CollatedSummaryBuilder.js.map +0 -7
  150. package/dpr/utils/ParentChildDataTableBuilder/ParentChildDataTableBuilder.js +0 -202
  151. package/dpr/utils/ParentChildDataTableBuilder/ParentChildDataTableBuilder.js.map +0 -7
  152. package/dpr/utils/ParentChildDataTableBuilder/ParentChildDataTableBuilder.test.ts +0 -503
  153. package/dpr/utils/ParentChildDataTableBuilder/ParentChildDataTableBuilder.ts +0 -224
  154. package/dpr/utils/ParentChildDataTableBuilder/types.d.js.map +0 -7
  155. package/dpr/utils/ParentChildDataTableBuilder/types.d.ts +0 -11
  156. package/dpr/utils/SectionedDataTableBuilder/SectionedDataTableBuilder.js +0 -311
  157. package/dpr/utils/SectionedDataTableBuilder/SectionedDataTableBuilder.js.map +0 -7
  158. package/dpr/utils/SectionedDataTableBuilder/SectionedDataTableBuilder.test.ts +0 -492
  159. package/dpr/utils/SectionedDataTableBuilder/SectionedDataTableBuilder.ts +0 -342
  160. package/dpr/utils/SectionedDataTableBuilder/types.d.js.map +0 -7
  161. package/dpr/utils/SectionedDataTableBuilder/types.d.ts +0 -5
  162. package/dpr/utils/SectionedFieldsTableBuilder/SectionedFieldsTableBuilder.js +0 -146
  163. package/dpr/utils/SectionedFieldsTableBuilder/SectionedFieldsTableBuilder.js.map +0 -7
  164. package/dpr/utils/SectionedFieldsTableBuilder/SectionedFieldsTableBuilder.test.ts +0 -140
  165. package/dpr/utils/SectionedFieldsTableBuilder/SectionedFieldsTableBuilder.ts +0 -150
  166. /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/actionsTemplate.js +0 -0
  167. /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/actionsTemplate.ts +0 -0
  168. /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/style.scss +0 -0
  169. /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/types.d.js +0 -0
  170. /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/utils.js +0 -0
  171. /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/utils.ts +0 -0
  172. /package/dpr/components/_reports/{report-actions → report-heading/report-actions}/view.njk +0 -0
  173. /package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/style.scss +0 -0
  174. /package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/types.d.js +0 -0
  175. /package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/types.d.ts +0 -0
  176. /package/dpr/components/_reports/{report-columns-form → report-heading/report-columns/report-columns-form}/view.njk +0 -0
  177. /package/dpr/components/_reports/{report-columns → report-heading/report-columns}/styles.scss +0 -0
  178. /package/dpr/components/_reports/{report-download-message → report-heading/report-download-message}/style.scss +0 -0
  179. /package/dpr/components/_reports/{report-download-message → report-heading/report-download-message}/view.njk +0 -0
  180. /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/style.scss +0 -0
  181. /package/dpr/components/_reports/{report-data-table → report-page/report-template/report-pagination}/types.d.js +0 -0
  182. /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/types.d.ts +0 -0
  183. /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/utils.js +0 -0
  184. /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/utils.test.ts +0 -0
  185. /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/utils.ts +0 -0
  186. /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-pagination}/view.njk +0 -0
  187. /package/dpr/components/_reports/{report-pagination → report-page/report-template/report-section/report-data-table}/types.d.js +0 -0
  188. /package/dpr/components/_reports/{report-summary-table → report-page/report-template/report-summary-table}/view.njk +0 -0
  189. /package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/style.scss +0 -0
  190. /package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/utils.js +0 -0
  191. /package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/utils.ts +0 -0
  192. /package/dpr/components/_reports/{report-totals → report-page/report-template/report-totals}/view.njk +0 -0
  193. /package/dpr/utils/{ParentChildDataTableBuilder → TemplateBuilder/ParentChildDataBuilder}/types.d.js +0 -0
  194. /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 CollatedSummaryBuilder_exports = {};
30
- __export(CollatedSummaryBuilder_exports, {
31
- CollatedSummaryBuilder: () => CollatedSummaryBuilder,
32
- default: () => CollatedSummaryBuilder_default
29
+ var SummaryDataHelper_exports = {};
30
+ __export(SummaryDataHelper_exports, {
31
+ CollatedSummaryBuilder: () => CollatedSummaryBuilder
33
32
  });
34
- module.exports = __toCommonJS(CollatedSummaryBuilder_exports);
35
- var import_SummaryDataTableBuilder = __toESM(require("../SummaryDataTableBuilder/SummaryDataTableBuilder"));
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=CollatedSummaryBuilder.js.map
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 '../../types/api'
3
- import CollatedSummaryBuilder from './CollatedSummaryBuilder'
4
- import { AsyncSummary } from '../../types/UserReports'
5
- import { DataTable } from '../DataTableBuilder/types'
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 '../../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'
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