@ampath/esm-reports-app 1.0.0-next.55 → 1.0.0-next.57

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 (67) hide show
  1. package/dist/295.js +1 -1
  2. package/dist/410.js +1 -1
  3. package/dist/580.js +1 -0
  4. package/dist/580.js.map +1 -0
  5. package/dist/907.js +2 -1
  6. package/dist/907.js.map +1 -1
  7. package/dist/998.css +1 -0
  8. package/dist/998.css.map +1 -0
  9. package/dist/998.js +1 -0
  10. package/dist/998.js.map +1 -0
  11. package/dist/ampath-esm-reports-app.js +1 -1
  12. package/dist/routes.json +1 -1
  13. package/package.json +1 -1
  14. package/src/common/daily-summary-table.tsx +55 -0
  15. package/src/common/linelist-table/index.ts +3 -0
  16. package/src/common/linelist-table/linelist-columns.ts +48 -0
  17. package/src/common/linelist-table/linelist-table.component.tsx +442 -0
  18. package/src/common/linelist-table/linelist-table.scss +306 -0
  19. package/src/common/linelist-table/linelist-table.test.tsx +120 -0
  20. package/src/common/linelist-table/use-all-rows.ts +93 -0
  21. package/src/common/linelist-table/use-column-layout.ts +123 -0
  22. package/src/common/report-filters/report-filters.component.tsx +11 -5
  23. package/src/common/report-filters/report-filters.scss +63 -7
  24. package/src/common/report-page/use-page-scale.ts +27 -17
  25. package/src/common/report-placeholder/index.ts +1 -0
  26. package/src/common/report-placeholder/report-placeholder.component.tsx +57 -32
  27. package/src/common/report-placeholder/report-placeholder.scss +2 -0
  28. package/src/common/report-placeholder/use-generated-location.ts +62 -0
  29. package/src/common/report-register/index.ts +1 -0
  30. package/src/common/report-register/register-layout.component.tsx +26 -4
  31. package/src/common/report-register/register-layout.scss +10 -0
  32. package/src/common/report-register/use-location-name.ts +54 -0
  33. package/src/reports/moh-505/moh-505.component.tsx +9 -3
  34. package/src/reports/moh-705B/moh-204b-register.component.tsx +11 -2
  35. package/src/reports/moh-705B/moh-705b.component.tsx +533 -418
  36. package/src/reports/moh-705B/moh-705b.scss +44 -2
  37. package/src/reports/moh-705a/moh-705a.component.tsx +533 -421
  38. package/src/reports/moh-705a/moh-705a.scss +44 -2
  39. package/src/reports/moh-705a/registers/moh-204a-register.component.tsx +12 -3
  40. package/src/reports/moh-706/moh-706.component.tsx +9 -3
  41. package/src/reports/moh-710/moh-710.component.tsx +9 -3
  42. package/src/reports/moh-711/moh-711.component.tsx +9 -3
  43. package/src/reports/moh-717/moh-717.component.tsx +12 -3
  44. package/src/reports/moh-731/linelist/moh-731-indicators.ts +1040 -0
  45. package/src/reports/moh-731/linelist/moh-731-linelist-sections.ts +423 -0
  46. package/src/reports/moh-731/linelist/moh-731-linelist.component.tsx +102 -0
  47. package/src/reports/moh-731/linelist/use-open-moh-731-linelist.ts +50 -0
  48. package/src/reports/moh-731/moh-731.component.tsx +138 -85
  49. package/src/reports/moh-731/moh-731.scss +51 -4
  50. package/src/reports/moh-731/sections/hiv-and-tb-treatment.component.tsx +74 -77
  51. package/src/reports/moh-731/sections/hiv-testing-and-pre-exposure.component.tsx +84 -70
  52. package/src/reports/moh-731/sections/pmtct.component.tsx +43 -43
  53. package/src/reports/moh-731/summary/moh-731-summary.component.tsx +313 -0
  54. package/src/reports/moh-731/summary/moh-731-summary.config.ts +520 -0
  55. package/src/reports/moh-731/summary/moh-731-summary.scss +242 -0
  56. package/src/reports/moh-740/moh-740.component.scss +3 -1
  57. package/src/reports/moh-740/moh-740.component.tsx +14 -4
  58. package/src/reports/moh-745/moh-745.component.tsx +7 -3
  59. package/src/root.component.tsx +2 -0
  60. package/webpack.config.js +22 -1
  61. package/dist/427.js +0 -2
  62. package/dist/427.js.map +0 -1
  63. package/dist/441.js +0 -1
  64. package/dist/441.js.map +0 -1
  65. package/dist/907.css +0 -1
  66. package/dist/907.css.map +0 -1
  67. /package/dist/{427.js.LICENSE.txt → 907.js.LICENSE.txt} +0 -0
@@ -0,0 +1,242 @@
1
+ @use '@carbon/layout';
2
+ @use '@carbon/type';
3
+ @use '@openmrs/esm-styleguide/src/vars' as *;
4
+
5
+ /* The Summary tab: the report regrouped into compact tables with totals, a tab
6
+ * per section. Same light rules and panel fill as the rest of the report. */
7
+
8
+ .summary {
9
+ --summary-grid: #e2e2e2;
10
+ }
11
+
12
+ /* Section tabs, with the codes switch and the export on the same line */
13
+ .bar {
14
+ display: flex;
15
+ flex-wrap: wrap;
16
+ align-items: flex-end;
17
+ justify-content: space-between;
18
+ gap: layout.$spacing-03;
19
+ border-bottom: 1px solid $ui-03;
20
+ }
21
+
22
+ .sectionTabs {
23
+ flex: 0 1 auto;
24
+ width: auto;
25
+ min-width: 0;
26
+ margin-bottom: -1px;
27
+ }
28
+
29
+ .tools {
30
+ display: flex;
31
+ align-items: center;
32
+ gap: layout.$spacing-03;
33
+ padding-bottom: layout.$spacing-02;
34
+ }
35
+
36
+ .panel {
37
+ padding: layout.$spacing-04 0 0;
38
+ }
39
+
40
+ /* Headline totals: one slim line */
41
+ .strip {
42
+ display: flex;
43
+ flex-wrap: wrap;
44
+ gap: layout.$spacing-03;
45
+ margin-bottom: layout.$spacing-04;
46
+ }
47
+
48
+ .headline {
49
+ display: inline-flex;
50
+ align-items: baseline;
51
+ gap: layout.$spacing-03;
52
+ padding: layout.$spacing-02 layout.$spacing-04;
53
+ background-color: $ui-02;
54
+ border: 1px solid $ui-03;
55
+ cursor: pointer;
56
+
57
+ &:hover {
58
+ border-color: var(--cds-link-primary, #0f62fe);
59
+ }
60
+
61
+ &:focus-visible {
62
+ outline: 2px solid var(--cds-focus, #0f62fe);
63
+ outline-offset: -2px;
64
+ }
65
+ }
66
+
67
+ .headlineLabel {
68
+ @include type.type-style('label-01');
69
+ color: $text-02;
70
+ }
71
+
72
+ .headlineValue {
73
+ @include type.type-style('productive-heading-03');
74
+ color: $color-gray-100;
75
+ font-variant-numeric: tabular-nums;
76
+ }
77
+
78
+ /* Sub-sections side by side where there is room, one per row on a phone */
79
+ .grid {
80
+ display: grid;
81
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, 26rem), 1fr));
82
+ gap: layout.$spacing-04;
83
+ align-items: start;
84
+ }
85
+
86
+ .card {
87
+ padding: layout.$spacing-04;
88
+ background-color: $ui-02;
89
+ border: 1px solid $ui-03;
90
+ min-width: 0;
91
+ }
92
+
93
+ .cardTitle {
94
+ @include type.type-style('heading-compact-01');
95
+ margin-bottom: layout.$spacing-03;
96
+ color: $color-gray-100;
97
+ }
98
+
99
+ .note {
100
+ @include type.type-style('helper-text-01');
101
+ margin: -(layout.$spacing-02) 0 layout.$spacing-03;
102
+ color: $text-02;
103
+ }
104
+
105
+ .tableTitle {
106
+ @include type.type-style('label-01');
107
+ margin: layout.$spacing-04 0 layout.$spacing-02;
108
+ color: $text-02;
109
+ }
110
+
111
+ .tableScroll {
112
+ overflow-x: auto;
113
+ }
114
+
115
+ .table {
116
+ width: 100%;
117
+ border-collapse: collapse;
118
+ font-size: 0.8125rem;
119
+ line-height: 1.2;
120
+ font-variant-numeric: tabular-nums;
121
+
122
+ th,
123
+ td {
124
+ padding: 0.3125rem 0.5rem;
125
+ text-align: right;
126
+ white-space: nowrap;
127
+ border-bottom: 1px solid var(--summary-grid);
128
+ }
129
+
130
+ thead th {
131
+ padding-top: 0.25rem;
132
+ padding-bottom: 0.25rem;
133
+ font-size: 0.75rem;
134
+ font-weight: 600;
135
+ color: $text-02;
136
+ background-color: var(--cds-layer-01, #f4f4f4);
137
+ }
138
+
139
+ tbody tr:hover td,
140
+ tbody tr:hover th {
141
+ background-color: $brand-primary-10;
142
+ }
143
+
144
+ /* Total row: bold, set off by a double rule */
145
+ tfoot th,
146
+ tfoot td {
147
+ font-weight: 600;
148
+ border-top: 3px double #b8b8b8;
149
+ border-bottom: none;
150
+ }
151
+ }
152
+
153
+ /* The row labels stay in view when a wide table scrolls sideways */
154
+ .labelCol {
155
+ position: sticky;
156
+ left: 0;
157
+ width: 1%;
158
+ text-align: left !important;
159
+ font-weight: 400;
160
+ color: $color-gray-100;
161
+ background-color: $ui-02;
162
+ }
163
+
164
+ thead .labelCol {
165
+ background-color: var(--cds-layer-01, #f4f4f4);
166
+ }
167
+
168
+ .totalCol {
169
+ font-weight: 600;
170
+ background-color: var(--cds-layer-01, #f4f4f4);
171
+ }
172
+
173
+ /* A table with no breakdown: the labels take the width, the figures a narrow column */
174
+ .single .labelCol {
175
+ width: auto;
176
+ }
177
+
178
+ .single .totalCol {
179
+ width: 6rem;
180
+ }
181
+
182
+ .group {
183
+ color: $text-02;
184
+ }
185
+
186
+ /* Rows shown for reference, never added into the total */
187
+ .ofWhich .labelCol {
188
+ padding-left: layout.$spacing-05;
189
+ font-style: italic;
190
+ }
191
+
192
+ .excluded .labelCol {
193
+ color: $text-02;
194
+ }
195
+
196
+ /* A figure: its value, opening its linelist; its MOH code when codes are shown */
197
+ .value {
198
+ display: inline-flex;
199
+ align-items: baseline;
200
+ gap: layout.$spacing-02;
201
+ padding: 0;
202
+ font: inherit;
203
+ font-weight: inherit;
204
+ color: var(--cds-link-primary, #0f62fe);
205
+ background: none;
206
+ border: none;
207
+ cursor: pointer;
208
+
209
+ &:hover {
210
+ text-decoration: underline;
211
+ }
212
+
213
+ &:focus-visible {
214
+ outline: 2px solid var(--cds-focus, #0f62fe);
215
+ outline-offset: 2px;
216
+ }
217
+ }
218
+
219
+ .zero {
220
+ color: $text-02;
221
+ }
222
+
223
+ .strong {
224
+ font-weight: 600;
225
+ }
226
+
227
+ .code {
228
+ font-size: 0.6875rem;
229
+ font-weight: 400;
230
+ color: $text-02;
231
+ }
232
+
233
+ .none {
234
+ color: $text-02;
235
+ }
236
+
237
+ @media (max-width: $breakpoint-phone-max) {
238
+ .tools {
239
+ width: 100%;
240
+ justify-content: space-between;
241
+ }
242
+ }
@@ -17,7 +17,9 @@ $meta: 6.5pt; // facility strip
17
17
  display: flex;
18
18
  flex-direction: column;
19
19
  width: 100%;
20
- row-gap: 0.5rem;
20
+ /* No gap of its own: the placeholder carries the spacing below the filters,
21
+ as on every other report, and a gap here doubled it. */
22
+ row-gap: 0;
21
23
  padding: 0.75rem 0;
22
24
  }
23
25
 
@@ -3,7 +3,7 @@ import styles from './moh-740.component.scss';
3
3
  import { ReportFiltersComponent, type ReportPeriod, useRestorePeriod } from '../../common/report-filters';
4
4
  import { ReportSkeleton } from '../../common/report-skeleton';
5
5
  import { ReportPage } from '../../common/report-page';
6
- import { ReportPlaceholder } from '../../common/report-placeholder';
6
+ import { ReportPlaceholder, useGeneratedLocation } from '../../common/report-placeholder';
7
7
  import { showReportError } from '../../common/report-error';
8
8
  import { type Moh740Data, type Moh740Dto } from './types';
9
9
  import { formatDate, useSession } from '@openmrs/esm-framework';
@@ -30,6 +30,11 @@ const Moh740Report: React.FC<Moh740ReportProps> = () => {
30
30
  const session = useSession();
31
31
  const locationUuid = session.sessionLocation?.uuid;
32
32
 
33
+ /* Only a report for the current location counts: after switching location the
34
+ old figures would otherwise be shown, and labelled, as the new location's. */
35
+ const { isForCurrentLocation, hasLocationChanged, markGenerated } = useGeneratedLocation();
36
+ const isReportGenerated = Boolean(moh740Data) && isForCurrentLocation;
37
+
33
38
  /* The masthead names the location the report was generated from, and the
34
39
  period it covers; the sign-off records who produced it and when. */
35
40
  const facility = session?.sessionLocation?.display ?? moh740Data?.facility ?? '';
@@ -46,6 +51,7 @@ const Moh740Report: React.FC<Moh740ReportProps> = () => {
46
51
  const resp = await fetchMoh740Report(reportFilters);
47
52
  setMoh740Data(resp ?? null);
48
53
  setHasGenerated(true);
54
+ markGenerated(reportFilters.locationUuid);
49
55
  } catch (error: any) {
50
56
  showReportError('the MOH-740 report', error);
51
57
  } finally {
@@ -78,7 +84,7 @@ const Moh740Report: React.FC<Moh740ReportProps> = () => {
78
84
  mode="both"
79
85
  onGenerate={getMoh740ReportData}
80
86
  isLoading={isLoading}
81
- isReportGenerated={Boolean(moh740Data)}
87
+ isReportGenerated={isReportGenerated}
82
88
  onPeriodChange={setSelectedPeriod}
83
89
  />
84
90
  </div>
@@ -88,7 +94,7 @@ const Moh740Report: React.FC<Moh740ReportProps> = () => {
88
94
  <ReportSkeleton blocks={3} />
89
95
  ) : (
90
96
  <>
91
- {moh740Data ? (
97
+ {isReportGenerated ? (
92
98
  <ReportPage>
93
99
  <div className={styles.headerContainer}>
94
100
  <div className={styles.mainTitleBox}>
@@ -1275,7 +1281,11 @@ const Moh740Report: React.FC<Moh740ReportProps> = () => {
1275
1281
  </div>
1276
1282
  </ReportPage>
1277
1283
  ) : (
1278
- <ReportPlaceholder reportName="MOH-740" isEmptyResult={hasGenerated} />
1284
+ <ReportPlaceholder
1285
+ reportName="MOH-740"
1286
+ isEmptyResult={hasGenerated && isForCurrentLocation}
1287
+ isLocationChanged={hasGenerated && hasLocationChanged}
1288
+ />
1279
1289
  )}
1280
1290
  </>
1281
1291
  )}
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import { ReportFiltersComponent, type ReportPeriod, useRestorePeriod } from '../../common/report-filters';
3
3
  import { showReportError } from '../../common/report-error';
4
- import { hasReportData, ReportPlaceholder } from '../../common/report-placeholder';
4
+ import { hasReportData, ReportPlaceholder, useGeneratedLocation } from '../../common/report-placeholder';
5
5
 
6
6
  import styles from './moh-745.scss';
7
7
  import classNames from 'classnames';
@@ -15,7 +15,10 @@ import { type CancerScreeningResult } from './registers/type';
15
15
 
16
16
  const Moh745Component: React.FC = () => {
17
17
  const [moh745Data, setMoh745Data] = useState<CancerScreeningResult | null>(null);
18
- const isReportGenerated = hasReportData(moh745Data);
18
+ /* Only a report for the current location counts: after switching location the
19
+ old figures would otherwise be shown, and labelled, as the new location's. */
20
+ const { isForCurrentLocation, hasLocationChanged, markGenerated } = useGeneratedLocation();
21
+ const isReportGenerated = hasReportData(moh745Data) && isForCurrentLocation;
19
22
  const [isLoading, setIsLoading] = useState<boolean>(false);
20
23
  const [startDate, setStartDate] = useState<string>('');
21
24
  const [endDate, setEndDate] = useState<string>('');
@@ -47,6 +50,7 @@ const Moh745Component: React.FC = () => {
47
50
  const data = await getMoh745(params);
48
51
  if(data){
49
52
  setMoh745Data(data);
53
+ markGenerated(params.locationUuids);
50
54
  }else{
51
55
  setMoh745Data(null);
52
56
  }
@@ -78,7 +82,7 @@ const Moh745Component: React.FC = () => {
78
82
  generatedPeriod={{ startDate, endDate }}
79
83
  />
80
84
  {isLoading && <ReportSkeleton />}
81
- {!isLoading && !isReportGenerated && <ReportPlaceholder reportName="MOH-745" />}
85
+ {!isLoading && !isReportGenerated && <ReportPlaceholder reportName="MOH-745" isLocationChanged={hasReportData(moh745Data) && hasLocationChanged} />}
82
86
  {!isLoading && isReportGenerated && (
83
87
  <ReportPage>
84
88
  <h3 className={styles.reportTitle}>CANCER SCREENING MONTHLY SUMMARY FORM</h3>
@@ -23,6 +23,7 @@ import Moh511710Register from './reports/moh-710/registers/moh-511-710-register.
23
23
  import Moh731Report from './reports/moh-731/moh-731.component';
24
24
  import Moh366Register from './reports/moh-731/registers/moh-366.component';
25
25
  import PrepRegisterComponent from './reports/moh-731/registers/prep-register.component';
26
+ import Moh731Linelist from './reports/moh-731/linelist/moh-731-linelist.component';
26
27
  import styles from './root.scss';
27
28
 
28
29
  const RootComponent: React.FC = () => {
@@ -53,6 +54,7 @@ const RootComponent: React.FC = () => {
53
54
  <Route path="/moh-510-register" element={<Moh510Register />} />
54
55
  <Route path="/moh-511-710-register" element={<Moh511710Register />} />
55
56
  <Route path="/moh-731" element={<Moh731Report />} />
57
+ <Route path="/moh-731-linelist" element={<Moh731Linelist />} />
56
58
  <Route path="/moh-366-register" element={<Moh366Register />} />
57
59
  <Route path="/prep-register" element={<PrepRegisterComponent />} />
58
60
  </Routes>
package/webpack.config.js CHANGED
@@ -1 +1,22 @@
1
- module.exports = require('openmrs/default-webpack-config');
1
+ const path = require('path');
2
+ const config = (module.exports = require('openmrs/default-webpack-config'));
3
+ config.watchConfig.ignored = ['.git', 'test-results', `${path.resolve(__dirname, 'dist')}/**`];
4
+ config.overrides.resolve = {
5
+ fallback: {
6
+ crypto: false,
7
+ stream: false,
8
+ os: false,
9
+ path: false,
10
+ zlib: false,
11
+ https: false,
12
+ http: false,
13
+ util: false,
14
+ url: false,
15
+ },
16
+ extensions: ['.tsx', '.ts', '.jsx', '.js', '.scss'],
17
+ alias: {
18
+ '@openmrs/esm-framework': '@openmrs/esm-framework/src/internal',
19
+ },
20
+ };
21
+
22
+ module.exports = config;