mirror of https://github.com/apache/nifi.git
NIFI-820:
- Creating a context menu item for accessing provenance directly for a selected component.
This commit is contained in:
parent
26edab3185
commit
f8c3377c84
|
@ -15,7 +15,9 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
--%>
|
--%>
|
||||||
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
<div id="provenance">
|
<div id="provenance">
|
||||||
|
<span id="intial-component-query" class="hidden"><c:out value="${param.componentId}"/></span>
|
||||||
<span id="nifi-controller-uri" class="hidden"></span>
|
<span id="nifi-controller-uri" class="hidden"></span>
|
||||||
<span id="nifi-content-viewer-url" class="hidden"></span>
|
<span id="nifi-content-viewer-url" class="hidden"></span>
|
||||||
<div id="provenance-header-and-filter">
|
<div id="provenance-header-and-filter">
|
||||||
|
|
|
@ -57,10 +57,11 @@ div.context-menu-item.hover {
|
||||||
color: #027fd2;
|
color: #027fd2;
|
||||||
}
|
}
|
||||||
|
|
||||||
img.context-menu-item-img {
|
.context-menu-item-img {
|
||||||
float: left;
|
float: left;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.context-menu-item-text {
|
div.context-menu-item-text {
|
||||||
|
@ -72,6 +73,10 @@ div.context-menu-item-text {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.context-menu-provenance {
|
||||||
|
background-position: top left;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
General Styles
|
General Styles
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -426,6 +426,22 @@ nf.Actions = (function () {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens provenance with the component in the specified selection.
|
||||||
|
*
|
||||||
|
* @argument {selection} selection The selection
|
||||||
|
*/
|
||||||
|
openProvenance: function (selection) {
|
||||||
|
if (selection.size() === 1) {
|
||||||
|
var selectionData = selection.datum();
|
||||||
|
|
||||||
|
// open the provenance page with the specified component
|
||||||
|
nf.Shell.showPage('provenance?' + $.param({
|
||||||
|
componentId: selectionData.component.id
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the components in the specified selection.
|
* Starts the components in the specified selection.
|
||||||
*
|
*
|
||||||
|
|
|
@ -245,6 +245,20 @@ nf.ContextMenu = (function () {
|
||||||
return nf.CanvasUtils.isProcessGroup(selection);
|
return nf.CanvasUtils.isProcessGroup(selection);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the current selection could have provenance.
|
||||||
|
*
|
||||||
|
* @param {selection} selection
|
||||||
|
*/
|
||||||
|
var canAccessProvenance = function (selection) {
|
||||||
|
// ensure the correct number of components are selected
|
||||||
|
if (selection.size() !== 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !nf.CanvasUtils.isConnection(selection) && !nf.CanvasUtils.isProcessGroup(selection) && !nf.CanvasUtils.isRemoteProcessGroup(selection) && nf.Common.canAccessProvenance();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the current selection is a remote process group.
|
* Determines whether the current selection is a remote process group.
|
||||||
*
|
*
|
||||||
|
@ -313,7 +327,12 @@ nf.ContextMenu = (function () {
|
||||||
$(this).removeClass('hover');
|
$(this).removeClass('hover');
|
||||||
}).appendTo(contextMenu);
|
}).appendTo(contextMenu);
|
||||||
|
|
||||||
$('<img class="context-menu-item-img"></img>').attr('src', item['img']).appendTo(menuItem);
|
// create the img and conditionally add the style
|
||||||
|
var img = $('<div class="context-menu-item-img"></div>').css('background-image', 'url(' + item['img'] + ')').appendTo(menuItem);
|
||||||
|
if (nf.Common.isDefinedAndNotNull(item['imgStyle'])) {
|
||||||
|
img.addClass(item['imgStyle']);
|
||||||
|
}
|
||||||
|
|
||||||
$('<div class="context-menu-item-text"></div>').text(item['text']).appendTo(menuItem);
|
$('<div class="context-menu-item-text"></div>').text(item['text']).appendTo(menuItem);
|
||||||
$('<div class="clear"></div>').appendTo(menuItem);
|
$('<div class="clear"></div>').appendTo(menuItem);
|
||||||
}
|
}
|
||||||
|
@ -360,6 +379,7 @@ nf.ContextMenu = (function () {
|
||||||
{condition: canStartTransmission, menuItem: {img: 'images/iconTransmissionActive.png', text: 'Enable transmission', action: 'enableTransmission'}},
|
{condition: canStartTransmission, menuItem: {img: 'images/iconTransmissionActive.png', text: 'Enable transmission', action: 'enableTransmission'}},
|
||||||
{condition: canStopTransmission, menuItem: {img: 'images/iconTransmissionInactive.png', text: 'Disable transmission', action: 'disableTransmission'}},
|
{condition: canStopTransmission, menuItem: {img: 'images/iconTransmissionInactive.png', text: 'Disable transmission', action: 'disableTransmission'}},
|
||||||
{condition: supportsStats, menuItem: {img: 'images/iconChart.png', text: 'Stats', action: 'showStats'}},
|
{condition: supportsStats, menuItem: {img: 'images/iconChart.png', text: 'Stats', action: 'showStats'}},
|
||||||
|
{condition: canAccessProvenance, menuItem: {img: 'images/iconProvenance.png', imgStyle: 'context-menu-provenance', text: 'Data provenance', action: 'openProvenance'}},
|
||||||
{condition: canMoveToFront, menuItem: {img: 'images/iconToFront.png', text: 'Bring to front', action: 'toFront'}},
|
{condition: canMoveToFront, menuItem: {img: 'images/iconToFront.png', text: 'Bring to front', action: 'toFront'}},
|
||||||
{condition: isConnection, menuItem: {img: 'images/iconGoTo.png', text: 'Go to source', action: 'showSource'}},
|
{condition: isConnection, menuItem: {img: 'images/iconGoTo.png', text: 'Go to source', action: 'showSource'}},
|
||||||
{condition: isConnection, menuItem: {img: 'images/iconGoTo.png', text: 'Go to destination', action: 'showDestination'}},
|
{condition: isConnection, menuItem: {img: 'images/iconGoTo.png', text: 'Go to destination', action: 'showDestination'}},
|
||||||
|
@ -416,6 +436,7 @@ nf.ContextMenu = (function () {
|
||||||
|
|
||||||
addMenuItem(contextMenu, {
|
addMenuItem(contextMenu, {
|
||||||
img: menuItem.img,
|
img: menuItem.img,
|
||||||
|
imgStyle: menuItem.imgStyle,
|
||||||
text: menuItem.text,
|
text: menuItem.text,
|
||||||
click: function (evt) {
|
click: function (evt) {
|
||||||
executeAction(menuItem.action, selection, evt);
|
executeAction(menuItem.action, selection, evt);
|
||||||
|
|
|
@ -258,19 +258,6 @@ nf.ProvenanceTable = (function () {
|
||||||
* @param {boolean} isClustered Whether or not this NiFi clustered
|
* @param {boolean} isClustered Whether or not this NiFi clustered
|
||||||
*/
|
*/
|
||||||
var initSearchDialog = function (isClustered) {
|
var initSearchDialog = function (isClustered) {
|
||||||
$.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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// configure the start and end date picker
|
// configure the start and end date picker
|
||||||
$('#provenance-search-start-date, #provenance-search-end-date').datepicker({
|
$('#provenance-search-start-date, #provenance-search-end-date').datepicker({
|
||||||
showAnim: '',
|
showAnim: '',
|
||||||
|
@ -402,6 +389,19 @@ nf.ProvenanceTable = (function () {
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -441,6 +441,11 @@ nf.ProvenanceTable = (function () {
|
||||||
$('<div class="searchable-field-value"><input type="text" class="searchable-field-input"/></div>').appendTo(searchableField);
|
$('<div class="searchable-field-value"><input type="text" class="searchable-field-input"/></div>').appendTo(searchableField);
|
||||||
$('<div class="clear"></div>').appendTo(searchableField);
|
$('<div class="clear"></div>').appendTo(searchableField);
|
||||||
|
|
||||||
|
// make the component id accessible for populating
|
||||||
|
if (field.id === 'ProcessorID') {
|
||||||
|
searchableField.find('input').addClass('searchable-component-id');
|
||||||
|
}
|
||||||
|
|
||||||
// ensure the no searchable fields message is hidden
|
// ensure the no searchable fields message is hidden
|
||||||
$('#no-searchable-fields').hide();
|
$('#no-searchable-fields').hide();
|
||||||
};
|
};
|
||||||
|
@ -949,12 +954,23 @@ nf.ProvenanceTable = (function () {
|
||||||
* @param {boolean} isClustered Whether or not this instance is clustered
|
* @param {boolean} isClustered Whether or not this instance is clustered
|
||||||
*/
|
*/
|
||||||
init: function (isClustered) {
|
init: function (isClustered) {
|
||||||
return loadLineageCapabilities().done(function () {
|
return $.Deferred(function (deferred) {
|
||||||
initDetailsDialog();
|
// handles init failure
|
||||||
initProvenanceQueryDialog();
|
var failure = function (xhr, status, error) {
|
||||||
initSearchDialog(isClustered);
|
deferred.reject();
|
||||||
initProvenanceTable(isClustered);
|
nf.Common.handleAjaxError(xhr, status, error);
|
||||||
}).fail(nf.Common.handleAjaxError);
|
};
|
||||||
|
|
||||||
|
// load the lineage capabilities
|
||||||
|
loadLineageCapabilities().done(function () {
|
||||||
|
initDetailsDialog();
|
||||||
|
initProvenanceQueryDialog();
|
||||||
|
initProvenanceTable(isClustered);
|
||||||
|
initSearchDialog(isClustered).done(function () {
|
||||||
|
deferred.resolve();
|
||||||
|
}).fail(failure);
|
||||||
|
}).fail(failure);
|
||||||
|
}).promise();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -178,8 +178,22 @@ nf.Provenance = (function () {
|
||||||
$.when(loadControllerConfig(), loadAuthorities(), detectedCluster()).done(function () {
|
$.when(loadControllerConfig(), loadAuthorities(), detectedCluster()).done(function () {
|
||||||
// create the provenance table
|
// create the provenance table
|
||||||
nf.ProvenanceTable.init(isClustered).done(function () {
|
nf.ProvenanceTable.init(isClustered).done(function () {
|
||||||
|
var search;
|
||||||
|
|
||||||
|
// look for a processor id in the query search
|
||||||
|
var initialComponentId = $('#intial-component-query').text();
|
||||||
|
if ($.trim(initialComponentId) !== '') {
|
||||||
|
// populate initial search component
|
||||||
|
$('input.searchable-component-id').val(initialComponentId);
|
||||||
|
|
||||||
|
// build the search criteria
|
||||||
|
search = {
|
||||||
|
'search[ProcessorID]': initialComponentId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// load the provenance table
|
// load the provenance table
|
||||||
nf.ProvenanceTable.loadProvenanceTable();
|
nf.ProvenanceTable.loadProvenanceTable(search);
|
||||||
|
|
||||||
// once the table is initialized, finish initializing the page
|
// once the table is initialized, finish initializing the page
|
||||||
initializeProvenancePage().done(function () {
|
initializeProvenancePage().done(function () {
|
||||||
|
|
Loading…
Reference in New Issue