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": "फ़िल्टर जल्दी चलेगा" } }