Skip to content

Commit ab36bbd

Browse files
committed
MC-19639: Admin Analytics modal allows user to navigate the admin
- MC-19638: User can dismiss the Admin Analytics modal with ESC key
1 parent 028f594 commit ab36bbd

File tree

2 files changed

+68
-14
lines changed

2 files changed

+68
-14
lines changed

app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
<item name="text" xsi:type="string" translate="true"><![CDATA[
8686
<p>Help us improve Magento Admin by allowing us to collect usage data.</p>
8787
<p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p>
88-
<p>You can learn more and opt out at any time by following the instructions in <a href="https://docs.magento.com/m2/ce/user_guide/stores/admin.html" target="_blank">merchant documentation</a>.</p>
88+
<p>You can learn more and opt out at any time by following the instructions in <a href="https://docs.magento.com/m2/ce/user_guide/stores/admin.html" target="_blank" tabindex="0">merchant documentation</a>.</p>
8989
]]></item>
9090
</item>
9191
</argument>

app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,7 @@ define([
2020
enableLogAction: '${ $.provider }:data.enableLogAction',
2121
disableLogAction: '${ $.provider }:data.disableLogAction'
2222
},
23-
options: {
24-
keyEventHandlers: {
25-
/**
26-
* Prevents escape key from exiting out of modal
27-
*/
28-
escapeKey: function () {
29-
return;
30-
}
31-
}
32-
},
23+
options: {},
3324
notificationWindow: null
3425
},
3526

@@ -41,11 +32,32 @@ define([
4132
this._super();
4233
},
4334

35+
/**
36+
* Configure ESC and TAB so user can't leave modal
37+
* without selecting an option
38+
*
39+
* @returns {Object} Chainable.
40+
*/
41+
initModalEvents: function () {
42+
this._super();
43+
//Don't allow ESC key to close modal
44+
this.options.keyEventHandlers.escapeKey = function(e){e.preventDefault()};
45+
//Restrict tab action to the modal
46+
this.options.keyEventHandlers.tabKey = this.handleTabKey.bind(this);
47+
48+
return this;
49+
},
50+
4451
/**
4552
* Once the modal is opened it hides the X
4653
*/
4754
onOpened: function () {
48-
$('.modal-header button.action-close').hide();
55+
$('.modal-header button.action-close').attr("disabled", true).hide();
56+
57+
this.focusableElements = $(this.rootSelector).find("a[href], button:enabled");
58+
this.firstFocusableElement = this.focusableElements[0];
59+
this.lastFocusableElement = this.focusableElements[this.focusableElements.length - 1];
60+
this.firstFocusableElement.focus();
4961
},
5062

5163
/**
@@ -104,10 +116,52 @@ define([
104116
* Allows admin usage popup to be shown first and then new release notification
105117
*/
106118
openReleasePopup: function () {
107-
var notifiModal = registry.get('release_notification.release_notification.notification_modal_1');
119+
var notificationModal = registry.get('release_notification.release_notification.notification_modal_1');
108120

109121
if (analyticsPopupConfig.releaseVisible) {
110-
notifiModal.initializeContentAfterAnalytics();
122+
notificationModal.initializeContentAfterAnalytics();
123+
}
124+
},
125+
126+
/**
127+
* Handle Tab and Shift+Tab key event
128+
*
129+
* Keep the tab actions restricted to the popup modal
130+
* so the user must select an option to dismiss the modal
131+
*/
132+
handleTabKey: function(event) {
133+
var modal = this;
134+
var KEY_TAB = 9;
135+
136+
function handleBackwardTab() {
137+
if ( document.activeElement === modal.firstFocusableElement
138+
|| document.activeElement === $(modal.rootSelector)[0]
139+
) {
140+
event.preventDefault();
141+
modal.lastFocusableElement.focus();
142+
}
143+
}
144+
function handleForwardTab() {
145+
if ( document.activeElement === modal.lastFocusableElement) {
146+
event.preventDefault();
147+
modal.firstFocusableElement.focus();
148+
}
149+
}
150+
151+
switch(event.keyCode) {
152+
case KEY_TAB:
153+
if ( modal.focusableElements.length === 1 ) {
154+
event.preventDefault();
155+
break;
156+
}
157+
if ( event.shiftKey ) {
158+
handleBackwardTab();
159+
break;
160+
}
161+
handleForwardTab();
162+
break;
163+
default:
164+
break;
111165
}
112166
}
113167
}

0 commit comments

Comments
 (0)