MDL-74054 qbank_viewquestiontext: Convert from filter to question bank control

This replaces the "Show question text in the question list?" filter, which was
never really a filter, with a new widget displayed alongside other question bank
controls like "Create a new question" and "Reset columns".

It also refactors the logic of displaying the question text field or not, so that
it is all handled within the qbank_viewquestiontext plugin rather than relying on
code in the view.
This commit is contained in:
Mark Johnson 2023-09-05 16:25:59 +01:00 committed by Andrew Nicols
parent 63894ec2fe
commit 33e52fe4ed
No known key found for this signature in database
GPG Key ID: 6D1E3157C8CFBF14
27 changed files with 532 additions and 182 deletions

10
question/amd/build/refresh_ui.min.js vendored Normal file
View File

@ -0,0 +1,10 @@
define("core_question/refresh_ui",["exports","core/fragment","core/templates"],(function(_exports,_fragment,_templates){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Question bank UI refresh utility
*
* @module core_question/refresh_ui
* @copyright 2023 Catalyst IT Europe Ltd.
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_fragment=_interopRequireDefault(_fragment),_templates=_interopRequireDefault(_templates);var _default={refresh:(uiRoot,returnUrl)=>new Promise(((resolve,reject)=>{const fragmentData=uiRoot.dataset,viewData={},sortData={};returnUrl&&returnUrl.searchParams.forEach(((value,key)=>{const sortItem=key.match(/sortdata\[([^\]]+)\]/);sortItem?sortData[sortItem.pop()]=value:viewData[key]=value})),viewData.sortdata=JSON.stringify(sortData),_fragment.default.loadFragment(fragmentData.component,fragmentData.callback,fragmentData.contextid,viewData).then(((html,js)=>(_templates.default.replaceNode(uiRoot,html,js),resolve(),html))).catch(reject)}))};return _exports.default=_default,_exports.default}));
//# sourceMappingURL=refresh_ui.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"refresh_ui.min.js","sources":["../src/refresh_ui.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 * Question bank UI refresh utility\n *\n * @module core_question/refresh_ui\n * @copyright 2023 Catalyst IT Europe Ltd.\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Fragment from 'core/fragment';\nimport Templates from 'core/templates';\n\nexport default {\n /**\n * Reload the question bank UI, retaining the current filters and sort data.\n *\n * @param {Element} uiRoot The root element of the UI to be refreshed. Must contain \"component\", \"callback\" and \"contextid\" in\n * its data attributes, to be passed to the Fragment API.\n * @param {URL} returnUrl The url of the current page, containing filter and sort parameters.\n * @return {Promise} Resolved when the refresh is complete.\n */\n refresh: (uiRoot, returnUrl) => {\n return new Promise((resolve, reject) => {\n const fragmentData = uiRoot.dataset;\n const viewData = {};\n const sortData = {};\n if (returnUrl) {\n returnUrl.searchParams.forEach((value, key) => {\n // Match keys like 'sortdata[fieldname]' and convert them to an array,\n // because the fragment API doesn't like non-alphanum argument keys.\n const sortItem = key.match(/sortdata\\[([^\\]]+)\\]/);\n if (sortItem) {\n // The item returned by sortItem.pop() is the contents of the matching group, the field name.\n sortData[sortItem.pop()] = value;\n } else {\n viewData[key] = value;\n }\n });\n }\n viewData.sortdata = JSON.stringify(sortData);\n // We have to use then() there, as loadFragment doesn't appear to work with await.\n Fragment.loadFragment(fragmentData.component, fragmentData.callback, fragmentData.contextid, viewData)\n .then((html, js) => {\n Templates.replaceNode(uiRoot, html, js);\n resolve();\n return html;\n })\n .catch(reject);\n });\n }\n};\n"],"names":["refresh","uiRoot","returnUrl","Promise","resolve","reject","fragmentData","dataset","viewData","sortData","searchParams","forEach","value","key","sortItem","match","pop","sortdata","JSON","stringify","loadFragment","component","callback","contextid","then","html","js","replaceNode","catch"],"mappings":";;;;;;;4LA0Be,CASXA,QAAS,CAACC,OAAQC,YACP,IAAIC,SAAQ,CAACC,QAASC,gBACnBC,aAAeL,OAAOM,QACtBC,SAAW,GACXC,SAAW,GACbP,WACAA,UAAUQ,aAAaC,SAAQ,CAACC,MAAOC,aAG7BC,SAAWD,IAAIE,MAAM,wBACvBD,SAEAL,SAASK,SAASE,OAASJ,MAE3BJ,SAASK,KAAOD,SAI5BJ,SAASS,SAAWC,KAAKC,UAAUV,4BAE1BW,aAAad,aAAae,UAAWf,aAAagB,SAAUhB,aAAaiB,UAAWf,UACxFgB,MAAK,CAACC,KAAMC,yBACCC,YAAY1B,OAAQwB,KAAMC,IACpCtB,UACOqB,QAEVG,MAAMvB"}

View File

@ -0,0 +1,65 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Question bank UI refresh utility
*
* @module core_question/refresh_ui
* @copyright 2023 Catalyst IT Europe Ltd.
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Fragment from 'core/fragment';
import Templates from 'core/templates';
export default {
/**
* Reload the question bank UI, retaining the current filters and sort data.
*
* @param {Element} uiRoot The root element of the UI to be refreshed. Must contain "component", "callback" and "contextid" in
* its data attributes, to be passed to the Fragment API.
* @param {URL} returnUrl The url of the current page, containing filter and sort parameters.
* @return {Promise} Resolved when the refresh is complete.
*/
refresh: (uiRoot, returnUrl) => {
return new Promise((resolve, reject) => {
const fragmentData = uiRoot.dataset;
const viewData = {};
const sortData = {};
if (returnUrl) {
returnUrl.searchParams.forEach((value, key) => {
// Match keys like 'sortdata[fieldname]' and convert them to an array,
// because the fragment API doesn't like non-alphanum argument keys.
const sortItem = key.match(/sortdata\[([^\]]+)\]/);
if (sortItem) {
// The item returned by sortItem.pop() is the contents of the matching group, the field name.
sortData[sortItem.pop()] = value;
} else {
viewData[key] = value;
}
});
}
viewData.sortdata = JSON.stringify(sortData);
// We have to use then() there, as loadFragment doesn't appear to work with await.
Fragment.loadFragment(fragmentData.component, fragmentData.callback, fragmentData.contextid, viewData)
.then((html, js) => {
Templates.replaceNode(uiRoot, html, js);
resolve();
return html;
})
.catch(reject);
});
}
};

View File

@ -1,4 +1,4 @@
define("qbank_columnsortorder/actions",["exports","core/sortable_list","jquery","qbank_columnsortorder/repository","core/notification","core/fragment","core/templates"],(function(_exports,_sortable_list,_jquery,repository,_notification,_fragment,_templates){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}}
define("qbank_columnsortorder/actions",["exports","core/sortable_list","jquery","qbank_columnsortorder/repository","core/notification","core_question/refresh_ui"],(function(_exports,_sortable_list,_jquery,repository,_notification,_refresh_ui){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}}
/**
* Common javascript for handling actions on the admin page and the user's view of the question bank.
*
@ -6,6 +6,6 @@ define("qbank_columnsortorder/actions",["exports","core/sortable_list","jquery",
* @copyright 2023 onwards Catalyst IT Europe Ltd
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setupSortableLists=_exports.setupActionButtons=_exports.getColumnOrder=_exports.SELECTORS=void 0,_sortable_list=_interopRequireDefault(_sortable_list),_jquery=_interopRequireDefault(_jquery),repository=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}(repository),_notification=_interopRequireDefault(_notification),_fragment=_interopRequireDefault(_fragment),_templates=_interopRequireDefault(_templates);const SELECTORS={columnList:".qbank-column-list",sortableColumn:".qbank-sortable-column",removeLink:"[data-action=remove]",moveHandler:"[data-drag-type=move]",addColumn:".addcolumn",addLink:"[data-action=add]",actionLink:".action-link"};_exports.SELECTORS=SELECTORS;_exports.setupSortableLists=function(listRoot){let vertical=arguments.length>1&&void 0!==arguments[1]&&arguments[1],global=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const sortableList=new _sortable_list.default(listRoot,{moveHandlerSelector:SELECTORS.moveHandler,isHorizontal:!vertical});sortableList.getElementName=element=>Promise.resolve(element.data("name"));const sortableColumns=(0,_jquery.default)(SELECTORS.sortableColumn);return sortableColumns.on(_sortable_list.default.EVENTS.DROP,(()=>{repository.setColumnbankOrder(getColumnOrder(listRoot),global).catch(_notification.default.exception),listRoot.querySelectorAll(SELECTORS.sortableColumn).forEach((item=>item.classList.remove("active")))})),sortableColumns.on(_sortable_list.default.EVENTS.DRAGSTART,(event=>{event.currentTarget.classList.add("active")})),sortableColumns};_exports.setupActionButtons=function(uiRoot){let global=arguments.length>1&&void 0!==arguments[1]&&arguments[1];uiRoot.addEventListener("click",(async e=>{const actionLink=e.target.closest(SELECTORS.actionLink);if(actionLink)try{e.preventDefault();const action=actionLink.dataset.action;if("add"===action||"remove"===action){const hiddenColumns=[],addColumnList=document.querySelector(SELECTORS.addColumn);addColumnList&&addColumnList.querySelectorAll(SELECTORS.addLink).forEach((item=>{"add"===action&&item===actionLink||hiddenColumns.push(item.dataset.column)})),"remove"===action&&hiddenColumns.push(actionLink.dataset.column),await repository.setHiddenColumns(hiddenColumns,global)}else"reset"===action&&await Promise.all([repository.setColumnbankOrder([],global),repository.setHiddenColumns([],global),repository.setColumnSize("",global)]);const fragmentData=uiRoot.dataset,actionUrl=new URL(actionLink.href),returnUrl=new URL(actionUrl.searchParams.get("returnurl").replaceAll("&amp;","&")),viewData={},sortData={};returnUrl&&returnUrl.searchParams.forEach(((value,key)=>{const sortItem=key.match(/sortdata\[([^\]]+)\]/);sortItem?sortData[sortItem.pop()]=value:viewData[key]=value})),viewData.sortdata=JSON.stringify(sortData),_fragment.default.loadFragment(fragmentData.component,fragmentData.callback,fragmentData.contextid,viewData).then(((html,js)=>_templates.default.replaceNode(uiRoot,html,js))).catch(_notification.default.exception)}catch(ex){await _notification.default.exception(ex)}}))};const getColumnOrder=listRoot=>{const columns=Array.from(listRoot.querySelectorAll("[data-columnid]")).map((column=>column.dataset.columnid));return columns.filter(((value,index)=>columns.indexOf(value)===index))};_exports.getColumnOrder=getColumnOrder}));
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setupSortableLists=_exports.setupActionButtons=_exports.getColumnOrder=_exports.SELECTORS=void 0,_sortable_list=_interopRequireDefault(_sortable_list),_jquery=_interopRequireDefault(_jquery),repository=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}(repository),_notification=_interopRequireDefault(_notification),_refresh_ui=_interopRequireDefault(_refresh_ui);const SELECTORS={columnList:".qbank-column-list",sortableColumn:".qbank-sortable-column",removeLink:"[data-action=remove]",moveHandler:"[data-drag-type=move]",addColumn:".addcolumn",addLink:"[data-action=add]",actionLink:".action-link"};_exports.SELECTORS=SELECTORS;_exports.setupSortableLists=function(listRoot){let vertical=arguments.length>1&&void 0!==arguments[1]&&arguments[1],global=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const sortableList=new _sortable_list.default(listRoot,{moveHandlerSelector:SELECTORS.moveHandler,isHorizontal:!vertical});sortableList.getElementName=element=>Promise.resolve(element.data("name"));const sortableColumns=(0,_jquery.default)(SELECTORS.sortableColumn);return sortableColumns.on(_sortable_list.default.EVENTS.DROP,(()=>{repository.setColumnbankOrder(getColumnOrder(listRoot),global).catch(_notification.default.exception),listRoot.querySelectorAll(SELECTORS.sortableColumn).forEach((item=>item.classList.remove("active")))})),sortableColumns.on(_sortable_list.default.EVENTS.DRAGSTART,(event=>{event.currentTarget.classList.add("active")})),sortableColumns};_exports.setupActionButtons=function(uiRoot){let global=arguments.length>1&&void 0!==arguments[1]&&arguments[1];uiRoot.addEventListener("click",(async e=>{const actionLink=e.target.closest(SELECTORS.actionLink);if(actionLink)try{e.preventDefault();const action=actionLink.dataset.action;if("add"===action||"remove"===action){const hiddenColumns=[],addColumnList=document.querySelector(SELECTORS.addColumn);addColumnList&&addColumnList.querySelectorAll(SELECTORS.addLink).forEach((item=>{"add"===action&&item===actionLink||hiddenColumns.push(item.dataset.column)})),"remove"===action&&hiddenColumns.push(actionLink.dataset.column),await repository.setHiddenColumns(hiddenColumns,global)}else"reset"===action&&await Promise.all([repository.setColumnbankOrder([],global),repository.setHiddenColumns([],global),repository.setColumnSize("",global)]);const actionUrl=new URL(actionLink.href),returnUrl=new URL(actionUrl.searchParams.get("returnurl").replaceAll("&amp;","&"));await _refresh_ui.default.refresh(uiRoot,returnUrl)}catch(ex){await _notification.default.exception(ex)}}))};const getColumnOrder=listRoot=>{const columns=Array.from(listRoot.querySelectorAll("[data-columnid]")).map((column=>column.dataset.columnid));return columns.filter(((value,index)=>columns.indexOf(value)===index))};_exports.getColumnOrder=getColumnOrder}));
//# sourceMappingURL=actions.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -26,8 +26,7 @@ import SortableList from 'core/sortable_list';
import $ from 'jquery';
import * as repository from 'qbank_columnsortorder/repository';
import Notification from "core/notification";
import Fragment from "core/fragment";
import Templates from "core/templates";
import RefreshUi from 'core_question/refresh_ui';
export const SELECTORS = {
columnList: '.qbank-column-list',
@ -108,31 +107,9 @@ export const setupActionButtons = (uiRoot, global = false) => {
repository.setColumnSize('', global),
]);
}
const fragmentData = uiRoot.dataset;
const actionUrl = new URL(actionLink.href);
const returnUrl = new URL(actionUrl.searchParams.get('returnurl').replaceAll('&amp;', '&'));
const viewData = {};
const sortData = {};
if (returnUrl) {
returnUrl.searchParams.forEach((value, key) => {
// Match keys like 'sortdata[fieldname]' and convert them to an array,
// because the fragment API doesn't like non-alphanum argument keys.
const sortItem = key.match(/sortdata\[([^\]]+)\]/);
if (sortItem) {
// The item returned by sortItem.pop() is the contents of the matching group, the field name.
sortData[sortItem.pop()] = value;
} else {
viewData[key] = value;
}
});
}
viewData.sortdata = JSON.stringify(sortData);
// We have to use then() there, as loadFragment doesn't appear to work with await.
Fragment.loadFragment(fragmentData.component, fragmentData.callback, fragmentData.contextid, viewData)
.then((html, js) => {
return Templates.replaceNode(uiRoot, html, js);
})
.catch(Notification.exception);
await RefreshUi.refresh(uiRoot, returnUrl);
} catch (ex) {
await Notification.exception(ex);
}

View File

@ -1,11 +0,0 @@
define("qbank_viewquestiontext/datafilter/filtertypes/showtext",["exports","core/datafilter/filtertype"],(function(_exports,_filtertype){var obj;
/**
* Filter managing question text display.
*
* @module qbank_viewquestiontext/datafilter/filtertypes/showtext
* @author 2022 Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @copyright 2022 Catalyst IT Australia Pty Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_filtertype=(obj=_filtertype)&&obj.__esModule?obj:{default:obj};class _default extends _filtertype.default{}return _exports.default=_default,_exports.default}));
//# sourceMappingURL=showtext.min.js.map

View File

@ -1 +0,0 @@
{"version":3,"file":"showtext.min.js","sources":["../../../src/datafilter/filtertypes/showtext.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 * Filter managing question text display.\n *\n * @module qbank_viewquestiontext/datafilter/filtertypes/showtext\n * @author 2022 Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>\n * @copyright 2022 Catalyst IT Australia Pty Ltd\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport GenericFilter from 'core/datafilter/filtertype';\n\nexport default class extends GenericFilter {\n}\n"],"names":["GenericFilter"],"mappings":";;;;;;;;4KA0B6BA"}

View File

@ -0,0 +1,11 @@
define("qbank_viewquestiontext/question_text_format",["exports","qbank_viewquestiontext/repository","core_question/refresh_ui","core/notification"],(function(_exports,repository,_refresh_ui,_notification){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}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)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,repository=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}
/**
* Javascript for question_text_format question bank control.
*
* @module qbank_viewquestiontext/question_text_format
* @copyright 2023 Catalyst IT Europe Ltd.
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/(repository),_refresh_ui=_interopRequireDefault(_refresh_ui),_notification=_interopRequireDefault(_notification);const SELECTORS_formatSelectId="question-text-format",SELECTORS_returnUrl="[name=returnurl]";let uiRoot;const handleFormatChange=async e=>{const value=e.target.value;try{await repository.setQuestionTextFormat(value);const returnUrlInput=e.target.closest("form").querySelector(SELECTORS_returnUrl),returnUrl=new URL(returnUrlInput.value);await _refresh_ui.default.refresh(uiRoot,returnUrl)}catch(ex){_notification.default.exception(ex)}};_exports.init=uiRootId=>{uiRoot=document.getElementById(uiRootId);document.getElementById(SELECTORS_formatSelectId).addEventListener("change",handleFormatChange)}}));
//# sourceMappingURL=question_text_format.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"question_text_format.min.js","sources":["../src/question_text_format.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 * Javascript for question_text_format question bank control.\n *\n * @module qbank_viewquestiontext/question_text_format\n * @copyright 2023 Catalyst IT Europe Ltd.\n * @author Mark Johnson <mark.johnson@catalyst-eu.net>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as repository from 'qbank_viewquestiontext/repository';\nimport RefreshUi from 'core_question/refresh_ui';\nimport Notification from 'core/notification';\n\nconst SELECTORS = {\n formatSelectId: 'question-text-format',\n returnUrl: '[name=returnurl]',\n};\n\nlet uiRoot;\n\n/**\n * Save the selected format via a web service call, and refresh the UI.\n *\n * @param {Event} e Select field change event.\n * @return {Promise<void>}\n */\nconst handleFormatChange = async(e) => {\n const value = e.target.value;\n try {\n await repository.setQuestionTextFormat(value);\n const returnUrlInput = e.target.closest('form').querySelector(SELECTORS.returnUrl);\n const returnUrl = new URL(returnUrlInput.value);\n await RefreshUi.refresh(uiRoot, returnUrl);\n } catch (ex) {\n Notification.exception(ex);\n }\n};\n\n/**\n * Initialise question text format widget.\n *\n * Find the uiRoot element and attach a change listener to the question text format selector.\n *\n * @param {String} uiRootId\n */\nexport const init = (uiRootId) => {\n uiRoot = document.getElementById(uiRootId);\n const select = document.getElementById(SELECTORS.formatSelectId);\n select.addEventListener('change', handleFormatChange);\n};\n"],"names":["SELECTORS","uiRoot","handleFormatChange","async","value","e","target","repository","setQuestionTextFormat","returnUrlInput","closest","querySelector","returnUrl","URL","RefreshUi","refresh","ex","exception","uiRootId","document","getElementById","addEventListener"],"mappings":";;;;;;;;4HA4BMA,yBACc,uBADdA,oBAES,uBAGXC,aAQEC,mBAAqBC,MAAAA,UACjBC,MAAQC,EAAEC,OAAOF,gBAEbG,WAAWC,sBAAsBJ,aACjCK,eAAiBJ,EAAEC,OAAOI,QAAQ,QAAQC,cAAcX,qBACxDY,UAAY,IAAIC,IAAIJ,eAAeL,aACnCU,oBAAUC,QAAQd,OAAQW,WAClC,MAAOI,0BACQC,UAAUD,oBAWVE,WACjBjB,OAASkB,SAASC,eAAeF,UAClBC,SAASC,eAAepB,0BAChCqB,iBAAiB,SAAUnB"}

View File

@ -0,0 +1,3 @@
define("qbank_viewquestiontext/repository",["exports","core/ajax"],(function(_exports,_ajax){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setQuestionTextFormat=void 0;_exports.setQuestionTextFormat=format=>(0,_ajax.call)([{methodname:"qbank_viewquestiontext_set_question_text_format",args:{format:format}}])[0]}));
//# sourceMappingURL=repository.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"repository.min.js","sources":["../src/repository.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 * External function calls for qbank_columnsortorder\n *\n * @module qbank_viewquestiontext/repository\n * @copyright 2023 Catalyst IT Europe Ltd.\n * @author Mark Johnson <mark.johnson@catalyst-eu.net>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {call as fetchMany} from 'core/ajax';\n\n/**\n * Set the question text format.\n *\n * @param {Number} format The question text format.\n * @return {Promise}\n */\nexport const setQuestionTextFormat = (format) => {\n const responses = fetchMany([{\n methodname: 'qbank_viewquestiontext_set_question_text_format',\n args: {\n format\n },\n }]);\n return responses[0];\n};\n"],"names":["format","methodname","args"],"mappings":"0NAgCsCA,SAChB,cAAU,CAAC,CACzBC,WAAY,kDACZC,KAAM,CACFF,OAAAA,WAGS"}

View File

@ -0,0 +1,65 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Javascript for question_text_format question bank control.
*
* @module qbank_viewquestiontext/question_text_format
* @copyright 2023 Catalyst IT Europe Ltd.
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import * as repository from 'qbank_viewquestiontext/repository';
import RefreshUi from 'core_question/refresh_ui';
import Notification from 'core/notification';
const SELECTORS = {
formatSelectId: 'question-text-format',
returnUrl: '[name=returnurl]',
};
let uiRoot;
/**
* Save the selected format via a web service call, and refresh the UI.
*
* @param {Event} e Select field change event.
* @return {Promise<void>}
*/
const handleFormatChange = async(e) => {
const value = e.target.value;
try {
await repository.setQuestionTextFormat(value);
const returnUrlInput = e.target.closest('form').querySelector(SELECTORS.returnUrl);
const returnUrl = new URL(returnUrlInput.value);
await RefreshUi.refresh(uiRoot, returnUrl);
} catch (ex) {
Notification.exception(ex);
}
};
/**
* Initialise question text format widget.
*
* Find the uiRoot element and attach a change listener to the question text format selector.
*
* @param {String} uiRootId
*/
export const init = (uiRootId) => {
uiRoot = document.getElementById(uiRootId);
const select = document.getElementById(SELECTORS.formatSelectId);
select.addEventListener('change', handleFormatChange);
};

View File

@ -0,0 +1,41 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* External function calls for qbank_columnsortorder
*
* @module qbank_viewquestiontext/repository
* @copyright 2023 Catalyst IT Europe Ltd.
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {call as fetchMany} from 'core/ajax';
/**
* Set the question text format.
*
* @param {Number} format The question text format.
* @return {Promise}
*/
export const setQuestionTextFormat = (format) => {
const responses = fetchMany([{
methodname: 'qbank_viewquestiontext_set_question_text_format',
args: {
format
},
}]);
return responses[0];
};

View File

@ -0,0 +1,78 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace qbank_viewquestiontext\external;
use context_system;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_value;
use qbank_viewquestiontext\output\question_text_format;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/editlib.php');
/**
* External function for setting the question text format.
*
* @package qbank_viewquestiontext
* @copyright 2023 onwards Catalyst IT EU {@link https://catalyst-eu.net}
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class set_question_text_format extends external_api {
/**
* Returns description of method parameters.
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'format' => new external_value(PARAM_INT, 'Format for the question text', VALUE_REQUIRED),
]);
}
/**
* Returns description of method result value.
*/
public static function execute_returns(): void {
}
/**
* Save the question text format preference for the current user.
*
* @param int $format Format for the question text.
*/
public static function execute(int $format): void {
[
'format' => $format,
]
= self::validate_parameters(self::execute_parameters(),
[
'format' => $format,
]);
if (!in_array($format, [question_text_format::OFF, question_text_format::PLAIN, question_text_format::FULL])) {
throw new \invalid_parameter_exception('$format must be one of question_text_format::OFF, ::PLAIN or ::FULL.');
}
$context = context_system::instance();
self::validate_context($context);
\question_set_or_get_user_preference('qbshowtext', $format, 0, new \moodle_url('/'));
}
}

View File

@ -0,0 +1,93 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace qbank_viewquestiontext\output;
use core_question\local\bank\view;
use qbank_viewquestiontext\question_text_row;
use renderer_base;
/**
* Question text format selector.
*
* @package qbank_viewquestiontext
* @copyright 2023 onwards Catalyst IT EU {@link https://catalyst-eu.net}
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class question_text_format implements \templatable, \renderable {
/**
* @var int Question text is off.
*/
const OFF = 0;
/**
* @var int Question text is displayed in plain text mode.
*/
const PLAIN = 1;
/**
* @var int Question text is displayed fully rendered.
*/
const FULL = 2;
/** @var int|mixed The current display preference value. */
protected int $preference;
/**
* @var \moodle_url The return URL for redirecting back to the current question bank page.
*/
protected \moodle_url $returnurl;
/**
* Store the returnurl and the current preference value.
*
* @param view $qbank
* @throws \moodle_exception
*/
public function __construct(view $qbank) {
$row = new question_text_row($qbank);
$this->returnurl = new \moodle_url($qbank->returnurl);
$this->preference = question_get_display_preference($row->get_preference_key(), 0, PARAM_INT, new \moodle_url(''));
}
public function export_for_template(renderer_base $output): array {
return [
'formaction' => new \moodle_url('/question/bank/viewquestiontext/save.php'),
'sesskey' => sesskey(),
'returnurl' => $this->returnurl->out(false),
'options' => [
(object)[
'label' => get_string('showquestiontext_off', 'question'),
'value' => self::OFF,
'selected' => $this->preference === self::OFF,
],
(object)[
'label' => get_string('showquestiontext_plain', 'question'),
'value' => self::PLAIN,
'selected' => $this->preference === self::PLAIN,
],
(object)[
'label' => get_string('showquestiontext_full', 'question'),
'value' => self::FULL,
'selected' => $this->preference === self::FULL,
],
],
'label' => get_string('showquestiontext', 'core_question'),
];
}
}

View File

@ -16,8 +16,10 @@
namespace qbank_viewquestiontext;
use core\context;
use core_question\local\bank\plugin_features_base;
use core_question\local\bank\view;
use qbank_viewquestiontext\output\question_text_format;
/**
* Class columns is the entrypoint for the columns.
@ -29,15 +31,27 @@ use core_question\local\bank\view;
*/
class plugin_feature extends plugin_features_base {
public function get_question_columns($qbank): array {
return [
new question_text_row($qbank)
];
/**
* Return an additional row for displaying the question text, if user has a preference set to display it.
*
* @param view $qbank
* @return array
*/
public function get_question_columns(view $qbank): array {
$row = new question_text_row($qbank);
$preference = (int)question_get_display_preference($row->get_preference_key(), '0', PARAM_INT, new \moodle_url('/'));
if ($preference != question_text_format::OFF) {
return [
$row,
];
}
return [];
}
public function get_question_filters(view $qbank = null): array {
public function get_question_bank_controls(view $qbank, context $context, int $categoryid): array {
return [
new questiontext_condition($qbank),
400 => new question_text_format($qbank),
];
}
}

View File

@ -17,6 +17,7 @@
namespace qbank_viewquestiontext;
use core_question\local\bank\row_base;
use qbank_viewquestiontext\output\question_text_format;
use question_utils;
/**
@ -29,8 +30,8 @@ use question_utils;
*/
class question_text_row extends row_base {
/** @var bool if true, we will show the question text reduced to plain text, else it is fully rendered. */
protected $plain;
/** @var int if true, we will show the question text reduced to plain text, else it is fully rendered. */
protected $preference;
/** @var \stdClass $formatoptions options used when displaying the question text as HTML. */
protected $formatoptions;
@ -38,8 +39,7 @@ class question_text_row extends row_base {
protected function init(): void {
// Cannot use $this->get_preference because of PHP type hints.
$preference = question_get_display_preference($this->get_preference_key(), 0, PARAM_INT, new \moodle_url(''));
$this->plain = 1 === (int) $preference;
$this->preference = (int)question_get_display_preference($this->get_preference_key(), 0, PARAM_INT, new \moodle_url(''));
$this->formatoptions = new \stdClass();
$this->formatoptions->noclean = true;
$this->formatoptions->para = false;
@ -55,14 +55,12 @@ class question_text_row extends row_base {
protected function display_content($question, $rowclasses): void {
// Access 'showtext' filter from pagevars.
$display = $this->qbank->get_pagevars('filter')['showtext'] ?? null;
if ($display) {
$showtext = (int)$display['values'][0];
if ($this->preference !== question_text_format::OFF) {
$text = '';
if ($showtext === questiontext_condition::PLAIN) {
if ($this->preference === question_text_format::PLAIN) {
$text = question_utils::to_plain_text($question->questiontext,
$question->questiontextformat, ['noclean' => true, 'para' => false, 'filter' => false]);
} else if ($showtext === questiontext_condition::FULL) {
} else if ($this->preference === question_text_format::FULL) {
$text = question_rewrite_question_preview_urls($question->questiontext, $question->id,
$question->contextid, 'question', 'questiontext', $question->id,
$question->contextid, 'core_question');

View File

@ -1,108 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace qbank_viewquestiontext;
use core\output\datafilter;
use core_question\local\bank\condition;
use core_question\local\bank\view;
/**
* This class controls from which category questions are listed.
*
* @package qbank_viewquestiontext
* @copyright 2022 Catalyst IT Australia Pty Ltd
* @author Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class questiontext_condition extends condition {
/**
* @var int Question text is off.
*/
const OFF = 0;
/**
* @var int Question text is displayed in plain text mode.
*/
const PLAIN = 1;
/**
* @var int Question text is displayed fully rendered.
*/
const FULL = 2;
/**
* @var ?int $showtext Initial value of the filter, for determining the pre-selected option.
*/
protected ?int $showtext = null;
public function __construct(view $qbank = null) {
if (is_null($qbank)) {
return;
}
$filter = $qbank->get_pagevars('filter');
if (isset($filter['showtext'])) {
$this->showtext = (int)$filter['showtext']['values'][0];
}
}
public function allow_custom() {
return false;
}
public function allow_multiple() {
return false;
}
public static function get_condition_key() {
return 'showtext';
}
public function get_title() {
return get_string('showquestiontext', 'core_question');
}
public function get_join_list(): array {
return [
datafilter::JOINTYPE_ANY,
];
}
public function get_filter_class() {
return 'qbank_viewquestiontext/datafilter/filtertypes/showtext';
}
public function get_initial_values() {
return [
[
'value' => self::OFF,
'title' => get_string('showquestiontext_off', 'question'),
'selected' => $this->showtext === self::OFF,
],
[
'value' => self::PLAIN,
'title' => get_string('showquestiontext_plain', 'question'),
'selected' => $this->showtext === self::PLAIN,
],
[
'value' => self::FULL,
'title' => get_string('showquestiontext_full', 'question'),
'selected' => $this->showtext === self::FULL,
]
];
}
}

View File

@ -1,3 +1,4 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@ -14,15 +15,22 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Filter managing question text display.
* qbank_viewquestiontext external functions and service definitions.
*
* @module qbank_viewquestiontext/datafilter/filtertypes/showtext
* @author 2022 Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @copyright 2022 Catalyst IT Australia Pty Ltd
* @package qbank_viewquestiontext
* @category webservice
* @copyright 2023 Catalyst IT Europe Ltd
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import GenericFilter from 'core/datafilter/filtertype';
defined('MOODLE_INTERNAL') || die();
export default class extends GenericFilter {
}
$functions = [
'qbank_viewquestiontext_set_question_text_format' => [
'classname' => 'qbank_viewquestiontext\external\set_question_text_format',
'description' => 'Sets the preference for displaying and formatting the question text',
'type' => 'write',
'ajax' => true,
],
];

View File

@ -0,0 +1,48 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Synchronously save the question text display preference, and redirect back to the previous page.
*
* This is progressively enhanced by question_text_format.js, but this remains as a fallback.
*
* @package qbank_viewquestiontext
* @copyright 2023 onwards Catalyst IT EU {@link https://catalyst-eu.net}
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../config.php');
require_once($CFG->dirroot . '/question/editlib.php');
$format = required_param('format', PARAM_INT);
$returnurl = required_param('returnurl', PARAM_LOCALURL);
require_login();
require_sesskey();
$validformats = [
\qbank_viewquestiontext\output\question_text_format::OFF,
\qbank_viewquestiontext\output\question_text_format::PLAIN,
\qbank_viewquestiontext\output\question_text_format::FULL
];
if (!in_array($format, $validformats)) {
throw new \invalid_parameter_exception('$format must be one of question_text_format::OFF, ::PLAIN or ::FULL.');
}
question_set_or_get_user_preference('qbshowtext', $format, 0, new \moodle_url('/'));
redirect(new moodle_url($returnurl));

View File

@ -0,0 +1,3 @@
.jsenabled .question-text-format .input-group-append {
display: none;
}

View File

@ -0,0 +1,58 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template qbank_viewquestiontext/question_text_format
Example context (json):
{
"label": "Question text format",
"options": [
{
"value": 1,
"label": "Plain text",
"selected": true
},
{
"value": 2,
"label": "Fully rendered",
"selected": false
}
]
}
}}
<form class="question-text-format ml-1" action="{{formaction}}">
<input type="hidden" name="sesskey" value="{{sesskey}}">
<input type="hidden" name="returnurl" value="{{returnurl}}">
<div class="input-group">
<label class="input-group-prepend" for="question-text-format">
<span class="input-group-text">{{label}}</span>
</label>
<select class="form-control" name="format" id="question-text-format">
{{#options}}
<option value="{{value}}"{{#selected}} selected{{/selected}}>{{label}}</option>
{{/options}}
</select>
<div class="input-group-append">
<button class="btn btn-outline-dark mb-2">Save</button>
</div>
</div>
</form>
{{#js}}
require(['qbank_viewquestiontext/question_text_format'], QuestionTextFormat => {
QuestionTextFormat.init('questionscontainer');
});
{{/js}}

View File

@ -19,19 +19,19 @@ Feature: Use the qbank plugin manager page for viewquestiontext
@javascript
Scenario: Display of plain question text can be turned on and off
When I am on the "Test quiz" "mod_quiz > question bank" page logged in as admin
And I apply question bank filter "Show question text in the question list?" with value "text only"
And I set the field "Show question text in the question list?" to "text only"
Then I should see "Answer the first question"
And ".totestforhtml" "css_element" should not exist in the "Answer the first question" "table_row"
And I apply question bank filter "Show question text in the question list?" with value "No"
And I set the field "Show question text in the question list?" to "No"
And I should not see "Answer the first question"
@javascript
Scenario: Display of full question text can be turned on and off
When I am on the "Test quiz" "mod_quiz > question bank" page logged in as admin
And I apply question bank filter "Show question text in the question list?" with value "with images"
And I set the field "Show question text in the question list?" to "with images"
Then I should see "Answer the first question"
And ".totestforhtml" "css_element" should exist in the "Answer the first question" "table_row"
And I apply question bank filter "Show question text in the question list?" with value "No"
And I set the field "Show question text in the question list?" to "No"
And I should not see "Answer the first question"
@javascript
@ -53,5 +53,5 @@ Feature: Use the qbank plugin manager page for viewquestiontext
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "View question text" "table_row"
And I am on the "Test quiz" "mod_quiz > question bank" page
When I apply question bank filter "Show question text in the question list?" with value "text only"
When I set the field "Show question text in the question list?" to "text only"
And I should see "Answer the first question"

View File

@ -26,6 +26,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'qbank_viewquestiontext';
$plugin->version = 2023042400;
$plugin->version = 2023042401;
$plugin->requires = 2023041800;
$plugin->maturity = MATURITY_STABLE;

View File

@ -391,11 +391,6 @@ class view {
'core_question\local\bank\edit_menu_column' . column_base::ID_SEPARATOR . 'edit_menu_column',
];
if (question_get_display_preference('qbshowtext', 0, PARAM_INT, new \moodle_url(''))) {
$corequestionbankcolumns[] = 'qbank_viewquestiontext\question_text_row' . column_base::ID_SEPARATOR .
'question_text_row';
}
foreach ($corequestionbankcolumns as $columnid) {
[$columnclass, $columnname] = explode(column_base::ID_SEPARATOR, $columnid, 2);
if (class_exists($columnclass)) {

View File

@ -61,7 +61,7 @@ Feature: The questions in the question bank can be sorted in various ways
@javascript
Scenario: The question text can be shown in the list of questions
When I apply question bank filter "Show question text in the question list?" with value "Yes"
When I set the field "Show question text in the question list?" to "Yes"
Then I should see "Question 1 text"
And I should see "Question 2 text"
And I should see "Question 3 text"