diff --git a/public/question/bank/bulkmove/amd/build/modal_question_bank_bulkmove.min.js b/public/question/bank/bulkmove/amd/build/modal_question_bank_bulkmove.min.js index 848ff31809b..bede2b6d5e5 100644 --- a/public/question/bank/bulkmove/amd/build/modal_question_bank_bulkmove.min.js +++ b/public/question/bank/bulkmove/amd/build/modal_question_bank_bulkmove.min.js @@ -1,3 +1,3 @@ -define("qbank_bulkmove/modal_question_bank_bulkmove",["exports","core/modal","core/fragment","core/str","core/form-autocomplete","core_question/repository","core/templates","core/notification","core/pending"],(function(_exports,_modal,Fragment,_str,_formAutocomplete,_repository,_templates,_notification,_pending){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=_interopRequireDefault(_modal),Fragment=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Fragment),_formAutocomplete=_interopRequireDefault(_formAutocomplete),_templates=_interopRequireDefault(_templates),_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending);class ModalQuestionBankBulkmove extends _modal.default{static init(contextId,categoryId){document.addEventListener("click",(e=>{const trigger=e.target;trigger.classList.contains("dropdown-item")&&"move"===trigger.getAttribute("name")&&(e.preventDefault(),ModalQuestionBankBulkmove.create({contextId:contextId,title:(0,_str.getString)("bulkmoveheader","qbank_bulkmove"),show:!0,categoryId:categoryId}))}))}configure(modalConfig){this.contextId=modalConfig.contextId,this.targetBankContextId=modalConfig.contextId,this.initSelectedCategoryId(modalConfig.categoryId),modalConfig.removeOnClose=!0,super.configure(modalConfig)}initSelectedCategoryId(categoryId){const filter=new URLSearchParams(window.location.href).get("filter");if(filter){var _JSON$parse;const filteredCategoryId=null===(_JSON$parse=JSON.parse(filter))||void 0===_JSON$parse?void 0:_JSON$parse.category.values[0];return this.currentCategoryId=filteredCategoryId>0?filteredCategoryId:null,void(this.targetCategoryId=filteredCategoryId)}this.currentCategoryId=categoryId,this.targetCategoryId=categoryId}show(){return this.display(this.contextId,this.currentCategoryId),super.show()}async display(currentBankContextId,currentCategoryId){const displayPending=new _pending.default("qbank_bulkmove/bulk_move_modal");this.bodyPromise=await Fragment.loadFragment("qbank_bulkmove","bulk_move",currentBankContextId,{categoryid:currentCategoryId}),await this.setBody(this.bodyPromise),await this.enhanceSelects(),this.registerEnhancedEventListeners(),this.updateSaveButtonState(),displayPending.resolve()}registerEnhancedEventListeners(){document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY).addEventListener("change",(()=>{this.updateSaveButtonState()})),document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_BANK).addEventListener("change",(async e=>{await this.updateCategorySelector(e.currentTarget.value),this.updateSaveButtonState()})),this.getModal().on("click",ModalQuestionBankBulkmove.SELECTORS.SAVE_BUTTON,(e=>{e.preventDefault(),this.displayConfirmMove()}))}async displayConfirmMove(){this.setTitle((0,_str.getString)("confirm","core")),this.setBody((0,_str.getString)("confirmmove","qbank_bulkmove")),this.hasFooterContent()?this.showFooter():(this.setFooter(_templates.default.render("qbank_bulkmove/bulk_move_footer",{})),await this.getFooterPromise(),document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CONFIRM_BUTTON).addEventListener("click",(e=>{e.preventDefault(),this.moveQuestionsAfterConfirm(this.targetBankContextId,this.targetCategoryId)})),document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CANCEL_BUTTON).addEventListener("click",(e=>{e.preventDefault(),this.setTitle((0,_str.getString)("bulkmoveheader","qbank_bulkmove")),this.setBodyContent(_templates.default.renderForPromise("core/loading",{})),this.hideFooter(),this.display(this.targetBankContextId,this.targetCategoryId)})))}updateCategorySelector(selectedBankCmId){return selectedBankCmId?Fragment.loadFragment("core_question","category_selector",this.contextId,{bankcmid:selectedBankCmId}).then(((html,js)=>{const categorySelector=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.QUESTION_CATEGORY_SELECTOR);return _templates.default.replaceNode(categorySelector,html,js)})).then((()=>(document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_WARNING).classList.add("d-none"),this.enhanceSelects()))).catch(_notification.default.exception):(this.updateCategorySelectorState(!1),Promise.resolve())}updateCategorySelectorState(toEnable){const warning=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_WARNING),enhancedInput=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_ENHANCED_INPUT),suggestionButton=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_SUGGESTION),selection=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_SELECTION);toEnable?(warning.classList.add("d-none"),enhancedInput.removeAttribute("disabled"),suggestionButton.classList.remove("d-none")):(warning.classList.remove("d-none"),enhancedInput.setAttribute("disabled","disabled"),suggestionButton.classList.add("d-none"),selection.click())}updateSaveButtonState(){const saveButton=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SAVE_BUTTON),categorySelector=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY);[this.targetCategoryId,this.targetBankContextId]=categorySelector.value.split(","),this.targetCategoryId&&this.targetCategoryId!==this.currentCategoryId?saveButton.removeAttribute("disabled"):saveButton.setAttribute("disabled","disabled")}async moveQuestionsAfterConfirm(targetContextId,targetCategoryId){await this.setBody(_templates.default.render("core/loading",{}));const qelements=document.querySelectorAll(ModalQuestionBankBulkmove.SELECTORS.SELECTED_QUESTIONS),questionids=[];qelements.forEach((element=>{if(element.checked){const name=element.getAttribute("name");questionids.push(name.substr(1,name.length))}})),0===questionids.length&&await _notification.default.exception("No questions selected");try{window.location.href=await(0,_repository.moveQuestions)(targetContextId,targetCategoryId,questionids.join(),window.location.href)}catch(error){await _notification.default.exception(error)}}async enhanceSelects(){const placeholder=await(0,_str.getString)("searchbyname","mod_quiz");await _formAutocomplete.default.enhance(ModalQuestionBankBulkmove.SELECTORS.SEARCH_BANK,!1,"core_question/question_banks_datasource",placeholder,!1,!0,"",!0),await _formAutocomplete.default.enhance(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY,!1,null,placeholder,!1,!0,"",!0)}}return _exports.default=ModalQuestionBankBulkmove,_defineProperty(ModalQuestionBankBulkmove,"TYPE","qbank_bulkmove/bulkmove"),_defineProperty(ModalQuestionBankBulkmove,"SELECTORS",{SAVE_BUTTON:'[data-action="bulkmovesave"]',SELECTED_QUESTIONS:'table#categoryquestions input[id^="checkq"]',SEARCH_BANK:"#searchbanks",SEARCH_CATEGORY:".selectcategory",QUESTION_CATEGORY_SELECTOR:".question_category_selector",CATEGORY_OPTIONS:".selectcategory option",BANK_OPTIONS:"#searchbanks option",CATEGORY_ENHANCED_INPUT:".search-categories input",ORIGINAL_SELECTS:"select.bulk-move",CATEGORY_WARNING:"#searchcatwarning",CATEGORY_SUGGESTION:".search-categories span.form-autocomplete-downarrow",CATEGORY_SELECTION:'.search-categories span[role="option"][data-active-selection="true"]',CONFIRM_BUTTON:'.bulk-move-footer button[data-action="save"]',CANCEL_BUTTON:'.bulk-move-footer button[data-action="cancel"]'}),_exports.default})); +define("qbank_bulkmove/modal_question_bank_bulkmove",["exports","core/modal","core/fragment","core/str","core/form-autocomplete","core_question/repository","core/templates","core/notification","core/pending"],(function(_exports,_modal,Fragment,_str,_formAutocomplete,_repository,_templates,_notification,_pending){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=_interopRequireDefault(_modal),Fragment=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Fragment),_formAutocomplete=_interopRequireDefault(_formAutocomplete),_templates=_interopRequireDefault(_templates),_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending);class ModalQuestionBankBulkmove extends _modal.default{static init(contextId,categoryId){document.addEventListener("click",(e=>{const trigger=e.target;trigger.classList.contains("dropdown-item")&&"move"===trigger.getAttribute("name")&&(e.preventDefault(),ModalQuestionBankBulkmove.create({contextId:contextId,title:(0,_str.getString)("bulkmoveheader","qbank_bulkmove"),show:!0,categoryId:categoryId}))}))}configure(modalConfig){this.contextId=modalConfig.contextId,this.targetBankContextId=modalConfig.contextId,this.initSelectedCategoryId(modalConfig.categoryId),modalConfig.removeOnClose=!0,super.configure(modalConfig)}initSelectedCategoryId(categoryId){const filter=new URLSearchParams(window.location.href).get("filter");if(filter){var _JSON$parse;const filteredCategoryId=null===(_JSON$parse=JSON.parse(filter))||void 0===_JSON$parse?void 0:_JSON$parse.category.values[0];return this.currentCategoryId=filteredCategoryId>0?filteredCategoryId:null,void(this.targetCategoryId=filteredCategoryId)}this.currentCategoryId=categoryId,this.targetCategoryId=categoryId}show(){return this.display(this.contextId,this.currentCategoryId),super.show()}async display(currentBankContextId,currentCategoryId){const displayPending=new _pending.default("qbank_bulkmove/bulk_move_modal");this.bodyPromise=await Fragment.loadFragment("qbank_bulkmove","bulk_move",currentBankContextId,{categoryid:currentCategoryId}),await this.setBody(this.bodyPromise),await this.enhanceSelects(),this.registerEnhancedEventListeners(),this.updateSaveButtonState(),displayPending.resolve()}registerEnhancedEventListeners(){document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY).addEventListener("change",(()=>{this.updateSaveButtonState()})),document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_BANK).addEventListener("change",(async e=>{0!==parseInt(e.target.value)?(await this.updateCategorySelector(e.currentTarget.value),this.updateSaveButtonState()):await this.updateCategorySelector(null)})),this.getModal().on("click",ModalQuestionBankBulkmove.SELECTORS.SAVE_BUTTON,(e=>{e.preventDefault(),this.displayConfirmMove()}))}async displayConfirmMove(){this.setTitle((0,_str.getString)("confirm","core")),this.setBody((0,_str.getString)("confirmmove","qbank_bulkmove")),this.hasFooterContent()?this.showFooter():(this.setFooter(_templates.default.render("qbank_bulkmove/bulk_move_footer",{})),await this.getFooterPromise(),document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CONFIRM_BUTTON).addEventListener("click",(e=>{e.preventDefault(),this.moveQuestionsAfterConfirm(this.targetBankContextId,this.targetCategoryId)})),document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CANCEL_BUTTON).addEventListener("click",(e=>{e.preventDefault(),this.setTitle((0,_str.getString)("bulkmoveheader","qbank_bulkmove")),this.setBodyContent(_templates.default.renderForPromise("core/loading",{})),this.hideFooter(),this.display(this.targetBankContextId,this.targetCategoryId)})))}updateCategorySelector(selectedBankCmId){return selectedBankCmId?Fragment.loadFragment("core_question","category_selector",this.contextId,{bankcmid:selectedBankCmId}).then(((html,js)=>{const categorySelector=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.QUESTION_CATEGORY_SELECTOR);return _templates.default.replaceNode(categorySelector,html,js)})).then((()=>(document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_WARNING).classList.add("d-none"),this.enhanceSelects()))).catch(_notification.default.exception):(this.updateCategorySelectorState(!1),Promise.resolve())}updateCategorySelectorState(toEnable){const warning=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_WARNING),enhancedInput=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_ENHANCED_INPUT),suggestionButton=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_SUGGESTION),selection=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_SELECTION);toEnable?(warning.classList.add("d-none"),enhancedInput.removeAttribute("disabled"),suggestionButton.classList.remove("d-none")):(warning.classList.remove("d-none"),enhancedInput.setAttribute("disabled","disabled"),suggestionButton.classList.add("d-none"),selection.click())}updateSaveButtonState(){const saveButton=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SAVE_BUTTON),categorySelector=document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY);[this.targetCategoryId,this.targetBankContextId]=categorySelector.value.split(","),this.targetCategoryId&&this.targetCategoryId!==this.currentCategoryId?saveButton.removeAttribute("disabled"):saveButton.setAttribute("disabled","disabled")}async moveQuestionsAfterConfirm(targetContextId,targetCategoryId){await this.setBody(_templates.default.render("core/loading",{}));const qelements=document.querySelectorAll(ModalQuestionBankBulkmove.SELECTORS.SELECTED_QUESTIONS),questionids=[];qelements.forEach((element=>{if(element.checked){const name=element.getAttribute("name");questionids.push(name.substr(1,name.length))}})),0===questionids.length&&await _notification.default.exception("No questions selected");try{window.location.href=await(0,_repository.moveQuestions)(targetContextId,targetCategoryId,questionids.join(),window.location.href)}catch(error){await _notification.default.exception(error)}}async enhanceSelects(){const placeholder=await(0,_str.getString)("searchbyname","mod_quiz");await _formAutocomplete.default.enhance(ModalQuestionBankBulkmove.SELECTORS.SEARCH_BANK,!1,"core_question/question_banks_datasource",placeholder,!1,!0,"",!0),await _formAutocomplete.default.enhance(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY,!1,null,placeholder,!1,!0,"",!0)}}return _exports.default=ModalQuestionBankBulkmove,_defineProperty(ModalQuestionBankBulkmove,"TYPE","qbank_bulkmove/bulkmove"),_defineProperty(ModalQuestionBankBulkmove,"SELECTORS",{SAVE_BUTTON:'[data-action="bulkmovesave"]',SELECTED_QUESTIONS:'table#categoryquestions input[id^="checkq"]',SEARCH_BANK:"#searchbanks",SEARCH_CATEGORY:".selectcategory",QUESTION_CATEGORY_SELECTOR:".question_category_selector",CATEGORY_OPTIONS:".selectcategory option",BANK_OPTIONS:"#searchbanks option",CATEGORY_ENHANCED_INPUT:".search-categories input",ORIGINAL_SELECTS:"select.bulk-move",CATEGORY_WARNING:"#searchcatwarning",CATEGORY_SUGGESTION:".search-categories span.form-autocomplete-downarrow",CATEGORY_SELECTION:'.search-categories span[role="option"][data-active-selection="true"]',CONFIRM_BUTTON:'.bulk-move-footer button[data-action="save"]',CANCEL_BUTTON:'.bulk-move-footer button[data-action="cancel"]'}),_exports.default})); //# sourceMappingURL=modal_question_bank_bulkmove.min.js.map \ No newline at end of file diff --git a/public/question/bank/bulkmove/amd/build/modal_question_bank_bulkmove.min.js.map b/public/question/bank/bulkmove/amd/build/modal_question_bank_bulkmove.min.js.map index e7e76da3dca..ff104492040 100644 --- a/public/question/bank/bulkmove/amd/build/modal_question_bank_bulkmove.min.js.map +++ b/public/question/bank/bulkmove/amd/build/modal_question_bank_bulkmove.min.js.map @@ -1 +1 @@ -{"version":3,"file":"modal_question_bank_bulkmove.min.js","sources":["../src/modal_question_bank_bulkmove.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 .\n\n/**\n * Contain the logic for the bulkmove questions modal.\n *\n * @module qbank_bulkmove/modal_question_bank_bulkmove\n * @copyright 2024 onwards Catalyst IT EU {@link https://catalyst-eu.net}\n * @author Simon Adams \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Modal from 'core/modal';\nimport * as Fragment from 'core/fragment';\nimport {getString} from 'core/str';\nimport AutoComplete from 'core/form-autocomplete';\nimport {moveQuestions} from 'core_question/repository';\nimport Templates from 'core/templates';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\n\n\nexport default class ModalQuestionBankBulkmove extends Modal {\n static TYPE = 'qbank_bulkmove/bulkmove';\n\n static SELECTORS = {\n SAVE_BUTTON: '[data-action=\"bulkmovesave\"]',\n SELECTED_QUESTIONS: 'table#categoryquestions input[id^=\"checkq\"]',\n SEARCH_BANK: '#searchbanks',\n SEARCH_CATEGORY: '.selectcategory',\n QUESTION_CATEGORY_SELECTOR: '.question_category_selector',\n CATEGORY_OPTIONS: '.selectcategory option',\n BANK_OPTIONS: '#searchbanks option',\n CATEGORY_ENHANCED_INPUT: '.search-categories input',\n ORIGINAL_SELECTS: 'select.bulk-move',\n CATEGORY_WARNING: '#searchcatwarning',\n CATEGORY_SUGGESTION: '.search-categories span.form-autocomplete-downarrow',\n CATEGORY_SELECTION: '.search-categories span[role=\"option\"][data-active-selection=\"true\"]',\n CONFIRM_BUTTON: '.bulk-move-footer button[data-action=\"save\"]',\n CANCEL_BUTTON: '.bulk-move-footer button[data-action=\"cancel\"]'\n };\n\n /**\n * @param {integer} contextId The current bank context id.\n * @param {integer} categoryId The current question category id.\n */\n static init(contextId, categoryId) {\n document.addEventListener('click', (e) => {\n const trigger = e.target;\n if (trigger.classList.contains('dropdown-item') && trigger.getAttribute('name') === 'move') {\n e.preventDefault();\n ModalQuestionBankBulkmove.create({\n contextId,\n title: getString('bulkmoveheader', 'qbank_bulkmove'),\n show: true,\n categoryId: categoryId,\n });\n }\n });\n }\n\n /**\n * Set the initialised config on the class.\n *\n * @param {Object} modalConfig\n */\n configure(modalConfig) {\n this.contextId = modalConfig.contextId;\n this.targetBankContextId = modalConfig.contextId;\n this.initSelectedCategoryId(modalConfig.categoryId);\n modalConfig.removeOnClose = true;\n super.configure(modalConfig);\n }\n\n /**\n * Initialise the category select based on the data passed to the JS or if a filter is applied in the url.\n * @param {integer} categoryId\n */\n initSelectedCategoryId(categoryId) {\n const filter = new URLSearchParams(window.location.href).get('filter');\n if (filter) {\n const filteredCategoryId = JSON.parse(filter)?.category.values[0];\n this.currentCategoryId = filteredCategoryId > 0 ? filteredCategoryId : null;\n this.targetCategoryId = filteredCategoryId;\n return;\n }\n this.currentCategoryId = categoryId;\n this.targetCategoryId = categoryId;\n }\n\n /**\n * Render the modal contents.\n * @return {Promise}\n */\n show() {\n void this.display(this.contextId, this.currentCategoryId);\n return super.show();\n }\n\n /**\n * Get the content to display and enhance the selects into auto complete fields.\n * @param {integer} currentBankContextId\n * @param {integer} currentCategoryId\n */\n async display(currentBankContextId, currentCategoryId) {\n const displayPending = new Pending('qbank_bulkmove/bulk_move_modal');\n this.bodyPromise = await Fragment.loadFragment(\n 'qbank_bulkmove',\n 'bulk_move',\n currentBankContextId,\n {\n 'categoryid': currentCategoryId,\n }\n );\n\n await this.setBody(this.bodyPromise);\n await this.enhanceSelects();\n this.registerEnhancedEventListeners();\n this.updateSaveButtonState();\n displayPending.resolve();\n }\n\n /**\n * Register event listeners on the enhanced selects. Must be done after they have been enhanced.\n */\n registerEnhancedEventListeners() {\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY).addEventListener(\"change\", () => {\n this.updateSaveButtonState();\n });\n\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_BANK).addEventListener(\"change\", async(e) => {\n await this.updateCategorySelector(e.currentTarget.value);\n this.updateSaveButtonState();\n });\n\n this.getModal().on(\"click\", ModalQuestionBankBulkmove.SELECTORS.SAVE_BUTTON, (e) => {\n e.preventDefault();\n void this.displayConfirmMove();\n });\n }\n\n /**\n * Update the body with a confirmation prompt and set confirm cancel buttons in the footer.\n * @return {Promise}\n */\n async displayConfirmMove() {\n this.setTitle(getString('confirm', 'core'));\n this.setBody(getString('confirmmove', 'qbank_bulkmove'));\n if (!this.hasFooterContent()) {\n // We don't have the footer yet so go grab it and register event listeners on the buttons.\n this.setFooter(Templates.render('qbank_bulkmove/bulk_move_footer', {}));\n await this.getFooterPromise();\n\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CONFIRM_BUTTON).addEventListener(\"click\", (e) => {\n e.preventDefault();\n this.moveQuestionsAfterConfirm(this.targetBankContextId, this.targetCategoryId);\n });\n\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CANCEL_BUTTON).addEventListener(\"click\", (e) => {\n e.preventDefault();\n this.setTitle(getString('bulkmoveheader', 'qbank_bulkmove'));\n this.setBodyContent(Templates.renderForPromise('core/loading', {}));\n this.hideFooter();\n this.display(this.targetBankContextId, this.targetCategoryId);\n });\n } else {\n // We already have a footer so just show it.\n this.showFooter();\n }\n }\n\n /**\n * Update the category selector based on the selected question bank.\n *\n * @param {Number} selectedBankCmId\n * @return {Promise} Resolved when the update is complete.\n */\n updateCategorySelector(selectedBankCmId) {\n if (!selectedBankCmId) {\n this.updateCategorySelectorState(false);\n return Promise.resolve();\n } else {\n return Fragment.loadFragment(\n 'core_question',\n 'category_selector',\n this.contextId,\n {\n 'bankcmid': selectedBankCmId,\n }\n )\n .then((html, js) => {\n const categorySelector = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.QUESTION_CATEGORY_SELECTOR);\n return Templates.replaceNode(categorySelector, html, js);\n })\n .then(() => {\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_WARNING).classList.add('d-none');\n return this.enhanceSelects();\n })\n .catch(Notification.exception);\n }\n }\n\n /**\n * Disable/enable the enhanced category selector field.\n * @param {boolean} toEnable True to enable, false to disable the field.\n */\n updateCategorySelectorState(toEnable) {\n const warning = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_WARNING);\n const enhancedInput = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_ENHANCED_INPUT);\n const suggestionButton = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_SUGGESTION);\n const selection = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_SELECTION);\n\n if (toEnable) {\n warning.classList.add('d-none');\n enhancedInput.removeAttribute('disabled');\n suggestionButton.classList.remove('d-none');\n } else {\n warning.classList.remove('d-none');\n enhancedInput.setAttribute('disabled', 'disabled');\n suggestionButton.classList.add('d-none');\n selection.click(); // Clear selected category.\n }\n }\n\n /**\n * Disable the button if the selected category is the same as the one the questions already belong to. Enable it otherwise.\n */\n updateSaveButtonState() {\n const saveButton = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SAVE_BUTTON);\n const categorySelector = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY);\n [this.targetCategoryId, this.targetBankContextId] = categorySelector.value.split(',');\n\n if (this.targetCategoryId && this.targetCategoryId !== this.currentCategoryId) {\n saveButton.removeAttribute('disabled');\n } else {\n saveButton.setAttribute('disabled', 'disabled');\n }\n }\n\n /**\n * Move the selected questions to their new target category.\n * @param {integer} targetContextId the target bank context id.\n * @param {integer} targetCategoryId the target question category id.\n * @return {Promise}\n */\n async moveQuestionsAfterConfirm(targetContextId, targetCategoryId) {\n await this.setBody(Templates.render('core/loading', {}));\n const qelements = document.querySelectorAll(ModalQuestionBankBulkmove.SELECTORS.SELECTED_QUESTIONS);\n const questionids = [];\n qelements.forEach((element) => {\n if (element.checked) {\n const name = element.getAttribute('name');\n questionids.push(name.substr(1, name.length));\n }\n });\n if (questionids.length === 0) {\n await Notification.exception('No questions selected');\n }\n\n try {\n window.location.href = await moveQuestions(\n targetContextId,\n targetCategoryId,\n questionids.join(),\n window.location.href\n );\n } catch (error) {\n await Notification.exception(error);\n }\n }\n\n /**\n * Take the provided select options and enhance them into auto-complete fields.\n *\n * @return {Promise}\n */\n async enhanceSelects() {\n const placeholder = await getString('searchbyname', 'mod_quiz');\n\n await AutoComplete.enhance(\n ModalQuestionBankBulkmove.SELECTORS.SEARCH_BANK,\n false,\n 'core_question/question_banks_datasource',\n placeholder,\n false,\n true,\n '',\n true,\n );\n\n await AutoComplete.enhance(\n ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY,\n false,\n null,\n placeholder,\n false,\n true,\n '',\n true,\n );\n }\n}\n"],"names":["ModalQuestionBankBulkmove","Modal","contextId","categoryId","document","addEventListener","e","trigger","target","classList","contains","getAttribute","preventDefault","create","title","show","configure","modalConfig","targetBankContextId","initSelectedCategoryId","removeOnClose","filter","URLSearchParams","window","location","href","get","filteredCategoryId","JSON","parse","_JSON$parse","category","values","currentCategoryId","targetCategoryId","this","display","super","currentBankContextId","displayPending","Pending","bodyPromise","Fragment","loadFragment","setBody","enhanceSelects","registerEnhancedEventListeners","updateSaveButtonState","resolve","querySelector","SELECTORS","SEARCH_CATEGORY","SEARCH_BANK","async","updateCategorySelector","currentTarget","value","getModal","on","SAVE_BUTTON","displayConfirmMove","setTitle","hasFooterContent","showFooter","setFooter","Templates","render","getFooterPromise","CONFIRM_BUTTON","moveQuestionsAfterConfirm","CANCEL_BUTTON","setBodyContent","renderForPromise","hideFooter","selectedBankCmId","then","html","js","categorySelector","QUESTION_CATEGORY_SELECTOR","replaceNode","CATEGORY_WARNING","add","catch","Notification","exception","updateCategorySelectorState","Promise","toEnable","warning","enhancedInput","CATEGORY_ENHANCED_INPUT","suggestionButton","CATEGORY_SUGGESTION","selection","CATEGORY_SELECTION","removeAttribute","remove","setAttribute","click","saveButton","split","targetContextId","qelements","querySelectorAll","SELECTED_QUESTIONS","questionids","forEach","element","checked","name","push","substr","length","join","error","placeholder","AutoComplete","enhance","CATEGORY_OPTIONS","BANK_OPTIONS","ORIGINAL_SELECTS"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"modal_question_bank_bulkmove.min.js","sources":["../src/modal_question_bank_bulkmove.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 .\n\n/**\n * Contain the logic for the bulkmove questions modal.\n *\n * @module qbank_bulkmove/modal_question_bank_bulkmove\n * @copyright 2024 onwards Catalyst IT EU {@link https://catalyst-eu.net}\n * @author Simon Adams \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Modal from 'core/modal';\nimport * as Fragment from 'core/fragment';\nimport {getString} from 'core/str';\nimport AutoComplete from 'core/form-autocomplete';\nimport {moveQuestions} from 'core_question/repository';\nimport Templates from 'core/templates';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\n\n\nexport default class ModalQuestionBankBulkmove extends Modal {\n static TYPE = 'qbank_bulkmove/bulkmove';\n\n static SELECTORS = {\n SAVE_BUTTON: '[data-action=\"bulkmovesave\"]',\n SELECTED_QUESTIONS: 'table#categoryquestions input[id^=\"checkq\"]',\n SEARCH_BANK: '#searchbanks',\n SEARCH_CATEGORY: '.selectcategory',\n QUESTION_CATEGORY_SELECTOR: '.question_category_selector',\n CATEGORY_OPTIONS: '.selectcategory option',\n BANK_OPTIONS: '#searchbanks option',\n CATEGORY_ENHANCED_INPUT: '.search-categories input',\n ORIGINAL_SELECTS: 'select.bulk-move',\n CATEGORY_WARNING: '#searchcatwarning',\n CATEGORY_SUGGESTION: '.search-categories span.form-autocomplete-downarrow',\n CATEGORY_SELECTION: '.search-categories span[role=\"option\"][data-active-selection=\"true\"]',\n CONFIRM_BUTTON: '.bulk-move-footer button[data-action=\"save\"]',\n CANCEL_BUTTON: '.bulk-move-footer button[data-action=\"cancel\"]'\n };\n\n /**\n * @param {integer} contextId The current bank context id.\n * @param {integer} categoryId The current question category id.\n */\n static init(contextId, categoryId) {\n document.addEventListener('click', (e) => {\n const trigger = e.target;\n if (trigger.classList.contains('dropdown-item') && trigger.getAttribute('name') === 'move') {\n e.preventDefault();\n ModalQuestionBankBulkmove.create({\n contextId,\n title: getString('bulkmoveheader', 'qbank_bulkmove'),\n show: true,\n categoryId: categoryId,\n });\n }\n });\n }\n\n /**\n * Set the initialised config on the class.\n *\n * @param {Object} modalConfig\n */\n configure(modalConfig) {\n this.contextId = modalConfig.contextId;\n this.targetBankContextId = modalConfig.contextId;\n this.initSelectedCategoryId(modalConfig.categoryId);\n modalConfig.removeOnClose = true;\n super.configure(modalConfig);\n }\n\n /**\n * Initialise the category select based on the data passed to the JS or if a filter is applied in the url.\n * @param {integer} categoryId\n */\n initSelectedCategoryId(categoryId) {\n const filter = new URLSearchParams(window.location.href).get('filter');\n if (filter) {\n const filteredCategoryId = JSON.parse(filter)?.category.values[0];\n this.currentCategoryId = filteredCategoryId > 0 ? filteredCategoryId : null;\n this.targetCategoryId = filteredCategoryId;\n return;\n }\n this.currentCategoryId = categoryId;\n this.targetCategoryId = categoryId;\n }\n\n /**\n * Render the modal contents.\n * @return {Promise}\n */\n show() {\n void this.display(this.contextId, this.currentCategoryId);\n return super.show();\n }\n\n /**\n * Get the content to display and enhance the selects into auto complete fields.\n * @param {integer} currentBankContextId\n * @param {integer} currentCategoryId\n */\n async display(currentBankContextId, currentCategoryId) {\n const displayPending = new Pending('qbank_bulkmove/bulk_move_modal');\n this.bodyPromise = await Fragment.loadFragment(\n 'qbank_bulkmove',\n 'bulk_move',\n currentBankContextId,\n {\n 'categoryid': currentCategoryId,\n }\n );\n\n await this.setBody(this.bodyPromise);\n await this.enhanceSelects();\n this.registerEnhancedEventListeners();\n this.updateSaveButtonState();\n displayPending.resolve();\n }\n\n /**\n * Register event listeners on the enhanced selects. Must be done after they have been enhanced.\n */\n registerEnhancedEventListeners() {\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY).addEventListener(\"change\", () => {\n this.updateSaveButtonState();\n });\n\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_BANK).addEventListener(\"change\", async(e) => {\n if (parseInt(e.target.value) === 0) {\n // The autocomplete contains a dummy option containing the text that the limit has been reached and the user\n // has to refine the search. Selection of this dummy option has to be handled separately.\n await this.updateCategorySelector(null);\n return;\n }\n await this.updateCategorySelector(e.currentTarget.value);\n this.updateSaveButtonState();\n });\n\n this.getModal().on(\"click\", ModalQuestionBankBulkmove.SELECTORS.SAVE_BUTTON, (e) => {\n e.preventDefault();\n void this.displayConfirmMove();\n });\n }\n\n /**\n * Update the body with a confirmation prompt and set confirm cancel buttons in the footer.\n * @return {Promise}\n */\n async displayConfirmMove() {\n this.setTitle(getString('confirm', 'core'));\n this.setBody(getString('confirmmove', 'qbank_bulkmove'));\n if (!this.hasFooterContent()) {\n // We don't have the footer yet so go grab it and register event listeners on the buttons.\n this.setFooter(Templates.render('qbank_bulkmove/bulk_move_footer', {}));\n await this.getFooterPromise();\n\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CONFIRM_BUTTON).addEventListener(\"click\", (e) => {\n e.preventDefault();\n this.moveQuestionsAfterConfirm(this.targetBankContextId, this.targetCategoryId);\n });\n\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CANCEL_BUTTON).addEventListener(\"click\", (e) => {\n e.preventDefault();\n this.setTitle(getString('bulkmoveheader', 'qbank_bulkmove'));\n this.setBodyContent(Templates.renderForPromise('core/loading', {}));\n this.hideFooter();\n this.display(this.targetBankContextId, this.targetCategoryId);\n });\n } else {\n // We already have a footer so just show it.\n this.showFooter();\n }\n }\n\n /**\n * Update the category selector based on the selected question bank.\n *\n * @param {Number} selectedBankCmId\n * @return {Promise} Resolved when the update is complete.\n */\n updateCategorySelector(selectedBankCmId) {\n if (!selectedBankCmId) {\n this.updateCategorySelectorState(false);\n return Promise.resolve();\n } else {\n return Fragment.loadFragment(\n 'core_question',\n 'category_selector',\n this.contextId,\n {\n 'bankcmid': selectedBankCmId,\n }\n )\n .then((html, js) => {\n const categorySelector = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.QUESTION_CATEGORY_SELECTOR);\n return Templates.replaceNode(categorySelector, html, js);\n })\n .then(() => {\n document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_WARNING).classList.add('d-none');\n return this.enhanceSelects();\n })\n .catch(Notification.exception);\n }\n }\n\n /**\n * Disable/enable the enhanced category selector field.\n * @param {boolean} toEnable True to enable, false to disable the field.\n */\n updateCategorySelectorState(toEnable) {\n const warning = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_WARNING);\n const enhancedInput = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_ENHANCED_INPUT);\n const suggestionButton = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_SUGGESTION);\n const selection = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.CATEGORY_SELECTION);\n\n if (toEnable) {\n warning.classList.add('d-none');\n enhancedInput.removeAttribute('disabled');\n suggestionButton.classList.remove('d-none');\n } else {\n warning.classList.remove('d-none');\n enhancedInput.setAttribute('disabled', 'disabled');\n suggestionButton.classList.add('d-none');\n selection.click(); // Clear selected category.\n }\n }\n\n /**\n * Disable the button if the selected category is the same as the one the questions already belong to. Enable it otherwise.\n */\n updateSaveButtonState() {\n const saveButton = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SAVE_BUTTON);\n const categorySelector = document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY);\n [this.targetCategoryId, this.targetBankContextId] = categorySelector.value.split(',');\n\n if (this.targetCategoryId && this.targetCategoryId !== this.currentCategoryId) {\n saveButton.removeAttribute('disabled');\n } else {\n saveButton.setAttribute('disabled', 'disabled');\n }\n }\n\n /**\n * Move the selected questions to their new target category.\n * @param {integer} targetContextId the target bank context id.\n * @param {integer} targetCategoryId the target question category id.\n * @return {Promise}\n */\n async moveQuestionsAfterConfirm(targetContextId, targetCategoryId) {\n await this.setBody(Templates.render('core/loading', {}));\n const qelements = document.querySelectorAll(ModalQuestionBankBulkmove.SELECTORS.SELECTED_QUESTIONS);\n const questionids = [];\n qelements.forEach((element) => {\n if (element.checked) {\n const name = element.getAttribute('name');\n questionids.push(name.substr(1, name.length));\n }\n });\n if (questionids.length === 0) {\n await Notification.exception('No questions selected');\n }\n\n try {\n window.location.href = await moveQuestions(\n targetContextId,\n targetCategoryId,\n questionids.join(),\n window.location.href\n );\n } catch (error) {\n await Notification.exception(error);\n }\n }\n\n /**\n * Take the provided select options and enhance them into auto-complete fields.\n *\n * @return {Promise}\n */\n async enhanceSelects() {\n const placeholder = await getString('searchbyname', 'mod_quiz');\n\n await AutoComplete.enhance(\n ModalQuestionBankBulkmove.SELECTORS.SEARCH_BANK,\n false,\n 'core_question/question_banks_datasource',\n placeholder,\n false,\n true,\n '',\n true,\n );\n\n await AutoComplete.enhance(\n ModalQuestionBankBulkmove.SELECTORS.SEARCH_CATEGORY,\n false,\n null,\n placeholder,\n false,\n true,\n '',\n true,\n );\n }\n}\n"],"names":["ModalQuestionBankBulkmove","Modal","contextId","categoryId","document","addEventListener","e","trigger","target","classList","contains","getAttribute","preventDefault","create","title","show","configure","modalConfig","targetBankContextId","initSelectedCategoryId","removeOnClose","filter","URLSearchParams","window","location","href","get","filteredCategoryId","JSON","parse","_JSON$parse","category","values","currentCategoryId","targetCategoryId","this","display","super","currentBankContextId","displayPending","Pending","bodyPromise","Fragment","loadFragment","setBody","enhanceSelects","registerEnhancedEventListeners","updateSaveButtonState","resolve","querySelector","SELECTORS","SEARCH_CATEGORY","SEARCH_BANK","async","parseInt","value","updateCategorySelector","currentTarget","getModal","on","SAVE_BUTTON","displayConfirmMove","setTitle","hasFooterContent","showFooter","setFooter","Templates","render","getFooterPromise","CONFIRM_BUTTON","moveQuestionsAfterConfirm","CANCEL_BUTTON","setBodyContent","renderForPromise","hideFooter","selectedBankCmId","then","html","js","categorySelector","QUESTION_CATEGORY_SELECTOR","replaceNode","CATEGORY_WARNING","add","catch","Notification","exception","updateCategorySelectorState","Promise","toEnable","warning","enhancedInput","CATEGORY_ENHANCED_INPUT","suggestionButton","CATEGORY_SUGGESTION","selection","CATEGORY_SELECTION","removeAttribute","remove","setAttribute","click","saveButton","split","targetContextId","qelements","querySelectorAll","SELECTED_QUESTIONS","questionids","forEach","element","checked","name","push","substr","length","join","error","placeholder","AutoComplete","enhance","CATEGORY_OPTIONS","BANK_OPTIONS","ORIGINAL_SELECTS"],"mappings":"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"} \ No newline at end of file diff --git a/public/question/bank/bulkmove/amd/src/modal_question_bank_bulkmove.js b/public/question/bank/bulkmove/amd/src/modal_question_bank_bulkmove.js index 9d398bd8230..1252bb8ed08 100644 --- a/public/question/bank/bulkmove/amd/src/modal_question_bank_bulkmove.js +++ b/public/question/bank/bulkmove/amd/src/modal_question_bank_bulkmove.js @@ -141,6 +141,12 @@ export default class ModalQuestionBankBulkmove extends Modal { }); document.querySelector(ModalQuestionBankBulkmove.SELECTORS.SEARCH_BANK).addEventListener("change", async(e) => { + if (parseInt(e.target.value) === 0) { + // The autocomplete contains a dummy option containing the text that the limit has been reached and the user + // has to refine the search. Selection of this dummy option has to be handled separately. + await this.updateCategorySelector(null); + return; + } await this.updateCategorySelector(e.currentTarget.value); this.updateSaveButtonState(); }); diff --git a/public/question/bank/bulkmove/tests/behat/bulk_move.feature b/public/question/bank/bulkmove/tests/behat/bulk_move.feature index fbd3d42a9d6..33da2440b14 100644 --- a/public/question/bank/bulkmove/tests/behat/bulk_move.feature +++ b/public/question/bank/bulkmove/tests/behat/bulk_move.feature @@ -221,3 +221,58 @@ Feature: Use the qbank plugin manager page for bulkmove And I click on "move" "button" And I open the autocomplete suggestions list in the ".search-banks" "css_element" Then "New question bank" "autocomplete_suggestions" should exist + + @javascript + Scenario: Clicking the dummy option for showing the reached limit in course does not throw an error + Given the following "activities" exist: + | activity | name | course | idnumber | + | qbank | Question bank Course 1 1 | C1 | qbankc101 | + | qbank | Question bank Course 1 2 | C1 | qbankc102 | + | qbank | Question bank Course 1 3 | C1 | qbankc103 | + | qbank | Question bank Course 1 4 | C1 | qbankc104 | + | qbank | Question bank Course 1 5 | C1 | qbankc105 | + | qbank | Question bank Course 1 6 | C1 | qbankc106 | + | qbank | Question bank Course 1 7 | C1 | qbankc107 | + | qbank | Question bank Course 1 8 | C1 | qbankc108 | + | qbank | Question bank Course 1 9 | C1 | qbankc109 | + | qbank | Question bank Course 1 10 | C1 | qbankc110 | + | qbank | Question bank Course 2 1 | C2 | qbankc201 | + | qbank | Question bank Course 2 2 | C2 | qbankc202 | + | qbank | Question bank Course 2 3 | C2 | qbankc203 | + | qbank | Question bank Course 2 4 | C2 | qbankc204 | + | qbank | Question bank Course 2 5 | C2 | qbankc205 | + | qbank | Question bank Course 2 6 | C2 | qbankc206 | + | qbank | Question bank Course 2 7 | C2 | qbankc207 | + | qbank | Question bank Course 2 8 | C2 | qbankc208 | + | qbank | Question bank Course 2 9 | C2 | qbankc209 | + | qbank | Question bank Course 2 10 | C2 | qbankc210 | + | qbank | Question bank Course 3 1 | C3 | qbankc301 | + | qbank | Question bank Course 3 2 | C3 | qbankc302 | + | qbank | Question bank Course 3 2 | C3 | qbankc303 | + | qbank | Question bank Course 3 4 | C3 | qbankc304 | + | qbank | Question bank Course 3 5 | C3 | qbankc305 | + | qbank | Question bank Course 3 6 | C3 | qbankc306 | + | qbank | Question bank Course 3 7 | C3 | qbankc307 | + | qbank | Question bank Course 3 8 | C3 | qbankc308 | + | qbank | Question bank Course 3 9 | C3 | qbankc309 | + | qbank | Question bank Course 3 10 | C3 | qbankc310 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C3 | editingteacher | + When I am on the "C1" "Course" page logged in as "teacher1" + And I navigate to "Question banks" in current page administration + And I follow "Question bank 1" + And I select "Categories" from the "Question bank tertiary navigation" singleselect + And I follow "Test questions 5" + And I click on "Fifth question" "checkbox" + And I click on "With selected" "button" + And I click on "move" "button" + And I wait until the page is ready + And "Question bank" "autocomplete_selection" should exist + And I press the tab key + And I press the tab key + And I press the tab key + And I type "Question bank Course" + Then I click on "More than 20 results. You need to refine your search." item in the autocomplete list + And "More than 20 results. You need to refine your search." "autocomplete_selection" should exist + And I should see "You must select a question bank before you can select a category."