Repository: incubator-nifi
Updated Branches:
  refs/heads/develop 3295f7f19 -> f72fdcdb1


NIFI-618:
- Adding a context menu item that allows users to move components out of a 
process group.

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

Branch: refs/heads/develop
Commit: f72fdcdb150582880bfe5087743d179f32e869ad
Parents: 3295f7f
Author: Matt Gilman <[email protected]>
Authored: Mon Jun 15 21:27:06 2015 -0400
Committer: Matt Gilman <[email protected]>
Committed: Mon Jun 15 21:27:06 2015 -0400

----------------------------------------------------------------------
 .../nifi/groups/StandardProcessGroup.java       |   6 +-
 .../src/main/webapp/images/iconMoveToParent.png | Bin 0 -> 215 bytes
 .../src/main/webapp/js/nf/canvas/nf-actions.js  |  15 +++
 .../main/webapp/js/nf/canvas/nf-canvas-utils.js | 126 ++++++++++++-------
 .../main/webapp/js/nf/canvas/nf-context-menu.js |  12 +-
 5 files changed, 110 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/f72fdcdb/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
index 07e3e91..70701c0 100644
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
@@ -1685,7 +1685,11 @@ public final class StandardProcessGroup implements 
ProcessGroup {
             }
 
             if (isRootGroup() && (!snippet.getInputPorts().isEmpty() || 
!snippet.getOutputPorts().isEmpty())) {
-                throw new IllegalStateException("Cannot move Ports from the 
Root Group to a Non-Root Group");
+                throw new IllegalStateException("Cannot move Ports out of the 
root group");
+            }
+
+            if (destination.isRootGroup() && 
(!snippet.getInputPorts().isEmpty() || !snippet.getOutputPorts().isEmpty())) {
+                throw new IllegalStateException("Cannot move Ports into the 
root group");
             }
 
             for (final String id : 
replaceNullWithEmptySet(snippet.getInputPorts())) {

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/f72fdcdb/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconMoveToParent.png
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconMoveToParent.png
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconMoveToParent.png
new file mode 100644
index 0000000..283de3d
Binary files /dev/null and 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconMoveToParent.png
 differ

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/f72fdcdb/nifi/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/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
index 4d2da84..3b47a8d 100644
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
@@ -915,6 +915,21 @@ nf.Actions = (function () {
         },
         
         /**
+         * Moves the currently selected component into the current parent 
group.
+         */
+        moveIntoParent: function () {
+            var selection = nf.CanvasUtils.getSelection();
+
+            // ensure that components have been specified
+            if (selection.empty()) {
+                return;
+            }
+            
+            // move the current selection into the parent group
+            nf.CanvasUtils.moveComponentsToParent(selection);
+        },
+        
+        /**
          * Creates a new template based off the currently selected components. 
If no components
          * are selected, a template of the entire canvas is made.
          */

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/f72fdcdb/nifi/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/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/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
index 4c6be57..af4473e 100644
--- 
a/nifi/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/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
@@ -50,6 +50,58 @@ nf.CanvasUtils = (function () {
 
         return mid;
     };
+    
+    var moveComponents = function (components, groupId) {
+        return $.Deferred(function (deferred) {
+            // ensure the current selection is eligible for move into the 
specified group
+            nf.CanvasUtils.eligibleForMove(components, groupId).done(function 
() {
+                // create a snippet for the specified components and link to 
the data flow
+                var snippetDetails = nf.Snippet.marshal(components, true);
+                nf.Snippet.create(snippetDetails).done(function (response) {
+                    var snippet = response.snippet;
+
+                    // move the snippet into the target
+                    nf.Snippet.move(snippet.id, groupId).done(function () {
+                        var componentMap = d3.map();
+
+                        // add the id to the type's array
+                        var addComponent = function (type, id) {
+                            if (!componentMap.has(type)) {
+                                componentMap.set(type, []);
+                            }
+                            componentMap.get(type).push(id);
+                        };
+
+                        // go through each component being removed
+                        components.each(function (d) {
+                            addComponent(d.type, d.component.id);
+                        });
+
+                        // refresh all component types as necessary (handle 
components that have been removed)
+                        componentMap.forEach(function (type, ids) {
+                            nf[type].remove(ids);
+                        });
+
+                        // refresh the birdseye
+                        nf.Birdseye.refresh();
+                        deferred.resolve();
+                    }).fail(nf.Common.handleAjaxError).fail(function () {
+                        deferred.reject();
+                    }).always(function () {
+                        // unable to acutally move the components so attempt to
+                        // unlink and remove just the snippet
+                        nf.Snippet.unlink(snippet.id).done(function () {
+                            nf.Snippet.remove(snippet.id);
+                        });
+                    });
+                }).fail(nf.Common.handleAjaxError).fail(function () {
+                    deferred.reject();
+                });
+            }).fail(function () {
+                deferred.reject();
+            });
+        }).promise();
+    };
 
     return {
         config: {
@@ -1026,6 +1078,22 @@ nf.CanvasUtils = (function () {
         },
         
         /**
+         * Moves the specified components into the current parent group.
+         * 
+         * @param {selection} components
+         */
+        moveComponentsToParent: function (components) {
+            var groupId = nf.Canvas.getParentGroupId();
+            
+            // if the group id is null, we're already in the top most group
+            if (groupId === null) {
+                nf.Dialog.showOkDialog('Components are already in the topmost 
group.');
+            } else {
+                moveComponents(components, groupId);
+            }
+        },
+        
+        /**
          * Moves the specified components into the specified group.
          * 
          * @param {selection} components    The components to move
@@ -1033,46 +1101,11 @@ nf.CanvasUtils = (function () {
          */
         moveComponents: function (components, group) {
             var groupData = group.datum();
-
-            // ensure the current selection is eligible for move into the 
specified group
-            nf.CanvasUtils.eligibleForMove(components, group).done(function () 
{
-                // create a snippet for the specified components and link to 
the data flow
-                var snippetDetails = nf.Snippet.marshal(components, true);
-                nf.Snippet.create(snippetDetails).done(function (response) {
-                    var snippet = response.snippet;
-
-                    // move the snippet into the target
-                    nf.Snippet.move(snippet.id, 
groupData.component.id).done(function () {
-                        var componentMap = d3.map();
-
-                        // add the id to the type's array
-                        var addComponent = function (type, id) {
-                            if (!componentMap.has(type)) {
-                                componentMap.set(type, []);
-                            }
-                            componentMap.get(type).push(id);
-                        };
-
-                        // go through each component being removed
-                        components.each(function (d) {
-                            addComponent(d.type, d.component.id);
-                        });
-
-                        // refresh all component types as necessary (handle 
components that have been removed)
-                        componentMap.forEach(function (type, ids) {
-                            nf[type].remove(ids);
-                        });
-
-                        // reload the target group
-                        nf.ProcessGroup.reload(groupData.component);
-                    }).fail(nf.Common.handleAjaxError).always(function () {
-                        // unable to acutally move the components so attempt to
-                        // unlink and remove just the snippet
-                        nf.Snippet.unlink(snippet.id).done(function () {
-                            nf.Snippet.remove(snippet.id);
-                        });
-                    });
-                }).fail(nf.Common.handleAjaxError);
+            
+            // move the components into the destination and...
+            moveComponents(components, groupData.component.id).done(function 
() {
+                // reload the target group
+                nf.ProcessGroup.reload(groupData.component);
             });
         },
         
@@ -1161,15 +1194,15 @@ nf.CanvasUtils = (function () {
         },
         
         /**
-         * Ensures components are eligible to be moved. The new target can be 
optionally specified.
+         * Ensures components are eligible to be moved. The new group can be 
optionally specified.
          *
          * 1) Ensuring that the input and output ports are not connected 
outside of this group
          * 2) If the target is specified; ensuring there are no port name 
conflicts in the target group
          *
          * @argument {selection} selection      The selection being moved
-         * @argument {selection} group          The selection containing the 
new group
+         * @argument {string} groupId           The id of the new group
          */
-        eligibleForMove: function (selection, group) {
+        eligibleForMove: function (selection, groupId) {
             var inputPorts = [];
             var outputPorts = [];
 
@@ -1191,7 +1224,7 @@ nf.CanvasUtils = (function () {
                             // ports in the root group cannot be moved
                             if (nf.Canvas.getParentGroupId() === null) {
                                 nf.Dialog.showOkDialog({
-                                    dialogContent: 'Ports in the root group 
cannot be moved into another group.',
+                                    dialogContent: 'Cannot move Ports out of 
the root group',
                                     overlayBackground: false
                                 });
                                 portConnectionDeferred.reject();
@@ -1245,12 +1278,11 @@ nf.CanvasUtils = (function () {
                     // create a deferred for checking port names in the target
                     var portNameCheck = function () {
                         return $.Deferred(function (portNameDeferred) {
-                            var groupData = group.datum();
 
                             // add the get request
                             $.ajax({
                                 type: 'GET',
-                                url: config.urls.controller + 
'/process-groups/' + encodeURIComponent(groupData.component.id),
+                                url: config.urls.controller + 
'/process-groups/' + encodeURIComponent(groupId),
                                 data: {
                                     verbose: true
                                 },
@@ -1294,7 +1326,7 @@ nf.CanvasUtils = (function () {
 
                     // execute the checks in order
                     portConnectionCheck().done(function () {
-                        if (nf.Common.isDefinedAndNotNull(group)) {
+                        if (nf.Common.isDefinedAndNotNull(groupId)) {
                             $.when(portNameCheck()).done(function () {
                                 deferred.resolve();
                             }).fail(function () {

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/f72fdcdb/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
index 2d0a41d..e652dd4 100644
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-/* global nf */
+/* global nf, d3 */
 
 nf.ContextMenu = (function () {
 
@@ -276,6 +276,15 @@ nf.ContextMenu = (function () {
     var canStopTransmission = function (selection) {
         return nf.Common.isDFM() && 
nf.CanvasUtils.canAllStopTransmitting(selection);
     };
+    
+    /**
+     * Determines if the components in the specified selection can be moved 
into a parent group.
+     * 
+     * @param {type} selection
+     */
+    var canMoveToParent = function (selection) {
+        return !selection.empty() && nf.CanvasUtils.isDisconnected(selection) 
&& nf.Canvas.getParentGroupId() !== null;
+    };
 
     /**
      * Adds a menu item to the context menu.
@@ -363,6 +372,7 @@ nf.ContextMenu = (function () {
         {condition: isNotConnection, menuItem: {img: 
'images/iconCenterView.png', text: 'Center in view', action: 'center'}},
         {condition: isCopyable, menuItem: {img: 'images/iconCopy.png', text: 
'Copy', action: 'copy'}},
         {condition: isPastable, menuItem: {img: 'images/iconPaste.png', text: 
'Paste', action: 'paste'}},
+        {condition: canMoveToParent, menuItem: {img: 
'images/iconMoveToParent.png', text: 'Move to parent group', action: 
'moveIntoParent'}},
         {condition: isDeletable, menuItem: {img: 'images/iconDelete.png', 
text: 'Delete', action: 'delete'}}
     ];
 

Reply via email to