← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 11265: (PT, DV) Select orgunits by boundary/level option implemented.

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 11265 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2013-06-26 14:20:31 +0200
message:
  (PT, DV) Select orgunits by boundary/level option implemented.
added:
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/check.png
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/gear_18.png
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/images/check.png
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/images/gear_18.png
modified:
  dhis-2/dhis-web/dhis-web-pivot/src/main/java/org/hisp/dhis/pivot/action/InitializeAction.java
  dhis-2/dhis-web/dhis-web-pivot/src/main/resources/org/hisp/dhis/pivot/i18n_module.properties
  dhis-2/dhis-web/dhis-web-pivot/src/main/resources/org/hisp/dhis/pivot/i18n_module_fr_FR.properties
  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-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/i18n.vm
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/jsonInitialize.vm
  dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/InitializeAction.java
  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_fr_FR.properties
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/style.css
  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/java/org/hisp/dhis/pivot/action/InitializeAction.java'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/java/org/hisp/dhis/pivot/action/InitializeAction.java	2013-06-05 20:11:33 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/java/org/hisp/dhis/pivot/action/InitializeAction.java	2013-06-24 17:06:04 +0000
@@ -39,6 +39,7 @@
 import org.hisp.dhis.mapping.MapLegendSet;
 import org.hisp.dhis.mapping.MappingService;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
@@ -194,6 +195,13 @@
         return legendSets;
     }
     
+    private Collection<OrganisationUnitLevel> levels;
+
+    public Collection<OrganisationUnitLevel> getLevels()
+    {
+        return levels;
+    }
+    
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -245,6 +253,8 @@
         dimensions = dimensionService.getAllDimensions();
         
         legendSets = mappingService.getAllMapLegendSets();
+        
+        levels = organisationUnitService.getOrganisationUnitLevels();
 
         return SUCCESS;
     }

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/resources/org/hisp/dhis/pivot/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/resources/org/hisp/dhis/pivot/i18n_module.properties	2013-06-05 20:11:33 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/resources/org/hisp/dhis/pivot/i18n_module.properties	2013-06-25 16:34:25 +0000
@@ -121,4 +121,7 @@
 share=Share
 interpretation=interpretation
 write_your_interpretation=Write a comment, question or interpretation
-legend_set=Legend set
\ No newline at end of file
+legend_set=Legend set
+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

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/resources/org/hisp/dhis/pivot/i18n_module_fr_FR.properties'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/resources/org/hisp/dhis/pivot/i18n_module_fr_FR.properties	2013-06-05 20:11:33 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/resources/org/hisp/dhis/pivot/i18n_module_fr_FR.properties	2013-06-25 16:34:25 +0000
@@ -116,4 +116,7 @@
 data_sets_cannot_be_specified_as_filter=Ensembles de donn\u00E9es ne peuvent \u00EAtre d\u00E9finies comme filtre
 share=Partager
 interpretation=interpr\u00E9tation
-legend_set=Jeu de l\u00E9gendes
\ No newline at end of file
+legend_set=Jeu de l\u00E9gendes
+select_organisation_units=S\u00E9lectionner les unit\u00E9s d'organisation
+select_boundaries_and_level=S\u00E9lectionner limites et le niveau
+select_organisation_unit_level=S\u00E9lectionner le niveau de l'unit\u00E9 d'organisation
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/check.png'
Binary files dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/check.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/check.png	2013-06-26 12:18:21 +0000 differ
=== added file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/gear_18.png'
Binary files dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/gear_18.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/images/gear_18.png	2013-06-25 13:50:23 +0000 differ
=== 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-06-05 20:11:33 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js	2013-06-25 18:26:47 +0000
@@ -2033,9 +2033,13 @@
 				fixedPeriodAvailable,
 				fixedPeriodSelected,
 				period,
+				treePanel,
 				userOrganisationUnit,
 				userOrganisationUnitChildren,
-				treePanel,
+				userOrganisationUnitPanel,
+				organisationUnitLevel,
+				tool,
+				toolPanel,
 				organisationUnit,
 				dimensionIdAvailableStoreMap = {},
 				dimensionIdSelectedStoreMap = {},
@@ -3256,6 +3260,7 @@
 
 			userOrganisationUnit = Ext.create('Ext.form.field.Checkbox', {
 				columnWidth: 0.5,
+				style: 'padding-top:2px; padding-left:3px; margin-bottom:0',
 				boxLabel: PT.i18n.user_organisation_unit,
 				labelWidth: pt.conf.layout.form_label_width,
 				handler: function(chb, checked) {
@@ -3265,17 +3270,114 @@
 
 			userOrganisationUnitChildren = Ext.create('Ext.form.field.Checkbox', {
 				columnWidth: 0.5,
+				style: 'padding-top:2px; margin-bottom:0',
 				boxLabel: PT.i18n.user_organisation_unit_children,
 				labelWidth: pt.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: 'pt-combo',
+				style: 'margin-bottom:0',
+				width: pt.conf.layout.west_fieldset_width - pt.conf.layout.west_width_padding - 38,
+				valueField: 'level',
+				displayField: 'name',
+				emptyText: PT.i18n.select_organisation_unit_level,
+				editable: false,
+				hidden: true,
+				store: {
+					fields: ['id', 'name', 'level'],
+					data: pt.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('pt-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: PT.i18n.select_organisation_units + '&nbsp;&nbsp;',
+						param: 'explicit',
+						iconCls: 'pt-menu-item-selected'
+					},
+					{
+						text: PT.i18n.select_boundaries_and_level + '&nbsp;&nbsp;',
+						param: 'boundary'
+					}
+				],
+				listeners: {
+					afterrender: function() {
+						this.getEl().addCls('pt-btn-menu');
+					},
+					click: function(menu, item) {
+						this.clickHandler(item.param);
+					}
+				}
+			});
+			
+			tool = Ext.create('Ext.button.Button', {
+				cls: 'pt-button-organisationunitselection',
+				iconCls: 'pt-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="pt-panel-title-organisationunit">' + PT.i18n.organisation_units + '</div>',
-				bodyStyle: 'padding-top:5px',
+				bodyStyle: 'padding:2px',
 				hideCollapseTool: true,
 				collapsed: false,
 				getDimension: function() {
@@ -3284,21 +3386,28 @@
 							dimension: pt.conf.finals.dimension.organisationUnit.objectName,
 							items: []
 						};
-
-					if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue()) {
-						if (userOrganisationUnit.getValue()) {
-							config.items.push({id: 'USER_ORGUNIT'});
+						
+					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'});
+							}
 						}
-						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 {
+					else if (toolMenu.menuValue === 'boundary') {
 						for (var i = 0; i < r.length; i++) {
-							config.items.push({id: r[i].data.id});
+							config.items.push({id: 'LEVEL-' + organisationUnitLevel.getValue() + '-' + r[i].data.id});
 						}
 					}
-
+					
 					return config.items.length ? config : null;
 				},
 				onExpand: function() {
@@ -3310,14 +3419,25 @@
 				items: [
 					{
 						layout: 'column',
-						bodyStyle: 'border:0 none; padding-bottom:3px; padding-left:7px',
+						bodyStyle: 'border:0 none',
+						style: 'padding-bottom:2px',
 						items: [
-							userOrganisationUnit,
-							userOrganisationUnitChildren
+							toolPanel,
+							{
+								width: pt.conf.layout.west_fieldset_width - pt.conf.layout.west_width_padding - 38,
+								layout: 'column',
+								bodyStyle: 'border:0 none',
+								items: [
+									userOrganisationUnit,
+									userOrganisationUnitChildren,
+									organisationUnitLevel
+								]
+							}							
 						]
 					},
 					treePanel
 				],
+				suppressExpand: false,
 				listeners: {
 					added: function() {
 						pt.cmp.dimension.panels.push(this);
@@ -3940,7 +4060,8 @@
 					fixedPeriodRecords = [],
                     dimNames = [],
 					isOu = false,
-					isOuc = false;
+					isOuc = false,
+					isLevel = false;
 
 				// State
 				pt.viewport.interpretationButton.enable();
@@ -4089,11 +4210,29 @@
 						if (ouRecords[i].id === 'USER_ORGUNIT_CHILDREN') {
 							isOuc = 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);
+					userOrganisationUnit.setValue(isOu);
+					userOrganisationUnitChildren.setValue(isOuc);
+				}
 
 				// 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-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-06-06 06:23:39 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js	2013-06-25 17:47:12 +0000
@@ -844,6 +844,17 @@
 						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'),
+						isLevel = function() {
+							if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
+								for (var i = 0; i < xOuDimension.ids.length; i++) {
+									if (xOuDimension.ids[i].substr(0,5) === 'LEVEL') {
+										return true;
+									}
+								}
+							}
+							
+							return false;
+						}(),
 						co = dimConf.category.objectName,
 						ou = dimConf.organisationUnit.objectName,
 						layout;
@@ -864,6 +875,18 @@
 									dim.items = dim.items.concat(pt.init.user.ouc);
 								}
 							}
+							else if (isLevel) {
+								
+								// Items: get ids from metadata -> items
+								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 = pt.util.array.sortObjectsByString(dim.items);
+								}
+							}
 							else {
 								dim.items = Ext.clone(xLayout.dimensionNameItemsMap[dim.dimensionName]);
 							}

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css	2013-06-05 20:11:33 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css	2013-06-25 16:34:25 +0000
@@ -513,6 +513,16 @@
     padding-left: 18px;
 }
 
+.pt-menu-item-selected {
+    background-image:url('../images/check.png');
+    padding-left: 18px;
+}
+
+	/* Menu align */
+.pt-btn-menu {
+	margin-top: 2px;
+}
+
 /*----------------------------------------------------------------------------
  * Button
  *--------------------------------------------------------------------------*/
@@ -552,6 +562,19 @@
     background-image: linear-gradient(top, #d1d1d1,#e5e5e5);
 }
 
+/*----------------------------------------------------------------------------
+ * PT Button
+ *--------------------------------------------------------------------------*/
+
+.pt-button-icon-gear {
+	width: 22px !important;
+	height: 22px !important;
+	background: url('../images/gear_18.png') no-repeat;
+}
+
+.pt-button-organisationunitselection .x-btn-center {
+	width: 18px !important;
+}
 
 /*----------------------------------------------------------------------------
  * Tooltip

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/i18n.vm'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/i18n.vm	2013-06-05 20:11:33 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/i18n.vm	2013-06-25 16:34:25 +0000
@@ -122,5 +122,8 @@
 	share: '$encoder.jsEscape($i18n.getString( 'share' ) , "'")',
 	interpretation: '$encoder.jsEscape($i18n.getString( 'interpretation' ) , "'")',
 	write_your_interpretation: '$encoder.jsEscape($i18n.getString( 'write_your_interpretation' ) , "'")',
-	legend_set: '$encoder.jsEscape($i18n.getString( 'legend_set' ) , "'")'
+	legend_set: '$encoder.jsEscape($i18n.getString( 'legend_set' ) , "'")',
+	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' ) , "'")'
 };

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/jsonInitialize.vm'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/jsonInitialize.vm	2013-06-05 20:11:33 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/jsonInitialize.vm	2013-06-24 17:06:04 +0000
@@ -5,5 +5,6 @@
 "ouc":[#foreach($ou in $currentUser.getOrganisationUnit().getSortedChildren()){"id":"$ou.uid","name":"$ou.name"}#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],
-"legendSets":[#foreach($set in $legendSets){"id":"$!{set.uid}","name":"$!encoder.jsonEncode($!{set.name})", "legends":[#foreach($legend in $set.mapLegends){"id":"$!{legend.uid}","name":"$!{legend.name}","sv":"$!{legend.startValue}", "ev":"$!{legend.endValue}", "color":"$!{legend.color}"}#if($velocityCount<$set.mapLegends.size()),#end#end]}#if($velocityCount<$legendSets.size()),#end#end]
+"legendSets":[#foreach($set in $legendSets){"id":"$!{set.uid}","name":"$!encoder.jsonEncode($!{set.name})", "legends":[#foreach($legend in $set.mapLegends){"id":"$!{legend.uid}","name":"$!{legend.name}","sv":"$!{legend.startValue}", "ev":"$!{legend.endValue}", "color":"$!{legend.color}"}#if($velocityCount<$set.mapLegends.size()),#end#end]}#if($velocityCount<$legendSets.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]
 }
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/InitializeAction.java'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/InitializeAction.java	2013-04-23 17:32:47 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/InitializeAction.java	2013-06-26 12:18:21 +0000
@@ -38,6 +38,7 @@
 import org.hisp.dhis.i18n.I18nFormat;
 import org.hisp.dhis.mapping.MapLegendSet;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
@@ -186,6 +187,13 @@
         return legendSets;
     }
     
+    private Collection<OrganisationUnitLevel> levels;
+
+    public Collection<OrganisationUnitLevel> getLevels()
+    {
+        return levels;
+    }
+    
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -235,6 +243,8 @@
         last5Years = periodService.reloadPeriods( setNames( rp.getRelativePeriods() ) );
         
         dimensions = dimensionService.getAllDimensions();
+        
+        levels = organisationUnitService.getOrganisationUnitLevels();
 
         return SUCCESS;
     }

=== 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-05-29 15:57:30 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/org/hisp/dhis/visualizer/i18n_module.properties	2013-06-26 12:18:21 +0000
@@ -195,4 +195,7 @@
 plain_data_sources=Plain data source
 graphics=Graphics
 write_your_interpretation=Write a comment, question or interpretation
-sharing_settings=Sharing settings
\ No newline at end of file
+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

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/org/hisp/dhis/visualizer/i18n_module_fr_FR.properties'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/org/hisp/dhis/visualizer/i18n_module_fr_FR.properties	2013-05-29 15:57:30 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/org/hisp/dhis/visualizer/i18n_module_fr_FR.properties	2013-06-26 12:18:21 +0000
@@ -174,4 +174,7 @@
 create=Cr\u00E9er
 plain_data_sources=Source de donn\u00E9es simples
 graphics=Graphique
-sharing_settings=Param\u00E8tres de partage
\ No newline at end of file
+sharing_settings=Param\u00E8tres de partage
+select_organisation_units=S\u00E9lectionner les unit\u00E9s d'organisation
+select_boundaries_and_level=S\u00E9lectionner limites et le niveau
+select_organisation_unit_level=S\u00E9lectionner le niveau de l'unit\u00E9 d'organisation
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/style.css'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/style.css	2013-05-29 13:34:16 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/style.css	2013-06-26 12:18:21 +0000
@@ -387,6 +387,21 @@
 
 
 /*----------------------------------------------------------------------------
+ * DV Button
+ *--------------------------------------------------------------------------*/
+
+.dv-button-icon-gear {
+	width: 22px !important;
+	height: 22px !important;
+	background: url('../images/gear_18.png') no-repeat;
+}
+
+.dv-button-organisationunitselection .x-btn-center {
+	width: 18px !important;
+}
+
+
+/*----------------------------------------------------------------------------
  * Tooltip
  *--------------------------------------------------------------------------*/
 
@@ -754,6 +769,21 @@
  * DV Menu
  *--------------------------------------------------------------------------*/
 
+.dv-menu-item-selected {
+    background-image:url('../images/check.png');
+    padding-left: 18px;
+}
+
+	/* Menu align */
+.dv-btn-menu {
+	margin-top: 2px;
+}
+
+
+/*----------------------------------------------------------------------------
+ * DV Menu
+ *--------------------------------------------------------------------------*/
+
 	/* Menu item icon */
 .dv-menu-item-image {
     background-image:url('../images/dl_image.png');

=== added file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/images/check.png'
Binary files dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/images/check.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/images/check.png	2013-06-26 12:18:21 +0000 differ
=== added file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/images/gear_18.png'
Binary files dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/images/gear_18.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/images/gear_18.png	2013-06-26 12:18:21 +0000 differ
=== 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-06-05 17:33:09 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js	2013-06-26 12:18:21 +0000
@@ -2018,9 +2018,13 @@
 				fixedPeriodAvailable,
 				fixedPeriodSelected,
 				period,
+				treePanel,
 				userOrganisationUnit,
 				userOrganisationUnitChildren,
-				treePanel,
+				userOrganisationUnitPanel,
+				organisationUnitLevel,
+				tool,
+				toolPanel,
 				organisationUnit,
 				dimensionIdAvailableStoreMap = {},
 				dimensionIdSelectedStoreMap = {},
@@ -3562,6 +3566,7 @@
 
 			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) {
@@ -3571,6 +3576,7 @@
 
 			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) {
@@ -3578,10 +3584,106 @@
 				}
 			});
 
+			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-top:5px',
+				bodyStyle: 'padding:2px',
 				hideCollapseTool: true,
 				collapsed: false,
 				getDimension: function() {
@@ -3590,21 +3692,28 @@
 							dimension: dv.conf.finals.dimension.organisationUnit.objectName,
 							items: []
 						};
-
-					if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue()) {
-						if (userOrganisationUnit.getValue()) {
-							config.items.push({id: 'USER_ORGUNIT'});
+						
+					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'});
+							}
 						}
-						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 {
+					else if (toolMenu.menuValue === 'boundary') {
 						for (var i = 0; i < r.length; i++) {
-							config.items.push({id: r[i].data.id});
+							config.items.push({id: 'LEVEL-' + organisationUnitLevel.getValue() + '-' + r[i].data.id});
 						}
 					}
-
+					
 					return config.items.length ? config : null;
 				},
 				onExpand: function() {
@@ -3616,10 +3725,20 @@
 				items: [
 					{
 						layout: 'column',
-						bodyStyle: 'border:0 none; padding-bottom:3px; padding-left:7px',
+						bodyStyle: 'border:0 none',
+						style: 'padding-bottom:2px',
 						items: [
-							userOrganisationUnit,
-							userOrganisationUnitChildren
+							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
@@ -3885,7 +4004,7 @@
 
 						// Categories as filter
 						//if (layout.filters[i].dimension === dimConf.category.objectName) {
-							//alert(PT.i18n.categories_cannot_be_specified_as_filter);
+							//alert(DV.i18n.categories_cannot_be_specified_as_filter);
 							//return;
 						//}
 

=== 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-05-29 16:21:49 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/core.js	2013-06-26 12:18:21 +0000
@@ -3,7 +3,7 @@
 };
 
 Ext.onReady( function() {
-
+	
 DV.core.getConfig = function() {
 	var conf = {};
 
@@ -700,6 +700,17 @@
 					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'),
+					isLevel = function() {
+						if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
+							for (var i = 0; i < xOuDimension.ids.length; i++) {
+								if (xOuDimension.ids[i].substr(0,5) === 'LEVEL') {
+									return true;
+								}
+							}
+						}
+						
+						return false;
+					}(),
 					ou = dimConf.organisationUnit.objectName,
 					layout;
 
@@ -719,6 +730,18 @@
 								dim.items = dim.items.concat(dv.init.user.ouc);
 							}
 						}
+						else if (isLevel) {
+							
+							// Items: get ids from metadata -> items
+							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 = dv.util.array.sortObjectsByString(dim.items);
+							}
+						}
 						else {
 							dim.items = Ext.clone(xLayout.dimensionNameItemsMap[dim.dimensionName]);
 						}
@@ -1524,8 +1547,7 @@
 
 					//if (xLayout.showValues) {
 						//line.label = {
-							//display: 'rotate',
-							//'text-anchor': 'middle',
+							//display: 'over',
 							//field: store.rangeFields[i]
 						//};
 					//}
@@ -1674,7 +1696,7 @@
 				xLayout = util.chart.getExtendedLayout(layout);
 
 				dv.paramString = util.chart.getParamString(xLayout, true);
-				url = dv.init.contextPath + '/api/analytics.json' + dv.paramString;
+				url = dv.init.contextPath + '/api/analytics.json' + dv.paramString;				
 
 				if (!validateUrl(url)) {
 					return;

=== 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-05-29 15:57:30 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/i18n.vm	2013-06-26 12:18:21 +0000
@@ -195,4 +195,7 @@
 	plain_data_sources: '$encoder.jsEscape($i18n.getString( 'plain_data_sources' ) , "'")',
 	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' ) , "'")'
 };

=== 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-04-23 17:32:47 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/jsonInitialize.vm	2013-06-26 12:18:21 +0000
@@ -4,5 +4,6 @@
 "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]},
 "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]							
+"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]
 }
\ No newline at end of file


Follow ups