nifi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bbe...@apache.org
Subject [3/4] nifi-registry git commit: NIFIREG-30 - Add login component, auth guard to login, tenants, buckets, admin, and explorer routes. Also added route for login component.
Date Fri, 15 Dec 2017 20:13:08 GMT
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.js
new file mode 100644
index 0000000..75f2385
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.js
@@ -0,0 +1,234 @@
+/*
+ * 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.
+ */
+
+var covalentCore = require('@covalent/core');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var ngCore = require('@angular/core');
+var fdsSnackBarsModule = require('@fluid-design-system/snackbars');
+var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var ngMaterial = require('@angular/material');
+var $ = require('jquery');
+
+/**
+ * NfRegistryAddUsersToGroup constructor.
+ *
+ * @param nfRegistryApi         The api service.
+ * @param tdDataTableService    The covalent data table service module.
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param matDialogRef          The angular material dialog ref.
+ * @param fdsSnackBarService    The FDS snack bar service module.
+ * @param data                  The data passed into this component.
+ * @constructor
+ */
+function NfRegistryAddUsersToGroup(nfRegistryApi, tdDataTableService, nfRegistryService, matDialogRef, fdsSnackBarService, data) {
+    this.dataTableService = tdDataTableService;
+    this.snackBarService = fdsSnackBarService;
+    this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
+    this.dialogRef = matDialogRef;
+    this.data = data;
+    //make an independent copy of the users for sorting and selecting within the scope of this component
+    this.users = $.extend(true, [], this.nfRegistryService.users);
+    this.filteredUsers = [];
+    this.isAddSelectedUsersToGroupDisabled = true;
+    this.usersSearchTerms = [];
+    this.allUsersSelected = false;
+};
+
+NfRegistryAddUsersToGroup.prototype = {
+    constructor: NfRegistryAddUsersToGroup,
+
+    /**
+     * Initialize the component.
+     */
+    ngOnInit: function () {
+        var self = this;
+
+        this.data.group.users.forEach(function (groupUser) {
+            self.users = self.users.filter(function (user) {
+                return (user.identifier !== groupUser.identifier) ? true : false
+            });
+        });
+
+        this.filterUsers();
+        this.determineAllUsersSelectedState();
+    },
+
+    /**
+     * Filter users.
+     *
+     * @param {string} [sortBy]       The column name to sort `userGroupsColumns` by.
+     * @param {string} [sortOrder]    The order. Either 'ASC' or 'DES'
+     */
+    filterUsers: function (sortBy, sortOrder) {
+        // if `sortOrder` is `undefined` then use 'ASC'
+        if (sortOrder === undefined) {
+            sortOrder = 'ASC'
+        }
+        // if `sortBy` is `undefined` then find the first sortable column in `dropletColumns`
+        if (sortBy === undefined) {
+            var arrayLength = this.nfRegistryService.userGroupsColumns.length;
+            for (var i = 0; i < arrayLength; i++) {
+                if (this.nfRegistryService.userGroupsColumns[i].sortable === true) {
+                    sortBy = this.nfRegistryService.userGroupsColumns[i].name;
+                    //only one column can be actively sorted so we reset all to inactive
+                    this.nfRegistryService.userGroupsColumns.forEach(function (c) {
+                        c.active = false;
+                    });
+                    //and set this column as the actively sorted column
+                    this.nfRegistryService.userGroupsColumns[i].active = true;
+                    this.nfRegistryService.userGroupsColumns[i].sortOrder = sortOrder;
+                    break;
+                }
+            }
+        }
+
+        var newUsersData = this.users;
+
+        for (var i = 0; i < this.usersSearchTerms.length; i++) {
+            newUsersData = this.nfRegistryService.filterData(newUsersData, this.usersSearchTerms[i], true);
+        }
+
+        newUsersData = this.dataTableService.sortData(newUsersData, sortBy, sortOrder);
+        this.filteredUsers = newUsersData;
+    },
+
+    /**
+     * Sort `filteredUsers` by `column`.
+     *
+     * @param column    The column to sort by.
+     */
+    sortUsers: function (column) {
+        if (column.sortable) {
+            var sortBy = column.name;
+            var sortOrder = column.sortOrder = (column.sortOrder === 'ASC') ? 'DESC' : 'ASC';
+            this.filterUsers(sortBy, sortOrder);
+        }
+    },
+
+    /**
+     * Checks the `allUsersSelected` property state and either selects
+     * or deselects each of the `filteredUsers`.
+     */
+    toggleUsersSelectAll: function () {
+        if (this.allUsersSelected) {
+            this.selectAllUsers();
+        } else {
+            this.deselectAllUsers();
+        }
+    },
+
+    /**
+     * Sets the `checked` property of each of the `filteredUsers` to true
+     * and sets the `isAddSelectedUsersToGroupDisabled` and the `allUsersSelected`
+     * properties accordingly.
+     */
+    selectAllUsers: function () {
+        this.filteredUsers.forEach(function (c) {
+            c.checked = true;
+        });
+        this.isAddSelectedUsersToGroupDisabled = false;
+        this.allUsersSelected = true;
+    },
+
+    /**
+     * Sets the `checked` property of each group to false
+     * and sets the `isAddSelectedUsersToGroupDisabled` and the `allUsersSelected`
+     * properties accordingly.
+     */
+    deselectAllUsers: function () {
+        this.filteredUsers.forEach(function (c) {
+            c.checked = false;
+        });
+        this.isAddSelectedUsersToGroupDisabled = true;
+        this.allUsersSelected = false;
+    },
+
+    /**
+     * Checks of each of the `filteredUsers`'s checked property state
+     * and sets the `allBucketsSelected` and `isAddSelectedUsersToGroupDisabled`
+     * property accordingly.
+     */
+    determineAllUsersSelectedState: function () {
+        var selected = 0;
+        var allSelected = true;
+        this.filteredUsers.forEach(function (c) {
+            if (c.checked) {
+                selected++;
+            }
+            if (c.checked === undefined || c.checked === false) {
+                allSelected = false;
+            }
+        });
+
+        if (selected > 0) {
+            this.isAddSelectedUsersToGroupDisabled = false;
+        } else {
+            this.isAddSelectedUsersToGroupDisabled = true;
+        }
+
+        this.allUsersSelected = allSelected;
+    },
+
+    /**
+     * Adds each of the selected users to this group.
+     */
+    addSelectedUsersToGroup: function () {
+        var self = this;
+        this.filteredUsers.filter(function (filteredUser) {
+            if(filteredUser.checked) {
+                self.data.group.users.push(filteredUser);
+            }
+        });
+        this.nfRegistryApi.updateUserGroup(self.data.group.identifier, self.data.group.identity, self.data.group.users).subscribe(function (group) {
+            self.dialogRef.close();
+            var snackBarRef = self.snackBarService.openCoaster({
+                title: 'Success',
+                message: 'Selected users have been added to the ' + self.data.group.identity + ' group.',
+                verticalPosition: 'bottom',
+                horizontalPosition: 'right',
+                icon: 'fa fa-check-circle-o',
+                color: '#1EB475',
+                duration: 3000
+            });
+        });
+    },
+
+    /**
+     * Cancel adding selected users to groups and close the dialog.
+     */
+    cancel: function () {
+        this.dialogRef.close();
+    }
+};
+
+NfRegistryAddUsersToGroup.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-add-users-to-group.html!text')
+    })
+];
+
+NfRegistryAddUsersToGroup.parameters = [
+    NfRegistryApi,
+    covalentCore.TdDataTableService,
+    NfRegistryService,
+    ngMaterial.MatDialogRef,
+    fdsSnackBarsModule.FdsSnackBarService,
+    ngMaterial.MAT_DIALOG_DATA
+];
+
+module.exports = NfRegistryAddUsersToGroup;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.spec.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.spec.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.spec.js
new file mode 100644
index 0000000..d8e41cb
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.spec.js
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var NfRegistryAddUsersToGroup = require('nifi-registry/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.js');
+var rxjs = require('rxjs/Rx');
+var covalentCore = require('@covalent/core');
+var fdsSnackBarsModule = require('@fluid-design-system/snackbars');
+
+describe('NfRegistryAddUsersToGroup Component isolated unit tests', function () {
+    var comp;
+    var nfRegistryService;
+    var nfRegistryApi;
+    var snackBarService;
+    var dataTableService;
+
+    beforeEach(function () {
+        nfRegistryService = new NfRegistryService();
+        // setup the nfRegistryService
+        nfRegistryService.group = {identifier: 1, identity: 'Group 1', users: []};
+        nfRegistryService.users = [{identifier: 2, identity: 'User 1', checked: true}];
+
+        nfRegistryApi = new NfRegistryApi();
+        snackBarService = new fdsSnackBarsModule.FdsSnackBarService();
+        dataTableService = new covalentCore.TdDataTableService();
+        comp = new NfRegistryAddUsersToGroup(nfRegistryApi, dataTableService, nfRegistryService, {
+            close: function () {
+            }
+        }, snackBarService, {group: nfRegistryService.group});
+
+        // Spy
+        spyOn(nfRegistryApi, 'updateUserGroup').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of({identifier: 1, identity: 'Group 1'}));
+        spyOn(comp.dialogRef, 'close');
+        spyOn(comp.snackBarService, 'openCoaster');
+        spyOn(comp, 'filterUsers').and.callThrough();
+
+        // initialize the component
+        comp.ngOnInit();
+
+        //assertions
+        expect(comp.filterUsers).toHaveBeenCalled();
+        expect(comp.filteredUsers[0].identity).toEqual('User 1');
+        expect(comp.filteredUsers.length).toBe(1);
+        expect(comp).toBeDefined();
+    });
+
+    it('should make a call to the api to add selected users to the group', function () {
+        // select a group
+        comp.filteredUsers[0].checked = true;
+
+        // the function to test
+        comp.addSelectedUsersToGroup();
+
+        //assertions
+        expect(comp.dialogRef.close).toHaveBeenCalled();
+        expect(comp.snackBarService.openCoaster).toHaveBeenCalled();
+    });
+
+    it('should determine if all users are selected', function () {
+        // select a group
+        comp.filteredUsers[0].checked = true;
+
+        // the function to test
+        comp.determineAllUsersSelectedState();
+
+        //assertions
+        expect(comp.allUsersSelected).toBe(true);
+        expect(comp.isAddSelectedUsersToGroupDisabled).toBe(false);
+    });
+
+    it('should determine all user groups are not selected', function () {
+        // select a group
+        comp.filteredUsers[0].checked = false;
+
+        // the function to test
+        comp.determineAllUsersSelectedState();
+
+        //assertions
+        expect(comp.allUsersSelected).toBe(false);
+        expect(comp.isAddSelectedUsersToGroupDisabled).toBe(true);
+    });
+
+    it('should select all groups.', function () {
+        // The function to test
+        comp.selectAllUsers();
+
+        //assertions
+        expect(comp.filteredUsers[0].checked).toBe(true);
+        expect(comp.isAddSelectedUsersToGroupDisabled).toBe(false);
+        expect(comp.allUsersSelected).toBe(true);
+    });
+
+    it('should deselect all groups.', function () {
+        // select a group
+        comp.filteredUsers[0].checked = true;
+
+        // The function to test
+        comp.deselectAllUsers();
+
+        //assertions
+        expect(comp.filteredUsers[0].checked).toBe(false);
+        expect(comp.isAddSelectedUsersToGroupDisabled).toBe(true);
+        expect(comp.allUsersSelected).toBe(false);
+    });
+
+    it('should toggle all groups `checked` properties to true.', function () {
+        //Spy
+        spyOn(comp, 'selectAllUsers').and.callFake(function () {
+        });
+
+        comp.allUsersSelected = true;
+
+        // The function to test
+        comp.toggleUsersSelectAll();
+
+        //assertions
+        expect(comp.selectAllUsers).toHaveBeenCalled();
+    });
+
+    it('should toggle all groups `checked` properties to false.', function () {
+        //Spy
+        spyOn(comp, 'deselectAllUsers').and.callFake(function () {
+        });
+
+        comp.allUsersSelected = false;
+
+        // The function to test
+        comp.toggleUsersSelectAll();
+
+        //assertions
+        expect(comp.deselectAllUsers).toHaveBeenCalled();
+    });
+
+    it('should sort `groups` by `column`', function () {
+        // object to be updated by the test
+        var column = {name: 'name', label: 'Group Name', sortable: true};
+
+        // The function to test
+        comp.sortUsers(column);
+
+        //assertions
+        var filterUsersCall = comp.filterUsers.calls.mostRecent();
+        expect(filterUsersCall.args[0]).toBe('name');
+        expect(filterUsersCall.args[1]).toBe('ASC');
+    });
+
+    it('should cancel the creation of a new user', function () {
+        // the function to test
+        comp.cancel();
+
+        //assertions
+        expect(comp.dialogRef.close).toHaveBeenCalled();
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.html b/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.html
index b7fe21c..59e8cfd 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.html
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.html
@@ -40,10 +40,6 @@ limitations under the License.
                     (click)="createNewGroup()">
                 <span>Create new group</span>
             </button>
-            <button mat-menu-item [disabled]="nfRegistryService.getSelectedGroups().length > 0 || nfRegistryService.getSelectedUsers().length === 0 || nfRegistryService.groups.length === 0"
-                    (click)="addSelectedUsersToGroup()">
-                <span>Add selected users to group</span>
-            </button>
         </mat-menu>
         <div id="nifi-registry-users-administration-list-container-column-header" fxLayout="row"
              fxLayoutAlign="space-between center" class="td-data-table">
@@ -75,9 +71,9 @@ limitations under the License.
                     </div>
                     <div class="td-data-table-cell">
                         <div>
-                            <div *ngIf="userGroupsActions.length <= 4" fxLayout="row" fxLayoutAlign="end center">
+                            <div *ngIf="nfRegistryService.userGroupsActions.length <= 4" fxLayout="row" fxLayoutAlign="end center">
                                 <button (click)="row.checked = !row.checked;nfRegistryService.executeGroupAction(action, row)"
-                                        *ngFor="let action of userGroupsActions"
+                                        *ngFor="let action of nfRegistryService.userGroupsActions"
                                         matTooltip="{{action.tooltip}}" mat-icon-button color="accent"
                                         [disabled]="action.disabled ? '' : null">
                                     <i class="{{action.icon}}" aria-hidden="true"></i>
@@ -86,14 +82,14 @@ limitations under the License.
                                               (change)="nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"
                                               (click)="row.checked = !row.checked;nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"></mat-checkbox>
                             </div>
-                            <div *ngIf="userGroupsActions.length > 4" fxLayout="row" fxLayoutAlign="end center">
+                            <div *ngIf="nfRegistryService.userGroupsActions.length > 4" fxLayout="row" fxLayoutAlign="end center">
                                 <button (click)="row.checked = !row.checked" matTooltip="Actions" mat-icon-button
                                         [matMenuTriggerFor]="userTableActionMenu">
                                     <i class="fa fa-ellipsis-h" aria-hidden="true"></i>
                                 </button>
                                 <mat-menu #userTableActionMenu="matMenu" [overlapTrigger]="false">
                                     <button (click)="nfRegistryService.executeGroupAction(action, row)"
-                                            *ngFor="let action of userGroupsActions"
+                                            *ngFor="let action of nfRegistryService.userGroupsActions"
                                             matTooltip="{{action.tooltip}}" mat-menu-item
                                             [disabled]="action.disabled ? '' : null"
                                             (click)="nfRegistryService.sidenav.toggle()">
@@ -106,7 +102,7 @@ limitations under the License.
                                               (click)="row.checked = !row.checked;nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"></mat-checkbox>
                             </div>
                         </div>
-                        <div *ngIf="!userGroupsActions" fxLayout="row" fxLayoutAlign="end center">
+                        <div *ngIf="!nfRegistryService.userGroupsActions" fxLayout="row" fxLayoutAlign="end center">
                             <mat-checkbox class="pad-left-sm" [(ngModel)]="row.checked" [checked]="row.checked"
                                           (change)="nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"
                                           (click)="row.checked = !row.checked;nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"></mat-checkbox>
@@ -124,9 +120,9 @@ limitations under the License.
                     </div>
                     <div class="td-data-table-cell">
                         <div>
-                            <div *ngIf="usersActions.length <= 4" fxLayout="row" fxLayoutAlign="end center">
+                            <div *ngIf="nfRegistryService.usersActions.length <= 4" fxLayout="row" fxLayoutAlign="end center">
                                 <button (click)="row.checked = !row.checked;nfRegistryService.executeUserAction(action, row)"
-                                        *ngFor="let action of usersActions"
+                                        *ngFor="let action of nfRegistryService.usersActions"
                                         matTooltip="{{action.tooltip}}" mat-icon-button color="accent"
                                         [disabled]="action.disabled ? '' : null">
                                     <i class="{{action.icon}}" aria-hidden="true"></i>
@@ -135,14 +131,14 @@ limitations under the License.
                                               (change)="nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"
                                               (click)="row.checked = !row.checked;nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"></mat-checkbox>
                             </div>
-                            <div *ngIf="usersActions.length > 4" fxLayout="row" fxLayoutAlign="end center">
+                            <div *ngIf="nfRegistryService.usersActions.length > 4" fxLayout="row" fxLayoutAlign="end center">
                                 <button (click)="row.checked = !row.checked" matTooltip="Actions" mat-icon-button
                                         [matMenuTriggerFor]="userTableActionMenu">
                                     <i class="fa fa-ellipsis-h" aria-hidden="true"></i>
                                 </button>
                                 <mat-menu #userTableActionMenu="matMenu" [overlapTrigger]="false">
                                     <button (click)="nfRegistryService.executeUserAction(action, row)"
-                                            *ngFor="let action of usersActions"
+                                            *ngFor="let action of nfRegistryService.usersActions"
                                             matTooltip="{{action.tooltip}}" mat-menu-item
                                             [disabled]="action.disabled ? '' : null"
                                             (click)="nfRegistryService.sidenav.toggle()">
@@ -155,7 +151,7 @@ limitations under the License.
                                               (click)="row.checked = !row.checked;nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"></mat-checkbox>
                             </div>
                         </div>
-                        <div *ngIf="!usersActions" fxLayout="row" fxLayoutAlign="end center">
+                        <div *ngIf="!nfRegistryService.usersActions" fxLayout="row" fxLayoutAlign="end center">
                             <mat-checkbox class="pad-left-sm" [(ngModel)]="row.checked" [checked]="row.checked"
                                           (change)="nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"
                                           (click)="row.checked = !row.checked;nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"></mat-checkbox>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.js
index 1fdef66..2cc8ff1 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.js
@@ -25,7 +25,6 @@ var ngMaterial = require('@angular/material');
 var fdsDialogsModule = require('@fluid-design-system/dialogs');
 var NfRegistryAddUser = require('nifi-registry/components/administration/users/dialogs/add-user/nf-registry-add-user.js');
 var NfRegistryCreateNewGroup = require('nifi-registry/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.js');
-var NfRegistryAddSelectedUsersToGroup = require('nifi-registry/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.js');
 
 /**
  * NfRegistryUsersAdministration constructor.
@@ -45,26 +44,6 @@ function NfRegistryUsersAdministration(nfRegistryApi, nfStorage, nfRegistryServi
     this.nfRegistryApi = nfRegistryApi;
     this.dialogService = fdsDialogService;
     this.dialog = matDialog;
-    this.usersActions = [{
-        name: 'permissions',
-        icon: 'fa fa-pencil',
-        tooltip: 'Manage User Policies',
-        type: 'sidenav'
-    }, {
-        name: 'Delete',
-        icon: 'fa fa-trash',
-        tooltip: 'Delete User'
-    }];
-    this.userGroupsActions = [{
-        name: 'permissions',
-        icon: 'fa fa-pencil',
-        tooltip: 'Manage User Group Policies',
-        type: 'sidenav'
-    }, {
-        name: 'Delete',
-        icon: 'fa fa-trash',
-        tooltip: 'Delete User Group'
-    }];
 };
 
 NfRegistryUsersAdministration.prototype = {
@@ -76,27 +55,22 @@ NfRegistryUsersAdministration.prototype = {
     ngOnInit: function () {
         var self = this;
         this.nfRegistryService.inProgress = true;
-        // attempt kerberos authentication
-        this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
-            self.nfRegistryService.loadCurrentUser().subscribe(function (currentUser) {
-                self.route.params
-                    .switchMap(function (params) {
-                        self.nfRegistryService.adminPerspective = 'users';
-                        return new rxjs.Observable.forkJoin(
-                            self.nfRegistryApi.getUsers(),
-                            self.nfRegistryApi.getUserGroups()
-                        );
-                    })
-                    .subscribe(function (response) {
-                        var users = response[0];
-                        var groups = response[1];
-                        self.nfRegistryService.users = users;
-                        self.nfRegistryService.groups = groups;
-                        self.nfRegistryService.filterUsersAndGroups();
-                        self.nfRegistryService.inProgress = false;
-                    });
+        this.route.params
+            .switchMap(function (params) {
+                self.nfRegistryService.adminPerspective = 'users';
+                return new rxjs.Observable.forkJoin(
+                    self.nfRegistryApi.getUsers(),
+                    self.nfRegistryApi.getUserGroups()
+                );
+            })
+            .subscribe(function (response) {
+                var users = response[0];
+                var groups = response[1];
+                self.nfRegistryService.users = users;
+                self.nfRegistryService.groups = groups;
+                self.nfRegistryService.filterUsersAndGroups();
+                self.nfRegistryService.inProgress = false;
             });
-        });
     },
 
     /**
@@ -121,23 +95,6 @@ NfRegistryUsersAdministration.prototype = {
      */
     createNewGroup: function () {
         this.dialog.open(NfRegistryCreateNewGroup);
-    },
-
-    /**
-     * Opens the add selected users to groups dialog.
-     */
-    addSelectedUsersToGroup: function () {
-        if (this.nfRegistryService.getSelectedGroups().length === 0) {
-            // ok...only users are currently selected...go ahead and open the dialog to select groups
-            this.dialog.open(NfRegistryAddSelectedUsersToGroup);
-        } else {
-            self.dialogService.openConfirm({
-                title: 'Error: Groups may not be added to a group. Please deselect any groups and try again',
-                message: error.message,
-                acceptButton: 'Ok',
-                acceptButtonColor: 'fds-warn'
-            });
-        }
     }
 };
 

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-adminstration.spec.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-adminstration.spec.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-adminstration.spec.js
index 80fd245..9260dc3 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-adminstration.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-adminstration.spec.js
@@ -30,9 +30,8 @@ var NfRegistryExplorer = require('nifi-registry/components/explorer/nf-registry-
 var NfRegistryAdministration = require('nifi-registry/components/administration/nf-registry-administration.js');
 var NfRegistryUsersAdministration = require('nifi-registry/components/administration/users/nf-registry-users-administration.js');
 var NfRegistryAddUser = require('nifi-registry/components/administration/users/dialogs/add-user/nf-registry-add-user.js');
-var NfRegistryUserDetails = require('nifi-registry/components/administration/users/details/nf-registry-user-details.js');
-var NfRegistryUserPermissions = require('nifi-registry/components/administration/users/permissions/nf-registry-user-permissions.js');
-var NfRegistryUserGroupPermissions = require('nifi-registry/components/administration/user-group/permissions/nf-registry-user-group-permissions.js');
+var NfRegistryManageUser = require('nifi-registry/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js');
+var NfRegistryManageGroup = require('nifi-registry/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js');
 var NfRegistryBucketPermissions = require('nifi-registry/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js');
 var NfRegistryWorkflowAdministration = require('nifi-registry/components/administration/workflow/nf-registry-workflow-administration.js');
 var NfRegistryCreateBucket = require('nifi-registry/components/administration/workflow/dialogs/nf-registry-create-bucket.js');
@@ -46,6 +45,8 @@ var ngCommonHttp = require('@angular/common/http');
 var NfRegistryTokenInterceptor = require('nifi-registry/services/nf-registry.token.interceptor.js');
 var NfRegistryAuthService = require('nifi-registry/services/nf-registry.auth.service.js');
 var NfStorage = require('nifi-registry/services/nf-storage.service.js');
+var NfLoginComponent = require('nifi-registry/components/login/nf-registry-login.js');
+var NfUserLoginComponent = require('nifi-registry/components/login/dialogs/nf-registry-user-login.js');
 
 describe('NfRegistryUsersAdministration Component', function () {
     var comp;
@@ -70,9 +71,8 @@ describe('NfRegistryUsersAdministration Component', function () {
                 NfRegistryExplorer,
                 NfRegistryAdministration,
                 NfRegistryUsersAdministration,
-                NfRegistryUserDetails,
-                NfRegistryUserPermissions,
-                NfRegistryUserGroupPermissions,
+                NfRegistryManageUser,
+                NfRegistryManageGroup,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
@@ -80,7 +80,9 @@ describe('NfRegistryUsersAdministration Component', function () {
                 NfRegistryGridListViewer,
                 NfRegistryBucketGridListViewer,
                 NfRegistryDropletGridListViewer,
-                NfPageNotFoundComponent
+                NfPageNotFoundComponent,
+                NfLoginComponent,
+                NfUserLoginComponent
             ],
             entryComponents: [
                 NfRegistryCreateBucket
@@ -173,17 +175,6 @@ describe('NfRegistryUsersAdministration Component', function () {
         expect(comp.dialog.open).toHaveBeenCalled();
     });
 
-    it('should open a dialog to add selected users to groups', function () {
-        spyOn(comp.dialog, 'open')
-        fixture.detectChanges();
-
-        // the function to test
-        comp.addSelectedUsersToGroup();
-
-        //assertions
-        expect(comp.dialog.open).toHaveBeenCalled();
-    });
-
     it('should destroy the component', ngCoreTesting.fakeAsync(function () {
         fixture.detectChanges();
         // wait for async getBucket call

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/administration/users/permissions/nf-registry-user-permissions.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/permissions/nf-registry-user-permissions.html b/nifi-registry-web-ui/src/main/webapp/components/administration/users/permissions/nf-registry-user-permissions.html
deleted file mode 100644
index 2069e3c..0000000
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/users/permissions/nf-registry-user-permissions.html
+++ /dev/null
@@ -1,28 +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 fxFill>
-    <div fxLayout="row" fxLayoutAlign="space-between center" class="pad-top-sm pad-bottom-md pad-left-md pad-right-md">
-        <span class="md-card-title">{{nfRegistryService.user.identity}}</span>
-        <button mat-icon-button (click)="closeSideNav()">
-            <mat-icon color="primary">close</mat-icon>
-        </button>
-    </div>
-    <button id="nf-registry-user-permissions-side-nav-container" class="push-right-md" mat-raised-button color="fds-primary"
-            (click)="closeSideNav()">Close
-    </button>
-</div>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/administration/users/permissions/nf-registry-user-permissions.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/permissions/nf-registry-user-permissions.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/permissions/nf-registry-user-permissions.js
deleted file mode 100644
index cb6d17c..0000000
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/users/permissions/nf-registry-user-permissions.js
+++ /dev/null
@@ -1,69 +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.
- */
-var ngCore = require('@angular/core');
-var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
-var ngRouter = require('@angular/router');
-
-/**
- * NfRegistryUserPermissions constructor.
- *
- * @param nfRegistryService     The nf-registry.service module.
- * @param Router                The angular router module.
- * @constructor
- */
-function NfRegistryUserPermissions(nfRegistryService, Router) {
-    this.nfRegistryService = nfRegistryService;
-    this.router = Router;
-};
-
-NfRegistryUserPermissions.prototype = {
-    constructor: NfRegistryUserPermissions,
-
-    /**
-     * Initialize the component.
-     */
-    ngOnInit: function () {
-        this.nfRegistryService.sidenav.open();
-    },
-
-    /**
-     * Destroy the component.
-     */
-    ngOnDestroy: function () {
-        this.nfRegistryService.sidenav.close();
-    },
-
-    /**
-     * Navigate to administer users for current registry.
-     */
-    closeSideNav: function () {
-        this.router.navigateByUrl('/nifi-registry/administration/users');
-    }
-};
-
-NfRegistryUserPermissions.annotations = [
-    new ngCore.Component({
-        template: require('./nf-registry-user-permissions.html!text')
-    })
-];
-
-NfRegistryUserPermissions.parameters = [
-    NfRegistryService,
-    ngRouter.Router
-];
-
-module.exports = NfRegistryUserPermissions;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.html b/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.html
new file mode 100644
index 0000000..f9e2138
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.html
@@ -0,0 +1,154 @@
+<!--
+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 fxFill>
+    <div fxLayout="row" fxLayoutAlign="space-between center" class="pad-top-sm pad-bottom-md pad-left-md pad-right-md">
+        <span class="md-card-title">{{nfRegistryService.group.identity}}</span>
+        <button mat-icon-button (click)="closeSideNav()">
+            <mat-icon color="primary">close</mat-icon>
+        </button>
+    </div>
+    <div class="pad-bottom-md pad-left-md pad-right-md" flex fxLayoutAlign="start center">
+        <mat-input-container flex>
+            <input #groupnameInput matInput [disabled]="!nfRegistryService.currentUser.resourcePermissions.tenants.canWrite" placeholder="Identity/Group Name" value="{{nfRegistryService.group.identity}}"
+                   [(ngModel)]="_groupname">
+        </mat-input-container>
+        <button [disabled]="nfRegistryService.group.identity === _groupname"
+                (click)="updateGroupName(groupnameInput.value)"
+                class="input-button"
+                color="fds-regular"
+                mat-raised-button>
+            Save
+        </button>
+    </div>
+    <div class="pad-bottom-md pad-left-md pad-right-md" flex fxLayout="column" fxLayoutAlign="space-between start">
+        <div>
+            <span class="header">Special Privileges
+                <i matTooltip="Allows a group to manage NiFi Registry users and groups, buckets, proxies, and policies."
+                   class="pad-left-sm fa fa-question-circle-o help-icon"></i>
+            </span>
+        </div>
+        <mat-checkbox [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [checked]="nfRegistryService.group.resourcePermissions.buckets.canRead && nfRegistryService.group.resourcePermissions.buckets.canWrite && nfRegistryService.group.resourcePermissions.buckets.canDelete" (change)="toggleGroupManageBucketsPrivileges($event)">
+            <span class="description">Can manage buckets</span>
+        </mat-checkbox>
+        <div flex fxLayout="row" fxLayoutAlign="space-around center">
+            <mat-checkbox class="pad-left-md" [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [(checked)]="nfRegistryService.group.resourcePermissions.buckets.canRead" (change)="toggleGroupManageBucketsPrivileges($event, 'read')">
+                <span class="description">Read</span>
+            </mat-checkbox>
+            <mat-checkbox class="pad-left-md" [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [(checked)]="nfRegistryService.group.resourcePermissions.buckets.canWrite" (change)="toggleGroupManageBucketsPrivileges($event, 'write')">
+                <span class="description">Write</span>
+            </mat-checkbox>
+            <mat-checkbox class="pad-left-md" [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [(checked)]="nfRegistryService.group.resourcePermissions.buckets.canDelete" (change)="toggleGroupManageBucketsPrivileges($event, 'delete')">
+                <span class="description">Delete</span>
+            </mat-checkbox>
+        </div>
+        <mat-checkbox [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [checked]="nfRegistryService.group.resourcePermissions.tenants.canRead && nfRegistryService.group.resourcePermissions.tenants.canWrite && nfRegistryService.group.resourcePermissions.tenants.canDelete" (change)="toggleGroupManageTenantsPrivileges($event)">
+            <span class="description">Can manage users</span>
+        </mat-checkbox>
+        <div flex fxLayout="row" fxLayoutAlign="space-around center">
+            <mat-checkbox class="pad-left-md" [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [(checked)]="nfRegistryService.group.resourcePermissions.tenants.canRead" (change)="toggleGroupManageTenantsPrivileges($event, 'read')">
+                <span class="description">Read</span>
+            </mat-checkbox>
+            <mat-checkbox class="pad-left-md" [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [(checked)]="nfRegistryService.group.resourcePermissions.tenants.canWrite" (change)="toggleGroupManageTenantsPrivileges($event, 'write')">
+                <span class="description">Write</span>
+            </mat-checkbox>
+            <mat-checkbox class="pad-left-md" [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [(checked)]="nfRegistryService.group.resourcePermissions.tenants.canDelete" (change)="toggleGroupManageTenantsPrivileges($event, 'delete')">
+                <span class="description">Delete</span>
+            </mat-checkbox>
+        </div>
+        <mat-checkbox [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [checked]="nfRegistryService.group.resourcePermissions.policies.canRead && nfRegistryService.group.resourcePermissions.policies.canWrite && nfRegistryService.group.resourcePermissions.policies.canDelete" (change)="toggleGroupManagePoliciesPrivileges($event)">
+            <span class="description">Can manage policies</span>
+        </mat-checkbox>
+        <div flex fxLayout="row" fxLayoutAlign="space-around center">
+            <mat-checkbox class="pad-left-md" [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [(checked)]="nfRegistryService.group.resourcePermissions.policies.canRead" (change)="toggleGroupManagePoliciesPrivileges($event, 'read')">
+                <span class="description">Read</span>
+            </mat-checkbox>
+            <mat-checkbox class="pad-left-md" [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [(checked)]="nfRegistryService.group.resourcePermissions.policies.canWrite" (change)="toggleGroupManagePoliciesPrivileges($event, 'write')">
+                <span class="description">Write</span>
+            </mat-checkbox>
+            <mat-checkbox class="pad-left-md" [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [(checked)]="nfRegistryService.group.resourcePermissions.policies.canDelete" (change)="toggleGroupManagePoliciesPrivileges($event, 'delete')">
+                <span class="description">Delete</span>
+            </mat-checkbox>
+        </div>
+        <mat-checkbox [disabled]="!nfRegistryService.currentUser.resourcePermissions.policies.canWrite" [checked]="nfRegistryService.group.resourcePermissions.proxy.canWrite" (change)="toggleGroupManageProxyPrivileges($event)">
+            <span class="description">Can proxy user requests</span>
+        </mat-checkbox>
+    </div>
+    <mat-button-toggle-group name="nifi-registry-manage-group-perspective" class="pad-left-md tab-toggle-group">
+        <mat-button-toggle [checked]="manageGroupPerspective === 'membership'"
+                           value="membership"
+                           class="uppercase"
+                           (change)="manageGroupPerspective = 'membership'"
+                           i18n="User membership tab, group management sidenav|View the users that belong to this group.@@nf-admin-group-management-sidenav-membership-tab-title">
+            Membership
+        </mat-button-toggle>
+    </mat-button-toggle-group>
+    <div *ngIf="manageGroupPerspective === 'membership'">
+        <div *ngIf="nfRegistryService.group.users" fxFlex class="pad-top-md pad-bottom-sm pad-left-md pad-right-md">
+            <div flex fxLayout="row" fxLayoutAlign="space-between center">
+                <span class="md-card-title">Membership ({{nfRegistryService.group.users.length}})</span>
+                <button color="fds-secondary"
+                        [disabled]="!nfRegistryService.currentUser.resourcePermissions.tenants.canWrite"
+                        mat-raised-button
+                        (click)="addUsersToGroup()">
+                    Add Users
+                </button>
+            </div>
+            <div id="nifi-registry-group-membership-list-container-column-header" fxLayout="row"
+                 fxLayoutAlign="space-between center" class="td-data-table">
+                <div class="td-data-table-column" (click)="sortUsers(column)"
+                     *ngFor="let column of nfRegistryService.userGroupsColumns"
+                     fxFlex="{{column.width}}">
+                    {{column.label}}
+                    <i *ngIf="column.active && column.sortable && column.sortOrder === 'ASC'" class="fa fa-caret-up"
+                       aria-hidden="true"></i>
+                    <i *ngIf="column.active && column.sortable && column.sortOrder === 'DESC'" class="fa fa-caret-down"
+                       aria-hidden="true"></i>
+                </div>
+            </div>
+            <div id="nifi-registry-group-membership-list-container">
+                <div fxLayout="row" fxLayoutAlign="space-between center" class="td-data-table-row"
+                     [ngClass]="{'selected' : row.checked}" *ngFor="let row of filteredUsers"
+                     (click)="row.checked = !row.checked">
+                    <div class="td-data-table-cell" *ngFor="let column of nfRegistryService.userGroupsColumns"
+                         fxFlex="{{column.width}}">
+                        <div matTooltip="{{column.format ? column.format(row[column.name]) : row[column.name]}}">
+                            {{column.format ? column.format(row[column.name]) : row[column.name]}}
+                        </div>
+                    </div>
+                    <div class="td-data-table-cell">
+                        <div>
+                            <button (click)="removeUserFromGroup(row);row.checked = !row.checked;"
+                                    matTooltip="'Remove user from group'" mat-icon-button color="accent"
+                                    *ngIf="nfRegistryService.currentUser.resourcePermissions.tenants.canWrite">
+                                <i class="fa fa-minus-circle" aria-hidden="true"></i>
+                            </button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="mat-padding" *ngIf="nfRegistryService.group.users.length === 0" layout="row"
+                 layout-align="center center">
+                <h3>This group does not have any users yet.</h3>
+            </div>
+        </div>
+    </div>
+    <button id="nf-registry-user-permissions-side-nav-container" class="push-right-md" mat-raised-button
+            color="fds-primary"
+            (click)="closeSideNav()">Close
+    </button>
+</div>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/580f7754/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js
new file mode 100644
index 0000000..a519887
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js
@@ -0,0 +1,577 @@
+/*
+ * 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.
+ */
+
+var covalentCore = require('@covalent/core');
+var fdsDialogsModule = require('@fluid-design-system/dialogs');
+var fdsSnackBarsModule = require('@fluid-design-system/snackbars');
+var ngCore = require('@angular/core');
+var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var ngRouter = require('@angular/router');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var ngMaterial = require('@angular/material');
+var NfRegistryAddUsersToGroup = require('nifi-registry/components/administration/users/dialogs/add-users-to-group/nf-registry-add-users-to-group.js');
+
+/**
+ * NfRegistryManageGroup constructor.
+ *
+ * @param nfRegistryApi         The api service.
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param tdDataTableService    The covalent data table service module.
+ * @param fdsDialogService      The FDS dialog service.
+ * @param fdsSnackBarService    The FDS snack bar service module.
+ * @param activatedRoute        The angular route module.
+ * @param router                The angular router module.
+ * @param matDialog             The angular material dialog module.
+ * @constructor
+ */
+function NfRegistryManageGroup(nfRegistryApi, nfRegistryService, tdDataTableService, fdsDialogService, fdsSnackBarService, activatedRoute, router, matDialog) {
+    this.filteredUsers = [];
+    this.usersSearchTerms = [];
+    this._groupname = '';
+    this.manageGroupPerspective = 'membership';
+
+    // Services
+    this.nfRegistryService = nfRegistryService;
+    this.route = activatedRoute;
+    this.router = router;
+    this.dialog = matDialog;
+    this.nfRegistryApi = nfRegistryApi;
+    this.dialogService = fdsDialogService;
+    this.snackBarService = fdsSnackBarService;
+    this.dataTableService = tdDataTableService;
+};
+
+NfRegistryManageGroup.prototype = {
+    constructor: NfRegistryManageGroup,
+
+    /**
+     * Initialize the component.
+     */
+    ngOnInit: function () {
+        var self = this;
+        this.nfRegistryService.sidenav.open();
+
+        // subscribe to the route params
+        self.route.params
+            .switchMap(function (params) {
+                return self.nfRegistryApi.getUserGroup(params['groupId']);
+            })
+            .subscribe(function (response) {
+                self.nfRegistryService.group = response;
+                self._groupname = response.identity;
+                self.filterUsers();
+            });
+    },
+
+    /**
+     * Destroy the component.
+     */
+    ngOnDestroy: function () {
+        this.nfRegistryService.sidenav.close();
+    },
+
+    /**
+     * Navigate to administer users for current registry.
+     */
+    closeSideNav: function () {
+        this.router.navigateByUrl('/nifi-registry/administration/users');
+    },
+
+    /**
+     * Toggles the manage bucket privileges for the group.
+     *
+     * @param $event
+     * @param policyAction      The action to be toggled
+     */
+    toggleGroupManageBucketsPrivileges: function ($event, policyAction) {
+        var self = this;
+        if ($event.checked) {
+            for (var resource in this.nfRegistryService.BUCKETS_PRIVS) {
+                if (this.nfRegistryService.BUCKETS_PRIVS.hasOwnProperty(resource)) {
+                    this.nfRegistryService.BUCKETS_PRIVS[resource].forEach(function (action) {
+                        if (!policyAction || (action === policyAction)) {
+                            self.nfRegistryApi.getPolicyActionResource(action, resource).subscribe(function (policy) {
+                                if (policy.status && policy.status === 409) {
+                                    // resource does NOT exist, let's create it
+                                    self.nfRegistryApi.postPolicyActionResource(action, resource, self.nfRegistryService.group.users, []).subscribe(
+                                        function (response) {
+                                            // can manage buckets privileges created and granted!!!...now update the view
+                                            response.userGroups.forEach(function (group) {
+                                                if (group.identifier === self.nfRegistryService.group.identifier) {
+                                                    self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                        self.nfRegistryService.group = response;
+                                                    });
+                                                }
+                                            });
+                                        });
+                                } else {
+                                    // resource exists, let's update it
+                                    policy.userGroups.push(self.nfRegistryService.group);
+                                    self.nfRegistryApi.putPolicyActionResource(policy.identifier, policy.action,
+                                        policy.resource, policy.users, policy.userGroups).subscribe(
+                                        function (response) {
+                                            // can manage buckets privileges updated!!!...now update the view
+                                            response.userGroups.forEach(function (group) {
+                                                if (group.identifier === self.nfRegistryService.group.identifier) {
+                                                    self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                        self.nfRegistryService.group = response;
+                                                    });
+                                                }
+                                            });
+                                        });
+                                }
+                            });
+                        }
+                    });
+                }
+            }
+        } else {
+            // Remove the current group from the administrator resources
+            for (var resource in this.nfRegistryService.BUCKETS_PRIVS) {
+                if (this.nfRegistryService.BUCKETS_PRIVS.hasOwnProperty(resource)) {
+                    this.nfRegistryService.BUCKETS_PRIVS[resource].forEach(function (action) {
+                        if (!policyAction || (action === policyAction)) {
+                            self.nfRegistryApi.getPolicyActionResource(action, resource).subscribe(function (policy) {
+                                if (policy.status && policy.status === 409) {
+                                    // resource does NOT exist
+                                } else {
+                                    // resource exists, let's filter out the current group and update it
+                                    policy.userGroups = policy.userGroups.filter(function (group) {
+                                        return (group.identifier !== self.nfRegistryService.group.identifier) ? true : false;
+                                    });
+                                    self.nfRegistryApi.putPolicyActionResource(policy.identifier, policy.action,
+                                        policy.resource, policy.users, policy.userGroups).subscribe(
+                                        function (response) {
+                                            // can manage buckets privileges updated!!!...now update the view
+                                            self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                self.nfRegistryService.group = response;
+                                            });
+                                        });
+                                }
+                            });
+                        }
+                    });
+                }
+            }
+
+        }
+    },
+
+    /**
+     * Toggles the manage tenants privileges for the group.
+     *
+     * @param $event
+     * @param policyAction      The action to be toggled
+     */
+    toggleGroupManageTenantsPrivileges: function ($event, policyAction) {
+        var self = this;
+        if ($event.checked) {
+            for (var resource in this.nfRegistryService.TENANTS_PRIVS) {
+                if (this.nfRegistryService.TENANTS_PRIVS.hasOwnProperty(resource)) {
+                    this.nfRegistryService.TENANTS_PRIVS[resource].forEach(function (action) {
+                        if (!policyAction || (action === policyAction)) {
+                            self.nfRegistryApi.getPolicyActionResource(action, resource).subscribe(function (policy) {
+                                if (policy.status && policy.status === 409) {
+                                    // resource does NOT exist, let's create it
+                                    self.nfRegistryApi.postPolicyActionResource(action, resource, self.nfRegistryService.group.users, []).subscribe(
+                                        function (response) {
+                                            // can manage tenants privileges created and granted!!!...now update the view
+                                            response.userGroups.forEach(function (group) {
+                                                if (group.identifier === self.nfRegistryService.group.identifier) {
+                                                    self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                        self.nfRegistryService.group = response;
+                                                    });
+                                                }
+                                            });
+                                        });
+                                } else {
+                                    // resource exists, let's update it
+                                    policy.userGroups.push(self.nfRegistryService.group);
+                                    self.nfRegistryApi.putPolicyActionResource(policy.identifier, policy.action,
+                                        policy.resource, policy.users, policy.userGroups).subscribe(
+                                        function (response) {
+                                            // can manage tenants privileges updated!!!...now update the view
+                                            response.userGroups.forEach(function (group) {
+                                                if (group.identifier === self.nfRegistryService.group.identifier) {
+                                                    self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                        self.nfRegistryService.group = response;
+                                                    });
+                                                }
+                                            });
+                                        });
+                                }
+                            });
+                        }
+                    });
+                }
+            }
+        } else {
+            // Remove the current group from the administrator resources
+            for (var resource in this.nfRegistryService.TENANTS_PRIVS) {
+                if (this.nfRegistryService.TENANTS_PRIVS.hasOwnProperty(resource)) {
+                    this.nfRegistryService.TENANTS_PRIVS[resource].forEach(function (action) {
+                        if (!policyAction || (action === policyAction)) {
+                            self.nfRegistryApi.getPolicyActionResource(action, resource).subscribe(function (policy) {
+                                if (policy.status && policy.status === 409) {
+                                    // resource does NOT exist
+                                } else {
+                                    // resource exists, let's filter out the current group and update it
+                                    policy.userGroups = policy.userGroups.filter(function (group) {
+                                        return (group.identifier !== self.nfRegistryService.group.identifier) ? true : false;
+                                    });
+                                    self.nfRegistryApi.putPolicyActionResource(policy.identifier, policy.action,
+                                        policy.resource, policy.users, policy.userGroups).subscribe(
+                                        function (response) {
+                                            // can manage tenants privileges updated!!!...now update the view
+                                            self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                self.nfRegistryService.group = response;
+                                            });
+                                        });
+                                }
+                            });
+                        }
+                    });
+                }
+            }
+
+        }
+    },
+
+    /**
+     * Toggles the manage policies privileges for the group.
+     *
+     * @param $event
+     * @param policyAction      The action to be toggled
+     */
+    toggleGroupManagePoliciesPrivileges: function ($event, policyAction) {
+        var self = this;
+        if ($event.checked) {
+            for (var resource in this.nfRegistryService.POLICIES_PRIVS) {
+                if (this.nfRegistryService.POLICIES_PRIVS.hasOwnProperty(resource)) {
+                    this.nfRegistryService.POLICIES_PRIVS[resource].forEach(function (action) {
+                        if (!policyAction || (action === policyAction)) {
+                            self.nfRegistryApi.getPolicyActionResource(action, resource).subscribe(function (policy) {
+                                if (policy.status && policy.status === 409) {
+                                    // resource does NOT exist, let's create it
+                                    self.nfRegistryApi.postPolicyActionResource(action, resource, self.nfRegistryService.group.users, []).subscribe(
+                                        function (response) {
+                                            // can manage policies privileges created and granted!!!...now update the view
+                                            response.userGroups.forEach(function (group) {
+                                                if (group.identifier === self.nfRegistryService.group.identifier) {
+                                                    self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                        self.nfRegistryService.group = response;
+                                                    });
+                                                }
+                                            });
+                                        });
+                                } else {
+                                    // resource exists, let's update it
+                                    policy.userGroups.push(self.nfRegistryService.group);
+                                    self.nfRegistryApi.putPolicyActionResource(policy.identifier, policy.action,
+                                        policy.resource, policy.users, policy.userGroups).subscribe(
+                                        function (response) {
+                                            // can manage policies privileges updated!!!...now update the view
+                                            response.userGroups.forEach(function (group) {
+                                                if (group.identifier === self.nfRegistryService.group.identifier) {
+                                                    self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                        self.nfRegistryService.group = response;
+                                                    });
+                                                }
+                                            });
+                                        });
+                                }
+                            });
+                        }
+                    });
+                }
+            }
+        } else {
+            // Remove the current group from the administrator resources
+            for (var resource in this.nfRegistryService.POLICIES_PRIVS) {
+                if (this.nfRegistryService.POLICIES_PRIVS.hasOwnProperty(resource)) {
+                    this.nfRegistryService.POLICIES_PRIVS[resource].forEach(function (action) {
+                        if (!policyAction || (action === policyAction)) {
+                            self.nfRegistryApi.getPolicyActionResource(action, resource).subscribe(function (policy) {
+                                if (policy.status && policy.status === 409) {
+                                    // resource does NOT exist
+                                } else {
+                                    // resource exists, let's filter out the current group and update it
+                                    policy.userGroups = policy.userGroups.filter(function (group) {
+                                        return (group.identifier !== self.nfRegistryService.group.identifier) ? true : false;
+                                    });
+                                    self.nfRegistryApi.putPolicyActionResource(policy.identifier, policy.action,
+                                        policy.resource, policy.users, policy.userGroups).subscribe(
+                                        function (response) {
+                                            // can manage policies privileges updated!!!...now update the view
+                                            self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                self.nfRegistryService.group = response;
+                                            });
+                                        });
+                                }
+                            });
+                        }
+                    });
+                }
+            }
+
+        }
+    },
+
+    /**
+     * Toggles the manage proxy privileges for the group.
+     *
+     * @param $event
+     * @param policyAction      The action to be toggled
+     */
+    toggleGroupManageProxyPrivileges: function ($event, policyAction) {
+        var self = this;
+        if ($event.checked) {
+            for (var resource in this.nfRegistryService.PROXY_PRIVS) {
+                if (this.nfRegistryService.PROXY_PRIVS.hasOwnProperty(resource)) {
+                    this.nfRegistryService.PROXY_PRIVS[resource].forEach(function (action) {
+                        if (!policyAction || (action === policyAction)) {
+                            self.nfRegistryApi.getPolicyActionResource(action, resource).subscribe(function (policy) {
+                                if (policy.status && policy.status === 409) {
+                                    // resource does NOT exist, let's create it
+                                    self.nfRegistryApi.postPolicyActionResource(action, resource, self.nfRegistryService.group.users, []).subscribe(
+                                        function (response) {
+                                            // can manage proxy privileges created and granted!!!...now update the view
+                                            response.userGroups.forEach(function (group) {
+                                                if (group.identifier === self.nfRegistryService.group.identifier) {
+                                                    self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                        self.nfRegistryService.group = response;
+                                                    });
+                                                }
+                                            });
+                                        });
+                                } else {
+                                    // resource exists, let's update it
+                                    policy.userGroups.push(self.nfRegistryService.group);
+                                    self.nfRegistryApi.putPolicyActionResource(policy.identifier, policy.action,
+                                        policy.resource, policy.users, policy.userGroups).subscribe(
+                                        function (response) {
+                                            // can manage proxy privileges updated!!!...now update the view
+                                            response.userGroups.forEach(function (group) {
+                                                if (group.identifier === self.nfRegistryService.group.identifier) {
+                                                    self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                        self.nfRegistryService.group = response;
+                                                    });
+                                                }
+                                            });
+                                        });
+                                }
+                            });
+                        }
+                    });
+                }
+            }
+        } else {
+            // Remove the current group from the administrator resources
+            for (var resource in this.nfRegistryService.PROXY_PRIVS) {
+                if (this.nfRegistryService.PROXY_PRIVS.hasOwnProperty(resource)) {
+                    this.nfRegistryService.PROXY_PRIVS[resource].forEach(function (action) {
+                        if (!policyAction || (action === policyAction)) {
+                            self.nfRegistryApi.getPolicyActionResource(action, resource).subscribe(function (policy) {
+                                if (policy.status && policy.status === 409) {
+                                    // resource does NOT exist
+                                } else {
+                                    // resource exists, let's filter out the current group and update it
+                                    policy.userGroups = policy.userGroups.filter(function (group) {
+                                        return (group.identifier !== self.nfRegistryService.group.identifier) ? true : false;
+                                    });
+                                    self.nfRegistryApi.putPolicyActionResource(policy.identifier, policy.action,
+                                        policy.resource, policy.users, policy.userGroups).subscribe(
+                                        function (response) {
+                                            // can manage proxy privileges updated!!!...now update the view
+                                            self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier).subscribe(function(response) {
+                                                self.nfRegistryService.group = response;
+                                            });
+                                        });
+                                }
+                            });
+                        }
+                    });
+                }
+            }
+
+        }
+    },
+
+    /**
+     * Opens a modal dialog UX enabling the addition of users to this group.
+     */
+    addUsersToGroup: function () {
+        var self = this;
+        this.dialog.open(NfRegistryAddUsersToGroup, {
+            data: {
+                group: this.nfRegistryService.group
+            }
+        }).afterClosed().subscribe(function () {
+            self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier)
+                .subscribe(function (response) {
+                    self.nfRegistryService.group = response;
+                    self._groupname = response.identity;
+                    self.filterUsers();
+                });
+        });
+    },
+
+    /**
+     * Filter users.
+     *
+     * @param {string} [sortBy]       The column name to sort `userGroupsColumns` by.
+     * @param {string} [sortOrder]    The order. Either 'ASC' or 'DES'
+     */
+    filterUsers: function (sortBy, sortOrder) {
+        // if `sortOrder` is `undefined` then use 'ASC'
+        if (sortOrder === undefined) {
+            sortOrder = 'ASC'
+        }
+        // if `sortBy` is `undefined` then find the first sortable column in `userGroupsColumns`
+        if (sortBy === undefined) {
+            var arrayLength = this.nfRegistryService.userGroupsColumns.length;
+            for (var i = 0; i < arrayLength; i++) {
+                if (this.nfRegistryService.userGroupsColumns[i].sortable === true) {
+                    sortBy = this.nfRegistryService.userGroupsColumns[i].name;
+                    //only one column can be actively sorted so we reset all to inactive
+                    this.nfRegistryService.userGroupsColumns.forEach(function (c) {
+                        c.active = false;
+                    });
+                    //and set this column as the actively sorted column
+                    this.nfRegistryService.userGroupsColumns[i].active = true;
+                    this.nfRegistryService.userGroupsColumns[i].sortOrder = sortOrder;
+                    break;
+                }
+            }
+        }
+
+        var newUsersData = this.nfRegistryService.group.users || [];
+
+        for (var i = 0; i < this.usersSearchTerms.length; i++) {
+            newUsersData = this.filterData(newUsersData, this.usersSearchTerms[i], true);
+        }
+
+        newUsersData = this.dataTableService.sortData(newUsersData, sortBy, sortOrder);
+        this.filteredUsers = newUsersData;
+    },
+
+    /**
+     * Sort `users` by `column`.
+     *
+     * @param column    The column to sort by.
+     */
+    sortUsers: function (column) {
+        if (column.sortable) {
+            var sortBy = column.name;
+            var sortOrder = column.sortOrder = (column.sortOrder === 'ASC') ? 'DESC' : 'ASC';
+            this.filterUsers(sortBy, sortOrder);
+
+            //only one column can be actively sorted so we reset all to inactive
+            this.nfRegistryService.userGroupsColumns.forEach(function (c) {
+                c.active = false;
+            });
+            //and set this column as the actively sorted column
+            column.active = true;
+        }
+    },
+
+    /**
+     * Remove user from group.
+     *
+     * @param user
+     */
+    removeUserFromGroup: function (user) {
+        var self = this;
+        var users = this.nfRegistryService.group.users.filter(function (u) {
+            if (u.identifier !== user.identifier) {
+                return u;
+            }
+        });
+
+        this.nfRegistryApi.updateUserGroup(this.nfRegistryService.group.identifier, this.nfRegistryService.group.identity, users).subscribe(function (response) {
+            self.nfRegistryApi.getUserGroup(self.nfRegistryService.group.identifier)
+                .subscribe(function (response) {
+                    self.nfRegistryService.group = response;
+                    self.filterUsers();
+                });
+            var snackBarRef = self.snackBarService.openCoaster({
+                title: 'Success',
+                message: 'The user has been removed from the ' + this.nfRegistryService.group.identity + ' group.',
+                verticalPosition: 'bottom',
+                horizontalPosition: 'right',
+                icon: 'fa fa-check-circle-o',
+                color: '#1EB475',
+                duration: 3000
+            });
+        });
+    },
+
+    /**
+     * Update group name.
+     *
+     * @param groupname
+     */
+    updateGroupName: function (groupname) {
+        var self = this;
+        this.nfRegistryApi.updateUserGroup(this.nfRegistryService.group.identifier, groupname, this.nfRegistryService.group.users).subscribe(function (response) {
+            if (!response.status || response.status === 200) {
+                self.nfRegistryService.group = response;
+                self.nfRegistryService.groups.filter(function (group) {
+                    if (self.nfRegistryService.group.identifier === group.identifier) {
+                        group.identity = response.identity;
+                    }
+                });
+                var snackBarRef = self.snackBarService.openCoaster({
+                    title: 'Success',
+                    message: 'This group name has been updated.',
+                    verticalPosition: 'bottom',
+                    horizontalPosition: 'right',
+                    icon: 'fa fa-check-circle-o',
+                    color: '#1EB475',
+                    duration: 3000
+                });
+            } else if (response.status === 409) {
+                self._groupname = self.nfRegistryService.group.identity;
+                self.dialogService.openConfirm({
+                    title: 'Error',
+                    message: 'This group already exists. Please enter a different identity/group name.',
+                    acceptButton: 'Ok',
+                    acceptButtonColor: 'fds-warn'
+                });
+            }
+        });
+    }
+};
+
+NfRegistryManageGroup.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-manage-group.html!text')
+    })
+];
+
+NfRegistryManageGroup.parameters = [
+    NfRegistryApi,
+    NfRegistryService,
+    covalentCore.TdDataTableService,
+    fdsDialogsModule.FdsDialogService,
+    fdsSnackBarsModule.FdsSnackBarService,
+    ngRouter.ActivatedRoute,
+    ngRouter.Router,
+    ngMaterial.MatDialog
+];
+
+module.exports = NfRegistryManageGroup;


Mime
View raw message