瀏覽代碼

AMBARI-6671. Ambari-admin view: Create Group Management Page (with mock data).(jaimin)

Jaimin Jetly 11 年之前
父節點
當前提交
577da0a949

+ 3 - 0
ambari-admin/src/main/resources/ui/admin-web/app/index.html

@@ -113,12 +113,15 @@
     <script src="scripts/controllers/users/UsersListCtrl.js"></script>
     <script src="scripts/controllers/users/UsersListCtrl.js"></script>
     <script src="scripts/controllers/users/UsersShowCtrl.js"></script>
     <script src="scripts/controllers/users/UsersShowCtrl.js"></script>
     <script src="scripts/controllers/groups/GroupsListCtrl.js"></script>
     <script src="scripts/controllers/groups/GroupsListCtrl.js"></script>
+    <script src="scripts/controllers/groups/GroupsCreateCtrl.js"></script>
+    <script src="scripts/controllers/groups/GroupsEditCtrl.js"></script>
     <script src="scripts/controllers/ambariViews/ViewsListCtrl.js"></script>
     <script src="scripts/controllers/ambariViews/ViewsListCtrl.js"></script>
     <script src="scripts/controllers/ambariViews/ViewsEditCtrl.js"></script>
     <script src="scripts/controllers/ambariViews/ViewsEditCtrl.js"></script>
     <script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script>
     <script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script>
     <script src="scripts/directives/linkToDir.js"></script>
     <script src="scripts/directives/linkToDir.js"></script>
     <script src="scripts/directives/PasswordVerify.js"></script>
     <script src="scripts/directives/PasswordVerify.js"></script>
     <script src="scripts/services/User.js"></script>
     <script src="scripts/services/User.js"></script>
+    <script src="scripts/services/Group.js"></script>
     <!-- endbuild -->
     <!-- endbuild -->
 </body>
 </body>
 </html>
 </html>

+ 6 - 0
ambari-admin/src/main/resources/ui/admin-web/app/scripts/app.js

@@ -22,6 +22,9 @@ angular.module('ambariAdminConsole', [
   'ui.bootstrap',
   'ui.bootstrap',
   'restangular'
   'restangular'
 ])
 ])
+.constant('Settings',{
+	baseUrl: '/api/v1'
+})
 .config(['RestangularProvider', '$httpProvider', function(RestangularProvider, $httpProvider) {
 .config(['RestangularProvider', '$httpProvider', function(RestangularProvider, $httpProvider) {
   // Config Ajax-module
   // Config Ajax-module
   RestangularProvider.setBaseUrl('/api/v1');
   RestangularProvider.setBaseUrl('/api/v1');
@@ -29,4 +32,7 @@ angular.module('ambariAdminConsole', [
 
 
   $httpProvider.defaults.headers.post['Content-Type'] = 'plain/text';
   $httpProvider.defaults.headers.post['Content-Type'] = 'plain/text';
   $httpProvider.defaults.headers.put['Content-Type'] = 'plain/text';
   $httpProvider.defaults.headers.put['Content-Type'] = 'plain/text';
+  $httpProvider.defaults.headers.post['X-Requested-By'] = 'ambari';
+  $httpProvider.defaults.headers.put['X-Requested-By'] = 'ambari';
+  $httpProvider.defaults.headers.common['X-Requested-By'] = 'ambari';
 }]);
 }]);

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

@@ -42,7 +42,6 @@ angular.module('ambariAdminConsole')
     for(var i=0, max = obj.length; i < max; i++){
     for(var i=0, max = obj.length; i < max; i++){
       item = obj[i];
       item = obj[i];
       if(item != false && result.indexOf(item) < 0){
       if(item != false && result.indexOf(item) < 0){
-
         result.push(item);
         result.push(item);
       }
       }
     }
     }

+ 32 - 0
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsCreateCtrl.js

@@ -0,0 +1,32 @@
+/**
+ * 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('GroupsCreateCtrl',['$scope', 'Group', '$location', function($scope, Group, $location) {
+  $scope.group = new Group();
+
+  $scope.createGroup = function() {
+    $scope.form.submitted = true;
+    if ($scope.form.$valid){
+      $scope.group.save().then(function() {
+        $location.path('/groups');
+      });
+    }
+  };
+}]);

+ 59 - 0
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsEditCtrl.js

@@ -0,0 +1,59 @@
+/**
+ * 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('GroupsEditCtrl',['$scope', 'Group', '$routeParams', function($scope, Group, $routeParams) {
+  $scope.editMode = false;
+  $scope.group = new Group($routeParams.id);
+  $scope.group.editingUsers = "";
+
+    
+  $scope.group.getMembers();
+  
+  $scope.removeMember = function(member) {
+    $scope.group.removeMember(member).finally(function() {
+      $scope.group.getMembers();
+    });
+  };
+
+  $scope.toggleEditMode = function() {
+    $scope.editMode = !$scope.editMode;
+    if( $scope.editMode ){
+      $scope.group.editingUsers = $scope.group.members.join(', ');
+    } else {
+      var oldMembers = $scope.group.members;
+      $scope.group.members = [];
+      var members = $scope.group.editingUsers.split(',');
+      var member;
+      angular.forEach(members,function(member) {
+        if(member && $scope.group.members.indexOf(member) < 0){
+          $scope.group.members.push(member.trim());
+        }
+      });
+
+      if(!angular.equals(oldMembers, $scope.group.members)){
+        $scope.group.saveMembers().finally(function() {
+          $scope.group.getMembers();
+        });
+      }
+    }
+  };
+
+
+}]);

+ 15 - 1
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsListCtrl.js

@@ -18,5 +18,19 @@
 'use strict';
 'use strict';
 
 
 angular.module('ambariAdminConsole')
 angular.module('ambariAdminConsole')
-.controller('GroupsListCtrl',['$scope', function($scope) {
+.controller('GroupsListCtrl',['$scope', 'Group', function($scope, Group) {
+	$scope.groups = [];
+
+	Group.all().then(function(groups) {
+		$scope.groups = groups;	
+	})
+	.catch(function(data) {
+		console.error('Get groups list error');
+	});
+
+	$scope.deleteGroup = function(group) {
+		group.destroy().then(function() {
+			$scope.groups.splice( $scope.groups.indexOf(group), 1);
+		});
+	};
 }]);
 }]);

+ 2 - 2
ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js

@@ -54,8 +54,8 @@ angular.module('ambariAdminConsole')
     },
     },
     edit: {
     edit: {
       url: '/groups/:id/edit',
       url: '/groups/:id/edit',
-      templateUrl: 'views/groups/create.html',
-      controller: 'GroupsCreateCtrl'
+      templateUrl: 'views/groups/edit.html',
+      controller: 'GroupsEditCtrl'
     },
     },
     create: {
     create: {
       url: '/groups/new',
       url: '/groups/new',

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

@@ -0,0 +1,160 @@
+/**
+ * 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')
+.factory('Group', ['$http', '$q', 'Settings', function($http, $q, Settings) {
+  function Group(item){
+    if(typeof item === 'string'){
+      this.group_name = item;
+    } else if(typeof item === 'object'){
+      angular.extend(this, item.Groups);
+      this.getMembers();
+    }
+  }
+
+  Group.prototype.save = function() {
+    var deferred = $q.defer();
+
+    $http({
+      method : 'POST',
+      url: Settings.baseUrl + '/groups',
+      data:{
+        'Groups/group_name': this.group_name
+      }
+    })
+    .success(function(data) {
+      deferred.resolve();
+    })
+    .error(function(data) {
+      deferred.reject(data);
+    });
+
+    return deferred.promise;
+  };
+
+  Group.prototype.destroy = function() {
+    var deferred = $q.defer();
+    $http.delete(Settings.baseUrl + '/groups/' +this.group_name)
+    .success(function() {
+      deferred.resolve();
+    })
+    .error(function(data) {
+      deferred.reject(data);
+    });
+
+    return deferred.promise;
+  };
+
+  Group.prototype.getMembers = function() {
+    var deferred = $q.defer();
+    var self = this;
+
+    $http({
+      method: 'GET',
+      url: Settings.baseUrl + '/groups/' + this.group_name + '/members'
+    })
+    .success(function(data) {
+      self.members = [];
+      angular.forEach(data.items, function(member) {
+        self.members.push(member.MemberInfo.user_name);
+      });
+      deferred.resolve(self.members);
+    })
+    .error(function(data) {
+      deferred.reject(data);
+    });
+
+    return deferred.promise;
+  };
+
+  Group.prototype.saveMembers = function() {
+    var self = this;
+    var deferred = $q.defer();
+
+    var members = [];
+    angular.forEach(this.members, function(member) {
+      members.push({
+        'MemberInfo/user_name' : member,
+        'MemberInfo/group_name' : self.group_name
+      });
+    });
+
+    $http({
+      method: 'PUT',
+      url: Settings.baseUrl + '/groups/' + this.group_name + '/members',
+      data: members
+    })
+    .success(function(data) {
+      deferred.resolve(data);
+    })
+    .error(function(data) {
+      deferred.reject(data);
+    });
+    return deferred.promise;
+  }
+
+  Group.prototype.addMember = function(memberName) {
+    var deferred = $q.defer();
+
+    $http({
+      method: 'POST',
+      url: Settings.baseUrl + '/groups/' + this.group_name + '/members' + '/'+ member.user_name
+    })
+    .success(function(data) {
+      deferred.resolve(data)
+    })
+    .error(function(data) {
+      deferred.reject(data);
+    });
+
+    return deferred.promise;
+  };
+
+  Group.prototype.removeMember = function(memberId) {
+    return $http.delete(Settings.baseUrl + '/groups/'+this.group_name+'/members/'+memberId);
+  };
+
+  Group.all = function() {
+    var deferred = $q.defer();
+
+    $http({
+      method: 'GET',
+      url: Settings.baseUrl + '/groups',
+      params: {
+        'fields': 'Groups/ldap_group'
+      }
+    })
+    .success(function(data) {
+      var groups = [];
+      if(Array.isArray(data.items)){
+        angular.forEach(data.items, function(item) {
+          groups.push(new Group(item));
+        });
+      }
+      deferred.resolve(groups);
+    })
+    .error(function(data) {
+      deferred.reject(data);
+    });
+
+    return deferred.promise;
+  };
+
+  return Group;
+}]);

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

@@ -75,4 +75,12 @@ table.no-border tr td{
 .views-list-pane .panel-body table tbody td{
 .views-list-pane .panel-body table tbody td{
   border-top: none;
   border-top: none;
   vertical-align: middle;
   vertical-align: middle;
+}
+
+.group-edit .users button.close{
+  float: none;
+  -webkit-transform: translateY(1px);
+  -ms-transform: translateY(1px);
+  -o-transform: translateY(1px);
+  transform: translateY(1px);
 }
 }

+ 36 - 0
ambari-admin/src/main/resources/ui/admin-web/app/views/groups/create.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.
+-->
+<h2>Create local group</h2>
+<hr>
+<form class="form-horizontal" role="form" novalidate name="form">
+  <div class="form-group" ng-class="{'has-error' : form.user_name.$error.required && form.submitted}">
+    <label for="groupname" class="col-sm-2 control-label">Group name:</label>
+    <div class="col-sm-10">
+      <input type="text" id="groupname" class="form-control" name="group_name" placeholder="User name" ng-model="group.group_name" required>
+      <div class="alert alert-danger top-margin" ng-show="form.group_name.$error.required && form.submitted">
+        Required
+      </div>
+    </div>
+  </div>
+  <div class="form-group">
+    <div class="col-sm-offset-2 col-sm-10">
+      <button class="btn btn-primary" ng-click="createGroup()">Create</button>
+    </div>
+  </div>
+      
+</form>

+ 50 - 0
ambari-admin/src/main/resources/ui/admin-web/app/views/groups/edit.html

@@ -0,0 +1,50 @@
+<!--
+* 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.
+-->
+<h2>Edit {{group.group_name}}</h2>
+<hr>
+<form class="form-horizontal group-edit" role="form" novalidate name="form">
+  <div class="form-group" ng-class="{'has-error' : form.user_name.$error.required && form.submitted}">
+    <label for="groupname" class="col-sm-2 control-label">Group name:</label>
+    <div class="col-sm-10">
+      <input type="text" id="groupname" class="form-control" disabled="disabled" name="group_name" placeholder="User name" ng-model="group.group_name" required>
+    </div>
+  </div>
+  <div class="form-group">
+    <label for="" class="col-sm-2 control-label">Users</label>
+    <div class="col-sm-10">
+      <div ng-switch="editMode">
+        <div class="well users" ng-switch-when="false">
+          <span ng-repeat="member in group.members" >
+            <link-to route='users.show' id="{{member}}">
+              {{member}}
+            </link-to>
+            <button type="button" class="close" ng-click="removeMember(member)"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
+            {{$last ? '' : ', '}}
+          </span>
+        </div>
+        <div ng-switch-when="true">
+          <textarea class="form-control bottom-margin" id=""  ng-model="group.editingUsers"></textarea>
+        </div>
+        
+      </div>
+        
+
+      <button class="btn btn-primary pull-right" ng-click="toggleEditMode()"><span class="glyphicon {{editMode ? 'glyphicon-save' : 'glyphicon-pencil'}}"></span> {{editMode ? 'Save': 'Edit'}}</button>
+    </div>
+  </div>
+</form>

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

@@ -19,7 +19,7 @@
   <div class="clearfix">
   <div class="clearfix">
     <h3 class="pull-left">Groups management</h3>
     <h3 class="pull-left">Groups management</h3>
     <div class="pull-right top-buffer">
     <div class="pull-right top-buffer">
-      <a href="#{{ROUTES.groups.new}}" class="btn btn-primary"><span class="glyphicon glyphicon-plus"></span> Create Local Group</a>
+      <link-to route="groups.create" class="btn btn-primary"><span class="glyphicon glyphicon-plus"></span> Create Local Group</link-to>
       <button class="btn btn-default ">Sync LDAP</button>
       <button class="btn btn-default ">Sync LDAP</button>
     </div>
     </div>
   </div>
   </div>
@@ -34,25 +34,12 @@
       </tr>
       </tr>
     </thead>
     </thead>
     <tbody>
     <tbody>
-      <tr>
-        <td>operators</td>
-        <td>Local</td>
-        <td>
-          <ul>
-            <li>v 2 members</li>
-            <li>admin</li>
-            <li>usaku</li>
-          </ul>
-        </td>
+      <tr ng-repeat="group in groups">
+        <td>{{group.group_name}}</td>
+        <td>{{group.ldap_group ? 'LDAP' : 'Local'}}</td>
+        <td>{{group.members.length}} {{group.members.length === 1 ? 'member' : 'members'}}</td>
         <td>
         <td>
-          <a href="" class="btn btn-default">edit</a> <a href="" class="btn btn-danger">delete</a>
-        </td>
-      </tr>
-      <tr>
-        <td>sysadmins</td>
-        <td>LDAP</td>
-        <td>> 20 members</td>
-        <td><a href="" class="btn btn-default">edit</a> <a href="" class="btn btn-danger">delete</a></td>
+          <link-to route="groups.edit" id="{{group.group_name}}"class="btn btn-default">Edit</link-to> <a href class="btn btn-danger" ng-click="deleteGroup(group)">delete</a></td>
       </tr>
       </tr>
     </tbody>
     </tbody>
   </table>
   </table>

+ 1 - 1
ambari-web/app/templates/application.hbs

@@ -49,10 +49,10 @@
               </button>
               </button>
               <ul class="dropdown-menu">
               <ul class="dropdown-menu">
                   <li><a href="" {{action showAboutPopup target="controller"}}>{{t app.aboutAmbari}}</a></li>
                   <li><a href="" {{action showAboutPopup target="controller"}}>{{t app.aboutAmbari}}</a></li>
+                  <li><a href="/views/ADMIN_VIEW/1.0.0/INSTANCE/#/">{{t app.manageAmbari}}</a></li>
                 {{#if isClusterDataLoaded}}
                 {{#if isClusterDataLoaded}}
                   {{#if App.isAdmin}}
                   {{#if App.isAdmin}}
                       <li><a href="" {{action showSettingsPopup target="controller"}}>{{t app.settings}}</a></li>
                       <li><a href="" {{action showSettingsPopup target="controller"}}>{{t app.settings}}</a></li>
-                      <li><a href="/views/ADMIN_VIEW/1.0.0/INSTANCE/#/">{{t app.manageAmbari}}</a></li>
                   {{/if}}
                   {{/if}}
                 {{/if}}
                 {{/if}}
                   <li class="break"></li>
                   <li class="break"></li>