Repository: nifi
Updated Branches:
  refs/heads/master d1ebddce9 -> a90a77024


[NIFI-3035] add deep linking URL to canvas components and PGs. This closes #1559


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

Branch: refs/heads/master
Commit: a90a770244fa9002a0999c20175e36582fbf994d
Parents: d1ebddc
Author: Scott Aslan <[email protected]>
Authored: Wed Mar 15 16:19:02 2017 -0400
Committer: Matt Gilman <[email protected]>
Committed: Wed Mar 22 14:23:02 2017 -0400

----------------------------------------------------------------------
 nifi-assembly/LICENSE                           |  23 +++
 .../src/main/resources/META-INF/LICENSE         |  23 +++
 .../nifi-framework/nifi-web/nifi-web-ui/pom.xml |   4 +
 .../nifi-web-ui/src/main/frontend/package.json  |   3 +-
 .../src/main/resources/META-INF/LICENSE         |  23 +++
 .../src/main/webapp/WEB-INF/pages/canvas.jsp    |   1 +
 .../header/components/nf-ng-funnel-component.js |   3 +
 .../header/components/nf-ng-label-component.js  |   3 +
 .../src/main/webapp/js/nf/canvas/nf-actions.js  |  30 +++-
 .../main/webapp/js/nf/canvas/nf-canvas-utils.js | 165 ++++++++++++++++++-
 .../src/main/webapp/js/nf/canvas/nf-canvas.js   |  13 ++
 .../main/webapp/js/nf/canvas/nf-connection.js   |  15 ++
 .../src/main/webapp/js/nf/canvas/nf-graph.js    |   7 +-
 .../webapp/js/nf/canvas/nf-process-group.js     |   4 +
 .../main/webapp/js/nf/canvas/nf-selectable.js   |  18 +-
 .../src/main/webapp/js/nf/nf-dialog.js          |   2 +-
 16 files changed, 312 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-assembly/LICENSE
----------------------------------------------------------------------
diff --git a/nifi-assembly/LICENSE b/nifi-assembly/LICENSE
index a6f1a03..edfd806 100644
--- a/nifi-assembly/LICENSE
+++ b/nifi-assembly/LICENSE
@@ -445,6 +445,29 @@ For details see http://qtip2.com
     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     OTHER DEALINGS IN THE SOFTWARE.
 
+This product bundles 'url-search-params' which is available under an MIT style 
license.
+For details see https://github.com/WebReflection/url-search-params
+
+    Copyright (C) 2015 by WebReflection
+
+    Permission is hereby granted, free of charge, to any person obtaining a 
copy
+    of this software and associated documentation files (the "Software"), to 
deal
+    in the Software without restriction, including without limitation the 
rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
 This product bundles 'jQuery MiniColors' which is available under the MIT 
License.
 For details see http://www.abeautifulsite.net/
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/src/main/resources/META-INF/LICENSE
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/src/main/resources/META-INF/LICENSE
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/src/main/resources/META-INF/LICENSE
index f4b4b09..175ec8f 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/src/main/resources/META-INF/LICENSE
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework-nar/src/main/resources/META-INF/LICENSE
@@ -474,6 +474,29 @@ For details see http://qtip2.com
     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     OTHER DEALINGS IN THE SOFTWARE.
 
+This product bundles 'url-search-params' which is available under an MIT style 
license.
+For details see https://github.com/WebReflection/url-search-params
+
+    Copyright (C) 2015 by WebReflection
+
+    Permission is hereby granted, free of charge, to any person obtaining a 
copy
+    of this software and associated documentation files (the "Software"), to 
deal
+    in the Software without restriction, including without limitation the 
rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
 This product bundles 'jQuery MiniColors' which is available under the MIT 
License.
 For details see http://www.abeautifulsite.net/
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
index 9108fe7..08c0d46 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
@@ -226,6 +226,10 @@
                                         <!-- reset.css -->
                                         <include>reset.css/reset.css</include>
                                         <include>reset.css/README.md</include>
+                                        <!-- URLSearchParams Polyfill -->
+                                        
<include>url-search-params/build/url-search-params.js</include>
+                                        
<include>url-search-params/README.md</include>
+                                        
<include>url-search-params/LICENSE.txt</include>
                                     </includes>
                                 </resource>
                             </resources>

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/frontend/package.json
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/frontend/package.json
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/frontend/package.json
index ca432a5..4e56011 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/frontend/package.json
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/frontend/package.json
@@ -14,7 +14,8 @@
     "jsonlint": "1.6.2",
     "JSON2": "0.1.0",
     "reset.css": "2.0.2",
-    "d3": "3.5.17"
+    "d3": "3.5.17",
+    "url-search-params": "0.6.1"
   },
   "description": "Apache NiFi 3rd party client side resources.",
   "repository": {

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/META-INF/LICENSE
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/META-INF/LICENSE
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/META-INF/LICENSE
index 903b555..6d29fb0 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/META-INF/LICENSE
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/META-INF/LICENSE
@@ -422,6 +422,29 @@ For details see http://qtip2.com
     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     OTHER DEALINGS IN THE SOFTWARE.
 
+This product bundles 'url-search-params' which is available under an MIT style 
license.
+For details see https://github.com/WebReflection/url-search-params
+
+    Copyright (C) 2015 by WebReflection
+
+    Permission is hereby granted, free of charge, to any person obtaining a 
copy
+    of this software and associated documentation files (the "Software"), to 
deal
+    in the Software without restriction, including without limitation the 
rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
 This product bundles 'jQuery MiniColors' which is available under the MIT 
License.
 For details see http://www.abeautifulsite.net/
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
index 48db66e..77f7841 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp
@@ -40,6 +40,7 @@
         <link rel="stylesheet" href="fonts/flowfont/flowfont.css" 
type="text/css" />
         <link rel="stylesheet" 
href="assets/angular-material/angular-material.min.css" type="text/css" />
         <link rel="stylesheet" 
href="assets/font-awesome/css/font-awesome.min.css" type="text/css" />
+        <script type="text/javascript" 
src="assets/url-search-params/build/url-search-params.js"></script>
         <script type="text/javascript" 
src="js/codemirror/lib/codemirror-compressed.js"></script>
         <script type="text/javascript" src="assets/d3/d3.min.js"></script>
         <script type="text/javascript" 
src="assets/jquery/dist/jquery.min.js"></script>

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-funnel-component.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-funnel-component.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-funnel-component.js
index 94db750..1384954 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-funnel-component.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-funnel-component.js
@@ -136,6 +136,9 @@
                         'selectAll': true
                     });
 
+                    // update component visibility
+                    nfGraph.updateVisibility();
+
                     // update the birdseye
                     nfBirdseye.refresh();
                 }).fail(nfErrorHandler.handleAjaxError);

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-label-component.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-label-component.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-label-component.js
index 9562109..394c395 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-label-component.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-label-component.js
@@ -141,6 +141,9 @@
                         'selectAll': true
                     });
 
+                    // update component visibility
+                    nfGraph.updateVisibility();
+
                     // update the birdseye
                     nfBirdseye.refresh();
                 }).fail(nfErrorHandler.handleAjaxError);

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
index 1fe8aba..a728c52 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
@@ -406,18 +406,24 @@
          * @param {selection} selection     The selection
          */
         show: function (selection) {
-            if (selection.size() === 1) {
-                // deselect the current selection
-                var currentlySelected = nfCanvasUtils.getSelection();
-                currentlySelected.classed('selected', false);
+            // deselect the current selection
+            var currentlySelected = nfCanvasUtils.getSelection();
+            currentlySelected.classed('selected', false);
 
-                // select only the component/connection in question
-                selection.classed('selected', true);
-                nfActions.center(selection);
+            // select only the component/connection in question
+            selection.classed('selected', true);
 
-                // inform Angular app that values have changed
-                nfNgBridge.digest();
+            if (selection.size() === 1) {
+                nfActions.center(selection);
+            } else {
+                nfNgBridge.injector.get('navigateCtrl').zoomFit();
             }
+
+            // update URL deep linking params
+            nfCanvasUtils.setURLParameters(nfCanvasUtils.getGroupId(), 
selection);
+
+            // inform Angular app that values have changed
+            nfNgBridge.digest();
         },
 
         /**
@@ -935,6 +941,9 @@
                             }
                         }
 
+                        // update URL deep linking params
+                        nfCanvasUtils.setURLParameters();
+
                         // refresh the birdseye
                         nfBirdseye.refresh();
                         // inform Angular app values have changed
@@ -986,6 +995,9 @@
                                 
nfConnection.remove(components.get('Connection'));
                             }
 
+                            // update URL deep linking params
+                            nfCanvasUtils.setURLParameters();
+
                             // refresh the birdseye
                             nfBirdseye.refresh();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
index 055157f..f7ad2ac 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
@@ -241,8 +241,8 @@
         /**
          * Shows the specified component in the specified group.
          *
-         * @argument {string} groupId       The id of the group
-         * @argument {string} componentId   The id of the component
+         * @param {string} groupId       The id of the group
+         * @param {string} componentId   The id of the component
          */
         showComponent: function (groupId, componentId) {
             // ensure the group id is specified
@@ -257,12 +257,12 @@
                         // reload
                         nfCanvas.reload().done(function () {
                             deferred.resolve();
-                        }).fail(function () {
+                        }).fail(function (xhr, status, error) {
                             nfDialog.showOkDialog({
-                                headerText: 'Process Group',
+                                headerText: 'Error',
                                 dialogContent: 'Unable to load the group for 
the specified component.'
                             });
-                            deferred.reject();
+                            deferred.reject(xhr, status, error);
                         });
                     } else {
                         deferred.resolve();
@@ -277,7 +277,7 @@
                         nfActions.show(component);
                     } else {
                         nfDialog.showOkDialog({
-                            headerText: 'Process Group',
+                            headerText: 'Error',
                             dialogContent: 'Unable to find the specified 
component.'
                         });
                     }
@@ -286,6 +286,159 @@
         },
 
         /**
+         * Displays the URL deep link on the canvas.
+         *
+         * @param forceCanvasLoad   Boolean enabling the update of the URL 
parameters.
+         */
+        showDeepLink: function (forceCanvasLoad) {
+            // deselect components
+            nfCanvasUtils.getSelection().classed('selected', false);
+
+            // close the ok dialog if open
+            if ($('#nf-ok-dialog').is(':visible') === true) {
+                $('#nf-ok-dialog').modal('hide');
+            }
+
+            // Feature detection and browser support for URLSearchParams
+            if ('URLSearchParams' in window) {
+                var urlSearchParams = new URL(window.location).searchParams;
+                var groupId = nfCanvasUtils.getGroupId();
+                var componentIds = [];
+
+                if (urlSearchParams.get('processGroupId')) {
+                    groupId = urlSearchParams.get('processGroupId');
+                }
+                if (urlSearchParams.get('componentIds')) {
+                    componentIds = 
urlSearchParams.get('componentIds').split(',');
+                }
+
+                // load the graph but do not update the browser history
+                if (componentIds.length >= 1) {
+                    return nfCanvasUtils.showComponents(groupId, componentIds, 
forceCanvasLoad);
+                } else {
+                    return 
nfCanvasUtils.getComponentByType('ProcessGroup').enterGroup(groupId);
+                }
+            }
+        },
+
+        /**
+         * Shows the specified components in the specified group.
+         *
+         * @param {string} groupId       The id of the group
+         * @param {array} componentIds   The ids of the components
+         * @param {bool} forceCanvasLoad   Boolean to force reload of the 
canvas.
+         */
+        showComponents: function (groupId, componentIds, forceCanvasLoad) {
+            // ensure the group id is specified
+            if (nfCommon.isDefinedAndNotNull(groupId)) {
+                // initiate a graph refresh
+                var refreshGraph = $.Deferred(function (deferred) {
+                    // load a different group if necessary
+                    if (groupId !== nfCanvas.getGroupId() || forceCanvasLoad) {
+                        // set the new group id
+                        nfCanvas.setGroupId(groupId);
+
+                        // reload
+                        nfCanvas.reload().done(function () {
+                            deferred.resolve();
+                        }).fail(function (xhr, status, error) {
+                            nfDialog.showOkDialog({
+                                headerText: 'Error',
+                                dialogContent: 'Unable to enter the selected 
group.'
+                            });
+
+                            deferred.reject(xhr, status, error);
+                        });
+                    } else {
+                        deferred.resolve();
+                    }
+                }).promise();
+
+                // when the refresh has completed, select the match
+                refreshGraph.done(function () {
+                    // get the components to select
+                    var components = d3.selectAll('g.component, 
g.connection').filter(function (d) {
+                        if (componentIds.indexOf(d.id) >= 0) {
+                            // remove located components from array so that 
only unfound components will remain
+                            componentIds.splice(componentIds.indexOf(d.id), 1);
+                            return d;
+                        }
+                    });
+
+                    if (componentIds.length > 0) {
+                        var dialogContent = $('<p></p>').text('Specified 
component(s) not found: ' + componentIds.join(', ') + 
'.').append('<br/><br/>').append($('<p>Unable to select component(s).</p>'));
+
+                        nfDialog.showOkDialog({
+                            headerText: 'Error',
+                            dialogContent: dialogContent
+                        });
+                    }
+
+                    nfActions.show(components);
+                });
+
+                return refreshGraph;
+            }
+        },
+
+        MAX_URL_LENGTH: 2000,  // the maximum (suggested) safe string length 
of a URL supported by all browsers and application servers
+
+        /**
+         * Set the parameters of the URL.
+         *
+         * @param groupId       The process group id.
+         * @param selections    The component ids.
+         */
+        setURLParameters: function (groupId, selections) {
+            // Feature detection and browser support for URLSearchParams
+            if ('URLSearchParams' in window) {
+                if (!nfCommon.isDefinedAndNotNull(groupId)) {
+                    groupId = nfCanvasUtils.getGroupId();
+                }
+
+                if (!nfCommon.isDefinedAndNotNull(selections)) {
+                    selections = nfCanvasUtils.getSelection();
+                }
+
+                var selectedComponentIds = [];
+                selections.each(function (selection) {
+                    selectedComponentIds.push(selection.id);
+                });
+
+                // get all URL parameters
+                var params = new URL(window.location).searchParams;
+                params.set('processGroupId', groupId);
+                params.set('componentIds', selectedComponentIds.sort());
+
+                // create object whose keys are the parameter name and the 
values are the parameter values
+                var paramsObject = {};
+                params.forEach(function (v, k) {
+                    paramsObject[k] = v;
+                });
+
+                var url = new URL(window.location);
+                var newUrl = url.origin + url.pathname;
+
+                if 
(nfCommon.isDefinedAndNotNull(nfCanvasUtils.getParentGroupId()) || 
selectedComponentIds.length > 0) {
+                    if 
(!nfCommon.isDefinedAndNotNull(nfCanvasUtils.getParentGroupId())) {
+                        // we are in the root group so set processGroupId 
param value to 'root' alias
+                        paramsObject['processGroupId'] = 'root';
+                    }
+
+                    if ((url.origin + url.pathname + '?' + 
$.param(paramsObject)).length <= nfCanvasUtils.MAX_URL_LENGTH) {
+                        newUrl = url.origin + url.pathname + '?' + 
$.param(paramsObject);
+                    } else if 
(nfCommon.isDefinedAndNotNull(nfCanvasUtils.getParentGroupId())) {
+                        // silently remove all component ids
+                        paramsObject['componentIds'] = '';
+                        newUrl = url.origin + url.pathname + '?' + 
$.param(paramsObject);
+                    }
+                }
+
+                window.history.replaceState({'previous_url': url.href}, 
window.document.title, newUrl);
+            }
+        },
+
+        /**
          * Gets the currently selected components and connections.
          *
          * @returns {selection}     The currently selected components and 
connections

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
index 74b43d8..051f397 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
@@ -284,6 +284,9 @@
                     // since the context menu event propagated back to the 
canvas, clear the selection
                     nfCanvasUtils.getSelection().classed('selected', false);
 
+                    // update URL deep linking params
+                    nfCanvasUtils.setURLParameters();
+
                     // show the context menu on the canvas
                     nfContextMenu.show();
 
@@ -553,9 +556,15 @@
 
                         // remove the selection box
                         selectionBox.remove();
+
+                        // update URL deep linking params
+                        nfCanvasUtils.setURLParameters();
                     } else if (panning === false) {
                         // deselect as necessary if we are not panning
                         nfCanvasUtils.getSelection().classed('selected', 
false);
+
+                        // update URL deep linking params
+                        nfCanvasUtils.setURLParameters();
                     }
 
                     // inform Angular app values have changed
@@ -697,6 +706,10 @@
                     } else if (evt.keyCode === 65) {
                         // ctrl-a
                         nfActions.selectAll();
+
+                        // update URL deep linking params
+                        nfCanvasUtils.setURLParameters();
+
                         nfNgBridge.digest();
 
                         // only want to prevent default if the action was 
performed, otherwise default select all would be overridden

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
index 14f6880..6b0e5a9 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
@@ -310,6 +310,9 @@
             .on('mousedown.selection', function () {
                 // select the connection when clicking the selectable path
                 nfSelectable.select(d3.select(this.parentNode));
+
+                // update URL deep linking params
+                nfCanvasUtils.setURLParameters();
             })
             .call(nfContextMenu.activate);
     };
@@ -630,6 +633,9 @@
                         .on('mousedown.selection', function () {
                             // select the connection when clicking the label
                             nfSelectable.select(d3.select(this.parentNode));
+
+                            // update URL deep linking params
+                            nfCanvasUtils.setURLParameters();
                         })
                         .call(nfContextMenu.activate);
 
@@ -660,6 +666,9 @@
                         .on('mousedown.selection', function () {
                             // select the connection when clicking the label
                             nfSelectable.select(d3.select(this.parentNode));
+
+                            // update URL deep linking params
+                            nfCanvasUtils.setURLParameters();
                         })
                         .call(nfContextMenu.activate);
 
@@ -740,6 +749,9 @@
                         .on('mousedown.selection', function () {
                             // select the connection when clicking the label
                             nfSelectable.select(d3.select(this.parentNode));
+
+                            // update URL deep linking params
+                            nfCanvasUtils.setURLParameters();
                         })
                         .call(nfContextMenu.activate);
 
@@ -777,6 +789,9 @@
                             .on('mousedown.selection', function () {
                                 // select the connection when clicking the 
label
                                 
nfSelectable.select(d3.select(this.parentNode));
+
+                                // update URL deep linking params
+                                nfCanvasUtils.setURLParameters();
                             })
                             .call(nfContextMenu.activate);
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js
index 394bf42..9cc4345 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-graph.js
@@ -206,8 +206,8 @@
             nfProcessor.init(nfConnectable, nfDraggable, nfSelectable, 
nfContextMenu);
             nfConnection.init(nfSelectable, nfContextMenu, 
nfConnectionConfiguration);
 
-            // load the graph
-            return nfProcessGroup.enterGroup(nfCanvasUtils.getGroupId());
+            // display the deep link
+            return nfCanvasUtils.showDeepLink(true);
         },
 
         /**
@@ -389,6 +389,9 @@
         updateVisibility: function () {
             updateComponentVisibility();
             nfGraph.pan();
+
+            // update URL deep linking params
+            nfCanvasUtils.setURLParameters();
         },
 
         /**

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
index bec3d6c..c142b75 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
@@ -1279,6 +1279,10 @@
                         transition: true
                     });
                 }
+
+                // update URL deep linking params
+                nfCanvasUtils.setURLParameters(groupId, d3.select());
+
             }).fail(function () {
                 nfDialog.showOkDialog({
                     headerText: 'Process Group',

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-selectable.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-selectable.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-selectable.js
index c8b5179..c24457d 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-selectable.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-selectable.js
@@ -21,21 +21,24 @@
     if (typeof define === 'function' && define.amd) {
         define(['d3',
                 'nf.ng.Bridge',
-                'nf.ContextMenu'],
-            function (d3, nfNgBridge, nfContextMenu) {
-                return (nf.Selectable = factory(d3, nfNgBridge, 
nfContextMenu));
+                'nf.ContextMenu',
+                'nf.CanvasUtils'],
+            function (d3, nfNgBridge, nfContextMenu, nfCanvasUtils) {
+                return (nf.Selectable = factory(d3, nfNgBridge, nfContextMenu, 
nfCanvasUtils));
             });
     } else if (typeof exports === 'object' && typeof module === 'object') {
         module.exports = (nf.Selectable =
             factory(require('d3'),
                 require('nf.ng.Bridge'),
-                require('nf.ContextMenu')));
+                require('nf.ContextMenu'),
+                require('nf.CanvasUtils')));
     } else {
         nf.Selectable = factory(root.d3,
             root.nf.ng.Bridge,
-            root.nf.ContextMenu);
+            root.nf.ContextMenu,
+            root.nf.CanvasUtils);
     }
-}(this, function (d3, nfNgBridge, nfContextMenu) {
+}(this, function (d3, nfNgBridge, nfContextMenu, nfCanvasUtils) {
     'use strict';
 
     var nfSelectable = {
@@ -77,6 +80,9 @@
             components.on('mousedown.selection', function () {
                 // get the clicked component to update selection
                 nfSelectable.select(d3.select(this));
+
+                // update URL deep linking params
+                nfCanvasUtils.setURLParameters();
             });
         }
     };

http://git-wip-us.apache.org/repos/asf/nifi/blob/a90a7702/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-dialog.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-dialog.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-dialog.js
index fff81b4..01a5411 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-dialog.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-dialog.js
@@ -70,7 +70,7 @@
 
             // regardless of whether the dialog is already visible, the new 
content will be appended
             var content = $('<p></p>').append(options.dialogContent);
-            $('#nf-ok-dialog-content').append(content);
+            $('#nf-ok-dialog-content').append(content).append('</br>');
 
             // update the button model
             $('#nf-ok-dialog').modal('setButtonModel', [{

Reply via email to