You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ve...@apache.org on 2015/04/03 23:52:00 UTC

incubator-ranger git commit: RANGER-204 : Update show/hide users/groups functionality

Repository: incubator-ranger
Updated Branches:
  refs/heads/master 6ba785079 -> b15105336


RANGER-204 : Update show/hide users/groups functionality

Signed-off-by: Velmurugan Periasamy <ve...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/b1510533
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/b1510533
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/b1510533

Branch: refs/heads/master
Commit: b15105336769622148e9cc81e2be48b48e46dda9
Parents: 6ba7850
Author: Gautam Borad <gb...@gmail.com>
Authored: Wed Apr 1 23:54:53 2015 +0530
Committer: Velmurugan Periasamy <ve...@apache.org>
Committed: Fri Apr 3 17:50:33 2015 -0400

----------------------------------------------------------------------
 .../scripts/collection_bases/VXGroupListBase.js |   2 +
 .../scripts/collection_bases/VXUserListBase.js  |   2 +
 .../src/main/webapp/scripts/models/VXGroup.js   |   2 +
 .../src/main/webapp/scripts/models/VXUser.js    |   2 +
 .../main/webapp/scripts/modules/XAOverrides.js  | 208 ++++++++++++++++-
 .../scripts/modules/globalize/message/en.js     |   1 +
 .../scripts/views/users/UserTableLayout.js      | 231 ++++---------------
 .../templates/users/UserTableLayout_tmpl.html   |  28 +--
 8 files changed, 277 insertions(+), 199 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b1510533/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js b/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js
index 4b86d08..20edf0b 100644
--- a/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js
+++ b/security-admin/src/main/webapp/scripts/collection_bases/VXGroupListBase.js
@@ -40,6 +40,8 @@ define(function(require){
 		initialize : function() {
 			this.modelName = 'VXGroup';
 			this.modelAttrName = 'vXGroups';
+			var multiSelect = new Backbone.Picky.MultiSelect(this);
+			_.extend(this, multiSelect);
 			this.bindErrorEvents();
             this._changes = { };
 			this.on('change', this._onChange);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b1510533/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js b/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js
index 2c7f5fc..3745bc0 100644
--- a/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js
+++ b/security-admin/src/main/webapp/scripts/collection_bases/VXUserListBase.js
@@ -40,6 +40,8 @@ define(function(require){
 		initialize : function() {
 			this.modelName = 'VXUser';
 			this.modelAttrName = 'vXUsers';
+			var multiSelect = new Backbone.Picky.MultiSelect(this);
+			_.extend(this, multiSelect);
 			this.bindErrorEvents();
             this._changes = { };
 			this.on('change', this._onChange);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b1510533/security-admin/src/main/webapp/scripts/models/VXGroup.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/models/VXGroup.js b/security-admin/src/main/webapp/scripts/models/VXGroup.js
index fdad8aa..3aa3615 100644
--- a/security-admin/src/main/webapp/scripts/models/VXGroup.js
+++ b/security-admin/src/main/webapp/scripts/models/VXGroup.js
@@ -35,6 +35,8 @@ define(function(require){
 		 */
 		initialize: function() {
 			this.modelName = 'VXGroup';
+			var selectable = new Backbone.Picky.Selectable(this);
+			_.extend(this, selectable);
 			this.bindErrorEvents();
 			this.toView();
 		},

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b1510533/security-admin/src/main/webapp/scripts/models/VXUser.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/models/VXUser.js b/security-admin/src/main/webapp/scripts/models/VXUser.js
index b74ed5a..875b828 100644
--- a/security-admin/src/main/webapp/scripts/models/VXUser.js
+++ b/security-admin/src/main/webapp/scripts/models/VXUser.js
@@ -34,6 +34,8 @@ define(function(require){
 		 */
 		initialize: function() {
 			this.modelName = 'VXUser';
+			var selectable = new Backbone.Picky.Selectable(this);
+			_.extend(this, selectable);
 			this.bindErrorEvents();
 			this.toView();
 		},

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b1510533/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/modules/XAOverrides.js b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
index f312065..11085d5 100644
--- a/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
+++ b/security-admin/src/main/webapp/scripts/modules/XAOverrides.js
@@ -762,7 +762,11 @@
 		    onChange: function () {
 		      var checked = this.checkbox().prop("checked");
 		      this.$el.parent().toggleClass("selected", checked);
-		      this.model.set('isVisible', checked)
+		      if(checked){
+		      	this.model.select();
+		      }else{
+		      	this.model.deselect();
+		      }
 		      this.model.trigger("backgrid:selected", this.model, checked);
 		    },
 
@@ -936,4 +940,206 @@
 		    }
 		  };
 
+	Backbone.Picky = (function(Backbone, _) {
+		var Picky = {};
+
+		// Picky.SingleSelect
+		// ------------------
+		// A single-select mixin for Backbone.Collection, allowing a single
+		// model to be selected within a collection. Selection of another
+		// model within the collection causes the previous model to be
+		// deselected.
+
+		Picky.SingleSelect = function(collection) {
+			this.collection = collection;
+		};
+
+		_.extend(Picky.SingleSelect.prototype, {
+
+			// Select a model, deselecting any previously
+			// selected model
+			select: function(model) {
+				if (model && this.selected === model) {
+					return;
+				}
+
+				this.deselect();
+
+				this.selected = model;
+				this.selected.select();
+				this.trigger("select:one", model);
+			},
+
+			// Deselect a model, resulting in no model
+			// being selected
+			deselect: function(model) {
+				if (!this.selected) {
+					return;
+				}
+
+				model = model || this.selected;
+				if (this.selected !== model) {
+					return;
+				}
+
+				this.selected.deselect();
+				this.trigger("deselect:one", this.selected);
+				delete this.selected;
+			}
+
+		});
+
+		// Picky.MultiSelect
+		// -----------------
+		// A mult-select mixin for Backbone.Collection, allowing a collection to
+		// have multiple items selected, including `selectAll` and `selectNone`
+		// capabilities.
+
+		Picky.MultiSelect = function(collection) {
+			this.collection = collection;
+			this.selected = {};
+		};
+
+		_.extend(Picky.MultiSelect.prototype, {
+
+			// Select a specified model, make sure the
+			// model knows it's selected, and hold on to
+			// the selected model.
+			select: function(model) {
+				if (this.selected[model.id]) {
+					return;
+				}
+
+				this.selected[model.id] = model;
+				model.select();
+				calculateSelectedLength(this);
+			},
+
+			// Deselect a specified model, make sure the
+			// model knows it has been deselected, and remove
+			// the model from the selected list.
+			deselect: function(model) {
+				if (!this.selected[model.id]) {
+					return;
+				}
+
+				delete this.selected[model.id];
+				model.deselect();
+				calculateSelectedLength(this);
+			},
+
+			// Select all models in this collection
+			selectAll: function() {
+				this.each(function(model) {
+					model.select();
+				});
+				calculateSelectedLength(this);
+			},
+
+			// Deselect all models in this collection
+			selectNone: function() {
+				if (this.selectedLength === 0) {
+					return;
+				}
+				this.each(function(model) {
+					model.deselect();
+				});
+				calculateSelectedLength(this);
+			},
+
+			// Toggle select all / none. If some are selected, it
+			// will select all. If all are selected, it will select 
+			// none. If none are selected, it will select all.
+			toggleSelectAll: function() {
+				if (this.selectedLength === this.length) {
+					this.selectNone();
+				} else {
+					this.selectAll();
+				}
+			}
+		});
+
+		// Picky.Selectable
+		// ----------------
+		// A selectable mixin for Backbone.Model, allowing a model to be selected,
+		// enabling it to work with Picky.MultiSelect or on it's own
+
+		Picky.Selectable = function(model) {
+			this.model = model;
+		};
+
+		_.extend(Picky.Selectable.prototype, {
+
+			// Select this model, and tell our
+			// collection that we're selected
+			select: function() {
+				if (this.selected) {
+					return;
+				}
+
+				this.selected = true;
+				this.trigger("selected", this);
+
+				if (this.collection) {
+					this.collection.select(this);
+				}
+			},
+
+			// Deselect this model, and tell our
+			// collection that we're deselected
+			deselect: function() {
+				if (!this.selected) {
+					return;
+				}
+
+				this.selected = false;
+				this.trigger("deselected", this);
+
+				if (this.collection) {
+					this.collection.deselect(this);
+				}
+			},
+
+			// Change selected to the opposite of what
+			// it currently is
+			toggleSelected: function() {
+				if (this.selected) {
+					this.deselect();
+				} else {
+					this.select();
+				}
+			}
+		});
+
+		// Helper Methods
+		// --------------
+
+		// Calculate the number of selected items in a collection
+		// and update the collection with that length. Trigger events
+		// from the collection based on the number of selected items.
+		var calculateSelectedLength = function(collection) {
+			collection.selectedLength = _.size(collection.selected);
+
+			var selectedLength = collection.selectedLength;
+			var length = collection.length;
+
+			if (selectedLength === length) {
+				collection.trigger("select:all", collection);
+				return;
+			}
+
+			if (selectedLength === 0) {
+				collection.trigger("select:none", collection);
+				return;
+			}
+
+			if (selectedLength > 0 && selectedLength < length) {
+				collection.trigger("select:some", collection);
+				return;
+			}
+		};
+
+		return Picky;
+	})(Backbone, _);
+
 });

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b1510533/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js b/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
index 9b5b5e8..843d70c 100644
--- a/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
+++ b/security-admin/src/main/webapp/scripts/modules/globalize/message/en.js
@@ -142,6 +142,7 @@ define(function(require) {
 				accountStatus					: 'Account Status',
 				ActiveStatus_STATUS_ENABLED 	: 'Enabled',
 				ActiveStatus_STATUS_DISABLED 	: 'Disabled',
+				visibility						: 'Visibility',
 				VisibilityStatus_IS_VISIBLE     : 'Visible',
 				VisibilityStatus_IS_HIDDEN      : 'Hidden',
 				commonNameForCertificate 		: 'Common Name For Certificate',

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b1510533/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js b/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
index 161a09a..74ecdbe 100644
--- a/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
+++ b/security-admin/src/main/webapp/scripts/views/users/UserTableLayout.js
@@ -57,7 +57,9 @@ define(function(require){
     		visualSearch: '.visual_search',
     		btnShowMore : '[data-id="showMore"]',
 			btnShowLess : '[data-id="showLess"]',
-    		btnSave		: '[data-id="save"]'
+    		btnSave		: '[data-id="save"]',
+    		btnShowHide		: '[data-action="showHide"]',
+    		visibilityDropdown : '[data-id="visibilityDropdown"]'
     	},
 
 		/** ui events hash */
@@ -67,6 +69,8 @@ define(function(require){
 			events['click ' + this.ui.btnShowMore]  = 'onShowMore';
 			events['click ' + this.ui.btnShowLess]  = 'onShowLess';
 			events['click ' + this.ui.btnSave]  = 'onSave';
+			events['click ' + this.ui.visibilityDropdown +' li a']  = 'onVisibilityChange';
+			
 			return events;
 		},
 
@@ -93,16 +97,8 @@ define(function(require){
 		/** all events binding here */
 		bindEvents : function(){
 			var that = this;
-            this.listenTo(this.collection,"backgrid:selected", this.onModelChange);
-            this.listenTo(this.groupList,"backgrid:selected", this.onModelChange);
 			/*this.listenTo(this.model, "change:foo", this.modelChanged, this);*/
 			/*this.listenTo(communicator.vent,'someView:someEvent', this.someEventHandler, this)'*/
-			this.collection.on('change', function(){
-				that.preventNavigation();
-			});
-			this.groupList.on('change', function(){
-				that.preventNavigation();
-			});
 		},
 
 		/** on render callback */
@@ -114,33 +110,6 @@ define(function(require){
 				this.renderUserTab();
 			this.addVisualSearch();
 		},
-
-		preventNavigation : function(){
-            XAUtil.preventNavigation(localization.tt('dialogMsg.preventNavUserList'),this.rTableList.$el);
-			this.rTableList.$el.find('table').addClass('dirtyField');
-			//this.ui.btnSave.removeClass('disabled');
-		},
-
-		allowNavigation : function(){
-			XAUtil.allowNavigation();
-			this.rTableList.$el.find('table').removeClass('dirtyField');
-			//this.ui.btnSave.addClass('disabled');
-		},
-
-		onModelChange : function(model, selected){
-			/*var that = this;
-			if(! (model.id in that.chgFlags)){
-				that.chgFlags[model.id] = true;
-			} else {
-                that.chgFlags[model.id] ^= true;
-            }
-
-			if (_.some(that.chgFlags)){
-                that.preventNavigation();
-			} else {
-                that.allowNavigation();
-			}*/
-		},
 		onTabChange : function(e){
 			var that = this;
 			this.chgFlags = [];
@@ -155,14 +124,18 @@ define(function(require){
 			}
 			$(this.rUserDetail.el).hide();
 		},
-		onSave : function(e){
+		onVisibilityChange : function(e){
 			var that = this;
+			var status = $(e.currentTarget).attr('data-id') == 'visible' ? true : false;
 			var updateReq = {};
 			var collection = this.showUsers ? this.collection : this.groupList;
 
-			collection.changed_models().each(function(m){
-				m.toServer();
-				updateReq[m.get('id')] = m.get('isVisible');
+			_.each(collection.selected, function(m){
+				if( m.get('isVisible') != status ){
+					m.set('isVisible', status);
+					m.toServer();
+					updateReq[m.get('id')] = m.get('isVisible');
+				}
 			});
 
 			var clearCache = function(coll){
@@ -178,7 +151,6 @@ define(function(require){
 				collection.setUsersVisibility(updateReq, {
 					success : function(){
 						that.chgFlags = [];
-						that.allowNavigation();
 						clearCache(collection);
 					}
 				});
@@ -186,18 +158,17 @@ define(function(require){
 			    collection.setGroupsVisibility(updateReq, {
 					success : function(){
 						that.chgFlags = [];
-						that.allowNavigation();
 						clearCache(collection);
 					}
                 });
 			}
-
 		},
 		renderUserTab : function(){
 			var that = this;
 			if(_.isUndefined(this.collection)){
 				this.collection = new VXUserList();
 			}	
+			this.collection.selectNone();
 			this.renderUserListTable();
 			this.collection.fetch({
 				cache:true
@@ -214,6 +185,7 @@ define(function(require){
 			if(_.isUndefined(this.groupList)){
 				this.groupList = new VXGroupList();
 			}
+			this.groupList.selectNone();
 			this.renderGroupListTable();
 			this.groupList.fetch({
 				cache:true
@@ -228,61 +200,13 @@ define(function(require){
 		renderUserListTable : function(){
 			var that = this;
 			var tableRow = Backgrid.Row.extend({
-
 				render: function () {
     				tableRow.__super__.render.apply(this, arguments);
-    				if (this.model.get("isVisible") == 0) {
-      					this.el.classList.add("tr-inactive");
+    				if(!this.model.get('isVisible')){
+    					this.$el.addClass('tr-inactive');
     				}
     				return this;
-				},				
-				events: {
-					'change' : 'onClickCheckbox'
-				},
-				onClickCheckbox: function(e) {
-					if (this.model.get("isVisible") == 0) {
-						this.el.classList.add("tr-inactive");						
-					} else {
-						this.el.classList.remove("tr-inactive");
-					};
 				},
-				/*
-				initialize : function(){
-					var that = this;
-					var args = Array.prototype.slice.apply(arguments);
-					Backgrid.Row.prototype.initialize.apply(this, args);
-					this.listenTo(this.model, 'model:highlightBackgridRow', function(){
-						that.$el.addClass("alert");
-						$("html, body").animate({scrollTop: that.$el.position().top},"linear");
-						setTimeout(function () {
-							that.$el.removeClass("alert");
-						}, 1500);
-					}, this);
-				},
-				onClick: function (e) {
-				   if($(e.target).is('a'))
-					   return;
-				   this.$el.parent('tbody').find('tr').removeClass('tr-active');
-				   this.$el.toggleClass('tr-active');
-				   var groupList = new VXGroupList();
-				   var userModel = this.model;
-				   groupList.getGroupsForUser(this.model.id,{
-					  cache : false, 
-					  success :function(msResponse){
-						  var groupColl = msResponse.vXGroups ? msResponse.vXGroups : null; 
-						  if(that.rUserDetail){
-								$(that.rUserDetail.el).hide();
-								$(that.rUserDetail.el).html(new vUserInfo({
-									  model : userModel,
-									  groupList : new VXGroupList(groupColl)
-								  }).render().$el).slideDown();
-							}
-					  },
-					  error : function(){
-						  console.log('error..');
-					  }
-				   });
-				} */
 			});
 			this.rTableList.show(new XATableLayout({
 				columns: this.getColumns(),
@@ -300,7 +224,7 @@ define(function(require){
 		getColumns : function(){
 			var cols = {
 				
-				isVisible : {
+				select : {
 					label : localization.tt("lbl.isVisible"),
 					//cell : Backgrid.SelectCell.extend({className: 'cellWidth-1'}),
 					cell: "select-row",
@@ -374,41 +298,26 @@ define(function(require){
 							return '--';
 						}
 					}),
-					/*cell	: Backgrid.HtmlCell.extend({className: 'cellWidth-1'}),
-					label : localization.tt("lbl.groups"),
-					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
-						fromRaw: function (rawValue) {
-							var html = '';
-							if(!_.isUndefined(rawValue)){
-								_.each(rawValue,function(name){
-									html += '<span class="label label-info">'+name+'</span>';
-								});
-								return html;
-							}else
-								return '--';
-						}
-					}),*/
 					editable : false,
 					sortable : false
 				},
-			/*	status : {
-					label : localization.tt("lbl.status"),
+				isVisible : {
+					label	: localization.tt("lbl.visibility"),
 					cell	: Backgrid.HtmlCell.extend({className: 'cellWidth-1'}),
 					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
 						fromRaw: function (rawValue, model) {
-							var status = model.has('status') ? 'Active' : 'Deactive';
-							if(model.has('status'))
-								return '<span class="label label-success">' +status + '</span>';
-							else
-								return '<span class="label label-important">' +status + '</span>';
-						//	return model.has('status') ? 'On' : 'Off';
+							if(!_.isUndefined(rawValue)){
+								if(rawValue)
+									return '<span class="label label-success">'+XAEnums.VisibilityStatus.STATUS_VISIBLE.label+'</span>';
+								else
+									return '<span class="label label-green">'+XAEnums.VisibilityStatus.STATUS_HIDDEN.label+'</span>';
+							}else
+								return '--';
 						}
 					}),
-					click : false,
-					drag : false,
 					editable:false,
-					sortable:false,
-				},*/
+					sortable:false
+				},
 				
 			};
 			return this.collection.constructor.getTableCols(cols, this.collection);
@@ -416,55 +325,22 @@ define(function(require){
 		
 		renderGroupListTable : function(){
 			var that = this;
-			/*var tableRow = Backgrid.Row.extend({
-				events: {
-					'click' : 'onClick'
-				},
-				initialize : function(){
-					var that = this;
-					var args = Array.prototype.slice.apply(arguments);
-					Backgrid.Row.prototype.initialize.apply(this, args);
-					this.listenTo(this.model, 'model:highlightBackgridRow1', function(){
-						that.$el.addClass("alert");
-						$("html, body").animate({scrollTop: that.$el.position().top},"linear");
-						setTimeout(function () {
-							that.$el.removeClass("alert");
-						}, 1500);
-					}, this);
+			
+			var tableRow = Backgrid.Row.extend({
+				render: function () {
+    				tableRow.__super__.render.apply(this, arguments);
+    				if(!this.model.get('isVisible')){
+    					this.$el.addClass('tr-inactive');
+    				}
+    				return this;
 				},
-				onClick: function (e) {
-				   if($(e.target).is('a'))
-					   return;
-				   this.$el.parent('tbody').find('tr').removeClass('tr-active');
-				   this.$el.toggleClass('tr-active');	
-				   var userList = new VXUserList();
-				   var gid = this.model.id;
-				   var groupModel = new VXGroup({id:gid});
-				   groupModel.fetch().done(function(msResponse){
-					   userList.getUsersOfGroup(gid,{
-						   success :function(msResponse){
-							   var userColl = msResponse.vXUsers ? msResponse.vXUsers : null; 
-							   if(that.rUserDetail){
-								   $(that.rUserDetail.el).hide();
-								   $(that.rUserDetail.el).html(new vUserInfo({
-									   model 	: groupModel,
-									   userList: new VXUserList(userColl)
-								   }).render().$el).slideDown(); 
-							   }
-						   },
-						   error : function(){
-							   console.log('error..');
-						   }
-					   });
-				   });
-				}
-			});*/
+			});
 			this.rTableList.show(new XATableLayout({
 				columns: this.getGroupColumns(),
 				collection: this.groupList,
 				includeFilter : false,
 				gridOpts : {
-//					row: tableRow,
+					row: tableRow,
 					header : XABackgrid,
 					emptyText : 'No Groups found!'
 				}
@@ -475,7 +351,7 @@ define(function(require){
 		getGroupColumns : function(){
 			var cols = {
 				
-                isVisible : {
+                select : {
 					label : localization.tt("lbl.isVisible"),
 					//cell : Backgrid.SelectCell.extend({className: 'cellWidth-1'}),
 					cell: "select-row",
@@ -514,23 +390,23 @@ define(function(require){
 					editable:false,
 					sortable:false,
 				},
-				/*status : {
-					label : localization.tt("lbl.status"),
+				isVisible : {
+					label	: localization.tt("lbl.visibility"),
 					cell	: Backgrid.HtmlCell.extend({className: 'cellWidth-1'}),
 					formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
 						fromRaw: function (rawValue, model) {
-							var status = model.has('status') ? 'Active' : 'Deactive';
-							if(model.has('status'))
-								return '<span class="label label-success">' +status + '</span>';
-							else
-								return '<span class="label label-important">' +status + '</span>';
+							if(!_.isUndefined(rawValue)){
+								if(rawValue)
+									return '<span class="label label-success">'+XAEnums.VisibilityStatus.STATUS_VISIBLE.label+'</span>';
+								else
+									return '<span class="label label-green">'+XAEnums.VisibilityStatus.STATUS_HIDDEN.label+'</span>';
+							}else
+								return '--';
 						}
 					}),
-					click : false,
-					drag : false,
 					editable:false,
-					sortable:false,
-				}, */
+					sortable:false
+				}
 			};
 			return this.groupList.constructor.getTableCols(cols, this.groupList);
 		},
@@ -548,8 +424,6 @@ define(function(require){
 				                   	{text : "Visibility", label :"isVisible", 'multiple' : true, 'optionsArr' : XAUtil.enumToSelectLabelValuePairs(XAEnums.VisibilityStatus)},
 				                   {text : "User Source", label :"userSource", 'multiple' : true, 'optionsArr' : XAUtil.enumToSelectLabelValuePairs(XAEnums.UserTypes)},
 								];
-				                  // {text : 'Start Date',label :'startDate'},{text : 'End Date',label :'endDate'},
-				                  // {text : 'Today',label :'today'}];
 			}else{
 				placeholder = localization.tt('h.searchForYourGroup');
 				coll = this.groupList;
@@ -557,9 +431,6 @@ define(function(require){
 				serverAttrName  = [{text : "Group Name", label :"name"},
 				                   {text : "Visibility", label :"isVisible", 'multiple' : true, 'optionsArr' : XAUtil.enumToSelectLabelValuePairs(XAEnums.VisibilityStatus)},
 				                   {text : "Group Source", label :"groupSource", 'multiple' : true, 'optionsArr' : XAUtil.enumToSelectLabelValuePairs(XAEnums.GroupTypes)},];
-				
-				                   //{text : 'Start Date',label :'startDate'},{text : 'End Date',label :'endDate'},
-				                   //{text : 'Today',label :'today'}];
 
 			}
 			var query = (!_.isUndefined(coll.VSQuery)) ? coll.VSQuery : '';

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b1510533/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
----------------------------------------------------------------------
diff --git a/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html b/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
index 21006b1..3dbefd4 100644
--- a/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
+++ b/security-admin/src/main/webapp/templates/users/UserTableLayout_tmpl.html
@@ -14,14 +14,6 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 --}}
-<!-- <ul class="nav nav-tabs">
-  <li class="active" data-js="users">
-    <a data-toggle="tab" href="#users">Users</a>
-  </li>
-  <li data="groups" data-js="groups">
-  	<a data-toggle="tab" href="#groups">Groups</a>
-  </li>
-</ul> -->
   <ul class="nav nav-tabs tabs clearfix">
     <li data="groups" data-js="groups"> 
       <a data-toggle="tab" href="#groups">Groups</a> 
@@ -31,13 +23,8 @@
     </li>
   </ul>
 
-
-
-
 <h3 class="wrap-header bold"> {{tt 'lbl.userListing'}} </h3>
-
 <div class="wrap non-collapsible m-height ">
-
 	<div>
 		<div class="span9">
 			<div class="visual_search"></div>
@@ -45,14 +32,19 @@
 		<div class="clearfix">
 			<a href="#!/user/create" class="btn btn-primary btn-right" type="button" data-id="addNewUser"> {{tt 'lbl.addNewUser'}} </a>
 			<a href="#!/group/create" class="btn btn-primary btn-right" type="button" data-id="addNewGroup" style="display:none;"> {{tt 'lbl.addNewGroup'}} </a>
-            <a href="javascript:void(0)" class="_allowNav btn btn-primary btn-right" type="button" data-id="save" style="display:block;" > {{tt 'btn.setVisibility'}} </a>
+      <div class="btn-group btn-right">
+        <a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#">
+          {{tt 'btn.setVisibility'}}
+          <span class="caret"></span>
+        </a>
+        <ul class="dropdown-menu" data-id="visibilityDropdown">
+          <li><a href="javascript:void(0);" data-id="visible">{{tt 'lbl.VisibilityStatus_IS_VISIBLE'}}</a></li>
+          <li><a href="javascript:void(0);" data-id="hidden">{{tt 'lbl.VisibilityStatus_IS_HIDDEN'}}</a></li>
+        </ul>
+      </div>
 		</div>
 		<div data-id="r_tableList" class="clickable">
           <b class="_prevNav"></b>
 		</div>
 	</div>
-
-	<!-- <div class="span3">
-		<div id="userDetail"></div>
-	</div> -->
 </div>