You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2017/01/20 21:19:37 UTC
[04/12] nifi git commit: [NIFI-3359] Modularize all of nifi-web-ui
except canvas directory - Removing shell.jsp from summary.jsp. - This closes
#1428
http://git-wip-us.apache.org/repos/asf/nifi/blob/dc934cbb/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 7da8593..2826e3a 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
@@ -15,1446 +15,1508 @@
* limitations under the License.
*/
-/* global nf, top, Slick */
-
-nf.ng.ProvenanceTable = function (provenanceLineageCtrl) {
+/* global nf, top, define, module, require, exports */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery',
+ 'Slick',
+ 'nf.Common',
+ 'nf.Dialog',
+ 'nf.ErrorHandler',
+ 'nf.Storage',
+ 'nf.ng.Bridge'],
+ function ($, Slick, common, dialog, errorHandler, storage, angularBridge) {
+ return (nf.ng.ProvenanceTable = factory($, Slick, common, dialog, errorHandler, storage, angularBridge));
+ });
+ } else if (typeof exports === 'object' && typeof module === 'object') {
+ module.exports = (nf.ng.ProvenanceTable =
+ factory(require('jquery'),
+ require('Slick'),
+ require('nf.Common'),
+ require('nf.Dialog'),
+ require('nf.ErrorHandler'),
+ require('nf.Storage'),
+ require('nf.ng.Bridge')));
+ } else {
+ nf.ng.ProvenanceTable = factory(root.$,
+ root.Slick,
+ root.nf.Common,
+ root.nf.Dialog,
+ root.nf.ErrorHandler,
+ root.nf.Storage,
+ root.nf.ng.Bridge);
+ }
+}(this, function ($, Slick, common, dialog, errorHandler, storage, angularBridge) {
'use strict';
- /**
- * Configuration object used to hold a number of configuration items.
- */
- var config = {
- maxResults: 1000,
- defaultStartTime: '00:00:00',
- defaultEndTime: '23:59:59',
- styles: {
- hidden: 'hidden'
- },
- urls: {
- searchOptions: '../nifi-api/provenance/search-options',
- replays: '../nifi-api/provenance-events/replays',
- provenance: '../nifi-api/provenance',
- provenanceEvents: '../nifi-api/provenance-events/',
- clusterSearch: '../nifi-api/flow/cluster/search-results',
- d3Script: 'js/d3/d3.min.js',
- lineageScript: 'js/nf/provenance/nf-provenance-lineage.js',
- uiExtensionToken: '../nifi-api/access/ui-extension-token',
- downloadToken: '../nifi-api/access/download-token'
- }
- };
+ var nfProvenanceTable = function (provenanceLineageCtrl) {
+ 'use strict';
- /**
- * The last search performed
- */
- var cachedQuery = {};
-
- /**
- * Downloads the content for the provenance event that is currently loaded in the specified direction.
- *
- * @param {string} direction
- */
- var downloadContent = function (direction) {
- var eventId = $('#provenance-event-id').text();
-
- // build the url
- var dataUri = config.urls.provenanceEvents + encodeURIComponent(eventId) + '/content/' + encodeURIComponent(direction);
-
- // perform the request once we've received a token
- nf.Common.getAccessToken(config.urls.downloadToken).done(function (downloadToken) {
- var parameters = {};
-
- // conditionally include the ui extension token
- if (!nf.Common.isBlank(downloadToken)) {
- parameters['access_token'] = downloadToken;
+ /**
+ * Configuration object used to hold a number of configuration items.
+ */
+ var config = {
+ maxResults: 1000,
+ defaultStartTime: '00:00:00',
+ defaultEndTime: '23:59:59',
+ styles: {
+ hidden: 'hidden'
+ },
+ urls: {
+ searchOptions: '../nifi-api/provenance/search-options',
+ replays: '../nifi-api/provenance-events/replays',
+ provenance: '../nifi-api/provenance',
+ provenanceEvents: '../nifi-api/provenance-events/',
+ clusterSearch: '../nifi-api/flow/cluster/search-results',
+ d3Script: 'js/d3/d3.min.js',
+ lineageScript: 'js/nf/provenance/nf-provenance-lineage.js',
+ uiExtensionToken: '../nifi-api/access/ui-extension-token',
+ downloadToken: '../nifi-api/access/download-token'
}
+ };
- // conditionally include the cluster node id
- var clusterNodeId = $('#provenance-event-cluster-node-id').text();
- if (!nf.Common.isBlank(clusterNodeId)) {
- parameters['clusterNodeId'] = clusterNodeId;
- }
+ /**
+ * The last search performed
+ */
+ var cachedQuery = {};
- // open the url
- if ($.isEmptyObject(parameters)) {
- window.open(dataUri);
- } else {
- window.open(dataUri + '?' + $.param(parameters));
- }
- }).fail(function () {
- nf.Dialog.showOkDialog({
- headerText: 'Provenance',
- dialogContent: 'Unable to generate access token for downloading content.'
- });
- });
- };
+ /**
+ * Downloads the content for the provenance event that is currently loaded in the specified direction.
+ *
+ * @param {string} direction
+ */
+ var downloadContent = function (direction) {
+ var eventId = $('#provenance-event-id').text();
- /**
- * Views the content for the provenance event that is currently loaded in the specified direction.
- *
- * @param {string} direction
- */
- var viewContent = function (direction) {
- var controllerUri = $('#nifi-controller-uri').text();
- var eventId = $('#provenance-event-id').text();
-
- // build the uri to the data
- var dataUri = controllerUri + 'provenance-events/' + encodeURIComponent(eventId) + '/content/' + encodeURIComponent(direction);
-
- // generate tokens as necessary
- var getAccessTokens = $.Deferred(function (deferred) {
- if (nf.Storage.hasItem('jwt')) {
- // generate a token for the ui extension and another for the callback
- var uiExtensionToken = $.ajax({
- type: 'POST',
- url: config.urls.uiExtensionToken
- });
- var downloadToken = $.ajax({
- type: 'POST',
- url: config.urls.downloadToken
+ // build the url
+ var dataUri = config.urls.provenanceEvents + encodeURIComponent(eventId) + '/content/' + encodeURIComponent(direction);
+
+ // perform the request once we've received a token
+ common.getAccessToken(config.urls.downloadToken).done(function (downloadToken) {
+ var parameters = {};
+
+ // conditionally include the ui extension token
+ if (!common.isBlank(downloadToken)) {
+ parameters['access_token'] = downloadToken;
+ }
+
+ // conditionally include the cluster node id
+ var clusterNodeId = $('#provenance-event-cluster-node-id').text();
+ if (!common.isBlank(clusterNodeId)) {
+ parameters['clusterNodeId'] = clusterNodeId;
+ }
+
+ // open the url
+ if ($.isEmptyObject(parameters)) {
+ window.open(dataUri);
+ } else {
+ window.open(dataUri + '?' + $.param(parameters));
+ }
+ }).fail(function () {
+ dialog.showOkDialog({
+ headerText: 'Provenance',
+ dialogContent: 'Unable to generate access token for downloading content.'
});
+ });
+ };
- // wait for each token
- $.when(uiExtensionToken, downloadToken).done(function (uiExtensionTokenResult, downloadTokenResult) {
- var uiExtensionToken = uiExtensionTokenResult[0];
- var downloadToken = downloadTokenResult[0];
- deferred.resolve(uiExtensionToken, downloadToken);
- }).fail(function () {
- nf.Dialog.showOkDialog({
- headerText: 'Provenance',
- dialogContent: 'Unable to generate access token for viewing content.'
+ /**
+ * Views the content for the provenance event that is currently loaded in the specified direction.
+ *
+ * @param {string} direction
+ */
+ var viewContent = function (direction) {
+ var controllerUri = $('#nifi-controller-uri').text();
+ var eventId = $('#provenance-event-id').text();
+
+ // build the uri to the data
+ var dataUri = controllerUri + 'provenance-events/' + encodeURIComponent(eventId) + '/content/' + encodeURIComponent(direction);
+
+ // generate tokens as necessary
+ var getAccessTokens = $.Deferred(function (deferred) {
+ if (storage.hasItem('jwt')) {
+ // generate a token for the ui extension and another for the callback
+ var uiExtensionToken = $.ajax({
+ type: 'POST',
+ url: config.urls.uiExtensionToken
+ });
+ var downloadToken = $.ajax({
+ type: 'POST',
+ url: config.urls.downloadToken
});
- deferred.reject();
- });
- } else {
- deferred.resolve('', '');
- }
- }).promise();
- // perform the request after we've received the tokens
- getAccessTokens.done(function (uiExtensionToken, downloadToken) {
- var dataUriParameters = {};
+ // wait for each token
+ $.when(uiExtensionToken, downloadToken).done(function (uiExtensionTokenResult, downloadTokenResult) {
+ var uiExtensionToken = uiExtensionTokenResult[0];
+ var downloadToken = downloadTokenResult[0];
+ deferred.resolve(uiExtensionToken, downloadToken);
+ }).fail(function () {
+ dialog.showOkDialog({
+ headerText: 'Provenance',
+ dialogContent: 'Unable to generate access token for viewing content.'
+ });
+ deferred.reject();
+ });
+ } else {
+ deferred.resolve('', '');
+ }
+ }).promise();
- // conditionally include the cluster node id
- var clusterNodeId = $('#provenance-event-cluster-node-id').text();
- if (!nf.Common.isBlank(clusterNodeId)) {
- dataUriParameters['clusterNodeId'] = clusterNodeId;
- }
+ // perform the request after we've received the tokens
+ getAccessTokens.done(function (uiExtensionToken, downloadToken) {
+ var dataUriParameters = {};
- // include the download token if applicable
- if (!nf.Common.isBlank(downloadToken)) {
- dataUriParameters['access_token'] = downloadToken;
- }
+ // conditionally include the cluster node id
+ var clusterNodeId = $('#provenance-event-cluster-node-id').text();
+ if (!common.isBlank(clusterNodeId)) {
+ dataUriParameters['clusterNodeId'] = clusterNodeId;
+ }
- // include parameters if necessary
- if ($.isEmptyObject(dataUriParameters) === false) {
- dataUri = dataUri + '?' + $.param(dataUriParameters);
- }
+ // include the download token if applicable
+ if (!common.isBlank(downloadToken)) {
+ dataUriParameters['access_token'] = downloadToken;
+ }
- // open the content viewer
- var contentViewerUrl = $('#nifi-content-viewer-url').text();
+ // include parameters if necessary
+ if ($.isEmptyObject(dataUriParameters) === false) {
+ dataUri = dataUri + '?' + $.param(dataUriParameters);
+ }
- // 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
+ var contentViewerUrl = $('#nifi-content-viewer-url').text();
- var contentViewerParameters = {
- 'ref': dataUri
- };
+ // 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 += '&';
+ }
- // include the download token if applicable
- if (!nf.Common.isBlank(uiExtensionToken)) {
- contentViewerParameters['access_token'] = uiExtensionToken;
- }
+ var contentViewerParameters = {
+ 'ref': dataUri
+ };
- // open the content viewer
- window.open(contentViewerUrl + $.param(contentViewerParameters));
- });
- };
+ // include the download token if applicable
+ if (!common.isBlank(uiExtensionToken)) {
+ contentViewerParameters['access_token'] = uiExtensionToken;
+ }
- /**
- * Initializes the details dialog.
- */
- var initDetailsDialog = function () {
- // initialize the properties tabs
- $('#event-details-tabs').tabbs({
- tabStyle: 'tab',
- selectedTabStyle: 'selected-tab',
- scrollableTabContentStyle: 'scrollable',
- tabs: [{
- name: 'Details',
- tabContentId: 'event-details-tab-content'
- }, {
- name: 'Attributes',
- tabContentId: 'attributes-tab-content'
- }, {
- name: 'Content',
- tabContentId: 'content-tab-content'
- }]
- });
-
- $('#event-details-dialog').modal({
- scrollableContentStyle: 'scrollable',
- headerText: 'Provenance Event',
- buttons: [{
- buttonText: 'Ok',
- color: {
- base: '#728E9B',
- hover: '#004849',
- text: '#ffffff'
- },
+ // open the content viewer
+ window.open(contentViewerUrl + $.param(contentViewerParameters));
+ });
+ };
+
+ /**
+ * Initializes the details dialog.
+ */
+ var initDetailsDialog = function () {
+ // initialize the properties tabs
+ $('#event-details-tabs').tabbs({
+ tabStyle: 'tab',
+ selectedTabStyle: 'selected-tab',
+ scrollableTabContentStyle: 'scrollable',
+ tabs: [{
+ name: 'Details',
+ tabContentId: 'event-details-tab-content'
+ }, {
+ name: 'Attributes',
+ tabContentId: 'attributes-tab-content'
+ }, {
+ name: 'Content',
+ tabContentId: 'content-tab-content'
+ }]
+ });
+
+ $('#event-details-dialog').modal({
+ scrollableContentStyle: 'scrollable',
+ headerText: 'Provenance Event',
+ buttons: [{
+ buttonText: 'Ok',
+ color: {
+ base: '#728E9B',
+ hover: '#004849',
+ text: '#ffffff'
+ },
+ handler: {
+ click: function () {
+ $('#event-details-dialog').modal('hide');
+ }
+ }
+ }],
handler: {
- click: function () {
- $('#event-details-dialog').modal('hide');
+ close: function () {
+ // clear the details
+ $('#additional-provenance-details').empty();
+ $('#attributes-container').empty();
+ $('#parent-flowfiles-container').empty();
+ $('#child-flowfiles-container').empty();
+ $('#provenance-event-cluster-node-id').text('');
+ $('#modified-attribute-toggle').removeClass('checkbox-checked').addClass('checkbox-unchecked');
+ },
+ open: function () {
+ common.toggleScrollable($('#' + this.find('.tab-container').attr('id') + '-content').get(0));
}
}
- }],
- handler: {
- close: function () {
- // clear the details
- $('#additional-provenance-details').empty();
- $('#attributes-container').empty();
- $('#parent-flowfiles-container').empty();
- $('#child-flowfiles-container').empty();
- $('#provenance-event-cluster-node-id').text('');
- $('#modified-attribute-toggle').removeClass('checkbox-checked').addClass('checkbox-unchecked');
- },
- open: function () {
- nf.Common.toggleScrollable($('#' + this.find('.tab-container').attr('id') + '-content').get(0));
- }
- }
- });
-
- // toggle which attributes are visible
- $('#modified-attribute-toggle').on('click', function () {
- var unmodifiedAttributes = $('#attributes-container div.attribute-unmodified');
- if (unmodifiedAttributes.is(':visible')) {
- $('#attributes-container div.attribute-unmodified').hide();
- } else {
- $('#attributes-container div.attribute-unmodified').show();
- }
- });
-
- // input download
- $('#input-content-download').on('click', function () {
- downloadContent('input');
- });
-
- // output download
- $('#output-content-download').on('click', function () {
- downloadContent('output');
- });
-
- // if a content viewer url is specified, use it
- if (nf.Common.isContentViewConfigured()) {
- // input view
- $('#input-content-view').on('click', function () {
- viewContent('input');
});
- // output view
- $('#output-content-view').on('click', function () {
- viewContent('output');
+ // toggle which attributes are visible
+ $('#modified-attribute-toggle').on('click', function () {
+ var unmodifiedAttributes = $('#attributes-container div.attribute-unmodified');
+ if (unmodifiedAttributes.is(':visible')) {
+ $('#attributes-container div.attribute-unmodified').hide();
+ } else {
+ $('#attributes-container div.attribute-unmodified').show();
+ }
});
- }
- // handle the replay and downloading
- $('#replay-content').on('click', function () {
- var replayEntity = {
- 'eventId': $('#provenance-event-id').text()
- };
+ // input download
+ $('#input-content-download').on('click', function () {
+ downloadContent('input');
+ });
- // conditionally include the cluster node id
- var clusterNodeId = $('#provenance-event-cluster-node-id').text();
- if (!nf.Common.isBlank(clusterNodeId)) {
- replayEntity['clusterNodeId'] = clusterNodeId;
- }
+ // output download
+ $('#output-content-download').on('click', function () {
+ downloadContent('output');
+ });
- $.ajax({
- type: 'POST',
- url: config.urls.replays,
- data: JSON.stringify(replayEntity),
- dataType: 'json',
- contentType: 'application/json'
- }).done(function (response) {
- nf.Dialog.showOkDialog({
- headerText: 'Provenance',
- dialogContent: 'Successfully submitted replay request.'
+ // if a content viewer url is specified, use it
+ if (common.isContentViewConfigured()) {
+ // input view
+ $('#input-content-view').on('click', function () {
+ viewContent('input');
});
- }).fail(nf.Common.handleAjaxError);
- $('#event-details-dialog').modal('hide');
- });
+ // output view
+ $('#output-content-view').on('click', function () {
+ viewContent('output');
+ });
+ }
- // show the replay panel
- $('#replay-details').show();
- };
+ // handle the replay and downloading
+ $('#replay-content').on('click', function () {
+ var replayEntity = {
+ 'eventId': $('#provenance-event-id').text()
+ };
- /**
- * Initializes the search dialog.
- *
- * @param {boolean} isClustered Whether or not this NiFi clustered
- */
- var initSearchDialog = function (isClustered, provenanceTableCtrl) {
- // configure the start and end date picker
- $('#provenance-search-start-date, #provenance-search-end-date').datepicker({
- showAnim: '',
- showOtherMonths: true,
- selectOtherMonths: true
- });
-
- // initialize the default start date/time
- $('#provenance-search-start-date').datepicker('setDate', '+0d');
- $('#provenance-search-end-date').datepicker('setDate', '+0d');
- $('#provenance-search-start-time').val('00:00:00');
- $('#provenance-search-end-time').val('23:59:59');
-
- // initialize the default file sizes
- $('#provenance-search-minimum-file-size').val('');
- $('#provenance-search-maximum-file-size').val('');
-
- // allow users to be able to search a specific node
- if (isClustered) {
- // make the dialog larger to support the select location
- $('#provenance-search-dialog').height(575);
-
- // get the nodes in the cluster
- $.ajax({
- type: 'GET',
- url: config.urls.clusterSearch,
- dataType: 'json'
- }).done(function (response) {
- var nodeResults = response.nodeResults;
-
- // create the searchable options
- var searchableOptions = [{
- text: 'cluster',
- value: null
- }];
-
- // sort the nodes
- nodeResults.sort(function (a, b) {
- var compA = a.address.toUpperCase();
- var compB = b.address.toUpperCase();
- return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
- });
+ // conditionally include the cluster node id
+ var clusterNodeId = $('#provenance-event-cluster-node-id').text();
+ if (!common.isBlank(clusterNodeId)) {
+ replayEntity['clusterNodeId'] = clusterNodeId;
+ }
- // add each node
- $.each(nodeResults, function (_, nodeResult) {
- searchableOptions.push({
- text: nodeResult.address,
- value: nodeResult.id
+ $.ajax({
+ type: 'POST',
+ url: config.urls.replays,
+ data: JSON.stringify(replayEntity),
+ dataType: 'json',
+ contentType: 'application/json'
+ }).done(function (response) {
+ dialog.showOkDialog({
+ headerText: 'Provenance',
+ dialogContent: 'Successfully submitted replay request.'
});
- });
+ }).fail(errorHandler.handleAjaxError);
- // populate the combo
- $('#provenance-search-location').combo({
- options: searchableOptions
- });
- }).fail(nf.Common.handleAjaxError);
+ $('#event-details-dialog').modal('hide');
+ });
- // show the node search combo
- $('#provenance-search-location-container').show();
- }
+ // show the replay panel
+ $('#replay-details').show();
+ };
- // configure the search dialog
- $('#provenance-search-dialog').modal({
- scrollableContentStyle: 'scrollable',
- headerText: 'Search Events',
- buttons: [{
- buttonText: 'Search',
- color: {
- base: '#728E9B',
- hover: '#004849',
- text: '#ffffff'
- },
- handler: {
- click: function () {
- $('#provenance-search-dialog').modal('hide');
-
- var search = {};
-
- // extract the start date time
- var startDate = $.trim($('#provenance-search-start-date').val());
- var startTime = $.trim($('#provenance-search-start-time').val());
- if (startDate !== '') {
- if (startTime === '') {
- startTime = config.defaultStartTime;
- $('#provenance-search-start-time').val(startTime);
- }
- search['startDate'] = startDate + ' ' + startTime + ' ' + $('.timezone:first').text();
- }
+ /**
+ * Initializes the search dialog.
+ *
+ * @param {boolean} isClustered Whether or not this NiFi clustered
+ */
+ var initSearchDialog = function (isClustered, provenanceTableCtrl) {
+ // configure the start and end date picker
+ $('#provenance-search-start-date, #provenance-search-end-date').datepicker({
+ showAnim: '',
+ showOtherMonths: true,
+ selectOtherMonths: true
+ });
- // extract the end date time
- var endDate = $.trim($('#provenance-search-end-date').val());
- var endTime = $.trim($('#provenance-search-end-time').val());
- if (endDate !== '') {
- if (endTime === '') {
- endTime = config.defaultEndTime;
- $('#provenance-search-end-time').val(endTime);
- }
- search['endDate'] = endDate + ' ' + endTime + ' ' + $('.timezone:first').text();
- }
+ // initialize the default start date/time
+ $('#provenance-search-start-date').datepicker('setDate', '+0d');
+ $('#provenance-search-end-date').datepicker('setDate', '+0d');
+ $('#provenance-search-start-time').val('00:00:00');
+ $('#provenance-search-end-time').val('23:59:59');
- // extract the min/max file size
- var minFileSize = $.trim($('#provenance-search-minimum-file-size').val());
- if (minFileSize !== '') {
- search['minimumFileSize'] = minFileSize;
- }
+ // initialize the default file sizes
+ $('#provenance-search-minimum-file-size').val('');
+ $('#provenance-search-maximum-file-size').val('');
- var maxFileSize = $.trim($('#provenance-search-maximum-file-size').val());
- if (maxFileSize !== '') {
- search['maximumFileSize'] = maxFileSize;
- }
+ // allow users to be able to search a specific node
+ if (isClustered) {
+ // make the dialog larger to support the select location
+ $('#provenance-search-dialog').height(575);
+
+ // get the nodes in the cluster
+ $.ajax({
+ type: 'GET',
+ url: config.urls.clusterSearch,
+ dataType: 'json'
+ }).done(function (response) {
+ var nodeResults = response.nodeResults;
+
+ // create the searchable options
+ var searchableOptions = [{
+ text: 'cluster',
+ value: null
+ }];
+
+ // sort the nodes
+ nodeResults.sort(function (a, b) {
+ var compA = a.address.toUpperCase();
+ var compB = b.address.toUpperCase();
+ return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
+ });
- // limit search to a specific node
- if (isClustered) {
- var searchLocation = $('#provenance-search-location').combo('getSelectedOption');
- if (searchLocation.value !== null) {
- search['clusterNodeId'] = searchLocation.value;
- }
- }
+ // add each node
+ $.each(nodeResults, function (_, nodeResult) {
+ searchableOptions.push({
+ text: nodeResult.address,
+ value: nodeResult.id
+ });
+ });
- // add the search criteria
- search['searchTerms'] = getSearchCriteria();
+ // populate the combo
+ $('#provenance-search-location').combo({
+ options: searchableOptions
+ });
+ }).fail(errorHandler.handleAjaxError);
- // reload the table
- provenanceTableCtrl.loadProvenanceTable(search);
- }
- }
- },
- {
- buttonText: 'Cancel',
+ // show the node search combo
+ $('#provenance-search-location-container').show();
+ }
+
+ // configure the search dialog
+ $('#provenance-search-dialog').modal({
+ scrollableContentStyle: 'scrollable',
+ headerText: 'Search Events',
+ buttons: [{
+ buttonText: 'Search',
color: {
- base: '#E3E8EB',
- hover: '#C7D2D7',
- text: '#004849'
+ base: '#728E9B',
+ hover: '#004849',
+ text: '#ffffff'
},
handler: {
click: function () {
$('#provenance-search-dialog').modal('hide');
+
+ var search = {};
+
+ // extract the start date time
+ var startDate = $.trim($('#provenance-search-start-date').val());
+ var startTime = $.trim($('#provenance-search-start-time').val());
+ if (startDate !== '') {
+ if (startTime === '') {
+ startTime = config.defaultStartTime;
+ $('#provenance-search-start-time').val(startTime);
+ }
+ search['startDate'] = startDate + ' ' + startTime + ' ' + $('.timezone:first').text();
+ }
+
+ // extract the end date time
+ var endDate = $.trim($('#provenance-search-end-date').val());
+ var endTime = $.trim($('#provenance-search-end-time').val());
+ if (endDate !== '') {
+ if (endTime === '') {
+ endTime = config.defaultEndTime;
+ $('#provenance-search-end-time').val(endTime);
+ }
+ search['endDate'] = endDate + ' ' + endTime + ' ' + $('.timezone:first').text();
+ }
+
+ // extract the min/max file size
+ var minFileSize = $.trim($('#provenance-search-minimum-file-size').val());
+ if (minFileSize !== '') {
+ search['minimumFileSize'] = minFileSize;
+ }
+
+ var maxFileSize = $.trim($('#provenance-search-maximum-file-size').val());
+ if (maxFileSize !== '') {
+ search['maximumFileSize'] = maxFileSize;
+ }
+
+ // limit search to a specific node
+ if (isClustered) {
+ var searchLocation = $('#provenance-search-location').combo('getSelectedOption');
+ if (searchLocation.value !== null) {
+ search['clusterNodeId'] = searchLocation.value;
+ }
+ }
+
+ // add the search criteria
+ search['searchTerms'] = getSearchCriteria();
+
+ // reload the table
+ provenanceTableCtrl.loadProvenanceTable(search);
}
}
- }]
- });
-
- return $.ajax({
- type: 'GET',
- url: config.urls.searchOptions,
- dataType: 'json'
- }).done(function (response) {
- var provenanceOptions = response.provenanceOptions;
-
- // load all searchable fields
- $.each(provenanceOptions.searchableFields, function (_, field) {
- appendSearchableField(field);
+ },
+ {
+ buttonText: 'Cancel',
+ color: {
+ base: '#E3E8EB',
+ hover: '#C7D2D7',
+ text: '#004849'
+ },
+ handler: {
+ click: function () {
+ $('#provenance-search-dialog').modal('hide');
+ }
+ }
+ }]
});
- });
- };
- /**
- * Initializes the provenance query dialog.
- */
- var initProvenanceQueryDialog = function () {
- // initialize the dialog
- $('#provenance-query-dialog').modal({
- scrollableContentStyle: 'scrollable',
- headerText: 'Searching provenance events...'
- });
- };
+ return $.ajax({
+ type: 'GET',
+ url: config.urls.searchOptions,
+ dataType: 'json'
+ }).done(function (response) {
+ var provenanceOptions = response.provenanceOptions;
- /**
- * Appends the specified searchable field to the search dialog.
- *
- * @param {type} field The searchable field
- */
- var appendSearchableField = function (field) {
- var searchableField = $('<div class="searchable-field"></div>').appendTo('#searchable-fields-container');
- $('<span class="searchable-field-id hidden"></span>').text(field.id).appendTo(searchableField);
- $('<div class="searchable-field-name"></div>').text(field.label).appendTo(searchableField);
- $('<div class="searchable-field-value"><input type="text" class="searchable-field-input"/></div>').appendTo(searchableField);
- $('<div class="clear"></div>').appendTo(searchableField);
-
- // make the searchable accessible for populating
- if (field.id === 'ProcessorID') {
- searchableField.find('input').addClass('searchable-component-id');
- } else if (field.id === 'FlowFileUUID') {
- searchableField.find('input').addClass('searchable-flowfile-uuid');
- }
+ // load all searchable fields
+ $.each(provenanceOptions.searchableFields, function (_, field) {
+ appendSearchableField(field);
+ });
+ });
+ };
- // ensure the no searchable fields message is hidden
- $('#no-searchable-fields').hide();
- };
+ /**
+ * Initializes the provenance query dialog.
+ */
+ var initProvenanceQueryDialog = function () {
+ // initialize the dialog
+ $('#provenance-query-dialog').modal({
+ scrollableContentStyle: 'scrollable',
+ headerText: 'Searching provenance events...'
+ });
+ };
- /**
- * Gets the search criteria that the user has specified.
- */
- var getSearchCriteria = function () {
- var searchCriteria = {};
- $('#searchable-fields-container').children('div.searchable-field').each(function () {
- var searchableField = $(this);
- var fieldId = searchableField.children('span.searchable-field-id').text();
- var searchValue = $.trim(searchableField.find('input.searchable-field-input').val());
-
- // if the field isn't blank include it in the search
- if (!nf.Common.isBlank(searchValue)) {
- searchCriteria[fieldId] = searchValue;
+ /**
+ * Appends the specified searchable field to the search dialog.
+ *
+ * @param {type} field The searchable field
+ */
+ var appendSearchableField = function (field) {
+ var searchableField = $('<div class="searchable-field"></div>').appendTo('#searchable-fields-container');
+ $('<span class="searchable-field-id hidden"></span>').text(field.id).appendTo(searchableField);
+ $('<div class="searchable-field-name"></div>').text(field.label).appendTo(searchableField);
+ $('<div class="searchable-field-value"><input type="text" class="searchable-field-input"/></div>').appendTo(searchableField);
+ $('<div class="clear"></div>').appendTo(searchableField);
+
+ // make the searchable accessible for populating
+ if (field.id === 'ProcessorID') {
+ searchableField.find('input').addClass('searchable-component-id');
+ } else if (field.id === 'FlowFileUUID') {
+ searchableField.find('input').addClass('searchable-flowfile-uuid');
}
- });
- return searchCriteria;
- };
- /**
- * Initializes the provenance table.
- *
- * @param {boolean} isClustered Whether or not this instance is clustered
- */
- var initProvenanceTable = function (isClustered, provenanceTableCtrl) {
- // define the function for filtering the list
- $('#provenance-filter').keyup(function () {
- applyFilter();
- });
-
- // filter options
- var filterOptions = [{
- text: 'by component name',
- value: 'componentName'
- }, {
- text: 'by component type',
- value: 'componentType'
- }, {
- text: 'by type',
- value: 'eventType'
- }];
-
- // if clustered, allowing filtering by node id
- if (isClustered) {
- filterOptions.push({
- text: 'by node',
- value: 'clusterNodeAddress'
+ // ensure the no searchable fields message is hidden
+ $('#no-searchable-fields').hide();
+ };
+
+ /**
+ * Gets the search criteria that the user has specified.
+ */
+ var getSearchCriteria = function () {
+ var searchCriteria = {};
+ $('#searchable-fields-container').children('div.searchable-field').each(function () {
+ var searchableField = $(this);
+ var fieldId = searchableField.children('span.searchable-field-id').text();
+ var searchValue = $.trim(searchableField.find('input.searchable-field-input').val());
+
+ // if the field isn't blank include it in the search
+ if (!common.isBlank(searchValue)) {
+ searchCriteria[fieldId] = searchValue;
+ }
});
- }
+ return searchCriteria;
+ };
- // initialize the filter combo
- $('#provenance-filter-type').combo({
- options: filterOptions,
- select: function (option) {
+ /**
+ * Initializes the provenance table.
+ *
+ * @param {boolean} isClustered Whether or not this instance is clustered
+ */
+ var initProvenanceTable = function (isClustered, provenanceTableCtrl) {
+ // define the function for filtering the list
+ $('#provenance-filter').keyup(function () {
applyFilter();
- }
- });
-
- // clear the current search
- $('#clear-provenance-search').click(function () {
- // clear each searchable field
- $('#searchable-fields-container').find('input.searchable-field-input').each(function () {
- $(this).val('');
});
- // reset the default start date/time
- $('#provenance-search-start-date').datepicker('setDate', '+0d');
- $('#provenance-search-end-date').datepicker('setDate', '+0d');
- $('#provenance-search-start-time').val('00:00:00');
- $('#provenance-search-end-time').val('23:59:59');
-
- // reset the minimum and maximum file size
- $('#provenance-search-minimum-file-size').val('');
- $('#provenance-search-maximum-file-size').val('');
+ // filter options
+ var filterOptions = [{
+ text: 'by component name',
+ value: 'componentName'
+ }, {
+ text: 'by component type',
+ value: 'componentType'
+ }, {
+ text: 'by type',
+ value: 'eventType'
+ }];
- // if we are clustered reset the selected option
+ // if clustered, allowing filtering by node id
if (isClustered) {
- $('#provenance-search-location').combo('setSelectedOption', {
- text: 'cluster'
+ filterOptions.push({
+ text: 'by node',
+ value: 'clusterNodeAddress'
});
}
- // reset the stored query
- cachedQuery = {};
-
- // reload the table
- provenanceTableCtrl.loadProvenanceTable();
- });
-
- // add hover effect and click handler for opening the dialog
- $('#provenance-search-button').click(function () {
- $('#provenance-search-dialog').modal('show');
-
- // adjust the field width for a potential scrollbar
- var searchFieldContainer = $('#searchable-fields-container');
- if (searchFieldContainer.get(0).scrollHeight > searchFieldContainer.innerHeight()) {
- $('input.searchable-field-input').width(245);
- } else {
- $('input.searchable-field-input').width(260);
- }
- });
+ // initialize the filter combo
+ $('#provenance-filter-type').combo({
+ options: filterOptions,
+ select: function (option) {
+ applyFilter();
+ }
+ });
- // define a custom formatter for the more details column
- var moreDetailsFormatter = function (row, cell, value, columnDef, dataContext) {
- return '<div title="View Details" class="pointer show-event-details fa fa-info-circle"></div>';
- };
+ // clear the current search
+ $('#clear-provenance-search').click(function () {
+ // clear each searchable field
+ $('#searchable-fields-container').find('input.searchable-field-input').each(function () {
+ $(this).val('');
+ });
- // define how general values are formatted
- var valueFormatter = function (row, cell, value, columnDef, dataContext) {
- return nf.Common.formatValue(value);
- };
+ // reset the default start date/time
+ $('#provenance-search-start-date').datepicker('setDate', '+0d');
+ $('#provenance-search-end-date').datepicker('setDate', '+0d');
+ $('#provenance-search-start-time').val('00:00:00');
+ $('#provenance-search-end-time').val('23:59:59');
- // determine if the this page is in the shell
- var isInShell = (top !== window);
+ // reset the minimum and maximum file size
+ $('#provenance-search-minimum-file-size').val('');
+ $('#provenance-search-maximum-file-size').val('');
- // define how the column is formatted
- var showLineageFormatter = function (row, cell, value, columnDef, dataContext) {
- var markup = '';
+ // if we are clustered reset the selected option
+ if (isClustered) {
+ $('#provenance-search-location').combo('setSelectedOption', {
+ text: 'cluster'
+ });
+ }
- // conditionally include the cluster node id
- if (nf.Common.SUPPORTS_SVG) {
- markup += '<div title="Show Lineage" class="pointer show-lineage icon icon-lineage" style="margin-right: 3px;"></div>';
- }
+ // reset the stored query
+ cachedQuery = {};
- // conditionally support going to the component
- var isRemotePort = dataContext.componentType === 'Remote Input Port' || dataContext.componentType === 'Remote Output Port';
- if (isInShell && nf.Common.isDefinedAndNotNull(dataContext.groupId) && isRemotePort === false) {
- markup += '<div class="pointer go-to fa fa-long-arrow-right" title="Go To"></div>';
- }
+ // reload the table
+ provenanceTableCtrl.loadProvenanceTable();
+ });
- return markup;
- };
+ // add hover effect and click handler for opening the dialog
+ $('#provenance-search-button').click(function () {
+ $('#provenance-search-dialog').modal('show');
- // initialize the provenance table
- var provenanceColumns = [
- {
- id: 'moreDetails',
- name: ' ',
- sortable: false,
- resizable: false,
- formatter: moreDetailsFormatter,
- width: 50,
- maxWidth: 50
- },
- {
- id: 'eventTime',
- name: 'Date/Time',
- field: 'eventTime',
- sortable: true,
- defaultSortAsc: false,
- resizable: true
- },
- {id: 'eventType', name: 'Type', field: 'eventType', sortable: true, resizable: true},
- {id: 'flowFileUuid', name: 'FlowFile Uuid', field: 'flowFileUuid', sortable: true, resizable: true},
- {id: 'fileSize', name: 'Size', field: 'fileSize', sortable: true, defaultSortAsc: false, resizable: true},
- {
- id: 'componentName',
- name: 'Component Name',
- field: 'componentName',
- sortable: true,
- resizable: true,
- formatter: valueFormatter
- },
- {id: 'componentType', name: 'Component Type', field: 'componentType', sortable: true, resizable: true}
- ];
-
- // conditionally show the cluster node identifier
- if (isClustered) {
- provenanceColumns.push({
- id: 'clusterNodeAddress',
- name: 'Node',
- field: 'clusterNodeAddress',
- sortable: true,
- resizable: true
+ // adjust the field width for a potential scrollbar
+ var searchFieldContainer = $('#searchable-fields-container');
+ if (searchFieldContainer.get(0).scrollHeight > searchFieldContainer.innerHeight()) {
+ $('input.searchable-field-input').width(245);
+ } else {
+ $('input.searchable-field-input').width(260);
+ }
});
- }
- // conditionally show the action column
- if (nf.Common.SUPPORTS_SVG || isInShell) {
- provenanceColumns.push({
- id: 'actions',
- name: ' ',
- formatter: showLineageFormatter,
- resizable: false,
- sortable: false,
- width: 50,
- maxWidth: 50
- });
- }
+ // define a custom formatter for the more details column
+ var moreDetailsFormatter = function (row, cell, value, columnDef, dataContext) {
+ return '<div title="View Details" class="pointer show-event-details fa fa-info-circle"></div>';
+ };
- var provenanceOptions = {
- forceFitColumns: true,
- enableTextSelectionOnCells: true,
- enableCellNavigation: true,
- enableColumnReorder: false,
- autoEdit: false,
- multiSelect: false,
- rowHeight: 24
- };
+ // define how general values are formatted
+ var valueFormatter = function (row, cell, value, columnDef, dataContext) {
+ return common.formatValue(value);
+ };
- // create the remote model
- var provenanceData = new Slick.Data.DataView({
- inlineFilters: false
- });
- provenanceData.setItems([]);
- provenanceData.setFilterArgs({
- searchString: '',
- property: 'name'
- });
- provenanceData.setFilter(filter);
-
- // initialize the sort
- sort({
- columnId: 'eventTime',
- sortAsc: false
- }, provenanceData);
-
- // initialize the grid
- var provenanceGrid = new Slick.Grid('#provenance-table', provenanceData, provenanceColumns, provenanceOptions);
- provenanceGrid.setSelectionModel(new Slick.RowSelectionModel());
- provenanceGrid.registerPlugin(new Slick.AutoTooltips());
-
- // initialize the grid sorting
- provenanceGrid.setSortColumn('eventTime', false);
- provenanceGrid.onSort.subscribe(function (e, args) {
- sort({
- columnId: args.sortCol.field,
- sortAsc: args.sortAsc
- }, provenanceData);
- });
+ // determine if the this page is in the shell
+ var isInShell = (top !== window);
- // configure a click listener
- provenanceGrid.onClick.subscribe(function (e, args) {
- var target = $(e.target);
+ // define how the column is formatted
+ var showLineageFormatter = function (row, cell, value, columnDef, dataContext) {
+ var markup = '';
- // get the node at this row
- var item = provenanceData.getItem(args.row);
+ // conditionally include the cluster node id
+ if (common.SUPPORTS_SVG) {
+ markup += '<div title="Show Lineage" class="pointer show-lineage icon icon-lineage" style="margin-right: 3px;"></div>';
+ }
- // determine the desired action
- if (provenanceGrid.getColumns()[args.cell].id === 'actions') {
- if (target.hasClass('show-lineage')) {
- provenanceLineageCtrl.showLineage(item.flowFileUuid, item.eventId.toString(), item.clusterNodeId, provenanceTableCtrl);
- } else if (target.hasClass('go-to')) {
- goTo(item);
+ // conditionally support going to the component
+ var isRemotePort = dataContext.componentType === 'Remote Input Port' || dataContext.componentType === 'Remote Output Port';
+ if (isInShell && common.isDefinedAndNotNull(dataContext.groupId) && isRemotePort === false) {
+ markup += '<div class="pointer go-to fa fa-long-arrow-right" title="Go To"></div>';
}
- } else if (provenanceGrid.getColumns()[args.cell].id === 'moreDetails') {
- if (target.hasClass('show-event-details')) {
- provenanceTableCtrl.showEventDetails(item.eventId, item.clusterNodeId);
+
+ return markup;
+ };
+
+ // initialize the provenance table
+ var provenanceColumns = [
+ {
+ id: 'moreDetails',
+ name: ' ',
+ sortable: false,
+ resizable: false,
+ formatter: moreDetailsFormatter,
+ width: 50,
+ maxWidth: 50
+ },
+ {
+ id: 'eventTime',
+ name: 'Date/Time',
+ field: 'eventTime',
+ sortable: true,
+ defaultSortAsc: false,
+ resizable: true
+ },
+ {
+ id: 'eventType',
+ name: 'Type',
+ field: 'eventType',
+ sortable: true,
+ resizable: true
+ },
+ {
+ id: 'flowFileUuid',
+ name: 'FlowFile Uuid',
+ field: 'flowFileUuid',
+ sortable: true,
+ resizable: true
+ },
+ {
+ id: 'fileSize',
+ name: 'Size',
+ field: 'fileSize',
+ sortable: true,
+ defaultSortAsc: false,
+ resizable: true
+ },
+ {
+ id: 'componentName',
+ name: 'Component Name',
+ field: 'componentName',
+ sortable: true,
+ resizable: true,
+ formatter: valueFormatter
+ },
+ {
+ id: 'componentType',
+ name: 'Component Type',
+ field: 'componentType',
+ sortable: true,
+ resizable: true
}
+ ];
+
+ // conditionally show the cluster node identifier
+ if (isClustered) {
+ provenanceColumns.push({
+ id: 'clusterNodeAddress',
+ name: 'Node',
+ field: 'clusterNodeAddress',
+ sortable: true,
+ resizable: true
+ });
}
- });
-
- // wire up the dataview to the grid
- provenanceData.onRowCountChanged.subscribe(function (e, args) {
- provenanceGrid.updateRowCount();
- provenanceGrid.render();
-
- // update the total number of displayed events if necessary
- $('#displayed-events').text(nf.Common.formatInteger(args.current));
- });
- provenanceData.onRowsChanged.subscribe(function (e, args) {
- provenanceGrid.invalidateRows(args.rows);
- provenanceGrid.render();
- });
-
- // hold onto an instance of the grid
- $('#provenance-table').data('gridInstance', provenanceGrid);
-
- // initialize the number of displayed items
- $('#displayed-events').text('0');
- $('#total-events').text('0');
- };
- /**
- * Applies the filter found in the filter expression text field.
- */
- var applyFilter = function () {
- // get the dataview
- var provenanceGrid = $('#provenance-table').data('gridInstance');
+ // conditionally show the action column
+ if (common.SUPPORTS_SVG || isInShell) {
+ provenanceColumns.push({
+ id: 'actions',
+ name: ' ',
+ formatter: showLineageFormatter,
+ resizable: false,
+ sortable: false,
+ width: 50,
+ maxWidth: 50
+ });
+ }
- // ensure the grid has been initialized
- if (nf.Common.isDefinedAndNotNull(provenanceGrid)) {
- var provenanceData = provenanceGrid.getData();
+ var provenanceOptions = {
+ forceFitColumns: true,
+ enableTextSelectionOnCells: true,
+ enableCellNavigation: true,
+ enableColumnReorder: false,
+ autoEdit: false,
+ multiSelect: false,
+ rowHeight: 24
+ };
- // update the search criteria
+ // create the remote model
+ var provenanceData = new Slick.Data.DataView({
+ inlineFilters: false
+ });
+ provenanceData.setItems([]);
provenanceData.setFilterArgs({
- searchString: getFilterText(),
- property: $('#provenance-filter-type').combo('getSelectedOption').value
+ searchString: '',
+ property: 'name'
});
- provenanceData.refresh();
- }
- };
+ provenanceData.setFilter(filter);
- /**
- * Get the text out of the filter field. If the filter field doesn't
- * have any text it will contain the text 'filter list' so this method
- * accounts for that.
- */
- var getFilterText = function () {
- return $('#provenance-filter').val();
- };
+ // initialize the sort
+ sort({
+ columnId: 'eventTime',
+ sortAsc: false
+ }, provenanceData);
- /**
- * Performs the provenance filtering.
- *
- * @param {object} item The item subject to filtering
- * @param {object} args Filter arguments
- * @returns {Boolean} Whether or not to include the item
- */
- var filter = function (item, args) {
- if (args.searchString === '') {
- return true;
- }
+ // initialize the grid
+ var provenanceGrid = new Slick.Grid('#provenance-table', provenanceData, provenanceColumns, provenanceOptions);
+ provenanceGrid.setSelectionModel(new Slick.RowSelectionModel());
+ provenanceGrid.registerPlugin(new Slick.AutoTooltips());
+
+ // initialize the grid sorting
+ provenanceGrid.setSortColumn('eventTime', false);
+ provenanceGrid.onSort.subscribe(function (e, args) {
+ sort({
+ columnId: args.sortCol.field,
+ sortAsc: args.sortAsc
+ }, provenanceData);
+ });
- try {
- // perform the row filtering
- var filterExp = new RegExp(args.searchString, 'i');
- } catch (e) {
- // invalid regex
- return false;
- }
+ // configure a click listener
+ provenanceGrid.onClick.subscribe(function (e, args) {
+ var target = $(e.target);
- return item[args.property].search(filterExp) >= 0;
- };
+ // get the node at this row
+ var item = provenanceData.getItem(args.row);
- /**
- * Sorts the data according to the sort details.
- *
- * @param {type} sortDetails
- * @param {type} data
- */
- var sort = function (sortDetails, data) {
- // defines a function for sorting
- var comparer = function (a, b) {
- if (sortDetails.columnId === 'eventTime') {
- var aTime = nf.Common.parseDateTime(a[sortDetails.columnId]).getTime();
- var bTime = nf.Common.parseDateTime(b[sortDetails.columnId]).getTime();
- if (aTime === bTime) {
- return a['id'] - b['id'];
- } else {
- return aTime - bTime;
- }
- } else if (sortDetails.columnId === 'fileSize') {
- var aSize = nf.Common.parseSize(a[sortDetails.columnId]);
- var bSize = nf.Common.parseSize(b[sortDetails.columnId]);
- if (aSize === bSize) {
- return a['id'] - b['id'];
- } else {
- return aSize - bSize;
- }
- } else {
- var aString = nf.Common.isDefinedAndNotNull(a[sortDetails.columnId]) ? a[sortDetails.columnId] : '';
- var bString = nf.Common.isDefinedAndNotNull(b[sortDetails.columnId]) ? b[sortDetails.columnId] : '';
- if (aString === bString) {
- return a['id'] - b['id'];
- } else {
- return aString === bString ? 0 : aString > bString ? 1 : -1;
+ // determine the desired action
+ if (provenanceGrid.getColumns()[args.cell].id === 'actions') {
+ if (target.hasClass('show-lineage')) {
+ provenanceLineageCtrl.showLineage(item.flowFileUuid, item.eventId.toString(), item.clusterNodeId, provenanceTableCtrl);
+ } else if (target.hasClass('go-to')) {
+ goTo(item);
+ }
+ } else if (provenanceGrid.getColumns()[args.cell].id === 'moreDetails') {
+ if (target.hasClass('show-event-details')) {
+ provenanceTableCtrl.showEventDetails(item.eventId, item.clusterNodeId);
+ }
}
- }
- };
+ });
- // perform the sort
- data.sort(comparer, sortDetails.sortAsc);
- };
+ // wire up the dataview to the grid
+ provenanceData.onRowCountChanged.subscribe(function (e, args) {
+ provenanceGrid.updateRowCount();
+ provenanceGrid.render();
- /**
- * Submits a new provenance query.
- *
- * @argument {object} provenance The provenance query
- * @returns {deferred}
- */
- var submitProvenance = function (provenance) {
- var provenanceEntity = {
- 'provenance': {
- 'request': $.extend({
- maxResults: config.maxResults,
- summarize: true,
- incrementalResults: false
- }, provenance)
- }
- };
+ // update the total number of displayed events if necessary
+ $('#displayed-events').text(common.formatInteger(args.current));
+ });
+ provenanceData.onRowsChanged.subscribe(function (e, args) {
+ provenanceGrid.invalidateRows(args.rows);
+ provenanceGrid.render();
+ });
- // submit the provenance request
- return $.ajax({
- type: 'POST',
- url: config.urls.provenance,
- data: JSON.stringify(provenanceEntity),
- dataType: 'json',
- contentType: 'application/json'
- }).fail(nf.Common.handleAjaxError);
- };
+ // hold onto an instance of the grid
+ $('#provenance-table').data('gridInstance', provenanceGrid);
- /**
- * Gets the results from the provenance query for the specified id.
- *
- * @param {object} provenance
- * @returns {deferred}
- */
- var getProvenance = function (provenance) {
- var url = provenance.uri;
- if (nf.Common.isDefinedAndNotNull(provenance.request.clusterNodeId)) {
- url += '?' + $.param({
- clusterNodeId: provenance.request.clusterNodeId,
- summarize: true,
- incrementalResults: false
- });
- } else {
- url += '?' + $.param({
- summarize: true,
- incrementalResults: false
- });
- }
+ // initialize the number of displayed items
+ $('#displayed-events').text('0');
+ $('#total-events').text('0');
+ };
- return $.ajax({
- type: 'GET',
- url: url,
- dataType: 'json'
- }).fail(nf.Common.handleAjaxError);
- };
+ /**
+ * Applies the filter found in the filter expression text field.
+ */
+ var applyFilter = function () {
+ // get the dataview
+ var provenanceGrid = $('#provenance-table').data('gridInstance');
- /**
- * Cancels the specified provenance query.
- *
- * @param {object} provenance
- * @return {deferred}
- */
- var cancelProvenance = function (provenance) {
- var url = provenance.uri;
- if (nf.Common.isDefinedAndNotNull(provenance.request.clusterNodeId)) {
- url += '?' + $.param({
- clusterNodeId: provenance.request.clusterNodeId
- });
- }
+ // ensure the grid has been initialized
+ if (common.isDefinedAndNotNull(provenanceGrid)) {
+ var provenanceData = provenanceGrid.getData();
- return $.ajax({
- type: 'DELETE',
- url: url,
- dataType: 'json'
- }).fail(nf.Common.handleAjaxError);
- };
+ // update the search criteria
+ provenanceData.setFilterArgs({
+ searchString: getFilterText(),
+ property: $('#provenance-filter-type').combo('getSelectedOption').value
+ });
+ provenanceData.refresh();
+ }
+ };
- /**
- * Checks the results of the specified provenance.
- *
- * @param {object} provenance
- */
- var loadProvenanceResults = function (provenance, provenanceTableCtrl) {
- var provenanceRequest = provenance.request;
- var provenanceResults = provenance.results;
-
- // ensure there are groups specified
- if (nf.Common.isDefinedAndNotNull(provenanceResults.provenanceEvents)) {
- var provenanceTable = $('#provenance-table').data('gridInstance');
- var provenanceData = provenanceTable.getData();
-
- // set the items
- provenanceData.setItems(provenanceResults.provenanceEvents);
- provenanceData.reSort();
- provenanceTable.invalidate();
-
- // update the stats last refreshed timestamp
- $('#provenance-last-refreshed').text(provenanceResults.generated);
-
- // update the oldest event available
- $('#oldest-event').html(nf.Common.formatValue(provenanceResults.oldestEvent));
-
- // record the server offset
- provenanceTableCtrl.serverTimeOffset = provenanceResults.timeOffset;
-
- // determines if the specified query is blank (no search terms, start or end date)
- var isBlankQuery = function (query) {
- return nf.Common.isUndefinedOrNull(query.startDate) && nf.Common.isUndefinedOrNull(query.endDate) && $.isEmptyObject(query.searchTerms);
- };
+ /**
+ * Get the text out of the filter field. If the filter field doesn't
+ * have any text it will contain the text 'filter list' so this method
+ * accounts for that.
+ */
+ var getFilterText = function () {
+ return $('#provenance-filter').val();
+ };
- // update the filter message based on the request
- if (isBlankQuery(provenanceRequest)) {
- var message = 'Showing the most recent ';
- if (provenanceResults.totalCount >= config.maxResults) {
- message += (nf.Common.formatInteger(config.maxResults) + ' of ' + provenanceResults.total + ' events, please refine the search.');
- } else {
- message += ('events.');
- }
- $('#provenance-query-message').text(message);
- $('#clear-provenance-search').hide();
- } else {
- var message = 'Showing ';
- if (provenanceResults.totalCount >= config.maxResults) {
- message += (nf.Common.formatInteger(config.maxResults) + ' of ' + provenanceResults.total + ' events that match the specified query, please refine the search.');
- } else {
- message += ('the events that match the specified query.');
- }
- $('#provenance-query-message').text(message);
- $('#clear-provenance-search').show();
+ /**
+ * Performs the provenance filtering.
+ *
+ * @param {object} item The item subject to filtering
+ * @param {object} args Filter arguments
+ * @returns {Boolean} Whether or not to include the item
+ */
+ var filter = function (item, args) {
+ if (args.searchString === '') {
+ return true;
}
- // update the total number of events
- $('#total-events').text(nf.Common.formatInteger(provenanceResults.provenanceEvents.length));
- } else {
- $('#total-events').text('0');
- }
- };
-
- /**
- * Goes to the specified component if possible.
- *
- * @argument {object} item The event it
- */
- var goTo = function (item) {
- // ensure the component is still present in the flow
- if (nf.Common.isDefinedAndNotNull(item.groupId)) {
- // only attempt this if we're within a frame
- if (top !== window) {
- // and our parent has canvas utils and shell defined
- if (nf.Common.isDefinedAndNotNull(parent.nf) && nf.Common.isDefinedAndNotNull(parent.nf.CanvasUtils) && nf.Common.isDefinedAndNotNull(parent.nf.Shell)) {
- parent.nf.CanvasUtils.showComponent(item.groupId, item.componentId);
- parent.$('#shell-close-button').click();
- }
+ try {
+ // perform the row filtering
+ var filterExp = new RegExp(args.searchString, 'i');
+ } catch (e) {
+ // invalid regex
+ return false;
}
- }
- };
- function ProvenanceTableCtrl() {
+ return item[args.property].search(filterExp) >= 0;
+ };
/**
- * The server time offset
+ * Sorts the data according to the sort details.
+ *
+ * @param {type} sortDetails
+ * @param {type} data
*/
- this.serverTimeOffset = null;
- }
+ var sort = function (sortDetails, data) {
+ // defines a function for sorting
+ var comparer = function (a, b) {
+ if (sortDetails.columnId === 'eventTime') {
+ var aTime = common.parseDateTime(a[sortDetails.columnId]).getTime();
+ var bTime = common.parseDateTime(b[sortDetails.columnId]).getTime();
+ if (aTime === bTime) {
+ return a['id'] - b['id'];
+ } else {
+ return aTime - bTime;
+ }
+ } else if (sortDetails.columnId === 'fileSize') {
+ var aSize = common.parseSize(a[sortDetails.columnId]);
+ var bSize = common.parseSize(b[sortDetails.columnId]);
+ if (aSize === bSize) {
+ return a['id'] - b['id'];
+ } else {
+ return aSize - bSize;
+ }
+ } else {
+ var aString = common.isDefinedAndNotNull(a[sortDetails.columnId]) ? a[sortDetails.columnId] : '';
+ var bString = common.isDefinedAndNotNull(b[sortDetails.columnId]) ? b[sortDetails.columnId] : '';
+ if (aString === bString) {
+ return a['id'] - b['id'];
+ } else {
+ return aString === bString ? 0 : aString > bString ? 1 : -1;
+ }
+ }
+ };
- ProvenanceTableCtrl.prototype = {
- constructor: ProvenanceTableCtrl,
+ // perform the sort
+ data.sort(comparer, sortDetails.sortAsc);
+ };
/**
- * Initializes the provenance table. Returns a deferred that will indicate when/if the table has initialized successfully.
+ * Submits a new provenance query.
*
- * @param {boolean} isClustered Whether or not this instance is clustered
+ * @argument {object} provenance The provenance query
+ * @returns {deferred}
*/
- init: function (isClustered) {
- var self = this;
- return $.Deferred(function (deferred) {
- // handles init failure
- var failure = function (xhr, status, error) {
- deferred.reject();
- nf.Common.handleAjaxError(xhr, status, error);
- };
-
- // initialize the lineage view
- provenanceLineageCtrl.init();
+ var submitProvenance = function (provenance) {
+ var provenanceEntity = {
+ 'provenance': {
+ 'request': $.extend({
+ maxResults: config.maxResults,
+ summarize: true,
+ incrementalResults: false
+ }, provenance)
+ }
+ };
- // initialize the table view
- initDetailsDialog();
- initProvenanceQueryDialog();
- initProvenanceTable(isClustered, self);
- initSearchDialog(isClustered, self).done(function () {
- deferred.resolve();
- }).fail(failure);
- }).promise();
- },
+ // submit the provenance request
+ return $.ajax({
+ type: 'POST',
+ url: config.urls.provenance,
+ data: JSON.stringify(provenanceEntity),
+ dataType: 'json',
+ contentType: 'application/json'
+ }).fail(errorHandler.handleAjaxError);
+ };
/**
- * Update the size of the grid based on its container's current size.
+ * Gets the results from the provenance query for the specified id.
+ *
+ * @param {object} provenance
+ * @returns {deferred}
*/
- resetTableSize: function () {
- var provenanceGrid = $('#provenance-table').data('gridInstance');
- if (nf.Common.isDefinedAndNotNull(provenanceGrid)) {
- provenanceGrid.resizeCanvas();
+ var getProvenance = function (provenance) {
+ var url = provenance.uri;
+ if (common.isDefinedAndNotNull(provenance.request.clusterNodeId)) {
+ url += '?' + $.param({
+ clusterNodeId: provenance.request.clusterNodeId,
+ summarize: true,
+ incrementalResults: false
+ });
+ } else {
+ url += '?' + $.param({
+ summarize: true,
+ incrementalResults: false
+ });
}
- },
+
+ return $.ajax({
+ type: 'GET',
+ url: url,
+ dataType: 'json'
+ }).fail(errorHandler.handleAjaxError);
+ };
/**
- * Updates the value of the specified progress bar.
+ * Cancels the specified provenance query.
*
- * @param {jQuery} progressBar
- * @param {integer} value
- * @returns {undefined}
+ * @param {object} provenance
+ * @return {deferred}
*/
- updateProgress: function (progressBar, value) {
- // remove existing labels
- progressBar.find('div.progress-label').remove();
- progressBar.find('md-progress-linear').remove();
+ var cancelProvenance = function (provenance) {
+ var url = provenance.uri;
+ if (common.isDefinedAndNotNull(provenance.request.clusterNodeId)) {
+ url += '?' + $.param({
+ clusterNodeId: provenance.request.clusterNodeId
+ });
+ }
- // update the progress bar
- var label = $('<div class="progress-label"></div>').text(value + '%');
- (nf.ng.Bridge.injector.get('$compile')($('<md-progress-linear ng-cloak ng-value="' + value + '" class="md-hue-2" md-mode="determinate" aria-label="Progress"></md-progress-linear>'))(nf.ng.Bridge.rootScope)).appendTo(progressBar);
- progressBar.append(label);
- },
+ return $.ajax({
+ type: 'DELETE',
+ url: url,
+ dataType: 'json'
+ }).fail(errorHandler.handleAjaxError);
+ };
/**
- * Loads the provenance table with events according to the specified optional
- * query. If not query is specified or it is empty, the most recent entries will
- * be returned.
+ * Checks the results of the specified provenance.
*
- * @param {object} query
+ * @param {object} provenance
*/
- loadProvenanceTable: function (query) {
- var self = this;
- var provenanceProgress = $('#provenance-percent-complete');
-
- // add support to cancel outstanding requests - when the button is pressed we
- // could be in one of two stages, 1) waiting to GET the status or 2)
- // in the process of GETting the status. Handle both cases by cancelling
- // the setTimeout (1) and by setting a flag to indicate that a request has
- // been request so we can ignore the results (2).
-
- var cancelled = false;
- var provenance = null;
- var provenanceTimer = null;
-
- // update the progress bar value
- self.updateProgress(provenanceProgress, 0);
-
- // show the 'searching...' dialog
- $('#provenance-query-dialog').modal('setButtonModel', [{
- buttonText: 'Cancel',
- color: {
- base: '#E3E8EB',
- hover: '#C7D2D7',
- text: '#004849'
- },
- handler: {
- click: function () {
- cancelled = true;
+ var loadProvenanceResults = function (provenance, provenanceTableCtrl) {
+ var provenanceRequest = provenance.request;
+ var provenanceResults = provenance.results;
- // we are waiting for the next poll attempt
- if (provenanceTimer !== null) {
- // cancel it
- clearTimeout(provenanceTimer);
+ // ensure there are groups specified
+ if (common.isDefinedAndNotNull(provenanceResults.provenanceEvents)) {
+ var provenanceTable = $('#provenance-table').data('gridInstance');
+ var provenanceData = provenanceTable.getData();
- // cancel the provenance
- closeDialog();
- }
+ // set the items
+ provenanceData.setItems(provenanceResults.provenanceEvents);
+ provenanceData.reSort();
+ provenanceTable.invalidate();
+
+ // update the stats last refreshed timestamp
+ $('#provenance-last-refreshed').text(provenanceResults.generated);
+
+ // update the oldest event available
+ $('#oldest-event').html(common.formatValue(provenanceResults.oldestEvent));
+
+ // record the server offset
+ provenanceTableCtrl.serverTimeOffset = provenanceResults.timeOffset;
+
+ // determines if the specified query is blank (no search terms, start or end date)
+ var isBlankQuery = function (query) {
+ return common.isUndefinedOrNull(query.startDate) && common.isUndefinedOrNull(query.endDate) && $.isEmptyObject(query.searchTerms);
+ };
+
+ // update the filter message based on the request
+ if (isBlankQuery(provenanceRequest)) {
+ var message = 'Showing the most recent ';
+ if (provenanceResults.totalCount >= config.maxResults) {
+ message += (common.formatInteger(config.maxResults) + ' of ' + provenanceResults.total + ' events, please refine the search.');
+ } else {
+ message += ('events.');
+ }
+ $('#provenance-query-message').text(message);
+ $('#clear-provenance-search').hide();
+ } else {
+ var message = 'Showing ';
+ if (provenanceResults.totalCount >= config.maxResults) {
+ message += (common.formatInteger(config.maxResults) + ' of ' + provenanceResults.total + ' events that match the specified query, please refine the search.');
+ } else {
+ message += ('the events that match the specified query.');
}
+ $('#provenance-query-message').text(message);
+ $('#clear-provenance-search').show();
}
- }]).modal('show');
-
- // -----------------------------
- // determine the provenance query
- // -----------------------------
-
- // handle the specified query appropriately
- if (nf.Common.isDefinedAndNotNull(query)) {
- // store the last query performed
- cachedQuery = query;
- } else if (!$.isEmptyObject(cachedQuery)) {
- // use the last query performed
- query = cachedQuery;
+
+ // update the total number of events
+ $('#total-events').text(common.formatInteger(provenanceResults.provenanceEvents.length));
} else {
- // don't use a query
- query = {};
+ $('#total-events').text('0');
}
+ };
- // closes the searching dialog and cancels the query on the server
- var closeDialog = function () {
- // cancel the provenance results since we've successfully processed the results
- if (nf.Common.isDefinedAndNotNull(provenance)) {
- cancelProvenance(provenance);
+ /**
+ * Goes to the specified component if possible.
+ *
+ * @argument {object} item The event it
+ */
+ var goTo = function (item) {
+ // ensure the component is still present in the flow
+ if (common.isDefinedAndNotNull(item.groupId)) {
+ // only attempt this if we're within a frame
+ if (top !== window) {
+ // and our parent has canvas utils and shell defined
+ if (common.isDefinedAndNotNull(parent.nf) && common.isDefinedAndNotNull(parent.nf.CanvasUtils) && common.isDefinedAndNotNull(parent.nf.Shell)) {
+ parent.nf.CanvasUtils.showComponent(item.groupId, item.componentId);
+ parent.$('#shell-close-button').click();
+ }
}
+ }
+ };
- // close the dialog
- $('#provenance-query-dialog').modal('hide');
- };
+ function ProvenanceTableCtrl() {
- // polls the server for the status of the provenance
- var pollProvenance = function () {
- getProvenance(provenance).done(function (response) {
- // update the provenance
- provenance = response.provenance;
+ /**
- // process the provenance
- processProvenanceResponse();
- }).fail(closeDialog);
- };
+ * The server time offset
+ */
+ this.serverTimeOffset = null;
+ }
+
+ ProvenanceTableCtrl.prototype = {
+ constructor: ProvenanceTableCtrl,
+
+ /**
+ * Initializes the provenance table. Returns a deferred that will indicate when/if the table has initialized successfully.
+ *
+ * @param {boolean} isClustered Whether or not this instance is clustered
+ */
+ init: function (isClustered) {
+ var provenanceTableCtrl = this;
+ return $.Deferred(function (deferred) {
+ // handles init failure
+ var failure = function (xhr, status, error) {
+ deferred.reject();
+ errorHandler.handleAjaxError(xhr, status, error);
+ };
+
+ // initialize the lineage view
+ provenanceLineageCtrl.init();
+
+ // initialize the table view
+ initDetailsDialog();
+ initProvenanceQueryDialog();
+ initProvenanceTable(isClustered, provenanceTableCtrl);
+ initSearchDialog(isClustered, provenanceTableCtrl).done(function () {
+ deferred.resolve();
+ }).fail(failure);
+
<TRUNCATED>