diff --git a/packages/openchs-android/package-lock.json b/packages/openchs-android/package-lock.json
index 459c01f64..267d5214a 100644
--- a/packages/openchs-android/package-lock.json
+++ b/packages/openchs-android/package-lock.json
@@ -5,7 +5,6 @@
"requires": true,
"packages": {
"": {
- "name": "openchs-android",
"version": "0.0.1",
"hasInstallScript": true,
"license": "AGPL-3.0",
@@ -29,7 +28,7 @@
"lodash": "4.17.21",
"moment": "2.29.4",
"native-base": "3.4.9",
- "openchs-models": "1.27.17",
+ "openchs-models": "1.27.18",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-native": "0.69.7",
@@ -2342,6 +2341,7 @@
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
"graceful-fs": "^4.2.9",
"jest-regex-util": "^28.0.2",
"jest-util": "^28.1.3",
@@ -3066,6 +3066,7 @@
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
"graceful-fs": "^4.2.9",
"jest-regex-util": "^28.0.2",
"jest-util": "^28.1.3",
@@ -3310,6 +3311,7 @@
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
"graceful-fs": "^4.2.9",
"jest-regex-util": "^28.0.2",
"jest-util": "^28.1.3",
@@ -12390,6 +12392,7 @@
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
"graceful-fs": "^4.2.9",
"jest-regex-util": "^27.5.1",
"jest-serializer": "^27.5.1",
@@ -13042,6 +13045,7 @@
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
"graceful-fs": "^4.2.9",
"jest-regex-util": "^28.0.2",
"jest-util": "^28.1.3",
@@ -13330,6 +13334,7 @@
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
"graceful-fs": "^4.2.9",
"jest-regex-util": "^28.0.2",
"jest-util": "^28.1.3",
@@ -13661,6 +13666,7 @@
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
"graceful-fs": "^4.2.9",
"jest-regex-util": "^28.0.2",
"jest-util": "^28.1.3",
@@ -14021,6 +14027,7 @@
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
"graceful-fs": "^4.2.9",
"jest-regex-util": "^28.0.2",
"jest-util": "^28.1.3",
@@ -15288,6 +15295,9 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+ "dependencies": {
+ "graceful-fs": "^4.1.6"
+ },
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
@@ -15323,6 +15333,9 @@
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
"integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==",
+ "dependencies": {
+ "graceful-fs": "^4.1.9"
+ },
"optionalDependencies": {
"graceful-fs": "^4.1.9"
}
@@ -17164,6 +17177,9 @@
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
"integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==",
+ "dependencies": {
+ "graceful-fs": "^4.1.6"
+ },
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
@@ -18643,9 +18659,9 @@
}
},
"node_modules/openchs-models": {
- "version": "1.27.17",
- "resolved": "https://registry.npmjs.org/openchs-models/-/openchs-models-1.27.17.tgz",
- "integrity": "sha512-oAhrPVy+UMOHlSZv7eNwK6LtVyTsjjml4Jcbsid+IZVBCrCJK8lUbPlJxfVpphkeXuYZa6npNXk+vYXiP/ZmpA==",
+ "version": "1.27.18",
+ "resolved": "https://registry.npmjs.org/openchs-models/-/openchs-models-1.27.18.tgz",
+ "integrity": "sha512-i6Ku41kAq1J6+F0wmKs3zWqP7Zigy+RcOPWoxCaeKrzAczJR6cZI3kOADEk7nD4w9n9uOGMyQ5sLJk7F8Nr2HQ==",
"peerDependencies": {
"lodash": "*",
"moment": "*"
@@ -23642,8 +23658,10 @@
"integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==",
"dev": true,
"dependencies": {
+ "chokidar": "^3.4.1",
"graceful-fs": "^4.1.2",
- "neo-async": "^2.5.0"
+ "neo-async": "^2.5.0",
+ "watchpack-chokidar2": "^2.0.1"
},
"optionalDependencies": {
"chokidar": "^3.4.1",
@@ -23750,6 +23768,7 @@
"anymatch": "^2.0.0",
"async-each": "^1.0.1",
"braces": "^2.3.2",
+ "fsevents": "^1.2.7",
"glob-parent": "^3.1.0",
"inherits": "^2.0.3",
"is-binary-path": "^1.0.0",
@@ -24178,6 +24197,7 @@
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
+ "fsevents": "~2.3.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
@@ -39033,9 +39053,9 @@
}
},
"openchs-models": {
- "version": "1.27.17",
- "resolved": "https://registry.npmjs.org/openchs-models/-/openchs-models-1.27.17.tgz",
- "integrity": "sha512-oAhrPVy+UMOHlSZv7eNwK6LtVyTsjjml4Jcbsid+IZVBCrCJK8lUbPlJxfVpphkeXuYZa6npNXk+vYXiP/ZmpA=="
+ "version": "1.27.18",
+ "resolved": "https://registry.npmjs.org/openchs-models/-/openchs-models-1.27.18.tgz",
+ "integrity": "sha512-i6Ku41kAq1J6+F0wmKs3zWqP7Zigy+RcOPWoxCaeKrzAczJR6cZI3kOADEk7nD4w9n9uOGMyQ5sLJk7F8Nr2HQ=="
},
"opencollective-postinstall": {
"version": "2.0.3",
diff --git a/packages/openchs-android/package.json b/packages/openchs-android/package.json
index e0d3629b6..de56e676e 100644
--- a/packages/openchs-android/package.json
+++ b/packages/openchs-android/package.json
@@ -50,7 +50,7 @@
"lodash": "4.17.21",
"moment": "2.29.4",
"native-base": "3.4.9",
- "openchs-models": "1.27.17",
+ "openchs-models": "1.27.18",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-native": "0.69.7",
diff --git a/packages/openchs-android/src/action/mydashboard/CustomFilterActions.js b/packages/openchs-android/src/action/mydashboard/CustomFilterActions.js
index d7537823c..8e5d93900 100644
--- a/packages/openchs-android/src/action/mydashboard/CustomFilterActions.js
+++ b/packages/openchs-android/src/action/mydashboard/CustomFilterActions.js
@@ -2,14 +2,23 @@ import _ from "lodash";
import CustomFilterService from "../../service/CustomFilterService";
import moment from "moment";
-
class CustomFilterActions {
-
static getInitialState() {
return {
- selectedCustomFilters: {}
+ selectedCustomFilters: {},
+ openedCodedConceptUuids: []
+ }
+ }
+ static onCodedConceptFilterToggled(state, action, context) {
+ const newState = {...state};
+ if (_.some(newState.openedCodedConceptUuids, (x) => action.conceptUuid === x)) {
+ _.remove(newState["openedCodedConceptUuids"], (x) => action.conceptUuid === x);
+ newState["openedCodedConceptUuids"] = [...newState["openedCodedConceptUuids"]];
+ } else {
+ newState["openedCodedConceptUuids"] = [...newState["openedCodedConceptUuids"], action.conceptUuid];
}
+ return newState;
}
static onLoad(state, action, context) {
@@ -105,11 +114,11 @@ class CustomFilterActions {
const previousValue = state.selectedCustomFilters[titleKey];
if (_.some(previousValue, pv => pv.groupSubjectUUID === groupSubjectUUID)) {
const newState = _.filter(previousValue, pv => pv.groupSubjectUUID !== groupSubjectUUID);
- return {...state, selectedCustomFilters: {...state.selectedCustomFilters, [titleKey]: newState}}
+ return {...state, selectedCustomFilters: {...state.selectedCustomFilters, [titleKey]: newState}, openedCodedConceptUuids: []}
}
const newState = {subjectTypeUUID, groupSubjectUUID, name};
const selectedCustomFilters = {...state.selectedCustomFilters, [titleKey]: [...previousValue, newState]};
- return {...state, selectedCustomFilters};
+ return {...state, selectedCustomFilters, openedCodedConceptUuids: []};
}
}
@@ -124,6 +133,7 @@ const CustomFilterNames = {
ON_MIN_TIME_CUSTOM_FILTER_SELECT: `${ActionPrefix}.ON_MIN_TIME_CUSTOM_FILTER_SELECT`,
ON_MAX_TIME_CUSTOM_FILTER_SELECT: `${ActionPrefix}.ON_MAX_TIME_CUSTOM_FILTER_SELECT`,
ON_GROUP_SUBJECT_CHANGE: `${ActionPrefix}.ON_GROUP_SUBJECT_CHANGE`,
+ ON_CODED_CONCEPT_FILTER_TOGGLED: `${ActionPrefix}.ON_CODED_CONCEPT_FILTER_TOGGLED`
};
const CustomFilterMap = new Map([
@@ -136,6 +146,7 @@ const CustomFilterMap = new Map([
[CustomFilterNames.ON_MIN_TIME_CUSTOM_FILTER_SELECT, CustomFilterActions.onMinTimeSelect],
[CustomFilterNames.ON_MAX_TIME_CUSTOM_FILTER_SELECT, CustomFilterActions.onMaxTimeSelect],
[CustomFilterNames.ON_GROUP_SUBJECT_CHANGE, CustomFilterActions.onGroupSubjectFilterChange],
+ [CustomFilterNames.ON_CODED_CONCEPT_FILTER_TOGGLED, CustomFilterActions.onCodedConceptFilterToggled],
]);
export {
diff --git a/packages/openchs-android/src/action/mydashboard/MyDashboardActions.js b/packages/openchs-android/src/action/mydashboard/MyDashboardActions.js
index 9cdaa3b3a..c9d648425 100644
--- a/packages/openchs-android/src/action/mydashboard/MyDashboardActions.js
+++ b/packages/openchs-android/src/action/mydashboard/MyDashboardActions.js
@@ -10,6 +10,10 @@ import UserInfoService from "../../service/UserInfoService";
import DashboardCacheService from "../../service/DashboardCacheService";
import {firebaseEvents, logEvent} from "../../utility/Analytics";
+function getApplicableEncounterTypes(state) {
+ return _.isEmpty(state.selectedGeneralEncounterTypes) ? state.selectedEncounterTypes : state.selectedGeneralEncounterTypes;
+}
+
class MyDashboardActions {
static getInitialState(context) {
return {
@@ -91,9 +95,9 @@ class MyDashboardActions {
MyDashboardActions.commonIndividuals(individualService.allScheduledVisitsIn(state.date.value, encountersFilters, generalEncountersFilters, queryProgramEncounter, queryGeneralEncounter), state.individualUUIDs),
MyDashboardActions.commonIndividuals(individualService.allOverdueVisitsIn(state.date.value, encountersFilters, generalEncountersFilters, queryProgramEncounter, queryGeneralEncounter), state.individualUUIDs),
MyDashboardActions.commonIndividuals(individualService.recentlyCompletedVisitsIn(state.date.value, encountersFilters, generalEncountersFilters, queryProgramEncounter, queryGeneralEncounter), state.individualUUIDs),
- MyDashboardActions.commonIndividuals(individualService.recentlyRegistered(state.date.value, individualFilters), state.individualUUIDs),
+ MyDashboardActions.commonIndividuals(individualService.recentlyRegistered(state.date.value, individualFilters, state.selectedPrograms, getApplicableEncounterTypes(state)), state.individualUUIDs),
MyDashboardActions.commonIndividuals(individualService.recentlyEnrolled(state.date.value, enrolmentFilters), state.individualUUIDs),
- MyDashboardActions.commonIndividuals(individualService.allIn(state.date.value, individualFilters), state.individualUUIDs, true)
+ MyDashboardActions.commonIndividuals(individualService.allIn(state.date.value, individualFilters, state.selectedPrograms, getApplicableEncounterTypes(state)), state.individualUUIDs, true)
]
: [state.scheduled, state.overdue, state.recentlyCompletedVisits, state.recentlyCompletedRegistration, state.recentlyCompletedEnrolment, state.total]);
@@ -175,7 +179,12 @@ class MyDashboardActions {
(listType === 'total' || listType === 'recentlyCompletedRegistration') ? state.individualFilters : state.encountersFilters;
const queryProgramEncounter = MyDashboardActions.shouldQueryProgramEncounter(state);
const queryGeneralEncounter = MyDashboardActions.shouldQueryGeneralEncounter(state);
- const allIndividuals = methodMap.get(listType)(state.date.value, filters, state.generalEncountersFilters, queryProgramEncounter, queryGeneralEncounter);
+ let allIndividuals;
+ if (listType === "recentlyCompletedRegistration" || listType === "total")
+ allIndividuals = methodMap.get(listType)(state.date.value, filters, state.selectedPrograms, getApplicableEncounterTypes(state));
+ else
+ allIndividuals = methodMap.get(listType)(state.date.value, filters, state.generalEncountersFilters, queryProgramEncounter, queryGeneralEncounter);
+
const commonIndividuals = MyDashboardActions.commonIndividuals(allIndividuals, state.individualUUIDs, listType === 'total');
const totalToDisplay = listType === 'total' ? commonIndividuals : _.orderBy(commonIndividuals, ({visitInfo}) => visitInfo.sortingBy, 'desc');
return {
@@ -236,9 +245,8 @@ class MyDashboardActions {
const addressUUIDs = action.locationSearchCriteria.clone().getAllAddressLevelUUIDs();
const locationQuery = (path) => _.map(addressUUIDs, (address) => `${path} = \'${address}\'`);
const subjectTypeQuery = (path) => `${path} = "${action.selectedSubjectType.uuid}"`;
- const visitQuery = (path) => shouldApplyValidEnrolmentQuery ? action.selectedEncounterTypes.map((encounter) => `${path} = \'${encounter.uuid}\'`) : '';
- const generalVisitQuery = (path) => _.map(action.selectedGeneralEncounterTypes, (encounter) => `${path} = \'${encounter.uuid}\'`);
- const generalVisitQueryFromIndividual = _.map(action.selectedGeneralEncounterTypes, (encounter) => `$encounter.encounterType.uuid = \'${encounter.uuid}\' AND $encounter.voided = false`);
+ const visitQuery = (path) => shouldApplyValidEnrolmentQuery ? action.selectedEncounterTypes.map((encounterType) => `${path} = \'${encounterType.uuid}\'`) : '';
+ const generalVisitQuery = (path) => _.map(action.selectedGeneralEncounterTypes, (encounterType) => `${path} = \'${encounterType.uuid}\'`);
const programQuery = (path) => shouldApplyValidEnrolmentQuery ? _.map(action.selectedPrograms, (program) => `${path} = \'${program.uuid}\'`) : '';
const validEnrolmentQuery = (path) => shouldApplyValidEnrolmentQuery ? `${path}.voided = false and ${path}.programExitDateTime = null` : '';
const genderQuery = (path) => _.map(action.selectedGenders, (gender) => `${path} = "${gender.name}"`);
@@ -256,21 +264,16 @@ class MyDashboardActions {
const restIndividualFilters = [
MyDashboardActions.orQuery(programQuery('$enrolment.program.uuid')),
- MyDashboardActions.orQuery(visitQuery('$enrolment.encounters.encounterType.uuid')),
validEnrolmentQuery('$enrolment')
].filter(Boolean).join(" AND ");
const buildEnrolmentSubQueryForIndividual = () => _.isEmpty(restIndividualFilters) ? '' :
'SUBQUERY(enrolments, $enrolment, ' + restIndividualFilters + ' ).@count > 0';
- const encounterQuery = () => _.isEmpty(MyDashboardActions.orQuery(generalVisitQueryFromIndividual)) ? '' :
- 'SUBQUERY(encounters, $encounter, ' + MyDashboardActions.orQuery(generalVisitQueryFromIndividual) + ' ).@count > 0';
-
const individualFilters = [
subjectTypeQuery('subjectType.uuid'),
MyDashboardActions.orQuery(genderQuery('gender.name')),
MyDashboardActions.orQuery(locationQuery('lowestAddressLevel.uuid')),
- encounterQuery(),
buildEnrolmentSubQueryForIndividual()
].filter(Boolean).join(" AND ");
diff --git a/packages/openchs-android/src/service/IndividualService.js b/packages/openchs-android/src/service/IndividualService.js
index dd63a8b83..329f77ee6 100644
--- a/packages/openchs-android/src/service/IndividualService.js
+++ b/packages/openchs-android/src/service/IndividualService.js
@@ -112,7 +112,6 @@ class IndividualService extends BaseService {
_uniqIndividualWithVisitName(individualsWithVisits, individualWithVisit) {
const permissionAllowed = individualWithVisit.visitInfo.allow;
-
if (individualsWithVisits.has(individualWithVisit.individual.uuid)) {
const prevDate = individualsWithVisits.get(individualWithVisit.individual.uuid).visitInfo.sortingBy;
const smallerDate = moment(prevDate).isBefore(individualWithVisit.visitInfo.sortingBy) ? prevDate : individualWithVisit.visitInfo.sortingBy;
@@ -134,7 +133,10 @@ class IndividualService extends BaseService {
return individualsWithVisits;
}
- allIn(ignored, queryAdditions) {
+ allIn(ignored, queryAdditions, programs = [], encounterTypes = []) {
+ if (encounterTypes.length > 0 || programs.length > 0)
+ return null;
+
return this.db.objects(Individual.schema.name)
.filtered('voided = false ')
.filtered((_.isEmpty(queryAdditions) ? 'uuid != null' : `${queryAdditions}`))
@@ -349,8 +351,7 @@ class IndividualService extends BaseService {
fromDate)
.filtered((_.isEmpty(queryAdditions) ? 'uuid != null' : `${queryAdditions}`))
.map((enc) => {
- const individual = enc.programEnrolment.individual;
- return individual;
+ return enc.programEnrolment.individual;
})
.reduce(this._uniqIndividualsFrom, new Map())
.values()]
@@ -411,17 +412,25 @@ class IndividualService extends BaseService {
.map(_.identity);
}
- recentlyRegistered(date, addressQuery) {
+ recentlyRegistered(date, addressQuery, programs = [], encounterTypes = []) {
let fromDate = moment(date).subtract(1, 'day').startOf('day').toDate();
let tillDate = moment(date).endOf('day').toDate();
- return [...this.db.objects(Individual.schema.name)
+ let individuals = this.db.objects(Individual.schema.name)
.filtered('voided = false ' +
'AND registrationDate <= $0 ' +
'AND registrationDate >= $1 ',
tillDate,
fromDate)
.filtered((_.isEmpty(addressQuery) ? 'uuid != null' : `${addressQuery}`))
- .map((individual) => {
+ .map((individual) => individual);
+
+ if (encounterTypes.length > 0 && programs.length > 0) {
+ individuals = _.filter(individuals, (individual) => individual.hasProgramEncounterOfType(encounterTypes));
+ } else if (encounterTypes.length > 0) {
+ individuals = _.filter(individuals, (individual) => individual.hasEncounterOfType(encounterTypes));
+ }
+
+ return [...individuals.map((individual) => {
const registrationDate = individual.registrationDate;
return {
individual,
@@ -433,8 +442,7 @@ class IndividualService extends BaseService {
allow: true,
}
};
- })
- .reduce(this._uniqIndividualWithVisitName, new Map())
+ }).reduce(this._uniqIndividualWithVisitName, new Map())
.values()]
.map(_.identity);
}
diff --git a/packages/openchs-android/src/views/beneficiaryMode/ExitBeneficiaryModeButton.js b/packages/openchs-android/src/views/beneficiaryMode/ExitBeneficiaryModeButton.js
index a3163a40d..74248ab18 100644
--- a/packages/openchs-android/src/views/beneficiaryMode/ExitBeneficiaryModeButton.js
+++ b/packages/openchs-android/src/views/beneficiaryMode/ExitBeneficiaryModeButton.js
@@ -1,6 +1,5 @@
import {Modal, Text, TouchableNativeFeedback, View} from "react-native";
import React from "react";
-import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import AbstractComponent from "../../framework/view/AbstractComponent";
import Colors from "../primitives/Colors";
import BeneficiaryModePinService from "../../service/BeneficiaryModePinService";
diff --git a/packages/openchs-android/src/views/filter/CustomFilters.js b/packages/openchs-android/src/views/filter/CustomFilters.js
index b0b57e7e0..27f5d9583 100644
--- a/packages/openchs-android/src/views/filter/CustomFilters.js
+++ b/packages/openchs-android/src/views/filter/CustomFilters.js
@@ -12,19 +12,39 @@ import Separator from "../primitives/Separator";
import {TextInput, View} from 'react-native';
import Distances from "../primitives/Distances";
import Colors from '../primitives/Colors';
-import {Text} from "native-base";
+import {Box, Button, Text} from "native-base";
import DatePicker from "../primitives/DatePicker";
import TimePicker from "../primitives/TimePicker";
import moment from "moment";
import ValidationErrorMessage from "../form/ValidationErrorMessage";
import IndividualService from "../../service/IndividualService";
import RadioGroup, {RadioLabelValue} from "../primitives/RadioGroup";
-import IndividualSearchCriteria from "../../service/query/IndividualSearchCriteria";
import AddressLevelsState from "../../action/common/AddressLevelsState";
import MultiSelectFilterModel from "../../model/MultiSelectFilterModel";
+import AvniIcon from "../common/AvniIcon";
+import Fonts from "../primitives/Fonts";
+import MessageService from "../../service/MessageService";
-class CustomFilters extends AbstractComponent {
+function CollapsedFilter({onExpand, concept, I18n}) {
+ return
+
+ ;
+}
+
+function ExpandedFilter({onCollapse, concept, I18n}) {
+ return
+
+ ;
+}
+class CustomFilters extends AbstractComponent {
constructor(props, context) {
super(props, context, Reducers.reducerKeys.customFilterActions);
this.conceptService = context.getService(ConceptService);
@@ -269,19 +289,37 @@ class CustomFilters extends AbstractComponent {
, idx)
}
+ dispatchCodedAction(conceptAnswerName, conceptAnswers) {
+ this.dispatchAction(CustomFilterNames.ON_CODED_CUSTOM_FILTER_SELECT,
+ {
+ titleKey: filter.titleKey,
+ subjectTypeUUID: filter.subjectTypeUUID,
+ conceptAnswerName,
+ conceptAnswers
+ });
+ }
+
+ toggleCodedFilter(concept) {
+ this.dispatchAction(CustomFilterNames.ON_CODED_CONCEPT_FILTER_TOGGLED, {conceptUuid: concept.uuid});
+ }
+
codedConceptFilter(concept, filter, idx) {
+ const showCodedFilter = this.state.openedCodedConceptUuids.includes(concept.uuid);
const conceptAnswers = concept.getAnswers();
const selectedOne = this.state.selectedCustomFilters[filter.titleKey].map(c => c.name);
const optsFnMap = conceptAnswers.reduce((conceptMap, conceptAnswers) => conceptMap.set(conceptAnswers.concept.name, conceptAnswers), new Map());
const filterModel = new MultiSelectFilterModel(filter.titleKey, optsFnMap, new Map(), selectedOne).selectOption(selectedOne);
- return this.wrap( this.dispatchAction(CustomFilterNames.ON_CODED_CUSTOM_FILTER_SELECT,
- {
- titleKey: filter.titleKey,
- subjectTypeUUID: filter.subjectTypeUUID,
- conceptAnswerName,
- conceptAnswers
- })}/>, idx);
+ return this.wrap(showCodedFilter ? <>
+ this.toggleCodedFilter(concept)} concept={concept} I18n={this.I18n}/>
+ this.dispatchAction(CustomFilterNames.ON_CODED_CUSTOM_FILTER_SELECT,
+ {
+ titleKey: filter.titleKey,
+ subjectTypeUUID: filter.subjectTypeUUID,
+ conceptAnswerName,
+ conceptAnswers
+ })}/>> :
+ this.toggleCodedFilter(concept)} I18n={this.I18n}/>, idx);
}
_invokeCallbacks() {
@@ -296,10 +334,8 @@ class CustomFilters extends AbstractComponent {
{this.renderConceptFilters(_.filter(this.props.filters, filter => filter.type === CustomFilter.type.Concept))}
{this.renderOtherFilters(_.filter(this.props.filters, filter => filter.type !== CustomFilter.type.Concept))}
- )
-
+ );
}
-
}
const styles = {
diff --git a/packages/openchs-android/src/views/mydashbaord/MyDashboardView.js b/packages/openchs-android/src/views/mydashbaord/MyDashboardView.js
index f09f53e20..ab1611888 100644
--- a/packages/openchs-android/src/views/mydashbaord/MyDashboardView.js
+++ b/packages/openchs-android/src/views/mydashbaord/MyDashboardView.js
@@ -1,5 +1,5 @@
import React from "react";
-import {Text, TouchableNativeFeedback, View, ScrollView} from 'react-native';
+import {ScrollView, Text, TouchableNativeFeedback, View} from 'react-native';
import ListView from "deprecated-react-native-listview";
import AbstractComponent from "../../framework/view/AbstractComponent";
import Path from "../../framework/routing/Path";
@@ -19,6 +19,7 @@ import moment from "moment";
import RefreshReminder from "./RefreshReminder";
import {YearReviewBanner} from "../yearReview/YearReviewBanner";
import AvniIcon from '../common/AvniIcon';
+import _ from 'lodash';
@Path('/MyDashboard')
class MyDashboardView extends AbstractComponent {
@@ -93,9 +94,16 @@ class MyDashboardView extends AbstractComponent {
setTimeout(() => this.dispatchAction(Actions.ON_LOAD, {fetchFromDB: true}), 0);
}
+ renderableVisits() {
+ const {selectedPrograms, selectedGeneralEncounterTypes, visits} = this.state;
+ if (!_.isEmpty(selectedPrograms) || !_.isEmpty(selectedGeneralEncounterTypes))
+ return _.filter(visits, (visit) => _.isNil(visit.visits.total));
+ return visits;
+ }
+
render() {
- General.logDebug(this.viewName(), 'render');
- const dataSource = this.ds.cloneWithRows((this.state.visits));
+ General.logDebug(this.viewName(), "render");
+ const dataSource = this.ds.cloneWithRows(this.renderableVisits());
const date = this.state.date;
return (
diff --git a/packages/openchs-android/translations/en.json b/packages/openchs-android/translations/en.json
index 7816f5033..d37bb5cb7 100644
--- a/packages/openchs-android/translations/en.json
+++ b/packages/openchs-android/translations/en.json
@@ -472,6 +472,8 @@
"status": "Status",
"type": "Type",
"filters": "Filters",
- "scrollToBottomToSave": "Scroll to Bottom to Save"
+ "scrollToBottomToSave": "Scroll to Bottom to Save",
+ "openCodedFilter": "may take few seconds to open",
+ "closeCodedFilter": "may speed up"
}
}
diff --git a/packages/openchs-android/translations/hi_IN.json b/packages/openchs-android/translations/hi_IN.json
index b357a260c..7bfa4c3ba 100644
--- a/packages/openchs-android/translations/hi_IN.json
+++ b/packages/openchs-android/translations/hi_IN.json
@@ -341,6 +341,8 @@
"programName": "प्रोग्राम का नाम:",
"rolesNotConfigured": "भूमिकाएँ कॉन्फ़िगर नहीं की गईं",
"rolesNotConfiguredDescription": "सदस्य जोड़ने के लिए भूमिकाएँ कॉन्फ़िगर करें।",
- "scrollToBottomToSave": "सेव करने के लिए स्क्रॉल करें"
+ "scrollToBottomToSave": "सेव करने के लिए स्क्रॉल करें",
+ "openCodedFilter": "कुछ सेकंड लगेगा",
+ "closeCodedFilter": "फ़िल्टर जल्दी चलेगा"
}
}