nifi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bbe...@apache.org
Subject [4/4] nifi-registry git commit: NIFIREG-30 - GET users/groups, delete user/group, delete users/groups, create group, introduce group side nav - Add selected users to selected groups - Update JS unit tests - Add kerberos support
Date Tue, 28 Nov 2017 19:34:46 GMT
NIFIREG-30 - GET users/groups, delete user/group, delete users/groups, create group, introduce group side nav
- Add selected users to selected groups
- Update JS unit tests
- Add kerberos support

This closes #40.

Signed-off-by: Bryan Bende <bbende@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/nifi-registry/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi-registry/commit/247985ad
Tree: http://git-wip-us.apache.org/repos/asf/nifi-registry/tree/247985ad
Diff: http://git-wip-us.apache.org/repos/asf/nifi-registry/diff/247985ad

Branch: refs/heads/master
Commit: 247985ada0aca56f72924c84e264ffdf29e31f80
Parents: a2f639f
Author: Scott Aslan <scottyaslan@gmail.com>
Authored: Fri Nov 17 10:08:59 2017 -0500
Committer: Bryan Bende <bbende@apache.org>
Committed: Tue Nov 28 14:34:19 2017 -0500

----------------------------------------------------------------------
 .../src/main/frontend/karma.conf.js             |   1 +
 .../src/main/frontend/package.json              |   3 +-
 .../src/main/locale/messages.es.xlf             |  36 ++
 .../platform/core/common/styles/_links.scss     |   1 +
 .../platform/core/common/styles/_tables.scss    |   2 +
 .../nf-registry-administration.spec.js          |  18 +-
 .../nf-registry-user-group-permissions.html     |  28 +
 .../nf-registry-user-group-permissions.js       |  70 ++
 .../users/add/nf-registry-add-user.html         |  28 -
 .../users/add/nf-registry-add-user.js           |  69 --
 ...nf-registry-add-selected-users-to-group.html |  75 +++
 .../nf-registry-add-selected-users-to-group.js  | 237 +++++++
 .../dialogs/add-user/nf-registry-add-user.html  |  46 ++
 .../dialogs/add-user/nf-registry-add-user.js    |  78 +++
 .../nf-registry-create-new-group.html           |  46 ++
 .../nf-registry-create-new-group.js             |  87 +++
 .../users/nf-registry-users-administration.html | 160 +++--
 .../users/nf-registry-users-administration.js   | 159 +++--
 .../nf-registry-user-permissions.html           |   6 +-
 .../nf-registry-bucket-permissions.js           |   8 +-
 .../dialogs/nf-registry-create-bucket.html      |   2 +-
 .../dialogs/nf-registry-create-bucket.js        |   9 +-
 .../dialogs/nf-registry-create-bucket.spec.js   |  19 +-
 .../nf-registry-workflow-administration.html    |  22 +-
 .../nf-registry-workflow-administration.js      |  38 +-
 .../nf-registry-workflow-administration.spec.js |  18 +-
 .../nf-registry-bucket-grid-list-viewer.js      |  50 +-
 .../nf-registry-bucket-grid-list-viewer.spec.js |  20 +-
 .../nf-registry-droplet-grid-list-viewer.js     |  59 +-
 ...nf-registry-droplet-grid-list-viewer.spec.js |  20 +-
 .../registry/nf-registry-grid-list-viewer.html  |   2 +-
 .../registry/nf-registry-grid-list-viewer.js    |  45 +-
 .../nf-registry-grid-list-viewer.spec.js        |  21 +-
 .../explorer/nf-registry-explorer.spec.js       |  16 +-
 .../src/main/webapp/nf-registry.html            |   9 +-
 .../src/main/webapp/nf-registry.js              |  74 ++-
 .../src/main/webapp/nf-registry.module.js       |  29 +-
 .../src/main/webapp/nf-registry.routes.js       |   6 +-
 .../src/main/webapp/nf-registry.spec.js         |  16 +-
 .../src/main/webapp/services/nf-registry.api.js | 451 ++++++++-----
 .../webapp/services/nf-registry.api.spec.js     | 511 +++++++--------
 .../webapp/services/nf-registry.auth.service.js |  46 ++
 .../main/webapp/services/nf-registry.service.js | 635 +++++++++++++------
 .../webapp/services/nf-registry.service.spec.js |  71 ++-
 .../services/nf-registry.token.interceptor.js   |  49 ++
 .../main/webapp/services/nf-storage.service.js  | 219 +++++++
 .../src/main/webapp/systemjs.builder.config.js  |  10 +-
 .../src/main/webapp/systemjs.spec.config.js     |   3 +
 .../main/webapp/theming/_structureElements.scss |  30 +-
 .../users/_structureElements.scss               |   7 +-
 50 files changed, 2668 insertions(+), 997 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/frontend/karma.conf.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/frontend/karma.conf.js b/nifi-registry-web-ui/src/main/frontend/karma.conf.js
index b0543ca..bffdba2 100644
--- a/nifi-registry-web-ui/src/main/frontend/karma.conf.js
+++ b/nifi-registry-web-ui/src/main/frontend/karma.conf.js
@@ -65,6 +65,7 @@ module.exports = function (config) {
             'node_modules/hammerjs/hammer.js',
             'node_modules/moment/moment.js',
             'node_modules/superagent/superagent.js',
+            'node_modules/tslib/tslib.js',
 
             // RxJs
             {pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false},

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/frontend/package.json
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/frontend/package.json b/nifi-registry-web-ui/src/main/frontend/package.json
index 7320b0e..efd0d4f 100644
--- a/nifi-registry-web-ui/src/main/frontend/package.json
+++ b/nifi-registry-web-ui/src/main/frontend/package.json
@@ -33,6 +33,7 @@
     "@angular/platform-browser": "4.4.4",
     "@angular/platform-browser-dynamic": "4.4.4",
     "@angular/router": "4.4.4",
+    "angular2-jwt": "0.2.3",
     "canonical-path": "0.0.2",
     "grunt": "0.4.5",
     "grunt-cli": "1.2.0",
@@ -59,7 +60,7 @@
     "superagent": "3.6.3",
     "systemjs": "0.20.17",
     "systemjs-plugin-text": "0.0.11",
-    "zone.js": "0.8.4"
+    "zone.js": "0.8.7"
   },
   "bundleDependencies": [],
   "private": true

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/locale/messages.es.xlf
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/locale/messages.es.xlf b/nifi-registry-web-ui/src/main/locale/messages.es.xlf
index 91c9e1d..9a093c9 100644
--- a/nifi-registry-web-ui/src/main/locale/messages.es.xlf
+++ b/nifi-registry-web-ui/src/main/locale/messages.es.xlf
@@ -41,6 +41,42 @@
         <note priority="1" from="description">A button for creating a new bucket in the registry.@@nf-admin-workflow-create-bucket-button.</note>
         <note priority="1" from="meaning">Create new bucket button</note>
        </trans-unit>
+      <trans-unit id="nf-admin-workflow-add-user-button" datatype="html">
+         <source>Add</source>
+         <target state="new">añadir</target>
+        <note priority="1" from="description">A button for adding a new user in the registry.@@nf-admin-workflow-add-user-button.</note>
+        <note priority="1" from="meaning">Add new user button</note>
+       </trans-unit>
+      <trans-unit id="nf-admin-workflow-cancel-add-user-button" datatype="html">
+         <source>Cancel</source>
+         <target state="new">Cancelar</target>
+        <note priority="1" from="description">A button for cancelling the creation of a new user in the registry.@@nf-admin-workflow-add-user-button.</note>
+        <note priority="1" from="meaning">Cancel creation of new user</note>
+       </trans-unit>
+      <trans-unit id="nf-admin-workflow-create-new-group-button" datatype="html">
+         <source>Create</source>
+         <target state="new">Crear</target>
+        <note priority="1" from="description">A button for creating a new group in the registry.@@nf-admin-workflow-create-new-group-button.</note>
+        <note priority="1" from="meaning">Create new group button</note>
+       </trans-unit>
+      <trans-unit id="nf-admin-workflow-cancel-create-new-group-button" datatype="html">
+         <source>Cancel</source>
+         <target state="new">Cancelar</target>
+        <note priority="1" from="description">A button for cancelling the creation of a new group in the registry.@@nf-admin-workflow-cancel-create-new-group-button.</note>
+        <note priority="1" from="meaning">Cancel creation of new group</note>
+       </trans-unit>
+      <trans-unit id="nf-admin-workflow-add-selected-users-to-group-button" datatype="html">
+         <source>Add</source>
+         <target state="new">añadir</target>
+        <note priority="1" from="description">A button for adding users to an existing group in the registry.@@nf-admin-workflow-create-new-group-button.</note>
+        <note priority="1" from="meaning">Add selected users to group button</note>
+       </trans-unit>
+      <trans-unit id="nf-admin-workflow-cancel-add-selected-users-to-group-button" datatype="html">
+         <source>Cancel</source>
+         <target state="new">Cancelar</target>
+        <note priority="1" from="description">A button for cancelling the addition of selected users to a group in the registry.@@nf-admin-workflow-cancel-create-new-group-button.</note>
+        <note priority="1" from="meaning">Cancel addition of selected users to group</note>
+       </trans-unit>
     </body>
   </file>
 </xliff>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/platform/core/common/styles/_links.scss
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/platform/core/common/styles/_links.scss b/nifi-registry-web-ui/src/main/platform/core/common/styles/_links.scss
index c6973c3..2ce0fa9 100644
--- a/nifi-registry-web-ui/src/main/platform/core/common/styles/_links.scss
+++ b/nifi-registry-web-ui/src/main/platform/core/common/styles/_links.scss
@@ -21,6 +21,7 @@ body[fds] .link {
   color: $linkColor;
   font-size: 14px;
   text-decoration: none;
+  line-height: 24px;
 }
 
 body[fds] .link:hover {

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/platform/core/common/styles/_tables.scss
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/platform/core/common/styles/_tables.scss b/nifi-registry-web-ui/src/main/platform/core/common/styles/_tables.scss
index 3afa500..904a176 100644
--- a/nifi-registry-web-ui/src/main/platform/core/common/styles/_tables.scss
+++ b/nifi-registry-web-ui/src/main/platform/core/common/styles/_tables.scss
@@ -106,4 +106,6 @@ body[fds] .table-title {
 
 body[fds] div .td-data-table {
   border-bottom: 2px solid $grey7;
+  border-right: 1px transparent;
+  border-left: 1px transparent;
 }

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/nf-registry-administration.spec.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/nf-registry-administration.spec.js b/nifi-registry-web-ui/src/main/webapp/components/administration/nf-registry-administration.spec.js
index cd22d39..27694ce 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/nf-registry-administration.spec.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/nf-registry-administration.spec.js
@@ -18,6 +18,10 @@
 var NfRegistryRoutes = require('nifi-registry/nf-registry.routes.js');
 var ngCoreTesting = require('@angular/core/testing');
 var ngCommon = require('@angular/common');
+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 ngPlatformBrowser = require('@angular/platform-browser');
 var FdsDemo = require('nifi-registry/components/fluid-design-system/fds-demo.js');
 var NfRegistry = require('nifi-registry/nf-registry.js');
@@ -27,9 +31,10 @@ var NfPageNotFoundComponent = require('nifi-registry/components/page-not-found/n
 var NfRegistryExplorer = require('nifi-registry/components/explorer/nf-registry-explorer.js');
 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/add/nf-registry-add-user.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 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 NfRegistryGridListViewer = require('nifi-registry/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js');
@@ -54,6 +59,7 @@ describe('NfRegistryAdministration Component', function () {
                 ngMoment.MomentModule,
                 ngHttp.HttpModule,
                 ngHttp.JsonpModule,
+                ngCommonHttp.HttpClientModule,
                 fdsCore,
                 NfRegistryRoutes
             ],
@@ -65,6 +71,7 @@ describe('NfRegistryAdministration Component', function () {
                 NfRegistryUsersAdministration,
                 NfRegistryUserDetails,
                 NfRegistryUserPermissions,
+                NfRegistryUserGroupPermissions,
                 NfRegistryBucketPermissions,
                 NfRegistryAddUser,
                 NfRegistryWorkflowAdministration,
@@ -75,7 +82,14 @@ describe('NfRegistryAdministration Component', function () {
             ],
             providers: [
                 NfRegistryService,
+                NfRegistryAuthService,
                 NfRegistryApi,
+                NfStorage,
+                {
+                    provide: ngCommonHttp.HTTP_INTERCEPTORS,
+                    useClass: NfRegistryTokenInterceptor,
+                    multi: true
+                },
                 {
                     provide: ngCommon.APP_BASE_HREF,
                     useValue: '/'
@@ -93,7 +107,7 @@ describe('NfRegistryAdministration Component', function () {
         nfRegistryApi = ngCoreTesting.TestBed.get(NfRegistryApi);
         de = fixture.debugElement.query(ngPlatformBrowser.By.css('#nifi-registry-administration-perspective'));
         el = de.nativeElement;
-        
+
         // Spy
         spyOn(nfRegistryApi, 'getDroplets').and.callFake(function () {
         }).and.returnValue(rxjs.Observable.of([{

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/user-group/permissions/nf-registry-user-group-permissions.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/user-group/permissions/nf-registry-user-group-permissions.html b/nifi-registry-web-ui/src/main/webapp/components/administration/user-group/permissions/nf-registry-user-group-permissions.html
new file mode 100644
index 0000000..f67161c
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/user-group/permissions/nf-registry-user-group-permissions.html
@@ -0,0 +1,28 @@
+<!--
+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"><i class="fa fa-users push-right-sm" aria-hidden="true"></i>{{nfRegistryService.group.identity}}</span>
+        <button mat-icon-button (click)="closeSideNav()">
+            <mat-icon color="primary">close</mat-icon>
+        </button>
+    </div>
+    <button id="nf-registry-user-group-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/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/user-group/permissions/nf-registry-user-group-permissions.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/user-group/permissions/nf-registry-user-group-permissions.js b/nifi-registry-web-ui/src/main/webapp/components/administration/user-group/permissions/nf-registry-user-group-permissions.js
new file mode 100644
index 0000000..fe20949
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/user-group/permissions/nf-registry-user-group-permissions.js
@@ -0,0 +1,70 @@
+/*
+ * 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');
+
+/**
+ * NfRegistryUserGroupsPermissions constructor.
+ *
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param Router                The angular router module.
+ * @constructor
+ */
+function NfRegistryUserGroupsPermissions(nfRegistryService, Router) {
+    this.nfRegistryService = nfRegistryService;
+    this.router = Router;
+};
+
+NfRegistryUserGroupsPermissions.prototype = {
+    constructor: NfRegistryUserGroupsPermissions,
+
+    /**
+     * Initialize the component.
+     */
+    ngOnInit: function () {
+        this.nfRegistryService.sidenav.open();
+    },
+
+    /**
+     * Destroy the component.
+     */
+    ngOnDestroy: function () {
+        this.nfRegistryService.group = {};
+        this.nfRegistryService.sidenav.close();
+    },
+
+    /**
+     * Navigate to administer users for current registry.
+     */
+    closeSideNav: function () {
+        this.router.navigateByUrl('/nifi-registry/administration/users');
+    }
+};
+
+NfRegistryUserGroupsPermissions.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-user-group-permissions.html!text')
+    })
+];
+
+NfRegistryUserGroupsPermissions.parameters = [
+    NfRegistryService,
+    ngRouter.Router
+];
+
+module.exports = NfRegistryUserGroupsPermissions;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/users/add/nf-registry-add-user.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/add/nf-registry-add-user.html b/nifi-registry-web-ui/src/main/webapp/components/administration/users/add/nf-registry-add-user.html
deleted file mode 100644
index c605fde..0000000
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/users/add/nf-registry-add-user.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-md pad-bottom-md pad-left-sm pad-right-sm">
-        <span class="md-card-title">Add User</span>
-        <button mat-icon-button (click)="closeSideNav()">
-            <mat-icon color="primary">close</mat-icon>
-        </button>
-    </div>
-    <button id="nf-registry-add-user-side-nav-container" mat-raised-button color="fds-primary" (click)="closeSideNav()">
-        Close
-    </button>
-</div>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/users/add/nf-registry-add-user.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/add/nf-registry-add-user.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/add/nf-registry-add-user.js
deleted file mode 100644
index 0688fd8..0000000
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/users/add/nf-registry-add-user.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');
-
-/**
- * NfRegistryAddUser constructor.
- *
- * @param nfRegistryService     The nf-registry.service module.
- * @param Router                The angular router module.
- * @constructor
- */
-function NfRegistryAddUser(nfRegistryService, Router) {
-    this.nfRegistryService = nfRegistryService;
-    this.router = Router;
-};
-
-NfRegistryAddUser.prototype = {
-    constructor: NfRegistryAddUser,
-
-    /**
-     * 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');
-    }
-};
-
-NfRegistryAddUser.annotations = [
-    new ngCore.Component({
-        template: require('./nf-registry-add-user.html!text')
-    })
-];
-
-NfRegistryAddUser.parameters = [
-    NfRegistryService,
-    ngRouter.Router
-];
-
-module.exports = NfRegistryAddUser;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.html b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.html
new file mode 100644
index 0000000..bea66a5
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.html
@@ -0,0 +1,75 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<div id="nifi-registry-admin-add-selected-users-to-group-dialog">
+    <div class="pad-bottom-md" fxLayout="row" fxLayoutAlign="space-between center">
+        <span class="md-card-title">Add to group</span>
+        <button mat-icon-button (click)="cancel()">
+            <mat-icon color="primary">close</mat-icon>
+        </button>
+    </div>
+    <div class="pad-bottom-md">
+        <div id="nifi-registry-users-administration-list-container-column-header" class="td-data-table">
+            <div class="td-data-table-column" (click)="sortUserGroups($event, column)"
+                 *ngFor="let column of 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 class="td-data-table-column">
+                <mat-checkbox [(ngModel)]="allUsersAndGroupsSelected"
+                              (checked)="allUsersAndGroupsSelected"
+                              (change)="toggleUserGroupsSelectAll()"></mat-checkbox>
+            </div>
+        </div>
+        <div id="nifi-registry-add-selected-users-to-group-list-container">
+            <div [ngClass]="{'selected' : row.checked}" *ngFor="let row of filteredUserGroups"
+                 (click)="row.checked = !row.checked;determineAllUserGroupsSelectedState()">
+                <div *ngFor="let column of userGroupsColumns" fxLayout="row"
+                     fxLayoutAlign="space-between center" class="td-data-table-row">
+                    <div *ngIf="row.users && row.users.length > 0" class="td-data-table-cell" fxFlex="{{column.width}}">
+                        <div>
+                            <i class="fa fa-users push-right-sm" aria-hidden="true"></i>{{column.format ?
+                            column.format(row[column.name]) : row[column.name]}}
+                        </div>
+                    </div>
+                    <div class="td-data-table-cell">
+                        <mat-checkbox [(ngModel)]="row.checked" [checked]="row.checked"
+                                      (change)="determineAllUserGroupsSelectedState()"
+                                      (click)="row.checked = !row.checked;determineAllUserGroupsSelectedState()">
+                        </mat-checkbox>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div fxLayout="row">
+        <span fxFlex></span>
+        <button (click)="cancel()" color="fds-regular" mat-raised-button
+                i18n="Cancel addition of selected users to group|A button for cancelling the addition of selected users to a group in the registry.@@nf-admin-workflow-cancel-add-selected-users-to-group-button">
+            Cancel
+        </button>
+        <button [disabled]="isAddSelectedUsersToSelectedGroupsDisabled" class="push-left-sm" (click)="addSelectedUsersToSelectedGroups()"
+                color="fds-primary" mat-raised-button
+                i18n="Add selected users to group button|A button for adding users to an existing group in the registry.@@nf-admin-workflow-add-selected-users-to-group-button">
+            Add
+        </button>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.js
new file mode 100644
index 0000000..39dbb90
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-selected-users-to-group/nf-registry-add-selected-users-to-group.js
@@ -0,0 +1,237 @@
+/*
+ * 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');
+
+/**
+ * NfRegistryAddSelectedToGroup 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.
+ * @constructor
+ */
+function NfRegistryAddSelectedToGroup(nfRegistryApi, TdDataTableService, nfRegistryService, matDialogRef, FdsSnackBarService) {
+    this.dataTableService = TdDataTableService;
+    this.snackBarService = FdsSnackBarService;
+    this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
+    this.dialogRef = matDialogRef;
+    this.filteredUserGroups = [];
+    //make an independent copy of the groups for sorting and selecting within the scope of this component
+    this.groups = $.extend(true, [], this.nfRegistryService.groups);
+    this.selectedGroups = [];
+    this.allUsersAndGroupsSelected = false;
+    this.isAddSelectedUsersToSelectedGroupsDisabled = true;
+    this.userGroupsSearchTerms = [];
+    this.userGroupsColumns = [
+        {
+            name: 'identity',
+            label: 'Display Name',
+            sortable: true,
+            tooltip: 'User name.',
+            width: 100
+        }
+    ];
+};
+
+NfRegistryAddSelectedToGroup.prototype = {
+    constructor: NfRegistryAddSelectedToGroup,
+
+    /**
+     * Initialize the component.
+     */
+    ngOnInit: function () {
+        this.filterGroups();
+    },
+
+    /**
+     * Filter groups.
+     *
+     * @param {string} [sortBy]       The column name to sort `userGroupsColumns` by.
+     * @param {string} [sortOrder]    The order. Either 'ASC' or 'DES'
+     */
+    filterGroups: 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.userGroupsColumns.length;
+            for (var i = 0; i < arrayLength; i++) {
+                if (this.userGroupsColumns[i].sortable === true) {
+                    sortBy = this.userGroupsColumns[i].name;
+                    //only one column can be actively sorted so we reset all to inactive
+                    this.userGroupsColumns.forEach(function (c) {
+                        c.active = false;
+                    });
+                    //and set this column as the actively sorted column
+                    this.userGroupsColumns[i].active = true;
+                    this.userGroupsColumns[i].sortOrder = sortOrder;
+                    break;
+                }
+            }
+        }
+
+        var newUserGroupsData = this.groups;
+
+        for (var i = 0; i < this.userGroupsSearchTerms.length; i++) {
+            newUserGroupsData = this.nfRegistryService.filterData(newUserGroupsData, this.userGroupsSearchTerms[i], true);
+        }
+
+        newUserGroupsData = this.dataTableService.sortData(newUserGroupsData, sortBy, sortOrder);
+        this.filteredUserGroups = newUserGroupsData;
+    },
+
+    /**
+     * Sort `filteredUserGroups` by `column`.
+     *
+     * @param column    The column to sort by.
+     */
+    sortUserGroups: function (sortEvent, column) {
+        if (column.sortable) {
+            var sortBy = column.name;
+            var sortOrder = column.sortOrder = (column.sortOrder === 'ASC') ? 'DESC' : 'ASC';
+            this.filterGroups(sortBy, sortOrder);
+        }
+    },
+
+    /**
+     * Checks the `allUsersAndGroupsSelected` property state and either selects
+     * or deselects each of the `filteredUserGroups`.
+     */
+    toggleUserGroupsSelectAll: function () {
+        if (this.allUsersAndGroupsSelected) {
+            this.selectAllUserGroups();
+        } else {
+            this.deselectAllUserGroups();
+        }
+    },
+
+    /**
+     * Sets the `checked` property of each of the `filteredUserGroups` to true
+     * and sets the `isAddSelectedUsersToSelectedGroupsDisabled` and the `allUsersAndGroupsSelected`
+     * properties accordingly.
+     */
+    selectAllUserGroups: function () {
+        this.filteredUserGroups.forEach(function (c) {
+            c.checked = true;
+        });
+        this.isAddSelectedUsersToSelectedGroupsDisabled = false;
+        this.allUsersAndGroupsSelected = true;
+    },
+
+    /**
+     * Sets the `checked` property of each group to false
+     * and sets the `isAddSelectedUsersToSelectedGroupsDisabled` and the `allUsersAndGroupsSelected`
+     * properties accordingly.
+     */
+    deselectAllUserGroups: function () {
+        this.filteredUserGroups.forEach(function (c) {
+            c.checked = false;
+        });
+        this.isAddSelectedUsersToSelectedGroupsDisabled = true;
+        this.allUsersAndGroupsSelected = false;
+    },
+
+    /**
+     * Checks of each of the `filteredUserGroups`'s checked property state
+     * and sets the `allBucketsSelected` and `isAddSelectedUsersToSelectedGroupsDisabled`
+     * property accordingly.
+     */
+    determineAllUserGroupsSelectedState: function () {
+        var selected = 0;
+        var allSelected = true;
+        this.filteredUserGroups.forEach(function (c) {
+            if (c.checked) {
+                selected++;
+            }
+            if (c.checked === undefined || c.checked === false) {
+                allSelected = false;
+            }
+        });
+
+        if (selected > 0) {
+            this.isAddSelectedUsersToSelectedGroupsDisabled = false;
+        } else {
+            this.isAddSelectedUsersToSelectedGroupsDisabled = true;
+        }
+
+        this.allUsersAndGroupsSelected = allSelected;
+    },
+
+    /**
+     * Adds the selected users to each of the selected groups.
+     */
+    addSelectedUsersToSelectedGroups: function () {
+        var self = this;
+        var selectedUsers = this.nfRegistryService.filteredUsers.filter(function (filteredUser) {
+            return filteredUser.checked;
+        });
+        var groupIds = this.filteredUserGroups.filter(function (filteredUserGroup) {
+            return filteredUserGroup.checked;
+        });
+        groupIds.forEach(function (groupId) {
+            self.nfRegistryApi.getUserGroup(groupId.identifier).subscribe(function (group) {
+                self.nfRegistryApi.updateUserGroup(groupId.identifier, groupId.identity, selectedUsers.concat(group.users)).subscribe(function (group) {
+                    self.dialogRef.close();
+                    var snackBarRef = self.snackBarService.openCoaster({
+                        title: 'Success',
+                        message: 'Selected users have been added to the ' + 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();
+    }
+};
+
+NfRegistryAddSelectedToGroup.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-add-selected-users-to-group.html!text')
+    })
+];
+
+NfRegistryAddSelectedToGroup.parameters = [
+    NfRegistryApi,
+    covalentCore.TdDataTableService,
+    NfRegistryService,
+    ngMaterial.MatDialogRef,
+    fdsSnackBarsModule.FdsSnackBarService
+];
+
+module.exports = NfRegistryAddSelectedToGroup;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-user/nf-registry-add-user.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-user/nf-registry-add-user.html b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-user/nf-registry-add-user.html
new file mode 100644
index 0000000..ac76861
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-user/nf-registry-add-user.html
@@ -0,0 +1,46 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<div id="nifi-registry-admin-add-user-dialog">
+    <div class="pad-bottom-md" fxLayout="row" fxLayoutAlign="space-between center">
+        <span class="md-card-title">Add User</span>
+        <button mat-icon-button (click)="cancel()">
+            <mat-icon color="primary">close</mat-icon>
+        </button>
+    </div>
+    <div fxLayout="column" fxLayoutAlign="space-between start" class="pad-bottom-md">
+        <div class="pad-bottom-md fill-available-width">
+            <mat-input-container floatPlaceholder="always" fxFlex>
+                <input #newUserInput matInput floatPlaceholder="always" placeholder="Identity/Username" focused="true">
+            </mat-input-container>
+        </div>
+        <mat-checkbox [(ngModel)]="keepDialogOpen">
+            Keep this dialog open after adding user
+        </mat-checkbox>
+    </div>
+    <div fxLayout="row">
+        <span fxFlex></span>
+        <button (click)="cancel()" color="fds-regular" mat-raised-button
+                i18n="Cancel creation of new user|A button for cancelling the creation of a new user in the registry.@@nf-admin-workflow-create-bucket-button">
+            Cancel
+        </button>
+        <button [disabled]="newUserInput.value.length === 0" class="push-left-sm" (click)="addUser(newUserInput)" color="fds-primary" mat-raised-button
+                i18n="Add new user button|A button for adding a new user in the registry.@@nf-admin-workflow-add-user-button">
+            Add
+        </button>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-user/nf-registry-add-user.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-user/nf-registry-add-user.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-user/nf-registry-add-user.js
new file mode 100644
index 0000000..0dc7a81
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/add-user/nf-registry-add-user.js
@@ -0,0 +1,78 @@
+/*
+ * 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 NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var ngMaterial = require('@angular/material');
+
+/**
+ * NfRegistryAddUser constructor.
+ *
+ * @param nfRegistryApi         The api service.
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param matDialogRef          The angular material dialog ref.
+ * @constructor
+ */
+function NfRegistryAddUser(nfRegistryApi, nfRegistryService, matDialogRef) {
+    this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
+    this.dialogRef = matDialogRef;
+    this.keepDialogOpen = false;
+};
+
+NfRegistryAddUser.prototype = {
+    constructor: NfRegistryAddUser,
+
+    /**
+     * Create a new user.
+     *
+     * @param addUserInput     The addUserInput element.
+     */
+    addUser: function (addUserInput) {
+        var self = this;
+        this.nfRegistryApi.addUser(null, addUserInput.value).subscribe(function (user) {
+            self.nfRegistryService.users.push(user);
+            self.nfRegistryService.allUsersAndGroupsSelected = false;
+            self.nfRegistryService.filterUsersAndGroups();
+            if (self.keepDialogOpen !== true) {
+                self.dialogRef.close();
+            }
+        });
+    },
+
+    /**
+     * Cancel creation of a new bucket and close dialog.
+     */
+    cancel: function () {
+        this.dialogRef.close();
+    }
+};
+
+NfRegistryAddUser.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-add-user.html!text')
+    })
+];
+
+NfRegistryAddUser.parameters = [
+    NfRegistryApi,
+    NfRegistryService,
+    ngMaterial.MatDialogRef
+];
+
+module.exports = NfRegistryAddUser;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.html b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.html
new file mode 100644
index 0000000..889fddc
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.html
@@ -0,0 +1,46 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<div id="nifi-registry-admin-create-new-group-dialog">
+    <div class="pad-bottom-md" fxLayout="row" fxLayoutAlign="space-between center">
+        <span class="md-card-title">Create New Group</span>
+        <button mat-icon-button (click)="cancel()">
+            <mat-icon color="primary">close</mat-icon>
+        </button>
+    </div>
+    <div fxLayout="column" fxLayoutAlign="space-between start" class="pad-bottom-md">
+        <div class="pad-bottom-md fill-available-width">
+            <mat-input-container floatPlaceholder="always" fxFlex>
+                <input #createNewGroupInput matInput floatPlaceholder="always" placeholder="Display Name" focused="true">
+            </mat-input-container>
+        </div>
+        <mat-checkbox [(ngModel)]="keepDialogOpen">
+            Keep this dialog open after creating group
+        </mat-checkbox>
+    </div>
+    <div fxLayout="row">
+        <span fxFlex></span>
+        <button (click)="cancel()" color="fds-regular" mat-raised-button
+                i18n="Cancel creation of new group|A button for cancelling the creation of a new group in the registry.@@nf-admin-workflow-cancel-create-new-group-button">
+            Cancel
+        </button>
+        <button [disabled]="createNewGroupInput.value.length === 0" class="push-left-sm" (click)="createNewGroup(createNewGroupInput)" color="fds-primary" mat-raised-button
+                i18n="Create new group button|A button for creating a new group in the registry.@@nf-admin-workflow-create-new-group-button">
+            Create
+        </button>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.js b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.js
new file mode 100644
index 0000000..c1fc2c6
--- /dev/null
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/users/dialogs/create-new-group/nf-registry-create-new-group.js
@@ -0,0 +1,87 @@
+/*
+ * 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 NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var ngMaterial = require('@angular/material');
+
+/**
+ * NfRegistryCreateNewGroup constructor.
+ *
+ * @param nfRegistryApi         The api service.
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param matDialogRef          The angular material dialog ref.
+ * @constructor
+ */
+function NfRegistryCreateNewGroup(nfRegistryApi, nfRegistryService, matDialogRef) {
+    this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
+    this.dialogRef = matDialogRef;
+    this.keepDialogOpen = false;
+};
+
+NfRegistryCreateNewGroup.prototype = {
+    constructor: NfRegistryCreateNewGroup,
+
+    /**
+     * Create a new group.
+     *
+     * @param createNewGroupInput     The createNewGroupInput element.
+     */
+    createNewGroup: function (createNewGroupInput) {
+        if(!this.nfRegistryService.isMultiUserGroupActionsDisabled) {
+            var self = this;
+            var selectedUsers = this.nfRegistryService.filteredUsers.filter(function (filteredUser) {
+                return filteredUser.checked;
+            });
+            var selectedUserGroups = this.nfRegistryService.filteredUserGroups.filter(function (filteredUserGroup) {
+                return filteredUserGroup.checked;
+            });
+
+            this.nfRegistryApi.createNewGroup(null, createNewGroupInput.value, selectedUsers.concat(selectedUserGroups)).subscribe(function (group) {
+                self.nfRegistryService.groups.push(group);
+                self.nfRegistryService.filterUsersAndGroups();
+                self.nfRegistryService.allUsersAndGroupsSelected = false;
+                if (self.keepDialogOpen !== true) {
+                    self.dialogRef.close();
+                }
+            });
+        }
+    },
+
+    /**
+     * Cancel creation of a new bucket and close dialog.
+     */
+    cancel: function () {
+        this.dialogRef.close();
+    }
+};
+
+NfRegistryCreateNewGroup.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-create-new-group.html!text')
+    })
+];
+
+NfRegistryCreateNewGroup.parameters = [
+    NfRegistryApi,
+    NfRegistryService,
+    ngMaterial.MatDialogRef
+];
+
+module.exports = NfRegistryCreateNewGroup;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/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 bbff1cb..60f1270 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
@@ -17,25 +17,36 @@ limitations under the License.
 
 <div id="nifi-registry-users-administration-perspective" class="mat-elevation-z5">
     <div fxFlex class="pad-top-md pad-bottom-sm pad-left-md pad-right-md">
-        <span class="md-card-title">Authorized Users ({{nfRegistryService.users.length}})</span>
+        <span class="md-card-title">Authorized Users ({{nfRegistryService.users.length + nfRegistryService.groups.length}})</span>
         <div flex class="push-right-sm" fxLayout="row" fxLayoutAlign="end center">
-            <td-chips class="push-right-sm" [items]="nfRegistryService.autoCompleteUsers" (add)="nfRegistryService.usersSearchAdd($event)"
+            <td-chips class="push-right-sm" [items]="nfRegistryService.autoCompleteUsersAndGroups"
+                      (add)="nfRegistryService.usersSearchAdd($event)"
                       (remove)="nfRegistryService.usersSearchRemove($event)"></td-chips>
-            <button class="push-top-sm push-right-sm" color="fds-secondary" mat-raised-button (click)="execute({name: 'add'})">
+            <button class="push-top-sm push-right-sm" color="fds-secondary" mat-raised-button (click)="addUser()">
                 Add User
             </button>
-            <button class="push-top-sm" color="fds-primary" mat-raised-button [matMenuTriggerFor]="userActionMenu">
+            <button class="push-top-sm" [disabled]="nfRegistryService.isMultiUserActionsDisabled" color="fds-primary"
+                    mat-raised-button [matMenuTriggerFor]="userActionMenu">
                 Actions<i class="fa fa-caret-down" aria-hidden="true"></i>
             </button>
         </div>
         <mat-menu class="fds-primary-dropdown-button-menu" #userActionMenu="matMenu" [overlapTrigger]="false">
-            <button mat-menu-item> Need to loop over and provide list of all actions available to all currently selected
-                users
+            <button mat-menu-item
+                    (click)="nfRegistryService.deleteSelectedUsersAndGroups()">
+                <span>Delete</span>
+            </button>
+            <button mat-menu-item [disabled]="nfRegistryService.isMultiUserGroupActionsDisabled"
+                    (click)="createNewGroup()">
+                <span>Create new group</span>
+            </button>
+            <button mat-menu-item [disabled]="nfRegistryService.isMultiUserGroupActionsDisabled || 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">
-            <div class="td-data-table-column" (click)="nfRegistryService.sortUsers($event, column)"
+            <div class="td-data-table-column" (click)="nfRegistryService.sortUsersAndGroups($event, column)"
                  *ngFor="let column of nfRegistryService.userColumns"
                  fxFlex="{{column.width}}">
                 {{column.label}}
@@ -46,66 +57,113 @@ limitations under the License.
             </div>
             <div class="td-data-table-column">
                 <div fxLayout="row" fxLayoutAlign="end center">
-                    <mat-checkbox class="pad-left-sm" [(ngModel)]="nfRegistryService.allUsersSelected"
-                                 (checked)="nfRegistryService.allUsersSelected"
-                                 (change)="nfRegistryService.toggleUsersSelectAll()"></mat-checkbox>
+                    <mat-checkbox class="pad-left-sm" [(ngModel)]="nfRegistryService.allUsersAndGroupsSelected"
+                                  (checked)="nfRegistryService.allUsersAndGroupsSelected"
+                                  (change)="nfRegistryService.toggleUsersSelectAll()"></mat-checkbox>
                 </div>
             </div>
         </div>
         <div id="nifi-registry-users-administration-list-container">
-            <div fxLayout="row" fxLayoutAlign="space-between center" class="td-data-table-row"
-                 [ngClass]="{'selected' : row.checked}" *ngFor="let row of nfRegistryService.filteredUsers"
-                 (click)="row.checked = !row.checked;nfRegistryService.toggleUserSelect(row)">
-                <div class="td-data-table-cell" *ngFor="let column of nfRegistryService.userColumns"
-                     fxFlex="{{column.width}}">
-                    <div *ngIf="column.name !== 'status'">
-                        {{column.format ? column.format(row[column.name]) : row[column.name]}}
+            <div [ngClass]="{'selected' : row.checked}" *ngFor="let row of nfRegistryService.filteredUserGroups"
+                 (click)="row.checked = !row.checked;nfRegistryService.determineAllUsersAndGroupsSelectedState(row)">
+                <div *ngFor="let column of nfRegistryService.userColumns" fxLayout="row" fxLayoutAlign="space-between center" class="td-data-table-row">
+                    <div *ngIf="row.users && row.users.length > 0" class="td-data-table-cell" fxFlex="{{column.width}}">
+                        <div>
+                            <i class="fa fa-users push-right-sm" aria-hidden="true"></i>{{column.format ? column.format(row[column.name]) : row[column.name]}}
+                        </div>
                     </div>
-                    <div *ngIf="column.name === 'status'">
-                        <i [ngClass]="(row[column.name] === 'authorized')?'fa fa-check-circle authorized':'fa fa-ban suspended'"
-                           aria-hidden="true"></i>
+                    <div class="td-data-table-cell">
+                        <div>
+                            <div *ngIf="userGroupsActions.length <= 4" fxLayout="row" fxLayoutAlign="end center">
+                                <button (click)="row.checked = !row.checked;nfRegistryService.executeGroupAction(action, row)"
+                                        *ngFor="let action of userGroupsActions"
+                                        matTooltip="{{action.tooltip}}" mat-icon-button color="accent"
+                                        [disabled]="action.disabled ? '' : null">
+                                    <i class="{{action.icon}}" aria-hidden="true"></i>
+                                </button>
+                                <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>
+                            </div>
+                            <div *ngIf="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"
+                                            matTooltip="{{action.tooltip}}" mat-menu-item
+                                            [disabled]="action.disabled ? '' : null"
+                                            (click)="nfRegistryService.sidenav.toggle()">
+                                        <i class="{{action.icon}}" aria-hidden="true"></i>
+                                        <span>{{action.name}}</span>
+                                    </button>
+                                </mat-menu>
+                                <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>
+                            </div>
+                        </div>
+                        <div *ngIf="!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>
+                        </div>
                     </div>
                 </div>
-                <div class="td-data-table-cell">
-                    <div *ngIf="row.actions">
-                        <div *ngIf="row.actions.length <= 4" fxLayout="row" fxLayoutAlign="end center">
-                            <button (click)="execute(action, row)" *ngFor="let action of row.actions"
-                                    matTooltip="{{action.tooltip}}" mat-icon-button color="accent"
-                                    [disabled]="action.disabled ? '' : null">
-                                <i class="{{action.icon}}" aria-hidden="true"></i>
-                            </button>
-                            <mat-checkbox class="pad-left-sm" [(ngModel)]="row.checked" [checked]="row.checked"
-                                         (change)="nfRegistryService.toggleUserSelect(row)"
-                                         (click)="row.checked = !row.checked;nfRegistryService.toggleUserSelect(row)"></mat-checkbox>
+            </div>
+            <div [ngClass]="{'selected' : row.checked}" *ngFor="let row of nfRegistryService.filteredUsers"
+                 (click)="row.checked = !row.checked;nfRegistryService.determineAllUsersAndGroupsSelectedState(row)">
+                <div *ngFor="let column of nfRegistryService.userColumns" fxLayout="row" fxLayoutAlign="space-between center" class="td-data-table-row">
+                    <div *ngIf="!row.users" class="td-data-table-cell" fxFlex="{{column.width}}">
+                        <div>
+                            {{column.format ? column.format(row[column.name]) : row[column.name]}}
                         </div>
-                        <div *ngIf="row.actions.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)="execute(action, row)" *ngFor="let action of row.actions"
-                                        matTooltip="{{action.tooltip}}" mat-menu-item
-                                        [disabled]="action.disabled ? '' : null"
-                                        (click)="nfRegistryService.sidenav.toggle()">
+                    </div>
+                    <div class="td-data-table-cell">
+                        <div>
+                            <div *ngIf="usersActions.length <= 4" fxLayout="row" fxLayoutAlign="end center">
+                                <button (click)="row.checked = !row.checked;nfRegistryService.executeUserAction(action, row)"
+                                        *ngFor="let action of usersActions"
+                                        matTooltip="{{action.tooltip}}" mat-icon-button color="accent"
+                                        [disabled]="action.disabled ? '' : null">
                                     <i class="{{action.icon}}" aria-hidden="true"></i>
-                                    <span>{{action.name}}</span>
                                 </button>
-                            </mat-menu>
+                                <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>
+                            </div>
+                            <div *ngIf="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"
+                                            matTooltip="{{action.tooltip}}" mat-menu-item
+                                            [disabled]="action.disabled ? '' : null"
+                                            (click)="nfRegistryService.sidenav.toggle()">
+                                        <i class="{{action.icon}}" aria-hidden="true"></i>
+                                        <span>{{action.name}}</span>
+                                    </button>
+                                </mat-menu>
+                                <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>
+                            </div>
+                        </div>
+                        <div *ngIf="!usersActions" fxLayout="row" fxLayoutAlign="end center">
                             <mat-checkbox class="pad-left-sm" [(ngModel)]="row.checked" [checked]="row.checked"
-                                         (change)="nfRegistryService.toggleUserSelect(row)"
-                                         (click)="row.checked = !row.checked;nfRegistryService.toggleUserSelect(row)"></mat-checkbox>
+                                          (change)="nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"
+                                          (click)="row.checked = !row.checked;nfRegistryService.determineAllUsersAndGroupsSelectedState(row)"></mat-checkbox>
                         </div>
                     </div>
-                    <div *ngIf="!row.actions" fxLayout="row" fxLayoutAlign="end center">
-                        <mat-checkbox class="pad-left-sm" [(ngModel)]="row.checked" [checked]="row.checked"
-                                     (change)="nfRegistryService.toggleUserSelect(row)"
-                                     (click)="row.checked = !row.checked;nfRegistryService.toggleUserSelect(row)"></mat-checkbox>
-                    </div>
                 </div>
             </div>
         </div>
-        <div class="mat-padding" *ngIf="!nfRegistryService.filteredUsers.length > 0" layout="row"
+        <div class="mat-padding" *ngIf="nfRegistryService.filteredUsers.length === 0 && nfRegistryService.filteredUserGroups.length === 0" layout="row"
              layout-align="center center">
             <h3>No results to display.</h3>
         </div>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/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 54e5abb..9c833cb 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
@@ -15,25 +15,56 @@
  * limitations under the License.
  */
 var ngCore = require('@angular/core');
+var rxjs = require('rxjs/Rx');
 var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var NfStorage = require('nifi-registry/services/nf-storage.service.js');
 var ngRouter = require('@angular/router');
 var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
+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.
  *
+ * @param nfRegistryApi         The api service.
+ * @param nfStorage             A wrapper for the browser's local storage.
  * @param nfRegistryService     The nf-registry.service module.
- * @param ActivatedRoute        The angular activated route module.
- * @param Router                The angular router module.
- * @param FdsDialogService      The FDS dialog service.
+ * @param activatedRoute        The angular activated route module.
+ * @param fdsDialogService      The FDS dialog service.
+ * @param matDialog             The angular material dialog module.
  * @constructor
  */
-function NfRegistryUsersAdministration(nfRegistryService, ActivatedRoute, Router, FdsDialogService) {
-    this.route = ActivatedRoute;
+function NfRegistryUsersAdministration(nfRegistryApi, nfStorage, nfRegistryService, activatedRoute, fdsDialogService, matDialog) {
+    this.route = activatedRoute;
+    this.nfStorage = nfStorage;
     this.nfRegistryService = nfRegistryService;
-    this.router = Router;
-    this.dialogService = FdsDialogService;
+    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 = {
@@ -44,15 +75,26 @@ NfRegistryUsersAdministration.prototype = {
      */
     ngOnInit: function () {
         var self = this;
-        this.route.params
-            .switchMap(function (params) {
-                self.nfRegistryService.adminPerspective = 'users';
-                return self.nfRegistryService.api.getUsers();
-            })
-            .subscribe(function (users) {
-                self.nfRegistryService.users = self.nfRegistryService.filteredUsers = users;
-                self.nfRegistryService.filterUsers();
+        // 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();
+                    });
             });
+        });
     },
 
     /**
@@ -61,55 +103,46 @@ NfRegistryUsersAdministration.prototype = {
     ngOnDestroy: function () {
         this.nfRegistryService.adminPerspective = '';
         this.nfRegistryService.users = this.nfRegistryService.filteredUsers = [];
-        this.nfRegistryService.allUsersSelected = false;
+        this.nfRegistryService.groups = this.nfRegistryService.filteredUserGroups = [];
+        this.nfRegistryService.allUsersAndGroupsSelected = false;
+        this.nfRegistryService.isMultiUserActionsDisabled = true;
+        this.nfRegistryService.isMultiUserGroupActionsDisabled = false;
     },
 
     /**
-     * Execute the given user action.
-     *
-     * @param action        The action object.
-     * @param user          The user object the `action` will act upon.
+     * Opens the create new bucket dialog.
      */
-    execute: function (action, user) {
-        var self = this;
-        if (user) {
-            user.checked = !user.checked;
-        }
-        switch (action.name.toLowerCase()) {
-            case 'delete':
-                this.dialogService.openConfirm({
-                    title: 'Delete User',
-                    message: 'User will be deleted.',
-                    cancelButton: 'Cancel',
-                    acceptButton: 'Delete',
-                    acceptButtonColor: 'fds-warn'
-                }).afterClosed().subscribe(
-                    function (accept) {
-                        if (accept) {
-                            self.nfRegistryService.api.deleteUser(user.identifier);
-                        }
-                    });
-                break;
-            case 'suspend':
-                this.dialogService.openConfirm({
-                    title: 'Suspend User',
-                    message: 'User permissions will be suspended.',
-                    cancelButton: 'Cancel',
-                    acceptButton: 'Confirm',
-                    acceptButtonColor: 'fds-critical'
-                }).afterClosed().subscribe(
-                    function (accept) {
-                        if (accept) {
-                            self.nfRegistryService.api.suspendUser(user.identifier);
-                        }
-                    });
-                break;
-            case 'add':
-                this.router.navigateByUrl('/nifi-registry/administration/users(sidenav:user/add)');
-                break;
-            default:
-                this.router.navigateByUrl('/nifi-registry/administration/users(' + action.type + ':user/' + action.name + '/' + user.id + ')');
-                break;
+    addUser: function () {
+        this.dialog.open(NfRegistryAddUser);
+    },
+
+    /**
+     * Opens the create new group dialog.
+     */
+    createNewGroup: function () {
+        this.dialog.open(NfRegistryCreateNewGroup);
+    },
+
+    /**
+     * Opens the add selected users to group dialog.
+     */
+    addSelectedUsersToGroup: function () {
+        // the menu button that calls this method should be disabled if a group is selected
+        // let's just make sure
+        var selectedUserGroups = this.nfRegistryService.filteredUserGroups.filter(function (filteredUserGroup) {
+            return filteredUserGroup.checked;
+        });
+
+        if (selectedUserGroups.length > 0) {
+            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'
+            });
+        } else {
+            // ok...only users are currently selected...go ahead and open the dialog to select groups
+            this.dialog.open(NfRegistryAddSelectedUsersToGroup);
         }
     }
 };
@@ -125,10 +158,12 @@ NfRegistryUsersAdministration.annotations = [
 ];
 
 NfRegistryUsersAdministration.parameters = [
+    NfRegistryApi,
+    NfStorage,
     NfRegistryService,
     ngRouter.ActivatedRoute,
-    ngRouter.Router,
-    fdsDialogsModule.FdsDialogService
+    fdsDialogsModule.FdsDialogService,
+    ngMaterial.MatDialog
 ];
 
 module.exports = NfRegistryUsersAdministration;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/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
index d92ed6b..2069e3c 100644
--- 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
@@ -16,13 +16,13 @@ limitations under the License.
 -->
 
 <div fxFill>
-    <div fxLayout="row" fxLayoutAlign="space-between center" class="pad-top-md pad-bottom-md pad-left-sm pad-right-sm">
-        <span class="md-card-title">User Permissions</span>
+    <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" mat-raised-button color="fds-primary"
+    <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/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js
index 726398b..74f5689 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/buckets/permissions/nf-registry-bucket-permissions.js
@@ -16,18 +16,21 @@
  */
 var ngCore = require('@angular/core');
 var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
 var ngRouter = require('@angular/router');
 
 /**
  * NfRegistryBucketPermissions constructor.
  *
+ * @param nfRegistryApi         The api service.
  * @param nfRegistryService     The nf-registry.service module.
  * @param ActivatedRoute        The angular activated route module.
  * @param Router                The angular router module.
  * @constructor
  */
-function NfRegistryBucketPermissions(nfRegistryService, ActivatedRoute, Router) {
+function NfRegistryBucketPermissions(nfRegistryApi, nfRegistryService, ActivatedRoute, Router) {
     this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
     this.route = ActivatedRoute;
     this.router = Router;
 };
@@ -43,7 +46,7 @@ NfRegistryBucketPermissions.prototype = {
         this.nfRegistryService.sidenav.open();
         this.route.params
             .switchMap(function (params) {
-                return self.nfRegistryService.api.getBucket(params['bucketId']);
+                return self.nfRegistryApi.getBucket(params['bucketId']);
             })
             .subscribe(function (bucket) {
                 self.nfRegistryService.bucket = bucket;
@@ -73,6 +76,7 @@ NfRegistryBucketPermissions.annotations = [
 ];
 
 NfRegistryBucketPermissions.parameters = [
+    NfRegistryApi,
     NfRegistryService,
     ngRouter.ActivatedRoute,
     ngRouter.Router

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.html b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.html
index 0c1d87e..6f2f9d0 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.html
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.html
@@ -25,7 +25,7 @@ limitations under the License.
     <div fxLayout="column" fxLayoutAlign="space-between start" class="pad-bottom-md">
         <div class="pad-bottom-md fill-available-width">
             <mat-input-container floatPlaceholder="always" fxFlex>
-                <input #newBucketInput matInput floatPlaceholder="always" placeholder="Bucket Name">
+                <input #newBucketInput matInput floatPlaceholder="always" placeholder="Bucket Name" focused="true">
             </mat-input-container>
         </div>
         <mat-checkbox [(ngModel)]="keepDialogOpen">

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/247985ad/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.js b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.js
index a77e80d..115b699 100644
--- a/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.js
+++ b/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/dialogs/nf-registry-create-bucket.js
@@ -16,17 +16,20 @@
  */
 var ngCore = require('@angular/core');
 var NfRegistryService = require('nifi-registry/services/nf-registry.service.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
 var ngMaterial = require('@angular/material');
 
 /**
  * NfRegistryCreateBucket constructor.
  *
+ * @param nfRegistryApi         The api service.
  * @param nfRegistryService     The nf-registry.service module.
  * @param matDialogRef          The angular material dialog ref.
  * @constructor
  */
-function NfRegistryCreateBucket(nfRegistryService, matDialogRef) {
+function NfRegistryCreateBucket(nfRegistryApi, nfRegistryService, matDialogRef) {
     this.nfRegistryService = nfRegistryService;
+    this.nfRegistryApi = nfRegistryApi;
     this.dialogRef = matDialogRef;
     this.keepDialogOpen = false;
 };
@@ -41,9 +44,10 @@ NfRegistryCreateBucket.prototype = {
      */
     createBucket: function (newBucketInput) {
         var self = this;
-        this.nfRegistryService.api.createBucket(newBucketInput.value).subscribe(function (bucket) {
+        this.nfRegistryApi.createBucket(newBucketInput.value).subscribe(function (bucket) {
             self.nfRegistryService.buckets.push(bucket);
             self.nfRegistryService.filterBuckets();
+            self.nfRegistryService.allBucketsSelected = false;
             if (self.keepDialogOpen !== true) {
                 self.dialogRef.close();
             }
@@ -65,6 +69,7 @@ NfRegistryCreateBucket.annotations = [
 ];
 
 NfRegistryCreateBucket.parameters = [
+    NfRegistryApi,
     NfRegistryService,
     ngMaterial.MatDialogRef
 ];


Mime
View raw message