diff --git a/ui/app/clinical/consultation/controllers/bacteriologyController.js b/ui/app/clinical/consultation/controllers/bacteriologyController.js index 5a4045d355..308f93f9b9 100644 --- a/ui/app/clinical/consultation/controllers/bacteriologyController.js +++ b/ui/app/clinical/consultation/controllers/bacteriologyController.js @@ -55,7 +55,7 @@ angular.module('bahmni.clinical') }; $scope.$on('$stateChangeStart', function () { - if ($scope.bacteriologyForm.$dirty) { + if ($scope.bacteriologyForm && $scope.bacteriologyForm.$dirty) { $state.dirtyConsultationForm = true; } }); diff --git a/ui/app/clinical/consultation/controllers/consultationController.js b/ui/app/clinical/consultation/controllers/consultationController.js index 126b9589c2..3ccc736adf 100644 --- a/ui/app/clinical/consultation/controllers/consultationController.js +++ b/ui/app/clinical/consultation/controllers/consultationController.js @@ -7,10 +7,10 @@ angular.module('bahmni.clinical').controller('ConsultationController', 'ngDialog', '$filter', 'configurations', 'visitConfig', 'conditionsService', 'configurationService', 'auditLogService', 'confirmBox', 'virtualConsultService', 'adhocTeleconsultationService', function ($scope, $rootScope, $state, $location, $translate, clinicalAppConfigService, diagnosisService, urlHelper, contextChangeHandler, - spinner, encounterService, messagingService, sessionService, retrospectiveEntryService, patientContext, $q, - patientVisitHistoryService, $stateParams, $window, visitHistory, clinicalDashboardConfig, appService, - ngDialog, $filter, configurations, visitConfig, conditionsService, configurationService, auditLogService, confirmBox, - virtualConsultService, adhocTeleconsultationService) { + spinner, encounterService, messagingService, sessionService, retrospectiveEntryService, patientContext, $q, + patientVisitHistoryService, $stateParams, $window, visitHistory, clinicalDashboardConfig, appService, + ngDialog, $filter, configurations, visitConfig, conditionsService, configurationService, auditLogService, confirmBox, + virtualConsultService, adhocTeleconsultationService) { var ERROR = 1; var DateUtil = Bahmni.Common.Util.DateUtil; var getPreviousActiveCondition = Bahmni.Common.Domain.Conditions.getPreviousActiveCondition; @@ -23,7 +23,6 @@ angular.module('bahmni.clinical').controller('ConsultationController', }; $scope.showComment = true; $scope.showSaveAndContinueButton = true; - $scope.visitHistory = visitHistory; $scope.consultationBoardLink = clinicalAppConfigService.getConsultationBoardLink(); $scope.showControlPanel = false; @@ -181,7 +180,7 @@ angular.module('bahmni.clinical').controller('ConsultationController', var initialize = function () { var appExtensions = clinicalAppConfigService.getAllConsultationBoards(); - $scope.adtNavigationConfig = {forwardUrl: Bahmni.Clinical.Constants.adtForwardUrl, title: $translate.instant("CLINICAL_GO_TO_DASHBOARD_LABEL"), privilege: Bahmni.Clinical.Constants.adtPrivilege }; + $scope.adtNavigationConfig = { forwardUrl: Bahmni.Clinical.Constants.adtForwardUrl, title: $translate.instant("CLINICAL_GO_TO_DASHBOARD_LABEL"), privilege: Bahmni.Clinical.Constants.adtPrivilege }; $scope.availableBoards = $scope.availableBoards.concat(appExtensions); $scope.showSaveConfirmDialogConfig = appService.getAppDescriptor().getConfigValue('showSaveConfirmDialog'); var adtNavigationConfig = appService.getAppDescriptor().getConfigValue('adtNavigationConfig'); @@ -203,7 +202,7 @@ angular.module('bahmni.clinical').controller('ConsultationController', event.preventDefault(); spinner.hide(toState.spinnerToken); ngDialog.close(); - $scope.toStateConfig = {toState: toState, toParams: toParams}; + $scope.toStateConfig = { toState: toState, toParams: toParams }; $scope.displayConfirmationDialog(); } } @@ -212,7 +211,7 @@ angular.module('bahmni.clinical').controller('ConsultationController', }); $scope.adtNavigationURL = function (visitUuid) { - return appService.getAppDescriptor().formatUrl($scope.adtNavigationConfig.forwardUrl, {'patientUuid': $scope.patient.uuid, 'visitUuid': visitUuid}); + return appService.getAppDescriptor().formatUrl($scope.adtNavigationConfig.forwardUrl, { 'patientUuid': $scope.patient.uuid, 'visitUuid': visitUuid }); }; var cleanUpListenerErrorsOnForm = $scope.$on("event:errorsOnForm", function () { @@ -225,7 +224,7 @@ angular.module('bahmni.clinical').controller('ConsultationController', event.preventDefault(); $scope.targetUrl = event.currentTarget.getAttribute('href'); } - ngDialog.openConfirm({template: '../common/ui-helper/views/saveConfirmation.html', scope: $scope}); + ngDialog.openConfirm({ template: '../common/ui-helper/views/saveConfirmation.html', scope: $scope }); } if ($scope.showTeleConsultationWindow) { var childScope = {}; @@ -235,7 +234,7 @@ angular.module('bahmni.clinical').controller('ConsultationController', event.preventDefault(); confirmBox({ scope: childScope, - actions: [{name: 'ok', display: 'Ok'}], + actions: [{ name: 'ok', display: 'Ok' }], className: "ngdialog-theme-default delete-program-popup" }); } @@ -351,6 +350,11 @@ angular.module('bahmni.clinical').controller('ConsultationController', if ($scope.currentBoard === board) { return; } + $scope.isObservationPage = board.id == "bahmni.clinical.consultation.observations" ? true : false; + $scope.isSave = false; + if ($scope.currentBoard) { + $scope.isSwitchedFromObservationToOtherPage = $scope.currentBoard.id == "bahmni.clinical.consultation.observations" ? true : false; + } if (!isFormValid()) { $scope.$parent.$broadcast("event:errorsOnForm"); return; @@ -473,19 +477,48 @@ angular.module('bahmni.clinical').controller('ConsultationController', _.each($scope.consultation.observationForms, function (observationForm) { if (valid && observationForm.component) { var value = observationForm.component.getValue(); + if (value.errors) { - messagingService.showMessage('error', "{{'CLINICAL_FORM_ERRORS_MESSAGE_KEY' | translate }}"); - valid = false; + if ($state.current !== undefined && $state.current.name === "patient.dashboard.show.observations") { + messagingService.showMessage('error', "{{'CLINICAL_FORM_ERRORS_MESSAGE_KEY' | translate }}"); + valid = false; + } + else { + messagingService.showMessage('error', "{{'CLINICAL_FORM_ERRORS_ON_OBSERVATION_TAB_MESSAGE_KEY' | translate }}"); + valid = false; + } } } }); return valid; }; + var checkForObservationPageError = function (shouldAllow, contxChange) { + if (!$scope.isSave) { + if ($scope.isSwitchedFromObservationToOtherPage && !shouldAllow) { + $scope.isErrorPresentInObsTab = true; + shouldAllow = $scope.isErrorPresentInObsTab; + } else if ($scope.isSwitchedFromObservationToOtherPage && shouldAllow) { + $scope.isErrorPresentInObsTab = false; + } + } else if ($scope.isSave) { + if ($scope.isErrorPresentInObsTab) { + if (!$scope.isObservationPage) { + var errorMessage = contxChange["errorMessage"] ? contxChange["errorMessage"] : "{{'CLINICAL_FORM_ERRORS_MESSAGE_KEY' | translate }}"; + messagingService.showMessage('error', errorMessage); + } else if ($scope.isObservationPage) { + $scope.isErrorPresentInObsTab = false; + } + } + } + return shouldAllow; + }; + var isFormValid = function () { var contxChange = contextChange(); var shouldAllow = contxChange["allow"]; var discontinuedDrugOrderValidationMessage = discontinuedDrugOrderValidation($scope.consultation.discontinuedDrugs); + shouldAllow = checkForObservationPageError(shouldAllow, contxChange); if (!shouldAllow) { var errorMessage = contxChange["errorMessage"] ? contxChange["errorMessage"] : "{{'CLINICAL_FORM_ERRORS_MESSAGE_KEY' | translate }}"; messagingService.showMessage('error', errorMessage); @@ -493,7 +526,7 @@ angular.module('bahmni.clinical').controller('ConsultationController', var errorMessage = discontinuedDrugOrderValidationMessage; messagingService.showMessage('error', errorMessage); } - return shouldAllow && !discontinuedDrugOrderValidationMessage && isObservationFormValid(); + return shouldAllow && !discontinuedDrugOrderValidationMessage; }; var copyConsultationToScope = function (consultationWithDiagnosis) { @@ -510,7 +543,8 @@ angular.module('bahmni.clinical').controller('ConsultationController', }); $scope.save = function (toStateConfig) { - if (!isFormValid()) { + $scope.isSave = true; + if (!isFormValid() || !isObservationFormValid() || $scope.isErrorPresentInObsTab) { $scope.$parent.$parent.$broadcast("event:errorsOnForm"); return $q.when({}); } @@ -535,13 +569,12 @@ angular.module('bahmni.clinical').controller('ConsultationController', $rootScope.cdssAlerts = cdssAlerts; } preSaveEvents(); - return spinner.forPromise($q.all([preSavePromise(), - encounterService.getEncounterType($state.params.programUuid, sessionService.getLoginLocationUuid())]).then(function (results) { - var encounterData = results[0]; - encounterData.encounterTypeUuid = results[1].uuid; - var params = angular.copy($state.params); - params.cachebuster = Math.random(); - return encounterService.create(encounterData) + return spinner.forPromise($q.all([preSavePromise(), encounterService.getEncounterType($state.params.programUuid, sessionService.getLoginLocationUuid())]).then(function (results) { + var encounterData = results[0]; + encounterData.encounterTypeUuid = results[1].uuid; + var params = angular.copy($state.params); + params.cachebuster = Math.random(); + return encounterService.create(encounterData) .then(function (saveResponse) { $state.dirtyConsultationForm = false; $state.orderRemoved = false; @@ -583,7 +616,7 @@ angular.module('bahmni.clinical').controller('ConsultationController', var message = Bahmni.Clinical.Error.translate(error) || "{{'CLINICAL_SAVE_FAILURE_MESSAGE_KEY' | translate}}"; messagingService.showMessage('error', message); }); - })); + })); } catch (error) { var displayErrors = function (error) { if (angular.isArray(error)) { diff --git a/ui/app/common/concept-set/directives/conceptSet.js b/ui/app/common/concept-set/directives/conceptSet.js index d9e085b57f..70ea1a4533 100644 --- a/ui/app/common/concept-set/directives/conceptSet.js +++ b/ui/app/common/concept-set/directives/conceptSet.js @@ -1,8 +1,8 @@ 'use strict'; angular.module('bahmni.common.conceptSet') - .directive('conceptSet', ['contextChangeHandler', 'appService', 'observationsService', 'messagingService', 'conceptSetService', 'conceptSetUiConfigService', 'spinner', - function (contextChangeHandler, appService, observationsService, messagingService, conceptSetService, conceptSetUiConfigService, spinner) { + .directive('conceptSet', ['contextChangeHandler', 'appService', 'observationsService', 'messagingService', 'conceptSetService', 'conceptSetUiConfigService', 'spinner', '$state', + function (contextChangeHandler, appService, observationsService, messagingService, conceptSetService, conceptSetUiConfigService, spinner, $state) { var controller = function ($scope) { var conceptSetName = $scope.conceptSetName; var ObservationUtil = Bahmni.Common.Obs.ObservationUtil; @@ -412,6 +412,18 @@ angular.module('bahmni.common.conceptSet') deregisterAddMore(); cleanUpListenerShowPrevious(); }); + + $scope.$on('$stateChangeStart', function () { + if ($scope.obsForm && $scope.obsForm.$dirty) { + $state.dirtyConsultationForm = true; + } + }); + + $scope.$on("event:changes-saved", function () { + if ($scope.obsForm) { + $scope.obsForm.$dirty = false; + } + }); }; return { diff --git a/ui/app/common/concept-set/directives/formControls.js b/ui/app/common/concept-set/directives/formControls.js index 694d349669..1fc31c3da0 100644 --- a/ui/app/common/concept-set/directives/formControls.js +++ b/ui/app/common/concept-set/directives/formControls.js @@ -1,8 +1,7 @@ 'use strict'; - angular.module('bahmni.common.conceptSet') - .directive('formControls', ['formService', 'spinner', '$timeout', '$translate', - function (formService, spinner, $timeout, $translate) { + .directive('formControls', ['formService', 'spinner', '$timeout', '$translate', '$state', 'messagingService', + function (formService, spinner, $timeout, $translate, $state, messagingService) { var loadedFormDetails = {}; var loadedFormTranslations = {}; var unMountReactContainer = function (formUuid) { @@ -11,7 +10,6 @@ angular.module('bahmni.common.conceptSet') unMountForm(document.getElementById(formUuid)); }); }; - var controller = function ($scope) { var formUuid = $scope.form.formUuid; var formVersion = $scope.form.formVersion; @@ -20,7 +18,6 @@ angular.module('bahmni.common.conceptSet') var collapse = $scope.form.collapseInnerSections && $scope.form.collapseInnerSections.value; var validateForm = $scope.validateForm || false; var locale = $translate.use(); - if (!loadedFormDetails[formUuid]) { spinner.forPromise(formService.getFormDetail(formUuid, { v: "custom:(resources:(value))" }) .then(function (response) { @@ -56,7 +53,6 @@ angular.module('bahmni.common.conceptSet') unMountReactContainer($scope.form.formUuid); }, 0, false); } - $scope.$watch('form.collapseInnerSections', function () { var collapse = $scope.form.collapseInnerSections && $scope.form.collapseInnerSections.value; if (loadedFormDetails[formUuid]) { @@ -64,13 +60,11 @@ angular.module('bahmni.common.conceptSet') formUuid, collapse, $scope.patient, validateForm, locale, loadedFormTranslations[formUuid]); } }); - $scope.$on('$destroy', function () { if ($scope.$parent.consultation && $scope.$parent.consultation.observationForms) { if ($scope.form.component) { var formObservations = $scope.form.component.getValue(); $scope.form.observations = formObservations.observations; - var hasError = formObservations.errors; if (!_.isEmpty(hasError)) { $scope.form.isValid = false; @@ -78,8 +72,76 @@ angular.module('bahmni.common.conceptSet') } } }); + function checkGroupMembers (formObservation, consultationObservation) { + var isGroupMemberChanged = []; + if (formObservation.groupMembers && formObservation.groupMembers.length > 0 && consultationObservation.groupMembers && consultationObservation.groupMembers.length > 0) { + for (var formGroupIndex = 0; formGroupIndex < formObservation.groupMembers.length; formGroupIndex++) { + var formGroupMember = formObservation.groupMembers[formGroupIndex]; + for (var consultationGroupIndex = 0; consultationGroupIndex < consultationObservation.groupMembers.length; consultationGroupIndex++) { + var consultationGroupMember = consultationObservation.groupMembers[consultationGroupIndex]; + (formGroupMember.value && formGroupMember.value.uuid && consultationGroupMember.value && consultationGroupMember.value.uuid) ? + isGroupMemberChanged[formGroupIndex] = (consultationGroupMember.value.uuid === formGroupMember.value.uuid) ? false : true : + isGroupMemberChanged[formGroupIndex] = (consultationGroupMember.value === formGroupMember.value || (formGroupMember.value && consultationGroupMember.value === formGroupMember.value.toString())) ? false : true; + if (!isGroupMemberChanged[formGroupIndex]) { + break; + } + } + } + return isGroupMemberChanged.includes(true) ? true : false; + } else { + if (formObservation.value && formObservation.value.uuid && consultationObservation.value && consultationObservation.value.uuid) { + return (consultationObservation.value.uuid === formObservation.value.uuid) ? false : true; + } else { + return !((consultationObservation.value === formObservation.value || (formObservation.value && consultationObservation.value === formObservation.value.toString()))); + } + } + } + function checkFormChanges ($scope) { + var isChanged = []; + $scope.dirtyForm = false; + if ($scope.form.observations.length > 0) { + if ($scope.$parent.consultation.observations.length === 0) { + return true; + } + for (var formIndex = 0; formIndex < $scope.form.observations.length; formIndex++) { + var formObservation = $scope.form.observations[formIndex]; + for (var consultationIndex = 0; consultationIndex < $scope.$parent.consultation.observations.length; consultationIndex++) { + var consultationObservation = $scope.$parent.consultation.observations[consultationIndex]; + isChanged[formIndex] = checkGroupMembers(formObservation, consultationObservation); + if (!isChanged[formIndex]) { + break; + } + } + } + return isChanged.includes(true); + } + } + $scope.$on('$stateChangeStart', function (event, next, current) { + var uuid = $state.params.patientUuid; + var currentUuid = current.patientUuid; + if ($scope.form.component) { + var formObservations = $scope.form.component.getValue(); + $scope.form.observations = formObservations.observations; + } + if (!$scope.changesSaved) { + $scope.dirtyForm = checkFormChanges($scope); + } + $state.newPatientUuid = currentUuid; + next.url.includes("/patient/search") ? $state.isPatientSearch = true : $state.isPatientSearch = false; + var isNavigating = next.url.includes("/patient/search") || (uuid !== currentUuid); + $state.dirtyConsultationForm = $state.discardChanges ? false : $scope.dirtyForm; + if (isNavigating && $state.dirtyConsultationForm) { + messagingService.showMessage('alert', "{{'ALERT_MESSAGE_ON_EXIT' | translate }}"); + $state.reviewButtonFocused = true; + event.preventDefault(); + spinner.hide(next.spinnerToken); + } + }); + $scope.$on("event:changes-saved", function () { + $scope.changesSaved = true; + $scope.dirtyForm = false; + }); }; - return { restrict: 'E', scope: { diff --git a/ui/app/common/concept-set/views/conceptSet.html b/ui/app/common/concept-set/views/conceptSet.html index c45e9eb14c..be644d4b4c 100644 --- a/ui/app/common/concept-set/views/conceptSet.html +++ b/ui/app/common/concept-set/views/conceptSet.html @@ -1,4 +1,4 @@ -