Repository: nifi
Updated Branches:
  refs/heads/master de2dd93f2 -> b330fd160


http://git-wip-us.apache.org/repos/asf/nifi/blob/b330fd16/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 a07627c..55df1e9 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
@@ -300,6 +300,15 @@ nf.ContextMenu = (function () {
     var canEmptyQueue = function (selection) {
         return nf.Common.isDFM() && isConnection(selection);
     };
+
+    /**
+     * Only DFMs can list a queue.
+     *
+     * @param {selection} selection
+     */
+    var canListQueue = function (selection) {
+        return nf.Common.isDFM() && isConnection(selection) && 
nf.CanvasUtils.supportsModification(selection);
+    };
     
     /**
      * Determines if the components in the specified selection can be moved 
into a parent group.
@@ -403,6 +412,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: canListQueue, menuItem: {img: 'images/iconListQueue.png', 
text: 'List queue', action: 'listQueue'}},
         {condition: canEmptyQueue, menuItem: {img: 
'images/iconEmptyQueue.png', text: 'Empty queue', action: 'emptyQueue'}},
         {condition: isDeletable, menuItem: {img: 'images/iconDelete.png', 
text: 'Delete', action: 'delete'}}
     ];

http://git-wip-us.apache.org/repos/asf/nifi/blob/b330fd16/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-queue-listing.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-queue-listing.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-queue-listing.js
new file mode 100644
index 0000000..3c33f3a
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-queue-listing.js
@@ -0,0 +1,570 @@
+/*
+ * 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.
+ */
+
+/* global nf */
+
+/**
+ * Lists FlowFiles from a given connection.
+ */
+nf.QueueListing = (function () {
+
+    var DEFAULT_SORT_COL = 'QUEUE_POSITION';
+    var DEFAULT_SORT_ASC = true;
+
+    /**
+     * Initializes the listing request status dialog.
+     */
+    var initializeListingRequestStatusDialog = function () {
+        // initialize the listing request progress bar
+        var listingRequestProgressBar = 
$('#listing-request-percent-complete').progressbar();
+
+        // configure the drop request status dialog
+        $('#listing-request-status-dialog').modal({
+            overlayBackground: false,
+            handler: {
+                close: function () {
+                    // reset the progress bar
+                    
listingRequestProgressBar.find('div.progress-label').remove();
+
+                    // update the progress bar
+                    var label = $('<div 
class="progress-label"></div>').text('0%');
+                    listingRequestProgressBar.progressbar('value', 
0).append(label);
+
+                    // clear the current button model
+                    
$('#listing-request-status-dialog').modal('setButtonModel', []);
+                }
+            }
+        }).draggable({
+            containment: 'parent',
+            handle: '.dialog-header'
+        });
+    };
+
+    /**
+     * Downloads the content for the flowfile currently being viewed.
+     */
+    var downloadContent = function () {
+        var dataUri = $('#flowfile-uri').text() + '/content';
+
+        // conditionally include the cluster node id
+        var clusterNodeId = $('#flowfile-cluster-node-id').text();
+        if (!nf.Common.isBlank(clusterNodeId)) {
+            window.open(dataUri + '?' + $.param({
+                    'clusterNodeId': clusterNodeId
+                }));
+        } else {
+            window.open(dataUri);
+        }
+    };
+
+    /**
+     * Views the content for the flowfile currently being viewed.
+     */
+    var viewContent = function () {
+        var dataUri = $('#flowfile-uri').text() + '/content';
+
+        // conditionally include the cluster node id
+        var clusterNodeId = $('#flowfile-cluster-node-id').text();;
+        if (!nf.Common.isBlank(clusterNodeId)) {
+            var parameters = {
+                'clusterNodeId': clusterNodeId
+            };
+
+            dataUri = dataUri + '?' + $.param(parameters);
+        }
+
+        // open the content viewer
+        var contentViewerUrl = $('#nifi-content-viewer-url').text();
+
+        // if there's already a query string don't add another ?... this 
assumes valid
+        // input meaning that if the url has already included a ? it also 
contains at
+        // least one query parameter
+        if (contentViewerUrl.indexOf('?') === -1) {
+            contentViewerUrl += '?';
+        } else {
+            contentViewerUrl += '&';
+        }
+
+        // open the content viewer
+        window.open(contentViewerUrl + $.param({
+                'ref': dataUri
+            }));
+    };
+
+    /**
+     * Initializes the flowfile details dialog.
+     */
+    var initFlowFileDetailsDialog = function () {
+        $('#content-download').on('click', downloadContent);
+
+        // only show if content viewer is configured
+        if (nf.Common.isContentViewConfigured()) {
+            $('#content-view').show();
+            $('#content-view').on('click', viewContent);
+        }
+
+        $('#flowfile-details-tabs').tabbs({
+            tabStyle: 'tab',
+            selectedTabStyle: 'selected-tab',
+            tabs: [{
+                name: 'Details',
+                tabContentId: 'flowfile-details-tab-content'
+            }, {
+                name: 'Attributes',
+                tabContentId: 'flowfile-attributes-tab-content'
+            }]
+        });
+
+        $('#flowfile-details-dialog').modal({
+            headerText: 'FlowFile',
+            overlayBackground: false,
+            buttons: [{
+                buttonText: 'Ok',
+                handler: {
+                    click: function () {
+                        $('#flowfile-details-dialog').modal('hide');
+                    }
+                }
+            }],
+            handler: {
+                close: function () {
+                    // clear the details
+                    $('#flowfile-attributes-container').empty();
+                    $('#flowfile-cluster-node-id').text('');
+                    $('#additional-flowfile-details').empty();
+                }
+            }
+        }).draggable({
+            containment: 'parent',
+            handle: '.dialog-header'
+        });
+    };
+
+    /**
+     * Performs a listing on the specified connection.
+     *
+     * @param connection the connection
+     * @param sortCol the sort column
+     * @param sortAsc if sort is asc
+     */
+    var performListing = function (connection, sortCol, sortAsc) {
+        var MAX_DELAY = 4;
+        var cancelled = false;
+        var listingRequest = null;
+        var listingRequestTimer = null;
+
+        return $.Deferred(function (deferred) {
+            // updates the progress bar
+            var updateProgress = function (percentComplete) {
+                // remove existing labels
+                var progressBar = $('#listing-request-percent-complete');
+                progressBar.find('div.progress-label').remove();
+
+                // 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
+            $('#listing-request-status-dialog').modal('setButtonModel', [{
+                buttonText: 'Stop',
+                handler: {
+                    click: function () {
+                        cancelled = true;
+
+                        // we are waiting for the next poll attempt
+                        if (listingRequestTimer !== null) {
+                            // cancel it
+                            clearTimeout(listingRequestTimer);
+
+                            // cancel the listing request
+                            completeListingRequest();
+                        }
+                    }
+                }
+            }]);
+
+            // completes the listing request by removing it
+            var completeListingRequest = function () {
+                $('#listing-request-status-dialog').modal('hide');
+
+                var reject = cancelled;
+
+                // ensure the listing requests are present
+                if (nf.Common.isDefinedAndNotNull(listingRequest)) {
+                    $.ajax({
+                        type: 'DELETE',
+                        url: listingRequest.uri,
+                        dataType: 'json'
+                    });
+
+                    // use the listing request from when the listing completed
+                    if (nf.Common.isEmpty(listingRequest.flowFileSummaries)) {
+                        if (cancelled === false) {
+                            reject = true;
+
+                            // show the dialog
+                            nf.Dialog.showOkDialog({
+                                dialogContent: 'The queue has no FlowFiles.',
+                                overlayBackground: false
+                            });
+                        }
+                    } else {
+                        // update the queue size
+                        
$('#total-flowfiles-count').text(nf.Common.formatInteger(listingRequest.queueSize.objectCount));
+                        
$('#total-flowfiles-size').text(nf.Common.formatDataSize(listingRequest.queueSize.byteCount));
+
+                        // get the grid to load the data
+                        var queueListingGrid = 
$('#queue-listing-table').data('gridInstance');
+                        var queueListingData = queueListingGrid.getData();
+
+                        // load the flowfiles
+                        queueListingData.beginUpdate();
+                        
queueListingData.setItems(listingRequest.flowFileSummaries, 'uuid');
+                        queueListingData.endUpdate();
+                    }
+                } else {
+                    reject = true;
+                }
+
+                if (reject) {
+                    deferred.reject();
+                } else {
+                    deferred.resolve();
+                }
+            };
+
+            // process the listing request
+            var processListingRequest = function (delay) {
+                // update the percent complete
+                updateProgress(listingRequest.percentCompleted);
+
+                // update the status of the listing request
+                
$('#listing-request-status-message').text(listingRequest.state);
+
+                // close the dialog if the
+                if (listingRequest.finished === true || cancelled === true) {
+                    completeListingRequest();
+                } else {
+                    // wait delay to poll again
+                    listingRequestTimer = setTimeout(function () {
+                        // clear the listing request timer
+                        listingRequestTimer = null;
+
+                        // schedule to poll the status again in nextDelay
+                        pollListingRequest(Math.min(MAX_DELAY, delay * 2));
+                    }, delay * 1000);
+                }
+            };
+
+            // schedule for the next poll iteration
+            var pollListingRequest = function (nextDelay) {
+                $.ajax({
+                    type: 'GET',
+                    url: listingRequest.uri,
+                    dataType: 'json'
+                }).done(function(response) {
+                    listingRequest = response.listingRequest;
+                    processListingRequest(nextDelay);
+                
}).fail(completeListingRequest).fail(nf.Common.handleAjaxError);
+            };
+
+            // issue the request to list the flow files
+            $.ajax({
+                type: 'POST',
+                url: connection.component.uri + '/listing-requests',
+                data: {
+                    sortColumn: sortCol,
+                    sortOrder: sortAsc ? 'asc' : 'desc'
+                },
+                dataType: 'json'
+            }).done(function(response) {
+                // initialize the progress bar value
+                updateProgress(0);
+
+                // show the progress dialog
+                $('#listing-request-status-dialog').modal('show');
+
+                // process the drop request
+                listingRequest = response.listingRequest;
+                processListingRequest(1);
+            }).fail(completeListingRequest).fail(nf.Common.handleAjaxError);
+        }).promise();
+    };
+
+    /**
+     * Shows the details for the specified flowfile.
+     *
+     * @param flowFileSummary the flowfile summary
+     */
+    var showFlowFileDetails = function (flowFileSummary) {
+        // formats an flowfile detail
+        var formatFlowFileDetail = function (label, value) {
+            $('<div class="flowfile-detail"></div>').append(
+                $('<div class="detail-name"></div>').text(label)).append(
+                $('<div class="detail-value">' + nf.Common.formatValue(value) 
+ '</div>').ellipsis()).append(
+                $('<div 
class="clear"></div>')).appendTo('#additional-flowfile-details');
+        };
+
+        // formats the content value
+        var formatContentValue = function (element, value) {
+            if (nf.Common.isDefinedAndNotNull(value)) {
+                element.removeClass('unset').text(value);
+            } else {
+                element.addClass('unset').text('No value set');
+            }
+        };
+
+        $.ajax({
+            type: 'GET',
+            url: flowFileSummary.uri,
+            dataType: 'json'
+        }).done(function(response) {
+            var flowFile = response.flowFile;
+
+            // show the URI to this flowfile
+            $('#flowfile-uri').text(flowFile.uri);
+
+            // show the flowfile details dialog
+            $('#flowfile-uuid').html(nf.Common.formatValue(flowFile.uuid));
+            
$('#flowfile-filename').html(nf.Common.formatValue(flowFile.filename));
+            
$('#flowfile-queue-position').html(nf.Common.formatValue(flowFile.position));
+            
$('#flowfile-file-size').html(nf.Common.formatValue(flowFile.contentClaimFileSize));
+            
$('#flowfile-queued-duration').text(nf.Common.formatDuration(flowFile.queuedDuration));
+            
$('#flowfile-lineage-duration').text(nf.Common.formatDuration(flowFile.lineageDuration));
+            $('#flowfile-penalized').text(flowFile.penalized === true ? 'Yes' 
: 'No');
+
+            // conditionally show the cluster node identifier
+            if (nf.Common.isDefinedAndNotNull(flowFile.clusterNodeId)) {
+                // save the cluster node id
+                $('#flowfile-cluster-node-id').text(flowFile.clusterNodeId);
+
+                // render the cluster node address
+                formatFlowFileDetail('Node Address', 
flowFile.clusterNodeAddress);
+            }
+
+            if (nf.Common.isDefinedAndNotNull(flowFile.contentClaimContainer)) 
{
+                // content claim
+                formatContentValue($('#content-container'), 
flowFile.contentClaimContainer);
+                formatContentValue($('#content-section'), 
flowFile.contentClaimSection);
+                formatContentValue($('#content-identifier'), 
flowFile.contentClaimIdentifier);
+                formatContentValue($('#content-offset'), 
flowFile.contentClaimOffset);
+                formatContentValue($('#content-bytes'), 
flowFile.contentClaimFileSizeBytes);
+
+                // input content file size
+                var contentSize = $('#content-size');
+                formatContentValue(contentSize, flowFile.contentClaimFileSize);
+                if 
(nf.Common.isDefinedAndNotNull(flowFile.contentClaimFileSize)) {
+                    // over the default tooltip with the actual byte count
+                    contentSize.attr('title', 
nf.Common.formatInteger(flowFile.contentClaimFileSizeBytes) + ' bytes');
+                }
+
+                // show the content details
+                $('#flowfile-content-details').show();
+            } else {
+                $('#flowfile-content-details').hide();
+            }
+
+            // attributes
+            var attributesContainer = $('#flowfile-attributes-container');
+
+            // get any action details
+            $.each(flowFile.attributes, function (attributeName, 
attributeValue) {
+                // create the attribute record
+                var attributeRecord = $('<div class="attribute-detail"></div>')
+                    .append($('<div class="attribute-name">' + 
nf.Common.formatValue(attributeName) + '</div>').ellipsis())
+                    .appendTo(attributesContainer);
+
+                // add the current value
+                attributeRecord
+                    .append($('<div class="attribute-value">' + 
nf.Common.formatValue(attributeValue) + '</div>').ellipsis())
+                    .append('<div class="clear"></div>');
+            });
+
+            // show the dialog
+            $('#flowfile-details-dialog').modal('show');
+        }).fail(nf.Common.handleAjaxError);
+    };
+
+    /**
+     * Resets the table size.
+     */
+    var resetTableSize = function () {
+        var queueListingGrid = $('#queue-listing-table').data('gridInstance');
+        if (nf.Common.isDefinedAndNotNull(queueListingGrid)) {
+            queueListingGrid.resizeCanvas();
+        }
+    };
+
+    return {
+        init: function () {
+            initializeListingRequestStatusDialog();
+            initFlowFileDetailsDialog();
+
+            // listen for browser resize events to update the page size
+            $(window).resize(function () {
+                resetTableSize();
+            });
+
+            // define a custom formatter for showing more processor details
+            var moreDetailsFormatter = function (row, cell, value, columnDef, 
dataContext) {
+                return '<img src="images/iconDetails.png" title="View Details" 
class="pointer show-flowfile-details" style="margin-top: 5px; float: left;"/>';
+            };
+
+            // function for formatting data sizes
+            var dataSizeFormatter = function (row, cell, value, columnDef, 
dataContext) {
+                return nf.Common.formatDataSize(value);
+            };
+
+            // function for formatting durations
+            var durationFormatter = function (row, cell, value, columnDef, 
dataContext) {
+                return nf.Common.formatDuration(value);
+            }
+
+            // function for formatting penalization
+            var penalizedFormatter = function (row, cell, value, columnDef, 
dataContext) {
+                var markup = '';
+
+                if (value === true) {
+                    markup += 'Yes';
+                }
+
+                return markup;
+            }
+
+            // initialize the queue listing table
+            var queueListingColumns = [
+                {id: 'moreDetails', field: 'moreDetails', name: '&nbsp;', 
sortable: false, resizable: false, formatter: moreDetailsFormatter, width: 50, 
maxWidth: 50},
+                {id: 'QUEUE_POSITION', name: 'Position', field: 'position', 
sortable: true, resizable: false, width: 75, maxWidth: 75},
+                {id: 'FLOWFILE_UUID', name: 'UUID', field: 'uuid', sortable: 
true, resizable: true},
+                {id: 'FILENAME', name: 'Filename', field: 'filename', 
sortable: true, resizable: true},
+                {id: 'FLOWFILE_SIZE', name: 'File Size', field: 'size', 
sortable: true, resizable: true, defaultSortAsc: false, formatter: 
dataSizeFormatter},
+                {id: 'QUEUED_DURATION', name: 'Queued Duration', field: 
'queuedDuration', sortable: true, resizable: true, formatter: 
durationFormatter},
+                {id: 'FLOWFILE_AGE', name: 'Lineage Duration', field: 
'lineageDuration', sortable: true, resizable: true, formatter: 
durationFormatter},
+                {id: 'PENALIZATION', name: 'Penalized', field: 'penalized', 
sortable: true, resizable: false, width: 100, maxWidth: 100, formatter: 
penalizedFormatter}
+            ];
+
+            // conditionally show the cluster node identifier
+            if (nf.Canvas.isClustered()) {
+                queueListingColumns.push({id: 'clusterNodeAddress', name: 
'Node', field: 'clusterNodeAddress', sortable: false, resizable: true});
+            }
+
+            var queueListingOptions = {
+                forceFitColumns: true,
+                enableTextSelectionOnCells: true,
+                enableCellNavigation: false,
+                enableColumnReorder: false,
+                autoEdit: false
+            };
+
+            // initialize the dataview
+            var queueListingData = new Slick.Data.DataView({
+                inlineFilters: false
+            });
+            queueListingData.setItems([]);
+
+            // initialize the grid
+            var queueListingGrid = new Slick.Grid('#queue-listing-table', 
queueListingData, queueListingColumns, queueListingOptions);
+            queueListingGrid.setSelectionModel(new Slick.RowSelectionModel());
+            queueListingGrid.registerPlugin(new Slick.AutoTooltips());
+            queueListingGrid.onSort.subscribe(function (e, args) {
+                var connection = $('#queue-listing-table').data('connection');
+                performListing(connection, args.sortCol.id, args.sortAsc);
+            });
+
+            // configure a click listener
+            queueListingGrid.onClick.subscribe(function (e, args) {
+                var target = $(e.target);
+
+                // get the node at this row
+                var item = queueListingData.getItem(args.row);
+
+                // determine the desired action
+                if (queueListingGrid.getColumns()[args.cell].id === 
'moreDetails') {
+                    if (target.hasClass('show-flowfile-details')) {
+                        showFlowFileDetails(item);
+                    }
+                }
+            });
+
+            // wire up the dataview to the grid
+            queueListingData.onRowCountChanged.subscribe(function (e, args) {
+                queueListingGrid.updateRowCount();
+                queueListingGrid.render();
+
+                // update the total number of displayed flowfiles
+                $('#displayed-flowfiles').text(args.current);
+            });
+            queueListingData.onRowsChanged.subscribe(function (e, args) {
+                queueListingGrid.invalidateRows(args.rows);
+                queueListingGrid.render();
+            });
+
+            // hold onto an instance of the grid
+            $('#queue-listing-table').data('gridInstance', queueListingGrid);
+
+            // initialize the number of display items
+            $('#displayed-flowfiles').text('0');
+        },
+
+        /**
+         * Shows the listing of the FlowFiles from a given connection.
+         *
+         * @param   {object}    The connection
+         */
+        listQueue: function (connection) {
+            var queueListingGrid = 
$('#queue-listing-table').data('gridInstance');
+            queueListingGrid.setSortColumn(DEFAULT_SORT_COL, DEFAULT_SORT_ASC);
+
+            // perform the initial listing
+            performListing(connection, DEFAULT_SORT_COL, 
DEFAULT_SORT_ASC).done(function () {
+                // update the connection name
+                var connectionName = 
nf.CanvasUtils.formatConnectionName(connection.component);
+                if (connectionName === '') {
+                    connectionName = 'Connection';
+                }
+                $('#queue-listing-header-text').text(connectionName);
+
+                // show the listing container
+                nf.Shell.showContent('#queue-listing-container').done(function 
() {
+                    $('#queue-listing-table').removeData('connection');
+
+                    // clear the table
+                    var queueListingData = queueListingGrid.getData();
+
+                    // clear the flowfiles
+                    queueListingData.beginUpdate();
+                    queueListingData.setItems([], 'uuid');
+                    queueListingData.endUpdate();
+
+                    // reset stats
+                    $('#displayed-flowfiles, 
#total-flowfiles-count').text('0');
+                    
$('#total-flowfiles-size').text(nf.Common.formatDataSize(0));
+                });
+
+                // adjust the table size
+                resetTableSize();
+
+                // store the connection for access later
+                $('#queue-listing-table').data('connection', connection);
+            });
+        }
+    };
+}());
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/b330fd16/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
index cf83e16..6b4a5ea 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
@@ -463,6 +463,16 @@ nf.Common = (function () {
         },
 
         /**
+         * Returns whether a content viewer has been configured.
+         *
+         * @returns {boolean}
+         */
+        isContentViewConfigured: function () {
+            var contentViewerUrl = $('#nifi-content-viewer-url').text();
+            return !nf.Common.isBlank(contentViewerUrl);
+        },
+
+        /**
          * Populates the specified field with the specified value. If the 
value is 
          * undefined, the field will read 'No value set.' If the value is an 
empty
          * string, the field will read 'Empty string set.'

http://git-wip-us.apache.org/repos/asf/nifi/blob/b330fd16/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
index faa6adc..0ea44b2 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-table.js
@@ -70,16 +70,6 @@ nf.ProvenanceTable = (function () {
     };
 
     /**
-     * Returns whether a content viewer has been configured.
-     * 
-     * @returns {boolean}
-     */
-    var isContentViewConfigured = function () {
-        var contentViewerUrl = $('#nifi-content-viewer-url').text();
-        return !nf.Common.isBlank(contentViewerUrl);
-    };
-
-    /**
      * Downloads the content for the provenance event that is currently loaded 
in the specified direction.
      * 
      * @param {string} direction
@@ -206,7 +196,7 @@ nf.ProvenanceTable = (function () {
         });
 
         // if a content viewer url is specified, use it
-        if (isContentViewConfigured()) {
+        if (nf.Common.isContentViewConfigured()) {
             // input view
             $('#input-content-view').on('click', function () {
                 viewContent('input');

Reply via email to