diff --git a/docs/en_US/release_notes_4_20.rst b/docs/en_US/release_notes_4_20.rst index b7cdb5e3c..73ef586c2 100644 --- a/docs/en_US/release_notes_4_20.rst +++ b/docs/en_US/release_notes_4_20.rst @@ -27,5 +27,6 @@ Bug fixes | `Issue #5128 `_ - Change some colors and opacity to comply with WCAG color contrast standards. | `Issue #5143 `_ - Fix an accessibility issue to maximize the panel for all alertify dialog. | `Issue #5221 `_ - Improve logic to get the DDL statements as a part of the comparison. +| `Issue #5241 `_ - Fixed tab key navigation issue for Grant Wizard. | `Issue #5279 `_ - Fixed Unicode character issue causing error on Python2 environment. | `Issue #5292 `_ - Fixed focus color issue for Alertify dialog buttons. \ No newline at end of file diff --git a/web/pgadmin/browser/static/js/wizard.js b/web/pgadmin/browser/static/js/wizard.js index 72590c9e5..3068572d1 100644 --- a/web/pgadmin/browser/static/js/wizard.js +++ b/web/pgadmin/browser/static/js/wizard.js @@ -155,6 +155,7 @@ define([ 'click button.wizard-finish': 'finishWizard', 'click button.wizard-help': 'onDialogHelp', 'click a.close-error': 'closeErrorMsg', + 'keydown': 'keydownHandler', }, initialize: function(options) { this.options = _.extend({}, this.options, options.options); @@ -239,6 +240,60 @@ define([ delete this.el; // Delete the variable reference to this node return true; }, + keydownHandler: function(event) { + let wizardHeader = $(event.currentTarget).find('.wizard-header'); + let wizardFooter = $(event.currentTarget).find('.wizard-footer'); + let gridElement = $(event.currentTarget).find('.select-row-cell:first'); + let gridElementLast = $(event.currentTarget).find('.select-row-cell:last'); + + let firstWizardHeaderButton = $(wizardHeader).find('button:enabled:first'); + let lastWizardHeaderButton = $(wizardHeader).find('button:enabled:last'); + let lastWizardFooterBtn = $(wizardFooter).find('button:enabled:last'); + let firstWizardFooterBtn = $(wizardFooter).find('button:enabled:first'); + + + if (event.shiftKey && event.keyCode === 9) { + // Move backwards + if(firstWizardHeaderButton && $(firstWizardHeaderButton).is($(event.target))) { + if (lastWizardFooterBtn) { + $(lastWizardFooterBtn).focus(); + event.preventDefault(); + event.stopPropagation(); + } + } + else if ($(firstWizardFooterBtn).is($(event.target))){ + if ($(gridElement).find('.custom-control-input').is(':visible')){ + $(gridElementLast).find('.custom-control-input').focus(); + event.preventDefault(); + event.stopPropagation(); + }else if ($(event.currentTarget).find('.wizard-content').find('.CodeMirror-scroll').is(':visible')){ + $(lastWizardHeaderButton).focus(); + } + } + } else if (event.keyCode === 9) { + // Move forwards + // If taget is last button then goto first element + if(lastWizardFooterBtn && $(lastWizardFooterBtn).is($(event.target))) { + $(firstWizardHeaderButton).focus(); + event.preventDefault(); + event.stopPropagation(); + }else if (event.target.innerText == 'Name'){ + if ($(gridElement).find('.custom-control-input').is(':visible')){ + $(gridElement).find('.custom-control-input').focus(); + }else { + $(firstWizardFooterBtn).focus(); + } + event.preventDefault(); + event.stopPropagation(); + } else if(event.target.tagName == 'DIV') { + $(event.currentTarget).find('.custom-control-input:first').trigger('focus'); + event.preventDefault(); + event.stopPropagation(); + } else if(event.target.tagName == 'TEXTAREA'){ + $(firstWizardFooterBtn).focus(); + } + } + }, enableDisableNext: function(disable) { if (typeof(disable) != 'undefined') { this.options.disable_next = disable; diff --git a/web/pgadmin/static/js/backgrid.pgadmin.js b/web/pgadmin/static/js/backgrid.pgadmin.js index b05e1422f..157c74262 100644 --- a/web/pgadmin/static/js/backgrid.pgadmin.js +++ b/web/pgadmin/static/js/backgrid.pgadmin.js @@ -1772,7 +1772,7 @@ define([ this.tabKeyPress = false; this.$el.datetimepicker(options); this.$el.datetimepicker('show'); - this.picker = this.$el.data('DateTimePicker'); + this.picker = this.$el.data('datetimepicker'); }, events: { 'hide.datetimepicker': 'closeIt', @@ -1780,9 +1780,56 @@ define([ 'keydown': 'keydownHandler', }, keydownHandler: function(event) { + let stopBubble = false; + let self = this; + if (!event.altKey && event.keyCode == 38){ + let currdate = self.$el.data('datetimepicker').date().clone(); + if (self.$el.data('datetimepicker').widget.find('.datepicker').is(':visible')){ + $(this.el).datetimepicker('date', currdate.subtract(7, 'd')); + }else{ + $(this.el).datetimepicker('date', currdate.add(7, 'm')); + } + }else if (!event.altKey && event.keyCode == 40){ + let currdate = self.$el.data('datetimepicker').date().clone(); + if (self.$el.data('datetimepicker').widget.find('.datepicker').is(':visible')){ + $(this.el).datetimepicker('date', currdate.add(7, 'd')); + }else{ + $(this.el).datetimepicker('date', currdate.subtract(7, 'm')); + } + }else if (event.keyCode == 39){ + let currdate = self.$el.data('datetimepicker').date().clone(); + $(this.el).datetimepicker('date', currdate.add(1, 'd')); + }else if (event.keyCode == 37){ + let currdate = self.$el.data('datetimepicker').date().clone(); + $(this.el).datetimepicker('date', currdate.subtract(1, 'd')); + } + + if (event.altKey && event.keyCode == 84){ + if (self.$el.data('datetimepicker').widget.find('.timepicker').is(':visible')){ + self.$el.data('datetimepicker').widget.find('.fa-calendar').click(); + }else{ + self.$el.data('datetimepicker').widget.find('.fa-clock-o').click(); + } + } + + if(event.altKey && event.keyCode == 38){ + let currdate = self.$el.data('datetimepicker').date().clone(); + $(this.el).datetimepicker('date', currdate.add(1, 'h')); + }else if(event.altKey && event.keyCode == 40){ + let currdate = self.$el.data('datetimepicker').date().clone(); + $(this.el).datetimepicker('date', currdate.subtract(1, 'h')); + } + + if (event.keyCode == 27){ + this.$el.datetimepicker('hide'); + stopBubble = true; + } + + if(stopBubble) { + event.stopImmediatePropagation(); + } // If Tab key pressed from Cell and not from Datetime picker element // then we should trigger edited event so that we can goto next cell - let self = this; let tabKeyPressed = true; if (event.keyCode === 9 && self.el === event.target) { self.closeIt(event, tabKeyPressed); diff --git a/web/pgadmin/static/scss/_alertify.overrides.scss b/web/pgadmin/static/scss/_alertify.overrides.scss index b20b5ca04..abbe4646a 100644 --- a/web/pgadmin/static/scss/_alertify.overrides.scss +++ b/web/pgadmin/static/scss/_alertify.overrides.scss @@ -281,7 +281,7 @@ } -.ajs-commands { +.ajs-commands, .ajs-close { button { @extend .btn-secondary; outline: none !important; diff --git a/web/pgadmin/static/vendor/backgrid/backgrid-select-all.js b/web/pgadmin/static/vendor/backgrid/backgrid-select-all.js index e9bcf5130..4e0c5c48b 100644 --- a/web/pgadmin/static/vendor/backgrid/backgrid-select-all.js +++ b/web/pgadmin/static/vendor/backgrid/backgrid-select-all.js @@ -101,9 +101,10 @@ } else if (command.save() || command.moveLeft() || command.moveRight() || command.moveUp() || command.moveDown()) { - e.preventDefault(); - e.stopPropagation(); + if(this.model) { + e.preventDefault(); + e.stopPropagation(); this.model.trigger("backgrid:edited", this.model, this.column, command); } } @@ -127,7 +128,7 @@ var id = 'selectall-' + _.uniqueId(this.column.get('name')); this.$el.empty().append([ '
', - ' ', + ' ', ' ', diff --git a/web/pgadmin/tools/grant_wizard/static/js/grant_wizard.js b/web/pgadmin/tools/grant_wizard/static/js/grant_wizard.js index 763edef57..6c581288b 100644 --- a/web/pgadmin/tools/grant_wizard/static/js/grant_wizard.js +++ b/web/pgadmin/tools/grant_wizard/static/js/grant_wizard.js @@ -431,29 +431,6 @@ define([ hooks: { onshow: function() { commonUtils.findAndSetFocus($(this.elements.body)); - let self = this; - let containerFooter = $(this.elements.content).find('.wizard-buttons').find('.ml-auto'); - //To get last header button - let lastHeaderButton = $(this.elements.content).find('.wizard-header').find('.ml-auto').find('button:first'); - - $(containerFooter).on('keydown', 'button', function(event) { - if (!event.shiftKey && event.keyCode == 9 && $(this).nextAll('button:not([disabled])').length == 0) { - // set focus back to first editable input element of current active tab once we cycle through all enabled buttons. - let container = $(self.elements.content).find('.wizard-header'); - commonUtils.findAndSetFocus(container.find('button:not([disabled]):first')); - return false; - } - }); - - $(lastHeaderButton).on('keydown', function(event) { - if (event.shiftKey && event.keyCode == 9) { - // set focus back to first element of current active tab once we cycle through all enabled buttons. - let container = $(self.elements.content).find('.wizard-footer'); - commonUtils.findAndSetFocus(container.find('button:not([disabled]):last')); - return false; - } - }); - }, }, @@ -1218,7 +1195,6 @@ define([ }; }); } - // Call Grant Wizard Dialog and set dimensions for wizard Alertify.wizardDialog(true).resizeTo(pgBrowser.stdW.lg,pgBrowser.stdH.lg); },