NIFI-730:

- Adding progress bar for showing current status of drop request.
- Allowing the user to cancel the current drop request.
This commit is contained in:
Matt Gilman 2015-10-14 12:39:19 -04:00
parent a2ae99f899
commit cad0e7cf0f
14 changed files with 409 additions and 208 deletions

View File

@ -38,11 +38,14 @@ public class DropRequestDTO {
private Boolean finished;
private Integer currentCount;
private String currentSize;
private Long currentSize;
private String current;
private Integer originalCount;
private String originalSize;
private Long originalSize;
private String original;
private Integer droppedCount;
private String droppedSize;
private Long droppedSize;
private String dropped;
private String state;
@ -151,19 +154,33 @@ public class DropRequestDTO {
}
/**
* @return the siez of the flow files currently queued.
* @return the size of the flow files currently queued in bytes.
*/
@ApiModelProperty(
value = "The size of flow files currently queued."
value = "The size of flow files currently queued in bytes."
)
public String getCurrentSize() {
public Long getCurrentSize() {
return currentSize;
}
public void setCurrentSize(String currentSize) {
public void setCurrentSize(Long currentSize) {
this.currentSize = currentSize;
}
/**
* @return the count and size of the currently queued flow files.
*/
@ApiModelProperty(
value = "The count and size of flow files currently queued."
)
public String getCurrent() {
return current;
}
public void setCurrent(String current) {
this.current = current;
}
/**
* @return the number of flow files to be dropped as a result of this request.
*/
@ -179,19 +196,33 @@ public class DropRequestDTO {
}
/**
* @return the size of the flow files to be dropped as a result of this request.
* @return the size of the flow files to be dropped as a result of this request in bytes.
*/
@ApiModelProperty(
value = "The size of flow files to be dropped as a result of this request."
value = "The size of flow files to be dropped as a result of this request in bytes."
)
public String getOriginalSize() {
public Long getOriginalSize() {
return originalSize;
}
public void setOriginalSize(String originalSize) {
public void setOriginalSize(Long originalSize) {
this.originalSize = originalSize;
}
/**
* @return the count and size of flow files to be dropped as a result of this request.
*/
@ApiModelProperty(
value = "The count and size of flow files to be dropped as a result of this request."
)
public String getOriginal() {
return original;
}
public void setOriginal(String original) {
this.original = original;
}
/**
* @return the number of flow files that have been dropped thus far.
*/
@ -207,19 +238,33 @@ public class DropRequestDTO {
}
/**
* @return the size of the flow files that have been dropped thus far.
* @return the size of the flow files that have been dropped thus far in bytes.
*/
@ApiModelProperty(
value = "The size of flow files that have been dropped thus far."
value = "The size of flow files that have been dropped thus far in bytes."
)
public String getDroppedSize() {
public Long getDroppedSize() {
return droppedSize;
}
public void setDroppedSize(String droppedSize) {
public void setDroppedSize(Long droppedSize) {
this.droppedSize = droppedSize;
}
/**
* @return the count and size of the flow files that have been dropped thus far.
*/
@ApiModelProperty(
value = "The count and size of flow files that have been dropped thus far."
)
public String getDropped() {
return dropped;
}
public void setDropped(String dropped) {
this.dropped = dropped;
}
/**
* @return the current state of the drop request.
*/

View File

@ -552,8 +552,9 @@ public interface NiFiServiceFacade {
* @param groupId group
* @param connectionId The ID of the connection
* @param dropRequestId The flow file drop request
* @return The DropRequest
*/
void deleteFlowFileDropRequest(String groupId, String connectionId, String dropRequestId);
DropRequestDTO deleteFlowFileDropRequest(String groupId, String connectionId, String dropRequestId);
// ----------------------------------------
// InputPort methods

View File

@ -810,8 +810,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public void deleteFlowFileDropRequest(String groupId, String connectionId, String dropRequestId) {
connectionDAO.deleteFlowFileDropRequest(groupId, connectionId, dropRequestId);
public DropRequestDTO deleteFlowFileDropRequest(String groupId, String connectionId, String dropRequestId) {
return dtoFactory.createDropRequestDTO(connectionDAO.deleteFlowFileDropRequest(groupId, connectionId, dropRequestId));
}
@Override

View File

@ -1086,7 +1086,8 @@ public class ConnectionResource extends ApplicationResource {
}
// delete the drop request
serviceFacade.deleteFlowFileDropRequest(groupId, connectionId, dropRequestId);
final DropRequestDTO dropRequest = serviceFacade.deleteFlowFileDropRequest(groupId, connectionId, dropRequestId);
dropRequest.setUri(generateResourceUri("controller", "process-groups", groupId, "connections", connectionId, "contents", "drop-requests", dropRequestId));
// create the revision
final RevisionDTO revision = new RevisionDTO();
@ -1095,6 +1096,7 @@ public class ConnectionResource extends ApplicationResource {
// create the response entity
final DropRequestEntity entity = new DropRequestEntity();
entity.setRevision(revision);
entity.setDropRequest(dropRequest);
return generateOkResponse(entity).build();
}

View File

@ -312,13 +312,16 @@ public final class DtoFactory {
final QueueSize dropped = dropRequest.getDroppedSize();
dto.setDroppedCount(dropped.getObjectCount());
dto.setDroppedSize(FormatUtils.formatDataSize(dropped.getByteCount()));
dto.setDroppedSize(dropped.getByteCount());
dto.setDropped(FormatUtils.formatCount(dropped.getObjectCount()) + " / " + FormatUtils.formatDataSize(dropped.getByteCount()));
if (dropRequest.getOriginalSize() != null) {
final QueueSize original = dropRequest.getOriginalSize();
dto.setOriginalCount(original.getObjectCount());
dto.setOriginalSize(FormatUtils.formatDataSize(original.getByteCount()));
dto.setPercentCompleted((dropped.getObjectCount() * 100 ) / original.getObjectCount());
dto.setOriginalSize(original.getByteCount());
dto.setOriginal(FormatUtils.formatCount(original.getObjectCount()) + " / " + FormatUtils.formatDataSize(original.getByteCount()));
dto.setPercentCompleted((dropped.getObjectCount() * 100) / original.getObjectCount());
} else {
dto.setPercentCompleted(0);
}
@ -326,7 +329,8 @@ public final class DtoFactory {
if (dropRequest.getCurrentSize() != null) {
final QueueSize current = dropRequest.getCurrentSize();
dto.setCurrentCount(current.getObjectCount());
dto.setCurrentSize(FormatUtils.formatDataSize(current.getByteCount()));
dto.setCurrentSize(current.getByteCount());
dto.setCurrent(FormatUtils.formatCount(current.getObjectCount()) + " / " + FormatUtils.formatDataSize(current.getByteCount()));
}
return dto;

View File

@ -134,6 +134,7 @@ public interface ConnectionDAO {
* @param groupId group id
* @param id The id of the connection
* @param dropRequestId The drop request id
* @return The drop request
*/
void deleteFlowFileDropRequest(String groupId, String id, String dropRequestId);
DropFlowFileStatus deleteFlowFileDropRequest(String groupId, String id, String dropRequestId);
}

View File

@ -496,10 +496,10 @@ public class StandardConnectionDAO extends ComponentDAO implements ConnectionDAO
}
@Override
public void deleteFlowFileDropRequest(String groupId, String connectionId, String dropRequestId) {
public DropFlowFileStatus deleteFlowFileDropRequest(String groupId, String connectionId, String dropRequestId) {
final Connection connection = locateConnection(groupId, connectionId);
final FlowFileQueue queue = connection.getFlowFileQueue();
queue.cancelDropFlowFileRequest(dropRequestId);
return queue.cancelDropFlowFileRequest(dropRequestId);
}
/* setters */

View File

@ -119,6 +119,7 @@
<jsp:include page="/WEB-INF/partials/canvas/secure-port-details.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/label-configuration.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/connection-configuration.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/drop-request-status-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/connection-details.jsp"/>
<div id="faded-background"></div>
<div id="glass-pane"></div>

View File

@ -0,0 +1,29 @@
<%--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--%>
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<div id="drop-request-status-dialog">
<div class="dialog-content">
<div class="setting">
<div class="setting-field">
<div id="drop-request-status-message"></div>
</div>
<div class="setting-field">
<div id="drop-request-percent-complete"></div>
</div>
</div>
</div>
</div>

View File

@ -269,6 +269,31 @@ div.go-to-link {
height: 195px;
}
#drop-request-status-dialog {
display: none;
width: 400px;
height: 135px;
z-index: 1301;
}
#drop-request-percent-complete {
width: 378px;
border-radius: 0;
}
#drop-request-percent-complete .ui-progressbar-value {
border-radius: 0;
}
div.progress-label {
color: #000000;
display: block;
font-weight: bold;
text-align: center;
width: 378px;
margin-top: 4px;
}
#nf-ok-dialog {
z-index: 1302;
display: none;

View File

@ -24,6 +24,31 @@ nf.Actions = (function () {
controller: '../nifi-api/controller'
}
};
/**
* Initializes the drop request status dialog.
*/
var initializeDropRequestStatusDialog = function () {
// initialize the drop requst progress bar
var dropRequestProgressBar = $('#drop-request-percent-complete').progressbar();
// configure the drop request status dialog
$('#drop-request-status-dialog').modal({
headerText: 'Emptying queue',
overlayBackground: false,
handler: {
close: function () {
// reset the progress bar
dropRequestProgressBar.find('div.progress-label').remove();
// update the progress bar
var label = $('<div class="progress-label"></div>').text('0%');
dropRequestProgressBar.progressbar('value', 0).append(label);
}
}
});
};
/**
* Updates the resource with the specified data.
@ -78,6 +103,13 @@ nf.Actions = (function () {
};
return {
/**
* Initializes the actions.
*/
init: function () {
initializeDropRequestStatusDialog();
},
/**
* Enters the specified process group.
*
@ -855,56 +887,144 @@ nf.Actions = (function () {
return;
}
var MAX_DELAY = 4;
// prompt the user before emptying the queue
nf.Dialog.showYesNoDialog({
dialogContent: 'Are you sure you want to empty the queue? All data enqueued at the time of the request will be removed from the dataflow.',
overlayBackground: false,
yesHandler: function () {
// get the connection data
var connection = selection.datum();
var MAX_DELAY = 4;
var cancelled = false;
var dropRequest = null;
var dropRequestTimer = null;
// process the drop request
var processDropRequest = function (dropRequest, nextDelay) {
// see if the drop request has completed
if (dropRequest.finished === true) {
// request is finished so it can be removed
deleteDropRequest(dropRequest);
} else {
// update the UI with the current status of the drop request
schedule(dropRequest, nextDelay);
}
};
// updates the progress bar
var updateProgress = function (percentComplete) {
// remove existing labels
var progressBar = $('#drop-request-percent-complete');
progressBar.find('div.progress-label').remove();
// schedule for the next poll iteration
var schedule = function (dropRequest, delay) {
setTimeout(function () {
// update the progress bar
var label = $('<div class="progress-label"></div>').text(percentComplete + '%');
if (percentComplete > 0) {
label.css('margin-top', '-19px');
}
progressBar.progressbar('value', percentComplete).append(label);
};
// update the button model of the drop request status dialog
$('#drop-request-status-dialog').modal('setButtonModel', [{
buttonText: 'Cancel',
handler: {
click: function () {
cancelled = true;
// we are waiting for the next poll attempt
if (dropRequestTimer !== null) {
// cancel it
clearTimeout(dropRequestTimer);
// cancel the provenance
completeDropRequest();
}
}
}
}]);
// completes the drop request by removing it and showing how many flowfiles were deleted
var completeDropRequest = function () {
if (nf.Common.isDefinedAndNotNull(dropRequest)) {
$.ajax({
type: 'DELETE',
url: dropRequest.uri,
dataType: 'json'
}).done(function(response) {
// report the results of this drop request
dropRequest = response.dropRequest;
// parse the dropped stats to render results
var tokens = dropRequest.dropped.split(/ \/ /);
var results = $('<div></div>').text('Successfully removed ' + tokens[0] + ' (' + tokens[1] + ') FlowFiles');
nf.Dialog.showOkDialog({
dialogContent: results,
overlayBackground: false
});
}).always(function() {
$('#drop-request-status-dialog').modal('hide');
});
} else {
// nothing was removed
nf.Dialog.showYesNoDialog({
dialogContent: 'No FlowFiles were removed.',
overlayBackground: false
});
// close the dialog
$('#drop-request-status-dialog').modal('hide');
}
};
// process the drop request
var processDropRequest = function (delay) {
// update the percent complete
updateProgress(dropRequest.percentCompleted);
// update the status of the drop request
$('#drop-request-status-message').text(dropRequest.state);
// update the current number of enqueued flowfiles
if (nf.Common.isDefinedAndNotNull(dropRequest.currentCount)) {
connection.status.queued = dropRequest.current;
nf.Connection.refresh(connection.id);
}
// close the dialog if the
if (dropRequest.finished === true || cancelled === true) {
completeDropRequest();
} else {
// wait delay to poll again
dropRequestTimer = setTimeout(function () {
// clear the drop request timer
dropRequestTimer = null;
// schedule to poll the status again in nextDelay
pollDropRequest(Math.min(MAX_DELAY, delay * 2));
}, delay * 1000);
}
};
// schedule for the next poll iteration
var pollDropRequest = function (nextDelay) {
$.ajax({
type: 'GET',
url: dropRequest.uri,
dataType: 'json'
}).done(function(response) {
dropRequest = response.dropRequest;
processDropRequest(nextDelay);
}).fail(completeDropRequest);
};
// issue the request to delete the flow files
$.ajax({
type: 'GET',
url: dropRequest.uri,
type: 'DELETE',
url: connection.component.uri + '/contents',
dataType: 'json'
}).done(function(response) {
var dropRequest = response.dropRequest;
processDropRequest(dropRequest, Math.min(MAX_DELAY, delay * 2));
}).fail(nf.Common.handleAjaxError);
}, delay * 1000);
};
// delete the drop request
var deleteDropRequest = function (dropRequest) {
$.ajax({
type: 'DELETE',
url: dropRequest.uri,
dataType: 'json'
}).done(function() {
// drop request has been deleted
}).fail(nf.Common.handleAjaxError);
};
// get the connection data
var connection = selection.datum();
// issue the request to delete the flow files
$.ajax({
type: 'DELETE',
url: connection.component.uri + '/contents',
dataType: 'json'
}).done(function(response) {
processDropRequest(response.dropRequest, 1);
}).fail(nf.Common.handleAjaxError);
// initialize the progress bar value
updateProgress(0);
// show the progress dialog
$('#drop-request-status-dialog').modal('show');
// process the drop request
dropRequest = response.dropRequest;
processDropRequest(1);
}).fail(completeDropRequest);
}
});
},
/**

View File

@ -188,7 +188,7 @@ nf.Canvas = (function () {
if (!refreshContainer.is(':visible')) {
$('#stats-last-refreshed').addClass('alert');
var refreshMessage = "This flow has been modified by '" + revision.lastModifier + "'. Please refresh.";
// update the tooltip
var refreshRequiredIcon = $('#refresh-required-icon');
if (refreshRequiredIcon.data('qtip')) {
@ -198,10 +198,10 @@ nf.Canvas = (function () {
content: refreshMessage
}, nf.CanvasUtils.config.systemTooltipConfig));
}
refreshContainer.show();
}
// insert the refresh needed text in the settings - if necessary
if (!settingsRefreshIcon.is(':visible')) {
$('#settings-last-refreshed').addClass('alert');
@ -333,7 +333,7 @@ nf.Canvas = (function () {
'offset': '100%',
'stop-color': '#ffffff'
});
// define the gradient for the expiration icon
var expirationBackground = defs.append('linearGradient')
.attr({
@ -343,7 +343,7 @@ nf.Canvas = (function () {
'x2': '0%',
'y2': '100%'
});
expirationBackground.append('stop')
.attr({
'offset': '0%',
@ -397,106 +397,106 @@ nf.Canvas = (function () {
// prevent further propagation (to parents and others handlers
// on the same element to prevent zoom behavior)
d3.event.stopImmediatePropagation();
// prevents the browser from changing to a text selection cursor
d3.event.preventDefault();
}
})
.on('mousemove.selection', function () {
// update selection box if shift is held down
if (d3.event.shiftKey) {
// get the selection box
var selectionBox = d3.select('rect.selection');
if (!selectionBox.empty()) {
// get the original position
var originalPosition = selectionBox.datum();
var position = d3.mouse(canvas.node());
var d = {};
if (originalPosition[0] < position[0]) {
d.x = originalPosition[0];
d.width = position[0] - originalPosition[0];
} else {
d.x = position[0];
d.width = originalPosition[0] - position[0];
.on('mousemove.selection', function () {
// update selection box if shift is held down
if (d3.event.shiftKey) {
// get the selection box
var selectionBox = d3.select('rect.selection');
if (!selectionBox.empty()) {
// get the original position
var originalPosition = selectionBox.datum();
var position = d3.mouse(canvas.node());
var d = {};
if (originalPosition[0] < position[0]) {
d.x = originalPosition[0];
d.width = position[0] - originalPosition[0];
} else {
d.x = position[0];
d.width = originalPosition[0] - position[0];
}
if (originalPosition[1] < position[1]) {
d.y = originalPosition[1];
d.height = position[1] - originalPosition[1];
} else {
d.y = position[1];
d.height = originalPosition[1] - position[1];
}
// update the selection box
selectionBox.attr(d);
// prevent further propagation (to parents)
d3.event.stopPropagation();
}
}
})
.on('mouseup.selection', function () {
// ensure this originated from clicking the canvas, not a component.
// when clicking on a component, the event propagation is stopped so
// it never reaches the canvas. we cannot do this however on up events
// since the drag events break down
if (canvasClicked === false) {
return;
}
if (originalPosition[1] < position[1]) {
d.y = originalPosition[1];
d.height = position[1] - originalPosition[1];
} else {
d.y = position[1];
d.height = originalPosition[1] - position[1];
// reset the canvas click flag
canvasClicked = false;
// get the selection box
var selectionBox = d3.select('rect.selection');
if (!selectionBox.empty()) {
var selectionBoundingBox = {
x: parseInt(selectionBox.attr('x'), 10),
y: parseInt(selectionBox.attr('y'), 10),
width: parseInt(selectionBox.attr('width'), 10),
height: parseInt(selectionBox.attr('height'), 10)
};
// see if a component should be selected or not
d3.selectAll('g.component').classed('selected', function (d) {
// consider it selected if its already selected or enclosed in the bounding box
return d3.select(this).classed('selected') ||
d.component.position.x >= selectionBoundingBox.x && (d.component.position.x + d.dimensions.width) <= (selectionBoundingBox.x + selectionBoundingBox.width) &&
d.component.position.y >= selectionBoundingBox.y && (d.component.position.y + d.dimensions.height) <= (selectionBoundingBox.y + selectionBoundingBox.height);
});
// see if a connection should be selected or not
d3.selectAll('g.connection').classed('selected', function (d) {
// consider all points
var points = [d.start].concat(d.bends, [d.end]);
// determine the bounding box
var x = d3.extent(points, function (pt) {
return pt.x;
});
var y = d3.extent(points, function (pt) {
return pt.y;
});
// consider it selected if its already selected or enclosed in the bounding box
return d3.select(this).classed('selected') ||
x[0] >= selectionBoundingBox.x && x[1] <= (selectionBoundingBox.x + selectionBoundingBox.width) &&
y[0] >= selectionBoundingBox.y && y[1] <= (selectionBoundingBox.y + selectionBoundingBox.height);
});
// remove the selection box
selectionBox.remove();
} else if (panning === false) {
// deselect as necessary if we are not panning
nf.CanvasUtils.getSelection().classed('selected', false);
}
// update the selection box
selectionBox.attr(d);
// prevent further propagation (to parents)
d3.event.stopPropagation();
}
}
})
.on('mouseup.selection', function () {
// ensure this originated from clicking the canvas, not a component.
// when clicking on a component, the event propagation is stopped so
// it never reaches the canvas. we cannot do this however on up events
// since the drag events break down
if (canvasClicked === false) {
return;
}
// reset the canvas click flag
canvasClicked = false;
// get the selection box
var selectionBox = d3.select('rect.selection');
if (!selectionBox.empty()) {
var selectionBoundingBox = {
x: parseInt(selectionBox.attr('x'), 10),
y: parseInt(selectionBox.attr('y'), 10),
width: parseInt(selectionBox.attr('width'), 10),
height: parseInt(selectionBox.attr('height'), 10)
};
// see if a component should be selected or not
d3.selectAll('g.component').classed('selected', function (d) {
// consider it selected if its already selected or enclosed in the bounding box
return d3.select(this).classed('selected') ||
d.component.position.x >= selectionBoundingBox.x && (d.component.position.x + d.dimensions.width) <= (selectionBoundingBox.x + selectionBoundingBox.width) &&
d.component.position.y >= selectionBoundingBox.y && (d.component.position.y + d.dimensions.height) <= (selectionBoundingBox.y + selectionBoundingBox.height);
// update the toolbar
nf.CanvasToolbar.refresh();
});
// see if a connection should be selected or not
d3.selectAll('g.connection').classed('selected', function (d) {
// consider all points
var points = [d.start].concat(d.bends, [d.end]);
// determine the bounding box
var x = d3.extent(points, function (pt) {
return pt.x;
});
var y = d3.extent(points, function (pt) {
return pt.y;
});
// consider it selected if its already selected or enclosed in the bounding box
return d3.select(this).classed('selected') ||
x[0] >= selectionBoundingBox.x && x[1] <= (selectionBoundingBox.x + selectionBoundingBox.width) &&
y[0] >= selectionBoundingBox.y && y[1] <= (selectionBoundingBox.y + selectionBoundingBox.height);
});
// remove the selection box
selectionBox.remove();
} else if (panning === false) {
// deselect as necessary if we are not panning
nf.CanvasUtils.getSelection().classed('selected', false);
}
// update the toolbar
nf.CanvasToolbar.refresh();
});
// define a function for update the graph dimensions
var updateGraphSize = function () {
// get the location of the bottom of the graph
@ -510,7 +510,7 @@ nf.Canvas = (function () {
var top = parseInt(canvasContainer.css('top'), 10);
var windowHeight = $(window).height();
var canvasHeight = (windowHeight - (bottom + top));
// canvas/svg
canvasContainer.css({
'height': canvasHeight + 'px',
@ -536,7 +536,7 @@ nf.Canvas = (function () {
}
}).on('keydown', function (evt) {
var isCtrl = evt.ctrlKey || evt.metaKey;
// consider escape, before checking dialogs
if (!isCtrl && evt.keyCode === 27) {
// esc
@ -552,7 +552,7 @@ nf.Canvas = (function () {
// first consider read only property detail dialog
if ($('div.property-detail').is(':visible')) {
nf.Common.removeAllPropertyDetailDialogs();
// prevent further bubbling as we're already handled it
evt.stopPropagation();
evt.preventDefault();
@ -570,7 +570,7 @@ nf.Canvas = (function () {
var dialogMax = null;
// identify the top most cancellable
$.each(cancellables, function(_, cancellable) {
$.each(cancellables, function (_, cancellable) {
var dialog = $(cancellable);
var zIndex = dialog.css('zIndex');
@ -615,10 +615,10 @@ nf.Canvas = (function () {
}
}
}
return;
}
// if a dialog is open, disable canvas shortcuts
if ($('.dialog').is(':visible')) {
return;
@ -833,7 +833,7 @@ nf.Canvas = (function () {
bulletinIcon.show();
}
}
// update controller service and reporting task bulletins
nf.Settings.setBulletins(controllerStatus.controllerServiceBulletins, controllerStatus.reportingTaskBulletins);
@ -934,21 +934,17 @@ nf.Canvas = (function () {
};
return {
CANVAS_OFFSET: 0,
/**
* Determines if the current broswer supports SVG.
*/
SUPPORTS_SVG: !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect,
/**
* Hides the splash that is displayed while the application is loading.
*/
hideSplash: function () {
$('#splash').fadeOut();
},
/**
* Stop polling for revision.
*/
@ -956,7 +952,6 @@ nf.Canvas = (function () {
// set polling flag
revisionPolling = false;
},
/**
* Remove the status poller.
*/
@ -964,7 +959,6 @@ nf.Canvas = (function () {
// set polling flag
statusPolling = false;
},
/**
* Reloads the flow from the server based on the currently specified group id.
* To load another group, update nf.Canvas.setGroupId and call nf.Canvas.reload.
@ -973,7 +967,7 @@ nf.Canvas = (function () {
return $.Deferred(function (deferred) {
// hide the context menu
nf.ContextMenu.hide();
// get the process group to refresh everything
var processGroupXhr = reloadProcessGroup(nf.Canvas.getGroupId());
var statusXhr = reloadFlowStatus();
@ -1007,7 +1001,6 @@ nf.Canvas = (function () {
});
}).promise();
},
/**
* Reloads the status.
*/
@ -1021,7 +1014,6 @@ nf.Canvas = (function () {
});
}).promise();
},
/**
* Initialize NiFi.
*/
@ -1099,6 +1091,7 @@ nf.Canvas = (function () {
nf.GraphControl.init();
nf.Search.init();
nf.Settings.init();
nf.Actions.init();
// initialize the component behaviors
nf.Draggable.init();
@ -1146,7 +1139,6 @@ nf.Canvas = (function () {
}).fail(nf.Common.handleAjaxError);
}).fail(nf.Common.handleAjaxError);
},
/**
* Defines the gradient colors used to render processors.
*
@ -1155,7 +1147,6 @@ nf.Canvas = (function () {
defineProcessorColors: function (colors) {
setColors(colors, 'processor');
},
/**
* Defines the gradient colors used to render label.
*
@ -1164,7 +1155,6 @@ nf.Canvas = (function () {
defineLabelColors: function (colors) {
setColors(colors, 'label');
},
/**
* Return whether this instance of NiFi is clustered.
*
@ -1173,14 +1163,12 @@ nf.Canvas = (function () {
isClustered: function () {
return clustered === true;
},
/**
* Returns whether site to site communications is secure.
*/
isSecureSiteToSite: function () {
return secureSiteToSite;
},
/**
* Set the group id.
*
@ -1189,14 +1177,12 @@ nf.Canvas = (function () {
setGroupId: function (gi) {
groupId = gi;
},
/**
* Get the group id.
*/
getGroupId: function () {
return groupId;
},
/**
* Set the group name.
*
@ -1205,14 +1191,12 @@ nf.Canvas = (function () {
setGroupName: function (gn) {
groupName = gn;
},
/**
* Get the group name.
*/
getGroupName: function () {
return groupName;
},
/**
* Set the parent group id.
*
@ -1221,16 +1205,14 @@ nf.Canvas = (function () {
setParentGroupId: function (pgi) {
parentGroupId = pgi;
},
/**
* Get the parent group id.
*/
getParentGroupId: function () {
return parentGroupId;
},
View: (function () {
/**
* Updates component visibility based on their proximity to the screen's viewport.
*/
@ -1297,8 +1279,8 @@ nf.Canvas = (function () {
.classed('entering', function () {
return visible && !wasVisible;
}).classed('leaving', function () {
return !visible && wasVisible;
});
return !visible && wasVisible;
});
};
// get the all components
@ -1385,7 +1367,6 @@ nf.Canvas = (function () {
// add the behavior to the canvas and disable dbl click zoom
svg.call(behavior).on('dblclick.zoom', null);
},
/**
* Whether or not a component should be rendered based solely on the current scale.
*
@ -1394,7 +1375,6 @@ nf.Canvas = (function () {
shouldRenderPerScale: function () {
return nf.Canvas.View.scale() >= MIN_SCALE_TO_RENDER;
},
/**
* Updates component visibility based on the current translation/scale.
*/
@ -1402,7 +1382,6 @@ nf.Canvas = (function () {
updateComponentVisibility();
nf.Graph.pan();
},
/**
* Sets/gets the current translation.
*
@ -1415,7 +1394,6 @@ nf.Canvas = (function () {
behavior.translate(translate);
}
},
/**
* Sets/gets the current scale.
*
@ -1428,7 +1406,6 @@ nf.Canvas = (function () {
behavior.scale(scale);
}
},
/**
* Zooms in a single zoom increment.
*/
@ -1453,7 +1430,6 @@ nf.Canvas = (function () {
height: 1
});
},
/**
* Zooms out a single zoom increment.
*/
@ -1478,7 +1454,6 @@ nf.Canvas = (function () {
height: 1
});
},
/**
* Zooms to fit the entire graph on the canvas.
*/
@ -1525,7 +1500,6 @@ nf.Canvas = (function () {
height: canvasHeight / newScale
});
},
/**
* Zooms to the actual size (1 to 1).
*/
@ -1574,7 +1548,6 @@ nf.Canvas = (function () {
// center as appropriate
nf.CanvasUtils.centerBoundingBox(box);
},
/**
* Refreshes the view based on the configured translation and scale.
*

View File

@ -278,11 +278,11 @@ nf.ContextMenu = (function () {
};
/**
* Only DFMs can delete flow files from a connection.
* Only DFMs can empty a queue.
*
* @param {selection} selection
*/
var canDeleteFlowFiles = function (selection) {
var canEmptyQueue = function (selection) {
return nf.Common.isDFM() && isConnection(selection);
};
@ -382,7 +382,7 @@ nf.ContextMenu = (function () {
{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: canDeleteFlowFiles, menuItem: {img: 'images/iconDelete.png', text: 'Empty queue', action: 'emptyQueue'}},
{condition: canEmptyQueue, menuItem: {img: 'images/iconEmptyQueue.png', text: 'Empty queue', action: 'emptyQueue'}},
{condition: isDeletable, menuItem: {img: 'images/iconDelete.png', text: 'Delete', action: 'delete'}}
];