@ampath/esm-reports-app 1.0.0-next.10
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/.editorconfig +12 -0
- package/.eslintignore +2 -0
- package/.eslintrc +57 -0
- package/.husky/pre-commit +7 -0
- package/.husky/pre-push +6 -0
- package/.prettierignore +14 -0
- package/.turbo.json +18 -0
- package/.yarn/plugins/@yarnpkg/plugin-outdated.cjs +35 -0
- package/LICENSE +401 -0
- package/README.md +9 -0
- package/__mocks__/react-i18next.js +50 -0
- package/dist/138.js +2 -0
- package/dist/138.js.LICENSE.txt +20 -0
- package/dist/138.js.map +1 -0
- package/dist/184.js +2 -0
- package/dist/184.js.LICENSE.txt +14 -0
- package/dist/184.js.map +1 -0
- package/dist/197.js +1 -0
- package/dist/205.js +1 -0
- package/dist/205.js.map +1 -0
- package/dist/282.js +2 -0
- package/dist/282.js.LICENSE.txt +32 -0
- package/dist/282.js.map +1 -0
- package/dist/300.js +1 -0
- package/dist/311.js +1 -0
- package/dist/311.js.map +1 -0
- package/dist/335.js +1 -0
- package/dist/353.js +1 -0
- package/dist/353.js.map +1 -0
- package/dist/478.js +2 -0
- package/dist/478.js.LICENSE.txt +9 -0
- package/dist/478.js.map +1 -0
- package/dist/540.js +2 -0
- package/dist/540.js.LICENSE.txt +9 -0
- package/dist/540.js.map +1 -0
- package/dist/55.js +1 -0
- package/dist/652.js +1 -0
- package/dist/677.js +1 -0
- package/dist/677.js.map +1 -0
- package/dist/812.js +1 -0
- package/dist/812.js.map +1 -0
- package/dist/961.js +2 -0
- package/dist/961.js.LICENSE.txt +19 -0
- package/dist/961.js.map +1 -0
- package/dist/99.js +1 -0
- package/dist/ampath-esm-reports-app.js +1 -0
- package/dist/ampath-esm-reports-app.js.buildmanifest.json +539 -0
- package/dist/ampath-esm-reports-app.js.map +1 -0
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -0
- package/dist/routes.json +1 -0
- package/e2e/README.md +115 -0
- package/e2e/core/global-setup.ts +32 -0
- package/e2e/core/index.ts +1 -0
- package/e2e/core/test.ts +20 -0
- package/e2e/fixtures/api.ts +26 -0
- package/e2e/fixtures/index.ts +1 -0
- package/e2e/pages/index.ts +1 -0
- package/e2e/pages/root-page.ts +32 -0
- package/e2e/specs/template-app.spec.ts +23 -0
- package/e2e/support/github/Dockerfile +34 -0
- package/e2e/support/github/docker-compose.yml +24 -0
- package/e2e/support/github/run-e2e-docker-env.sh +37 -0
- package/example.env +6 -0
- package/jest.config.js +33 -0
- package/package.json +106 -0
- package/playwright.config.ts +32 -0
- package/prettier.config.js +8 -0
- package/src/common/report-filters/report-filters.component.tsx +127 -0
- package/src/common/report-filters/report-filters.scss +49 -0
- package/src/config-schema.ts +12 -0
- package/src/createDashboardLink.tsx +9 -0
- package/src/dashboard/reports-dasboard.tsx +41 -0
- package/src/dashboard/reports-dashboard.module.scss +14 -0
- package/src/dashboard-meta/reports-dashboard.meta.ts +6 -0
- package/src/declarations.d.ts +5 -0
- package/src/index.ts +20 -0
- package/src/reports/datatable-wrapper/datatable-wrapper.component.tsx +54 -0
- package/src/reports/moh-240/moh-240.component.tsx +12 -0
- package/src/reports/moh-240/sub-reports/moh-240-register.component.tsx +42 -0
- package/src/reports/moh-240/sub-reports/page-summary.component.tsx +95 -0
- package/src/reports/moh-505/moh-505.component.tsx +234 -0
- package/src/reports/moh-705B/moh-705b.component.tsx +466 -0
- package/src/reports/moh-705B/moh-705b.scss +41 -0
- package/src/reports/moh-705a/moh-705a.component.tsx +473 -0
- package/src/reports/moh-705a/moh-705a.scss +41 -0
- package/src/reports/moh-706/moh-706.component.tsx +26 -0
- package/src/reports/moh-706/moh-706.scss +18 -0
- package/src/reports/moh-706/sub-reports/bacteriology/bacteriology.component.tsx +117 -0
- package/src/reports/moh-706/sub-reports/blood-chemistry/blood-chemistry.component.tsx +311 -0
- package/src/reports/moh-706/sub-reports/drug-susceptibility-testing/drug-susceptibility-testing.component.tsx +137 -0
- package/src/reports/moh-706/sub-reports/haematology/haematology.component.tsx +172 -0
- package/src/reports/moh-706/sub-reports/histology-and-cytology/histology-and-cytology.component.tsx +88 -0
- package/src/reports/moh-706/sub-reports/parasitology/parasitology.component.tsx +114 -0
- package/src/reports/moh-706/sub-reports/serology/serology.component.tsx +40 -0
- package/src/reports/moh-706/sub-reports/specimen-referral-to-higher-levels/specimen-referral-to-higher-levels.component.tsx +39 -0
- package/src/reports/moh-706/sub-reports/urine-analysis/urine-analysis.component.tsx +101 -0
- package/src/reports/moh-710/moh-710.component.tsx +663 -0
- package/src/reports/moh-710/moh-710.scss +41 -0
- package/src/reports/moh-711/moh-711.component.tsx +121 -0
- package/src/reports/moh-711/moh711.scss +71 -0
- package/src/reports/moh-711/sections/anc.component.tsx +134 -0
- package/src/reports/moh-711/sections/cervical-cancer.component.tsx +104 -0
- package/src/reports/moh-711/sections/chanis.component.tsx +367 -0
- package/src/reports/moh-711/sections/family-planning.component.tsx +221 -0
- package/src/reports/moh-711/sections/gbv.component.tsx +115 -0
- package/src/reports/moh-711/sections/maternity.component.tsx +280 -0
- package/src/reports/moh-711/sections/medical-social-work.component.tsx +83 -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 +92 -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 +42 -0
- package/src/reports/moh-711/sections/tb-screening.component.tsx +57 -0
- package/src/reports/moh-717/moh-717.component.tsx +152 -0
- package/src/reports/moh-717/moh717.scss +150 -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 +94 -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 +489 -0
- package/src/reports/moh-717/sections/pharmacy.component.tsx +43 -0
- package/src/reports/moh-717/sections/preparedby.component.tsx +47 -0
- package/src/reports/moh-717/sections/special-services.component.tsx +114 -0
- package/src/reports/moh-745/moh-745.component.tsx +629 -0
- package/src/reports/moh-745/moh-745.scss +67 -0
- package/src/reports/table-wrapper/table-row-mapper.component.tsx +42 -0
- package/src/reports/table-wrapper/table-wrapper.component.tsx +21 -0
- package/src/reports/table-wrapper/table-wrapper.scss +31 -0
- package/src/resources/moh-705.resource.ts +60 -0
- package/src/resources/moh-710.resource.ts +34 -0
- package/src/resources/moh-711.resource.ts +34 -0
- package/src/resources/moh-717.resource.ts +35 -0
- package/src/resources/moh-745.resource.ts +34 -0
- package/src/root.component.tsx +35 -0
- package/src/root.scss +15 -0
- package/src/routes.json +27 -0
- package/src/utils/get-base-url.ts +12 -0
- package/src/utils/utils.ts +7 -0
- package/tools/i18next-parser.config.js +89 -0
- package/tools/setup-tests.ts +1 -0
- package/tools/update-openmrs-deps.mjs +43 -0
- package/translations/am.json +24 -0
- package/translations/en.json +24 -0
- package/translations/es.json +24 -0
- package/translations/fr.json +24 -0
- package/translations/he.json +24 -0
- package/translations/km.json +24 -0
- package/tsconfig.json +24 -0
- package/webpack.config.js +1 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
|
|
2
|
+
h3 {
|
|
3
|
+
text-align: center;
|
|
4
|
+
}
|
|
5
|
+
.tableContainer {
|
|
6
|
+
margin-left: 2rem;
|
|
7
|
+
margin-bottom: 2rem;
|
|
8
|
+
margin-top: 1rem;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.sectionTitle {
|
|
12
|
+
margin-left: 1rem ;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.table {
|
|
16
|
+
width: auto;
|
|
17
|
+
border-collapse: collapse;
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.tableBordered td,
|
|
22
|
+
.tableBordered th {
|
|
23
|
+
border: 1px solid #ccc;
|
|
24
|
+
padding: 0.3rem;
|
|
25
|
+
font-size: small;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.tableBordered th {
|
|
29
|
+
font-weight: bold;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.tableStriped tbody tr:nth-of-type(odd) {
|
|
33
|
+
background-color: #f9f9f9;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.rotateUp {
|
|
37
|
+
writing-mode: vertical-rl;
|
|
38
|
+
transform: rotate(180deg);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
span {
|
|
42
|
+
font-weight: normal;
|
|
43
|
+
padding: 2px;
|
|
44
|
+
}
|
|
45
|
+
.location {
|
|
46
|
+
margin: 2rem;
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-wrap: nowrap;
|
|
49
|
+
align-items: center;
|
|
50
|
+
gap: 12px;
|
|
51
|
+
white-space: nowrap;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
.line {
|
|
56
|
+
display: inline-block;
|
|
57
|
+
width: 150px;
|
|
58
|
+
border-bottom: 1px solid #000;
|
|
59
|
+
margin-left: 4px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.shortLine {
|
|
63
|
+
display: inline-block;
|
|
64
|
+
width: 90px;
|
|
65
|
+
border-bottom: 1px solid #000;
|
|
66
|
+
margin-left: 4px;
|
|
67
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TableRow, TableCell } from "@carbon/react";
|
|
3
|
+
import styles from './table-wrapper.scss';
|
|
4
|
+
import { navigate } from "@openmrs/esm-framework";
|
|
5
|
+
|
|
6
|
+
interface TableRowMapperProps {
|
|
7
|
+
tableRows: {
|
|
8
|
+
tableCells: Array<{
|
|
9
|
+
key: string;
|
|
10
|
+
label: any;
|
|
11
|
+
strong: boolean;
|
|
12
|
+
colSpan: number;
|
|
13
|
+
rowSpan: number;
|
|
14
|
+
}>
|
|
15
|
+
}[],
|
|
16
|
+
data?: any
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const TableRowMapper: React.FC<TableRowMapperProps> = ({ tableRows, data }) => {
|
|
20
|
+
return <>
|
|
21
|
+
{tableRows.map((tR) => (
|
|
22
|
+
<TableRow>
|
|
23
|
+
{tR.tableCells.map((tC, i) => {
|
|
24
|
+
const value = data ? data[tC.key] : "";
|
|
25
|
+
|
|
26
|
+
const onClick = () => {
|
|
27
|
+
if (!tC.label) {
|
|
28
|
+
navigate({ to: "home/reports/moh-240" });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return <TableCell className={styles.dataCell} colSpan={tC.colSpan} key={i} onClick={onClick} {...({ rowSpan: tC.rowSpan } as any)}>
|
|
33
|
+
{tC.label ? (tC.strong ? <strong>{tC.label}</strong> : tC.label) : value}
|
|
34
|
+
</TableCell>
|
|
35
|
+
|
|
36
|
+
})}
|
|
37
|
+
</TableRow>
|
|
38
|
+
))}
|
|
39
|
+
</>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default TableRowMapper;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Table, TableBody } from '@carbon/react';
|
|
3
|
+
import styles from './table-wrapper.scss';
|
|
4
|
+
|
|
5
|
+
interface TableWrapperProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const TableWrapper: React.FC<TableWrapperProps> = ({ children }) => {
|
|
10
|
+
return <>
|
|
11
|
+
<div className={styles.tableWrapper}>
|
|
12
|
+
<Table size="sm" className={styles.tableComponent}>
|
|
13
|
+
<TableBody>
|
|
14
|
+
{children}
|
|
15
|
+
</TableBody>
|
|
16
|
+
</Table>
|
|
17
|
+
</div>
|
|
18
|
+
</>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default TableWrapper;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
.tableWrapper {
|
|
2
|
+
overflow-x: auto;
|
|
3
|
+
border: 1px solid #d0d0d0;
|
|
4
|
+
border-radius: 4px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.tableContainer {
|
|
8
|
+
width: 100%;
|
|
9
|
+
border-collapse: collapse;
|
|
10
|
+
|
|
11
|
+
thead {
|
|
12
|
+
background-color: #f4f4f4;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
tbody tr {
|
|
16
|
+
border-bottom: 1px solid #e0e0e0;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.dataCell {
|
|
21
|
+
padding: 0.01rem;
|
|
22
|
+
border: 1px solid #d0d0d0;
|
|
23
|
+
text-align: center;
|
|
24
|
+
height: 20px;
|
|
25
|
+
min-width: 50px;
|
|
26
|
+
font-size: small;
|
|
27
|
+
|
|
28
|
+
&:hover {
|
|
29
|
+
background-color: #f0f7ff;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
2
|
+
import { getEtlBaseUrl } from '../utils/get-base-url';
|
|
3
|
+
|
|
4
|
+
interface Moh710Params {
|
|
5
|
+
locationUuids: string;
|
|
6
|
+
startDate?: string;
|
|
7
|
+
endDate?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function getMoh705a(params: Moh710Params): Promise<any> {
|
|
11
|
+
const etlBaseUrl = await getEtlBaseUrl();
|
|
12
|
+
const url = `${etlBaseUrl}/moh-705a`;
|
|
13
|
+
const queryparams = {
|
|
14
|
+
locationUuids: params.locationUuids || '',
|
|
15
|
+
startDate: params.startDate || '',
|
|
16
|
+
endDate: params.endDate || '',
|
|
17
|
+
};
|
|
18
|
+
const queryString = new URLSearchParams(
|
|
19
|
+
Object.fromEntries(Object.entries(queryparams).filter(([_, v]) => v !== undefined && v !== null)),
|
|
20
|
+
).toString();
|
|
21
|
+
try {
|
|
22
|
+
const response = await openmrsFetch(`${url}?${queryString}`);
|
|
23
|
+
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
const errorText = await response.text();
|
|
26
|
+
throw new Error(`Failed to fetch dashboard summary: ${response.status} - ${errorText}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
return data;
|
|
31
|
+
} catch (error: any) {
|
|
32
|
+
throw new Error(`An error occurred while fetching the MOH-710 report: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function getMoh705b(params: Moh710Params): Promise<any> {
|
|
37
|
+
const etlBaseUrl = await getEtlBaseUrl();
|
|
38
|
+
const url = `${etlBaseUrl}/moh-705b`;
|
|
39
|
+
const queryparams = {
|
|
40
|
+
locationUuids: params.locationUuids || '',
|
|
41
|
+
startDate: params.startDate || '',
|
|
42
|
+
endDate: params.endDate || '',
|
|
43
|
+
};
|
|
44
|
+
const queryString = new URLSearchParams(
|
|
45
|
+
Object.fromEntries(Object.entries(queryparams).filter(([_, v]) => v !== undefined && v !== null)),
|
|
46
|
+
).toString();
|
|
47
|
+
try {
|
|
48
|
+
const response = await openmrsFetch(`${url}?${queryString}`);
|
|
49
|
+
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
const errorText = await response.text();
|
|
52
|
+
throw new Error(`Failed to fetch dashboard summary: ${response.status} - ${errorText}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const data = await response.json();
|
|
56
|
+
return data;
|
|
57
|
+
} catch (error: any) {
|
|
58
|
+
throw new Error(`An error occurred while fetching the MOH-710 report: ${error.message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
2
|
+
import { getEtlBaseUrl } from '../utils/get-base-url';
|
|
3
|
+
|
|
4
|
+
interface Moh710Params {
|
|
5
|
+
locationUuids: string;
|
|
6
|
+
startDate?: string;
|
|
7
|
+
endDate?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function getMoh710(params: Moh710Params): Promise<any> {
|
|
11
|
+
const etlBaseUrl = await getEtlBaseUrl();
|
|
12
|
+
const url = `${etlBaseUrl}/moh-710`;
|
|
13
|
+
const queryparams = {
|
|
14
|
+
locationUuids: params.locationUuids || '',
|
|
15
|
+
startDate: params.startDate || '',
|
|
16
|
+
endDate: params.endDate || '',
|
|
17
|
+
};
|
|
18
|
+
const queryString = new URLSearchParams(
|
|
19
|
+
Object.fromEntries(Object.entries(queryparams).filter(([_, v]) => v !== undefined && v !== null)),
|
|
20
|
+
).toString();
|
|
21
|
+
try {
|
|
22
|
+
const response = await openmrsFetch(`${url}?${queryString}`);
|
|
23
|
+
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
const errorText = await response.text();
|
|
26
|
+
throw new Error(`Failed to fetch dashboard summary: ${response.status} - ${errorText}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
return data;
|
|
31
|
+
} catch (error: any) {
|
|
32
|
+
throw new Error(`An error occurred while fetching the MOH-710 report: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
2
|
+
import { getEtlBaseUrl } from '../utils/get-base-url';
|
|
3
|
+
|
|
4
|
+
interface Moh711Params {
|
|
5
|
+
locationUuids: string;
|
|
6
|
+
startDate?: string;
|
|
7
|
+
endDate?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function getMoh711(params: Moh711Params): Promise<any> {
|
|
11
|
+
const etlBaseUrl = await getEtlBaseUrl();
|
|
12
|
+
const url = `${etlBaseUrl}/moh-711`;
|
|
13
|
+
const queryparams = {
|
|
14
|
+
locationUuids: params.locationUuids || '',
|
|
15
|
+
startDate: params.startDate || '',
|
|
16
|
+
endDate: params.endDate || '',
|
|
17
|
+
};
|
|
18
|
+
const queryString = new URLSearchParams(
|
|
19
|
+
Object.fromEntries(Object.entries(queryparams).filter(([_, v]) => v !== undefined && v !== null)),
|
|
20
|
+
).toString();
|
|
21
|
+
try {
|
|
22
|
+
const response = await openmrsFetch(`${url}?${queryString}`);
|
|
23
|
+
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
const errorText = await response.text();
|
|
26
|
+
throw new Error(`Failed to fetch dashboard summary: ${response.status} - ${errorText}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
return data;
|
|
31
|
+
} catch (error: any) {
|
|
32
|
+
throw new Error(`An error occurred while fetching the MOH-711 report: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
2
|
+
import { getEtlBaseUrl } from '../utils/get-base-url';
|
|
3
|
+
|
|
4
|
+
interface Moh717Params {
|
|
5
|
+
locationUuids: string;
|
|
6
|
+
startDate?: string;
|
|
7
|
+
endDate?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function getMoh717(params: Moh717Params): Promise<any> {
|
|
11
|
+
const etlBaseUrl = await getEtlBaseUrl();
|
|
12
|
+
const url = `${etlBaseUrl}/moh-717`;
|
|
13
|
+
const queryparams = {
|
|
14
|
+
locationUuids: params.locationUuids || '',
|
|
15
|
+
startDate: params.startDate || '',
|
|
16
|
+
endDate: params.endDate || '',
|
|
17
|
+
};
|
|
18
|
+
const queryString = new URLSearchParams(
|
|
19
|
+
Object.fromEntries(Object.entries(queryparams).filter(([_, v]) => v !== undefined && v !== null)),
|
|
20
|
+
).toString();
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const response = await openmrsFetch(`${url}?${queryString}`);
|
|
24
|
+
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
const errorText = await response.text();
|
|
27
|
+
throw new Error(`Failed to fetch dashboard summary: ${response.status} - ${errorText}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const data = await response.json();
|
|
31
|
+
return data;
|
|
32
|
+
} catch (error: any) {
|
|
33
|
+
throw new Error(`An error occurred while fetching the MOH-717 report: ${error.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
2
|
+
import { getEtlBaseUrl } from '../utils/get-base-url';
|
|
3
|
+
|
|
4
|
+
interface Moh710Params {
|
|
5
|
+
locationUuids: string;
|
|
6
|
+
startDate?: string;
|
|
7
|
+
endDate?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function getMoh745(params: Moh710Params): Promise<any> {
|
|
11
|
+
const etlBaseUrl = await getEtlBaseUrl();
|
|
12
|
+
const url = `${etlBaseUrl}/moh-745`;
|
|
13
|
+
const queryparams = {
|
|
14
|
+
locationUuids: params.locationUuids || '',
|
|
15
|
+
startDate: params.startDate || '',
|
|
16
|
+
endDate: params.endDate || '',
|
|
17
|
+
};
|
|
18
|
+
const queryString = new URLSearchParams(
|
|
19
|
+
Object.fromEntries(Object.entries(queryparams).filter(([_, v]) => v !== undefined && v !== null)),
|
|
20
|
+
).toString();
|
|
21
|
+
try {
|
|
22
|
+
const response = await openmrsFetch(`${url}?${queryString}`);
|
|
23
|
+
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
const errorText = await response.text();
|
|
26
|
+
throw new Error(`Failed to fetch dashboard summary: ${response.status} - ${errorText}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
return data;
|
|
31
|
+
} catch (error: any) {
|
|
32
|
+
throw new Error(`An error occurred while fetching the MOH-710 report: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { BrowserRouter, Route, Routes } from 'react-router-dom';
|
|
3
|
+
import ReportsDashboard from './dashboard/reports-dasboard';
|
|
4
|
+
import Moh710Report from './reports/moh-710/moh-710.component';
|
|
5
|
+
import Moh711Report from './reports/moh-711/moh-711.component';
|
|
6
|
+
import Moh717Report from './reports/moh-717/moh-717.component';
|
|
7
|
+
import MoH706Report from './reports/moh-706/moh-706.component';
|
|
8
|
+
import Moh240Report from './reports/moh-240/moh-240.component';
|
|
9
|
+
import Moh505Report from './reports/moh-505/moh-505.component';
|
|
10
|
+
import Moh705BComponent from './reports/moh-705B/moh-705b.component';
|
|
11
|
+
import Moh705AComponent from './reports/moh-705a/moh-705a.component';
|
|
12
|
+
import Moh745Component from './reports/moh-745/moh-745.component';
|
|
13
|
+
|
|
14
|
+
const RootComponent: React.FC = () => {
|
|
15
|
+
const baseName = window.getOpenmrsSpaBase() + 'home/reports';
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<BrowserRouter basename={baseName}>
|
|
19
|
+
<Routes>
|
|
20
|
+
<Route path="/" element={<ReportsDashboard />} />
|
|
21
|
+
<Route path="/moh-710" element={<Moh710Report />} />
|
|
22
|
+
<Route path="/moh-711" element={<Moh711Report />} />
|
|
23
|
+
<Route path="/moh-717" element={<Moh717Report />} />
|
|
24
|
+
<Route path="/moh-706" element={<MoH706Report />} />
|
|
25
|
+
<Route path="/moh-240" element={<Moh240Report />} />
|
|
26
|
+
<Route path="/moh-505" element={<Moh505Report />} />
|
|
27
|
+
<Route path="/moh-705a" element={<Moh705AComponent />} />
|
|
28
|
+
<Route path="/moh-705b" element={<Moh705BComponent />} />
|
|
29
|
+
<Route path="/moh-745" element={<Moh745Component />} />
|
|
30
|
+
</Routes>
|
|
31
|
+
</BrowserRouter>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default RootComponent;
|
package/src/root.scss
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@use '@carbon/layout';
|
|
2
|
+
@use '@carbon/type';
|
|
3
|
+
|
|
4
|
+
.container {
|
|
5
|
+
padding: layout.$spacing-07;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.welcome {
|
|
9
|
+
@include type.type-style('heading-04');
|
|
10
|
+
margin: layout.$spacing-05 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.explainer {
|
|
14
|
+
margin-bottom: layout.$spacing-07;
|
|
15
|
+
}
|
package/src/routes.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.openmrs.org/routes.schema.json",
|
|
3
|
+
"backendDependencies": {
|
|
4
|
+
"fhir2": ">=1.2",
|
|
5
|
+
"webservices.rest": ">=2.2.0"
|
|
6
|
+
},
|
|
7
|
+
"extensions": [
|
|
8
|
+
{
|
|
9
|
+
"name": "ampath-reports-dashboard-link",
|
|
10
|
+
"component": "reportsDashboardLink",
|
|
11
|
+
"slot": "homepage-dashboard-slot",
|
|
12
|
+
"meta": {
|
|
13
|
+
"name": "reports",
|
|
14
|
+
"slot": "ampath-reports-dashboard-slot",
|
|
15
|
+
"title": "Reports"
|
|
16
|
+
},
|
|
17
|
+
"online": true,
|
|
18
|
+
"offline": true
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"component": "root",
|
|
22
|
+
"name": "ampath-reports-dashboard-root",
|
|
23
|
+
"slot": "ampath-reports-dashboard-slot"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"pages": []
|
|
27
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getConfig } from '@openmrs/esm-framework';
|
|
2
|
+
import { moduleName } from '../index';
|
|
3
|
+
|
|
4
|
+
export async function getEtlBaseUrl() {
|
|
5
|
+
const { etlBaseUrl } = await getConfig(moduleName);
|
|
6
|
+
return etlBaseUrl ?? null;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export async function getSubDomain() {
|
|
10
|
+
const { subDomain } = await getConfig(moduleName);
|
|
11
|
+
return subDomain ?? null;
|
|
12
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
contextSeparator: '_',
|
|
3
|
+
// Key separator used in your translation keys
|
|
4
|
+
|
|
5
|
+
createOldCatalogs: false,
|
|
6
|
+
// Save the \_old files
|
|
7
|
+
|
|
8
|
+
defaultNamespace: 'translations',
|
|
9
|
+
// Default namespace used in your i18next config
|
|
10
|
+
|
|
11
|
+
defaultValue: '',
|
|
12
|
+
// Default value to give to empty keys
|
|
13
|
+
// You may also specify a function accepting the locale, namespace, and key as arguments
|
|
14
|
+
|
|
15
|
+
indentation: 2,
|
|
16
|
+
// Indentation of the catalog files
|
|
17
|
+
|
|
18
|
+
keepRemoved: false,
|
|
19
|
+
// Keep keys from the catalog that are no longer in code
|
|
20
|
+
|
|
21
|
+
keySeparator: '.',
|
|
22
|
+
// Key separator used in your translation keys
|
|
23
|
+
// If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.
|
|
24
|
+
|
|
25
|
+
// see below for more details
|
|
26
|
+
lexers: {
|
|
27
|
+
hbs: ['HandlebarsLexer'],
|
|
28
|
+
handlebars: ['HandlebarsLexer'],
|
|
29
|
+
|
|
30
|
+
htm: ['HTMLLexer'],
|
|
31
|
+
html: ['HTMLLexer'],
|
|
32
|
+
|
|
33
|
+
mjs: ['JavascriptLexer'],
|
|
34
|
+
js: ['JavascriptLexer'], // if you're writing jsx inside .js files, change this to JsxLexer
|
|
35
|
+
ts: ['JavascriptLexer'],
|
|
36
|
+
jsx: ['JsxLexer'],
|
|
37
|
+
tsx: ['JsxLexer'],
|
|
38
|
+
|
|
39
|
+
default: ['JavascriptLexer'],
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
lineEnding: 'auto',
|
|
43
|
+
// Control the line ending. See options at https://github.com/ryanve/eol
|
|
44
|
+
|
|
45
|
+
locales: ['en'],
|
|
46
|
+
// An array of the locales in your applications
|
|
47
|
+
|
|
48
|
+
namespaceSeparator: ':',
|
|
49
|
+
// Namespace separator used in your translation keys
|
|
50
|
+
// If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.
|
|
51
|
+
|
|
52
|
+
output: '$NAMESPACE/$LOCALE.json',
|
|
53
|
+
// Supports $LOCALE and $NAMESPACE injection
|
|
54
|
+
// Supports JSON (.json) and YAML (.yml) file formats
|
|
55
|
+
// Where to write the locale files relative to process.cwd()
|
|
56
|
+
|
|
57
|
+
pluralSeparator: '_',
|
|
58
|
+
// Plural separator used in your translation keys
|
|
59
|
+
// If you want to use plain english keys, separators such as `_` might conflict. You might want to set `pluralSeparator` to a different string that does not occur in your keys.
|
|
60
|
+
|
|
61
|
+
input: undefined,
|
|
62
|
+
// An array of globs that describe where to look for source files
|
|
63
|
+
// relative to the location of the configuration file
|
|
64
|
+
|
|
65
|
+
sort: true,
|
|
66
|
+
// Whether or not to sort the catalog
|
|
67
|
+
|
|
68
|
+
useKeysAsDefaultValue: false,
|
|
69
|
+
// Whether to use the keys as the default value; ex. "Hello": "Hello", "World": "World"
|
|
70
|
+
// This option takes precedence over the `defaultValue` and `skipDefaultValues` options
|
|
71
|
+
// You may also specify a function accepting the locale and namespace as arguments
|
|
72
|
+
|
|
73
|
+
verbose: false,
|
|
74
|
+
// Display info about the parsing including some stats
|
|
75
|
+
|
|
76
|
+
failOnWarnings: false,
|
|
77
|
+
// Exit with an exit code of 1 on warnings
|
|
78
|
+
|
|
79
|
+
customValueTemplate: null,
|
|
80
|
+
// If you wish to customize the value output the value as an object, you can set your own format.
|
|
81
|
+
// ${defaultValue} is the default value you set in your translation function.
|
|
82
|
+
// Any other custom property will be automatically extracted.
|
|
83
|
+
//
|
|
84
|
+
// Example:
|
|
85
|
+
// {
|
|
86
|
+
// message: "${defaultValue}",
|
|
87
|
+
// description: "${maxLength}", // t('my-key', {maxLength: 150})
|
|
88
|
+
// }
|
|
89
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
try {
|
|
4
|
+
// NB for other places use '@openmrs/*@next'; here we want to ignore patient-common-lib
|
|
5
|
+
execSync(`yarn up --fixed '@openmrs/*@next' 'openmrs@next'`, {
|
|
6
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
|
7
|
+
windowsHide: true,
|
|
8
|
+
});
|
|
9
|
+
} catch (error) {
|
|
10
|
+
console.error(`Error while updating dependencies: ${error.message ?? error}`);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
execSync(`yarn dedupe`, {
|
|
16
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
|
17
|
+
windowsHide: true,
|
|
18
|
+
});
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error(`Error while deduplicating dependencies: ${error.message ?? error}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
execSync(`git diff-index --quiet HEAD --`, {
|
|
26
|
+
stdio: 'ignore',
|
|
27
|
+
windowsHide: true,
|
|
28
|
+
});
|
|
29
|
+
process.exit(0);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
// git diff-index --quite HEAD --
|
|
32
|
+
// exits with status 1 if there are changes; we only need to run yarn verify if there are changes
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
execSync(`yarn verify`, {
|
|
37
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
|
38
|
+
windowsHide: true,
|
|
39
|
+
});
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error(`Error while running yarn verify: ${error.message ?? error}. Updates require manual intervention.`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"casualGreeting": "hey",
|
|
3
|
+
"configSystem": "የማዋቀር ስርዓት",
|
|
4
|
+
"configSystemExplainer": "ከዚህ በታች የሚታየው ሰላምታ የሚመራው በማዋቀር ስርዓቱ ነው። የማዋቀር ባህሪያቱን ለመቀየር በአሳሹ ውስጥ ያለውን የስፓነር አዶ ጠቅ ያድርጉ የአስፈፃሚ መሳሪያዎች ፓነልን ለመሳብ። በመቀጠል በ <4>የፍለጋ ውቅረት</4> ግቤት ውስጥ <2>አብነት</2>ን ይተይቡ። ይህ ለዚህ ሞጁል ተዛማጅ የሆኑትን ብቻ ለማሳየት የማዋቀሪያ ባህሪያትን ማጣራት አለበት. በUI ውስጥ የሚንፀባረቁትን ለውጦች ለማየት የእነዚህን ንብረቶች እሴቶች መለወጥ እና <6>አስቀምጥ</6>ን ጠቅ ማድረግ ይችላሉ",
|
|
5
|
+
"connect": "ተገናኝ",
|
|
6
|
+
"connectExplainer": "ከማህበረሰቡ ጋር ይገናኙ",
|
|
7
|
+
"dataFetching": "ውሂብ ማምጣት",
|
|
8
|
+
"designDocs": "የንድፍ መመሪያ",
|
|
9
|
+
"designDocsExplainer": "የ O3 ንድፍ ሰነድ ያንብቡ",
|
|
10
|
+
"explainer": "የሚከተሉት ምሳሌዎች የ O3 ማዕቀፍ አንዳንድ ቁልፍ ባህሪያትን ያሳያሉ",
|
|
11
|
+
"extensionExplainer": "አንዳንድ ባለቀለም ሳጥኖች እዚህ አሉ። በአንድ ማስገቢያ ውስጥ እንደ ቅጥያ ስለተያያዙ፣ አስተዳዳሪው ውቅረትን ተጠቅሞ የሚታዩትን ሳጥኖች መለወጥ ይችላል። እነዚህ ሳጥኖች በዚህ ሞጁል ውስጥ ይገለጻሉ, ነገር ግን በተለየ ሞጁል ውስጥ ቢሆኑም እንኳ ከዚህ ማስገቢያ ጋር ማያያዝ ይችላሉ",
|
|
12
|
+
"extensionSystem": "የኤክስቴንሽን ስርዓት",
|
|
13
|
+
"formalGreeting": "ሀሎ",
|
|
14
|
+
"frontendDocs": "የፊት-መጨረሻ መመሪያ",
|
|
15
|
+
"getPatient": "የተሰየመ ታካሚ ያግኙ",
|
|
16
|
+
"getStarted": "እንጀምር",
|
|
17
|
+
"getStartedExplainer": "ከዚህ አብነት የፊት ለፊት ሞጁል ይፍጠሩ",
|
|
18
|
+
"learnExplainer": "የ O3 ማዕቀፍን እንዴት መጠቀም እንደሚችሉ ይወቁ",
|
|
19
|
+
"loading": "በመጫን ላይ",
|
|
20
|
+
"patientGetterExplainer": "በሽተኛውን ከኤፒአይ ለማውጣት ከታች ያለውን አዝራር ጠቅ ያድርጉ",
|
|
21
|
+
"resources": "መርጃዎች",
|
|
22
|
+
"usefulLinks": "ከዚህ በታች ወደ ጠቃሚ ሀብቶች አንዳንድ አገናኞች አሉ",
|
|
23
|
+
"welcomeText": "ወደ O3 አብነት መተግበሪያ እንኳን በደህና መጡ"
|
|
24
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"casualGreeting": "hey",
|
|
3
|
+
"configSystem": "Configuration system",
|
|
4
|
+
"configSystemExplainer": "The greeting shown below is driven by the configuration system. To change the configuration properties, click the spanner icon in the navbar to pull up the Implementer Tools panel. Then, type <2>template</2> into the <4>Search configuration</4> input. This should filter the configuration properties to show only those that are relevant to this module. You can change the values of these properties and click <6>Save</6> to see the changes reflected in the UI",
|
|
5
|
+
"connect": "Connect",
|
|
6
|
+
"connectExplainer": "Get in touch with the community",
|
|
7
|
+
"dataFetching": "Data fetching",
|
|
8
|
+
"designDocs": "Design docs",
|
|
9
|
+
"designDocsExplainer": "Read the O3 design documentation",
|
|
10
|
+
"explainer": "The following examples demonstrate some key features of the O3 framework",
|
|
11
|
+
"extensionExplainer": "Here are some colored boxes. Because they are attached as extensions within a slot, an admin can change what boxes are shown using configuration. These boxes happen to be defined in this module, but they could attach to this slot even if they were in a different module",
|
|
12
|
+
"extensionSystem": "Extension system",
|
|
13
|
+
"formalGreeting": "hello",
|
|
14
|
+
"frontendDocs": "Frontend docs",
|
|
15
|
+
"getPatient": "Get a patient named",
|
|
16
|
+
"getStarted": "Get started",
|
|
17
|
+
"getStartedExplainer": "Create a frontend module from this template",
|
|
18
|
+
"learnExplainer": "Learn how to use the O3 framework",
|
|
19
|
+
"loading": "Loading",
|
|
20
|
+
"patientGetterExplainer": "Try clicking the button below to fetch a patient from the backend",
|
|
21
|
+
"resources": "Resources",
|
|
22
|
+
"usefulLinks": "Below are some links to useful resources",
|
|
23
|
+
"welcomeText": "Welcome to the O3 Template app"
|
|
24
|
+
}
|