@ampath/esm-reports-app 1.0.0-next.41 → 1.0.0-next.45

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 (183) hide show
  1. package/dist/143.css +1 -0
  2. package/dist/143.css.map +1 -0
  3. package/dist/143.js +1 -0
  4. package/dist/143.js.map +1 -0
  5. package/dist/197.js +1 -1
  6. package/dist/282.js +1 -1
  7. package/dist/282.js.map +1 -1
  8. package/dist/295.css +1 -0
  9. package/dist/295.css.map +1 -0
  10. package/dist/295.js +1 -0
  11. package/dist/295.js.map +1 -0
  12. package/dist/300.js +1 -1
  13. package/dist/311.js +1 -1
  14. package/dist/311.js.map +1 -1
  15. package/dist/335.js +1 -1
  16. package/dist/353.js +1 -1
  17. package/dist/353.js.map +1 -1
  18. package/dist/410.js +1 -0
  19. package/dist/410.js.map +1 -0
  20. package/dist/427.js +2 -0
  21. package/dist/427.js.LICENSE.txt +35 -0
  22. package/dist/427.js.map +1 -0
  23. package/dist/441.js +1 -0
  24. package/dist/441.js.map +1 -0
  25. package/dist/478.js +1 -1
  26. package/dist/478.js.map +1 -1
  27. package/dist/540.js +1 -1
  28. package/dist/540.js.map +1 -1
  29. package/dist/55.js +1 -1
  30. package/dist/652.js +1 -1
  31. package/dist/961.js +1 -1
  32. package/dist/961.js.map +1 -1
  33. package/dist/99.js +1 -1
  34. package/dist/ampath-esm-reports-app.js +1 -1
  35. package/dist/ampath-esm-reports-app.js.map +1 -1
  36. package/dist/routes.json +1 -1
  37. package/package.json +2 -2
  38. package/src/common/report-error/index.ts +1 -0
  39. package/src/common/report-error/show-report-error.ts +25 -0
  40. package/src/common/report-filters/date-range.ts +137 -0
  41. package/src/common/report-filters/index.ts +4 -0
  42. package/src/common/report-filters/report-filters.component.tsx +281 -151
  43. package/src/common/report-filters/report-filters.scss +180 -55
  44. package/src/common/report-filters/types.ts +66 -0
  45. package/src/common/report-filters/use-restore-period.ts +43 -0
  46. package/src/common/report-page/index.ts +2 -0
  47. package/src/common/report-page/report-page.component.tsx +32 -0
  48. package/src/common/report-page/report-page.scss +45 -0
  49. package/src/common/report-page/use-page-scale.ts +50 -0
  50. package/src/common/report-placeholder/has-report-data.ts +15 -0
  51. package/src/common/report-placeholder/index.ts +2 -0
  52. package/src/common/report-placeholder/report-placeholder.component.tsx +56 -0
  53. package/src/common/report-placeholder/report-placeholder.scss +46 -0
  54. package/src/common/report-register/index.ts +5 -0
  55. package/src/common/report-register/register-columns.ts +34 -0
  56. package/src/common/report-register/register-layout.component.tsx +237 -0
  57. package/src/common/report-register/register-layout.scss +140 -0
  58. package/src/common/report-register/register-table.scss +62 -0
  59. package/src/common/report-register/report-parents.ts +27 -0
  60. package/src/common/report-register/rows-to-csv.ts +59 -0
  61. package/src/common/report-register/use-patient-list.ts +92 -0
  62. package/src/common/report-skeleton/index.ts +1 -0
  63. package/src/common/report-skeleton/report-skeleton.component.tsx +46 -0
  64. package/src/common/report-skeleton/report-skeleton.scss +29 -0
  65. package/src/config-schema.ts +9 -1
  66. package/src/dashboard/report-catalog.ts +173 -0
  67. package/src/dashboard/reports-dasboard.tsx +101 -35
  68. package/src/dashboard/reports-dashboard.module.scss +269 -11
  69. package/src/index.ts +13 -1
  70. package/src/reports/datatable-wrapper/datatable-wrapper.component.tsx +50 -48
  71. package/src/reports/moh-240/moh-240-header.component.tsx +54 -56
  72. package/src/reports/moh-240/moh-240.columns.ts +64 -0
  73. package/src/reports/moh-240/moh-240.component.tsx +65 -84
  74. package/src/reports/moh-240/moh-240.scss +36 -7
  75. package/src/reports/moh-240/sub-reports/moh-240-register.component.tsx +27 -65
  76. package/src/reports/moh-240/sub-reports/page-summary.component.tsx +2 -2
  77. package/src/reports/moh-505/moh-505-header.component.tsx +59 -57
  78. package/src/reports/moh-505/moh-505.component.tsx +51 -56
  79. package/src/reports/moh-505/moh-505.scss +116 -2
  80. package/src/reports/moh-705B/moh-204b-register.component.tsx +41 -42
  81. package/src/reports/moh-705B/moh-204b.columns.ts +39 -0
  82. package/src/reports/moh-705B/moh-705b.component.tsx +492 -473
  83. package/src/reports/moh-705B/moh-705b.scss +110 -24
  84. package/src/reports/moh-705a/moh-705a.component.tsx +496 -476
  85. package/src/reports/moh-705a/moh-705a.scss +109 -24
  86. package/src/reports/moh-705a/registers/moh-204a-register.component.tsx +41 -42
  87. package/src/reports/moh-705a/registers/moh-204a.columns.ts +57 -0
  88. package/src/reports/moh-706/moh-706-header.component.tsx +58 -56
  89. package/src/reports/moh-706/moh-706.component.tsx +84 -55
  90. package/src/reports/moh-706/moh-706.scss +115 -19
  91. package/src/reports/moh-710/moh-710.component.tsx +743 -727
  92. package/src/reports/moh-710/moh-710.scss +140 -23
  93. package/src/reports/moh-710/registers/moh-511-710-register.component.tsx +48 -43
  94. package/src/reports/moh-710/registers/moh-511-710.columns.ts +52 -0
  95. package/src/reports/moh-711/moh-711.component.tsx +94 -106
  96. package/src/reports/moh-711/moh711.scss +95 -64
  97. package/src/reports/moh-711/registers/moh-333-register.component.tsx +92 -94
  98. package/src/reports/moh-711/registers/moh-333.columns.ts +119 -0
  99. package/src/reports/moh-711/registers/moh-405-register.component.tsx +88 -89
  100. package/src/reports/moh-711/registers/moh-405.columns.ts +120 -0
  101. package/src/reports/moh-711/registers/moh-406-register.component.tsx +85 -88
  102. package/src/reports/moh-711/registers/moh-406.columns.ts +133 -0
  103. package/src/reports/moh-711/registers/moh-510-register.component.tsx +38 -44
  104. package/src/reports/moh-711/registers/moh-511-register.component.tsx +42 -43
  105. package/src/reports/moh-711/registers/moh-511.columns.ts +59 -0
  106. package/src/reports/moh-711/sections/anc.component.tsx +3 -3
  107. package/src/reports/moh-711/sections/cervical-cancer.component.tsx +3 -3
  108. package/src/reports/moh-711/sections/chanis.component.tsx +2 -3
  109. package/src/reports/moh-711/sections/family-planning.component.tsx +2 -2
  110. package/src/reports/moh-711/sections/gbv.component.tsx +2 -2
  111. package/src/reports/moh-711/sections/maternity.component.tsx +3 -8
  112. package/src/reports/moh-711/sections/medical-social-work.component.tsx +2 -12
  113. package/src/reports/moh-711/sections/other.component.tsx +2 -2
  114. package/src/reports/moh-711/sections/physiotherapy.component.tsx +2 -2
  115. package/src/reports/moh-711/sections/pnc.component.tsx +7 -5
  116. package/src/reports/moh-711/sections/post-abortion.component.tsx +2 -2
  117. package/src/reports/moh-711/sections/rehabilitation.component.tsx +2 -2
  118. package/src/reports/moh-711/sections/report-compiled-by.component.tsx +12 -4
  119. package/src/reports/moh-711/sections/tb-screening.component.tsx +2 -2
  120. package/src/reports/moh-717/moh-717.component.tsx +100 -121
  121. package/src/reports/moh-717/moh717.scss +163 -102
  122. package/src/reports/moh-717/sections/maternity.component.tsx +1 -1
  123. package/src/reports/moh-717/sections/orthopaedic-trauma.component.tsx +1 -1
  124. package/src/reports/moh-717/sections/outpatient.component.tsx +23 -23
  125. package/src/reports/moh-717/sections/preparedby.component.tsx +7 -2
  126. package/src/reports/moh-717/sections/special-services.component.tsx +1 -1
  127. package/src/reports/moh-731/moh-731.component.tsx +127 -110
  128. package/src/reports/moh-731/moh-731.scss +396 -68
  129. package/src/reports/moh-731/registers/moh-366.columns.ts +38 -0
  130. package/src/reports/moh-731/registers/moh-366.component.tsx +76 -83
  131. package/src/reports/moh-731/registers/prep-register.component.tsx +70 -78
  132. package/src/reports/moh-731/registers/prep.columns.ts +34 -0
  133. package/src/reports/moh-731/sections/hiv-and-tb-treatment.component.tsx +1031 -751
  134. package/src/reports/moh-731/sections/hiv-testing-and-pre-exposure.component.tsx +230 -86
  135. package/src/reports/moh-731/sections/pmtct.component.tsx +185 -64
  136. package/src/reports/moh-740/moh-740.component.scss +159 -79
  137. package/src/reports/moh-740/moh-740.component.tsx +261 -230
  138. package/src/reports/moh-740/moh-740.resource.ts +17 -10
  139. package/src/reports/moh-740/registers/moh-222-daily-register/moh-222-daily-register.tsx +77 -96
  140. package/src/reports/moh-740/registers/moh-270-permanent-register/moh-270-permanent-register.tsx +50 -70
  141. package/src/reports/moh-740/registers/moh-740-patient-list.tsx +61 -32
  142. package/src/reports/moh-740/registers/moh-740.columns.ts +52 -0
  143. package/src/reports/moh-740/shared/utils/indicator-register-map.ts +3 -3
  144. package/src/reports/moh-740/types/index.ts +3 -3
  145. package/src/reports/moh-745/moh-745.component.tsx +897 -877
  146. package/src/reports/moh-745/moh-745.scss +104 -46
  147. package/src/reports/moh-745/registers/moh-412-register.component.tsx +42 -43
  148. package/src/reports/moh-745/registers/moh-412.columns.ts +52 -0
  149. package/src/reports/table-wrapper/table-wrapper.component.tsx +23 -14
  150. package/src/reports/table-wrapper/table-wrapper.scss +1 -16
  151. package/src/resources/moh-505.resource.ts +18 -35
  152. package/src/resources/moh-705.resource.ts +28 -39
  153. package/src/resources/moh-706.resource.ts +17 -30
  154. package/src/resources/moh-710.resource.ts +7 -17
  155. package/src/resources/moh-711.resource.ts +46 -64
  156. package/src/resources/moh-717.resource.ts +7 -17
  157. package/src/resources/moh-731.resource.ts +26 -32
  158. package/src/resources/moh-745.resource.ts +18 -20
  159. package/src/resources/patient-list-page.ts +66 -0
  160. package/src/root.component.tsx +28 -26
  161. package/src/root.scss +36 -0
  162. package/src/utils/get-base-url.ts +39 -7
  163. package/tsconfig.json +1 -1
  164. package/dist/110.js +0 -1
  165. package/dist/110.js.map +0 -1
  166. package/dist/184.js +0 -2
  167. package/dist/184.js.LICENSE.txt +0 -14
  168. package/dist/184.js.map +0 -1
  169. package/dist/205.js +0 -1
  170. package/dist/205.js.map +0 -1
  171. package/dist/812.js +0 -1
  172. package/dist/812.js.map +0 -1
  173. package/dist/822.js +0 -2
  174. package/dist/822.js.LICENSE.txt +0 -20
  175. package/dist/822.js.map +0 -1
  176. package/dist/ampath-esm-reports-app.js.buildmanifest.json +0 -560
  177. package/dist/main.js +0 -1
  178. package/dist/main.js.map +0 -1
  179. package/src/reports/moh-731/registers/moh-366.scss +0 -45
  180. package/src/reports/moh-731/registers/prep-registers.scss +0 -45
  181. package/src/reports/moh-740/registers/moh-222-daily-register/moh-222-daily-register.scss +0 -18
  182. package/src/reports/moh-740/registers/moh-270-permanent-register/moh-270-permanent-register.scss +0 -18
  183. /package/src/{reports/moh-740/shared/utils → utils}/format-indicator.ts +0 -0
@@ -1,118 +1,446 @@
1
- .table {
2
- border: 2px solid #000;
3
- margin: 2rem;
4
- table-layout: fixed;
1
+ @use '@openmrs/esm-styleguide/src/vars' as *;
5
2
 
6
- td:nth-child(1) {
7
- width: 40%;
8
- }
3
+ /* A replica of the printed MOH 731 (Ver. July 2023) facility summary sheet,
4
+ laid out as a real A4 portrait page.
5
+
6
+ Everything is expressed in the units the document is drawn in -- millimetres
7
+ for geometry, points for type -- so the sheet occupies exactly one A4 page on
8
+ screen and prints at 1:1. */
9
+
10
+ $page-w: 210mm; // A4 portrait
11
+ $page-h: 297mm;
12
+ $page-margin: 8mm;
13
+
14
+ $ink: #000; // rules, borders and body text
15
+ $bar: #d9d9d9; // grey fill behind the numbered section bars
16
+ $rule: 1px solid $ink;
17
+ $dotted: 1px dotted $ink; // sub-block and column separators inside a section
18
+
19
+ /* Sized so the whole return fits one A4 page. The binding constraint is
20
+ height, not width: stacking the tallest column of each section plus the
21
+ masthead comes to 271mm of the 281mm available at a 2.7mm row. */
22
+
23
+ $text: 5.5pt; // body size for labels and codes
24
+ $title: 8pt; // masthead only
25
+ $caption: 4.5pt; // "Male" / "Female" column captions
26
+
27
+ $box-w: 8.5mm; // every value box
28
+ $box-h: 2.5mm; // a little taller than the label line, as on the form
29
+ $row-h: 2.7mm; // one indicator row: the box plus hairline clearance
30
+
31
+ $pad: 1.5mm; // padding inside columns and the sheet's bands
32
+ $gap: 0.8mm; // between a code and its box
33
+ $block-gap: 1mm; // above a sub-block heading
34
+ $label-gap: 4mm; // between a row label and its first code
9
35
 
10
- td:nth-child(2) {
11
- width: 25%;
36
+ /* Width of the label column. Fixed rather than content-sized so that every
37
+ block within a column lines its codes and boxes up at the same offset, as
38
+ the form does -- the blocks are separate tables, so left to size themselves
39
+ each one lands somewhere slightly different. Overridden per column in
40
+ section 3, whose columns are narrower. */
41
+ $label-w: 36mm;
42
+ $section-gap: 0.8mm; // around a divider
43
+
44
+ /* Holds the fixed-width page without making the app scroll sideways.
45
+
46
+ No padding of its own: vertical padding here is dead space, and horizontal
47
+ padding would eat into the width the page needs and bring on a scrollbar that
48
+ is not otherwise required. The left and right gutter comes from `.page` in
49
+ root.scss, which every route already sits inside. */
50
+
51
+ .viewport {
52
+ overflow-x: auto;
12
53
  }
13
54
 
14
- td:nth-child(3) {
15
- width: 27.5%;
55
+ .form {
56
+ box-sizing: border-box;
57
+ width: $page-w;
58
+ min-height: $page-h;
59
+ padding: $page-margin;
60
+ margin: 0 auto;
61
+ color: $ink;
62
+ font-size: $text;
63
+ line-height: 1.15;
64
+ background-color: #fff;
65
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
66
+ /* Set by `usePageScale` from the measured container width, floored at 1 so
67
+ the sheet is never drawn smaller than the paper. Reset to 1 for print. */
68
+ zoom: var(--page-zoom, 1);
16
69
  }
17
70
 
18
- tr {
71
+ /* Ministry line, above the ruled sheet */
72
+
73
+ .ministryLine {
19
74
  display: flex;
20
75
  justify-content: space-between;
76
+ margin-bottom: $pad;
77
+ font-weight: 700;
78
+ font-size: $text;
79
+ }
80
+
81
+ /* The ruled sheet itself */
82
+
83
+ .sheet {
84
+ border: $rule;
21
85
  }
22
86
 
23
- span {
24
- font-weight: normal;
87
+ /* Masthead */
88
+
89
+ /* The title is centred on the full width of the sheet, not on the space left
90
+ over beside the version box. The version box is taken out of flow so it
91
+ cannot push the title off centre. */
92
+
93
+ .formHeader {
94
+ position: relative;
95
+ padding: $pad;
96
+ border-bottom: $rule;
25
97
  }
26
98
 
99
+ .formTitle {
100
+ text-align: center;
101
+
102
+ strong {
103
+ display: block;
104
+ font-size: $title;
105
+ font-weight: 700;
106
+ }
107
+ }
27
108
 
109
+ .formVersion {
110
+ position: absolute;
111
+ top: $pad;
112
+ right: $pad;
113
+ padding: 0.5mm 1mm;
114
+ font-size: $text;
115
+ border: $dotted;
116
+ white-space: nowrap;
28
117
  }
29
118
 
119
+ /* County / Sub County / Facility fill-in line */
30
120
 
31
121
  .locationContainer {
32
- border: 2px solid #000;
33
- width: 100%;
122
+ display: flex;
123
+ flex-wrap: nowrap;
124
+ align-items: baseline;
125
+ justify-content: center;
126
+ gap: 2.5mm;
127
+ padding: $pad;
128
+ font-size: $text;
129
+ white-space: nowrap;
130
+ border-bottom: $rule;
131
+ }
132
+
133
+ /* These carry the facility and period once a report is generated, so they need
134
+ to hold text on the rule rather than just draw it. */
135
+
136
+ .line,
137
+ .shortLine {
138
+ display: inline-block;
139
+ padding: 0 1mm;
140
+ margin-left: 1mm;
141
+ overflow: hidden;
142
+ font-weight: 600;
34
143
  text-align: center;
35
- margin: 2rem;
144
+ text-overflow: ellipsis;
145
+ white-space: nowrap;
146
+ vertical-align: bottom;
147
+ border-bottom: $rule;
36
148
  }
37
149
 
38
- .border {
39
- background-color: #f2f2f2;
40
- border-bottom: 2px solid #000;
41
- width: 100%;
42
- font-weight: bold;
150
+ .line {
151
+ width: 27mm;
43
152
  }
44
- .border2 {
45
- background-color: #f2f2f2;
46
- border-top: 2px solid #000;
47
- border-bottom: 2px solid #000;
48
- width: 100%;
49
- font-weight: bold;
153
+
154
+ .shortLine {
155
+ width: 12mm;
50
156
  }
51
157
 
52
- .border3 {
53
- border-top: 2px solid #000;
54
- border-right: 2px dotted #000;
55
- width: 78.5%;
158
+ /* Numbered section bar, full width of the sheet. `text-align` is stated rather
159
+ than left to inherit: CSS Modules does not scope bare element selectors, and
160
+ other report stylesheets ship a global `h5 { text-align: center }`. */
161
+
162
+ .sectionHeader {
163
+ padding: 0.8mm $pad;
164
+ text-align: left;
165
+ font-size: $text;
166
+ font-weight: 700;
167
+ background-color: $bar;
168
+ border-bottom: $rule;
56
169
  }
57
170
 
58
- .flexColumn {
59
- display: inline-block;
60
- flex-direction: column;
61
- margin: 2rem;
171
+ /* The same bar, but scoped to one column -- sections 4 and 5 sit inside the
172
+ right-hand column of section 3 on the printed form. */
173
+
174
+ .columnHeader {
175
+ padding: 0.8mm $pad;
176
+ text-align: left;
177
+ margin: $block-gap (-$pad) $pad;
178
+ font-size: $text;
179
+ font-weight: 700;
180
+ background-color: $bar;
181
+ border-top: $rule;
182
+ border-bottom: $rule;
62
183
  }
63
184
 
185
+ /* Column grid inside a section */
186
+
64
187
  .flexRow {
65
188
  display: flex;
66
- justify-content: space-between;
189
+ align-items: stretch;
190
+ border-bottom: $rule;
67
191
  }
68
- .rectangle {
69
- width: 50px;
70
- height: 20px;
71
- border: 2px solid #000;
72
- display: inline-block;
73
- margin-left: 5px;
192
+
193
+ .flexColumn {
194
+ flex: 1 1 0;
195
+ min-width: 0;
196
+ padding: $pad;
74
197
  }
75
- .textBox {
76
- display: inline-block;
77
- align-items: center;
78
- justify-content: start;
79
- gap: 8px;
80
- white-space: nowrap;
81
- cursor: pointer;
198
+
199
+ /* No rule between columns by default: on the form only section 3 divides its
200
+ columns, and it does so with a dotted line (see `.borderRight` below). */
201
+
202
+ /* Section 3 only: columns 1 and 2 are grouped so the sign-off can run along
203
+ their foot while section 5 continues in column 3 beside it. */
204
+
205
+ /* Section 3's columns are not equal thirds on the form. Column 1 carries a
206
+ male and a female value on every row, so it takes 45% of the width, against
207
+ 26% and 29% for the single-value columns beside it. Splitting evenly left
208
+ column 1 about 21mm short, which forced its labels to wrap. */
209
+
210
+ .colGroup {
211
+ display: flex;
212
+ flex: 71 1 0; // columns 1 and 2 together
213
+ flex-direction: column;
214
+ min-width: 0;
82
215
  }
83
- .textBox2 {
84
- margin-left: 10px;
216
+
217
+ .colPair > .borderRight {
218
+ flex: 63 1 0; // column 1, of the pair
219
+ --label-w: 24mm;
85
220
  }
86
- .spaceAfter {
87
- padding-right: 6vw;
221
+
222
+ .colPair > .flexColumn:last-child {
223
+ flex: 37 1 0; // column 2
224
+ --label-w: 25mm;
225
+ }
226
+
227
+ .flexRow > .borderLeft {
228
+ flex: 29 1 0; // column 3
229
+ --label-w: 30mm;
230
+ }
231
+
232
+ .colPair {
233
+ display: flex;
234
+ flex: 1 1 auto;
235
+ align-items: stretch;
236
+ min-width: 0;
237
+ /* clearance between the last indicator rows and the sign-off rule below */
238
+ padding-bottom: 1.5mm;
88
239
  }
240
+
241
+
242
+
243
+ /* Section 3's column separators, dotted as on the form */
244
+
89
245
  .borderRight {
90
- border-right: 2px dotted #000;
91
- padding-right: 4vw;
246
+ padding: $pad;
247
+ border-right: $dotted;
92
248
  }
249
+
93
250
  .borderLeft {
94
- border-left: 2px dotted #000;
95
- padding-left: 1vw;
251
+ padding: $pad;
252
+ border-left: $dotted;
96
253
  }
97
254
 
98
- .reviewSection {
99
- display: grid;
100
- grid-template-columns: repeat(5, 1fr);
101
- column-gap: 20px;
102
- text-align: center;
103
- font-size: 14px;
104
- margin-top: 10px;
105
- font-weight: bold;
255
+ /* Indicator rows.
256
+
257
+ Measured off the form: each section splits into two equal 90mm halves, and a
258
+ block occupies only about 70mm of its half, left aligned, leaving ~15mm of
259
+ trailing slack. That slack is what reads as the gap between column 1 and
260
+ column 2 -- there is no gutter between them. So the table is sized to its
261
+ content rather than stretched: stretching pushed the value boxes onto the
262
+ column boundary and closed the gap up.
263
+
264
+ Auto layout, not fixed: `.textBox` is `nowrap` (a code must never be split
265
+ from its box) so it has a hard minimum width, and a fixed layout would hand
266
+ out narrower columns and push the pair outside the section rule. */
267
+
268
+ .block {
269
+ width: auto;
270
+ max-width: 100%;
271
+ border-collapse: collapse;
272
+ table-layout: auto;
273
+
274
+ td {
275
+ height: $row-h;
276
+ padding: 0.1mm 0.8mm 0.1mm 0;
277
+ font-size: $text;
278
+ vertical-align: middle;
279
+ }
280
+
281
+ /* Fixed width so codes and boxes align across every block in the column */
282
+ td:first-child:not([colspan]) {
283
+ box-sizing: border-box;
284
+ width: var(--label-w, #{$label-w});
285
+ padding-right: $label-gap;
286
+ overflow-wrap: anywhere;
287
+ }
288
+ }
289
+
290
+ /* Sub-block heading, e.g. "1.1 HIV Tests". Flush with the column's left edge,
291
+ in line with the row labels beneath it. */
292
+
293
+ .blockTitle {
294
+ padding-top: $block-gap;
295
+ padding-bottom: 0.6mm;
296
+ padding-left: 0;
297
+ font-size: $text;
298
+ font-weight: 700;
299
+ }
300
+
301
+ /* A heading within a block, e.g. "Below 6 months" */
302
+
303
+ .groupTitle {
304
+ padding-top: 1mm;
305
+ padding-left: 0;
306
+ font-size: $text;
307
+ font-weight: 700;
106
308
  }
107
309
 
310
+ /* "Male" / "Female (including PMTCT)" column captions */
311
+
108
312
  .subTitle {
109
- font-weight: bold;
313
+ padding-bottom: 0.5mm;
314
+ font-size: $caption;
315
+ font-weight: 400;
316
+ text-align: center;
317
+ vertical-align: bottom;
110
318
  }
111
319
 
320
+ /* The separator between sub-blocks: one dotted rule across the column, so every
321
+ separator in a section is the same length. */
322
+
323
+ .divider {
324
+ height: 0;
325
+ margin: $section-gap 0;
326
+ border: none;
327
+ border-top: $dotted;
328
+ }
329
+
330
+ .spaceAfter {
331
+ padding-right: 2mm;
332
+ }
112
333
 
113
334
  .emptyColumn {
114
- min-width: 10rem;
335
+ width: auto;
115
336
  }
116
337
 
338
+ /* Code plus its value box */
117
339
 
340
+ .textBox,
341
+ .textBox2 {
342
+ display: flex;
343
+ align-items: center;
344
+ justify-content: flex-end;
345
+ gap: $gap;
346
+ white-space: nowrap;
347
+ }
348
+
349
+ .textBox span {
350
+ font-size: $text;
351
+ font-variant-numeric: tabular-nums;
352
+ }
353
+
354
+ .rectangle {
355
+ display: inline-flex;
356
+ align-items: center;
357
+ justify-content: center;
358
+ flex-shrink: 0;
359
+ box-sizing: border-box;
360
+ width: $box-w;
361
+ height: $box-h;
362
+ font-size: $text;
363
+ font-variant-numeric: tabular-nums;
364
+ background-color: #fff;
365
+ border: $rule;
366
+ }
367
+
368
+ /* Only the boxes wired to a register drill-down carry the hover text, so the
369
+ attribute doubles as the selector: a box with no linelist behind it must not
370
+ offer a pointer cursor it cannot honour. */
371
+
372
+ .rectangle[title]:hover {
373
+ background-color: $brand-primary-10;
374
+ border-color: var(--brand-01);
375
+ cursor: pointer;
376
+ }
377
+
378
+ /* Sign-off strip along the foot of the sheet */
379
+
380
+ .reviewSection {
381
+ display: grid;
382
+ grid-template-columns: 22mm repeat(4, 1fr);
383
+ align-items: end;
384
+ column-gap: 4mm;
385
+ /* the form leaves about 1.7mm clear between a label and its rule */
386
+ row-gap: 1.5mm;
387
+ /* pushed to the foot of the grouped columns, clear of the rows above */
388
+ margin-top: auto;
389
+ padding: 1.5mm $pad 1mm;
390
+ font-size: $text;
391
+ /* full-width rule across columns 1 and 2, as on the form */
392
+ border-top: $rule;
118
393
 
394
+ span {
395
+ text-align: center;
396
+ }
397
+ }
398
+
399
+ .reviewLabel {
400
+ text-align: left;
401
+ }
402
+
403
+ /* A fixed height keeps the prefilled cells (name, date) on the same baseline as
404
+ the blank ones (designation, signature), which have no content to give them
405
+ height. */
406
+
407
+ .reviewRule {
408
+ min-height: $row-h;
409
+ padding-bottom: 0.3mm;
410
+ text-align: center;
411
+ border-bottom: $rule;
412
+ }
413
+
414
+ /* No responsive reflow: this is a replica of a fixed A4 sheet, so on a narrow
415
+ screen the page keeps its proportions and scrolls inside `.viewport` rather
416
+ than restacking into something the printed form does not do. */
417
+
418
+ @media print {
419
+ @page {
420
+ size: A4 portrait;
421
+ margin: $page-margin;
422
+ }
423
+
424
+ /* The app chrome is hidden by `.page` in root.scss; this only needs to undo
425
+ the on-screen scroll container. */
426
+
427
+ .viewport {
428
+ overflow: visible;
429
+ }
430
+
431
+ .form {
432
+ width: auto;
433
+ min-height: 0;
434
+ padding: 0;
435
+ margin: 0;
436
+ box-shadow: none;
437
+ /* paper geometry stands on its own; magnification is for screens */
438
+ zoom: 1;
439
+ }
440
+
441
+ .flexRow,
442
+ .reviewSection {
443
+ break-inside: avoid;
444
+ page-break-inside: avoid;
445
+ }
446
+ }
@@ -0,0 +1,38 @@
1
+ import { ageBandColumns, type RegisterColumn } from '../../../common/report-register';
2
+
3
+ const tbColumn = (heading: string, field: string, under15: boolean): RegisterColumn => ({
4
+ header: `${heading} ${under15 ? '< 15 yrs' : '15+ yrs'}`,
5
+ value: (row) => ((under15 ? row.age < 15 : row.age >= 15) ? (row.started_on_art === 'Y' ? row[field] : 'NA') : ''),
6
+ });
7
+
8
+ /**
9
+ * The columns the MOH 366 register prints, in order.
10
+ *
11
+ * Kept beside the table it mirrors: most cells are not fields but a
12
+ * presentation of them -- an age band crossed with a gender -- so an export
13
+ * that listed the raw response would not line up with the printed register at
14
+ * all.
15
+ */
16
+ export const moh366Columns: RegisterColumn[] = [
17
+ { header: 'No', value: (_row, index) => index + 1 },
18
+ { header: 'Date', value: (row) => (row.date ? new Date(row.date).toLocaleDateString('en-GB') : '') },
19
+ { header: 'AMRSID', value: (row) => row.amrsID },
20
+ { header: 'National Identification Number', value: (row) => row.national_id_number },
21
+ { header: 'Client CCC Number', value: (row) => row.ccc_number?.replace('-', '') },
22
+ { header: 'Age', value: (row) => row.age },
23
+
24
+ ...ageBandColumns('Starting ART', (row) => (row.started_on_art === 'Y' ? 'Y' : '')),
25
+
26
+ tbColumn('Screened for TB', 'screened_for_tb', true),
27
+ tbColumn('Screened for TB', 'screened_for_tb', false),
28
+ tbColumn('Started TPT', 'started_on_tpt', true),
29
+ tbColumn('Started TPT', 'started_on_tpt', false),
30
+
31
+ ...ageBandColumns('Currently on ART', (row) =>
32
+ row.revisit ? row.revisit : row.current_on_art > 0 ? row.current_on_art : 1,
33
+ ),
34
+
35
+ { header: 'DSD Status', value: (row) => row.dsd_status },
36
+ { header: 'DSD Type', value: (row) => row.dsd_type },
37
+ { header: 'Remarks', value: (row) => row.remarks },
38
+ ];