← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 10189: (PT) Sharing implemented.

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 10189 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2013-03-13 20:55:13 +0100
message:
  (PT) Sharing implemented.
added:
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/images/grid-sharing_16.png
modified:
  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-mapping/src/main/webapp/dhis-web-mapping/app/styles/style.css
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/jsonInitialize.vm
  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/styles/style.css
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/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
=== added file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/images/grid-sharing_16.png'
Binary files dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/images/grid-sharing_16.png	1970-01-01 00:00:00 +0000 and dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/images/grid-sharing_16.png	2013-03-13 19:09:29 +0000 differ
=== 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	2013-03-11 15:11:59 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/app.js	2013-03-13 19:53:02 +0000
@@ -18,6 +18,7 @@
 	// Init
 
 	var gis = GIS.core.getInstance();
+	GIS.app.instances = [gis];
 
 	GIS.app.getInits = function(r) {
 		var init = Ext.decode(r.responseText);
@@ -266,6 +267,30 @@
 			window.setPosition(4,35);
 		};
 
+		util.gui.window.addHideOnBlurHandler = function(w) {
+			var el = Ext.get(Ext.query('.x-mask')[0]);
+
+			el.on('click', function() {
+				if (w.hideOnBlur) {
+					w.hide();
+				}
+			});
+
+			w.hasHideOnBlurHandler = true;
+		};
+
+		util.gui.window.addDestroyOnBlurHandler = function(w) {
+			var el = Ext.get(Ext.query('.x-mask')[0]);
+
+			el.on('click', function() {
+				if (w.destroyOnBlur) {
+					w.destroy();
+				}
+			});
+
+			w.hasDestroyOnBlurHandler = true;
+		};
+
 		return util;
 	};
 
@@ -762,7 +787,7 @@
 						else {
 							layer.filterWindow.destroy();
 						}
-					}
+					}organisationUnitLe
 
 					layer.filterWindow = layer.id === gis.layer.facility.id ?
 						GIS.app.FilterWindowFacility(layer) : GIS.app.FilterWindow(layer);
@@ -1450,6 +1475,256 @@
 		return window;
 	};
 
+	GIS.app.SharingWindow = function(sharing) {
+
+		// Objects
+		var UserGroupRow,
+
+		// Functions
+			getBody,
+
+		// Components
+			userGroupStore,
+			userGroupField,
+			userGroupButton,
+			userGroupRowContainer,
+			publicGroup,
+			window;
+
+		UserGroupRow = function(obj, isPublicAccess, disallowPublicAccess) {
+			var getData,
+				store,
+				getItems,
+				combo,
+				getAccess,
+				panel;
+
+			getData = function() {
+				var data = [
+					{id: 'r-------', name: 'Can view'}, //i18n
+					{id: 'rw------', name: 'Can edit and view'}
+				];
+
+				if (isPublicAccess) {
+					data.unshift({id: '-------', name: 'None'});
+				}
+
+				return data;
+			}
+
+			store = Ext.create('Ext.data.Store', {
+				fields: ['id', 'name'],
+				data: getData()
+			});
+
+			getItems = function() {
+				var items = [];
+
+				combo = Ext.create('Ext.form.field.ComboBox', {
+					fieldLabel: isPublicAccess ? 'Public access' : obj.name, //i18n
+					labelStyle: 'color:#333',
+					cls: 'gis-combo',
+					width: 380,
+					labelWidth: 250,
+					queryMode: 'local',
+					valueField: 'id',
+					displayField: 'name',
+					labelSeparator: null,
+					editable: false,
+					disabled: !!disallowPublicAccess,
+					value: obj.access,
+					store: store
+				});
+
+				items.push(combo);
+
+				if (!isPublicAccess) {
+					items.push(Ext.create('Ext.Img', {
+						src: 'images/grid-delete_16.png',
+						style: 'margin-top:2px; margin-left:7px',
+						overCls: 'pointer',
+						width: 16,
+						height: 16,
+						listeners: {
+							render: function(i) {
+								i.getEl().on('click', function(e) {
+									i.up('panel').destroy();
+									window.doLayout();
+								});
+							}
+						}
+					}));
+				}
+
+				return items;
+			};
+
+			getAccess = function() {
+				return {
+					id: obj.id,
+					name: obj.name,
+					access: combo.getValue()
+				};
+			};
+
+			panel = Ext.create('Ext.panel.Panel', {
+				layout: 'column',
+				bodyStyle: 'border:0 none',
+				getAccess: getAccess,
+				items: getItems()
+			});
+
+			return panel;
+		};
+
+		getBody = function() {
+			var body = {
+				object: {
+					id: sharing.object.id,
+					name: sharing.object.name,
+					publicAccess: publicGroup.down('combobox').getValue(),
+					user: {
+						id: gis.init.user.id,
+						name: gis.init.user.name
+					}
+				}
+			};
+
+			if (userGroupRowContainer.items.items.length > 1) {
+				body.object.userGroupAccesses = [];
+				for (var i = 1, item; i < userGroupRowContainer.items.items.length; i++) {
+					item = userGroupRowContainer.items.items[i];
+					body.object.userGroupAccesses.push(item.getAccess());
+				}
+			}
+
+			return body;
+		};
+
+		// Initialize
+		userGroupStore = Ext.create('Ext.data.Store', {
+			fields: ['id', 'name'],
+			proxy: {
+				type: 'ajax',
+				url: gis.baseUrl + gis.conf.url.path_api + 'sharing/search',
+				reader: {
+					type: 'json',
+					root: 'userGroups'
+				}
+			}
+		});
+
+		userGroupField = Ext.create('Ext.form.field.ComboBox', {
+			valueField: 'id',
+			displayField: 'name',
+			emptyText: 'Search for user groups', //i18n
+			queryParam: 'key',
+			queryDelay: 200,
+			minChars: 1,
+			hideTrigger: true,
+			fieldStyle: 'height:26px; padding-left:6px; border-radius:1px; font-size:11px',
+			style: 'margin-bottom:5px',
+			width: 380,
+			store: userGroupStore,
+			listeners: {
+				beforeselect: function(cb) { // beforeselect instead of select, fires regardless of currently selected item
+					userGroupButton.enable();
+				},
+				afterrender: function(cb) {
+					cb.inputEl.on('keyup', function() {
+						userGroupButton.disable();
+					});
+				}
+			}
+		});
+
+		userGroupButton = Ext.create('Ext.button.Button', {
+			text: '+',
+			style: 'margin-left:2px; padding-right:4px; padding-left:4px; border-radius:1px',
+			disabled: true,
+			height: 26,
+			handler: function(b) {
+				userGroupRowContainer.add(UserGroupRow({
+					id: userGroupField.getValue(),
+					name: userGroupField.getRawValue(),
+					access: 'r-------'
+				}));
+
+				userGroupField.clearValue();
+				b.disable();
+			}
+		});
+
+		userGroupRowContainer = Ext.create('Ext.container.Container', {
+			bodyStyle: 'border:0 none'
+		});
+
+		publicGroup = userGroupRowContainer.add(UserGroupRow({
+			id: sharing.object.id,
+			name: sharing.object.name,
+			access: sharing.object.publicAccess
+		}, true, !sharing.meta.allowPublicAccess));
+
+		if (Ext.isArray(sharing.object.userGroupAccesses)) {
+			for (var i = 0, userGroupRow; i < sharing.object.userGroupAccesses.length; i++) {
+				userGroupRow = UserGroupRow(sharing.object.userGroupAccesses[i]);
+				userGroupRowContainer.add(userGroupRow);
+			}
+		}
+
+		window = Ext.create('Ext.window.Window', {
+			title: 'Sharing settings',
+			bodyStyle: 'padding:8px 8px 3px; background-color:#fff',
+			width: 434,
+			resizable: false,
+			modal: true,
+			destroyOnBlur: true,
+			items: [
+				{
+					html: sharing.object.name,
+					bodyStyle: 'border:0 none; font-weight:bold; color:#333',
+					style: 'margin-bottom:8px'
+				},
+				{
+					xtype: 'container',
+					layout: 'column',
+					bodyStyle: 'border:0 none',
+					items: [
+						userGroupField,
+						userGroupButton
+					]
+				},
+				userGroupRowContainer
+			],
+			bbar: [
+				'->',
+				{
+					text: 'Save',
+					handler: function() {
+						Ext.Ajax.request({
+							url: gis.baseUrl + gis.conf.url.path_api + 'sharing?type=map&id=' + sharing.object.id,
+							method: 'POST',
+							headers: {
+								'Content-Type': 'application/json'
+							},
+							params: Ext.encode(getBody())
+						});
+
+						window.destroy();
+					}
+				}
+			],
+			listeners: {
+				show: function(w) {
+					var pos = gis.viewport.mapWindow.getPosition();
+					w.setPosition(pos[0] + 5, pos[1] + 5);
+				}
+			}
+		});
+
+		return window;
+	};
+
     GIS.app.MapControlPanel = function(name, fn) {
 		var button,
 			panel;
@@ -1487,17 +1762,31 @@
 			tbar,
 			bbar,
 			info,
-
 			nameTextfield,
-			systemCheckbox,
 			createButton,
 			updateButton,
 			cancelButton,
+			mapWindow,
 
-			mapWindow;
+		// Vars
+			windowWidth = 500,
+			windowCmpWidth = windowWidth - 22;
 
 		gis.store.maps.on('load', function(store, records) {
-			info.setText(records.length + ' favorite' + (records.length !== 1 ? 's' : '') + ' available');
+			var pager = store.proxy.reader.jsonData.pager;
+
+			info.setText('Page ' + pager.page + ' of ' + pager.pageCount);
+
+			prevButton.enable();
+			nextButton.enable();
+
+			if (pager.page === 1) {
+				prevButton.disable();
+			}
+
+			if (pager.page === pager.pageCount) {
+				nextButton.disable();
+			}
 		});
 
 		NameWindow = function(id) {
@@ -1506,10 +1795,10 @@
 
 			nameTextfield = Ext.create('Ext.form.field.Text', {
 				height: 26,
-				width: 300,
-				labelWidth: 70,
-				fieldStyle: 'padding-left: 6px; border-radius: 1px; border-color: #bbb',
-				fieldLabel: 'Name', //i18n
+				width: 250,
+				fieldStyle: 'padding-left: 6px; border-radius: 1px; border-color: #bbb; font-size:11px',
+				style: 'margin-bottom:0',
+				emptyText: 'Favorite name',
 				value: id ? record.data.name : '',
 				listeners: {
 					afterrender: function() {
@@ -1518,14 +1807,6 @@
 				}
 			});
 
-			systemCheckbox = Ext.create('Ext.form.field.Checkbox', {
-				labelWidth: 70,
-				fieldLabel: 'System', //i18n
-				style: 'margin-bottom: 0',
-				disabled: !gis.init.security.isAdmin,
-				checked: !id ? false : (record.data.user ? false : true)
-			});
-
 			createButton = Ext.create('Ext.button.Button', {
 				text: 'Create', //i18n
 				handler: function() {
@@ -1557,15 +1838,12 @@
 								longitude: lonlat.lon,
 								latitude: lonlat.lat,
 								zoom: gis.olmap.getZoom(),
-								mapViews: views
+								mapViews: views,
+								user: {
+									id: 'currentUser'
+								}
 							};
 
-							if (!system) {
-								map.user = {
-									id: 'currentUser'
-								};
-							}
-
 							Ext.Ajax.request({
 								url: gis.baseUrl + gis.conf.url.path_api + 'maps/',
 								method: 'POST',
@@ -1595,11 +1873,10 @@
 			updateButton = Ext.create('Ext.button.Button', {
 				text: 'Update', //i18n
 				handler: function() {
-					var name = nameTextfield.getValue(),
-						system = systemCheckbox.getValue();
+					var name = nameTextfield.getValue();
 
 					Ext.Ajax.request({
-						url: gis.baseUrl + gis.conf.url.path_gis + 'renameMap.action?id=' + id + '&name=' + name + '&user=' + !system,
+						url: gis.baseUrl + gis.conf.url.path_gis + 'renameMap.action?id=' + id + '&name=' + name + '&user=true',
 						success: function() {
 							gis.store.maps.loadStore();
 
@@ -1622,10 +1899,7 @@
 				cls: 'gis-container-default',
 				resizable: false,
 				modal: true,
-				items: [
-					nameTextfield,
-					systemCheckbox
-				],
+				items: nameTextfield,
 				bbar: [
 					cancelButton,
 					'->',
@@ -1654,9 +1928,9 @@
 		});
 
 		searchTextfield = Ext.create('Ext.form.field.Text', {
-			width: 340,
+			width: windowCmpWidth - addButton.width - 11,
 			height: 26,
-			fieldStyle: 'padding-right: 0; padding-left: 6px; border-radius: 1px; border-color: #bbb',
+			fieldStyle: 'padding-right: 0; padding-left: 6px; border-radius: 1px; border-color: #bbb; font-size:11px',
 			emptyText: 'Search for favorites', //i18n
 			enableKeyEvents: true,
 			currentValue: '',
@@ -1714,7 +1988,7 @@
 				{
 					dataIndex: 'name',
 					sortable: false,
-					width: 340,
+					width: windowCmpWidth - 108,
 					renderer: function(value, metaData, record) {
 						var fn = function() {
 							var el = Ext.get(record.data.id);
@@ -1735,25 +2009,20 @@
 				{
 					xtype: 'actioncolumn',
 					sortable: false,
-					width: 80,
+					width: 100,
 					items: [
 						{
 							iconCls: 'gis-grid-row-icon-edit',
 							getClass: function(value, metaData, record) {
-								var system = !record.data.user,
-									isAdmin = gis.init.security.isAdmin;
-
-								if (isAdmin || (!isAdmin && !system)) {
+								if (gis.init.user.isAdmin) {
 									return 'tooltip-map-edit';
 								}
 							},
 							handler: function(grid, rowIndex, colIndex, col, event) {
 								var record = this.up('grid').store.getAt(rowIndex),
-									id = record.data.id,
-									system = !record.data.user,
-									isAdmin = gis.init.security.isAdmin;
+									id = record.data.id;
 
-								if (isAdmin || (!isAdmin && !system)) {
+								if (gis.init.user.isAdmin) {
 									var id = this.up('grid').store.getAt(rowIndex).data.id;
 									nameWindow = new NameWindow(id);
 									nameWindow.show();
@@ -1763,10 +2032,7 @@
 						{
 							iconCls: 'gis-grid-row-icon-overwrite',
 							getClass: function(value, metaData, record) {
-								var system = !record.data.user,
-									isAdmin = gis.init.security.isAdmin;
-
-								if (isAdmin || (!isAdmin && !system)) {
+								if (gis.init.user.isAdmin) {
 									return 'tooltip-map-overwrite';
 								}
 							},
@@ -1824,6 +2090,30 @@
 							}
 						},
 						{
+							iconCls: 'gis-grid-row-icon-sharing',
+							getClass: function() {
+								return 'tooltip-map-sharing';
+							},
+							handler: function(grid, rowIndex) {
+								var record = this.up('grid').store.getAt(rowIndex),
+									id = record.data.id,
+									window;
+
+								Ext.Ajax.request({
+									url: gis.baseUrl + gis.conf.url.path_api + 'sharing?type=map&id=' + id,
+									method: 'GET',
+									failure: function(r) {
+										alert(r.responseText);
+									},
+									success: function(r) {
+										var sharing = Ext.decode(r.responseText);
+										window = GIS.app.SharingWindow(sharing);
+										window.show();
+									}
+								});
+							}
+						},
+						{
 							iconCls: 'gis-grid-row-icon-dashboard',
 							getClass: function() {
 								return 'tooltip-map-dashboard';
@@ -1847,10 +2137,7 @@
 						{
 							iconCls: 'gis-grid-row-icon-delete',
 							getClass: function(value, metaData, record) {
-								var system = !record.data.user,
-									isAdmin = gis.init.security.isAdmin;
-
-								if (isAdmin || (!isAdmin && !system)) {
+								if (gis.init.user.isAdmin) {
 									return 'tooltip-map-delete';
 								}
 							},
@@ -1873,7 +2160,7 @@
 						}
 					],
 					renderer: function(value, metaData, record) {
-						if (!gis.init.security.isAdmin && !record.data.user) {
+						if (!gis.init.user.isAdmin && !record.data.user) {
 							metaData.tdCls = 'gis-grid-row-icon-disabled';
 						}
 					}
@@ -1908,35 +2195,40 @@
 				},
 				afterrender: function() {
 					var fn = function() {
-						var editArray = document.getElementsByClassName('tooltip-map-edit'),
-							overwriteArray = document.getElementsByClassName('tooltip-map-overwrite'),
-							dashboardArray = document.getElementsByClassName('tooltip-map-dashboard'),
-							deleteArray = document.getElementsByClassName('tooltip-map-delete'),
+						var editArray = Ext.query('.tooltip-map-edit'),
+							overwriteArray = Ext.query('.tooltip-map-overwrite'),
+							sharingArray = Ext.query('.tooltip-map-sharing'),
+							dashboardArray = Ext.query('.tooltip-map-dashboard'),
+							deleteArray = Ext.query('.tooltip-map-delete'),
 							el;
 
-						for (var i = 0; i < deleteArray.length; i++) {
-							el = editArray[i];
+						for (var i = 0; i < editArray.length; i++) {
+							var el = editArray[i];
 							Ext.create('Ext.tip.ToolTip', {
 								target: el,
-								html: 'Rename',
+								html: 'Rename', //i18n
 								'anchor': 'bottom',
 								anchorOffset: -14,
 								showDelay: 1000
 							});
+						}
 
+						for (var i = 0; i < overwriteArray.length; i++) {
 							el = overwriteArray[i];
 							Ext.create('Ext.tip.ToolTip', {
 								target: el,
-								html: 'Overwrite',
+								html: 'Overwrite', //i18n
 								'anchor': 'bottom',
 								anchorOffset: -14,
 								showDelay: 1000
 							});
+						}
 
-							el = deleteArray[i];
+						for (var i = 0; i < sharingArray.length; i++) {
+							el = sharingArray[i];
 							Ext.create('Ext.tip.ToolTip', {
 								target: el,
-								html: 'Delete',
+								html: 'Share with other people', //i18n
 								'anchor': 'bottom',
 								anchorOffset: -14,
 								showDelay: 1000
@@ -1947,7 +2239,18 @@
 							el = dashboardArray[i];
 							Ext.create('Ext.tip.ToolTip', {
 								target: el,
-								html: 'Add to dashboard',
+								html: 'Add to dashboard', //i18n
+								'anchor': 'bottom',
+								anchorOffset: -14,
+								showDelay: 1000
+							});
+						}
+
+						for (var i = 0; i < deleteArray.length; i++) {
+							el = deleteArray[i];
+							Ext.create('Ext.tip.ToolTip', {
+								target: el,
+								html: 'Delete', //i18n
 								'anchor': 'bottom',
 								anchorOffset: -14,
 								showDelay: 1000
@@ -1977,19 +2280,18 @@
 			bodyStyle: 'padding:5px',
 			resizable: false,
 			modal: true,
-			width: 450,
+			width: windowWidth,
 			items: [
 				{
 					xtype: 'panel',
 					layout: 'hbox',
-					width: 422,
 					cls: 'gis-container-inner',
 					items: [
 						addButton,
 						{
 							height: 24,
 							width: 1,
-							style: 'width: 1px; margin-left: 7px; margin-right: 7px; margin-top: 1px',
+							style: 'width:1px; margin-left:5px; margin-right:5px; margin-top:1px',
 							bodyStyle: 'border-left: 1px solid #aaa'
 						},
 						searchTextfield
@@ -4472,7 +4774,7 @@
 								viewport.mapWindow.show();
 							}
 						});
-						if (gis.init.security.isAdmin) {
+						if (gis.init.user.isAdmin) {
 							a.push({
 								text: 'Legend', //i18n
 								menu: {},
@@ -4692,6 +4994,8 @@
 
 		initialize = function() {
 			gis.init = GIS.app.getInits(r);
+			gis.baseUrl = gis.init.contextPath;
+
 			gis.util = GIS.app.getUtils();
 			gis.store = GIS.app.getStores();
 

=== 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	2013-02-05 23:26:21 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js	2013-03-13 19:09:29 +0000
@@ -51,9 +51,8 @@
 			}
 		},
 		url: {
-			base: '../../',
-			path_api: 'api/',
-			path_gis: 'dhis-web-mapping/'
+			path_api: '/api/',
+			path_gis: '/dhis-web-mapping/'
 		},
 		layout: {
 			widget: {
@@ -347,7 +346,7 @@
 };
 
 GIS.core.createSelectHandlers = function(gis, layer) {
-	var isRelocate = !!GIS.app ? (gis.init.security.isAdmin ? true : false) : false,
+	var isRelocate = !!GIS.app ? (gis.init.user.isAdmin ? true : false) : false,
 		isInfo = !!GIS.app,
 
 		window,
@@ -715,7 +714,7 @@
 			menuItems.push( Ext.create('Ext.menu.Item', {
 				text: GIS.i18n.relocate,
 				iconCls: 'gis-menu-item-icon-relocate',
-				disabled: !gis.init.security.isAdmin,
+				disabled: !gis.init.user.isAdmin,
 				handler: function(item) {
 					gis.olmap.relocate.active = true;
 					gis.olmap.relocate.feature = feature;
@@ -1732,7 +1731,7 @@
 GIS.core.getInstance = function(config) {
 	var gis = {};
 
-	gis.baseUrl = config && config.baseUrl ? config.baseUrl : '../../';
+	gis.baseUrl = config && config.baseUrl ? config.baseUrl : '../..';
 	gis.el = config && config.el ? config.el : null;
 
 	gis.conf = GIS.core.getConfigs();

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/styles/style.css'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/styles/style.css	2013-03-08 11:00:41 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/styles/style.css	2013-03-13 19:53:02 +0000
@@ -139,6 +139,46 @@
 
 /* GIS */
 
+/*----------------------------------------------------------------------------
+ * Combobox
+ *--------------------------------------------------------------------------*/
+
+	/* Combobox text position*/
+.x-webkit .x-form-empty-field {
+    line-height: 14px;
+}
+
+	/* Combobox font size */
+.x-form-text, textarea.x-form-field {
+    font-size: 10px;
+}
+
+	/* Combobox field label font */
+.x-form-item-label {
+    font-size: 11px;
+    color: #111;
+}
+
+
+/*----------------------------------------------------------------------------
+ * GIS Combobox
+ *--------------------------------------------------------------------------*/
+
+	/* Combobox text position*/
+.gis-combo .x-form-text {
+    padding-left: 5px;
+}
+.gis-combo .small .x-form-field {
+	padding-top: 2px;
+}
+
+	/* Combobox border-radius */
+.gis-combo input {
+    border-radius: 2px 0px 0px 0px;
+    font-size: 10px !important;
+}
+
+
 /* Panel */
 
 .x-panel-header	{ /* Panel header */
@@ -146,6 +186,7 @@
 	padding: 7px 4px 4px 7px;
 }
 
+
 /* Form */
 
 .gis-form-subtitle,
@@ -431,6 +472,7 @@
 
 .gis-grid-row-icon-edit,
 .gis-grid-row-icon-overwrite,
+.gis-grid-row-icon-sharing,
 .gis-grid-row-icon-dashboard,
 .gis-grid-row-icon-delete {
 	width: 16px;
@@ -444,6 +486,10 @@
 	background: url('../images/grid-save_16.png') no-repeat;
 	margin-left: 4px;
 }
+.gis-grid-row-icon-sharing {
+	background: url('../images/grid-sharing_16.png') no-repeat;
+	margin-left: 4px;
+}
 .gis-grid-row-icon-dashboard {
 	background: url('../images/grid-dashboard_16.png') no-repeat;
 	margin-left: 4px;
@@ -461,6 +507,7 @@
 .gis-grid-row-icon-disabled * {
 	cursor: default !important;
 }
+.gis-grid-row-icon-disabled img.gis-grid-row-icon-sharing,
 .gis-grid-row-icon-disabled img.gis-grid-row-icon-dashboard {
 	cursor: pointer !important;
 }
@@ -544,8 +591,6 @@
 }
 
 /* Tooltip */
-
-/* Tooltip */
 .x-tip {
     border-radius: 2px;
     padding: 1px 4px;
@@ -556,6 +601,7 @@
 .x-tip .x-tip-body {
 	font-size: 10px;
 	color: #fff;
+	-webkit-text-stroke: 0.2px #fff;
 }
 
 .x-tip-anchor {

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/jsonInitialize.vm'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/jsonInitialize.vm	2012-12-14 16:56:33 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/jsonInitialize.vm	2013-03-13 19:09:29 +0000
@@ -25,7 +25,9 @@
     }#if( $velocityCount < $overlaysSize ),#end
 #end
   ],
-  "security": {
+  "user": {
+  	"id":"$!currentUser.uid",
+  	"name":"$currentUser.name",
     "isAdmin": $auth.hasAccess( "dhis-web-mapping", "deleteMapLegendSet" )
   },
   "rootNodes": [

=== 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-03-13 16:19:28 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js	2013-03-13 19:53:02 +0000
@@ -108,14 +108,27 @@
 					w.setPosition(targetx, y);
 				}
 			},
-			addBlurHandler: function(w) {
-				var el = Ext.get(Ext.query('.x-mask')[0]);
-
-				el.on('click', function() {
-					w.hide();
-				});
-
-				w.hasBlurHandler = true;
+			addHideOnBlurHandler: function(w) {
+				var el = Ext.get(Ext.query('.x-mask')[0]);
+
+				el.on('click', function() {
+					if (w.hideOnBlur) {
+						w.hide();
+					}
+				});
+
+				w.hasHideOnBlurHandler = true;
+			},
+			addDestroyOnBlurHandler: function(w) {
+				var el = Ext.get(Ext.query('.x-mask')[0]);
+
+				el.on('click', function() {
+					if (w.destroyOnBlur) {
+						w.destroy();
+					}
+				});
+
+				w.hasDestroyOnBlurHandler = true;
 			}
 		};
 
@@ -685,6 +698,7 @@
 			rowStore: rowStore,
 			colStore: colStore,
 			filterStore: filterStore,
+			hideOnBlur: true,
 			items: {
 				layout: 'column',
 				bodyStyle: 'border:0 none',
@@ -717,13 +731,12 @@
 					}
 				}
 			],
-			hasBlurHandler: false,
 			listeners: {
 				show: function(w) {
 					pt.util.window.setAnchorPosition(w, pt.viewport.layoutButton);
 
-					if (!w.hasBlurHandler) {
-						pt.util.window.addBlurHandler(w);
+					if (!w.hasHideOnBlurHandler) {
+						pt.util.window.addHideOnBlurHandler(w);
 					}
 				}
 			}
@@ -841,6 +854,7 @@
 			autoShow: true,
 			modal: true,
 			resizable: false,
+			hideOnBlur: true,
 			getOptions: function() {
 				return {
 					showSubTotals: showSubTotals.getValue(),
@@ -883,13 +897,12 @@
 					}
 				}
 			],
-			hasBlurHandler: false,
 			listeners: {
 				show: function(w) {
 					pt.util.window.setAnchorPosition(w, pt.viewport.optionsButton);
 
-					if (!w.hasBlurHandler) {
-						pt.util.window.addBlurHandler(w);
+					if (!w.hasHideOnBlurHandler) {
+						pt.util.window.addHideOnBlurHandler(w);
 					}
 				}
 			}
@@ -1057,10 +1070,10 @@
 
 			nameTextfield = Ext.create('Ext.form.field.Text', {
 				height: 26,
-				width: 300,
-				labelWidth: 70,
-				fieldStyle: 'padding-left: 6px; border-radius: 1px; border-color: #bbb',
-				fieldLabel: 'Name', //i18n
+				width: 250,
+				fieldStyle: 'padding-left: 6px; border-radius: 1px; border-color: #bbb; font-size:11px',
+				style: 'margin-bottom:0',
+				emptyText: 'Favorite name',
 				value: id ? record.data.name : '',
 				listeners: {
 					afterrender: function() {
@@ -1073,10 +1086,9 @@
 				text: 'Create', //i18n
 				handler: function() {
 					var favorite = getBody();
-
 					favorite.name = nameTextfield.getValue();
 
-					if (favorite) {
+					if (favorite && favorite.name) {
 						Ext.Ajax.request({
 							url: pt.baseUrl + '/api/reportTables/',
 							method: 'POST',
@@ -1099,9 +1111,6 @@
 							}
 						});
 					}
-					else {
-						alert('Please create a table first');
-					}
 				}
 			});
 
@@ -1153,12 +1162,11 @@
 			window = Ext.create('Ext.window.Window', {
 				title: id ? 'Rename favorite' : 'Create new favorite',
 				//iconCls: 'pt-window-title-icon-favorite',
-				bodyStyle: 'padding:8px; background:#fff',
+				bodyStyle: 'padding:5px; background:#fff',
 				resizable: false,
 				modal: true,
-				items: [
-					nameTextfield
-				],
+				items: nameTextfield,
+				destroyOnBlur: true,
 				bbar: [
 					cancelButton,
 					'->',
@@ -1166,7 +1174,16 @@
 				],
 				listeners: {
 					show: function(w) {
-						pt.util.window.setAnchorPosition(w, pt.viewport.favoriteButton);
+						pt.util.window.setAnchorPosition(w, addButton);
+
+						if (!w.hasDestroyBlurHandler) {
+							pt.util.window.addDestroyOnBlurHandler(w);
+						}
+
+						pt.viewport.favoriteWindow.destroyOnBlur = false;
+					},
+					destroy: function() {
+						pt.viewport.favoriteWindow.destroyOnBlur = true;
 					}
 				}
 			});
@@ -1180,6 +1197,7 @@
 			height: 26,
 			style: 'border-radius: 1px;',
 			menu: {},
+			disabled: !Ext.isObject(pt.xSettings),
 			handler: function() {
 				nameWindow = new NameWindow(null, 'create');
 				nameWindow.show();
@@ -1243,8 +1261,6 @@
 			cls: 'pt-grid',
 			scroll: false,
 			hideHeaders: true,
-			bodyStyle: 'padding-bottom:1px solid red !important',
-			style: 'padding-bottom:1px solid red !important',
 			columns: [
 				{
 					dataIndex: 'name',
@@ -1339,8 +1355,6 @@
 								var record = this.up('grid').store.getAt(rowIndex),
 									id = record.data.id,
 									window;
-									//name = record.data.name,
-									//message = 'Add to dashboard?\n\n' + name;
 
 								Ext.Ajax.request({
 									url: pt.baseUrl + '/api/sharing?type=reportTable&id=' + id,
@@ -1350,7 +1364,7 @@
 										alert(r.responseText);
 									},
 									success: function(r) {
-										sharing = Ext.decode(r.responseText);
+										var sharing = Ext.decode(r.responseText);
 										window = PT.app.SharingWindow(sharing);
 										window.show();
 									}
@@ -1421,47 +1435,29 @@
 				},
 				afterrender: function() {
 					var fn = function() {
-						var editArray = document.getElementsByClassName('tooltip-favorite-edit'),
-							overwriteArray = document.getElementsByClassName('tooltip-favorite-overwrite'),
-							dashboardArray = document.getElementsByClassName('tooltip-favorite-dashboard'),
-							sharingArray = document.getElementsByClassName('tooltip-favorite-sharing'),
-							deleteArray = document.getElementsByClassName('tooltip-favorite-delete'),
+						var editArray = Ext.query('.tooltip-favorite-edit'),
+							overwriteArray = Ext.query('.tooltip-favorite-overwrite'),
+							//dashboardArray = Ext.query('.tooltip-favorite-dashboard'),
+							sharingArray = Ext.query('.tooltip-favorite-sharing'),
+							deleteArray = Ext.query('.tooltip-favorite-delete'),
 							el;
 
-						for (var i = 0; i < deleteArray.length; i++) {
-							el = editArray[i];
+						for (var i = 0; i < editArray.length; i++) {
+							var el = editArray[i];
 							Ext.create('Ext.tip.ToolTip', {
 								target: el,
-								html: 'Rename',
+								html: 'Rename', //i18n
 								'anchor': 'bottom',
 								anchorOffset: -14,
 								showDelay: 1000
 							});
+						}
 
+						for (var i = 0; i < overwriteArray.length; i++) {
 							el = overwriteArray[i];
 							Ext.create('Ext.tip.ToolTip', {
 								target: el,
-								html: 'Overwrite',
-								'anchor': 'bottom',
-								anchorOffset: -14,
-								showDelay: 1000
-							});
-
-							el = deleteArray[i];
-							Ext.create('Ext.tip.ToolTip', {
-								target: el,
-								html: 'Delete',
-								'anchor': 'bottom',
-								anchorOffset: -14,
-								showDelay: 1000
-							});
-						}
-
-						for (var i = 0; i < dashboardArray.length; i++) {
-							el = dashboardArray[i];
-							Ext.create('Ext.tip.ToolTip', {
-								target: el,
-								html: 'Add to dashboard',
+								html: 'Overwrite', //i18n
 								'anchor': 'bottom',
 								anchorOffset: -14,
 								showDelay: 1000
@@ -1472,7 +1468,18 @@
 							el = sharingArray[i];
 							Ext.create('Ext.tip.ToolTip', {
 								target: el,
-								html: 'Share with other people',
+								html: 'Share with other people', //i18n
+								'anchor': 'bottom',
+								anchorOffset: -14,
+								showDelay: 1000
+							});
+						}
+
+						for (var i = 0; i < deleteArray.length; i++) {
+							el = deleteArray[i];
+							Ext.create('Ext.tip.ToolTip', {
+								target: el,
+								html: 'Delete', //i18n
 								'anchor': 'bottom',
 								anchorOffset: -14,
 								showDelay: 1000
@@ -1498,10 +1505,11 @@
 		favoriteWindow = Ext.create('Ext.window.Window', {
 			title: 'Manage favorites',
 			//iconCls: 'pt-window-title-icon-favorite',
-			bodyStyle: 'padding: 5px; background-color:#fff',
+			bodyStyle: 'padding:5px; background-color:#fff',
 			resizable: false,
 			modal: true,
 			width: windowWidth,
+			destroyOnBlur: true,
 			items: [
 				{
 					xtype: 'panel',
@@ -1512,7 +1520,7 @@
 						{
 							height: 24,
 							width: 1,
-							style: 'width: 1px; margin-left: 5px; margin-right: 5px; margin-top: 1px',
+							style: 'width:1px; margin-left:5px; margin-right:5px; margin-top:1px',
 							bodyStyle: 'border-left: 1px solid #aaa'
 						},
 						searchTextfield
@@ -1524,8 +1532,8 @@
 				show: function(w) {
 					pt.util.window.setAnchorPosition(w, pt.viewport.favoriteButton);
 
-					if (!w.hasBlurHandler) {
-						pt.util.window.addBlurHandler(w);
+					if (!w.hasDestroyOnBlurHandler) {
+						pt.util.window.addDestroyOnBlurHandler(w);
 					}
 				}
 			}
@@ -1737,6 +1745,7 @@
 			width: 434,
 			resizable: false,
 			modal: true,
+			destroyOnBlur: true,
 			items: [
 				{
 					html: sharing.object.name,
@@ -1774,7 +1783,17 @@
 			],
 			listeners: {
 				show: function(w) {
-					w.setPosition(w.getPosition()[0], 33);
+					var pos = pt.viewport.favoriteWindow.getPosition();
+					w.setPosition(pos[0] + 5, pos[1] + 5);
+
+					if (!w.hasDestroyOnBlurHandler) {
+						pt.util.window.addDestroyOnBlurHandler(w);
+					}
+
+					pt.viewport.favoriteWindow.destroyOnBlur = false;
+				},
+				destroy: function() {
+					pt.viewport.favoriteWindow.destroyOnBlur = true;
 				}
 			}
 		});

=== 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-03-13 11:59:50 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css	2013-03-13 19:09:29 +0000
@@ -512,7 +512,7 @@
 }
 
 .x-tip-anchor {
-	border-bottom-color: #111;
+	border-top-color: #111;
 }
 
 
@@ -542,8 +542,8 @@
 
 .pt-grid-row-icon-edit,
 .pt-grid-row-icon-overwrite,
+.pt-grid-row-icon-sharing,
 .pt-grid-row-icon-dashboard,
-.pt-grid-row-icon-sharing,
 .pt-grid-row-icon-delete {
 	width: 16px;
 	height: 16px;
@@ -556,14 +556,14 @@
 	background: url('../images/grid-save_16.png') no-repeat;
 	margin-left: 4px;
 }
+.pt-grid-row-icon-sharing {
+	background: url('../images/grid-sharing_16.png') no-repeat;
+	margin-left: 4px;
+}
 .pt-grid-row-icon-dashboard {
 	background: url('../images/grid-dashboard_16.png') no-repeat;
 	margin-left: 4px;
 }
-.pt-grid-row-icon-sharing {
-	background: url('../images/grid-sharing_16.png') no-repeat;
-	margin-left: 4px;
-}
 .pt-grid-row-icon-delete {
 	background: url('../images/grid-delete_16.png') no-repeat;
 	margin-left: 4px;
@@ -577,8 +577,8 @@
 .pt-grid-row-icon-disabled * {
 	cursor: default !important;
 }
-.pt-grid-row-icon-disabled img.pt-grid-row-icon-dashboard,
-.pt-grid-row-icon-disabled img.pt-grid-row-icon-sharing {
+.pt-grid-row-icon-disabled img.pt-grid-row-icon-sharing,
+.pt-grid-row-icon-disabled img.pt-grid-row-icon-dashboard {
 	cursor: pointer !important;
 }
 

=== 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-03-13 12:34:10 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/jsonInitialize.vm	2013-03-13 19:09:29 +0000
@@ -1,6 +1,6 @@
 #set($oucSize = $currentUser.getOrganisationUnit().getSortedChildren().size()){
 "contextPath":"$!{contextPath}",
-"user":{"id":"$!currentUser.id","name":"$currentUser.name","isAdmin":true,
+"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]},
 "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],


Follow ups