You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rz...@apache.org on 2015/11/20 02:01:39 UTC

ambari git commit: AMBARI-13756. FE: Create a switchable "Role" section for admin view (rzang)

Repository: ambari
Updated Branches:
  refs/heads/trunk b7a32bdc7 -> 765e68b25


AMBARI-13756. FE: Create a switchable "Role" section for admin view (rzang)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/765e68b2
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/765e68b2
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/765e68b2

Branch: refs/heads/trunk
Commit: 765e68b258864f202a8a00ac770ba8223dc006d5
Parents: b7a32bd
Author: Richard Zang <rz...@apache.org>
Authored: Thu Nov 19 17:00:38 2015 -0800
Committer: Richard Zang <rz...@apache.org>
Committed: Thu Nov 19 17:00:38 2015 -0800

----------------------------------------------------------------------
 .../main/resources/ui/admin-web/app/index.html  |   1 +
 .../clusters/ClustersManageAccessCtrl.js        |   6 +-
 .../controllers/clusters/UserAccessListCtrl.js  | 131 +++++++++++++++++++
 .../controllers/groups/GroupsEditCtrl.js        |   4 +-
 .../scripts/controllers/users/UsersShowCtrl.js  |   4 +-
 .../ui/admin-web/app/scripts/routes.js          |   5 +
 .../admin-web/app/scripts/services/Cluster.js   |  32 ++++-
 .../ui/admin-web/app/scripts/services/User.js   |   4 +-
 .../resources/ui/admin-web/app/styles/main.css  |  18 +++
 .../app/views/clusters/manageAccess.html        |  14 +-
 .../app/views/clusters/userAccessList.html      |  83 ++++++++++++
 .../ui/admin-web/app/views/groups/edit.html     |  14 +-
 .../ui/admin-web/app/views/leftNavbar.html      |   2 +-
 .../ui/admin-web/app/views/users/show.html      |  16 ++-
 14 files changed, 306 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index 44b957f..a6eab79 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -137,6 +137,7 @@
     <script src="scripts/controllers/ambariViews/ViewsEditCtrl.js"></script>
     <script src="scripts/controllers/ambariViews/CreateViewInstanceCtrl.js"></script>
     <script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script>
+    <script src="scripts/controllers/clusters/UserAccessListCtrl.js"></script>
     <script src="scripts/controllers/stackVersions/StackVersionsCreateCtrl.js"></script>
     <script src="scripts/controllers/stackVersions/StackVersionsListCtrl.js"></script>
     <script src="scripts/controllers/stackVersions/StackVersionsEditCtrl.js"></script>

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ClustersManageAccessCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ClustersManageAccessCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ClustersManageAccessCtrl.js
index 6aae599..1f3d3f6 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ClustersManageAccessCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ClustersManageAccessCtrl.js
@@ -18,7 +18,7 @@
 'use strict';
 
 angular.module('ambariAdminConsole')
-.controller('ClustersManageAccessCtrl', ['$scope', 'Cluster', '$routeParams', 'Alert', 'PermissionLoader', 'PermissionSaver', function($scope, Cluster, $routeParams, Alert, PermissionLoader, PermissionSaver) {
+.controller('ClustersManageAccessCtrl', ['$scope', '$location', 'Cluster', '$routeParams', 'Alert', 'PermissionLoader', 'PermissionSaver', function($scope, $location, Cluster, $routeParams, Alert, PermissionLoader, PermissionSaver) {
   $scope.identity = angular.identity;
   function reloadClusterData(){
     PermissionLoader.getClusterPermissions({
@@ -69,4 +69,8 @@ angular.module('ambariAdminConsole')
       $scope.save();
     }
   }, true);
+
+  $scope.switchToList = function() {
+    $location.url('/clusters/' + $routeParams.id + '/userAccessList');
+  }
 }]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/UserAccessListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/UserAccessListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/UserAccessListCtrl.js
new file mode 100644
index 0000000..4799e93
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/UserAccessListCtrl.js
@@ -0,0 +1,131 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.controller('UserAccessListCtrl',['$scope', '$location', 'Cluster', '$modal', '$rootScope', '$routeParams', 'PermissionSaver', 'Alert',
+function($scope, $location, Cluster, $modal, $rootScope, $routeParams, PermissionSaver, Alert) {
+  $scope.users = [];
+  $scope.usersPerPage = 10;
+  $scope.currentPage = 1;
+  $scope.totalUsers = 1;
+  $scope.currentNameFilter = '';
+  $scope.maxVisiblePages = 20;
+  $scope.roles = [];
+  $scope.clusterId = $routeParams.id;
+
+  $scope.pageChanged = function() {
+    $scope.loadUsers();
+  };
+  $scope.usersPerPageChanges = function() {
+    $scope.resetPagination();
+  };
+
+  $scope.loadUsers = function(){
+    Cluster.getPrivilegesWithFilters({
+      clusterId: $routeParams.id,
+      nameFilter: $scope.currentNameFilter,
+      typeFilter: $scope.currentTypeFilter,
+      roleFilter: $scope.currentRoleFilter,
+      currentPage: $scope.currentPage,
+      usersPerPage: $scope.usersPerPage
+    }).then(function(data) {
+      $scope.totalUsers = data.itemTotal;
+      $scope.users = data.items.map(function (user) {
+        var name = encodeURIComponent(user.PrivilegeInfo.principal_name);
+        var type = user.PrivilegeInfo.principal_type.toLowerCase();
+        user.PrivilegeInfo.encoded_name = name;
+        user.PrivilegeInfo.url = type == 'user'? (type + 's/' + name) : (type + 's/' + name + '/edit');
+        return user.PrivilegeInfo;
+      });
+      $scope.loadRoles();
+    });
+  };
+
+  $scope.loadRoles = function() {
+    Cluster.getPermissions({
+      clusterId: $routeParams.id
+    }).then(function(data) {
+      $scope.roles = data.map(function(item) {
+        return item.PermissionInfo;
+      });
+    });
+  };
+
+  // TODO change to PUT after it's available
+  $scope.save = function(user) {
+    Cluster.deletePrivilege(
+    $routeParams.id,
+    user.privilege_id
+    ).then(
+      function() {
+        Cluster.createPrivileges(
+        {
+          clusterId: $routeParams.id
+        },
+        [{PrivilegeInfo: {
+          permission_name: user.permission_name,
+          principal_name: user.principal_name,
+          principal_type: user.principal_type
+        }}]
+        ).then($scope.loadUsers)
+        .catch(function(data) {
+          Alert.error('Cannot save permissions', data.data.message);
+          $scope.loadUsers();
+        });
+      }
+    );
+
+  };
+
+  $scope.resetPagination = function() {
+    $scope.currentPage = 1;
+    $scope.loadUsers();
+  };
+
+  $scope.roleFilterOptions = [
+    {label: 'All', value: ''},
+    {label: 'Operator', value: 'CLUSTER.OPERATE'},
+    {label:'Read Only', value: 'CLUSTER.READ'}
+  ];
+  $scope.currentRoleFilter = $scope.roleFilterOptions[0];
+
+
+  $scope.typeFilterOptions = [
+    {label:'All', value:''},
+    {label:'Group', value:'GROUP'},
+    {label:'User', value:'USER'}
+  ];
+  $scope.currentTypeFilter = $scope.typeFilterOptions[0];
+
+
+  $scope.loadUsers();
+
+  $rootScope.$watch(function(scope) {
+    return scope.LDAPSynced;
+  }, function(LDAPSynced) {
+    if(LDAPSynced === true){
+      $rootScope.LDAPSynced = false;
+      $scope.loadUsers();
+    }
+  });
+
+  $scope.switchToBlock = function() {
+    $location.url('/clusters/' + $routeParams.id + '/manageAccess');
+  }
+}]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsEditCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsEditCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsEditCtrl.js
index b886fef..9e0c220 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsEditCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsEditCtrl.js
@@ -93,12 +93,12 @@ angular.module('ambariAdminConsole')
       if(privilege.type === 'CLUSTER'){
         // This is cluster
         privileges.clusters[privilege.cluster_name] = privileges.clusters[privilege.cluster_name] || [];
-        privileges.clusters[privilege.cluster_name].push(privilege.permission_name);
+        privileges.clusters[privilege.cluster_name].push(privilege.permission_label);
       } else if ( privilege.type === 'VIEW'){
         privileges.views[privilege.instance_name] = privileges.views[privilege.instance_name] || { privileges:[]};
         privileges.views[privilege.instance_name].version = privilege.version;
         privileges.views[privilege.instance_name].view_name = privilege.view_name;
-        privileges.views[privilege.instance_name].privileges.push(privilege.permission_name);
+        privileges.views[privilege.instance_name].privileges.push(privilege.permission_label);
       }
     });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersShowCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersShowCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersShowCtrl.js
index 2496717..cd4e020 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersShowCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersShowCtrl.js
@@ -169,12 +169,12 @@ angular.module('ambariAdminConsole')
         if(privilege.type === 'CLUSTER'){
           // This is cluster
           privileges.clusters[privilege.cluster_name] = privileges.clusters[privilege.cluster_name] || [];
-          privileges.clusters[privilege.cluster_name].push(privilege.permission_name);
+          privileges.clusters[privilege.cluster_name].push(privilege.permission_label);
         } else if ( privilege.type === 'VIEW'){
           privileges.views[privilege.instance_name] = privileges.views[privilege.instance_name] || { privileges:[]};
           privileges.views[privilege.instance_name].version = privilege.version;
           privileges.views[privilege.instance_name].view_name = privilege.view_name;
-          privileges.views[privilege.instance_name].privileges.push(privilege.permission_name);
+          privileges.views[privilege.instance_name].privileges.push(privilege.permission_label);
 
         }
       });

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
index f34d931..260d0a7 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
@@ -102,6 +102,11 @@ angular.module('ambariAdminConsole')
       url: '/clusters/:id/manageAccess',
       templateUrl: 'views/clusters/manageAccess.html',
       controller: 'ClustersManageAccessCtrl'
+    },
+    manageAccess2: {
+      url: '/clusters/:id/userAccessList',
+      templateUrl: 'views/clusters/userAccessList.html',
+      controller: 'UserAccessListCtrl'
     }
   },
   dashboard:{

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
index fdfb8e2..a758c88 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
@@ -114,6 +114,29 @@ angular.module('ambariAdminConsole')
 
       return deferred.promise;
     },
+    getPrivilegesWithFilters: function(params) {
+      var deferred = $q.defer();
+
+      $http({
+        method: 'GET',
+        url: Settings.baseUrl + '/clusters/'+ params.clusterId + '/privileges?'
+        + 'fields=PrivilegeInfo/*'
+        + '&PrivilegeInfo/principal_name.matches(.*' + params.nameFilter + '.*)'
+        + '&PrivilegeInfo/principal_type.matches(.*' + params.typeFilter.value + '.*)'
+        + '&PrivilegeInfo/permission_name.matches(.*' + params.roleFilter.value + '.*)'
+        + '&from=' + (params.currentPage - 1) * params.usersPerPage
+        + '&page_size=' + params.usersPerPage
+        + '&sortBy=PrivilegeInfo/principal_name'
+      })
+      .success(function(data) {
+        deferred.resolve(data);
+      })
+      .catch(function(data) {
+        deferred.reject(data);
+      });
+
+      return deferred.promise;
+    },
     createPrivileges: function(params, data) {
       return $http({
         method: 'POST',
@@ -135,15 +158,10 @@ angular.module('ambariAdminConsole')
         data: privileges
       });
     },
-    deletePrivilege: function(clusterId, permissionName, principalType, principalName) {
+    deletePrivilege: function(clusterId, id) {
       return $http({
         method: 'DELETE',
-        url: Settings.baseUrl + '/clusters/'+clusterId+'/privileges',
-        params: {
-          'PrivilegeInfo/principal_type': principalType,
-          'PrivilegeInfo/principal_name': principalName,
-          'PrivilegeInfo/permission_name': permissionName
-        }
+        url: Settings.baseUrl + '/clusters/'+clusterId+'/privileges/' + id
       });
     },
     editName: function(oldName, newName) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js
index c87f9d2..c6765d0 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js
@@ -79,10 +79,8 @@ angular.module('ambariAdminConsole')
       return Restangular.one('users', userId).remove();
     },
     getPrivileges : function(userId) {
-      return $http.get(Settings.baseUrl + '/privileges', {
+      return $http.get(Settings.baseUrl + '/users/' + userId + '/privileges', {
         params:{
-          'PrivilegeInfo/principal_type': 'USER',
-          'PrivilegeInfo/principal_name': encodeURIComponent(userId),
           'fields': '*'
         }
       });

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
index ff963ee..602c56c 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
@@ -1330,4 +1330,22 @@ accordion .panel-group .panel{
   padding-left: 20px;
   margin-top: 10px;
   margin-bottom: 10px;
+}
+
+.layout-switch-icon {
+  font-size: 20px;
+}
+
+.layout-switch-icon.disabled {
+  opacity: 0.4;
+  cursor: pointer;
+}
+
+.layout-switch-icon.disabled:hover {
+  opacity: 0.6;
+}
+
+thead.view-permission-header > tr > th {
+  border-top: 0px;
+  padding-top: 40px;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/manageAccess.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/manageAccess.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/manageAccess.html
index d5dcfa2..924a27f 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/manageAccess.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/manageAccess.html
@@ -19,21 +19,25 @@
 <div class="cluster-manage-access-pane">
   <div class="clearfix">
     <ol class="breadcrumb pull-left">
-      <li class="active">{{clusterName}} Permissions</li>
+      <li class="active">{{clusterName}} Roles</li>
     </ol>
   </div>
   <hr>
+  <div class="pull-right">
+    <i class="glyphicon glyphicon-th-large layout-switch-icon"></i>
+    <i class="glyphicon glyphicon-list layout-switch-icon disabled" ng-click="switchToList()" tooltip="Switch&nbsp;to&nbsp;list&nbsp;view"></i>
+  </div>
   <table class="table">
     <thead>
       <tr>
-        <th class="col-sm-2" width="20%"><label>Permission</label></th>
-        <th class="col-sm-5" width="40%"><label>Grant permission to these users</label></th>
-        <th class="col-sm-5" width="40%"><label>Grant permission to these groups</label></th>
+        <th class="col-sm-2" width="20%"><label>Roles</label></th>
+        <th class="col-sm-5" width="40%"><label>Assign roles to these users</label></th>
+        <th class="col-sm-5" width="40%"><label>Assign roles to these groups</label></th>
       </tr>
     </thead>
     <tbody>
       <tr ng-repeat="permission in permissions">
-        <td><label class="" tooltip="{{permission.PermissionInfo.permission_name}}">{{permission.PermissionInfo.permission_name | translate}}</label></td>
+        <td><label class="" tooltip="{{permission.PermissionInfo.permission_name}}">{{permission.PermissionInfo.permission_label}}</label></td>
         <td>
           <div class="" ng-switch="isEditMode">
             <editable-list items-source="permissionsEdit[permission.PermissionInfo.permission_name].USER" resource-type="User" editable="true"></editable-list>

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/userAccessList.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/userAccessList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/userAccessList.html
new file mode 100644
index 0000000..64369ab
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/userAccessList.html
@@ -0,0 +1,83 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<div class="users-pane">
+  <div class="clearfix">
+    <ol class="breadcrumb pull-left">
+      <li class="active">Roles</li>
+    </ol>
+  </div>
+  <hr>
+  <div class="pull-right">
+    <i class="glyphicon glyphicon-th-large layout-switch-icon disabled" ng-click="switchToBlock()" tooltip="Switch to block view"></i>
+    <i class="glyphicon glyphicon-list layout-switch-icon"></i>
+  </div>
+  <table class="table table-striped table-hover">
+    <thead>
+    <tr>
+      <th>
+        <div class="search-container">
+          <label for="">Name</label>
+          <input type="text" class="form-control namefilter" placeholder="Any" ng-model="currentNameFilter" ng-change="resetPagination()">
+          <button type="button" class="close clearfilter" ng-show="currentNameFilter" ng-click="currentNameFilter=''; resetPagination()">
+            <span aria-hidden="true">&times;</span><span class="sr-only">Close</span>
+          </button>
+        </div>
+      </th>
+      <th>
+        <label for="">Type</label>
+        <select class="form-control typefilter"
+                ng-model="currentTypeFilter"
+                ng-options="item.label for item in typeFilterOptions"
+                ng-change="resetPagination()">
+        </select>
+
+      </th>
+      <th>
+        <label for="">Role</label>
+        <select class="form-control statusfilter"
+                ng-model="currentRoleFilter"
+                ng-options="item.label for item in roleFilterOptions"
+                ng-change="resetPagination()">
+        </select>
+      </th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr ng-repeat="user in users">
+      <td>
+        <a href="#/{{user.url}}">{{user.encoded_name}}</a>
+      </td>
+      <td>{{user.principal_type}}</td>
+      <td>
+        <select ng-model="user.permission_name" ng-change="save(user)"
+                ng-options="role.permission_name as role.permission_label for role in roles">
+        </select>
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <div class="col-sm-12">
+    <div class="pull-right left-margin">
+      <pagination class="paginator" total-items="totalUsers" max-size="maxVisiblePages" items-per-page="usersPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
+    </div>
+    <div class="pull-right">
+      <select class="form-control" ng-model="usersPerPage" ng-change="usersPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/edit.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/edit.html
index f11ef9e..4934e1e 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/edit.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/edit.html
@@ -50,8 +50,8 @@
         <table class="table">
           <thead>
             <tr>
-              <th>Resource</th>
-              <th>Permissions</th>
+              <th>Cluster</th>
+              <th>Cluster Role</th>
             </tr>
           </thead>
           <tbody>
@@ -64,9 +64,17 @@
                 <span tooltip="{{item}}" ng-repeat="item in privilege">{{item | translate}}{{$last ? '' : ', '}}</span>
               </td>
             </tr>
+          </tbody>
+          <thead class="view-permission-header">
+            <tr>
+              <th>View</th>
+              <th>View Permissions</th>
+            </tr>
+          </thead>
+          <tbody>
             <tr ng-repeat="(name, privilege) in privileges.views">
               <td>
-                <span class="glyphicon glyphicon-th"></span> 
+                <span class="glyphicon glyphicon-th"></span>
                 <a href="#/views/{{privilege.view_name}}/versions/{{privilege.version}}/instances/{{name}}/edit">{{name}}</a>
               </td>
               <td>

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
index 471d899..7ff564a 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
@@ -65,7 +65,7 @@
 
         <ul class="nav nav-pills nav-stacked" ng-show="cluster.Clusters.provisioning_state == 'INSTALLED' ">
           <li ng-class="{active: isActive('clusters.manageAccess')}">
-            <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="permissions">Permissions</a>
+            <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="permissions">Roles</a>
           </li>
           <li><a href="#/dashboard"  class="gotodashboard">Go to Dashboard</a></li>
         </ul>

http://git-wip-us.apache.org/repos/asf/ambari/blob/765e68b2/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html
index 36efe6f..ca89e39 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html
@@ -72,8 +72,8 @@
         <table class="table">
           <thead>
             <tr>
-              <th>Resource</th>
-              <th>Permissions</th>
+              <th>Cluster</th>
+              <th>Cluster Role</th>
             </tr>
           </thead>
           <tbody ng-hide="user.admin">
@@ -86,13 +86,21 @@
                 <span tooltip="{{item}}" ng-repeat="item in privilege">{{item | translate}}{{$last ? '' : ', '}}</span>
               </td>
             </tr>
+          </tbody>
+          <thead class="view-permission-header">
+            <tr>
+              <th>View</th>
+              <th>View Permissions</th>
+            </tr>
+          </thead>
+          <tbody ng-hide="user.admin">
             <tr ng-repeat="(name, privilege) in privileges.views">
               <td>
-                <span class="glyphicon glyphicon-th"></span> 
+                <span class="glyphicon glyphicon-th"></span>
                 <a href="#/views/{{privilege.view_name}}/versions/{{privilege.version}}/instances/{{name}}/edit">{{name}}</a>
               </td>
               <td>
-                <span tooltip="{{item}}" ng-repeat="item in privilege.privileges">{{item | translate}}{{$last ? '' : ', '}}</span> 
+                <span tooltip="{{item}}" ng-repeat="item in privilege.privileges">{{item | translate}}{{$last ? '' : ', '}}</span>
               </td>
             </tr>
           </tbody>