NIFI-3803 - Allow use of up/down arrow keys...

...during selection in Add Processor dialog

* Added navigation logic to both Add Processor and Add CS dialogs.
* No extending to the SlickGrid library done.
* Ported the new functionality to the Add Reporting Task dialog.
* Mimicked SlickGrid's PageUp/Down behavior.
* This closes #2170
This commit is contained in:
yuri1969 2017-09-18 22:58:59 +02:00 committed by Matt Gilman
parent ea2c91f9d0
commit c29ee4a6fa
No known key found for this signature in database
GPG Key ID: DF61EC19432AEE37
6 changed files with 194 additions and 40 deletions

View File

@ -475,6 +475,7 @@
<include>${staging.dir}/js/nf/canvas/nf-draggable.js</include>
<include>${staging.dir}/js/nf/canvas/nf-connectable.js</include>
<include>${staging.dir}/js/nf/canvas/nf-graph.js</include>
<include>${staging.dir}/js/nf/nf-filtered-dialog-common.js</include>
<include>${staging.dir}/js/nf/nf-status-history.js</include>
<include>${staging.dir}/js/nf/canvas/nf-queue-listing.js</include>
<include>${staging.dir}/js/nf/canvas/nf-policy-management.js</include>

View File

@ -57,6 +57,7 @@ nf.canvas.script.tags=<script type="text/javascript" src="js/nf/nf-ng-bridge.js?
<script type="text/javascript" src="js/nf/canvas/nf-draggable.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-connectable.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-graph.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-filtered-dialog-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-status-history.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-queue-listing.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-policy-management.js?${project.version}"></script>\n\

View File

@ -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()
}
};

View File

@ -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

View File

@ -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

View File

@ -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;
}));