@kenyaemr/esm-facility-dashboard-app 5.4.2-pre.2122 → 5.4.2-pre.2126
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/.turbo/turbo-build.log +18 -18
- package/dist/367.js +1 -1
- package/dist/367.js.map +1 -1
- package/dist/574.js +1 -1
- package/dist/983.js +1 -0
- package/dist/983.js.map +1 -0
- package/dist/kenyaemr-esm-facility-dashboard-app.js +1 -1
- package/dist/kenyaemr-esm-facility-dashboard-app.js.buildmanifest.json +32 -32
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/constants.ts +4 -0
- package/src/hooks/useFacilityDashboardSurveillance.ts +106 -28
- package/src/surveillance/charts/base-cumulative-progress-tracking-chart.component.tsx +50 -0
- package/src/surveillance/charts/base-indicator-trend-chart.component.tsx +9 -3
- package/src/surveillance/charts/base-progress-tracking-chart.component.tsx +16 -10
- package/src/surveillance/charts/charts.scss +4 -0
- package/src/surveillance/charts/delayed-eac-charts.component.tsx +81 -15
- package/src/surveillance/charts/dna-pcr-pending-chart.component.tsx +84 -15
- package/src/surveillance/charts/hei-final-outcome.component.tsx +80 -17
- package/src/surveillance/charts/hiv-not-linked-to-art.component.tsx +74 -15
- package/src/surveillance/charts/missed-opportunity-vl-chart.component.tsx +83 -15
- package/src/surveillance/charts/pbfw-not-in-prep.component.tsx +78 -29
- package/src/surveillance/surveillance-dashboard.component.tsx +15 -10
- package/src/surveillance/surveillance-filters.component.tsx +23 -16
- package/src/surveillance/surveillance.scss +14 -1
- package/src/types/index.ts +14 -0
- package/translations/en.json +31 -12
- package/dist/561.js +0 -1
- package/dist/561.js.map +0 -1
- package/src/surveillance/charts/base-art-progress-tracking-chart.component.tsx +0 -56
|
@@ -2,12 +2,12 @@ import '@carbon/charts/styles.css';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import BaseIndicatorTrendChart from './base-indicator-trend-chart.component';
|
|
5
|
-
import
|
|
5
|
+
import BaseProgressTrackingChart from './base-progress-tracking-chart.component';
|
|
6
6
|
import useFacilityDashboardSurveillance from '../../hooks/useFacilityDashboardSurveillance';
|
|
7
|
-
import { useSurveillanceData } from '../../hooks/useSurveillanceData';
|
|
8
7
|
import EmptyState from '../empty-state/empty-state-log.components';
|
|
9
8
|
import styles from './charts.scss';
|
|
10
9
|
import { InlineLoading } from '@carbon/react';
|
|
10
|
+
import BaseCumulativeProgressTrackingChart from './base-cumulative-progress-tracking-chart.component';
|
|
11
11
|
type HIVPositiveNotLinkedToARTProps = {
|
|
12
12
|
startDate?: Date;
|
|
13
13
|
endDate?: Date;
|
|
@@ -15,40 +15,99 @@ type HIVPositiveNotLinkedToARTProps = {
|
|
|
15
15
|
const HIVPositiveNotLinkedToART: React.FC<HIVPositiveNotLinkedToARTProps> = ({ startDate, endDate }) => {
|
|
16
16
|
const { t } = useTranslation();
|
|
17
17
|
|
|
18
|
-
const {
|
|
18
|
+
const {
|
|
19
|
+
error,
|
|
20
|
+
isLoading,
|
|
21
|
+
surveillanceSummary,
|
|
22
|
+
getCompletedPercentage,
|
|
23
|
+
getPendingPercentage,
|
|
24
|
+
getThirtydaysRunninPercentage,
|
|
25
|
+
getThirtydaysRunninPendingPercentage,
|
|
26
|
+
} = useFacilityDashboardSurveillance(startDate, endDate);
|
|
19
27
|
|
|
20
|
-
const
|
|
28
|
+
const cumulativeHivPositivePatientData = {
|
|
29
|
+
data: [
|
|
30
|
+
{
|
|
31
|
+
group: 'Completed',
|
|
32
|
+
value: getCompletedPercentage(
|
|
33
|
+
surveillanceSummary?.getHivPositiveNotLinked,
|
|
34
|
+
surveillanceSummary?.getHivTestedPositive,
|
|
35
|
+
),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
group: 'Pending',
|
|
39
|
+
value: getPendingPercentage(
|
|
40
|
+
surveillanceSummary?.getHivPositiveNotLinked,
|
|
41
|
+
surveillanceSummary?.getHivTestedPositive,
|
|
42
|
+
),
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
21
46
|
|
|
22
|
-
const
|
|
23
|
-
surveillanceSummary,
|
|
24
|
-
|
|
47
|
+
const notLinkedToArtData = getThirtydaysRunninPercentage(
|
|
48
|
+
surveillanceSummary?.getMonthlyPatientsTestedHivPositive.data,
|
|
49
|
+
surveillanceSummary?.getMonthlyHivPositiveNotLinkedPatients.data,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const lineGraphData = getThirtydaysRunninPendingPercentage(
|
|
53
|
+
surveillanceSummary?.getMonthlyPatientsTestedHivPositive.data,
|
|
54
|
+
surveillanceSummary?.getMonthlyHivPositiveNotLinkedPatients.data,
|
|
25
55
|
);
|
|
26
56
|
|
|
57
|
+
if (error) {
|
|
58
|
+
return <EmptyState subTitle={t('errorLoadingData', 'Error loading data')} />;
|
|
59
|
+
}
|
|
60
|
+
|
|
27
61
|
return (
|
|
28
|
-
<div>
|
|
62
|
+
<div className={styles.chartContainer}>
|
|
29
63
|
{isLoading ? (
|
|
30
64
|
<InlineLoading status="active" iconDescription="Loading" description="Loading data..." />
|
|
31
65
|
) : (
|
|
32
|
-
|
|
66
|
+
<div className={styles.chartContainer}>
|
|
33
67
|
<div className={styles.chart}>
|
|
34
|
-
{
|
|
68
|
+
{lineGraphData.length > 0 ? (
|
|
35
69
|
<BaseIndicatorTrendChart
|
|
36
|
-
data={
|
|
70
|
+
data={lineGraphData}
|
|
37
71
|
title={t('hivPositiveNotLinkedToART', 'HIV +VE Not linked to ART')}
|
|
38
|
-
yAxisTitle={t('
|
|
72
|
+
yAxisTitle={t('percentageTestedPositiveNotLinked', '% tested positive not linked')}
|
|
39
73
|
/>
|
|
40
74
|
) : (
|
|
41
75
|
<EmptyState subTitle={t('noHivPositiveNotLinked', 'No HIV +VE Not linked to ART data to display')} />
|
|
42
76
|
)}
|
|
43
77
|
</div>
|
|
44
78
|
<div className={styles.chart}>
|
|
45
|
-
{
|
|
46
|
-
<
|
|
79
|
+
{notLinkedToArtData.length > 0 ? (
|
|
80
|
+
<BaseProgressTrackingChart
|
|
81
|
+
data={notLinkedToArtData}
|
|
82
|
+
stackTitle={t('progressInAddressingLinkedToArt', 'Progress in addressing Linkage to ART')}
|
|
83
|
+
leftAxiTtitle={t('percentageHivPositive', '% HIV positive')}
|
|
84
|
+
/>
|
|
47
85
|
) : (
|
|
48
86
|
<EmptyState subTitle={'No Linkage to ART data to display'} />
|
|
49
87
|
)}
|
|
50
88
|
</div>
|
|
51
|
-
|
|
89
|
+
<div className={styles.chart}>
|
|
90
|
+
{surveillanceSummary?.getHivTestedPositive > 0 ? (
|
|
91
|
+
<div className={styles.cumulativeChart}>
|
|
92
|
+
<BaseCumulativeProgressTrackingChart
|
|
93
|
+
data={cumulativeHivPositivePatientData}
|
|
94
|
+
title={t(
|
|
95
|
+
'cumulativeProgressOfAddressingLinkedToArt',
|
|
96
|
+
'Cumulative progress of addressing Linkage to ART',
|
|
97
|
+
)}
|
|
98
|
+
yAxisTitle={t('percentageHivPositive', '% HIV positive')}
|
|
99
|
+
/>
|
|
100
|
+
</div>
|
|
101
|
+
) : (
|
|
102
|
+
<EmptyState
|
|
103
|
+
subTitle={t(
|
|
104
|
+
'noCumulativeHivPositiveNotLinked',
|
|
105
|
+
'No cumulative HIV +VE Not linked to ART data to display',
|
|
106
|
+
)}
|
|
107
|
+
/>
|
|
108
|
+
)}
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
52
111
|
)}
|
|
53
112
|
</div>
|
|
54
113
|
);
|
|
@@ -6,29 +6,97 @@ import useFacilityDashboardSurveillance from '../../hooks/useFacilityDashboardSu
|
|
|
6
6
|
import { useSurveillanceData } from '../../hooks/useSurveillanceData';
|
|
7
7
|
import EmptyState from '../empty-state/empty-state-log.components';
|
|
8
8
|
import { InlineLoading } from '@carbon/react';
|
|
9
|
+
import BaseCumulativeProgressTrackingChart from './base-cumulative-progress-tracking-chart.component';
|
|
10
|
+
import BaseProgressTrackingChart from './base-progress-tracking-chart.component';
|
|
9
11
|
type MissedOpportunityChartProps = {
|
|
10
12
|
startDate?: Date;
|
|
11
13
|
endDate?: Date;
|
|
12
14
|
};
|
|
13
15
|
const MissedOpportunityChart: React.FC<MissedOpportunityChartProps> = ({ startDate, endDate }) => {
|
|
14
16
|
const { t } = useTranslation();
|
|
15
|
-
const {
|
|
17
|
+
const {
|
|
18
|
+
error,
|
|
19
|
+
isLoading,
|
|
20
|
+
surveillanceSummary,
|
|
21
|
+
getCompletedPercentage,
|
|
22
|
+
getPendingPercentage,
|
|
23
|
+
getThirtydaysRunninPercentage,
|
|
24
|
+
getThirtydaysRunninPendingPercentage,
|
|
25
|
+
} = useFacilityDashboardSurveillance(startDate, endDate);
|
|
16
26
|
|
|
17
|
-
const
|
|
27
|
+
const cumulativeMissedoppotunityVLData = {
|
|
28
|
+
data: [
|
|
29
|
+
{
|
|
30
|
+
group: 'Completed',
|
|
31
|
+
value: getCompletedPercentage(
|
|
32
|
+
surveillanceSummary?.getEligibleForVlSampleNotTaken,
|
|
33
|
+
surveillanceSummary?.getEligibleForVl,
|
|
34
|
+
),
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
group: 'Pending',
|
|
38
|
+
value: getPendingPercentage(
|
|
39
|
+
surveillanceSummary?.getEligibleForVlSampleNotTaken,
|
|
40
|
+
surveillanceSummary?.getEligibleForVl,
|
|
41
|
+
),
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const thirtyDaysrunningData = getThirtydaysRunninPercentage(
|
|
47
|
+
surveillanceSummary?.getMonthlyEligibleForVl.data,
|
|
48
|
+
surveillanceSummary?.getMonthlyEligibleForVlSampleNotTaken.data,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const lineGraphData = getThirtydaysRunninPendingPercentage(
|
|
52
|
+
surveillanceSummary?.getMonthlyEligibleForVl.data,
|
|
53
|
+
surveillanceSummary?.getMonthlyEligibleForVlSampleNotTaken.data,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
if (error) {
|
|
57
|
+
return <EmptyState subTitle={t('errorLoadingData', 'Error loading data')} />;
|
|
58
|
+
}
|
|
18
59
|
return (
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
60
|
+
<>
|
|
61
|
+
<div className={styles.chart}>
|
|
62
|
+
{isLoading ? (
|
|
63
|
+
<InlineLoading status="active" iconDescription="Loading" description="Loading data..." />
|
|
64
|
+
) : lineGraphData.length > 0 ? (
|
|
65
|
+
<BaseIndicatorTrendChart
|
|
66
|
+
data={lineGraphData}
|
|
67
|
+
title={t('missedoppotunityVL', 'Missed opportunity in viral load testing')}
|
|
68
|
+
yAxisTitle={t('percentageMissedVL', '% of missed opportunity VL')}
|
|
69
|
+
/>
|
|
70
|
+
) : (
|
|
71
|
+
<EmptyState subTitle={t('nomissedoppotunityVL', 'No missed opportunity VL data to display')} />
|
|
72
|
+
)}
|
|
73
|
+
</div>
|
|
74
|
+
<div className={styles.chart}>
|
|
75
|
+
{thirtyDaysrunningData.length > 0 ? (
|
|
76
|
+
<BaseProgressTrackingChart
|
|
77
|
+
data={thirtyDaysrunningData}
|
|
78
|
+
stackTitle={t('progressInAddressingDelayedVL', 'Progress in addressing delayed VL testing')}
|
|
79
|
+
leftAxiTtitle={t('percentageEligibleForVL', '% eligible for VL')}
|
|
80
|
+
/>
|
|
81
|
+
) : (
|
|
82
|
+
<EmptyState subTitle={t('noEligibleForVL', 'No eligible for VL data to display')} />
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
<div className={styles.chart}>
|
|
86
|
+
{surveillanceSummary?.getEligibleForVl > 0 ? (
|
|
87
|
+
<div className={styles.cumulativeChart}>
|
|
88
|
+
<BaseCumulativeProgressTrackingChart
|
|
89
|
+
data={cumulativeMissedoppotunityVLData}
|
|
90
|
+
title={t('cumulativeProgressMissedoppotunityVL', 'Cumulative Progress in addressing delayed VL Testing')}
|
|
91
|
+
/>
|
|
92
|
+
</div>
|
|
93
|
+
) : (
|
|
94
|
+
<EmptyState
|
|
95
|
+
subTitle={t('noCumulativeMissedoppotunityVL', 'No cumulative missed opportunity VL data to display')}
|
|
96
|
+
/>
|
|
97
|
+
)}
|
|
98
|
+
</div>
|
|
99
|
+
</>
|
|
32
100
|
);
|
|
33
101
|
};
|
|
34
102
|
|
|
@@ -4,10 +4,10 @@ import { useTranslation } from 'react-i18next';
|
|
|
4
4
|
import BaseIndicatorTrendChart from './base-indicator-trend-chart.component';
|
|
5
5
|
import BaseProgressTrackingChart from './base-progress-tracking-chart.component';
|
|
6
6
|
import useFacilityDashboardSurveillance from '../../hooks/useFacilityDashboardSurveillance';
|
|
7
|
-
import { useSurveillanceData } from '../../hooks/useSurveillanceData';
|
|
8
7
|
import EmptyState from '../empty-state/empty-state-log.components';
|
|
9
8
|
import styles from './charts.scss';
|
|
10
9
|
import { InlineLoading } from '@carbon/react';
|
|
10
|
+
import BaseCumulativeProgressTrackingChart from './base-cumulative-progress-tracking-chart.component';
|
|
11
11
|
|
|
12
12
|
type PBFWNotInPrepProps = {
|
|
13
13
|
startDate?: Date;
|
|
@@ -15,40 +15,89 @@ type PBFWNotInPrepProps = {
|
|
|
15
15
|
};
|
|
16
16
|
const PBFWNotInPrep: React.FC<PBFWNotInPrepProps> = ({ startDate, endDate }) => {
|
|
17
17
|
const { t } = useTranslation();
|
|
18
|
-
const {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const monthlyhighRiskPBFWNotOnPrepPatientData = useSurveillanceData(
|
|
18
|
+
const {
|
|
19
|
+
error,
|
|
20
|
+
isLoading,
|
|
22
21
|
surveillanceSummary,
|
|
23
|
-
|
|
22
|
+
getCompletedPercentage,
|
|
23
|
+
getPendingPercentage,
|
|
24
|
+
getThirtydaysRunninPercentage,
|
|
25
|
+
getThirtydaysRunninPendingPercentage,
|
|
26
|
+
} = useFacilityDashboardSurveillance(startDate, endDate);
|
|
27
|
+
|
|
28
|
+
const cumulativeHighRiskPBFWNotOnPrepValueData = {
|
|
29
|
+
data: [
|
|
30
|
+
{
|
|
31
|
+
group: 'Completed',
|
|
32
|
+
value: getCompletedPercentage(
|
|
33
|
+
surveillanceSummary?.getPregnantPostpartumNotInPrep,
|
|
34
|
+
surveillanceSummary?.getPregnantOrPostpartumClients,
|
|
35
|
+
),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
group: 'Pending',
|
|
39
|
+
value: getPendingPercentage(
|
|
40
|
+
surveillanceSummary?.getPregnantPostpartumNotInPrep,
|
|
41
|
+
surveillanceSummary?.getPregnantOrPostpartumClients,
|
|
42
|
+
),
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const thirtyDaysrunningData = getThirtydaysRunninPercentage(
|
|
48
|
+
surveillanceSummary?.getMonthlyPregnantOrPostpartumClients.data,
|
|
49
|
+
surveillanceSummary?.getMonthlyHighRiskPBFWNotOnPrep.data,
|
|
24
50
|
);
|
|
25
51
|
|
|
52
|
+
const lineGraphData = getThirtydaysRunninPendingPercentage(
|
|
53
|
+
surveillanceSummary?.getMonthlyPregnantOrPostpartumClients.data,
|
|
54
|
+
surveillanceSummary?.getMonthlyHighRiskPBFWNotOnPrep.data,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
if (error) {
|
|
58
|
+
return <EmptyState subTitle={t('errorLoadingData', 'Error loading data')} />;
|
|
59
|
+
}
|
|
60
|
+
|
|
26
61
|
return (
|
|
27
62
|
<div>
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
63
|
+
<div className={styles.chart}>
|
|
64
|
+
{lineGraphData.length > 0 ? (
|
|
65
|
+
<BaseIndicatorTrendChart
|
|
66
|
+
data={lineGraphData}
|
|
67
|
+
title={t('prepNotlinked', 'High risk +ve PBFW not on PrEP')}
|
|
68
|
+
yAxisTitle={t('percentageHightRiskPBFW', '% of high risk PBFW not on PrEP')}
|
|
69
|
+
/>
|
|
70
|
+
) : (
|
|
71
|
+
<EmptyState subTitle={t('noHighRiskPBFW', 'No high risk PBFW not on PrEP data to display')} />
|
|
72
|
+
)}
|
|
73
|
+
</div>
|
|
74
|
+
<div className={styles.chart}>
|
|
75
|
+
{thirtyDaysrunningData.length > 0 ? (
|
|
76
|
+
<BaseProgressTrackingChart
|
|
77
|
+
data={thirtyDaysrunningData}
|
|
78
|
+
stackTitle={t('progressEnrollingHighRiskPBFWToPrEP', 'Progress enroling high risk PBFW to PrEP')}
|
|
79
|
+
leftAxiTtitle={t('percentageOfPregnantOrPostpartumPatients', '% of pregnant or postpartum patients')}
|
|
80
|
+
/>
|
|
81
|
+
) : (
|
|
82
|
+
<EmptyState subTitle={t('noHighRiskPBFW', 'No high risk PBFW not on PrEP data to display')} />
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
<br />
|
|
86
|
+
<div className={styles.chart}>
|
|
87
|
+
{surveillanceSummary?.getPregnantOrPostpartumClients > 0 ? (
|
|
88
|
+
<div className={styles.cumulativeChart}>
|
|
89
|
+
<BaseCumulativeProgressTrackingChart
|
|
90
|
+
data={cumulativeHighRiskPBFWNotOnPrepValueData}
|
|
91
|
+
title={t(
|
|
92
|
+
'cumulativeProgressMissedoppotunityVL',
|
|
93
|
+
'Cumulative progress of missed opportunity in viral load testing',
|
|
94
|
+
)}
|
|
95
|
+
/>
|
|
49
96
|
</div>
|
|
50
|
-
|
|
51
|
-
|
|
97
|
+
) : (
|
|
98
|
+
<EmptyState subTitle={t('noHighRiskPBFW', 'No High risk PBFW Not on PrEP data to display')} />
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
52
101
|
</div>
|
|
53
102
|
);
|
|
54
103
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
import FacilityDashboardHeader from '../components/header/header.component';
|
|
4
4
|
import HIVPositiveNotLinkedToART from './charts/hiv-not-linked-to-art.component';
|
|
@@ -11,12 +11,17 @@ import DNAPCRPendingCharts from './charts/dna-pcr-pending-chart.component';
|
|
|
11
11
|
import HEIFinalOutcomesChart from './charts/hei-final-outcome.component';
|
|
12
12
|
import { SurveillanceindicatorsFilter } from '../types';
|
|
13
13
|
import { Tabs, TabList, Tab, TabPanels, TabPanel } from '@carbon/react';
|
|
14
|
+
import { formattedDate, thirtyDays, today } from '../constants';
|
|
15
|
+
import { CardHeader } from '@openmrs/esm-patient-common-lib/src';
|
|
16
|
+
import styles from './surveillance.scss';
|
|
14
17
|
const SurveillancelanceDashboard = () => {
|
|
15
18
|
const { t } = useTranslation();
|
|
16
19
|
const [currFilters, setCurrFilters] = useState<SurveillanceindicatorsFilter>({
|
|
17
20
|
indicator: 'getHivPositiveNotLinked',
|
|
18
21
|
});
|
|
19
22
|
const [activeTab, setActiveTab] = useState(0);
|
|
23
|
+
const defaultStartDate = useMemo(() => new Date(thirtyDays()), []);
|
|
24
|
+
const defaultEndDate = useMemo(() => new Date(today()), []);
|
|
20
25
|
|
|
21
26
|
return (
|
|
22
27
|
<div>
|
|
@@ -24,8 +29,8 @@ const SurveillancelanceDashboard = () => {
|
|
|
24
29
|
|
|
25
30
|
<Tabs onChange={({ selectedIndex }) => setActiveTab(selectedIndex)}>
|
|
26
31
|
<TabList>
|
|
27
|
-
<Tab>{t('
|
|
28
|
-
<Tab>{t('
|
|
32
|
+
<Tab>{t('realTimeGapReview', 'Realtime gap review')}</Tab>
|
|
33
|
+
<Tab>{t('progressTracker', 'Progress tracker')}</Tab>
|
|
29
34
|
</TabList>
|
|
30
35
|
<TabPanels>
|
|
31
36
|
<TabPanel>
|
|
@@ -34,26 +39,26 @@ const SurveillancelanceDashboard = () => {
|
|
|
34
39
|
<SurveillanceSummaryCards startDate={currFilters.startdate} endDate={currFilters.endDate} />
|
|
35
40
|
</>
|
|
36
41
|
</TabPanel>
|
|
37
|
-
<TabPanel>
|
|
42
|
+
<TabPanel className={styles.tabPanel}>
|
|
38
43
|
<>
|
|
39
44
|
<SurveillanceFilters filters={currFilters} onFiltersChange={setCurrFilters} tabSelected={activeTab} />
|
|
40
45
|
{currFilters.indicator === 'getHivPositiveNotLinked' && (
|
|
41
|
-
<HIVPositiveNotLinkedToART startDate={
|
|
46
|
+
<HIVPositiveNotLinkedToART startDate={defaultStartDate} endDate={defaultEndDate} />
|
|
42
47
|
)}
|
|
43
48
|
{currFilters.indicator === 'getPregnantPostpartumNotInPrep' && (
|
|
44
|
-
<PBFWNotInPrep startDate={
|
|
49
|
+
<PBFWNotInPrep startDate={defaultStartDate} endDate={defaultEndDate} />
|
|
45
50
|
)}
|
|
46
51
|
{currFilters.indicator === 'getEligibleForVlSampleNotTaken' && (
|
|
47
|
-
<DelayedEACCharts startDate={
|
|
52
|
+
<DelayedEACCharts startDate={defaultStartDate} endDate={defaultEndDate} />
|
|
48
53
|
)}
|
|
49
54
|
{currFilters.indicator === 'getVirallyUnsuppressedWithoutEAC' && (
|
|
50
|
-
<MissedOpportunityChart startDate={
|
|
55
|
+
<MissedOpportunityChart startDate={defaultStartDate} endDate={defaultEndDate} />
|
|
51
56
|
)}
|
|
52
57
|
{currFilters.indicator === 'getHeiSixToEightWeeksWithoutPCRResults' && (
|
|
53
|
-
<DNAPCRPendingCharts startDate={
|
|
58
|
+
<DNAPCRPendingCharts startDate={defaultStartDate} endDate={defaultEndDate} />
|
|
54
59
|
)}
|
|
55
60
|
{currFilters.indicator === 'getHei24MonthsWithoutDocumentedOutcome' && (
|
|
56
|
-
<HEIFinalOutcomesChart startDate={
|
|
61
|
+
<HEIFinalOutcomesChart startDate={defaultStartDate} endDate={defaultEndDate} />
|
|
57
62
|
)}
|
|
58
63
|
</>
|
|
59
64
|
</TabPanel>
|
|
@@ -5,6 +5,7 @@ import { SurveillanceindicatorsFilter } from '../types';
|
|
|
5
5
|
import styles from './surveillance.scss';
|
|
6
6
|
import { DATE_PICKER_CONTROL_FORMAT, DATE_PICKER_FORMAT, today } from '../constants';
|
|
7
7
|
import { formatDatetime } from '@openmrs/esm-framework';
|
|
8
|
+
import { CardHeader } from '@openmrs/esm-patient-common-lib/src';
|
|
8
9
|
|
|
9
10
|
type Props = {
|
|
10
11
|
filters: SurveillanceindicatorsFilter;
|
|
@@ -16,7 +17,7 @@ const SurveillanceFilters: React.FC<Props> = ({ filters, onFiltersChange, tabSel
|
|
|
16
17
|
const MaxDate: Date = today();
|
|
17
18
|
const indicators = [
|
|
18
19
|
{ key: 'getHivPositiveNotLinked', label: 'HIV +ve not linked' },
|
|
19
|
-
{ key: 'getPregnantPostpartumNotInPrep', label: 'High risk
|
|
20
|
+
{ key: 'getPregnantPostpartumNotInPrep', label: 'High risk -ve PBFW not enrolled to PrEP' },
|
|
20
21
|
{ key: 'getEligibleForVlSampleNotTaken', label: 'Delayed EAC' },
|
|
21
22
|
{ key: 'getVirallyUnsuppressedWithoutEAC', label: 'Missed opportunity VL' },
|
|
22
23
|
{ key: 'getHeiSixToEightWeeksWithoutPCRResults', label: 'DNA-PCR Pending' },
|
|
@@ -24,7 +25,7 @@ const SurveillanceFilters: React.FC<Props> = ({ filters, onFiltersChange, tabSel
|
|
|
24
25
|
];
|
|
25
26
|
return (
|
|
26
27
|
<div className={styles.filtersContainer}>
|
|
27
|
-
{tabSelected === 0
|
|
28
|
+
{tabSelected === 0 ? (
|
|
28
29
|
<DatePicker
|
|
29
30
|
datePickerType="range"
|
|
30
31
|
minDate={formatDatetime(MaxDate)}
|
|
@@ -52,23 +53,29 @@ const SurveillanceFilters: React.FC<Props> = ({ filters, onFiltersChange, tabSel
|
|
|
52
53
|
size="md"
|
|
53
54
|
/>
|
|
54
55
|
</DatePicker>
|
|
56
|
+
) : (
|
|
57
|
+
<div className={styles.cardHeaderContainer}>
|
|
58
|
+
<CardHeader title={t('thirtyDaysProgressTracker', 'Thirty days progress tracker')}>{''}</CardHeader>
|
|
59
|
+
</div>
|
|
55
60
|
)}
|
|
56
61
|
|
|
57
62
|
{tabSelected === 1 && (
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
<div className={styles.dropdownContainer}>
|
|
64
|
+
<Dropdown
|
|
65
|
+
className={styles.filterInput}
|
|
66
|
+
autoAlign
|
|
67
|
+
id="filters"
|
|
68
|
+
itemToString={(item: { key: string; label: string }) =>
|
|
69
|
+
indicators.find(({ key }) => key === item.key)?.label ?? ''
|
|
70
|
+
}
|
|
71
|
+
items={indicators}
|
|
72
|
+
selectedItem={indicators.find(({ key }) => key === filters.indicator)}
|
|
73
|
+
label={t('indicator', 'Indicator')}
|
|
74
|
+
onChange={({ selectedItem: { key } }) => {
|
|
75
|
+
onFiltersChange({ ...filters, indicator: key });
|
|
76
|
+
}}
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
72
79
|
)}
|
|
73
80
|
</div>
|
|
74
81
|
);
|
|
@@ -7,10 +7,23 @@
|
|
|
7
7
|
display: flex;
|
|
8
8
|
flex-direction: row;
|
|
9
9
|
gap: layout.$spacing-05;
|
|
10
|
-
justify-content:
|
|
10
|
+
justify-content: space-between;
|
|
11
11
|
flex-wrap: wrap;
|
|
12
|
+
align-items: center;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
.filterInput {
|
|
15
16
|
width: 330px;
|
|
16
17
|
}
|
|
18
|
+
|
|
19
|
+
.cardHeaderContainer {
|
|
20
|
+
flex: 1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.dropdownContainer {
|
|
24
|
+
margin-left: auto;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.tabPanel {
|
|
28
|
+
background-color: colors.$white;
|
|
29
|
+
}
|
package/src/types/index.ts
CHANGED
|
@@ -21,6 +21,12 @@ export type SurveillanceSummary = {
|
|
|
21
21
|
getMonthlyEligibleForVlSampleNotTaken: HivPositiveNotLinkedData;
|
|
22
22
|
getMonthlyHei24MonthsWithoutDocumentedOutcome: HivPositiveNotLinkedData;
|
|
23
23
|
getMonthlyVirallyUnsuppressedWithoutEAC: HivPositiveNotLinkedData;
|
|
24
|
+
getMonthlyPatientsTestedHivPositive: HivPositiveNotLinkedData;
|
|
25
|
+
getMonthlyPregnantOrPostpartumClients: HivPositiveNotLinkedData;
|
|
26
|
+
getMonthlyHeiSixToEightWeeksOld: HivPositiveNotLinkedData;
|
|
27
|
+
getMonthlyEligibleForVl: HivPositiveNotLinkedData;
|
|
28
|
+
getMonthlyHei24MonthsOld: HivPositiveNotLinkedData;
|
|
29
|
+
getMonthlyVirallyUnsuppressed: HivPositiveNotLinkedData;
|
|
24
30
|
};
|
|
25
31
|
|
|
26
32
|
export type IndicationMode = 'decreasing' | 'increasing';
|
|
@@ -37,3 +43,11 @@ export type HivPositiveNotLinked = {
|
|
|
37
43
|
value: number;
|
|
38
44
|
group?: string;
|
|
39
45
|
};
|
|
46
|
+
|
|
47
|
+
export type Linkage = {
|
|
48
|
+
group?: string;
|
|
49
|
+
value?: number;
|
|
50
|
+
};
|
|
51
|
+
export type LinkageData = {
|
|
52
|
+
data: Array<Linkage>;
|
|
53
|
+
};
|
package/translations/en.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"aboveSiteDashboard": "Above site facility Dashboard",
|
|
3
3
|
"aboveSiteFacilityDashboard": "Above site facility Dashboard",
|
|
4
|
+
"cumulativeProgressDelayedEAC": "Cumulative Progress in addressing delayed EAC",
|
|
5
|
+
"cumulativeProgressDnapcrPending": "Cumulative Progress in addressing HEI PCR results",
|
|
6
|
+
"cumulativeProgressHeiFinalOutcomes": "Cumulative progress in addressing HEI final outcome",
|
|
7
|
+
"cumulativeProgressMissedoppotunityVL": "Cumulative progress of missed opportunity in viral load testing",
|
|
8
|
+
"cumulativeProgressOfAddressingLinkedToArt": "Cumulative progress of addressing Linkage to ART",
|
|
4
9
|
"day": "Day",
|
|
5
|
-
"days": "Days",
|
|
6
10
|
"delayedEAC": "Delayed enhanced adherence counselling",
|
|
7
11
|
"delayedVLTesting": "Number of client on ART that visited, were eligible for VL sampling and no VL was done",
|
|
8
12
|
"dnapcrPending": "HEI (6-8 weeks) without DNA-PCR Results",
|
|
9
13
|
"endDate": "End date",
|
|
14
|
+
"errorLoadingData": "Error loading data",
|
|
10
15
|
"facilitydashboard": "Facility Dashboard",
|
|
11
16
|
"facilitydashboardLeftPannel": "facility Dashboard Left Panel",
|
|
12
17
|
"heiFinalOutcomes": "Undocumented final outcome",
|
|
@@ -16,30 +21,44 @@
|
|
|
16
21
|
"hivPositiveClientsnotLinkedToArt": "HIV Positive Clients not linked to ART",
|
|
17
22
|
"hivPositiveNotLinkedToART": "HIV +VE Not linked to ART",
|
|
18
23
|
"indicator": "Indicator",
|
|
19
|
-
"kpi": "KPI",
|
|
20
24
|
"missedoppotunityVL": "Missed opportunity in viral load testing",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
25
|
+
"noCumulativeDnapcrPending": "No cumulative HEI (6-8 weeks) without DNA-PCR data to display",
|
|
26
|
+
"noCumulativeHivPositiveNotLinked": "No cumulative HIV +VE Not linked to ART data to display",
|
|
27
|
+
"noCumulativeMissedoppotunityVL": "No cumulative missed opportunity VL data to display",
|
|
28
|
+
"noDelayedEAC": "No delayed EAC data to display",
|
|
29
|
+
"noEligibleForVL": "No eligible for VL data to display",
|
|
30
|
+
"noHEIFinalOutcome": "No HEI final outcome data to display",
|
|
23
31
|
"noheiFinalOutcomes": "No undocumented final outcome data to display",
|
|
24
32
|
"noHighRiskPBFW": "No High risk PBFW Not on PrEP data to display",
|
|
25
33
|
"noHivPositiveNotLinked": "No HIV +VE Not linked to ART data to display",
|
|
26
34
|
"nomissedoppotunityVL": "No missed opportunity VL data to display",
|
|
27
35
|
"noPendingPCRDNAResults": "No pending PCR DNA results data to display",
|
|
28
36
|
"numberDelayedEAC": "Number of Delayed EAC",
|
|
29
|
-
"numberHEIOutcome": "Number of undocumented final outcome",
|
|
30
|
-
"numberHightRiskPBFW": "Number of High risk PBFW Not on PrEP",
|
|
31
|
-
"numberHivPositive": "Number HIV positive",
|
|
32
|
-
"numberMissedVL": "Number of missed opportunity VL",
|
|
33
|
-
"numberOfPendingPCRDNAResults": "Number of HEI (6-8 weeks) without DNA-PCR Results",
|
|
34
|
-
"numberTestedPositiveNotLinked": "Number tested positive not linked",
|
|
35
37
|
"pbfwNotLinked": "High risk -ve PBFW Not linked to PrEP",
|
|
36
|
-
"
|
|
38
|
+
"percentageDelayedEAC": "% Delayed EAC",
|
|
39
|
+
"percentageEligibleForVL": "% eligible for VL",
|
|
40
|
+
"percentageHEIFinalOutcome": "% HEI final outcome",
|
|
41
|
+
"percentageHEIOutcome": "% undocumented final outcome",
|
|
42
|
+
"percentageHEIPCRResults": "% HEI (6-8 weeks) PCR result",
|
|
43
|
+
"percentageHightRiskPBFW": "% of high risk PBFW not on PrEP",
|
|
44
|
+
"percentageHivPositive": "% HIV positive",
|
|
45
|
+
"percentageMissedVL": "% of missed opportunity VL",
|
|
46
|
+
"percentageOfPendingPCRDNAResults": "% HEI (6-8 weeks) without DNA-PCR results",
|
|
47
|
+
"percentageOfPregnantOrPostpartumPatients": "% of pregnant or postpartum patients",
|
|
48
|
+
"percentageTestedPositiveNotLinked": "% tested positive not linked",
|
|
37
49
|
"prepNotlinked": "High risk -ve PBFW not on PrEP",
|
|
50
|
+
"progressEnrollingHighRiskPBFWToPrEP": "Progress enroling high risk PBFW to PrEP",
|
|
51
|
+
"progressInAddressingDelayedEAC": "Progress in addressing delayed EAC",
|
|
52
|
+
"progressInAddressingDelayedVL": "Progress in addressing delayed VL testing",
|
|
53
|
+
"progressInAddressingHEIFinalOutcome": "Progress in addressing HEI final Outcome",
|
|
54
|
+
"progressInAddressingHEIPCRResults ": "Progress in addressing HEI PCR results",
|
|
38
55
|
"progressInAddressingLinkedToArt": "Progress in addressing Linkage to ART",
|
|
39
|
-
"
|
|
56
|
+
"progressTracker": "Progress tracker",
|
|
57
|
+
"realTimeGapReview": "Realtime gap review",
|
|
40
58
|
"startDate": "Start date",
|
|
41
59
|
"surveillance": "Surveillance",
|
|
42
60
|
"surveillanceSummary": "Surveillance Summary",
|
|
61
|
+
"thirtyDaysProgressTracker": "Thirty days progress tracker",
|
|
43
62
|
"viewOnSuperset": "View on Superset",
|
|
44
63
|
"virallyUnSuppressedWithoutAdherenceCounselingFor2Weeks": "Virally Unsuppressed clients without enhanced adherence counseling (EAC) within 2 weeks"
|
|
45
64
|
}
|