← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 11683: (DV) New orgunitselection method: boundaries/groups + User orgunit grand children + (PT) Minor bu...

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 11683 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2013-08-16 17:11:58 +0200
message:
  (DV) New orgunitselection method: boundaries/groups + User orgunit grand children + (PT) Minor bug fixed.
modified:
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js
  dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/org/hisp/dhis/visualizer/i18n_module.properties
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/core.js
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/i18n.vm
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/jsonInitialize.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-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js	2013-08-16 11:55:26 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js	2013-08-16 14:44:33 +0000
@@ -460,6 +460,18 @@
 				}
 			});
 
+			store.organisationUnitGroup = Ext.create('Ext.data.Store', {
+				fields: ['id', 'name'],
+				proxy: {
+					type: 'ajax',
+					url: init.contextPath + conf.finals.ajax.path_api + conf.finals.ajax.organisationunitgroup_getall,
+					reader: {
+						type: 'json',
+						root: 'organisationUnitGroups'
+					}
+				}
+			});
+
 			store.legendSet = Ext.create('Ext.data.Store', {
 				fields: ['id', 'name', 'index'],
 				data: function() {
@@ -473,18 +485,6 @@
 				]
 			});
 			
-			store.organisationUnitGroup = Ext.create('Ext.data.Store', {
-				fields: ['id', 'name'],
-				proxy: {
-					type: 'ajax',
-					url: init.contextPath + conf.finals.ajax.path_api + conf.finals.ajax.organisationunitgroup_getall,
-					reader: {
-						type: 'json',
-						root: 'organisationUnitGroups'
-					}
-				}
-			});
-
 			pt.store = store;
 		}());
 
@@ -3406,13 +3406,6 @@
 					id: pt.conf.finals.root.id,
 					expanded: true,
 					children: pt.init.rootNodes
-				},
-				listeners: {
-					load: function(s, node, r) {
-						//for (var i = 0; i < r.length; i++) {
-							//r[i].data.text = pt.conf.util.jsonEncodeString(r[i].data.text);
-						//}
-					}
 				}
 			}),
 			xable: function(values) {
@@ -3614,19 +3607,20 @@
 			items: tool
 		});
 		
+
 		organisationUnit = {
-			xtype: 'panel',
-			title: '<div class="pt-panel-title-organisationunit">' + PT.i18n.organisation_units + '</div>',
-			bodyStyle: 'padding:2px',
-			hideCollapseTool: true,
-			collapsed: false,
-			getDimension: function() {
-				var r = treePanel.getSelectionModel().getSelection(),
-					config = {
-						dimension: pt.conf.finals.dimension.organisationUnit.objectName,
-						items: []
-					};
-					
+            xtype: 'panel',
+            title: '<div class="dv-panel-title-organisationunit">' + DV.i18n.organisation_units + '</div>',
+            bodyStyle: 'padding:2px',
+            hideCollapseTool: true,
+            collapsed: false,
+            getDimension: function() {
+                var r = treePanel.getSelectionModel().getSelection(),
+                    config = {
+                        dimension: dv.conf.finals.dimension.organisationUnit.objectName,
+                        items: []
+                    };
+
 				if (toolMenu.menuValue === 'orgunit') {
 					if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue() || userOrganisationUnitGrandChildren.getValue()) {
 						if (userOrganisationUnit.getValue()) {
@@ -3656,14 +3650,14 @@
 				}
 				else if (toolMenu.menuValue === 'level') {
 					var levels = organisationUnitLevel.getValue();
-					
+
 					for (var i = 0; i < levels.length; i++) {
 						config.items.push({
 							id: 'LEVEL-' + levels[i],
 							name: ''
 						});
 					}
-						
+
 					for (var i = 0; i < r.length; i++) {
 						config.items.push({
 							id: r[i].data.id,
@@ -3673,14 +3667,14 @@
 				}
 				else if (toolMenu.menuValue === 'group') {
 					var groupIds = organisationUnitGroup.getValue();
-					
+
 					for (var i = 0; i < groupIds.length; i++) {
 						config.items.push({
 							id: 'OU_GROUP-' + groupIds[i],
 							name: ''
 						});
 					}
-						
+
 					for (var i = 0; i < r.length; i++) {
 						config.items.push({
 							id: r[i].data.id,
@@ -3688,48 +3682,45 @@
 						});
 					}
 				}
-				
-				return config.items.length ? config : null;
-			},
-			onExpand: function() {
-				var h = pt.viewport.westRegion.hasScrollbar ?
-					pt.conf.layout.west_scrollbarheight_accordion_organisationunit : pt.conf.layout.west_maxheight_accordion_organisationunit;
-				pt.util.dimension.panel.setHeight(h);
-				treePanel.setHeight(this.getHeight() - pt.conf.layout.west_fill_accordion_organisationunit);
-			},
-			items: [
-				{
-					layout: 'column',
-					bodyStyle: 'border:0 none',
-					style: 'padding-bottom:2px',
-					items: [
-						toolPanel,
-						{
-							width: pt.conf.layout.west_fieldset_width - pt.conf.layout.west_width_padding - 38,
-							layout: 'column',
-							bodyStyle: 'border:0 none',
-							items: [
-								userOrganisationUnit,
-								userOrganisationUnitChildren,
-								userOrganisationUnitGrandChildren,
-								organisationUnitLevel,
-								organisationUnitGroup
-							]
-						}							
-					]
-				},
-				treePanel
-			],
-			suppressExpand: false,
-			listeners: {
-				added: function() {
-					pt.cmp.dimension.panels.push(this);
-				},
-				expand: function(p) {
-					p.onExpand();
-				}
-			}
-		};
+
+                return config.items.length ? config : null;
+            },
+            onExpand: function() {
+                var h = dv.viewport.westRegion.hasScrollbar ?
+                    dv.conf.layout.west_scrollbarheight_accordion_organisationunit : dv.conf.layout.west_maxheight_accordion_organisationunit;
+                dv.util.dimension.panel.setHeight(h);
+                treePanel.setHeight(this.getHeight() - dv.conf.layout.west_fill_accordion_organisationunit);
+            },
+            items: [
+                {
+                    layout: 'column',
+                    bodyStyle: 'border:0 none',
+                    style: 'padding-bottom:2px',
+                    items: [
+                        toolPanel,
+                        {
+                            width: dv.conf.layout.west_fieldset_width - dv.conf.layout.west_width_padding - 38,
+                            layout: 'column',
+                            bodyStyle: 'border:0 none',
+                            items: [
+                                userOrganisationUnit,
+                                userOrganisationUnitChildren,
+                                organisationUnitLevel
+                            ]
+                        }
+                    ]
+                },
+                treePanel
+            ],
+            listeners: {
+                added: function() {
+                    dv.cmp.dimension.panels.push(this);
+                },
+                expand: function(p) {
+                    p.onExpand();
+                }
+            }
+        };
 
 		getDimensionPanels = function(dimensions, iconCls) {
 			var	getAvailableStore,

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js	2013-08-16 13:37:01 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js	2013-08-16 15:10:28 +0000
@@ -32,7 +32,7 @@
 		(function() {
 			conf.finals = {
 				ajax: {
-					path_pivot: '/dhis-web-pivot/',
+					path_module: '/dhis-web-pivot/',
 					path_api: '/api/',
 					path_commons: '/dhis-web-commons-ajax-json/',
 					data_get: 'chartValues.json',
@@ -735,7 +735,7 @@
 						return;
 					}
 
-					// Get object names and isOu/isOuc
+					// Get object names and user orgunits
 					for (var i = 0, dim, dims = [].concat(config.columns, config.rows, config.filters); i < dims.length; i++) {
 						dim = dims[i];
 
@@ -746,7 +746,7 @@
 								objectNames.push(dim.dimension);
 							}
 
-							// isOu/isOuc
+							// user orgunits
 							if (dim.dimension === dimConf.organisationUnit.objectName && Ext.isArray(dim.items)) {
 								for (var j = 0; j < dim.items.length; j++) {
 									if (dim.items[j].id === 'USER_ORGUNIT') {
@@ -786,6 +786,7 @@
 
 					layout.userOrganisationUnit = isOu;
 					layout.userOrganisationUnitChildren = isOuc;
+					layout.userOrganisationUnitGrandChildren = isOugc;
 
 					layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : null;
 
@@ -1255,41 +1256,41 @@
 									var userOu,
 										userOuc,
 										userOugc;
-										
+
 									if (isUserOrgunit) {
 										userOu = [{
-											id: pt.init.user.ou,
-											name: response.metaData.names[pt.init.user.ou]
+											id: dv.init.user.ou,
+											name: response.metaData.names[dv.init.user.ou]
 										}];
 									}
 									if (isUserOrgunitChildren) {
 										userOuc = [];
-										
-										for (var i = 0; i < pt.init.user.ouc.length; i++) {
+
+										for (var j = 0; j < dv.init.user.ouc.length; j++) {
 											userOuc.push({
-												id: pt.init.user.ouc[i],
-												name: response.metaData.names[pt.init.user.ouc[i]]
+												id: dv.init.user.ouc[j],
+												name: response.metaData.names[dv.init.user.ouc[j]]
 											});
 										}
 
-										userOuc = pt.util.array.sortObjectsByString(userOuc);
+										userOuc = dv.util.array.sortObjectsByString(userOuc);
 									}
 									if (isUserOrgunitGrandChildren) {
-										var userOuOuc = [].concat(pt.init.user.ou, pt.init.user.ouc),
+										var userOuOuc = [].concat(dv.init.user.ou, dv.init.user.ouc),
 											responseOu = response.metaData.ou;
-											
+
 										userOugc = [];
 
-										for (var i = 0; i < responseOu.length; i++) {
-											if (!Ext.Array.contains(userOuOuc, responseOu[i])) {
+										for (var j = 0; j < responseOu.length; j++) {
+											if (!Ext.Array.contains(userOuOuc, responseOu[j])) {
 												userOugc.push({
-													id: responseOu[i],
-													name: response.metaData.names[responseOu[i]]
+													id: responseOu[j],
+													name: response.metaData.names[responseOu[j]]
 												});
 											}
 										}
 
-										userOugc = pt.util.array.sortObjectsByString(userOugc);
+										userOugc = dv.util.array.sortObjectsByString(userOugc);
 									}
 
 									dim.items = [].concat(userOu || [], userOuc || [], userOugc || []);
@@ -1297,14 +1298,14 @@
 								else if (isLevel || isGroup) {
 									var responseOu = response.metaData.ou;
 
-									for (var i = 0; i < responseOu.length; i++) {
+									for (var j = 0; j < responseOu.length; j++) {
 										dim.items.push({
-											id: responseOu[i],
-											name: response.metaData.names[responseOu[i]]
+											id: responseOu[j],
+											name: response.metaData.names[responseOu[j]]
 										});
 									}
 
-									dim.items = pt.util.array.sortObjectsByString(dim.items);
+									dim.items = dv.util.array.sortObjectsByString(dim.items);
 								}
 								else {
 									dim.items = Ext.clone(xLayout.dimensionNameItemsMap[dim.dimensionName]);
@@ -1312,9 +1313,12 @@
 							}
 							else {
 								// Items: get ids from metadata -> items
-								if (Ext.isArray(metaDataDim) && dim.dimensionName !== dimConf.organisationUnit.dimensionName) {
+								if (Ext.isArray(metaDataDim)) {
 									for (var j = 0, ids = Ext.clone(response.metaData[dim.dimensionName]); j < ids.length; j++) {
-										dim.items.push({id: ids[j]});
+										dim.items.push({
+											id: ids[j],
+											name: response.metaData.names[ids[j]]
+										});
 									}
 								}
 								// Items: get items from xLayout

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/org/hisp/dhis/visualizer/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/org/hisp/dhis/visualizer/i18n_module.properties	2013-07-24 10:33:49 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/org/hisp/dhis/visualizer/i18n_module.properties	2013-08-16 14:44:33 +0000
@@ -41,7 +41,6 @@
 trend_line=Show trend lines
 hide_subtitle=Hide chart subtitle
 hide_legend=Hide chart legend
-user_orgunit=User organisation unit
 domain_axis_label=Domain axis title
 range_axis_label=Range axis title
 target=Target
@@ -123,7 +122,6 @@
 wm_first_filter_used=The first one is being used.
 available_attribute=Available attribute 
 selected_attribute=Selected attribute
-user_orgunit_children=User organisation unit children
 show_data=Show series data
 share=Share
 interpretation=interpretation
@@ -163,8 +161,9 @@
 last_5_financial_years=Last 5 financial years
 prev_year=Prev year
 next_year=Next year
-user_organisation_unit=User organisation unit
-user_organisation_unit_children=User organisation unit children
+user_organisation_unit=User org unit
+user_organisation_unit_children=Org unit children
+user_organisation_unit_grandchildren=Org unit grand children
 filters=Filters
 at_least_one_dimension_must_be_specified_as_row_or_column=At least one dimension must be specified as row or column
 at_least_one_period_must_be_specified_as_column_row_or_filter=At least one period must be specified as column, row or filter
@@ -198,5 +197,7 @@
 write_your_interpretation=Write a comment, question or interpretation
 sharing_settings=Sharing settings
 select_organisation_units=Select organisation units
-select_boundaries_and_level=Select boundaries and level
-select_organisation_unit_level=Select organisation unit level
\ No newline at end of file
+select_boundaries_and_levels=Select boundaries and levels
+select_organisation_unit_levels=Select organisation unit levels
+select_boundaries_and_groups=Select boundaries and groups
+select_organisation_unit_groups=Select organisation unit groups
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js	2013-08-13 09:32:39 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js	2013-08-16 14:44:33 +0000
@@ -488,7 +488,7 @@
                     if (Ext.isString(uid)) {
                         this.setProxy({
                             type: 'ajax',
-                            url: conf.finals.ajax.path_commons + 'getOperands.action?uid=' + uid,
+							url: init.contextPath + conf.finals.ajax.path_commons + 'getOperands.action?uid=' + uid,
                             reader: {
                                 type: 'json',
                                 root: 'operands'
@@ -527,7 +527,7 @@
                 fields: ['id', 'name'],
                 proxy: {
                     type: 'ajax',
-                    url: conf.finals.ajax.path_api + conf.finals.ajax.dataset_get,
+					url: init.contextPath + conf.finals.ajax.path_api + conf.finals.ajax.dataset_get,
                     reader: {
                         type: 'json',
                         root: 'dataSets'
@@ -575,7 +575,7 @@
                 data: []
             });
 
-            store.charts = Ext.create('Ext.data.Store', {
+            store.chart = Ext.create('Ext.data.Store', {
                 fields: ['id', 'name', 'lastUpdated', 'access'],
                 proxy: {
                     type: 'ajax',
@@ -617,6 +617,18 @@
                 }
             });
 
+			store.organisationUnitGroup = Ext.create('Ext.data.Store', {
+				fields: ['id', 'name'],
+				proxy: {
+					type: 'ajax',
+					url: init.contextPath + conf.finals.ajax.path_api + conf.finals.ajax.organisationunitgroup_getall,
+					reader: {
+						type: 'json',
+						root: 'organisationUnitGroups'
+					}
+				}
+			});
+
             store.getDimensionStore = function() {
                 return Ext.create('Ext.data.Store', {
                     fields: ['id', 'name'],
@@ -1072,7 +1084,7 @@
 			windowWidth = 500,
 			windowCmpWidth = windowWidth - 22;
 
-		dv.store.charts.on('load', function(store, records) {
+		dv.store.chart.on('load', function(store, records) {
 			var pager = store.proxy.reader.jsonData.pager;
 
 			info.setText('Page ' + pager.page + ' of ' + pager.pageCount);
@@ -1131,7 +1143,7 @@
 
 		NameWindow = function(id) {
 			var window,
-				record = dv.store.charts.getById(id);
+				record = dv.store.chart.getById(id);
 
 			nameTextfield = Ext.create('Ext.form.field.Text', {
 				height: 26,
@@ -1169,7 +1181,7 @@
 
 								dv.viewport.interpretationButton.enable();
 
-								dv.store.charts.loadStore();
+								dv.store.chart.loadStore();
 
 								window.destroy();
 							}
@@ -1206,7 +1218,7 @@
 										alert(r.responseText);
 									},
 									success: function(r) {
-										dv.store.charts.loadStore();
+										dv.store.chart.loadStore();
 										window.destroy();
 									}
 								});
@@ -1282,7 +1294,7 @@
 
 						var value = this.getValue(),
 							url = value ? dv.init.contextPath + '/api/charts/query/' + value + '.json?links=false' : null,
-							store = dv.store.charts;
+							store = dv.store.chart;
 
 						store.page = 1;
 						store.loadStore(url);
@@ -1296,7 +1308,7 @@
 			handler: function() {
 				var value = searchTextfield.getValue(),
 					url = value ? dv.init.contextPath + '/api/charts/query/' + value + '.json?links=false' : null,
-					store = dv.store.charts;
+					store = dv.store.chart;
 
 				store.page = store.page <= 1 ? 1 : store.page - 1;
 				store.loadStore(url);
@@ -1308,7 +1320,7 @@
 			handler: function() {
 				var value = searchTextfield.getValue(),
 					url = value ? dv.init.contextPath + '/api/charts/query/' + value + '.json?links=false' : null,
-					store = dv.store.charts;
+					store = dv.store.chart;
 
 				store.page = store.page + 1;
 				store.loadStore(url);
@@ -1395,7 +1407,7 @@
 												success: function() {
 													dv.favorite = favorite;
 													dv.viewport.interpretationButton.enable();
-													dv.store.charts.loadStore();
+													dv.store.chart.loadStore();
 												}
 											});
 										}
@@ -1448,7 +1460,7 @@
 											url: dv.init.contextPath + '/api/charts/' + record.data.id,
 											method: 'DELETE',
 											success: function() {
-												dv.store.charts.loadStore();
+												dv.store.chart.loadStore();
 											}
 										});
 									}
@@ -1462,7 +1474,7 @@
 					width: 6
 				}
 			],
-			store: dv.store.charts,
+			store: dv.store.chart,
 			bbar: [
 				info,
 				'->',
@@ -1479,7 +1491,7 @@
 					this.store.page = 1;
 					this.store.loadStore();
 
-					dv.store.charts.on('load', function() {
+					dv.store.chart.on('load', function() {
 						if (this.isVisible()) {
 							this.fireEvent('afterrender');
 						}
@@ -1896,7 +1908,7 @@
 				handler: function() {
 					if (textArea.getValue()) {
 						Ext.Ajax.request({
-							url: dv.conf.finals.ajax.path_api + 'interpretations/chart/' + dv.favorite.id,
+							url: dv.init.contextPath + dv.conf.finals.ajax.path_api + 'interpretations/chart/' + dv.favorite.id,
 							method: 'POST',
 							params: textArea.getValue(),
 							headers: {'Content-Type': 'text/html'},
@@ -2450,7 +2462,7 @@
                         fields: ['id', 'name', 'index'],
                         proxy: {
                             type: 'ajax',
-                            url: dv.conf.finals.ajax.path_api + dv.conf.finals.ajax.indicatorgroup_get,
+							url: dv.init.contextPath + dv.conf.finals.ajax.path_api + dv.conf.finals.ajax.indicatorgroup_get,
                             reader: {
                                 type: 'json',
                                 root: 'indicatorGroups'
@@ -2487,12 +2499,12 @@
                             }
                             else {
                                 if (cb.getValue() === 0) {
-                                    store.proxy.url = dv.conf.finals.ajax.path_api + dv.conf.finals.ajax.indicator_getall;
-                                    store.load();
-                                }
-                                else {
-                                    store.proxy.url = dv.conf.finals.ajax.path_api + dv.conf.finals.ajax.indicator_get + cb.getValue() + '.json';
-                                    store.load();
+									store.proxy.url = dv.init.contextPath + dv.conf.finals.ajax.path_api + dv.conf.finals.ajax.indicator_getall;
+									store.load();
+								}
+								else {
+									store.proxy.url = dv.init.contextPath + dv.conf.finals.ajax.path_api + dv.conf.finals.ajax.indicator_get + cb.getValue() + '.json';
+									store.load();
                                 }
                             }
                         }
@@ -2601,7 +2613,7 @@
             fields: ['id', 'name', 'index'],
             proxy: {
                 type: 'ajax',
-                url: dv.conf.finals.ajax.path_api + dv.conf.finals.ajax.dataelementgroup_get,
+				url: dv.init.contextPath + dv.conf.finals.ajax.path_api + dv.conf.finals.ajax.dataelementgroup_get,
                 reader: {
                     type: 'json',
                     root: 'dataElementGroups'
@@ -3477,21 +3489,21 @@
             },
             selectByGroup: function(id) {
                 if (id) {
-                    var url = dv.conf.finals.ajax.path_visualizer + dv.conf.finals.ajax.organisationunit_getbygroup,
+                    var url = dv.conf.finals.ajax.path_module + dv.conf.finals.ajax.organisationunit_getbygroup,
                         params = {id: id};
                     this.select(url, params);
                 }
             },
             selectByLevel: function(level) {
                 if (level) {
-                    var url = dv.conf.finals.ajax.path_visualizer + dv.conf.finals.ajax.organisationunit_getbylevel,
+                    var url = dv.conf.finals.ajax.path_module + dv.conf.finals.ajax.organisationunit_getbylevel,
                         params = {level: level};
                     this.select(url, params);
                 }
             },
             selectByIds: function(ids) {
                 if (ids) {
-                    var url = dv.conf.finals.ajax.path_visualizer + dv.conf.finals.ajax.organisationunit_getbyids;
+                    var url = dv.conf.finals.ajax.path_module + dv.conf.finals.ajax.organisationunit_getbyids;
                     Ext.Array.each(ids, function(item) {
                         url = Ext.String.urlAppend(url, 'ids=' + item);
                     });
@@ -3504,7 +3516,7 @@
             store: Ext.create('Ext.data.TreeStore', {
                 proxy: {
                     type: 'ajax',
-                    url: dv.conf.finals.ajax.path_visualizer + dv.conf.finals.ajax.organisationunitchildren_get
+                    url: dv.conf.finals.ajax.path_module + dv.conf.finals.ajax.organisationunitchildren_get
                 },
                 root: {
                     id: dv.conf.finals.root.id,
@@ -3512,9 +3524,16 @@
                     children: dv.init.rootNodes
                 }
             }),
-            xable: function(checked, value) {
-                this.setDisabled(!!(checked || value));
-            },
+			xable: function(values) {
+				for (var i = 0; i < values.length; i++) {
+					if (!!values[i]) {
+						this.disable();
+						return;
+					}
+				}
+
+				this.enable();
+			},
             listeners: {
                 added: function() {
                     dv.cmp.dimension.organisationUnit.treepanel = this;
@@ -3558,194 +3577,268 @@
             }
         });
 
-        userOrganisationUnit = Ext.create('Ext.form.field.Checkbox', {
-            columnWidth: 0.5,
-            style: 'padding-top:2px; padding-left:3px; margin-bottom:0',
-            boxLabel: DV.i18n.user_organisation_unit,
-            labelWidth: dv.conf.layout.form_label_width,
-            handler: function(chb, checked) {
-                treePanel.xable(checked, userOrganisationUnitChildren.getValue());
-            }
-        });
-
-        userOrganisationUnitChildren = Ext.create('Ext.form.field.Checkbox', {
-            columnWidth: 0.5,
-            style: 'padding-top:2px; margin-bottom:0',
-            boxLabel: DV.i18n.user_organisation_unit_children,
-            labelWidth: dv.conf.layout.form_label_width,
-            handler: function(chb, checked) {
-                treePanel.xable(checked, userOrganisationUnit.getValue());
-            }
-        });
-
-        userOrganisationUnitPanel = Ext.create('Ext.panel.Panel', {
-            columnWidth: 0.9,
-            layout: 'column',
-            bodyStyle: 'border:0 none; padding-bottom:3px; padding-left:7px',
-            items: [
-                userOrganisationUnit,
-                userOrganisationUnitChildren
-            ]
-        });
-
-        organisationUnitLevel = Ext.create('Ext.form.field.ComboBox', {
-            cls: 'dv-combo',
-            style: 'margin-bottom:0',
-            width: dv.conf.layout.west_fieldset_width - dv.conf.layout.west_width_padding - 38,
-            valueField: 'level',
-            displayField: 'name',
-            emptyText: DV.i18n.select_organisation_unit_level,
-            editable: false,
-            hidden: true,
-            store: {
-                fields: ['id', 'name', 'level'],
-                data: dv.init.organisationUnitLevels
-            }
-        });
-
-        toolMenu = Ext.create('Ext.menu.Menu', {
-            shadow: false,
-            showSeparator: false,
-            menuValue: 'explicit',
-            clickHandler: function(param) {
-                var items = this.items.items;
-                this.menuValue = param;
-
-                // Menu item icon cls
-                for (var i = 0; i < items.length; i++) {
-                    if (items[i].param === param) {
-                        items[i].setIconCls('dv-menu-item-selected');
-                    }
-                    else {
-                        items[i].setIconCls('');
-                    }
-                }
-
-                // Gui
-                if (param === 'explicit') {
-                    userOrganisationUnit.show();
-                    userOrganisationUnitChildren.show();
-                    organisationUnitLevel.hide();
-
-                    if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue()) {
-                        treePanel.disable();
-                    }
-                }
-                else if (param === 'boundary') {
-                    userOrganisationUnit.hide();
-                    userOrganisationUnitChildren.hide();
-                    organisationUnitLevel.show();
-                    treePanel.enable();
-                }
-            },
-            items: [
-                {
-                    text: DV.i18n.select_organisation_units + '&nbsp;&nbsp;',
-                    param: 'explicit',
-                    iconCls: 'dv-menu-item-selected'
-                },
-                {
-                    text: DV.i18n.select_boundaries_and_level + '&nbsp;&nbsp;',
-                    param: 'boundary'
-                }
-            ],
-            listeners: {
-                afterrender: function() {
-                    this.getEl().addCls('dv-btn-menu');
-                },
-                click: function(menu, item) {
-                    this.clickHandler(item.param);
-                }
-            }
-        });
-
-        tool = Ext.create('Ext.button.Button', {
-            cls: 'dv-button-organisationunitselection',
-            iconCls: 'dv-button-icon-gear',
-            width: 36,
-            height: 24,
-            menu: toolMenu
-        });
-
-        toolPanel = Ext.create('Ext.panel.Panel', {
-            width: 36,
-            bodyStyle: 'border:0 none; text-align:right',
-            style: 'margin-right:2px',
-            items: tool
-        });
-
-        organisationUnit = {
-            xtype: 'panel',
-            title: '<div class="dv-panel-title-organisationunit">' + DV.i18n.organisation_units + '</div>',
-            bodyStyle: 'padding:2px',
-            hideCollapseTool: true,
-            collapsed: false,
-            getDimension: function() {
-                var r = treePanel.getSelectionModel().getSelection(),
-                    config = {
-                        dimension: dv.conf.finals.dimension.organisationUnit.objectName,
-                        items: []
-                    };
-
-                if (toolMenu.menuValue === 'explicit') {
-                    if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue()) {
-                        if (userOrganisationUnit.getValue()) {
-                            config.items.push({id: 'USER_ORGUNIT'});
-                        }
-                        if (userOrganisationUnitChildren.getValue()) {
-                            config.items.push({id: 'USER_ORGUNIT_CHILDREN'});
-                        }
-                    }
-                    else {
-                        for (var i = 0; i < r.length; i++) {
-                            config.items.push({id: r[i].data.id});
-                        }
-                    }
-                }
-                else if (toolMenu.menuValue === 'boundary') {
-                    for (var i = 0; i < r.length; i++) {
-                        config.items.push({id: 'LEVEL-' + organisationUnitLevel.getValue() + '-' + r[i].data.id});
-                    }
-                }
-
-                return config.items.length ? config : null;
-            },
-            onExpand: function() {
-                var h = dv.viewport.westRegion.hasScrollbar ?
-                    dv.conf.layout.west_scrollbarheight_accordion_organisationunit : dv.conf.layout.west_maxheight_accordion_organisationunit;
-                dv.util.dimension.panel.setHeight(h);
-                treePanel.setHeight(this.getHeight() - dv.conf.layout.west_fill_accordion_organisationunit);
-            },
-            items: [
-                {
-                    layout: 'column',
-                    bodyStyle: 'border:0 none',
-                    style: 'padding-bottom:2px',
-                    items: [
-                        toolPanel,
-                        {
-                            width: dv.conf.layout.west_fieldset_width - dv.conf.layout.west_width_padding - 38,
-                            layout: 'column',
-                            bodyStyle: 'border:0 none',
-                            items: [
-                                userOrganisationUnit,
-                                userOrganisationUnitChildren,
-                                organisationUnitLevel
-                            ]
-                        }
-                    ]
-                },
-                treePanel
-            ],
-            listeners: {
-                added: function() {
-                    dv.cmp.dimension.panels.push(this);
-                },
-                expand: function(p) {
-                    p.onExpand();
-                }
-            }
-        };
+		userOrganisationUnit = Ext.create('Ext.form.field.Checkbox', {
+			columnWidth: 0.28,
+			style: 'padding-top:2px; padding-left:3px; margin-bottom:0',
+			boxLabel: DV.i18n.user_organisation_unit,
+			labelWidth: dv.conf.layout.form_label_width,
+			handler: function(chb, checked) {
+				treePanel.xable([checked, userOrganisationUnitChildren.getValue(), userOrganisationUnitGrandChildren.getValue()]);
+			}
+		});
+
+		userOrganisationUnitChildren = Ext.create('Ext.form.field.Checkbox', {
+			columnWidth: 0.31,
+			style: 'padding-top:2px; margin-bottom:0',
+			boxLabel: DV.i18n.user_organisation_unit_children,
+			labelWidth: dv.conf.layout.form_label_width,
+			handler: function(chb, checked) {
+				treePanel.xable([checked, userOrganisationUnit.getValue(), userOrganisationUnitGrandChildren.getValue()]);
+			}
+		});
+
+		userOrganisationUnitGrandChildren = Ext.create('Ext.form.field.Checkbox', {
+			columnWidth: 0.41,
+			style: 'padding-top:2px; margin-bottom:0',
+			boxLabel: DV.i18n.user_organisation_unit_grandchildren,
+			labelWidth: dv.conf.layout.form_label_width,
+			handler: function(chb, checked) {
+				treePanel.xable([checked, userOrganisationUnit.getValue(), userOrganisationUnitChildren.getValue()]);
+			}
+		});
+
+		organisationUnitLevel = Ext.create('Ext.form.field.ComboBox', {
+			cls: 'dv-combo',
+			multiSelect: true,
+			style: 'margin-bottom:0',
+			width: dv.conf.layout.west_fieldset_width - dv.conf.layout.west_width_padding - 38,
+			valueField: 'level',
+			displayField: 'name',
+			emptyText: DV.i18n.select_organisation_unit_levels,
+			editable: false,
+			hidden: true,
+			store: {
+				fields: ['id', 'name', 'level'],
+				data: dv.init.organisationUnitLevels
+			}
+		});
+
+		organisationUnitGroup = Ext.create('Ext.form.field.ComboBox', {
+			cls: 'dv-combo',
+			multiSelect: true,
+			style: 'margin-bottom:0',
+			width: dv.conf.layout.west_fieldset_width - dv.conf.layout.west_width_padding - 38,
+			valueField: 'id',
+			displayField: 'name',
+			emptyText: DV.i18n.select_organisation_unit_groups,
+			editable: false,
+			hidden: true,
+			store: dv.store.organisationUnitGroup
+		});
+
+		toolMenu = Ext.create('Ext.menu.Menu', {
+			shadow: false,
+			showSeparator: false,
+			menuValue: 'orgunit',
+			clickHandler: function(param) {
+				var items = this.items.items;
+				this.menuValue = param;
+
+				// Menu item icon cls
+				for (var i = 0; i < items.length; i++) {
+					if (items[i].param === param) {
+						items[i].setIconCls('dv-menu-item-selected');
+					}
+					else {
+						items[i].setIconCls('');
+					}
+				}
+
+				// Gui
+				if (param === 'orgunit') {
+					userOrganisationUnit.show();
+					userOrganisationUnitChildren.show();
+					userOrganisationUnitGrandChildren.show();
+					organisationUnitLevel.hide();
+					organisationUnitGroup.hide();
+
+					if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue()) {
+						treePanel.disable();
+					}
+				}
+				else if (param === 'level') {
+					userOrganisationUnit.hide();
+					userOrganisationUnitChildren.hide();
+					userOrganisationUnitGrandChildren.hide();
+					organisationUnitLevel.show();
+					organisationUnitGroup.hide();
+					treePanel.enable();
+				}
+				else if (param === 'group') {
+					userOrganisationUnit.hide();
+					userOrganisationUnitChildren.hide();
+					userOrganisationUnitGrandChildren.hide();
+					organisationUnitLevel.hide();
+					organisationUnitGroup.show();
+					treePanel.enable();
+				}
+			},
+			items: [
+				{
+					text: DV.i18n.select_organisation_units + '&nbsp;&nbsp;',
+					param: 'orgunit',
+					iconCls: 'dv-menu-item-selected'
+				},
+				{
+					text: DV.i18n.select_boundaries_and_levels + '&nbsp;&nbsp;',
+					param: 'level'
+				},
+				{
+					text: DV.i18n.select_boundaries_and_groups + '&nbsp;&nbsp;',
+					param: 'group'
+				}
+			],
+			listeners: {
+				afterrender: function() {
+					this.getEl().addCls('dv-btn-menu');
+				},
+				click: function(menu, item) {
+					this.clickHandler(item.param);
+				}
+			}
+		});
+
+		tool = Ext.create('Ext.button.Button', {
+			cls: 'dv-button-organisationunitselection',
+			iconCls: 'dv-button-icon-gear',
+			width: 36,
+			height: 24,
+			menu: toolMenu
+		});
+
+		toolPanel = Ext.create('Ext.panel.Panel', {
+			width: 36,
+			bodyStyle: 'border:0 none; text-align:right',
+			style: 'margin-right:2px',
+			items: tool
+		});
+
+		organisationUnit = {
+			xtype: 'panel',
+			title: '<div class="dv-panel-title-organisationunit">' + DV.i18n.organisation_units + '</div>',
+			bodyStyle: 'padding:2px',
+			hideCollapseTool: true,
+			collapsed: false,
+			getDimension: function() {
+				var r = treePanel.getSelectionModel().getSelection(),
+					config = {
+						dimension: dv.conf.finals.dimension.organisationUnit.objectName,
+						items: []
+					};
+
+				if (toolMenu.menuValue === 'orgunit') {
+					if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue() || userOrganisationUnitGrandChildren.getValue()) {
+						if (userOrganisationUnit.getValue()) {
+							config.items.push({
+								id: 'USER_ORGUNIT',
+								name: ''
+							});
+						}
+						if (userOrganisationUnitChildren.getValue()) {
+							config.items.push({
+								id: 'USER_ORGUNIT_CHILDREN',
+								name: ''
+							});
+						}
+						if (userOrganisationUnitGrandChildren.getValue()) {
+							config.items.push({
+								id: 'USER_ORGUNIT_GRANDCHILDREN',
+								name: ''
+							});
+						}
+					}
+					else {
+						for (var i = 0; i < r.length; i++) {
+							config.items.push({id: r[i].data.id});
+						}
+					}
+				}
+				else if (toolMenu.menuValue === 'level') {
+					var levels = organisationUnitLevel.getValue();
+
+					for (var i = 0; i < levels.length; i++) {
+						config.items.push({
+							id: 'LEVEL-' + levels[i],
+							name: ''
+						});
+					}
+
+					for (var i = 0; i < r.length; i++) {
+						config.items.push({
+							id: r[i].data.id,
+							name: ''
+						});
+					}
+				}
+				else if (toolMenu.menuValue === 'group') {
+					var groupIds = organisationUnitGroup.getValue();
+
+					for (var i = 0; i < groupIds.length; i++) {
+						config.items.push({
+							id: 'OU_GROUP-' + groupIds[i],
+							name: ''
+						});
+					}
+
+					for (var i = 0; i < r.length; i++) {
+						config.items.push({
+							id: r[i].data.id,
+							name: ''
+						});
+					}
+				}
+
+				return config.items.length ? config : null;
+			},
+			onExpand: function() {
+				var h = dv.viewport.westRegion.hasScrollbar ?
+					dv.conf.layout.west_scrollbarheight_accordion_organisationunit : dv.conf.layout.west_maxheight_accordion_organisationunit;
+				dv.util.dimension.panel.setHeight(h);
+				treePanel.setHeight(this.getHeight() - dv.conf.layout.west_fill_accordion_organisationunit);
+			},
+			items: [
+				{
+					layout: 'column',
+					bodyStyle: 'border:0 none',
+					style: 'padding-bottom:2px',
+					items: [
+						toolPanel,
+						{
+							width: dv.conf.layout.west_fieldset_width - dv.conf.layout.west_width_padding - 38,
+							layout: 'column',
+							bodyStyle: 'border:0 none',
+							items: [
+								userOrganisationUnit,
+								userOrganisationUnitChildren,
+								userOrganisationUnitGrandChildren,
+								organisationUnitLevel,
+								organisationUnitGroup
+							]
+						}
+					]
+				},
+				treePanel
+			],
+			suppressExpand: false,
+			listeners: {
+				added: function() {
+					dv.cmp.dimension.panels.push(this);
+				},
+				expand: function(p) {
+					p.onExpand();
+				}
+			}
+		};
 
         getDimensionPanels = function(dimensions, iconCls) {
             var	getAvailableStore,
@@ -4414,7 +4507,10 @@
                 fixedPeriodRecords = [],
                 isOu = false,
                 isOuc = false,
-                isLevel = false;
+				isOugc = false,
+                isLevel = false,
+				levels = [],
+				groups = [];
 
             // State
             dv.viewport.interpretationButton.enable();
@@ -4521,29 +4617,32 @@
                     if (ouRecords[i].id === 'USER_ORGUNIT_CHILDREN') {
                         isOuc = true;
                     }
+					if (ouRecords[i].id === 'USER_ORGUNIT_GRANDCHILDREN') {
+						isOugc = true;
+					}
                     if (ouRecords[i].id.substr(0,5) === 'LEVEL') {
                         isLevel = true;
                     }
-                }
-            }
-
-            if (isLevel) {
-                var ouRecords = recMap[dimConf.organisationUnit.objectName],
-                    level;
-
-                if (Ext.isArray(ouRecords) && ouRecords.length) {
-                    level = ouRecords[i].id.split('-')[1];
-                }
-
-                toolMenu.clickHandler('boundary');
-                organisationUnitLevel.setValue(level);
-            }
-            else {
-                toolMenu.clickHandler('explicit');
-
-                userOrganisationUnit.setValue(isOu);
-                userOrganisationUnitChildren.setValue(isOuc);
-            }
+					if (ouRecords[i].id.substr(0,8) === 'OU_GROUP') {
+						groups.push(parseInt(ouRecords[i].id.split('-')[1]));
+					}
+                }
+            }
+
+			if (levels.length) {
+				toolMenu.clickHandler('level');
+				organisationUnitLevel.setValue(levels);
+			}
+			else if (groups.length) {
+				toolMenu.clickHandler('group');
+				organisationUnitGroup.setValue(groups);
+			}
+			else {
+				toolMenu.clickHandler('orgunit');
+				userOrganisationUnit.setValue(isOu);
+				userOrganisationUnitChildren.setValue(isOuc);
+				userOrganisationUnitGrandChildren.setValue(isOugc);
+			}
 
             // If fav has organisation units, wait for tree callback before update
             if (recMap[dimConf.organisationUnit.objectName] && Ext.isObject(graphMap)) {

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/core.js	2013-08-13 11:46:30 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/core.js	2013-08-16 15:10:28 +0000
@@ -36,11 +36,9 @@
         (function() {
             conf.finals = {
                 ajax: {
-                    path_visualizer: '../',
-                    path_api: '../../api/',
-                    path_commons: '../../dhis-web-commons-ajax-json/',
-                    initialize: 'initialize.action',
-                    redirect: 'dhis-web-commons-about/redirect.action',
+					path_module: '/dhis-web-visualizer/',
+					path_api: '/api/',
+					path_commons: '/dhis-web-commons-ajax-json/',
                     data_get: 'chartValues.json',
                     indicator_get: 'indicatorGroups/',
                     indicator_getall: 'indicators.json?paging=false&links=false',
@@ -606,7 +604,8 @@
                         objectNames = [],
                         dims,
                         isOu = false,
-                        isOuc = false;
+                        isOuc = false,
+						isOugc = false;
 
                     config.columns = getValidatedDimensionArray(config.columns);
                     config.rows = getValidatedDimensionArray(config.rows);
@@ -632,7 +631,7 @@
                         return;
                     }
 
-                    // Get object names and isOu/isOuc
+                    // Get object names and user orgunits
                     for (var i = 0, dim, dims = [].concat(config.columns, config.rows, config.filters); i < dims.length; i++) {
                         dim = dims[i];
 
@@ -643,7 +642,7 @@
                                 objectNames.push(dim.dimension);
                             }
 
-                            // isOu/isOuc
+							// user orgunits
                             if (dim.dimension === dimConf.organisationUnit.objectName && Ext.isArray(dim.items)) {
                                 for (var j = 0; j < dim.items.length; j++) {
                                     if (dim.items[j].id === 'USER_ORGUNIT') {
@@ -652,6 +651,9 @@
                                     else if (dim.items[j].id === 'USER_ORGUNIT_CHILDREN') {
                                         isOuc = true;
                                     }
+									else if (dim.items[j].id === 'USER_ORGUNIT_GRANDCHILDREN') {
+										isOugc = true;
+									}
                                 }
                             }
                         }
@@ -691,6 +693,7 @@
 
                     layout.userOrganisationUnit = isOu;
                     layout.userOrganisationUnitChildren = isOuc;
+					layout.userOrganisationUnitGrandChildren = isOugc;
 
                     layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : null;
 
@@ -1076,6 +1079,7 @@
                         xOuDimension = xLayout.objectNameDimensionsMap[dimConf.organisationUnit.objectName],
                         isUserOrgunit = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT'),
                         isUserOrgunitChildren = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT_CHILDREN'),
+                        isUserOrgunitGrandChildren = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT_GRANDCHILDREN'),
                         isLevel = function() {
                             if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
                                 for (var i = 0; i < xOuDimension.ids.length; i++) {
@@ -1087,6 +1091,17 @@
 
                             return false;
                         }(),
+                        isGroup = function() {
+                            if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
+                                for (var i = 0; i < xOuDimension.ids.length; i++) {
+                                    if (xOuDimension.ids[i].substr(0,8) === 'OU_GROUP') {
+                                        return true;
+                                    }
+                                }
+                            }
+
+                            return false;
+                        }(),
                         ou = dimConf.organisationUnit.objectName,
                         layout;
 
@@ -1098,40 +1113,79 @@
 
                         // If ou and children
                         if (dim.dimensionName === ou) {
-                            if (isUserOrgunit || isUserOrgunitChildren) {
+                            if (isUserOrgunit || isUserOrgunitChildren || isUserOrgunitGrandChildren) {
+                                var userOu,
+                                    userOuc,
+                                    userOugc;
+
                                 if (isUserOrgunit) {
-                                    dim.items = dim.items.concat(init.user.ou);
+                                    userOu = [{
+                                        id: dv.init.user.ou,
+                                        name: response.metaData.names[dv.init.user.ou]
+                                    }];
                                 }
                                 if (isUserOrgunitChildren) {
-                                    dim.items = dim.items.concat(init.user.ouc);
-                                }
-                            }
-                            else if (isLevel) {
-
-                                // Items: get ids from metadata -> items
+                                    userOuc = [];
+
+                                    for (var j = 0; j < dv.init.user.ouc.length; j++) {
+                                        userOuc.push({
+                                            id: dv.init.user.ouc[j],
+                                            name: response.metaData.names[dv.init.user.ouc[j]]
+                                        });
+                                    }
+
+                                    userOuc = dv.util.array.sortObjectsByString(userOuc);
+                                }
+                                if (isUserOrgunitGrandChildren) {
+                                    var userOuOuc = [].concat(dv.init.user.ou, dv.init.user.ouc),
+                                        responseOu = response.metaData.ou;
+
+                                    userOugc = [];
+
+                                    for (var j = 0; j < responseOu.length; j++) {
+                                        if (!Ext.Array.contains(userOuOuc, responseOu[j])) {
+                                            userOugc.push({
+                                                id: responseOu[j],
+                                                name: response.metaData.names[responseOu[j]]
+                                            });
+                                        }
+                                    }
+
+                                    userOugc = dv.util.array.sortObjectsByString(userOugc);
+                                }
+
+                                dim.items = [].concat(userOu || [], userOuc || [], userOugc || []);
+                            }
+                            else if (isLevel || isGroup) {
+                                var responseOu = response.metaData.ou;
+
+                                for (var j = 0; j < responseOu.length; j++) {
+                                    dim.items.push({
+                                        id: responseOu[j],
+                                        name: response.metaData.names[responseOu[j]]
+                                    });
+                                }
+
+                                dim.items = dv.util.array.sortObjectsByString(dim.items);
+                            }
+                            else {
+                                dim.items = Ext.clone(xLayout.dimensionNameItemsMap[dim.dimensionName]);
+                            }
+                        }
+                        else {
+                            // Items: get ids from metadata -> items
+                            //if (Ext.isArray(metaDataDim) && dim.dimensionName !== dimConf.organisationUnit.dimensionName) {
+                            if (Ext.isArray(metaDataDim)) {
                                 for (var j = 0, ids = Ext.clone(response.metaData[dim.dimensionName]); j < ids.length; j++) {
                                     dim.items.push({
                                         id: ids[j],
                                         name: response.metaData.names[ids[j]]
                                     });
-
-                                    dim.items = util.array.sortObjectsByString(dim.items);
-                                }
-                            }
-                            else {
-                                dim.items = Ext.clone(xLayout.dimensionNameItemsMap[dim.dimensionName]);
-                            }
-                        }
-                        else {
-                            // Items: get ids from metadata -> items
-                            if (Ext.isArray(metaDataDim) && dim.dimensionName !== dimConf.organisationUnit.dimensionName) {
-                                for (var j = 0, ids = Ext.clone(response.metaData[dim.dimensionName]); j < ids.length; j++) {
-                                    dim.items.push({id: ids[j]});
                                 }
                             }
                             // Items: get items from xLayout
                             else {
-                                dim.items = Ext.clone(xLayout.dimensionNameItemsMap[dim.dimensionName]);
+                                dim.items = Ext.clone(xLayout.objectNameItemsMap[dim.objectName]);
                             }
                         }
                     }

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/i18n.vm'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/i18n.vm	2013-07-24 10:33:49 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/i18n.vm	2013-08-16 14:44:33 +0000
@@ -41,7 +41,6 @@
 	trend_line:'$encoder.jsEscape($i18n.getString( 'trend_line' ) , "'")',
 	hide_subtitle:'$encoder.jsEscape($i18n.getString( 'hide_subtitle' ) , "'")',
 	hide_legend:'$encoder.jsEscape($i18n.getString( 'hide_legend' ) , "'")',
-	user_orgunit:'$encoder.jsEscape($i18n.getString( 'user_orgunit' ) , "'")',
 	domain_axis_label:'$encoder.jsEscape($i18n.getString( 'domain_axis_label' ) , "'")',
 	range_axis_label:'$encoder.jsEscape($i18n.getString( 'range_axis_label' ) , "'")',
 	target:'$encoder.jsEscape($i18n.getString( 'target' ) , "'")',
@@ -122,7 +121,6 @@
 	wm_multiple_filter_orgunit:'$encoder.jsEscape($i18n.getString( 'wm_multiple_filter_orgunit' ) , "'")',
 	wm_multiple_filter_groups:'$encoder.jsEscape($i18n.getString( 'wm_multiple_filter_groups' ) , "'")',
 	wm_first_filter_used:'$encoder.jsEscape($i18n.getString( 'wm_first_filter_used' ) , "'")',
-	user_orgunit_children:'$encoder.jsEscape($i18n.getString( 'user_orgunit_children' ) , "'")',
 	show_data:'$encoder.jsEscape($i18n.getString( 'show_data' ) , "'")',
 	share:'$encoder.jsEscape($i18n.getString( 'share' ) , "'")',
 	interpretation:'$encoder.jsEscape($i18n.getString( 'interpretation' ) , "'")',
@@ -164,6 +162,7 @@
 	next_year: '$encoder.jsEscape($i18n.getString( 'next_year' ) , "'")',
 	user_organisation_unit: '$encoder.jsEscape($i18n.getString( 'user_organisation_unit' ) , "'")',
 	user_organisation_unit_children: '$encoder.jsEscape($i18n.getString( 'user_organisation_unit_children' ) , "'")',
+	user_organisation_unit_grandchildren: '$encoder.jsEscape($i18n.getString( 'user_organisation_unit_grandchildren' ) , "'")',
 	filters: '$encoder.jsEscape($i18n.getString( 'filters' ) , "'")',
 	at_least_one_dimension_must_be_specified_as_row_or_column: '$encoder.jsEscape($i18n.getString( 'at_least_one_dimension_must_be_specified_as_row_or_column' ) , "'")',
 	at_least_one_period_must_be_specified_as_column_row_or_filter: '$encoder.jsEscape($i18n.getString( 'at_least_one_period_must_be_specified_as_column_row_or_filter' ) , "'")',
@@ -196,7 +195,10 @@
 	graphics: '$encoder.jsEscape($i18n.getString( 'graphics' ) , "'")',
     sharing_settings: '$encoder.jsEscape($i18n.getString( 'sharing_settings' ) , "'")',
 	select_organisation_units: '$encoder.jsEscape($i18n.getString( 'select_organisation_units' ) , "'")',
-	select_boundaries_and_level: '$encoder.jsEscape($i18n.getString( 'select_boundaries_and_level' ) , "'")',
-	select_organisation_unit_level: '$encoder.jsEscape($i18n.getString( 'select_organisation_unit_level' ) , "'")',
-	radar_chart: '$encoder.jsEscape($i18n.getString( 'radar_chart' ) , "'")'
+	select_boundaries_and_levels: '$encoder.jsEscape($i18n.getString( 'select_boundaries_and_levels' ) , "'")',
+	select_organisation_unit_levels: '$encoder.jsEscape($i18n.getString( 'select_organisation_unit_levels' ) , "'")',
+	radar_chart: '$encoder.jsEscape($i18n.getString( 'radar_chart' ) , "'")',
+	select_boundaries_and_groups: '$encoder.jsEscape($i18n.getString( 'select_boundaries_and_groups' ) , "'")',
+	select_organisation_unit_groups: '$encoder.jsEscape($i18n.getString( 'select_organisation_unit_groups' ) , "'")',
+    user_organisation_unit_grandchildren: '$encoder.jsEscape($i18n.getString( 'user_organisation_unit_grandchildren' ) , "'")'
 };

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/jsonInitialize.vm'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/jsonInitialize.vm	2013-08-02 12:12:32 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/jsonInitialize.vm	2013-08-16 14:44:33 +0000
@@ -5,8 +5,8 @@
 {
 "contextPath":"$!{contextPath}",
 "user":{"id":"$!currentUser.uid","name":"$currentUser.name","isAdmin":true,
-"ou":{"id":"$currentUser.getOrganisationUnit().uid","name":"$currentUser.getOrganisationUnit().name"},
-"ouc":[#foreach($ou in $currentUser.getOrganisationUnit().getSortedChildren()){"id":"$ou.uid","name":"$ou.name"}#if($velocityCount < $oucSize),#end#end]},
+"ou":"$currentUser.getOrganisationUnit().uid",
+"ouc":[#foreach($ou in $currentUser.getOrganisationUnit().getSortedChildren())"$ou.uid"#if($velocityCount < $oucSize),#end#end]},
 "rootNodes":[#foreach($node in $rootNodes){"id": "$!{node.uid}","text": "$!encoder.jsonEncode( ${node.name} )","level": 1,"hasChildrenWithCoordinates": $!{node.hasChildrenWithCoordinates()},"expanded": true}#if($velocityCount<$rootNodes.size()),#end#end],
 "dimensions":[#foreach($dim in $dimensions){"id":"$!{dim.uid}","name":"$!encoder.jsonEncode($!{dim.name})"}#if($velocityCount<$dimensions.size()),#end#end],
 "organisationUnitLevels":[#foreach($level in $levels){"id":"$!{level.uid}","name":"$!encoder.jsonEncode($!{level.name})","level":"$!{level.level}"}#if($velocityCount<$levels.size()),#end#end]