@ampath/esm-reports-app 1.0.0-next.76 → 1.0.0-next.78

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.
@@ -0,0 +1,157 @@
1
+ import React, { useState } from 'react';
2
+ import { RegisterLayout, usePatientList } from '../../../common/report-register';
3
+ import { useLocation, useSearchParams } from 'react-router-dom';
4
+ import classNames from 'classnames';
5
+ import { useSession } from '@openmrs/esm-framework';
6
+
7
+ import styles from './moh-407.scss';
8
+ import { Moh407xportColumns } from './moh-407.columns';
9
+ import { getMoh407PatientList } from '../../../resources/moh-711.resource';
10
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@carbon/react';
11
+ import { ReportFiltersComponent, type ReportPeriod } from '../../../common/report-filters';
12
+
13
+ interface Moh407RegisterComponentProps {}
14
+
15
+ const Moh407RegisterComponent: React.FC<Moh407RegisterComponentProps> = () => {
16
+ const [searchParams, setSearchParams] = useSearchParams();
17
+ const location = useLocation();
18
+ const session = useSession();
19
+
20
+ const from = searchParams.get('from');
21
+ const isDrilldown = Boolean(from);
22
+ const [generatedPeriod, setGeneratedPeriod] = useState<{ startDate: string; endDate: string } | null>(() => {
23
+ const startDate = searchParams.get('startDate');
24
+ const endDate = searchParams.get('endDate');
25
+ return !isDrilldown && startDate && endDate ? { startDate, endDate } : null;
26
+ });
27
+ const isGenerated = isDrilldown || Boolean(generatedPeriod);
28
+
29
+ const startDate = generatedPeriod?.startDate ?? searchParams.get('startDate');
30
+ const endDate = generatedPeriod?.endDate ?? searchParams.get('endDate');
31
+ const locationUuids = searchParams.get('locationUuids') ?? session?.sessionLocation?.uuid ?? '';
32
+ const indicator = searchParams.get('indicator');
33
+ const reportName = location.state?.reportName || 'moh711Report';
34
+
35
+ const {
36
+ rows: patientlist,
37
+ total,
38
+ isTotalExact,
39
+ isLoading,
40
+ page,
41
+ pageSize,
42
+ onPageChange,
43
+ fetchAll,
44
+ } = usePatientList(
45
+ ({ startIndex, limit }) => {
46
+ if (!isDrilldown && !generatedPeriod) {
47
+ return Promise.resolve({ results: [], total: 0, isTotalExact: true });
48
+ }
49
+
50
+ return getMoh407PatientList({
51
+ startDate,
52
+ endDate,
53
+ locationUuids,
54
+ indicator,
55
+ reportName,
56
+ startIndex,
57
+ limit,
58
+ from,
59
+ });
60
+ },
61
+ [startDate, endDate, locationUuids, indicator, reportName, from, isDrilldown, generatedPeriod],
62
+ );
63
+
64
+ const generate = ({ startDate, endDate }: ReportPeriod) => {
65
+ setGeneratedPeriod({ startDate, endDate });
66
+ setSearchParams((currentParams) => {
67
+ const nextParams = new URLSearchParams(currentParams);
68
+ nextParams.set('startDate', startDate);
69
+ nextParams.set('endDate', endDate);
70
+ if (!nextParams.has('locationUuids') && locationUuids) {
71
+ nextParams.set('locationUuids', locationUuids);
72
+ }
73
+ return nextParams;
74
+ });
75
+ };
76
+
77
+ return (
78
+ <>
79
+ {!isDrilldown && (
80
+ <ReportFiltersComponent
81
+ reportName="MOH 407 Register"
82
+ mode="range"
83
+ onGenerate={generate}
84
+ isLoading={isLoading}
85
+ isReportGenerated={Boolean(generatedPeriod)}
86
+ generatedPeriod={generatedPeriod ?? undefined}
87
+ backLink={{ label: 'All registers', to: '/?tab=registers' }}
88
+ />
89
+ )}
90
+ <RegisterLayout
91
+ parentLabel={isDrilldown ? 'MOH-711 Report' : 'All registers'}
92
+ parentPath={isDrilldown ? '/moh-711' : '/?tab=registers'}
93
+ title="MOH 407 Register"
94
+ isLoading={isLoading}
95
+ isEmpty={isGenerated && patientlist.length === 0}
96
+ page={page}
97
+ pageSize={pageSize}
98
+ total={total}
99
+ isTotalExact={isTotalExact}
100
+ onPageChange={onPageChange}
101
+ fetchAll={isGenerated ? fetchAll : undefined}
102
+ columns={Moh407xportColumns}
103
+ >
104
+ {isGenerated && (
105
+ <div className={styles.tableContainer}>
106
+ <Table className={classNames(`${styles.table}`, `${styles.tableBordered}`, `${styles.tableStriped}`)}>
107
+ <TableHead>
108
+ <TableRow>
109
+ <TableHeader aria-rowspan={2}>Serial Number</TableHeader>
110
+ <TableHeader aria-rowspan={2}>Date</TableHeader>
111
+ <TableHeader aria-rowspan={2}>National Identification Number</TableHeader>
112
+ <TableHeader aria-rowspan={2}>Patient Names</TableHeader>
113
+ <TableHeader aria-rowspan={2}>Patient Visit</TableHeader>
114
+ <TableHeader aria-rowspan={2}>Residence</TableHeader>
115
+ <TableHeader aria-rowspan={2}>Sex</TableHeader>
116
+ <TableHeader colSpan={2}>Age</TableHeader>
117
+ <TableHeader aria-rowspan={2}>Pregnant or Breastfeeding</TableHeader>
118
+ <TableHeader>Nutritional Assessment</TableHeader>
119
+ <TableHeader aria-rowspan={2}>Nutrition Status</TableHeader>
120
+ <TableHeader aria-rowspan={2}>Serostatus</TableHeader>
121
+ <TableHeader aria-rowspan={2}>Medical Condition</TableHeader>
122
+ <TableHeader aria-rowspan={2}>Food Secure</TableHeader>
123
+ <TableHeader aria-rowspan={2}>Nutrition Intervention</TableHeader>
124
+ <TableHeader aria-rowspan={2}>Remarks</TableHeader>
125
+ </TableRow>
126
+ <TableRow>
127
+ <TableHeader>Years</TableHeader>
128
+ <TableHeader>Months</TableHeader>
129
+ <TableHeader>Figure for z score</TableHeader>
130
+ </TableRow>
131
+ </TableHead>
132
+ <TableBody>
133
+ {patientlist.length > 0 ? (
134
+ patientlist.map((patient, index) => (
135
+ <TableRow key={patient.person_id || patient.id || index}>
136
+ {Moh407xportColumns.map((column, columnIndex) => (
137
+ <TableCell key={`${column.header}-${columnIndex}`}>
138
+ {String(column.value(patient, (page - 1) * pageSize + index) ?? '')}
139
+ </TableCell>
140
+ ))}
141
+ </TableRow>
142
+ ))
143
+ ) : (
144
+ <TableRow>
145
+ <TableCell colSpan={Moh407xportColumns.length}>No data available</TableCell>
146
+ </TableRow>
147
+ )}
148
+ </TableBody>
149
+ </Table>
150
+ </div>
151
+ )}
152
+ </RegisterLayout>
153
+ </>
154
+ );
155
+ };
156
+
157
+ export default Moh407RegisterComponent;
@@ -0,0 +1,24 @@
1
+ import { type RegisterColumn } from '../../../common/report-register/register-columns';
2
+
3
+ /**
4
+ * MOH 407 columns, flattened from the register's two-row table header.
5
+ */
6
+ export const Moh407xportColumns: RegisterColumn[] = [
7
+ { header: 'Serial Number', value: (_row, index) => index + 1 },
8
+ { header: 'Date', value: (row) => row.date ?? '' },
9
+ { header: 'National Identification Number', value: (row) => row.national_identification_number ?? '' },
10
+ { header: 'Patient Names', value: (row) => row.patient_names ?? '' },
11
+ { header: 'Patient Visit', value: (row) => row.patient_visit ?? '' },
12
+ { header: 'Residence', value: (row) => row.residence ?? '' },
13
+ { header: 'Sex', value: (row) => row.sex ?? '' },
14
+ { header: 'Age - Years', value: (row) => row.age_years ?? '' },
15
+ { header: 'Age - Months', value: (row) => row.age_months ?? '' },
16
+ { header: 'Pregnant or Breastfeeding', value: (row) => row.pregnant_or_breastfeeding ?? '' },
17
+ { header: 'Nutritional Assessment - Figure for z score', value: (row) => row.z_score ?? '' },
18
+ { header: 'Nutrition Status', value: (row) => row.nutrition_status ?? '' },
19
+ { header: 'Serostatus', value: (row) => row.serostatus ?? '' },
20
+ { header: 'Medical Condition', value: (row) => row.medical_condition ?? '' },
21
+ { header: 'Food Secure', value: (row) => row.food_secure ?? '' },
22
+ { header: 'Nutrition Intervention', value: (row) => row.nutrition_intervention ?? '' },
23
+ { header: 'Remarks', value: (row) => row.remarks ?? '' },
24
+ ];
@@ -0,0 +1,64 @@
1
+ @use '@openmrs/esm-styleguide/src/vars' as *;
2
+
3
+
4
+ .tableContainer {
5
+ width: 100%;
6
+ }
7
+
8
+ /* Sized to content rather than to the frame, so a long value -- a full name,
9
+ say -- widens its own column instead of wrapping. `.tableScroll` in the
10
+ layout scrolls when the table outgrows the page. */
11
+
12
+ .table {
13
+ width: auto;
14
+ min-width: 100%;
15
+ margin: 0;
16
+ font-size: 0.75rem;
17
+ border-collapse: collapse;
18
+ }
19
+
20
+ .tableBordered td,
21
+ .tableBordered th {
22
+ padding: 0.125rem 0.5rem;
23
+ font-size: 0.75rem;
24
+ line-height: 1.3;
25
+ border: 1px solid $ui-04;
26
+ }
27
+
28
+ .tableBordered th {
29
+ font-weight: 600;
30
+ color: $color-gray-100;
31
+ background-color: $ui-01;
32
+ /* headings carry deliberate line breaks, so they wrap where the markup says */
33
+ white-space: normal;
34
+ }
35
+
36
+ .tableBordered td {
37
+ white-space: nowrap;
38
+ }
39
+
40
+ /* Long prose columns (diagnoses, referrals, comments) wrap inside a bounded
41
+ width instead of stretching the row past the fold. */
42
+ .tableBordered td.wrapCell {
43
+ white-space: normal;
44
+ min-width: 8rem;
45
+ max-width: 16rem;
46
+ overflow-wrap: anywhere;
47
+ }
48
+
49
+ .tableStriped tbody tr:nth-of-type(odd) {
50
+ background-color: $ui-01;
51
+ }
52
+
53
+ .tableStriped tbody tr:hover {
54
+ background-color: $brand-primary-10;
55
+ }
56
+
57
+ .textCentre {
58
+ text-align: center;
59
+ }
60
+
61
+ .verticalText {
62
+ writing-mode: vertical-rl;
63
+ transform: rotate(180deg);
64
+ }
@@ -1,22 +1,35 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { useLocation, useSearchParams } from 'react-router-dom';
3
3
  import { RegisterLayout, usePatientList } from '../../../common/report-register';
4
4
  import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@carbon/react';
5
5
  import classNames from 'classnames';
6
+ import dayjs from 'dayjs';
7
+ import { useSession } from '@openmrs/esm-framework';
6
8
 
7
9
  import styles from './moh-512.scss';
8
10
  import { moh512ExportColumns } from './moh-512-columns';
9
11
  import { getMoh512PatientList } from '../../../resources/moh-711.resource';
12
+ import { ReportFiltersComponent, type ReportPeriod } from '../../../common/report-filters';
10
13
 
11
14
  interface Moh512RegisterComponentProps {}
12
15
 
13
16
  const Moh512RegisterComponent: React.FC<Moh512RegisterComponentProps> = () => {
14
- const [searchParams] = useSearchParams();
17
+ const [searchParams, setSearchParams] = useSearchParams();
15
18
  const location = useLocation();
19
+ const session = useSession();
16
20
 
17
- const startDate = searchParams.get('startDate');
18
- const endDate = searchParams.get('endDate');
19
- const locationUuids = searchParams.get('locationUuids');
21
+ const from = searchParams.get('from');
22
+ const isDrilldown = Boolean(from);
23
+ const [generatedPeriod, setGeneratedPeriod] = useState<{ startDate: string; endDate: string } | null>(() => {
24
+ const startDate = searchParams.get('startDate');
25
+ const endDate = searchParams.get('endDate');
26
+ return !isDrilldown && startDate && endDate ? { startDate, endDate } : null;
27
+ });
28
+ const isGenerated = isDrilldown || Boolean(generatedPeriod);
29
+
30
+ const startDate = generatedPeriod?.startDate ?? searchParams.get('startDate');
31
+ const endDate = generatedPeriod?.endDate ?? searchParams.get('endDate');
32
+ const locationUuids = searchParams.get('locationUuids') ?? session?.sessionLocation?.uuid ?? '';
20
33
  const indicator = searchParams.get('indicator');
21
34
  const reportName = location.state?.reportName || '';
22
35
 
@@ -30,8 +43,12 @@ const Moh512RegisterComponent: React.FC<Moh512RegisterComponentProps> = () => {
30
43
  onPageChange,
31
44
  fetchAll,
32
45
  } = usePatientList(
33
- ({ startIndex, limit }) =>
34
- getMoh512PatientList({
46
+ ({ startIndex, limit }) => {
47
+ if (!isDrilldown && !generatedPeriod) {
48
+ return Promise.resolve({ results: [], total: 0, isTotalExact: true });
49
+ }
50
+
51
+ return getMoh512PatientList({
35
52
  startDate,
36
53
  endDate,
37
54
  locationUuids,
@@ -39,10 +56,24 @@ const Moh512RegisterComponent: React.FC<Moh512RegisterComponentProps> = () => {
39
56
  reportName,
40
57
  startIndex,
41
58
  limit,
42
- }),
43
- [startDate, endDate, locationUuids, indicator, reportName],
59
+ });
60
+ },
61
+ [startDate, endDate, locationUuids, indicator, reportName, isDrilldown, generatedPeriod],
44
62
  );
45
63
 
64
+ const generate = ({ startDate, endDate }: ReportPeriod) => {
65
+ setGeneratedPeriod({ startDate, endDate });
66
+ setSearchParams((currentParams) => {
67
+ const nextParams = new URLSearchParams(currentParams);
68
+ nextParams.set('startDate', startDate);
69
+ nextParams.set('endDate', endDate);
70
+ if (!nextParams.has('locationUuids') && locationUuids) {
71
+ nextParams.set('locationUuids', locationUuids);
72
+ }
73
+ return nextParams;
74
+ });
75
+ };
76
+
46
77
  const columns = [
47
78
  { key: 'date', label: 'Date' },
48
79
  { key: 'cr_id', label: 'Client Number' },
@@ -89,52 +120,71 @@ const Moh512RegisterComponent: React.FC<Moh512RegisterComponentProps> = () => {
89
120
  ];
90
121
 
91
122
  return (
92
- <RegisterLayout
93
- parentLabel="MOH-711 Report"
94
- parentPath="/moh-711"
95
- title="MOH 512 Register"
96
- isLoading={isLoading}
97
- isEmpty={patientlist.length === 0}
98
- page={page}
99
- pageSize={pageSize}
100
- total={total}
101
- isTotalExact={isTotalExact}
102
- onPageChange={onPageChange}
103
- fetchAll={fetchAll}
104
- columns={moh512ExportColumns}
105
- >
106
- <div className={styles.tableContainer}>
107
- <Table className={classNames(styles.table, styles.tableBordered, styles.tableStriped)}>
108
- <TableHead>
109
- <TableRow>
110
- {columns.map((column) => (
111
- <TableHeader key={column.key}>{column.label}</TableHeader>
112
- ))}
113
- </TableRow>
114
- </TableHead>
115
-
116
- <TableBody>
117
- {isLoading ? (
118
- <TableRow>
119
- <TableCell colSpan={columns.length}>Loading register...</TableCell>
120
- </TableRow>
121
- ) : patientlist.length === 0 ? (
122
- <TableRow>
123
- <TableCell colSpan={columns.length}>No records found.</TableCell>
124
- </TableRow>
125
- ) : (
126
- patientlist.map((patient, index) => (
127
- <TableRow key={patient.person_id || patient.id || index}>
123
+ <>
124
+ {!isDrilldown && (
125
+ <ReportFiltersComponent
126
+ reportName="MOH 512 Register"
127
+ mode="range"
128
+ onGenerate={generate}
129
+ isLoading={isLoading}
130
+ isReportGenerated={Boolean(generatedPeriod)}
131
+ generatedPeriod={generatedPeriod ?? undefined}
132
+ backLink={{ label: 'All registers', to: '/?tab=registers' }}
133
+ />
134
+ )}
135
+ <RegisterLayout
136
+ parentLabel={isDrilldown ? 'MOH-711 Report' : 'All registers'}
137
+ parentPath={isDrilldown ? '/moh-711' : '/?tab=registers'}
138
+ title="MOH 512 Register"
139
+ isLoading={isLoading}
140
+ isEmpty={isGenerated && patientlist.length === 0}
141
+ page={page}
142
+ pageSize={pageSize}
143
+ total={total}
144
+ isTotalExact={isTotalExact}
145
+ onPageChange={onPageChange}
146
+ fetchAll={isGenerated ? fetchAll : undefined}
147
+ columns={moh512ExportColumns}
148
+ >
149
+ {isGenerated && (
150
+ <div className={styles.tableContainer}>
151
+ <Table className={classNames(styles.table, styles.tableBordered, styles.tableStriped)}>
152
+ <TableHead>
153
+ <TableRow>
128
154
  {columns.map((column) => (
129
- <TableCell key={column.key}>{patient[column.key] ?? ''}</TableCell>
155
+ <TableHeader key={column.key}>{column.label}</TableHeader>
130
156
  ))}
131
157
  </TableRow>
132
- ))
133
- )}
134
- </TableBody>
135
- </Table>
136
- </div>
137
- </RegisterLayout>
158
+ </TableHead>
159
+
160
+ <TableBody>
161
+ {isLoading ? (
162
+ <TableRow>
163
+ <TableCell colSpan={columns.length}>Loading register...</TableCell>
164
+ </TableRow>
165
+ ) : patientlist.length === 0 ? (
166
+ <TableRow>
167
+ <TableCell colSpan={columns.length}>No records found.</TableCell>
168
+ </TableRow>
169
+ ) : (
170
+ patientlist.map((patient, index) => (
171
+ <TableRow key={patient.person_id || patient.id || index}>
172
+ {columns.map((column) => (
173
+ <TableCell key={column.key}>
174
+ {column.key === 'date' && patient[column.key]
175
+ ? dayjs(patient[column.key]).format('YYYY-MM-DD')
176
+ : (patient[column.key] ?? '')}
177
+ </TableCell>
178
+ ))}
179
+ </TableRow>
180
+ ))
181
+ )}
182
+ </TableBody>
183
+ </Table>
184
+ </div>
185
+ )}
186
+ </RegisterLayout>
187
+ </>
138
188
  );
139
189
  };
140
190
 
@@ -3,6 +3,7 @@ import { useSearchParams } from 'react-router-dom';
3
3
  import { RegisterLayout, usePatientList } from '../../../common/report-register';
4
4
  import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@carbon/react';
5
5
  import classNames from 'classnames';
6
+ import dayjs from 'dayjs';
6
7
 
7
8
  import styles from './tb-register.scss';
8
9
  import { TBExportColumns } from './tb-register-columns';
@@ -70,9 +71,11 @@ const TbRegisterComponent: React.FC<TbRegisterComponentProps> = () => {
70
71
  {patientlist?.length > 0 ? (
71
72
  patientlist?.map((patient, i) => (
72
73
  <TableRow key={patient.person_id || patient.id}>
73
- <TableCell>{patient.date}</TableCell>
74
+ <TableCell>{patient.date ? dayjs(patient.date).format('YYYY-MM-DD') : ''}</TableCell>
74
75
  <TableCell>{patient.cr_id}</TableCell>
75
- <TableCell>{patient.date_of_birth}</TableCell>
76
+ <TableCell>
77
+ {patient.date_of_birth ? dayjs(patient.date_of_birth).format('YYYY-MM-DD') : ''}
78
+ </TableCell>
76
79
  <TableCell>{patient.gender}</TableCell>
77
80
  <TableCell>{patient.tb_screening}</TableCell>
78
81
  <TableCell>{patient.rtc}</TableCell>
@@ -1,15 +1,38 @@
1
1
  import React from 'react';
2
+ import { Button } from '@carbon/react';
3
+ import { useNavigate } from 'react-router-dom';
2
4
 
3
5
  import styles from '../moh711.scss';
4
6
  import classNames from 'classnames';
5
7
 
6
8
  interface ChanisComponentProps {
7
9
  moh711Data: any;
10
+ startDate: string;
11
+ endDate: string;
12
+ locationUuids: string;
8
13
  }
9
14
 
10
- const ChanisComponent: React.FC<ChanisComponentProps> = ({ moh711Data }) => {
15
+ const ChanisComponent: React.FC<ChanisComponentProps> = ({ moh711Data, startDate, endDate, locationUuids }) => {
16
+ const navigate = useNavigate();
17
+
18
+ const openRegister = () => {
19
+ const params = new URLSearchParams({
20
+ startDate,
21
+ endDate,
22
+ locationUuids,
23
+ from: 'moh-711',
24
+ });
25
+
26
+ navigate(`/moh-407-register?${params}`, {
27
+ state: { from: '/moh-711', reportName: 'moh711Report' },
28
+ });
29
+ };
30
+
11
31
  return (
12
32
  <div className={styles.section}>
33
+ <Button kind="ghost" size="sm" onClick={openRegister}>
34
+ Open MOH 407 Register
35
+ </Button>
13
36
  <table className={classNames(`${styles.table}`, `${styles.tableBordered}`, `${styles.tableStriped}`)}>
14
37
  <thead>
15
38
  <tr>
@@ -39,8 +39,8 @@ export async function getMoh711(params: Moh711Params): Promise<any> {
39
39
 
40
40
  export async function getMoh406PatientList(params: PatientListParams): Promise<PatientListPage> {
41
41
  const endPoint = (() => {
42
- if (params.from && params.from?.toLowerCase() === "moh-717") {
43
- return "moh-717-patient-list";
42
+ if (params.from && params.from?.toLowerCase() === 'moh-717') {
43
+ return 'moh-717-patient-list';
44
44
  }
45
45
  return 'moh-406-patient-list';
46
46
  })();
@@ -70,8 +70,8 @@ export async function getMoh406PatientList(params: PatientListParams): Promise<P
70
70
 
71
71
  export async function getMoh405PatientList(params: PatientListParams): Promise<PatientListPage> {
72
72
  const endPoint = (() => {
73
- if (params.from && params.from?.toLowerCase() === "moh-717") {
74
- return "moh-717-patient-list";
73
+ if (params.from && params.from?.toLowerCase() === 'moh-717') {
74
+ return 'moh-717-patient-list';
75
75
  }
76
76
  return 'moh-405-patient-list';
77
77
  })();
@@ -101,8 +101,8 @@ export async function getMoh405PatientList(params: PatientListParams): Promise<P
101
101
 
102
102
  export async function getMoh333PatientList(params: PatientListParams): Promise<PatientListPage> {
103
103
  const endPoint = (() => {
104
- if (params.from && params.from?.toLowerCase() === "moh-717") {
105
- return "moh-717-patient-list";
104
+ if (params.from && params.from?.toLowerCase() === 'moh-717') {
105
+ return 'moh-717-patient-list';
106
106
  }
107
107
  return 'moh-333-patient-list';
108
108
  })();
@@ -130,31 +130,6 @@ export async function getMoh333PatientList(params: PatientListParams): Promise<P
130
130
  }
131
131
  }
132
132
 
133
- // export async function getMoh510PatientList(params: PatientListParams): Promise<PatientListPage> {
134
- // const url = await buildEtlUrl('moh-510-patient-list', {
135
- // locationUuids: params.locationUuids || '',
136
- // startDate: params.startDate || '',
137
- // endDate: params.endDate || '',
138
- // indicator: Array.isArray(params.indicator) ? params.indicator.join(',') : params.indicator || '',
139
- // ...pageParams(params),
140
- // reportName: params.reportName || '',
141
- // });
142
- // try {
143
- // const response = await openmrsFetch(url);
144
-
145
- // if (!response.ok) {
146
- // const errorText = await response.text();
147
- // throw new Error(`Failed to fetch patient list: ${response.status} - ${errorText}`);
148
- // }
149
-
150
- // const data = await response.json();
151
-
152
- // return toPatientListPage(data, params.startIndex ?? 0, params.limit ?? PAGE_SIZE);
153
- // } catch (error: any) {
154
- // throw new Error(`An error occurred while fetching the MOH-705 patient list: ${error.message}`);
155
- // }
156
- // }
157
-
158
133
  export async function getMoh511PatientList(params: PatientListParams): Promise<PatientListPage> {
159
134
  const url = await buildEtlUrl('moh-511-patient-list', {
160
135
  locationUuids: params.locationUuids || '',
@@ -229,3 +204,28 @@ export async function getMoh512PatientList(params: PatientListParams): Promise<P
229
204
  throw new Error(`An error occurred while fetching the MOH-512 patient list: ${error.message}`);
230
205
  }
231
206
  }
207
+
208
+ export async function getMoh407PatientList(params: PatientListParams): Promise<PatientListPage> {
209
+ const url = await buildEtlUrl('moh-407-patient-list', {
210
+ locationUuids: params.locationUuids || '',
211
+ startDate: params.startDate || '',
212
+ endDate: params.endDate || '',
213
+ indicator: Array.isArray(params.indicator) ? params.indicator.join(',') : params.indicator || '',
214
+ reportName: params.reportName || 'moh711Report',
215
+ ...pageParams(params),
216
+ });
217
+ try {
218
+ const response = await openmrsFetch(url);
219
+
220
+ if (!response.ok) {
221
+ const errorText = await response.text();
222
+ throw new Error(`Failed to fetch patient list: ${response.status} - ${errorText}`);
223
+ }
224
+
225
+ const data = await response.json();
226
+
227
+ return toPatientListPage(data, params.startIndex ?? 0, params.limit ?? PAGE_SIZE);
228
+ } catch (error: any) {
229
+ throw new Error(`An error occurred while fetching the MOH-407 patient list: ${error.message}`);
230
+ }
231
+ }
@@ -33,6 +33,7 @@ import Moh270DailyRegister from './reports/moh-740/registers/moh-270-permanent-r
33
33
  import Moh512RegisterComponent from './reports/moh-711/registers/moh-512.component';
34
34
  import TbRegisterComponent from './reports/moh-711/registers/tb-register.component';
35
35
  import Moh413Component from './reports/moh-710/registers/moh-413/moh-413.component';
36
+ import Moh407RegisterComponent from './reports/moh-711/registers/moh-407-register.component';
36
37
 
37
38
  const RootComponent: React.FC = () => {
38
39
  const baseName = window.getOpenmrsSpaBase() + 'home/reports';
@@ -73,6 +74,7 @@ const RootComponent: React.FC = () => {
73
74
  <Route path="/moh-512-register" element={<Moh512RegisterComponent />} />
74
75
  <Route path="/tb-register" element={<TbRegisterComponent />} />
75
76
  <Route path="/moh-413-register" element={<Moh413Component />} />
77
+ <Route path="/moh-407-register" element={<Moh407RegisterComponent />} />
76
78
  </Routes>
77
79
  </div>
78
80
  </BrowserRouter>