mirror of https://github.com/apache/nifi.git
NIFI-618:
- Adding a context menu item that allows users to move components out of a process group.
This commit is contained in:
parent
3295f7f193
commit
f72fdcdb15
|
@ -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())) {
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 215 B |
|
@ -914,6 +914,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.
|
||||
|
|
|
@ -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: {
|
||||
|
@ -1025,6 +1077,22 @@ nf.CanvasUtils = (function () {
|
|||
return origin;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -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 () {
|
||||
|
|
|
@ -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'}}
|
||||
];
|
||||
|
||||
|
|
Loading…
Reference in New Issue