@ampath/esm-reports-app 1.0.0-next.8 → 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/197.js +1 -1
- package/dist/282.js +1 -1
- package/dist/282.js.map +1 -1
- package/dist/295.css +1 -0
- package/dist/295.css.map +1 -0
- package/dist/295.js +1 -0
- package/dist/295.js.map +1 -0
- package/dist/299.js +2 -0
- package/dist/299.js.LICENSE.txt +3 -0
- package/dist/299.js.map +1 -0
- package/dist/300.js +1 -1
- package/dist/311.js +1 -1
- package/dist/311.js.map +1 -1
- package/dist/335.js +1 -1
- package/dist/353.js +1 -1
- package/dist/353.js.map +1 -1
- package/dist/354.js +2 -0
- package/dist/354.js.LICENSE.txt +20 -0
- package/dist/354.js.map +1 -0
- package/dist/410.js +1 -0
- package/dist/410.js.map +1 -0
- package/dist/457.js +2 -0
- package/dist/457.js.LICENSE.txt +261 -0
- package/dist/457.js.map +1 -0
- package/dist/478.js +1 -1
- package/dist/478.js.map +1 -1
- package/dist/480.js +1 -0
- package/dist/540.js +1 -1
- package/dist/540.js.map +1 -1
- package/dist/55.js +1 -1
- package/dist/600.js +2 -0
- package/dist/600.js.LICENSE.txt +35 -0
- package/dist/600.js.map +1 -0
- package/dist/652.js +1 -1
- package/dist/757.js +1 -0
- package/dist/757.js.map +1 -0
- package/dist/781.js +1 -0
- package/dist/781.js.map +1 -0
- package/dist/961.js +1 -1
- package/dist/961.js.map +1 -1
- package/dist/99.js +1 -1
- package/dist/99.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 +4 -2
- package/src/common/daily-summary-table.tsx +55 -0
- package/src/common/linelist-table/index.ts +3 -0
- package/src/common/linelist-table/linelist-columns.ts +48 -0
- package/src/common/linelist-table/linelist-table.component.tsx +442 -0
- package/src/common/linelist-table/linelist-table.scss +306 -0
- package/src/common/linelist-table/linelist-table.test.tsx +120 -0
- package/src/common/linelist-table/use-all-rows.ts +93 -0
- package/src/common/linelist-table/use-column-layout.ts +123 -0
- package/src/common/report-error/index.ts +1 -0
- package/src/common/report-error/show-report-error.ts +25 -0
- package/src/common/report-filters/date-range.ts +137 -0
- package/src/common/report-filters/index.ts +4 -0
- package/src/common/report-filters/report-filters.component.tsx +317 -99
- package/src/common/report-filters/report-filters.scss +264 -32
- package/src/common/report-filters/types.ts +79 -0
- package/src/common/report-filters/use-restore-period.ts +43 -0
- package/src/common/report-header/index.ts +1 -0
- package/src/common/report-header/use-location-details.ts +58 -0
- package/src/common/report-page/download-sheet-pdf.ts +225 -0
- package/src/common/report-page/index.ts +3 -0
- package/src/common/report-page/report-page.component.tsx +32 -0
- package/src/common/report-page/report-page.scss +45 -0
- package/src/common/report-page/use-page-scale.ts +60 -0
- package/src/common/report-placeholder/has-report-data.ts +15 -0
- package/src/common/report-placeholder/index.ts +3 -0
- package/src/common/report-placeholder/report-placeholder.component.tsx +81 -0
- package/src/common/report-placeholder/report-placeholder.scss +48 -0
- package/src/common/report-placeholder/use-generated-location.ts +62 -0
- package/src/common/report-register/index.ts +6 -0
- package/src/common/report-register/register-columns.ts +46 -0
- package/src/common/report-register/register-layout.component.tsx +265 -0
- package/src/common/report-register/register-layout.scss +150 -0
- package/src/common/report-register/register-table.scss +71 -0
- package/src/common/report-register/report-parents.ts +29 -0
- package/src/common/report-register/rows-to-csv.ts +89 -0
- package/src/common/report-register/use-location-name.ts +54 -0
- package/src/common/report-register/use-patient-list.ts +92 -0
- package/src/common/report-skeleton/index.ts +1 -0
- package/src/common/report-skeleton/report-skeleton.component.tsx +46 -0
- package/src/common/report-skeleton/report-skeleton.scss +29 -0
- package/src/config-schema.ts +9 -1
- package/src/dashboard/report-catalog.ts +191 -0
- package/src/dashboard/reports-dasboard.tsx +189 -18
- package/src/dashboard/reports-dashboard.module.scss +357 -14
- package/src/index.ts +13 -1
- package/src/registers/moh-240/moh-240-register.scss +41 -0
- package/src/registers/moh-240/moh-240.component.test.tsx +166 -0
- package/src/registers/moh-240/moh-240.component.tsx +164 -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 +551 -0
- package/src/registers/moh-362/moh-362-lab-register.scss +412 -0
- package/src/registers/moh-362/moh-362-linkage-register.component.tsx +215 -0
- package/src/registers/moh-362/moh-362-linkage-register.scss +91 -0
- package/src/registers/moh-362/moh-362.component.tsx +117 -0
- package/src/registers/moh-362/moh-362.scss +11 -0
- package/src/registers/moh-362/moh-362.types.ts +87 -0
- 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 +202 -0
- package/src/registers/register-file-name.ts +18 -0
- package/src/registers/tb-lab-register/tb-lab-register-table.component.tsx +116 -0
- package/src/registers/tb-lab-register/tb-lab-register-table.scss +123 -0
- package/src/registers/tb-lab-register/tb-lab-register.columns.ts +164 -0
- package/src/registers/tb-lab-register/tb-lab-register.component.test.tsx +232 -0
- package/src/registers/tb-lab-register/tb-lab-register.component.tsx +153 -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/datatable-wrapper/datatable-wrapper.component.tsx +63 -48
- package/src/reports/moh-240/moh-240-header.component.tsx +62 -0
- package/src/reports/moh-240/moh-240.columns.ts +113 -0
- package/src/reports/moh-240/moh-240.component.tsx +72 -9
- package/src/reports/moh-240/moh-240.scss +40 -0
- package/src/reports/moh-240/sub-reports/moh-240-register.component.tsx +31 -37
- package/src/reports/moh-240/sub-reports/page-summary.component.tsx +143 -106
- package/src/reports/moh-505/moh-505-header.component.tsx +67 -0
- package/src/reports/moh-505/moh-505.component.tsx +441 -0
- package/src/reports/moh-505/moh-505.scss +117 -0
- package/src/reports/moh-705B/moh-204b-register.component.tsx +246 -0
- package/src/reports/moh-705B/moh-204b.columns.ts +39 -0
- package/src/reports/moh-705B/moh-705b.component.tsx +659 -0
- package/src/reports/moh-705B/moh-705b.scss +172 -0
- package/src/reports/moh-705a/moh-705a.component.tsx +661 -0
- package/src/reports/moh-705a/moh-705a.scss +172 -0
- package/src/reports/moh-705a/registers/moh-204a-register.component.tsx +331 -0
- package/src/reports/moh-705a/registers/moh-204a.columns.ts +57 -0
- package/src/reports/moh-705a/type.ts +6 -0
- package/src/reports/moh-706/moh-706-header.component.tsx +66 -0
- package/src/reports/moh-706/moh-706.component.tsx +150 -24
- package/src/reports/moh-706/moh-706.scss +119 -11
- package/src/reports/moh-706/sub-reports/bacteriology/bacteriology.component.tsx +35 -28
- package/src/reports/moh-706/sub-reports/blood-chemistry/blood-chemistry.component.tsx +229 -305
- package/src/reports/moh-706/sub-reports/haematology/haematology.component.tsx +26 -19
- package/src/reports/moh-706/sub-reports/histology-and-cytology/histology-and-cytology.component.tsx +23 -23
- package/src/reports/moh-706/sub-reports/parasitology/parasitology.component.tsx +25 -18
- package/src/reports/moh-706/sub-reports/serology/serology.component.tsx +21 -14
- package/src/reports/moh-706/sub-reports/specimen-referral-to-higher-levels/specimen-referral-to-higher-levels.component.tsx +2 -2
- package/src/reports/moh-706/sub-reports/urine-analysis/urine-analysis.component.tsx +27 -20
- package/src/reports/moh-710/moh-710.component.tsx +815 -632
- package/src/reports/moh-710/moh-710.scss +142 -21
- package/src/reports/moh-710/registers/moh-413/moh-413-columns.ts +22 -0
- package/src/reports/moh-710/registers/moh-413/moh-413.component.tsx +140 -0
- package/src/reports/moh-710/registers/moh-413/moh-413.scss +64 -0
- package/src/reports/moh-710/registers/moh-510/moh-510.columns.ts +40 -0
- package/src/reports/moh-710/registers/moh-510/moh-510.component.tsx +191 -0
- package/src/reports/moh-710/registers/moh-510/moh-510.scss +130 -0
- package/src/reports/moh-710/registers/moh-511-710-register.component.tsx +268 -0
- package/src/reports/moh-710/registers/moh-511-710.columns.ts +52 -0
- package/src/reports/moh-710/registers/type.ts +31 -0
- package/src/reports/moh-711/moh-711.component.tsx +153 -1269
- package/src/reports/moh-711/moh711.scss +135 -20
- package/src/reports/moh-711/registers/moh-333-register.component.tsx +680 -0
- package/src/reports/moh-711/registers/moh-333.columns.ts +119 -0
- package/src/reports/moh-711/registers/moh-405-register.component.tsx +566 -0
- package/src/reports/moh-711/registers/moh-405.columns.ts +120 -0
- package/src/reports/moh-711/registers/moh-406-register.component.tsx +581 -0
- package/src/reports/moh-711/registers/moh-406.columns.ts +133 -0
- package/src/reports/moh-711/registers/moh-407-register.component.tsx +157 -0
- package/src/reports/moh-711/registers/moh-407.columns.ts +24 -0
- package/src/reports/moh-711/registers/moh-407.scss +64 -0
- package/src/reports/moh-711/registers/moh-510-register.component.tsx +55 -0
- package/src/reports/moh-711/registers/moh-511-register.component.tsx +270 -0
- package/src/reports/moh-711/registers/moh-511.columns.ts +59 -0
- package/src/reports/moh-711/registers/moh-512-columns.ts +94 -0
- package/src/reports/moh-711/registers/moh-512.component.tsx +191 -0
- package/src/reports/moh-711/registers/moh-512.scss +64 -0
- package/src/reports/moh-711/registers/tb-register-columns.ts +17 -0
- package/src/reports/moh-711/registers/tb-register.component.tsx +96 -0
- package/src/reports/moh-711/registers/tb-register.scss +64 -0
- package/src/reports/moh-711/registers/type.ts +192 -0
- package/src/reports/moh-711/sections/anc.component.tsx +159 -0
- package/src/reports/moh-711/sections/cervical-cancer.component.tsx +148 -0
- package/src/reports/moh-711/sections/chanis.component.tsx +389 -0
- package/src/reports/moh-711/sections/family-planning.component.tsx +299 -0
- package/src/reports/moh-711/sections/gbv.component.tsx +115 -0
- package/src/reports/moh-711/sections/maternity.component.tsx +321 -0
- package/src/reports/moh-711/sections/medical-social-work.component.tsx +73 -0
- package/src/reports/moh-711/sections/other.component.tsx +47 -0
- package/src/reports/moh-711/sections/physiotherapy.component.tsx +61 -0
- package/src/reports/moh-711/sections/pnc.component.tsx +127 -0
- package/src/reports/moh-711/sections/post-abortion.component.tsx +42 -0
- package/src/reports/moh-711/sections/rehabilitation.component.tsx +57 -0
- package/src/reports/moh-711/sections/report-compiled-by.component.tsx +50 -0
- package/src/reports/moh-711/sections/tb-screening.component.tsx +94 -0
- package/src/reports/moh-717/moh-717.component.tsx +149 -985
- package/src/reports/moh-717/moh717.scss +217 -21
- package/src/reports/moh-717/registers/nutrition-register.component.tsx +48 -0
- package/src/reports/moh-717/sections/finance.component.tsx +42 -0
- package/src/reports/moh-717/sections/inpatient.component.tsx +374 -0
- package/src/reports/moh-717/sections/maternity.component.tsx +126 -0
- package/src/reports/moh-717/sections/medical-records.component.tsx +35 -0
- package/src/reports/moh-717/sections/mortuary.component.tsx +43 -0
- package/src/reports/moh-717/sections/operations.component.tsx +53 -0
- package/src/reports/moh-717/sections/orthopaedic-trauma.component.tsx +98 -0
- package/src/reports/moh-717/sections/outpatient.component.tsx +597 -0
- package/src/reports/moh-717/sections/pharmacy.component.tsx +43 -0
- package/src/reports/moh-717/sections/preparedby.component.tsx +52 -0
- package/src/reports/moh-717/sections/special-services.component.tsx +114 -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/linelist/moh-731-indicators.ts +1122 -0
- package/src/reports/moh-731/linelist/moh-731-linelist-sections.ts +472 -0
- package/src/reports/moh-731/linelist/moh-731-linelist.component.tsx +102 -0
- package/src/reports/moh-731/linelist/use-open-moh-731-linelist.ts +50 -0
- package/src/reports/moh-731/moh-731.component.tsx +269 -0
- package/src/reports/moh-731/moh-731.scss +496 -0
- package/src/reports/moh-731/registers/moh-366.columns.ts +38 -0
- package/src/reports/moh-731/registers/moh-366.component.tsx +471 -0
- package/src/reports/moh-731/registers/prep-register.component.tsx +284 -0
- package/src/reports/moh-731/registers/prep.columns.ts +34 -0
- package/src/reports/moh-731/sections/hiv-and-tb-treatment.component.tsx +1206 -0
- package/src/reports/moh-731/sections/hiv-testing-and-pre-exposure.component.tsx +727 -0
- package/src/reports/moh-731/sections/pmtct.component.tsx +572 -0
- package/src/reports/moh-731/summary/moh-731-summary.component.tsx +313 -0
- package/src/reports/moh-731/summary/moh-731-summary.config.ts +527 -0
- package/src/reports/moh-731/summary/moh-731-summary.scss +247 -0
- package/src/reports/moh-740/moh-740.component.scss +202 -0
- package/src/reports/moh-740/moh-740.component.tsx +1332 -0
- package/src/reports/moh-740/moh-740.resource.ts +54 -0
- package/src/reports/moh-740/registers/moh-222-daily-register/moh-222-daily-register.tsx +149 -0
- package/src/reports/moh-740/registers/moh-270-permanent-register/moh-270-permanent-register.tsx +123 -0
- package/src/reports/moh-740/registers/moh-740-patient-list.scss +0 -0
- package/src/reports/moh-740/registers/moh-740-patient-list.tsx +60 -0
- package/src/reports/moh-740/registers/moh-740.columns.ts +54 -0
- package/src/reports/moh-740/shared/data-cell/data-cell.scss +6 -0
- package/src/reports/moh-740/shared/data-cell/data-cell.tsx +23 -0
- package/src/reports/moh-740/shared/utils/indicator-register-map.ts +159 -0
- package/src/reports/moh-740/types/index.ts +223 -0
- package/src/reports/moh-745/moh-745.component.tsx +2058 -0
- package/src/reports/moh-745/moh-745.scss +142 -0
- package/src/reports/moh-745/registers/moh-412-register.component.tsx +249 -0
- package/src/reports/moh-745/registers/moh-412.columns.ts +52 -0
- package/src/reports/moh-745/registers/type.ts +223 -0
- package/src/reports/table-wrapper/table-row-mapper.component.tsx +20 -5
- package/src/reports/table-wrapper/table-wrapper.component.tsx +23 -14
- package/src/reports/table-wrapper/table-wrapper.scss +1 -16
- package/src/resources/moh-267.resource.ts +27 -0
- package/src/resources/moh-362.resource.ts +27 -0
- package/src/resources/moh-505.resource.ts +69 -0
- package/src/resources/moh-705.resource.ts +118 -0
- package/src/resources/moh-706.resource.ts +80 -0
- package/src/resources/moh-710.resource.ts +60 -9
- package/src/resources/moh-711.resource.ts +206 -9
- package/src/resources/moh-717.resource.ts +26 -9
- package/src/resources/moh-729b.resource.ts +25 -0
- package/src/resources/moh-731.resource.ts +90 -0
- package/src/resources/moh-745.resource.ts +76 -0
- package/src/resources/patient-list-page.ts +66 -0
- package/src/resources/presumptive-tb.resource.ts +27 -0
- package/src/root.component.tsx +79 -8
- package/src/root.scss +36 -0
- package/src/routes.json +3 -1
- package/src/utils/format-indicator.ts +39 -0
- package/src/utils/get-base-url.ts +39 -7
- package/src/utils/utils.ts +30 -1
- package/tsconfig.json +1 -1
- package/webpack.config.js +22 -1
- package/dist/138.js +0 -2
- package/dist/138.js.LICENSE.txt +0 -20
- package/dist/138.js.map +0 -1
- package/dist/184.js +0 -2
- package/dist/184.js.LICENSE.txt +0 -14
- package/dist/184.js.map +0 -1
- package/dist/205.js +0 -1
- package/dist/205.js.map +0 -1
- package/dist/812.js +0 -1
- package/dist/812.js.map +0 -1
- package/dist/879.js +0 -1
- package/dist/879.js.map +0 -1
- package/dist/ampath-esm-reports-app.js.buildmanifest.json +0 -539
- package/dist/main.js +0 -1
- package/dist/main.js.map +0 -1
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
@use '@carbon/layout';
|
|
2
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
3
|
+
|
|
4
|
+
/* MOH 267 PrEP Daily Activity Register (Ver. July 2023) as A4 landscape pages,
|
|
5
|
+
drawn in the units the paper is measured in (mm, pt) so a page is one sheet,
|
|
6
|
+
as on page 3 of the form: the ruled visits, the page and month totals, and
|
|
7
|
+
on the last page the summary tables, all inside one frame. Heights are fixed
|
|
8
|
+
so a page never spills over: 22 visits on a full page, 15 with the summary
|
|
9
|
+
on the last. */
|
|
10
|
+
|
|
11
|
+
/* On screen a page is the printable area only, A4 landscape less its 8mm
|
|
12
|
+
margins: the card around it gives the margin, and `usePageScale` is told
|
|
13
|
+
this width. */
|
|
14
|
+
$page-w: 297mm - 2 * 8mm;
|
|
15
|
+
$page-h: 210mm - 2 * 8mm;
|
|
16
|
+
|
|
17
|
+
$ink: #000;
|
|
18
|
+
$rule: 0.6pt solid $ink;
|
|
19
|
+
$thick: 1.4pt solid $ink;
|
|
20
|
+
$dotted: 0.6pt dotted $ink;
|
|
21
|
+
$shade: #e8e8e8; // the lower half of (c), and cells that do not apply
|
|
22
|
+
|
|
23
|
+
$heading-h: 23.8mm;
|
|
24
|
+
$ids-h: 3.4mm;
|
|
25
|
+
$line-h: 3.35mm; // half a visit's row: each visit takes two lines
|
|
26
|
+
$total-h: 4mm;
|
|
27
|
+
|
|
28
|
+
/* The card the pages sit in, drawn like the filter card above it */
|
|
29
|
+
.reportFrame {
|
|
30
|
+
margin: layout.$spacing-05 0 layout.$spacing-07;
|
|
31
|
+
padding: layout.$spacing-05;
|
|
32
|
+
background-color: $ui-02;
|
|
33
|
+
border: 1px solid $ui-03;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Holds the fixed-width pages without making the app scroll sideways */
|
|
37
|
+
.viewport {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
gap: layout.$spacing-09;
|
|
41
|
+
overflow-x: auto;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.page {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
flex: none;
|
|
48
|
+
box-sizing: border-box;
|
|
49
|
+
width: $page-w;
|
|
50
|
+
height: $page-h;
|
|
51
|
+
margin: 0 auto;
|
|
52
|
+
color: $ink;
|
|
53
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
54
|
+
font-size: 7pt;
|
|
55
|
+
line-height: 1.15;
|
|
56
|
+
background-color: #fff;
|
|
57
|
+
/* set by `usePageScale` from the measured container width, floored at 1 */
|
|
58
|
+
zoom: var(--page-zoom, 1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.runningHead {
|
|
62
|
+
display: grid;
|
|
63
|
+
grid-template-columns: 1fr auto 1fr;
|
|
64
|
+
margin-bottom: 1.6mm;
|
|
65
|
+
font-size: 9.5pt;
|
|
66
|
+
font-weight: 700;
|
|
67
|
+
|
|
68
|
+
span:last-child {
|
|
69
|
+
text-align: right;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* The ruled sheet: visits, totals and summary in one heavy border. A full
|
|
74
|
+
page's frame ends with its totals; the last page's runs down to the foot. */
|
|
75
|
+
.frame {
|
|
76
|
+
display: flex;
|
|
77
|
+
flex-direction: column;
|
|
78
|
+
min-height: 0;
|
|
79
|
+
border: $thick;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.lastFrame {
|
|
83
|
+
flex: 1;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.register {
|
|
87
|
+
width: 100%;
|
|
88
|
+
table-layout: fixed;
|
|
89
|
+
border-collapse: collapse;
|
|
90
|
+
|
|
91
|
+
th,
|
|
92
|
+
td {
|
|
93
|
+
padding: 0 0.6mm;
|
|
94
|
+
overflow: hidden;
|
|
95
|
+
text-align: center;
|
|
96
|
+
vertical-align: middle;
|
|
97
|
+
border: $rule;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* the frame draws the outer edge */
|
|
101
|
+
tr > :first-child {
|
|
102
|
+
border-left: none;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
tr > :last-child {
|
|
106
|
+
border-right: none;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
thead tr:first-child > * {
|
|
110
|
+
border-top: none;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.headings th {
|
|
115
|
+
height: $heading-h;
|
|
116
|
+
font-size: 7.5pt;
|
|
117
|
+
font-weight: 700;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* code lists in the headings, in regular type and set left */
|
|
121
|
+
.codeHeading {
|
|
122
|
+
font-size: 6.5pt !important;
|
|
123
|
+
font-weight: 400 !important;
|
|
124
|
+
text-align: left !important;
|
|
125
|
+
vertical-align: middle;
|
|
126
|
+
|
|
127
|
+
strong {
|
|
128
|
+
font-size: 7pt;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.codes {
|
|
133
|
+
font-weight: 400;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* (a), (b) … under the headings, in a heavy rule as on the form */
|
|
137
|
+
.columnIds th {
|
|
138
|
+
height: $ids-h;
|
|
139
|
+
font-size: 7pt;
|
|
140
|
+
font-weight: 400;
|
|
141
|
+
border-top: $thick;
|
|
142
|
+
border-bottom: $thick;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* A heading holding two labels: upper cell over lower cell */
|
|
146
|
+
.splitHeader {
|
|
147
|
+
padding: 0 !important;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.splitStack {
|
|
151
|
+
display: flex;
|
|
152
|
+
flex-direction: column;
|
|
153
|
+
height: $heading-h;
|
|
154
|
+
|
|
155
|
+
span {
|
|
156
|
+
display: flex;
|
|
157
|
+
flex: 1;
|
|
158
|
+
align-items: center;
|
|
159
|
+
justify-content: center;
|
|
160
|
+
padding: 0 1mm;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
span:first-child {
|
|
164
|
+
border-bottom: $rule;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.upperLine td,
|
|
169
|
+
.lowerLine td {
|
|
170
|
+
height: $line-h;
|
|
171
|
+
white-space: nowrap;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* the two halves of (c): national ID over NUPI */
|
|
175
|
+
.upperCell {
|
|
176
|
+
border-bottom: $dotted !important;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.lowerCell {
|
|
180
|
+
border-top: $dotted !important;
|
|
181
|
+
background-color: $shade;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.left {
|
|
185
|
+
text-align: left !important;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* remarks may take both lines of the row, never more */
|
|
189
|
+
.clamp {
|
|
190
|
+
display: -webkit-box;
|
|
191
|
+
overflow: hidden;
|
|
192
|
+
white-space: normal;
|
|
193
|
+
-webkit-box-orient: vertical;
|
|
194
|
+
-webkit-line-clamp: 2;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.totalRow th,
|
|
198
|
+
.totalRow td {
|
|
199
|
+
height: $total-h;
|
|
200
|
+
font-weight: 700;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Summary tables at the foot of the last page, spaced across the sheet as on the form */
|
|
204
|
+
|
|
205
|
+
.summary {
|
|
206
|
+
display: flex;
|
|
207
|
+
flex: 1;
|
|
208
|
+
align-items: flex-start;
|
|
209
|
+
justify-content: space-between;
|
|
210
|
+
padding: 3mm 1.5mm 0;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.summaryTable {
|
|
214
|
+
border-collapse: collapse;
|
|
215
|
+
font-size: 5.5pt;
|
|
216
|
+
line-height: 1.1;
|
|
217
|
+
|
|
218
|
+
th,
|
|
219
|
+
td {
|
|
220
|
+
height: 3.8mm;
|
|
221
|
+
padding: 0 0.5mm;
|
|
222
|
+
text-align: center;
|
|
223
|
+
border: $rule;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
th {
|
|
227
|
+
font-weight: 700;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
td {
|
|
231
|
+
width: 5.1mm;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.ageTable {
|
|
236
|
+
width: 66mm;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.rowLabel {
|
|
240
|
+
width: 15mm;
|
|
241
|
+
text-align: left !important;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.notApplicable {
|
|
245
|
+
background-color: $shade;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.methodColumn {
|
|
249
|
+
display: flex;
|
|
250
|
+
flex-direction: column;
|
|
251
|
+
gap: 3mm;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.methodTable {
|
|
255
|
+
width: 69mm;
|
|
256
|
+
|
|
257
|
+
td {
|
|
258
|
+
width: auto;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.rowLabel {
|
|
262
|
+
width: 22.5mm;
|
|
263
|
+
height: 5.8mm;
|
|
264
|
+
font-weight: 400;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
thead th:not(:first-child) {
|
|
268
|
+
font-size: 5.5pt;
|
|
269
|
+
text-align: left;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.seroconverting {
|
|
274
|
+
width: 30mm;
|
|
275
|
+
|
|
276
|
+
th {
|
|
277
|
+
width: 22.5mm;
|
|
278
|
+
height: 5.5mm;
|
|
279
|
+
text-align: left;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
td {
|
|
283
|
+
width: 7.5mm;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.pageFoot {
|
|
288
|
+
display: flex;
|
|
289
|
+
justify-content: space-between;
|
|
290
|
+
margin-top: auto;
|
|
291
|
+
padding-top: 1.2mm;
|
|
292
|
+
font-size: 8pt;
|
|
293
|
+
font-weight: 700;
|
|
294
|
+
|
|
295
|
+
span:first-child {
|
|
296
|
+
font-weight: 400;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
|
|
3
|
+
import { type Moh267Row } from './moh-267.types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The figures in MOH 267's summary tables, counted from the register's visits
|
|
7
|
+
* by MOH 731's PrEP rules (the visits and their flags come from the MOH 731
|
|
8
|
+
* PrEP visits base):
|
|
9
|
+
*
|
|
10
|
+
* - Number initiated (New) on PrEP (g): visits flagged new (MOH 731 1.3).
|
|
11
|
+
* - Number Current on PrEP (New + Refill + Restart): clients whose latest
|
|
12
|
+
* visit in the period is New, Continuing or Restart.
|
|
13
|
+
* - Number diagnosed with STI (j): visits with an STI (MOH 731 1.4).
|
|
14
|
+
* - Number Seroconverting while on PrEP (i): MOH 731 1.5.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const AGE_BANDS: Array<{ label: string; min: number; max?: number }> = [
|
|
18
|
+
{ label: '10 - 14 Yrs', min: 10, max: 14 },
|
|
19
|
+
{ label: '15 - 19 Yrs', min: 15, max: 19 },
|
|
20
|
+
{ label: '20 - 24 Yrs', min: 20, max: 24 },
|
|
21
|
+
{ label: '25 - 29 Yrs', min: 25, max: 29 },
|
|
22
|
+
{ label: '≥ 30 Yrs', min: 30 },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
/** The populations of the age-by-sex tables, by the register's population type */
|
|
26
|
+
export const POPULATIONS = ['General Population', 'MSM/MSW', 'FSW', 'PWID/PWUD', 'Discordant Couple', 'VP'] as const;
|
|
27
|
+
|
|
28
|
+
export type Population = (typeof POPULATIONS)[number];
|
|
29
|
+
export type Sex = 'M' | 'F';
|
|
30
|
+
|
|
31
|
+
/** The PrEP methods across the method table, then its Total of every method */
|
|
32
|
+
export const METHODS = [
|
|
33
|
+
'Event driven oral PrEP',
|
|
34
|
+
'Daily oral PrEP',
|
|
35
|
+
'Dapivirine Vaginal ring',
|
|
36
|
+
'Cabotegravir Injectable',
|
|
37
|
+
] as const;
|
|
38
|
+
|
|
39
|
+
const inBand = (row: Moh267Row, band: { min: number; max?: number }) => {
|
|
40
|
+
const age = Number(row.age);
|
|
41
|
+
return row.age !== null && row.age !== undefined && row.age !== '' && Number.isFinite(age)
|
|
42
|
+
? age >= band.min && (band.max === undefined || age <= band.max)
|
|
43
|
+
: false;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/** Each client's latest visit in the period */
|
|
47
|
+
const latestPerClient = (rows: Moh267Row[]) => {
|
|
48
|
+
const latest = new Map<unknown, Moh267Row>();
|
|
49
|
+
rows.forEach((row) => latest.set(row.patient_id ?? row, row)); // rows come oldest first
|
|
50
|
+
return Array.from(latest.values());
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** One age-by-sex table: the count for a population, age band and sex */
|
|
54
|
+
export type AgeSexCounts = (population: Population | 'TOTAL', bandIndex: number, sex: Sex) => number;
|
|
55
|
+
|
|
56
|
+
const ageSexCounts =
|
|
57
|
+
(rows: Moh267Row[]): AgeSexCounts =>
|
|
58
|
+
(population, bandIndex, sex) =>
|
|
59
|
+
rows.filter(
|
|
60
|
+
(row) =>
|
|
61
|
+
(population === 'TOTAL' || row.population_type === population) &&
|
|
62
|
+
row.sex === sex &&
|
|
63
|
+
inBand(row, AGE_BANDS[bandIndex]),
|
|
64
|
+
).length;
|
|
65
|
+
|
|
66
|
+
const isCurrent = (row: Moh267Row) => ['New', 'Continuing', 'Restart'].includes(row.prep_status ?? '');
|
|
67
|
+
|
|
68
|
+
export function moh267Summary(rows: Moh267Row[], endDate: string) {
|
|
69
|
+
const latest = latestPerClient(rows);
|
|
70
|
+
const newVisits = rows.filter((row) => Number(row.is_new) === 1);
|
|
71
|
+
const threeMonthsBefore = dayjs(endDate).subtract(3, 'month');
|
|
72
|
+
|
|
73
|
+
/* clients on each method, for the method table: by their latest visit */
|
|
74
|
+
const byMethod = (clients: Moh267Row[]) => (method: (typeof METHODS)[number] | 'Total') =>
|
|
75
|
+
clients.filter((row) => method === 'Total' || row.prep_method === method).length;
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
initiated: ageSexCounts(newVisits),
|
|
79
|
+
current: ageSexCounts(latest.filter(isCurrent)),
|
|
80
|
+
sti: ageSexCounts(rows.filter((row) => row.sti_diagnosed === 'Yes')),
|
|
81
|
+
methods: [
|
|
82
|
+
{ label: 'Number initiated (New) on PrEP', count: byMethod(newVisits) },
|
|
83
|
+
{
|
|
84
|
+
label: 'Number continuing / currently on (Refills) PrEP',
|
|
85
|
+
count: byMethod(latest.filter((row) => row.prep_status === 'Continuing')),
|
|
86
|
+
},
|
|
87
|
+
{ label: 'Number Restarting PrEP', count: byMethod(latest.filter((row) => row.prep_status === 'Restart')) },
|
|
88
|
+
{
|
|
89
|
+
label: 'Number on PrEP for at-least 3 months',
|
|
90
|
+
count: byMethod(
|
|
91
|
+
latest.filter(
|
|
92
|
+
(row) =>
|
|
93
|
+
isCurrent(row) && row.prep_start_date && !dayjs(row.prep_start_date).isAfter(threeMonthsBefore, 'day'),
|
|
94
|
+
),
|
|
95
|
+
),
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
seroconverted: rows.filter((row) => Number(row.is_seroconverted) === 1).length,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type Moh267Summary = ReturnType<typeof moh267Summary>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import { useSession } from '@openmrs/esm-framework';
|
|
4
|
+
|
|
5
|
+
import { ReportFiltersComponent, type ReportPeriod, useRestorePeriod } from '../../common/report-filters';
|
|
6
|
+
import { downloadSheetsPdf } from '../../common/report-page';
|
|
7
|
+
import { showReportError } from '../../common/report-error';
|
|
8
|
+
import { ReportPlaceholder, useGeneratedLocation } from '../../common/report-placeholder';
|
|
9
|
+
import { ReportSkeleton } from '../../common/report-skeleton';
|
|
10
|
+
import { getMoh267 } from '../../resources/moh-267.resource';
|
|
11
|
+
import { registerFileName } from '../register-file-name';
|
|
12
|
+
import Moh267Register from './moh-267-register.component';
|
|
13
|
+
import { type Moh267Row } from './moh-267.types';
|
|
14
|
+
import styles from './moh-267-register.scss';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* MOH 267 PrEP Daily Activity Register, opened from the landing page's
|
|
18
|
+
* Registers tab, with the reports' filter bar. Its visits are MOH 731's PrEP
|
|
19
|
+
* visits (1.3 to 1.5), so the register and the report agree.
|
|
20
|
+
*/
|
|
21
|
+
const Moh267RegisterPage: React.FC = () => {
|
|
22
|
+
const [rows, setRows] = useState<Moh267Row[] | null>(null);
|
|
23
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
24
|
+
/* TOTAL this Month: the visits in the calendar month of the period's end,
|
|
25
|
+
whatever range the register itself covers */
|
|
26
|
+
const [monthVisits, setMonthVisits] = useState(0);
|
|
27
|
+
const [period, setPeriod] = useState<{ startDate: string; endDate: string }>({ startDate: '', endDate: '' });
|
|
28
|
+
|
|
29
|
+
const session = useSession();
|
|
30
|
+
const locationUuids = session?.sessionLocation?.uuid ?? '';
|
|
31
|
+
/* Only a register for the current location counts */
|
|
32
|
+
const { isForCurrentLocation, hasLocationChanged, markGenerated } = useGeneratedLocation('moh267Location');
|
|
33
|
+
const isGenerated = rows !== null && isForCurrentLocation;
|
|
34
|
+
|
|
35
|
+
const generate = async ({ startDate, endDate }: ReportPeriod) => {
|
|
36
|
+
setIsLoading(true);
|
|
37
|
+
setPeriod({ startDate, endDate });
|
|
38
|
+
try {
|
|
39
|
+
const monthStart = dayjs(endDate).startOf('month').format('YYYY-MM-DD');
|
|
40
|
+
const monthEnd = dayjs(endDate).endOf('month').format('YYYY-MM-DD');
|
|
41
|
+
const isWholeMonth = startDate === monthStart && endDate === monthEnd;
|
|
42
|
+
const [visits, month] = await Promise.all([
|
|
43
|
+
getMoh267({ locationUuids, startDate, endDate }),
|
|
44
|
+
isWholeMonth ? null : getMoh267({ locationUuids, startDate: monthStart, endDate: monthEnd }),
|
|
45
|
+
]);
|
|
46
|
+
setRows(visits);
|
|
47
|
+
setMonthVisits((month ?? visits).length);
|
|
48
|
+
markGenerated(locationUuids);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
showReportError('the MOH 267 register', error);
|
|
51
|
+
} finally {
|
|
52
|
+
setIsLoading(false);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
useRestorePeriod(generate);
|
|
57
|
+
|
|
58
|
+
/* Download PDF saves every page as an A4 landscape page, made from copies,
|
|
59
|
+
so the pages on screen are left as they are */
|
|
60
|
+
const sheetsRef = useRef<HTMLDivElement>(null);
|
|
61
|
+
const downloadPdf = async () => {
|
|
62
|
+
const pages = Array.from(sheetsRef.current?.querySelectorAll<HTMLElement>('[data-register-page]') ?? []);
|
|
63
|
+
const name = registerFileName('MOH-267', session?.sessionLocation?.display ?? '', period);
|
|
64
|
+
/* styled by its own stylesheets in Arial only, and may run to many pages */
|
|
65
|
+
await downloadSheetsPdf(pages, name, { orientation: 'landscape', stylesheetsOnly: true, image: 'jpeg' });
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<>
|
|
70
|
+
<ReportFiltersComponent
|
|
71
|
+
reportName="MOH 267 PrEP Daily Activity Register"
|
|
72
|
+
mode="both"
|
|
73
|
+
onGenerate={generate}
|
|
74
|
+
isLoading={isLoading}
|
|
75
|
+
isReportGenerated={isGenerated}
|
|
76
|
+
generatedPeriod={period}
|
|
77
|
+
defaultTab="custom"
|
|
78
|
+
backLink={{ label: 'All registers', to: '/?tab=registers' }}
|
|
79
|
+
onDownloadPdf={downloadPdf}
|
|
80
|
+
/>
|
|
81
|
+
{isLoading && <ReportSkeleton />}
|
|
82
|
+
{!isLoading && !isGenerated && (
|
|
83
|
+
<ReportPlaceholder reportName="MOH 267 register" isLocationChanged={rows !== null && hasLocationChanged} />
|
|
84
|
+
)}
|
|
85
|
+
{!isLoading && isGenerated && (
|
|
86
|
+
<div className={styles.reportFrame} ref={sheetsRef}>
|
|
87
|
+
<Moh267Register rows={rows} endDate={period.endDate} monthVisits={monthVisits} />
|
|
88
|
+
</div>
|
|
89
|
+
)}
|
|
90
|
+
</>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export default Moh267RegisterPage;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One PrEP visit in the MOH 267 PrEP Daily Activity Register (Ver. July 2023),
|
|
5
|
+
* column by column as on the form, as the ETL returns it (/moh-267-register):
|
|
6
|
+
* the same visits as MOH 731 1.3 to 1.5, one per client per day, with the
|
|
7
|
+
* form's codes as words.
|
|
8
|
+
*/
|
|
9
|
+
export interface Moh267Row {
|
|
10
|
+
patient_id?: number;
|
|
11
|
+
/** (a) */
|
|
12
|
+
prep_number?: string | null;
|
|
13
|
+
/** (b) */
|
|
14
|
+
date_of_visit?: string | null;
|
|
15
|
+
/** (c) upper */
|
|
16
|
+
id_number?: string | null;
|
|
17
|
+
/** (c) lower */
|
|
18
|
+
nupi?: string | null;
|
|
19
|
+
/** (d) */
|
|
20
|
+
age?: number | string | null;
|
|
21
|
+
/** (e) M or F */
|
|
22
|
+
sex?: string | null;
|
|
23
|
+
/** (f) General Population, Discordant Couple, MSM/MSW, FSW, PWID/PWUD or VP */
|
|
24
|
+
population_type?: string | null;
|
|
25
|
+
/** (g) New, Continuing, Discontinued or Restart */
|
|
26
|
+
prep_status?: string | null;
|
|
27
|
+
/** (h) Daily oral PrEP, Event driven oral PrEP, Dapivirine Vaginal ring, Cabotegravir Injectable (or Lenacapavir) */
|
|
28
|
+
prep_method?: string | null;
|
|
29
|
+
/** (i) Negative, Positive, Inconclusive or NA */
|
|
30
|
+
hiv_result?: string | null;
|
|
31
|
+
/** (j) Yes or No */
|
|
32
|
+
sti_diagnosed?: string | null;
|
|
33
|
+
/** (k) */
|
|
34
|
+
remarks?: string | null;
|
|
35
|
+
/** the PrEP start date, for the clients on PrEP at least 3 months */
|
|
36
|
+
prep_start_date?: string | null;
|
|
37
|
+
/** MOH 731 1.3: an Initial visit that is not a transfer-in */
|
|
38
|
+
is_new?: number | null;
|
|
39
|
+
/** MOH 731 1.5: a Follow-up visit with a positive HIV test */
|
|
40
|
+
is_seroconverted?: number | null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Blank rather than "null" / "undefined" in a cell */
|
|
44
|
+
export const text = (value: unknown) => (value === null || value === undefined ? '' : String(value));
|
|
45
|
+
|
|
46
|
+
/** DD/MM/YYYY, as the form asks */
|
|
47
|
+
export const formDate = (value: unknown) => (value ? dayjs(String(value)).format('DD/MM/YYYY') : '');
|