├── .gitignore ├── .tx └── config ├── README.md ├── api ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── openmrs │ │ │ └── module │ │ │ └── coreapps │ │ │ ├── CoreAppsConstants.java │ │ │ ├── CoreAppsProperties.java │ │ │ ├── contextmodel │ │ │ ├── PatientContextModel.java │ │ │ ├── PatientEncounterContextModel.java │ │ │ └── PersonContextModel.java │ │ │ ├── customdatatype │ │ │ ├── CodedConceptDatatype.java │ │ │ └── LocationDatatype.java │ │ │ ├── parser │ │ │ └── ParseEncounterToJson.java │ │ │ └── utils │ │ │ ├── PatientProgramComparator.java │ │ │ └── VisitTypeHelper.java │ └── resources │ │ ├── liquibase.xml │ │ ├── messages.properties │ │ ├── messages_ar.properties │ │ ├── messages_ar_EG.properties │ │ ├── messages_de.properties │ │ ├── messages_el.properties │ │ ├── messages_en_GB.properties │ │ ├── messages_es.properties │ │ ├── messages_fa.properties │ │ ├── messages_fr.properties │ │ ├── messages_fr_FR.properties │ │ ├── messages_hi.properties │ │ ├── messages_hi_IN.properties │ │ ├── messages_hr.properties │ │ ├── messages_ht.properties │ │ ├── messages_hy.properties │ │ ├── messages_id_ID.properties │ │ ├── messages_it.properties │ │ ├── messages_ja.properties │ │ ├── messages_ja_JP.properties │ │ ├── messages_km.properties │ │ ├── messages_ku.properties │ │ ├── messages_lt.properties │ │ ├── messages_my.properties │ │ ├── messages_pl.properties │ │ ├── messages_ps.properties │ │ ├── messages_pt.properties │ │ ├── messages_pt_BR.properties │ │ ├── messages_ru.properties │ │ ├── messages_ru_RU.properties │ │ ├── messages_si.properties │ │ ├── messages_sq.properties │ │ ├── messages_sr.properties │ │ ├── messages_sw.properties │ │ ├── messages_sw_KE.properties │ │ ├── messages_ta.properties │ │ ├── messages_te.properties │ │ ├── messages_tr_TR.properties │ │ ├── messages_uk.properties │ │ ├── messages_ur.properties │ │ ├── messages_vi.properties │ │ ├── messages_zh.properties │ │ ├── messages_zh_CN.properties │ │ └── moduleApplicationContext.xml │ └── test │ └── java │ └── org │ └── openmrs │ └── module │ └── coreapps │ ├── parser │ └── ParseEncounterToJsonTest.java │ └── utils │ └── PatientProgramComparatorTest.java ├── omod ├── karma.conf.js ├── npm-shrinkwrap.json ├── package.json ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── openmrs │ │ │ │ └── module │ │ │ │ └── coreapps │ │ │ │ ├── CoreAppsActivator.java │ │ │ │ ├── contextmodel │ │ │ │ ├── AppContextModelGenerator.java │ │ │ │ └── VisitContextModel.java │ │ │ │ ├── filter │ │ │ │ └── AdminAuthorisationFilter.java │ │ │ │ ├── fragment │ │ │ │ └── controller │ │ │ │ │ ├── DiagnosesFragmentController.java │ │ │ │ │ ├── EditPatientIdentifierFragmentController.java │ │ │ │ │ ├── FindPatientFragmentController.java │ │ │ │ │ ├── FormatAddressFragmentController.java │ │ │ │ │ ├── PatientHeaderFragmentController.java │ │ │ │ │ ├── StickyNoteFragmentController.java │ │ │ │ │ ├── administrativenotification │ │ │ │ │ └── NotificationsFragmentController.java │ │ │ │ │ ├── clinicianfacing │ │ │ │ │ ├── DiagnosisWidgetFragmentController.java │ │ │ │ │ └── VisitsSectionFragmentController.java │ │ │ │ │ ├── conditionlist │ │ │ │ │ └── ConditionsFragmentController.java │ │ │ │ │ ├── dashboardwidgets │ │ │ │ │ ├── CustomLinksWidgetFragmentController.java │ │ │ │ │ └── DashboardWidgetFragmentController.java │ │ │ │ │ ├── diagnosis │ │ │ │ │ └── EncounterDiagnosesFragmentController.java │ │ │ │ │ ├── encounter │ │ │ │ │ └── MostRecentEncounterFragmentController.java │ │ │ │ │ ├── mergepatients │ │ │ │ │ └── PatientSearchAndSelectWidgetFragmentController.java │ │ │ │ │ ├── patientdashboard │ │ │ │ │ ├── ActiveDrugOrdersFragmentController.java │ │ │ │ │ ├── ContactInfoFragmentController.java │ │ │ │ │ ├── ContactInfoInlineFragmentController.java │ │ │ │ │ ├── EditVisitFragmentController.java │ │ │ │ │ └── VisitIncludesFragmentController.java │ │ │ │ │ ├── patientheader │ │ │ │ │ └── ActiveVisitStatusFragmentController.java │ │ │ │ │ ├── patientsearch │ │ │ │ │ └── PatientSearchWidgetFragmentController.java │ │ │ │ │ ├── program │ │ │ │ │ └── ProgramHistoryFragmentController.java │ │ │ │ │ └── visit │ │ │ │ │ ├── ParsedObs.java │ │ │ │ │ ├── ParserEncounterIntoSimpleObjects.java │ │ │ │ │ ├── QuickVisitFragmentController.java │ │ │ │ │ ├── RetrospectiveVisitFragmentController.java │ │ │ │ │ ├── VisitDatesFragmentController.java │ │ │ │ │ ├── VisitDetailsFragmentController.java │ │ │ │ │ └── VisitFragmentController.java │ │ │ │ ├── helper │ │ │ │ ├── BreadcrumbHelper.java │ │ │ │ └── SimplePatientPageController.java │ │ │ │ ├── htmlformentry │ │ │ │ ├── CodedOrFreeTextAnswerListWidget.java │ │ │ │ ├── CodedOrFreeTextAnswerWidget.java │ │ │ │ ├── CodedOrFreeTextObsTagHandler.java │ │ │ │ ├── EncounterDiagnosesByObsElement.java │ │ │ │ ├── EncounterDiagnosesByObsTagHandler.java │ │ │ │ ├── EncounterDiagnosesElement.java │ │ │ │ ├── EncounterDiagnosesTagHandler.java │ │ │ │ └── EncounterDispositionTagHandler.java │ │ │ │ ├── page │ │ │ │ └── controller │ │ │ │ │ ├── ActiveVisitsPageController.java │ │ │ │ │ ├── MarkPatientDeadPageController.java │ │ │ │ │ ├── MergeVisitsPageController.java │ │ │ │ │ ├── adt │ │ │ │ │ ├── AwaitingAdmissionDiagnosisFormatter.java │ │ │ │ │ └── AwaitingAdmissionPageController.java │ │ │ │ │ ├── applist │ │ │ │ │ └── AppListPageController.java │ │ │ │ │ ├── clinicianfacing │ │ │ │ │ └── PatientPageController.java │ │ │ │ │ ├── conditionlist │ │ │ │ │ ├── ManageConditionPageController.java │ │ │ │ │ └── ManageConditionsPageController.java │ │ │ │ │ ├── datamanagement │ │ │ │ │ ├── DataManagementPageController.java │ │ │ │ │ └── MergePatientsPageController.java │ │ │ │ │ ├── findpatient │ │ │ │ │ └── FindPatientPageController.java │ │ │ │ │ ├── patientdashboard │ │ │ │ │ └── PatientDashboardPageController.java │ │ │ │ │ ├── providermanagement │ │ │ │ │ ├── EditProviderPageController.java │ │ │ │ │ └── ProviderListPageController.java │ │ │ │ │ ├── relationships │ │ │ │ │ └── ListPageController.java │ │ │ │ │ ├── summarydashboard │ │ │ │ │ ├── ProgramEnrollmentsPageController.java │ │ │ │ │ └── SummaryDashboardPageController.java │ │ │ │ │ ├── systemadministration │ │ │ │ │ └── SystemAdministrationPageController.java │ │ │ │ │ └── vitals │ │ │ │ │ └── PatientPageController.java │ │ │ │ └── web │ │ │ │ ├── controller │ │ │ │ └── CoreappsRestController.java │ │ │ │ └── resource │ │ │ │ └── LatestObsResource.java │ │ ├── resources │ │ │ ├── apps │ │ │ │ ├── activeVisits_app.json │ │ │ │ ├── awaitingAdmission_app.json │ │ │ │ ├── clinicianPatientDashboardOtherActions_app.json │ │ │ │ ├── conditionList_app.json │ │ │ │ ├── coreappsAppTemplates.json │ │ │ │ ├── dashboardWidgets_app.json │ │ │ │ ├── dataManagement_app.json │ │ │ │ ├── diagnoses_app.json │ │ │ │ ├── findpatient_app.json │ │ │ │ ├── fragmentIncludes_extension.json │ │ │ │ ├── manageConcepts_app.json │ │ │ │ ├── mergePatients_app.json │ │ │ │ ├── mostRecentVitals_app.json │ │ │ │ ├── overallActions_extension.json │ │ │ │ ├── patientDashboard_app.json │ │ │ │ ├── patientHeader_extension.json │ │ │ │ └── systemAdministration_app.json │ │ │ ├── config.xml │ │ │ └── webModuleApplicationContext.xml │ │ ├── web │ │ │ ├── dashboardwidgets │ │ │ │ ├── bahmniappointments │ │ │ │ │ ├── bahmniappointments.component.js │ │ │ │ │ ├── bahmniappointments.controller.js │ │ │ │ │ ├── bahmniappointments.html │ │ │ │ │ └── index.js │ │ │ │ ├── dashboardwidgets.services.js │ │ │ │ ├── dashboardwidgetscommons.service.js │ │ │ │ ├── dataintegrityviolations │ │ │ │ │ ├── dataintegrityviolations.component.js │ │ │ │ │ ├── dataintegrityviolations.controller.js │ │ │ │ │ ├── dataintegrityviolations.html │ │ │ │ │ └── index.js │ │ │ │ ├── datepicker │ │ │ │ │ ├── datepicker.component.js │ │ │ │ │ ├── datepicker.controller.js │ │ │ │ │ ├── datepicker.html │ │ │ │ │ ├── index.js │ │ │ │ │ └── locales │ │ │ │ │ │ └── bootstrap-datepicker.ht.js │ │ │ │ ├── index.js │ │ │ │ ├── latestobsforconceptlist │ │ │ │ │ ├── index.js │ │ │ │ │ ├── latestobsforconceptlist.component.js │ │ │ │ │ ├── latestobsforconceptlist.controller.js │ │ │ │ │ ├── latestobsforconceptlist.html │ │ │ │ │ └── latestobsforconceptlist.spec.js │ │ │ │ ├── obsacrossencounters │ │ │ │ │ ├── index.js │ │ │ │ │ ├── obsacrossencounters.component.js │ │ │ │ │ ├── obsacrossencounters.controller.js │ │ │ │ │ ├── obsacrossencounters.html │ │ │ │ │ └── obsacrossencounters.spec.js │ │ │ │ ├── obsgraph │ │ │ │ │ ├── index.js │ │ │ │ │ ├── obsgraph.component.js │ │ │ │ │ ├── obsgraph.controller.js │ │ │ │ │ └── obsgraph.html │ │ │ │ ├── programs │ │ │ │ │ ├── index.js │ │ │ │ │ ├── programs.component.js │ │ │ │ │ ├── programs.controller.js │ │ │ │ │ └── programs.html │ │ │ │ ├── programstatistics │ │ │ │ │ ├── index.js │ │ │ │ │ ├── programstatistics.component.js │ │ │ │ │ ├── programstatistics.controller.js │ │ │ │ │ └── programstatistics.html │ │ │ │ ├── programstatus │ │ │ │ │ ├── index.js │ │ │ │ │ ├── programstatus.component.js │ │ │ │ │ ├── programstatus.controller.js │ │ │ │ │ ├── programstatus.html │ │ │ │ │ └── programstatus.spec.js │ │ │ │ ├── relationships │ │ │ │ │ ├── index.js │ │ │ │ │ ├── relationships.component.js │ │ │ │ │ ├── relationships.controller.js │ │ │ │ │ └── relationships.html │ │ │ │ └── visitbyencountertype │ │ │ │ │ ├── index.js │ │ │ │ │ ├── visitbyencountertype.component.js │ │ │ │ │ ├── visitbyencountertype.controller.js │ │ │ │ │ └── visitbyencountertype.html │ │ │ └── karma.context.js │ │ └── webapp │ │ │ ├── fragments │ │ │ ├── administrativenotification │ │ │ │ └── notifications.gsp │ │ │ ├── clinicianfacing │ │ │ │ ├── diagnosisWidget.gsp │ │ │ │ └── visitsSection.gsp │ │ │ ├── conditionlist │ │ │ │ └── conditions.gsp │ │ │ ├── dashboardwidgets │ │ │ │ ├── customLinksWidget.gsp │ │ │ │ └── dashboardWidget.gsp │ │ │ ├── datamanagement │ │ │ │ ├── codeDiagnosisDialog.gsp │ │ │ │ └── diagnosisAutocompleteTemplate.gsp │ │ │ ├── diagnosis │ │ │ │ └── encounterDiagnoses.gsp │ │ │ ├── encounter │ │ │ │ └── mostRecentEncounter.gsp │ │ │ ├── findPatientById.gsp │ │ │ ├── formatAddress.gsp │ │ │ ├── htmlformentry │ │ │ │ ├── codedOrFreeTextAnswer.gsp │ │ │ │ └── codedOrFreeTextAnswerList.gsp │ │ │ ├── mergepatients │ │ │ │ └── patientSearchAndSelectWidget.gsp │ │ │ ├── patientHeader.gsp │ │ │ ├── patientdashboard │ │ │ │ ├── activeDrugOrders.gsp │ │ │ │ ├── contactInfo.gsp │ │ │ │ ├── contactInfoInline.gsp │ │ │ │ ├── editVisit.gsp │ │ │ │ ├── editVisitDatesDialog.gsp │ │ │ │ ├── encountertemplate │ │ │ │ │ ├── defaultEncounterTemplate.gsp │ │ │ │ │ ├── hiddenEncounterTemplate.gsp │ │ │ │ │ └── noDetailsEncounterTemplate.gsp │ │ │ │ ├── visitDetailsTemplate.gsp │ │ │ │ ├── visitIncludes.gsp │ │ │ │ └── visits.gsp │ │ │ ├── patientheader │ │ │ │ └── activeVisitStatus.gsp │ │ │ ├── patientsearch │ │ │ │ └── patientSearchWidget.gsp │ │ │ ├── program │ │ │ │ └── programHistory.gsp │ │ │ └── stickyNote.gsp │ │ │ ├── owas │ │ │ └── conceptdictionary.owa │ │ │ ├── pages │ │ │ ├── activeVisits.gsp │ │ │ ├── adt │ │ │ │ └── awaitingAdmission.gsp │ │ │ ├── applist │ │ │ │ └── appList.gsp │ │ │ ├── clinicianfacing │ │ │ │ └── patient.gsp │ │ │ ├── conditionlist │ │ │ │ ├── manageCondition.gsp │ │ │ │ └── manageConditions.gsp │ │ │ ├── datamanagement │ │ │ │ ├── dataManagement.gsp │ │ │ │ ├── mergePatients-chooseRecords.gsp │ │ │ │ └── mergePatients-confirmSamePerson.gsp │ │ │ ├── findpatient │ │ │ │ └── findPatient.gsp │ │ │ ├── markPatientDead.gsp │ │ │ ├── mergeVisits.gsp │ │ │ ├── noAccess.gsp │ │ │ ├── patientdashboard │ │ │ │ ├── deletedPatient.gsp │ │ │ │ ├── patientDashboard.gsp │ │ │ │ └── patientNotFound.gsp │ │ │ ├── providermanagement │ │ │ │ ├── editProvider.gsp │ │ │ │ ├── findPatient.gsp │ │ │ │ └── providerList.gsp │ │ │ ├── relationships │ │ │ │ └── list.gsp │ │ │ ├── summarydashboard │ │ │ │ ├── programEnrollments.gsp │ │ │ │ └── summaryDashboard.gsp │ │ │ ├── systemadministration │ │ │ │ └── systemAdministration.gsp │ │ │ └── vitals │ │ │ │ └── patient.gsp │ │ │ └── resources │ │ │ ├── fonts │ │ │ ├── fontawesome-stickyNote.eot │ │ │ ├── fontawesome-stickyNote.svg │ │ │ ├── fontawesome-stickyNote.ttf │ │ │ ├── fontawesome-stickyNote.woff │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ ├── partials │ │ │ ├── clickToEditObs.html │ │ │ └── deleteDialog.html │ │ │ ├── scripts │ │ │ ├── conditionlist │ │ │ │ ├── common.functions.js │ │ │ │ ├── controllers │ │ │ │ │ ├── condition.controller.js │ │ │ │ │ └── conditions.controller.js │ │ │ │ ├── emr.messages.js │ │ │ │ ├── lib │ │ │ │ │ └── polyfills.js │ │ │ │ └── restful-services │ │ │ │ │ └── restful-service.js │ │ │ ├── custom │ │ │ │ ├── deletePatient.js │ │ │ │ ├── findPatientById.js │ │ │ │ ├── markPatientDead.js │ │ │ │ ├── utilsTimezone.js │ │ │ │ └── visits.js │ │ │ ├── datamanagement │ │ │ │ └── mergePatients.js │ │ │ ├── diagnoses │ │ │ │ ├── diagnoses-angular.js │ │ │ │ └── diagnoses.js │ │ │ ├── fragments │ │ │ │ ├── datamanagement │ │ │ │ │ ├── codeDiagnosisDialog.js │ │ │ │ │ └── findDiagnosis.js │ │ │ │ ├── encounterTemplates.js │ │ │ │ ├── patientdashboard │ │ │ │ │ └── encountertemplate │ │ │ │ │ │ └── defaultEncounterTemplate.js │ │ │ │ └── visitDetails.js │ │ │ ├── htmlformentry │ │ │ │ ├── codedOrFreeTextAnswer.js │ │ │ │ └── codedOrFreeTextAnswerList.js │ │ │ ├── patientdashboard │ │ │ │ └── patient.js │ │ │ ├── patientsearch │ │ │ │ └── patientSearchWidget.js │ │ │ ├── providermanagement │ │ │ │ └── editProvider.js │ │ │ ├── relationships │ │ │ │ └── relationships.js │ │ │ ├── stickyNote │ │ │ │ ├── app.js │ │ │ │ ├── controllers │ │ │ │ │ └── stickyNoteCtrl.js │ │ │ │ ├── directives │ │ │ │ │ └── clickToEditObs.js │ │ │ │ └── resources │ │ │ │ │ └── xeditable.min.js │ │ │ └── visit │ │ │ │ ├── encounterToggle.js │ │ │ │ ├── filterTable.js │ │ │ │ └── jquery.dataTables.js │ │ │ └── styles │ │ │ ├── adt │ │ │ ├── awaitingAdmission.scss │ │ │ └── inpatient.scss │ │ │ ├── bootstrap.scss │ │ │ ├── clinicianfacing │ │ │ └── patient.scss │ │ │ ├── conditionlist │ │ │ └── conditions.scss │ │ │ ├── datamanagement │ │ │ ├── dataManagement.scss │ │ │ └── mergePatients.scss │ │ │ ├── diagnoses │ │ │ └── encounterDiagnoses.scss │ │ │ ├── encounterToggle.scss │ │ │ ├── htmlformentry │ │ │ └── codedOrFreeTextAnswerList.scss │ │ │ ├── markpatientdead │ │ │ └── markPatientDead.scss │ │ │ ├── patientHeader.scss │ │ │ ├── patientdashboard │ │ │ └── patientDashboard.scss │ │ │ ├── patientsearch │ │ │ └── patientSearchWidget.scss │ │ │ ├── providermanagement │ │ │ └── providermanagement.scss │ │ │ ├── relationships │ │ │ └── list.scss │ │ │ ├── stickynote │ │ │ └── stickyNoteIcon.scss │ │ │ ├── systemadministration │ │ │ └── systemadministration.scss │ │ │ └── visit │ │ │ └── visits.scss │ └── test │ │ ├── java │ │ └── org │ │ │ └── openmrs │ │ │ └── module │ │ │ └── coreapps │ │ │ ├── AppTest.java │ │ │ ├── fragment │ │ │ └── controller │ │ │ │ ├── DiagnosesFragmentControllerTest.java │ │ │ │ ├── PatientHeaderFragmentControllerTest.java │ │ │ │ ├── clinicianfacing │ │ │ │ └── PatientPageControllerTest.java │ │ │ │ ├── diagnosis │ │ │ │ └── EncounterDiagnosesFragmentControllerTest.java │ │ │ │ ├── patientdashboard │ │ │ │ ├── ActiveDrugOrdersFragmentControllerTest.java │ │ │ │ └── ContactInfoFragmentControllerTest.java │ │ │ │ ├── patientsearch │ │ │ │ └── PatientSearchWidgetFragmentControllerTest.java │ │ │ │ └── visit │ │ │ │ ├── ParserEncounterIntoSimpleObjectsTest.java │ │ │ │ ├── QuickVisitFragmentControllerTest.java │ │ │ │ ├── RetrospectiveVisitFragmentControllerTest.java │ │ │ │ ├── VisitDatesFragmentControllerTest.java │ │ │ │ └── VisitDetailsFragmentControllerTest.java │ │ │ ├── htmlformentry │ │ │ ├── CodedOrFreeTextAnswerListWidgetTest.java │ │ │ ├── CodedOrFreeTextObsTagHandlerComponentTest.java │ │ │ ├── EncounterDiagnosesByObsTagHandlerComponentTest.java │ │ │ ├── EncounterDiagnosesElementTest.java │ │ │ ├── EncounterDiagnosesTagHandlerComponentTest.java │ │ │ ├── EncounterDiagnosesTagHandlerTest.java │ │ │ └── EncounterDispositionTagHandlerComponentTest.java │ │ │ ├── page │ │ │ └── controller │ │ │ │ └── MergeVisitsPageControllerTest.java │ │ │ └── web │ │ │ └── controller │ │ │ └── LatestObsRestControllerTest.java │ │ ├── resources │ │ ├── TestingApplicationContext.xml │ │ ├── codedOrFreeTextObsForm.xml │ │ ├── coreappsTestDispositionConfig.json │ │ ├── dispensedMedication_app.json │ │ ├── encounterDiagnosesSimpleForm.xml │ │ ├── encounterDispositionSimpleForm.xml │ │ ├── obsGroupAndEncounterForm.xml │ │ └── test-hibernate.cfg.xml │ │ └── webapp │ │ ├── provided │ │ └── scripts │ │ │ ├── angular.min.js │ │ │ ├── jquery-1.12.4.min.js │ │ │ ├── knockout-2.2.1.js │ │ │ └── underscore-min.js │ │ └── resources │ │ └── scripts │ │ ├── diagnoses │ │ └── diagnoses.js │ │ └── visit.js └── webpack.config.js └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.iml 3 | *.idea 4 | .settings 5 | .project 6 | .classpath 7 | *.sass-cache 8 | target 9 | *.rubygems-provided 10 | *.rubygems 11 | 12 | .DS_Store 13 | 14 | .vscode 15 | 16 | # Package Files # 17 | *.jar 18 | *.war 19 | *.ear 20 | 21 | omod/src/main/webapp/resources/styles/**/*.css 22 | omod/src/main/webapp/resources/styles/**/*.css.map 23 | omod/src/main/webapp/resources/styles/lib 24 | 25 | omod/node 26 | omod/node_modules 27 | omod/src/main/compass 28 | 29 | # JS 30 | node 31 | node_modules 32 | npm-debug.log 33 | /bin/ 34 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com/ 3 | 4 | [o:openmrs:p:OpenMRS:r:coreapps-module] 5 | source_file = api/src/main/resources/messages.properties 6 | source_lang = en 7 | file_filter = api/src/main/resources/messages_.properties 8 | type = UNICODEPROPERTIES -------------------------------------------------------------------------------- /api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | org.openmrs.module 6 | coreapps 7 | 3.0.0-SNAPSHOT 8 | 9 | 10 | coreapps-api 11 | jar 12 | Core Apps Module API 13 | API project for CoreApps 14 | 15 | 16 | 17 | 18 | src/main/resources 19 | true 20 | 21 | 22 | 23 | 24 | 25 | src/test/resources 26 | true 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /api/src/main/java/org/openmrs/module/coreapps/CoreAppsProperties.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps; 2 | 3 | import org.openmrs.Location; 4 | import org.openmrs.module.emrapi.utils.ModuleProperties; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.util.StringUtils; 7 | 8 | /** 9 | * Properties for this module. 10 | */ 11 | @Component("coreAppsProperties") 12 | public class CoreAppsProperties extends ModuleProperties { 13 | 14 | // when adding a new patient identifier via the patient dashboard, the location to use if not specified (and the identifier type requires a location) 15 | public Location getDefaultPatientIdentifierLocation() { 16 | return getLocationByGlobalProperty(CoreAppsConstants.GP_DEFAULT_PATIENT_IDENTIFIER_LOCATION); 17 | } 18 | 19 | public int getRecentDiagnosisPeriodInDays() { 20 | String gp = getGlobalProperty(CoreAppsConstants.GP_RECENT_DIAGNOSIS_PERIOD_IN_DAYS, false); 21 | if (StringUtils.hasText(gp)) { 22 | try { 23 | return Integer.parseInt(gp); 24 | } catch (NumberFormatException e) { 25 | throw new IllegalStateException("Invalid configuration: number of days expected in " + CoreAppsConstants.GP_RECENT_DIAGNOSIS_PERIOD_IN_DAYS, e); 26 | } 27 | } 28 | return 730; //2 years 29 | } 30 | 31 | public String getDashboardUrl() { 32 | String url = getGlobalProperty(CoreAppsConstants.GP_DASHBOARD_URL, false); 33 | if (!StringUtils.hasText(url)) { 34 | return "/coreapps/clinicianfacing/patient.page?patientId={{patientId}}"; 35 | } 36 | else { 37 | return url; 38 | } 39 | } 40 | 41 | public String getDashboardUrlWithoutQueryParams() { 42 | String url = getGlobalProperty(CoreAppsConstants.GP_DASHBOARD_URL, false); 43 | if (!StringUtils.hasText(url)) { 44 | return "/coreapps/clinicianfacing/patient.page"; 45 | } 46 | else { 47 | return url.substring(0, url.indexOf("?")); 48 | } 49 | 50 | } 51 | 52 | public String getVisitsPageUrl() { 53 | String url = getGlobalProperty(CoreAppsConstants.GP_VISITS_PAGE_URL, false); 54 | if (!StringUtils.hasText(url)) { 55 | return "/coreapps/patientdashboard/patientDashboard.page?patientId={{patient.uuid}}#visits"; 56 | } 57 | else { 58 | return url; 59 | } 60 | } 61 | 62 | public String getVisitsPageWithSpecificVisitUrl() { 63 | String url = getGlobalProperty(CoreAppsConstants.GP_VISITS_PAGE_WITH_SPECIFIC_URL, false); 64 | if (!StringUtils.hasText(url)) { 65 | return "/coreapps/patientdashboard/patientDashboard.page?patientId={{patient.uuid}}&visitId={{visit.id}}#visits"; 66 | } 67 | else { 68 | return url; 69 | } 70 | } 71 | 72 | public Integer getPatientDashboardEncounterCount() { 73 | return getIntegerByGlobalProperty(CoreAppsConstants.GP_PATIENTDASHBOARD_ENCOUNTER_COUNT); 74 | } 75 | } -------------------------------------------------------------------------------- /api/src/main/java/org/openmrs/module/coreapps/contextmodel/PatientContextModel.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.contextmodel; 2 | 3 | import org.openmrs.Patient; 4 | 5 | /** 6 | * A very simple view of a patient, suitable for use in an app contextModel. 7 | * Ideally we'll eventually replace this with the actual patient web service representation, so we should keep anything 8 | * represented here consistent with that view 9 | */ 10 | public class PatientContextModel { 11 | 12 | private PersonContextModel person; 13 | 14 | /** 15 | * @deprecated this will disappear for consistency with web services, so prefer to use the uuid property 16 | */ 17 | @Deprecated 18 | private Integer patientId; 19 | 20 | private String uuid; 21 | 22 | public PatientContextModel(Patient patient) { 23 | this.person = new PersonContextModel(patient); 24 | this.patientId = patient.getPatientId(); 25 | this.uuid = patient.getUuid(); 26 | } 27 | 28 | public PersonContextModel getPerson() { 29 | return person; 30 | } 31 | 32 | /** 33 | * @deprecated this will disappear for consistency with web services, so prefer to use the uuid property 34 | */ 35 | @Deprecated 36 | public Integer getPatientId() { 37 | return patientId; 38 | } 39 | 40 | public String getUuid() { 41 | return uuid; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /api/src/main/java/org/openmrs/module/coreapps/contextmodel/PatientEncounterContextModel.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.contextmodel; 2 | 3 | import org.openmrs.Encounter; 4 | 5 | import java.util.Date; 6 | 7 | public class PatientEncounterContextModel { 8 | 9 | Date encounterDatetime; 10 | String encounterTypeName; 11 | String encounterTypeUuid; 12 | 13 | public PatientEncounterContextModel(Encounter encounter) { 14 | this.encounterDatetime = encounter.getEncounterDatetime(); 15 | this.encounterTypeName = encounter.getEncounterType().getName(); 16 | this.encounterTypeUuid = encounter.getEncounterType().getUuid(); 17 | } 18 | 19 | public Date getEncounterDatetime() { 20 | return encounterDatetime; 21 | } 22 | 23 | public String getEncounterTypeName() { 24 | return encounterTypeName; 25 | } 26 | 27 | public String getEncounterTypeUuid() { 28 | return encounterTypeUuid; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /api/src/main/java/org/openmrs/module/coreapps/contextmodel/PersonContextModel.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.contextmodel; 2 | 3 | import org.openmrs.Person; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * A very simple view of a person, suitable for use in an app contextModel. 9 | * Ideally we'll eventually replace this with the actual patient web service representation, so we should keep anything 10 | * represented here consistent with that view 11 | */ 12 | public class PersonContextModel { 13 | 14 | private String uuid; 15 | 16 | private Date birthdate; 17 | 18 | private boolean birthdateEstimated; 19 | 20 | private String gender; 21 | 22 | private boolean dead; 23 | 24 | private Integer age; 25 | 26 | private Date deathdate; 27 | 28 | public PersonContextModel(Person person) { 29 | this.uuid = person.getUuid(); 30 | this.birthdate = person.getBirthdate(); 31 | this.birthdateEstimated = person.getBirthdateEstimated(); 32 | this.gender = person.getGender(); 33 | this.dead = person.getDead(); 34 | this.age = person.getAge(); 35 | this.deathdate = person.getDeathDate(); 36 | } 37 | 38 | public String getUuid() { 39 | return uuid; 40 | } 41 | 42 | public Date getBirthdate() { 43 | return birthdate; 44 | } 45 | 46 | public boolean isBirthdateEstimated() { 47 | return birthdateEstimated; 48 | } 49 | 50 | public String getGender() { 51 | return gender; 52 | } 53 | 54 | public boolean isDead() { 55 | return dead; 56 | } 57 | 58 | public Integer getAge() { 59 | return age; 60 | } 61 | 62 | public Date getDeathdate() { 63 | return deathdate; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /api/src/main/java/org/openmrs/module/coreapps/customdatatype/CodedConceptDatatype.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.customdatatype; 2 | 3 | import org.openmrs.customdatatype.SerializingCustomDatatype; 4 | import org.springframework.stereotype.Component; 5 | 6 | /** 7 | * This class allows for coded concepts to be displayed as a drop-down when creating visit attributes. 8 | * The concept id MUST be set in the datatype configuration field. 9 | */ 10 | @Component 11 | public class CodedConceptDatatype extends SerializingCustomDatatype { 12 | 13 | /** 14 | * @see org.openmrs.customdatatype.SerializingCustomDatatype#serialize(java.lang.Object) 15 | */ 16 | @Override 17 | public String serialize(String typedValue) { 18 | return typedValue; 19 | } 20 | 21 | /** 22 | * @see org.openmrs.customdatatype.SerializingCustomDatatype#deserialize(java.lang.String) 23 | */ 24 | @Override 25 | public String deserialize(String serializedValue) { 26 | return serializedValue; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /api/src/main/java/org/openmrs/module/coreapps/customdatatype/LocationDatatype.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.customdatatype; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | import org.openmrs.Location; 5 | import org.openmrs.api.context.Context; 6 | import org.openmrs.customdatatype.SerializingCustomDatatype; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component("coreapps.LocationDatatype") 10 | public class LocationDatatype extends SerializingCustomDatatype{ 11 | 12 | @Override 13 | public String serialize(Location location) { 14 | if (location == null || location.getUuid() == null) { 15 | return null; 16 | } 17 | return location.getUuid(); 18 | } 19 | 20 | @Override 21 | public Location deserialize(String serializedValue) { 22 | if (StringUtils.isEmpty(serializedValue)) { 23 | return null; 24 | } 25 | return Context.getLocationService().getLocationByUuid(serializedValue); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /api/src/main/java/org/openmrs/module/coreapps/utils/PatientProgramComparator.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.utils; 2 | 3 | import org.openmrs.PatientProgram; 4 | import org.openmrs.util.OpenmrsUtil; 5 | 6 | import java.util.Comparator; 7 | 8 | /** 9 | * Note that this sorts the *most recent* first 10 | */ 11 | public class PatientProgramComparator implements Comparator { 12 | 13 | @Override 14 | public int compare(PatientProgram patientProgram1, PatientProgram patientProgram2) { 15 | 16 | // first sort by date enrolled (which should never be null, but we will sort null earliest) 17 | int result = OpenmrsUtil.compareWithNullAsEarliest(patientProgram2.getDateEnrolled(), patientProgram1.getDateEnrolled()); 18 | 19 | if (result != 0) { 20 | return result; 21 | } 22 | 23 | // then by date completed, with "active" (no completion date) ranking first 24 | // assumption: never should be two active programs (ie both date completed should not be null) 25 | result = OpenmrsUtil.compareWithNullAsLatest(patientProgram2.getDateCompleted(), patientProgram1.getDateCompleted()); 26 | 27 | if (result != 0) { 28 | return result; 29 | } 30 | 31 | result = OpenmrsUtil.compare(patientProgram2.getDateCreated(), patientProgram1.getDateCreated()); 32 | 33 | if (result != 0) { 34 | return result; 35 | } 36 | 37 | // just something to make this deterministic 38 | else { 39 | return patientProgram1.getUuid().compareTo(patientProgram2.getUuid()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /api/src/main/resources/liquibase.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 12 | Updated the value of patient dashboard URL global property 13 | 14 | 15 | property ='coreapps.dashboardUrl' and property_value='/coreapps/clinicianfacing/patient.page?patientId={{patientId}}&app=pih.app.clinicianDashboard' 16 | 17 | 18 | 19 | Remove incorrect default value of coreapps.patientSearchHandler global property 20 | 21 | 22 | property ='coreapps.patientSearchHandler' and property_value='patientByIdentifier' 23 | 24 | 25 | -------------------------------------------------------------------------------- /api/src/main/resources/moduleApplicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /omod/karma.conf.js: -------------------------------------------------------------------------------- 1 | process.env.CHROME_BIN = require('puppeteer').executablePath(); 2 | 3 | module.exports = function(config) { 4 | var pkg = require("./package.json"); 5 | var webpackConfig = require('./webpack.config'); 6 | webpackConfig.devtool = 'inline-source-map'; 7 | 8 | //Disable CommonsChunkPlugin as it breaks tests. 9 | var commonsChunkPluginIndex = webpackConfig.plugins.findIndex(function(plugin) { return plugin.chunkNames }); 10 | webpackConfig.plugins.splice(commonsChunkPluginIndex, 1); 11 | 12 | var karmaConfig = { 13 | browsers: ['ChromeHeadless'], 14 | customLaunchers: { 15 | ChromeHeadlessDocker: { 16 | base: 'ChromeHeadless', 17 | flags: [ 18 | "--disable-gpu", 19 | "--disable-dev-shm-usage", 20 | "--disable-setuid-sandbox", 21 | "--no-sandbox", 22 | ] 23 | } 24 | }, 25 | files: [ 26 | { pattern: 'node_modules/babel-polyfill/browser.js', instrument: false}, 27 | { pattern: pkg.config.sourceDir + '/karma.context.js' } 28 | ], 29 | frameworks: ['jasmine'], 30 | preprocessors: { 31 | '**/karma.context.js': ['webpack', 'sourcemap'] 32 | }, 33 | webpack: webpackConfig, 34 | webpackMiddleware: { 35 | stats: "errors-only" 36 | }, 37 | reporters: ['progress'], 38 | port: 9876, 39 | colors: true, 40 | logLevel: config.LOG_INFO, 41 | autoWatch: true, 42 | concurrency: Infinity, 43 | singleRun: true 44 | }; 45 | 46 | config.set(karmaConfig); 47 | }; -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/filter/AdminAuthorisationFilter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, 3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can 4 | * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under 5 | * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. 6 | * 7 | * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS 8 | * graphic logo is a trademark of OpenMRS Inc. 9 | */ 10 | package org.openmrs.module.coreapps.filter; 11 | 12 | import java.io.IOException; 13 | import java.util.Collection; 14 | 15 | import javax.servlet.Filter; 16 | import javax.servlet.FilterChain; 17 | import javax.servlet.FilterConfig; 18 | import javax.servlet.ServletException; 19 | import javax.servlet.ServletRequest; 20 | import javax.servlet.ServletResponse; 21 | import javax.servlet.http.HttpServletRequest; 22 | import javax.servlet.http.HttpServletResponse; 23 | 24 | import org.openmrs.User; 25 | import org.openmrs.api.context.Context; 26 | import org.openmrs.module.coreapps.CoreAppsConstants; 27 | import org.openmrs.web.WebConstants; 28 | 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | 32 | /** 33 | * This filter checks if an authenticated user trying to access administrative functions has the 34 | * System Administration privelege. It will intercept any requests with *admin/* in 35 | * its url. Unauthorised user will be redirected to the home page. 36 | */ 37 | public class AdminAuthorisationFilter implements Filter { 38 | 39 | private static final Logger log = LoggerFactory.getLogger(AdminAuthorisationFilter.class); 40 | 41 | /** 42 | * @see Filter#init(FilterConfig) 43 | */ 44 | public void init(FilterConfig filterConfig) throws ServletException { 45 | 46 | } 47 | 48 | /** 49 | * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, 50 | * javax.servlet.ServletResponse, javax.servlet.FilterChain) 51 | */ 52 | public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 53 | HttpServletRequest httpReq = (HttpServletRequest) req; 54 | User user = Context.getAuthenticatedUser(); 55 | if (user != null && !user.hasPrivilege(CoreAppsConstants.PRIVILEGE_SYSTEM_ADMINISTRATOR)) { 56 | httpReq.getSession().setAttribute(WebConstants.DENIED_PAGE, httpReq.getRequestURI()); 57 | HttpServletResponse httpRes = (HttpServletResponse) res; 58 | log.info("User {} lacks the privilege {}", user, CoreAppsConstants.PRIVILEGE_SYSTEM_ADMINISTRATOR); 59 | httpRes.sendRedirect(httpReq.getContextPath() + "/login.htm"); 60 | return; 61 | } 62 | chain.doFilter(req, res); 63 | } 64 | 65 | /** 66 | * @see Filter#destroy() 67 | */ 68 | public void destroy() { 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/FormatAddressFragmentController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the OpenMRS Public License 3 | * Version 1.0 (the "License"); you may not use this file except in 4 | * compliance with the License. You may obtain a copy of the License at 5 | * http://license.openmrs.org 6 | * 7 | * Software distributed under the License is distributed on an "AS IS" 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9 | * License for the specific language governing rights and limitations 10 | * under the License. 11 | * 12 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 13 | */ 14 | 15 | package org.openmrs.module.coreapps.fragment.controller; 16 | 17 | import org.apache.commons.beanutils.PropertyUtils; 18 | import org.openmrs.PersonAddress; 19 | import org.openmrs.layout.address.AddressSupport; 20 | import org.openmrs.layout.address.AddressTemplate; 21 | import org.openmrs.ui.framework.fragment.FragmentConfiguration; 22 | import org.openmrs.ui.framework.fragment.FragmentModel; 23 | 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | import java.util.Set; 27 | 28 | /** 29 | * Uses the default address layout from core 30 | */ 31 | public class FormatAddressFragmentController { 32 | 33 | public void controller(FragmentConfiguration config, 34 | FragmentModel model) { 35 | config.require("address"); 36 | PersonAddress address = (PersonAddress) config.getAttribute("address"); 37 | 38 | AddressTemplate addressSupport = AddressSupport.getInstance().getDefaultLayoutTemplate(); 39 | Set tokens = addressSupport.getNameMappings().keySet(); 40 | 41 | List formattedLines = new ArrayList(); 42 | for (String lineFormat : addressSupport.getLineByLineFormat()) { 43 | formattedLines.add(replaceWithProperties(lineFormat, tokens, address)); 44 | } 45 | 46 | model.addAttribute("lines", formattedLines); 47 | } 48 | 49 | private String replaceWithProperties(String lineFormat, Set tokens, Object object) { 50 | // replace all tokens with {{{token}}} so we can do simple string replacement below. (in case the value contains a token) 51 | for (String token : tokens) { 52 | lineFormat = lineFormat.replace(token, "{{{" + token + "}}}"); 53 | } 54 | 55 | // now substitute in values for {{{token}}} 56 | for (String token : tokens) { 57 | String replacement; 58 | try { 59 | replacement = (String) PropertyUtils.getProperty(object, token); 60 | } catch (Exception e) { 61 | throw new IllegalStateException("Then token '" + token + "' in the default address layout is not an address property"); 62 | } 63 | lineFormat = lineFormat.replace("{{{" + token + "}}}", replacement == null ? "" : replacement); 64 | } 65 | 66 | return lineFormat; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/administrativenotification/NotificationsFragmentController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.fragment.controller.administrativenotification; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.openmrs.module.appframework.domain.AdministrativeNotification; 5 | import org.openmrs.module.appframework.service.AdministrativeNotificationService; 6 | import org.openmrs.module.appui.UiSessionContext; 7 | import org.openmrs.ui.framework.annotation.SpringBean; 8 | import org.openmrs.ui.framework.fragment.FragmentModel; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class NotificationsFragmentController { 14 | 15 | public void get(@SpringBean AdministrativeNotificationService service, 16 | UiSessionContext sessionContext, 17 | FragmentModel model) { 18 | List notifications = new ArrayList(); 19 | for (AdministrativeNotification candidate : service.getAdministrativeNotifications()) { 20 | if (StringUtils.isEmpty(candidate.getRequiredPrivilege()) || 21 | sessionContext.getCurrentUser().hasPrivilege(candidate.getRequiredPrivilege())) { 22 | notifications.add(candidate); 23 | } 24 | } 25 | 26 | model.addAttribute("notifications", notifications); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/clinicianfacing/DiagnosisWidgetFragmentController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The contents of this file are subject to the OpenMRS Public License 3 | * Version 1.0 (the "License"); you may not use this file except in 4 | * compliance with the License. You may obtain a copy of the License at 5 | * http://license.openmrs.org 6 | * 7 | * Software distributed under the License is distributed on an "AS IS" 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9 | * License for the specific language governing rights and limitations 10 | * under the License. 11 | * 12 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 13 | */ 14 | package org.openmrs.module.coreapps.fragment.controller.clinicianfacing; 15 | 16 | import org.openmrs.Patient; 17 | import org.openmrs.module.coreapps.CoreAppsProperties; 18 | import org.openmrs.module.emrapi.diagnosis.Diagnosis; 19 | import org.openmrs.module.emrapi.patient.PatientDomainWrapper; 20 | import org.openmrs.ui.framework.annotation.InjectBeans; 21 | import org.openmrs.ui.framework.fragment.FragmentConfiguration; 22 | 23 | import java.util.Calendar; 24 | import java.util.List; 25 | 26 | 27 | public class DiagnosisWidgetFragmentController { 28 | 29 | public void controller(FragmentConfiguration config, @InjectBeans PatientDomainWrapper patientWrapper, 30 | @InjectBeans CoreAppsProperties properties) { 31 | config.require("patient"); 32 | Object patient = config.get("patient"); 33 | 34 | if (patient instanceof Patient) { 35 | patientWrapper.setPatient((Patient) patient); 36 | config.addAttribute("patient", patientWrapper); 37 | } else if (patient instanceof PatientDomainWrapper) { 38 | patientWrapper = (PatientDomainWrapper) patient; 39 | } else { 40 | throw new IllegalArgumentException("Patient must be of type Patient or PatientDomainWrapper"); 41 | } 42 | 43 | int days = properties.getRecentDiagnosisPeriodInDays(); 44 | Calendar recent = Calendar.getInstance(); 45 | recent.set(Calendar.DATE, -days); 46 | 47 | List recentDiagnoses = patientWrapper.getUniqueDiagnosesSince(recent.getTime()); 48 | config.addAttribute("recentDiagnoses", recentDiagnoses); 49 | config.addAttribute("recentPeriodIndays", days); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/conditionlist/ConditionsFragmentController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, 3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can 4 | * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under 5 | * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. 6 | * 7 | * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS 8 | * graphic logo is a trademark of OpenMRS Inc. 9 | */ 10 | package org.openmrs.module.coreapps.fragment.controller.conditionlist; 11 | 12 | import org.openmrs.Patient; 13 | import org.openmrs.api.context.Context; 14 | import org.openmrs.module.coreapps.CoreAppsConstants; 15 | import org.openmrs.ui.framework.annotation.FragmentParam; 16 | import org.openmrs.ui.framework.fragment.FragmentModel; 17 | 18 | /** 19 | * Controller for a fragment that displays conditions for a patient 20 | */ 21 | public class ConditionsFragmentController { 22 | 23 | public void controller(FragmentModel model, @FragmentParam("patientId") Patient patient) { 24 | model.addAttribute("hasModifyConditionsPrivilege", 25 | Context.getAuthenticatedUser().hasPrivilege(CoreAppsConstants.MANAGE_CONDITIONS_PRIVILEGE)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/dashboardwidgets/CustomLinksWidgetFragmentController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.fragment.controller.dashboardwidgets; 2 | 3 | import org.codehaus.jackson.map.ObjectMapper; 4 | import org.openmrs.Location; 5 | import org.openmrs.Patient; 6 | import org.openmrs.Visit; 7 | import org.openmrs.module.appframework.domain.AppDescriptor; 8 | import org.openmrs.module.appui.UiSessionContext; 9 | import org.openmrs.module.emrapi.adt.AdtService; 10 | import org.openmrs.module.emrapi.visit.VisitDomainWrapper; 11 | import org.openmrs.ui.framework.UiUtils; 12 | import org.openmrs.ui.framework.annotation.FragmentParam; 13 | import org.openmrs.ui.framework.annotation.SpringBean; 14 | import org.openmrs.ui.framework.fragment.FragmentConfiguration; 15 | import org.springframework.web.bind.annotation.RequestParam; 16 | 17 | import java.util.Map; 18 | 19 | public class CustomLinksWidgetFragmentController { 20 | 21 | public void controller(FragmentConfiguration config, 22 | UiUtils uiUtils, 23 | @FragmentParam("app") AppDescriptor app, 24 | @SpringBean("adtService") AdtService adtService, 25 | @RequestParam("patientId") Patient patient, 26 | UiSessionContext sessionContext) { 27 | 28 | Location visitLocation = adtService.getLocationThatSupportsVisits(sessionContext.getSessionLocation()); 29 | VisitDomainWrapper activeVisit = adtService.getActiveVisit(patient, visitLocation); 30 | 31 | ObjectMapper mapper = new ObjectMapper(); 32 | Map links = mapper.convertValue(app.getConfig().get("links"), Map.class); 33 | 34 | replacePatientVariables(links, patient, uiUtils); 35 | 36 | if (activeVisit != null) { 37 | replaceVisitVariables(links, activeVisit.getVisit(), uiUtils); 38 | } 39 | 40 | config.addAttribute("icon", app.getIcon()); 41 | config.addAttribute("label", app.getLabel()); 42 | config.addAttribute("links", links); 43 | } 44 | 45 | private void replacePatientVariables(Map links, Patient patient, UiUtils uiUtils) { 46 | for(Map.Entry entry: links.entrySet()){ 47 | entry.setValue(uiUtils.urlBind(entry.getValue(), patient)); 48 | } 49 | } 50 | 51 | private void replaceVisitVariables(Map links, Visit visit, UiUtils uiUtils) { 52 | for(Map.Entry entry: links.entrySet()){ 53 | entry.setValue(uiUtils.urlBind(entry.getValue(), visit)); 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/mergepatients/PatientSearchAndSelectWidgetFragmentController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.fragment.controller.mergepatients; 2 | 3 | import org.openmrs.Patient; 4 | import org.openmrs.api.AdministrationService; 5 | import org.openmrs.api.context.Context; 6 | import org.openmrs.module.appui.UiSessionContext; 7 | import org.openmrs.module.coreapps.CoreAppsConstants; 8 | import org.openmrs.module.emrapi.utils.GeneralUtils; 9 | import org.openmrs.ui.framework.UiFrameworkConstants; 10 | import org.openmrs.ui.framework.annotation.FragmentParam; 11 | import org.openmrs.ui.framework.annotation.SpringBean; 12 | import org.openmrs.ui.framework.fragment.FragmentModel; 13 | import org.openmrs.util.OpenmrsConstants; 14 | 15 | import java.text.SimpleDateFormat; 16 | import java.util.List; 17 | import java.util.Locale; 18 | 19 | /** 20 | * Fragment controller for patient search widget; sets the min # of search characters based on global property, 21 | * and loads last viewed patients for current user if "showLastViewedPatients" fragment config param=true 22 | */ 23 | public class PatientSearchAndSelectWidgetFragmentController { 24 | 25 | public void controller(FragmentModel model, UiSessionContext sessionContext, 26 | @SpringBean("adminService") AdministrationService administrationService, 27 | @FragmentParam(value = "showLastViewedPatients", required = false) Boolean showLastViewedPatients) { 28 | 29 | showLastViewedPatients = showLastViewedPatients != null ? showLastViewedPatients : false; 30 | 31 | model.addAttribute("minSearchCharacters", 32 | administrationService.getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_MIN_SEARCH_CHARACTERS, "1")); 33 | 34 | model.addAttribute("searchDelayShort", 35 | administrationService.getGlobalProperty(CoreAppsConstants.GP_SEARCH_DELAY_SHORT, "300")); 36 | 37 | model.addAttribute("searchDelayLong", 38 | administrationService.getGlobalProperty(CoreAppsConstants.GP_SEARCH_DELAY_LONG, "1000")); 39 | 40 | model.addAttribute("dateFormatJS", "DD MMM YYYY"); // TODO really should be driven by global property, but currently we only have a property for the java date format 41 | model.addAttribute("locale", Context.getLocale().getLanguage()); 42 | model.addAttribute("defaultLocale", new Locale(administrationService.getGlobalProperty((OpenmrsConstants.GLOBAL_PROPERTY_DEFAULT_LOCALE), "en")).getLanguage()); 43 | model.addAttribute("dateFormatter", new SimpleDateFormat(administrationService.getGlobalProperty(UiFrameworkConstants.GP_FORMATTER_DATE_FORMAT), 44 | Context.getLocale())); 45 | model.addAttribute("showLastViewedPatients", showLastViewedPatients); 46 | 47 | if (showLastViewedPatients) { 48 | List patients = GeneralUtils.getLastViewedPatients(sessionContext.getCurrentUser()); 49 | model.addAttribute("lastViewedPatients", patients); 50 | } 51 | 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/patientdashboard/ContactInfoFragmentController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The contents of this file are subject to the OpenMRS Public License 3 | * Version 1.0 (the "License"); you may not use this file except in 4 | * compliance with the License. You may obtain a copy of the License at 5 | * http://license.openmrs.org 6 | * 7 | * Software distributed under the License is distributed on an "AS IS" 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9 | * License for the specific language governing rights and limitations 10 | * under the License. 11 | * 12 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 13 | */ 14 | 15 | package org.openmrs.module.coreapps.fragment.controller.patientdashboard; 16 | 17 | import org.openmrs.Patient; 18 | import org.openmrs.module.emrapi.patient.PatientDomainWrapper; 19 | import org.openmrs.ui.framework.annotation.InjectBeans; 20 | import org.openmrs.ui.framework.fragment.FragmentConfiguration; 21 | 22 | public class ContactInfoFragmentController { 23 | 24 | public void controller(FragmentConfiguration config, 25 | @InjectBeans PatientDomainWrapper wrapper) { 26 | 27 | config.require("contextModel"); 28 | config.require("patient"); 29 | Object patient = config.get("patient"); 30 | if (patient instanceof Patient) { 31 | wrapper.setPatient((Patient) patient); 32 | config.addAttribute("patient", wrapper); 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/patientdashboard/ContactInfoInlineFragmentController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The contents of this file are subject to the OpenMRS Public License 3 | * Version 1.0 (the "License"); you may not use this file except in 4 | * compliance with the License. You may obtain a copy of the License at 5 | * http://license.openmrs.org 6 | * 7 | * Software distributed under the License is distributed on an "AS IS" 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9 | * License for the specific language governing rights and limitations 10 | * under the License. 11 | * 12 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 13 | */ 14 | 15 | package org.openmrs.module.coreapps.fragment.controller.patientdashboard; 16 | 17 | import org.openmrs.Patient; 18 | import org.openmrs.module.emrapi.patient.PatientDomainWrapper; 19 | import org.openmrs.ui.framework.annotation.InjectBeans; 20 | import org.openmrs.ui.framework.fragment.FragmentConfiguration; 21 | 22 | public class ContactInfoInlineFragmentController { 23 | 24 | public void controller(FragmentConfiguration config, 25 | @InjectBeans PatientDomainWrapper wrapper) { 26 | 27 | config.require("contextModel"); 28 | config.require("patient"); 29 | Object patient = config.get("patient"); 30 | if (patient instanceof Patient) { 31 | wrapper.setPatient((Patient) patient); 32 | config.addAttribute("patient", wrapper); 33 | } 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/patientdashboard/EditVisitFragmentController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.fragment.controller.patientdashboard; 2 | 3 | import org.openmrs.Visit; 4 | import org.openmrs.VisitType; 5 | import org.openmrs.VisitAttributeType; 6 | import org.openmrs.api.VisitService; 7 | import org.openmrs.module.appui.UiSessionContext; 8 | import org.openmrs.module.coreapps.utils.VisitTypeHelper; 9 | import org.openmrs.module.emrapi.adt.AdtService; 10 | import org.openmrs.module.emrapi.patient.PatientDomainWrapper; 11 | import org.openmrs.ui.framework.annotation.SpringBean; 12 | import org.openmrs.ui.framework.fragment.FragmentConfiguration; 13 | import org.openmrs.ui.framework.fragment.FragmentModel; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * EditVisit fragment. Allow editing of visit type and attributes 19 | */ 20 | public class EditVisitFragmentController { 21 | 22 | public void controller(FragmentConfiguration config, 23 | FragmentModel model, 24 | @SpringBean("adtService") AdtService adtService, 25 | @SpringBean("visitService") VisitService visitService, 26 | @SpringBean("visitTypeHelper") VisitTypeHelper visitTypeHelper, 27 | UiSessionContext sessionContext){ 28 | 29 | config.require("patient"); 30 | config.require("visit"); 31 | 32 | PatientDomainWrapper patientWrapper; 33 | Object patient = config.get("patient"); 34 | if (patient instanceof PatientDomainWrapper) { 35 | patientWrapper = (PatientDomainWrapper) patient; 36 | } else { 37 | throw new IllegalArgumentException("Patient must be of type PatientDomainWrapper"); 38 | } 39 | 40 | Visit visit = (Visit) config.get("visit"); 41 | 42 | // get visit types 43 | List visitTypes = visitTypeHelper.getUnRetiredVisitTypes(); 44 | 45 | // get visit attribute types 46 | List visitAttributeTypes = visitService.getAllVisitAttributeTypes(); 47 | 48 | model.addAttribute("patient", patientWrapper); 49 | model.addAttribute("visit", visit); 50 | model.addAttribute("visitTypes", visitTypes); 51 | model.addAttribute("visitAttributeTypes", visitAttributeTypes); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/patientheader/ActiveVisitStatusFragmentController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The contents of this file are subject to the OpenMRS Public License 3 | * Version 1.0 (the "License"); you may not use this file except in 4 | * compliance with the License. You may obtain a copy of the License at 5 | * http://license.openmrs.org 6 | * 7 | * Software distributed under the License is distributed on an "AS IS" 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9 | * License for the specific language governing rights and limitations 10 | * under the License. 11 | * 12 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 13 | */ 14 | 15 | package org.openmrs.module.coreapps.fragment.controller.patientheader; 16 | 17 | import org.openmrs.Location; 18 | import org.openmrs.Patient; 19 | import org.openmrs.module.appui.UiSessionContext; 20 | import org.openmrs.module.coreapps.utils.VisitTypeHelper; 21 | import org.openmrs.module.emrapi.adt.AdtService; 22 | import org.openmrs.module.emrapi.patient.PatientDomainWrapper; 23 | import org.openmrs.module.emrapi.visit.VisitDomainWrapper; 24 | import org.openmrs.ui.framework.UiUtils; 25 | import org.openmrs.ui.framework.annotation.FragmentParam; 26 | import org.openmrs.ui.framework.annotation.SpringBean; 27 | import org.openmrs.ui.framework.fragment.FragmentConfiguration; 28 | import org.openmrs.ui.framework.fragment.FragmentModel; 29 | 30 | public class ActiveVisitStatusFragmentController { 31 | 32 | public void controller(FragmentConfiguration config, 33 | @FragmentParam("patient") PatientDomainWrapper pdw, 34 | @SpringBean("adtService") AdtService adtService, 35 | @SpringBean("visitTypeHelper") VisitTypeHelper visitTypeHelper, 36 | UiSessionContext sessionContext, UiUtils uiUtils, FragmentModel model) { 37 | 38 | config.addAttribute("activeVisitStartDatetime", null); 39 | 40 | Patient patient = pdw.getPatient(); 41 | 42 | VisitDomainWrapper activeVisit = (VisitDomainWrapper) config.getAttribute("activeVisit"); 43 | if (activeVisit == null) { 44 | try { 45 | Location visitLocation = adtService.getLocationThatSupportsVisits(sessionContext.getSessionLocation()); 46 | activeVisit = adtService.getActiveVisit(patient, visitLocation); 47 | } catch (IllegalArgumentException ex) { 48 | // location does not support visits 49 | } 50 | } 51 | if (activeVisit != null) { 52 | config.addAttribute("activeVisit", activeVisit); 53 | config.addAttribute("activeVisitStartDatetime", uiUtils.format(activeVisit.getStartDatetime())); 54 | config.addAttribute("showVisitTypeOnPatientHeaderSection", visitTypeHelper.showVisitTypeOnPatientHeaderSection()); 55 | 56 | String color = (String) visitTypeHelper.getVisitTypeColorAndShortName(activeVisit.getVisit().getVisitType()).get("color"); 57 | 58 | model.addAttribute("visitAttributeColor", color); 59 | } 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/visit/ParsedObs.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The contents of this file are subject to the OpenMRS Public License 3 | * Version 1.0 (the "License"); you may not use this file except in 4 | * compliance with the License. You may obtain a copy of the License at 5 | * http://license.openmrs.org 6 | * 7 | * Software distributed under the License is distributed on an "AS IS" 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9 | * License for the specific language governing rights and limitations 10 | * under the License. 11 | * 12 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 13 | */ 14 | package org.openmrs.module.coreapps.fragment.controller.visit; 15 | 16 | import org.openmrs.ui.framework.SimpleObject; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | /** 22 | * Helper for converting the contents of an encounter to JSON 23 | */ 24 | public class ParsedObs { 25 | 26 | private List obs = new ArrayList(); 27 | 28 | private List diagnoses = new ArrayList(); 29 | 30 | private List dispositions = new ArrayList(); 31 | 32 | public ParsedObs() { 33 | } 34 | 35 | public List getObs() { 36 | return obs; 37 | } 38 | 39 | public void setObs(List obs) { 40 | this.obs = obs; 41 | } 42 | 43 | public List getDiagnoses() { 44 | return diagnoses; 45 | } 46 | 47 | public void setDiagnoses(List diagnoses) { 48 | this.diagnoses = diagnoses; 49 | } 50 | 51 | public List getDispositions() { 52 | return dispositions; 53 | } 54 | 55 | public void setDispositions(List dispositions) { 56 | this.dispositions = dispositions; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/fragment/controller/visit/VisitFragmentController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The contents of this file are subject to the OpenMRS Public License 3 | * Version 1.0 (the "License"); you may not use this file except in 4 | * compliance with the License. You may obtain a copy of the License at 5 | * http://license.openmrs.org 6 | * 7 | * Software distributed under the License is distributed on an "AS IS" 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9 | * License for the specific language governing rights and limitations 10 | * under the License. 11 | * 12 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 13 | */ 14 | package org.openmrs.module.coreapps.fragment.controller.visit; 15 | 16 | import org.openmrs.Location; 17 | import org.openmrs.Patient; 18 | import org.openmrs.Visit; 19 | import org.openmrs.module.appui.AppUiConstants; 20 | import org.openmrs.module.emrapi.adt.AdtService; 21 | import org.openmrs.module.emrapi.visit.VisitDomainWrapper; 22 | import org.openmrs.ui.framework.UiUtils; 23 | import org.openmrs.ui.framework.annotation.SpringBean; 24 | import org.openmrs.ui.framework.fragment.action.FragmentActionResult; 25 | import org.openmrs.ui.framework.fragment.action.SuccessResult; 26 | import org.springframework.transaction.annotation.Transactional; 27 | import org.springframework.web.bind.annotation.RequestParam; 28 | 29 | import javax.servlet.http.HttpServletRequest; 30 | import java.util.Date; 31 | 32 | public class VisitFragmentController { 33 | 34 | @Transactional 35 | public FragmentActionResult start(@SpringBean("adtService") AdtService adtService, 36 | @RequestParam("patientId") Patient patient, 37 | @RequestParam("locationId") Location location, 38 | @RequestParam(value = "stopActiveVisit", required = false) Boolean stopActive, 39 | UiUtils uiUtils, HttpServletRequest request) { 40 | 41 | VisitDomainWrapper activeVisit = adtService.getActiveVisit(patient, location); 42 | 43 | // if patient has an active visit close it 44 | if (patient != null && (activeVisit != null)) { 45 | Visit visit = activeVisit.getVisit(); 46 | if (visit != null && stopActive) { 47 | adtService.closeAndSaveVisit(visit); 48 | } 49 | } 50 | 51 | // create new visit and save it 52 | adtService.ensureVisit(patient, new Date(), location); 53 | 54 | request.getSession().setAttribute(AppUiConstants.SESSION_ATTRIBUTE_INFO_MESSAGE, 55 | uiUtils.message("emr.visit.createQuickVisit.successMessage", uiUtils.format(patient))); 56 | request.getSession().setAttribute(AppUiConstants.SESSION_ATTRIBUTE_TOAST_MESSAGE, "true"); 57 | return new SuccessResult(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/helper/SimplePatientPageController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.helper; 2 | 3 | import org.openmrs.Patient; 4 | import org.openmrs.module.appframework.domain.AppDescriptor; 5 | import org.openmrs.module.emrapi.patient.PatientDomainWrapper; 6 | import org.openmrs.ui.framework.annotation.InjectBeans; 7 | import org.openmrs.ui.framework.page.PageModel; 8 | import org.openmrs.ui.framework.page.Redirect; 9 | import org.springframework.web.bind.annotation.RequestParam; 10 | 11 | public class SimplePatientPageController { 12 | 13 | /** 14 | * Simple controller, sufficient for patient pages that will do all their work client-side and/or do not need 15 | * data beyond what is directly on PatientDomainWrapper. 16 | * 17 | * Exposes a model with: 18 | * * "patient" as a PatientDomainWrapper, based on the "patientId" parameter 19 | * * "app" as an AppDescriptor, based on the optional "app" parameter 20 | * 21 | * @param patient 22 | * @param patientDomainWrapper 23 | * @param app 24 | * @param model 25 | * @return 26 | */ 27 | public Redirect get(@RequestParam("patientId") Patient patient, 28 | @InjectBeans PatientDomainWrapper patientDomainWrapper, 29 | @RequestParam(required = false, value = "app") AppDescriptor app, 30 | PageModel model) { 31 | 32 | if (patient.isVoided() || patient.isPersonVoided()) { 33 | return new Redirect("coreapps", "patientdashboard/deletedPatient", "patientId=" + patient.getId()); 34 | } 35 | 36 | patientDomainWrapper.setPatient(patient); 37 | model.addAttribute("app", app); 38 | model.addAttribute("patient", patientDomainWrapper); 39 | 40 | return null; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/adt/AwaitingAdmissionDiagnosisFormatter.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.page.controller.adt; 2 | 3 | import org.openmrs.api.context.Context; 4 | import org.openmrs.module.emrapi.diagnosis.Diagnosis; 5 | import org.openmrs.module.reporting.data.converter.DataConverter; 6 | 7 | import java.util.List; 8 | 9 | public class AwaitingAdmissionDiagnosisFormatter implements DataConverter { 10 | 11 | @Override 12 | public Object convert(Object o) { 13 | List diagnoses = (List) o; 14 | StringBuffer output = new StringBuffer(); 15 | String prefix = ""; 16 | 17 | for (Diagnosis diagnosis : diagnoses) { 18 | if (diagnosis.getDiagnosis() != null) { 19 | output.append(prefix); 20 | prefix = ", "; 21 | output.append(diagnosis.getDiagnosis().formatWithoutSpecificAnswer(Context.getLocale())); 22 | } 23 | } 24 | 25 | return output.toString(); 26 | } 27 | 28 | @Override 29 | public Class getInputDataType() { 30 | return List.class; 31 | } 32 | 33 | @Override 34 | public Class getDataType() { 35 | return String.class; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/applist/AppListPageController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.page.controller.applist; 2 | 3 | import org.openmrs.module.appframework.domain.AppDescriptor; 4 | import org.openmrs.module.appframework.domain.Extension; 5 | import org.openmrs.module.appframework.service.AppFrameworkService; 6 | import org.openmrs.module.appui.UiSessionContext; 7 | import org.openmrs.ui.framework.annotation.SpringBean; 8 | import org.openmrs.ui.framework.page.PageModel; 9 | import org.springframework.web.bind.annotation.RequestParam; 10 | 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class AppListPageController { 15 | 16 | public void controller(@RequestParam("app") AppDescriptor app, PageModel model, UiSessionContext emrContext, 17 | @SpringBean("appFrameworkService") AppFrameworkService appFrameworkService) { 18 | 19 | emrContext.requireAuthentication(); 20 | 21 | List extensions = appFrameworkService.getExtensionsForCurrentUser(app.getId() + ".apps"); 22 | 23 | Collections.sort(extensions); 24 | 25 | model.addAttribute("app", app); 26 | model.addAttribute("extensions", extensions); 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/conditionlist/ManageConditionPageController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.page.controller.conditionlist; 2 | 3 | /** 4 | * The contents of this file are subject to the OpenMRS Public License 5 | * Version 1.0 (the "License"); you may not use this file except in 6 | * compliance with the License. You may obtain a copy of the License at 7 | * http://license.openmrs.org 8 | *

9 | * Software distributed under the License is distributed on an "AS IS" 10 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing rights and limitations 12 | * under the License. 13 | *

14 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 15 | */ 16 | 17 | import org.apache.commons.lang.StringUtils; 18 | import org.openmrs.ui.framework.page.PageModel; 19 | import org.springframework.web.bind.annotation.RequestParam; 20 | import org.openmrs.module.coreapps.CoreAppsConstants; 21 | import org.openmrs.api.context.Context; 22 | 23 | public class ManageConditionPageController { 24 | 25 | public void controller(PageModel model, @RequestParam(value = "conditionUuid", required = false) String conditionUuid, @RequestParam(value = "returnUrl", required = false) String returnUrl) { 26 | model.addAttribute("returnUrl", returnUrl); 27 | model.addAttribute("editingCondition", StringUtils.isNotBlank(conditionUuid)); 28 | String conditionListClasses = Context.getAdministrationService().getGlobalProperty(CoreAppsConstants.GLOBAL_PROPERTY_CONDITIONS_CRITERIA); 29 | model.addAttribute("conditionListClasses", conditionListClasses); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/conditionlist/ManageConditionsPageController.java: -------------------------------------------------------------------------------- 1 | /** 2 | This Source Code Form is subject to the terms of the Mozilla Public License, 3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can 4 | * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under 5 | * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. 6 | * 7 | * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS 8 | * graphic logo is a trademark of OpenMRS Inc. 9 | */ 10 | package org.openmrs.module.coreapps.page.controller.conditionlist; 11 | 12 | import org.apache.commons.lang.StringUtils; 13 | import org.openmrs.Patient; 14 | import org.openmrs.api.context.Context; 15 | import org.openmrs.module.coreapps.CoreAppsConstants; 16 | import org.openmrs.ui.framework.UiUtils; 17 | import org.openmrs.ui.framework.page.PageModel; 18 | import org.springframework.web.bind.annotation.RequestParam; 19 | 20 | import java.util.Collections; 21 | 22 | /** 23 | * Controller for a fragment that displays conditions for a patient 24 | * 25 | * @author owais.hussain@ihsinformatics.com 26 | */ 27 | public class ManageConditionsPageController { 28 | 29 | public void controller(PageModel model, @RequestParam("patientId") Patient patient, 30 | @RequestParam(value = "returnUrl", required = false) String returnUrl, UiUtils ui) { 31 | if (StringUtils.isBlank(returnUrl)) { 32 | returnUrl = ui.pageLink("coreapps", "clinicianfacing/patient", 33 | Collections.singletonMap("patientId", (Object) patient.getId())); 34 | } 35 | 36 | model.addAttribute("patient", patient); 37 | model.addAttribute("returnUrl", returnUrl); 38 | model.addAttribute("hasModifyConditionsPrivilege", 39 | Context.getAuthenticatedUser().hasPrivilege(CoreAppsConstants.MANAGE_CONDITIONS_PRIVILEGE)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/datamanagement/DataManagementPageController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.page.controller.datamanagement; 2 | 3 | 4 | import org.openmrs.module.appframework.domain.Extension; 5 | import org.openmrs.module.appframework.service.AppFrameworkService; 6 | import org.openmrs.module.appui.UiSessionContext; 7 | import org.openmrs.ui.framework.annotation.SpringBean; 8 | import org.openmrs.ui.framework.page.PageModel; 9 | 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | public class DataManagementPageController { 14 | 15 | public static final String DATA_MANAGEMENT_EXTENSION_POINT = "dataManagement.apps"; 16 | 17 | public void controller(PageModel model, UiSessionContext emrContext, 18 | @SpringBean("appFrameworkService") AppFrameworkService appFrameworkService) { 19 | 20 | emrContext.requireAuthentication(); 21 | 22 | List extensions = appFrameworkService.getExtensionsForCurrentUser(DATA_MANAGEMENT_EXTENSION_POINT); 23 | 24 | Collections.sort(extensions); 25 | model.addAttribute("extensions", extensions); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/findpatient/FindPatientPageController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.page.controller.findpatient; 2 | 3 | import org.openmrs.module.appframework.domain.AppDescriptor; 4 | import org.openmrs.module.appui.UiSessionContext; 5 | import org.openmrs.module.coreapps.helper.BreadcrumbHelper; 6 | import org.openmrs.ui.framework.UiUtils; 7 | import org.openmrs.ui.framework.page.PageModel; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | 10 | /** 11 | * 12 | */ 13 | public class FindPatientPageController { 14 | 15 | /** 16 | * This page is built to be shared across multiple apps. To use it, you must pass an "app" 17 | * request parameter, which must be the id of an existing app that is an instance of 18 | * coreapps.template.findPatient 19 | * 20 | * @param model 21 | * @param app 22 | * @param sessionContext 23 | */ 24 | public void get(PageModel model, @RequestParam("app") AppDescriptor app, UiSessionContext sessionContext, 25 | UiUtils ui) { 26 | 27 | model.addAttribute("afterSelectedUrl", app.getConfig().get("afterSelectedUrl").getTextValue()); 28 | model.addAttribute("heading", app.getConfig().get("heading").getTextValue()); 29 | model.addAttribute("label", app.getConfig().get("label").getTextValue()); 30 | model.addAttribute("showLastViewedPatients", app.getConfig().get("showLastViewedPatients").getBooleanValue()); 31 | if (app.getConfig().get("registrationAppLink") == null) { 32 | model.addAttribute("registrationAppLink",""); 33 | } else { 34 | model.addAttribute("registrationAppLink", app.getConfig().get("registrationAppLink").getTextValue()); 35 | } 36 | model.addAttribute("columnConfig", app.getConfig().get("columnConfig")); 37 | BreadcrumbHelper.addBreadcrumbsIfDefinedInApp(app, model, ui); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/providermanagement/ProviderListPageController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.page.controller.providermanagement; 2 | 3 | import org.openmrs.api.context.Context; 4 | import org.openmrs.module.providermanagement.Provider; 5 | import org.openmrs.module.providermanagement.ProviderManagementUtils; 6 | import org.openmrs.module.providermanagement.relationship.ProviderPersonRelationship; 7 | import org.openmrs.module.providermanagement.ProviderRole; 8 | import org.openmrs.module.providermanagement.api.ProviderManagementService; 9 | import org.openmrs.module.providermanagement.exception.PersonIsNotProviderException; 10 | import org.openmrs.ui.framework.annotation.SpringBean; 11 | import org.openmrs.ui.framework.page.PageModel; 12 | 13 | import java.util.ArrayList; 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | public class ProviderListPageController { 19 | 20 | public void get(PageModel model, 21 | @SpringBean("providerManagementService") ProviderManagementService providerManagementService 22 | ) throws PersonIsNotProviderException { 23 | 24 | Map> providers = new HashMap>(); 25 | List providerRoleList = providerManagementService.getRestrictedProviderRoles(false); 26 | if (providerRoleList != null && !providerRoleList.isEmpty()) { 27 | List providersByRoles = Context.getService(ProviderManagementService.class).getProvidersByRoles(providerRoleList); 28 | for (Provider providerByRole : providersByRoles) { 29 | List supervisorsForProvider = ProviderManagementUtils.getSupervisors(providerByRole); 30 | if (supervisorsForProvider == null) { 31 | supervisorsForProvider = new ArrayList(); 32 | } 33 | providers.put(providerByRole, supervisorsForProvider); 34 | } 35 | } 36 | model.addAttribute("providersList", providers); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/relationships/ListPageController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.page.controller.relationships; 2 | 3 | import org.openmrs.module.coreapps.helper.SimplePatientPageController; 4 | 5 | public class ListPageController extends SimplePatientPageController { 6 | 7 | // GET defined in superclass 8 | 9 | } 10 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/summarydashboard/SummaryDashboardPageController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.page.controller.summarydashboard; 2 | 3 | import org.openmrs.api.context.Context; 4 | import org.openmrs.module.appframework.context.AppContextModel; 5 | import org.openmrs.module.appframework.domain.AppDescriptor; 6 | import org.openmrs.module.appframework.domain.Extension; 7 | import org.openmrs.module.appframework.service.AppFrameworkService; 8 | import org.openmrs.module.appui.UiSessionContext; 9 | import org.openmrs.module.coreapps.CoreAppsConstants; 10 | import org.openmrs.ui.framework.annotation.SpringBean; 11 | import org.openmrs.ui.framework.page.PageModel; 12 | import org.openmrs.ui.framework.page.Redirect; 13 | import org.springframework.web.bind.annotation.RequestParam; 14 | 15 | import java.util.Collections; 16 | import java.util.List; 17 | 18 | public class SummaryDashboardPageController { 19 | 20 | public Object controller(@RequestParam("app") AppDescriptor app, 21 | @SpringBean("appFrameworkService") AppFrameworkService appFrameworkService, 22 | PageModel model, 23 | UiSessionContext sessionContext) { 24 | 25 | if (!Context.hasPrivilege(CoreAppsConstants.PRIVILEGE_SUMMARY_DASHBOARD)) { 26 | return new Redirect("coreapps", "noAccess", ""); 27 | } 28 | 29 | model.addAttribute("app", app); 30 | 31 | AppContextModel contextModel = sessionContext.generateAppContextModel(); 32 | model.addAttribute("appContextModel", contextModel); 33 | 34 | List actions = appFrameworkService.getExtensionsForCurrentUser(app.getId() + ".actions", contextModel); 35 | Collections.sort(actions); 36 | model.addAttribute("actions", actions); 37 | 38 | List includeFragments = appFrameworkService.getExtensionsForCurrentUser(app.getId() + ".includeFragments", contextModel); 39 | Collections.sort(includeFragments); 40 | model.addAttribute("includeFragments", includeFragments); 41 | 42 | List firstColumnFragments = appFrameworkService.getExtensionsForCurrentUser(app.getId() + ".firstColumnFragments", contextModel); 43 | Collections.sort(firstColumnFragments); 44 | model.addAttribute("firstColumnFragments", firstColumnFragments); 45 | 46 | List secondColumnFragments = appFrameworkService.getExtensionsForCurrentUser(app.getId() + ".secondColumnFragments", contextModel); 47 | Collections.sort(secondColumnFragments); 48 | model.addAttribute("secondColumnFragments", secondColumnFragments); 49 | 50 | return null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /omod/src/main/java/org/openmrs/module/coreapps/page/controller/systemadministration/SystemAdministrationPageController.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.page.controller.systemadministration; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import org.openmrs.api.APIAuthenticationException; 7 | import org.openmrs.module.appframework.domain.Extension; 8 | import org.openmrs.module.appframework.service.AppFrameworkService; 9 | import org.openmrs.module.appui.UiSessionContext; 10 | import org.openmrs.ui.framework.annotation.SpringBean; 11 | import org.openmrs.ui.framework.page.PageModel; 12 | 13 | public class SystemAdministrationPageController { 14 | 15 | public static final String SYSTEM_ADMINISTRATION_EXTENSION_POINT = "systemAdministration.apps"; 16 | 17 | public void controller(PageModel model, UiSessionContext emrContext, 18 | @SpringBean("appFrameworkService") AppFrameworkService appFrameworkService) { 19 | 20 | emrContext.requireAuthentication(); 21 | if (!emrContext.getCurrentUser().hasPrivilege("App: coreapps.systemAdministration") 22 | && (!emrContext.getCurrentUser().isSuperUser())) { 23 | throw new APIAuthenticationException(); 24 | } 25 | 26 | List extensions = appFrameworkService.getExtensionsForCurrentUser(SYSTEM_ADMINISTRATION_EXTENSION_POINT); 27 | 28 | Collections.sort(extensions); 29 | model.addAttribute("extensions", extensions); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /omod/src/main/resources/apps/activeVisits_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "coreapps.activeVisits", 4 | "instanceOf": "coreapps.template.activeVisits", 5 | "description": "coreapps.activeVisits.app.description", 6 | "order": 10, 7 | "extensions": [ 8 | { 9 | "id": "${project.parent.groupId}.${project.parent.artifactId}.activeVisitsHomepageLink", 10 | "extensionPointId": "org.openmrs.referenceapplication.homepageLink", 11 | "type": "link", 12 | "label": "coreapps.activeVisits.app.label", 13 | "url": "coreapps/activeVisits.page?app=coreapps.activeVisits", 14 | "icon": "icon-calendar", 15 | "requiredPrivilege": "App: coreapps.activeVisits" 16 | } 17 | ] 18 | } 19 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/awaitingAdmission_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "coreapps.awaitingAdmission", 4 | "instanceOf": "coreapps.template.awaitingAdmission", 5 | "description": "coreapps.awaitingAdmission.app.description", 6 | "order": 10, 7 | "extensions": [ 8 | { 9 | "id": "${project.parent.groupId}.${project.parent.artifactId}.awaitingAdmissionHomepageLink", 10 | "extensionPointId": "org.openmrs.referenceapplication.homepageLink", 11 | "type": "link", 12 | "label": "coreapps.app.awaitingAdmission.label", 13 | "url": "coreapps/adt/awaitingAdmission.page?app=coreapps.awaitingAdmission", 14 | "icon": "icon-list-ul", 15 | "requiredPrivilege": "App: coreapps.awaitingAdmission" 16 | } 17 | ] 18 | } 19 | ] 20 | -------------------------------------------------------------------------------- /omod/src/main/resources/apps/clinicianPatientDashboardOtherActions_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "${project.parent.artifactId}.clinicianFacingPatientDashboardApp", 4 | "description": "Contains extension points for the clinician facing patient dashboard", 5 | "extensionPoints": [ 6 | { 7 | "id": "clinicianFacingPatientDashboard.otherActions", 8 | "description": "Action items to add to the list below the 'General Actions' on the clinician facing patient dashboard" 9 | } 10 | ], 11 | "contextModel": [ "patient", "visit" ] 12 | } 13 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/conditionList_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "coreapps.conditionlist", 4 | "label": "coreapps.conditionui.conditions", 5 | "icon": "icon-medical", 6 | "order": 100, 7 | "extensions": [ 8 | { 9 | "id": "${project.parent.groupId}.${project.parent.artifactId}.conditionlist", 10 | "appId": "coreapps.conditionlist", 11 | "extensionPointId": "patientDashboard.secondColumnFragments", 12 | "extensionParams": { 13 | "provider": "${project.parent.artifactId}", 14 | "fragment": "conditionlist/conditions" 15 | } 16 | } 17 | ] 18 | } 19 | ] 20 | -------------------------------------------------------------------------------- /omod/src/main/resources/apps/dataManagement_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "coreapps.dataManagementApp", 4 | "description": "Data Management App", 5 | "extensionPoints": [ 6 | { 7 | "id": "dataManagement.apps", 8 | "description": "Apps on the Data Management Home Page" 9 | } 10 | ], 11 | "extensions": [ 12 | { 13 | "id": "coreapps.datamanagement.homepageLink", 14 | "extensionPointId": "org.openmrs.referenceapplication.homepageLink", 15 | "type": "link", 16 | "label": "coreapps.app.dataManagement.label", 17 | "url": "coreapps/datamanagement/dataManagement.page", 18 | "icon": "icon-hdd", 19 | "order": 89, 20 | "requiredPrivilege": "App: coreapps.dataManagement" 21 | } 22 | ] 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /omod/src/main/resources/apps/diagnoses_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "coreapps.diagnoses", 4 | "label": "coreapps.clinicianfacing.diagnoses", 5 | "icon": "icon-diagnosis", 6 | "order": 1, 7 | "extensions": [ 8 | { 9 | "id": "${project.parent.groupId}.${project.parent.artifactId}.diagnoses.clinicianDashboardFirstColumn", 10 | "appId": "coreapps.diagnoses", 11 | "extensionPointId": "patientDashboard.firstColumnFragments", 12 | "extensionParams": { 13 | "provider": "${project.parent.artifactId}", 14 | "fragment": "clinicianfacing/diagnosisWidget" 15 | } 16 | } 17 | ] 18 | } 19 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/findpatient_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "coreapps.findPatient", 4 | "instanceOf": "coreapps.template.findPatient", 5 | "description": "Basic patient search that goes to the patient dashboard", 6 | "order": 2, 7 | "extensions": [ 8 | { 9 | "id": "coreapps.activeVisitsHomepageLink", 10 | "extensionPointId": "org.openmrs.referenceapplication.homepageLink", 11 | "type": "link", 12 | "label": "coreapps.findPatient.app.label", 13 | "url": "coreapps/findpatient/findPatient.page?app=coreapps.findPatient", 14 | "icon": "icon-search", 15 | "requiredPrivilege": "App: coreapps.findPatient" 16 | } 17 | ] 18 | } 19 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/fragmentIncludes_extension.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "${project.parent.groupId}.${project.parent.artifactId}.patientDashboard.includeFragments", 4 | "extensionPointId": "patientDashboard.includeFragments", 5 | "extensionParams": { 6 | "provider": "${project.parent.artifactId}", 7 | "fragment": "patientdashboard/visitIncludes" 8 | } 9 | } 10 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/manageConcepts_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "owa.conceptdictionary", 4 | "description": "Concept OWA Dictionary", 5 | "order": 0, 6 | "extensions": [ 7 | { 8 | "id": "owa.conceptdictionary.adminGroup", 9 | "extensionPointId": "org.openmrs.module.adminui.adminGroups", 10 | "type": "group", 11 | "label": "Concepts", 12 | "icon": "icon-book" 13 | }, 14 | { 15 | "id": "owa.conceptdictionary.adminLink", 16 | "extensionPointId": "org.openmrs.module.adminui.adminLinks", 17 | "type": "link", 18 | "label": "Manage Concept Dictionary", 19 | "url": "owa/conceptdictionary/index.html", 20 | "extensionParams": { 21 | "group": "owa.conceptdictionary.adminGroup" 22 | } 23 | } 24 | ] 25 | } 26 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/mergePatients_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "coreapps.mergePatients", 4 | "description": "Merge patients medical records", 5 | "order": 1, 6 | "extensions": [ 7 | { 8 | "id": "coreapps.mergePatientsHomepageLink", 9 | "extensionPointId": "dataManagement.apps", 10 | "type": "link", 11 | "label": "coreapps.mergePatientsLong", 12 | "url": "coreapps/datamanagement/mergePatients.page?app=coreapps.mergePatients", 13 | "icon": "icon-group", 14 | "requiredPrivilege": "App: coreapps.mergePatient" 15 | } 16 | ] 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /omod/src/main/resources/apps/mostRecentVitals_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "coreapps.mostRecentVitals", 4 | "instanceOf": "coreapps.template.mostRecentEncounter", 5 | "description": "coreapps.mostRecentVitals.app.description", 6 | "label": "coreapps.clinicianfacing.vitals", 7 | "icon": "icon-vitals", 8 | "order": 10, 9 | "config": { 10 | "encounterTypeUuid": "67a71486-1a54-468f-ac3e-7091a9a79584", 11 | "encounterDateLabel": "coreapps.clinicianfacing.lastVitalsDateLabel" 12 | }, 13 | "extensions": [ 14 | { 15 | "id": "${project.parent.groupId}.${project.parent.artifactId}.mostRecentVitals.clinicianDashboardFirstColumn", 16 | "appId": "coreapps.mostRecentVitals", 17 | "extensionPointId": "patientDashboard.firstColumnFragments", 18 | "extensionParams": { 19 | "provider": "${project.parent.artifactId}", 20 | "fragment": "encounter/mostRecentEncounter" 21 | } 22 | } 23 | ] 24 | } 25 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/overallActions_extension.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "${project.parent.groupId}.${project.parent.artifactId}.createVisit", 4 | "extensionPointId": "patientDashboard.overallActions", 5 | "type": "script", 6 | "label": "coreapps.task.startVisit.label", 7 | "script": "visit.showQuickVisitCreationDialog({{patient.patientId}})", 8 | "icon": "icon-check-in", 9 | "order": -20, 10 | "require": "!visit && !patient.person.dead", 11 | "requiredPrivilege": "Task: coreapps.createVisit" 12 | }, 13 | { 14 | "id": "${project.parent.groupId}.${project.parent.artifactId}.createRetrospectiveVisit", 15 | "extensionPointId": "patientDashboard.overallActions", 16 | "type": "script", 17 | "label": "coreapps.task.createRetrospectiveVisit.label", 18 | "script": "visit.showRetrospectiveVisitCreationDialog()", 19 | "icon": "icon-plus", 20 | "order": -12, 21 | "requiredPrivilege": "Task: coreapps.createRetrospectiveVisit" 22 | }, 23 | { 24 | "id": "${project.parent.groupId}.${project.parent.artifactId}.mergeVisits", 25 | "extensionPointId": "patientDashboard.overallActions", 26 | "type": "link", 27 | "label": "coreapps.task.mergeVisits.label", 28 | "url": "coreapps/mergeVisits.page?patientId={{patient.uuid}}", 29 | "icon": "icon-link", 30 | "order": 13, 31 | "requiredPrivilege": "Task: coreapps.mergeVisits" 32 | }, 33 | { 34 | "id": "${project.parent.groupId}.${project.parent.artifactId}.markPatientDead", 35 | "extensionPointId": "patientDashboard.overallActions", 36 | "type": "Link", 37 | "label": "coreapps.markPatientDead.label", 38 | "url": "coreapps/markPatientDead.page?patientId={{patient.uuid}}", 39 | "icon": "icon-plus-sign-alt", 40 | "order": 24, 41 | "requiredPrivilege": "Task: coreapps.markPatientDead" 42 | }, 43 | { 44 | "id": "${project.parent.groupId}.${project.parent.artifactId}.deletePatient", 45 | "extensionPointId": "patientDashboard.overallActions", 46 | "type": "script", 47 | "label": "coreapps.task.deletePatient.label", 48 | "script": "delPatient.showDeletePatientCreationDialog('{{patient.uuid}}')", 49 | "icon": "icon-remove", 50 | "order": 25, 51 | "requiredPrivilege": "Task: coreapps.deletePatient" 52 | } 53 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/patientDashboard_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "${project.parent.artifactId}.patientDashboardApp", 4 | "description": "${project.parent.artifactId}.patientDashboard.description", 5 | "extensionPoints": [ 6 | { 7 | "id": "patientDashboard.visitActions", 8 | "description": "${project.parent.artifactId}.patientDashboard.extension.visits.description" 9 | }, 10 | { 11 | "id": "patientDashboard.overallActions", 12 | "description" : "${project.parent.artifactId}.patientDashboard.extension.actions.description" 13 | }, 14 | { 15 | "id": "patientDashboard.tabs", 16 | "description" : "Tabs to be added to the Data Entry Patient Dashboard" 17 | }, 18 | { 19 | "id": "patientDashboard.includeFragments", 20 | "description" : "Fragment to be added to the Patient Dashboards, may include javascript, css and possibly probably html code" 21 | } 22 | ], 23 | "contextModel": [ "patientId", "activeVisitId" ], 24 | "requiredPrivilege": "App: coreapps.patientDashboard" 25 | } 26 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/patientHeader_extension.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "${project.parent.groupId}.${project.parent.artifactId}.patientHeader.secondLineFragments.activeVisitStatus", 4 | "extensionPointId": "patientHeader.secondLineFragments", 5 | "extensionParams": { 6 | "provider": "${project.parent.artifactId}", 7 | "fragment": "patientheader/activeVisitStatus" 8 | } 9 | }, 10 | { 11 | "id": "${project.parent.groupId}.${project.parent.artifactId}.patientHeader.secondLineFragments.stickyNote", 12 | "extensionPointId": "patientHeader.secondLineFragments", 13 | "extensionParams": { 14 | "provider": "${project.parent.artifactId}", 15 | "fragment": "stickyNote" 16 | } 17 | } 18 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/apps/systemAdministration_app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "${project.parent.artifactId}.systemAdministrationApp", 4 | "description": "System Administration App", 5 | "extensionPoints": [ 6 | { 7 | "id": "systemAdministration.apps", 8 | "description": "Apps on the System Administration App Home Page" 9 | } 10 | ], 11 | "extensions": [ 12 | { 13 | "id": "coreapps.systemadministration.homepageLink", 14 | "extensionPointId": "org.openmrs.referenceapplication.homepageLink", 15 | "type": "link", 16 | "label": "coreapps.app.systemAdministration.label", 17 | "url": "coreapps/systemadministration/systemAdministration.page", 18 | "icon": "icon-cogs", 19 | "order": 100, 20 | "requiredPrivilege": "App: coreapps.systemAdministration" 21 | } 22 | ] 23 | } 24 | ] -------------------------------------------------------------------------------- /omod/src/main/resources/webModuleApplicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/bahmniappointments/bahmniappointments.component.js: -------------------------------------------------------------------------------- 1 | import BahmniAppointmentsController from './bahmniappointments.controller'; 2 | import template from './bahmniappointments.html'; 3 | 4 | export let BahmniAppointmentsComponent = { 5 | template, 6 | controller: BahmniAppointmentsController, 7 | selector: 'bahmniappointments', 8 | bindings: { 9 | config: '<' 10 | } 11 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/bahmniappointments/bahmniappointments.controller.js: -------------------------------------------------------------------------------- 1 | export default class BahmniAppointmentsController { 2 | constructor(openmrsRest, widgetsCommons, openmrsTranslate) { 3 | 'ngInject'; 4 | 5 | Object.assign(this, { openmrsRest, widgetsCommons, openmrsTranslate }); 6 | } 7 | 8 | $onInit() { 9 | //innitialise 10 | this.appointments = []; 11 | this.serverUrl = ""; 12 | this.startDate = new Date(); 13 | this.openmrsRest.setBaseAppPath("/coreapps"); 14 | this.openmrsRest.getServerUrl().then((result) => { 15 | this.serverUrl = result; 16 | }); 17 | //overiding default 'POST method' configurations 18 | let methodConfig = { 19 | url: '/appointments/search', 20 | actions: { save: { method: 'POST', isArray: true } } 21 | } 22 | 23 | this.openmrsRest.create(methodConfig, { 24 | patientUuid: this.config.patientUuid, 25 | startDate: this.startDate, 26 | limit: this.config.maxRecords 27 | }).then((response) => { 28 | this.getAppointments(response); 29 | }) 30 | } 31 | 32 | getAppointments(appointments) { 33 | if (appointments.length > 0) { 34 | angular.forEach(appointments, (appointment) => { 35 | let appointmentDetails = { 36 | date: appointment.startDateTime, 37 | startTime: appointment.startDateTime, 38 | endTime: appointment.endDateTime, 39 | ServiceType: appointment.service.name 40 | }; 41 | this.appointments.push(appointmentDetails); 42 | }) 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/bahmniappointments/bahmniappointments.html: -------------------------------------------------------------------------------- 1 |

    2 |
  • 3 |
    {{$ctrl.widgetsCommons.formatDate(appointment.date,$ctrl.config.JSDateFormat,$ctrl.config.language)}} {{appointment.startTime | date:'h:mm a'}} - {{appointment.endTime | date:'h:mm a'}} {{appointment.ServiceType | translate }}
    4 |
  • 5 |

    6 | {{'coreapps.none' | translate }} 7 |

    8 |
-------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/bahmniappointments/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import commons from './../dashboardwidgets.services'; 4 | import openmrsTranslate from '@openmrs/angularjs-openmrs-api'; 5 | 6 | import { BahmniAppointmentsComponent } from './bahmniappointments.component'; 7 | 8 | 9 | export default angular.module("openmrs-contrib-dashboardwidgets.appointments", [ openmrsApi, commons , openmrsTranslate]) 10 | .component(BahmniAppointmentsComponent.selector, BahmniAppointmentsComponent).name; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/dashboardwidgets.services.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import WidgetsCommons from './dashboardwidgetscommons.service'; 3 | 4 | let services = angular.module('dashboardwidgets.services', []); 5 | 6 | services.service('widgetsCommons', WidgetsCommons); 7 | 8 | export default services.name; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/dataintegrityviolations/dataintegrityviolations.component.js: -------------------------------------------------------------------------------- 1 | import DataIntegrityViolationsController from './dataintegrityviolations.controller'; 2 | import template from './dataintegrityviolations.html'; 3 | 4 | export let DatatIntegrityViolationsComponent = { 5 | template, 6 | controller: DataIntegrityViolationsController, 7 | selector: 'dataintegrityviolations', 8 | bindings: { 9 | config: '<' 10 | } 11 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/dataintegrityviolations/dataintegrityviolations.controller.js: -------------------------------------------------------------------------------- 1 | export default class DataIntegrityViolationsController { 2 | constructor (openmrsRest) { 3 | 'ngInject'; 4 | 5 | Object.assign(this, { openmrsRest }); 6 | } 7 | 8 | $onInit() { 9 | this.dataViolations = []; 10 | 11 | this.openmrsRest.setBaseAppPath("/coreapps"); 12 | this.openmrsRest.getServerUrl().then((result) => { 13 | this.serverUrl = result; 14 | }); 15 | 16 | // Set default maxResults if not defined 17 | if (angular.isUndefined(this.config.maxResults)) { 18 | this.config.maxResults = 6; 19 | } 20 | 21 | this.openmrsRest.list('dataintegrity/integrityresults', { patient: this.config.patientUuid, v: 'full', limit: this.config.maxResults }).then((resp) => { 22 | for (let index = 0; index < resp.results.length; index++) { 23 | this.dataViolations.push(resp.results[index]); 24 | } 25 | }); 26 | } 27 | } -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/dataintegrityviolations/dataintegrityviolations.html: -------------------------------------------------------------------------------- 1 |
2 |
    3 |
  • 4 |
    5 | 12 |
    13 | {{ dataViolation.notes ? dataViolation.notes : dataViolation.rule.ruleName}} 14 |
    15 |
    16 |
  • 17 |
18 |
19 |
20 | None 21 |
-------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/dataintegrityviolations/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import { DatatIntegrityViolationsComponent } from './dataintegrityviolations.component'; 4 | 5 | export default angular.module("openmrs-contrib-dashboardwidgets.dataintegrityviolations", [ openmrsApi ]) 6 | .component(DatatIntegrityViolationsComponent.selector, DatatIntegrityViolationsComponent).name; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/datepicker/datepicker.component.js: -------------------------------------------------------------------------------- 1 | import controller from './datepicker.controller'; 2 | import template from './datepicker.html'; 3 | 4 | export let DatepickerComponent = { 5 | template, 6 | controller, 7 | selector: 'openmrsDatepicker', 8 | bindings: { 9 | ngModel: '=', 10 | format: '@', 11 | language: '@', 12 | startDate: '<', 13 | endDate: '<', 14 | clearBtn: '<' 15 | } 16 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/datepicker/datepicker.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | 6 |
7 |
8 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/datepicker/locales/bootstrap-datepicker.ht.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creole translation for bootstrap-datetimepicker> 3 | * (Not provided by standard npm install of bootstrap-datepicker) 4 | */ 5 | (function($){ 6 | $.fn.datepicker.dates['ht'] = { 7 | days: ["dimanch", "lendi", "madi", "mèkredi", "jedi", "vandredi", "samdi"], 8 | daysShort: ["dim", "len", "mad", "mek", "jed", "van", "sam" ], 9 | daysMin: ["d", "l", "ma", "me", "j", "v", "s", "d"], 10 | months: ["janvye", "fevriye", "mas", "avril", "me", "jen", "jiyè", "out", "septanm", "oktòb", "novanm", "desanm"], 11 | monthsShort: ["jan", "fev", "mas", "avr", "me", "jen", "jiy", "out", "sep", "okt", "nov", "des"], 12 | today: "Jodi a", 13 | suffix: [], 14 | meridiem: ["am", "pm"], 15 | weekStart: 1, 16 | format: "dd/mm/yyyy" 17 | }; 18 | }(jQuery)); 19 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | 3 | import DataIntegrityViolations from './dataintegrityviolations'; 4 | import LatestObsForConceptList from './latestobsforconceptlist'; 5 | import ObsAcrossEncounters from './obsacrossencounters'; 6 | import ObsGraph from './obsgraph'; 7 | import Programs from './programs'; 8 | import ProgramStatistics from './programstatistics'; 9 | import ProgramStatus from './programstatus'; 10 | import Relationships from './relationships'; 11 | import VisitByEncounterType from './visitbyencountertype'; 12 | import BahmniAppointments from './bahmniappointments'; 13 | 14 | export default angular.module("openmrs-contrib-dashboardwidgets", [ DataIntegrityViolations, LatestObsForConceptList, 15 | ObsAcrossEncounters, ObsGraph, Programs, ProgramStatistics, ProgramStatus, Relationships, VisitByEncounterType ,BahmniAppointments]).name; 16 | 17 | 18 | angular.element(document).ready(function() { 19 | for (var dashboardwidget of document.getElementsByClassName('openmrs-contrib-dashboardwidgets')) { 20 | angular.bootstrap(dashboardwidget, [ 'openmrs-contrib-dashboardwidgets' ]); 21 | } 22 | }); -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/latestobsforconceptlist/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import commons from './../dashboardwidgets.services'; 4 | import { LatestObsForConceptListComponent } from './latestobsforconceptlist.component'; 5 | 6 | export default angular.module("openmrs-contrib-dashboardwidgets.latestobsforconceptlist", [ openmrsApi, commons ]) 7 | .component(LatestObsForConceptListComponent.selector, LatestObsForConceptListComponent).name; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/latestobsforconceptlist/latestobsforconceptlist.component.js: -------------------------------------------------------------------------------- 1 | import LatestObsForConceptListController from './latestobsforconceptlist.controller'; 2 | import template from './latestobsforconceptlist.html'; 3 | 4 | export let LatestObsForConceptListComponent = { 5 | template, 6 | controller: LatestObsForConceptListController, 7 | selector: 'latestobsforconceptlist', 8 | scope: {}, 9 | bindings: { 10 | config: '<' 11 | } 12 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/latestobsforconceptlist/latestobsforconceptlist.controller.js: -------------------------------------------------------------------------------- 1 | export default class LatestObsForConceptListController { 2 | constructor($filter, openmrsRest, widgetsCommons , openmrsTranslate) { 3 | 'ngInject'; 4 | 5 | Object.assign(this, {$filter, openmrsRest, openmrsTranslate, widgetsCommons }); 6 | } 7 | 8 | $onInit() { 9 | this.openmrsRest.setBaseAppPath("/coreapps"); 10 | this.maxAgeInDays = this.widgetsCommons.maxAgeToDays(this.config.maxAge); 11 | 12 | // Fetch last obs or obsGroup for the list of concepts 13 | return this.openmrsRest.list('latestobs', { 14 | patient: this.config.patientUuid, 15 | v: 'custom:(' + 16 | 'obsDatetime,' + 17 | 'concept:(uuid,display,datatype:(uuid),names:(name,locale,localePreferred,voided,conceptNameType)),' + 18 | 'value:(uuid,display,names:(name,locale,localePreferred,voided,conceptNameType)),' + 19 | 'groupMembers:(value,concept:(display,names:(name,locale,localePreferred,voided,conceptNameType))))', 20 | concept: this.config.concepts.split(',').map(c => c.trim()).join(','), 21 | nLatestObs: this.config.nLatestObs || 1 22 | }).then((resp) => { 23 | // Process the results from the list of concepts as not all of them may have data 24 | this.obs = resp.results.filter( 25 | // Don't add obs older than maxAge 26 | obs => angular.isUndefined(this.maxAgeInDays) || this.widgetsCommons.dateToDaysAgo(obs.obsDatetime) <= this.maxAgeInDays 27 | ).map(inputObs => { 28 | const displayObs = { obsDaysAgo: this.widgetsCommons.dateToDaysAgoMessage(inputObs.obsDatetime) }; 29 | displayObs.conceptName = this.widgetsCommons.getConceptName(inputObs.concept, this.config.conceptNameType, this.config.locale); 30 | if (inputObs.groupMembers) { // If obs is obs group 31 | displayObs.groupMembers = inputObs.groupMembers.map(member => { 32 | const prefix = ["FSN", "shortName", "preferred"].includes(this.config.obsGroupLabels) ? 33 | "(" + this.widgetsCommons.getConceptName(member.concept, this.config.obsGroupLabels, this.config.locale) + ") " : ""; 34 | const value = this.getObsValue(member); 35 | return { "prefix": prefix, "value": value }; 36 | }); 37 | } else { 38 | displayObs.value = this.getObsValue(inputObs); 39 | } 40 | return displayObs; 41 | }); 42 | }); 43 | } 44 | 45 | getObsValue(obs) { 46 | if (this.widgetsCommons.hasDatatypeDateOrSimilar(obs.concept)) { 47 | return this.$filter('date')(new Date(obs.value), this.config.dateFormat); 48 | } else if (this.widgetsCommons.hasDatatypeCoded(obs.concept)) { 49 | return this.widgetsCommons.getConceptName(obs.value, this.config.conceptNameType, this.config.locale); 50 | } else { 51 | return obs.value.display || obs.value; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/latestobsforconceptlist/latestobsforconceptlist.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • 3 |
    4 | 5 | {{obs.conceptName}}:  6 | 7 |
    8 | 9 | {{member.prefix}} {{member.value}} 10 | , 11 | 12 |
    13 | 14 | {{obs.value}} 15 | 16 | 17 | {{obs.obsDaysAgo}} 18 | 19 |
    20 |
  • 21 | 22 |

    23 | 24 | {{ 'coreapps.none.inLastTime' | translate }} {{$ctrl.maxAgeInDays}} {{ 'coreapps.days' | translate }} 25 | 26 | 27 | {{ 'coreapps.none' | translate }} 28 | 29 |

    30 |
-------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/obsacrossencounters/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import openmrsTranslate from '@openmrs/angularjs-openmrs-api'; 4 | import commons from './../dashboardwidgets.services'; 5 | 6 | import { ObsAcrossEncountersComponent } from './obsacrossencounters.component'; 7 | 8 | export default angular.module("openmrs-contrib-dashboardwidgets.obsacrossencounters", [ openmrsApi, openmrsTranslate, commons ]) 9 | .component(ObsAcrossEncountersComponent.selector, ObsAcrossEncountersComponent).name; 10 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/obsacrossencounters/obsacrossencounters.component.js: -------------------------------------------------------------------------------- 1 | import ObsAcrossEncountersController from './obsacrossencounters.controller'; 2 | import template from './obsacrossencounters.html'; 3 | 4 | export let ObsAcrossEncountersComponent = { 5 | template, 6 | controller: ObsAcrossEncountersController, 7 | selector: 'obsacrossencounters', 8 | bindings: { 9 | config: '<' 10 | } 11 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/obsacrossencounters/obsacrossencounters.html: -------------------------------------------------------------------------------- 1 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 48 | 49 | 50 |
{{ column | translate }}
41 | 42 | {{ cell.translate ? (cell.value | translate) : cell.value }} 43 | 44 | 45 | {{ cellElem.translate ? (cellElem.value | translate) : cellElem.value }}{{ $last ? '' : ', ' }} 46 | 47 |
51 | 52 |

53 | 54 | {{ 'coreapps.none.inLastTime' | translate }} {{$ctrl.output.maxAgeInDays}} {{ 'coreapps.days' | translate }} 55 | 56 | 57 | {{ 'coreapps.none' | translate }} 58 | 59 |

60 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/obsgraph/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import openmrsTranslate from '@openmrs/angularjs-openmrs-api'; 4 | import chartjs from 'angular-chart.js'; 5 | import commons from './../dashboardwidgets.services'; 6 | 7 | import { ObsGraphComponent } from './obsgraph.component'; 8 | 9 | export default angular.module("openmrs-contrib-dashboardwidgets.obsgraph", [openmrsApi, openmrsTranslate, commons, chartjs]) 10 | .component(ObsGraphComponent.selector, ObsGraphComponent) 11 | .config(['ChartJsProvider', function (ChartJsProvider) { 12 | ChartJsProvider.setOptions({ 13 | chartColors: ['#00463f', '#bf4f44', "#567fad"], 14 | spanGaps: true, 15 | elements: { 16 | line: { 17 | tension: 0 18 | } 19 | } 20 | }); 21 | }]).name; 22 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/obsgraph/obsgraph.component.js: -------------------------------------------------------------------------------- 1 | import ObsGraphController from './obsgraph.controller'; 2 | import template from './obsgraph.html'; 3 | 4 | export let ObsGraphComponent = { 5 | template, 6 | controller: ObsGraphController, 7 | selector: 'obsgraph', 8 | bindings: { 9 | config: '<' 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/obsgraph/obsgraph.html: -------------------------------------------------------------------------------- 1 |
2 | 4 |
5 |
6 |
7 | 8 | {{$ctrl.series.join(", ")}} 9 | 10 |
11 | 12 | {{ 'coreapps.none.inLastTime' | translate }} {{$ctrl.maxAgeInDays}} {{ 'coreapps.days' | translate }} 13 | 14 |
15 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/programs/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import openmrsTranslate from '@openmrs/angularjs-openmrs-api'; 4 | import commons from './../dashboardwidgets.services'; 5 | 6 | import { ProgramsComponent } from './programs.component'; 7 | 8 | export default angular.module("openmrs-contrib-dashboardwidgets.programs", [ openmrsApi, openmrsTranslate, commons ]) 9 | .component(ProgramsComponent.selector, ProgramsComponent).name; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/programs/programs.component.js: -------------------------------------------------------------------------------- 1 | // NOTE: work-in-progress, consider this not yet an "official" release of this widgets, future changes may not be bacwards-compatible and change functionality signficantly 2 | // TODO: document when we do an "official" release 3 | 4 | import ProgramsController from './programs.controller'; 5 | import template from './programs.html'; 6 | 7 | export let ProgramsComponent = { 8 | template, 9 | controller: ProgramsController, 10 | selector: 'programs', 11 | bindings: { 12 | config: '<' 13 | } 14 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/programs/programs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 |
    19 |
  • 20 | 21 | 22 | {{ patientProgram.program.display | limitTo: 16 }}{{patientProgram.program.display.length > 16 ? '...' : ''}} 23 | 24 | 25 |
    {{ $ctrl.widgetsCommons.formatDate(patientProgram.dateEnrolled,$ctrl.config.JSDateFormat,$ctrl.config.language) }} - {{'coreapps.dashboardwidgets.programs.current' | translate }}
    26 |
    {{ $ctrl.widgetsCommons.formatDate(patientProgram.dateEnrolled,$ctrl.config.JSDateFormat,$ctrl.config.language) }} - {{ $ctrl.widgetsCommons.formatDate(patientProgram.dateCompleted,$ctrl.config.JSDateFormat,$ctrl.config.language) }}
    27 |
  • 28 | 29 |
  • 30 | {{'coreapps.none' | translate }} 31 |
  • 32 | 33 |
34 | 35 | 36 |
37 | 38 | 39 | 40 |
41 | 42 |
43 |
44 | 48 |
49 |
50 |
51 | 52 | 53 |
54 |
55 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/programstatistics/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import openmrsTranslate from '@openmrs/angularjs-openmrs-api'; 4 | 5 | import { ProgramStatisticsComponent } from './programstatistics.component'; 6 | 7 | export default angular.module("openmrs-contrib-dashboardwidgets.programstatistics", [ openmrsApi, openmrsTranslate ]) 8 | .component(ProgramStatisticsComponent.selector, ProgramStatisticsComponent).name; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/programstatistics/programstatistics.component.js: -------------------------------------------------------------------------------- 1 | // NOTE: work-in-progress, consider this not yet an "official" release of this widgets, future changes may not be bacwards-compatible and change functionality signficantly 2 | // TODO: document when we do an "official" release 3 | 4 | import ProgramStatisticsController from './programstatistics.controller'; 5 | import template from './programstatistics.html'; 6 | 7 | export let ProgramStatisticsComponent = { 8 | template, 9 | controller: ProgramStatisticsController, 10 | selector: 'programstatistics', 11 | bindings: { 12 | config: '<' 13 | } 14 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/programstatistics/programstatistics.controller.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | 3 | export default class ProgramStatisticsController { 4 | 5 | constructor($filter, openmrsRest, openmrsTranslate) { 6 | 'ngInject'; 7 | 8 | Object.assign(this, {$filter, openmrsRest, openmrsTranslate}); 9 | } 10 | 11 | $onInit() { 12 | this.activate(); 13 | let ctrl = this; 14 | } 15 | 16 | activate() { 17 | this.openmrsRest.setBaseAppPath("/coreapps"); 18 | this.getEverEnrolledInProgram(); 19 | this.getCurrentlyEnrolledInProgram(); 20 | } 21 | 22 | getEverEnrolledInProgram() { 23 | return this.openmrsRest.get('reportingrest/cohort', { 24 | v: "ref", 25 | uuid: 'reporting.library.cohortDefinition.builtIn.patientsWithEnrollment', 26 | programs: [this.config.program] 27 | }).then((response) => { 28 | this.everEnrolled = (response && 'count' in response ? response.count : this.$filter('translate')('coreapps.dashboardwidgets.programstatistics.error')); 29 | }); 30 | } 31 | 32 | getCurrentlyEnrolledInProgram() { 33 | return this.openmrsRest.get('reportingrest/cohort', { 34 | v: "ref", 35 | uuid: 'reporting.library.cohortDefinition.builtIn.patientsInProgram', 36 | programs: [this.config.program], 37 | onDate: new Date 38 | }).then((response) => { 39 | this.currentlyEnrolled = (response && 'count' in response ? response.count : this.$filter('translate')('coreapps.dashboardwidgets.programstatistics.error')); 40 | }); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/programstatistics/programstatistics.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • {{'coreapps.dashboardwidgets.programstatistics.currentlyEnrolled' | translate }}: {{ $ctrl.currentlyEnrolled != null ? $ctrl.currentlyEnrolled : 'coreapps.dashboardwidgets.programstatistics.loading' | translate }}
  • 3 |
  • {{'coreapps.dashboardwidgets.programstatistics.everEnrolled' | translate }}: {{ $ctrl.everEnrolled != null ? $ctrl.everEnrolled : 'coreapps.dashboardwidgets.programstatistics.loading' | translate }}
  • 4 |
-------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/programstatus/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import openmrsTranslate from '@openmrs/angularjs-openmrs-api'; 4 | import datepicker from './../datepicker'; 5 | import commons from './../dashboardwidgets.services'; 6 | 7 | import { ProgramStatusComponent } from './programstatus.component'; 8 | 9 | export default angular.module("openmrs-contrib-dashboardwidgets.programstatus", [ openmrsApi, datepicker, openmrsTranslate, commons ]) 10 | .component(ProgramStatusComponent.selector, ProgramStatusComponent).name; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/programstatus/programstatus.component.js: -------------------------------------------------------------------------------- 1 | // NOTE: work-in-progress, consider this not yet an "official" release of this widgets, future changes may not be bacwards-compatible and change functionality signficantly 2 | // TODO: document when complete 3 | 4 | 5 | import controller from './programstatus.controller'; 6 | import template from './programstatus.html'; 7 | 8 | export let ProgramStatusComponent = { 9 | template, 10 | controller, 11 | selector: 'programstatus', 12 | bindings: { 13 | config: '<' 14 | } 15 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/relationships/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import openmrsTranslate from '@openmrs/angularjs-openmrs-api'; 4 | import typeahead from 'angular-ui-bootstrap/src/typeahead'; 5 | 6 | import { RelationshipsComponent } from './relationships.component'; 7 | 8 | export default angular.module("openmrs-contrib-dashboardwidgets.relationships", [ openmrsApi, typeahead, openmrsTranslate ]) 9 | .component(RelationshipsComponent.selector, RelationshipsComponent).name; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/relationships/relationships.component.js: -------------------------------------------------------------------------------- 1 | import RelationshipsController from './relationships.controller'; 2 | import template from './relationships.html'; 3 | 4 | export let RelationshipsComponent = { 5 | template, 6 | controller: RelationshipsController, 7 | selector: 'relationships', 8 | bindings: { 9 | config: '<' 10 | } 11 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/visitbyencountertype/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import openmrsApi from '@openmrs/angularjs-openmrs-api'; 3 | import commons from './../dashboardwidgets.services'; 4 | import openmrsTranslate from '@openmrs/angularjs-openmrs-api'; 5 | 6 | import { VisitByEncounterTypeComponent } from './visitbyencountertype.component'; 7 | 8 | 9 | export default angular.module("openmrs-contrib-dashboardwidgets.visitbyencountertype", [ openmrsApi, commons , openmrsTranslate]) 10 | .component(VisitByEncounterTypeComponent.selector, VisitByEncounterTypeComponent).name; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/visitbyencountertype/visitbyencountertype.component.js: -------------------------------------------------------------------------------- 1 | import VisitByEncounterTypeController from './visitbyencountertype.controller'; 2 | import template from './visitbyencountertype.html'; 3 | 4 | export let VisitByEncounterTypeComponent = { 5 | template, 6 | controller: VisitByEncounterTypeController, 7 | selector: 'visitbyencountertype', 8 | bindings: { 9 | config: '<' 10 | } 11 | }; -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/visitbyencountertype/visitbyencountertype.controller.js: -------------------------------------------------------------------------------- 1 | export default class VisitByEncounterTypeController { 2 | constructor(openmrsRest, widgetsCommons , openmrsTranslate) { 3 | 'ngInject'; 4 | 5 | Object.assign(this, {openmrsRest, widgetsCommons , openmrsTranslate}); 6 | } 7 | 8 | $onInit() { 9 | this.visits = []; 10 | this.serverUrl = ""; 11 | 12 | this.openmrsRest.setBaseAppPath("/coreapps"); 13 | this.openmrsRest.getServerUrl().then((result) => { 14 | this.serverUrl = result; 15 | }); 16 | 17 | //fetchVisits 18 | this.openmrsRest.get('visit', { 19 | patient: this.config.patientUuid, 20 | limit: this.getMaxRecords(), 21 | fromStartDate: this.widgetsCommons.maxAgeToDate(this.config.maxAge), 22 | v: 'custom:(uuid,startDatetime,stopDatetime,encounters:(uuid,encounterDatetime,encounterType:(uuid,display)))' 23 | }).then((response) => { 24 | this.getVisits(response.results); 25 | }) 26 | } 27 | 28 | getVisits(visits) { 29 | angular.forEach(visits, (visit) => { 30 | let encounterTypes = []; 31 | if(this.getCombineEncounterTypes()){ 32 | let vis = {startDatetime: visit.startDatetime, encounterType: '', uuid: visit.uuid}; 33 | angular.forEach(visit.encounters, (encounter) => { 34 | if (encounterTypes.indexOf(encounter.encounterType.display) == -1) { 35 | if (vis.encounterType === '') { 36 | vis.encounterType = encounter.encounterType.display; 37 | } else { 38 | vis.encounterType += ', ' + encounter.encounterType.display; 39 | } 40 | encounterTypes.push(encounter.encounterType.display); 41 | } 42 | }); 43 | this.visits.push(vis); 44 | } else { 45 | angular.forEach(visit.encounters, (encounter) => { 46 | if (encounterTypes.indexOf(encounter.encounterType.display) == -1) { 47 | let vis = {startDatetime: this.config.showEncounterDate === 'true' ? encounter.encounterDatetime : visit.startDatetime }; 48 | vis.encounterType = encounter.encounterType.display; 49 | encounterTypes.push(encounter.encounterType.display); 50 | this.visits.push(vis); 51 | } 52 | }) 53 | } 54 | }) 55 | } 56 | 57 | getCombineEncounterTypes() { 58 | if(this.config.combineEncounterTypes === 'false'){ 59 | return false; 60 | } else { 61 | return true; 62 | } 63 | } 64 | 65 | getMaxRecords() { 66 | if(this.config.maxRecords == '' || angular.isUndefined(this.config.maxRecords)){ 67 | return 6; 68 | } else { 69 | return this.config.maxRecords; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /omod/src/main/web/dashboardwidgets/visitbyencountertype/visitbyencountertype.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /omod/src/main/web/karma.context.js: -------------------------------------------------------------------------------- 1 | var context = require.context('.', true, /.spec\.js$/); 2 | context.keys().forEach(context); -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/administrativenotification/notifications.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | def filterActions = { actions -> 3 | if (!actions) { return [] }; 4 | return actions.findAll { 5 | !it.requiredPrivilege || context.hasPrivilege(it.requiredPrivilege) 6 | } 7 | } 8 | 9 | def actionHref = { act -> 10 | if (act.url) { 11 | return "/" + ui.contextPath() + act.url; 12 | } 13 | else if (act.script) { 14 | return "javascript:" + act.script; 15 | } 16 | else { 17 | return "#"; 18 | } 19 | } 20 | %> 21 | <% if (notifications) { %> 22 |
23 | <% notifications.each { notification -> 24 | def actions = filterActions(notification.actions) 25 | %> 26 |
27 |
28 | <% if (notification.icon) { %> 29 | 30 | <% } %> 31 |

${ ui.message(notification.label) }

32 | <% if (notification.actions) { %> 33 |

34 | <% notification.actions.each { act -> %> 35 | ${ui.message(act.label)} 36 | <% } %> 37 |

38 | <% } %> 39 |
40 |
41 | <% } %> 42 |
43 | <% } %> -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/clinicianfacing/diagnosisWidget.gsp: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |

${ ui.message("coreapps.clinicianfacing.diagnoses").toUpperCase() }

5 |
6 |
7 | <% if (!config.recentDiagnoses) { %> 8 | ${ ui.message("coreapps.none.inLastPeriod", ui.encodeHtmlContent(ui.format(config.recentPeriodIndays))) } 9 | <% } else { %> 10 |
    11 | <% config.recentDiagnoses.each { %> 12 |
  • 13 | <% if(it.diagnosis.nonCodedAnswer) { %> 14 | "${ui.escapeHtml(it.diagnosis.nonCodedAnswer)}" 15 | <% } else { %> 16 | ${ui.format(it.diagnosis.codedAnswer)} 17 | <% } %> 18 |
  • 19 | <% } %> 20 |
21 | <% } %> 22 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/conditionlist/conditions.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.includeFragment("appui", "standardEmrIncludes") 3 | 4 | ui.includeJavascript("uicommons", "angular.min.js") 5 | ui.includeJavascript("uicommons", "angular-ui/ui-bootstrap-tpls-0.11.2.min.js") 6 | ui.includeJavascript("uicommons", "angular-resource.min.js") 7 | ui.includeJavascript("uicommons", "angular-common.js") 8 | 9 | ui.includeJavascript("coreapps", "conditionlist/restful-services/restful-service.js"); 10 | ui.includeJavascript("coreapps", "conditionlist/emr.messages.js") 11 | ui.includeJavascript("coreapps", "conditionlist/common.functions.js") 12 | ui.includeJavascript("coreapps", "conditionlist/controllers/conditions.controller.js") 13 | 14 | ui.includeJavascript("coreapps", "conditionlist/common.functions.js") 15 | 16 | ui.includeCss("coreapps", "conditionlist/conditions.css") 17 | %> 18 | 19 |
21 |
22 | 23 | 24 |

${ui.message('coreapps.conditionui.conditions').toUpperCase()}

25 | 27 |
28 | 29 |
30 |
    31 |
  • {{formatCondition(condition)}}
  • 32 |
33 |

34 | ${ui.message("coreapps.none")} 35 |

36 |
37 | 38 | 52 |
53 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/dashboardwidgets/customLinksWidget.gsp: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/dashboardwidgets/dashboardWidget.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.includeJavascript("coreapps", "web/coreapps.vendor.js") 3 | ui.includeJavascript("coreapps", "web/coreapps.dashboardwidgets.js") 4 | ui.includeJavascript("uicommons", "handlebars/handlebars.js") 5 | 6 | def editIcon = config.editIcon ?: "icon-share-alt" 7 | %> 8 |
9 |
10 | 11 |

${ ui.message(config.label) }

12 | <% if (editIcon && config.detailsUrl) { %> 13 | 15 | <% } %> 16 |
17 |
18 | <${config.widget} config="${config.json}"> 19 |
20 |
21 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/datamanagement/diagnosisAutocompleteTemplate.gsp: -------------------------------------------------------------------------------- 1 | <% /* This is a knockout template, so we can use data-binds inside */ %> 2 | 34 | <% /* This is an underscore template */ %> 35 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/findPatientById.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.includeJavascript("coreapps", "custom/findPatientById.js") 3 | 4 | %> 5 | 6 | 32 | 33 | 34 | 35 |
36 | 37 |
38 |
39 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/formatAddress.gsp: -------------------------------------------------------------------------------- 1 |
2 | <% lines.each { %> 3 | ${ ui.encodeHtml(it) }
4 | <% } %> 5 |
-------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/htmlformentry/codedOrFreeTextAnswer.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | config.require("formFieldName") 3 | 4 | ui.includeJavascript("uicommons", "angular.min.js") 5 | ui.includeJavascript("uicommons", "angular-resource.min.js") 6 | ui.includeJavascript("uicommons", "angular-ui/ui-bootstrap-tpls-0.6.0.min.js") 7 | ui.includeJavascript("uicommons", "angular-common.js") 8 | ui.includeJavascript("uicommons", "angular-sanitize.min.js") 9 | ui.includeJavascript("uicommons", "services/conceptSearchService.js") 10 | ui.includeJavascript("uicommons", "directives/coded-or-free-text-answer.js") 11 | ui.includeJavascript("coreapps", "htmlformentry/codedOrFreeTextAnswer.js") 12 | 13 | ui.includeCss("coreapps", "htmlformentry/codedOrFreeTextAnswerList.css") 14 | %> 15 | 16 |
17 | class="${ ui.escapeAttribute(config.containerClasses) }"<% } %>> 18 | 19 | 20 | 21 |

22 | 23 |
24 | 25 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/patientdashboard/activeDrugOrders.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | def careSettings = activeDrugOrders.collect{it.careSetting}.unique(); 3 | detailsUrl = detailsUrl ? detailsUrl.replace("{{patientUuid}}", patient.uuid) : null; 4 | returnUrl = returnUrl ? returnUrl.replace("{{patientUuid}}", patient.uuid) : ""; 5 | %> 6 | 7 | 15 | 16 |
17 | 18 |
19 | 20 |

${ ui.message("coreapps.patientdashboard.activeDrugOrders").toUpperCase() }

21 | <% if (detailsUrl && context.hasPrivilege("App: orderentryui.drugOrders")) { %> 22 | 23 | 24 | 25 | <% } %> 26 |
27 | 28 |
29 | <% if (!activeDrugOrders) { %> 30 | ${ ui.message("emr.none") } 31 | <% } else { %> 32 | 33 | <% careSettings.each { careSetting -> %> 34 |

${ ui.format(careSetting) }

35 |
    36 | <% activeDrugOrders.findAll{ it.careSetting == careSetting }.each { %> 37 |
  • 38 | 39 | ${ it.dosingInstructionsInstance.getDosingInstructionsAsString(sessionContext.locale) } 40 | <% if (displayActivationDate) { %> 41 | ${ ui.formatDatetimePretty(it.dateActivated) } 42 | <% } %> 43 |
  • 44 | <% } %> 45 |
46 | <% } %> 47 | <% } %> 48 |
49 | 50 |
51 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/patientdashboard/contactInfo.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | config.contextModel.put("returnUrl", ui.thisUrl()) 3 | %> 4 | 5 |

${ui.message("coreapps.patientDashBoard.contactinfo")}

6 | 7 |
8 | 9 | <%= ui.includeFragment("appui", "extensionPoint", [ id: "patientHeader.editPatientContactInfo", contextModel: config.contextModel ]) %> 10 | 11 |
12 | 13 |
14 |
15 | ${ ui.message("coreapps.person.address")}:
16 |
${ ui.format(config.patient.personAddress).replace("\n", "
") }
17 |
18 |
19 |
20 | ${ ui.message("coreapps.person.telephoneNumber")}: 21 | ${config.patient.telephoneNumber ?: ''} 22 |
23 |
24 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/patientdashboard/contactInfoInline.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | config.contextModel.put("returnUrl", ui.thisUrl()) 3 | %> 4 | 5 |
6 | 7 | ${ ui.encodeHtmlContent(ui.format(config.patient.personAddress).replace("\n", ", "))} 8 | ${ ui.message("coreapps.person.address")} 9 | 10 | 11 | 12 | ${ ui.encodeHtmlContent(config.patient.telephoneNumber ?: '') } 13 | 14 | ${ ui.message("coreapps.person.telephoneNumber")} 15 | 16 | <% if(!config.hideEditDemographicsButton) { %> 17 | 18 | <%= ui.includeFragment("appui", "extensionPoint", [ id: "patientHeader.editPatientContactInfo", contextModel: config.contextModel ]) %> 19 | 20 | <% } %> 21 |
22 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/patientdashboard/editVisitDatesDialog.gsp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/patientdashboard/encountertemplate/hiddenEncounterTemplate.gsp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/patientdashboard/encountertemplate/noDetailsEncounterTemplate.gsp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/patientdashboard/visitDetailsTemplate.gsp: -------------------------------------------------------------------------------- 1 |
2 | [[ if (stopDatetime) { ]] 3 | ${ ui.message("coreapps.visitDetails", '[[- startDatetime ]]', '[[- stopDatetime ]]') } 4 | [[ } else { ]] 5 | ${ ui.message("coreapps.activeVisit") } 6 | 7 | ${ ui.message("coreapps.activeVisit.time", '[[- startDatetime ]]') } 8 | [[ } ]] 9 | [[ if (canDeleteVisit) { ]] 10 | ${ ui.message("coreapps.task.deleteVisit.label")} 11 | | 12 | [[ } ]] 13 | ${ ui.message("coreapps.task.editVisitDate.label")} 14 | [[ if (canEditVisit) { ]] 15 | | 16 | ${ ui.message("coreapps.task.editVisit.label")} 17 | [[ } ]] 18 | 19 |
20 | 21 |
22 | [[ if (stopDatetime) { ]] 23 |

${ ui.message("coreapps.patientDashboard.actionsForInactiveVisit") }

24 | [[ } ]] 25 | <% visitActions.each { task -> %> 26 | 27 | [[ if (_.contains(availableVisitActions, '${task.id}')) { ]] 28 | 29 | <% def returnUrl = ui.thisUrl().replaceAll("visitId=\\d+","") + "visitId={{visit.id}}"; // make sure the returnUrl includes a visit parameter so that it can be dynamically populated based on current selected visit 30 | def url = task.url(contextPath, appContextModel.with("visit", [id: "{{visit.id}}", uuid: "{{visit.uuid}}", active: "{{visit.active}}"]), returnUrl); // strip out any hard-coded id, uuid, or active with the appropriate template so that it can be dynamically populated based on current selected visit 31 | if (task.type != "script") { 32 | %> 33 | 34 | <% } else { // script 35 | %> 36 | 37 | <% } %> 38 | ${ ui.message(task.label) } 39 | 40 | [[ } ]] 41 | <% } %> 42 |
43 | [[ if (encounters.length > 0) { ]] 44 |

${ ui.message("coreapps.patientDashBoard.encounters")}

45 | [[ } ]] 46 |
    47 | [[ _.each(encounters, function(encounter) { ]] 48 | [[= encounterTemplates.displayEncounter(encounter, patient) ]] 49 | [[ }); ]] 50 |
51 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/patientheader/activeVisitStatus.gsp: -------------------------------------------------------------------------------- 1 | <% if (config.activeVisit) { %> 2 | <% def visit = config.activeVisit.visit %> 3 | 4 |
5 | ${ui.message("coreapps.patientHeader.activeVisit.at", config.activeVisitStartDatetime)} 6 |
7 | 8 | <% if (config.showVisitTypeOnPatientHeaderSection == false) { %> 9 | <% if (config.activeVisit.admitted) { %> 10 |
11 | ${ui.message("coreapps.patientHeader.activeVisit.inpatient", ui.encodeHtmlContent(ui.format(config.activeVisit.latestAdtEncounter.location)))} 12 |
13 | <% } else { %> 14 |
15 | ${ui.message("coreapps.patientHeader.activeVisit.outpatient")} 16 |
17 | <% } %> 18 | <% } else { %> 19 | 27 | 28 | <% if (config.activeVisit.admitted) { %> 29 |
30 | ${ui.message("coreapps.patientHeader.activeVisit.inpatient", ui.format(config.activeVisit.latestAdtEncounter.location))} 31 |
32 | <% } else { %> 33 |
34 | <% if(visit.visitType.name) { %> 35 | ${visit.visitType.name} 36 | <% } else { %> 37 | ${ui.message("coreapps.patientHeader.activeVisit.outpatient")} 38 | <% } %> 39 |
40 | <% } %> 41 | <% } %> 42 | 43 | <% } %> 44 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/program/programHistory.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.includeJavascript("coreapps", "web/coreapps.vendor.js") 3 | ui.includeJavascript("coreapps", "web/coreapps.dashboardwidgets.js") 4 | ui.includeJavascript("uicommons", "handlebars/handlebars.js") 5 | %> 6 | 7 | <% config.programJson.eachWithIndex { json, idx -> %> 8 | 9 |
10 |
11 | 12 |

${ ui.message(config.label) }

13 |
14 |
15 | 16 |
17 |
18 | 19 | 22 | <% } %> 23 | 24 | -------------------------------------------------------------------------------- /omod/src/main/webapp/fragments/stickyNote.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.includeJavascript("uicommons", "angular.min.js") 3 | ui.includeJavascript("uicommons", "angular-resource.min.js") 4 | ui.includeJavascript("uicommons", "angular-common.js") 5 | ui.includeJavascript("uicommons", "angular-app.js") 6 | 7 | ui.includeJavascript("uicommons", "services/obsService.js") 8 | ui.includeJavascript("uicommons", "services/encounterService.js") 9 | 10 | ui.includeJavascript("uicommons", "ngDialog/ngDialog.js") 11 | ui.includeCss("uicommons", "ngDialog/ngDialog.min.css") 12 | 13 | ui.includeJavascript("uicommons", "moment.min.js") 14 | 15 | %> 16 | 17 | <% 18 | ui.includeJavascript("coreapps", "stickyNote/resources/xeditable.min.js") 19 | 20 | ui.includeJavascript("coreapps", "stickyNote/app.js") 21 | ui.includeJavascript("coreapps", "stickyNote/controllers/stickyNoteCtrl.js") 22 | 23 | ui.includeCss("coreapps", "stickynote/stickyNoteIcon.css") 24 | ui.includeJavascript("coreapps", "stickyNote/directives/clickToEditObs.js") 25 | %> 26 | 46 | 47 | 63 | 64 |
65 |
66 | 67 |
68 |
69 | -------------------------------------------------------------------------------- /omod/src/main/webapp/owas/conceptdictionary.owa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmrs/openmrs-module-coreapps/39db8f5b7e5f9c851038595068941e52363ca6df/omod/src/main/webapp/owas/conceptdictionary.owa -------------------------------------------------------------------------------- /omod/src/main/webapp/pages/applist/appList.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.decorateWith("appui", "standardEmrPage") 3 | 4 | def htmlSafeId = { extension -> 5 | "${ extension.id.replace(".", "-") }-app" 6 | } 7 | %> 8 | 9 | 15 | 16 |
17 | <% extensions.each { extension -> %> 18 | 19 | 20 | <% if (extension.icon) { %> 21 | 22 | <% } %> 23 | ${ ui.message(extension.label) } 24 | 25 | 26 | <% } %> 27 |
28 | -------------------------------------------------------------------------------- /omod/src/main/webapp/pages/datamanagement/dataManagement.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.decorateWith("appui", "standardEmrPage", [ title: ui.message("coreapps.app.dataManagement.label"), includeBootstrap: false ]) 3 | ui.includeCss("coreapps", "datamanagement/dataManagement.css") 4 | 5 | def htmlSafeId = { extension -> 6 | "${ extension.id.replace(".", "-") }-app" 7 | } 8 | %> 9 | 10 | 16 | 17 |
18 | <% extensions.each { extension -> %> 19 | 27 | 28 | <% } %> 29 |
30 | -------------------------------------------------------------------------------- /omod/src/main/webapp/pages/findpatient/findPatient.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.decorateWith("appui", "standardEmrPage") 3 | %> 4 | 19 | 20 |

21 | ${ ui.message(heading) } 22 |

23 | <% if (breadcrumbs) { %> 24 | ${ ui.includeFragment("coreapps", "patientsearch/patientSearchWidget", 25 | [ afterSelectedUrl: afterSelectedUrl, 26 | showLastViewedPatients: showLastViewedPatients, 27 | breadcrumbOverride: breadcrumbs, 28 | registrationAppLink: registrationAppLink, 29 | columnConfig: columnConfig])} 30 | <% } else { %> 31 | ${ ui.includeFragment("coreapps", "patientsearch/patientSearchWidget", 32 | [ afterSelectedUrl: afterSelectedUrl, 33 | showLastViewedPatients: showLastViewedPatients, 34 | registrationAppLink: registrationAppLink, 35 | columnConfig: columnConfig])} 36 | <% } %> 37 | -------------------------------------------------------------------------------- /omod/src/main/webapp/pages/noAccess.gsp: -------------------------------------------------------------------------------- 1 | ${ ui.message("coreapps.noAccess") } -------------------------------------------------------------------------------- /omod/src/main/webapp/pages/patientdashboard/deletedPatient.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.decorateWith("appui", "standardEmrPage") 3 | %> 4 | 5 | 11 | 12 |

${ ui.message("coreapps.deletedPatient.title") }

13 | 14 |

${ ui.message("coreapps.deletedPatient.description") }

-------------------------------------------------------------------------------- /omod/src/main/webapp/pages/patientdashboard/patientNotFound.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.decorateWith("appui", "standardEmrPage") 3 | %> 4 | 5 | 11 | 12 |
13 |

${ ui.message("coreapps.patientNotFound.Description") }

14 |
15 | -------------------------------------------------------------------------------- /omod/src/main/webapp/pages/providermanagement/findPatient.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | 3 | ui.decorateWith("appui", "standardEmrPage") 4 | ui.includeCss("registrationapp", "findPatient.css") 5 | 6 | ui.includeCss("coreapps", "providermanagement/providermanagement.css") 7 | 8 | ui.includeJavascript("coreapps", "providermanagement/editProvider.js") 9 | 10 | def baseUrl = ui.pageLink("coreapps", "providermanagement/findPatient") 11 | def afterSelectedUrl = '/coreapps/providermanagement/editProvider?personId={{personId}}' 12 | 13 | %> 14 | ${ ui.includeFragment("uicommons", "validationMessages")} 15 | 16 | 35 | 36 | 37 | ${ ui.message("coreapps.provider.search") } 38 | 39 | 44 | 45 |
46 |
47 | ${ ui.includeFragment("coreapps", "patientsearch/patientSearchWidget", 48 | [ afterSelectedUrl: afterSelectedUrl, 49 | rowSelectionHandler: "selectPatientHandler", 50 | initialSearchFromParameter: "search", 51 | showLastViewedPatients: 'false' ])} 52 |
53 | 54 |
55 | -------------------------------------------------------------------------------- /omod/src/main/webapp/pages/systemadministration/systemAdministration.gsp: -------------------------------------------------------------------------------- 1 | <% 2 | ui.decorateWith("appui", "standardEmrPage", [ title: ui.message("coreapps.app.systemAdministration.label") ]) 3 | ui.includeCss("coreapps", "systemadministration/systemadministration.css") 4 | 5 | 6 | def htmlSafeId = { extension -> 7 | "${ extension.id.replace(".", "-") }-app" 8 | } 9 | %> 10 | 11 | 17 | 18 | ${ ui.includeFragment("coreapps", "administrativenotification/notifications") } 19 | 20 |
21 |
22 | <% if (context.hasPrivilege("App: coreapps.systemAdministration")) { %> 23 | <% extensions.each { extension -> %> 24 | 27 | <% if (extension.icon) { %> 28 | 29 | <% } %> 30 | ${ ui.message(extension.label) } 31 | 32 | <% } %> 33 | <% } %> 34 |
35 |
36 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/fonts/fontawesome-stickyNote.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmrs/openmrs-module-coreapps/39db8f5b7e5f9c851038595068941e52363ca6df/omod/src/main/webapp/resources/fonts/fontawesome-stickyNote.eot -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/fonts/fontawesome-stickyNote.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/fonts/fontawesome-stickyNote.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmrs/openmrs-module-coreapps/39db8f5b7e5f9c851038595068941e52363ca6df/omod/src/main/webapp/resources/fonts/fontawesome-stickyNote.ttf -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/fonts/fontawesome-stickyNote.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmrs/openmrs-module-coreapps/39db8f5b7e5f9c851038595068941e52363ca6df/omod/src/main/webapp/resources/fonts/fontawesome-stickyNote.woff -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmrs/openmrs-module-coreapps/39db8f5b7e5f9c851038595068941e52363ca6df/omod/src/main/webapp/resources/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmrs/openmrs-module-coreapps/39db8f5b7e5f9c851038595068941e52363ca6df/omod/src/main/webapp/resources/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmrs/openmrs-module-coreapps/39db8f5b7e5f9c851038595068941e52363ca6df/omod/src/main/webapp/resources/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmrs/openmrs-module-coreapps/39db8f5b7e5f9c851038595068941e52363ca6df/omod/src/main/webapp/resources/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/partials/deleteDialog.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ msgs[module.getProvider() + '.clickToEditObs.delete.title'] }}

4 |
5 |
6 | 7 |
    8 |
  • 9 | {{ msgs[module.getProvider() + '.clickToEditObs.delete.confirm'] }} 10 |
  • 11 |
12 | 14 | 15 |
16 |
-------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/conditionlist/common.functions.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app.commonFunctionsFactory', []).service('CommonFunctions', CommonFunctions); 5 | 6 | CommonFunctions.$inject = ['$filter']; 7 | 8 | function CommonFunctions($filter) { 9 | 10 | return { 11 | extractUrlArgs: extractUrlArgs 12 | }; 13 | 14 | function extractUrlArgs(urlArgs) { 15 | var urlParams = {}; 16 | var args = urlArgs.replace(/^\?/, ''); 17 | if (args.indexOf("&") > 0) { 18 | var params = args.split("&"); 19 | for (var i = 0; i < params.length; i++) { 20 | var paramArgs = params[i].split("=", 2); 21 | 22 | if (paramArgs && Array.isArray(paramArgs) && paramArgs.length === 2) { 23 | var key = paramArgs[0]; 24 | if (key in urlParams) { 25 | var val = urlParams[key]; 26 | if (Array.isArray(val)) { 27 | val.push(paramArgs[1]); 28 | } else { 29 | val = [val]; 30 | } 31 | urlParams[key] = val; 32 | } else { 33 | urlParams[key] = paramArgs[1]; 34 | } 35 | } else { 36 | urlParams[params[i]] = params[i]; 37 | } 38 | } 39 | } 40 | 41 | return urlParams; 42 | } 43 | } 44 | })(); 45 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/conditionlist/emr.messages.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | jQuery(function () { 3 | if (typeof emr !== "undefined") { 4 | emr.loadMessages([ 5 | "coreapps.conditionui.getCondition.failure", 6 | "coreapps.conditionui.updateCondition.success", 7 | "coreapps.conditionui.updateCondition.added", 8 | "coreapps.conditionui.updateCondition.edited", 9 | "coreapps.conditionui.updateCondition.error", 10 | "coreapps.conditionui.updateCondition.onSetDate.error", 11 | "coreapps.conditionui.removeCondition.success", 12 | "coreapps.conditionui.removeCondition.message" 13 | ]); 14 | } 15 | }); 16 | })(); 17 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/conditionlist/lib/polyfills.js: -------------------------------------------------------------------------------- 1 | // implementations stolen from https://github.com/jonathantneal/array-flat-polyfill under CC0-1.0 License 2 | (function() { 3 | if (!Array.prototype.flat) { 4 | Object.defineProperty(Array.prototype, 'flat', { 5 | configurable: true, 6 | value: function flat () { 7 | var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]); 8 | 9 | return depth ? Array.prototype.reduce.call(this, function (acc, cur) { 10 | if (Array.isArray(cur)) { 11 | acc.push.apply(acc, flat.call(cur, depth - 1)); 12 | } else { 13 | acc.push(cur); 14 | } 15 | 16 | return acc; 17 | }, []) : Array.prototype.slice.call(this); 18 | }, 19 | writable: true 20 | }); 21 | } 22 | 23 | if (!Array.prototype.flatMap) { 24 | Object.defineProperty(Array.prototype, 'flatMap', { 25 | configurable: true, 26 | value: function flatMap (callback) { 27 | return Array.prototype.map.apply(this, arguments).flat(); 28 | }, 29 | writable: true 30 | }); 31 | } 32 | })(); 33 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/conditionlist/restful-services/restful-service.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | angular.module('app.restfulServices', []).service('RestfulService', RestfulService); 4 | 5 | RestfulService.$inject = ['$http']; 6 | 7 | function RestfulService($http) { 8 | var baseUrl; 9 | 10 | return { 11 | setBaseUrl: setBaseUrl, 12 | get: get, 13 | post: post, 14 | delete: remove 15 | }; 16 | 17 | function setBaseUrl(restWsUrl) { 18 | if (restWsUrl) { 19 | baseUrl = restWsUrl; 20 | } 21 | } 22 | 23 | function get(resource, request, successCallback, errorCallback) { 24 | var url = baseUrl + '/' + resource; 25 | if (typeof request === 'object' && request !== null && Object.keys(request).length > 0) { 26 | url += '?' + Object.keys(request).map(function (key) { 27 | return encodeURI(key) + '=' + encodeURI(request[key]); 28 | }).join('&'); 29 | } 30 | 31 | return $http({ 32 | method: 'GET', 33 | headers: { Accept: 'application/json' }, 34 | url: url 35 | }).then(function (response) { 36 | if (typeof successCallback === 'function') { 37 | successCallback(response.data); 38 | } 39 | }, function (response) { 40 | if (typeof errorCallback === 'function') { 41 | errorCallback(response); 42 | } 43 | }); 44 | } 45 | 46 | function post(resource, request, successCallback, errorCallback) { 47 | return $http({ 48 | method: 'POST', 49 | headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, 50 | url: baseUrl + '/' + resource, 51 | data: request 52 | }).then(function (response) { 53 | if (typeof successCallback === 'function') { 54 | successCallback(response.data); 55 | } 56 | }, function (error) { 57 | if (typeof errorCallback === 'function') { 58 | errorCallback(error); 59 | } 60 | }); 61 | } 62 | 63 | function remove(resource, successCallback, errorCallback) { 64 | return $http({ 65 | method: 'DELETE', 66 | headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, 67 | url: baseUrl + '/' + resource 68 | }).then(function (response) { 69 | if (typeof successCallback === 'function') { 70 | successCallback(response); 71 | } 72 | }, function (error) { 73 | if (typeof errorCallback === 'function') { 74 | errorCallback(error); 75 | } 76 | }); 77 | } 78 | } 79 | })(); 80 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/custom/deletePatient.js: -------------------------------------------------------------------------------- 1 | var delPatient = delPatient || {}; 2 | 3 | delPatient.deletePatientCreationDialog = null; 4 | 5 | /** 6 | * Functions used to Delete a Patient 7 | */ 8 | 9 | delPatient.returnUrl = "/coreapps/findpatient/findPatient.page?app=coreapps.findPatient"; 10 | 11 | delPatient.createDeletePatientCreationDialog = function() { 12 | emr.loadMessages([ 13 | "coreapps.task.deletePatient.deletePatientSuccessful", 14 | "coreapps.task.deletePatient.deletePatientUnsuccessful" 15 | ]); 16 | delPatient.deletePatientCreationDialog = emr.setupConfirmationDialog({ 17 | selector: '#delete-patient-creation-dialog', 18 | actions: { 19 | confirm: function() { 20 | var deleteReason = jq('#delete-reason').val().trim(); //Retrieve text from text box 21 | if(deleteReason && deleteReason.length > 0) { //Should not be invalid or empty 22 | jq.ajax({ 23 | url: '/' + OPENMRS_CONTEXT_PATH + '/ws/rest/v1/patient/'+delPatient.patientUUID+'?reason='+deleteReason, 24 | type: 'DELETE', 25 | success: function() { 26 | emr.successMessage('coreapps.task.deletePatient.deletePatientSuccessful'); 27 | jq('#delete-patient-creation-dialog' + ' .icon-spin').css('display', 'inline-block').parent().addClass('disabled'); 28 | delPatient.deletePatientCreationDialog.close(); 29 | jq(setTimeout(delPatient.goToReturnUrl, 1275)); //Allow the success message to display before redirecting to another page 30 | }, 31 | error: function() { 32 | emr.errorMessage("coreapps.task.deletePatient.deletePatientUnsuccessful"); 33 | delPatient.deletePatientCreationDialog.close(); 34 | } 35 | }); 36 | } else { 37 | jq('#delete-reason-empty').css({'color' : 'red', display : 'inline'}).show(); //Show warning message if empty 38 | jq('#delete-reason').val(""); //Clear the text box 39 | } 40 | }, 41 | cancel: function() { 42 | //Clear fields, close dialog box 43 | jq('#delete-reason').val(""); 44 | jq('#delete-reason-empty').hide(); 45 | delPatient.deletePatientCreationDialog.close(); 46 | } 47 | } 48 | }); 49 | }; 50 | 51 | delPatient.showDeletePatientCreationDialog = function(patientUUID) { 52 | delPatient.patientUUID = patientUUID; 53 | if (delPatient.deletePatientCreationDialog == null) { 54 | delPatient.createDeletePatientCreationDialog(); 55 | } 56 | jq('#delete-reason-empty').hide(); 57 | delPatient.deletePatientCreationDialog.show(); 58 | }; 59 | 60 | delPatient.goToReturnUrl = function() { 61 | emr.navigateTo({ applicationUrl: emr.applyContextModel(delPatient.returnUrl)}); 62 | }; -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/custom/findPatientById.js: -------------------------------------------------------------------------------- 1 | 2 | var jq = jQuery; 3 | function getPatientById(id, hiddenId, fullNameField, callbackFunction, patientNotFoundMsg) { 4 | jQuery.ajax({ 5 | url: emr.fragmentActionLink("coreapps", "findPatient", "searchById", { primaryId: id }), 6 | dataType: 'json', 7 | type: 'POST' 8 | }) 9 | .success(function(data) { 10 | var id = data.patientId; 11 | jq("#" + hiddenId).val(id); 12 | 13 | if (id != 0 && data.primaryIdentifiers && data.primaryIdentifiers[0]) { 14 | var identifierId = data.primaryIdentifiers[0].identifier; 15 | jq("#" + fullNameField).text(data.preferredName.fullName); 16 | 17 | } 18 | }) 19 | .complete(function(data) { 20 | callbackFunction(); 21 | }) 22 | .error(function(data) { 23 | jq("#" + hiddenId).val(0); 24 | jq("#" + fullNameField).text(patientNotFoundMsg); 25 | }); 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/custom/markPatientDead.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Show the container, and enable all elements in it 3 | * @param containerId 4 | */ 5 | function showContainer(containerId) { 6 | jq(containerId).removeClass('hidden'); 7 | jq(containerId + ' :input').attr('disabled', false); 8 | jq(containerId + ' :input').prop('checked', false); 9 | } 10 | 11 | /** 12 | * Hide the container, and disables all elements in it 13 | * @param containerId 14 | */ 15 | function hideContainer(containerId) { 16 | jq(containerId).addClass('hidden'); 17 | jq(containerId + ' :input').attr('disabled', true); 18 | jq(containerId + ' :input').prop('checked', false); 19 | } 20 | 21 | function showAlert(alertId) { 22 | jq(alertId).removeClass('hidden'); 23 | } 24 | 25 | function hideAlert(alertId) { 26 | jq(alertId).addClass('hidden'); 27 | } 28 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/custom/utilsTimezone.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns date translated according to preferred locale when Date Format displays the month as an abbreviation (MMM). 3 | * Ex: Date: 02-Jan-2021 Format: DD-MMM-YYYY Locale: fr_FR --> Return: 02-janv.-2021 4 | * @param {object} date Input Date 5 | * @param {string} format Date Format 6 | * @param {string} locale The preferred locale 7 | */ 8 | function formatDatetime(date, format, locale) { 9 | const DEFAULT_FORMAT = 'DD.MMM.YYYY, HH:mm:ss'; 10 | if(locale == undefined) { 11 | locale= 'en' 12 | } 13 | try { 14 | moment.locale(locale); 15 | return moment(date).format(format); 16 | } catch (err) { 17 | return moment(date).format(DEFAULT_FORMAT); 18 | } 19 | } 20 | 21 | function formatDate(date, format, locale) { 22 | const DEFAULT_FORMAT = 'YYYY-MMM-DD'; 23 | if(locale == undefined) { 24 | locale= 'en' 25 | } 26 | try { 27 | moment.locale(locale); 28 | return moment(date).format(format); 29 | } catch (err) { 30 | return moment(date).format(DEFAULT_FORMAT); 31 | } 32 | } 33 | 34 | 35 | function formatTime(date, format) { 36 | const DEFAULT_FORMAT = 'HH:mm'; 37 | try { 38 | return moment(date).format(format); 39 | } catch (err) { 40 | return moment(date).format(DEFAULT_FORMAT); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/datamanagement/mergePatients.js: -------------------------------------------------------------------------------- 1 | var jq = jQuery; 2 | jq(function() { 3 | jq('input[type=text]').first().focus(); 4 | 5 | jq('#cancel-button').click(function() { 6 | window.history.back(); 7 | }); 8 | }); 9 | 10 | function checkConfirmButton() { 11 | //Check if IDs are known 12 | var patient1Id = jq("#patient1").val(); 13 | var patient2Id = jq("#patient2").val(); 14 | 15 | //Check if input fields are not blank 16 | var patient1Text = jq("#patient1-text").val().trim(); 17 | var patient2Text = jq("#patient2-text").val().trim(); 18 | 19 | if (patient1Id > 0 && patient2Id > 0 && (patient1Id != patient2Id) && patient1Text.length > 0 && patient2Text.length > 0) { 20 | enableButton(); 21 | jq("#confirm-button").focus(); 22 | } else { 23 | disableButton(); 24 | } 25 | } 26 | 27 | function enableButton() { 28 | jq("#confirm-button").removeAttr("disabled"); 29 | jq("#confirm-button").removeClass("disabled"); 30 | } 31 | 32 | function disableButton() { 33 | jq("#confirm-button").attr("disabled","disabled"); 34 | jq("#confirm-button").addClass('disabled'); 35 | } 36 | 37 | function completePatientIdField(pId) { 38 | var patient1Id = jq("#patient1-text"); 39 | var patient2Id = jq("#patient2-text"); 40 | 41 | if (patient1Id.val() == '') { 42 | patient1Id.val(pId); 43 | simulateEnterKey(patient1Id); 44 | 45 | } else if (patient2Id.val() == '') { 46 | patient2Id.val(pId); 47 | simulateEnterKey(patient2Id); 48 | } else if (typeof isUnknownPatient !== 'undefined' && isUnknownPatient) { 49 | patient2Id.val(pId); 50 | simulateEnterKey(patient2Id); 51 | } else { 52 | patient1Id.val(pId); 53 | simulateEnterKey(patient1Id); 54 | patient2Id.val(''); 55 | simulateEnterKey(patient2Id); 56 | } 57 | } 58 | 59 | function handlePatientRowSelection(action, callback) { 60 | this.action = action; 61 | this.callback = callback; 62 | 63 | this.handle = function (row) { 64 | action(row.patientIdentifier.identifier); 65 | } 66 | } 67 | 68 | function simulateEnterKey(elementInput) { 69 | var press = jQuery.Event("keypress"); 70 | press.keyCode = 13; 71 | press.which = 13; 72 | elementInput.trigger(press); 73 | } 74 | 75 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/fragments/datamanagement/codeDiagnosisDialog.js: -------------------------------------------------------------------------------- 1 | var codeDiagnosisDialog = null; 2 | 3 | function showCodeDiagnosisDialog (patientId, visitId, patientIdentifier, personName, obsId, nonCodedDiagnosis) { 4 | jq("#hiddenPatientId").val(patientId); 5 | jq("#hiddenNonCodedObsId").val(obsId); 6 | 7 | patientDashboardLink = patientDashboardLink + "?patientId=" + patientId + "&visitId=" + visitId; 8 | instructionsTemplate = instructionsTemplate.replace("{1}", "" + nonCodedDiagnosis + "" ); 9 | instructionsTemplate = instructionsTemplate.replace("{2}", 10 | "" + personName + " (" + patientIdentifier + " )" 12 | + "" ); 13 | jq("#instructions").html(instructionsTemplate + ": "); 14 | codeDiagnosisDialog.show(); 15 | return false; 16 | } 17 | 18 | function createCodeDiagnosisDialog() { 19 | viewModel =ConsultFormViewModel(); 20 | formatTemplate = _.template(jq('#autocomplete-render-template').html()); 21 | ko.applyBindings(viewModel, jq('#contentForm').get(0)); 22 | codeDiagnosisDialog = null; 23 | codeDiagnosisDialog = emr.setupConfirmationDialog({ 24 | selector: '#code-diagnosis-dialog', 25 | actions: { 26 | confirm: function() { 27 | var newDiagnoses = jq("input[name='diagnosis']"); 28 | var diagnosesArray = new Array(); 29 | var obsId = jq("#hiddenNonCodedObsId").val(); 30 | jq.each(newDiagnoses, function(i, item) { 31 | var newDiagnosis = jq.parseJSON(jq(item).val()); 32 | diagnosesArray.push(newDiagnosis); 33 | }); 34 | 35 | emr.getFragmentActionWithCallback('coreapps', 'diagnoses', 'codeDiagnosis' 36 | , { patientId: jq("#hiddenPatientId").val(), 37 | nonCodedObsId: obsId, 38 | diagnosis: JSON.stringify(diagnosesArray) } 39 | , function(data) { 40 | emr.successMessage(data.message); 41 | jq("#obs-id-" + obsId).remove(); 42 | codeDiagnosisDialog.close(); 43 | }); 44 | }, 45 | cancel: function() { 46 | codeDiagnosisDialog.close(); 47 | } 48 | } 49 | }); 50 | } 51 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/fragments/encounterTemplates.js: -------------------------------------------------------------------------------- 1 | //Uses the namespace pattern from http://stackoverflow.com/a/5947280 2 | (function( encounterTemplates, $, undefined) { 3 | 4 | var templates = {}; 5 | var defaultTemplate; 6 | var parameters = {}; 7 | 8 | encounterTemplates.setTemplate = function(encounterTypeUuid, templateId) { 9 | templates[encounterTypeUuid] = _.template(jq('#' + templateId).html()); 10 | }; 11 | 12 | encounterTemplates.setDefaultTemplate = function(templateId) { 13 | defaultTemplate = _.template(jq('#' + templateId).html()); 14 | }; 15 | 16 | encounterTemplates.setParameter = function(encounterTypeUuid, name, value) { 17 | if (!(encounterTypeUuid in parameters)) { 18 | parameters[encounterTypeUuid] = {}; 19 | } 20 | parameters[encounterTypeUuid][name] = value; 21 | }; 22 | 23 | encounterTemplates.displayEncounter = function(encounter, patient) { 24 | var template; 25 | if (templates[encounter.encounterType.uuid]) { 26 | template = templates[encounter.encounterType.uuid]; 27 | } else { 28 | template = defaultTemplate; 29 | } 30 | 31 | var data = { 32 | encounter: encounter, 33 | patient: patient 34 | }; 35 | data.config = _.extend({ 36 | icon: "icon-time" 37 | }, parameters[encounter.encounterType.uuid]); 38 | 39 | return template(data); 40 | }; 41 | 42 | }( window.encounterTemplates = window.encounterTemplates || {}, jQuery )); -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/htmlformentry/codedOrFreeTextAnswer.js: -------------------------------------------------------------------------------- 1 | angular.module('codedOrFreeTextAnswer', [ 'uicommons.widget.coded-or-free-text-answer' ]). 2 | 3 | controller('AnswerCtrl', ['$scope', '$http', '$timeout', '$element', 4 | function($scope, $http, $timeout, $element) { 5 | 6 | $scope.answer = null; 7 | 8 | $scope.init = function(varName) { 9 | var initialValue = window[varName]; 10 | if (initialValue) { 11 | $scope.answer = initialValue; 12 | } 13 | } 14 | 15 | $scope.toSubmit = function() { 16 | if (!$scope.answer) { 17 | return ""; 18 | } else if ($scope.answer.conceptName) { 19 | return "ConceptName:" + $scope.answer.conceptName.uuid; 20 | } else if ($scope.answer.concept) { 21 | return "Concept:" + $scope.answer.concept.uuid; 22 | } else if ($scope.answer.word) { 23 | return "NonCoded:" + $scope.answer.word; 24 | } else { 25 | return ""; 26 | } 27 | } 28 | }]); -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/stickyNote/app.js: -------------------------------------------------------------------------------- 1 | // Declare the Angular modules and dependencies 2 | angular.module('coreapps.fragment.stickyNote', ['obsService', 'encounterService', 'xeditable', 'ngDialog']); -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/stickyNote/controllers/stickyNoteCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('coreapps.fragment.stickyNote').controller('stickyNoteCtrl', ['$scope', '$window', '$log', 2 | function($scope, $window, $log) { 3 | 4 | if ($window.coreapps.stickyNote.config.concept == null) { 5 | $log.error("The concept passed in the config is 'null'. Check the server logs for more details") 6 | } 7 | 8 | $scope.config = { 9 | patient: $window.coreapps.stickyNote.config.patient.uuid, 10 | concept: $window.coreapps.stickyNote.config.concept.uuid, 11 | locale: $window.coreapps.stickyNote.config.locale, 12 | defaultLocale: $window.coreapps.stickyNote.config.defaultLocale 13 | }; 14 | 15 | $scope.module = { 16 | 'getProvider': function() { 17 | return "coreapps"; 18 | }, 19 | 'getPath': function(openmrsContextPath) { 20 | return openmrsContextPath + '/' + this.getProvider(); 21 | }, 22 | 'getPartialsPath': function(openmrsContextPath) { 23 | return openmrsContextPath + '/ms/uiframework/resource/' + this.getProvider() + '/partials'; 24 | } 25 | } 26 | 27 | }]) 28 | ; -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/visit/encounterToggle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Provide functionality to show or hide ALL encounter details. 3 | */ 4 | function toggle(){ 5 | jq('.encounterview').removeClass('open'); 6 | jq(".view-details").click(); 7 | if(jq('#i-toggle').hasClass('icon-arrow-up')){ 8 | jq('#i-toggle').removeClass('icon-arrow-up'); 9 | jq('#i-toggle').addClass('icon-arrow-down'); 10 | jq('#i-toggle').attr('title', "${ui.message('coreapps.showAllEncounterDetails')}"); 11 | } else { 12 | jq('#i-toggle').removeClass('icon-arrow-down'); 13 | jq('#i-toggle').addClass('icon-arrow-up'); 14 | jq('#i-toggle').attr('title', "${ui.message('coreapps.hideAllEncounterDetails')}"); 15 | } 16 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/scripts/visit/filterTable.js: -------------------------------------------------------------------------------- 1 | window.filter = []; 2 | 3 | $(document).ready(function () { 4 | $(".filter").click(function () { 5 | var filterValue = $(this).attr("value"); 6 | 7 | if (!(window.filter.indexOf(filterValue) < 0)) { 8 | if ($(this).hasClass("enabled")) { 9 | $(this).removeClass("enabled"); 10 | $(this).addClass("disabled"); 11 | window.filter.splice(filter.indexOf(filterValue),1); 12 | $('#active-visits').DataTable().draw(); 13 | } 14 | } else { 15 | window.filter.push(filterValue); 16 | $('#active-visits').DataTable().draw(); 17 | $(this).addClass("enabled"); 18 | $(this).removeClass("disabled"); 19 | } 20 | }) 21 | }) 22 | 23 | /* Custom filtering function which will filter data in column four */ 24 | $(document).ready(function () { 25 | if($.fn.dataTable){ 26 | $.fn.dataTable.ext.search.push( 27 | function( settings, data, dataIndex ) { 28 | filter = window.filter; 29 | var type = parseFloat( data[4].replace(/\s/g, '') ).toString(); 30 | if ( !(filter.indexOf(type) < 0) || filter == "" ) 31 | { 32 | return true; 33 | } 34 | return false; 35 | } 36 | ); 37 | } 38 | }); 39 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/adt/awaitingAdmission.scss: -------------------------------------------------------------------------------- 1 | 2 | .inpatient-current-location-filter { 3 | display: inline-block; 4 | float: right; 5 | margin-top: 5px; 6 | margin-bottom: 5px; 7 | } 8 | 9 | .inpatient-admitTo-location-filter { 10 | display: inline-block; 11 | float: right; 12 | margin-top: 5px; 13 | margin-bottom: 5px; 14 | } 15 | 16 | #content h2 { 17 | display: inline-block; 18 | float: left; 19 | margin-bottom: 0; 20 | } 21 | 22 | i.admitIcon { 23 | text-decoration: none; 24 | } 25 | 26 | #active-visits_wrapper { 27 | min-height: 0; 28 | 29 | .dataTables_filter { 30 | float: right; 31 | width: 26%; 32 | } 33 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/adt/inpatient.scss: -------------------------------------------------------------------------------- 1 | .inpatient-count { 2 | display: inline-block; 3 | float: left; 4 | } 5 | 6 | .inpatient-filter { 7 | display: inline-block; 8 | float: right; 9 | margin-top: 10px; 10 | 11 | label { 12 | margin-right: 10px; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/clinicianfacing/patient.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | @import "compass/css3"; 3 | 4 | .float-left { 5 | float: left; 6 | clear: left; 7 | width: 97.91666%; 8 | } 9 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/conditionlist/conditions.scss: -------------------------------------------------------------------------------- 1 | .conditionStatus { 2 | font-weight: bold; 3 | } 4 | 5 | form { 6 | display: inline; 7 | } 8 | 9 | td { 10 | text-overflow: ellipsis; 11 | overflow: hidden; 12 | } 13 | label { 14 | padding-right: 10px; 15 | } 16 | 17 | .heading { 18 | margin-bottom: 10px; 19 | } 20 | 21 | #status label { 22 | display: inline; 23 | padding-right: 20px; 24 | } 25 | 26 | .inline { 27 | display: inline; 28 | } 29 | 30 | #condition > form { 31 | width: 100%; 32 | } 33 | 34 | .horizontal { 35 | display: table; 36 | } 37 | 38 | .horizontal > * { 39 | display: table-cell; 40 | } 41 | 42 | form > div { 43 | margin-bottom: 15px; 44 | 45 | } 46 | 47 | .conditions-table { 48 | border: none; 49 | width: 100%; 50 | } 51 | 52 | ul#concept-and-date { 53 | min-width: 200px; 54 | list-style: none; 55 | padding-top: 10px; 56 | padding-bottom: 10px; 57 | } 58 | 59 | ul#concept-and-date .group { 60 | display: inline; 61 | padding-right: 20px; 62 | } 63 | 64 | .actions { 65 | margin-top: 15px; 66 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/datamanagement/dataManagement.scss: -------------------------------------------------------------------------------- 1 | .app{ 2 | font-size: unset !important; 3 | white-space: normal !important; 4 | width: 166px !important; 5 | color: #363463 !important; 6 | -webkit-appearance: unset !important; 7 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/datamanagement/mergePatients.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | @import "reference"; 3 | 4 | $darkGray: #666666; 5 | $green: #51A351; 6 | 7 | 8 | #merge-patient-container { 9 | margin: 40px auto; 10 | border: 1px solid #EEE; 11 | padding: 5px 10px; 12 | 13 | form { 14 | 15 | p { 16 | text-align: left !important; 17 | margin-bottom: 10px; 18 | 19 | input { 20 | min-width: auto; 21 | display: inline-block; 22 | max-width: 120px; 23 | } 24 | 25 | span { 26 | display: inline-block; 27 | color: #888; 28 | } 29 | } 30 | } 31 | } 32 | 33 | .col { 34 | float:left; margin:0; width:45%; height:100%; 35 | } 36 | .col-separator { 37 | float:left; margin:0; width:10%; 38 | } 39 | 40 | .center { 41 | margin-left: auto; 42 | margin-right: auto; 43 | } 44 | 45 | .patient { 46 | cursor: pointer; 47 | background: #F9F9F9; 48 | border: 2px solid #CCC; 49 | width: 320px; 50 | float: left; 51 | @include border-radius(4px); 52 | 53 | .row { 54 | padding-top: 10px; 55 | padding-bottom: 10px; 56 | background: #EAEAEA; 57 | margin: 1px; 58 | 59 | div { 60 | span { display: block } 61 | } 62 | } 63 | 64 | h3 { 65 | font-size: 1.2em; 66 | margin: 0 67 | } 68 | 69 | &.selected { 70 | background: lighten($link, 20%); 71 | border-color: $link; 72 | 73 | .row { 74 | background: $link; 75 | 76 | h3 { 77 | color: #003F5E; 78 | } 79 | 80 | div { 81 | color: #FFF; 82 | } 83 | } 84 | } 85 | } 86 | 87 | .address { 88 | height:200px; 89 | } 90 | 91 | .identifiers { 92 | height: 90px; 93 | } 94 | 95 | h2 { 96 | em { 97 | display: block; 98 | } 99 | } 100 | 101 | .name { 102 | height: 90px; 103 | } 104 | 105 | .section-content { 106 | padding-left: 1em; 107 | padding-bottom: 0.7em; 108 | } 109 | 110 | .spacer { 111 | width: 20px; 112 | } 113 | 114 | .separator { 115 | display:block; 116 | float:left; 117 | margin: 30% 0; 118 | width:73px; 119 | } 120 | 121 | .person-address { 122 | display: inline-block; 123 | border-bottom: 1px $darkerGrey solid; 124 | } 125 | 126 | .buttons { 127 | display: inline-block; 128 | } 129 | 130 | .messages-container { 131 | padding-top: 15px; 132 | padding-bottom: 15px; 133 | width: 750px; 134 | display: inline-block; 135 | 136 | .message { 137 | display: inline-block; 138 | } 139 | 140 | .message-bold { 141 | display: inline-block; 142 | padding-bottom: 4px; 143 | font-weight: bold; 144 | } 145 | 146 | .message-title { 147 | font-size: 22px; 148 | display: inline-block; 149 | padding-bottom: 6px; 150 | font-weight: bold; 151 | } 152 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/diagnoses/encounterDiagnoses.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | @import "compass/css3"; 3 | 4 | #display-encounter-diagnoses-container { 5 | font-size: 0.9em; 6 | h3 { 7 | border-bottom: 1px solid #CCC; 8 | padding-bottom: 5px; 9 | } 10 | li { 11 | margin-bottom: 10px; 12 | .diagnosis { 13 | display: inline-block; 14 | background: #006191; 15 | border-left: 8px #006191 solid; 16 | padding: 5px 10px; 17 | width: 84%; 18 | color: white; 19 | @include border-radius(3px); 20 | 21 | &.primary { 22 | border-left: 8px $success solid; 23 | } 24 | 25 | .actions { 26 | float: right; 27 | font-size: 0.8em; 28 | margin-top: 5px; 29 | 30 | input { 31 | float: none; 32 | margin: 0px 0px 0px 10px; 33 | font-size: 0.8em; 34 | } 35 | label { 36 | vertical-align: top; 37 | display: inline; 38 | } 39 | } 40 | } 41 | i { 42 | display: inline; 43 | } 44 | } 45 | 46 | .matched-name { 47 | display: block; 48 | font-size: 1em; 49 | } 50 | 51 | .preferred-name { 52 | margin-top: 5px; 53 | display: block; 54 | font-family: $primaryLightFont; 55 | small { 56 | font-size: 1em; 57 | color: $darkerGrey; 58 | } 59 | } 60 | 61 | .code { 62 | float: right; 63 | font-family: $primaryLightFont; 64 | font-size: 0.9em; 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/encounterToggle.scss: -------------------------------------------------------------------------------- 1 | #i-toggle{ 2 | position: absolute; 3 | margin-left: 950px; 4 | top: 190px; 5 | display: none; 6 | color: #337ab7; 7 | cursor: pointer; 8 | font-size: 0.9em; 9 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/htmlformentry/codedOrFreeTextAnswerList.scss: -------------------------------------------------------------------------------- 1 | .selected-answer { 2 | 3 | background-color: white; 4 | border-radius: 5px; 5 | padding: 5px; 6 | margin: 5px 1px; 7 | 8 | .code { 9 | display: inline-block; 10 | min-width: 50px; 11 | } 12 | 13 | .name { 14 | display: inline-block; 15 | min-width: 500px; 16 | } 17 | 18 | .actions { 19 | float: right; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/markpatientdead/markPatientDead.scss: -------------------------------------------------------------------------------- 1 | #death-date-display { 2 | min-width: 35%; 3 | } 4 | 5 | span.field-error { 6 | padding: 1px 6px 1px 6px; 7 | margin-left: 4px; 8 | margin-right: 4px; 9 | vertical-align: middle; 10 | color: red; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/patientsearch/patientSearchWidget.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | 3 | $rowHighlightBackground: #F26522; 4 | $green: #51A351; 5 | 6 | #patient-search-form { 7 | position: relative; 8 | max-width: 750px; 9 | } 10 | 11 | #patient-search { 12 | display: inline; 13 | } 14 | 15 | #patient-search-clear-button { 16 | position: absolute; 17 | right: 0; 18 | padding: 14px; 19 | } 20 | 21 | #patient-search-results { 22 | margin-top: 1em; 23 | display: none; 24 | 25 | .patient-search-result { 26 | padding: 10px 5px; 27 | cursor: pointer; 28 | 29 | &:nth-child(odd) { 30 | background-color: $bodyBackground; 31 | } 32 | 33 | .patient-identifier { 34 | display: inline-block; 35 | .identifier-type { 36 | display: block; 37 | font-size: 0.6em; 38 | text-decoration: underline; 39 | } 40 | .identifier { 41 | display: block; 42 | } 43 | } 44 | 45 | .preferred-name { 46 | display: inline-block; 47 | font-size: 1.5em; 48 | padding: 5px; 49 | width: 50%; 50 | } 51 | 52 | .age, .gender { 53 | font-size: 1.2em; 54 | } 55 | 56 | a { 57 | float: right; 58 | } 59 | } 60 | 61 | #patient-search-results-table tbody tr:hover{ 62 | background-color: $rowHighlightBackground; 63 | cursor: pointer; 64 | } 65 | 66 | #patient-search-results-table tbody tr:hover { 67 | background: $link; 68 | cursor: pointer; 69 | color: white; 70 | } 71 | 72 | #patient-search-results-table tbody tr td.dataTables_empty:hover{ 73 | background: white; 74 | cursor: default; 75 | color: #363463; 76 | } 77 | 78 | #patient-search-results-table_wrapper { 79 | min-height: 0px; 80 | } 81 | } 82 | 83 | .search_table_row_highlight{ 84 | background-color: $rowHighlightBackground !important; 85 | } 86 | 87 | .search-widget-info{ 88 | font-size: 0.7em; 89 | font-style: italic; 90 | } 91 | 92 | .recent-lozenge { 93 | display: inline-block; 94 | vertical-align: text-bottom; 95 | font-size: 0.7em; 96 | border: 1px solid $green; 97 | color: $green; 98 | padding: 1px 2px; 99 | border-radius: 4px; 100 | margin-left: 5px; 101 | } 102 | 103 | img.search-spinner{ 104 | vertical-align: middle; 105 | } 106 | 107 | .patient-search-error{ 108 | color: $error; 109 | } 110 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/providermanagement/providermanagement.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | @import "reference"; 3 | 4 | $fontPath: "../fonts"; 5 | 6 | /* fix so that the 1000px max size works with bootstrap 7 | if the UI changes, we can remove this 8 | */ 9 | @media (min-width: 1200px) { 10 | .container { 11 | width: 970px; 12 | } 13 | } 14 | 15 | #add-patient-dialog { 16 | width: 650px; 17 | } 18 | 19 | #sticky { 20 | padding: 0.5ex; 21 | height: 50px; 22 | width: 940px; 23 | transition: box-shadow 400ms; 24 | } 25 | 26 | #sticky.stick { 27 | position: fixed; 28 | top: 0; 29 | z-index: 2; 30 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); 31 | } 32 | 33 | .borderless td, .borderless th { 34 | border: none; 35 | } 36 | 37 | #retire-button { 38 | background-color: #7786ff; 39 | background: #7786ff; 40 | border: #7786ff 1px solid; 41 | color: white; 42 | display: inline-block; 43 | max-width: 250px; 44 | min-width: 0; 45 | margin-right: 10px; 46 | } 47 | 48 | #register-provider-div { 49 | float: right; 50 | } 51 | 52 | #search-patient-div { 53 | width: 70%; 54 | } 55 | .disabled { 56 | opacity: 0.4 57 | } 58 | .hidden { 59 | visibility: hidden; 60 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/relationships/list.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | 3 | .relationship { 4 | position: relative; 5 | border: 1px solid $lighterGrey; 6 | padding: 3px; 7 | margin-left: 10px; 8 | 9 | i { 10 | cursor: pointer; 11 | } 12 | } 13 | 14 | .add-confirm-spacer { 15 | min-height: 110px; 16 | } 17 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/stickynote/stickyNoteIcon.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'fontawesome-stickyNote'; 3 | src: url('../../fonts/fontawesome-stickyNote.eot'); 4 | src: url('../../fonts/fontawesome-stickyNote.eot#iefix') format('embedded-opentype'), 5 | url('../../fonts/fontawesome-stickyNote.ttf') format('truetype'), 6 | url('../../fonts/fontawesome-stickyNote.woff') format('woff'), 7 | url('../../fonts/fontawesome-stickyNote.svg#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | .icon-sticky-note-o:before { 13 | font-family: 'fontawesome-stickyNote' !important; 14 | content: "\e900"; 15 | } 16 | .icon-sticky-note:before { 17 | font-family: 'fontawesome-stickyNote' !important; 18 | content: "\e901"; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/systemadministration/systemadministration.scss: -------------------------------------------------------------------------------- 1 | .homeList a { 2 | font-size: unset; 3 | white-space: normal; 4 | width: 166px !important; 5 | color: #363463; 6 | 7 | &:hover{ 8 | background: #e2e2e2; 9 | border-color: #d0d0d0; 10 | color: #363463; 11 | } 12 | } 13 | 14 | .app { 15 | -webkit-appearance: unset !important; 16 | } 17 | 18 | @media only screen and (min-width : 320px) and (max-width : 365px) { 19 | .homeList a { 20 | width: 117px !important; 21 | } 22 | } 23 | 24 | @media only screen and (max-width : 410px) and (min-width : 375px) { 25 | .homeList a { 26 | width: 140px !important; 27 | } 28 | } 29 | 30 | @media only screen and (max-width : 414px) and (min-width : 411px) { 31 | .homeList a { 32 | width: 158px !important; 33 | } 34 | } 35 | 36 | @media only screen and (min-width : 768px) and (max-width : 991px) { 37 | .homeList a { 38 | width: 156px !important; 39 | } 40 | } 41 | 42 | @media only screen and (max-width : 992px) { 43 | .schedulingList { 44 | margin-left: unset !important; 45 | } 46 | } -------------------------------------------------------------------------------- /omod/src/main/webapp/resources/styles/visit/visits.scss: -------------------------------------------------------------------------------- 1 | .disabled { 2 | opacity: 0.4 3 | } 4 | .enabled { 5 | opacity: 1 6 | } 7 | p.filters { 8 | float: right; 9 | } 10 | .filter { 11 | display:inline-block; 12 | } 13 | 14 | .edit-visit-table td{ 15 | max-width: 80px; 16 | } 17 | .dialog select{ 18 | min-width: 100px !important; 19 | } 20 | .date input{ 21 | width: 100px; 22 | } 23 | .add-on{ 24 | left: 137px !important; 25 | top: -25px; 26 | position: inherit; 27 | } 28 | -------------------------------------------------------------------------------- /omod/src/test/java/org/openmrs/module/coreapps/AppTest.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps; 2 | 3 | import org.junit.Test; 4 | import org.openmrs.module.appframework.AppTestUtil; 5 | import org.openmrs.module.appframework.domain.AppDescriptor; 6 | import org.openmrs.module.appframework.domain.AppTemplate; 7 | 8 | import static org.hamcrest.Matchers.hasSize; 9 | import static org.hamcrest.Matchers.is; 10 | import static org.junit.Assert.assertThat; 11 | 12 | /** 13 | * 14 | */ 15 | public class AppTest { 16 | 17 | @Test 18 | public void testFindPatientAppTemplateIsLoaded() throws Exception { 19 | AppTemplate template = AppTestUtil.getAppTemplate("coreapps.template.findPatient"); 20 | assertThat(template.getConfigOptions().get(0).getName(), is("afterSelectedUrl")); 21 | } 22 | 23 | @Test 24 | public void testFindPatientAppIsLoaded() throws Exception { 25 | AppDescriptor app = AppTestUtil.getAppDescriptor("coreapps.findPatient"); 26 | assertThat(app.getOrder(), is(2)); 27 | assertThat(app.getInstanceOf(), is("coreapps.template.findPatient")); 28 | assertThat(app.getTemplate().getId(), is("coreapps.template.findPatient")); 29 | String expectedUrl = app.getTemplate().getConfigOptions().get(0).getDefaultValue().getTextValue(); 30 | assertThat(app.getConfig().get("afterSelectedUrl").getTextValue(), is(expectedUrl)); 31 | String expectedLabel = app.getTemplate().getConfigOptions().get(1).getDefaultValue().getTextValue(); 32 | assertThat(app.getConfig().get("label").getTextValue(), is(expectedLabel)); 33 | String expectedHeading = app.getTemplate().getConfigOptions().get(2).getDefaultValue().getTextValue(); 34 | assertThat(app.getConfig().get("heading").getTextValue(), is(expectedHeading)); 35 | String expectedShowPatientLink = app.getTemplate().getConfigOptions().get(5).getDefaultValue().getTextValue(); 36 | assertThat(app.getConfig().get("registrationAppLink").getTextValue(), is(expectedShowPatientLink)); 37 | } 38 | 39 | @Test 40 | public void testFindPatientAppHasHomepageExtension() throws Exception { 41 | AppDescriptor app = AppTestUtil.getAppDescriptor("coreapps.findPatient"); 42 | assertThat(app.getExtensions(), hasSize(1)); 43 | assertThat(app.getExtensions().get(0).getExtensionPointId(), is("org.openmrs.referenceapplication.homepageLink")); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /omod/src/test/java/org/openmrs/module/coreapps/fragment/controller/patientdashboard/ContactInfoFragmentControllerTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The contents of this file are subject to the OpenMRS Public License 3 | * Version 1.0 (the "License"); you may not use this file except in 4 | * compliance with the License. You may obtain a copy of the License at 5 | * http://license.openmrs.org 6 | * 7 | * Software distributed under the License is distributed on an "AS IS" 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9 | * License for the specific language governing rights and limitations 10 | * under the License. 11 | * 12 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 13 | */ 14 | package org.openmrs.module.coreapps.fragment.controller.patientdashboard; 15 | 16 | import org.junit.Before; 17 | import org.junit.Test; 18 | import org.openmrs.Patient; 19 | import org.openmrs.module.appframework.context.AppContextModel; 20 | import org.openmrs.module.appframework.feature.FeatureToggleProperties; 21 | import org.openmrs.module.emrapi.patient.PatientDomainWrapper; 22 | import org.openmrs.ui.framework.fragment.FragmentConfiguration; 23 | 24 | import static org.hamcrest.Matchers.instanceOf; 25 | import static org.hamcrest.core.Is.is; 26 | import static org.junit.Assert.assertThat; 27 | import static org.mockito.Mockito.mock; 28 | 29 | public class ContactInfoFragmentControllerTest { 30 | 31 | ContactInfoFragmentController controller; 32 | 33 | FragmentConfiguration config; 34 | 35 | FeatureToggleProperties toggle; 36 | 37 | PatientDomainWrapper wrapper; 38 | 39 | AppContextModel contextModel; 40 | 41 | @Before 42 | public void before() { 43 | controller = new ContactInfoFragmentController(); 44 | config = new FragmentConfiguration(); 45 | toggle = mock(FeatureToggleProperties.class); 46 | wrapper = mock(PatientDomainWrapper.class); 47 | contextModel = mock(AppContextModel.class); 48 | } 49 | 50 | @Test 51 | public void shouldReturnPatient() { 52 | //given 53 | Patient patient = new Patient(); 54 | config.addAttribute("patient", patient); 55 | config.addAttribute("contextModel", contextModel); 56 | 57 | controller.controller(config, wrapper); 58 | assertThat(config.get("patient"), is(instanceOf(PatientDomainWrapper.class))); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /omod/src/test/java/org/openmrs/module/coreapps/page/controller/MergeVisitsPageControllerTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The contents of this file are subject to the OpenMRS Public License 3 | * Version 1.0 (the "License"); you may not use this file except in 4 | * compliance with the License. You may obtain a copy of the License at 5 | * http://license.openmrs.org 6 | *

7 | * Software distributed under the License is distributed on an "AS IS" 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9 | * License for the specific language governing rights and limitations 10 | * under the License. 11 | *

12 | * Copyright (C) OpenMRS, LLC. All Rights Reserved. 13 | */ 14 | package org.openmrs.module.coreapps.page.controller; 15 | 16 | 17 | import org.junit.Assert; 18 | import org.junit.Before; 19 | import org.junit.Test; 20 | 21 | import java.util.Arrays; 22 | import java.util.List; 23 | 24 | 25 | public class MergeVisitsPageControllerTest { 26 | 27 | MergeVisitsPageController controller; 28 | 29 | private final String RETURN_URL_WITH_VISIT_ID = "http://localhost:8080/openmrs/coreapps/patientdashboard/patientDashboard.page?patientId=9e121f61-457f-4eaa-9121-62fbb9acdaad&visitId=7"; 30 | private final String RETURN_URL_WITHOUT_VISIT_ID = "http://localhost:8080/openmrs/coreapps/patientdashboard/patientDashboard.page?patientId=9e121f61-457f-4eaa-9121-62fbb9acdaad"; 31 | 32 | @Before 33 | public void setup() { 34 | controller = new MergeVisitsPageController(); 35 | 36 | } 37 | 38 | @Test 39 | public void test_shouldRemoveVisitParameterFromReturnURL() { 40 | List merged_visits_ids = Arrays.asList("6,7,8,9"); 41 | Assert.assertEquals(controller.removeVisitIdFromURLIfVisitWasMerged(RETURN_URL_WITH_VISIT_ID, merged_visits_ids), RETURN_URL_WITHOUT_VISIT_ID); 42 | } 43 | 44 | @Test 45 | public void test_shouldNotRemoveVisitParameterFromReturnURL() { 46 | List merged_visits_ids = Arrays.asList("3,4,5,6"); 47 | Assert.assertEquals(controller.removeVisitIdFromURLIfVisitWasMerged(RETURN_URL_WITH_VISIT_ID, merged_visits_ids), RETURN_URL_WITH_VISIT_ID); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /omod/src/test/java/org/openmrs/module/coreapps/web/controller/LatestObsRestControllerTest.java: -------------------------------------------------------------------------------- 1 | package org.openmrs.module.coreapps.web.controller; 2 | 3 | import org.junit.Test; 4 | import org.openmrs.module.webservices.rest.web.RestTestConstants1_8; 5 | import org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest; 6 | import org.springframework.mock.web.MockHttpServletRequest; 7 | import org.springframework.mock.web.MockHttpServletResponse; 8 | 9 | import java.util.List; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | 13 | public class LatestObsRestControllerTest extends MainResourceControllerTest { 14 | 15 | @Override 16 | public String getURI() { 17 | return "latestobs"; 18 | } 19 | 20 | @Override 21 | public String getUuid() { 22 | return RestTestConstants1_8.OBS_UUID; 23 | } 24 | 25 | @Override 26 | public long getAllCount() { 27 | return 0; 28 | } 29 | 30 | @Test 31 | public void testSearchForSingleConcept() throws Exception { 32 | MockHttpServletRequest request = newGetRequest(getURI()); 33 | request.addParameter("patient", "5946f880-b197-400b-9caa-a3c661d23041"); 34 | request.addParameter("concept", "11716f9c-1434-4f8d-b9fc-9aa14c4d6126"); 35 | MockHttpServletResponse response = handle(request); 36 | List allNonVoidedObsList = deserialize(response).get("results"); 37 | 38 | assertEquals(1, allNonVoidedObsList.size()); 39 | } 40 | 41 | @Test 42 | public void testSearchForMultipleConcept() throws Exception { 43 | MockHttpServletRequest request = newGetRequest(getURI()); 44 | request.addParameter("patient", "5946f880-b197-400b-9caa-a3c661d23041"); 45 | request.addParameter("concept", "11716f9c-1434-4f8d-b9fc-9aa14c4d6126, 95312123-e0c2-466d-b6b1-cb6e990d0d65"); 46 | MockHttpServletResponse response = handle(request); 47 | List allNonVoidedObsList = deserialize(response).get("results"); 48 | 49 | assertEquals(2, allNonVoidedObsList.size()); 50 | } 51 | 52 | @Test 53 | public void testSearchForMultipleLatestObsBasedOnNLatestObsParameter() throws Exception { 54 | MockHttpServletRequest request = newGetRequest(getURI()); 55 | request.addParameter("nLatestObs", "2"); 56 | request.addParameter("concept", "c607c80f-1ea9-4da3-bb88-6276ce8868dd"); 57 | MockHttpServletResponse response = handle(request); 58 | List nLatestNonVoidedObs = deserialize(response).get("results"); 59 | 60 | assertEquals(nLatestNonVoidedObs.size(), 2); 61 | } 62 | 63 | @Test 64 | public void testSearchForSingleLatestObsBasedOnMissingNLatestObsParameter() throws Exception { 65 | MockHttpServletRequest request = newGetRequest(getURI()); 66 | request.addParameter("concept", "c607c80f-1ea9-4da3-bb88-6276ce8868dd"); 67 | MockHttpServletResponse response = handle(request); 68 | List nLatestNonVoidedObs = deserialize(response).get("results"); 69 | 70 | assertEquals(nLatestNonVoidedObs.size(), 1); 71 | } 72 | } -------------------------------------------------------------------------------- /omod/src/test/resources/TestingApplicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 13 | 14 | classpath:hibernate.cfg.xml 15 | classpath:test-hibernate.cfg.xml 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | org.openmrs 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /omod/src/test/resources/codedOrFreeTextObsForm.xml: -------------------------------------------------------------------------------- 1 | 2 | Date: 3 | Location: 4 | Provider: 5 | Encounter Type: 6 | Test: 7 | 8 | 9 | -------------------------------------------------------------------------------- /omod/src/test/resources/coreappsTestDispositionConfig.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "uuid": "d2d89630-b698-11e2-9e96-0800200c9a66", 4 | "name": "disposition.admission", 5 | "conceptCode": "org.openmrs.module.emrapi: Admit to hospital", 6 | "actions": [], 7 | "additionalObs": [ 8 | { "label": "Admission Location", 9 | "conceptCode": "org.openmrs.module.emrapi: Admission Location", 10 | "params" : { 11 | "style": "location", 12 | "required": "true" 13 | } 14 | 15 | } 16 | ] 17 | }, 18 | { 19 | "uuid": "66de7f60-b73a-11e2-9e96-0800200c9a66", 20 | "name": "disposition.transfer", 21 | "conceptCode": "org.openmrs.module.emrapi: Transfer out of hospital", 22 | "actions": [] 23 | }, 24 | { 25 | "uuid": "77d23160-b73a-11e2-9e96-0800200c9a66", 26 | "name": "disposition.discharged", 27 | "conceptCode": "org.openmrs.module.emrapi: Discharged", 28 | "actions": [] 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /omod/src/test/resources/dispensedMedication_app.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "coreapps.dispensedMedication", 3 | "instanceOf": "coreapps.template.dashboardWidget", 4 | "description": "Show dispensed medications as drug orders", 5 | "order": 10, 6 | "config": { 7 | "displayActivationDate": true, 8 | "detailsUrl": "../../owa/orderentry/index.html?patient={{patientUuid}}", 9 | "returnUrl": "/openmrs/custom/returnUrl.page?patientId={{patientUuid}}" 10 | }, 11 | "extensions": [ 12 | { 13 | "id": "org.openmrs.module.coreapps.dispensedMedication.clinicianDashboardFirstColumn", 14 | "appId": "coreapps.dispensedMedication", 15 | "extensionPointId": "patientDashboard.secondColumnFragments", 16 | "extensionParams": { 17 | "provider": "coreapps", 18 | "fragment": "patientdashboard/activeDrugOrders" 19 | } 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /omod/src/test/resources/encounterDiagnosesSimpleForm.xml: -------------------------------------------------------------------------------- 1 | 2 | Date: 3 | Location: 4 | Provider: 5 | 6 | 7 | 8 | Encounter Type: 9 | 10 | 11 | -------------------------------------------------------------------------------- /omod/src/test/resources/encounterDispositionSimpleForm.xml: -------------------------------------------------------------------------------- 1 | 2 | Date: 3 | Location: 4 | Provider: 5 | 6 | Disposition: 7 | 8 | 9 | -------------------------------------------------------------------------------- /omod/src/test/resources/obsGroupAndEncounterForm.xml: -------------------------------------------------------------------------------- 1 | 2 | Date: 3 | Location: 4 | Provider: 5 | 6 | Dose: 7 | 8 | Diagnosis: 9 | 10 | -------------------------------------------------------------------------------- /omod/src/test/resources/test-hibernate.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /omod/src/test/webapp/resources/scripts/visit.js: -------------------------------------------------------------------------------- 1 | describe("Visit javascript functions", function() { 2 | 3 | // temporarily ignored (this has been broken for a long time, but nobody noticed since we didn't have jasmine enabled fort this module) 4 | // the problem is that emr.js which is called here is from the uicommons module, and I don't know how to reference that from here. 5 | // it("should create the creation form dialog object", function() { 6 | // spyOn(emr, 'setupConfirmationDialog'); 7 | // quickVisitCreationDialogMock = jasmine.createSpyObj('dialog', ['close']); 8 | // emr.setupConfirmationDialog.andReturn(quickVisitCreationDialogMock); 9 | // 10 | // visit.createQuickVisitCreationDialog(); 11 | // 12 | // expect(emr.setupConfirmationDialog).toHaveBeenCalled(); 13 | // expect(quickVisitCreationDialogMock.close).toHaveBeenCalled(); 14 | // }); 15 | 16 | it("should display the quick visit creation form dialog", function() { 17 | visit.quickVisitCreationDialog = jasmine.createSpyObj('dialog', ['show']); 18 | visit.showQuickVisitCreationDialog(); 19 | expect(visit.quickVisitCreationDialog.show).toHaveBeenCalled(); 20 | }); 21 | }) --------------------------------------------------------------------------------