← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15784: PT DV GIS ER EV api sync.

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 15784 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2014-06-20 13:32:24 +0200
message:
  PT DV GIS ER EV api sync.
modified:
  dhis-2/dhis-web/dhis-web-event-reports/src/main/webapp/dhis-web-event-reports/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-event-visualizer/src/main/webapp/dhis-web-event-visualizer/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js


--
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-event-reports/src/main/webapp/dhis-web-event-reports/app/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-event-reports/src/main/webapp/dhis-web-event-reports/app/scripts/app.js	2014-06-16 13:51:41 +0000
+++ dhis-2/dhis-web/dhis-web-event-reports/src/main/webapp/dhis-web-event-reports/app/scripts/app.js	2014-06-20 11:31:08 +0000
@@ -3159,7 +3159,7 @@
 			fields: ['id', 'name'],
 			proxy: {
 				type: 'ajax',
-				url: ns.core.init.contextPath + '/api/organisationUnitGroups.json?paging=false&links=false',
+				url: ns.core.init.contextPath + '/api/organisationUnitGroups.json?fields=id,name&paging=false',
 				reader: {
 					type: 'json',
 					root: 'organisationUnitGroups'
@@ -4547,13 +4547,14 @@
 					format: 'json',
 					noCache: false,
 					extraParams: {
-						links: 'false'
+						fields: 'children[id,name,level]'
 					},
 					url: ns.core.init.contextPath + '/api/organisationUnits',
 					reader: {
 						type: 'json',
 						root: 'children'
-					}
+					},
+					sortParam: false
 				},
 				sorters: [{
 					property: 'name',
@@ -4566,9 +4567,17 @@
 				},
 				listeners: {
 					load: function(store, node, records) {
+                        var numberOfLevels = ns.core.init.organisationUnitLevels.length;
+
 						Ext.Array.each(records, function(record) {
-							record.set('leaf', !record.raw.hasChildren);
-						});
+                            //if (Ext.isBoolean(record.data.hasChildren)) {
+                                //record.set('leaf', !record.data.hasChildren);
+                            //}
+
+                            if (Ext.isNumber(numberOfLevels)) {
+                                record.set('leaf', parseInt(record.raw.level) === numberOfLevels);
+                            }
+                        });
 					}
 				}
 			}),

=== modified file 'dhis-2/dhis-web/dhis-web-event-visualizer/src/main/webapp/dhis-web-event-visualizer/app/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-event-visualizer/src/main/webapp/dhis-web-event-visualizer/app/scripts/app.js	2014-06-17 15:44:02 +0000
+++ dhis-2/dhis-web/dhis-web-event-visualizer/src/main/webapp/dhis-web-event-visualizer/app/scripts/app.js	2014-06-20 11:31:08 +0000
@@ -4197,13 +4197,14 @@
 					format: 'json',
 					noCache: false,
 					extraParams: {
-						links: 'false'
+						fields: 'children[id,name,level]'
 					},
 					url: ns.core.init.contextPath + '/api/organisationUnits',
 					reader: {
 						type: 'json',
 						root: 'children'
-					}
+					},
+					sortParam: false
 				},
 				sorters: [{
 					property: 'name',
@@ -4216,9 +4217,17 @@
 				},
 				listeners: {
 					load: function(store, node, records) {
+                        var numberOfLevels = ns.core.init.organisationUnitLevels.length;
+
 						Ext.Array.each(records, function(record) {
-							record.set('leaf', !record.raw.hasChildren);
-						});
+                            //if (Ext.isBoolean(record.data.hasChildren)) {
+                                //record.set('leaf', !record.data.hasChildren);
+                            //}
+
+                            if (Ext.isNumber(numberOfLevels)) {
+                                record.set('leaf', parseInt(record.raw.level) === numberOfLevels);
+                            }
+                        });
 					}
 				}
 			}),

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/app.js	2014-06-12 11:37:11 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/app.js	2014-06-20 10:41:50 +0000
@@ -514,7 +514,7 @@
 				fields: ['id', 'name'],
 				proxy: {
 					type: 'ajax',
-					url: gis.init.contextPath + gis.conf.finals.url.path_api + 'organisationUnitGroupSets.json?paging=false&links=false',
+					url: gis.init.contextPath + '/api/organisationUnitGroupSets.json?fields=id,name&paging=false',
 					reader: {
 						type: 'json',
 						root: 'organisationUnitGroupSets'
@@ -547,7 +547,7 @@
 				fields: ['id', 'name'],
 				proxy: {
 					type: 'ajax',
-					url: init.contextPath + '/api/organisationUnitGroups.json?paging=false&links=false',
+					url: init.contextPath + '/api/organisationUnitGroups.json?fields=id,name&paging=false',
 					reader: {
 						type: 'json',
 						root: 'organisationUnitGroups'
@@ -559,7 +559,7 @@
 				fields: ['id', 'name'],
 				proxy: {
 					type: 'ajax',
-					url: gis.init.contextPath + gis.conf.finals.url.path_api + 'mapLegendSets.json?links=false&paging=false',
+					url: gis.init.contextPath + '/api/mapLegendSets.json?fields=id,name&paging=false',
 					reader: {
 						type: 'json',
 						root: 'mapLegendSets'
@@ -585,7 +585,7 @@
 			});
 
 			store.maps = Ext.create('Ext.data.Store', {
-				fields: ['id', 'name', 'lastUpdated', 'access'],
+				fields: ['id', 'name', 'access'],
 				proxy: {
 					type: 'ajax',
 					reader: {
@@ -596,7 +596,7 @@
 				isLoaded: false,
 				pageSize: 10,
 				page: 1,
-				defaultUrl: gis.init.contextPath + gis.conf.finals.url.path_api + 'maps.json?viewClass=sharing&fields=id,name,access',
+				defaultUrl: gis.init.contextPath + gis.conf.finals.url.path_api + 'maps.json?fields=id,name,access',
 				loadStore: function(url) {
 					this.proxy.url = url || this.defaultUrl;
 
@@ -915,32 +915,54 @@
 		});
 
         var operatorCmpWidth = 70,
-            valueCmpWidth = 304,
+            valueCmpWidth = 306,
             buttonCmpWidth = 20,
-            nameCmpWidth = 400;
+            nameCmpWidth = 400,
+            namePadding = '2px 3px',
+            margin = '3px 0 1px';
 
         Ext.define('Ext.ux.panel.DataElementIntegerContainer', {
 			extend: 'Ext.container.Container',
 			alias: 'widget.dataelementintegerpanel',
 			layout: 'column',
             bodyStyle: 'border:0 none',
+            style: 'margin: ' + margin,
             getRecord: function() {
-                return {
-                    id: this.dataElement.id,
-                    name: this.dataElement.name,
-                    operator: this.operatorCmp.getValue(),
-                    value: this.valueCmp.getValue()
-                };
+                var record = {};
+
+                record.dimension = this.dataElement.id;
+                record.name = this.dataElement.name;
+
+                if (this.valueCmp.getValue()) {
+					record.filter = this.operatorCmp.getValue() + ':' + this.valueCmp.getValue();
+				}
+
+				return record;
             },
+            setRecord: function(record) {
+				if (record.filter) {
+					var a = record.filter.split(':');
+
+					this.operatorCmp.setValue(a[0]);
+					this.valueCmp.setValue(a[1]);
+				}
+			},
             initComponent: function() {
                 var container = this;
 
+                this.nameCmp = Ext.create('Ext.form.Label', {
+                    text: this.dataElement.name,
+                    width: nameCmpWidth,
+                    style: 'padding:' + namePadding
+                });
+
                 this.operatorCmp = Ext.create('Ext.form.field.ComboBox', {
                     valueField: 'id',
                     displayField: 'name',
                     queryMode: 'local',
                     editable: false,
                     width: operatorCmpWidth,
+					style: 'margin-bottom:0',
                     value: 'EQ',
                     store: {
                         fields: ['id', 'name'],
@@ -957,7 +979,7 @@
 
                 this.valueCmp = Ext.create('Ext.form.field.Number', {
                     width: valueCmpWidth,
-                    value: 0
+					style: 'margin-bottom:0'
                 });
 
                 this.addCmp = Ext.create('Ext.button.Button', {
@@ -976,12 +998,6 @@
                     }
                 });
 
-                this.nameCmp = Ext.create('Ext.form.Label', {
-                    text: this.dataElement.name,
-                    width: nameCmpWidth,
-                    style: 'padding:2px'
-                });
-
                 this.items = [
                     this.nameCmp,
                     this.operatorCmp,
@@ -996,26 +1012,42 @@
 
         Ext.define('Ext.ux.panel.DataElementStringContainer', {
 			extend: 'Ext.container.Container',
-			alias: 'widget.dataelementintegerpanel',
+			alias: 'widget.dataelementstringpanel',
 			layout: 'column',
             bodyStyle: 'border:0 none',
+            style: 'margin: ' + margin,
             getRecord: function() {
-                return {
-                    id: this.dataElement.id,
-                    name: this.dataElement.name,
-                    operator: this.operatorCmp.getValue(),
-                    value: this.valueCmp.getValue()
-                };
+                var record = {};
+
+                record.dimension = this.dataElement.id;
+                record.name = this.dataElement.name;
+
+                if (this.valueCmp.getValue()) {
+					record.filter = this.operatorCmp.getValue() + ':' + this.valueCmp.getValue();
+				}
+
+				return record;
+            },
+            setRecord: function(record) {
+                this.operatorCmp.setValue(record.operator);
+                this.valueCmp.setValue(record.filter);
             },
             initComponent: function() {
                 var container = this;
 
+                this.nameCmp = Ext.create('Ext.form.Label', {
+                    text: this.dataElement.name,
+                    width: nameCmpWidth,
+                    style: 'padding:' + namePadding
+                });
+
                 this.operatorCmp = Ext.create('Ext.form.field.ComboBox', {
                     valueField: 'id',
                     displayField: 'name',
                     queryMode: 'local',
                     editable: false,
                     width: operatorCmpWidth,
+					style: 'margin-bottom:0',
                     value: 'LIKE',
                     store: {
                         fields: ['id', 'name'],
@@ -1027,12 +1059,16 @@
                 });
 
                 this.valueCmp = Ext.create('Ext.form.field.Text', {
-                    width: valueCmpWidth
+                    width: valueCmpWidth,
+					style: 'margin-bottom:0'
                 });
 
                 this.addCmp = Ext.create('Ext.button.Button', {
                     text: '+',
-                    width: buttonCmpWidth
+                    width: buttonCmpWidth,
+                    handler: function() {
+						container.duplicateDataElement();
+					}
                 });
 
                 this.removeCmp = Ext.create('Ext.button.Button', {
@@ -1043,12 +1079,6 @@
                     }
                 });
 
-                this.nameCmp = Ext.create('Ext.form.Label', {
-                    text: this.dataElement.name,
-                    width: nameCmpWidth,
-                    style: 'padding:2px'
-                });
-
                 this.items = [
                     this.nameCmp,
                     this.operatorCmp,
@@ -1066,23 +1096,43 @@
 			alias: 'widget.dataelementdatepanel',
 			layout: 'column',
             bodyStyle: 'border:0 none',
+            style: 'margin: ' + margin,
             getRecord: function() {
-                return {
-                    id: this.dataElement.id,
-                    name: this.dataElement.name,
-                    operator: this.operatorCmp.getValue(),
-                    value: this.valueCmp.getSubmitValue()
-                };
+                var record = {};
+
+                record.dimension = this.dataElement.id;
+                record.name = this.dataElement.name;
+
+                if (this.valueCmp.getValue()) {
+					record.filter = this.operatorCmp.getValue() + ':' + this.valueCmp.getSubmitValue();
+				}
+
+				return record;
+            },
+            setRecord: function(record) {
+				if (record.filter && Ext.isString(record.filter)) {
+					var a = record.filter.split(':');
+
+					this.operatorCmp.setValue(a[0]);
+					this.valueCmp.setValue(a[1]);
+				}
             },
             initComponent: function() {
                 var container = this;
 
+                this.nameCmp = Ext.create('Ext.form.Label', {
+                    text: this.dataElement.name,
+                    width: nameCmpWidth,
+                    style: 'padding:' + namePadding
+                });
+
                 this.operatorCmp = Ext.create('Ext.form.field.ComboBox', {
                     valueField: 'id',
                     displayField: 'name',
                     queryMode: 'local',
                     editable: false,
                     width: operatorCmpWidth,
+                    style: 'margin-bottom:0',
                     value: 'EQ',
                     store: {
                         fields: ['id', 'name'],
@@ -1099,12 +1149,16 @@
 
                 this.valueCmp = Ext.create('Ext.form.field.Date', {
 					width: valueCmpWidth,
+					style: 'margin-bottom:0',
 					format: 'Y-m-d'
 				});
 
                 this.addCmp = Ext.create('Ext.button.Button', {
                     text: '+',
-                    width: buttonCmpWidth
+                    width: buttonCmpWidth,
+                    handler: function() {
+						container.duplicateDataElement();
+					}
                 });
 
                 this.removeCmp = Ext.create('Ext.button.Button', {
@@ -1115,12 +1169,6 @@
                     }
                 });
 
-                this.nameCmp = Ext.create('Ext.form.Label', {
-                    text: this.dataElement.name,
-                    width: nameCmpWidth,
-                    style: 'padding:2px'
-                });
-
                 this.items = [
                     this.nameCmp,
                     this.operatorCmp,
@@ -1138,22 +1186,38 @@
 			alias: 'widget.dataelementbooleanpanel',
 			layout: 'column',
             bodyStyle: 'border:0 none',
+            style: 'margin: ' + margin,
             getRecord: function() {
-                return {
-                    id: this.dataElement.id,
-                    name: this.dataElement.name,
-                    value: this.valueCmp.getValue()
-                };
+                var record = {};
+
+                record.dimension = this.dataElement.id;
+                record.name = this.dataElement.name;
+
+                if (this.valueCmp.getValue()) {
+					record.filter = 'EQ:' + this.valueCmp.getValue();
+				}
+
+				return record;
+            },
+            setRecord: function(record) {
+                this.valueCmp.setValue(record.filter);
             },
             initComponent: function() {
                 var container = this;
 
+                this.nameCmp = Ext.create('Ext.form.Label', {
+                    text: this.dataElement.name,
+                    width: nameCmpWidth,
+                    style: 'padding:' + namePadding
+                });
+
                 this.valueCmp = Ext.create('Ext.form.field.ComboBox', {
                     valueField: 'id',
                     displayField: 'name',
                     queryMode: 'local',
                     editable: false,
                     width: operatorCmpWidth + valueCmpWidth,
+                    style: 'margin-bottom:0',
                     value: 'false',
                     store: {
                         fields: ['id', 'name'],
@@ -1166,7 +1230,10 @@
 
                 this.addCmp = Ext.create('Ext.button.Button', {
                     text: '+',
-                    width: buttonCmpWidth
+                    width: buttonCmpWidth,
+                    handler: function() {
+						container.duplicateDataElement();
+					}
                 });
 
                 this.removeCmp = Ext.create('Ext.button.Button', {
@@ -1177,12 +1244,6 @@
                     }
                 });
 
-                this.nameCmp = Ext.create('Ext.form.Label', {
-                    text: this.dataElement.name,
-                    width: nameCmpWidth,
-                    style: 'padding:2px'
-                });
-
                 this.items = [
                     this.nameCmp,
                     this.valueCmp,
@@ -1199,19 +1260,29 @@
 			alias: 'widget.dataelementoptionpanel',
 			layout: 'column',
             bodyStyle: 'border:0 none',
+            style: 'margin: ' + margin,
             getRecord: function() {
-				var valueArray = this.valueCmp.getValue().split(';');
+				var valueArray = this.valueCmp.getValue().split(';'),
+					record = {};
 
 				for (var i = 0; i < valueArray.length; i++) {
 					valueArray[i] = Ext.String.trim(valueArray[i]);
 				}
 
-                return {
-                    id: this.dataElement.id,
-                    name: this.dataElement.name,
-                    operator: this.operatorCmp.getValue(),
-                    value: valueArray.join(';')
-                };
+				record.dimension = this.dataElement.id;
+				record.name = this.dataElement.name;
+
+				if (Ext.Array.clean(valueArray).length) {
+					record.filter = this.operatorCmp.getValue() + ':' + valueArray.join(';');
+				}
+
+				return record;
+            },
+            setRecord: function(record) {
+				if (Ext.isString(record.filter) && record.filter) {
+					var a = record.filter.split(':');
+					this.valueCmp.setOptionValues(a[1].split(';'));
+				}
             },
             initComponent: function() {
                 var container = this;
@@ -1219,7 +1290,7 @@
                 this.nameCmp = Ext.create('Ext.form.Label', {
                     text: this.dataElement.name,
                     width: nameCmpWidth,
-                    style: 'padding:2px 2px 2px 1px'
+                    style: 'padding:' + namePadding
                 });
 
                 this.operatorCmp = Ext.create('Ext.form.field.ComboBox', {
@@ -1227,6 +1298,7 @@
                     displayField: 'name',
                     queryMode: 'local',
                     editable: false,
+                    style: 'margin-bottom:0',
                     width: operatorCmpWidth,
                     value: 'IN',
                     store: {
@@ -1255,7 +1327,7 @@
 							params: params,
 							disableCaching: false,
 							success: function(r) {
-								var options = Ext.decode(r.responseText),
+								var options = Ext.decode(r.responseText).options,
 									data = [];
 
 								Ext.each(options, function(option) {
@@ -1281,6 +1353,7 @@
 
                 this.searchCmp = Ext.create('Ext.form.field.ComboBox', {
                     width: 62,
+                    style: 'margin-bottom:0',
                     emptyText: 'Search..',
                     valueField: 'id',
                     displayField: 'name',
@@ -1289,7 +1362,7 @@
                     enableKeyEvents: true,
                     queryMode: 'local',
                     listConfig: {
-                        minWidth: 300
+                        minWidth: 304
                     },
                     store: this.valueStore,
                     listeners: {
@@ -1336,10 +1409,10 @@
                             Ext.Ajax.request({
                                 url: gis.init.contextPath + '/api/optionSets/' + container.dataElement.optionSet.id + '/options.json',
                                 params: {
-                                    'max': 15
+                                    'max': 14
                                 },
                                 success: function(r) {
-                                    var options = Ext.decode(r.responseText),
+                                    var options = Ext.decode(r.responseText).options,
                                         data = [];
 
                                     Ext.each(options, function(option) {
@@ -1359,7 +1432,8 @@
                 });
 
                 this.valueCmp = Ext.create('Ext.form.field.Text', {
-					width: 224,
+					width: 226,
+                    style: 'margin-bottom:0',
 					addOptionValue: function(option) {
 						var value = this.getValue();
 
@@ -1377,13 +1451,25 @@
 						}
 
 						this.setValue(value += option);
-					}
+					},
+                    setOptionValues: function(optionArray) {
+                        var value = '';
+
+                        for (var i = 0; i < optionArray.length; i++) {
+                            value += optionArray[i] + (i < (optionArray.length - 1) ? '; ' : '');
+                        }
+
+                        this.setValue(value);
+                    }
 				});
 
                 this.addCmp = Ext.create('Ext.button.Button', {
                     text: '+',
                     width: buttonCmpWidth,
-                    style: 'font-weight:bold'
+                    style: 'font-weight:bold',
+                    handler: function() {
+						container.duplicateDataElement();
+					}
                 });
 
                 this.removeCmp = Ext.create('Ext.button.Button', {
@@ -1407,6 +1493,7 @@
                 this.callParent();
             }
         });
+
     };
 
     // Objects
@@ -3919,7 +4006,12 @@
 		// stores
 		var programStore,
 			stagesByProgramStore,
-            dataElementsByStageStore,
+            //dataElementsByStageStore,
+
+        // cache
+            stageStorage = {},
+            attributeStorage = {},
+            dataElementStorage = {},
 
 		// components
 			program,
@@ -3933,8 +4025,36 @@
             selectDataElements,
             dataElement,
 
+            periodMode,
+            onPeriodModeSelect,
+            getDateLink,
 			startDate,
 			endDate,
+            startEndDate,
+
+            onPeriodChange,
+            onCheckboxAdd,
+            intervalListeners,
+            relativePeriodCmpMap = {},
+            weeks,
+            months,
+            biMonths,
+            quarters,
+            sixMonths,
+            financialYears,
+            years,
+            relativePeriod,
+            checkboxes = [],
+
+            fixedPeriodAvailable,
+            fixedPeriodSelected,
+            onPeriodTypeSelect,
+            periodType,
+            prevYear,
+            nextYear,
+            fixedPeriodSettings,
+            fixedPeriodAvailableSelected,
+            periods,
 			period,
 
 			treePanel,
@@ -3943,6 +4063,7 @@
 			userOrganisationUnitGrandChildren,
 			organisationUnitLevel,
 			organisationUnitGroup,
+            organisationUnitPanel,
 			toolMenu,
 			tool,
 			toolPanel,
@@ -3968,11 +4089,14 @@
 			fields: ['id', 'name'],
 			proxy: {
 				type: 'ajax',
-				url: gis.init.contextPath + '/api/programs.json?links=false',
+				url: gis.init.contextPath + '/api/programs.json?fields=id,name&paging=false',
 				reader: {
 					type: 'json',
 					root: 'programs'
-				}
+				},
+				pageParam: false,
+				startParam: false,
+				limitParam: false
 			},
 			sortInfo: {field: 'name', direction: 'ASC'},
 			isLoaded: false,
@@ -4047,10 +4171,10 @@
 			storage: {},
 			store: programStore,
             getRecord: function() {
-                return {
+                return this.getValue ? {
                     id: this.getValue(),
                     name: this.getRawValue()
-                };
+                } : null;
             },
 			listeners: {
 				select: function(cb) {
@@ -4059,27 +4183,67 @@
 			}
 		});
 
-		onProgramSelect = function(programId) {
+		onProgramSelect = function(programId, layout) {
+            var load;
+
+            programId = layout ? layout.program.id : programId;
 			stage.clearValue();
 
 			dataElementsByStageStore.removeAll();
 			dataElementSelected.removeAll();
 
-			stagesByProgramStore.proxy.url = gis.init.contextPath + '/api/programs/' + programId + '.json?viewClass=withoutOrganisationUnits&links=false&paging=false';
-			stagesByProgramStore.load({
-				callback: function(records) {
-					stage.enable();
-					stage.clearValue();
-					stage.queryMode = 'local';
-
-					if (records.length === 1) {
-						stage.setValue(records[0].data.id);
-
-						onStageSelect(records[0].data.id);
-					}
-				}
-			});
-
+            load = function(stages) {
+                stage.enable();
+                stage.clearValue();
+
+                stagesByProgramStore.removeAll();
+                stagesByProgramStore.loadData(stages);
+
+                //ns.app.aggregateLayoutWindow.resetData();
+				//ns.app.queryLayoutWindow.resetData();
+
+                stageId = (layout ? layout.programStage.id : null) || (stages.length === 1 ? stages[0].id : null);
+
+                if (stageId) {
+                    stage.setValue(stageId);
+                    onStageSelect(stageId, layout);
+                }
+            };
+
+            if (stageStorage.hasOwnProperty(programId)) {
+                load(stageStorage[programId]);
+            }
+            else {
+                Ext.Ajax.request({
+                    url: gis.init.contextPath + '/api/programs.json?filter=id:eq:' + programId + '&fields=programStages[id,name],programTrackedEntityAttributes[attribute[id,name,valueType,optionSet[id,name]]]&paging=false',
+                    success: function(r) {
+                        var program = Ext.decode(r.responseText).programs[0],
+                            stages,
+                            attributes,
+                            stageId;
+
+                        if (!program) {
+                            return;
+                        }
+
+                        stages = program.programStages;
+                        attributes = Ext.Array.pluck(program.programTrackedEntityAttributes, 'attribute');
+
+                        // attributes cache
+                        if (Ext.isArray(attributes) && attributes.length) {
+                            attributeStorage[programId] = attributes;
+                        }
+
+                        if (Ext.isArray(stages) && stages.length) {
+
+                            // stages cache
+                            stageStorage[programId] = stages;
+
+                            load(stages);
+                        }
+                    }
+                });
+            }
 		};
 
 		stage = Ext.create('Ext.form.field.ComboBox', {
@@ -4092,7 +4256,7 @@
 			labelCls: 'gis-form-item-label-top',
 			labelSeparator: '',
 			emptyText: 'Select stage',
-			queryMode: 'remote',
+			queryMode: 'local',
 			forceSelection: true,
 			columnWidth: 0.5,
 			style: 'margin:1px 0 1px 0',
@@ -4100,10 +4264,10 @@
 			listConfig: {loadMask: false},
 			store: stagesByProgramStore,
             getRecord: function() {
-                return {
+                return this.getValue() ? {
                     id: this.getValue(),
                     name: this.getRawValue()
-                };
+                } : null;
             },
 			listeners: {
 				select: function(cb) {
@@ -4112,65 +4276,68 @@
 			}
 		});
 
-		onStageSelect = function(stageId) {
-			dataElementSelected.removeAll();
-
-			loadDataElements(stageId);
-		};
-
-		loadDataElements = function(item, programId) {
-			var dataElements,
-				load,
-				fn;
-
-			programId = programId || program.getValue() || null;
-
-			load = function(attributes, dataElements) {
-				var data = Ext.Array.clean([].concat(attributes || [], dataElements || []));
-				dataElementsByStageStore.loadData(data);
-			};
-
-			fn = function(attributes) {
-
-				// data elements
-				if (Ext.isString(item)) {
-					Ext.Ajax.request({
-						url: gis.init.contextPath + '/api/programStages/' + item + '.json?links=false&paging=false',
-						success: function(r) {
-							var dataElements = Ext.Array.pluck(Ext.decode(r.responseText).programStageDataElements, 'dataElement');
-							load(attributes, dataElements);
-						}
-					});
-				}
-				else if (Ext.isArray(item)) {
-					load(attributes, item);
-				}
-			};
-
-			// attributes
-			if (programId) {
-				if (program.storage[programId]) {
-					fn(program.storage[programId]);
-				}
-				else {
-					Ext.Ajax.request({
-						url: gis.init.contextPath + '/api/programs/' + programId + '.json?viewClass=withoutOrganisationUnits&links=false',
-						success: function(r) {
-							var attributes = Ext.decode(r.responseText).attributes;
-
-							if (attributes) {
-								for (var i = 0; i < attributes.length; i++) {
-									attributes[i].type = attributes[i].valueType;
-								}
-
-								program.storage[programId] = attributes;
-							}
-
-							fn(attributes);
-						}
-					});
-				}
+		onStageSelect = function(stageId, layout) {
+            if (!layout) {
+				dataElementSelected.removeAll();
 			}
+
+			loadDataElements(stageId, layout);
+		};
+
+		loadDataElements = function(stageId, layout) {
+			var programId = layout ? layout.program.id : (program.getValue() || null),
+                load;
+
+            stageId = stageId || layout.programStage.id;
+
+			load = function(dataElements) {
+                var attributes = attributeStorage[programId],
+                    data = Ext.Array.clean([].concat(attributes || [], dataElements || []));
+
+				dataElementsByStageStore.loadData(dataElements);
+
+                if (layout) {
+                    var dataDimensions = gis.util.layout.getDataDimensionsFromLayout(layout),
+                        records = [];
+
+                    for (var i = 0, dim, row; i < dataDimensions.length; i++) {
+                        dim = dataDimensions[i];
+                        row = dataElementsByStageStore.getById(dim.dimension);
+
+                        if (row) {
+                            records.push(Ext.applyIf(dim, row.data));
+                        }
+                    }
+
+                    selectDataElements(records, layout);
+                }
+			};
+
+            // data elements
+            if (dataElementStorage.hasOwnProperty(stageId)) {
+                load(dataElementStorage[stageId]);
+            }
+            else {
+                Ext.Ajax.request({
+                    url: gis.init.contextPath + '/api/programStages.json?filter=id:eq:' + stageId + '&fields=programStageDataElements[dataElement[id,name,type,optionSet[id,name]]]',
+                    success: function(r) {
+                        var objects = Ext.decode(r.responseText).programStages,
+                            dataElements;
+
+                        if (!objects.length) {
+                            load();
+                            return;
+                        }
+
+                        dataElements = Ext.Array.pluck(objects[0].programStageDataElements, 'dataElement');
+
+                        // data elements cache
+                        dataElementStorage[stageId] = dataElements;
+
+                        load(dataElements);
+                    }
+                });
+            }
 		};
 
 		dataElementAvailable = Ext.create('Ext.ux.form.MultiSelect', {
@@ -4228,19 +4395,35 @@
             bodyStyle: 'padding:2px 0 1px 3px; overflow-y: scroll',
             tbar: {
                 height: 27,
-                items: {
-					xtype: 'label',
-                    text: 'Selected data items',
-                    style: 'padding-left:6px; color:#222',
-					cls: 'ns-toolbar-multiselect-left-label'
-				}
+                items: [
+					{
+						xtype: 'label',
+						text: 'Selected data items',
+						style: 'padding-left:6px; color:#222',
+						cls: 'ns-toolbar-multiselect-left-label'
+					},
+					'->',
+					{
+						xtype: 'button',
+						icon: 'images/arrowupdouble.png',
+						width: 22,
+						height: 22,
+						handler: function() {
+							dataElementSelected.removeAllDataElements();
+						}
+					}
+				]
             },
             getChildIndex: function(child) {
-				this.items.each(function(item, index) {
-					if (item.id === child.id) {
-						return index;
+				var items = this.items.items;
+
+				for (var i = 0; i < items.length; i++) {
+					if (items[i].id === child.id) {
+						return i;
 					}
-				});
+				}
+
+				return items.length;
 			},
 			hasDataElement: function(dataElementId) {
 				var hasDataElement = false;
@@ -4252,6 +4435,14 @@
 				});
 
 				return hasDataElement;
+			},
+			removeAllDataElements: function() {
+				var items = this.items.items,
+					len = items.length;
+
+				for (var i = 0; i < len; i++) {
+					items[0].removeDataElement();
+				}
 			}
         });
 
@@ -4259,6 +4450,8 @@
 			var getUxType,
 				ux;
 
+            element.type = element.type || element.valueType;
+
 			index = index || dataElementSelected.items.items.length;
 
 			getUxType = function(element) {
@@ -4266,7 +4459,7 @@
 					return 'Ext.ux.panel.DataElementOptionContainer';
 				}
 
-				if (element.type === 'int') {
+				if (element.type === 'int' || element.type === 'number') {
 					return 'Ext.ux.panel.DataElementIntegerContainer';
 				}
 
@@ -4292,16 +4485,20 @@
 				if (!dataElementSelected.hasDataElement(element.id)) {
 					dataElementsByStageStore.add(element);
 					dataElementsByStageStore.sort();
+
+                    //ns.app.aggregateLayoutWindow.removeDimension(element.id);
+                    //ns.app.queryLayoutWindow.removeDimension(element.id);
 				}
 			};
 
 			ux.duplicateDataElement = function() {
 				var index = dataElementSelected.getChildIndex(ux) + 1;
-
 				addUxFromDataElement(element, index);
 			};
 
 			dataElementsByStageStore.removeAt(dataElementsByStageStore.findExact('id', element.id));
+
+            return ux;
 		};
 
         selectDataElements = function(items) {
@@ -4487,20 +4684,21 @@
 					}
 				}
 			},
-			store: Ext.create('Ext.data.TreeStore', {
+            store: Ext.create('Ext.data.TreeStore', {
 				fields: ['id', 'name'],
 				proxy: {
 					type: 'rest',
 					format: 'json',
 					noCache: false,
 					extraParams: {
-						links: 'false'
+						fields: 'children[id,name,level]'
 					},
 					url: gis.init.contextPath + '/api/organisationUnits',
 					reader: {
 						type: 'json',
 						root: 'children'
-					}
+					},
+					sortParam: false
 				},
 				sorters: [{
 					property: 'name',
@@ -4513,9 +4711,17 @@
 				},
 				listeners: {
 					load: function(store, node, records) {
+                        var numberOfLevels = gis.init.organisationUnitLevels.length;
+
 						Ext.Array.each(records, function(record) {
-							record.set('leaf', !record.raw.hasChildren);
-						});
+                            //if (Ext.isBoolean(record.data.hasChildren)) {
+                                //record.set('leaf', !record.data.hasChildren);
+                            //}
+
+                            if (Ext.isNumber(numberOfLevels)) {
+                                record.set('leaf', parseInt(record.raw.level) === numberOfLevels);
+                            }
+                        });
 					}
 				}
 			}),
@@ -5183,20 +5389,21 @@
 					}
 				}
 			},
-			store: Ext.create('Ext.data.TreeStore', {
+            store: Ext.create('Ext.data.TreeStore', {
 				fields: ['id', 'name'],
 				proxy: {
 					type: 'rest',
 					format: 'json',
 					noCache: false,
 					extraParams: {
-						links: 'false'
+						fields: 'children[id,name,level]'
 					},
 					url: gis.init.contextPath + '/api/organisationUnits',
 					reader: {
 						type: 'json',
 						root: 'children'
-					}
+					},
+					sortParam: false
 				},
 				sorters: [{
 					property: 'name',
@@ -5209,9 +5416,17 @@
 				},
 				listeners: {
 					load: function(store, node, records) {
+                        var numberOfLevels = gis.init.organisationUnitLevels.length;
+
 						Ext.Array.each(records, function(record) {
-							record.set('leaf', !record.raw.hasChildren);
-						});
+                            //if (Ext.isBoolean(record.data.hasChildren)) {
+                                //record.set('leaf', !record.data.hasChildren);
+                            //}
+
+                            if (Ext.isNumber(numberOfLevels)) {
+                                record.set('leaf', parseInt(record.raw.level) === numberOfLevels);
+                            }
+                        });
 					}
 				}
 			}),
@@ -5883,20 +6098,21 @@
 					}
 				}
 			},
-			store: Ext.create('Ext.data.TreeStore', {
+            store: Ext.create('Ext.data.TreeStore', {
 				fields: ['id', 'name'],
 				proxy: {
 					type: 'rest',
 					format: 'json',
 					noCache: false,
 					extraParams: {
-						links: 'false'
+						fields: 'children[id,name,level]'
 					},
 					url: gis.init.contextPath + '/api/organisationUnits',
 					reader: {
 						type: 'json',
 						root: 'children'
-					}
+					},
+					sortParam: false
 				},
 				sorters: [{
 					property: 'name',
@@ -5909,9 +6125,17 @@
 				},
 				listeners: {
 					load: function(store, node, records) {
+                        var numberOfLevels = gis.init.organisationUnitLevels.length;
+
 						Ext.Array.each(records, function(record) {
-							record.set('leaf', !record.raw.hasChildren);
-						});
+                            //if (Ext.isBoolean(record.data.hasChildren)) {
+                                //record.set('leaf', !record.data.hasChildren);
+                            //}
+
+                            if (Ext.isNumber(numberOfLevels)) {
+                                record.set('leaf', parseInt(record.raw.level) === numberOfLevels);
+                            }
+                        });
 					}
 				}
 			}),
@@ -6518,10 +6742,10 @@
 				var path;
 
 				if (Ext.isString(uid)) {
-					path = '/dataElementGroups/' + uid + '.json?domainType=aggregate&links=false&paging=false';
+                    path = '/dataElements.json?fields=id,name&domainType=aggregate&paging=false&filter=dataElement.dataElementGroups.id:eq:' + uid;
 				}
 				else if (uid === 0) {
-					path = '/dataElements.json?domainType=aggregate&paging=false&links=false';
+					path = '/dataElements.json?fields=id,name&domainType=aggregate&paging=false';
 				}
 
 				if (!path) {
@@ -6555,7 +6779,7 @@
 				if (Ext.isString(uid)) {
 					this.setProxy({
 						type: 'ajax',
-						url: gis.init.contextPath + '/api/generatedDataElementOperands.json?links=false&dataElementGroup=' + uid,
+						url: gis.init.contextPath + '/api/dataElementOperands.json?fields=id,name&paging=false&filter=dataElement.dataElementGroups.id:eq:' + uid,
 						reader: {
 							type: 'json',
 							root: 'dataElementOperands'
@@ -6597,7 +6821,7 @@
             fields: ['id', 'name'],
             proxy: {
                 type: 'ajax',
-                url: gis.init.contextPath + '/api/dataSets.json?paging=false&links=false',
+                url: gis.init.contextPath + '/api/dataSets.json?fields=id,name&paging=false',
                 reader: {
                     type: 'json',
                     root: 'dataSets'
@@ -6745,7 +6969,7 @@
 				select: function() {
 					indicator.clearValue();
 
-					indicator.store.proxy.url = gis.init.contextPath + gis.conf.finals.url.path_api +  'indicatorGroups/' + this.getValue() + '.json?links=false&paging=false';
+					indicator.store.proxy.url = gis.init.contextPath + '/api/indicators.json?fields=id,name&paging=false&filter=indicatorGroups.id:eq:' + this.getValue();
 					indicator.store.load();
 				}
 			}
@@ -6765,19 +6989,20 @@
 			listeners: {
 				select: function(cb) {
 					Ext.Ajax.request({
-						url: gis.init.contextPath + gis.conf.finals.url.path_api + 'indicators/' + this.getValue() + '.json?links=false',
+						url: gis.init.contextPath + '/api/indicators.json?fields=legendSet[id]&paging=false&filter=id:eq:' + this.getValue(),
 						success: function(r) {
 							r = Ext.decode(r.responseText);
 
-							if (Ext.isDefined(r.legendSet) && r.legendSet && r.legendSet.id) {
+							if (Ext.isObject(r.mapLegendSet) && r.mapLegendSet.id) {
 								legendType.setValue(gis.conf.finals.widget.legendtype_predefined);
 								legendTypeToggler(gis.conf.finals.widget.legendtype_predefined);
+
 								if (gis.store.legendSets.isLoaded) {
-									legendSet.setValue(r.legendSet.id);
+									legendSet.setValue(r.mapLegendSet.id);
 								}
 								else {
 									gis.store.legendSets.loadFn( function() {
-										legendSet.setValue(r.legendSet.id);
+										legendSet.setValue(r.mapLegendSet.id);
 									});
 								}
 							}
@@ -6850,20 +7075,20 @@
 					}
 
 					Ext.Ajax.request({
-						url: gis.init.contextPath + gis.conf.finals.url.path_api + 'dataElements/' + id + '.json?links=false',
+						url: gis.init.contextPath + '/api/dataElements.json?fields=legendSet[id]&paging=false&filter=id:eq:' + this.getValue(),
 						success: function(r) {
 							r = Ext.decode(r.responseText);
 
-							if (Ext.isDefined(r.legendSet) && r.legendSet && r.legendSet.id) {
+							if (Ext.isObject(r.mapLegendSet) && r.mapLegendSet.id) {
 								legendType.setValue(gis.conf.finals.widget.legendtype_predefined);
 								legendTypeToggler(gis.conf.finals.widget.legendtype_predefined);
 
 								if (gis.store.legendSets.isLoaded) {
-									legendSet.setValue(r.legendSet.id);
+									legendSet.setValue(r.mapLegendSet.id);
 								}
 								else {
 									gis.store.legendSets.loadFn( function() {
-										legendSet.setValue(r.legendSet.id);
+										legendSet.setValue(r.mapLegendSet.id);
 									});
 								}
 							}
@@ -7206,20 +7431,21 @@
 					}
 				}
 			},
-			store: Ext.create('Ext.data.TreeStore', {
+            store: Ext.create('Ext.data.TreeStore', {
 				fields: ['id', 'name'],
 				proxy: {
 					type: 'rest',
 					format: 'json',
 					noCache: false,
 					extraParams: {
-						links: 'false'
+						fields: 'children[id,name,level]'
 					},
 					url: gis.init.contextPath + '/api/organisationUnits',
 					reader: {
 						type: 'json',
 						root: 'children'
-					}
+					},
+					sortParam: false
 				},
 				sorters: [{
 					property: 'name',
@@ -7232,9 +7458,17 @@
 				},
 				listeners: {
 					load: function(store, node, records) {
+                        var numberOfLevels = gis.init.organisationUnitLevels.length;
+
 						Ext.Array.each(records, function(record) {
-							record.set('leaf', !record.raw.hasChildren);
-						});
+                            //if (Ext.isBoolean(record.data.hasChildren)) {
+                                //record.set('leaf', !record.data.hasChildren);
+                            //}
+
+                            if (Ext.isNumber(numberOfLevels)) {
+                                record.set('leaf', parseInt(record.raw.level) === numberOfLevels);
+                            }
+                        });
 					}
 				}
 			}),
@@ -8489,7 +8723,7 @@
 			if (base.length) {
 
 				// hide base layer
-				if (base === 'false') {
+				if (Ext.Array.contains(['false', 'none', 'no', 'off'], base)) {
 					for (var i = 0, item; i < layersPanel.layerItems.length; i++) {
 						item = layersPanel.layerItems[i];
 
@@ -8641,6 +8875,7 @@
                                                 }
 											}
 
+											init.user = init.user || {};
 											init.user.ou = ou;
                                             init.user.ouc = ouc;
 										}

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js	2014-05-27 11:08:21 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js	2014-06-19 11:37:49 +0000
@@ -1050,15 +1050,15 @@
             for (var i = 0, element; i < view.dataElements.length; i++) {
                 element = view.dataElements[i];
 
-                paramString += '&dimension=' + element.id;
-
-                if (element.value) {
-					if (element.operator) {
-						paramString += ':' + element.operator;
-					}
-
-					paramString += ':' + element.value;
-                }
+                paramString += '&dimension=' + element.dimension + (element.filter ? ':' + element.filter : '');
+
+                //if (element.filter) {
+					//if (element.operator) {
+						//paramString += ':' + element.operator;
+					//}
+
+					//paramString += ':' + element.value;
+                //}
             }
 
 			Ext.data.JsonP.request({
@@ -2586,6 +2586,21 @@
 					}
 				}
 			};
+
+            util.layout.getDataDimensionsFromLayout = function(layout) {
+                var dimensions = Ext.Array.clean([].concat(layout.columns || [], layout.rows || [], layout.filters || [])),
+                    ignoreKeys = ['pe', 'ou'],
+                    dataDimensions = [];
+
+                for (var i = 0; i < dimensions.length; i++) {
+                    if (!Ext.Array.contains(ignoreKeys, dimensions[i].dimension)) {
+                        dataDimensions.push(dimensions[i]);
+                    }
+                }
+
+                return dataDimensions;
+            };
+
 		}());
 
 		gis.init = init;

=== 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	2014-06-18 11:16:24 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js	2014-06-20 10:41:50 +0000
@@ -2707,10 +2707,11 @@
                 }
 
 				if (Ext.isString(uid)) {
-					path = '/dataElementGroups/' + uid + '/operands' + (filter ? '/query/' + filter : '') + '.json';
+					//path = '/dataElementGroups/' + uid + '/operands' + (filter ? '/query/' + filter : '') + '.json';
+					path = '/dataElementOperands.json?fields=id,name&filter=dataElement.dataElementGroups.id:eq:' + uid + (filter ? '&filter=name:like:' + filter : '');
 				}
 				else if (uid === 0) {
-					path = '/generatedDataElementOperands.json?fields=id,name' + (filter ? '&filter=name:like:' + filter : '');
+					path = '/dataElementOperands.json?fields=id,name' + (filter ? '&filter=name:like:' + filter : '');
 				}
 
 				if (!path) {
@@ -4357,13 +4358,14 @@
 					format: 'json',
 					noCache: false,
 					extraParams: {
-						links: 'false'
+						fields: 'children[id,name,level]'
 					},
 					url: ns.core.init.contextPath + '/api/organisationUnits',
 					reader: {
 						type: 'json',
 						root: 'children'
-					}
+					},
+					sortParam: false
 				},
 				sorters: [{
 					property: 'name',
@@ -4376,9 +4378,17 @@
 				},
 				listeners: {
 					load: function(store, node, records) {
+                        var numberOfLevels = ns.core.init.organisationUnitLevels.length;
+
 						Ext.Array.each(records, function(record) {
-							record.set('leaf', !record.raw.hasChildren);
-						});
+                            //if (Ext.isBoolean(record.data.hasChildren)) {
+                                //record.set('leaf', !record.data.hasChildren);
+                            //}
+
+                            if (Ext.isNumber(numberOfLevels)) {
+                                record.set('leaf', parseInt(record.raw.level) === numberOfLevels);
+                            }
+                        });
 					}
 				}
 			}),

=== 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	2014-06-18 11:16:24 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js	2014-06-20 10:41:50 +0000
@@ -2521,10 +2521,11 @@
                 }
 
 				if (Ext.isString(uid)) {
-					path = '/dataElementGroups/' + uid + '/operands' + (filter ? '/query/' + filter : '') + '.json';
+					//path = '/dataElementGroups/' + uid + '/operands' + (filter ? '/query/' + filter : '') + '.json';
+					path = '/dataElementOperands.json?fields=id,name&filter=dataElement.dataElementGroups.id:eq:' + uid + (filter ? '&filter=name:like:' + filter : '');
 				}
 				else if (uid === 0) {
-					path = '/generatedDataElementOperands.json?fields=id,name' + (filter ? '&filter=name:like:' + filter : '');
+					path = '/dataElementOperands.json?fields=id,name' + (filter ? '&filter=name:like:' + filter : '');
 				}
 
 				if (!path) {
@@ -2537,8 +2538,6 @@
                 Ext.Ajax.request({
                     url: ns.core.init.contextPath + '/api' + path,
                     params: {
-                        viewClass: 'basic',
-                        links: 'false',
                         page: store.nextPage,
                         pageSize: 50
                     },
@@ -4159,13 +4158,14 @@
 					format: 'json',
 					noCache: false,
 					extraParams: {
-						links: 'false'
+						fields: 'children[id,name,level]'
 					},
 					url: ns.core.init.contextPath + '/api/organisationUnits',
 					reader: {
 						type: 'json',
 						root: 'children'
-					}
+					},
+					sortParam: false
 				},
 				sorters: [{
 					property: 'name',
@@ -4178,9 +4178,17 @@
 				},
 				listeners: {
 					load: function(store, node, records) {
+                        var numberOfLevels = ns.core.init.organisationUnitLevels.length;
+
 						Ext.Array.each(records, function(record) {
-							record.set('leaf', !record.raw.hasChildren);
-						});
+                            //if (Ext.isBoolean(record.data.hasChildren)) {
+                                //record.set('leaf', !record.data.hasChildren);
+                            //}
+
+                            if (Ext.isNumber(numberOfLevels)) {
+                                record.set('leaf', parseInt(record.raw.level) === numberOfLevels);
+                            }
+                        });
 					}
 				}
 			}),