diff --git a/src/actions/CT/OTZ/OtzTotalWithDurableVlResultsActions.js b/src/actions/CT/OTZ/OtzTotalWithDurableVlResultsActions.js new file mode 100644 index 00000000..a59efe35 --- /dev/null +++ b/src/actions/CT/OTZ/OtzTotalWithDurableVlResultsActions.js @@ -0,0 +1,36 @@ +import moment from 'moment'; +import { CACHING, PAGES } from '../../../constants'; +import * as actionTypes from '../../types'; +import { getAll } from '../../../views/Shared/Api'; + +export const loadOtzTotalWithDurableVLResults = () => async (dispatch, getState) => { + const diffInMinutes = moment().diff( + moment(getState().otzTotalWithDurableVlResults.lastFetch), + 'minutes' + ); + if (getState().ui.ctTab !== 'otz' && + getState().ui.currentPage !== PAGES.ct) { + return; + } + else if ((diffInMinutes < CACHING.LONG) && getState().filters.filtered === false) { + return; + } else { + await dispatch(fetchOtzTotalWithDurableVLResults()); + } +} + +export const fetchOtzTotalWithDurableVLResults = () => async (dispatch, getState) => { + dispatch({ type: actionTypes.CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_REQUEST }); + const params = { + county: getState().filters.counties, + subCounty: getState().filters.subCounties, + facility: getState().filters.facilities, + partner: getState().filters.partners, + agency: getState().filters.agencies, + project: getState().filters.projects, + gender: getState().filters.genders, + datimAgeGroup: getState().filters.datimAgeGroups + }; + const response = await getAll('care-treatment/getOtzTotalWithDurableVl', params); + dispatch({ type: actionTypes.CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_FETCH, payload: { filtered: getState().filters.filtered, list: response }}); +}; diff --git a/src/actions/types.js b/src/actions/types.js index 688cb4a1..9ca05a22 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -586,6 +586,11 @@ export const CT_OTZ_ENROLLED_FAILED = 'CT_OTZ_ENROLLED_FAILED' export const CT_OTZ_TOTAL_WITH_VL_RESULTS_REQUEST = 'CT_OTZ_TOTAL_WITH_VL_RESULTS_REQUEST' export const CT_OTZ_TOTAL_WITH_VL_RESULTS_FETCH = 'CT_OTZ_TOTAL_WITH_VL_RESULTS_FETCH' export const CT_OTZ_TOTAL_WITH_VL_RESULTS_FAILED = 'CT_OTZ_TOTAL_WITH_VL_RESULTS_FAILED' + +export const CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_REQUEST = 'CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_REQUEST' +export const CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_FETCH = 'CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_FETCH' +export const CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_FAILED = 'CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_FAILED' + export const CT_OTZ_TOTAL_WITH_VL_RESULTS_LESS_THAN_1000_REQUEST = 'CT_OTZ_TOTAL_WITH_VL_RESULTS_LESS_THAN_1000_REQUEST' export const CT_OTZ_TOTAL_WITH_VL_RESULTS_LESS_THAN_1000_FETCH = 'CT_OTZ_TOTAL_WITH_VL_RESULTS_LESS_THAN_1000_FETCH' export const CT_OTZ_TOTAL_WITH_VL_RESULTS_LESS_THAN_1000_FAILED = 'CT_OTZ_TOTAL_WITH_VL_RESULTS_LESS_THAN_1000_FAILED' diff --git a/src/reducers/CT/OTZ/otzTotalWithDurableVlResults.js b/src/reducers/CT/OTZ/otzTotalWithDurableVlResults.js new file mode 100644 index 00000000..a1721b62 --- /dev/null +++ b/src/reducers/CT/OTZ/otzTotalWithDurableVlResults.js @@ -0,0 +1,31 @@ +import * as actionTypes from "../../../actions/types"; + +const initialState = { + lastFetch: null, + loading: false, + listUnfiltered: [], + listFiltered: [], +}; + +export default (state = initialState, action) => { + let newState = { ...state }; + switch (action.type) { + case actionTypes.CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_REQUEST: + newState.loading = true; + return newState; + case actionTypes.CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_FETCH: + if (action.payload.filtered === true) { + newState.listFiltered = action.payload.list; + } else { + newState.listUnfiltered = action.payload.list; + newState.lastFetch = Date.now(); + } + newState.loading = false; + return newState; + case actionTypes.CT_OTZ_TOTAL_WITH_DURABLE_VL_RESULTS_FAILED: + newState.loading = false; + return newState; + default: + return state; + } +} diff --git a/src/reducers/index.js b/src/reducers/index.js index fdde4b82..06360418 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -178,6 +178,7 @@ import otzVlSuppressionByAgeNotEnrolled from './CT/OTZ/otzVlSuppressionByAgeNotE import otzVlSuppressionByCountyNotEnrolled from './CT/OTZ/otzVlSuppressionByCountyNotEnrolled'; import otzVlSuppressionByPartnerNotEnrolled from './CT/OTZ/otzVlSuppressionByPartnerNotEnrolled'; import otzVlSuppressionBySexNotEnrolled from './CT/OTZ/otzVlSuppressionBySexNotEnrolled'; +import otzTotalWithDurableVlResults from './CT/OTZ/otzTotalWithDurableVlResults'; import CovidAdultPLHIVCurrentOnTreatment from './CT/Covid/covidAdultPLHIVCurrentOnTreatment'; import CovidAdultPLHIVPartiallyVaccinated from './CT/Covid/covidAdultPLHIVPartiallyVaccinated'; @@ -498,6 +499,7 @@ export default combineReducers({ otzVlSuppressionBySexNotEnrolled, otzVlSuppressionByPartnerNotEnrolled, otzVlSuppressionByCountyNotEnrolled, + otzTotalWithDurableVlResults, ovcOverallServ, ovcServByGender, diff --git a/src/selectors/CT/OTZ/otzTotalWithDurableVlResults.js b/src/selectors/CT/OTZ/otzTotalWithDurableVlResults.js new file mode 100644 index 00000000..b7a9d7f2 --- /dev/null +++ b/src/selectors/CT/OTZ/otzTotalWithDurableVlResults.js @@ -0,0 +1,12 @@ +import { createSelector } from 'reselect'; + +const filtered = state => state.filters.filtered; +const listFiltered = state => state.otzTotalWithDurableVlResults.listFiltered; +const listUnfiltered = state => state.otzTotalWithDurableVlResults.listUnfiltered; + +export const getOtzTotalWithDurableVlResults = createSelector( + [listUnfiltered, listFiltered, filtered], + (listUnfiltered, listFiltered, filtered) => { + return filtered ? listFiltered : listUnfiltered; + } +); diff --git a/src/views/CT/CT.js b/src/views/CT/CT.js index 3bf98fd2..dbd30912 100644 --- a/src/views/CT/CT.js +++ b/src/views/CT/CT.js @@ -362,6 +362,7 @@ import { loadIITTracingOutcomes } from './../../actions/CT/TreatmentOutcomes/IIT import { loadViralLoadUptakeUToU } from '../../actions/CT/ViralLoad/viralLoadUptakeUToUActions'; import { loadViralLoadCategorizationUToU } from '../../actions/CT/ViralLoad/viralLoadCategorizationUToUActions'; import { loadAlhivOnArtByAgeSex } from '../../actions/CT/OTZ/OtzAlhivOnArtByAgeSexActions'; +import { loadOtzTotalWithDurableVLResults } from '../../actions/CT/OTZ/OtzTotalWithDurableVlResultsActions'; const NewOnArt = Loadable({ loader: () => import('./NewOnArt/NewOnArt'), loading: Loading, delay: LOADING_DELAY }); const CurrentOnArt = Loadable({ @@ -730,6 +731,7 @@ const CT = () => { dispatch(loadOtzVlSuppressionBySexNotEnrolled()); dispatch(loadOtzVlSuppressionByPartnerNotEnrolled()); dispatch(loadOtzVlSuppressionByCountyNotEnrolled()); + dispatch(loadOtzTotalWithDurableVLResults()); dispatch(loadAlhivOnArtByAgeSex()); break; case 'ovc': diff --git a/src/views/CT/OTZ/OTZOverview.js b/src/views/CT/OTZ/OTZOverview.js index cb1b2169..95fa0c33 100644 --- a/src/views/CT/OTZ/OTZOverview.js +++ b/src/views/CT/OTZ/OTZOverview.js @@ -4,6 +4,7 @@ import { useSelector } from 'react-redux'; import * as otzTotalAdolescentsSelector from '../../../selectors/CT/OTZ/otzTotalAdolescents'; import * as otzEnrolledSelector from '../../../selectors/CT/OTZ/otzEnrolled'; import * as otzTotalWithVlResultsSelector from '../../../selectors/CT/OTZ/otzTotalWithVlResults'; +import * as otzTotalWithDurableVlResultsSelector from '../../../selectors/CT/OTZ/otzTotalWithDurableVlResults'; import * as otzTotalWithWithResultsLessThan1000Selector from '../../../selectors/CT/OTZ/otzTotalWithWithResultsLessThan1000'; import { formatNumber, roundNumber } from '../../../utils/utils'; import DataCard from '../../Shared/DataCard'; @@ -20,6 +21,9 @@ const OTZOverview = () => { const otzTotalWithVlResults = useSelector( otzTotalWithVlResultsSelector.getOtzTotalWithVlResults ); + const otzTotalWithDurableVlResults = useSelector( + otzTotalWithDurableVlResultsSelector.getOtzTotalWithDurableVlResults + ); const otzTotalWithVlResultsLessThan1000 = useSelector( otzTotalWithWithResultsLessThan1000Selector.getOtzTotalWithVlResultsLessThan1000 ); @@ -48,6 +52,15 @@ const OTZOverview = () => { otzEnrolled.enrolledInOTZ) * 100 : 0, + + totalWithDurableVlResults: otzTotalWithDurableVlResults?.totalDurable, + totalWithDurableVlResultsPerc: + parseInt(otzTotalWithVlResultsLessThan1000.totalWithVlLessThan1000, 10) > 0 + ? (otzTotalWithDurableVlResults?.totalDurable / + otzTotalWithVlResultsLessThan1000.totalWithVlLessThan1000) * + 100 + : 0, + totalWithVlLessThan1000: otzTotalWithVlResultsLessThan1000.totalWithVlLessThan1000, totalWithVlLessThan1000Perc: @@ -62,6 +75,7 @@ const OTZOverview = () => { otzEnrolled, otzTotalWithVlResults, otzTotalWithVlResultsLessThan1000, + otzTotalWithDurableVlResults, ]); useEffect(() => { @@ -69,48 +83,65 @@ const OTZOverview = () => { }, [loadOtzTotalAdolescents]); return ( - - - - - - - - - - - - - - + <> + + + + + + + + + + + + + + + + + + + + ); }; diff --git a/src/views/CT/OTZ/OtzEnrollmentOnOTZBySex.js b/src/views/CT/OTZ/OtzEnrollmentOnOTZBySex.js index 502cf6ce..280f10ce 100644 --- a/src/views/CT/OTZ/OtzEnrollmentOnOTZBySex.js +++ b/src/views/CT/OTZ/OtzEnrollmentOnOTZBySex.js @@ -5,41 +5,22 @@ import HighchartsReact from 'highcharts-react-official'; import { useSelector } from 'react-redux'; import * as otzEnrollmentAmongAlhivBySex from '../../../selectors/CT/OTZ/otzEnrollmentAmongAlhivBySex'; -import * as otzTotalAdolescentsSelector from '../../../selectors/CT/OTZ/otzTotalAdolescents'; const OtzEnrollmentOnOTZBySex = () => { const [otzEnrollmentAmongAlHivOnArtBySex, setOtzEnrollmentAmongAlHivOnArtBySex] = useState({}); const otzEnrollmentsBySex = useSelector(otzEnrollmentAmongAlhivBySex.getOtzEnrollmentAmongAlHivOnArtBySex); - const adolescents = useSelector(otzTotalAdolescentsSelector.getOtzTotalAdolescentsByGender); - let femalePercentage = 0; let femaleTxCurr = 0; - let malePercentage = 0; let maleTxCurr = 0; const femaleVals = otzEnrollmentsBySex.filter(obj => obj.Gender === 'Female'); const maleVals = otzEnrollmentsBySex.filter(obj => obj.Gender === 'Male'); if (femaleVals.length > 0) { - const femaleAdolescents = adolescents.filter(obj => obj.Gender === 'Female'); - if (femaleAdolescents.length > 0) { - const totalFemaleAdolescents = femaleAdolescents[0].totalAdolescents; - if (totalFemaleAdolescents > 0) { - femalePercentage = ((femaleVals[0].TXCurr/totalFemaleAdolescents)*100); - } - } femaleTxCurr = femaleVals[0].TXCurr; } if (maleVals.length > 0) { - console.log(maleVals) - const maleAdolescents = adolescents.filter(obj => obj.Gender === 'Male'); - if (maleAdolescents.length > 0) { - const totalMaleAdolescents = maleAdolescents[0].totalAdolescents; - if (totalMaleAdolescents > 0) { - malePercentage = ((maleVals[0].TXCurr/totalMaleAdolescents)*100); - } - } maleTxCurr = maleVals[0].TXCurr; } diff --git a/src/views/CT/OTZ/OtzEnrollmentTrends.js b/src/views/CT/OTZ/OtzEnrollmentTrends.js index 86e2f17c..e4bbd5fc 100644 --- a/src/views/CT/OTZ/OtzEnrollmentTrends.js +++ b/src/views/CT/OTZ/OtzEnrollmentTrends.js @@ -16,7 +16,7 @@ const OtzEnrollmentTrends = () => { const loadOtzEnrollmentAmongAlhivOnArtByMonth = useCallback(async () => { setEnrollmentAmongAlhivOnArtByMonth({ chart: { - type: 'column', + type: 'line', }, title: { text: '', @@ -28,8 +28,6 @@ const OtzEnrollmentTrends = () => { crosshair: true, }, yAxis: { - // type: 'logarithmic', - // minorTickInterval: 0.1, title: { text: 'NUMBER OF PATIENTS', },