← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17626: New system setting: Infrastructural indicators + GIS ou left click shows infr data + context menu...

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 17626 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Sun 2014-11-30 19:39:25 +0100
message:
  New system setting: Infrastructural indicators + GIS ou left click shows infr data + context menu moved to right click.
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/configuration/Configuration.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/configuration/hibernate/Configuration.hbm.xml
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/ConfigurationController.java
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/i18n/i18n_app.properties
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/app.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/core.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/styles/style.css
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/GetGeneralSettingsAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/SetGeneralSettingsAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/resources/org/hisp/dhis/settings/i18n_module.properties
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/webapp/dhis-web-maintenance-settings/systemGeneralSettings.vm


--
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-api/src/main/java/org/hisp/dhis/configuration/Configuration.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/configuration/Configuration.java	2014-08-08 09:41:58 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/configuration/Configuration.java	2014-11-26 12:22:29 +0000
@@ -30,6 +30,7 @@
 
 import java.io.Serializable;
 
+import org.hisp.dhis.indicator.IndicatorGroup;
 import org.hisp.dhis.dataelement.DataElementGroup;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
@@ -63,6 +64,8 @@
     
     private OrganisationUnitLevel offlineOrganisationUnitLevel;
 
+    private IndicatorGroup infrastructuralIndicators;
+
     private DataElementGroup infrastructuralDataElements;
     
     private PeriodType infrastructuralPeriodType;
@@ -153,6 +156,16 @@
         return offlineOrganisationUnitLevel;
     }
 
+    public IndicatorGroup getInfrastructuralIndicators()
+    {
+        return infrastructuralIndicators;
+    }
+
+    public void setInfrastructuralIndicators( IndicatorGroup infrastructuralIndicators )
+    {
+        this.infrastructuralIndicators = infrastructuralIndicators;
+    }
+
     public DataElementGroup getInfrastructuralDataElements()
     {
         return infrastructuralDataElements;

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/configuration/hibernate/Configuration.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/configuration/hibernate/Configuration.hbm.xml	2014-08-08 09:41:58 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/configuration/hibernate/Configuration.hbm.xml	2014-11-26 12:22:29 +0000
@@ -20,6 +20,9 @@
     <many-to-one name="offlineOrganisationUnitLevel" class="org.hisp.dhis.organisationunit.OrganisationUnitLevel"
         column="offlineorgunitlevelid" foreign-key="fk_configuration_offline_orgunit_level" />
 
+    <many-to-one name="infrastructuralIndicators" class="org.hisp.dhis.indicator.IndicatorGroup"
+        column="infrastructuralindicatorsid" foreign-key="fk_configuration_infrastructural_indicators" />
+
     <many-to-one name="infrastructuralDataElements" class="org.hisp.dhis.dataelement.DataElementGroup"
         column="infrastructuraldataelementsid" foreign-key="fk_configuration_infrastructural_dataelements" />
 

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/ConfigurationController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/ConfigurationController.java	2014-11-11 12:51:06 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/ConfigurationController.java	2014-11-26 12:22:29 +0000
@@ -66,6 +66,12 @@
         return setModel( model, configurationService.getConfiguration().getOfflineOrganisationUnitLevel() );
     }
 
+    @RequestMapping( value = "/infrastructuralIndicators", method = RequestMethod.GET )
+    private String getInfrastructuralIndicators( Model model, HttpServletRequest request )
+    {
+        return setModel( model, configurationService.getConfiguration().getInfrastructuralIndicators() );
+    }
+
     @RequestMapping( value = "/infrastructuralDataElements", method = RequestMethod.GET )
     private String getInfrastructuralDataElements( Model model, HttpServletRequest request )
     {

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/i18n/i18n_app.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/i18n/i18n_app.properties	2014-11-17 15:42:17 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/i18n/i18n_app.properties	2014-11-26 16:42:41 +0000
@@ -403,7 +403,7 @@
 relative=Relative
 reporting_rates=Reporting rates
 event_layer=Event layer
-coordinate=Coordinate
+coordinates=Coordinates
 go_to_pivot_tables=Go to pivot tables
 open_this_map_as_table=Open this map as table
 open_last_table=Open last table

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/app.js	2014-11-20 14:39:52 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/app.js	2014-11-28 14:03:54 +0000
@@ -5331,7 +5331,11 @@
 		// Stores
 
 		infrastructuralDataElementValuesStore = Ext.create('Ext.data.Store', {
-			fields: ['name', 'value']
+			fields: ['name', 'value'],
+            sorters: [{
+                property: 'name',
+                direction: 'ASC'
+            }]
 		});
 
 		// Components
@@ -6114,7 +6118,11 @@
 		// Stores
 
 		infrastructuralDataElementValuesStore = Ext.create('Ext.data.Store', {
-			fields: ['name', 'value']
+			fields: ['name', 'value'],
+            sorters: [{
+                property: 'name',
+                direction: 'ASC'
+            }]
 		});
 
 		// Components
@@ -7021,7 +7029,11 @@
 		});
 
 		infrastructuralDataElementValuesStore = Ext.create('Ext.data.Store', {
-			fields: ['name', 'value']
+			fields: ['name', 'value'],
+            sorters: [{
+                property: 'name',
+                direction: 'ASC'
+            }]
 		});
 
 		legendsByLegendSetStore = Ext.create('Ext.data.Store', {
@@ -9020,7 +9032,7 @@
             listeners: {
                 resize: function() {
                     var width = this.getWidth();
-                    
+
                     if (width < 800 && this.fullSize) {
                         this.toggleCmp(false);
                         this.fullSize = false;
@@ -9500,14 +9512,49 @@
                                             }
                                         });
 
+                                        // infrastructural indicator group
+                                        requests.push({
+                                            url: init.contextPath + '/api/configuration/infrastructuralIndicators.json',
+                                            success: function(r) {
+                                                var obj = Ext.decode(r.responseText);
+                                                init.systemSettings.infrastructuralIndicatorGroup = Ext.isObject(obj) ? obj : null;
+
+                                                if (!Ext.isObject(obj)) {
+                                                    Ext.Ajax.request({
+                                                        url: init.contextPath + '/api/indicatorGroups.json?fields=id,name,indicators[id,name]&pageSize=1',
+                                                        success: function(r) {
+                                                            r = Ext.decode(r.responseText);
+                                                            init.systemSettings.infrastructuralIndicatorGroup = r.indicatorGroups ? r.indicatorGroups[0] : null;
+                                                        },
+                                                        callback: fn
+                                                    });
+                                                }
+                                                else {
+                                                    fn();
+                                                }
+                                            }
+                                        });
+
                                         // infrastructural data element group
                                         requests.push({
                                             url: init.contextPath + '/api/configuration/infrastructuralDataElements.json',
                                             success: function(r) {
                                                 var obj = Ext.decode(r.responseText);
-
                                                 init.systemSettings.infrastructuralDataElementGroup = Ext.isObject(obj) ? obj : null;
-                                                fn();
+
+                                                if (!Ext.isObject(obj)) {
+                                                    Ext.Ajax.request({
+                                                        url: init.contextPath + '/api/dataElementGroups.json?fields=id,name,dataElements[id,name]&pageSize=1',
+                                                        success: function(r) {
+                                                            r = Ext.decode(r.responseText);
+                                                            init.systemSettings.infrastructuralDataElementGroup = r.dataElementGroups ? r.dataElementGroups[0] : null;
+                                                        },
+                                                        callback: fn
+                                                    });
+                                                }
+                                                else {
+                                                    fn();
+                                                }
                                             }
                                         });
 
@@ -9517,7 +9564,7 @@
                                             success: function(r) {
                                                 var obj = Ext.decode(r.responseText);
 
-                                                init.systemSettings.infrastructuralPeriodType = Ext.isObject(obj) ? obj : null;
+                                                init.systemSettings.infrastructuralPeriodType = Ext.isObject(obj) ? obj : {id: 'Yearly', code: 'Yearly', name: 'Yearly'};
                                                 fn();
                                             }
                                         });

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/core.js	2014-11-25 14:09:19 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/core.js	2014-11-30 18:36:23 +0000
@@ -181,11 +181,12 @@
 
 	GIS.core.createSelectHandlers = function(gis, layer) {
 		var isRelocate = !!GIS.app ? !!gis.init.user.isAdmin : false,
-			options = {},
 			infrastructuralPeriod,
+            destroyDataPopups,
 			defaultHoverSelect,
 			defaultHoverUnselect,
-			defaultClickSelect,
+            defaultLeftClickSelect,
+			defaultRightClickSelect,
             selectHandlers,
 			dimConf = gis.conf.finals.dimension,
             defaultHoverWindow,
@@ -193,6 +194,41 @@
             isBoundary = layer.id === 'boundary',
             isEvent = layer.id === 'event';
 
+        layer.dataPopups = [];
+
+        destroyDataPopups = function() {
+            if (layer.dataPopups) {
+                for (var i = 0, popup; i < layer.dataPopups.length; i++) {
+                    popup = layer.dataPopups[i];
+
+                    if (popup && popup.destroy) {
+                        popup.destroy();
+                        popup = null;
+                        layer.dataPopups[i] = null;
+                    }
+                }
+
+                layer.dataPopups = Ext.clean(layer.dataPopups);
+            }
+        };
+
+        layer.onMouseDown = function(e) {
+            if (OpenLayers.Event.isRightClick(e)) {
+                defaultRightClickSelect(layer.getFeatureFromEvent(e), e);
+            }
+            else {
+                defaultLeftClickSelect(layer.getFeatureFromEvent(e), e);
+            }
+        };
+
+        layer.registerMouseDownEvent = function() {
+            layer.events.register('mousedown', null, layer.onMouseDown);
+        };
+
+        layer.unregisterMouseDownEvent = function() {
+            layer.events.unregister('mousedown', null, layer.onMouseDown);
+        };
+
 		defaultHoverSelect = function fn(feature) {
             if (isBoundary) {
                 var style = layer.core.getDefaultFeatureStyle();
@@ -230,13 +266,168 @@
 				centerRegionY = gis.viewport.centerRegion.getPosition()[1] + (GIS.app ? 32 : 0);
 
 			defaultHoverWindow.setPosition(centerRegionCenterX - (defaultHoverWindow.getWidth() / 2), centerRegionY);
+
+            layer.registerMouseDownEvent();
 		};
 
 		defaultHoverUnselect = function fn(feature) {
 			defaultHoverWindow.destroy();
+
+            // remove mouse click event
+            layer.unregisterMouseDownEvent();
+
+            // destroy popups
+            //destroyDataPopups();
 		};
 
-		defaultClickSelect = function fn(feature) {
+        defaultLeftClickSelect = function fn(feature, e) {
+            var generator = gis.init.periodGenerator,
+                periodType = gis.init.systemSettings.infrastructuralPeriodType.name,
+                attr = feature.attributes,
+                iig = gis.init.systemSettings.infrastructuralIndicatorGroup || gis.init.systemSettings.indicatorGroups[0] || {},
+                ideg = gis.init.systemSettings.infrastructuralDataElementGroup || {},
+
+                indicators = iig.indicators || [],
+                dataElements = ideg.dataElements || [],
+                data = [].concat(indicators, dataElements),
+                period = generator.filterFuturePeriodsExceptCurrent(generator.generateReversedPeriods(periodType))[0],
+                paramString = '?',
+                showWindow,
+                success,
+                failure,
+                getData,
+                getParamString;
+
+            showWindow = function(html) {
+                destroyDataPopups();
+
+                win = Ext.create('Ext.window.Window', {
+                    bodyStyle: 'background-color: #fff; padding: 5px; line-height: 13px',
+                    autoScroll: true,
+                    closeAction: 'destroy',
+                    title: 'Infrastructural data',
+                    resizable: false,
+                    html: html,
+                    listeners: {
+                        show: function() {
+                            var winHeight = this.getHeight(),
+                                viewportHeight = gis.viewport.getHeight(),
+                                diff = (winHeight + e.y) - viewportHeight;
+
+                            if (diff > 0) {
+                                this.setHeight(winHeight - diff - 5);
+                                this.setWidth(this.getWidth() + 18);
+                            }
+                        }
+                    }
+                });
+
+                win.showAt(e.x + 20, e.y);
+
+                layer.dataPopups.push(win);
+            };
+
+            success = function(r) {
+                var html = '',
+                    records = [],
+                    dxIndex,
+                    valueIndex,
+                    win;
+
+                if (r.rows && r.rows.length) {
+
+                    // index
+                    for (var i = 0; i < r.headers.length; i++) {
+                        if (r.headers[i].name === 'dx') {
+                            dxIndex = i;
+                        }
+
+                        if (r.headers[i].name === 'value') {
+                            valueIndex = i;
+                        }
+                    }
+
+                    // records
+                    for (var i = 0; i < r.rows.length; i++) {
+                        records.push({
+                            name: r.metaData.names[r.rows[i][dxIndex]],
+                            value: r.rows[i][valueIndex]
+                        });
+                    }
+
+                    gis.util.array.sort(records);
+
+                    // html
+                    html += '<div style="font-weight: bold; color: #333">' + attr.name + '</div>';
+                    html += '<div style="font-weight: bold; color: #333; padding-bottom: 5px">' + r.metaData.names[period.iso] + '</div>';
+
+                    for (var i = 0; i < records.length; i++) {
+                        html += records[i].name + ': ' + '<span style="color:#333">' + records[i].value + '</span>' + (i < records.length - 1 ? '<br/>' : '');
+                    }
+                }
+                else {
+                    html = 'No data found for<br/><br/>Indicators in group: <span style="color:#333">' + iig.name + '</span>' +
+                           '<br/>Data elements in group: <span style="color:#333">' + ideg.name + '</span>' +
+                           '<br/>Period: <span style="color:#333">' + period.name + '</span>' +
+                           '<br/><br/>To change groups, please go to general settings.';
+                }
+
+                showWindow(html);
+            };
+
+            failure = function(r) {
+                console.log(r);
+            };
+
+            getData = function(paramString) {
+                if (GIS.plugin && !GIS.app) {
+                    Ext.data.JsonP.request({
+                        url: gis.init.contextPath + '/api/analytics.jsonp' + paramString,
+                        success: success,
+                        failure: failure
+                    });
+                }
+                else {
+                    Ext.Ajax.request({
+                        url: gis.init.contextPath + '/api/analytics.json' + paramString,
+                        disableCaching: false,
+                        success: function(r) {
+                            success(Ext.decode(r.responseText));
+                        },
+                        failure: failure
+                    });
+                }
+            };
+
+            getParamString = function(data) {
+
+                // data
+                paramString += 'dimension=dx:';
+
+                for (var i = 0; i < data.length; i++) {
+                    paramString += data[i].id + (i < data.length - 1 ? ';' : '');
+                }
+
+                // period
+                paramString += '&filter=pe:' + period.iso;
+
+                // orgunit
+                paramString += '&dimension=ou:' + attr.id;
+
+                getData(paramString);
+            };
+
+            // init
+            if (!data.length) {
+                showWindow('No indicator or data element groups found.');
+                return;
+            }
+
+            getParamString(data);
+
+        };
+
+		defaultRightClickSelect = function fn(feature) {
 			var showInfo,
 				showRelocate,
 				drill,
@@ -293,7 +484,7 @@
 			// Infrastructural data
 			showInfo = function() {
 				Ext.Ajax.request({
-					url: gis.init.contextPath + '/api/organisationUnits/' + att.id + '.json?links=false',
+					url: gis.init.contextPath + '/api/organisationUnits/' + att.id + '.json?fields=id,name,code,address,email,phoneNumber,coordinates,parent[id,name],organisationUnitGroups[id,name]',
 					success: function(r) {
 						var ou = Ext.decode(r.responseText);
 
@@ -343,7 +534,7 @@
 
                                         if (Ext.isString(ou.coordinates)) {
                                             var co = ou.coordinates.replace("[","").replace("]","").replace(",",", ");
-											a.push({html: GIS.i18n.coordinate, cls: 'gis-panel-html-title'}, {html: co, cls: 'gis-panel-html'}, {cls: 'gis-panel-html-separator'});
+											a.push({html: GIS.i18n.coordinates, cls: 'gis-panel-html-title'}, {html: co, cls: 'gis-panel-html'}, {cls: 'gis-panel-html-separator'});
                                         }
 
                                         if (Ext.isArray(ou.organisationUnitGroups) && ou.organisationUnitGroups.length) {
@@ -406,52 +597,68 @@
 												select: function(cmp) {
 													var period = cmp.getValue(),
 														url = gis.init.contextPath + '/api/analytics.json?',
-														group = gis.init.systemSettings.infrastructuralDataElementGroup;
-
-													if (group && group.dataElements) {
-														url += 'dimension=dx:';
-
-														for (var i = 0; i < group.dataElements.length; i++) {
-															url += group.dataElements[i].id;
-															url += i < group.dataElements.length - 1 ? ';' : '';
-														}
-													}
-
-													url += '&filter=pe:' + period;
-													url += '&filter=ou:' + att.id;
+                                                        iig = gis.init.systemSettings.infrastructuralIndicatorGroup || {},
+                                                        ideg = gis.init.systemSettings.infrastructuralDataElementGroup || {},
+
+                                                        indicators = iig.indicators || [],
+                                                        dataElements = ideg.dataElements || [],
+                                                        data = [].concat(indicators, dataElements),
+                                                        paramString = '';
+
+                                                    // data
+                                                    paramString += 'dimension=dx:';
+
+                                                    for (var i = 0; i < data.length; i++) {
+                                                        paramString += data[i].id + (i < data.length - 1 ? ';' : '');
+                                                    }
+
+                                                    // period
+                                                    paramString += '&filter=pe:' + period;
+
+                                                    // orgunit
+                                                    paramString += '&dimension=ou:' + att.id;
 
 													Ext.Ajax.request({
-														url: url,
+														url: url + paramString,
 														success: function(r) {
-															var response = Ext.decode(r.responseText),
-																data = [];
-
-															if (Ext.isArray(response.rows)) {
-																for (var i = 0; i < response.rows.length; i++) {
-																	data.push({
-																		name: response.metaData.names[response.rows[i][0]],
-																		value: response.rows[i][1]
-																	});
-																}
-															}
-
-															layer.widget.infrastructuralDataElementValuesStore.loadData(data);
+                                                            var records = [];
+
+                                                            r = Ext.decode(r.responseText);
+
+                                                            if (!r.rows && r.rows.length) {
+                                                                return;
+                                                            }
+                                                            else {
+                                                                // index
+                                                                for (var i = 0; i < r.headers.length; i++) {
+                                                                    if (r.headers[i].name === 'dx') {
+                                                                        dxIndex = i;
+                                                                    }
+
+                                                                    if (r.headers[i].name === 'value') {
+                                                                        valueIndex = i;
+                                                                    }
+                                                                }
+
+                                                                // records
+                                                                for (var i = 0; i < r.rows.length; i++) {
+                                                                    records.push({
+                                                                        name: r.metaData.names[r.rows[i][dxIndex]],
+                                                                        value: parseFloat(r.rows[i][valueIndex])
+                                                                    });
+                                                                }
+
+                                                                layer.widget.infrastructuralDataElementValuesStore.loadData(records);
+                                                            }
 														}
 													});
-
-													//layer.widget.infrastructuralDataElementValuesStore.load({
-														//params: {
-															//periodId: infrastructuralPeriod,
-															//organisationUnitId: att.internalId
-														//}
-													//});
 												}
 											}
 										},
 										{
 											xtype: 'grid',
-											cls: 'gis-grid',
-											height: 300, //todo
+											cls: 'gis-grid plain',
+											height: 313, //todo
 											width: 258,
 											scroll: 'vertical',
 											columns: [
@@ -635,14 +842,8 @@
 			menu.showAt([gis.olmap.mouseMove.x, gis.olmap.mouseMove.y]);
 		};
 
-		options = {
-            onHoverSelect: defaultHoverSelect,
-            onHoverUnselect: defaultHoverUnselect,
-            onClickSelect: defaultClickSelect
-        };
-
 		if (isEvent) {
-			options.onClickSelect = function fn(feature) {
+			defaultLeftClickSelect = function fn(feature) {
                 var ignoreKeys = ['label', 'value', 'nameColumnMap', 'psi', 'ps', 'longitude', 'latitude', 'eventdate', 'ou', 'oucode', 'ouname', 'popupText'],
                     attributes = feature.attributes,
                     map = attributes.nameColumnMap,
@@ -673,6 +874,7 @@
 
                 eventWindow = Ext.create('Ext.window.Window', {
                     title: 'Event',
+                    title: 'Event',
                     layout: 'fit',
                     resizable: false,
                     bodyStyle: 'background-color:#fff; padding:5px',
@@ -695,7 +897,10 @@
             };
 		}
 
-		selectHandlers = new OpenLayers.Control.newSelectFeature(layer, options);
+		selectHandlers = new OpenLayers.Control.newSelectFeature(layer, {
+            onHoverSelect: defaultHoverSelect,
+            onHoverUnselect: defaultHoverUnselect
+        });
 
 		gis.olmap.addControl(selectHandlers);
 		selectHandlers.activate();
@@ -1784,6 +1989,11 @@
                     gis.viewport.shareButton.enable();
 				}
 			}
+
+            // mouse events
+            if (layer.unregisterMouseDownEvent) {
+                layer.unregisterMouseDownEvent();
+            }
 		};
 
 		loader = {
@@ -2715,6 +2925,7 @@
 				}
 
 				key = key || 'name';
+                direction = direction || 'ASC';
 
 				array.sort( function(a, b) {
 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/styles/style.css'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/styles/style.css	2014-11-06 15:44:09 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/styles/style.css	2014-11-27 20:09:23 +0000
@@ -996,6 +996,9 @@
 .gis-grid .x-grid-row .x-grid-cell { /* remove blurry borders */
 	border-top: 0 none;
 }
+.gis-grid.plain .x-grid-row .x-grid-cell {
+	border-style: none;
+}
 
 .gis-grid .link,
 .gis-grid .link * {

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/GetGeneralSettingsAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/GetGeneralSettingsAction.java	2014-11-25 12:35:16 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/GetGeneralSettingsAction.java	2014-11-26 12:22:29 +0000
@@ -32,6 +32,8 @@
 import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
 import org.hisp.dhis.configuration.Configuration;
 import org.hisp.dhis.configuration.ConfigurationService;
+import org.hisp.dhis.indicator.IndicatorGroup;
+import org.hisp.dhis.indicator.IndicatorService;
 import org.hisp.dhis.dataelement.DataElementGroup;
 import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
@@ -67,6 +69,13 @@
         this.configurationService = configurationService;
     }
 
+    private IndicatorService indicatorService;
+
+    public void setIndicatorService( IndicatorService indicatorService )
+    {
+        this.indicatorService = indicatorService;
+    }
+
     private DataElementService dataElementService;
 
     public void setDataElementService( DataElementService dataElementService )
@@ -124,6 +133,13 @@
     {
         return aggregationStrategies;
     }
+    
+    private List<IndicatorGroup> indicatorGroups;
+    
+    public List<IndicatorGroup> getIndicatorGroups()
+    {
+        return indicatorGroups;
+    }
 
     private List<DataElementGroup> dataElementGroups;
 
@@ -186,6 +202,10 @@
 
             offlineOrganisationUnitLevel = organisationUnitService.getOrganisationUnitLevelByLevel( size );
         }
+        
+        indicatorGroups = new ArrayList<>( indicatorService.getAllIndicatorGroups() );
+        
+        Collections.sort( indicatorGroups, IdentifiableObjectNameComparator.INSTANCE );
 
         dataElementGroups = new ArrayList<>( dataElementService.getAllDataElementGroups() );
 

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/SetGeneralSettingsAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/SetGeneralSettingsAction.java	2014-11-25 12:39:54 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/SetGeneralSettingsAction.java	2014-11-26 12:22:29 +0000
@@ -44,6 +44,7 @@
 import org.apache.commons.lang3.StringUtils;
 import org.hisp.dhis.configuration.Configuration;
 import org.hisp.dhis.configuration.ConfigurationService;
+import org.hisp.dhis.indicator.IndicatorService;
 import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.i18n.I18n;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
@@ -84,6 +85,13 @@
     {
         this.configurationService = configurationService;
     }
+    
+    private IndicatorService indicatorService;
+    
+    public void setIndicatorService( IndicatorService indicatorService )
+    {
+        this.indicatorService = indicatorService;
+    }
 
     private DataElementService dataElementService;
 
@@ -131,6 +139,13 @@
         this.databaseServerCpus = databaseServerCpus;
     }
 
+    private Integer infrastructuralIndicators;
+
+    public void setInfrastructuralIndicators( Integer infrastructuralIndicators )
+    {
+        this.infrastructuralIndicators = infrastructuralIndicators;
+    }
+
     private Integer infrastructuralDataElements;
 
     public void setInfrastructuralDataElements( Integer infrastructuralDataElements )
@@ -271,6 +286,11 @@
             organisationUnitService.updateVersion();
         }
 
+        if ( infrastructuralIndicators != null )
+        {
+            configuration.setInfrastructuralIndicators( indicatorService.getIndicatorGroup( infrastructuralIndicators ) );
+        }
+
         if ( infrastructuralDataElements != null )
         {
             configuration.setInfrastructuralDataElements( dataElementService

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/resources/META-INF/dhis/beans.xml	2014-11-30 10:30:06 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/resources/META-INF/dhis/beans.xml	2014-11-30 18:36:23 +0000
@@ -11,6 +11,7 @@
     class="org.hisp.dhis.settings.action.system.GetGeneralSettingsAction"
     scope="prototype">
     <property name="configurationService" ref="org.hisp.dhis.configuration.ConfigurationService" />
+    <property name="indicatorService" ref="org.hisp.dhis.indicator.IndicatorService" />
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
     <property name="userGroupService" ref="org.hisp.dhis.user.UserGroupService" />
     <property name="periodService" ref="org.hisp.dhis.period.PeriodService" />
@@ -22,6 +23,7 @@
     scope="prototype">
     <property name="systemSettingManager" ref="org.hisp.dhis.setting.SystemSettingManager" />
     <property name="configurationService" ref="org.hisp.dhis.configuration.ConfigurationService" />
+    <property name="indicatorService" ref="org.hisp.dhis.indicator.IndicatorService" />
     <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
     <property name="userGroupService" ref="org.hisp.dhis.user.UserGroupService" />
     <property name="periodService" ref="org.hisp.dhis.period.PeriodService" />

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/resources/org/hisp/dhis/settings/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/resources/org/hisp/dhis/settings/i18n_module.properties	2014-11-25 12:35:16 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/resources/org/hisp/dhis/settings/i18n_module.properties	2014-11-26 12:22:29 +0000
@@ -123,4 +123,5 @@
 help_page_link = Help page link
 acceptance_required_before_approval=Acceptance required before approval
 system_notifications_email_address=System notifications email address
-default_analysis_relative_period=Default relative period for analysis
\ No newline at end of file
+default_analysis_relative_period=Default relative period for analysis
+infrastructural_indicators=Infrastructural indicators
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/webapp/dhis-web-maintenance-settings/systemGeneralSettings.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/webapp/dhis-web-maintenance-settings/systemGeneralSettings.vm	2014-11-25 12:35:16 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/webapp/dhis-web-maintenance-settings/systemGeneralSettings.vm	2014-11-26 12:22:29 +0000
@@ -5,6 +5,7 @@
         cacheStrategy: getFieldValue('cacheStrategy'),
         analyticsMaxLimit: getFieldValue('analyticsMaxLimit'),
         databaseServerCpus: getFieldValue('databaseServerCpus'),
+        infrastructuralIndicators: getFieldValue('infrastructuralIndicators'),
         infrastructuralDataElements: getFieldValue('infrastructuralDataElements'),
         infrastructuralPeriodType: getFieldValue('infrastructuralPeriodType'),
         analysisRelativePeriod: getFieldValue('analysisRelativePeriod'),
@@ -68,6 +69,16 @@
 </select>
 </div>
 
+<div class="settingLabel">$i18n.getString( "infrastructural_indicators" )</div>
+
+<div class="setting">
+<select id="infrastructuralIndicators" name="infrastructuralIndicators">
+    #foreach ( $group in $indicatorGroups )
+    <option value="$group.id" #if( $group.id == $configuration.infrastructuralIndicators.id )selected="selected"#end>$group.name</option>
+    #end
+</select>
+</div>
+
 <div class="settingLabel">$i18n.getString( "infrastructural_data_elements" )</div>
 
 <div class="setting">