MDL-85437 AI: Move focus to the AI drawer
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,3 +1,3 @@
|
||||
define("aiplacement_courseassist/selectors",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;return _exports.default={ELEMENTS:{AIDRAWER:"#ai-drawer",AIDRAWER_BODY:"#ai-drawer .ai-drawer-body",PAGE:"#page",MAIN_REGION:'[role="main"]',AIDRAWER_CLOSE:"#ai-drawer-close",RESPONSE:".course-assist-response"},ACTIONS:{SUMMARY:'.course-assist-controls [data-action="summarise"]',EXPLAIN:'.course-assist-controls [data-action="explain"]',RETRY:'.course-assist-controls [data-action="retry"]',DECLINE:'.ai-policy-block [data-action="decline"]',ACCEPT:'.ai-policy-block [data-action="accept"]',REGENERATE:'.course-assist-controls [data-action="regenerate"]',CANCEL:'.course-assist-controls [data-action="cancel"]'}},_exports.default}));
|
||||
define("aiplacement_courseassist/selectors",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;return _exports.default={ELEMENTS:{AIDRAWER:"#ai-drawer",AIDRAWER_BODY:"#ai-drawer .ai-drawer-body",PAGE:"#page",MAIN_REGION:'[role="main"]',AIDRAWER_CLOSE:"#ai-drawer-close",RESPONSE:".course-assist-response",JUMPTO:'.course-assist-controls [data-region="jumpto"]',ACTION:'.course-assist-controls [data-input-type="action"]'},ACTIONS:{SUMMARY:'.course-assist-controls [data-action="summarise"]',EXPLAIN:'.course-assist-controls [data-action="explain"]',RETRY:'.course-assist-controls [data-action="retry"]',DECLINE:'.ai-policy-block [data-action="decline"]',ACCEPT:'.ai-policy-block [data-action="accept"]',REGENERATE:'.course-assist-controls [data-action="regenerate"]',CANCEL:'.course-assist-controls [data-action="cancel"]'}},_exports.default}));
|
||||
|
||||
//# sourceMappingURL=selectors.min.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"selectors.min.js","sources":["../src/selectors.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Define all of the selectors we will be using on the AI Course assistant.\n *\n * @module aiplacement_courseassist/selectors\n * @copyright 2024 Huong Nguyen <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nexport default {\n ELEMENTS: {\n AIDRAWER: '#ai-drawer',\n AIDRAWER_BODY: '#ai-drawer .ai-drawer-body',\n PAGE: '#page',\n MAIN_REGION: '[role=\"main\"]',\n AIDRAWER_CLOSE: '#ai-drawer-close',\n RESPONSE: '.course-assist-response',\n },\n ACTIONS: {\n SUMMARY: '.course-assist-controls [data-action=\"summarise\"]',\n EXPLAIN: '.course-assist-controls [data-action=\"explain\"]',\n RETRY: '.course-assist-controls [data-action=\"retry\"]',\n DECLINE: '.ai-policy-block [data-action=\"decline\"]',\n ACCEPT: '.ai-policy-block [data-action=\"accept\"]',\n REGENERATE: '.course-assist-controls [data-action=\"regenerate\"]',\n CANCEL: '.course-assist-controls [data-action=\"cancel\"]',\n }\n};\n"],"names":["ELEMENTS","AIDRAWER","AIDRAWER_BODY","PAGE","MAIN_REGION","AIDRAWER_CLOSE","RESPONSE","ACTIONS","SUMMARY","EXPLAIN","RETRY","DECLINE","ACCEPT","REGENERATE","CANCEL"],"mappings":"oLAsBe,CACXA,SAAU,CACNC,SAAU,aACVC,cAAe,6BACfC,KAAM,QACNC,YAAa,gBACbC,eAAgB,mBAChBC,SAAU,2BAEdC,QAAS,CACLC,QAAS,oDACTC,QAAS,kDACTC,MAAO,gDACPC,QAAS,2CACTC,OAAQ,0CACRC,WAAY,qDACZC,OAAQ"}
|
||||
{"version":3,"file":"selectors.min.js","sources":["../src/selectors.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Define all of the selectors we will be using on the AI Course assistant.\n *\n * @module aiplacement_courseassist/selectors\n * @copyright 2024 Huong Nguyen <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nexport default {\n ELEMENTS: {\n AIDRAWER: '#ai-drawer',\n AIDRAWER_BODY: '#ai-drawer .ai-drawer-body',\n PAGE: '#page',\n MAIN_REGION: '[role=\"main\"]',\n AIDRAWER_CLOSE: '#ai-drawer-close',\n RESPONSE: '.course-assist-response',\n JUMPTO: '.course-assist-controls [data-region=\"jumpto\"]',\n ACTION: '.course-assist-controls [data-input-type=\"action\"]',\n },\n ACTIONS: {\n SUMMARY: '.course-assist-controls [data-action=\"summarise\"]',\n EXPLAIN: '.course-assist-controls [data-action=\"explain\"]',\n RETRY: '.course-assist-controls [data-action=\"retry\"]',\n DECLINE: '.ai-policy-block [data-action=\"decline\"]',\n ACCEPT: '.ai-policy-block [data-action=\"accept\"]',\n REGENERATE: '.course-assist-controls [data-action=\"regenerate\"]',\n CANCEL: '.course-assist-controls [data-action=\"cancel\"]',\n }\n};\n"],"names":["ELEMENTS","AIDRAWER","AIDRAWER_BODY","PAGE","MAIN_REGION","AIDRAWER_CLOSE","RESPONSE","JUMPTO","ACTION","ACTIONS","SUMMARY","EXPLAIN","RETRY","DECLINE","ACCEPT","REGENERATE","CANCEL"],"mappings":"oLAsBe,CACXA,SAAU,CACNC,SAAU,aACVC,cAAe,6BACfC,KAAM,QACNC,YAAa,gBACbC,eAAgB,mBAChBC,SAAU,0BACVC,OAAQ,iDACRC,OAAQ,sDAEZC,QAAS,CACLC,QAAS,oDACTC,QAAS,kDACTC,MAAO,gDACPC,QAAS,2CACTC,OAAQ,0CACRC,WAAY,qDACZC,OAAQ"}
|
||||
@@ -58,6 +58,9 @@ const AICourseAssist = class {
|
||||
this.aiDrawerElement = document.querySelector(Selectors.ELEMENTS.AIDRAWER);
|
||||
this.aiDrawerBodyElement = document.querySelector(Selectors.ELEMENTS.AIDRAWER_BODY);
|
||||
this.pageElement = document.querySelector(Selectors.ELEMENTS.PAGE);
|
||||
this.jumpToElement = document.querySelector(Selectors.ELEMENTS.JUMPTO);
|
||||
this.actionElement = document.querySelector(Selectors.ELEMENTS.ACTION);
|
||||
this.aiDrawerCloseElement = this.aiDrawerElement.querySelector(Selectors.ELEMENTS.AIDRAWER_CLOSE);
|
||||
this.lastAction = '';
|
||||
this.responses = new Map();
|
||||
|
||||
@@ -75,6 +78,7 @@ const AICourseAssist = class {
|
||||
e.preventDefault();
|
||||
this.openAIDrawer();
|
||||
this.lastAction = 'summarise';
|
||||
this.actionElement.focus();
|
||||
const isPolicyAccepted = await this.isPolicyAccepted();
|
||||
if (!isPolicyAccepted) {
|
||||
// Display policy.
|
||||
@@ -89,6 +93,7 @@ const AICourseAssist = class {
|
||||
e.preventDefault();
|
||||
this.openAIDrawer();
|
||||
this.lastAction = 'explain';
|
||||
this.actionElement.focus();
|
||||
const isPolicyAccepted = await this.isPolicyAccepted();
|
||||
if (!isPolicyAccepted) {
|
||||
// Display policy.
|
||||
@@ -111,6 +116,21 @@ const AICourseAssist = class {
|
||||
this.closeAIDrawer();
|
||||
}
|
||||
});
|
||||
|
||||
// Focus on the AI drawer's close button when the jump-to element is focused.
|
||||
this.jumpToElement.addEventListener('focus', () => {
|
||||
this.aiDrawerCloseElement.focus();
|
||||
});
|
||||
|
||||
// Focus on the action element when the AI drawer container receives focus.
|
||||
this.aiDrawerElement.addEventListener('focus', () => {
|
||||
this.actionElement.focus();
|
||||
});
|
||||
|
||||
// Remove active from the action element when it loses focus.
|
||||
this.actionElement.addEventListener('blur', () => {
|
||||
this.actionElement.classList.remove('active');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,10 +232,13 @@ const AICourseAssist = class {
|
||||
// Close message drawer if it is shown.
|
||||
MessageDrawerHelper.hide();
|
||||
this.aiDrawerElement.classList.add('show');
|
||||
this.aiDrawerElement.setAttribute('tabindex', 0);
|
||||
this.aiDrawerBodyElement.setAttribute('aria-live', 'polite');
|
||||
if (!this.pageElement.classList.contains('show-drawer-right')) {
|
||||
this.addPadding();
|
||||
}
|
||||
this.jumpToElement.setAttribute('tabindex', 0);
|
||||
this.jumpToElement.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,10 +246,21 @@ const AICourseAssist = class {
|
||||
*/
|
||||
closeAIDrawer() {
|
||||
this.aiDrawerElement.classList.remove('show');
|
||||
this.aiDrawerElement.setAttribute('tabindex', -1);
|
||||
this.aiDrawerBodyElement.removeAttribute('aria-live');
|
||||
if (this.pageElement.classList.contains('show-drawer-right') && this.aiDrawerBodyElement.dataset.removepadding === '1') {
|
||||
this.removePadding();
|
||||
}
|
||||
this.jumpToElement.setAttribute('tabindex', -1);
|
||||
|
||||
// We can enforce a focus-visible state on the focus element using element.focus({focusVisible: true}).
|
||||
// Unfortunately, this feature isn't supported in all browsers, only Firefox provides support for it.
|
||||
// Therefore, we will apply the active class to the action element and set focus on it.
|
||||
// This action will make the action element appear focused.
|
||||
// When the action element loses focus,
|
||||
// we will remove the active class at {@see registerEventListeners()}
|
||||
this.actionElement.classList.add('active');
|
||||
this.actionElement.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,8 @@ export default {
|
||||
MAIN_REGION: '[role="main"]',
|
||||
AIDRAWER_CLOSE: '#ai-drawer-close',
|
||||
RESPONSE: '.course-assist-response',
|
||||
JUMPTO: '.course-assist-controls [data-region="jumpto"]',
|
||||
ACTION: '.course-assist-controls [data-input-type="action"]',
|
||||
},
|
||||
ACTIONS: {
|
||||
SUMMARY: '.course-assist-controls [data-action="summarise"]',
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="right"
|
||||
aria-controls="ai-drawer"
|
||||
data-input-type="action"
|
||||
data-bs-delay="200"
|
||||
>
|
||||
{{^isdropdown}}
|
||||
{{> aiplacement_courseassist/sparkles_icon }}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
]
|
||||
}
|
||||
}}
|
||||
<div {{#isdropdown}}id="#ai-features"{{/isdropdown}}
|
||||
<div {{#isdropdown}}id="ai-features"{{/isdropdown}}
|
||||
class="course-assist-controls py-3">
|
||||
{{#isdropdown}}
|
||||
{{> aiplacement_courseassist/actions_dropdown }}
|
||||
@@ -50,4 +50,5 @@
|
||||
{{> aiplacement_courseassist/action_button }}
|
||||
{{/actions}}
|
||||
{{/isdropdown}}
|
||||
{{> core_message/message_jumpto }}
|
||||
</div>
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
data-bs-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
data-input-type="action"
|
||||
>
|
||||
{{> aiplacement_courseassist/sparkles_icon }}
|
||||
{{#str}} aifeatures, aiplacement_courseassist {{/str}}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"contextid": "1"
|
||||
}
|
||||
}}
|
||||
<div class="ai-drawer" id="ai-drawer">
|
||||
<div class="ai-drawer" id="ai-drawer" tabindex="-1">
|
||||
<div class="ai-drawer-header">
|
||||
<button id="ai-drawer-close" class="btn ai-drawer-button" type="button">
|
||||
{{#pix}} e/cancel, core {{/pix}}
|
||||
|
||||
Reference in New Issue
Block a user