http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html
index 85d659d..da1ab3f 100644
--- 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html
@@ -119,14 +119,14 @@
   </div>
 
   <div id="upload-definition-file-panel" ng-if="createController">
-    <div class="col-sm-12 big-radio clearfix hide-soft" ng-class="{'disabled' 
: networkLost || useRedhatSatellite,'visible':stackRepoUpdateLinkExists}">
-      <input type="radio" ng-model="selectedOption.index" value="1" 
ng-change="togglePublicLocalOptionSelect()" ng-disabled="networkLost || 
useRedhatSatellite">
-      <span>{{'versions.usePublic' | translate}}</span>
+    <div class="checkbox col-sm-12 big-radio clearfix hide-soft" 
ng-class="{'disabled' : networkLost || 
useRedhatSatellite,'visible':stackRepoUpdateLinkExists}">
+      <input id="use-public" type="radio" ng-model="selectedOption.index" 
value="1" ng-change="togglePublicLocalOptionSelect()" ng-disabled="networkLost 
|| useRedhatSatellite">
+      <label for="use-public">{{'versions.usePublic' | translate}}</label>
       <a id="public-disabled-link" href="javascript:void(0);" 
ng-if="networkLost" 
ng-click="showPublicRepoDisabledDialog()">{{'versions.networkIssues.networkLost'|
 translate}}</a>
     </div>
-    <div class="col-sm-12 big-radio clearfix">
-      <input type="radio" ng-model="selectedOption.index" value="2" 
ng-change="togglePublicLocalOptionSelect()">
-      {{'versions.useLocal' | translate}}
+    <div class="checkbox col-sm-12 big-radio clearfix">
+      <input id="use-local" type="radio" ng-model="selectedOption.index" 
value="2" ng-change="togglePublicLocalOptionSelect()">
+      <label for="use-local">{{'versions.useLocal' | translate}}</label>
     </div>
   </div>
 
@@ -181,20 +181,22 @@
                 <div class="col-sm-9">
                   <div class="form-group repo-name-url 
{{repository.Repositories.repo_name}}"
                        ng-class="{'has-error': repository.hasError }" 
ng-repeat="repository in os.repositories">
-                    <span class="repo-name-label control-label 
col-sm-3">{{repository.Repositories.repo_id}}</span>
-                    <div class="col-sm-7 repo-url">
-                      <input type="text" class="form-control"
-                             
placeholder="{{(repository.Repositories.repo_name.indexOf('UTILS') < 0 
)?('versions.repository.placeholder' | translate) : ''}}"
-                             ng-model="repository.Repositories.base_url"
-                             ng-change="onRepoUrlChange(repository)" 
ng-disabled="useRedhatSatellite">
+                    <div ng-if="showRepo(repository)">
+                      <span class="repo-name-label control-label 
col-sm-3">{{repository.Repositories.repo_id}}</span>
+                      <div class="col-sm-7 repo-url">
+                        <input type="text" class="form-control"
+                               
placeholder="{{(repository.Repositories.repo_name.indexOf('UTILS') < 0 
)?('versions.repository.placeholder' | translate) : ''}}"
+                               ng-model="repository.Repositories.base_url"
+                               ng-change="onRepoUrlChange(repository)" 
ng-disabled="useRedhatSatellite">
+                      </div>
+                      <i class="fa fa-undo orange-icon cursor-pointer"
+                         ng-if="selectedOption.index == 1 && 
repository.Repositories.base_url != repository.Repositories.initial_base_url
+                         || selectedOption.index == 2 && 
repository.Repositories.base_url != ''
+                         || editController && repository.Repositories.base_url 
!= repository.Repositories.initial_base_url"
+                         ng-click="undoChange(repository)"
+                         tooltip-html-unsafe="{{'common.undo' | translate}}"
+                         aria-hidden="true"></i>
                     </div>
-                    <i class="fa fa-undo orange-icon cursor-pointer"
-                       ng-if="selectedOption.index == 1 && 
repository.Repositories.base_url != repository.Repositories.initial_base_url
-                       || selectedOption.index == 2 && 
repository.Repositories.base_url != ''
-                       || editController && repository.Repositories.base_url 
!= repository.Repositories.initial_base_url"
-                       ng-click="undoChange(repository)"
-                       tooltip-html-unsafe="{{'common.undo' | translate}}"
-                       aria-hidden="true"></i>
                   </div>
                 </div>
                 <div class="col-sm-1 remove-icon" ng-click="removeOS()" 
ng-class="{'disabled' : useRedhatSatellite}"><i
@@ -204,22 +206,21 @@
             </div>
           </div>
           <div class="clearfix advanced-radio-buttons">
-            <div class="col-sm-9" id="skip-validation">
+            <div class="col-sm-9">
               <div class="checkbox">
-                <label>
-                  <input type="checkbox" ng-model="skipValidation" 
ng-change="clearErrors()"
-                         ng-disabled="useRedhatSatellite">
+                <input type="checkbox" id="skip-validation" 
ng-model="skipValidation" ng-change="clearErrors()" 
ng-disabled="useRedhatSatellite">
+                <label for="skip-validation">
                   <span ng-class="{'disabled' : 
useRedhatSatellite}">{{'versions.skipValidation' | translate}}</span>
                   <i class="fa fa-question-circle"
                      
tooltip-html-unsafe="{{'versions.alerts.skipValidationWarning' | translate}}" 
aria-hidden="true"></i>
                 </label>
               </div>
             </div>
-            <div class="col-sm-9" id="use-redhat">
+            <div class="col-sm-9">
               <div class="checkbox">
-                <label>
-                  <input type="checkbox" ng-model="useRedhatSatellite" 
ng-change="clearErrors()"
-                         ng-disabled="isPublicRepoSelected()">
+                <input type="checkbox" id="use-redhat" 
ng-model="useRedhatSatellite" ng-change="clearErrors()"
+                       ng-disabled="isPublicRepoSelected()">
+                <label for="use-redhat">
                   <span ng-class="{'disabled' : isPublicRepoSelected()}"
                         tooltip="{{(isPublicRepoSelected())? 
('versions.useRedhatSatellite.disabledMsg' | translate) : 
''}}">{{'versions.useRedhatSatellite.title' | translate}}</span>
                   <i class="fa fa-question-circle"

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
index 0c9e1b9..dbd1021 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
@@ -16,7 +16,6 @@
 * limitations under the License.
 -->
 <ol class="breadcrumb">
-    <li> <link-to route="views.listViewUrls">{{'urls.viewUrls' | 
translate}}</link-to></li>
     <li class="active">{{'urls.createNewUrl' | translate}}</li>
 </ol>
 <hr>
@@ -25,9 +24,9 @@
 
             <form class="form-horizontal create-user-form" role="form" 
novalidate name="formHolder.form" autocomplete="off">
                 <div class="form-group" ng-class="{'has-error' : 
formHolder.form.url_name.$error.required  && formHolder.form.submitted}">
-                    <label for="urlname" class="col-sm-2 
control-label">{{'urls.name' | translate}}</label>
+                    <label for="urlname" class="col-sm-2 
control-label">{{'common.name' | translate}}</label>
                     <div class="col-sm-10">
-                        <input ng-minlength="2" ng-maxlength="25" type="text" 
id="urlname" class="form-control urlname-input" name="url_name" 
placeholder="{{'urls.name' | translate}}" ng-model="url.urlName" required 
autocomplete="off">
+                        <input ng-minlength="2" ng-maxlength="25" type="text" 
id="urlname" class="form-control urlname-input" name="url_name" 
placeholder="{{'common.name' | translate}}" ng-model="url.urlName" required 
autocomplete="off">
                         <div class="alert alert-danger top-margin" 
ng-show="formHolder.form.url_name.$error.required  && 
formHolder.form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div>
                         <div class="alert alert-danger top-margin" 
ng-show="formHolder.form.url_name.$error.minlength   && 
formHolder.form.submitted">{{'common.alerts.minimumTwoChars' | translate}}</div>
                         <div class="alert alert-danger top-margin" 
ng-show="formHolder.form.url_name.$error.maxlength   && 
formHolder.form.submitted">{{'common.alerts.maxTwentyFiveChars' | 
translate}}</div>
@@ -68,7 +67,6 @@
                 <div class="form-group">
                     <div class="col-sm-offset-2 col-sm-10">
                         <button ng-disabled="stepTwoNotCompleted" class="btn 
btn-primary pull-right left-margin saveuser" 
ng-click="saveUrl()">{{'common.controls.save' | translate}}</button>
-                        <link-to route="views.listViewUrls" class="btn 
btn-default pull-right cancel">{{'common.controls.cancel' | 
translate}}</link-to>
 
                     </div>
                 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
index 9198818..61366db 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
@@ -16,7 +16,6 @@
 * limitations under the License.
 -->
 <ol class="breadcrumb">
-  <li> <link-to route="views.listViewUrls">{{'urls.viewUrls' | 
translate}}</link-to></li>
   <li class="active">{{'urls.edit' | translate}} {{url.url_name}}</li>
   <div class="pull-right top-margin-4">
     <button class="btn deleteuser-btn btn-danger" 
ng-click="deleteUrl()">{{'views.urlDelete' | translate}}</button>
@@ -27,9 +26,9 @@
 
 <form  class="form-horizontal create-user-form" role="form" novalidate 
name="url_form" autocomplete="off">
   <div class="form-group" ng-class="{'has-error' : 
url_form.url_name.$error.required  && url_form.submitted}">
-    <label for="urlname" class="col-sm-2 control-label">{{'urls.name' | 
translate}}</label>
+    <label for="urlname" class="col-sm-2 control-label">{{'common.name' | 
translate}}</label>
     <div class="col-sm-10">
-      <input disabled type="text" id="urlname" class="form-control 
urlname-input" name="url_name" placeholder="{{'urls.name' | translate}}" 
ng-model="url.url_name" required autocomplete="off">
+      <input disabled type="text" id="urlname" class="form-control 
urlname-input" name="url_name" placeholder="{{'common.name' | translate}}" 
ng-model="url.url_name" required autocomplete="off">
       <div class="alert alert-danger top-margin" 
ng-show="url_form.url_name.$error.required  && 
url_form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div>
     </div>
   </div>
@@ -70,7 +69,6 @@
   <div class="form-group">
     <div class="col-sm-offset-2 col-sm-10">
       <button ng-disabled="stepTwoNotCompleted" class="btn btn-primary 
pull-right left-margin saveuser" 
ng-click="updateUrl()">{{'common.controls.save' | translate}}</button>
-      <link-to route="views.listViewUrls" class="btn btn-default pull-right 
cancel">{{'common.controls.cancel' | translate}}</link-to>
     </div>
   </div>
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupEdit.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupEdit.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupEdit.html
new file mode 100644
index 0000000..5656417
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupEdit.html
@@ -0,0 +1,122 @@
+<!--
+* 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 id="group-edit">
+  <div class="clearfix">
+    <ol class="breadcrumb pull-left">
+      <li><a href="#/userManagement?tab=groups">{{'common.groups' | 
translate}}</a></li>
+      <li class="active">{{group.group_name}}</li>
+    </ol>
+    <div class="pull-right">
+      <div ng-switch="group.group_type != 'LOCAL'">
+        <button
+          ng-switch-when="true"
+          class="btn disabled deletegroup-btn"
+          tooltip="{{'common.cannotDelete' | translate: '{term: 
constants.group}'}}">
+          {{'common.delete' | translate: '{term: constants.group}'}}
+        </button>
+        <button ng-switch-when="false" class="btn btn-danger deletegroup-btn" 
ng-click="deleteGroup(group)">
+          {{'common.delete' | translate: '{term: constants.group}'}}
+        </button>
+      </div>
+    </div>
+  </div>
+
+  <form class="form-horizontal" role="form" novalidate name="form" >
+    <div class="form-group">
+      <label class="col-sm-2 control-label">{{'common.type' | 
translate}}</label>
+      <div class="col-sm-10">
+        <label class="control-label">{{group.groupTypeName | 
translate}}</label>
+      </div>
+    </div>
+    <div class="form-group">
+      <label class="col-sm-2 control-label">{{group.groupTypeName | 
translate}} {{'groups.members' | translate}}</label>
+      <div class="col-sm-10">
+        <editable-list items-source="group.editingUsers" resource-type="User" 
editable="group.group_type == 'LOCAL'"></editable-list>
+      </div>
+    </div>
+    <div class="form-group">
+      <label for="role" class="col-sm-2 roles-label">
+        {{'groups.role' | translate}}
+        <i class="fa fa-question-circle" aria-hidden="true" 
ng-click="showHelpPage()"></i>
+      </label>
+      <div class="col-sm-3">
+        <select class="form-control"
+                id="role"
+                name="role"
+                ng-change="updateRole()"
+                ng-options="item as item.permission_label for item in 
roleOptions track by item.permission_name"
+                ng-model="currentRole">
+        </select>
+      </div>
+    </div>
+    <div class="form-group">
+      <label class="col-sm-2 control-label">{{'common.privileges' | 
translate}}</label>
+      <div class="col-sm-10">
+        <table class="table" ng-hide="hidePrivileges">
+          <thead>
+          <tr>
+            <th>{{'common.cluster' | translate}}</th>
+            <th>{{'common.clusterRole' | translate}}</th>
+          </tr>
+          </thead>
+          <tbody>
+          <tr ng-repeat="(name, privilege) in privileges.clusters">
+            <td>
+              <span class="glyphicon glyphicon-cloud"></span>
+              <a href="#/clusters/{{name}}/manageAccess">{{name}}</a>
+            </td>
+            <td>
+              <span tooltip="{{item}}" ng-repeat="item in privilege">{{item | 
translate}}{{$last ? '' : ', '}}</span>
+            </td>
+          </tr>
+          <tr>
+            <td ng-show="noClusterPriv">{{'common.alerts.noPrivileges' | 
translate: '{term: constants.cluster}'}}</td>
+          </tr>
+          </tbody>
+          <thead class="view-permission-header">
+          <tr>
+            <th>{{'common.view' | translate}}</th>
+            <th>{{'common.viewPermissions' | translate}}</th>
+          </tr>
+          </thead>
+          <tbody>
+          <tr ng-repeat="(name, privilege) in privileges.views">
+            <td>
+              <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>
+            </td>
+            <td>
+              <i class="fa fa-trash-o" aria-hidden="true" 
ng-click="removeViewPrivilege(name, privilege);"></i>
+            </td>
+          </tr>
+          <tr>
+            <td ng-show="noViewPriv">{{'common.alerts.noPrivileges' | 
translate: '{term: constants.view}'}}</td>
+          </tr>
+          </tbody>
+        </table>
+        <div class="alert alert-info" ng-show="hidePrivileges">
+          {{'common.alerts.noPrivilegesDescription' | translate: '{term: 
constants.group.toLowerCase()}'}}
+        </div>
+      </div>
+    </div>
+  </form>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html
new file mode 100644
index 0000000..d79d14e
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html
@@ -0,0 +1,94 @@
+<!--
+* 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="groups-pane">
+  <div class="clearfix panel">
+    <button class="btn btn-default creategroup-btn pull-right" 
ng-click="createGroup()">
+      {{'groups.createLocal' | translate}}
+    </button>
+  </div>
+  <table class="table table-striped table-hover col-sm-12">
+    <thead>
+      <tr>
+        <th class="col-sm-6">
+          <span>{{'groups.name' | translate}}</span>
+        </th>
+        <th class="col-sm-2">
+          <span>{{'common.type' | translate}}</span>
+        </th>
+        <th class="col-sm-2">
+          <span>{{'groups.members' | translate}}</span>
+        </th>
+        <th class="col-sm-2">
+          <span>{{'common.actions' | translate}}</span>
+        </th>
+      </tr>
+      <tr>
+        <th class="col-sm-6">
+          <div class="search-container">
+            <input type="text" class="form-control namefilter" 
placeholder="{{'common.any' | translate}}" ng-model="filter.name" 
ng-change="resetPagination()">
+            <button type="button" class="close" ng-show="filter.name" 
ng-click="filter.name=''; resetPagination()"><span 
aria-hidden="true">&times;</span><span 
class="sr-only">{{'common.controls.close' | translate}}</span></button>
+          </div>
+        </th>
+        <th class="col-sm-2">
+          <select class="form-control typefilter"
+                  ng-model="filter.type"
+                  ng-options="item.label for item in typeFilterOptions"
+                  ng-change="resetPagination();">
+          </select>
+        </th>
+        <th class="col-sm-2"></th>
+        <th class="col-sm-2"></th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr ng-repeat="group in groups">
+        <td class="col-sm-8">
+          <span>{{group.group_name}}</span>
+        </td>
+        <td class="col-sm-2">{{group.groupTypeName | translate}}</td>
+        <td class="col-sm-2">{{'groups.membersPlural' | translate: '{n: 
group.members && group.members.length || 0}'}}</td>
+        <td class="entity-actions">
+          <link-to route="userManagement.editGroup" class="link-to-group" 
id="{{group.group_name}}">
+            <i class="fa fa-pencil"></i>
+          </link-to>
+          <a href ng-click="deleteGroup(group)">
+            <i class="fa fa-trash-o"></i>
+          </a>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  <div ng-if="isLoading" class="spinner-container">
+    <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
+  </div>
+  <div class="alert empty-table-alert col-sm-12" ng-show="!groups.length && 
!isLoading">
+    {{'common.alerts.nothingToDisplay' | translate: '{term: 
constants.groups}'}}
+  </div>
+  <div class="col-sm-12 table-bar" ng-show="totalGroups > 
minRowsToShowPagination">
+    <div class="pull-left filtered-info">
+      <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, 
total: tableInfo.total, term: constants.groups}'}}</span>
+      <span ng-show="isNotEmptyFilter">- <a href 
ng-click="clearFilters()">{{'common.controls.clearFilters' | 
translate}}</a></span>
+    </div>
+    <div class="pull-right left-margin">
+      <pagination class="paginator" total-items="totalGroups" 
max-size="maxVisiblePages" items-per-page="groupsPerPage" 
ng-model="currentPage" ng-change="pageChanged()"></pagination>
+    </div>
+    <div class="pull-right">
+      <select class="form-control" ng-model="groupsPerPage" 
ng-change="groupsPerPageChanges()" ng-options="currOption for currOption in 
[10, 25, 50, 100]"></select>
+    </div>
+  </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/main.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/main.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/main.html
new file mode 100644
index 0000000..8520fc2
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/main.html
@@ -0,0 +1,36 @@
+<!--
+* 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 id="user-management">
+  <ul class="nav nav-tabs">
+    <li ng-class="{active: activeTab === 'USERS'}">
+      <a href="#/userManagement?tab=users" >{{'common.users' | translate}}</a>
+    </li>
+    <li ng-class="{active: activeTab === 'GROUPS'}">
+      <a href="#/userManagement?tab=groups" >{{'common.groups' | 
translate}}</a>
+    </li>
+  </ul>
+  <div>
+    <div class="users" ng-if="activeTab === 'USERS'">
+      <div ng-include="'views/userManagement/usersList.html'" 
ng-controller="UsersListCtrl"></div>
+    </div>
+    <div class="groups" ng-if="activeTab === 'GROUPS'">
+      <div ng-include="'views/userManagement/groupsList.html'" 
ng-controller="GroupsListCtrl"></div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/changePassword.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/changePassword.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/changePassword.html
new file mode 100644
index 0000000..f29d315
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/changePassword.html
@@ -0,0 +1,46 @@
+<!--
+* 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="modal-header">
+  <h3 class="modal-title">{{'users.changePasswordFor' | translate: '{userName: 
userName}'}}</h3>
+</div>
+<div class="modal-body">
+  <form class="form-horizontal" novalidate name="form.passwordChangeForm" 
role="form" >
+    <div class="form-group" ng-class="{'has-error' : 
(form.passwordChangeForm.currentPassword.$error.required && 
form.passwordChangeForm.submitted)}">
+      <label for="" class="col-sm-4 control-label" >{{'users.yourPassword' | 
translate}}</label>
+      <div class="col-sm-8">
+        <input type="password" name="currentPassword" class="form-control 
bottom-margin" placeholder="{{'users.yourPassword' | translate}}" required 
ng-model="passwordData.currentUserPassword" autocomplete="off">
+        <div class="alert alert-danger no-margin-bottom" 
ng-show='form.passwordChangeForm.password.$error.required && 
form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | 
translate}}</div>
+      </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">{{'users.newPassword' | 
translate}}:</label>
+      <div class="col-sm-8">
+        <input type="password" class="form-control bottom-margin" 
name="password" placeholder="{{'users.newPassword' | translate}}" required 
ng-model="passwordData.password" autocomplete="off">
+        <input type="password" class="form-control bottom-margin" 
name="confirmPassword" placeholder="{{'users.newPasswordConfirmation' | 
translate}}" 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'>{{'users.alerts.wrongPassword'
 | translate}}</div>
+        <div class="alert alert-danger no-margin-bottom" 
ng-show='form.passwordChangeForm.password.$error.required && 
form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | 
translate}}</div>
+      </div>
+
+    </div>
+  </form>
+</div>
+<div class="modal-footer">
+  <button class="btn btn-default" 
ng-click="cancel()">{{'common.controls.cancel' | translate}}</button>
+  <button class="btn btn-primary" ng-click="ok()">{{'common.controls.ok' | 
translate}}</button>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html
new file mode 100644
index 0000000..e11b478
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html
@@ -0,0 +1,86 @@
+<!--
+* 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.
+-->
+
+<form id="create-group-form" role="form" novalidate 
name="form.groupCreateForm">
+  <div class="modal-header">
+    <h1 class="modal-title">
+      {{'groups.createLocal' | translate}}
+    </h1>
+  </div>
+  <div class="modal-body">
+    <div class="form-group"
+         ng-class="{ 'has-error': 
(form.groupCreateForm.groupName.$error.required || 
form.groupCreateForm.groupName.$error.pattern) && 
form.groupCreateForm.submitted }">
+      <label for="groupName">
+        {{'groups.name' | translate}}<span>&nbsp;*</span>&nbsp;
+      </label>
+      <input type="text"
+             placeholder="{{'groups.name' | translate}}"
+             ng-pattern="/^([a-zA-Z0-9._\s]+)$/"
+             autofocus
+             ng-maxlength="80"
+             autocomplete="off"
+             class="form-control"
+             ng-model="formData.groupName"
+             name="groupName"
+             id="groupName"
+             ng-change="checkIfInstanceExist()"
+             required>
+      <span class="help-block validation-block"
+            ng-show='form.groupCreateForm.groupName.$error.required && 
form.groupCreateForm.submitted'>
+        {{'common.alerts.fieldRequired' | translate}}
+      </span>
+      <span class="help-block validation-block"
+            ng-show='form.groupCreateForm.groupName.$error.pattern && 
form.groupCreateForm.submitted'>
+        {{'common.alerts.noSpecialChars' | translate}}
+      </span>
+    </div>
+
+    <div class="form-group">
+      <label>{{'groups.addUsers' | translate}}</label>
+      <div>
+        <editable-list items-source="formData.members" resource-type="User" 
editable="true"></editable-list>
+      </div>
+    </div>
+
+    <div class="row">
+      <div class="form-group col-sm-6"
+           ng-class="{ 'has-error': form.groupCreateForm.role.$error.required 
&& form.groupCreateForm.submitted }">
+        <label for="role" class="nowrap roles-label">
+          {{'groups.role' | translate}}
+          <i class="fa fa-question-circle" aria-hidden="true" 
ng-click="showHelpPage()"></i>
+        </label>
+        <select
+          class="form-control"
+          id="role"
+          name="role"
+          ng-model="formData.role">
+          <option value="" class="hide">{{'common.select' | 
translate}}</option>
+          <option ng-repeat="role in roleOptions" 
value="{{role.permission_name}}">{{role.permission_label}}</option>
+        </select>
+        <span class="help-block validation-block" 
ng-show='form.groupCreateForm.role.$error.required && 
form.groupCreateForm.submitted'>
+          {{'common.alerts.fieldRequired' | translate}}
+        </span>
+      </div>
+    </div>
+
+  </div>
+  <div class="modal-footer">
+    <button class="btn btn-default" 
ng-click="cancel()">{{'common.controls.cancel' | translate}}</button>
+    <button class="btn btn-primary" ng-click="save()" 
type="submit">{{'common.controls.save' | translate}}</button>
+  </div>
+</form>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html
new file mode 100644
index 0000000..2a71102
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html
@@ -0,0 +1,147 @@
+<!--
+* 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.
+-->
+
+<form id="create-user-form" role="form" novalidate name="form.userCreateForm">
+  <div class="modal-header">
+    <h1 class="modal-title">
+      {{'users.create' | translate}}
+    </h1>
+  </div>
+  <div class="modal-body">
+    <div class="form-group"
+         ng-class="{ 'has-error': 
(form.userCreateForm.userName.$error.required || 
form.userCreateForm.userName.$error.pattern) && form.userCreateForm.submitted 
}">
+      <label for="userName">
+        {{'users.username' | translate}}<span>&nbsp;*</span>&nbsp;
+        <i class="fa fa-question-circle" aria-hidden="true"></i>
+      </label>
+      <input type="text"
+             autofocus
+             placeholder="{{'users.user.name' | translate}}"
+             ng-pattern="/^[^<>&`|\\]+$/"
+             ng-maxlength="80"
+             tooltip="{{'users.userNameTip' | translate}}"
+             autocomplete="off"
+             tooltip-trigger="focus"
+             class="form-control"
+             ng-model="formData.userName"
+             name="userName"
+             id="userName"
+             ng-change="checkIfInstanceExist()"
+             required>
+      <span class="help-block validation-block"
+            ng-show='form.userCreateForm.userName.$error.required && 
form.userCreateForm.submitted'>
+        {{'common.alerts.fieldRequired' | translate}}
+      </span>
+      <span class="help-block validation-block"
+            ng-show='form.userCreateForm.userName.$error.pattern && 
form.userCreateForm.submitted'>
+        {{'common.alerts.noSpecialChars' | translate}}
+      </span>
+    </div>
+
+    <div class="row">
+      <div class="form-group col-sm-6"
+           ng-class="{ 'has-error': 
form.userCreateForm.password.$error.required && form.userCreateForm.submitted 
}">
+        <label for="password">
+          {{'users.password' | translate}}<span>&nbsp;*</span>
+        </label>
+        <input type="password"
+               id="password"
+               class="form-control"
+               name="password"
+               placeholder="{{'users.password' | translate}}"
+               required
+               ng-model="formData.password"
+               autocomplete="off">
+        <span class="help-block validation-block"
+              ng-show='form.userCreateForm.password.$error.required && 
form.userCreateForm.submitted'>
+          {{'common.alerts.fieldRequired' | translate}}
+        </span>
+      </div>
+      <div class="form-group col-sm-6"
+           ng-class="{ 'has-error': 
form.userCreateForm.confirmPassword.$error.passwordVerify || 
(form.userCreateForm.confirmPassword.$error.required && 
form.userCreateForm.submitted) }">
+        <label for="confirmPassword">
+          {{'users.confirmPassword' | translate}}<span>&nbsp;*</span>
+        </label>
+        <input type="password"
+               id="confirmPassword"
+               class="form-control"
+               name="confirmPassword"
+               placeholder="{{'users.confirmPassword' | translate}}"
+               required
+               password-verify="formData.password"
+               ng-model="formData.confirmPassword"
+               autocomplete="off">
+        <span class="help-block validation-block"
+              ng-show='form.userCreateForm.confirmPassword.$error.required && 
form.userCreateForm.submitted'>
+          {{'common.alerts.fieldRequired' | translate}}
+        </span>
+        <span class="help-block validation-block"
+              
ng-show='form.userCreateForm.confirmPassword.$error.passwordVerify'>
+          {{'users.alerts.wrongPassword' | translate}}
+        </span>
+      </div>
+    </div>
+
+    <div class="row">
+      <div class="form-group col-sm-6"
+           ng-class="{ 'has-error': form.userCreateForm.role.$error.required 
&& form.userCreateForm.submitted }">
+        <label for="role" class="nowrap roles-label">
+          {{'users.role' | translate}}<span>&nbsp;*</span>
+          <i class="fa fa-question-circle" aria-hidden="true" 
ng-click="showHelpPage()"></i>
+        </label>
+        <select
+          class="form-control"
+          id="role"
+          name="role"
+          ng-model="formData.role"
+          required>
+          <option value="" class="hide">{{'common.select' | 
translate}}</option>
+          <option ng-repeat="role in roleOptions" 
value="{{role.permission_name}}">{{role.permission_label}}</option>
+        </select>
+        <span class="help-block validation-block" 
ng-show='form.userCreateForm.role.$error.required && 
form.userCreateForm.submitted'>
+          {{'common.alerts.fieldRequired' | translate}}
+        </span>
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label>
+        {{'users.isAmbariAdmin' | translate}}<span>&nbsp;*</span>
+        <i class="fa fa-question-circle" aria-hidden="true"></i>
+      </label>
+      <div>
+        <toggle-switch model="formData.isAdmin" on-label="{{'common.yes' | 
translate}}" off-label="{{'common.no' | translate}}" class="switch-primary" 
data-off-color="danger"></toggle-switch>
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label>
+        {{'users.isActive' | translate}}<span>&nbsp;*</span>
+        <i class="fa fa-question-circle" aria-hidden="true"></i>
+      </label>
+      <div>
+        <toggle-switch model="formData.isActive" on-label="{{'users.active' | 
translate}}" off-label="{{'users.inactive' | translate}}" 
class="switch-primary" data-off-color="danger"></toggle-switch>
+      </div>
+    </div>
+
+  </div>
+  <div class="modal-footer">
+    <button class="btn btn-default" 
ng-click="cancel()">{{'common.controls.cancel' | translate}}</button>
+    <button class="btn btn-primary" ng-click="save()" 
type="submit">{{'common.controls.save' | translate}}</button>
+  </div>
+</form>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html
new file mode 100644
index 0000000..cc46173
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html
@@ -0,0 +1,140 @@
+<!--
+* 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 ng-show="user" id="user-edit">
+  <div class="clearfix">
+    <ol class="breadcrumb pull-left">
+      <li><a href="#/userManagement?tab=users">{{'common.users' | 
translate}}</a></li>
+      <li class="active"><span class="glyphicon glyphicon-flash" 
ng-show="user.admin"></span>{{user.user_name}}</li>
+    </ol>
+    <div class="pull-right">
+      <div ng-switch="isCurrentUser || user.user_type != 'LOCAL'">
+        <button class="btn deleteuser-btn disabled btn-default" 
ng-switch-when="true" tooltip="{{'common.cannotDelete' | translate: '{term: 
constants.user}'}}">{{'common.delete' | translate: '{term: 
constants.user}'}}</button>
+        <button class="btn deleteuser-btn btn-danger" ng-switch-when="false" 
ng-click="deleteUser()">{{'common.delete' | translate: '{term: 
constants.user}'}}</button>
+      </div>
+    </div>
+  </div>
+  <hr>
+  <form class="form-horizontal" role="form" >
+    <div class="form-group">
+      <label class="col-sm-2 ">{{'common.type' | translate}}</label>
+      <div class="col-sm-10">
+        <label>{{user.userTypeName}}</label>
+      </div>
+    </div>
+    <div class="form-group">
+      <label class="col-sm-2 ">{{'users.status' | translate}}</label>
+      <div class="col-sm-10">
+        <toggle-switch on-change="toggleUserActive()" 
disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: 
constants.status}'}}" ng-disabled="isCurrentUser" model="user.active" 
on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | 
translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" 
data-off-color="danger"></toggle-switch>
+      </div>
+    </div>
+    <div class="form-group">
+      <label class="col-sm-2 "><span class="glyphicon glyphicon-flash"></span> 
{{'users.ambariAdmin' | translate}}</label>
+      <div class="col-sm-10">
+        <toggle-switch on-change="toggleUserAdmin()" 
disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: 
constants.admin}'}}" ng-disabled="isCurrentUser" model="user.admin" 
on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" 
class="switch-primary userstatus {{user ? '' : 'no-animation'}}" 
data-off-color="danger"></toggle-switch>
+      </div>
+    </div>
+    <div class="form-group">
+      <label class="col-sm-2 ">{{'users.password' | translate}}</label>
+      <div class="col-sm-10">
+        <div ng-switch="user.user_type != 'LOCAL'">
+          <button class="btn deleteuser-btn disabled btn-default" 
ng-switch-when="true" tooltip="{{'users.alerts.cannotChange' | translate: 
'{term: constants.password}'}}">{{'users.changePassword' | translate}}</button>
+          <a href ng-click="openChangePwdDialog()" ng-switch-when="false" 
class="btn btn-default changepassword">{{'users.changePassword' | 
translate}}</a>
+        </div>
+          
+      </div>
+    </div>
+    <div class="form-group">
+      <label class="col-sm-2 ">{{getUserMembership(user.user_type)}}</label>
+      <div class="col-sm-10">
+        <editable-list items-source="editingGroupsList" resource-type="Group" 
editable="user.user_type == 'LOCAL'"></editable-list>
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label for="role" class="col-sm-2 roles-label">
+        {{'users.role' | translate}}
+        <i class="fa fa-question-circle" aria-hidden="true" 
ng-click="showHelpPage()"></i>
+      </label>
+      <div class="col-sm-3">
+        <select ng-hide="user.admin"
+                class="form-control"
+                id="role"
+                name="role"
+                ng-options="item as item.permission_label for item in 
roleOptions track by item.permission_name"
+                ng-change="updateRole()"
+                ng-model="currentRole">
+        </select>
+        <span ng-show="user.admin" 
class="roles-label">{{user.roles[0].permission_label}}</span>
+      </div>
+    </div>
+
+    <div class="form-group" >
+      <label class="col-sm-2 ">{{'common.privileges' | translate}}</label>
+      <div class="col-sm-10">
+        <table class="table" ng-hide="hidePrivileges || user.admin">
+          <thead>
+            <tr>
+              <th>{{'common.cluster' | translate}}</th>
+              <th>{{'common.clusterRole' | translate}}</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr ng-repeat="(name, privilege) in privilegesView.clusters">
+              <td>
+                <span class="glyphicon glyphicon-cloud"></span> 
+                <a href="#/clusters/{{name}}/manageAccess">{{name}}</a>
+              </td>
+              <td>
+                <span 
tooltip="{{privilege.permission_label}}">{{privilege.permission_label}}</span>
+              </td>
+            </tr>
+            <tr>
+              <td ng-show="noClusterPriv">{{'common.alerts.noPrivileges' | 
translate: '{term: constants.cluster}'}}</td>
+            </tr>
+          </tbody>
+          <thead class="view-permission-header">
+            <tr>
+              <th>{{'common.view' | translate}}</th>
+              <th>{{'common.viewPermissions' | translate}}</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr ng-repeat="(name, privilege) in privilegesView.views">
+              <td>
+                <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 track by $index">{{item | translate}}{{$last ? '' : ', 
'}}</span>
+              </td>
+              <td>
+                <i class="fa fa-trash-o" aria-hidden="true" 
ng-click="removeViewPrivilege(name, privilege);"></i>
+              </td>
+            </tr>
+            <tr>
+              <td ng-show="noViewPriv">{{'common.alerts.noPrivileges' | 
translate: '{term: constants.view}'}}</td>
+            </tr>
+          </tbody>
+        </table>
+        <div class="alert alert-info" ng-show="hidePrivileges && 
!user.admin">{{'common.alerts.noPrivilegesDescription' | translate: '{term: 
constants.user}'}}</div>
+        <div class="alert alert-info" 
ng-show="user.admin">{{'users.userIsAdmin' | translate}}</div>
+      </div>
+    </div>
+  </form>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
new file mode 100644
index 0000000..4a33a31
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html
@@ -0,0 +1,119 @@
+<!--
+* 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 panel">
+    <button class="btn btn-default createuser-btn pull-right" 
ng-click="createUser();">
+      {{'users.create' | translate}}
+    </button>
+  </div>
+  <table class="table table-striped table-hover">
+    <thead>
+      <tr class="fix-bottom">
+        <th>
+          <span>{{'users.username' | translate}}</span>
+        </th>
+        <th>
+          <span>{{'clusters.role' | translate}}</span>
+        </th>
+        <th>
+          <span>{{'users.status' | translate}}</span>
+        </th>
+        <th>
+          <span>{{'common.type' | translate}}</span>
+        </th>
+        <th>
+          <span>{{'common.group' | translate}}</span>
+        </th>
+        <th class="entity-actions">
+          <span>{{'common.actions' | translate}}</span>
+        </th>
+      </tr>
+      <tr class="fix-top">
+        <th>
+          <div class="search-container">
+            <input type="text" class="form-control namefilter" 
placeholder="{{'common.any' | translate}}" ng-model="filters.name" 
ng-change="resetPagination()">
+            <button type="button" class="close clearfilter" 
ng-show="filters.name" ng-click="filters.name=''; resetPagination()">
+              <span aria-hidden="true">&times;</span><span 
class="sr-only">{{'common.controls.close' | translate}}</span>
+            </button>
+          </div>
+        </th>
+        <th></th>
+        <th>
+          <select class="form-control statusfilter"
+                  ng-model="filters.status"
+                  ng-options="item.label for item in activeFilterOptions"
+                  ng-change="resetPagination()">
+          </select>
+        </th>
+        <th>
+          <select class="form-control typefilter"
+                  ng-model="filters.type"
+                  ng-options="item.label for item in typeFilterOptions"
+                  ng-change="resetPagination()">
+          </select>
+        </th>
+        <th></th>
+        <th></th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr ng-repeat="user in users">
+        <td>
+          <span>{{user.Users.user_name}}</span>
+        </td>
+        <td>
+          <span>{{user.Users.roles[0].permission_label}}</span>
+        </td>
+        <td>
+          <span>
+            {{(user.Users.active ? 'users.active' : 'users.inactive') | 
translate}}
+          </span>
+        </td>
+        <td><span>{{user.Users.userTypeName}}</span></td>
+        <td><span>{{user.Users.groups.length ? user.Users.groups.join(' ') : 
'-'}}</span></td>
+        <td class="entity-actions">
+          <a href="#/users/{{user.Users.encodedName}}/edit">
+            <i class="fa fa-pencil"></i>
+          </a>
+          <a href ng-click="deleteUser(user.Users)">
+            <i class="fa fa-trash-o"></i>
+          </a>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  <div ng-if="isLoading" class="spinner-container">
+    <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
+  </div>
+  <div class="alert empty-table-alert col-sm-12" ng-show="!users.length && 
!isLoading">
+    {{'common.alerts.nothingToDisplay' | translate: '{term: constants.users}'}}
+  </div>
+  <div class="col-sm-12 table-bar" ng-show="totalUsers > 
minRowsToShowPagination">
+    <div class="pull-left filtered-info">
+      <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, 
total: tableInfo.total, term: constants.users}'}}</span>
+      <span ng-show="isNotEmptyFilter">- <a href 
ng-click="clearFilters()">{{'common.controls.clearFilters' | 
translate}}</a></span>
+    </div>
+    <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/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html
deleted file mode 100644
index 80a3b04..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html
+++ /dev/null
@@ -1,82 +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.
--->
-<ol class="breadcrumb">
-  <li><a href="#/users">{{'common.users' | translate}}</a></li>
-  <li class="active">{{'users.create' | translate}}</li>
-</ol>
-<hr>
-<form class="form-horizontal create-user-form" role="form" novalidate 
name="form" autocomplete="off">
-  <div class="form-group" ng-class="{'has-error' : 
form.user_name.$error.required && form.submitted}">
-    <label for="username" class="col-sm-2 control-label">{{'users.username' | 
translate}}</label>
-    <div class="col-sm-10"
-         ng-class="{'has-error': form.user_name.$error.pattern}">
-      <input
-        autofocus
-        type="text"
-        id="username"
-        class="form-control username-input"
-        name="user_name"
-        placeholder="{{'users.userName' | translate}}"
-        ng-model="user.user_name"
-        ng-required="true"
-        ng-pattern="/^[^<>&`|\\]+$/"
-        ng-maxlength="80"
-        tooltip="{{'users.userNameTip' | translate}}"
-        autocomplete="off"
-        tooltip-trigger="focus">
-      <div class="alert alert-danger top-margin" 
ng-show="form.user_name.$error.required && 
form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div>
-    </div>
-  </div>
-  <div class="form-group">
-    <label for="" class="col-sm-2 control-label">{{'common.type' | 
translate}}</label>
-    <div class="col-sm-10">
-      <label for="" class="control-label">{{'common.local' | 
translate}}</label>
-    </div>
-  </div>
-  <div class="form-group">
-    <label for="" class="col-sm-2 control-label">{{'users.status' | 
translate}}</label>
-    <div class="col-sm-10">
-      <toggle-switch model="user.active" on-label="{{'users.active' | 
translate}}" off-label="{{'users.inactive' | translate}}" class="switch-primary 
userstatus" data-off-color="danger"></toggle-switch>
-    </div>
-  </div>
-  <div class="form-group">
-    <label for="" class="col-sm-2 control-label"><span class="glyphicon 
glyphicon-flash"></span>{{'users.ambariAdmin' | translate}}</label>
-    <div class="col-sm-10">
-      <toggle-switch ng-disabled="isCurrentUser" model="user.admin" 
on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" 
class="switch-primary userstatus" data-off-color="danger"></toggle-switch>
-    </div>
-    </div>
-  <div class="form-group" ng-class="{'has-error' : 
(form.password.$error.required && form.submitted) || 
form.confirmPassword.$error.passwordVerify}">
-    <label for="password" class="col-sm-2 control-label">{{'users.password' | 
translate}}</label>
-    <div class="col-sm-10">
-      <input type="password" class="form-control bottom-margin userpassword" 
name="password" placeholder="{{'users.password' | translate}}" required 
ng-model="user.password" autocomplete="off">
-      <input type="password" class="form-control bottom-margin 
userpasswordconfirm" name="confirmPassword" 
placeholder="{{'users.passwordConfirmation' | translate}}" required 
ng-model="user.passwordConfirmation"
-        password-verify="user.password" autocomplete="off">
-
-      <div class="alert alert-danger" 
ng-show='form.confirmPassword.$error.passwordVerify'>{{'users.alerts.wrongPassword'
 | translate}}</div>
-      <div class="alert alert-danger" ng-show='form.password.$error.required 
&& form.submitted'>{{'users.alerts.passwordRequired' | translate}}</div>
-      
-    </div>
-  </div>
-  <div class="form-group">
-    <div class="col-sm-offset-2 col-sm-10">
-      <button class="btn btn-primary pull-right left-margin saveuser" 
ng-click="createUser()">{{'common.controls.save' | translate}}</button>
-      <a class="btn btn-default pull-right cancel" href 
ng-click="cancel()">{{'common.controls.cancel' | translate}}</a>
-    </div>
-  </div>
-      
-</form>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
deleted file mode 100644
index 09024a5..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
+++ /dev/null
@@ -1,96 +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.
--->
-
-<div class="users-pane">
-  <div class="clearfix">
-    <ol class="breadcrumb pull-left">
-      <li class="active">{{'common.users' | translate}}</li>
-    </ol>
-    <div class="pull-right top-margin-4">
-      <link-to route="users.create" class="btn btn-primary 
createuser-btn"><span class="glyphicon glyphicon-plus"></span> {{'users.create' 
| translate}}</link-to>
-    </div>
-  </div>
-  <hr>
-  <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 ? 'users.showAll' : 'users.showAdmin') | 
translate}}"
-          ></span>
-        </th>
-        <th>
-          <div class="search-container">
-            <label for="">{{'users.username' | translate}}</label>
-            <input type="text" class="form-control namefilter" 
placeholder="{{'common.any' | translate}}" 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">{{'common.controls.close' | translate}}</span></button>
-          </div>
-        </th>
-        <th>
-          <label for="">{{'common.type' | translate}}</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="">{{'users.status' | translate}}</label>
-          <select class="form-control statusfilter" 
-            ng-model="currentActiveFilter"
-            ng-options="item.label for item in activeFilterOptions"
-            ng-change="resetPagination()">
-          </select>
-        </th>
-      </tr>
-    </thead>
-    <tbody>
-      <tr ng-repeat="user in users">
-        <td>
-          <span class="glyphicon" tooltip="{{user.Users.admin ? 
constants.admin : ''}}" ng-class="{'glyphicon-flash' : 
user.Users.admin}"></span>
-        </td>
-        <td>
-           <a 
href="#/users/{{user.Users.encoded_name}}">{{user.Users.user_name}}</a>
-        </td>
-        <td>{{user.Users.userTypeName}}</td>
-        <td><span ng-class="user.Users.active ? 'text-success' : 
'text-danger'">{{(user.Users.active ? 'users.active' : 'users.inactive') | 
translate}}</span></td>
-      </tr>
-    </tbody>
-  </table>
-  <div ng-if="isLoading" class="spinner-container">
-    <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
-  </div>
-  <div class="alert alert-info col-sm-12" ng-show="!users.length && 
!isLoading">
-    {{'common.alerts.nothingToDisplay' | translate: '{term: constants.users}'}}
-  </div>
-  <div class="col-sm-12 table-bar">
-    <div class="pull-left filtered-info">
-      <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, 
total: tableInfo.total, term: constants.users}'}}</span>
-      <span ng-show="isNotEmptyFilter">- <a href 
ng-click="clearFilters()">{{'common.controls.clearFilters' | 
translate}}</a></span>
-    </div>
-    <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/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html
 
b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html
deleted file mode 100644
index f29d315..0000000
--- 
a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html
+++ /dev/null
@@ -1,46 +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.
--->
-<div class="modal-header">
-  <h3 class="modal-title">{{'users.changePasswordFor' | translate: '{userName: 
userName}'}}</h3>
-</div>
-<div class="modal-body">
-  <form class="form-horizontal" novalidate name="form.passwordChangeForm" 
role="form" >
-    <div class="form-group" ng-class="{'has-error' : 
(form.passwordChangeForm.currentPassword.$error.required && 
form.passwordChangeForm.submitted)}">
-      <label for="" class="col-sm-4 control-label" >{{'users.yourPassword' | 
translate}}</label>
-      <div class="col-sm-8">
-        <input type="password" name="currentPassword" class="form-control 
bottom-margin" placeholder="{{'users.yourPassword' | translate}}" required 
ng-model="passwordData.currentUserPassword" autocomplete="off">
-        <div class="alert alert-danger no-margin-bottom" 
ng-show='form.passwordChangeForm.password.$error.required && 
form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | 
translate}}</div>
-      </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">{{'users.newPassword' | 
translate}}:</label>
-      <div class="col-sm-8">
-        <input type="password" class="form-control bottom-margin" 
name="password" placeholder="{{'users.newPassword' | translate}}" required 
ng-model="passwordData.password" autocomplete="off">
-        <input type="password" class="form-control bottom-margin" 
name="confirmPassword" placeholder="{{'users.newPasswordConfirmation' | 
translate}}" 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'>{{'users.alerts.wrongPassword'
 | translate}}</div>
-        <div class="alert alert-danger no-margin-bottom" 
ng-show='form.passwordChangeForm.password.$error.required && 
form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | 
translate}}</div>
-      </div>
-
-    </div>
-  </form>
-</div>
-<div class="modal-footer">
-  <button class="btn btn-default" 
ng-click="cancel()">{{'common.controls.cancel' | translate}}</button>
-  <button class="btn btn-primary" ng-click="ok()">{{'common.controls.ok' | 
translate}}</button>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/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
deleted file mode 100644
index f965c5d..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html
+++ /dev/null
@@ -1,122 +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.
--->
-    
-<div ng-show="user" class="user-edit-panel">
-  <div class="clearfix">
-    <ol class="breadcrumb pull-left">
-      <li><a href="#/users">{{'common.users' | translate}}</a></li>
-      <li class="active"><span class="glyphicon glyphicon-flash" 
ng-show="user.admin"></span>{{user.user_name}}</li>
-    </ol>
-    <div class="pull-right top-margin-4">
-      <div ng-switch="isCurrentUser || user.user_type != 'LOCAL'">
-        <button class="btn deleteuser-btn disabled btn-default" 
ng-switch-when="true" tooltip="{{'common.cannotDelete' | translate: '{term: 
constants.user}'}}">{{'common.delete' | translate: '{term: 
constants.user}'}}</button>
-        <button class="btn deleteuser-btn btn-danger" ng-switch-when="false" 
ng-click="deleteUser()">{{'common.delete' | translate: '{term: 
constants.user}'}}</button>
-      </div>
-    </div>
-  </div>
-  <hr>
-  <form class="form-horizontal" role="form" >
-    <div class="form-group">
-      <label for="" class="col-sm-2 control-label">{{'common.type' | 
translate}}</label>
-      <div class="col-sm-10">
-        <label for="" class="control-label">{{user.userTypeName}}</label>
-      </div>
-    </div>
-    <div class="form-group">
-      <label for="" class="col-sm-2 control-label">{{'users.status' | 
translate}}</label>
-      <div class="col-sm-10">
-        <toggle-switch on-change="toggleUserActive()" 
disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: 
constants.status}'}}" ng-disabled="isCurrentUser" model="user.active" 
on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | 
translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" 
data-off-color="danger"></toggle-switch>
-      </div>
-    </div>
-    <div class="form-group">
-      <label for="" class="col-sm-2 control-label"><span class="glyphicon 
glyphicon-flash"></span> {{'users.ambariAdmin' | translate}}</label>
-      <div class="col-sm-10">
-        <toggle-switch on-change="toggleUserAdmin()" 
disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: 
constants.admin}'}}" ng-disabled="isCurrentUser" model="user.admin" 
on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" 
class="switch-primary userstatus {{user ? '' : 'no-animation'}}" 
data-off-color="danger"></toggle-switch>
-      </div>
-    </div>
-    <div class="form-group">
-      <label for="password" class="col-sm-2 control-label">{{'users.password' 
| translate}}</label>
-      <div class="col-sm-10">
-        <div ng-switch="user.user_type != 'LOCAL'">
-          <button class="btn deleteuser-btn disabled btn-default" 
ng-switch-when="true" tooltip="{{'users.alerts.cannotChange' | translate: 
'{term: constants.password}'}}">{{'users.changePassword' | translate}}</button>
-          <a href ng-click="openChangePwdDialog()" ng-switch-when="false" 
class="btn btn-default changepassword">{{'users.changePassword' | 
translate}}</a>
-        </div>
-          
-      </div>
-    </div>
-    <div class="form-group">
-      <label for="groups" class="col-sm-2 
control-label">{{getUserMembership(user.user_type)}}</label>
-      <div class="col-sm-10">
-        <editable-list items-source="editingGroupsList" resource-type="Group" 
editable="user.user_type == 'LOCAL'"></editable-list>
-      </div>
-        
-    </div>
-    <div class="form-group" >
-      <label for="" class="col-sm-2 control-label">{{'common.privileges' | 
translate}}</label>
-      <div class="col-sm-10">
-        <table class="table" ng-hide="hidePrivileges || user.admin">
-          <thead>
-            <tr>
-              <th>{{'common.cluster' | translate}}</th>
-              <th>{{'common.clusterRole' | translate}}</th>
-            </tr>
-          </thead>
-          <tbody>
-            <tr ng-repeat="(name, privilege) in privileges.clusters">
-              <td>
-                <span class="glyphicon glyphicon-cloud"></span> 
-                <a href="#/clusters/{{name}}/manageAccess">{{name}}</a>
-              </td>
-              <td>
-                <span 
tooltip="{{privilege.permission_label}}">{{privilege.permission_label}}</span>
-              </td>
-            </tr>
-            <tr>
-              <td ng-show="noClusterPriv">{{'common.alerts.noPrivileges' | 
translate: '{term: constants.cluster}'}}</td>
-            </tr>
-          </tbody>
-          <thead class="view-permission-header">
-            <tr>
-              <th>{{'common.view' | translate}}</th>
-              <th>{{'common.viewPermissions' | translate}}</th>
-            </tr>
-          </thead>
-          <tbody>
-            <tr ng-repeat="(name, privilege) in privileges.views">
-              <td>
-                <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 track by $index">{{item | translate}}{{$last ? '' : ', 
'}}</span>
-              </td>
-              <td>
-                <i class="fa fa-trash-o" aria-hidden="true" 
ng-click="removePrivilege(name, privilege);"></i>
-              </td>
-            </tr>
-            <tr>
-              <td ng-show="noViewPriv">{{'common.alerts.noPrivileges' | 
translate: '{term: constants.view}'}}</td>
-            </tr>
-          </tbody>
-        </table>
-        <div class="alert alert-info" ng-show="!privileges && 
!user.admin">{{'common.alerts.noPrivilegesDescription' | translate: '{term: 
constants.user}'}}</div>
-        <div class="alert alert-info" 
ng-show="user.admin">{{'users.userIsAdmin' | translate}}</div>
-      </div>
-    </div>
-  </form>
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/bower.json
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/bower.json 
b/ambari-admin/src/main/resources/ui/admin-web/bower.json
index dbdf005..c38f464 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/bower.json
+++ b/ambari-admin/src/main/resources/ui/admin-web/bower.json
@@ -2,7 +2,7 @@
   "name": "adminconsole",
   "private": true,
   "dependencies": {
-    "bootstrap": "3.1.1",
+    "bootstrap": "3.3.7",
     "angular": "1.2.26",
     "angular-route": "1.2.26",
     "angular-bootstrap": "0.11.0",

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js 
b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
index 2f47b85..9b377d1 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
@@ -24,10 +24,10 @@ var gulp = require('gulp');
 var $ = require('gulp-load-plugins')();
 
 gulp.task('styles', function () {
-  return gulp.src('app/styles/*.css')
+  return gulp.src('app/styles/**/*.css')
     .pipe($.order([
-      'app/styles/main.css',
-      'app/styles/custom-admin-ui.css'   // This should always be the last 
stylesheet. So it can be dropped and be effective on build time
+      'app/styles/theme/bootstrap-ambari.css',
+      'app/styles/main.css'
     ], { base: './' }))
     .pipe($.concat('main.css'))
     .pipe($.autoprefixer('last 1 version'))
@@ -64,8 +64,8 @@ gulp.task('images', function () {
 });
 
 gulp.task('fonts', function () {
-  return $.bowerFiles()
-    .pipe($.filter('**/*.{eot,svg,ttf,woff}'))
+  return gulp.src('app/bower_components/**/fonts/*.{eot,svg,ttf,woff}')
+    .pipe($.addSrc('app/assets/fonts/*'))
     .pipe($.flatten())
     .pipe(gulp.dest('dist/fonts'))
     .pipe($.size());

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/package.json
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/package.json 
b/ambari-admin/src/main/resources/ui/admin-web/package.json
index efcd9d4..b7c514c 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/package.json
+++ b/ambari-admin/src/main/resources/ui/admin-web/package.json
@@ -5,19 +5,19 @@
   "devDependencies": {
     "bower": "1.3.8",
     "gulp": "^3.8.8",
+    "gulp-add-src": "^0.2.0",
     "gulp-autoprefixer": "0.0.7",
-    "gulp-bower-files": "0.2.1",
     "gulp-cache": "0.1.1",
     "gulp-clean": "0.2.4",
+    "gulp-concat": "2.6.0",
     "gulp-filter": "0.4.1",
     "gulp-flatten": "0.0.2",
     "gulp-load-plugins": "0.5.0",
+    "gulp-order": "1.1.1",
     "gulp-plumber": "0.6.6",
     "gulp-size": "0.3.0",
     "gulp-uglify": "0.2.1",
     "gulp-useref": "0.4.2",
-    "gulp-concat": "2.6.0",
-    "gulp-order": "1.1.1",
     "http-server": "0.6.1",
     "karma": "0.12.16",
     "karma-chrome-launcher": "0.1.4",

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
 
b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
new file mode 100644
index 0000000..1bbe47a
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
@@ -0,0 +1,211 @@
+/**
+ * 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.
+ */
+
+describe('#AppCtrl', function () {
+
+  var scope, ctrl, $httpBackend, $window, clusterService, deferred;
+
+  beforeEach(function () {
+    module('ambariAdminConsole', function ($provide) {
+      $provide.value('$route', {
+        current: null
+      });
+      $provide.value('$window', {
+        location: {
+          pathname: 
'http://c6401.ambari.apache.org:8080/views/ADMIN_VIEW/2.0.0/INSTANCE/#/'
+        },
+        localStorage: {
+          getItem: function () {
+            return null;
+          },
+          setItem: angular.noop
+        }
+      });
+      localStorage.ambari = JSON.stringify({
+        app: {
+          authenticated: true,
+          loginName: 'admin',
+          user: 'user'
+        }
+      });
+    });
+    inject(function (_$httpBackend_, $rootScope, $controller, _$window_, 
_Cluster_, _$q_) {
+      clusterService = _Cluster_;
+      deferred = _$q_.defer();
+      spyOn(clusterService, 'getStatus').andReturn(deferred.promise);
+      deferred.resolve({
+        Clusters: {
+          provisioning_state: 'INIT'
+        }
+      });
+      $window = _$window_;
+      $httpBackend = _$httpBackend_;
+      
$httpBackend.whenGET(/api\/v1\/services\/AMBARI\/components\/AMBARI_SERVER.+/).respond(200,
 {
+        RootServiceComponents: {
+          component_version: 2.2,
+          properties: {
+            'user.inactivity.timeout.default': 20
+          }
+        }
+      });
+      $httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, {
+          "href": 
"http://c6401.ambari.apache.org:8080/api/v1/views?fields=versions/instances/ViewInstanceInfo&versions/ViewVersionInfo/system=false&versions/instances/ViewInstanceInfo/visible=true";,
+          "items": [
+            {
+              "ViewInfo": {
+                "view_name": "SLIDER"
+              },
+              "href": 
"http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER";,
+              "versions": [
+                {
+                  "ViewVersionInfo": {
+                    "system": false,
+                    "version": "1.0.0",
+                    "view_name": "SLIDER"
+                  },
+                  "href": 
"http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0";,
+                  "instances": [
+                    {
+                      "ViewInstanceInfo": {
+                        "context_path": "/views/SLIDER/1.0.0/VisibleInstance",
+                        "description": "VisibleInstance",
+                        "icon64_path": null,
+                        "icon_path": null,
+                        "instance_data": {},
+                        "instance_name": "VisibleInstance",
+                        "label": "VisibleInstance",
+                        "properties": {
+                          "ambari.server.password": "123",
+                          "ambari.server.url": "123",
+                          "ambari.server.username": "123",
+                          "slider.user": null,
+                          "view.kerberos.principal": null,
+                          "view.kerberos.principal.keytab": null
+                        },
+                        "static": false,
+                        "version": "1.0.0",
+                        "view_name": "SLIDER",
+                        "visible": true
+                      },
+                      "href": 
"http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0/instances/VisibleInstance";
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        });
+      $httpBackend.whenGET(/\/persist\/user-pref-.*/).respond(200, {
+        data: {
+          data: {
+            addingNewRepository: true
+          }
+        }
+      });
+      scope = $rootScope.$new();
+      scope.$apply();
+      ctrl = $controller('AppCtrl', {
+        $scope: scope
+      });
+    });
+  });
+
+  afterEach(function() {
+    $httpBackend.verifyNoOutstandingExpectation();
+    $httpBackend.verifyNoOutstandingRequest();
+  });
+
+  describe('signout', function () {
+
+    beforeEach(function () {
+      $httpBackend.whenGET(/\/api\/v1\/logout\?_=\d+/).respond(200,{
+        message: "successfully logged out"
+      });
+      
$httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
+        items: [
+          {
+            AuthorizationInfo: {
+              authorization_id: "AMBARI.RENAME_CLUSTER"
+            }
+          }
+        ]
+      });
+    });
+
+    it('should reset window.location and ambari localstorage', function () {
+      scope.signOut();
+
+      runs(function() {
+        chai.expect($window.location.pathname).to.equal('/');
+      });
+
+      var data = JSON.parse(localStorage.ambari);
+      chai.expect(data.app.authenticated).to.equal(undefined);
+      chai.expect(data.app.loginName).to.equal(undefined);
+      chai.expect(data.app.user).to.equal(undefined);
+      $httpBackend.flush();
+    });
+  });
+
+  describe('roles loading', function () {
+
+    var mock = {
+        callback: angular.noop
+      },
+      cases = [
+        {
+          canPersistData: true,
+          items: [
+            {
+              AuthorizationInfo: {
+                authorization_id: 'CLUSTER.MANAGE_USER_PERSISTED_DATA'
+              }
+            }
+          ],
+          title: 'user can persist data'
+        },
+        {
+          canPersistData: false,
+          items: [],
+          title: 'user can\'t persist data'
+        }
+      ];
+
+    angular.forEach(cases, function (item) {
+
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          
$httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
+            items: item.items
+          });
+          spyOn(mock, 'callback');
+          scope.authDataLoad.promise.then(mock.callback);
+          $httpBackend.flush();
+        });
+
+        it('authDataLoad should be resolved with the correct argument', 
function () {
+          expect(mock.callback).toHaveBeenCalledWith(item.canPersistData);
+        });
+
+      });
+
+    });
+
+  });
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ClusterInformationCtrl_test.js
----------------------------------------------------------------------
diff --git 
a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ClusterInformationCtrl_test.js
 
b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ClusterInformationCtrl_test.js
new file mode 100644
index 0000000..2972e7f
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ClusterInformationCtrl_test.js
@@ -0,0 +1,102 @@
+/**
+ * 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.
+ */
+
+describe('ClusterInformationCtrl', function() {
+  beforeEach(module('ambariAdminConsole'));
+
+  var ctrl, $scope, Cluster, deferred, ConfirmationModal;
+
+  beforeEach(inject(function($controller, $rootScope, _Cluster_, _$q_, 
_ConfirmationModal_){
+    // The injector unwraps the underscores (_) from around the parameter 
names when matching
+    Cluster = _Cluster_;
+    ConfirmationModal = _ConfirmationModal_;
+    deferred = _$q_.defer();
+    $scope = $rootScope.$new();
+    $scope.$apply();
+    ctrl = $controller('ClusterInformationCtrl', {
+      $scope: $scope
+    });
+
+    spyOn(Cluster, 'getBlueprint').andReturn(deferred.promise);
+    spyOn(Cluster, 'editName').andReturn(deferred.promise);
+    spyOn(ConfirmationModal, 'show').andReturn(deferred.promise);
+  }));
+
+  describe('#getBlueprint', function() {
+    it('Cluster.getBlueprint should be called', function() {
+      $scope.cluster = {
+        Clusters: {
+          cluster_name: 'c1'
+        }
+      };
+      $scope.getBlueprint();
+      expect(Cluster.getBlueprint).toHaveBeenCalled();
+    });
+  });
+
+  describe('#toggleSaveButton', function() {
+    beforeEach(function() {
+      $scope.cluster = {
+        Clusters: {
+          cluster_name: 'c1'
+        }
+      };
+    });
+
+    it('isClusterNameEdited should be true', function() {
+      $scope.edit = {
+        clusterName: 'c2'
+      };
+      $scope.toggleSaveButton();
+      expect($scope.isClusterNameEdited).toBeTruthy();
+    });
+
+    it('isClusterNameEdited should be false', function() {
+      $scope.edit = {
+        clusterName: 'c1'
+      };
+      $scope.toggleSaveButton();
+      expect($scope.isClusterNameEdited).toBeFalsy();
+    });
+  });
+
+  describe('#confirmClusterNameChange', function() {
+    it('ConfirmationModal.show should be called', function() {
+      $scope.edit = {
+        clusterName: 'c1'
+      };
+      $scope.confirmClusterNameChange();
+      expect(ConfirmationModal.show).toHaveBeenCalled();
+    });
+  });
+
+  describe('#saveClusterName', function() {
+    it('Cluster.editName should be called', function() {
+      $scope.edit = {
+        clusterName: 'c1'
+      };
+      $scope.cluster = {
+        Clusters: {
+          cluster_name: 'c2'
+        }
+      };
+      $scope.saveClusterName();
+      expect(Cluster.editName).toHaveBeenCalledWith('c2', 'c1');
+    });
+  });
+});

Reply via email to