← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 21653: Tuning of the TC Add event functionality

 

------------------------------------------------------------
revno: 21653
committer: Markus Bekken <markus.bekken@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2016-01-07 22:16:02 +0100
message:
  Tuning of the TC Add event functionality
modified:
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/event-layout.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app_ar.properties
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/styles/style.css


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js	2016-01-07 19:39:37 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js	2016-01-07 21:16:02 +0000
@@ -53,6 +53,7 @@
     $scope.hiddenSections = {};
     $scope.tableMaxNumberOfDataElements = 7;
     $scope.xVisitScheduleDataElement = false;
+    $scope.eventsLoaded = false;
 
     
     //Labels
@@ -352,7 +353,8 @@
                 
                 TrackerRulesFactory.getRules($scope.selectedProgram.id).then(function(rules){                    
                     $scope.allProgramRules = rules;
-                    $scope.getEvents();                       
+                    $scope.getEvents();
+                    $scope.getEventPageForEvent($scope.currentEvent);
                     $rootScope.$broadcast('dataEntryControllerData', {programStages: $scope.programStages, eventsByStage: $scope.eventsByStage, addNewEvent: $scope.addNewEvent });
                 });           
             });
@@ -421,6 +423,7 @@
             $scope.allEventsSorted = orderByFilter($scope.allEventsSorted, '-sortingDate').reverse();
             sortEventsByStage(null);
             $scope.showDataEntry($scope.currentEvent, true);
+            $scope.eventsLoaded = true;
         }
     };
     
@@ -495,7 +498,7 @@
             if (stage.displayEventsInTable) {
                 return true;
             }
-
+            
             if ($scope.eventsByStage[stage.id].length === 0) {
                 return true;
             }
@@ -513,6 +516,28 @@
         return false;
     };
     
+    $scope.creatableStagesExist = function(stageList) {
+        if(stageList && stageList.length > 0) {
+            return true;
+        }
+        
+        return false;
+    };
+    
+    $scope.neverShowStageTasksInTopLine = {};   
+    $scope.displayStageTasksInTopLine = function(stage) {
+        if($scope.neverShowStageTasksInTopLine[stage.id]){
+            return false;
+        }   
+        
+        return $scope.stageNeedsEvent(stage);
+    };
+    
+    $scope.showStageTasks = false;
+    $scope.toggleShowStageTasks = function(){
+        $scope.showStageTasks = !$scope.showStageTasks;
+    };
+    
     $scope.addNewEvent = function(newEvent) {
         //Have to make sure the event is preprocessed - this does not happen unless "Dashboardwidgets" is invoked.
         newEvent = EventUtils.processEvent(newEvent, $scope.stagesById[newEvent.programStage], $scope.optionSets, $scope.prStDes);
@@ -522,29 +547,31 @@
         sortEventsByStage('ADD', newEvent);
     };
 
-    $scope.showCreateEvent = function (stage, eventCreationAction) {
-                
-        var stages = [];
+    $scope.showCreateEvent = function (stage, eventCreationAction) {        
+        
+        var availableStages = [];
         if(!stage){
             if(!$scope.allEventsSorted || $scope.allEventsSorted.length === 0){                
-                stages = $scope.programStages;
-            }
-            for(var key in $scope.eventsByStage){
-                var st = $scope.stagesById[key];
-                var needEvent = true;
-                if(st && st.repeatable){
-                    for (var j = 0; j < $scope.eventsByStage[st.id].length; j++) {
-                        if (!$scope.eventsByStage[st.id][j].eventDate && $scope.eventsByStage[st.id][j].status !== 'SKIPPED') {
-                            needEvent = false;
-                        }
-                    }
-                    if(needEvent){
-                        stages.push(st);
-                    }
-                }
-            }
-        }
-        
+                availableStages = $scope.programStages;
+            }
+            else{
+                angular.forEach($scope.programStages, function(stage){
+                    if($scope.stageNeedsEvent(stage)){
+                        availableStages.push(stage);
+                    }
+                });
+            }           
+            if(availableStages.length === 0) {
+                var dialogOptions = {
+                    headerText: 'error',
+                    bodyText: 'no_stages_available'
+                };
+                    
+                DialogService.showDialog({}, dialogOptions);
+                
+                return;
+            }
+        }        
         
         var modalInstance = $modal.open({
             templateUrl: 'components/dataentry/new-event.html',
@@ -557,7 +584,10 @@
                     return stage;
                 },                
                 stages: function(){
-                    return stages;
+                    return availableStages;
+                },
+                allStages: function(){
+                    return $scope.programStages;
                 },
                 tei: function(){
                     return $scope.selectedEntity;
@@ -577,32 +607,45 @@
                 },
                 eventCreationAction: function(){
                     return eventCreationAction;
-                }                
+                },
+                events: function(){
+                    return $scope.allEventsSorted;
+                }
             }
         });
-
-        modalInstance.result.then(function (dummyEvent, ev) {
-            if (angular.isObject(ev) && angular.isObject(dummyEvent)) {
-                
-                var newEvent = ev;
-                newEvent.orgUnitName = dummyEvent.orgUnitName;
-                newEvent.name = dummyEvent.name;
-                newEvent.excecutionDateLabel = dummyEvent.excecutionDateLabel;
-                newEvent.sortingDate = ev.eventDate ? ev.eventDate : ev.dueDate,
-                newEvent.statusColor = EventUtils.getEventStatusColor(ev);
-                newEvent.eventDate = DateUtils.formatFromApiToUser(ev.eventDate);
-                newEvent.dueDate = DateUtils.formatFromApiToUser(ev.dueDate);
-                newEvent.enrollmentStatus = dummyEvent.enrollmentStatus;
-
-                if (dummyEvent.coordinate) {
-                    newEvent.coordinate = {};
+        
+        modalInstance.result.then(function (eventContainer) {
+            
+            if(angular.isDefined(eventContainer)){                
+                var ev = eventContainer.ev;
+                var dummyEvent = eventContainer.dummyEvent;      
+            
+                if (angular.isObject(ev) && angular.isObject(dummyEvent)) {
+
+                    var newEvent = ev;
+                    newEvent.orgUnitName = dummyEvent.orgUnitName;
+                    newEvent.name = dummyEvent.name;
+                    newEvent.excecutionDateLabel = dummyEvent.excecutionDateLabel;
+                    newEvent.sortingDate = ev.eventDate ? ev.eventDate : ev.dueDate,
+                    newEvent.statusColor = EventUtils.getEventStatusColor(ev);
+                    newEvent.eventDate = DateUtils.formatFromApiToUser(ev.eventDate);
+                    newEvent.dueDate = DateUtils.formatFromApiToUser(ev.dueDate);
+                    newEvent.enrollmentStatus = dummyEvent.enrollmentStatus;
+
+                    if (dummyEvent.coordinate) {
+                        newEvent.coordinate = {};
+                    }
+                    
+                    //get stage from created event
+                    $scope.currentStage = $scope.stagesById[dummyEvent.programStage];
+                    
+                    $scope.addNewEvent(newEvent);
+
+                    $scope.currentEvent = null;
+                    $scope.showDataEntry(newEvent, true);
+                    //show page with event in event-layout
+                    $scope.getEventPageForEvent(newEvent);
                 }
-                
-                $scope.currentStage = stage;
-                $scope.addNewEvent(newEvent);
-
-                $scope.currentEvent = null;
-                $scope.showDataEntry(newEvent, true);
             }
         }, function () {
         });
@@ -628,7 +671,7 @@
                     }
                 }                
                 if(index !== -1){
-                    $scope.currentEvent = $scope.eventsByStage[event.programStage][index];
+                    $scope.currentEvent = $scope.eventsByStage[event.programStage][index];                    
                 }
                 
                 $scope.showDataEntryDiv = true;
@@ -909,13 +952,17 @@
         var i = item;
     };
     
-    $scope.saveDataValueForEvent = function (prStDe, field, eventToSave, suppressRulesExecution) {
-        //Blank out the input-saved class on the last saved due date:
-        $scope.eventDateSaved = false;
-        $scope.currentElement = {id: prStDe.dataElement.id, pending: true, saved: false, failed: false, event: eventToSave.event};
-        
-        //check for input validity
-        $scope.updateSuccess = false;
+    $scope.saveDataValueForEvent = function (prStDe, field, eventToSave, backgroundUpdate) {
+        
+        //Do not change the input notification variables for background updates
+        if(!backgroundUpdate) {
+            //Blank out the input-saved class on the last saved due date:
+            $scope.eventDateSaved = false;
+
+            //check for input validity
+            $scope.updateSuccess = false;
+        }
+        
         if (field && field.$invalid) {
             return false;
         }
@@ -934,10 +981,12 @@
             
             value = CommonUtils.formatDataValue(value, prStDe.dataElement, $scope.optionSets, 'API');
             
-            $scope.updateSuccess = false;
-
-            $scope.currentElement = {id: prStDe.dataElement.id, event: eventToSave.event, saved: false};            
-
+            //Do not change the input notification variables for background updates
+            if(!backgroundUpdate) {
+                $scope.updateSuccess = false;
+                $scope.currentElement = {id: prStDe.dataElement.id, event: eventToSave.event, saved: false, failed:false, pending:true};            
+            }
+            
             var ev = {event: eventToSave.event,
                 orgUnit: eventToSave.orgUnit,
                 program: eventToSave.program,
@@ -954,9 +1003,11 @@
             };
             return DHIS2EventFactory.updateForSingleValue(ev).then(function (response) {
 
-                $scope.currentElement.saved = true;
-                $scope.currentElement.pending = false;
-                $scope.currentElement.failed = false;
+                if(!backgroundUpdate) {
+                    $scope.currentElement.saved = true;
+                    $scope.currentElement.pending = false;
+                    $scope.currentElement.failed = false;
+                }
 
                 $scope.currentEventOriginal = angular.copy($scope.currentEvent);
 
@@ -965,10 +1016,20 @@
                 //In some cases, the rules execution should be suppressed to avoid the 
                 //possibility of infinite loops(rules updating datavalues, that triggers a new 
                 //rule execution)
-                if(!suppressRulesExecution) {
+                if(!backgroundUpdate) {
                     //Run rules on updated data:
                     $scope.executeRules();
                 }
+            }, function(error) {
+                //Do not change the input notification variables for background updates
+                if(!backgroundUpdate) {
+                    $scope.currentElement.saved = false;
+                    $scope.currentElement.pending = false;
+                    $scope.currentElement.failed = true;      
+                } else {
+                    $log.warn("Could not perform background update of " + prStDe.dataElement.id + " with value " +
+                            value);
+                }
             });
 
         }
@@ -1002,8 +1063,8 @@
         }
     };
 
-    $scope.saveEventDate = function () {
-        $scope.saveEventDateForEvent($scope.currentEvent);
+    $scope.saveEventDate = function () {        
+        $scope.saveEventDateForEvent($scope.currentEvent);        
     };
 
     $scope.saveEventDateForEvent = function (eventToSave) {
@@ -1047,6 +1108,7 @@
             $scope.validatedDateSetForEvent = {date: eventToSave.eventDate, event: eventToSave};
             $scope.currentElement = {id: "eventDate", event: eventToSave.event, saved: true};
             $scope.executeRules();
+            $scope.getEventPageForEvent($scope.currentEvent);
         }, function(error){
             
         });
@@ -1099,8 +1161,9 @@
             $scope.currentEvent.statusColor = EventUtils.getEventStatusColor($scope.currentEvent);
             $scope.schedulingEnabled = !$scope.schedulingEnabled;
             sortEventsByStage('UPDATE');
-        });
-
+            $scope.getEventPageForEvent($scope.currentEvent);
+        });        
+        
     };
 
     $scope.saveCoordinate = function (type) {
@@ -1556,6 +1619,24 @@
                 }
                                
                 var programStageID = $scope.currentEvent.programStage;
+
+                $scope.eventsByStage[programStageID].splice(index, 1);
+                $scope.currentStageEvents = $scope.eventsByStage[programStageID];
+                
+                //if event is last event in allEventsSorted and only element on page, show previous page
+                var GetPreviousEventPage = false;
+                if($scope.allEventsSorted[$scope.allEventsSorted.length-1].event === $scope.currentEvent.event){
+                    var index = $scope.allEventsSorted.length - 1;
+                    if(index !== 0){
+                        if(index % $scope.eventPageSize === 0){                            
+                            GetPreviousEventPage = true;
+                        }
+                    }
+                }                
+                sortEventsByStage('REMOVE');                                          
+                if(GetPreviousEventPage){
+                    $scope.getEventPage("BACKWARD");
+                }                
                 
                 if($scope.displayCustomForm === "TABLE"){
                     $scope.currentEvent = {};                
@@ -1563,10 +1644,7 @@
                 else {
                     $scope.currentEvent = null;
                 }
-
-                $scope.eventsByStage[programStageID].splice(index, 1);
-                $scope.currentStageEvents = $scope.eventsByStage[programStageID];
-                sortEventsByStage('REMOVE');                                
+                
             }, function(error){               
                 return $q.reject(error);
             });        
@@ -1745,7 +1823,23 @@
         }
         
         $scope.showDataEntry($scope.allEventsSorted[$scope.eventPagingStart], false);
-    };    
+    };   
+    
+    $scope.getEventPageForEvent = function(event){
+        var index = -1;
+        for(i = 0; i < $scope.allEventsSorted.length; i++){
+            if(event.event === $scope.allEventsSorted[i].event){
+                index = i;
+                break;
+            }
+        }
+        
+        if(index !== -1){
+            var page = Math.floor(index / $scope.eventPageSize);
+            $scope.eventPagingStart = page * $scope.eventPageSize;
+            $scope.eventPagingEnd = $scope.eventPagingStart + $scope.eventPageSize;
+        }
+    }
 
     $scope.deselectCurrent = function(id){        
         

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html	2015-12-30 02:55:18 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry.html	2016-01-07 21:16:02 +0000
@@ -3,9 +3,9 @@
     </div>
     <div class="panel-heading handle bold">
         {{dataentryWidget.title| translate}}
-        <span class="nav-pills" ng-if="stageNeedsEvent(currentStage)">
+        <!--<span class="nav-pills" ng-if="stageNeedsEvent(currentStage)">
             | <a href ng-click="showCreateEvent(currentStage, eventCreationActions.add)" title="{{'add_new_event'| translate}}"><span ng-class="{true: 'widget - link - active', false: 'widget - link'} [!editingDisabled]">{{'add_new_event'| translate}}</span></a>
-        </span>
+        </span>-->
         <span class="pull-right widget-link">            
             <a href ng-click="toggleLegend()" title="{{'event_color_legend'| translate}}" class="small-horizonal-spacing"><i class="fa fa-info-circle vertical-center"></i></a>
             <a href ng-click="toggleEventsTableDisplay()" title="{{showEventsAsTables ? 'toggle_table_view_off' : 'toggle_table_view_on'| translate}}" ng-show="stagesCanBeShownAsTable"><span ng-if="!showEventsAsTables"><i class="fa fa-bars vertical-center"></i></span><span ng-if="showEventsAsTables"><i class="fa fa-square vertical-center"></i></span></a>

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html	2016-01-05 20:54:16 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/default-form.html	2016-01-07 21:16:02 +0000
@@ -1,4 +1,4 @@
-<form name="outerForm" novalidate>
+<form name="outerForm" novalidate>    
     <table class="dhis2-list-table-striped dhis2-table-hover" ng-if='currentEvent && !currentStage.programStageSections.length'>
         <thead>
             <tr>
@@ -10,7 +10,7 @@
                 </th>
             </tr>
         </thead>
-        <tr class="col-md-12" ng-repeat="prStDe in currentStage.programStageDataElements" ng-if="!isHidden(prStDe.dataElement.id, currentEvent)">
+        <tr class="col-md-12" ng-repeat="prStDe in currentStage.programStageDataElements" ng-if="!isHidden(prStDe.dataElement.id, currentEvent)">            
             <td>
                 <span ng-bind="prStDe.dataElement.formName ? prStDe.dataElement.formName : prStDe.dataElement.name"></span>
                 <span class="hideInPrint">

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/event-layout.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/event-layout.html	2015-12-28 20:44:17 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/event-layout.html	2016-01-07 21:16:02 +0000
@@ -1,23 +1,93 @@
-<div class="row equal-height-columns">
-    <div class="col-sm-12">
-        <div ng-repeat="dhis2Event in allEventsSorted.slice(eventPagingStart, eventPagingEnd)" ng-init="$index = $index + 1">        
-            <div class="event-container" ng-click="getEventPage('BACKWARD')" ng-if="$index === 1 && eventPagingStart > 0">
+<div class="row">
+    <div ng-class="{'col-sm-9': showStageTasks, 'col-xs-6': showStageTasks, 'col-sm-11': !showStageTasks, 'col-xs-10': !showStageTasks}">
+        <div ng-repeat="dhis2Event in allEventsSorted.slice(eventPagingStart, eventPagingEnd)">            
+            <div class="event-container" ng-click="getEventPage('BACKWARD')" ng-if="$index === 0 && eventPagingStart > 0">
                 &nbsp;<br/>
                 {{'previous'| translate}}
             </div>
-            <div class="event-container" title="[{{'org_unit' | translate}}: {{dhis2Event.orgUnitName}}, {{'program_stage' | translate}}: {{dhis2Event.name}}]" ng-class="getEventStyle(dhis2Event)" ng-click="showDataEntry(dhis2Event, false)">
+            <div class="event-container" title="[{{'org_unit' | translate}}: {{dhis2Event.orgUnitName}}, {{'program_stage' | translate}}: {{dhis2Event.name}}]" ng-class="getEventStyle(dhis2Event)" ng-click="showDataEntry(dhis2Event, false)">                
                 {{dhis2Event.sortingDate}}<br/>
                 {{dhis2Event.orgUnitName.length > 15 ? dhis2Event.orgUnitName.substring(0,15).concat('...') : dhis2Event.orgUnitName}}<br/>
-                {{dhis2Event.name.length > 15 ? dhis2Event.name.substring(0,15).concat('...') : dhis2Event.name}}
+                {{dhis2Event.name.length > 15 ? dhis2Event.name.substring(0,15).concat('...') : dhis2Event.name}}                
             </div>
-            <div class="arrow-container" ng-if="$index < eventPageSize && $index + eventPagingStart < allEventsSorted.length">
+            <div class="arrow-container" ng-if="$index + 1 < eventPageSize && $index + 1 + eventPagingStart < allEventsSorted.length">
                 <i class="fa fa-arrow-right"></i>
             </div>
-            <div class="event-container" ng-click="getEventPage('FORWARD')" ng-if="$index === eventPageSize && $index < allEventsSorted.length">
+            <div class="event-container" ng-click="getEventPage('FORWARD')" ng-if="$index + 1 === eventPageSize && eventPagingEnd < allEventsSorted.length">
                 &nbsp;<br/>
                 {{'next'| translate}}
             </div>
-        </div>    
+        </div>        
+    </div>
+    <div ng-class="{'col-sm-3': showStageTasks, 'col-xs-6': showStageTasks, 'col-sm-1': !showStageTasks, 'col-xs-2': !showStageTasks}">
+        <div ng-if="showStageTasks && eventsLoaded" class="panel panel-info">
+            <div class="panel-heading">{{'new_event' | translate}}
+                <span class="pull-right">
+                    <a class="small-horizonal-spacing" href ng-click="toggleShowStageTasks()">
+                    <span><i class="fa fa-chevron-right vertical-center" title="{{'hide_menu' | translate}}"></i></span>                    
+                    </a>
+                </span>
+            </div>
+            <div class="panel-body">
+                <div class="container-fluid">
+                    <div class="row row-alternate" style="font-size: 12px" ng-repeat="stage in creatableStages = (programStages | filter:displayStageTasksInTopLine)" ng-if="selectedEnrollment.status === 'ACTIVE'">
+                        <div class="col-sm-12">{{stage.name}}</div>
+                        <div class="col-sm-12">
+
+                            <span>
+                                <a href title="{{'create_new_event'| translate}}" ng-click="showCreateEvent(stage,eventCreationActions.add)" style="vertical-align:middle">
+                                    {{'add'|translate}}
+                                </a>
+                                |
+                                <a href title="{{'schedule_new_event'| translate}}" ng-click="showCreateEvent(stage,eventCreationActions.schedule)" style="vertical-align:middle">
+                                    {{'schedule'|translate}}
+                                </a>
+                                <!-- hides referral in trunk
+                                |
+                                <a href title="{{'make_referral' | translate}}" ng-click="showCreateEvent(stage, eventCreationActions.referral)" style="vertical-align: middle" ng-if="showReferral">
+                                    {{'referral'|translate}}
+                                </a>
+                                -->
+                            </span>
+
+                        </div>
+                    </div>
+                </div>
+                <div ng-if="!creatableStagesExist(creatableStages)" class="alert alert-warning">{{'no_stages_available'| translate}}</div> 
+            </div>
+        </div>       
+        <div ng-if="!showStageTasks" class="pull-right">
+            <div>
+                <a href ng-click="toggleShowStageTasks()" title="{{'show_new_event_menu' | translate}}">
+                    <span class="badge stage-tasks-badge">                                     
+                        <span><i class="fa fa-chevron-left vertical-center"></i></span>                
+                    </span>
+                </a>
+            </div>
+            <div>
+                <a href class="disable-link-effects" ng-click="showCreateEvent(null, eventCreationActions.add)" title="{{'add_new_event'| translate}}">
+                    <span class="badge stage-tasks-badge">                                     
+                        <span><i class="fa fa-plus vertical-center"></i></span>                
+                    </span>
+                </a>                
+            </div>
+            <div>
+                <a href class="disable-link-effects" ng-click="showCreateEvent(null, eventCreationActions.schedule)" title="{{'schedule_new_event'| translate}}">
+                    <span class="badge stage-tasks-badge">                                     
+                        <span><i class="fa fa-clock-o vertical-center"></i></span>                
+                    </span>
+                </a>                
+            </div>
+            <!-- hides referral in trunk
+            <div>
+                <a href class="disable-link-effects" ng-click="showCreateEvent(null, eventCreationActions.referral)" title="{{'make_referral' | translate}}">
+                    <span class="badge stage-tasks-badge">                                     
+                                <span><i class="fa fa-hospital-o vertical-center"></i></span>                
+                    </span>
+                </a>                
+            </div>                 
+            -->
+        </div>
     </div>
     <div ng-if="allEventsSorted.length < 1">
         <div class="alert alert-warning">{{'no_events_exist'| translate}}</div> 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event-controller.js	2015-12-21 13:28:07 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event-controller.js	2016-01-07 21:16:02 +0000
@@ -13,20 +13,26 @@
                 eventsByStage,
                 stage,
                 stages,
+                allStages,
                 tei,
                 program,
                 orgUnit,
                 enrollment,                
                 eventCreationAction,
                 autoCreate,
-                EventUtils) {
+                EventUtils,
+                events) {
     $scope.stages = stages;
+    $scope.allStages = allStages;
+    $scope.events = events;
     $scope.eventCreationAction = eventCreationAction;
     $scope.eventCreationActions = EventCreationService.eventCreationActions;
     $scope.isNewEvent = (eventCreationAction === $scope.eventCreationActions.add);
     $scope.isScheduleEvent = (eventCreationAction === $scope.eventCreationActions.schedule || eventCreationAction === $scope.eventCreationActions.referral);
     $scope.isReferralEvent = (eventCreationAction === $scope.eventCreationActions.referral);
     $scope.model = {selectedStage: stage, dueDateInvalid: false, eventDateInvalid: false};
+    $scope.stageSpecifiedOnModalOpen = angular.isObject(stage) ? true : false;    
+    
     var orgPath = [];    
     var dummyEvent = {};
     
@@ -35,33 +41,101 @@
         dummyEvent = EventUtils.createDummyEvent(eventsByStage[stage.id], tei, program, stage, orgUnit, enrollment);
         
         $scope.newEvent = {programStage: stage};
-        $scope.dhis2Event = {eventDate: $scope.isScheduleEvent ? '' : DateUtils.getToday(), dueDate: dummyEvent.dueDate, excecutionDateLabel : dummyEvent.excecutionDateLabel, name: dummyEvent.name, invalid: true};
-
-        //custom code for folkehelsa. Set empty eventDate if selectedStage is previous pregnancies
-        if($scope.model.selectedStage.id === 'PUZaKR0Jh2k'){
-            $scope.dhis2Event.eventDate = '';
-        }
+        $scope.dhis2Event = {eventDate: $scope.isScheduleEvent ? '' : DateUtils.getToday(), dueDate: dummyEvent.dueDate, excecutionDateLabel : dummyEvent.excecutionDateLabel, name: dummyEvent.name, invalid: true};        
 
         if ($scope.model.selectedStage.periodType) {
             $scope.dhis2Event.eventDate = dummyEvent.dueDate;
             $scope.dhis2Event.periodName = dummyEvent.periodName;
             $scope.dhis2Event.periods = dummyEvent.periods;
             $scope.dhis2Event.selectedPeriod = dummyEvent.periods[0];
-        }
-        
-        orgPath.push(dummyEvent.orgUnit);
-    };
-    
-    if($scope.model.selectedStage){
-        prepareEvent();
+        }       
+    };
+    
+    function suggestStage(){        
+        var suggestedStage;
+        var events = $scope.events;        
+        var allStages = $scope.allStages;
+        
+        var availableStagesOrdered = $scope.stages.slice();
+        availableStagesOrdered.sort(function (a,b){
+            return a.sortOrder - b.sortOrder;
+        });
+        
+        var stagesById = [];
+        
+        if(angular.isUndefined(events) || events.length === 0){
+            suggestedStage = availableStagesOrdered[0];
+        }
+        else{
+            angular.forEach(allStages, function(stage){
+                stagesById[stage.id] = stage;
+            });
+            
+            var lastStageForEvents;
+            for(i = 0; i < events.length; i++){
+                var event = events[i];
+                var eventStage = stagesById[event.programStage];
+                    if(i > 0){
+                        if(eventStage.sortOrder > lastStageForEvents.sortOrder){
+                            lastStageForEvents = eventStage;
+                        }
+                        else if(eventStage.sortOrder === lastStageForEvents.sortOrder){
+                            if(eventStage.id !== lastStageForEvents.id){
+                                if(eventStage.name.localeCompare(lastStageForEvents.name) > 0){
+                                    lastStageForEvents = eventStage;
+                                }
+                            }                            
+                        }
+                    }
+                    else {
+                        lastStageForEvents = eventStage;
+                    }
+            }
+            
+            for(j = 0; j < availableStagesOrdered.length; j++){
+                var availableStage = availableStagesOrdered[j];
+                
+                if(availableStage.id === lastStageForEvents.id){
+                    suggestedStage = availableStage;
+                    break;
+                }
+                else if(availableStage.sortOrder === lastStageForEvents.sortOrder){
+                    if(availableStage.name.localeCompare(lastStageForEvents.name) > 0){
+                        suggestedStage = availableStage;
+                        break;
+                    }
+                }
+                else if(availableStage.sortOrder > lastStageForEvents.sortOrder){
+                    suggestedStage = availableStage;
+                    break;
+                }
+            }
+            
+            if(angular.isUndefined(suggestedStage)){
+                suggestedStage = availableStagesOrdered[availableStagesOrdered.length - 1];
+            }
+        }
+        
+        $scope.model.selectedStage = suggestedStage;
+        stage = $scope.model.selectedStage;
+    };
+    
+    if(!$scope.stageSpecifiedOnModalOpen){
+        //suggest stage
+        suggestStage();        
     }
+        
+    if(angular.isDefined(orgUnit) && angular.isDefined(orgUnit.id)){
+        orgPath.push(orgUnit.id);
+    }    
+    
     
     $scope.$watch('model.selectedStage', function(){       
         if(angular.isObject($scope.model.selectedStage)){
             stage = $scope.model.selectedStage;
             prepareEvent();
         }
-    });
+    });    
 
     //watch for changes in due/event-date
     $scope.$watchCollection('[dhis2Event.dueDate, dhis2Event.eventDate]', function () {
@@ -93,7 +167,8 @@
         if($scope.isReferralEvent && !$scope.selectedSearchingOrgUnit){
             $scope.orgUnitError = true;
             return false;
-        }
+        }        
+        
         $scope.orgUnitError =  false;
         
         if ($scope.model.selectedStage.periodType) {
@@ -123,7 +198,7 @@
         DHIS2EventFactory.create(newEvents).then(function (response) {
             if (response.response && response.response.importSummaries[0].status === 'SUCCESS') {
                 newEvent.event = response.response.importSummaries[0].reference;
-                $modalInstance.close(newEvent);
+                $modalInstance.close({dummyEvent: dummyEvent, ev: newEvent});
             }
             else {
                 var dialogOptions = {
@@ -216,7 +291,7 @@
             $scope.orgUnitsLoading = false;
         }
     };
-    
+   
     if($scope.isReferralEvent){
         initOrgUnits(orgPath[0]);
     }

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html	2015-12-21 13:28:07 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/new-event.html	2016-01-07 21:16:02 +0000
@@ -3,50 +3,56 @@
     <h3 ng-if="isScheduleEvent && !isReferralEvent">{{'schedule'| translate}}<span ng-if="model.selectedStage"> - {{model.selectedStage.name}}</span></h3>
     <h3 ng-if="isReferralEvent">{{'referral' | translate}}<span ng-if="model.selectedStage"> - {{model.selectedStage.name}}</span></h3>
 </div>
-<div class="modal-body page">
+<div class="modal-body page">    
     <form name="eventCreationForm" class="form-horizontal" role="form" novalidate>
-        <div ng-if="!model.selectedStage">
+        <div ng-if="!stageSpecifiedOnModalOpen">
             <div class="form-group">
-                <label class="col-sm-2 control-label">
-                    {{'program_stage' | translate}}
-                </label>
-                <div class="col-sm-10">
-                    <select class="form-control-program" 
-                            ng-model="model.selectedStage"
-                            ng-options="stage.name for stage in stages">                    
-                    </select>
-                </div>                
-            </div>            
+                <div class="col-sm-11">
+                    <label class="col-sm-3 control-label" style="padding-left: 0px">
+                        {{'program_stage' | translate}}
+                    </label>
+                    <div class="col-sm-9">
+                        <select class="form-control-program" 
+                                ng-model="model.selectedStage"                                
+                                ng-options="stage.name for stage in stages">                    
+                        </select>
+                    </div>                
+                </div>         
+            </div>               
         </div>
         
         <div ng-if="model.selectedStage && !model.selectedStage.periodType">
             <div ng-if="isScheduleEvent && !isReferralEvent && !model.selectedStage.hideDueDate" class="form-group">
-                <label class="col-sm-2 control-label">{{'scheduled_date'| translate}}</label>
-                <div class="col-sm-10">
-                    <input type="text" 
-                           class="form-control" 
-                           name="dueDate"
-                           placeholder="{{dhis2CalendarFormat.keyDateFormat}}" 
-                           ng-rquired="true" 
-                           d2-date
-                           ng-model="dhis2Event.dueDate">
-                    <span ng-if="model.dueDateInvalid" class="error">{{'required'| translate}}</span>
-                </div>                
+                <div class="col-sm-11">
+                    <label class="col-sm-3 control-label">{{'scheduled_date'| translate}}</label>
+                    <div class="col-sm-9">
+                        <input type="text" 
+                               class="form-control" 
+                               name="dueDate"
+                               placeholder="{{dhis2CalendarFormat.keyDateFormat}}" 
+                               ng-rquired="true" 
+                               d2-date
+                               ng-model="dhis2Event.dueDate">
+                        <span ng-if="model.dueDateInvalid" class="error">{{'required'| translate}}</span>
+                    </div> 
+                </div>
             </div>
             <div ng-if="isNewEvent" class="form-group">
-                <label class="col-sm-2 control-label">{{model.selectedStage.excecutionDateLabel}}</label>
-                <div class="col-sm-10">
-                    <input type="text" 
-                           class="form-control" 
-                           name="eventDate"
-                           placeholder="{{dhis2CalendarFormat.keyDateFormat}}" 
-                           ng-rquired="true" 
-                           d2-date
-                           max-date="0"
-                           min-date=""
-                           ng-model="dhis2Event.eventDate">
-                    <span ng-if="model.eventDateInvalid" class="error">{{'required'| translate}}</span>
-                </div>
+                <div class="col-sm-11">
+                    <label class="col-sm-3 control-label" style="padding-left: 0px">{{model.selectedStage.excecutionDateLabel}}</label>
+                    <div class="col-sm-9">
+                        <input type="text" 
+                               class="form-control" 
+                               name="eventDate"
+                               placeholder="{{dhis2CalendarFormat.keyDateFormat}}" 
+                               ng-rquired="true" 
+                               d2-date
+                               max-date="0"
+                               min-date=""
+                               ng-model="dhis2Event.eventDate">
+                        <span ng-if="model.eventDateInvalid" class="error">{{'required'| translate}}</span>
+                    </div>
+                </div>                
             </div>
             <div ng-if="isReferralEvent">
                 <h4>Select an organizaton unit</h4>

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties	2016-01-07 18:03:55 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties	2016-01-07 21:16:02 +0000
@@ -397,3 +397,8 @@
 value_must_be_email=Please enter a valid email address
 complete_and_exit =Complete and exit
 are_you_sure_to_cancel_registration=Are you sure you want to cancel this registration?
+schedule_new_event=Schedule new event
+schedule=Schedule
+scheduled_date=Scheduled date
+show_new_event_menu=Show new event menu
+no_stages_available=All the expected events are already present, cannot create more events.
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app_ar.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app_ar.properties	2016-01-07 18:03:55 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app_ar.properties	2016-01-07 21:16:02 +0000
@@ -271,3 +271,8 @@
 value_must_be_email = \u064a\u062c\u0628 \u0623\u0646 \u062a\u0643\u0648\u0646 \u0642\u064a\u0645\u0629 \u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a(\u062c\u0648\u062c\u0644 \u062a\u0631\u062c\u0645\u0629)
 complete_and_exit=\u0643\u0627\u0645\u0644\u0629 \u0648\u0627\u0644\u062e\u0631\u0648\u062c(\u062c\u0648\u062c\u0644 \u062a\u0631\u062c\u0645\u0629)
 are_you_sure_to_cancel_registration=\u0647\u0644 \u0623\u0646\u062a \u0645\u062a\u0623\u0643\u062f \u0623\u0646\u0643 \u062a\u0631\u064a\u062f \u0625\u0644\u063a\u0627\u0621 \u0647\u0630\u0627 \u0627\u0644\u062a\u0633\u062c\u064a\u0644\u061f
+schedule_new_event=\u062c\u062f\u0648\u0644\u0629 \u062d\u062f\u062b \u062c\u062f\u064a\u062f
+schedule=\u0627\u0644\u062c\u062f\u0648\u0644 \u0627\u0644\u0632\u0645\u0646\u064a
+scheduled_date=\u0627\u0644\u0645\u0648\u0639\u062f \u0627\u0644\u0645\u0642\u0631\u0631
+show_new_event_menu=\u0625\u0638\u0647\u0627\u0631 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062d\u062f\u062b \u062c\u062f\u064a\u062f\u0629
+no_stages_available=\u0643\u0644 \u0627\u0644\u0623\u062d\u062f\u0627\u062b \u0627\u0644\u0645\u062a\u0648\u0642\u0639\u0629 \u0645\u0648\u062c\u0648\u062f\u0629 \u0628\u0627\u0644\u0641\u0639\u0644 \u060c \u0644\u0627 \u064a\u0645\u0643\u0646 \u062e\u0644\u0642 \u0627\u0644\u0645\u0632\u064a\u062f \u0645\u0646 \u0627\u0644\u0623\u062d\u062f\u0627\u062b

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/styles/style.css'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/styles/style.css	2016-01-05 20:54:16 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/styles/style.css	2016-01-07 21:16:02 +0000
@@ -1443,3 +1443,39 @@
     padding-top: 16px;
 }
 
+.row-alternate:nth-child(even) {
+    background-color: #ebf0f6;
+}
+
+.row-alternate:nth-child(odd) {
+    background-color: white;
+}
+
+.stage-task-badge-placement {
+    padding-right: 10px;
+    padding-top: 5px;
+}
+
+.stage-tasks-badge {
+    margin-top: 4px;
+    margin-right: 4px;
+    width: 26px;
+    height: 26px;
+    padding-left: 7.5px;
+    padding-right: 6px;
+    background-color: #d9edf7;
+    color: #3162C5;
+    font-size: 14px;
+    border-radius: 13px;    
+    text-align: left;
+}
+
+a.disable-link-effects:focus {
+    border: none;
+    border-image: none;
+    text-decoration: none;
+    outline-style: none;
+}
+
+
+