http://git-wip-us.apache.org/repos/asf/nifi/blob/bf3b1640/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 e6252cb..2dbb513 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 @@ -15,9 +15,44 @@ * limitations under the License. */ -/* global nf, d3 */ - -nf.Connection = (function () { +/* global define, module, require, exports */ + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', + 'd3', + 'nf.Common', + 'nf.Dialog', + 'nf.ErrorHandler', + 'nf.Client', + 'nf.CanvasUtils'], + function ($, d3, common, dialog, errorHandler, client, canvasUtils) { + return (nf.Connection = factory($, d3, common, dialog, errorHandler, client, canvasUtils)); + }); + } else if (typeof exports === 'object' && typeof module === 'object') { + module.exports = (nf.Connection = + factory(require('jquery'), + require('d3'), + require('nf.Common'), + require('nf.Dialog'), + require('nf.ErrorHandler'), + require('nf.Client'), + require('nf.CanvasUtils'))); + } else { + nf.Connection = factory(root.$, + root.d3, + root.nf.Common, + root.nf.Dialog, + root.nf.ErrorHandler, + root.nf.Client, + root.nf.CanvasUtils); + } +}(this, function ($, d3, common, dialog, errorHandler, client, canvasUtils) { + 'use strict'; + + var nfCanvas; + var nfSelectable; + var nfContextMenu; // the dimensions for the connection label var dimensions = { @@ -162,7 +197,7 @@ nf.Connection = (function () { for (var i = 0; i < line.length; i++) { if (i + 1 < line.length) { var distance = distanceToSegment(p, line[i], line[i + 1]); - if (nf.Common.isUndefined(minimumDistance) || distance < minimumDistance) { + if (common.isUndefined(minimumDistance) || distance < minimumDistance) { minimumDistance = distance; index = i; } @@ -197,7 +232,7 @@ nf.Connection = (function () { * @param {object} terminal */ var isGroup = function (terminal) { - return terminal.groupId !== nf.Canvas.getGroupId() && (isInputPortType(terminal.type) || isOutputPortType(terminal.type)); + return terminal.groupId !== canvasUtils.getGroupId() && (isInputPortType(terminal.type) || isOutputPortType(terminal.type)); }; /** @@ -207,7 +242,7 @@ nf.Connection = (function () { * @return {boolean} Whether expiration is configured */ var isExpirationConfigured = function (connection) { - if (nf.Common.isDefinedAndNotNull(connection.flowFileExpiration)) { + if (common.isDefinedAndNotNull(connection.flowFileExpiration)) { var match = connection.flowFileExpiration.match(/^(\d+).*/); if (match !== null && match.length > 0) { if (parseInt(match[0], 10) > 0) { @@ -274,9 +309,9 @@ nf.Connection = (function () { }) .on('mousedown.selection', function () { // select the connection when clicking the selectable path - nf.Selectable.select(d3.select(this.parentNode)); + nfSelectable.select(d3.select(this.parentNode)); }) - .call(nf.ContextMenu.activate); + .call(nfContextMenu.activate); }; // determines whether the specified connection contains an unsupported relationship @@ -284,7 +319,7 @@ nf.Connection = (function () { var unavailable = false; // verify each selected relationship is still available - if (nf.Common.isDefinedAndNotNull(d.component.selectedRelationships) && nf.Common.isDefinedAndNotNull(d.component.availableRelationships)) { + if (common.isDefinedAndNotNull(d.component.selectedRelationships) && common.isDefinedAndNotNull(d.component.availableRelationships)) { $.each(d.component.selectedRelationships, function (_, selectedRelationship) { if ($.inArray(selectedRelationship, d.component.availableRelationships) === -1) { unavailable = true; @@ -331,7 +366,7 @@ nf.Connection = (function () { // determines whether the connection is in warning based on the object count threshold var isWarningCount = function (d) { var percentUseCount = d.status.aggregateSnapshot.percentUseCount; - if (nf.Common.isDefinedAndNotNull(percentUseCount)) { + if (common.isDefinedAndNotNull(percentUseCount)) { return percentUseCount >= 61 && percentUseCount <= 85; } @@ -341,7 +376,7 @@ nf.Connection = (function () { // determines whether the connection is in error based on the object count threshold var isErrorCount = function (d) { var percentUseCount = d.status.aggregateSnapshot.percentUseCount; - if (nf.Common.isDefinedAndNotNull(percentUseCount)) { + if (common.isDefinedAndNotNull(percentUseCount)) { return percentUseCount > 85; } @@ -356,7 +391,7 @@ nf.Connection = (function () { // determines whether the connection is in warning based on the data size threshold var isWarningBytes = function (d) { var percentUseBytes = d.status.aggregateSnapshot.percentUseBytes; - if (nf.Common.isDefinedAndNotNull(percentUseBytes)) { + if (common.isDefinedAndNotNull(percentUseBytes)) { return percentUseBytes >= 61 && percentUseBytes <= 85; } @@ -366,7 +401,7 @@ nf.Connection = (function () { // determines whether the connection is in error based on the data size threshold var isErrorBytes = function (d) { var percentUseBytes = d.status.aggregateSnapshot.percentUseBytes; - if (nf.Common.isDefinedAndNotNull(percentUseBytes)) { + if (common.isDefinedAndNotNull(percentUseBytes)) { return percentUseBytes > 85; } @@ -384,10 +419,10 @@ nf.Connection = (function () { var transition = false; // extract the options if specified - if (nf.Common.isDefinedAndNotNull(options)) { - updatePath = nf.Common.isDefinedAndNotNull(options.updatePath) ? options.updatePath : updatePath; - updateLabel = nf.Common.isDefinedAndNotNull(options.updateLabel) ? options.updateLabel : updateLabel; - transition = nf.Common.isDefinedAndNotNull(options.transition) ? options.transition : transition; + if (common.isDefinedAndNotNull(options)) { + updatePath = common.isDefinedAndNotNull(options.updatePath) ? options.updatePath : updatePath; + updateLabel = common.isDefinedAndNotNull(options.updateLabel) ? options.updateLabel : updateLabel; + transition = common.isDefinedAndNotNull(options.transition) ? options.transition : transition; } if (updatePath === true) { @@ -397,7 +432,7 @@ nf.Connection = (function () { if (d.permissions.canRead) { // if there are more than one selected relationship, mark this as grouped - if (nf.Common.isDefinedAndNotNull(d.component.selectedRelationships) && d.component.selectedRelationships.length > 1) { + if (common.isDefinedAndNotNull(d.component.selectedRelationships) && d.component.selectedRelationships.length > 1) { grouped = true; } } @@ -472,7 +507,7 @@ nf.Connection = (function () { if (updatePath === true) { // calculate the start and end points - var sourceComponentId = nf.CanvasUtils.getConnectionSourceComponentId(d); + var sourceComponentId = canvasUtils.getConnectionSourceComponentId(d); var sourceData = d3.select('#id-' + sourceComponentId).datum(); var end; @@ -487,9 +522,9 @@ nf.Connection = (function () { }; } - // if we are currently dragging the endpoint to a new target, use that + // if we are currently dragging the endpoint to a new target, use that // position, otherwise we need to calculate it for the current target - if (nf.Common.isDefinedAndNotNull(d.end) && d.end.dragging === true) { + if (common.isDefinedAndNotNull(d.end) && d.end.dragging === true) { // since we're dragging, use the same object thats bound to the endpoint drag event end = d.end; @@ -499,7 +534,7 @@ nf.Connection = (function () { var newDestinationData = newDestination.datum(); // get the position on the new destination perimeter - var newEnd = nf.CanvasUtils.getPerimeterPoint(endAnchor, { + var newEnd = canvasUtils.getPerimeterPoint(endAnchor, { 'x': newDestinationData.position.x, 'y': newDestinationData.position.y, 'width': newDestinationData.dimensions.width, @@ -511,11 +546,11 @@ nf.Connection = (function () { end.y = newEnd.y; } } else { - var destinationComponentId = nf.CanvasUtils.getConnectionDestinationComponentId(d); + var destinationComponentId = canvasUtils.getConnectionDestinationComponentId(d); var destinationData = d3.select('#id-' + destinationComponentId).datum(); // get the position on the destination perimeter - end = nf.CanvasUtils.getPerimeterPoint(endAnchor, { + end = canvasUtils.getPerimeterPoint(endAnchor, { 'x': destinationData.position.x, 'y': destinationData.position.y, 'width': destinationData.dimensions.width, @@ -532,7 +567,7 @@ nf.Connection = (function () { } // get the position on the source perimeter - var start = nf.CanvasUtils.getPerimeterPoint(startAnchor, { + var start = canvasUtils.getPerimeterPoint(startAnchor, { 'x': sourceData.position.x, 'y': sourceData.position.y, 'width': sourceData.dimensions.width, @@ -544,21 +579,21 @@ nf.Connection = (function () { d.end = end; // update the connection paths - nf.CanvasUtils.transition(connection.select('path.connection-path'), transition) + canvasUtils.transition(connection.select('path.connection-path'), transition) .attr({ 'd': function () { var datum = [d.start].concat(d.bends, [d.end]); return lineGenerator(datum); } }); - nf.CanvasUtils.transition(connection.select('path.connection-selection-path'), transition) + canvasUtils.transition(connection.select('path.connection-selection-path'), transition) .attr({ 'd': function () { var datum = [d.start].concat(d.bends, [d.end]); return lineGenerator(datum); } }); - nf.CanvasUtils.transition(connection.select('path.connection-path-selectable'), transition) + canvasUtils.transition(connection.select('path.connection-path-selectable'), transition) .attr({ 'd': function () { var datum = [d.start].concat(d.bends, [d.end]); @@ -594,12 +629,12 @@ nf.Connection = (function () { }) .on('mousedown.selection', function () { // select the connection when clicking the label - nf.Selectable.select(d3.select(this.parentNode)); + nfSelectable.select(d3.select(this.parentNode)); }) - .call(nf.ContextMenu.activate); + .call(nfContextMenu.activate); // update the start point - nf.CanvasUtils.transition(startpoints, transition) + canvasUtils.transition(startpoints, transition) .attr('transform', function (p) { return 'translate(' + (p.x - 4) + ', ' + (p.y - 4) + ')'; }); @@ -624,12 +659,12 @@ nf.Connection = (function () { }) .on('mousedown.selection', function () { // select the connection when clicking the label - nf.Selectable.select(d3.select(this.parentNode)); + nfSelectable.select(d3.select(this.parentNode)); }) - .call(nf.ContextMenu.activate); + .call(nfContextMenu.activate); // update the end point - nf.CanvasUtils.transition(endpoints, transition) + canvasUtils.transition(endpoints, transition) .attr('transform', function (p) { return 'translate(' + (p.x - 4) + ', ' + (p.y - 4) + ')'; }); @@ -660,10 +695,10 @@ nf.Connection = (function () { var connectionData = connection.datum(); // if this is a self loop prevent removing the last two bends - var sourceComponentId = nf.CanvasUtils.getConnectionSourceComponentId(connectionData); - var destinationComponentId = nf.CanvasUtils.getConnectionDestinationComponentId(connectionData); + var sourceComponentId = canvasUtils.getConnectionSourceComponentId(connectionData); + var destinationComponentId = canvasUtils.getConnectionDestinationComponentId(connectionData); if (sourceComponentId === destinationComponentId && d.component.bends.length <= 2) { - nf.Dialog.showOkDialog({ + dialog.showOkDialog({ headerText: 'Connection', dialogContent: 'Looping connections must have at least two bend points.' }); @@ -704,12 +739,12 @@ nf.Connection = (function () { }) .on('mousedown.selection', function () { // select the connection when clicking the label - nf.Selectable.select(d3.select(this.parentNode)); + nfSelectable.select(d3.select(this.parentNode)); }) - .call(nf.ContextMenu.activate); + .call(nfContextMenu.activate); // update the midpoints - nf.CanvasUtils.transition(midpoints, transition) + canvasUtils.transition(midpoints, transition) .attr('transform', function (p) { return 'translate(' + (p.x - 4) + ', ' + (p.y - 4) + ')'; }); @@ -730,7 +765,7 @@ nf.Connection = (function () { // update visible connections if (connection.classed('visible')) { - // if there is no connection label this connection is becoming + // if there is no connection label this connection is becoming // visible so we need to render it if (connectionLabelContainer.empty()) { // connection label container @@ -741,9 +776,9 @@ nf.Connection = (function () { }) .on('mousedown.selection', function () { // select the connection when clicking the label - nf.Selectable.select(d3.select(this.parentNode)); + nfSelectable.select(d3.select(this.parentNode)); }) - .call(nf.ContextMenu.activate); + .call(nfContextMenu.activate); // connection label connectionLabelContainer.append('rect') @@ -846,7 +881,7 @@ nf.Connection = (function () { connectionFromLabel.text(null).selectAll('title').remove(); // apply ellipsis to the label as necessary - nf.CanvasUtils.ellipsis(connectionFromLabel, d.component.source.name); + canvasUtils.ellipsis(connectionFromLabel, d.component.source.name); }).append('title').text(function () { return d.component.source.name; }); @@ -955,7 +990,7 @@ nf.Connection = (function () { connectionToLabel.text(null).selectAll('title').remove(); // apply ellipsis to the label as necessary - nf.CanvasUtils.ellipsis(connectionToLabel, d.component.destination.name); + canvasUtils.ellipsis(connectionToLabel, d.component.destination.name); }).append('title').text(function (d) { return d.component.destination.name; }); @@ -998,10 +1033,10 @@ nf.Connection = (function () { // ----------------------- // get the connection name - var connectionNameValue = nf.CanvasUtils.formatConnectionName(d.component); + var connectionNameValue = canvasUtils.formatConnectionName(d.component); // is there a name to render - if (!nf.Common.isBlank(connectionNameValue)) { + if (!common.isBlank(connectionNameValue)) { // see if the connection name label is already rendered if (connectionName.empty()) { connectionName = connectionLabelContainer.append('g') @@ -1060,7 +1095,7 @@ nf.Connection = (function () { connectionToLabel.text(null).selectAll('title').remove(); // apply ellipsis to the label as necessary - nf.CanvasUtils.ellipsis(connectionToLabel, connectionNameValue); + canvasUtils.ellipsis(connectionToLabel, connectionNameValue); }).append('title').text(function () { return connectionNameValue; }); @@ -1288,31 +1323,31 @@ nf.Connection = (function () { } }) .select('title').text(function () { - if (d.permissions.canRead) { - return 'Expires FlowFiles older than ' + d.component.flowFileExpiration; - } else { - return ''; - } - }); + if (d.permissions.canRead) { + return 'Expires FlowFiles older than ' + d.component.flowFileExpiration; + } else { + return ''; + } + }); // update backpressure object fill connectionLabelContainer.select('rect.backpressure-object') .classed('not-configured', function () { - return nf.Common.isUndefinedOrNull(d.status.aggregateSnapshot.percentUseCount); + return common.isUndefinedOrNull(d.status.aggregateSnapshot.percentUseCount); }); connectionLabelContainer.selectAll('rect.backpressure-tick.object') .classed('not-configured', function () { - return nf.Common.isUndefinedOrNull(d.status.aggregateSnapshot.percentUseCount); + return common.isUndefinedOrNull(d.status.aggregateSnapshot.percentUseCount); }); // update backpressure data size fill connectionLabelContainer.select('rect.backpressure-data-size') .classed('not-configured', function () { - return nf.Common.isUndefinedOrNull(d.status.aggregateSnapshot.percentUseBytes); + return common.isUndefinedOrNull(d.status.aggregateSnapshot.percentUseBytes); }); connectionLabelContainer.selectAll('rect.backpressure-tick.data-size') .classed('not-configured', function () { - return nf.Common.isUndefinedOrNull(d.status.aggregateSnapshot.percentUseBytes); + return common.isUndefinedOrNull(d.status.aggregateSnapshot.percentUseBytes); }); if (d.permissions.canWrite) { @@ -1330,7 +1365,7 @@ nf.Connection = (function () { } // update the position of the label if possible - nf.CanvasUtils.transition(connection.select('g.connection-label-container'), transition) + canvasUtils.transition(connection.select('g.connection-label-container'), transition) .attr('transform', function () { var label = d3.select(this).select('rect.body'); var position = getLabelPosition(label); @@ -1354,7 +1389,7 @@ nf.Connection = (function () { // queued count value updated.select('text.queued tspan.count') .text(function (d) { - return nf.Common.substringBeforeFirst(d.status.aggregateSnapshot.queued, ' '); + return common.substringBeforeFirst(d.status.aggregateSnapshot.queued, ' '); }); var backpressurePercentDataSize = updated.select('rect.backpressure-percent.data-size'); @@ -1362,26 +1397,26 @@ nf.Connection = (function () { .duration(400) .attr({ 'width': function (d) { - if (nf.Common.isDefinedAndNotNull(d.status.aggregateSnapshot.percentUseBytes)) { + if (common.isDefinedAndNotNull(d.status.aggregateSnapshot.percentUseBytes)) { return (backpressureBarWidth * d.status.aggregateSnapshot.percentUseBytes) / 100; } else { return 0; } } }).each('end', function () { - backpressurePercentDataSize - .classed('warning', function (d) { - return isWarningBytes(d); - }) - .classed('error', function (d) { - return isErrorBytes(d); - }); + backpressurePercentDataSize + .classed('warning', function (d) { + return isWarningBytes(d); + }) + .classed('error', function (d) { + return isErrorBytes(d); + }); - deferred.resolve(); - }); + deferred.resolve(); + }); updated.select('rect.backpressure-data-size').select('title').text(function (d) { - if (nf.Common.isDefinedAndNotNull(d.status.aggregateSnapshot.percentUseBytes)) { + if (common.isDefinedAndNotNull(d.status.aggregateSnapshot.percentUseBytes)) { return 'Queue is ' + d.status.aggregateSnapshot.percentUseBytes + '% full based on Back Pressure Data Size Threshold'; } else { return 'Back Pressure Data Size Threshold is not configured'; @@ -1394,7 +1429,7 @@ nf.Connection = (function () { // queued size value updated.select('text.queued tspan.size') .text(function (d) { - return ' ' + nf.Common.substringAfterFirst(d.status.aggregateSnapshot.queued, ' '); + return ' ' + common.substringAfterFirst(d.status.aggregateSnapshot.queued, ' '); }); var backpressurePercentObject = updated.select('rect.backpressure-percent.object'); @@ -1402,26 +1437,26 @@ nf.Connection = (function () { .duration(400) .attr({ 'width': function (d) { - if (nf.Common.isDefinedAndNotNull(d.status.aggregateSnapshot.percentUseCount)) { + if (common.isDefinedAndNotNull(d.status.aggregateSnapshot.percentUseCount)) { return (backpressureBarWidth * d.status.aggregateSnapshot.percentUseCount) / 100; } else { return 0; } } }).each('end', function () { - backpressurePercentObject - .classed('warning', function (d) { - return isWarningCount(d); - }) - .classed('error', function (d) { - return isErrorCount(d); - }); + backpressurePercentObject + .classed('warning', function (d) { + return isWarningCount(d); + }) + .classed('error', function (d) { + return isErrorCount(d); + }); - deferred.resolve(); - }); + deferred.resolve(); + }); updated.select('rect.backpressure-object').select('title').text(function (d) { - if (nf.Common.isDefinedAndNotNull(d.status.aggregateSnapshot.percentUseCount)) { + if (common.isDefinedAndNotNull(d.status.aggregateSnapshot.percentUseCount)) { return 'Queue is ' + d.status.aggregateSnapshot.percentUseCount + '% full based on Back Pressure Object Threshold'; } else { return 'Back Pressure Object Threshold is not configured'; @@ -1463,7 +1498,7 @@ nf.Connection = (function () { */ var save = function (d, connection) { var entity = { - 'revision': nf.Client.getRevision(d), + 'revision': client.getRevision(d), 'component': connection }; @@ -1475,15 +1510,15 @@ nf.Connection = (function () { contentType: 'application/json' }).done(function (response) { // request was successful, update the entry - nf.Connection.set(response); + nfConnection.set(response); }).fail(function (xhr, status, error) { if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409) { - nf.Dialog.showOkDialog({ + dialog.showOkDialog({ headerText: 'Connection', - dialogContent: nf.Common.escapeHtml(xhr.responseText) + dialogContent: common.escapeHtml(xhr.responseText) }); } else { - nf.ErrorHandler.handleAjaxError(xhr, status, error); + errorHandler.handleAjaxError(xhr, status, error); } }); }; @@ -1492,20 +1527,23 @@ nf.Connection = (function () { var removeConnections = function (removed) { // consider reloading source/destination of connection being removed removed.each(function (d) { - nf.CanvasUtils.reloadConnectionSourceAndDestination(d.sourceId, d.destinationId); + canvasUtils.reloadConnectionSourceAndDestination(d.sourceId, d.destinationId); }); // remove the connection removed.remove(); }; - return { + var nfConnection = { config: { selfLoopXOffset: (dimensions.width / 2) + 5, selfLoopYOffset: 25 }, - init: function () { + init: function (selectable, contextMenu) { + nfSelectable = selectable; + nfContextMenu = contextMenu; + connectionMap = d3.map(); removedCache = d3.map(); addedCache = d3.map(); @@ -1600,7 +1638,7 @@ nf.Connection = (function () { // ensure the new destination is valid d3.select('g.hover').classed('connectable-destination', function () { - return nf.CanvasUtils.isValidConnectionDestination(d3.select(this)); + return canvasUtils.isValidConnectionDestination(d3.select(this)); }); // redraw this connection @@ -1629,11 +1667,11 @@ nf.Connection = (function () { }); } else { // prompt for the new port if appropriate - if (nf.CanvasUtils.isProcessGroup(destination) || nf.CanvasUtils.isRemoteProcessGroup(destination)) { + if (canvasUtils.isProcessGroup(destination) || canvasUtils.isRemoteProcessGroup(destination)) { // user will select new port and updated connect details will be set accordingly - nf.ConnectionConfiguration.showConfiguration(connection, destination).done(function () { + nfConnectionConfiguration.showConfiguration(connection, destination).done(function () { // reload the previous destination - nf.CanvasUtils.reloadConnectionSourceAndDestination(null, previousDestinationId); + canvasUtils.reloadConnectionSourceAndDestination(null, previousDestinationId); }).fail(function () { // reset the connection connection.call(updateConnections, { @@ -1644,15 +1682,15 @@ nf.Connection = (function () { } else { // get the destination details var destinationData = destination.datum(); - var destinationType = nf.CanvasUtils.getConnectableTypeForDestination(destination); + var destinationType = canvasUtils.getConnectableTypeForDestination(destination); var connectionEntity = { - 'revision': nf.Client.getRevision(connectionData), + 'revision': client.getRevision(connectionData), 'component': { 'id': connectionData.id, 'destination': { 'id': destinationData.id, - 'groupId': nf.Canvas.getGroupId(), + 'groupId': canvasUtils.getGroupId(), 'type': destinationType } } @@ -1664,8 +1702,8 @@ nf.Connection = (function () { x: destinationData.position.x + (destinationData.dimensions.width), y: destinationData.position.y + (destinationData.dimensions.height / 2) }; - var xOffset = nf.Connection.config.selfLoopXOffset; - var yOffset = nf.Connection.config.selfLoopYOffset; + var xOffset = nfConnection.config.selfLoopXOffset; + var yOffset = nfConnection.config.selfLoopYOffset; connectionEntity.component.bends = []; connectionEntity.component.bends.push({ @@ -1688,16 +1726,16 @@ nf.Connection = (function () { var updatedConnectionData = response.component; // refresh to update the label - nf.Connection.set(response); + nfConnection.set(response); // reload the previous destination and the new source/destination - nf.CanvasUtils.reloadConnectionSourceAndDestination(null, previousDestinationId); - nf.CanvasUtils.reloadConnectionSourceAndDestination(response.sourceId, response.destinationId); + canvasUtils.reloadConnectionSourceAndDestination(null, previousDestinationId); + canvasUtils.reloadConnectionSourceAndDestination(response.sourceId, response.destinationId); }).fail(function (xhr, status, error) { if (xhr.status === 400 || xhr.status === 401 || xhr.status === 403 || xhr.status === 404 || xhr.status === 409) { - nf.Dialog.showOkDialog({ + dialog.showOkDialog({ headerText: 'Connection', - dialogContent: nf.Common.escapeHtml(xhr.responseText) + dialogContent: common.escapeHtml(xhr.responseText) }); // reset the connection @@ -1706,7 +1744,7 @@ nf.Connection = (function () { 'updateLabel': false }); } else { - nf.ErrorHandler.handleAjaxError(xhr, status, error); + errorHandler.handleAjaxError(xhr, status, error); } }); } @@ -1743,10 +1781,10 @@ nf.Connection = (function () { .attr('width', width) .attr('height', height) .attr('stroke-width', function () { - return 1 / nf.Canvas.View.scale(); + return 1 / canvasUtils.scaleCanvasView(); }) .attr('stroke-dasharray', function () { - return 4 / nf.Canvas.View.scale(); + return 4 / canvasUtils.scaleCanvasView(); }) .datum({ x: position.x, @@ -1847,8 +1885,8 @@ nf.Connection = (function () { */ add: function (connectionEntities, options) { var selectAll = false; - if (nf.Common.isDefinedAndNotNull(options)) { - selectAll = nf.Common.isDefinedAndNotNull(options.selectAll) ? options.selectAll : selectAll; + if (common.isDefinedAndNotNull(options)) { + selectAll = common.isDefinedAndNotNull(options.selectAll) ? options.selectAll : selectAll; } // get the current time @@ -1868,7 +1906,7 @@ nf.Connection = (function () { $.each(connectionEntities, function (_, connectionEntity) { add(connectionEntity); }); - } else if (nf.Common.isDefinedAndNotNull(connectionEntities)) { + } else if (common.isDefinedAndNotNull(connectionEntities)) { add(connectionEntities); } @@ -1882,6 +1920,56 @@ nf.Connection = (function () { }, /** + * Determines if the specified selection is disconnected from other nodes. + * + * @argument {selection} selection The selection + */ + isDisconnected: function (selection) {⨠+ + // if nothing is selected return + if (selection.empty()) { + return false; + } + var connections = d3.map(); + var components = d3.map(); + var isDisconnected = true;â¨â¨ + + // include connections + selection.filter(function (d) { + return d.type === 'Connection'; + }).each(function (d) { + connections.set(d.id, d); + });â¨â¨ + + // include components and ensure their connections are included + selection.filter(function (d) { + return d.type !== 'Connection'; + }).each(function (d) { + components.set(d.id, d.component);â¨â¨ + + // check all connections of this component + $.each(nfConnection.getComponentConnections(d.id), function (_, connection) { + if (!connections.has(connection.id)) { + isDisconnected = false; + return false; + } + }); + }); + if (isDisconnected) {⨠+ + // go through each connection to ensure its source and destination are included + connections.forEach(function (id, connection) { + if (isDisconnected) {⨠+ + // determine whether this connection and its components are included within the selection + isDisconnected = components.has(canvasUtils.getConnectionSourceComponentId(connection)) && components.has(canvasUtils.getConnectionDestinationComponentId(connection)); + } + }); + } + return isDisconnected; + }, + + /** * Populates the graph with the specified connections. * * @argument {object | array} connectionEntities The connections to add @@ -1890,16 +1978,16 @@ nf.Connection = (function () { set: function (connectionEntities, options) { var selectAll = false; var transition = false; - if (nf.Common.isDefinedAndNotNull(options)) { - selectAll = nf.Common.isDefinedAndNotNull(options.selectAll) ? options.selectAll : selectAll; - transition = nf.Common.isDefinedAndNotNull(options.transition) ? options.transition : transition; + if (common.isDefinedAndNotNull(options)) { + selectAll = common.isDefinedAndNotNull(options.selectAll) ? options.selectAll : selectAll; + transition = common.isDefinedAndNotNull(options.transition) ? options.transition : transition; } var set = function (proposedConnectionEntity) { var currentConnectionEntity = connectionMap.get(proposedConnectionEntity.id); // set the connection if appropriate due to revision and wasn't previously removed - if (nf.Client.isNewerRevision(currentConnectionEntity, proposedConnectionEntity) && !removedCache.has(proposedConnectionEntity.id)) { + if (client.isNewerRevision(currentConnectionEntity, proposedConnectionEntity) && !removedCache.has(proposedConnectionEntity.id)) { connectionMap.set(proposedConnectionEntity.id, $.extend({ type: 'Connection' }, proposedConnectionEntity)); @@ -1922,7 +2010,7 @@ nf.Connection = (function () { $.each(connectionEntities, function (_, connectionEntity) { set(connectionEntity); }); - } else if (nf.Common.isDefinedAndNotNull(connectionEntities)) { + } else if (common.isDefinedAndNotNull(connectionEntities)) { set(connectionEntities); } @@ -1943,7 +2031,7 @@ nf.Connection = (function () { * @param {string} connectionId */ refresh: function (connectionId) { - if (nf.Common.isDefinedAndNotNull(connectionId)) { + if (common.isDefinedAndNotNull(connectionId)) { d3.select('#id-' + connectionId).call(updateConnections, { 'updatePath': true, 'updateLabel': true @@ -1992,7 +2080,7 @@ nf.Connection = (function () { * Removes all processors. */ removeAll: function () { - nf.Connection.remove(connectionMap.keys()); + nfConnection.remove(connectionMap.keys()); }, /** @@ -2008,7 +2096,7 @@ nf.Connection = (function () { url: connectionEntity.uri, dataType: 'json' }).done(function (response) { - nf.Connection.set(response); + nfConnection.set(response); }); } }, @@ -2046,7 +2134,7 @@ nf.Connection = (function () { var connections = []; connectionMap.forEach(function (_, entry) { // see if this component is the source or destination of this connection - if (nf.CanvasUtils.getConnectionSourceComponentId(entry) === id || nf.CanvasUtils.getConnectionDestinationComponentId(entry) === id) { + if (canvasUtils.getConnectionSourceComponentId(entry) === id || canvasUtils.getConnectionDestinationComponentId(entry) === id) { connections.push(entry); } }); @@ -2060,7 +2148,7 @@ nf.Connection = (function () { * @param {string} id */ get: function (id) { - if (nf.Common.isUndefined(id)) { + if (common.isUndefined(id)) { return connectionMap.values(); } else { return connectionMap.get(id); @@ -2085,4 +2173,6 @@ nf.Connection = (function () { expire(removedCache); } }; -}()); \ No newline at end of file + + return nfConnection; +})); \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/bf3b1640/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-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js index b51ddb0..ba0acb0 100644 --- a/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-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js @@ -15,9 +15,39 @@ * limitations under the License. */ -/* global nf, d3 */ - -nf.ContextMenu = (function () { +/* global define, module, require, exports */ + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', + 'd3', + 'nf.ErrorHandler', + 'nf.Common', + 'nf.CanvasUtils', + 'nf.ng.Bridge'], + function ($, d3, errorHandler, common, canvasUtils, angularBridge) { + return (nf.ContextMenu = factory($, d3, errorHandler, common, canvasUtils, angularBridge)); + }); + } else if (typeof exports === 'object' && typeof module === 'object') { + module.exports = (nf.ContextMenu = + factory(require('jquery'), + require('d3'), + require('nf.ErrorHandler'), + require('nf.Common'), + require('nf.CanvasUtils'), + require('nf.ng.Bridge'))); + } else { + nf.ContextMenu = factory(root.$, + root.d3, + root.nf.ErrorHandler, + root.nf.Common, + root.nf.CanvasUtils, + root.nf.ng.Bridge); + } +}(this, function ($, d3, errorHandler, common, canvasUtils, angularBridge) { + 'use strict'; + + var nfActions; /** * Returns whether the current group is not the root group. @@ -25,57 +55,57 @@ nf.ContextMenu = (function () { * @param {selection} selection The selection of currently selected components */ var isNotRootGroup = function (selection) { - return nf.Canvas.getParentGroupId() !== null && selection.empty(); + return canvasUtils.getParentGroupId() !== null && selection.empty(); }; /** * Determines whether the component in the specified selection is configurable. - * + * * @param {selection} selection The selection of currently selected components */ var isConfigurable = function (selection) { - return nf.CanvasUtils.isConfigurable(selection); + return canvasUtils.isConfigurable(selection); }; /** * Determines whether the component in the specified selection has configuration details. - * + * * @param {selection} selection The selection of currently selected components */ var hasDetails = function (selection) { - return nf.CanvasUtils.hasDetails(selection); + return canvasUtils.hasDetails(selection); }; /** * Determines whether the components in the specified selection are deletable. - * - * @param {selection} selection The selection of currently selected components + * + * @param {selection} selection The selection of currently selected components */ var isDeletable = function (selection) { - return nf.CanvasUtils.areDeletable(selection); + return canvasUtils.areDeletable(selection); }; /** * Determines whether the components in the specified selection are runnable. - * - * @param {selection} selection The selection of currently selected components + * + * @param {selection} selection The selection of currently selected components */ var isRunnable = function (selection) { - return nf.CanvasUtils.areRunnable(selection); + return canvasUtils.areRunnable(selection); }; /** * Determines whether the components in the specified selection are stoppable. - * - * @param {selection} selection The selection of currently selected components + * + * @param {selection} selection The selection of currently selected components */ var isStoppable = function (selection) { - return nf.CanvasUtils.areStoppable(selection); + return canvasUtils.areStoppable(selection); }; /** * Determines whether the components in the specified selection support stats. - * + * * @param {selection} selection The selection of currently selected components */ var supportsStats = function (selection) { @@ -84,12 +114,12 @@ nf.ContextMenu = (function () { return false; } - return nf.CanvasUtils.isProcessor(selection) || nf.CanvasUtils.isProcessGroup(selection) || nf.CanvasUtils.isRemoteProcessGroup(selection) || nf.CanvasUtils.isConnection(selection); + return canvasUtils.isProcessor(selection) || canvasUtils.isProcessGroup(selection) || canvasUtils.isRemoteProcessGroup(selection) || canvasUtils.isConnection(selection); }; /** * Determines whether the components in the specified selection has usage documentation. - * + * * @param {selection} selection The selection of currently selected components */ var hasUsage = function (selection) { @@ -97,43 +127,43 @@ nf.ContextMenu = (function () { if (selection.size() !== 1) { return false; } - if (nf.CanvasUtils.canRead(selection) === false) { + if (canvasUtils.canRead(selection) === false) { return false; } - return nf.CanvasUtils.isProcessor(selection); + return canvasUtils.isProcessor(selection); }; /** * Determines whether there is one component selected. - * + * * @param {selection} selection The selection of currently selected components */ var isNotConnection = function (selection) { - return selection.size() === 1 && !nf.CanvasUtils.isConnection(selection); + return selection.size() === 1 && !canvasUtils.isConnection(selection); }; /** * Determines whether the components in the specified selection are copyable. - * + * * @param {selection} selection The selection of currently selected components */ var isCopyable = function (selection) { - return nf.CanvasUtils.isCopyable(selection); + return canvasUtils.isCopyable(selection); }; /** * Determines whether the components in the specified selection are pastable. - * + * * @param {selection} selection The selection of currently selected components */ var isPastable = function (selection) { - return nf.CanvasUtils.isPastable(); + return canvasUtils.isPastable(); }; /** * Determines whether the specified selection is empty. - * + * * @param {selection} selection The seleciton */ var emptySelection = function (selection) { @@ -142,7 +172,7 @@ nf.ContextMenu = (function () { /** * Determines whether the componets in the specified selection support being moved to the front. - * + * * @param {selection} selection The selection */ var canMoveToFront = function (selection) { @@ -150,11 +180,11 @@ nf.ContextMenu = (function () { if (selection.size() !== 1) { return false; } - if (nf.CanvasUtils.canModify(selection) === false) { + if (canvasUtils.canModify(selection) === false) { return false; } - return nf.CanvasUtils.isConnection(selection); + return canvasUtils.isConnection(selection); }; /** @@ -163,7 +193,7 @@ nf.ContextMenu = (function () { * @param {selection} selection The selection */ var canAlign = function (selection) { - return nf.CanvasUtils.canAlign(selection); + return canvasUtils.canAlign(selection); }; /** @@ -172,12 +202,12 @@ nf.ContextMenu = (function () { * @param {selection} selection The selection */ var isColorable = function (selection) { - return nf.CanvasUtils.isColorable(selection); + return canvasUtils.isColorable(selection); }; /** * Determines whether the component in the specified selection is a connection. - * + * * @param {selection} selection The selection */ var isConnection = function (selection) { @@ -186,12 +216,12 @@ nf.ContextMenu = (function () { return false; } - return nf.CanvasUtils.isConnection(selection); + return canvasUtils.isConnection(selection); }; /** * Determines whether the component in the specified selection could possibly have downstream components. - * + * * @param {selection} selection The selection */ var hasDownstream = function (selection) { @@ -200,14 +230,14 @@ nf.ContextMenu = (function () { return false; } - return nf.CanvasUtils.isFunnel(selection) || nf.CanvasUtils.isProcessor(selection) || nf.CanvasUtils.isProcessGroup(selection) || - nf.CanvasUtils.isRemoteProcessGroup(selection) || nf.CanvasUtils.isInputPort(selection) || - (nf.CanvasUtils.isOutputPort(selection) && nf.Canvas.getParentGroupId() !== null); + return canvasUtils.isFunnel(selection) || canvasUtils.isProcessor(selection) || canvasUtils.isProcessGroup(selection) || + canvasUtils.isRemoteProcessGroup(selection) || canvasUtils.isInputPort(selection) || + (canvasUtils.isOutputPort(selection) && canvasUtils.getParentGroupId() !== null); }; /** * Determines whether the component in the specified selection could possibly have upstream components. - * + * * @param {selection} selection The selection */ var hasUpstream = function (selection) { @@ -216,9 +246,9 @@ nf.ContextMenu = (function () { return false; } - return nf.CanvasUtils.isFunnel(selection) || nf.CanvasUtils.isProcessor(selection) || nf.CanvasUtils.isProcessGroup(selection) || - nf.CanvasUtils.isRemoteProcessGroup(selection) || nf.CanvasUtils.isOutputPort(selection) || - (nf.CanvasUtils.isInputPort(selection) && nf.Canvas.getParentGroupId() !== null); + return canvasUtils.isFunnel(selection) || canvasUtils.isProcessor(selection) || canvasUtils.isProcessGroup(selection) || + canvasUtils.isRemoteProcessGroup(selection) || canvasUtils.isOutputPort(selection) || + (canvasUtils.isInputPort(selection) && canvasUtils.getParentGroupId() !== null); }; /** @@ -231,11 +261,11 @@ nf.ContextMenu = (function () { if (selection.size() !== 1) { return false; } - if (nf.CanvasUtils.canRead(selection) === false || nf.CanvasUtils.canModify(selection) === false) { + if (canvasUtils.canRead(selection) === false || canvasUtils.canModify(selection) === false) { return false; } - if (nf.CanvasUtils.isProcessor(selection)) { + if (canvasUtils.isProcessor(selection)) { var processorData = selection.datum(); return processorData.component.persistsState === true; } else { @@ -245,7 +275,7 @@ nf.ContextMenu = (function () { /** * Determines whether the current selection is a process group. - * + * * @param {selection} selection */ var isProcessGroup = function (selection) { @@ -254,7 +284,7 @@ nf.ContextMenu = (function () { return false; } - return nf.CanvasUtils.isProcessGroup(selection); + return canvasUtils.isProcessGroup(selection); }; /** @@ -268,56 +298,56 @@ nf.ContextMenu = (function () { return false; } - return !nf.CanvasUtils.isLabel(selection) && !nf.CanvasUtils.isConnection(selection) && !nf.CanvasUtils.isProcessGroup(selection) - && !nf.CanvasUtils.isRemoteProcessGroup(selection) && nf.Common.canAccessProvenance(); + return !canvasUtils.isLabel(selection) && !canvasUtils.isConnection(selection) && !canvasUtils.isProcessGroup(selection) + && !canvasUtils.isRemoteProcessGroup(selection) && common.canAccessProvenance(); }; /** * Determines whether the current selection is a remote process group. - * - * @param {selection} selection + * + * @param {selection} selection */ var isRemoteProcessGroup = function (selection) { // ensure the correct number of components are selected if (selection.size() !== 1) { return false; } - if (nf.CanvasUtils.canRead(selection) === false) { + if (canvasUtils.canRead(selection) === false) { return false; } - return nf.CanvasUtils.isRemoteProcessGroup(selection); + return canvasUtils.isRemoteProcessGroup(selection); }; /** * Determines if the components in the specified selection support starting transmission. - * + * * @param {selection} selection */ var canStartTransmission = function (selection) { - if (nf.CanvasUtils.canModify(selection) === false) { + if (canvasUtils.canModify(selection) === false) { return false; } - - return nf.CanvasUtils.canAllStartTransmitting(selection); + + return canvasUtils.canAllStartTransmitting(selection); }; /** * Determines if the components in the specified selection support stopping transmission. - * + * * @param {selection} selection */ var canStopTransmission = function (selection) { - if (nf.CanvasUtils.canModify(selection) === false) { + if (canvasUtils.canModify(selection) === false) { return false; } - - return nf.CanvasUtils.canAllStopTransmitting(selection); + + return canvasUtils.canAllStopTransmitting(selection); }; - + /** * Only DFMs can empty a queue. - * + * * @param {selection} selection */ var canEmptyQueue = function (selection) { @@ -332,31 +362,31 @@ nf.ContextMenu = (function () { var canListQueue = function (selection) { return isConnection(selection); }; - + /** * Determines if the components in the specified selection can be moved into a parent group. - * + * * @param {type} selection */ var canMoveToParent = function (selection) { - if (nf.CanvasUtils.canModify(selection) === false) { + if (canvasUtils.canModify(selection) === false) { return false; } // TODO - also check can modify in parent - - return !selection.empty() && nf.CanvasUtils.isDisconnected(selection) && nf.Canvas.getParentGroupId() !== null; + + return !selection.empty() && canvasUtils.getComponentByType('Connection').isDisconnected(selection) && canvasUtils.getParentGroupId() !== null; }; /** * Adds a menu item to the context menu. - * + * * { * click: refresh (function), * text: 'Start' (string), * clazz: 'fa fa-refresh' * } - * + * * @param {jQuery} contextMenu The context menu * @param {object} item The menu item configuration */ @@ -377,10 +407,10 @@ nf.ContextMenu = (function () { // create the img and conditionally add the style var img = $('<div class="context-menu-item-img"></div>').addClass(item['clazz']).appendTo(menuItem); - if (nf.Common.isDefinedAndNotNull(item['imgStyle'])) { + if (common.isDefinedAndNotNull(item['imgStyle'])) { img.addClass(item['imgStyle']); } - + $('<div class="context-menu-item-text"></div>').text(item['text']).appendTo(menuItem); $('<div class="clear"></div>').appendTo(menuItem); } @@ -388,7 +418,7 @@ nf.ContextMenu = (function () { /** * Positions and shows the context menu. - * + * * @param {jQuery} contextMenu The context menu * @param {object} options The context menu configuration */ @@ -401,17 +431,17 @@ nf.ContextMenu = (function () { /** * Executes the specified action with the optional selection. - * + * * @param {string} action * @param {selection} selection * @param {mouse event} evt */ var executeAction = function (action, selection, evt) { // execute the action - nf.Actions[action](selection, evt); + nfActions[action](selection, evt); // close the context menu - nf.ContextMenu.hide(); + nfContextMenu.hide(); }; // defines the available actions and the conditions which they apply @@ -425,7 +455,7 @@ nf.ContextMenu = (function () { {condition: isStoppable, menuItem: {clazz: 'fa fa-stop', text: 'Stop', action: 'stop'}}, {condition: isRemoteProcessGroup, menuItem: {clazz: 'fa fa-cloud', text: 'Remote ports', action: 'remotePorts'}}, {condition: canStartTransmission, menuItem: {clazz: 'fa fa-bullseye', text: 'Enable transmission', action: 'enableTransmission'}}, - {condition: canStopTransmission, menuItem: {clazz: 'icon icon-transmit-false', text: 'Disable transmission', action: 'disableTransmission'}}, + {condition: canStopTransmission, menuItem: { clazz: 'icon icon-transmit-false', text: 'Disable transmission', action: 'disableTransmission'}}, {condition: supportsStats, menuItem: {clazz: 'fa fa-area-chart', text: 'Status History', action: 'showStats'}}, {condition: canAccessProvenance, menuItem: {clazz: 'icon icon-provenance', imgStyle: 'context-menu-provenance', text: 'Data provenance', action: 'openProvenance'}}, {condition: isStatefulProcessor, menuItem: {clazz: 'fa fa-tasks', text: 'View state', action: 'viewState'}}, @@ -446,20 +476,28 @@ nf.ContextMenu = (function () { {condition: canEmptyQueue, menuItem: {clazz: 'fa fa-minus-circle', text: 'Empty queue', action: 'emptyQueue'}}, {condition: isDeletable, menuItem: {clazz: 'fa fa-trash', text: 'Delete', action: 'delete'}}, {condition: canAlign, menuItem: {clazz: 'fa fa-align-center', text: 'Align vertical', action: 'alignVertical'}}, - {condition: canAlign, menuItem: {clazz: 'fa fa-align-center fa-rotate-90', text: 'Align horizontal', action: 'alignHorizontal'}} + {condition: canAlign, menuItem: { clazz: 'fa fa-align-center fa-rotate-90', text: 'Align horizontal', action: 'alignHorizontal'}} ]; - return { - init: function () { - $('#context-menu').on('contextmenu', function(evt) { + var nfContextMenu = { + + /** + * Initialize the context menu. + * + * @param actions The reference to the actions controller. + */ + init: function (actions) { + nfActions = actions; + + $('#context-menu').on('contextmenu', function (evt) { // stop propagation and prevent default evt.preventDefault(); evt.stopPropagation(); }); }, - + /** - * Shows the context menu. + * Shows the context menu. */ show: function () { var contextMenu = $('#context-menu').empty(); @@ -468,17 +506,17 @@ nf.ContextMenu = (function () { var breadCrumb = $('#breadcrumbs').get(0); // get the current selection - var selection = nf.CanvasUtils.getSelection(); + var selection = canvasUtils.getSelection(); // consider each component action for the current selection $.each(actions, function (_, action) { // determine if this action is application for this selection - if (action.condition(selection)) { + if (action.condition(selection, canvasUtils.getComponentByType('Connection'))) { var menuItem = action.menuItem; addMenuItem(contextMenu, { clazz: menuItem.clazz, - imgStyle: menuItem.imgStyle, + imgStyle: menuItem.imgStyle, text: menuItem.text, click: function (evt) { executeAction(menuItem.action, selection, evt); @@ -505,25 +543,25 @@ nf.ContextMenu = (function () { }); // inform Angular app incase we've click on the canvas - nf.ng.Bridge.digest(); + angularBridge.digest(); }, - + /** * Hides the context menu. */ hide: function () { $('#context-menu').hide(); }, - + /** * Activates the context menu for the components in the specified selection. - * + * * @param {selection} components The components to enable the context menu for */ activate: function (components) { components.on('contextmenu.selection', function () { // get the clicked component to update selection - nf.ContextMenu.show(); + nfContextMenu.show(); // stop propagation and prevent default d3.event.preventDefault(); @@ -531,4 +569,6 @@ nf.ContextMenu = (function () { }); } }; -}()); \ No newline at end of file + + return nfContextMenu; +})); \ No newline at end of file
