http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
new file mode 100644
index 0000000..978244c
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
@@ -0,0 +1,82 @@
+/*
+ * 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 rxjs = require('rxjs/Rx');
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+var ngRouter = require('@angular/router');
+var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
+
+/**
+ * NfRegistryBucketGridListViewer constructor.
+ *
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param ActivatedRoute        The angular activated route module.
+ * @constructor
+ */
+function NfRegistryBucketGridListViewer(nfRegistryService, ActivatedRoute) {
+    this.route = ActivatedRoute;
+    this.nfRegistryService = nfRegistryService;
+};
+
+NfRegistryBucketGridListViewer.prototype = {
+    constructor: NfRegistryBucketGridListViewer,
+
+    /**
+     * Initialize the component.
+     */
+    ngOnInit: function () {
+        var self = this;
+        this.nfRegistryService.explorerViewType = 'grid-list';
+        this.route.params
+            .switchMap(function (params) {
+                return new rxjs.Observable.forkJoin(
+                    self.nfRegistryService.api.getBuckets(),
+                    self.nfRegistryService.api.getDroplets(params['bucketId']),
+                    self.nfRegistryService.api.getBucket(params['bucketId'])
+                );
+            })
+            .subscribe(function (response) {
+                var buckets = response[0];
+                var droplets = response[1];
+                var bucket = response[2];
+                self.nfRegistryService.bucket = bucket;
+                self.nfRegistryService.buckets = buckets;
+                self.nfRegistryService.droplets = droplets;
+                self.nfRegistryService.filterDroplets();
+                self.nfRegistryService.setBreadcrumbState('in');
+            });
+    },
+
+    /**
+     * Destroy the component.
+     */
+    ngOnDestroy: function () {
+        this.nfRegistryService.bucket = {};
+        this.nfRegistryService.setBreadcrumbState('out');
+    }
+};
+
+NfRegistryBucketGridListViewer.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-grid-list-viewer.html!text'),
+        animations: [nfRegistryAnimations.flyInOutAnimation]
+    })
+];
+
+NfRegistryBucketGridListViewer.parameters = [NfRegistryService, 
ngRouter.ActivatedRoute];
+
+module.exports = NfRegistryBucketGridListViewer;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
new file mode 100644
index 0000000..7f17b15
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
@@ -0,0 +1,185 @@
+/*
+ * 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 NfRegistryRoutes = require('nifi-registry/nf-registry.routes.js');
+var ngCoreTesting = require('@angular/core/testing');
+var ngHttpTesting = require('@angular/http/testing');
+var ngCommon = require('@angular/common');
+var ngRouter = require('@angular/router');
+var FdsDemo = 
require('nifi-registry/components/fluid-design-system/fds-demo.js');
+var NfRegistry = require('nifi-registry/nf-registry.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+var NfPageNotFoundComponent = 
require('nifi-registry/components/page-not-found/nf-registry-page-not-found.js');
+var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-explorer.js');
+var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
+var NfRegistryGeneralAdministration = 
require('nifi-registry/components/administration/general/nf-registry-general-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 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 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');
+var NfRegistryBucketGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js');
+var NfRegistryDropletGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js');
+var fdsCore = require('@fluid-design-system/core');
+var ngMoment = require('angular2-moment');
+var rxjs = require('rxjs/Rx');
+var ngHttp = require('@angular/http');
+
+describe('NfRegistryBucketGridListViewer Component', function () {
+    var comp;
+    var fixture;
+    var nfRegistryService;
+    var nfRegistryApi;
+    var ngHttpService;
+
+    beforeEach(function () {
+        ngCoreTesting.TestBed.configureTestingModule({
+            imports: [
+                ngMoment.MomentModule,
+                ngHttp.HttpModule,
+                ngHttp.JsonpModule,
+                fdsCore,
+                NfRegistryRoutes
+            ],
+            declarations: [
+                FdsDemo,
+                NfRegistry,
+                NfRegistryExplorer,
+                NfRegistryAdministration,
+                NfRegistryGeneralAdministration,
+                NfRegistryUsersAdministration,
+                NfRegistryUserDetails,
+                NfRegistryUserPermissions,
+                NfRegistryBucketPermissions,
+                NfRegistryAddUser,
+                NfRegistryWorkflowAdministration,
+                NfRegistryGridListViewer,
+                NfRegistryBucketGridListViewer,
+                NfRegistryDropletGridListViewer,
+                NfPageNotFoundComponent
+            ],
+            providers: [
+                NfRegistryApi,
+                NfRegistryService,
+                {
+                    provide: ngCommon.APP_BASE_HREF,
+                    useValue: '/'
+                },
+                {
+                    provide: ngRouter.ActivatedRoute,
+                    useValue: {
+                        params: rxjs.Observable.of({bucketId: 
'2f7f9e54-dc09-4ceb-aa58-9fe581319cdc'})
+                    }
+                },
+                {
+                    provide: ngHttp.XHRBackend,
+                    useClass: ngHttpTesting.MockBackend
+                }
+            ]
+        });
+        fixture = 
ngCoreTesting.TestBed.createComponent(NfRegistryBucketGridListViewer);
+
+        // test instance
+        comp = fixture.componentInstance;
+
+        // from the root injector
+        nfRegistryService = ngCoreTesting.TestBed.get(NfRegistryService);
+        nfRegistryApi = ngCoreTesting.TestBed.get(NfRegistryApi);
+        ngHttpService = ngCoreTesting.TestBed.get(ngHttp.Http);
+
+        // because the NfRegistryBucketGridListViewer component is a nested 
route component we need to set up the nfRegistryService service manually
+        nfRegistryService.explorerViewType = 'grid-list';
+
+        //Spy
+        spyOn(ngHttpService, 'get').and.callThrough();
+        spyOn(nfRegistryApi, 'getBuckets').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of([{
+            identifier: '2f7f9e54-dc09-4ceb-aa58-9fe581319cdc',
+            name: 'Bucket #1'
+        }]));
+        spyOn(nfRegistryApi, 'getBucket').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of({
+            identifier: '2f7f9e54-dc09-4ceb-aa58-9fe581319cdc',
+            name: 'Bucket #1'
+        }));
+        spyOn(nfRegistryService, 'filterDroplets');
+    });
+
+    it('should have a defined component', ngCoreTesting.fakeAsync(function () {
+        spyOn(nfRegistryApi, 'getDroplets').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of([{
+            "identifier": "2e04b4fb-9513-47bb-aa74-1ae34616bfdc",
+            "name": "Flow #1",
+            "description": "This is flow #1",
+            "bucketIdentifier": "2f7f9e54-dc09-4ceb-aa58-9fe581319cdc",
+            "createdTimestamp": 1505931890999,
+            "modifiedTimestamp": 1505931890999,
+            "type": "FLOW",
+            "snapshotMetadata": null,
+            "link": {
+                "params": {
+                    "rel": "self"
+                },
+                "href": "flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc"
+            }
+        }]));
+        // 1st change detection triggers ngOnInit which makes getBuckets, 
getBucket, and getDroplets calls
+        fixture.detectChanges();
+        // wait for async getBuckets, getBucket, and getDroplets calls
+        ngCoreTesting.tick();
+        // 2nd change detection completes after the getBuckets, getBucket, and 
getDroplets calls
+        fixture.detectChanges();
+
+        //assertions
+        expect(comp).toBeDefined();
+        expect(nfRegistryService.breadCrumbState).toBe('in');
+        expect(nfRegistryService.bucket.name).toEqual('Bucket #1');
+        expect(nfRegistryService.buckets[0].name).toEqual('Bucket #1');
+        expect(nfRegistryService.buckets.length).toBe(1);
+        expect(nfRegistryService.droplets[0].name).toEqual('Flow #1');
+        expect(nfRegistryService.droplets.length).toBe(1);
+        expect(nfRegistryApi.getBuckets).toHaveBeenCalled();
+        expect(nfRegistryService.filterDroplets).toHaveBeenCalled();
+        expect(nfRegistryService.filterDroplets.calls.count()).toBe(1);
+
+        var getDropletsCall = nfRegistryApi.getDroplets.calls.first()
+        
expect(getDropletsCall.args[0]).toBe('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        var getBucketCall = nfRegistryApi.getBucket.calls.first()
+        
expect(getBucketCall.args[0]).toBe('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+    }));
+
+    it('should destroy the component', ngCoreTesting.fakeAsync(function () {
+        spyOn(nfRegistryApi, 'getDroplets').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of([]));
+        // 1st change detection triggers ngOnInit which makes getBuckets, 
getBucket, and getDroplets calls
+        fixture.detectChanges();
+        // wait for async getBuckets, getBucket, and getDroplets calls
+        ngCoreTesting.tick();
+        // 2nd change detection completes after the getBuckets, getBucket, and 
getDroplets calls
+        fixture.detectChanges();
+
+        // The function to test
+        comp.ngOnDestroy();
+
+        //assertions
+        expect(nfRegistryService.bucket.identifier).toBeUndefined();
+        expect(nfRegistryService.breadCrumbState).toBe('out');
+    }));
+});

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
new file mode 100644
index 0000000..3d3d4e4
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var ngCore = require('@angular/core');
+var rxjs = require('rxjs/Rx');
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+var ngRouter = require('@angular/router');
+var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
+
+/**
+ * NfRegistryDropletGridListViewer constructor.
+ *
+ * @param nfRegistryService     The nf-registry.service module.
+ * @param ActivatedRoute        The angular activated route module.
+ * @constructor
+ */
+function NfRegistryDropletGridListViewer(nfRegistryService, ActivatedRoute) {
+    this.route = ActivatedRoute;
+    this.nfRegistryService = nfRegistryService;
+};
+
+NfRegistryDropletGridListViewer.prototype = {
+    constructor: NfRegistryDropletGridListViewer,
+
+    /**
+     * Initialize the component.
+     */
+    ngOnInit: function () {
+        var self = this;
+        this.nfRegistryService.explorerViewType = 'grid-list';
+        this.route.params
+            .switchMap(function (params) {
+                return new rxjs.Observable.forkJoin(
+                    self.nfRegistryService.api.getDroplet(params['bucketId'], 
params['dropletType'], params['dropletId']),
+                    self.nfRegistryService.api.getBucket(params['bucketId']),
+                    self.nfRegistryService.api.getBuckets(),
+                    self.nfRegistryService.api.getDroplets(params['bucketId'])
+                );
+            })
+            .subscribe(function (response) {
+                var droplet = response[0];
+                var bucket = response[1];
+                var buckets = response[2];
+                var droplets = response[3];
+                self.nfRegistryService.bucket = bucket;
+                self.nfRegistryService.buckets = buckets;
+                self.nfRegistryService.droplet = droplet;
+                self.nfRegistryService.droplets = droplets;
+                self.nfRegistryService.filterDroplets();
+                self.nfRegistryService.setBreadcrumbState('in');
+            });
+    },
+
+    /**
+     * Destroy the component.
+     */
+    ngOnDestroy: function () {
+        this.nfRegistryService.bucket = {};
+        this.nfRegistryService.droplet = {};
+        this.nfRegistryService.setBreadcrumbState('out');
+    }
+};
+
+NfRegistryDropletGridListViewer.annotations = [
+    new ngCore.Component({
+        template: require('./nf-registry-grid-list-viewer.html!text'),
+        animations: [nfRegistryAnimations.flyInOutAnimation]
+    })
+];
+
+NfRegistryDropletGridListViewer.parameters = [NfRegistryService, 
ngRouter.ActivatedRoute];
+
+module.exports = NfRegistryDropletGridListViewer;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
new file mode 100644
index 0000000..1f98c80
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
@@ -0,0 +1,214 @@
+/*
+ * 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 NfRegistryRoutes = require('nifi-registry/nf-registry.routes.js');
+var ngCoreTesting = require('@angular/core/testing');
+var ngHttpTesting = require('@angular/http/testing');
+var ngCommon = require('@angular/common');
+var ngRouter = require('@angular/router');
+var FdsDemo = 
require('nifi-registry/components/fluid-design-system/fds-demo.js');
+var NfRegistry = require('nifi-registry/nf-registry.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+var NfPageNotFoundComponent = 
require('nifi-registry/components/page-not-found/nf-registry-page-not-found.js');
+var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-explorer.js');
+var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
+var NfRegistryGeneralAdministration = 
require('nifi-registry/components/administration/general/nf-registry-general-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 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 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');
+var NfRegistryBucketGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js');
+var NfRegistryDropletGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js');
+var fdsCore = require('@fluid-design-system/core');
+var ngMoment = require('angular2-moment');
+var rxjs = require('rxjs/Rx');
+var ngHttp = require('@angular/http');
+
+describe('NfRegistryDropletGridListViewer Component', function () {
+    var comp;
+    var fixture;
+    var nfRegistryService;
+    var nfRegistryApi;
+    var ngHttpService;
+
+    beforeEach(function () {
+        ngCoreTesting.TestBed.configureTestingModule({
+            imports: [
+                ngMoment.MomentModule,
+                ngHttp.HttpModule,
+                ngHttp.JsonpModule,
+                fdsCore,
+                NfRegistryRoutes
+            ],
+            declarations: [
+                FdsDemo,
+                NfRegistry,
+                NfRegistryExplorer,
+                NfRegistryAdministration,
+                NfRegistryGeneralAdministration,
+                NfRegistryUsersAdministration,
+                NfRegistryUserDetails,
+                NfRegistryUserPermissions,
+                NfRegistryBucketPermissions,
+                NfRegistryAddUser,
+                NfRegistryWorkflowAdministration,
+                NfRegistryGridListViewer,
+                NfRegistryBucketGridListViewer,
+                NfRegistryDropletGridListViewer,
+                NfPageNotFoundComponent
+            ],
+            providers: [
+                NfRegistryApi,
+                NfRegistryService,
+                {
+                    provide: ngCommon.APP_BASE_HREF,
+                    useValue: '/'
+                }, {
+                    provide: ngRouter.ActivatedRoute,
+                    useValue: {
+                        params: rxjs.Observable.of({
+                            bucketId: '2f7f9e54-dc09-4ceb-aa58-9fe581319cdc',
+                            dropletId: '2e04b4fb-9513-47bb-aa74-1ae34616bfdc',
+                            dropletType: 'flow'
+                        })
+                    }
+                },
+                {
+                    provide: ngHttp.XHRBackend,
+                    useClass: ngHttpTesting.MockBackend
+                }
+            ]
+        });
+
+        fixture = 
ngCoreTesting.TestBed.createComponent(NfRegistryDropletGridListViewer);
+
+        // test instance
+        comp = fixture.componentInstance;
+
+        // from the root injector
+        nfRegistryService = ngCoreTesting.TestBed.get(NfRegistryService);
+        nfRegistryApi = ngCoreTesting.TestBed.get(NfRegistryApi);
+        ngHttpService = ngCoreTesting.TestBed.get(ngHttp.Http);
+
+        // because the NfRegistryDropletGridListViewer component is a nested 
route component we need to set up the nfRegistryService service manually
+        nfRegistryService.perspective = 'explorer';
+        nfRegistryService.explorerViewType = 'grid-list';
+
+        //Spy
+        spyOn(ngHttpService, 'get').and.callThrough();
+        spyOn(nfRegistryApi, 'getDroplet').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of({
+            "identifier": "2e04b4fb-9513-47bb-aa74-1ae34616bfdc",
+            "name": "Flow #1",
+            "description": "This is flow #1",
+            "bucketIdentifier": "2f7f9e54-dc09-4ceb-aa58-9fe581319cdc",
+            "createdTimestamp": 1505931890999,
+            "modifiedTimestamp": 1505931890999,
+            "type": "FLOW",
+            "snapshotMetadata": null,
+            "link": {
+                "params": {
+                    "rel": "self"
+                },
+                "href": "flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc"
+            }
+        }));
+        spyOn(nfRegistryApi, 'getBuckets').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of([{
+            identifier: '2f7f9e54-dc09-4ceb-aa58-9fe581319cdc',
+            name: 'Bucket #1'
+        }]));
+        spyOn(nfRegistryApi, 'getBucket').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of({
+            identifier: '2f7f9e54-dc09-4ceb-aa58-9fe581319cdc',
+            name: 'Bucket #1'
+        }));
+        spyOn(nfRegistryService, 'filterDroplets');
+    });
+
+    it('should have a defined component', ngCoreTesting.fakeAsync(function () {
+        spyOn(nfRegistryApi, 'getDroplets').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of([{
+            "identifier": "2e04b4fb-9513-47bb-aa74-1ae34616bfdc",
+            "name": "Flow #1",
+            "description": "This is flow #1",
+            "bucketIdentifier": "2f7f9e54-dc09-4ceb-aa58-9fe581319cdc",
+            "createdTimestamp": 1505931890999,
+            "modifiedTimestamp": 1505931890999,
+            "type": "FLOW",
+            "snapshotMetadata": null,
+            "link": {
+                "params": {
+                    "rel": "self"
+                },
+                "href": "flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc"
+            }
+        }]));
+        // 1st change detection triggers ngOnInit which makes getBuckets, 
getBucket, getDroplet, and getDroplets calls
+        fixture.detectChanges();
+        // wait for async getBuckets, getBucket, getDroplet, and getDroplets 
calls
+        ngCoreTesting.tick();
+        // 2nd change detection completes after the getBuckets, getBucket, 
getDroplet, and getDroplets calls
+        fixture.detectChanges();
+
+        //assertions
+        expect(comp).toBeDefined();
+        expect(nfRegistryService.breadCrumbState).toBe('in');
+        expect(nfRegistryService.bucket.name).toEqual('Bucket #1');
+        expect(nfRegistryService.buckets[0].name).toEqual('Bucket #1');
+        expect(nfRegistryService.buckets.length).toBe(1);
+        expect(nfRegistryService.droplet.name).toEqual('Flow #1');
+        expect(nfRegistryService.droplets[0].name).toEqual('Flow #1');
+        expect(nfRegistryService.droplets.length).toBe(1);
+        expect(nfRegistryApi.getBuckets).toHaveBeenCalled();
+        expect(nfRegistryService.filterDroplets).toHaveBeenCalled();
+        expect(nfRegistryService.filterDroplets.calls.count()).toBe(1);
+
+        var getDropletsCall = nfRegistryApi.getDroplets.calls.first();
+        
expect(getDropletsCall.args[0]).toBe('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+
+        var getDropletCall = nfRegistryApi.getDroplet.calls.first();
+        
expect(getDropletCall.args[0]).toBe('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        expect(getDropletCall.args[1]).toBe('flow');
+        
expect(getDropletCall.args[2]).toBe('2e04b4fb-9513-47bb-aa74-1ae34616bfdc');
+
+        var getBucketCall = nfRegistryApi.getBucket.calls.first()
+        
expect(getBucketCall.args[0]).toBe('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+    }));
+
+    it('should destroy the component', ngCoreTesting.fakeAsync(function () {
+        spyOn(nfRegistryApi, 'getDroplets').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of([]));
+        // 1st change detection triggers ngOnInit which makes getBuckets, 
getBucket, getDroplet, and getDroplets calls
+        fixture.detectChanges();
+        // wait for async getBuckets, getBucket, getDroplet, and getDroplets 
calls
+        ngCoreTesting.tick();
+        // 2nd change detection completes after the getBuckets, getBucket, 
getDroplet, and getDroplets calls
+        fixture.detectChanges();
+
+        // The function to test
+        comp.ngOnDestroy();
+
+        //assertions
+        expect(nfRegistryService.droplet.identifier).toBeUndefined();
+        expect(nfRegistryService.breadCrumbState).toBe('out');
+    }));
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html
 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html
index d6113c0..2f0b343 100644
--- 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html
@@ -16,84 +16,12 @@ limitations under the License.
 -->
 
 <div class="pad-top-sm pad-bottom-sm pad-right-xxl pad-left-xxl">
-    <div *ngIf="false" class="pad-top-md pad-bottom-sm">
-        <md-button-toggle-group fxLayout="row" fxLayoutAlign="space-between 
center"
-                                class="expansion-panel-filter-toggle-group" 
multiple>
-            <md-button-toggle 
(change)="nfRegistryService.toggleDropletsFilter('type:asset')"
-                              
[checked]="nfRegistryService.isDropletFilterChecked('type:asset')">
-                <div fxFlex fxLayout="column" fxLayoutAlign="space-around 
stretch">
-                    <div class="md-display-1 pad-top-sm" fxFlex="55">
-                        {{nfRegistryService.getDropletTypeCount('asset')}}
-                    </div>
-                    <div class="pad-top-sm" fxFlex="45">Assets</div>
-                </div>
-            </md-button-toggle>
-            <md-button-toggle 
(change)="nfRegistryService.toggleDropletsFilter('type:extension')"
-                              
[checked]="nfRegistryService.isDropletFilterChecked('type:extension')">
-                <div fxFlex fxLayout="column" fxLayoutAlign="space-around 
stretch">
-                    <div class="md-display-1 pad-top-sm" fxFlex="55">
-                        {{nfRegistryService.getDropletTypeCount('extension')}}
-                    </div>
-                    <div class="pad-top-sm" fxFlex="45">Extensions</div>
-                </div>
-            </md-button-toggle>
-            <md-button-toggle 
(change)="nfRegistryService.toggleDropletsFilter('type:flow')"
-                              
[checked]="nfRegistryService.isDropletFilterChecked('type:flow')">
-                <div fxFlex fxLayout="column" fxLayoutAlign="space-around 
stretch">
-                    <div class="md-display-1 pad-top-sm" 
fxFlex="55">{{nfRegistryService.getDropletTypeCount('flow')}}
-                    </div>
-                    <div class="pad-top-sm" fxFlex="45">Flows</div>
-                </div>
-            </md-button-toggle>
-            <md-button-toggle 
(change)="nfRegistryService.toggleDropletsFilter('compliant.label:Compliant')"
-                              
[checked]="nfRegistryService.isDropletFilterChecked('compliant.label:Compliant')">
-                <div fxFlex fxLayout="column" fxLayoutAlign="space-around 
stretch">
-                    <div class="md-display-1 pad-top-sm" fxFlex="55">
-                        
{{nfRegistryService.getDropletCertificationCount('compliant')}}
-                    </div>
-                    <div class="pad-top-sm" fxFlex="45">Compliant</div>
-                </div>
-            </md-button-toggle>
-            <md-button-toggle 
(change)="nfRegistryService.toggleDropletsFilter('fleet.label:Fleet')"
-                              
[checked]="nfRegistryService.isDropletFilterChecked('fleet.label:Fleet')">
-                <div fxFlex fxLayout="column" fxLayoutAlign="space-around 
stretch">
-                    <div class="md-display-1 pad-top-sm" fxFlex="55">
-                        
{{nfRegistryService.getDropletCertificationCount('fleet')}}
-                    </div>
-                    <div class="pad-top-sm" fxFlex="45">Fleet</div>
-                </div>
-            </md-button-toggle>
-            <md-button-toggle 
(change)="nfRegistryService.toggleDropletsFilter('prod.label:Production Ready')"
-                              
[checked]="nfRegistryService.isDropletFilterChecked('prod.label:Production 
Ready')">
-                <div fxFlex fxLayout="column" fxLayoutAlign="space-around 
stretch">
-                    <div class="md-display-1 pad-top-sm" fxFlex="55">
-                        
{{nfRegistryService.getDropletCertificationCount('prod')}}
-                    </div>
-                    <div class="pad-top-sm" fxFlex="45">Production Ready</div>
-                </div>
-            </md-button-toggle>
-            <md-button-toggle 
(change)="nfRegistryService.toggleDropletsFilter('secure.label:Secure')"
-                              
[checked]="nfRegistryService.isDropletFilterChecked('secure.label:Secure')">
-                <div fxFlex fxLayout="column" fxLayoutAlign="space-around 
stretch">
-                    <div class="md-display-1 pad-top-sm" fxFlex="55">
-                        
{{nfRegistryService.getDropletCertificationCount('secure')}}
-                    </div>
-                    <div class="pad-top-sm" fxFlex="45">Secure</div>
-                </div>
-            </md-button-toggle>
-        </md-button-toggle-group>
-        <div id="nf-registry-droplet-filter-clear-grouping-button-container">
-            <span *ngIf="nfRegistryService.dropletsSearchTerms.length > 0"
-                  (click)="nfRegistryService.dropletsSearchTerms = 
[];nfRegistryService.filterDroplets(nfRegistryService.activeDropletColumn.name, 
nfRegistryService.activeDropletColumn.sortOrder);"><i
-                    class="fa fa-plus-circle fa-rotate-45" 
aria-hidden="true"></i><span class="pad-left-sm link">Clear 
Grouping</span></span>
-        </div>
-    </div>
     <div layout="row" layout-align="space-between center">
         <div flex fxLayout="row" fxLayoutAlign="end center">
             <td-chips [(ngModel)]="nfRegistryService.dropletsSearchTerms"
                       [items]="nfRegistryService.autoCompleteDroplets"
-                      (add)="nfRegistryService.dropletsSearchAdd($event)"
-                      
(remove)="nfRegistryService.dropletsSearchRemove($event)" 
class="push-right-sm"></td-chips>
+                      
(add)="nfRegistryService.filterDroplets(nfRegistryService.activeDropletColumn.name,
 nfRegistryService.activeDropletColumn.sortOrder);"
+                      
(remove)="nfRegistryService.filterDroplets(nfRegistryService.activeDropletColumn.name,
 nfRegistryService.activeDropletColumn.sortOrder);" 
class="push-right-sm"></td-chips>
             <span class="pad-right-sm">Sort by:</span>
             <div fxLayout="row" fxLayoutAlign="end center" 
[mdMenuTriggerFor]="dropletGridSortMenu">
                 <div 
id="droplet-sort-by-field">{{nfRegistryService.getSortByLabel()}}</div>
@@ -102,7 +30,7 @@ limitations under the License.
         </div>
         <md-menu #dropletGridSortMenu="mdMenu" [overlapTrigger]="false">
             <div *ngFor="let column of nfRegistryService.dropletColumns">
-                <button md-menu-item *ngIf="column.sortable" 
(click)="nfRegistryService.sortDroplets($event, column);">
+                <button md-menu-item *ngIf="column.sortable" 
(click)="nfRegistryService.sortDroplets(column);">
                     {{nfRegistryService.generateSortMenuLabels(column)}}
                 </button>
             </div>
@@ -112,18 +40,18 @@ limitations under the License.
 <div id="nifi-registry-explorer-grid-list-viewer-droplet-container" 
class="pad-right-xxl pad-left-xxl"
      *ngIf="nfRegistryService.filteredDroplets.length > 0">
     <div *ngFor="let droplet of nfRegistryService.filteredDroplets" 
[@flyInOut]>
-        <td-expansion-panel class="mat-elevation-z5" label={{droplet.label}} 
sublabel={{droplet.sublabel}}
-                            [disabled]="disabled">
+        <td-expansion-panel class="mat-elevation-z5" label={{droplet.name}} 
sublabel={{droplet.type}}
+                            [disabled]="disabled" 
(expanded)="nfRegistryService.getDropletSnapshotMetadata(droplet)">
             <ng-template td-expansion-panel-label>
                 <div fxLayout="column" fxLayoutAlign="space-between start">
-                    <span class="md-title 
capitalize">{{droplet.displayName}}</span>
+                    <span class="md-title capitalize">{{droplet.name}}</span>
                     <span class="md-subhead">{{droplet.type}}</span>
                 </div>
             </ng-template>
             <ng-template td-expansion-panel-sublabel>
                 <div fxLayout="row" fxLayoutAlign="space-between center">
                     <div class="pad-right-xxl pad-left-xxl" fxLayout="column" 
fxLayoutAlign="space-between start">
-                        <span class="uppercase">Versions</span> 
{{droplet.versions.length}}
+                        <span class="uppercase">Versions</span> 
{{droplet.versionCount}}
                     </div>
                 </div>
             </ng-template>
@@ -135,8 +63,8 @@ limitations under the License.
                         </button>
                         <md-menu class="fds-primary-dropdown-button-menu" 
#primaryButtonDropdownMenu="mdMenu"
                                  [overlapTrigger]="false">
-                            <button md-menu-item *ngFor="let action of 
droplet.actions"
-                                    (click)="execute(action, droplet)">
+                            <button md-menu-item *ngFor="let action of 
dropletActions"
+                                    
(click)="nfRegistryService.executeDropletAction(action, droplet)">
                                 <span>{{action.name}}</span>
                             </button>
                         </md-menu>
@@ -156,18 +84,18 @@ limitations under the License.
                         <div 
id="nifi-registry-explorer-grid-list-viewer-droplet-container-details-change-log"
                              fxFlex="75">
                             <td-steps mode="vertical">
-                                <td-step label="{{version.revision}}" 
sublabel="by {{version.author}}"
-                                         *ngFor="let version of 
droplet.versions; let i = index"
+                                <td-step label="{{snapshotMeta.version}}" 
sublabel="by {{snapshotMeta.author}}"
+                                         *ngFor="let snapshotMeta of 
droplet.snapshotMetadata; let i = index"
                                          [active]="i === 0 ? true : false">
                                     <ng-template td-step-label>
-                                        <span>{{version.created | 
amTimeAgo}}</span>
+                                        <span>{{snapshotMeta.timestamp | 
amTimeAgo}}</span>
                                     </ng-template>
                                     <div fxLayout="column" 
fxLayoutAlign="space-between stretch">
                                         <div fxLayout="row" class="md-body-2">
-                                            {{version.comment}}
+                                            {{snapshotMeta.comments}}
                                         </div>
                                         <div fxLayout="row" class="md-caption">
-                                            {{version.created}}
+                                            {{(snapshotMeta.timestamp | 
amFromUnix) | amDateFormat:'MMM-DD-YYYY'}} at {{(snapshotMeta.timestamp | 
amFromUnix) | amDateFormat:'h:mm A'}}
                                         </div>
                                     </div>
                                 </td-step>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js
 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js
index a7aa2fd..599bea3 100644
--- 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.js
@@ -15,23 +15,26 @@
  * 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 ngRouter = require('@angular/router');
 var nfRegistryAnimations = require('nifi-registry/nf-registry.animations.js');
-var fdsDialogsModule = require('@fluid-design-system/dialogs');
 
 /**
  * NfRegistryGridListViewer constructor.
  *
  * @param nfRegistryService     The nf-registry.service module.
  * @param ActivatedRoute        The angular activated route module.
- * @param TdDialogService       The covalent dialog service module.
  * @constructor
  */
-function NfRegistryGridListViewer(nfRegistryService, ActivatedRoute, 
FdsDialogService) {
+function NfRegistryGridListViewer(nfRegistryService, ActivatedRoute) {
     this.route = ActivatedRoute;
     this.nfRegistryService = nfRegistryService;
-    this.dialogService = FdsDialogService;
+    this.dropletActions = [{
+        'name': 'Delete',
+        'icon': 'fa fa-trash',
+        'tooltip': 'Delete'
+    }];
 };
 
 NfRegistryGridListViewer.prototype = {
@@ -45,17 +48,16 @@ NfRegistryGridListViewer.prototype = {
         this.nfRegistryService.explorerViewType = 'grid-list';
         this.route.params
             .switchMap(function (params) {
-                return 
self.nfRegistryService.getRegistry(params['registryId']);
+                return new 
rxjs.Observable.forkJoin(self.nfRegistryService.api.getDroplets(),
+                    self.nfRegistryService.api.getBuckets());
             })
-            .subscribe(function (registry) {
-                self.nfRegistryService.registry = registry;
-                
self.nfRegistryService.getBuckets(self.nfRegistryService.registry.id).then(function
 (buckets) {
-                    self.nfRegistryService.buckets = buckets;
-                    
self.nfRegistryService.getDroplets(self.nfRegistryService.registry.id, 
self.nfRegistryService.bucket.id, 
self.nfRegistryService.droplet.id).then(function (droplets) {
-                        self.nfRegistryService.droplets = 
self.nfRegistryService.filteredDroplets = droplets;
-                        self.nfRegistryService.filterDroplets();
-                    });
-                })
+            .subscribe(function (response) {
+                var droplets = response[0];
+                var buckets = response[1];
+                self.nfRegistryService.buckets = buckets;
+                self.nfRegistryService.droplets = droplets;
+                self.nfRegistryService.filterDroplets();
+                self.nfRegistryService.setBreadcrumbState('in');
             });
     },
 
@@ -63,34 +65,11 @@ NfRegistryGridListViewer.prototype = {
      * Destroy the component.
      */
     ngOnDestroy: function () {
-        this.nfRegistryService.registry = {};
+        this.nfRegistryService.explorerViewType = '';
         this.nfRegistryService.buckets = [];
         this.nfRegistryService.droplets = [];
         this.nfRegistryService.filteredDroplets = [];
-    },
-
-    /**
-     * Execute the given droplet action.
-     *
-     * @param action        The action object.
-     * @param droplet       The droplet object the `action` will act upon.
-     */
-    execute: function (action, droplet) {
-        var self = this;
-        if (action.name.toLowerCase() === 'delete') {
-            this.dialogService.openConfirm({
-                title: 'Delete Data Flow',
-                message: 'All versions of this data flow will be deleted.',
-                cancelButton: 'Cancel',
-                acceptButton: 'Delete',
-                acceptButtonColor: 'fds-warn'
-            }).afterClosed().subscribe(
-                function (accept) {
-                    if (accept) {
-                        self.nfRegistryService.deleteDroplet(droplet.id);
-                    }
-                });
-        }
+        this.nfRegistryService.setBreadcrumbState('out');
     }
 };
 
@@ -101,6 +80,6 @@ NfRegistryGridListViewer.annotations = [
     })
 ];
 
-NfRegistryGridListViewer.parameters = [NfRegistryService, 
ngRouter.ActivatedRoute, fdsDialogsModule.FdsDialogService];
+NfRegistryGridListViewer.parameters = [NfRegistryService, 
ngRouter.ActivatedRoute];
 
 module.exports = NfRegistryGridListViewer;

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.spec.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.spec.js
 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.spec.js
new file mode 100644
index 0000000..51af529
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.spec.js
@@ -0,0 +1,172 @@
+/*
+ * 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 NfRegistryRoutes = require('nifi-registry/nf-registry.routes.js');
+var ngCoreTesting = require('@angular/core/testing');
+var ngCommon = require('@angular/common');
+var ngRouter = require('@angular/router');
+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');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+var NfPageNotFoundComponent = 
require('nifi-registry/components/page-not-found/nf-registry-page-not-found.js');
+var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-explorer.js');
+var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
+var NfRegistryGeneralAdministration = 
require('nifi-registry/components/administration/general/nf-registry-general-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 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 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');
+var NfRegistryBucketGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js');
+var NfRegistryDropletGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js');
+var fdsCore = require('@fluid-design-system/core');
+var ngMoment = require('angular2-moment');
+var rxjs = require('rxjs/Rx');
+var ngHttp = require('@angular/http');
+
+describe('NfRegistryGridListViewer Component', function () {
+    var comp;
+    var fixture;
+    var de;
+    var el;
+    var nfRegistryService;
+    var nfRegistryApi;
+
+    beforeEach(function () {
+        ngCoreTesting.TestBed.configureTestingModule({
+            imports: [
+                ngMoment.MomentModule,
+                ngHttp.HttpModule,
+                ngHttp.JsonpModule,
+                fdsCore,
+                NfRegistryRoutes
+            ],
+            declarations: [
+                FdsDemo,
+                NfRegistry,
+                NfRegistryExplorer,
+                NfRegistryAdministration,
+                NfRegistryGeneralAdministration,
+                NfRegistryUsersAdministration,
+                NfRegistryUserDetails,
+                NfRegistryUserPermissions,
+                NfRegistryBucketPermissions,
+                NfRegistryAddUser,
+                NfRegistryWorkflowAdministration,
+                NfRegistryGridListViewer,
+                NfRegistryBucketGridListViewer,
+                NfRegistryDropletGridListViewer,
+                NfPageNotFoundComponent
+            ],
+            providers: [
+                NfRegistryApi,
+                NfRegistryService, {
+                    provide: ngCommon.APP_BASE_HREF,
+                    useValue: '/'
+                }, {
+                    provide: ngRouter.ActivatedRoute,
+                    useValue: {
+                        params: rxjs.Observable.of({})
+                    }
+                }
+            ]
+        });
+
+        fixture = 
ngCoreTesting.TestBed.createComponent(NfRegistryGridListViewer);
+
+        // test instance
+        comp = fixture.componentInstance;
+
+        // from the root injector
+        nfRegistryService = ngCoreTesting.TestBed.get(NfRegistryService);
+        nfRegistryApi = ngCoreTesting.TestBed.get(NfRegistryApi);
+
+        // because the NfRegistryGridListViewer component is a nested route 
component we need to set up the nfRegistryService service manually
+        nfRegistryService.perspective = 'explorer';
+
+        // Spy
+        spyOn(nfRegistryApi, 'getBuckets').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of([{
+            identifier: '2f7f9e54-dc09-4ceb-aa58-9fe581319cdc',
+            name: 'Bucket #1'
+        }]));
+        spyOn(nfRegistryService, 'filterDroplets');
+    });
+
+    it('should have a defined component', ngCoreTesting.fakeAsync(function () {
+        spyOn(nfRegistryApi, 'getDroplets').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of([{
+            "identifier": "2e04b4fb-9513-47bb-aa74-1ae34616bfdc",
+            "name": "Flow #1",
+            "description": "This is flow #1",
+            "bucketIdentifier": "2f7f9e54-dc09-4ceb-aa58-9fe581319cdc",
+            "createdTimestamp": 1505931890999,
+            "modifiedTimestamp": 1505931890999,
+            "type": "FLOW",
+            "snapshotMetadata": null,
+            "link": {
+                "params": {
+                    "rel": "self"
+                },
+                "href": "flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc"
+            }
+        }]));
+        // 1st change detection triggers ngOnInit which makes getBuckets and 
getDroplets calls
+        fixture.detectChanges();
+        // wait for async getBuckets and getDroplets calls
+        ngCoreTesting.tick();
+        // 2nd change detection completes after the getBuckets and getDroplets 
calls
+        fixture.detectChanges();
+
+        //assertions
+        expect(comp).toBeDefined();
+        expect(nfRegistryService.explorerViewType).toBe('grid-list');
+        expect(nfRegistryService.breadCrumbState).toBe('in');
+        expect(nfRegistryService.buckets[0].name).toEqual('Bucket #1');
+        expect(nfRegistryService.buckets.length).toBe(1);
+        expect(nfRegistryService.droplets[0].name).toEqual('Flow #1');
+        expect(nfRegistryService.droplets.length).toBe(1);
+        expect(nfRegistryApi.getDroplets).toHaveBeenCalled();
+        expect(nfRegistryApi.getBuckets).toHaveBeenCalled();
+        expect(nfRegistryService.filterDroplets).toHaveBeenCalled();
+    }));
+
+    it('should destroy the component', ngCoreTesting.fakeAsync(function () {
+        spyOn(nfRegistryApi, 'getDroplets').and.callFake(function () {
+        }).and.returnValue(rxjs.Observable.of([]));
+        // 1st change detection triggers ngOnInit which makes getBuckets and 
getDroplets calls
+        fixture.detectChanges();
+        // wait for async getBuckets and getDroplets calls
+        ngCoreTesting.tick();
+        // 2nd change detection completes after the getBuckets and getDroplets 
calls
+        fixture.detectChanges();
+
+        // The function to test
+        comp.ngOnDestroy();
+
+        //assertions
+        expect(nfRegistryService.explorerViewType).toBe('');
+        expect(nfRegistryService.buckets.length).toBe(0);
+        expect(nfRegistryService.droplets.length).toBe(0);
+        expect(nfRegistryService.filteredDroplets.length).toBe(0);
+        expect(nfRegistryService.breadCrumbState).toBe('out');
+    }));
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/explorer/nf-registry-explorer.spec.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/explorer/nf-registry-explorer.spec.js
 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/nf-registry-explorer.spec.js
new file mode 100644
index 0000000..b70e34b
--- /dev/null
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/explorer/nf-registry-explorer.spec.js
@@ -0,0 +1,109 @@
+/*
+ * 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 NfRegistryRoutes = require('nifi-registry/nf-registry.routes.js');
+var ngCoreTesting = require('@angular/core/testing');
+var ngCommon = require('@angular/common');
+var FdsDemo = 
require('nifi-registry/components/fluid-design-system/fds-demo.js');
+var NfRegistry = require('nifi-registry/nf-registry.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
+var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
+var NfPageNotFoundComponent = 
require('nifi-registry/components/page-not-found/nf-registry-page-not-found.js');
+var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-explorer.js');
+var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
+var NfRegistryGeneralAdministration = 
require('nifi-registry/components/administration/general/nf-registry-general-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 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 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');
+var NfRegistryBucketGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js');
+var NfRegistryDropletGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js');
+var fdsCore = require('@fluid-design-system/core');
+var ngMoment = require('angular2-moment');
+var ngHttp = require('@angular/http');
+
+describe('NfRegistryExplorer Component', function () {
+    var comp;
+    var fixture;
+    var nfRegistryService;
+
+    beforeEach(function () {
+        ngCoreTesting.TestBed.configureTestingModule({
+            imports: [
+                ngMoment.MomentModule,
+                ngHttp.HttpModule,
+                ngHttp.JsonpModule,
+                fdsCore,
+                NfRegistryRoutes
+            ],
+            declarations: [
+                FdsDemo,
+                NfRegistry,
+                NfRegistryExplorer,
+                NfRegistryAdministration,
+                NfRegistryGeneralAdministration,
+                NfRegistryUsersAdministration,
+                NfRegistryUserDetails,
+                NfRegistryUserPermissions,
+                NfRegistryBucketPermissions,
+                NfRegistryAddUser,
+                NfRegistryWorkflowAdministration,
+                NfRegistryGridListViewer,
+                NfRegistryBucketGridListViewer,
+                NfRegistryDropletGridListViewer,
+                NfPageNotFoundComponent
+            ],
+            providers: [
+                NfRegistryService,
+                NfRegistryApi,
+                {
+                    provide: ngCommon.APP_BASE_HREF,
+                    useValue: '/'
+                }
+            ]
+        });
+
+        fixture = ngCoreTesting.TestBed.createComponent(NfRegistryExplorer);
+
+        // test instance
+        comp = fixture.componentInstance;
+
+        // from the root injector
+        nfRegistryService = ngCoreTesting.TestBed.get(NfRegistryService);
+    });
+
+    it('should have a defined component', function () {
+        fixture.detectChanges();
+
+        //assertions
+        expect(comp).toBeDefined();
+        expect(nfRegistryService.perspective).toBe('explorer');
+    });
+
+    it('should destroy the component', function () {
+        fixture.detectChanges();
+
+        // The function to test
+        comp.ngOnDestroy();
+
+        //assertions
+        expect(nfRegistryService.perspective).toBe('');
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.html
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.html
 
b/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.html
index 7e9baf7..d8f8790 100644
--- 
a/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.html
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.html
@@ -979,7 +979,7 @@ limitations under the License.
                             </div>
                             <div layout="row" layout-align="space-between 
center">
                                 <div flex fxLayout="row" fxLayoutAlign="end 
center">
-                                    <td-chips 
[(ngModel)]="dropletsSearchTerms" [items]="autoCompleteDroplets" 
(add)="dropletsSearchAdd($event)" (remove)="dropletsSearchRemove($event)" 
class="push-right-sm"></td-chips>
+                                    <td-chips 
[(ngModel)]="dropletsSearchTerms" [items]="autoCompleteDroplets" 
(add)="nfRegistryService.filterDroplets(nfRegistryService.activeDropletColumn.name,
 nfRegistryService.activeDropletColumn.sortOrder);" 
(remove)="nfRegistryService.filterDroplets(nfRegistryService.activeDropletColumn.name,
 nfRegistryService.activeDropletColumn.sortOrder);" 
class="push-right-sm"></td-chips>
                                     <span class="pad-right-sm">Sort by:</span>
                                     <button color="fds-primary" 
md-raised-button [mdMenuTriggerFor]="dropletGridSortMenu">
                                         {{getSortBy()}}<i class="fa 
fa-caret-down" aria-hidden="true"></i>
@@ -987,7 +987,7 @@ limitations under the License.
                                 </div>
                                 <md-menu 
class="fds-primary-dropdown-button-menu" #dropletGridSortMenu="mdMenu" 
[overlapTrigger]="false">
                                     <div *ngFor="let column of dropletColumns">
-                                        <button md-menu-item 
*ngIf="column.sortable" (click)="sortDroplets($event, 
column);">{{column.label}} {{(column.sortOrder === 'ASC') ? 'DESC' : 
'ASC'}}</button>
+                                        <button md-menu-item 
*ngIf="column.sortable" (click)="sortDroplets(column);">{{column.label}} 
{{(column.sortOrder === 'ASC') ? 'DESC' : 'ASC'}}</button>
                                     </div>
                                 </md-menu>
                             </div>
@@ -1107,7 +1107,7 @@ limitations under the License.
             </div>
             <div layout="row" layout-align="space-between center">
                 <div flex fxLayout="row" fxLayoutAlign="end center">
-                    <td-chips [(ngModel)]="dropletsSearchTerms" 
[items]="autoCompleteDroplets" (add)="dropletsSearchAdd($event)" 
(remove)="dropletsSearchRemove($event)" class="push-right-sm"></td-chips>
+                    <td-chips [(ngModel)]="dropletsSearchTerms" 
[items]="autoCompleteDroplets" 
(add)="nfRegistryService.filterDroplets(nfRegistryService.activeDropletColumn.name,
 nfRegistryService.activeDropletColumn.sortOrder);" 
(remove)="nfRegistryService.filterDroplets(nfRegistryService.activeDropletColumn.name,
 nfRegistryService.activeDropletColumn.sortOrder);" 
class="push-right-sm"></td-chips>
                     <span class="pad-right-sm">Sort by:</span>
                     <button color="fds-primary" md-raised-button 
[mdMenuTriggerFor]="dropletGridSortMenu">
                         { {getSortBy()} }<i class="fa fa-caret-down" 
aria-hidden="true"></i>
@@ -1115,7 +1115,7 @@ limitations under the License.
                 </div>
                 <md-menu class="fds-primary-dropdown-button-menu" 
#dropletGridSortMenu="mdMenu" [overlapTrigger]="false">
                     <div *ngFor="let column of dropletColumns">
-                        <button md-menu-item *ngIf="column.sortable" 
(click)="sortDroplets($event, column);">{ {column.label} } { {(column.sortOrder 
=== 'ASC') ? 'DESC' : 'ASC'} }</button>
+                        <button md-menu-item *ngIf="column.sortable" 
(click)="sortDroplets(column);">{ {column.label} } { {(column.sortOrder === 
'ASC') ? 'DESC' : 'ASC'} }</button>
                     </div>
                 </md-menu>
             </div>
@@ -1362,7 +1362,7 @@ limitations under the License.
             return sortByColumnLabel;
         },
 
-        sortDroplets: function(sortEvent, column) {
+        sortDroplets: function(column) {
             if (column.sortable === true) {
                 // toggle column sort order
                 var sortOrder = column.sortOrder = (column.sortOrder === 
'ASC') ? 'DESC' : 'ASC';
@@ -1375,14 +1375,6 @@ limitations under the License.
             }
         },
 
-        dropletsSearchRemove: function(searchTerm) {
-            this.filterDroplets(this.activeColumn.name, 
this.activeColumn.sortOrder);
-        },
-
-        dropletsSearchAdd: function(searchTerm) {
-            this.filterDroplets(this.activeColumn.name, 
this.activeColumn.sortOrder);
-        },
-
         toggleDropletsFilter: function(searchTerm) {
             var applySearchTerm = true;
             // check if the search term is already applied and remove it if 
true

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.js
----------------------------------------------------------------------
diff --git 
a/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.js
 
b/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.js
index 84d6212..ead2a57 100644
--- 
a/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.js
+++ 
b/nifi-registry-web-ui/src/main/webapp/components/fluid-design-system/fds-demo.js
@@ -721,7 +721,7 @@ FdsDemo.prototype = {
         return sortByColumnLabel;
     },
 
-    sortDroplets: function (sortEvent, column) {
+    sortDroplets: function (column) {
         if (column.sortable === true) {
             // toggle column sort order
             var sortOrder = column.sortOrder = (column.sortOrder === 'ASC') ? 
'DESC' : 'ASC';
@@ -736,14 +736,6 @@ FdsDemo.prototype = {
         }
     },
 
-    dropletsSearchRemove: function (searchTerm) {
-        this.filterDroplets(this.activeColumn.name, 
this.activeColumn.sortOrder);
-    },
-
-    dropletsSearchAdd: function (searchTerm) {
-        this.filterDroplets(this.activeColumn.name, 
this.activeColumn.sortOrder);
-    },
-
     toggleDropletsFilter: function (searchTerm) {
         var applySearchTerm = true;
         // check if the search term is already applied and remove it if true

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/nf-registry.html
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/nf-registry.html 
b/nifi-registry-web-ui/src/main/webapp/nf-registry.html
index f8798dd..2bf1832 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.html
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.html
@@ -23,43 +23,43 @@ limitations under the License.
         <md-toolbar id="nifi-registry-toolbar">
             <img id="nifi-registry-logo" 
src="nifi-registry/images/registry-logo-web-app.svg">
             <div fxFlex="1 1 auto" class="pad-left-xl" 
[@flyInOut]="nfRegistryService.breadCrumbState">
-                <span 
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/{{nfRegistryService.registry.id}}">{{nfRegistryService.registry.name}}</span>
+                <span 
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}">{{nfRegistryService.registry.name}}</span>
                 <md-menu #availableRegistriesMenu="mdMenu" 
[overlapTrigger]="false">
                     <button md-menu-item *ngFor="let registry of 
nfRegistryService.registries"
-                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 'grid-list'}}/{{registry.id}}">
+                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 'grid-list'}}">
                         <span>{{registry.name}}</span>
                     </button>
                 </md-menu>
                 <span *ngIf="nfRegistryService.perspective === 
'administration'"> / Administration</span>
-                <span *ngIf="(nfRegistryService.perspective === 'explorer') && 
nfRegistryService.bucket.id"
+                <span *ngIf="(nfRegistryService.perspective === 'explorer') && 
nfRegistryService.bucket.identifier"
                       [mdMenuTriggerFor]="availableBucketsMenu"> / 
{{nfRegistryService.bucket.name}}<i
                         class="fa fa-caret-down pad-left-sm" 
aria-hidden="true"></i></span>
-                <span *ngIf="nfRegistryService.perspective === 'explorer' && 
nfRegistryService.registry.id && !nfRegistryService.bucket.id"
+                <span *ngIf="nfRegistryService.perspective === 'explorer' && 
!nfRegistryService.bucket.identifier"
                       [mdMenuTriggerFor]="availableBucketsMenu"> / All<i 
class="fa fa-caret-down pad-left-sm"
                                                                          
aria-hidden="true"></i></span>
                 <md-menu #availableBucketsMenu="mdMenu" 
[overlapTrigger]="false">
                     <button md-menu-item
-                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/{{nfRegistryService.registry.id}}">
+                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 'grid-list'}}">
                         <span>All buckets...</span>
                     </button>
                     <button md-menu-item *ngFor="let bucket of 
nfRegistryService.buckets"
-                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/{{nfRegistryService.registry.id}}/{{bucket.id}}">
+                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/buckets/{{bucket.identifier}}">
                         <span>{{bucket.name}}</span>
                     </button>
                 </md-menu>
-                <span *ngIf="nfRegistryService.perspective === 'explorer' && 
nfRegistryService.droplet.id"
+                <span *ngIf="nfRegistryService.perspective === 'explorer' && 
nfRegistryService.droplet.identifier"
                       [mdMenuTriggerFor]="availableDropletsMenu"> / 
{{nfRegistryService.droplet.name}}<i
                         class="fa fa-caret-down pad-left-sm" 
aria-hidden="true"></i></span>
                 <span [mdMenuTriggerFor]="availableDropletsMenu"
-                      *ngIf="nfRegistryService.perspective === 'explorer' && 
nfRegistryService.bucket.id && !nfRegistryService.droplet.id"> / All<i
+                      *ngIf="nfRegistryService.perspective === 'explorer' && 
nfRegistryService.bucket.identifier && !nfRegistryService.droplet.identifier"> 
/ All<i
                         class="fa fa-caret-down pad-left-sm" 
aria-hidden="true"></i></span>
                 <md-menu #availableDropletsMenu="mdMenu" 
[overlapTrigger]="false">
                     <button md-menu-item
-                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/{{nfRegistryService.registry.id}}/{{nfRegistryService.bucket.id}}">
+                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/buckets/{{nfRegistryService.bucket.identifier}}">
                         <span>All droplets...</span>
                     </button>
                     <button md-menu-item *ngFor="let droplet of 
nfRegistryService.droplets"
-                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/{{nfRegistryService.registry.id}}/{{nfRegistryService.bucket.id}}/{{droplet.id}}">
+                            
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 'grid-list'}}/{{droplet.link.href}}">
                         <span>{{droplet.name}}</span>
                     </button>
                 </md-menu>
@@ -72,12 +72,12 @@ limitations under the License.
             </button>
             <button md-ripple [@flyInOut] *ngIf="nfRegistryService.perspective 
=== 'explorer'" md-icon-button
                     mdTooltip="Registry Administration"
-                    
routerLink="/nifi-registry/administration/{{nfRegistryService.registry.id}}/general">
+                    routerLink="/nifi-registry/administration/general">
                 <i class="fa fa-wrench" aria-hidden="true"></i>
             </button>
             <button md-ripple [@flyInOut] *ngIf="nfRegistryService.perspective 
=== 'administration'" md-mini-fab
                     mdTooltip="Close settings and return to Explorer 
perspective."
-                    
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 
'grid-list'}}/{{nfRegistryService.registry.id}}">
+                    
routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? 
nfRegistryService.explorerViewType : 'grid-list'}}">
                 <md-icon color="primary">close</md-icon>
             </button>
         </md-toolbar>

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/nf-registry.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/nf-registry.js 
b/nifi-registry-web-ui/src/main/webapp/nf-registry.js
index 4c9263b..d207027 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.js
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.js
@@ -28,11 +28,7 @@ NfRegistry.prototype = {
     constructor: NfRegistry,
 
     ngOnInit: function () {
-        var self = this;
-        this.nfRegistryService.sidenav = this.sidenav;
-        this.nfRegistryService.getRegistries().then(function (registries) {
-            self.nfRegistryService.registries = registries;
-        });
+        this.nfRegistryService.sidenav = this.sidenav; //ngCore.ViewChild
     },
 
     ngAfterViewChecked: function () {

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js 
b/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js
index 9e83795..4cecd72 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.module.js
@@ -20,10 +20,10 @@ var ngMoment = require('angular2-moment');
 var NfRegistryRoutes = require('nifi-registry/nf-registry.routes.js');
 var FdsDemo = 
require('nifi-registry/components/fluid-design-system/fds-demo.js');
 var NfRegistry = require('nifi-registry/nf-registry.js');
+var NfRegistryApi = require('nifi-registry/services/nf-registry.api.js');
 var NfRegistryService = 
require('nifi-registry/services/nf-registry.service.js');
 var NfPageNotFoundComponent = 
require('nifi-registry/components/page-not-found/nf-registry-page-not-found.js');
 var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-explorer.js');
-var NfRegistryExplorerGridListViewer = 
require('nifi-registry/components/explorer/grid-list/nf-registry-explorer-grid-list-viewer.js');
 var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
 var NfRegistryGeneralAdministration = 
require('nifi-registry/components/administration/general/nf-registry-general-administration.js');
 var NfRegistryUsersAdministration = 
require('nifi-registry/components/administration/users/nf-registry-users-administration.js');
@@ -33,9 +33,10 @@ var NfRegistryUserPermissions = 
require('nifi-registry/components/administration
 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');
-var NfRegistryBucketGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/bucket/nf-registry-bucket-grid-list-viewer.js');
-var NfRegistryDropletGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/bucket/droplet/nf-registry-droplet-grid-list-viewer.js');
+var NfRegistryBucketGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js');
+var NfRegistryDropletGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js');
 var fdsCore = require('@fluid-design-system/core');
+var ngHttp = require('@angular/http');
 
 function NfRegistryModule() {
 };
@@ -49,10 +50,29 @@ NfRegistryModule.annotations = [
         imports: [
             ngMoment.MomentModule,
             fdsCore,
+            ngHttp.HttpModule,
+            ngHttp.JsonpModule,
             NfRegistryRoutes
         ],
-        declarations: [FdsDemo, NfRegistry, NfRegistryExplorer, 
NfRegistryExplorerGridListViewer, NfRegistryAdministration, 
NfRegistryGeneralAdministration, NfRegistryUsersAdministration, 
NfRegistryUserDetails, NfRegistryUserPermissions, NfRegistryBucketPermissions, 
NfRegistryAddUser, NfRegistryWorkflowAdministration, NfRegistryGridListViewer, 
NfRegistryBucketGridListViewer, NfRegistryDropletGridListViewer, 
NfPageNotFoundComponent],
-        providers: [NfRegistryService],
+        declarations: [
+            FdsDemo,
+            NfRegistry,
+            NfRegistryExplorer,
+            NfRegistryAdministration,
+            NfRegistryGeneralAdministration,
+            NfRegistryUsersAdministration,
+            NfRegistryUserDetails,
+            NfRegistryUserPermissions,
+            NfRegistryBucketPermissions,
+            NfRegistryAddUser,
+            NfRegistryWorkflowAdministration,
+            NfRegistryGridListViewer,
+            NfRegistryBucketGridListViewer,
+            NfRegistryDropletGridListViewer,
+            NfPageNotFoundComponent],
+        providers: [
+            NfRegistryService,
+            NfRegistryApi],
         bootstrap: [NfRegistry]
     })
 ];

http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/7b707a05/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
----------------------------------------------------------------------
diff --git a/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js 
b/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
index 46bcbec..4c95e1f 100644
--- a/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
+++ b/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
@@ -19,7 +19,6 @@ var ngRouter = require('@angular/router');
 var FdsDemo = 
require('nifi-registry/components/fluid-design-system/fds-demo.js');
 var NfPageNotFoundComponent = 
require('nifi-registry/components/page-not-found/nf-registry-page-not-found.js');
 var NfRegistryExplorer = 
require('nifi-registry/components/explorer/nf-registry-explorer.js');
-var NfRegistryExplorerGridListViewer = 
require('nifi-registry/components/explorer/grid-list/nf-registry-explorer-grid-list-viewer.js');
 var NfRegistryAdministration = 
require('nifi-registry/components/administration/nf-registry-administration.js');
 var NfRegistryGeneralAdministration = 
require('nifi-registry/components/administration/general/nf-registry-general-administration.js');
 var NfRegistryUsersAdministration = 
require('nifi-registry/components/administration/users/nf-registry-users-administration.js');
@@ -29,34 +28,31 @@ var NfRegistryUserPermissions = 
require('nifi-registry/components/administration
 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');
-var NfRegistryBucketGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/bucket/nf-registry-bucket-grid-list-viewer.js');
-var NfRegistryDropletGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/bucket/droplet/nf-registry-droplet-grid-list-viewer.js');
+var NfRegistryBucketGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js');
+var NfRegistryDropletGridListViewer = 
require('nifi-registry/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js');
 
 var NfRegistryRoutes = new ngRouter.RouterModule.forRoot([{
     path: 'nifi-registry/explorer',
     component: NfRegistryExplorer,
-    children: [{
-        path: 'grid-list',
-        component: NfRegistryExplorerGridListViewer,
-        children: [{
-            path: ':registryId',
-            component: NfRegistryGridListViewer,
-            children: [{
-                path: ':bucketId',
-                component: NfRegistryBucketGridListViewer,
-                children: [{
-                    path: ':dropletId',
-                    component: NfRegistryDropletGridListViewer
-                }]
-            }]
-        }]
-    }]
+    children: [
+        {
+            path: 'grid-list',
+            component: NfRegistryGridListViewer
+        }, {
+            path: 'grid-list/buckets/:bucketId',
+            component: NfRegistryBucketGridListViewer
+        },
+        {
+            path: 'grid-list/buckets/:bucketId/:dropletType/:dropletId',
+            component: NfRegistryDropletGridListViewer
+        }
+        ]
     // canActivate: [AuthGuard] //TODO: 
https://angular.io/api/router/CanActivate 
https://scotch.io/tutorials/routing-angular-2-single-page-apps-with-the-component-router
 }, {
     path: 'nifi-registry/fluid-design-system',
     component: FdsDemo
 }, {
-    path: 'nifi-registry/administration/:registryId',
+    path: 'nifi-registry/administration',
     component: NfRegistryAdministration,
     children: [{
         path: '',
@@ -73,12 +69,16 @@ var NfRegistryRoutes = new ngRouter.RouterModule.forRoot([{
         component: NfRegistryWorkflowAdministration
     }]
 }, {
+    path: 'nifi-registry/explorer/grid-list/buckets',
+    redirectTo: '/nifi-registry/explorer/grid-list',
+    pathMatch: 'full'
+}, {
     path: 'nifi-registry',
-    redirectTo: 
'/nifi-registry/explorer/grid-list/23f6cc59-0156-1000-06b4-2b0810089090',
+    redirectTo: '/nifi-registry/explorer/grid-list',
     pathMatch: 'full'
 }, {
     path: '',
-    redirectTo: 
'/nifi-registry/explorer/grid-list/23f6cc59-0156-1000-06b4-2b0810089090',
+    redirectTo: '/nifi-registry/explorer/grid-list',
     pathMatch: 'full'
 }, {
     path: '**',

Reply via email to