From b3990ecdcf0adc17dbcc442a09351e333dd291cf Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Thu, 28 Jan 2016 10:30:16 -0500 Subject: [PATCH] NIFI-1426: - Introducing a universal capture for key events to ensure a consistent behavior throughout the application. - Allowing backspace to remove components from the canvas. - Introducing a more consistent behavior around the escape button. Signed-off-by: Aldrin Piri --- .../src/main/webapp/WEB-INF/jsp/header.jsp | 2 + .../nifi-web/nifi-web-ui/pom.xml | 10 ++ .../filters/bulletin-board.properties | 1 + .../main/resources/filters/canvas.properties | 1 + .../main/resources/filters/cluster.properties | 1 + .../resources/filters/counters.properties | 1 + .../main/resources/filters/history.properties | 1 + .../main/resources/filters/login.properties | 1 + .../resources/filters/provenance.properties | 1 + .../main/resources/filters/summary.properties | 1 + .../resources/filters/templates.properties | 1 + .../main/resources/filters/users.properties | 1 + .../partials/canvas/label-configuration.jsp | 9 +- .../partials/status-history-dialog.jsp | 6 +- .../main/webapp/css/label-configuration.css | 14 +- .../src/main/webapp/css/status-history.css | 4 +- .../webapp/js/jquery/combo/jquery.combo.js | 10 ++ .../webapp/js/jquery/modal/jquery.modal.js | 7 +- .../js/jquery/nfeditor/jquery.nfeditor.js | 13 +- .../propertytable/jquery.propertytable.js | 34 ++++- .../src/main/webapp/js/nf/canvas/nf-canvas.js | 104 ++------------ .../js/nf/canvas/nf-controller-service.js | 2 +- .../js/nf/canvas/nf-label-configuration.js | 91 ++++++------ .../nf/canvas/nf-processor-configuration.js | 2 +- .../webapp/js/nf/canvas/nf-reporting-task.js | 2 +- .../src/main/webapp/js/nf/nf-common.js | 9 -- .../main/webapp/js/nf/nf-processor-details.js | 2 +- .../main/webapp/js/nf/nf-status-history.js | 47 ++++--- .../main/webapp/js/nf/nf-universal-capture.js | 131 ++++++++++++++++++ .../src/main/webapp/WEB-INF/jsp/worksheet.jsp | 1 + .../src/main/webapp/css/main.css | 2 +- .../src/main/webapp/js/application.js | 38 ++++- 32 files changed, 339 insertions(+), 211 deletions(-) create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-universal-capture.js diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/header.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/header.jsp index b847dd5a65..0f6fae3800 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/header.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-content-viewer/src/main/webapp/WEB-INF/jsp/header.jsp @@ -28,6 +28,8 @@ + + \n\ \n\ +\n\ \n\ \n\ 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 43e60f4804..289d94eaa4 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 @@ -16,6 +16,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/resources/filters/cluster.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/cluster.properties index 9327be658a..183ec6a672 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/cluster.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/cluster.properties @@ -15,6 +15,7 @@ nf.cluster.script.tags=\n\ \n\ +\n\ \n\ \n\ \n\ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/counters.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/counters.properties index be22f55a02..cfa7f361dd 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/counters.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/counters.properties @@ -15,6 +15,7 @@ nf.counters.script.tags=\n\ \n\ +\n\ \n\ \n\ \n\ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/history.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/history.properties index 9bbe64086f..0850127586 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/history.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/history.properties @@ -15,6 +15,7 @@ nf.history.script.tags=\n\ \n\ +\n\ \n\ \n\ \n\ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/login.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/login.properties index 28ff4b9270..7a65ac6540 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/login.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/login.properties @@ -14,6 +14,7 @@ # limitations under the License. nf.login.script.tags=\n\ +\n\ \n\ \n\ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/provenance.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/provenance.properties index daa7c43ef4..8d825cb2e9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/provenance.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/provenance.properties @@ -15,6 +15,7 @@ nf.provenance.script.tags=\n\ \n\ +\n\ \n\ \n\ \n\ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/summary.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/summary.properties index 2417adefd7..b7a26bae09 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/summary.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/summary.properties @@ -15,6 +15,7 @@ nf.summary.script.tags=\n\ \n\ +\n\ \n\ \n\ \n\ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/templates.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/templates.properties index 007bd69b54..a9299fc935 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/templates.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/templates.properties @@ -15,6 +15,7 @@ nf.templates.script.tags=\n\ \n\ +\n\ \n\ \n\ \n\ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/users.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/users.properties index 9824a8b55d..160cb49601 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/users.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/users.properties @@ -15,6 +15,7 @@ nf.users.script.tags=\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/WEB-INF/partials/canvas/label-configuration.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/label-configuration.jsp index 768cf9035b..2f15e9914c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/label-configuration.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/label-configuration.jsp @@ -15,8 +15,8 @@ limitations under the License. --%> <%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %> -
-
+
+
Label Value
@@ -30,9 +30,4 @@
-
-
Apply
-
Cancel
-
-
\ No newline at end of file diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/status-history-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/status-history-dialog.jsp index bd0c60f37c..010c7babd9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/status-history-dialog.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/status-history-dialog.jsp @@ -15,7 +15,7 @@ limitations under the License. --%> <%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %> -
+
@@ -30,8 +30,4 @@
-
-
Close
-
-
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/label-configuration.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/label-configuration.css index 30af32abf9..fe8412a7fe 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/label-configuration.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/label-configuration.css @@ -23,11 +23,13 @@ z-index: 1301; display: none; padding: 10px; - border: 3px solid #365C6A; - box-shadow: 4px 4px 6px rgba(0, 0, 0, 0.9); cursor: move; } +#label-configuration-contents { + margin-top: -50px; +} + #label-value { width: 375px; height: 210px; @@ -43,12 +45,4 @@ box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; -} - -#label-configuration-button-container { - position: absolute; - left: 0; - bottom: 0; - right: 0; - padding: 0 8px 10px; } \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/status-history.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/status-history.css index 41018b570b..c17fa15dac 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/status-history.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/status-history.css @@ -20,8 +20,6 @@ display: none; z-index: 1301; padding: 10px; - border: 3px solid #365C6A; - box-shadow: 4px 4px 6px rgba(0, 0, 0, 0.9); cursor: move; } @@ -86,6 +84,7 @@ float: left; margin-left: 2px; margin-bottom: 35px; + margin-top: -50px; } #status-history-chart-container { @@ -111,6 +110,7 @@ padding-top: 8px; padding: 3px; overflow: auto; + margin-top: -50px; } div.status-history-detail { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.js index 1da075c93e..b775d48fcb 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/combo/jquery.combo.js @@ -298,6 +298,16 @@ return this.each(function () { selectOption($(this), option.text, option.value); }); + }, + + /** + * Destroy's the combo. + */ + destroy: function () { + $(this).empty().unbind().removeData(); + + // remove the options if open + $('div.combo-glass-pane').click(); } }; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js index 00b240c38a..c251d35f22 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js @@ -203,11 +203,8 @@ $('#faded-background').show(); } - // show the centered dialog - performing these operation in the - // opposite order one might expect. for some reason, the call to - // center is causeing the graph to flicker in firefox (3.6). displaying - // the dialog container before centering seems to address the issue. - dialog.show().center(); + // center and show the dialog + dialog.center().show(); } }); }, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/nfeditor/jquery.nfeditor.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/nfeditor/jquery.nfeditor.js index 550ed3766c..41353d7c48 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/nfeditor/jquery.nfeditor.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/nfeditor/jquery.nfeditor.js @@ -109,16 +109,12 @@ 'Esc': function (cm) { if (isFunction(options.escape)) { options.escape(); - return; } - return CodeMirror.Pass; }, 'Enter': function (cm) { if (isFunction(options.enter)) { options.enter(); - return; } - return CodeMirror.Pass; } } }); @@ -161,6 +157,15 @@ codeMirror.addClass('modified'); }); + // handle keyHandled to stop event propagation/default as necessary + editor.on('keyHandled', function (cm, name, evt) { + if (name === 'Esc') { + // stop propagation of the escape event + evt.stopImmediatePropagation(); + evt.preventDefault(); + } + }); + // handle sensitive values differently if (sensitive) { code.addClass('sensitive'); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js index de257fa930..b686eb9c05 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js @@ -122,6 +122,10 @@ scope.save(); } else if (e.which === $.ui.keyCode.ESCAPE) { scope.cancel(); + + // prevent further propagation or escape press and prevent default behavior + e.stopImmediatePropagation(); + e.preventDefault(); } }; @@ -459,7 +463,7 @@ var configurationOptions = propertyContainer.data('options'); // create the wrapper - wrapper = $('
').css({ + wrapper = $('
').css({ 'z-index': 1999, 'position': 'absolute', 'background': 'white', @@ -572,6 +576,7 @@ }; this.destroy = function () { + combo.combo('destroy'); wrapper.remove(); }; @@ -630,7 +635,7 @@ */ var showPropertyValue = function (propertyGrid, descriptors, row, cell) { // remove any currently open detail dialogs - nf.Common.removeAllPropertyDetailDialogs(); + nf.UniversalCapture.removeAllPropertyDetailDialogs(); // get the property in question var propertyData = propertyGrid.getData(); @@ -734,7 +739,10 @@ minWidth: 175, minHeight: 100, readOnly: true, - resizable: true + resizable: true, + escape: function () { + cleanUp(); + } }); } else { // prevent dragging over standard components @@ -752,11 +760,17 @@ 'overflow-y': 'auto', 'resize': 'both', 'margin-bottom': '28px' - }).text(property.value).appendTo(wrapper); + }).text(property.value).on('keydown', function (evt) { + if (evt.which === $.ui.keyCode.ESCAPE) { + cleanUp(); + + evt.stopImmediatePropagation(); + evt.preventDefault(); + } + }).appendTo(wrapper); } - // add an ok button that will remove the entire pop up - var ok = $('
Ok
').on('click', function () { + var cleanUp = function () { // clean up the editor if (editor !== null) { editor.nfeditor('destroy'); @@ -764,7 +778,13 @@ // clean up the rest wrapper.hide().remove(); + }; + + // add an ok button that will remove the entire pop up + var ok = $('
Ok
').on('click', function () { + cleanUp(); }); + $('
').css({ 'position': 'absolute', 'bottom': '0', @@ -1306,7 +1326,7 @@ var clear = function (propertyTableContainer) { var options = propertyTableContainer.data('options'); if (options.readOnly === true) { - nf.Common.removeAllPropertyDetailDialogs(); + nf.UniversalCapture.removeAllPropertyDetailDialogs(); } else { // clear any existing new property dialogs if (nf.Common.isDefinedAndNotNull(options.dialogContainer)) { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js index 83d1b49ec1..dd9df5a995 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js @@ -537,92 +537,8 @@ nf.Canvas = (function () { nf.Settings.resetTableSize(); } }).on('keydown', function (evt) { - var isCtrl = evt.ctrlKey || evt.metaKey; - - // consider escape, before checking dialogs - if (!isCtrl && evt.keyCode === 27) { - // esc - - // prevent escape when a property value is being edited and it is unable to close itself - // (due to focus loss on field) - allowing this to continue would could cause other - // unsaved changes to be lost as it would end up cancel the entire configuration dialog - // not just the field itself - if ($('div.value-combo').is(':visible') || $('div.slickgrid-nfel-editor').is(':visible') || $('div.slickgrid-editor').is(':visible')) { - return; - } - - // first consider read only property detail dialog - if ($('div.property-detail').is(':visible')) { - nf.Common.removeAllPropertyDetailDialogs(); - - // prevent further bubbling as we're already handled it - evt.stopPropagation(); - evt.preventDefault(); - } else { - var target = $(evt.target); - if (target.length) { - var isBody = target.get(0) === $('#canvas-body').get(0); - var inShell = target.closest('#shell-dialog').length; - - // special handling for body and shell - if (isBody || inShell) { - var cancellables = $('.cancellable'); - if (cancellables.length) { - var zIndexMax = null; - var dialogMax = null; - - // identify the top most cancellable - $.each(cancellables, function (_, cancellable) { - var dialog = $(cancellable); - var zIndex = dialog.css('zIndex'); - - // if the dialog has a zIndex consider it - if (dialog.is(':visible') && nf.Common.isDefinedAndNotNull(zIndex)) { - zIndex = parseInt(zIndex, 10); - if (zIndexMax === null || zIndex > zIndexMax) { - zIndexMax = zIndex; - dialogMax = dialog; - } - } - }); - - // if we've identified a dialog to close do so and stop propagation - if (dialogMax !== null) { - // hide the cancellable - if (dialogMax.hasClass('modal')) { - dialogMax.modal('hide'); - } else { - dialogMax.hide(); - } - - // prevent further bubbling as we're already handled it - evt.stopPropagation(); - evt.preventDefault(); - } - } - } else { - // otherwise close the closest visible cancellable - var parentDialog = target.closest('.cancellable:visible').first(); - if (parentDialog.length) { - if (parentDialog.hasClass('modal')) { - parentDialog.modal('hide'); - } else { - parentDialog.hide(); - } - - // prevent further bubbling as we're already handled it - evt.stopPropagation(); - evt.preventDefault(); - } - } - } - } - - return; - } - // if a dialog is open, disable canvas shortcuts - if ($('.dialog').is(':visible')) { + if ($('.dialog').is(':visible') || $('#search-field').is(':focus')) { return; } @@ -630,41 +546,45 @@ nf.Canvas = (function () { var selection = nf.CanvasUtils.getSelection(); // handle shortcuts + var isCtrl = evt.ctrlKey || evt.metaKey; if (isCtrl) { if (evt.keyCode === 82) { // ctrl-r nf.Actions.reloadStatus(); - evt.preventDefault(); + // default prevented in nf-universal-capture.js } else if (evt.keyCode === 65) { // ctrl-a nf.Actions.selectAll(); nf.CanvasToolbar.refresh(); + // only want to prevent default if the action was performed, otherwise default select all would be overridden evt.preventDefault(); } else if (evt.keyCode === 67) { + // ctrl-c if (nf.Common.isDFM() && nf.CanvasUtils.isCopyable(selection)) { - // ctrl-c nf.Actions.copy(selection); + // only want to prevent default if the action was performed, otherwise default copy would be overridden evt.preventDefault(); } } else if (evt.keyCode === 86) { + // ctrl-v if (nf.Common.isDFM() && nf.CanvasUtils.isPastable()) { - // ctrl-p nf.Actions.paste(selection); + // only want to prevent default if the action was performed, otherwise default paste would be overridden evt.preventDefault(); } } } else { - if (evt.keyCode === 46) { + if (evt.keyCode == 8 || evt.keyCode === 46) { + // backspace or delete if (nf.Common.isDFM() && nf.CanvasUtils.isDeletable(selection)) { - // delete nf.Actions['delete'](selection); - - evt.preventDefault(); } + + // default prevented in nf-universal-capture.js } } }); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js index af8e78c0e3..ebaf6c1260 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js @@ -1379,7 +1379,7 @@ nf.ControllerService = (function () { }], select: function () { // remove all property detail dialogs - nf.Common.removeAllPropertyDetailDialogs(); + nf.UniversalCapture.removeAllPropertyDetailDialogs(); // update the property table size in case this is the first time its rendered if ($(this).text() === 'Properties') { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-label-configuration.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-label-configuration.js index e3674520f7..c308469ddf 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-label-configuration.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-label-configuration.js @@ -26,48 +26,59 @@ nf.LabelConfiguration = (function () { * Initializes the label details dialog. */ init: function () { - var apply = function () { - var revision = nf.Client.getRevision(); - - // get the new values - var labelValue = $('#label-value').val(); - var fontSize = $('#label-font-size').combo('getSelectedOption'); - - // save the new label value - $.ajax({ - type: 'PUT', - url: labelUri, - data: { - 'version': revision.version, - 'clientId': revision.clientId, - 'label': labelValue, - 'style[font-size]': fontSize.value - }, - dataType: 'json' - }).done(function (response) { - // update the revision - nf.Client.setRevision(response.revision); - - // get the label out of the response - nf.Label.set(response.label); - }).fail(nf.Common.handleAjaxError); - - - // reset and hide the dialog - labelUri = ''; - $('#label-configuration').hide(); - }; - - var cancel = function () { - labelUri = ''; - $('#label-configuration').hide(); - }; - // make the new property dialog draggable - $('#label-configuration').draggable({ + $('#label-configuration').modal({ + overlayBackground: true, + buttons: [{ + buttonText: 'Apply', + handler: { + click: function () { + var revision = nf.Client.getRevision(); + + // get the new values + var labelValue = $('#label-value').val(); + var fontSize = $('#label-font-size').combo('getSelectedOption'); + + // save the new label value + $.ajax({ + type: 'PUT', + url: labelUri, + data: { + 'version': revision.version, + 'clientId': revision.clientId, + 'label': labelValue, + 'style[font-size]': fontSize.value + }, + dataType: 'json' + }).done(function (response) { + // update the revision + nf.Client.setRevision(response.revision); + + // get the label out of the response + nf.Label.set(response.label); + }).fail(nf.Common.handleAjaxError); + + // reset and hide the dialog + this.modal('hide'); + } + } + }, { + buttonText: 'Cancel', + handler: { + click: function () { + this.modal('hide'); + } + } + }], + handler: { + close: function () { + labelUri = ''; + } + } + }).draggable({ containment: 'parent', cancel: 'textarea, .button, .combo' - }).on('click', '#label-configuration-apply', apply).on('click', '#label-configuration-cancel', cancel); + }); // create the available sizes var sizes = []; @@ -128,7 +139,7 @@ nf.LabelConfiguration = (function () { }); // show the detail dialog - $('#label-configuration').center().show(); + $('#label-configuration').modal('show'); } } }; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js index 6d04a00227..098f840b37 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js @@ -471,7 +471,7 @@ nf.ProcessorConfiguration = (function () { }], select: function () { // remove all property detail dialogs - nf.Common.removeAllPropertyDetailDialogs(); + nf.UniversalCapture.removeAllPropertyDetailDialogs(); // update the processor property table size in case this is the first time its rendered if ($(this).text() === 'Properties') { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js index f79aec1383..1656185369 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js @@ -311,7 +311,7 @@ nf.ReportingTask = (function () { }], select: function () { // remove all property detail dialogs - nf.Common.removeAllPropertyDetailDialogs(); + nf.UniversalCapture.removeAllPropertyDetailDialogs(); // update the property table size in case this is the first time its rendered if ($(this).text() === 'Properties') { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js index 6b4a5ea3ba..bf88a09a21 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js @@ -516,15 +516,6 @@ nf.Common = (function () { }); }, - /** - * Removes all read only property detail dialogs. - */ - removeAllPropertyDetailDialogs: function () { - var propertyDetails = $('body').children('div.property-detail'); - propertyDetails.find('div.nfel-editor').nfeditor('destroy'); - propertyDetails.hide().remove(); - }, - /** * Formats the tooltip for the specified property. * diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-processor-details.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-processor-details.js index 13eed45ac3..533e7bee5a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-processor-details.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-processor-details.js @@ -70,7 +70,7 @@ nf.ProcessorDetails = (function () { }], select: function () { // remove all property detail dialogs - nf.Common.removeAllPropertyDetailDialogs(); + nf.UniversalCapture.removeAllPropertyDetailDialogs(); // resize the property grid in case this is the first time its rendered if ($(this).text() === 'Properties') { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js index ac23e9d924..ac97726521 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js @@ -393,8 +393,7 @@ nf.StatusHistory = (function () { // show/center the dialog if necessary if (!statusHistoryDialog.is(':visible')) { - $('#glass-pane').show(); - statusHistoryDialog.center().show(); + statusHistoryDialog.modal('show'); } // the container for the main chart @@ -1163,24 +1162,36 @@ nf.StatusHistory = (function () { } }); - // make the new property dialog draggable - $('#status-history-dialog').draggable({ + // configure the dialog and make it draggable + $('#status-history-dialog').modal({ + overlayBackground: false, + buttons: [{ + buttonText: 'Close', + handler: { + click: function () { + this.modal('hide'); + } + } + }], + handler: { + close: function () { + // remove the current status history + $('#status-history-dialog').removeData('status-history').hide(); + + // reset the dom + $('#status-history-chart-container').empty(); + $('#status-history-chart-control-container').empty(); + $('#status-history-details').empty(); + + // clear the extent and selected descriptor + brushExtent = null; + descriptor = null; + instances = null; + } + } + }).draggable({ cancel: '#status-history-chart-container, #status-history-chart-control-container, div.status-history-detail, div.button, div.combo, div.summary-refresh', containment: 'parent' - }).on('click', '#status-history-close', function () { - // remove the current status history - $('#status-history-dialog').removeData('status-history').hide(); - $('#glass-pane').hide(); - - // reset the dom - $('#status-history-chart-container').empty(); - $('#status-history-chart-control-container').empty(); - $('#status-history-details').empty(); - - // clear the extent and selected descriptor - brushExtent = null; - descriptor = null; - instances = null; }); }, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-universal-capture.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-universal-capture.js new file mode 100644 index 0000000000..221a127d74 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-universal-capture.js @@ -0,0 +1,131 @@ +/* + * 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. + */ + +/** + * Captures keydown on the window to ensure certain keystrokes are handled in a consistent manner, particularly those + * that can lead to browser navigation/reload. + */ +$(document).ready(function () { + // setup a listener to ensure keystrokes are being overridden in a consistent manner + $(window).on('keydown', function (evt) { + // consider escape, before checking dialogs + var isCtrl = evt.ctrlKey || evt.metaKey; + if (!isCtrl && evt.keyCode === 27) { + // esc + + // prevent escape when editing a property with allowable values - that component does not handle key + // events so it can bubble up to here. once here we are unable to cancel the current edit so we simply + // return. this is not an issue for viewing in read only mode as the table is not in an edit mode. this + // is not an issue for other fields as they can handle key events locally and cancel the edit appropriately + var visibleCombo = $('div.value-combo'); + if (visibleCombo.is(':visible') && visibleCombo.parent().hasClass('combo-editor')) { + return; + } + + // consider property detail dialogs + if ($('div.property-detail').is(':visible')) { + nf.UniversalCapture.removeAllPropertyDetailDialogs(); + + // prevent further bubbling as we're already handled it + evt.stopImmediatePropagation(); + evt.preventDefault(); + } else { + var target = $(evt.target); + if (target.length) { + // special handling for body as the target + var cancellables = $('.cancellable'); + if (cancellables.length) { + var zIndexMax = null; + var dialogMax = null; + + // identify the top most cancellable + $.each(cancellables, function (_, cancellable) { + var dialog = $(cancellable); + var zIndex = dialog.css('zIndex'); + + // if the dialog has a zIndex consider it + if (dialog.is(':visible') && (zIndex !== null && typeof zIndex !== 'undefined')) { + zIndex = parseInt(zIndex, 10); + if (zIndexMax === null || zIndex > zIndexMax) { + zIndexMax = zIndex; + dialogMax = dialog; + } + } + }); + + // if we've identified a dialog to close do so and stop propagation + if (dialogMax !== null) { + // hide the cancellable + if (dialogMax.hasClass('modal')) { + dialogMax.modal('hide'); + } else { + dialogMax.hide(); + } + + // prevent further bubbling as we're already handled it + evt.stopImmediatePropagation(); + evt.preventDefault(); + + return; + } + } + + // now see if we're in a frame + if (top !== window) { + // and our parent has shell defined + if (typeof parent.nf !== 'undefined' && typeof parent.nf.Shell !== 'undefined') { + parent.$('#shell-close-button').click(); + + // prevent further bubbling as we're already handled it + evt.stopImmediatePropagation(); + evt.preventDefault(); + + return; + } + } + } + } + } else { + if (isCtrl) { + if (evt.keyCode === 82) { + // ctrl-r + evt.preventDefault(); + } + } else { + if (!$('input').is(':focus') && (evt.keyCode == 8 || evt.keyCode === 46)) { + // backspace or delete + evt.preventDefault(); + } + } + } + + }); +}); + +nf.UniversalCapture = (function() { + return { + /** + * Removes all read only property detail dialogs. + */ + removeAllPropertyDetailDialogs: function () { + var propertyDetails = $('body').find('div.property-detail'); + propertyDetails.find('div.nfel-editor').nfeditor('destroy'); // look for any nfel editors + propertyDetails.find('div.value-combo').combo('destroy'); // look for any combos + propertyDetails.hide().remove(); + } + }; +}()); \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/jsp/worksheet.jsp b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/jsp/worksheet.jsp index b142c18b2a..a7f93f1717 100644 --- a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/jsp/worksheet.jsp +++ b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/WEB-INF/jsp/worksheet.jsp @@ -53,6 +53,7 @@ + diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/main.css b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/main.css index ee306931ca..6d72ab8f35 100644 --- a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/main.css +++ b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/css/main.css @@ -393,7 +393,7 @@ div.slickgrid-nfel-editor .nfel-editor { margin-bottom: 30px; } -div.update-attribute-detail .nfel-editor { +div.property-detail .nfel-editor { margin-bottom: 30px; } diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/application.js b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/application.js index 80a3df88ed..a98df83ee9 100644 --- a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/application.js +++ b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-ui/src/main/webapp/js/application.js @@ -15,7 +15,7 @@ * limitations under the License. */ -/* global Slick */ +/* global Slick, nf */ $(document).ready(function () { ua.editable = $('#attribute-updater-editable').text() === 'true'; @@ -1545,7 +1545,7 @@ var ua = { var offset = cellNode.offset(); // create the wrapper - var wrapper = $('
').css({ + var wrapper = $('
').css({ 'z-index': 100000, 'position': 'absolute', 'background': 'white', @@ -1558,6 +1558,8 @@ var ua = { 'left': offset.left - 5 }).appendTo(container); + var editor = null; + // the attribute column does not get the nfel editor if (columnDefinition.id === 'attribute') { // make it draggable @@ -1575,7 +1577,14 @@ var ua = { 'overflow-y': 'auto', 'resize': 'both', 'margin-bottom': '28px' - }).text(value).appendTo(wrapper); + }).text(value).on('keydown', function (evt) { + if (evt.which === $.ui.keyCode.ESCAPE) { + cleanUp(); + + evt.stopImmediatePropagation(); + evt.preventDefault(); + } + }).appendTo(wrapper); } else { var languageId = 'nfel'; var editorClass = languageId + '-editor'; @@ -1587,21 +1596,35 @@ var ua = { }); // create the editor - $('
').addClass(editorClass).appendTo(wrapper).nfeditor({ + editor = $('
').addClass(editorClass).appendTo(wrapper).nfeditor({ languageId: languageId, width: (cellNode.width() - 5) + 'px', content: value, minWidth: 175, minHeight: 100, readOnly: true, - resizable: true + resizable: true, + escape: function () { + cleanUp(); + } }); } + var cleanUp = function () { + // clean up the editor + if (editor !== null) { + editor.nfeditor('destroy'); + } + + // clean up the rest + wrapper.hide().remove(); + }; + // add an ok button that will remove the entire pop up var ok = $('
Ok
').on('click', function () { - wrapper.hide().remove(); + cleaUp(); }); + $('
').css({ 'position': 'absolute', 'bottom': '0', @@ -1615,7 +1638,7 @@ var ua = { * Removes all currently open process property detail dialogs. */ removeAllDetailDialogs: function () { - $('body').children('div.update-attribute-detail').hide().remove(); + nf.UniversalCapture.removeAllPropertyDetailDialogs(); }, /** @@ -1677,6 +1700,7 @@ var ua = { if (e.which === $.ui.keyCode.ENTER && e.ctrlKey) { scope.save(); } else if (e.which === $.ui.keyCode.ESCAPE) { + e.stopImmediatePropagation(); e.preventDefault(); scope.cancel(); } else if (e.which === $.ui.keyCode.TAB && e.shiftKey) {