Browse Source

AMBARI-6962. Admin View: various UI improvements. (yusaku)

Yusaku Sako 10 years ago
parent
commit
48b61d0cc5
16 changed files with 160 additions and 213 deletions
  1. 2 1
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
  2. 0 154
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/EditViewInstanceCtrl.js
  3. 46 28
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js
  4. 0 1
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
  5. 10 1
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersListCtrl.js
  6. 7 2
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersShowCtrl.js
  7. 1 0
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js
  8. 4 3
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
  9. 24 0
      ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
  10. 9 0
      ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html
  11. 31 10
      ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html
  12. 4 4
      ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html
  13. 1 2
      ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
  14. 9 0
      ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
  15. 4 4
      ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html
  16. 8 3
      ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html

+ 2 - 1
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js

@@ -34,7 +34,8 @@ angular.module('ambariAdminConsole')
         visible: true,
         icon_path: '',
         icon64_path: '',
-        properties: viewVersion.ViewVersionInfo.parameters
+        properties: viewVersion.ViewVersionInfo.parameters,
+        description: ''
       };    
     });
   }

+ 0 - 154
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/EditViewInstanceCtrl.js

@@ -1,154 +0,0 @@
-/**
- * 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('EditViewInstanceCtrl', ['$scope', 'View', 'uiAlert', 'PermissionLoader', 'PermissionSaver', 'instance', '$modalInstance', '$modal', function($scope, View, uiAlert, PermissionLoader, PermissionSaver, instance, $modalInstance, $modal) {
-
-  $scope.instance = instance;
-  $scope.settings = {
-    'visible': $scope.instance.ViewInstanceInfo.visible,
-    'label': $scope.instance.ViewInstanceInfo.label
-  };
-  $scope.configuration = angular.copy($scope.instance.ViewInstanceInfo.properties);
-  
-  function reloadViewPrivilegies(){
-    PermissionLoader.getViewPermissions({
-      viewName: $scope.instance.ViewInstanceInfo.view_name,
-      version: $scope.instance.ViewInstanceInfo.version,
-      instanceId: $scope.instance.ViewInstanceInfo.instance_name
-    })
-    .then(function(permissions) {
-      // Refresh data for rendering
-      $scope.permissionsEdit = permissions;
-      $scope.permissions = angular.copy(permissions);
-    })
-    .catch(function(data) {
-      uiAlert.danger(data.data.status, data.data.message);
-    });
-  }
-
-  $scope.permissions = [];
-  
-  reloadViewPrivilegies();
-
-  $scope.edit = {};
-  $scope.edit.editSettingsDisabled = true;
-  
-
-  $scope.saveSettings = function() {
-    View.updateInstance($scope.instance.ViewInstanceInfo.view_name, $scope.instance.ViewInstanceInfo.version, $scope.instance.ViewInstanceInfo.instance_name, {
-      'ViewInstanceInfo':{
-        'visible': $scope.settings.visible,
-        'label': $scope.settings.label
-      }
-    })
-    .success(function() {
-      $scope.edit.editSettingsDisabled = true;
-    })
-    .catch(function(data) {
-      uiAlert.danger(data.data.status, data.data.message);
-    });
-  };
-
-  $scope.cancelSettings = function() {
-    $scope.settings = {
-      'visible': $scope.instance.ViewInstanceInfo.visible,
-      'label': $scope.instance.ViewInstanceInfo.label
-    };
-    $scope.edit.editSettingsDisabled = true;
-  };
-
-  $scope.edit.editConfigurationDisabled = true;
-
-  $scope.saveConfiguration = function() {
-    View.updateInstance($scope.instance.ViewInstanceInfo.view_name, $scope.instance.ViewInstanceInfo.version, $scope.instance.ViewInstanceInfo.instance_name, {
-      'ViewInstanceInfo':{
-        'properties': $scope.configuration
-      }
-    })
-    .success(function() {
-      $scope.edit.editConfigurationDisabled = true;
-    })
-    .catch(function(data) {
-      uiAlert.danger(data.data.status, data.data.message);
-    });
-  };
-  $scope.cancelConfiguration = function() {
-    $scope.configuration = angular.copy($scope.instance.ViewInstanceInfo.properties);
-    $scope.edit.editConfigurationDisabled = true;
-  };
-
-  // Permissions edit
-  $scope.edit.editPermissionDisabled = true;
-  $scope.cancelPermissions = function() {
-    $scope.permissionsEdit = angular.copy($scope.permissions); // Reset textedit areaes
-    $scope.edit.editPermissionDisabled = true;
-  };
-
-  $scope.savePermissions = function() {
-    PermissionSaver.saveViewPermissions(
-      $scope.permissions,
-      $scope.permissionsEdit,
-      {
-        view_name: $scope.instance.ViewInstanceInfo.view_name,
-        version: $scope.instance.ViewInstanceInfo.version,
-        instance_name: $scope.instance.ViewInstanceInfo.instance_name
-      }
-    )
-    .then(reloadViewPrivilegies)
-    .catch(function(data) {
-      reloadViewPrivilegies();
-      uiAlert.danger(data.data.status, data.data.message);
-    });
-    $scope.edit.editPermissionDisabled = true;
-  };
-
-  $scope.removePermission = function(permissionName, principalType, principalName) {
-    var modalInstance = $modal.open({
-      templateUrl: 'views/ambariViews/modals/create.html',
-      size: 'lg',
-      controller: 'CreateViewInstanceCtrl',
-      resolve: {
-        viewVersion: function(){
-          return '';
-        }
-      }
-    });
-
-
-
-    View.deletePrivilege({
-      view_name: $scope.instance.ViewInstanceInfo.view_name,
-      version: $scope.instance.ViewInstanceInfo.version,
-      instance_name: $scope.instance.ViewInstanceInfo.instance_name,
-      permissionName: permissionName,
-      principalType: principalType,
-      principalName: principalName
-    })
-    .then(reloadViewPrivilegies)
-    .catch(function(data) {
-      reloadViewPrivilegies();
-      uiAlert.danger(data.data.status, data.data.message);
-    });
-  };
-
-  $scope.close = function() {
-    $modalInstance.close();
-  };
-}]);

+ 46 - 28
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js

@@ -25,12 +25,19 @@ angular.module('ambariAdminConsole')
     View.getInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId)
     .then(function(instance) {
       $scope.instance = instance;
+
       $scope.settings = {
         'visible': $scope.instance.ViewInstanceInfo.visible,
-        'label': $scope.instance.ViewInstanceInfo.label
+        'label': $scope.instance.ViewInstanceInfo.label,
+        'description': $scope.instance.ViewInstanceInfo.description
       };
 
       $scope.configuration = angular.copy($scope.instance.ViewInstanceInfo.properties);
+      for(var confName in $scope.configuration){
+        if( $scope.configuration.hasOwnProperty(confName) ){
+          $scope.configuration[confName] = $scope.configuration[confName] === 'null' ? '' : $scope.configuration[confName];
+        }
+      }
       $scope.isConfigurationEmpty = angular.equals({}, $scope.configuration);
     })
     .catch(function(data) {
@@ -72,45 +79,56 @@ angular.module('ambariAdminConsole')
   reloadViewPrivilegies();
 
   $scope.editSettingsDisabled = true;
-  
+  $scope.toggleSettingsEdit = function() {
+    $scope.editSettingsDisabled = !$scope.editSettingsDisabled;
+  };
 
   $scope.saveSettings = function() {
-    View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, {
-      'ViewInstanceInfo':{
-        'visible': $scope.settings.visible,
-        'label': $scope.settings.label
-      }
-    })
-    .success(function() {
-      reloadViewInfo();
-      $scope.editSettingsDisabled = true;
-    })
-    .catch(function(data) {
-      uiAlert.danger(data.data.status, data.data.message);
-    });
+    if( $scope.settingsForm.$valid ){
+      View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, {
+        'ViewInstanceInfo':{
+          'visible': $scope.settings.visible,
+          'label': $scope.settings.label,
+          'description': $scope.settings.description
+        }
+      })
+      .success(function() {
+        reloadViewInfo();
+        $scope.editSettingsDisabled = true;
+      })
+      .catch(function(data) {
+        uiAlert.danger(data.data.status, data.data.message);
+      });
+    }
   };
   $scope.cancelSettings = function() {
     $scope.settings = {
       'visible': $scope.instance.ViewInstanceInfo.visible,
-      'label': $scope.instance.ViewInstanceInfo.label
+      'label': $scope.instance.ViewInstanceInfo.label,
+      'description': $scope.instance.ViewInstanceInfo.description
     };
     $scope.editSettingsDisabled = true;
   };
 
+  
   $scope.editConfigurationDisabled = true;
-
+  $scope.togglePropertiesEditing = function() {
+     $scope.editConfigurationDisabled = !$scope.editConfigurationDisabled;
+  }
   $scope.saveConfiguration = function() {
-    View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, {
-      'ViewInstanceInfo':{
-        'properties': $scope.configuration
-      }
-    })
-    .success(function() {
-      $scope.editConfigurationDisabled = true;
-    })
-    .catch(function(data) {
-      uiAlert.danger(data.data.status, data.data.message);
-    });
+    if( $scope.propertiesForm.$valid ){
+      View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, {
+        'ViewInstanceInfo':{
+          'properties': $scope.configuration
+        }
+      })
+      .success(function() {
+        $scope.editConfigurationDisabled = true;
+      })
+      .catch(function(data) {
+        uiAlert.danger(data.data.status, data.data.message);
+      });
+    }
   };
   $scope.cancelConfiguration = function() {
     $scope.configuration = angular.copy($scope.instance.ViewInstanceInfo.properties);

+ 0 - 1
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js

@@ -73,7 +73,6 @@ angular.module('ambariAdminConsole')
         return !!view; // Remove 'undefined'
       });
     }
-
     $scope.filteredViews = result;
   };
 }]);

+ 10 - 1
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersListCtrl.js

@@ -39,7 +39,8 @@ angular.module('ambariAdminConsole')
       usersPerPage: $scope.usersPerPage, 
       searchString: $scope.currentNameFilter,
       ldap_user: $scope.currentTypeFilter.value,
-      active: $scope.currentActiveFilter.value
+      active: $scope.currentActiveFilter.value,
+      admin: $scope.adminFilter
     }).then(function(data) {
       $scope.totalUsers = data.data.itemTotal;
       $scope.users = data.data.items;
@@ -66,6 +67,14 @@ angular.module('ambariAdminConsole')
   ];
   $scope.currentTypeFilter = $scope.typeFilterOptions[0];
 
+  $scope.adminFilter = false;
+  $scope.toggleAdminFilter = function() {
+    $scope.adminFilter = !$scope.adminFilter;
+    $scope.resetPagination();
+    $scope.loadUsers();
+  };
+
+
   $scope.loadUsers();
 
   $rootScope.$watch(function(scope) {

+ 7 - 2
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersShowCtrl.js

@@ -57,7 +57,6 @@ angular.module('ambariAdminConsole')
     $q.all(promises).then(function() {
       loadUserInfo();
     });
-    // $scope.user.user_groups = $scope.editingGroupsList.split(',');
     $scope.isGroupEditing = false;
   };
 
@@ -69,13 +68,19 @@ angular.module('ambariAdminConsole')
   $scope.openChangePwdDialog = function() {
     var modalInstance = $modal.open({
       templateUrl: 'views/users/modals/changePassword.html',
-      controller: ['$scope', function($scope) {
+      resolve: {
+        userName: function() {
+          return $scope.user.user_name;
+        }
+      },
+      controller: ['$scope', 'userName', function($scope, userName) {
         $scope.passwordData = {
           password: '',
           currentUserPassword: ''
         };
 
         $scope.form = {};
+        $scope.userName = userName;
 
         $scope.ok = function() {
           $scope.form.passwordChangeForm.submitted = true;

+ 1 - 0
ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js

@@ -43,6 +43,7 @@ angular.module('ambariAdminConsole')
         + '&page_size=' + params.usersPerPage
         + (params.ldap_user === '*' ? '' : '&Users/ldap_user=' + params.ldap_user)
         + (params.active === '*' ? '' : '&Users/active=' + params.active)
+        + (params.admin ? '&Users/admin=true' : '')
       );
     },
     get: function(userId) {

+ 4 - 3
ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js

@@ -72,7 +72,7 @@ angular.module('ambariAdminConsole')
       }
     }
 
-    self.isOpened = !self.instances.length;
+    // self.isOpened = !self.instances.length;
     self.versionsList = item.versions;
   }
 
@@ -177,7 +177,8 @@ angular.module('ambariAdminConsole')
           visible: instanceInfo.visible,
           icon_path: instanceInfo.icon_path,
           icon64_path: instanceInfo.icon64_path,
-          properties: properties
+          properties: properties,
+          description: instanceInfo.description
         }
       }
     })
@@ -239,7 +240,7 @@ angular.module('ambariAdminConsole')
     var fields = [
       'versions/ViewVersionInfo/version',
       'versions/instances/ViewInstanceInfo',
-      'versions/ViewVersionInfo'
+      'versions/*'
     ];
 
     $http({

+ 24 - 0
ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css

@@ -16,6 +16,17 @@
  * limitations under the License.
  */
 
+ .instances-table{
+  table-layout: fixed;
+ }
+ .description-column{
+  text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap;
+  max-width: 100%;
+  display: inline-block;
+ }
+
 .paginator{
   margin: 0;
 }
@@ -106,6 +117,11 @@
   width: 14px;
 }
 
+.settings-edit-toggle.disabled, .properties-toggle.disabled{
+  color: #999;
+  cursor: not-allowed;
+}
+
 .pulldown2{
   -webkit-transform: translateY(2px);
   -ms-transform: translateY(2px);
@@ -268,6 +284,14 @@ ul.nav li > a{
   cursor: pointer;
 }
 
+.admin-filter{
+  cursor: pointer;
+}
+
+.glyphicon-flash.no-filter{
+  color: #999;
+}
+
 .top-buffer{
   padding-top: 20px;
 }

+ 9 - 0
ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html

@@ -73,6 +73,15 @@
           </div>
         </div>
       </div>
+      <div class="form-group" ng-class="{'has-error' : form.isntanceCreateForm.description.$error.required && form.isntanceCreateForm.submitted }">
+        <label for="" class="control-label col-sm-2">Instance Description</label>
+        <div class="col-sm-10">
+          <input type="text" class="form-control" name="description" ng-model="instance.description" maxlength="140" required>
+          <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.isntanceCreateForm.description.$error.required && form.isntanceCreateForm.submitted'>
+            This field is required.
+          </div>
+        </div>
+      </div>
       <div class="form-group">
         <div class="col-sm-10 col-sm-offset-2">
           <div class="checkbox">

+ 31 - 10
ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html

@@ -28,12 +28,13 @@
 <div class="panel panel-default" ng-cloak ng-show="instance">
   <div class="panel-heading clearfix">
     <h3 class="panel-title pull-left">Settings</h3>
-    <div class="pull-right">
-      <a href ng-click="editSettingsDisabled = !editSettingsDisabled" ng-show="editSettingsDisabled" class="settings-edit-toggle"> <span class="glyphicon glyphicon-pencil"></span> Edit</a>
+    <div class="pull-right" ng-switch="instance.ViewInstanceInfo.static">
+      <a href ng-switch-when="false" ng-click="toggleSettingsEdit()" ng-show="editSettingsDisabled" class="settings-edit-toggle"> <span class="glyphicon glyphicon-pencil" ></span> Edit</a>
+      <a href ng-switch-when="true" class="settings-edit-toggle disabled" tooltip="You can`t edit XML driven instances"> <span class="glyphicon glyphicon-pencil" ></span> Edit</a>
     </div>
   </div>
   <div class="panel-body">
-    <form class="form-horizontal">
+    <form class="form-horizontal" name="settingsForm" novalidate>
       <div class="form-group">
         <label for="" class="col-sm-2 control-label">View Name</label>
         <div class="col-sm-10"><input disabled="disabled" type="text" class="form-control instancename-input" placeholder="Display Name" value="{{instance.ViewInstanceInfo.view_name}}"></div>
@@ -47,9 +48,23 @@
           <label for="" class="col-sm-2 control-label">Instance Name</label>
           <div class="col-sm-10"><input disabled="disabled" type="text" class="form-control instancename-input" placeholder="Display Name" value="{{instance.ViewInstanceInfo.instance_name}}"></div>
         </div>
-        <div class="form-group">
+        <div class="form-group" ng-class="{'has-error' : settingsForm.displayName.$error.required && !editSettingsDisabled}">
           <label for="" class="col-sm-2 control-label">Display Name</label>
-          <div class="col-sm-10"><input type="text" class="form-control instancename-input" placeholder="Display Name" ng-model="settings.label"></div>
+          <div class="col-sm-10">
+            <input type="text" class="form-control instancename-input" placeholder="Display Name" name="displayName" required ng-model="settings.label">
+            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='settingsForm.displayName.$error.required  && !editSettingsDisabled'>
+              This field is required.
+            </div>
+          </div>
+        </div>
+        <div class="form-group" ng-class="{'has-error' : settingsForm.description.$error.required  && !editSettingsDisabled}">
+          <label for="" class="control-label col-sm-2">Instance Description</label>
+          <div class="col-sm-10">
+            <input type="text" class="form-control" ng-model="settings.description" name="description" placeholder="Instance Description" required>
+            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='settingsForm.description.$error.required  && !editSettingsDisabled'>
+              This field is required.
+            </div>
+          </div>
         </div>
         <div class="form-group">
           <div class="col-sm-offset-2 col-sm-10">
@@ -123,16 +138,22 @@
 <div class="panel panel-default">
   <div class="panel-heading clearfix">
     <h3 class="panel-title pull-left">Properties</h3>
-    <div class="pull-right">
-      <a href ng-hide="isConfigurationEmpty" ng-click="editConfigurationDisabled = !editConfigurationDisabled" ng-show="editConfigurationDisabled" class="properties-toggle"> <span class="glyphicon glyphicon-pencil"></span> Edit</a>
+    <div class="pull-right" ng-switch="instance.ViewInstanceInfo.static">
+      <a href ng-switch-when="false" ng-hide="isConfigurationEmpty" ng-click="togglePropertiesEditing()" ng-show="editConfigurationDisabled" class="properties-toggle"> <span class="glyphicon glyphicon-pencil"></span> Edit</a>
+      <a href ng-switch-when="true" ng-hide="isConfigurationEmpty"  class="properties-toggle disabled"> <span class="glyphicon glyphicon-pencil"></span> Edit</a>
     </div>
   </div>
   <div class="panel-body">
-    <form action="" class="form-horizontal" ng-hide="isConfigurationEmpty">
+    <form name="propertiesForm" class="form-horizontal" ng-hide="isConfigurationEmpty" novalidate>
       <fieldset ng-disabled="editConfigurationDisabled">
-        <div class="form-group" ng-repeat="(propertyName, propertyValue) in configurationMeta">
+        <div class="form-group" ng-repeat="(propertyName, propertyValue) in configurationMeta" ng-class="{'has-error' : propertyValue.required && propertiesForm[propertyName].$error.required && !editConfigurationDisabled}">
           <label for="" class="control-label col-sm-3" ng-class="{'not-required': !propertyValue.required}" tooltip="{{propertyValue.description}}">{{propertyName}}{{propertyValue.required ? '*' : ''}}</label>
-          <div class="col-sm-9"><input type="{{propertyValue.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-model="configuration[propertyName]"></div>
+          <div class="col-sm-9">
+            <input type="{{propertyValue.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-required="propertyValue.required" name="{{propertyName}}" ng-model="configuration[propertyName]">
+            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='propertyValue.required && propertiesForm[propertyName].$error.required && !editConfigurationDisabled'>
+              This field is required.
+            </div>
+          </div>
         </div>
         <div class="form-group" ng-hide="editConfigurationDisabled">
           <div class="col-sm-offset-2 col-sm-10">

+ 4 - 4
ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html

@@ -46,18 +46,18 @@
             {{view.view_name}}
           </div>
           <div class="col-sm-3">{{view.versions}}</div>
-          <div class="col-sm-6">This is a description</div>
+          <div class="col-sm-6">{{view.description}}</div>
         </div>
       </accordion-heading>
-      <table class="table">
+      <table class="table instances-table">
         <tbody>
           <tr ng-repeat="instance in view.instances">
             <td class="col-sm-3"></td>
             <td class="col-sm-3">
               <a href="#/views/{{view.view_name}}/versions/{{instance.ViewInstanceInfo.version}}/instances/{{instance.ViewInstanceInfo.instance_name}}/edit" class="instance-link">{{instance.ViewInstanceInfo.label}}</a>
             </td>
-            <td class="col-sm-3">{{instance.ViewInstanceInfo.version}}</td>
-            <td class="col-sm-3">
+            <td class="col-sm-1">{{instance.ViewInstanceInfo.version}}</td>
+            <td class="col-sm-5 " ><div class="description-column" tooltip="{{instance.ViewInstanceInfo.description}}">{{instance.ViewInstanceInfo.description || 'No description'}}</div>
             </td>
           </tr>
         </tbody>

+ 1 - 2
ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html

@@ -33,9 +33,8 @@
         </th>
         <th>
           <label for="">Type</label>
-          
         </th>
-        <th>Members</th>
+        <th><label for="">Members</label></th>
       </tr>
       <tr>
         <th class="col-sm-8">

+ 9 - 0
ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html

@@ -29,6 +29,13 @@
   <table class="table table-striped table-hover">
     <thead>
       <tr>
+        <th width="30">
+          <span class="bottom-margin admin-filter glyphicon glyphicon-flash" 
+            ng-class="{'no-filter' : !adminFilter}" 
+            ng-click="toggleAdminFilter()"
+            tooltip="{{adminFilter ? 'Show all users' : 'Show only admin users'}}"
+          ></span>
+        </th>
         <th>
           <div class="search-container">
             <label for="">Username</label>
@@ -59,6 +66,8 @@
       <tr ng-repeat="user in users">
         <td>
           <span class="glyphicon" tooltip="{{user.Users.admin ? 'Ambari Admin' : ''}}" ng-class="{'glyphicon-flash' : user.Users.admin}"></span>
+        </td>
+        <td>
           <link-to route="users.show" id="{{user.Users.user_name}}">{{user.Users.user_name}}</link-to>
         </td>
         <td>{{user.Users.ldap_user ? 'LDAP' : 'Local'}}</td>

+ 4 - 4
ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html

@@ -16,7 +16,7 @@
 * limitations under the License.
 -->
 <div class="modal-header">
-  <h3 class="modal-title">Change Password</h3>
+  <h3 class="modal-title">Change Password for {{userName}}</h3>
 </div>
 <div class="modal-body">
   <form class="form-horizontal" novalidate name="form.passwordChangeForm" role="form" >
@@ -30,10 +30,10 @@
       </div>
     </div>
     <div class="form-group no-margin-bottom" ng-class="{'has-error' : (form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted) || form.passwordChangeForm.confirmPassword.$error.passwordVerify}">
-      <label for="" class="col-sm-4 control-label">New Password:</label>
+      <label for="" class="col-sm-4 control-label">New User Password:</label>
       <div class="col-sm-8">
-        <input type="password" class="form-control bottom-margin" name="password" placeholder="Password" required ng-model="passwordData.password" autocomplete="off">
-        <input type="password" class="form-control bottom-margin" name="confirmPassword" placeholder="Password confirmation" required ng-model="passwordData.passwordConfirmation"
+        <input type="password" class="form-control bottom-margin" name="password" placeholder="New User Password" required ng-model="passwordData.password" autocomplete="off">
+        <input type="password" class="form-control bottom-margin" name="confirmPassword" placeholder="New User Password Confirmation" required ng-model="passwordData.passwordConfirmation"
           password-verify="passwordData.password" autocomplete="off">
         <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.confirmPassword.$error.passwordVerify'>
           Password must match!

+ 8 - 3
ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html

@@ -52,7 +52,11 @@
     <div class="form-group">
       <label for="password" class="col-sm-2 control-label">Password</label>
       <div class="col-sm-10">
-        <a href ng-click="openChangePwdDialog()" ng-disabled="user.ldap_user" class="btn btn-default changepassword">Change Password</a>
+        <div ng-switch="user.ldap_user">
+          <button class="btn deleteuser-btn disabled btn-default" ng-switch-when="true" tooltip="Cannot Change Password">Change Password</button>
+          <a href ng-click="openChangePwdDialog()" ng-switch-when="false" class="btn btn-default changepassword">Change Password</a>
+        </div>
+          
       </div>
     </div>
     <div class="form-group">
@@ -82,7 +86,7 @@
       </div>
         
     </div>
-    <div class="form-group">
+    <div class="form-group" >
       <label for="" class="col-sm-2 control-label">Privileges</label>
       <div class="col-sm-10">
         <table class="table">
@@ -92,7 +96,7 @@
               <th>Permissions</th>
             </tr>
           </thead>
-          <tbody>
+          <tbody ng-hide="user.admin">
             <tr ng-repeat="(name, privilege) in privileges.clusters">
               <td>
                 <span class="glyphicon glyphicon-cloud"></span> 
@@ -114,6 +118,7 @@
           </tbody>
         </table>
         <div class="alert alert-info" ng-show="!privileges">This user does not have any privileges.</div>
+        <div class="alert alert-info" ng-show="user.admin">This user is an Ambari Admin and has all privileges.</div>
       </div>
     </div>
   </form>