@ampath/esm-reports-app 1.0.0-next.79 → 1.0.0-next.80
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/dist/0.css +1 -0
- package/dist/0.css.map +1 -0
- package/dist/0.js +1 -0
- package/dist/0.js.map +1 -0
- package/dist/410.js +1 -1
- package/dist/410.js.map +1 -1
- package/dist/600.js +1 -1
- package/dist/600.js.map +1 -1
- package/dist/757.js +1 -0
- package/dist/757.js.map +1 -0
- package/dist/ampath-esm-reports-app.js +1 -1
- package/dist/ampath-esm-reports-app.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/common/report-filters/report-filters.scss +15 -6
- package/src/common/report-page/download-sheet-pdf.ts +193 -27
- package/src/common/report-register/report-parents.ts +2 -0
- package/src/dashboard/report-catalog.ts +18 -0
- package/src/registers/moh-267/moh-267-register.component.tsx +407 -0
- package/src/registers/moh-267/moh-267-register.scss +298 -0
- package/src/registers/moh-267/moh-267-summary.ts +102 -0
- package/src/registers/moh-267/moh-267.component.tsx +94 -0
- package/src/registers/moh-267/moh-267.types.ts +47 -0
- package/src/registers/moh-362/moh-362-lab-register.component.tsx +469 -310
- package/src/registers/moh-362/moh-362-lab-register.scss +412 -0
- package/src/registers/moh-362/moh-362-linkage-register.component.tsx +188 -93
- package/src/registers/moh-362/moh-362-linkage-register.scss +91 -0
- package/src/registers/moh-362/moh-362.component.tsx +33 -15
- package/src/registers/moh-362/moh-362.types.ts +15 -25
- package/src/registers/presumptive-tb/presumptive-tb-register.component.tsx +391 -0
- package/src/registers/presumptive-tb/presumptive-tb-register.scss +262 -0
- package/src/registers/presumptive-tb/presumptive-tb.component.tsx +92 -0
- package/src/registers/presumptive-tb/presumptive-tb.types.ts +88 -0
- package/src/registers/register-catalog.ts +37 -3
- package/src/registers/register-file-name.ts +18 -0
- package/src/registers/tb4/tb4-parts.tsx +164 -0
- package/src/registers/tb4/tb4-patient-sheet.component.tsx +418 -0
- package/src/registers/tb4/tb4-register.scss +282 -0
- package/src/registers/tb4/tb4-treatment-sheet.component.tsx +349 -0
- package/src/registers/tb4/tb4.component.tsx +120 -0
- package/src/registers/tb4/tb4.types.ts +129 -0
- package/src/reports/acf-summary/acf-summary-form.component.tsx +176 -0
- package/src/reports/acf-summary/acf-summary-linelist.component.tsx +86 -0
- package/src/reports/acf-summary/acf-summary.component.tsx +97 -0
- package/src/reports/acf-summary/acf-summary.counts.ts +37 -0
- package/src/reports/acf-summary/acf-summary.scss +162 -0
- package/src/reports/moh-729b/moh-729b-form.component.tsx +385 -0
- package/src/reports/moh-729b/moh-729b-linelist.component.tsx +205 -0
- package/src/reports/moh-729b/moh-729b-summary.component.tsx +258 -0
- package/src/reports/moh-729b/moh-729b-summary.config.ts +229 -0
- package/src/reports/moh-729b/moh-729b.component.tsx +157 -0
- package/src/reports/moh-729b/moh-729b.config.ts +235 -0
- package/src/reports/moh-729b/moh-729b.scss +276 -0
- package/src/reports/moh-729b/moh-729b.types.ts +111 -0
- package/src/reports/moh-731/moh-731.component.tsx +10 -7
- package/src/reports/moh-731/moh-731.scss +3 -6
- package/src/reports/moh-731/summary/moh-731-summary.config.ts +2 -4
- package/src/reports/moh-731/summary/moh-731-summary.scss +5 -0
- package/src/resources/moh-267.resource.ts +27 -0
- package/src/resources/moh-729b.resource.ts +25 -0
- package/src/resources/presumptive-tb.resource.ts +27 -0
- package/src/root.component.tsx +14 -0
- package/dist/177.css +0 -1
- package/dist/177.css.map +0 -1
- package/dist/177.js +0 -1
- package/dist/177.js.map +0 -1
- package/dist/580.js +0 -1
- package/dist/580.js.map +0 -1
- package/src/registers/moh-362/moh-362-register.scss +0 -222
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The regimen codes of the MoH 729B Facility Monthly ARV Patient Summary
|
|
3
|
+
* (F-MAPS, Ver. July 2023), section by section as printed on its report page.
|
|
4
|
+
*
|
|
5
|
+
* `h` is each row's height as measured off the form (in its own units, scaled
|
|
6
|
+
* to millimetres by the sheet), so the two halves of the page keep the
|
|
7
|
+
* printed proportions: a two-line regimen gets a taller row.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type Regimen = [code: string, name: string, h?: number];
|
|
11
|
+
|
|
12
|
+
export interface RegimenSection {
|
|
13
|
+
title: string;
|
|
14
|
+
/** the heading row's height */
|
|
15
|
+
h: number;
|
|
16
|
+
rows: Regimen[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* Left half: ART */
|
|
20
|
+
|
|
21
|
+
export const ADULT_ART: RegimenSection[] = [
|
|
22
|
+
{
|
|
23
|
+
title: 'Adult ART 1st Line regimens',
|
|
24
|
+
h: 39,
|
|
25
|
+
rows: [
|
|
26
|
+
['AF2E', 'TDF + 3TC + DTG'],
|
|
27
|
+
['AF2B', 'TDF + 3TC + EFV'],
|
|
28
|
+
['AF1D', 'AZT + 3TC + DTG'],
|
|
29
|
+
['AF4C', 'ABC + 3TC + DTG'],
|
|
30
|
+
['AF2D', 'TDF + 3TC + ATV/r'],
|
|
31
|
+
['AF2F', 'TDF + 3TC + LPV/r'],
|
|
32
|
+
['AS2G', 'TAF + 3TC + DTG'],
|
|
33
|
+
['AF1E', 'AZT + 3TC + LPV/r'],
|
|
34
|
+
['AF1F', 'AZT + 3TC + ATV/r'],
|
|
35
|
+
['AF5X', 'Any other 1st line Adult regimens'],
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
title: 'Adult ART 2nd Line regimens',
|
|
40
|
+
h: 40,
|
|
41
|
+
rows: [
|
|
42
|
+
['AS1A', 'AZT + 3TC + LPV/r', 63],
|
|
43
|
+
['AS1B', 'AZT + 3TC + ATV/r', 64],
|
|
44
|
+
['AS1C', 'AZT + 3TC + DTG', 38],
|
|
45
|
+
['AS2A', 'TDF + 3TC + LPV/r', 38],
|
|
46
|
+
['AS2B', 'TDF + 3TC + DTG', 38],
|
|
47
|
+
['AS2C', 'TDF + 3TC + ATV/r', 38],
|
|
48
|
+
['AS5A', 'ABC + 3TC + LPV/r', 38],
|
|
49
|
+
['AS5B', 'ABC + 3TC + ATV/r', 38],
|
|
50
|
+
['AS5C', 'ABC + 3TC + DTG', 38],
|
|
51
|
+
['AS6X', 'Any other 2nd line Adult regimens', 45],
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
title: 'Adult ART 3rd Line regimens',
|
|
56
|
+
h: 44,
|
|
57
|
+
rows: [
|
|
58
|
+
['AT2D', 'TDF+3TC+DTG+DRV+RTV', 45],
|
|
59
|
+
['AT2F', 'TDF+3TC+DTG+ETV+DRV+RTV', 45],
|
|
60
|
+
['AT2G', 'TDF + 3TC + DTG', 44],
|
|
61
|
+
['AT2H', 'AZT + 3TC + DTG', 45],
|
|
62
|
+
['AT2I', 'AZT + 3TC + DTG + DRV + RTV', 45],
|
|
63
|
+
['AT2X', 'Any other 3rd line Adult regimens', 45],
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
/** The children's weight bands, then their Total */
|
|
69
|
+
export const WEIGHT_BANDS = ['3-5.9kg', '6-9.9kg', '10-13.9kg', '14-19.9kg', '20-24.9kg', '25-29.9kgs', '≥30kgs'];
|
|
70
|
+
|
|
71
|
+
export const PAEDIATRIC_ART: RegimenSection[] = [
|
|
72
|
+
{
|
|
73
|
+
title: 'Paediatric ART 1st Line regimens',
|
|
74
|
+
h: 40,
|
|
75
|
+
rows: [
|
|
76
|
+
['CF2G', 'ABC+3TC+DTG', 41],
|
|
77
|
+
['CF1D', 'AZT + 3TC + DTG', 41],
|
|
78
|
+
['CF4E', 'TDF + 3TC + DTG', 41],
|
|
79
|
+
['CF5X', 'Any other 1st line Paediatric regimens', 41],
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
title: 'Paediatric ART 2nd Line regimens',
|
|
84
|
+
h: 46,
|
|
85
|
+
rows: [
|
|
86
|
+
['CS1A', 'AZT + 3TC + LPV/r', 41],
|
|
87
|
+
['CS1B', 'AZT + 3TC + DTG', 41],
|
|
88
|
+
['CS2A', 'ABC + 3TC + LPV/r', 41],
|
|
89
|
+
['CS2B', 'ABC+3TC+DTG', 41],
|
|
90
|
+
['CS4X', 'Any other 2nd line Paediatric regimens', 41],
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
title: 'Paediatric ART 3rd Line regimens',
|
|
95
|
+
h: 54,
|
|
96
|
+
rows: [
|
|
97
|
+
['CT1H', 'AZT + 3TC + DRV+RTV+RAL', 41.5],
|
|
98
|
+
['CT2D', 'ABC + 3TC + DRV+RTV+RAL', 41.5],
|
|
99
|
+
['CT3X', 'Any other 3rd line Paediatric regimens', 41.5],
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
export const PREP: RegimenSection = {
|
|
105
|
+
title: 'PrEP',
|
|
106
|
+
h: 37,
|
|
107
|
+
rows: [
|
|
108
|
+
['PRP1A', 'TDF + FTC', 29.5],
|
|
109
|
+
['PRP1B', 'TDF + 3TC', 29.5],
|
|
110
|
+
['PRP1D', 'Dapivirine ring', 29.5],
|
|
111
|
+
['PRP1E', 'Cabotegravir', 29.5],
|
|
112
|
+
/* not printed on the form: added for clients on Lenacapavir */
|
|
113
|
+
['PRP1F', 'Lenacapavir', 29.5],
|
|
114
|
+
['PRP1X', 'Others', 29.5],
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/* Right half: PMTCT, PEP, Hepatitis B and OIs */
|
|
119
|
+
|
|
120
|
+
export const PMTCT_MOTHERS: RegimenSection = {
|
|
121
|
+
title: 'Pregnant women or HEI Mothers',
|
|
122
|
+
h: 39,
|
|
123
|
+
rows: [
|
|
124
|
+
['PM9', 'PMTCT HAART: TDF + 3TC + EFV'],
|
|
125
|
+
['PM12', 'PMTCT HAART: TDF + 3TC + DTG'],
|
|
126
|
+
['PM13', 'PMTCT HAART: AZT + 3TC + DTG'],
|
|
127
|
+
['PM14', 'PMTCT HAART: ABC + 3TC + DTG'],
|
|
128
|
+
['PM11', 'PMTCT HAART: TDF + 3TC + ATV/r'],
|
|
129
|
+
['PM7', 'PMTCT HAART: TDF + 3TC + LPV/r'],
|
|
130
|
+
['PM10', 'PMTCT HAART: AZT + 3TC + ATV/r'],
|
|
131
|
+
['PM5', 'PMTCT HAART: AZT + 3TC + LPV/r'],
|
|
132
|
+
['PM1X', 'Any other PMTCT regimens for Women'],
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/** The infants' age bands, then their Total */
|
|
137
|
+
export const INFANT_AGES = ['0-12 weeks', '12 weeks-6months', '7- 9 months', '10-12 months', 'Above 12 months'];
|
|
138
|
+
|
|
139
|
+
export const PMTCT_INFANTS: RegimenSection = {
|
|
140
|
+
title: 'Infants',
|
|
141
|
+
h: 40,
|
|
142
|
+
rows: [
|
|
143
|
+
[
|
|
144
|
+
'PC8',
|
|
145
|
+
'AZT liquid BID + NVP liquid OD for 6 weeks then NVP liquid OD until 6 weeks after complete cessation of Breastfeeding',
|
|
146
|
+
63,
|
|
147
|
+
],
|
|
148
|
+
['PC7', 'AZT liquid BID + NVP liquid OD for 6 weeks then NVP liquid OD for 6 weeks(If not breastfeeding)', 64],
|
|
149
|
+
['PC1X', 'Any other PMTCT regimens for Infants', 38],
|
|
150
|
+
],
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/** A numbered group of the right half, each regimen with a single count and a Total */
|
|
154
|
+
export interface TotalledGroup extends RegimenSection {
|
|
155
|
+
number?: string;
|
|
156
|
+
/** the heading's Total cell is shaded (Cryptococcal Meningitis) */
|
|
157
|
+
noTotal?: boolean;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const PEP: TotalledGroup[] = [
|
|
161
|
+
{
|
|
162
|
+
number: '1',
|
|
163
|
+
title: 'PEP for Adults',
|
|
164
|
+
h: 38,
|
|
165
|
+
rows: [
|
|
166
|
+
['PA3D', 'TDF + 3TC + DTG', 38],
|
|
167
|
+
['PA3C', 'TDF + 3TC + ATV/r', 38],
|
|
168
|
+
['PA1C', 'AZT + 3TC + ATV/r', 38],
|
|
169
|
+
['PA4X', 'Any other PEP regimens for Adults', 38],
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
number: '2',
|
|
174
|
+
title: 'PEP for Children',
|
|
175
|
+
h: 45,
|
|
176
|
+
rows: [
|
|
177
|
+
['PC3A', 'ABC + 3TC + LPV/r', 45],
|
|
178
|
+
['PC3C', 'ABC + 3TC + DTG', 45],
|
|
179
|
+
['PC4X', 'Any other PEP regimens for Children', 45],
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
export const HEPATITIS_B: TotalledGroup = {
|
|
185
|
+
title: 'Hepatitis B Patients who are HIV-ve',
|
|
186
|
+
h: 44,
|
|
187
|
+
rows: [
|
|
188
|
+
['HPB1A', 'TDF + 3TC (HIV-ve HepB patients)', 45],
|
|
189
|
+
['HPB1B', 'TDF + FTC (HIV-ve HepB patients)', 45],
|
|
190
|
+
['HPB1C', 'Any other HEP B regimens', 45],
|
|
191
|
+
],
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
/** The TPT group counted from MOH 731 3.4 Starting TPT */
|
|
195
|
+
export const TPT_HIV_POSITIVE = 'TPT HIV Positive';
|
|
196
|
+
|
|
197
|
+
export const OPPORTUNISTIC_INFECTIONS: TotalledGroup[] = [
|
|
198
|
+
{
|
|
199
|
+
number: '1',
|
|
200
|
+
title: 'Universal prophylaxis',
|
|
201
|
+
h: 43,
|
|
202
|
+
rows: [
|
|
203
|
+
['OI1A', 'Adult patients on Cotrimoxazole prophylaxis', 40],
|
|
204
|
+
['OI1C', 'Paediatric patients on Cotrimoxazole prophylaxis', 40],
|
|
205
|
+
['OI2A', 'Adult patients on Dapsone prophylaxis', 40],
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
number: '2',
|
|
210
|
+
title: TPT_HIV_POSITIVE,
|
|
211
|
+
h: 46,
|
|
212
|
+
rows: [
|
|
213
|
+
['ATPT1A', 'Adult patients (=>15 Yrs) newly started on 6H in the month', 41],
|
|
214
|
+
['ATPT1B', 'Adult patients (=>15 Yrs) newly started on 3HP in the month', 41],
|
|
215
|
+
['CTPT1A', 'Paed patients (<15 Yrs) newly started on 6H in the month', 41],
|
|
216
|
+
['CTPT1B', 'Paed patients (<15 Yrs) newly started on 3HP in the month', 41],
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
number: '3',
|
|
221
|
+
title: 'TPT HIV Negative',
|
|
222
|
+
h: 41,
|
|
223
|
+
rows: [['ATPT1C', 'HIV Negative Adult patients (=>15 Yrs) newly started on 3HP in the month', 54]],
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
number: '4',
|
|
227
|
+
title: 'Cryptococcal Menengitis New Clients only',
|
|
228
|
+
h: 40,
|
|
229
|
+
noTotal: true,
|
|
230
|
+
rows: [
|
|
231
|
+
['OI6B', 'New CM patients (=>15 Yrs) on liposomal Ampotericin+Flucytosine + fluconazole in the month', 84],
|
|
232
|
+
['OI6X', 'New CM patients (=>15 Yrs) on any other treatment in the month', 72],
|
|
233
|
+
],
|
|
234
|
+
},
|
|
235
|
+
];
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
@use '@carbon/layout';
|
|
2
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
3
|
+
|
|
4
|
+
/* The MoH 729B F-MAPS report page as one A3 portrait sheet, drawn in the units
|
|
5
|
+
the paper is measured in (mm, pt) so it prints as one sheet: the masthead,
|
|
6
|
+
the two halves of regimen codes side by side, and the sign-off beneath.
|
|
7
|
+
Row heights come from the form (moh-729b.config.ts). */
|
|
8
|
+
|
|
9
|
+
/* On screen a page is the printable area only, A3 portrait less its 8mm
|
|
10
|
+
margins: the card around it gives the margin, and `usePageScale` is told
|
|
11
|
+
this width. */
|
|
12
|
+
$page-w: 297mm - 2 * 8mm;
|
|
13
|
+
$page-h: 420mm - 2 * 8mm;
|
|
14
|
+
|
|
15
|
+
$ink: #000;
|
|
16
|
+
$rule: 0.6pt solid #000;
|
|
17
|
+
$shade: #a6a6a6; // cells not to be filled
|
|
18
|
+
$light-shade: #bfbfbf;
|
|
19
|
+
$band: #d9d9d9; // ADULT ART, PMTCT, PrEP
|
|
20
|
+
$heading: #f2f2f2; // each section's heading row
|
|
21
|
+
|
|
22
|
+
/* The card the page sits in, drawn like the filter card above it */
|
|
23
|
+
.reportFrame {
|
|
24
|
+
margin: layout.$spacing-05 0 layout.$spacing-07;
|
|
25
|
+
padding: layout.$spacing-05;
|
|
26
|
+
background-color: $ui-02;
|
|
27
|
+
border: 1px solid $ui-03;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Holds the fixed-width page without making the app scroll sideways */
|
|
31
|
+
.viewport {
|
|
32
|
+
overflow-x: auto;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.page {
|
|
36
|
+
display: flex;
|
|
37
|
+
flex-direction: column;
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
width: $page-w;
|
|
40
|
+
height: $page-h;
|
|
41
|
+
margin: 0 auto;
|
|
42
|
+
padding: 2mm 3mm 0;
|
|
43
|
+
color: $ink;
|
|
44
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
45
|
+
font-size: 7pt;
|
|
46
|
+
line-height: 1.15;
|
|
47
|
+
background-color: #fff;
|
|
48
|
+
/* set by `usePageScale` from the measured container width, floored at 1 */
|
|
49
|
+
zoom: var(--page-zoom, 1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.titleLine {
|
|
53
|
+
display: flex;
|
|
54
|
+
justify-content: space-between;
|
|
55
|
+
font-family: Calibri, Carlito, Arial, sans-serif;
|
|
56
|
+
font-size: 10.5pt;
|
|
57
|
+
font-weight: 700;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.formCode {
|
|
61
|
+
margin-top: 1mm;
|
|
62
|
+
font-size: 6pt;
|
|
63
|
+
font-weight: 700;
|
|
64
|
+
text-align: right;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Facility and county on the left, MFL code and sub-county on the right */
|
|
68
|
+
.fields {
|
|
69
|
+
display: flex;
|
|
70
|
+
justify-content: space-between;
|
|
71
|
+
margin-top: 1mm;
|
|
72
|
+
|
|
73
|
+
> .fieldGrid:first-child {
|
|
74
|
+
width: 82mm;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
> .fieldGrid:last-child {
|
|
78
|
+
width: 75mm;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.fieldGrid {
|
|
83
|
+
display: grid;
|
|
84
|
+
grid-template-columns: auto 1fr;
|
|
85
|
+
column-gap: 1mm;
|
|
86
|
+
row-gap: 2.6mm;
|
|
87
|
+
align-items: end;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.fieldLabel {
|
|
91
|
+
font-weight: 700;
|
|
92
|
+
text-align: right;
|
|
93
|
+
white-space: nowrap;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* The ruled line a field is written on; its caption sits beneath it */
|
|
97
|
+
.fieldLine {
|
|
98
|
+
position: relative;
|
|
99
|
+
min-height: 3.4mm;
|
|
100
|
+
padding-left: 1mm;
|
|
101
|
+
border-bottom: $rule;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.caption {
|
|
105
|
+
position: absolute;
|
|
106
|
+
top: 100%;
|
|
107
|
+
left: 0;
|
|
108
|
+
right: 0;
|
|
109
|
+
padding-top: 0.2mm;
|
|
110
|
+
font-weight: 700;
|
|
111
|
+
text-align: center;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* a line with a caption leaves room beneath it for the caption */
|
|
115
|
+
.captioned {
|
|
116
|
+
margin-bottom: 3mm;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Beginning and Ending, each with its (Day/Month/Year) */
|
|
120
|
+
.period {
|
|
121
|
+
display: grid;
|
|
122
|
+
grid-template-columns: 30mm 74mm 1fr 75mm;
|
|
123
|
+
column-gap: 1mm;
|
|
124
|
+
align-items: end;
|
|
125
|
+
margin: 1mm 0 1.5mm;
|
|
126
|
+
|
|
127
|
+
.caption {
|
|
128
|
+
font-weight: 400;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.halves {
|
|
133
|
+
display: flex;
|
|
134
|
+
align-items: stretch;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.half {
|
|
138
|
+
display: flex;
|
|
139
|
+
flex-direction: column;
|
|
140
|
+
flex-basis: 0;
|
|
141
|
+
min-width: 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.grid {
|
|
145
|
+
width: 100%;
|
|
146
|
+
table-layout: fixed;
|
|
147
|
+
border-collapse: collapse;
|
|
148
|
+
|
|
149
|
+
th,
|
|
150
|
+
td {
|
|
151
|
+
padding: 0 0.6mm;
|
|
152
|
+
overflow: hidden;
|
|
153
|
+
border: $rule;
|
|
154
|
+
vertical-align: middle;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
th {
|
|
158
|
+
font-weight: 700;
|
|
159
|
+
text-align: center;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
td {
|
|
163
|
+
text-align: left;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.columnHead th {
|
|
168
|
+
font-family: Cambria, Georgia, serif;
|
|
169
|
+
font-size: 6.5pt;
|
|
170
|
+
line-height: 1.1;
|
|
171
|
+
vertical-align: top;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.band th {
|
|
175
|
+
background-color: $band;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.heading th {
|
|
179
|
+
background-color: $heading;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.bandCell {
|
|
183
|
+
background-color: $band !important;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.code {
|
|
187
|
+
text-align: center !important;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.small {
|
|
191
|
+
font-size: 6.5pt;
|
|
192
|
+
line-height: 1;
|
|
193
|
+
text-align: left !important;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.leftText {
|
|
197
|
+
text-align: left !important;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.italicHeading {
|
|
201
|
+
font-style: italic;
|
|
202
|
+
text-align: left !important;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.count {
|
|
206
|
+
font-variant-numeric: tabular-nums;
|
|
207
|
+
text-align: center !important;
|
|
208
|
+
cursor: pointer;
|
|
209
|
+
|
|
210
|
+
&:hover,
|
|
211
|
+
&:focus-visible {
|
|
212
|
+
background-color: $brand-primary-10;
|
|
213
|
+
outline: 1px solid var(--brand-01);
|
|
214
|
+
outline-offset: -1px;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.shade {
|
|
219
|
+
background-color: $shade;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.lightShade {
|
|
223
|
+
background-color: $light-shade;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.blankCell {
|
|
227
|
+
background-color: #fff;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* The right half is shorter: the rest of its column is shaded, as printed */
|
|
231
|
+
.filler {
|
|
232
|
+
flex: 1;
|
|
233
|
+
background-color: $light-shade;
|
|
234
|
+
border: $rule;
|
|
235
|
+
border-top: none;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.instruction {
|
|
239
|
+
margin-top: 1mm;
|
|
240
|
+
font-size: 6.5pt;
|
|
241
|
+
font-weight: 700;
|
|
242
|
+
line-height: 1.6;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.signOff {
|
|
246
|
+
display: flex;
|
|
247
|
+
justify-content: space-between;
|
|
248
|
+
margin-top: 4mm;
|
|
249
|
+
padding: 0 0 0 18mm;
|
|
250
|
+
|
|
251
|
+
> .fieldGrid {
|
|
252
|
+
width: 102mm;
|
|
253
|
+
row-gap: 3.2mm;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
> .fieldGrid:last-child {
|
|
257
|
+
width: 120mm;
|
|
258
|
+
margin-right: 22mm;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.notes {
|
|
263
|
+
margin-top: 2mm;
|
|
264
|
+
font-weight: 700;
|
|
265
|
+
text-decoration: underline;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.pageFoot {
|
|
269
|
+
display: flex;
|
|
270
|
+
justify-content: space-between;
|
|
271
|
+
margin-top: auto;
|
|
272
|
+
padding-bottom: 1mm;
|
|
273
|
+
font-family: Calibri, Carlito, Arial, sans-serif;
|
|
274
|
+
font-size: 10pt;
|
|
275
|
+
font-weight: 700;
|
|
276
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ADULT_ART,
|
|
3
|
+
HEPATITIS_B,
|
|
4
|
+
OPPORTUNISTIC_INFECTIONS,
|
|
5
|
+
PAEDIATRIC_ART,
|
|
6
|
+
PEP,
|
|
7
|
+
PMTCT_MOTHERS,
|
|
8
|
+
PREP,
|
|
9
|
+
} from './moh-729b.config';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* One client counted on the form, as the ETL returns it (/moh-729b), with the
|
|
13
|
+
* form's regimen code worked out in SQL: a client active on ART in the month
|
|
14
|
+
* (by their current ARVs, reported line, age and pregnancy, and a child's
|
|
15
|
+
* weight band), or a client on PrEP in the month (by the PrEP prescribed at
|
|
16
|
+
* their latest visit).
|
|
17
|
+
*/
|
|
18
|
+
export interface Moh729bRow {
|
|
19
|
+
person_id: number;
|
|
20
|
+
patient_uuid?: string;
|
|
21
|
+
ccc_number?: string | null;
|
|
22
|
+
amrs_number?: string | null;
|
|
23
|
+
full_name?: string | null;
|
|
24
|
+
gender?: string | null;
|
|
25
|
+
birthdate?: string | null;
|
|
26
|
+
age?: number | null;
|
|
27
|
+
weight?: number | null;
|
|
28
|
+
rtc_date?: string | null;
|
|
29
|
+
/** concept ids joined by ' ## ', as stored in the HIV summary */
|
|
30
|
+
cur_arv_meds?: string | null;
|
|
31
|
+
/** 1, 2 or 3 */
|
|
32
|
+
arv_line?: number | null;
|
|
33
|
+
pregnant?: string | null;
|
|
34
|
+
/** PrEP only: the PrEP number, latest visit of the month and status at it */
|
|
35
|
+
prep_number?: string | null;
|
|
36
|
+
last_visit_date?: string | null;
|
|
37
|
+
prep_status?: string | null;
|
|
38
|
+
/** PEP only: the exposure the latest PEP of the month was given for */
|
|
39
|
+
exposure_date?: string | null;
|
|
40
|
+
exposure_type?: string | null;
|
|
41
|
+
/** Hepatitis B only: the ANC visit and the results MOH 731 2.4 counts it by */
|
|
42
|
+
anc_date?: string | null;
|
|
43
|
+
hiv_result?: string | null;
|
|
44
|
+
hbv_result?: string | null;
|
|
45
|
+
hbv_test_date?: string | null;
|
|
46
|
+
/** TPT only: the ART start, this month's TB screening and the TPT start */
|
|
47
|
+
arv_first_regimen_start_date?: string | null;
|
|
48
|
+
tb_screening_date?: string | null;
|
|
49
|
+
tb_screening_result?: string | null;
|
|
50
|
+
ipt_start_date?: string | null;
|
|
51
|
+
/** Adult, Paediatric, PMTCT, PrEP, PEP for Adults, PEP for Children, Hepatitis B or TPT HIV Positive */
|
|
52
|
+
client_group?: string | null;
|
|
53
|
+
/** e.g. TDF + 3TC + DTG */
|
|
54
|
+
regimen?: string | null;
|
|
55
|
+
/** the form's code, e.g. AF2E */
|
|
56
|
+
regimen_code?: string | null;
|
|
57
|
+
/** children only, as the form heads the bands, e.g. 10-13.9kg */
|
|
58
|
+
weight_band?: string | null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** The PEP regimen codes (PA… for adults, PC3A/PC3C/PC4X for children -- not the infants' PC7, PC8, PC1X) */
|
|
62
|
+
export const PEP_CODES = new Set(PEP.flatMap((group) => group.rows.map(([code]) => code)));
|
|
63
|
+
|
|
64
|
+
/** One count on the form: a regimen code, narrowed to a weight band or a line where the form splits it */
|
|
65
|
+
export interface Moh729bCell {
|
|
66
|
+
code: string;
|
|
67
|
+
band?: string;
|
|
68
|
+
line?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The form prints TAF + 3TC + DTG as AS2G among the adult 1st line regimens;
|
|
73
|
+
* its own list of codes (page 3) calls it AF2G, which is what the ETL returns.
|
|
74
|
+
*/
|
|
75
|
+
export const countedCode = (printed: string) => (printed === 'AS2G' ? 'AF2G' : printed);
|
|
76
|
+
|
|
77
|
+
export const inCell = (row: Moh729bRow, { code, band, line }: Moh729bCell) =>
|
|
78
|
+
row.regimen_code === countedCode(code) &&
|
|
79
|
+
(band === undefined || row.weight_band === band) &&
|
|
80
|
+
(line === undefined || Number(row.arv_line) === line);
|
|
81
|
+
|
|
82
|
+
/** A client in any of several counts (a total of counts that never overlap) */
|
|
83
|
+
export const inCells = (row: Moh729bRow, cells: Moh729bCell[]) => cells.some((cell) => inCell(row, cell));
|
|
84
|
+
|
|
85
|
+
/** A count in a link: `AF2E`, `CF2G~20-24.9kg`, `PM12~~2` */
|
|
86
|
+
export const encodeCell = ({ code, band, line }: Moh729bCell) =>
|
|
87
|
+
[code, band ?? '', line ?? ''].join('~').replace(/~+$/, '');
|
|
88
|
+
|
|
89
|
+
export const decodeCell = (value: string): Moh729bCell => {
|
|
90
|
+
const [code, band, line] = value.split('~');
|
|
91
|
+
return { code, band: band || undefined, line: Number(line) || undefined };
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/** The regimen a code stands for on the form, for a linelist's heading */
|
|
95
|
+
export const REGIMEN_NAMES: Record<string, string> = Object.fromEntries(
|
|
96
|
+
[...ADULT_ART, ...PAEDIATRIC_ART, PMTCT_MOTHERS, PREP, ...PEP, HEPATITIS_B, ...OPPORTUNISTIC_INFECTIONS].flatMap(
|
|
97
|
+
(section) => section.rows.map(([code, name]) => [countedCode(code), name]),
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const ORDINALS = ['', '1st', '2nd', '3rd'];
|
|
102
|
+
|
|
103
|
+
/** e.g. `AF2E TDF + 3TC + DTG`, `CF2G ABC+3TC+DTG · 20-24.9kg`, `PM12 … · 1st Line` */
|
|
104
|
+
export const describeCell = ({ code, band, line }: Moh729bCell) =>
|
|
105
|
+
[
|
|
106
|
+
`${countedCode(code)} ${REGIMEN_NAMES[countedCode(code)] ?? ''}`.trim(),
|
|
107
|
+
band,
|
|
108
|
+
line ? `${ORDINALS[line] ?? line} Line` : undefined,
|
|
109
|
+
]
|
|
110
|
+
.filter(Boolean)
|
|
111
|
+
.join(' · ');
|
|
@@ -248,13 +248,16 @@ const Moh731Report: React.FC<Moh731Props> = () => {
|
|
|
248
248
|
</div>
|
|
249
249
|
</TabPanel>
|
|
250
250
|
<TabPanel className={styles.summaryPanel}>
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
251
|
+
{/* in the same bordered card as the form, so both tabs read alike */}
|
|
252
|
+
<div className={styles.reportFrame}>
|
|
253
|
+
<Moh731Summary
|
|
254
|
+
data={moh731Data}
|
|
255
|
+
openLinelist={openSummaryLinelist}
|
|
256
|
+
sectionId={summarySection}
|
|
257
|
+
onSectionChange={selectSummarySection}
|
|
258
|
+
period={`${startDate}-${endDate}`}
|
|
259
|
+
/>
|
|
260
|
+
</div>
|
|
258
261
|
</TabPanel>
|
|
259
262
|
</TabPanels>
|
|
260
263
|
</Tabs>
|
|
@@ -47,22 +47,19 @@ $section-gap: 0.8mm; // around a divider
|
|
|
47
47
|
margin-top: layout.$spacing-05;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
/* Each tab's panel brings its own spacing
|
|
50
|
+
/* Each tab's panel brings its own spacing: both sit in the report card */
|
|
51
51
|
.formPanel,
|
|
52
52
|
.summaryPanel {
|
|
53
53
|
padding: 0;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
.summaryPanel {
|
|
57
|
-
margin-top: layout.$spacing-05;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
56
|
/* The card the sheet sits in, drawn like the filter card above it (same rule
|
|
61
57
|
and fill) so the report reads as the second panel of one page.
|
|
62
58
|
It wraps `.viewport` rather than styling it: the page is scaled to the
|
|
63
59
|
viewport's width, so padding there would push the sheet into a scrollbar. */
|
|
64
60
|
.reportFrame {
|
|
65
|
-
|
|
61
|
+
/* clear of the foot of the page when scrolled to the end */
|
|
62
|
+
margin: layout.$spacing-05 0 layout.$spacing-07;
|
|
66
63
|
padding: layout.$spacing-05;
|
|
67
64
|
background-color: $ui-02;
|
|
68
65
|
border: 1px solid $ui-03;
|
|
@@ -375,9 +375,8 @@ export const MOH_731_SUMMARY: SummarySection[] = [
|
|
|
375
375
|
note: 'Both tables are the clients on ART and add up to 3.2 Currently on ART. Not categorized: no stability, or no DSD model, recorded.',
|
|
376
376
|
tables: [
|
|
377
377
|
{
|
|
378
|
-
title: 'By stability',
|
|
379
378
|
columns: [],
|
|
380
|
-
totalLabel: 'Total
|
|
379
|
+
totalLabel: 'Total',
|
|
381
380
|
rows: [
|
|
382
381
|
{ label: 'Established', only: 'HV03-033' },
|
|
383
382
|
{ label: 'Not established', only: 'DSD-NE' },
|
|
@@ -385,9 +384,8 @@ export const MOH_731_SUMMARY: SummarySection[] = [
|
|
|
385
384
|
],
|
|
386
385
|
},
|
|
387
386
|
{
|
|
388
|
-
title: 'By model',
|
|
389
387
|
columns: [],
|
|
390
|
-
totalLabel: 'Total
|
|
388
|
+
totalLabel: 'Total',
|
|
391
389
|
rows: [
|
|
392
390
|
{ label: 'Community', only: 'DSD-CO' },
|
|
393
391
|
{ label: 'Facility', only: 'DSD-FA' },
|