diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
index c227c9b7e7..4f2cc8ebce 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
@@ -475,6 +475,7 @@
${staging.dir}/js/nf/canvas/nf-draggable.js
${staging.dir}/js/nf/canvas/nf-connectable.js
${staging.dir}/js/nf/canvas/nf-graph.js
+ ${staging.dir}/js/nf/nf-filtered-dialog-common.js
${staging.dir}/js/nf/nf-status-history.js
${staging.dir}/js/nf/canvas/nf-queue-listing.js
${staging.dir}/js/nf/canvas/nf-policy-management.js
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
index 9b04ecec9e..413c6c2f83 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties
@@ -57,6 +57,7 @@ nf.canvas.script.tags=\n\
\n\
\n\
+\n\
\n\
\n\
\n\
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js
index c9f80f3862..3af00da597 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js
@@ -26,10 +26,11 @@
'nf.Graph',
'nf.CanvasUtils',
'nf.ErrorHandler',
+ 'nf.FilteredDialogCommon',
'nf.Dialog',
'nf.Common'],
- function ($, Slick, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfDialog, nfCommon) {
- return (nf.ng.ProcessorComponent = factory($, Slick, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfDialog, nfCommon));
+ function ($, Slick, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfFilteredDialogCommon, nfDialog, nfCommon) {
+ return (nf.ng.ProcessorComponent = factory($, Slick, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfFilteredDialogCommon, nfDialog, nfCommon));
});
} else if (typeof exports === 'object' && typeof module === 'object') {
module.exports = (nf.ng.ProcessorComponent =
@@ -40,6 +41,7 @@
require('nf.Graph'),
require('nf.CanvasUtils'),
require('nf.ErrorHandler'),
+ require('nf.FilteredDialogCommon'),
require('nf.Dialog'),
require('nf.Common')));
} else {
@@ -50,10 +52,11 @@
root.nf.Graph,
root.nf.CanvasUtils,
root.nf.ErrorHandler,
+ root.nf.FilteredDialogCommon,
root.nf.Dialog,
root.nf.Common);
}
-}(this, function ($, Slick, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfDialog, nfCommon) {
+}(this, function ($, Slick, nfClient, nfBirdseye, nfGraph, nfCanvasUtils, nfErrorHandler, nfFilteredDialogCommon, nfDialog, nfCommon) {
'use strict';
return function (serviceProvider) {
@@ -81,7 +84,9 @@
// update the selection if possible
if (processorTypesData.getLength() > 0) {
- processorTypesGrid.setSelectedRows([0]);
+ nfFilteredDialogCommon.choseFirstRow(processorTypesGrid);
+ // make the first row visible
+ processorTypesGrid.scrollRowToTop(0);
}
}
};
@@ -722,9 +727,17 @@
// show the dialog
this.modal.show();
+ var navigationKeys = [$.ui.keyCode.UP, $.ui.keyCode.PAGE_UP, $.ui.keyCode.DOWN, $.ui.keyCode.PAGE_DOWN];
+
// setup the filter
- $('#processor-type-filter').focus().off('keyup').on('keyup', function (e) {
+ $('#processor-type-filter').off('keyup').on('keyup', function (e) {
var code = e.keyCode ? e.keyCode : e.which;
+
+ // ignore navigation keys
+ if ($.inArray(code, navigationKeys) !== -1) {
+ return;
+ }
+
if (code === $.ui.keyCode.ENTER) {
var selected = grid.getSelectedRows();
@@ -740,13 +753,19 @@
}
});
+ // setup row navigation
+ nfFilteredDialogCommon.addKeydownListener('#processor-type-filter', grid, dataview);
+
// adjust the grid canvas now that its been rendered
grid.resizeCanvas();
// auto select the first row if possible
if (dataview.getLength() > 0) {
- grid.setSelectedRows([0]);
+ nfFilteredDialogCommon.choseFirstRow(grid);
}
+
+ // set the initial focus
+ $('#processor-type-filter').focus()
}
};
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
index 86bec682b4..59041c4769 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-services.js
@@ -27,6 +27,7 @@
'nf.ProcessGroupConfiguration',
'nf.CanvasUtils',
'nf.ErrorHandler',
+ 'nf.FilteredDialogCommon',
'nf.Dialog',
'nf.Common',
'nf.ControllerService',
@@ -35,8 +36,8 @@
'nf.ComponentState',
'nf.ComponentVersion',
'nf.ng.Bridge'],
- function ($, d3, Slick, nfClient, nfShell, nfProcessGroupConfiguration, nfCanvasUtils, nfErrorHandler, nfDialog, nfCommon, nfControllerService, nfProcessGroup, nfPolicyManagement, nfComponentState, nfComponentVersion, nfNgBridge) {
- return (nf.ControllerServices = factory($, d3, Slick, nfClient, nfShell, nfProcessGroupConfiguration, nfCanvasUtils, nfErrorHandler, nfDialog, nfCommon, nfControllerService, nfProcessGroup, nfPolicyManagement, nfComponentState, nfComponentVersion, nfNgBridge));
+ function ($, d3, Slick, nfClient, nfShell, nfProcessGroupConfiguration, nfCanvasUtils, nfErrorHandler, nfFilteredDialogCommon, nfDialog, nfCommon, nfControllerService, nfProcessGroup, nfPolicyManagement, nfComponentState, nfComponentVersion, nfNgBridge) {
+ return (nf.ControllerServices = factory($, d3, Slick, nfClient, nfShell, nfProcessGroupConfiguration, nfCanvasUtils, nfErrorHandler, nfFilteredDialogCommon, nfDialog, nfCommon, nfControllerService, nfProcessGroup, nfPolicyManagement, nfComponentState, nfComponentVersion, nfNgBridge));
});
} else if (typeof exports === 'object' && typeof module === 'object') {
module.exports = (nf.ControllerServices =
@@ -48,6 +49,7 @@
require('nf.ProcessGroupConfiguration'),
require('nf.CanvasUtils'),
require('nf.ErrorHandler'),
+ require('nf.FilteredDialogCommon'),
require('nf.Dialog'),
require('nf.Common'),
require('nf.ControllerService'),
@@ -65,6 +67,7 @@
root.nf.ProcessGroupConfiguration,
root.nf.CanvasUtils,
root.nf.ErrorHandler,
+ root.nf.FilteredDialogCommon,
root.nf.Dialog,
root.nf.Common,
root.nf.ControllerService,
@@ -74,7 +77,7 @@
root.nf.ComponentVersion,
root.nf.ng.Bridge);
}
-}(this, function ($, d3, Slick, nfClient, nfShell, nfProcessGroupConfiguration, nfCanvasUtils, nfErrorHandler, nfDialog, nfCommon, nfControllerService, nfProcessGroup, nfPolicyManagement, nfComponentState, nfComponentVersion, nfNgBridge) {
+}(this, function ($, d3, Slick, nfClient, nfShell, nfProcessGroupConfiguration, nfCanvasUtils, nfErrorHandler, nfFilteredDialogCommon, nfDialog, nfCommon, nfControllerService, nfProcessGroup, nfPolicyManagement, nfComponentState, nfComponentVersion, nfNgBridge) {
'use strict';
var dblClick = null;
@@ -137,7 +140,9 @@
// update the selection if possible
if (controllerServiceTypesData.getLength() > 0) {
- controllerServiceTypesGrid.setSelectedRows([0]);
+ nfFilteredDialogCommon.choseFirstRow(controllerServiceTypesGrid);
+ // make the first row visible
+ controllerServiceTypesGrid.scrollRowToTop(0);
}
}
};
@@ -324,7 +329,7 @@
// select the new controller service
var row = controllerServicesData.getRowById(controllerServiceEntity.id);
- controllerServicesGrid.setSelectedRows([row]);
+ nfFilteredDialogCommon.choseRow(controllerServicesGrid, row);
controllerServicesGrid.scrollRowIntoView(row);
}).fail(nfErrorHandler.handleAjaxError);
@@ -1191,9 +1196,17 @@
var grid = $('#controller-service-types-table').data('gridInstance');
var dataview = grid.getData();
+ var navigationKeys = [$.ui.keyCode.UP, $.ui.keyCode.PAGE_UP, $.ui.keyCode.DOWN, $.ui.keyCode.PAGE_DOWN];
+
// update the keyhandler
$('#controller-service-type-filter').off('keyup').on('keyup', function (e) {
var code = e.keyCode ? e.keyCode : e.which;
+
+ // ignore navigation keys
+ if ($.inArray(code, navigationKeys) !== -1) {
+ return;
+ }
+
if (code === $.ui.keyCode.ENTER) {
var selected = grid.getSelectedRows();
@@ -1209,6 +1222,9 @@
}
});
+ // setup row navigation
+ nfFilteredDialogCommon.addKeydownListener('#controller-service-type-filter', grid, dataview);
+
// update the button model and show the dialog
$('#new-controller-service-dialog').modal('setButtonModel', [{
buttonText: 'Add',
@@ -1267,7 +1283,7 @@
// auto select the first row if possible
if (dataview.getLength() > 0) {
- grid.setSelectedRows([0]);
+ nfFilteredDialogCommon.choseFirstRow(grid);
}
// set the initial focus
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
index ee2dfda9da..4da6fc65c3 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
@@ -28,13 +28,14 @@
'nf.CanvasUtils',
'nf.ControllerServices',
'nf.ErrorHandler',
+ 'nf.FilteredDialogCommon',
'nf.ReportingTask',
'nf.Shell',
'nf.ComponentState',
'nf.ComponentVersion',
'nf.PolicyManagement'],
- function ($, Slick, d3, nfClient, nfDialog, nfCommon, nfCanvasUtils, nfControllerServices, nfErrorHandler, nfReportingTask, nfShell, nfComponentState, nfComponentVersion, nfPolicyManagement) {
- return (nf.Settings = factory($, Slick, d3, nfClient, nfDialog, nfCommon, nfCanvasUtils, nfControllerServices, nfErrorHandler, nfReportingTask, nfShell, nfComponentState, nfComponentVersion, nfPolicyManagement));
+ function ($, Slick, d3, nfClient, nfDialog, nfCommon, nfCanvasUtils, nfControllerServices, nfErrorHandler, nfFilteredDialogCommon, nfReportingTask, nfShell, nfComponentState, nfComponentVersion, nfPolicyManagement) {
+ return (nf.Settings = factory($, Slick, d3, nfClient, nfDialog, nfCommon, nfCanvasUtils, nfControllerServices, nfErrorHandler, nfFilteredDialogCommon, nfReportingTask, nfShell, nfComponentState, nfComponentVersion, nfPolicyManagement));
});
} else if (typeof exports === 'object' && typeof module === 'object') {
module.exports = (nf.Settings =
@@ -47,6 +48,7 @@
require('nf.CanvasUtils'),
require('nf.ControllerServices'),
require('nf.ErrorHandler'),
+ require('nf.FilteredDialogCommon'),
require('nf.ReportingTask'),
require('nf.Shell'),
require('nf.ComponentState'),
@@ -62,13 +64,14 @@
root.nf.CanvasUtils,
root.nf.ControllerServices,
root.nf.ErrorHandler,
+ root.nf.FilteredDialogCommon,
root.nf.ReportingTask,
root.nf.Shell,
root.nf.ComponentState,
root.nf.ComponentVersion,
root.nf.PolicyManagement);
}
-}(this, function ($, Slick, d3, nfClient, nfDialog, nfCommon, nfCanvasUtils, nfControllerServices, nfErrorHandler, nfReportingTask, nfShell, nfComponentState, nfComponentVersion, nfPolicyManagement) {
+}(this, function ($, Slick, d3, nfClient, nfDialog, nfCommon, nfCanvasUtils, nfControllerServices, nfErrorHandler, nfFilteredDialogCommon, nfReportingTask, nfShell, nfComponentState, nfComponentVersion, nfPolicyManagement) {
'use strict';
@@ -321,7 +324,7 @@
// update the selection if possible
if (reportingTaskTypesData.getLength() > 0) {
- reportingTaskTypesGrid.setSelectedRows([0]);
+ nfFilteredDialogCommon.choseFirstRow(reportingTaskTypesGrid);
}
}
};
@@ -451,7 +454,7 @@
// select the new reporting task
var row = reportingTaskData.getRowById(reportingTaskEntity.id);
- reportingTaskGrid.setSelectedRows([row]);
+ nfFilteredDialogCommon.choseRow(reportingTaskGrid, row);
reportingTaskGrid.scrollRowIntoView(row);
}).fail(nfErrorHandler.handleAjaxError);
@@ -465,26 +468,6 @@
* Initializes the new reporting task dialog.
*/
var initNewReportingTaskDialog = function () {
- // define the function for filtering the list
- $('#reporting-task-type-filter').on('keyup', function (e) {
- var code = e.keyCode ? e.keyCode : e.which;
- if (code === $.ui.keyCode.ENTER) {
- // get the grid reference
- var grid = $('#reporting-task-types-table').data('gridInstance');
- var selected = grid.getSelectedRows();
-
- if (selected.length > 0) {
- // grid configured with multi-select = false
- var item = grid.getDataItem(selected[0]);
- if (isSelectable(item)) {
- addSelectedReportingTask();
- }
- }
- } else {
- applyReportingTaskTypeFilter();
- }
- });
-
// initialize the reporting task type table
var reportingTaskTypesColumns = [
{
@@ -698,6 +681,35 @@
});
}).fail(nfErrorHandler.handleAjaxError);
+ var navigationKeys = [$.ui.keyCode.UP, $.ui.keyCode.PAGE_UP, $.ui.keyCode.DOWN, $.ui.keyCode.PAGE_DOWN];
+
+ // define the function for filtering the list
+ $('#reporting-task-type-filter').off('keyup').on('keyup', function (e) {
+ var code = e.keyCode ? e.keyCode : e.which;
+
+ // ignore navigation keys
+ if ($.inArray(code, navigationKeys) !== -1) {
+ return;
+ }
+
+ if (code === $.ui.keyCode.ENTER) {
+ var selected = reportingTaskTypesGrid.getSelectedRows();
+
+ if (selected.length > 0) {
+ // grid configured with multi-select = false
+ var item = reportingTaskTypesGrid.getDataItem(selected[0]);
+ if (isSelectable(item)) {
+ addSelectedReportingTask();
+ }
+ }
+ } else {
+ applyReportingTaskTypeFilter();
+ }
+ });
+
+ // setup row navigation
+ nfFilteredDialogCommon.addKeydownListener('#reporting-task-type-filter', reportingTaskTypesGrid, reportingTaskTypesGrid.getData());
+
// initialize the reporting task dialog
$('#new-reporting-task-dialog').modal({
scrollableContentStyle: 'scrollable',
@@ -1297,7 +1309,7 @@
// select the first row if possible
if (reportingTaskTypesData.getLength() > 0) {
- reportingTaskTypesGrid.setSelectedRows([0]);
+ nfFilteredDialogCommon.choseFirstRow(reportingTaskTypesGrid);
}
}
@@ -1349,7 +1361,7 @@
// select the desired service
var row = controllerServiceData.getRowById(controllerServiceId);
- controllerServiceGrid.setSelectedRows([row]);
+ nfFilteredDialogCommon.choseRow(controllerServiceGrid, row);
controllerServiceGrid.scrollRowIntoView(row);
// select the controller services tab
@@ -1367,7 +1379,7 @@
// select the desired service
var row = reportingTaskData.getRowById(reportingTaskId);
- reportingTaskGrid.setSelectedRows([row]);
+ nfFilteredDialogCommon.choseRow(reportingTaskGrid, row);
reportingTaskGrid.scrollRowIntoView(row);
// select the controller services tab
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-filtered-dialog-common.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-filtered-dialog-common.js
new file mode 100644
index 0000000000..d4194cf7e6
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-filtered-dialog-common.js
@@ -0,0 +1,105 @@
+/*
+ * 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 define, module, require, exports */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], function ($) {
+ return (nf.FilteredDialogCommon = factory($));
+ });
+ } else if (typeof exports === 'object' && typeof module === 'object') {
+ module.exports = (nf.FilteredDialogCommon = factory(require('jquery')));
+ } else {
+ nf.FilteredDialogCommon = factory(root.$);
+ }
+}(this, function ($) {
+ 'use strict';
+
+ var nfFilteredDialogCommon = {
+
+ /**
+ * Registers keydown event on dialog's filter input in order to navigate the grid's rows via keyboard arrow keys.
+ *
+ * @argument {string} filter Filter input box selector
+ * @argument {object} grid SlickGrid reference
+ * @argument {object} dataview Current grid dataset
+ */
+ addKeydownListener: function (filter, grid, dataview) {
+ var navigationKeys = [$.ui.keyCode.UP, $.ui.keyCode.PAGE_UP, $.ui.keyCode.DOWN, $.ui.keyCode.PAGE_DOWN];
+
+ // setup the navigation
+ $(filter).off('keydown').on('keydown', function(e) {
+ var code = e.keyCode ? e.keyCode : e.which;
+
+ // nonmodified navigation keys only
+ if ($.inArray(code, navigationKeys) === -1 || e.shiftKey || e.altKey || e.ctrlKey) {
+ return;
+ }
+
+ var selected = grid.getSelectedRows();
+
+ if (selected.length > 0) {
+ if (code === $.ui.keyCode.PAGE_UP) {
+ grid.navigatePageUp();
+ return;
+ }
+ if (code === $.ui.keyCode.PAGE_DOWN) {
+ grid.navigatePageDown();
+ return;
+ }
+
+ // grid multi-select = false
+ var nextIndex = selected[0];
+
+ // get the following/previous row
+ if (code === $.ui.keyCode.UP) {
+ nextIndex = Math.max(nextIndex - 1, 0);
+ } else {
+ nextIndex = Math.min(nextIndex + 1, dataview.getLength() - 1);
+ }
+
+ nfFilteredDialogCommon.choseRow(grid, nextIndex);
+ // ensure the newly selected row is visible
+ grid.scrollRowIntoView(nextIndex, false);
+ }
+ });
+ },
+
+ /**
+ * Selects the first row and activates the first cell within given SlickGrid.
+ *
+ * @argument {object} grid SlickGrid reference
+ */
+ choseFirstRow: function (grid) {
+ nfFilteredDialogCommon.choseRow(grid, 0);
+ },
+
+ /**
+ * Selects given row and activates the first cell in the row within given SlickGrid.
+ *
+ * @argument {object} grid SlickGrid reference
+ * @argument {int} index Row index
+ */
+ choseRow: function (grid, index) {
+ grid.setSelectedRows([index]);
+ grid.setActiveCell(index, 0);
+ }
+ };
+
+ return nfFilteredDialogCommon;
+}));
\ No newline at end of file