NIFI-480:

- Addressing issues caused by canceling a dialog by pressing escape. Previously pressing escape would cause too many dialogs to close. This could lead to potential configuration loss if there was other unsaved changes.
This commit is contained in:
Matt Gilman 2015-04-01 09:42:33 -04:00
parent 4752e284f6
commit 30fc75e2b8
5 changed files with 88 additions and 36 deletions

View File

@ -90,7 +90,7 @@
if (isDefinedAndNotNull(options)) {
// get the combo
var dialog = $(this).addClass('dialog cancellable');
var dialog = $(this).addClass('dialog cancellable modal');
var dialogHeaderText = $('<span class="dialog-header-text"></span>');
var dialogHeader = $('<div class="dialog-header"></div>').append(dialogHeaderText);

View File

@ -58,7 +58,7 @@
previousValue = args.item[args.column.field];
// create the wrapper
wrapper = $('<div></div>').css({
wrapper = $('<div></div>').addClass('slickgrid-editor').css({
'z-index': 100000,
'position': 'absolute',
'background': 'white',
@ -598,7 +598,7 @@
*/
var showPropertyValue = function (propertyGrid, descriptors, row, cell) {
// remove any currently open detail dialogs
removeAllPropertyDetailDialogs();
nf.CanvasUtils.removeAllPropertyDetailDialogs();
// get the property in question
var propertyData = propertyGrid.getData();
@ -694,13 +694,6 @@
}
};
/**
* Removes all currently open property detail dialogs.
*/
var removeAllPropertyDetailDialogs = function () {
$('body').children('div.property-detail').hide().remove();
};
var initPropertiesTable = function (table, options) {
// function for formatting the property name
var nameFormatter = function (row, cell, value, columnDef, dataContext) {
@ -1029,7 +1022,7 @@
var clear = function (propertyTableContainer) {
var options = propertyTableContainer.data('options');
if (options.readOnly === true) {
removeAllPropertyDetailDialogs();
nf.CanvasUtils.removeAllPropertyDetailDialogs();
} else {
// clear any existing new property dialogs
if (nf.Common.isDefinedAndNotNull(options.newPropertyDialogContainer)) {
@ -1077,7 +1070,7 @@
if (options.readOnly !== true && nf.Common.isDefinedAndNotNull(options.newPropertyDialogContainer)) {
// build the new property dialog
var newPropertyDialogMarkup =
'<div class="new-property-dialog dialog">' +
'<div class="new-property-dialog dialog cancellable">' +
'<div>' +
'<div class="setting-name">Property name</div>' +
'<div class="setting-field new-property-name-container">' +

View File

@ -678,20 +678,6 @@ nf.Actions = (function () {
}
},
/**
* Hides and open cancellable dialogs.
*/
hideDialogs: function () {
// ensure all cancellable dialogs are closed
var cancellable = $('.cancellable');
$.each(cancellable, function () {
// if this dialog is open, close it
if ($(this).is(':visible')) {
$(this).modal('hide');
}
});
},
/**
* Reloads the status for the entire canvas (components and flow.)
*/

View File

@ -870,6 +870,15 @@ nf.CanvasUtils = (function () {
return nf.Clipboard.isCopied();
},
/**
* 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();
},
/**
* Persists the current user view.
*/

View File

@ -538,18 +538,82 @@ nf.Canvas = (function () {
// consider escape, before checking dialogs
if (!isCtrl && evt.keyCode === 27) {
// esc
var target = $(evt.target);
if (target.length) {
if (target.get(0) === $('#canvas-body').get(0)) {
nf.Actions.hideDialogs();
} else {
target.closest('.cancellable.dialog:visible').modal('hide');
}
evt.stopPropagation();
evt.preventDefault();
// 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.CanvasUtils.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;
}