← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17646: WIP - centralized some code; i18nProvider; dynamic cacheManifest

 

------------------------------------------------------------
revno: 17646
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2014-12-03 18:48:48 +0100
message:
  WIP - centralized some code; i18nProvider; dynamic cacheManifest
removed:
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/en.json
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/fr.json
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/column-display-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/header-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/map-controller.js
added:
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app_fr.properties
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/d2Providers.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/controllers.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/directives.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/filters.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/providers.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/services.js
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/appcache/CacheManifest.java
modified:
  dhis-2/dhis-web/dhis-web-apps/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/app.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/directives.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/filters.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/eventList.html
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/home.html


--
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/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-apps/src/main/resources/struts.xml	2014-08-31 15:22:06 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/resources/struts.xml	2014-12-03 17:48:48 +0000
@@ -46,6 +46,15 @@
 		<action name="index" class="org.hisp.dhis.commons.action.NoAction">
 			<result name="success" type="redirect">index.html</result>
 		</action>
+		<action name="cacheManifest" class="org.hisp.dhis.appcache.CacheManifest">
+			<param name="appPath">dhis-web-event-capture</param>
+			<param name="i18nPath">i18n</param>
+			<param name="appCache">event-capture.appcache</param>			
+			<result type="stream">
+                <param name="contentType">text/cache-manifest</param>
+                <param name="inputName">inputStream</param>
+			</result> 
+		</action>
     </package>
     
 	<package name="dhis-web-tracker-capture" extends="dhis-web-commons" namespace="/dhis-web-tracker-capture">

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache	2014-11-20 18:38:54 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/event-capture.appcache	2014-12-03 17:48:48 +0000
@@ -57,6 +57,11 @@
 ../dhis-web-commons/javascripts/angular/plugins/angular-translate.min.js
 ../dhis-web-commons/javascripts/angular/plugins/angular-translate-loader-static-files.min.js
 ../dhis-web-commons/javascripts/angular/plugins/angular-translate-loader-url.min.js
+../dhis-web-commons/javascripts/angular/plugins/dhis2/providers.js
+../dhis-web-commons/javascripts/angular/plugins/dhis2/directives.js
+../dhis-web-commons/javascripts/angular/plugins/dhis2/filters.js
+../dhis-web-commons/javascripts/angular/plugins/dhis2/services.js
+../dhis-web-commons/javascripts/angular/plugins/dhis2/controllers.js
 
 ../dhis-web-commons/javascripts/moment/moment-with-langs.min.js       
 
@@ -105,12 +110,10 @@
 
 scripts/event-capture.js
 scripts/app.js
+scripts/d2Providers.js
 scripts/services.js
 scripts/directives.js
 scripts/controllers.js        
-scripts/column-display-controller.js
-scripts/header-controller.js
-scripts/map-controller.js
 scripts/notes-controller.js        
 scripts/filters.js
 scripts/orgunitTreeSearch.js
@@ -126,7 +129,3 @@
 views/notes.html
 views/serverside-pagination.html
 
-i18n/en.json
-
-NETWORK:
-*

=== removed file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/en.json'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/en.json	2014-11-19 09:55:11 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/en.json	1970-01-01 00:00:00 +0000
@@ -1,112 +0,0 @@
-{
-    "home": "Home",
-    "dhis2": "DHIS2",
-    "dhis2_home": "DHIS2 Home",
-    "event_capture": "Event capture",
-    "registering_unit": "Registering unit",
-    "registered_events": "Registered events",
-    "new_event_registration": "New event registration",    
-    "event_details": "Event details",
-    "no_registered_event": "There are no registered events.",
-    "event_registration_error": "Error in event registration",
-    "help": "Help",
-    "details": "Details",
-    "created_by": "Registered by",
-    "date": "Date",
-    "edit": "Edit",
-    "edit_in_grid": "Edit in grid",
-    "full_edit": "Full edit",
-    "update": "Update",
-    "save": "Save",
-    "save_and_add_new": "Save and add new",
-    "save_and_close": "Save and close",
-    "save_and_back": "Save and go back",
-    "delete": "Delete",
-    "cancel": "Cancel",
-    "close": "Close",
-    "discard": "Discard",
-    "back": "Back",
-    "go_back": "Go back",
-    "form_invalid": "Form is invalid. Please check for required fields.",
-    "required": "Required",
-    "int_required": "Value must be a number",
-    "string_required": "Value must be a text",
-    "date_required": "Value must be a date",
-    "option_required": "Value must be selected from drop-down",
-    "bool_required": "Value must be a boolean",
-    "ok": "Ok",
-    "done": "Done",
-    "remove": "Remove",
-    "are_you_sure_to_remove": "Are you sure you want to remove the selected item?",
-    "empty_form": "Empty form",
-    "please_fill_at_least_one_dataelement": "Your form is empty. Please fill at least one data element.",
-    "use_custom_form": "Custom form",
-    "use_default_form": "Default form",
-    "print_list": "Print list",
-    "print_form": "Print form",
-    "print_details": "Print details",
-    "show_hide_columns": "Show/hide columns",
-    "show_all": "Show all",
-    "hide": "Hide",
-    "select_columns_to_show": "Select columns to show",
-    "show_details": "Show details",
-    "add_your_comment_here": "Add your comment here",
-    "comments": "Comments",
-    "comment": "Comment",
-    "recorded_comments": "Recorded comments",
-    "show_comments": "Show comments",
-    "new_event": "New Event",
-    "data_element": "Data element",
-    "value": "Value",
-    "form_id": "Form id",
-    "register_event": "Register event",
-    "total_number_of_pages": "No. of pages",
-    "rows_per_page": "No. of rows per page",
-    "jump_to_page": "Jump to page",
-    "page": "Page ",
-    "first": "First",
-    "previous": "Previous",
-    "next": "Next",
-    "last": "Last",    
-    "org_units": "Organisation Units",
-    "org_unit": "Organisation Unit",
-    "programs": "Programs",
-    "program": "Program",
-    "program_stage": "Program stage",
-    "select_program": "Select program",
-    "select_program_stage": "Select program stage",
-    "period": "Period",
-    "periods": "Periods",
-    "start_date": "Start date",
-    "end_date": "End date",
-    "incident_date": "Incident date",
-    "lower_limit": "Lower limit",
-    "upper_limit": "Upper limit",
-    "please_select": "[Please Select]",    
-    "not_selected": "NOT_SELECTED",
-    "no_value": "NO_VALUE",
-    "search": "Search",
-    "locate_organisation_unit_by_name": "Locate organisation unit by name",
-    "register_new": "Register New",
-    "empty_event_list": "There are no events",
-    "empty_search_result": "Empty Search Result",
-    "no": "NO",
-    "yes": "YES",   
-    "offline_notification": "You are offline, data will be stored locally",
-    "online_nofification": "You are online",
-    "latitude": "Latitude",
-    "longitude": "Longitude",
-    "lat_lng": "[Latitude Longitude]",
-    "get_from_map": "Get from map",
-    "capture": "Capture",
-    "point_and_click_for_coordinate": "Point and click for coordinate",
-    "profile": "Profile",
-    "applications": "Apps",
-    "more_applications": "More apps",
-    "search_apps": "Search apps",
-    "settings": "Settings",
-    "account": "Account",
-    "help": "Help",
-    "log_out": "Log out",
-    "about_dhis2": "About DHIS 2"
-}

=== removed file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/fr.json'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/fr.json	2014-06-12 23:12:59 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/fr.json	1970-01-01 00:00:00 +0000
@@ -1,72 +0,0 @@
-{
-    "home": "Accueil",
-    "dhis2": "DHIS 2",
-    "dhis2_home": "Accueil DHIS 2",
-    "event_capture": "Enregistrement d'un événement",
-    "registering_unit": "Unité qui enregistre",
-    "registered_events": "Événements enregistrés",
-    "new_event_registration": "Enregistrement d'un nouvel événement",
-    "update_event": "Mise à jour de l'événement",
-    "no_registered_event": "Aucun événement n'est enregistré",
-    "event_registration_error": "Erreur lors de l'enregistrement d'un événement",
-    "help": "Aide",
-    "edit": "Editer",
-    "edit_in_grid": "Éditer en grille",
-    "full_edit": "Édition complète",
-    "update": "Mise à jour",
-    "save": "Sauvegarder",
-    "save_and_add_new": "Sauvegarder et ajouter",
-    "save_and_close": "Sauvegarder et fermer",
-    "save_and_back": "Sauvegarder et retourner",
-    "delete": "Supprimer",
-    "cancel": "Annuler",
-    "close": "Fermer",
-    "discard": "Effacer",
-    "back": "Retour",
-    "go_back": "Retourner",
-    "required": "Obligatoire",
-    "ok": "Ok",
-    "done": "Effectué",
-    "remove": "Enlever",
-    "are_you_sure_to_remove": "Souhaitez-vous supprimer l'élément sélectionné ?",
-    "show_hide_columns": "Afficher/Masquer les colonnes",
-    "show_all": "Tout afficher",
-    "hide": "Masquer",
-    "select_columns_to_show": "Sélectionner les colonnes à afficher",
-    "show_details": "Afficher les détails",
-    "new_event": "Nouvel événement",
-    "data_element": "Élément de donnée",
-    "value": "Valeur",
-    "register_event": "Enregistrer événement",
-    "total_number_of_pages": "Nb de pages",
-    "rows_per_page": "Nb de lignes par page",
-    "jump_to_page": "Aller à la page",
-    "page": "Page",
-    "first": "Début",
-    "previous": "Précédent",
-    "next": "Suivant",
-    "last": "Fin",    
-    "org_units": "Unités d'organisation",
-    "org_unit": "Unité d'organisation",
-    "programs": "Programmes",
-    "program": "Programme",
-    "program_stage": "Étape du programme",
-    "select_program": "Sélectionner un programme",
-    "select_program_stage": "Sélectionner une étape du programme",
-    "period": "Période",
-    "periods": "Périodes",
-    "start_date": "Date de début",
-    "end_date": "Date de fin",
-    "lower_limit": "Limite inférieure",
-    "upper_limit": "Limite supérieure",
-    "please_select": "[Veuillez sélectionner]",    
-    "not_selected": "Non sélectionné",   
-    "search": "Rechercher",
-    "register_new": "Nouvel enregistrement",
-    "empty_event_list": "Aucun événement n'est disponible",
-    "empty_search_result": "Aucun résultat ne correspond à cette recherche",
-    "no": "NON",
-    "yes": "OUI",   
-    "offline_notification": "Vous êtes actuellement hors connexion, vos données seront stockées localement",
-    "online_nofification": "Vous êtes connecté"
-}
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app.properties	2014-12-03 17:48:48 +0000
@@ -0,0 +1,113 @@
+home=Home
+dhis2=DHIS2
+dhis2_home=DHIS2 Home
+event_capture=Event capture
+registering_unit=Registering unit
+registered_events=Registered events
+new_event_registration=New event registration
+event_details=Event details
+no_registered_event=There are no registered events.
+event_registration_error=Error in event registration
+help=Help
+click_for_action=Click for more actions
+details=Details
+created_by=Registered by
+date=Date
+edit=Edit
+edit_in_grid=Edit in grid
+full_edit=Full edit
+update=Update
+save=Save
+save_and_add_new=Save and add new
+save_and_close=Save and close
+save_and_back=Save and go back
+delete=Delete
+cancel=Cancel
+close=Close
+discard=Discard
+back=Back
+go_back=Go back
+form_invalid=Form is invalid. Please check for required fields.
+required=Required
+int_required=Value must be a number
+string_required=Value must be a text
+date_required=Value must be a date
+option_required=Value must be selected from drop-down
+bool_required=Value must be a boolean
+ok=Ok
+done=Done
+remove=Remove
+are_you_sure_to_remove=Are you sure you want to remove the selected item?
+empty_form=Empty form
+please_fill_at_least_one_dataelement=Your form is empty. Please fill at least one data element.
+use_custom_form=Custom form
+use_default_form=Default form
+print_list=Print list
+print_form=Print form
+print_details=Print details
+show_hide_columns=Show/hide columns
+show_all=Show all
+hide=Hide
+select_columns_to_show=Select columns to show
+show_details=Show details
+add_your_comment_here=Add your comment here
+comments=Comments
+comment=Comment
+recorded_comments=Recorded comments
+show_comments=Show comments
+new_event=New Event
+data_element=Data element
+value=Value
+form_id=Form id
+register_event=Register event
+total_number_of_pages=No. of pages
+rows_per_page=No. of rows per page
+jump_to_page=Jump to page
+page=Page 
+first=First
+previous=Previous
+next=Next
+last=Last
+org_units=Organisation Units
+org_unit=Organisation Unit
+programs=Programs
+program=Program
+program_stage=Program stage
+select_program=Select program
+select_program_stage=Select program stage
+period=Period
+periods=Periods
+start_date=Start date
+end_date=End date
+incident_date=Incident date
+lower_limit=Lower limit
+upper_limit=Upper limit
+please_select=[Please Select]
+not_selected=NOT_SELECTED
+no_value=NO_VALUE
+search=Search
+locate_organisation_unit_by_name=Locate organisation unit by name
+register_new=Register New
+empty_event_list=There are no events
+empty_search_result=Empty Search Result
+no=NO
+yes=YES
+offline_notification=You are offline, data will be stored locally
+online_nofification=You are online
+latitude=Latitude
+longitude=Longitude
+lat_lng=[Latitude Longitude]
+get_from_map=Get from map
+capture=Capture
+point_and_click_for_coordinate=Point and click for coordinate
+loading_tree=Loading orgunit tree
+loading_metadata=Loading meta-data
+profile=Profile
+applications=Apps
+more_applications=More apps
+search_apps=Search apps
+settings=Settings
+account=Account
+log_out=Log out
+about_dhis2=About DHIS 2 
+update_event=Update Event

=== added file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app_fr.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app_fr.properties	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/i18n/i18n_app_fr.properties	2014-12-03 17:48:48 +0000
@@ -0,0 +1,70 @@
+home=Accueil
+dhis2=DHIS 2
+dhis2_home=Accueil DHIS 2
+event_capture=Enregistrement d'un \u00e9v\u00e9nement
+registering_unit=Unit\u00e9 qui enregistre
+registered_events=\u00c9v\u00e9nements enregistr\u00e9s
+new_event_registration=Enregistrement d'un nouvel \u00e9v\u00e9nement
+update_event=Mise \u00e0 jour de l'\u00e9v\u00e9nement
+no_registered_event=Aucun \u00e9v\u00e9nement n'est enregistr\u00e9
+event_registration_error=Erreur lors de l'enregistrement d'un \u00e9v\u00e9nement
+help=Aide
+edit=Editer
+edit_in_grid=\u00c9diter en grille
+full_edit=\u00c9dition compl\u00e8te
+update=Mise \u00e0 jour
+save=Sauvegarder
+save_and_add_new=Sauvegarder et ajouter
+save_and_close=Sauvegarder et fermer
+save_and_back=Sauvegarder et retourner
+delete=Supprimer
+cancel=Annuler
+close=Fermer
+discard=Effacer
+back=Retour
+go_back=Retourner
+required=Obligatoire
+ok=Ok
+done=Effectu\u00e9
+remove=Enlever
+are_you_sure_to_remove=Souhaitez-vous supprimer l'\u00e9l\u00e9ment s\u00e9lectionn\u00e9 ?
+show_hide_columns=Afficher/Masquer les colonnes
+show_all=Tout afficher
+hide=Masquer
+select_columns_to_show=S\u00e9lectionner les colonnes \u00e0 afficher
+show_details=Afficher les d\u00e9tails
+new_event=Nouvel \u00e9v\u00e9nement
+data_element=\u00c9l\u00e9ment de donn\u00e9e
+value=Valeur
+register_event=Enregistrer \u00e9v\u00e9nement
+total_number_of_pages=Nb de pages
+rows_per_page=Nb de lignes par page
+jump_to_page=Aller \u00e0 la page
+page=Page
+first=D\u00e9but
+previous=Pr\u00e9c\u00e9dent
+next=Suivant
+last=Fin    
+org_units=Unit\u00e9s d'organisation
+org_unit=Unit\u00e9 d'organisation
+programs=Programmes
+program=Programme
+program_stage=\u00c9tape du programme
+select_program=S\u00e9lectionner un programme
+select_program_stage=S\u00e9lectionner une \u00e9tape du programme
+period=P\u00e9riode
+periods=P\u00e9riodes
+start_date=Date de d\u00e9but
+end_date=Date de fin
+lower_limit=Limite inf\u00e9rieure
+upper_limit=Limite sup\u00e9rieure
+please_select=[Veuillez s\u00e9lectionner]    
+not_selected=Non s\u00e9lectionn\u00e9   
+search=Rechercher
+register_new=Nouvel enregistrement
+empty_event_list=Aucun \u00e9v\u00e9nement n'est disponible
+empty_search_result=Aucun r\u00e9sultat ne correspond \u00e0 cette recherche
+no=NON
+yes=OUI   
+offline_notification=Vous \u00eates actuellement hors connexion, vos donn\u00e9es seront stock\u00e9es localement
+online_nofification=Vous \u00eates connect\u00e9"

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html	2014-11-26 13:37:32 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/index.html	2014-12-03 17:48:48 +0000
@@ -1,5 +1,6 @@
 <!DOCTYPE html>
-<html manifest="event-capture.appcache" ng-app="eventCapture">
+<!--<html ng-app="eventCapture">-->
+<html manifest="cacheManifest.action" ng-app="eventCapture">
     <head>
         <title>Event Capture</title>
 
@@ -66,15 +67,18 @@
         <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/angular-translate.min.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/angular-translate-loader-static-files.min.js"></script>
         <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/angular-translate-loader-url.min.js"></script>
+        <!--<script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/dhis2/providers.js"></script>-->
+        <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/dhis2/directives.js"></script>
+        <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/dhis2/filters.js"></script>
+        <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/dhis2/services.js"></script>
+        <script type="text/javascript" src="../dhis-web-commons/javascripts/angular/plugins/dhis2/controllers.js"></script>
 
         <script type="text/javascript" src="scripts/event-capture.js"></script>
         <script type="text/javascript" src="scripts/app.js"></script>
+        <script type="text/javascript" src="scripts/d2Providers.js"></script>
         <script type="text/javascript" src="scripts/services.js"></script>
         <script type="text/javascript" src="scripts/directives.js"></script>
         <script type="text/javascript" src="scripts/controllers.js"></script>        
-        <script type="text/javascript" src="scripts/column-display-controller.js"></script>
-        <script type="text/javascript" src="scripts/header-controller.js"></script>
-        <script type="text/javascript" src="scripts/map-controller.js"></script>
         <script type="text/javascript" src="scripts/notes-controller.js"></script>        
         <script type="text/javascript" src="scripts/filters.js"></script>
         <!--<script type="text/javascript" src="scripts/orgunitTreeSearch.js"></script>-->

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/app.js	2014-11-03 10:34:14 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/app.js	2014-12-03 17:48:48 +0000
@@ -9,14 +9,18 @@
 		  'eventCaptureDirectives', 
 		  'eventCaptureControllers', 
 		  'eventCaptureServices',
-		  'eventCaptureFilters',
+		  'd2Filters',
+          'd2Directives',
+          'd2Services',
+          'd2Controllers',
 		  'angularLocalStorage', 
 		  'pascalprecht.translate',
+          'd2Providers',
           'd2Menu'])
               
 .value('DHIS2URL', '..')
 
-.config(function($httpProvider, $routeProvider, $translateProvider) {    
+.config(function($httpProvider, $routeProvider, d2I18nProvider) {    
             
     $httpProvider.defaults.useXDomain = true;
     delete $httpProvider.defaults.headers.common['X-Requested-With'];
@@ -33,10 +37,7 @@
         redirectTo : '/'
     });
     
-    $translateProvider.useStaticFilesLoader({
-        prefix: 'i18n/',
-        suffix: '.json'
-    });
-    
-    $translateProvider.preferredLanguage('en');    
+    
+    d2I18nProvider.initialize();
+    
 });
\ No newline at end of file

=== removed file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/column-display-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/column-display-controller.js	2014-11-03 11:11:25 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/column-display-controller.js	1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
-//Controller for column show/hide
-eventCaptureControllers.controller('ColumnDisplayController', 
-    function($scope, 
-            $modalInstance, 
-            hiddenGridColumns,
-            eventGridColumns){
-    
-    $scope.eventGridColumns = eventGridColumns;
-    $scope.hiddenGridColumns = hiddenGridColumns;
-    
-    $scope.close = function () {
-      $modalInstance.close($scope.eventGridColumns);
-    };
-    
-    $scope.showHideColumns = function(gridColumn){
-       
-        if(gridColumn.show){                
-            $scope.hiddenGridColumns--;            
-        }
-        else{
-            $scope.hiddenGridColumns++;            
-        }      
-    };    
-});
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js	2014-11-26 13:37:32 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/controllers.js	2014-12-03 17:48:48 +0000
@@ -22,7 +22,6 @@
                 ModalService,
                 DialogService) {   
    
-                      
     //selected org unit
     $scope.selectedOrgUnit = '';
     
@@ -45,11 +44,8 @@
     $scope.note = {};
     $scope.today = DateUtils.getToday();
     
-    var loginDetails = storage.get('LOGIN_DETAILS');
-    var storedBy = '';
-    if(loginDetails && loginDetails.userCredentials){
-        storedBy = loginDetails.userCredentials.username;
-    }
+    var userAccount = storage.get('USER_PROFILE');
+    var storedBy = userAccount ? userAccount.userName : '';    
     $scope.noteExists = false;
         
     //watch for selection of org unit from tree
@@ -310,7 +306,7 @@
             templateUrl: 'views/column-modal.html',
             controller: 'ColumnDisplayController',
             resolve: {
-                eventGridColumns: function () {
+                gridColumns: function () {
                     return $scope.eventGridColumns;
                 },
                 hiddenGridColumns: function(){

=== added file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/d2Providers.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/d2Providers.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/d2Providers.js	2014-12-03 17:48:48 +0000
@@ -0,0 +1,94 @@
+'use strict';
+
+/* Providers */
+var d2Providers = angular.module('d2Providers', [])
+
+.provider('d2I18n', function ($translateProvider) {
+    
+    return {
+
+        initialize: function () {
+            
+            var getTranslations = function(locale){
+                
+                var defaultUrl = 'i18n/i18n_app.properties';
+                var url = '';
+                if(locale === 'en' || !locale){
+                    url = defaultUrl;
+                }
+                else{
+                    url = 'i18n/i18n_app_' + locale + '.properties';
+                }
+                
+                var translation = {locale: locale};
+                var def = $.Deferred();
+
+                $.ajax({
+                    url: url,
+                    type: 'GET'
+                }).done(function(response) {
+                    console.log('custom locale');
+                    translation.keys = response;
+                    localStorage['LOCALE'] = locale;
+                    def.resolve(translation);
+                }).fail(function(){
+                    console.log('default locale');
+                    $.ajax({
+                        url: defaultUrl ,
+                        type: 'GET'
+                    }).done(function(response) {  
+                        translation= {locale: 'en', keys: response};
+                        localStorage['LOCALE'] = 'en';
+                        def.resolve(translation);
+                    });                
+                });
+
+                return def.promise();
+            };
+
+            var getLocale = function(){
+                var locale = '';
+                var def = $.Deferred();
+
+                $.ajax({
+                    url: '../api/me/profile.json',
+                    type: 'GET'
+                }).done( function(response) {
+                    localStorage['USER_PROFILE'] = JSON.stringify(response);
+                    if(response && response.settings && response.settings.keyUiLocale){
+                        locale = response.settings.keyUiLocale;
+                    }
+                    else{
+                        locale = 'en';
+                    }
+                }).always(function(){                
+                    getTranslations(locale).then(function(response){
+                        def.resolve(response);
+                    });
+                });
+
+                return def.promise();
+            };
+    
+            var userProfile = localStorage['USER_PROFILE'];
+            if(userProfile){
+                userProfile = JSON.parse(userProfile);                
+            }
+            
+            if(userProfile && userProfile.settings && userProfile.settings.keyUiLocale){
+                getTranslations(userProfile.settings.keyUiLocale).done(function(response){
+                    console.log('the locale is:  ', response.locale);
+                    $translateProvider.translations(response.locale, dhis2.util.parseJavaProperties(response.keys));
+                });
+            }
+            else{
+                getLocale().done(function(response){
+                    console.log('the locale is:  ', response.locale);
+                    $translateProvider.translations(response.locale, dhis2.util.parseJavaProperties(response.keys));
+                });
+            }
+        },
+        $get: function () {
+        }
+    };
+});
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/directives.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/directives.js	2014-11-26 11:12:10 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/directives.js	2014-12-03 17:48:48 +0000
@@ -2,411 +2,5 @@
 
 /* Directives */
 
-var eventCaptureDirectives = angular.module('eventCaptureDirectives', [])
-
-.directive('inputValidator', function() {
-    
-    return {
-        require: 'ngModel',
-        link: function (scope, element, attrs, ctrl) {  
-
-            ctrl.$parsers.push(function (value) {
-                return parseFloat(value || '');
-            });
-        }
-    };   
-})
-
-.directive('selectedOrgUnit', function($timeout, storage) {        
-
-    return {        
-        restrict: 'A',        
-        link: function(scope, element, attrs){
-            
-            //reloadtree, incase not loaded. get selected orgunit - if there is any - and inform angular 
-            $(function() {
-                dhis2.ou.store.open().done( function() {
-                    selection.load();
-                    $( "#orgUnitTree" ).one( "ouwtLoaded", function(event, ids, names) {
-                        dhis2.availability.startAvailabilityCheck();
-                        setSelectedOu(ids, names);
-                    });
-                });
-            });
-            
-            //listen to user selection, and inform angular         
-            selection.setListenerFunction( setSelectedOu, true );
-            
-            function setSelectedOu( ids, names ) {
-                var ou = {id: ids[0], name: names[0]};
-                $timeout(function() {
-                    scope.selectedOrgUnit = ou;
-                    scope.$apply();
-                });
-            }
-        }  
-    };
-})
-
-.directive('d2CustomForm', function($compile, $parse, CustomFormService) {
-    return{ 
-        restrict: 'E',
-        link: function(scope, elm, attrs){   
-            
-            var customFormType = attrs.customFormType;
-            var customFormObject = $parse(attrs.customFormObject)(scope);
-            
-            if(customFormType === 'PROGRAM_STAGE'){                
-                var customForm = CustomFormService.getForProgramStage(customFormObject);                
-                elm.html(customForm ? customForm : '');
-                $compile(elm.contents())(scope);                
-            }
-        }
-    };
-})
-
-.directive('d2ContextMenu', function(ContextMenuSelectedItem) {
-        
-    return {        
-        restrict: 'A',
-        link: function(scope, element, attrs){
-            var contextMenu = $("#contextMenu");                   
-            
-            element.click(function (e) {
-                var selectedItem = $.parseJSON(attrs.selectedItem);
-                ContextMenuSelectedItem.setSelectedItem(selectedItem);
-                
-                var menuHeight = contextMenu.height();
-                var menuWidth = contextMenu.width();
-                var winHeight = $(window).height();
-                var winWidth = $(window).width();
-
-                var pageX = e.pageX;
-                var pageY = e.pageY;
-
-                contextMenu.show();
-
-                if( (menuWidth + pageX) > winWidth ) {
-                  pageX -= menuWidth;
-                }
-
-                if( (menuHeight + pageY) > winHeight ) {
-                  pageY -= menuHeight;
-
-                  if( pageY < 0 ) {
-                      pageY = e.pageY;
-                  }
-                }
-                
-                contextMenu.css({
-                    left: pageX,
-                    top: pageY
-                });
-
-                return false;
-            });
-            
-            contextMenu.on("click", "a", function () {                    
-                contextMenu.hide();
-            });
-
-            $(document).click(function () {                                        
-                contextMenu.hide();
-            });
-        }     
-    };
-})
-
-.directive('d2Date', function(DateUtils, CalendarService, storage, $parse) {
-    return {
-        restrict: 'A',
-        require: 'ngModel',        
-        link: function(scope, element, attrs, ctrl) {    
-            
-            var calendarSetting = CalendarService.getSetting();            
-            var dateFormat = 'yyyy-mm-dd';
-            if(calendarSetting.keyDateFormat === 'dd-MM-yyyy'){
-                dateFormat = 'dd-mm-yyyy';
-            }            
-            
-            var minDate = $parse(attrs.minDate)(scope), 
-                maxDate = $parse(attrs.maxDate)(scope),
-                calendar = $.calendars.instance(calendarSetting.keyCalendar);
-            
-            element.calendarsPicker({
-                changeMonth: true,
-                dateFormat: dateFormat,
-                yearRange: '-120:+30',
-                minDate: minDate,
-                maxDate: maxDate,
-                calendar: calendar,
-                duration: "fast",
-                showAnim: "",
-                renderer: $.calendars.picker.themeRollerRenderer,
-                onSelect: function(date) {
-                    //scope.date = date;
-                    ctrl.$setViewValue(date);
-                    $(this).change();                    
-                    scope.$apply();
-                }
-            })
-            .change(function() {                
-                var rawDate = this.value;
-                var convertedDate = DateUtils.format(this.value);
-
-                if(rawDate != convertedDate){
-                    scope.invalidDate = true;
-                    ctrl.$setViewValue(this.value);                                   
-                    ctrl.$setValidity('foo', false);                    
-                    scope.$apply();     
-                }
-                else{
-                    scope.invalidDate = false;
-                    ctrl.$setViewValue(this.value);                                   
-                    ctrl.$setValidity('foo', true);                    
-                    scope.$apply();     
-                }
-            });    
-        }      
-    };   
-})
-
-.directive('blurOrChange', function() {
-    
-    return function( scope, elem, attrs) {
-        elem.calendarsPicker({
-            onSelect: function() {
-                scope.$apply(attrs.blurOrChange);
-                $(this).change();                                        
-            }
-        }).change(function() {
-            scope.$apply(attrs.blurOrChange);
-        });
-    };
-})
-
-.directive('d2TypeaheadValidation', function() {
-    
-    return {
-        require: 'ngModel',
-        restrict: 'A',
-        link: function (scope, element, attrs, ctrl) {
-            element.bind('blur', function () {                
-                if(ctrl.$viewValue && !ctrl.$modelValue){
-                    ctrl.$setViewValue();
-                    ctrl.$render();
-                }                
-            });
-        }
-    };
-})
-
-.directive('typeaheadOpenOnFocus', function () {
-  return {
-        require: ['typeahead', 'ngModel'],
-        link: function (scope, element, attr, ctrls) {
-            element.bind('focus', function () {
-                ctrls[0].getMatchesAsync(ctrls[1].$viewValue);
-                
-                scope.$watch(attr.ngModel, function(value) {
-                    if(value === '' || angular.isUndefined(value)){
-                        ctrls[0].getMatchesAsync(ctrls[1].$viewValue);
-                    }                
-                });
-            });
-        }
-    };
-})
-
-.directive('d2PopOver', function($compile, $templateCache){
-    return {        
-        restrict: 'EA',
-        link: function(scope, element, attrs){
-            var content = $templateCache.get("note.html");
-            content = $compile(content)(scope);
-            var options = {
-                    content: content,
-                    placement: 'right',
-                    trigger: 'hover',
-                    html: true,
-                    title: scope.title               
-                };            
-            $(element).popover(options);
-        },
-        scope: {
-            content: '=',
-            title: '@details',
-            template: "@template"
-        }
-    };
-})
-
-.directive('d2GoogleMap', function ($parse, $compile, storage) {
-    return {
-        restrict: 'E',
-        replace: true,
-        template: '<div></div>',
-        link: function(scope, element, attrs){
-            
-            //remove angular bootstrap ui modal draggable
-            $(".modal-content").draggable({ disabled: true });
-            
-            //get a default center
-            var latCenter = 12.31, lngCenter = 51.48;            
-            
-            //if there is any marker already - use it as center
-            if(angular.isObject(scope.location)){
-                if(scope.location.lat && scope.location.lng){
-                    latCenter = scope.location.lat;
-                    lngCenter = scope.location.lng;
-                }                
-            }
-            
-            //default map configurations 
-            var mapOptions = {
-                zoom: 3,
-                center: new google.maps.LatLng(latCenter, lngCenter),
-                mapTypeId: google.maps.MapTypeId.ROADMAP
-            },featureStyle = {
-                strokeWeight: 2,
-                strokeOpacity: 0.4,
-                fillOpacity: 0.4,
-                fillColor: 'green'
-            };
-            
-            var geojsons = $parse(attrs.geojsons)(scope);
-            var currentLayer = 0, currentGeojson = geojsons[0]; 
-            
-            var map = new google.maps.Map(document.getElementById(attrs.id), mapOptions);            
-            var currentGeojsonFeatures = map.data.addGeoJson(currentGeojson);
-            
-            var marker = new google.maps.Marker({
-                map: map
-            });
-            
-            if(angular.isObject(scope.location)){
-                if(scope.location.lat && scope.location.lng){                    
-                    addMarker({lat: scope.location.lat, lng: scope.location.lng});                    
-                }                
-            }
-            
-            function addMarker(loc){
-                var latLng = new google.maps.LatLng(loc.lat, loc.lng);
-                marker.setPosition(latLng);
-            }
-            
-            function centerMap(){
-                
-                if(currentGeojson && currentGeojson.features){
-                    var latLngBounds = new google.maps.LatLngBounds();
-                    angular.forEach(currentGeojson.features, function(feature){
-                        if(feature.geometry.type === 'MultiPolygon'){
-                            angular.forEach(feature.geometry.coordinates[0][0], function(coordinate){
-                                latLngBounds.extend(new google.maps.LatLng(coordinate[1],coordinate[0]));
-                            });
-                        }
-                        else if(feature.geometry.type === 'Point'){                        
-                            latLngBounds.extend(new google.maps.LatLng(feature.geometry.coordinates[1],feature.geometry.coordinates[0]));
-                        }
-                    });
-                    
-                    map.fitBounds(latLngBounds);
-                    map.panToBounds(latLngBounds);
-                }                
-            }
-            
-            function initializeMap(){                
-                google.maps.event.addListenerOnce(map, 'idle', function(){
-                    google.maps.event.trigger(map, 'resize');
-                    map.data.setStyle(featureStyle);
-                    centerMap();
-                });
-            }
-            
-            map.data.addListener('mouseover', function(e) {                
-                $("#polygon-label").text( e.feature.k.name );
-                map.data.revertStyle();
-                map.data.overrideStyle(e.feature, {fillOpacity: 0.8});
-            });
-            
-            map.data.addListener('mouseout', function() {                
-                $("#polygon-label").text( '' );
-                map.data.revertStyle();
-            });
-            
-            //drill-down based on polygons assigned to orgunits
-            map.data.addListener('rightclick', function(e){                
-                for (var i = 0; i < currentGeojsonFeatures.length; i++){
-                    map.data.remove(currentGeojsonFeatures[i]);
-                }
-                                
-                if(currentLayer >= geojsons.length-1){
-                    currentLayer = 0;
-                    currentGeojson = angular.copy(geojsons[currentLayer]);                    
-                }
-                else{
-                    currentLayer++;
-                    currentGeojson = angular.copy(geojsons[currentLayer]);
-                    currentGeojson.features = [];
-                    var selectedFeatures = [];
-                    angular.forEach(geojsons[currentLayer].features, function(feature){                    
-                        if(feature.properties.parent === e.feature.B){
-                            selectedFeatures.push(feature);
-                        }
-                    });
-                    
-                    if(selectedFeatures.length){
-                        currentGeojson.features = selectedFeatures;
-                    }                   
-                }                
-                currentGeojsonFeatures = map.data.addGeoJson(currentGeojson);
-                centerMap();         
-            });            
-            
-            //capturing coordinate from defined polygons
-            map.data.addListener('click', function(e) {                
-                scope.$apply(function(){
-                    addMarker({
-                       lat: e.latLng.lat(),
-                       lng: e.latLng.lng()
-                    });
-                    $parse(attrs.location).assign(scope.$parent, {lat: e.latLng.lat(), lng: e.latLng.lng()});                    
-                });                
-            });
-            
-            //capturing coordinate from anywhere in the map - incase no polygons are defined
-            google.maps.event.addListener(map, 'click', function(e){                
-                scope.$apply(function(){
-                    addMarker({
-                       lat: e.latLng.lat(),
-                       lng: e.latLng.lng()
-                    });
-                    $parse(attrs.location).assign(scope.$parent, {lat: e.latLng.lat(), lng: e.latLng.lng()});                    
-                });                
-            });
-            
-            initializeMap();
-        }
-    };
-})
-
-.directive('serversidePaginator', function factory() {
-    return {
-        restrict: 'E',
-        controller: function ($scope, Paginator) {
-            $scope.paginator = Paginator;
-        },
-        templateUrl: 'views/serverside-pagination.html'
-    };
-})
-
-.directive('clientsidePaginator', function factory() {
-    return {
-        restrict: 'E',
-        controller: function ($scope, Paginator) {
-            $scope.paginator = Paginator;
-        },
-        templateUrl: 'views/clientside-pagination.html'
-    };
-});
+var eventCaptureDirectives = angular.module('eventCaptureDirectives', []);
 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js	2014-11-26 11:12:10 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js	2014-12-03 17:48:48 +0000
@@ -74,8 +74,6 @@
  */
 $(document).ready(function()
 {
-    downloadMetaData();
-    
     $.ajaxSetup({
         type: 'POST',
         cache: false
@@ -162,13 +160,12 @@
 
 function downloadMetaData(){    
     
+    console.log('Loading required meta-data');
     var def = $.Deferred();
     var promise = def.promise();
     
     promise = promise.then( dhis2.ec.store.open );
-    promise = promise.then( getUserProfile );
     promise = promise.then( getCalendarSetting );
-    promise = promise.then( getLoginDetails );
     promise = promise.then( getOrgUnitLevels );
     //promise = promise.then( getGeoJsonsByLevel );
     promise = promise.then( getMetaPrograms );     
@@ -176,27 +173,15 @@
     promise = promise.then( getProgramStages );
     promise = promise.then( getOptionSets );
     promise.done( function() {           
+        console.log( 'Finished loading meta-data' ); 
+        dhis2.availability.startAvailabilityCheck();
+        console.log( 'Started availability check' );
         selection.responseReceived();
     });         
 
     def.resolve();
 }
 
-function getUserProfile()
-{
-    var def = $.Deferred();
-
-    $.ajax({
-        url: '../api/me/profile',
-        type: 'GET'
-    }).done( function(response) {            
-        localStorage['USER_PROFILE'] = JSON.stringify(response);           
-        def.resolve();
-    });
-    
-    return def.promise(); 
-}
-
 function getCalendarSetting()
 {
     var def = $.Deferred();
@@ -207,26 +192,13 @@
     }).done(function(response) {
         localStorage['CALENDAR_SETTING'] = JSON.stringify(response);
         def.resolve();
+    }).fail(function(){
+        def.resolve();
     });
 
     return def.promise();
 }
 
-function getLoginDetails()
-{
-    var def = $.Deferred();
-
-    $.ajax({
-        url: '../api/me',
-        type: 'GET'
-    }).done( function(response) {            
-        localStorage['LOGIN_DETAILS'] = JSON.stringify(response);           
-        def.resolve();
-    });
-    
-    return def.promise(); 
-}
-
 function getOrgUnitLevels()
 {
     var def = $.Deferred();
@@ -243,6 +215,8 @@
             });
         }
         def.resolve( ouLevels );
+    }).fail(function(){
+        def.resolve(null);
     });
     
     return def.promise();    
@@ -282,10 +256,11 @@
 
     build.done(function() {
         def.resolve();
-
         promise = promise.done( function () {
             mainDef.resolve();
-        } );
+        });
+    }).fail(function(){
+        mainDef.resolve();
     });
 
     builder.resolve();
@@ -325,6 +300,8 @@
         });
         
         def.resolve( programs );
+    }).fail(function(){
+        def.resolve( null );
     });
     
     return def.promise(); 
@@ -367,6 +344,8 @@
         promise = promise.done( function () {
             mainDef.resolve( programs );
         } );
+    }).fail(function(){
+        mainDef.resolve( null );
     });
 
     builder.resolve();
@@ -444,6 +423,8 @@
         promise = promise.done( function () {
             mainDef.resolve( programs );
         } );
+    }).fail(function(){
+        mainDef.resolve( null );
     });
 
     builder.resolve();
@@ -505,6 +486,8 @@
         promise = promise.done( function () {
             mainDef.resolve( programs );
         } );
+    }).fail(function(){
+        mainDef.resolve( null );
     });
 
     builder.resolve();
@@ -537,5 +520,4 @@
         setHeaderDelayMessage( i18n_sync_success );
         selection.responseReceived(); //notify angular
     });
-}
-
+}
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/filters.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/filters.js	2014-08-19 11:45:47 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/filters.js	2014-12-03 17:48:48 +0000
@@ -2,95 +2,4 @@
 
 /* Filters */
 
-var eventCaptureFilters = angular.module('eventCaptureFilters', [])
-
-.filter('gridFilter', function($filter){    
-    
-    return function(data, filters, filterTypes){
-
-        if(!data ){
-            return;
-        }
-        
-        if(!filters){
-            return data;
-        }        
-        else{            
-            
-            var dateFilter = {}, 
-                textFilter = {}, 
-                numberFilter = {},
-                filteredData = data;
-            
-            for(var key in filters){
-                
-                if(filterTypes[key] === 'date'){
-                    if(filters[key].start || filters[key].end){
-                        dateFilter[key] = filters[key];
-                    }
-                }
-                else if(filterTypes[key] === 'int'){
-                    if(filters[key].start || filters[key].end){
-                        numberFilter[key] = filters[key];
-                    }
-                }
-                else{
-                    textFilter[key] = filters[key];
-                }
-            }
-            
-            filteredData = $filter('filter')(filteredData, textFilter); 
-            filteredData = $filter('filter')(filteredData, dateFilter, dateComparator);            
-            filteredData = $filter('filter')(filteredData, numberFilter, numberComparator);
-                        
-            return filteredData;
-        } 
-    }; 
-    
-    function dateComparator(data,filter){
-        var start = moment(filter.start, 'YYYY-MM-DD');
-        var end = moment(filter.end, 'YYYY-MM-DD');  
-        var date = moment(data, 'YYYY-MM-DD'); 
-        
-        if(filter.start && filter.end){
-            return ( Date.parse(date) <= Date.parse(end) ) && (Date.parse(date) >= Date.parse(start));
-        }        
-        return ( Date.parse(date) <= Date.parse(end) ) || (Date.parse(date) >= Date.parse(start));
-    }
-    
-    function numberComparator(data,filter){
-        var start = filter.start;
-        var end = filter.end;
-        
-        if(filter.start && filter.end){
-            return ( data <= end ) && ( data >= start );
-        }        
-        return ( data <= end ) || ( data >= start );
-    }
-})
-
-.filter('paginate', function(Paginator) {
-    return function(input, rowsPerPage) {
-        if (!input) {
-            return input;
-        }
-
-        if (rowsPerPage) {
-            Paginator.rowsPerPage = rowsPerPage;
-        }       
-        
-        Paginator.itemCount = input.length;
-
-        return input.slice(parseInt(Paginator.page * Paginator.rowsPerPage), parseInt((Paginator.page + 1) * Paginator.rowsPerPage + 1) - 1);
-    };
-})
-
-.filter('forLoop', function() {
-    return function(input, start, end) {
-        input = new Array(end - start);
-        for (var i = 0; start < end; start++, i++) {
-            input[i] = start;
-        }
-        return input;
-    };
-});
\ No newline at end of file
+var eventCaptureFilters = angular.module('eventCaptureFilters', []);
\ No newline at end of file

=== removed file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/header-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/header-controller.js	2014-11-03 11:11:25 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/header-controller.js	1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
-//Controller for the header section
-eventCaptureControllers.controller('HeaderController',
-        function($scope,                
-                DHIS2URL,
-                TranslationService) {
-
-    TranslationService.translate();
-    
-    $scope.home = function(){        
-        window.location = DHIS2URL;
-    };
-    
-});
\ No newline at end of file

=== removed file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/map-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/map-controller.js	2014-11-03 11:11:25 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/map-controller.js	1970-01-01 00:00:00 +0000
@@ -1,26 +0,0 @@
-//controller for dealing with google map
-eventCaptureControllers.controller('MapController',
-        function($scope, 
-                $modalInstance,
-                DHIS2URL,
-                TranslationService,
-                geoJsons,
-                location) {
-
-    TranslationService.translate();
-    
-    $scope.home = function(){        
-        window.location = DHIS2URL;
-    };
-    
-    $scope.location = location;
-    $scope.geoJsons = geoJsons;
-    
-    $scope.close = function () {
-        $modalInstance.close();
-    };
-    
-    $scope.captureCoordinate = function(){        
-        $modalInstance.close($scope.location);
-    };
-});
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js	2014-11-20 11:36:44 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js	2014-12-03 17:48:48 +0000
@@ -4,7 +4,6 @@
 
 var eventCaptureServices = angular.module('eventCaptureServices', ['ngResource'])
 
-
 .factory('StorageService', function(){
     var store = new dhis2.storage.Store({
         name: 'dhis2ec',
@@ -109,125 +108,6 @@
     };
 })
 
-/* factory for loading logged in user profiles from DHIS2 */
-.factory('CurrentUserProfile', function($http) { 
-           
-    var profile, promise;
-    return {
-        get: function() {
-            if( !promise ){
-                promise = $http.get('../api/me/profile').then(function(response){
-                   profile = response.data;
-                   return profile;
-                });
-            }
-            return promise;         
-        }
-    };  
-})
-
-
-/* factory for fetching selected orgunit's coordinate */
-.factory('OrgUnitService', function($http) { 
-           
-    var orgUnitId, promise;
-    return {
-        get: function(id) {
-            if( !promise && id !== orgUnitId){
-                promise = $http.get('../api/me/profile').then(function(response){
-                   orgUnitId = id; 
-                   return response.data;;
-                });
-            }
-            return promise;         
-        }
-    };  
-})
-
-
-/* Factory to fetch geojsons */
-.factory('GeoJsonFactory', function($q, $rootScope, StorageService) { 
-    return {
-        getAll: function(){
-
-            var def = $q.defer();
-            
-            StorageService.currentStore.open().done(function(){
-                StorageService.currentStore.getAll('geoJsons').done(function(geoJsons){
-                    $rootScope.$apply(function(){
-                        def.resolve(geoJsons);
-                    });                    
-                });
-            });
-            
-            return def.promise;            
-        },
-        get: function(level){
-            
-            var def = $q.defer();
-            
-            StorageService.currentStore.open().done(function(){
-                StorageService.currentStore.get('geoJsons', level).done(function(geoJson){                    
-                    $rootScope.$apply(function(){
-                        def.resolve(geoJson);
-                    });
-                });
-            });                        
-            return def.promise;            
-        }
-    };
-})
-
-/* Factory to fetch optioSets */
-.factory('OptionSetService', function($q, $rootScope, StorageService) { 
-    return {
-        getAll: function(){
-            
-            var def = $q.defer();
-            
-            StorageService.currentStore.open().done(function(){
-                StorageService.currentStore.getAll('optionSets').done(function(optionSets){
-                    $rootScope.$apply(function(){
-                        def.resolve(optionSets);
-                    });                    
-                });
-            });            
-            
-            return def.promise;            
-        },
-        get: function(uid){
-            
-            var def = $q.defer();
-            
-            StorageService.currentStore.open().done(function(){
-                StorageService.currentStore.get('optionSets', uid).done(function(optionSet){                    
-                    $rootScope.$apply(function(){
-                        def.resolve(optionSet);
-                    });
-                });
-            });                        
-            return def.promise;            
-        },
-        getNameOrCode: function(options, key){
-            var val = key;            
-
-            if(options){
-                for(var i=0; i<options.length; i++){
-                    if( key === options[i].name){
-                        val = options[i].code;
-                        break;
-                    }
-                    if( key === options[i].code){
-                        val = options[i].name;
-                        break;
-                    }
-                }
-            }            
-            return val;
-        }
-    };
-})
-
 /* Factory to fetch programs */
 .factory('ProgramFactory', function($q, $rootScope, StorageService) {  
         
@@ -392,360 +272,4 @@
             return e;
         }        
     };
-})
-
-/* service for dealing with custom form */
-.service('CustomFormService', function(){
-    
-    return {
-        getForProgramStage: function(programStage){
-            
-            var htmlCode = programStage.dataEntryForm ? programStage.dataEntryForm.htmlCode : null;  
-            
-            if(htmlCode){                
-            
-                var programStageDataElements = [];
-
-                angular.forEach(programStage.programStageDataElements, function(prStDe){
-                    programStageDataElements[prStDe.dataElement.id] = prStDe;
-                });
-
-                var inputRegex = /<input.*?\/>/g,
-                    match,
-                    inputFields = [];                
-
-                while (match = inputRegex.exec(htmlCode)) {                
-                    inputFields.push(match[0]);
-                }
-                
-                for(var i=0; i<inputFields.length; i++){                    
-                    var inputField = inputFields[i];                    
-                    var inputElement = $.parseHTML( inputField );
-                    var attributes = {};
-                                       
-                    $(inputElement[0].attributes).each(function() {
-                        attributes[this.nodeName] = this.value;                       
-                    });
-                    
-                    var deId = '', newInputField;     
-                    if(attributes.hasOwnProperty('id')){
-                        deId = attributes['id'].substring(4, attributes['id'].length-1).split("-")[1]; 
-                        
-                        //name needs to be unique so that it can be used for validation in angularjs
-                        if(attributes.hasOwnProperty('name')){
-                            attributes['name'] = deId;
-                        }
-                        
-                        var maxDate = programStageDataElements[deId].allowFutureDate ? '' : 0;
-                        
-                        //check data element type and generate corresponding angular input field
-                        if(programStageDataElements[deId].dataElement.type == "int"){
-                            newInputField = '<input type="number" ' +
-                                            this.getAttributesAsString(attributes) +
-                                            ' ng-model="currentEvent.' + deId + '"' +
-                                            ' ng-required="prStDes.' + deId + '.compulsory"> ' + 
-                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'int_required\'| translate}}</span>';                                     
-                        }
-                        if(programStageDataElements[deId].dataElement.type == "string"){
-                            if(programStageDataElements[deId].dataElement.optionSet){
-                                var optionSetId = programStageDataElements[deId].dataElement.optionSet.id;
-                        		newInputField = '<input type="text" ' +
-                                            this.getAttributesAsString(attributes) +
-                                            ' ng-model="currentEvent.' + deId + '" ' +
-                                            ' ng-disabled="currentEvent[uid] == \'uid\'" ' +
-                                            ' ng-required="prStDes.' + deId + '.compulsory"' +
-                                            ' typeahead="option.name as option.name for option in optionSets.'+optionSetId+'.options | filter:$viewValue | limitTo:20"' +
-                                            ' typeahead-editable="false" ' +
-                                            ' d2-typeahead-validation ' +
-                                            ' class="typeahead" ' +
-                                            ' placeholder="&#xf0d7;&nbsp;&nbsp;" ' +
-                                            ' typeahead-open-on-focus ng-required="prStDes.'+deId+'.compulsory"> ' +
-                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'option_required\'| translate}}</span>';
-                        	}
-                        	else{
-                        		newInputField = '<input type="text" ' +
-                                            this.getAttributesAsString(attributes) +
-                                            ' ng-model="currentEvent.' + deId + '" ' +
-                                            ' ng-disabled="currentEvent[uid] == \'uid\'" ' +
-                                            ' ng-required="prStDes.' + deId + '.compulsory"> ' +
-                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'string_required\'| translate}}</span>';                                     
-                        	}
-                        }
-                        if(programStageDataElements[deId].dataElement.type == "bool"){
-                            newInputField = '<select ' +
-                                            this.getAttributesAsString(attributes) +
-                                            ' ng-model="currentEvent.' + deId + '" ' +
-                                            ' ng-required="prStDes.' + deId + '.compulsory">' + 
-                                            '<option value="">{{\'please_select\'| translate}}</option>' +
-                                            '<option value="false">{{\'no\'| translate}}</option>' + 
-                                            '<option value="true">{{\'yes\'| translate}}</option>' +
-                                            '</select> ' +
-                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'bool_required\'| translate}}</span>';                                     
-                        }
-                        if(programStageDataElements[deId].dataElement.type == "date"){
-                            newInputField = '<input type="text" ' +
-                                            this.getAttributesAsString(attributes) +
-                                            ' ng-model="currentEvent.' + deId + '"' +
-                                            ' d2-date ' +
-                                            ' max-date="' + maxDate + '"' + '\'' +
-                                            ' ng-required="prStDes.' + deId + '.compulsory"> ' +
-                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'date_required\'| translate}}</span>'; 
-                        }
-                        if(programStageDataElements[deId].dataElement.type == "trueOnly"){
-                            newInputField = '<input type="checkbox" ' +
-                                            this.getAttributesAsString(attributes) +
-                                            ' ng-model="currentEvent.' + deId + '"' +
-                                            ' ng-required="prStDes.' + deId + '.compulsory"> ' +
-                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'required\'| translate}}</span>';
-                        }
-
-                        htmlCode = htmlCode.replace(inputField, newInputField);
-                    }
-                }
-                return htmlCode;                
-            }
-            return null;
-        },
-        getAttributesAsString: function(attributes){
-            if(attributes){
-                var attributesAsString = '';                
-                for(var prop in attributes){
-                    if(prop != 'value'){
-                        attributesAsString += prop + '="' + attributes[prop] + '" ';
-                    }
-                }
-                return attributesAsString;
-            }
-            return null;
-        }
-    };            
-})
-
-/* Modal service for user interaction */
-.service('ModalService', ['$modal', function($modal) {
-
-        var modalDefaults = {
-            backdrop: true,
-            keyboard: true,
-            modalFade: true,
-            templateUrl: 'views/modal.html'
-        };
-
-        var modalOptions = {
-            closeButtonText: 'Close',
-            actionButtonText: 'OK',
-            headerText: 'Proceed?',
-            bodyText: 'Perform this action?'
-        };
-
-        this.showModal = function(customModalDefaults, customModalOptions) {
-            if (!customModalDefaults)
-                customModalDefaults = {};
-            customModalDefaults.backdrop = 'static';
-            return this.show(customModalDefaults, customModalOptions);
-        };
-
-        this.show = function(customModalDefaults, customModalOptions) {
-            //Create temp objects to work with since we're in a singleton service
-            var tempModalDefaults = {};
-            var tempModalOptions = {};
-
-            //Map angular-ui modal custom defaults to modal defaults defined in service
-            angular.extend(tempModalDefaults, modalDefaults, customModalDefaults);
-
-            //Map modal.html $scope custom properties to defaults defined in service
-            angular.extend(tempModalOptions, modalOptions, customModalOptions);
-
-            if (!tempModalDefaults.controller) {
-                tempModalDefaults.controller = function($scope, $modalInstance) {
-                    $scope.modalOptions = tempModalOptions;
-                    $scope.modalOptions.ok = function(result) {
-                        $modalInstance.close(result);
-                    };
-                    $scope.modalOptions.close = function(result) {
-                        $modalInstance.dismiss('cancel');
-                    };
-                };
-            }
-
-            return $modal.open(tempModalDefaults).result;
-        };
-
-    }])
-
-/* Dialog service for user interaction */
-.service('DialogService', ['$modal', function($modal) {
-
-        var dialogDefaults = {
-            backdrop: true,
-            keyboard: true,
-            backdropClick: true,
-            modalFade: true,            
-            templateUrl: 'views/dialog.html'
-        };
-
-        var dialogOptions = {
-            closeButtonText: 'close',
-            actionButtonText: 'ok',
-            headerText: 'dhis2_tracker',
-            bodyText: 'Perform this action?'
-        };
-
-        this.showDialog = function(customDialogDefaults, customDialogOptions) {
-            if (!customDialogDefaults)
-                customDialogDefaults = {};
-            customDialogDefaults.backdropClick = false;
-            return this.show(customDialogDefaults, customDialogOptions);
-        };
-
-        this.show = function(customDialogDefaults, customDialogOptions) {
-            //Create temp objects to work with since we're in a singleton service
-            var tempDialogDefaults = {};
-            var tempDialogOptions = {};
-
-            //Map angular-ui modal custom defaults to modal defaults defined in service
-            angular.extend(tempDialogDefaults, dialogDefaults, customDialogDefaults);
-
-            //Map modal.html $scope custom properties to defaults defined in service
-            angular.extend(tempDialogOptions, dialogOptions, customDialogOptions);
-
-            if (!tempDialogDefaults.controller) {
-                tempDialogDefaults.controller = function($scope, $modalInstance) {
-                    $scope.dialogOptions = tempDialogOptions;
-                    $scope.dialogOptions.ok = function(result) {
-                        $modalInstance.close(result);
-                    };                           
-                };
-            }
-
-            return $modal.open(tempDialogDefaults).result;
-        };
-
-    }])
-
-/* Context menu for grid*/
-.service('ContextMenuSelectedItem', function(){
-    this.selectedItem = '';
-    
-    this.setSelectedItem = function(selectedItem){  
-        this.selectedItem = selectedItem;        
-    };
-    
-    this.getSelectedItem = function(){
-        return this.selectedItem;
-    };
-})
-
-/* Translation service - gets logged in user profile for the server, 
- * and apply user's locale to translation
- */
-.service('TranslationService', function($translate, storage){
-    
-    this.translate = function(){
-        var profile = storage.get('USER_PROFILE');        
-        if( profile && profile.settings ){        
-            $translate.uses(profile.settings.keyUiLocale);
-        }
-    };
-})
-
-/* Pagination service */
-.service('Paginator', function () {
-    this.page = 1;
-    this.pageSize = 50;
-    this.itemCount = 0;
-    this.pageCount = 0;
-    this.toolBarDisplay = 5;
-
-    this.setPage = function (page) {
-        if (page > this.getPageCount()) {
-            return;
-        }
-
-        this.page = page;
-    };
-    
-    this.getPage = function(){
-        return this.page;
-    };
-    
-    this.setPageSize = function(pageSize){
-      this.pageSize = pageSize;
-    };
-    
-    this.getPageSize = function(){
-        return this.pageSize;
-    };
-    
-    this.setItemCount = function(itemCount){
-      this.itemCount = itemCount;
-    };
-    
-    this.getItemCount = function(){
-        return this.itemCount;
-    };
-    
-    this.setPageCount = function(pageCount){
-        this.pageCount = pageCount;
-    };
-
-    this.getPageCount = function () {
-        return this.pageCount;
-    };
-
-    this.lowerLimit = function() { 
-        var pageCountLimitPerPageDiff = this.getPageCount() - this.toolBarDisplay;
-
-        if (pageCountLimitPerPageDiff < 0) { 
-            return 0; 
-        }
-
-        if (this.getPage() > pageCountLimitPerPageDiff + 1) { 
-            return pageCountLimitPerPageDiff; 
-        } 
-
-        var low = this.getPage() - (Math.ceil(this.toolBarDisplay/2) - 1); 
-
-        return Math.max(low, 0);
-    };
-})
-
-/*this is just a hack - there should be better way */
-.service('ValidDate', function(){    
-    var dateValidation;    
-    return {
-        get: function(dt) {
-            dateValidation = dt;
-        },
-        set: function() {    
-            return dateValidation;
-        }
-    };
-            
-})
-
-/* service for getting calendar setting */
-.service('CalendarService', function(storage, $rootScope){    
-
-    return {
-        getSetting: function() {
-            
-            var dhis2CalendarFormat = {keyDateFormat: 'yyyy-MM-dd', keyCalendar: 'gregorian', momentFormat: 'YYYY-MM-DD'};                
-            var storedFormat = storage.get('CALENDAR_SETTING');
-            if(angular.isObject(storedFormat) && storedFormat.keyDateFormat && storedFormat.keyCalendar){
-                if(storedFormat.keyCalendar === 'iso8601'){
-                    storedFormat.keyCalendar = 'gregorian';
-                }
-
-                if(storedFormat.keyDateFormat === 'dd-MM-yyyy'){
-                    dhis2CalendarFormat.momentFormat = 'DD-MM-YYYY';
-                }
-                
-                dhis2CalendarFormat.keyCalendar = storedFormat.keyCalendar;
-                dhis2CalendarFormat.keyDateFormat = storedFormat.keyDateFormat;
-            }
-            $rootScope.dhis2CalendarFormat = dhis2CalendarFormat;
-            return dhis2CalendarFormat;
-        }
-    };            
 });

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/eventList.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/eventList.html	2014-11-03 10:34:14 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/eventList.html	2014-12-03 17:48:48 +0000
@@ -46,8 +46,7 @@
                                     
                                     <!-- sort icon begins -->                                
                                     <span ng-hide="eventGridColumn.showFilter" class="bold" ng-click="sortEventGrid(eventGridColumn)">
-                                        <i ng-show="sortHeader == eventGridColumn.id && !reverse" class="fa fa-sort-desc"></i>
-                                        <i ng-show="sortHeader == eventGridColumn.id && reverse" class="fa fa-sort-asc"></i>
+                                        <span ng-class="{true: 'red'} [sortHeader == eventGridColumn.id]"><i class="fa fa-sort"></i></span>
                                         <span ng-if="eventGridColumn.id !== 'uid'">{{eventGridColumn.name}}</span>
                                         <span ng-if="eventGridColumn.id == 'uid'">{{eventGridColumn.name | translate}}</span>
                                     </span>
@@ -95,7 +94,7 @@
                         </tr>                        
                     </thead>
                     <tbody id="list">
-                        <tr ng-repeat="dhis2Event in dhis2Events | orderBy:sortHeader:reverse | gridFilter:filterText:filterTypes">
+                        <tr title="{{'click_for_action' | translate}}" ng-repeat="dhis2Event in dhis2Events | orderBy:sortHeader:reverse | gridFilter:filterText:filterTypes">
                            
                             <!-- Visible when event is not under editing -->
                             <td d2-context-menu 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/home.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/home.html	2014-11-26 13:37:32 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/views/home.html	2014-12-03 17:48:48 +0000
@@ -18,13 +18,17 @@
     <img id="ouwt_loader" src="../images/ajax-loader-bar.gif"/>
 </div>
 
-<div class="page" id="mainPage" ng-show="selectedOrgUnit">
-    <h3>
-        {{'event_capture'| translate}}
-    </h3>
-
+<div class="page" id="mainPage">    
+    <div ng-if="!selectedOrgUnit">
+        <img src="../images/ajax-loader-bar.gif" alt="{{'in_progress'| translate}}" ng-if="!selectedOrgUnit"/>
+    </div> 
+    
     <!-- selection begins-->
-    <div>
+    <div ng-show="selectedOrgUnit">
+        <h3>
+            {{'event_capture'| translate}}
+        </h3>
+        
         <table>
             <tr>
                 <td><label>{{'registering_unit'| translate}}</label></td>

=== added directory 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2'
=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/controllers.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/controllers.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/controllers.js	2014-12-03 17:48:48 +0000
@@ -0,0 +1,69 @@
+'use strict';
+
+/* Controllers */
+var d2Controllers = angular.module('d2Controllers', [])
+
+//Controller for header page
+.controller('HeaderController',
+        function($scope,                
+                DHIS2URL,
+                TranslationService) {
+
+    TranslationService.translate();
+    
+    $scope.home = function(){        
+        window.location = DHIS2URL;
+    };    
+})
+
+//Controller for column show/hide
+.controller('ColumnDisplayController', 
+    function($scope, 
+            $modalInstance, 
+            hiddenGridColumns,
+            gridColumns){
+    
+    $scope.eventGridColumns = gridColumns;
+    $scope.hiddenGridColumns = hiddenGridColumns;
+    
+    $scope.close = function () {
+      $modalInstance.close($scope.eventGridColumns);
+    };
+    
+    $scope.showHideColumns = function(gridColumn){
+       
+        if(gridColumn.show){                
+            $scope.hiddenGridColumns--;            
+        }
+        else{
+            $scope.hiddenGridColumns++;            
+        }      
+    };    
+})
+
+//controller for dealing with google map
+.controller('MapController',
+        function($scope, 
+                $modalInstance,
+                DHIS2URL,
+                TranslationService,
+                geoJsons,
+                location) {
+
+    TranslationService.translate();
+    
+    $scope.home = function(){        
+        window.location = DHIS2URL;
+    };
+    
+    $scope.location = location;
+    $scope.geoJsons = geoJsons;
+    
+    $scope.close = function () {
+        $modalInstance.close();
+    };
+    
+    $scope.captureCoordinate = function(){        
+        $modalInstance.close($scope.location);
+    };
+});
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/directives.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/directives.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/directives.js	2014-12-03 17:48:48 +0000
@@ -0,0 +1,411 @@
+'use strict';
+
+/* Directives */
+
+var d2Directives = angular.module('d2Directives', [])
+
+.directive('inputValidator', function() {
+    
+    return {
+        require: 'ngModel',
+        link: function (scope, element, attrs, ctrl) {  
+
+            ctrl.$parsers.push(function (value) {
+                return parseFloat(value || '');
+            });
+        }
+    };   
+})
+
+.directive('selectedOrgUnit', function($timeout, storage) {        
+
+    return {        
+        restrict: 'A',        
+        link: function(scope, element, attrs){
+            
+            //once ou tree is loaded, start meta-data download
+            $(function() {
+                dhis2.ou.store.open().done( function() {
+                    selection.load();
+                    $( "#orgUnitTree" ).one( "ouwtLoaded", function(event, ids, names) {
+                        console.log('Finished loading orgunit tree');                        
+                        downloadMetaData();
+                    });
+                });
+            });
+            
+            //listen to user selection, and inform angular         
+            selection.setListenerFunction( setSelectedOu, true );
+            
+            function setSelectedOu( ids, names ) {
+                var ou = {id: ids[0], name: names[0]};
+                $timeout(function() {
+                    scope.selectedOrgUnit = ou;
+                    scope.$apply();
+                });
+            }
+        }  
+    };
+})
+
+.directive('blurOrChange', function() {
+    
+    return function( scope, elem, attrs) {
+        elem.calendarsPicker({
+            onSelect: function() {
+                scope.$apply(attrs.blurOrChange);
+                $(this).change();                                        
+            }
+        }).change(function() {
+            scope.$apply(attrs.blurOrChange);
+        });
+    };
+})
+
+.directive('d2TypeaheadValidation', function() {
+    
+    return {
+        require: 'ngModel',
+        restrict: 'A',
+        link: function (scope, element, attrs, ctrl) {
+            element.bind('blur', function () {                
+                if(ctrl.$viewValue && !ctrl.$modelValue){
+                    ctrl.$setViewValue();
+                    ctrl.$render();
+                }                
+            });
+        }
+    };
+})
+
+.directive('typeaheadOpenOnFocus', function () {
+  return {
+        require: ['typeahead', 'ngModel'],
+        link: function (scope, element, attr, ctrls) {
+            element.bind('focus', function () {
+                ctrls[0].getMatchesAsync(ctrls[1].$viewValue);
+                
+                scope.$watch(attr.ngModel, function(value) {
+                    if(value === '' || angular.isUndefined(value)){
+                        ctrls[0].getMatchesAsync(ctrls[1].$viewValue);
+                    }                
+                });
+            });
+        }
+    };
+})
+
+.directive('d2PopOver', function($compile, $templateCache){
+    return {        
+        restrict: 'EA',
+        link: function(scope, element, attrs){
+            var content = $templateCache.get("note.html");
+            content = $compile(content)(scope);
+            var options = {
+                    content: content,
+                    placement: 'right',
+                    trigger: 'hover',
+                    html: true,
+                    title: scope.title               
+                };            
+            $(element).popover(options);
+        },
+        scope: {
+            content: '=',
+            title: '@details',
+            template: "@template"
+        }
+    };
+})
+
+.directive('serversidePaginator', function factory() {
+    return {
+        restrict: 'E',
+        controller: function ($scope, Paginator) {
+            $scope.paginator = Paginator;
+        },
+        templateUrl: 'views/serverside-pagination.html'
+    };
+})
+
+.directive('clientsidePaginator', function factory() {
+    return {
+        restrict: 'E',
+        controller: function ($scope, Paginator) {
+            $scope.paginator = Paginator;
+        },
+        templateUrl: 'views/clientside-pagination.html'
+    };
+})
+
+.directive('d2GoogleMap', function ($parse, $compile, storage) {
+    return {
+        restrict: 'E',
+        replace: true,
+        template: '<div></div>',
+        link: function(scope, element, attrs){
+            
+            //remove angular bootstrap ui modal draggable
+            $(".modal-content").draggable({ disabled: true });
+            
+            //get a default center
+            var latCenter = 12.31, lngCenter = 51.48;            
+            
+            //if there is any marker already - use it as center
+            if(angular.isObject(scope.location)){
+                if(scope.location.lat && scope.location.lng){
+                    latCenter = scope.location.lat;
+                    lngCenter = scope.location.lng;
+                }                
+            }
+            
+            //default map configurations 
+            var mapOptions = {
+                zoom: 3,
+                center: new google.maps.LatLng(latCenter, lngCenter),
+                mapTypeId: google.maps.MapTypeId.ROADMAP
+            },featureStyle = {
+                strokeWeight: 2,
+                strokeOpacity: 0.4,
+                fillOpacity: 0.4,
+                fillColor: 'green'
+            };
+            
+            var geojsons = $parse(attrs.geojsons)(scope);
+            var currentLayer = 0, currentGeojson = geojsons[0]; 
+            
+            var map = new google.maps.Map(document.getElementById(attrs.id), mapOptions);            
+            var currentGeojsonFeatures = map.data.addGeoJson(currentGeojson);
+            
+            var marker = new google.maps.Marker({
+                map: map
+            });
+            
+            if(angular.isObject(scope.location)){
+                if(scope.location.lat && scope.location.lng){                    
+                    addMarker({lat: scope.location.lat, lng: scope.location.lng});                    
+                }                
+            }
+            
+            function addMarker(loc){
+                var latLng = new google.maps.LatLng(loc.lat, loc.lng);
+                marker.setPosition(latLng);
+            }
+            
+            function centerMap(){
+                
+                if(currentGeojson && currentGeojson.features){
+                    var latLngBounds = new google.maps.LatLngBounds();
+                    angular.forEach(currentGeojson.features, function(feature){
+                        if(feature.geometry.type === 'MultiPolygon'){
+                            angular.forEach(feature.geometry.coordinates[0][0], function(coordinate){
+                                latLngBounds.extend(new google.maps.LatLng(coordinate[1],coordinate[0]));
+                            });
+                        }
+                        else if(feature.geometry.type === 'Point'){                        
+                            latLngBounds.extend(new google.maps.LatLng(feature.geometry.coordinates[1],feature.geometry.coordinates[0]));
+                        }
+                    });
+                    
+                    map.fitBounds(latLngBounds);
+                    map.panToBounds(latLngBounds);
+                }                
+            }
+            
+            function initializeMap(){                
+                google.maps.event.addListenerOnce(map, 'idle', function(){
+                    google.maps.event.trigger(map, 'resize');
+                    map.data.setStyle(featureStyle);
+                    centerMap();
+                });
+            }
+            
+            map.data.addListener('mouseover', function(e) {                
+                $("#polygon-label").text( e.feature.k.name );
+                map.data.revertStyle();
+                map.data.overrideStyle(e.feature, {fillOpacity: 0.8});
+            });
+            
+            map.data.addListener('mouseout', function() {                
+                $("#polygon-label").text( '' );
+                map.data.revertStyle();
+            });
+            
+            //drill-down based on polygons assigned to orgunits
+            map.data.addListener('rightclick', function(e){                
+                for (var i = 0; i < currentGeojsonFeatures.length; i++){
+                    map.data.remove(currentGeojsonFeatures[i]);
+                }
+                                
+                if(currentLayer >= geojsons.length-1){
+                    currentLayer = 0;
+                    currentGeojson = angular.copy(geojsons[currentLayer]);                    
+                }
+                else{
+                    currentLayer++;
+                    currentGeojson = angular.copy(geojsons[currentLayer]);
+                    currentGeojson.features = [];
+                    var selectedFeatures = [];
+                    angular.forEach(geojsons[currentLayer].features, function(feature){                    
+                        if(feature.properties.parent === e.feature.B){
+                            selectedFeatures.push(feature);
+                        }
+                    });
+                    
+                    if(selectedFeatures.length){
+                        currentGeojson.features = selectedFeatures;
+                    }                   
+                }                
+                currentGeojsonFeatures = map.data.addGeoJson(currentGeojson);
+                centerMap();         
+            });            
+            
+            //capturing coordinate from defined polygons
+            map.data.addListener('click', function(e) {                
+                scope.$apply(function(){
+                    addMarker({
+                       lat: e.latLng.lat(),
+                       lng: e.latLng.lng()
+                    });
+                    $parse(attrs.location).assign(scope.$parent, {lat: e.latLng.lat(), lng: e.latLng.lng()});                    
+                });                
+            });
+            
+            //capturing coordinate from anywhere in the map - incase no polygons are defined
+            google.maps.event.addListener(map, 'click', function(e){                
+                scope.$apply(function(){
+                    addMarker({
+                       lat: e.latLng.lat(),
+                       lng: e.latLng.lng()
+                    });
+                    $parse(attrs.location).assign(scope.$parent, {lat: e.latLng.lat(), lng: e.latLng.lng()});                    
+                });                
+            });
+            
+            initializeMap();
+        }
+    };
+})
+
+.directive('d2CustomForm', function($compile, $parse, CustomFormService) {
+    return{ 
+        restrict: 'E',
+        link: function(scope, elm, attrs){   
+            
+            var customFormType = attrs.customFormType;
+            var customFormObject = $parse(attrs.customFormObject)(scope);
+            
+            if(customFormType === 'PROGRAM_STAGE'){                
+                var customForm = CustomFormService.getForProgramStage(customFormObject);                
+                elm.html(customForm ? customForm : '');
+                $compile(elm.contents())(scope);                
+            }
+        }
+    };
+})
+
+.directive('d2ContextMenu', function(ContextMenuSelectedItem) {
+        
+    return {        
+        restrict: 'A',
+        link: function(scope, element, attrs){
+            var contextMenu = $("#contextMenu");                   
+            
+            element.click(function (e) {
+                var selectedItem = $.parseJSON(attrs.selectedItem);
+                ContextMenuSelectedItem.setSelectedItem(selectedItem);
+                
+                var menuHeight = contextMenu.height();
+                var menuWidth = contextMenu.width();
+                var winHeight = $(window).height();
+                var winWidth = $(window).width();
+
+                var pageX = e.pageX;
+                var pageY = e.pageY;
+
+                contextMenu.show();
+
+                if( (menuWidth + pageX) > winWidth ) {
+                  pageX -= menuWidth;
+                }
+
+                if( (menuHeight + pageY) > winHeight ) {
+                  pageY -= menuHeight;
+
+                  if( pageY < 0 ) {
+                      pageY = e.pageY;
+                  }
+                }
+                
+                contextMenu.css({
+                    left: pageX,
+                    top: pageY
+                });
+
+                return false;
+            });
+            
+            contextMenu.on("click", "a", function () {                    
+                contextMenu.hide();
+            });
+
+            $(document).click(function () {                                        
+                contextMenu.hide();
+            });
+        }     
+    };
+})
+
+.directive('d2Date', function(DateUtils, CalendarService, storage, $parse) {
+    return {
+        restrict: 'A',
+        require: 'ngModel',        
+        link: function(scope, element, attrs, ctrl) {    
+            
+            var calendarSetting = CalendarService.getSetting();            
+            var dateFormat = 'yyyy-mm-dd';
+            if(calendarSetting.keyDateFormat === 'dd-MM-yyyy'){
+                dateFormat = 'dd-mm-yyyy';
+            }            
+            
+            var minDate = $parse(attrs.minDate)(scope), 
+                maxDate = $parse(attrs.maxDate)(scope),
+                calendar = $.calendars.instance(calendarSetting.keyCalendar);
+            
+            element.calendarsPicker({
+                changeMonth: true,
+                dateFormat: dateFormat,
+                yearRange: '-120:+30',
+                minDate: minDate,
+                maxDate: maxDate,
+                calendar: calendar,
+                duration: "fast",
+                showAnim: "",
+                renderer: $.calendars.picker.themeRollerRenderer,
+                onSelect: function(date) {
+                    //scope.date = date;
+                    ctrl.$setViewValue(date);
+                    $(this).change();                    
+                    scope.$apply();
+                }
+            })
+            .change(function() {                
+                var rawDate = this.value;
+                var convertedDate = DateUtils.format(this.value);
+
+                if(rawDate != convertedDate){
+                    scope.invalidDate = true;
+                    ctrl.$setViewValue(this.value);                                   
+                    ctrl.$setValidity('foo', false);                    
+                    scope.$apply();     
+                }
+                else{
+                    scope.invalidDate = false;
+                    ctrl.$setViewValue(this.value);                                   
+                    ctrl.$setValidity('foo', true);                    
+                    scope.$apply();     
+                }
+            });    
+        }      
+    };   
+});
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/filters.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/filters.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/filters.js	2014-12-03 17:48:48 +0000
@@ -0,0 +1,96 @@
+'use strict';
+
+/* Filters */
+
+var d2Filters = angular.module('d2Filters', [])
+
+.filter('gridFilter', function($filter){    
+    
+    return function(data, filters, filterTypes){
+
+        if(!data ){
+            return;
+        }
+        
+        if(!filters){
+            return data;
+        }        
+        else{            
+            
+            var dateFilter = {}, 
+                textFilter = {}, 
+                numberFilter = {},
+                filteredData = data;
+            
+            for(var key in filters){
+                
+                if(filterTypes[key] === 'date'){
+                    if(filters[key].start || filters[key].end){
+                        dateFilter[key] = filters[key];
+                    }
+                }
+                else if(filterTypes[key] === 'int'){
+                    if(filters[key].start || filters[key].end){
+                        numberFilter[key] = filters[key];
+                    }
+                }
+                else{
+                    textFilter[key] = filters[key];
+                }
+            }
+            
+            filteredData = $filter('filter')(filteredData, textFilter); 
+            filteredData = $filter('filter')(filteredData, dateFilter, dateComparator);            
+            filteredData = $filter('filter')(filteredData, numberFilter, numberComparator);
+                        
+            return filteredData;
+        } 
+    }; 
+    
+    function dateComparator(data,filter){
+        var start = moment(filter.start, 'YYYY-MM-DD');
+        var end = moment(filter.end, 'YYYY-MM-DD');  
+        var date = moment(data, 'YYYY-MM-DD'); 
+        
+        if(filter.start && filter.end){
+            return ( Date.parse(date) <= Date.parse(end) ) && (Date.parse(date) >= Date.parse(start));
+        }        
+        return ( Date.parse(date) <= Date.parse(end) ) || (Date.parse(date) >= Date.parse(start));
+    }
+    
+    function numberComparator(data,filter){
+        var start = filter.start;
+        var end = filter.end;
+        
+        if(filter.start && filter.end){
+            return ( data <= end ) && ( data >= start );
+        }        
+        return ( data <= end ) || ( data >= start );
+    }
+})
+
+.filter('paginate', function(Paginator) {
+    return function(input, rowsPerPage) {
+        if (!input) {
+            return input;
+        }
+
+        if (rowsPerPage) {
+            Paginator.rowsPerPage = rowsPerPage;
+        }       
+        
+        Paginator.itemCount = input.length;
+
+        return input.slice(parseInt(Paginator.page * Paginator.rowsPerPage), parseInt((Paginator.page + 1) * Paginator.rowsPerPage + 1) - 1);
+    };
+})
+
+.filter('forLoop', function() {
+    return function(input, start, end) {
+        input = new Array(end - start);
+        for (var i = 0; start < end; start++, i++) {
+            input[i] = start;
+        }
+        return input;
+    };
+});
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/providers.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/providers.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/providers.js	2014-12-03 17:48:48 +0000
@@ -0,0 +1,77 @@
+'use strict';
+
+/* Providers */
+var d2Providers = angular.module('d2Providers', [])
+
+.provider('d2I18n', function ($translateProvider) {
+    
+    var getTranslations = function(locale){
+        var translation = {locale: locale};
+        var def = $.Deferred();
+
+        $.ajax({
+            url: 'i18n/i18n_app_' + locale + '.properties' ,
+            type: 'GET'
+        }).done(function(response) {
+            translation.keys = response;
+            localStorage['LOCALE'] = locale;
+            def.resolve(translation);
+        }).fail(function(){
+            $.ajax({
+                url: 'i18n/i18n_app_en.properties' ,
+                type: 'GET'
+            }).done(function(response) {  
+                translation= {locale: 'en', keys: response};
+                localStorage['LOCALE'] = 'en';
+                def.resolve(translation);
+            });                
+        });
+
+        return def.promise();
+    };
+    return {
+        getLocale: function(){
+            var locale = '';
+            var def = $.Deferred();
+            
+            $.ajax({
+                url: '../api/me/profile.json',
+                type: 'GET'
+            }).done( function(response) {
+                localStorage['USER_PROFILE'] = JSON.stringify(response);
+                if(response && response.settings && response.settings.keyUiLocale){
+                    locale = response.settings.keyUiLocale;
+                }
+                else{
+                    locale = 'en';
+                }
+            }).always(function(){                
+                getTranslations(locale).then(function(response){
+                    def.resolve(response);
+                });
+            });
+
+            return def.promise();
+        },
+        initialize: function () {
+            
+            var userProfile = localStorage['USER_PROFILE'];
+            if(userProfile){
+                userProfile = JSON.parse(userProfile);                
+            }
+            
+            if(userProfile && userProfile.settings && userProfile.settings.keyUiLocale){
+                getTranslations(userProfile.settings.keyUiLocale).done(function(response){
+                    $translateProvider.translations(response.locale, dhis2.util.parseJavaProperties(response.keys));
+                });
+            }
+            else{
+                this.getLocale().done(function(response){
+                    $translateProvider.translations(response.locale, dhis2.util.parseJavaProperties(response.keys));                    
+                });
+            }
+        },
+        $get: function () {
+        }
+    };
+});
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/services.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/services.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/angular/plugins/dhis2/services.js	2014-12-03 17:48:48 +0000
@@ -0,0 +1,436 @@
+/* Pagination service */
+var d2Services = angular.module('d2Services', ['ngResource'])
+
+/* Factory to fetch geojsons */
+.factory('GeoJsonFactory', function($q, $rootScope, StorageService) { 
+    return {
+        getAll: function(){
+
+            var def = $q.defer();
+            
+            StorageService.currentStore.open().done(function(){
+                StorageService.currentStore.getAll('geoJsons').done(function(geoJsons){
+                    $rootScope.$apply(function(){
+                        def.resolve(geoJsons);
+                    });                    
+                });
+            });
+            
+            return def.promise;            
+        },
+        get: function(level){
+            
+            var def = $q.defer();
+            
+            StorageService.currentStore.open().done(function(){
+                StorageService.currentStore.get('geoJsons', level).done(function(geoJson){                    
+                    $rootScope.$apply(function(){
+                        def.resolve(geoJson);
+                    });
+                });
+            });                        
+            return def.promise;            
+        }
+    };
+})
+
+/* Factory to fetch optioSets */
+.factory('OptionSetService', function($q, $rootScope, StorageService) { 
+    return {
+        getAll: function(){
+            
+            var def = $q.defer();
+            
+            StorageService.currentStore.open().done(function(){
+                StorageService.currentStore.getAll('optionSets').done(function(optionSets){
+                    $rootScope.$apply(function(){
+                        def.resolve(optionSets);
+                    });                    
+                });
+            });            
+            
+            return def.promise;            
+        },
+        get: function(uid){
+            
+            var def = $q.defer();
+            
+            StorageService.currentStore.open().done(function(){
+                StorageService.currentStore.get('optionSets', uid).done(function(optionSet){                    
+                    $rootScope.$apply(function(){
+                        def.resolve(optionSet);
+                    });
+                });
+            });                        
+            return def.promise;            
+        },
+        getNameOrCode: function(options, key){
+            var val = key;            
+
+            if(options){
+                for(var i=0; i<options.length; i++){
+                    if( key === options[i].name){
+                        val = options[i].code;
+                        break;
+                    }
+                    if( key === options[i].code){
+                        val = options[i].name;
+                        break;
+                    }
+                }
+            }            
+            return val;
+        }
+    };
+})
+
+/* Factory for loading external data */
+.factory('ExternalDataFactory', function($http) {
+
+    return {        
+        get: function(fileName) {
+            var promise = $http.get( fileName ).then(function(response){
+                return response.data;
+            });            
+            return promise;
+        }
+    };
+})
+
+/* Translation service - gets logged in user profile for the server, 
+ * and apply user's locale to translation
+ */
+.service('TranslationService', function($translate, storage){
+    
+    this.translate = function(){
+        $translate.uses(storage.get('USER_PROFILE'));
+    };
+})
+
+/* service for getting calendar setting */
+.service('CalendarService', function(storage, $rootScope){    
+
+    return {
+        getSetting: function() {
+            
+            var dhis2CalendarFormat = {keyDateFormat: 'yyyy-MM-dd', keyCalendar: 'gregorian', momentFormat: 'YYYY-MM-DD'};                
+            var storedFormat = storage.get('CALENDAR_SETTING');
+            if(angular.isObject(storedFormat) && storedFormat.keyDateFormat && storedFormat.keyCalendar){
+                if(storedFormat.keyCalendar === 'iso8601'){
+                    storedFormat.keyCalendar = 'gregorian';
+                }
+
+                if(storedFormat.keyDateFormat === 'dd-MM-yyyy'){
+                    dhis2CalendarFormat.momentFormat = 'DD-MM-YYYY';
+                }
+                
+                dhis2CalendarFormat.keyCalendar = storedFormat.keyCalendar;
+                dhis2CalendarFormat.keyDateFormat = storedFormat.keyDateFormat;
+            }
+            $rootScope.dhis2CalendarFormat = dhis2CalendarFormat;
+            return dhis2CalendarFormat;
+        }
+    };            
+})
+
+/* service for dealing with custom form */
+.service('CustomFormService', function(){
+    
+    return {
+        getForProgramStage: function(programStage){
+            
+            var htmlCode = programStage.dataEntryForm ? programStage.dataEntryForm.htmlCode : null;  
+            
+            if(htmlCode){                
+            
+                var programStageDataElements = [];
+
+                angular.forEach(programStage.programStageDataElements, function(prStDe){
+                    programStageDataElements[prStDe.dataElement.id] = prStDe;
+                });
+
+                var inputRegex = /<input.*?\/>/g,
+                    match,
+                    inputFields = [];                
+
+                while (match = inputRegex.exec(htmlCode)) {                
+                    inputFields.push(match[0]);
+                }
+                
+                for(var i=0; i<inputFields.length; i++){                    
+                    var inputField = inputFields[i];                    
+                    var inputElement = $.parseHTML( inputField );
+                    var attributes = {};
+                                       
+                    $(inputElement[0].attributes).each(function() {
+                        attributes[this.nodeName] = this.value;                       
+                    });
+                    
+                    var deId = '', newInputField;     
+                    if(attributes.hasOwnProperty('id')){
+                        deId = attributes['id'].substring(4, attributes['id'].length-1).split("-")[1]; 
+                        
+                        //name needs to be unique so that it can be used for validation in angularjs
+                        if(attributes.hasOwnProperty('name')){
+                            attributes['name'] = deId;
+                        }
+                        
+                        var maxDate = programStageDataElements[deId].allowFutureDate ? '' : 0;
+                        
+                        //check data element type and generate corresponding angular input field
+                        if(programStageDataElements[deId].dataElement.type == "int"){
+                            newInputField = '<input type="number" ' +
+                                            this.getAttributesAsString(attributes) +
+                                            ' ng-model="currentEvent.' + deId + '"' +
+                                            ' ng-required="prStDes.' + deId + '.compulsory"> ' + 
+                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'int_required\'| translate}}</span>';                                     
+                        }
+                        if(programStageDataElements[deId].dataElement.type == "string"){
+                            if(programStageDataElements[deId].dataElement.optionSet){
+                                var optionSetId = programStageDataElements[deId].dataElement.optionSet.id;
+                        		newInputField = '<input type="text" ' +
+                                            this.getAttributesAsString(attributes) +
+                                            ' ng-model="currentEvent.' + deId + '" ' +
+                                            ' ng-disabled="currentEvent[uid] == \'uid\'" ' +
+                                            ' ng-required="prStDes.' + deId + '.compulsory"' +
+                                            ' typeahead="option.name as option.name for option in optionSets.'+optionSetId+'.options | filter:$viewValue | limitTo:20"' +
+                                            ' typeahead-editable="false" ' +
+                                            ' d2-typeahead-validation ' +
+                                            ' class="typeahead" ' +
+                                            ' placeholder="&#xf0d7;&nbsp;&nbsp;" ' +
+                                            ' typeahead-open-on-focus ng-required="prStDes.'+deId+'.compulsory"> ' +
+                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'option_required\'| translate}}</span>';
+                        	}
+                        	else{
+                        		newInputField = '<input type="text" ' +
+                                            this.getAttributesAsString(attributes) +
+                                            ' ng-model="currentEvent.' + deId + '" ' +
+                                            ' ng-disabled="currentEvent[uid] == \'uid\'" ' +
+                                            ' ng-required="prStDes.' + deId + '.compulsory"> ' +
+                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'string_required\'| translate}}</span>';                                     
+                        	}
+                        }
+                        if(programStageDataElements[deId].dataElement.type == "bool"){
+                            newInputField = '<select ' +
+                                            this.getAttributesAsString(attributes) +
+                                            ' ng-model="currentEvent.' + deId + '" ' +
+                                            ' ng-required="prStDes.' + deId + '.compulsory">' + 
+                                            '<option value="">{{\'please_select\'| translate}}</option>' +
+                                            '<option value="false">{{\'no\'| translate}}</option>' + 
+                                            '<option value="true">{{\'yes\'| translate}}</option>' +
+                                            '</select> ' +
+                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'bool_required\'| translate}}</span>';                                     
+                        }
+                        if(programStageDataElements[deId].dataElement.type == "date"){
+                            newInputField = '<input type="text" ' +
+                                            this.getAttributesAsString(attributes) +
+                                            ' ng-model="currentEvent.' + deId + '"' +
+                                            ' d2-date ' +
+                                            ' max-date="' + maxDate + '"' + '\'' +
+                                            ' ng-required="prStDes.' + deId + '.compulsory"> ' +
+                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'date_required\'| translate}}</span>'; 
+                        }
+                        if(programStageDataElements[deId].dataElement.type == "trueOnly"){
+                            newInputField = '<input type="checkbox" ' +
+                                            this.getAttributesAsString(attributes) +
+                                            ' ng-model="currentEvent.' + deId + '"' +
+                                            ' ng-required="prStDes.' + deId + '.compulsory"> ' +
+                                            '<span ng-show="outerForm.submitted && outerForm.'+ deId +'.$invalid" class="required">{{\'required\'| translate}}</span>';
+                        }
+
+                        htmlCode = htmlCode.replace(inputField, newInputField);
+                    }
+                }
+                return htmlCode;                
+            }
+            return null;
+        },
+        getAttributesAsString: function(attributes){
+            if(attributes){
+                var attributesAsString = '';                
+                for(var prop in attributes){
+                    if(prop != 'value'){
+                        attributesAsString += prop + '="' + attributes[prop] + '" ';
+                    }
+                }
+                return attributesAsString;
+            }
+            return null;
+        }
+    };            
+})
+
+/* Context menu for grid*/
+.service('ContextMenuSelectedItem', function(){
+    this.selectedItem = '';
+    
+    this.setSelectedItem = function(selectedItem){  
+        this.selectedItem = selectedItem;        
+    };
+    
+    this.getSelectedItem = function(){
+        return this.selectedItem;
+    };
+})
+
+/* Modal service for user interaction */
+.service('ModalService', ['$modal', function($modal) {
+
+    var modalDefaults = {
+        backdrop: true,
+        keyboard: true,
+        modalFade: true,
+        templateUrl: 'views/modal.html'
+    };
+
+    var modalOptions = {
+        closeButtonText: 'Close',
+        actionButtonText: 'OK',
+        headerText: 'Proceed?',
+        bodyText: 'Perform this action?'
+    };
+
+    this.showModal = function(customModalDefaults, customModalOptions) {
+        if (!customModalDefaults)
+            customModalDefaults = {};
+        customModalDefaults.backdrop = 'static';
+        return this.show(customModalDefaults, customModalOptions);
+    };
+
+    this.show = function(customModalDefaults, customModalOptions) {
+        //Create temp objects to work with since we're in a singleton service
+        var tempModalDefaults = {};
+        var tempModalOptions = {};
+
+        //Map angular-ui modal custom defaults to modal defaults defined in service
+        angular.extend(tempModalDefaults, modalDefaults, customModalDefaults);
+
+        //Map modal.html $scope custom properties to defaults defined in service
+        angular.extend(tempModalOptions, modalOptions, customModalOptions);
+
+        if (!tempModalDefaults.controller) {
+            tempModalDefaults.controller = function($scope, $modalInstance) {
+                $scope.modalOptions = tempModalOptions;
+                $scope.modalOptions.ok = function(result) {
+                    $modalInstance.close(result);
+                };
+                $scope.modalOptions.close = function(result) {
+                    $modalInstance.dismiss('cancel');
+                };
+            };
+        }
+
+        return $modal.open(tempModalDefaults).result;
+    };
+
+}])
+
+/* Dialog service for user interaction */
+.service('DialogService', ['$modal', function($modal) {
+
+    var dialogDefaults = {
+        backdrop: true,
+        keyboard: true,
+        backdropClick: true,
+        modalFade: true,            
+        templateUrl: 'views/dialog.html'
+    };
+
+    var dialogOptions = {
+        closeButtonText: 'close',
+        actionButtonText: 'ok',
+        headerText: 'dhis2_tracker',
+        bodyText: 'Perform this action?'
+    };
+
+    this.showDialog = function(customDialogDefaults, customDialogOptions) {
+        if (!customDialogDefaults)
+            customDialogDefaults = {};
+        customDialogDefaults.backdropClick = false;
+        return this.show(customDialogDefaults, customDialogOptions);
+    };
+
+    this.show = function(customDialogDefaults, customDialogOptions) {
+        //Create temp objects to work with since we're in a singleton service
+        var tempDialogDefaults = {};
+        var tempDialogOptions = {};
+
+        //Map angular-ui modal custom defaults to modal defaults defined in service
+        angular.extend(tempDialogDefaults, dialogDefaults, customDialogDefaults);
+
+        //Map modal.html $scope custom properties to defaults defined in service
+        angular.extend(tempDialogOptions, dialogOptions, customDialogOptions);
+
+        if (!tempDialogDefaults.controller) {
+            tempDialogDefaults.controller = function($scope, $modalInstance) {
+                $scope.dialogOptions = tempDialogOptions;
+                $scope.dialogOptions.ok = function(result) {
+                    $modalInstance.close(result);
+                };                           
+            };
+        }
+
+        return $modal.open(tempDialogDefaults).result;
+    };
+
+}])
+
+.service('Paginator', function () {
+    this.page = 1;
+    this.pageSize = 50;
+    this.itemCount = 0;
+    this.pageCount = 0;
+    this.toolBarDisplay = 5;
+
+    this.setPage = function (page) {
+        if (page > this.getPageCount()) {
+            return;
+        }
+
+        this.page = page;
+    };
+    
+    this.getPage = function(){
+        return this.page;
+    };
+    
+    this.setPageSize = function(pageSize){
+      this.pageSize = pageSize;
+    };
+    
+    this.getPageSize = function(){
+        return this.pageSize;
+    };
+    
+    this.setItemCount = function(itemCount){
+      this.itemCount = itemCount;
+    };
+    
+    this.getItemCount = function(){
+        return this.itemCount;
+    };
+    
+    this.setPageCount = function(pageCount){
+        this.pageCount = pageCount;
+    };
+
+    this.getPageCount = function () {
+        return this.pageCount;
+    };
+
+    this.lowerLimit = function() { 
+        var pageCountLimitPerPageDiff = this.getPageCount() - this.toolBarDisplay;
+
+        if (pageCountLimitPerPageDiff < 0) { 
+            return 0; 
+        }
+
+        if (this.getPage() > pageCountLimitPerPageDiff + 1) { 
+            return pageCountLimitPerPageDiff; 
+        } 
+
+        var low = this.getPage() - (Math.ceil(this.toolBarDisplay/2) - 1); 
+
+        return Math.max(low, 0);
+    };
+});

=== added file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/appcache/CacheManifest.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/appcache/CacheManifest.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/appcache/CacheManifest.java	2014-12-03 17:48:48 +0000
@@ -0,0 +1,201 @@
+package org.hisp.dhis.appcache;
+
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletContext;
+
+import org.apache.struts2.ServletActionContext;
+import org.hisp.dhis.user.UserSettingService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
+ *
+ */
+public class CacheManifest
+    implements Action
+{
+
+    @Autowired
+    private UserSettingService userSettingService;
+
+    private String appPath;
+
+    public void setAppPath( String appPath )
+    {
+        this.appPath = appPath;
+    }
+
+    private String i18nPath;
+
+    public void setI18nPath( String i18nPath )
+    {
+        this.i18nPath = i18nPath;
+    }
+
+    private String appCache;
+
+    public void setAppCache( String appCache )
+    {
+        this.appCache = appCache;
+    }
+
+    private InputStream inputStream;
+
+    public InputStream getInputStream()
+    {
+        return inputStream;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    @Override
+    public String execute()
+    {
+        File cacheManifest = null;
+        File i18nFolder = null;
+        StringBuffer stringBuffer = null;
+
+        String locale = userSettingService.getUserSetting( UserSettingService.KEY_UI_LOCALE ).toString();
+
+        String defaultTranslationFile = "i18n_app.properties";;
+        String translationFile = "";
+        if ( locale.equalsIgnoreCase( "en" ) )
+        {
+            System.out.println( "EN" );
+            translationFile = defaultTranslationFile;
+        }
+        else
+        {
+            System.out.println( locale );
+            translationFile = "i18n_app_" + locale + ".properties";
+        }
+
+        if ( appPath != null && appCache != null && i18nPath != null )
+        {
+
+            ServletContext servletContext = ServletActionContext.getServletContext();
+            String fullPath = servletContext.getRealPath( appPath );
+
+            File folder = new File( fullPath );
+            File[] files = folder.listFiles();
+
+            for ( int i = 0; i < files.length; i++ )
+            {
+                if ( files[i].isFile() && files[i].getName().equalsIgnoreCase( appCache ) )
+                {
+                    cacheManifest = new File( files[i].getAbsolutePath() );
+                }
+
+                if ( files[i].isDirectory() && files[i].getName().equalsIgnoreCase( i18nPath ) )
+                {
+                    i18nFolder = new File( files[i].getAbsolutePath() );
+                }
+            }
+        }
+
+        if ( cacheManifest != null )
+        {
+            try
+            {
+                FileReader fileReader = new FileReader( cacheManifest );
+                BufferedReader bufferedReader = new BufferedReader( fileReader );
+                stringBuffer = new StringBuffer();
+                String line;
+                while ( (line = bufferedReader.readLine()) != null )
+                {
+                    stringBuffer.append( line );
+                    stringBuffer.append( "\n" );
+                }
+                fileReader.close();
+
+                if ( i18nFolder != null )
+                {
+                    File[] i18nfiles = i18nFolder.listFiles();
+                    Boolean fileExists = false;
+                    for ( int i = 0; i < i18nfiles.length; i++ )
+                    {
+                        if ( i18nfiles[i].isFile() && i18nfiles[i].getName().equalsIgnoreCase( translationFile ) )
+                        {
+                            System.out.println("tx file");
+                            fileExists = true;
+                            stringBuffer.append( i18nPath + "/" + translationFile );
+                            stringBuffer.append( "\n" );
+                            break;
+                        }
+                    }
+
+                    if ( !fileExists )
+                    {
+                        System.out.println("No tx file");
+                        stringBuffer.append( i18nPath + "/" + defaultTranslationFile );
+                        stringBuffer.append( "\n" );
+                        
+                    }
+                    stringBuffer.append( "NETWORK:" );
+                    stringBuffer.append( "\n" );
+                    stringBuffer.append( "*" );
+
+                    System.out.println( "The manifest:  " + stringBuffer.toString() );
+                    inputStream = new ByteArrayInputStream( stringBuffer.toString().getBytes() );
+
+                    return SUCCESS;
+                }
+
+            }
+            catch ( IOException e )
+            {
+                e.printStackTrace();
+            }
+
+        }
+
+        stringBuffer = new StringBuffer();
+        stringBuffer.append( "CACHE MANIFEST" );
+        stringBuffer.append( "\n" );
+        stringBuffer.append( "NETWORK:" );
+        stringBuffer.append( "\n" );
+        stringBuffer.append( "*" );
+
+        inputStream = new ByteArrayInputStream( stringBuffer.toString().getBytes() );
+
+        return SUCCESS;
+    }
+}
\ No newline at end of file