From 89dc9538c013b3f22cf48422a1c600bca9eb2537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Trouv=C3=A9?= Date: Fri, 20 Oct 2023 09:41:53 +0200 Subject: [PATCH 1/9] Prevent export crash due to missing user context After user data removal by tool_dataprivacy `tool_dataprivacy\task\expired_retention_period` is used to remove user contexts When exporting appointments with custom profile field selected this lead to a crash. This is due to profile field visibility check using `profile_field_base::is_visible()` which is calling `context_user::instance()` with default strictness (`MUST_EXIST`)...leading to an exception when the context is removed. --- exportlib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exportlib.php b/exportlib.php index 3bc98af1..0a2b3341 100644 --- a/exportlib.php +++ b/exportlib.php @@ -659,7 +659,8 @@ public function get_header(scheduler $scheduler) { * @return string the value of this field for the given data */ public function get_value(slot $slot, $appointment) { - if (!$appointment instanceof appointment || $appointment->studentid == 0) { + if (!$appointment instanceof appointment || $appointment->studentid == 0 + || !context_user::instance($appointment->studentid, IGNORE_MISSING)) { return ''; } $this->field->set_userid($appointment->studentid); From 5a2a493a39963198a6c58921e4495379d42b9347 Mon Sep 17 00:00:00 2001 From: ewallah Date: Sun, 12 Nov 2023 11:13:33 +0100 Subject: [PATCH 2/9] Dynamic properties deprecated Creation of dynamic property mod_scheduler\privacy_test::$appointmentids is deprecated --- tests/privacy_test.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/privacy_test.php b/tests/privacy_test.php index dd4abf4e..520eca12 100644 --- a/tests/privacy_test.php +++ b/tests/privacy_test.php @@ -87,6 +87,11 @@ class privacy_test extends provider_testcase { */ protected $allstudents; + /** + * @var array all appointment ids involved in the scheduler + */ + protected $appointmentids; + protected function setUp(): void { global $DB, $CFG; From 583cb87e65fa585874258c03ece60f41bc185fe6 Mon Sep 17 00:00:00 2001 From: ewallah Date: Sun, 12 Nov 2023 11:17:03 +0100 Subject: [PATCH 3/9] Deprecated dynamic property Deprecated: Creation of dynamic property mod_scheduler\scheduler_test::$appointmentids is deprecated in mod/scheduler/tests/scheduler_test.php on line 95 --- tests/scheduler_test.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/scheduler_test.php b/tests/scheduler_test.php index 41429ebb..7f191d9a 100644 --- a/tests/scheduler_test.php +++ b/tests/scheduler_test.php @@ -62,6 +62,11 @@ class scheduler_test extends \advanced_testcase { */ protected $slotid; + /** + * @var array all appointment ids involved in the scheduler + */ + protected $appointmentids; + protected function setUp(): void { global $DB, $CFG; From 70162edb54d9772bd01cd83d9b1e529cec3852bb Mon Sep 17 00:00:00 2001 From: Leon Stringer Date: Fri, 12 Jul 2024 12:11:44 +0100 Subject: [PATCH 4/9] CONTRIB-9504 Fix Undefined constant "viewurl" Attempting to add a slot on a course with no teachers resulted in: Exception - Undefined constant "viewurl" instead of the expected: Slots cannot be added as this course has no teachers --- teacherview.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/teacherview.php b/teacherview.php index d4e7549d..8d76aa47 100644 --- a/teacherview.php +++ b/teacherview.php @@ -148,7 +148,7 @@ function scheduler_print_schedulebox(scheduler $scheduler, $studentid, $groupid $actionurl = new moodle_url($baseurl, array('what' => 'addslot')); if (!$scheduler->has_available_teachers()) { - throw new moodle_exception('needteachers', 'scheduler', viewurl); + throw new moodle_exception('needteachers', 'scheduler', $viewurl); } $mform = new scheduler_editslot_form($actionurl, $scheduler, $cm, $groupsicansee); From d3f03cfcf886086a9f93df4243485266d50ddb7e Mon Sep 17 00:00:00 2001 From: Leon Stringer Date: Fri, 12 Jul 2024 16:55:46 +0100 Subject: [PATCH 5/9] CONTRIB-9624 Fix Undefined array key "text" --- mod_form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod_form.php b/mod_form.php index 90dcfbf3..4dccef8c 100644 --- a/mod_form.php +++ b/mod_form.php @@ -230,7 +230,7 @@ public function save_mod_data(stdClass $data, context_module $context) { global $DB; $editor = $data->bookinginstructions_editor; - if ($editor) { + if ($editor && array_key_exists('text', $editor)) { $data->bookinginstructions = file_save_draft_area_files($editor['itemid'], $context->id, 'mod_scheduler', 'bookinginstructions', 0, $this->editoroptions, $editor['text']); From c834cee321f1f16403d772302bb7eb0b439bbe3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Kr=C3=BCger?= Date: Tue, 16 Jul 2024 17:21:20 +0200 Subject: [PATCH 6/9] MBS-3078: Remove YUI --- amd/build/delselected.min.js | 11 +++ amd/build/delselected.min.js.map | 1 + amd/build/saveseen.min.js | 3 + amd/build/saveseen.min.js.map | 1 + amd/build/studentlist.min.js | 3 + amd/build/studentlist.min.js.map | 1 + amd/src/delselected.js | 62 ++++++++++++++++ amd/src/saveseen.js | 70 +++++++++++++++++++ amd/src/studentlist.js | 32 +++++++++ renderer.php | 7 +- teacherview.php | 3 +- .../moodle-mod_scheduler-delselected-debug.js | 44 ------------ .../moodle-mod_scheduler-delselected-min.js | 1 - .../moodle-mod_scheduler-delselected.js | 44 ------------ .../moodle-mod_scheduler-saveseen-debug.js | 69 ------------------ .../moodle-mod_scheduler-saveseen-min.js | 1 - .../moodle-mod_scheduler-saveseen.js | 69 ------------------ .../moodle-mod_scheduler-studentlist-debug.js | 43 ------------ .../moodle-mod_scheduler-studentlist-min.js | 1 - .../moodle-mod_scheduler-studentlist.js | 43 ------------ yui/src/delselected/build.json | 10 --- yui/src/delselected/js/delselected.js | 40 ----------- yui/src/delselected/meta/delselected.json | 7 -- yui/src/saveseen/build.json | 10 --- yui/src/saveseen/js/saveseen.js | 64 ----------------- yui/src/saveseen/meta/saveseen.json | 7 -- yui/src/studentlist/build.json | 10 --- yui/src/studentlist/js/studentlist.js | 38 ---------- yui/src/studentlist/meta/studentlist.json | 7 -- 29 files changed, 187 insertions(+), 515 deletions(-) create mode 100644 amd/build/delselected.min.js create mode 100644 amd/build/delselected.min.js.map create mode 100644 amd/build/saveseen.min.js create mode 100644 amd/build/saveseen.min.js.map create mode 100644 amd/build/studentlist.min.js create mode 100644 amd/build/studentlist.min.js.map create mode 100644 amd/src/delselected.js create mode 100644 amd/src/saveseen.js create mode 100644 amd/src/studentlist.js delete mode 100644 yui/build/moodle-mod_scheduler-delselected/moodle-mod_scheduler-delselected-debug.js delete mode 100644 yui/build/moodle-mod_scheduler-delselected/moodle-mod_scheduler-delselected-min.js delete mode 100644 yui/build/moodle-mod_scheduler-delselected/moodle-mod_scheduler-delselected.js delete mode 100644 yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen-debug.js delete mode 100644 yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen-min.js delete mode 100644 yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen.js delete mode 100644 yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist-debug.js delete mode 100644 yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist-min.js delete mode 100644 yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist.js delete mode 100644 yui/src/delselected/build.json delete mode 100644 yui/src/delselected/js/delselected.js delete mode 100644 yui/src/delselected/meta/delselected.json delete mode 100644 yui/src/saveseen/build.json delete mode 100644 yui/src/saveseen/js/saveseen.js delete mode 100644 yui/src/saveseen/meta/saveseen.json delete mode 100644 yui/src/studentlist/build.json delete mode 100644 yui/src/studentlist/js/studentlist.js delete mode 100644 yui/src/studentlist/meta/studentlist.json diff --git a/amd/build/delselected.min.js b/amd/build/delselected.min.js new file mode 100644 index 00000000..e408b7e7 --- /dev/null +++ b/amd/build/delselected.min.js @@ -0,0 +1,11 @@ +define("mod_scheduler/delselected",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=_exports.collect_selection=_exports.SELECTORS=void 0; +/** + * TODO describe module delselected + * + * @module mod_scheduler/delselected + * @copyright 2024 ISB Bayern + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +const SELECTORS={DELACTION:"div.commandbar a#delselected",SELECTBOX:"table#slotmanager input.slotselect"};_exports.SELECTORS=SELECTORS;_exports.init=baseurl=>{let link=document.querySelector(SELECTORS.DELACTION);null!==link&&link.addEventListener("click",(function(){collect_selection(link,baseurl)}))};const collect_selection=(link,baseurl)=>{let sellist="";document.querySelectorAll(SELECTORS.SELECTBOX).forEach((function(box){box.checked&&(sellist.length>0&&(sellist+=","),sellist+=box.getAttribute("value"))})),link.setAttribute("href",baseurl+"&items="+sellist)};_exports.collect_selection=collect_selection})); + +//# sourceMappingURL=delselected.min.js.map \ No newline at end of file diff --git a/amd/build/delselected.min.js.map b/amd/build/delselected.min.js.map new file mode 100644 index 00000000..4cfa41c3 --- /dev/null +++ b/amd/build/delselected.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"delselected.min.js","sources":["../src/delselected.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 * TODO describe module delselected\n *\n * @module mod_scheduler/delselected\n * @copyright 2024 ISB Bayern\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Selectors used by the module.\n */\nexport const SELECTORS = {\n DELACTION: 'div.commandbar a#delselected',\n SELECTBOX: 'table#slotmanager input.slotselect',\n};\n\n/**\n * Add event listener to the delete link.\n * @param {*} baseurl\n */\nexport const init = (baseurl) => {\n let link = document.querySelector(SELECTORS.DELACTION);\n if (link !== null) {\n link.addEventListener('click', function() {\n collect_selection(link, baseurl);\n });\n }\n};\n\n/**\n * Copy the selected boxes into an input parameter of the respective form\n *\n * @param {String} link\n * @param {String} baseurl\n */\nexport const collect_selection = (link, baseurl) => {\n let sellist = '';\n document.querySelectorAll(SELECTORS.SELECTBOX).forEach(function(box) {\n if (box.checked) {\n if (sellist.length > 0) {\n sellist += ',';\n }\n sellist += box.getAttribute('value');\n }\n });\n link.setAttribute('href', baseurl + '&items=' + sellist);\n};\n"],"names":["SELECTORS","DELACTION","SELECTBOX","baseurl","link","document","querySelector","addEventListener","collect_selection","sellist","querySelectorAll","forEach","box","checked","length","getAttribute","setAttribute"],"mappings":";;;;;;;;MA0BaA,UAAY,CACrBC,UAAW,+BACXC,UAAW,iFAOMC,cACbC,KAAOC,SAASC,cAAcN,UAAUC,WAC/B,OAATG,MACAA,KAAKG,iBAAiB,SAAS,WAC3BC,kBAAkBJ,KAAMD,mBAWvBK,kBAAoB,CAACJ,KAAMD,eAChCM,QAAU,GACdJ,SAASK,iBAAiBV,UAAUE,WAAWS,SAAQ,SAASC,KACxDA,IAAIC,UACAJ,QAAQK,OAAS,IACjBL,SAAW,KAEfA,SAAWG,IAAIG,aAAa,aAGpCX,KAAKY,aAAa,OAAQb,QAAU,UAAYM"} \ No newline at end of file diff --git a/amd/build/saveseen.min.js b/amd/build/saveseen.min.js new file mode 100644 index 00000000..3ac3f93a --- /dev/null +++ b/amd/build/saveseen.min.js @@ -0,0 +1,3 @@ +define("mod_scheduler/saveseen",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.save_status=_exports.init=_exports.SELECTORS=_exports.MOD=void 0;const SELECTORS={CHECKBOXES:"table#slotmanager form.studentselectform input.studentselect"};_exports.SELECTORS=SELECTORS;_exports.MOD={};const save_status=(cmid,appid,newseen,spinner)=>{const url=M.cfg.wwwroot+"/mod/scheduler/ajax.php",params="action=saveseen&id="+cmid+"&appointmentid="+appid+"&seen="+newseen+"&sesskey="+M.cfg.sesskey,xhr=new XMLHttpRequest;xhr.timeout=5e3,xhr.onloadstart=()=>{spinner.style.visibility="visible"},xhr.onload=()=>{if(!(xhr.status>=200&&xhr.status<300)){const msg={name:xhr.status+" "+xhr.statusText,message:xhr.responseText};spinner.style.visibility="hidden";throw spinner.parentNode.removeChild(spinner),new Error(JSON.stringify(msg))}setTimeout((()=>{spinner.style.visibility="hidden";spinner.parentNode.removeChild(spinner)}),250)},xhr.onerror=()=>{spinner.style.visibility="hidden";throw spinner.parentNode.removeChild(spinner),new Error("Network request failed")},xhr.open("POST",url,!0),xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xhr.send(params)};_exports.save_status=save_status;_exports.init=cmid=>{document.querySelectorAll(SELECTORS.CHECKBOXES).forEach((function(box){box.addEventListener("change",(function(){var div=document.createElement("div"),span=document.createElement("span");div.classList.add("spinner-border","spinner-border-sm"),span.classList.add("sr-only"),div.appendChild(span),box.closest("div").appendChild(div),save_status(cmid,box.value,box.checked,div)}))}))}})); + +//# sourceMappingURL=saveseen.min.js.map \ No newline at end of file diff --git a/amd/build/saveseen.min.js.map b/amd/build/saveseen.min.js.map new file mode 100644 index 00000000..2d8ddf3c --- /dev/null +++ b/amd/build/saveseen.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"saveseen.min.js","sources":["../src/saveseen.js"],"sourcesContent":["\nexport const SELECTORS = {CHECKBOXES: 'table#slotmanager form.studentselectform input.studentselect'};\nexport const MOD = {};\n\n/**\n * Save the \"seen\" status.\n *\n * @param {Number} cmid the coursemodule id\n * @param {Number} appid the id of the relevant appointment\n * @param {Boolean} newseen\n * @param {Object} spinner The spinner icon shown while saving\n */\nexport const save_status = (cmid, appid, newseen, spinner, ) => {\n const url = M.cfg.wwwroot + '/mod/scheduler/ajax.php';\n // The request paramaters.\n const params = 'action=saveseen&id='+cmid+'&appointmentid='+appid+'&seen='+newseen+'&sesskey='+M.cfg.sesskey;\n const xhr = new XMLHttpRequest();\n\n // 5 seconds of timeout.\n xhr.timeout = 5000;\n\n xhr.onloadstart = () => {\n spinner.style.visibility = 'visible';\n };\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n setTimeout(() => {\n spinner.style.visibility = 'hidden';\n const parent = spinner.parentNode;\n parent.removeChild(spinner);\n\n }, 250);\n } else {\n const msg = {\n name: xhr.status + ' ' + xhr.statusText,\n message: xhr.responseText\n };\n spinner.style.visibility = 'hidden';\n const parent = spinner.parentNode;\n parent.removeChild(spinner);\n throw new Error(JSON.stringify(msg));\n }\n };\n\n xhr.onerror = () => {\n spinner.style.visibility = 'hidden';\n const parent = spinner.parentNode;\n parent.removeChild(spinner);\n throw new Error('Network request failed');\n };\n\n xhr.open('POST', url, true);\n xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');\n xhr.send(params);\n};\n\nexport const init = (cmid) => {\n document.querySelectorAll(SELECTORS.CHECKBOXES).forEach(function(box) {\n box.addEventListener('change', function() {\n var div = document.createElement('div');\n var span = document.createElement('span');\n div.classList.add('spinner-border', 'spinner-border-sm');\n span.classList.add('sr-only');\n div.appendChild(span);\n box.closest('div').appendChild(div);\n save_status(cmid, box.value, box.checked, div);\n });\n });\n};\n"],"names":["SELECTORS","CHECKBOXES","save_status","cmid","appid","newseen","spinner","url","M","cfg","wwwroot","params","sesskey","xhr","XMLHttpRequest","timeout","onloadstart","style","visibility","onload","status","msg","name","statusText","message","responseText","parentNode","removeChild","Error","JSON","stringify","setTimeout","onerror","open","setRequestHeader","send","document","querySelectorAll","forEach","box","addEventListener","div","createElement","span","classList","add","appendChild","closest","value","checked"],"mappings":"wMACaA,UAAY,CAACC,WAAY,0GACnB,SAUNC,YAAc,CAACC,KAAMC,MAAOC,QAASC,iBACxCC,IAAMC,EAAEC,IAAIC,QAAU,0BAEtBC,OAAS,sBAAsBR,KAAK,kBAAkBC,MAAM,SAASC,QAAQ,YAAYG,EAAEC,IAAIG,QAC/FC,IAAM,IAAIC,eAGhBD,IAAIE,QAAU,IAEdF,IAAIG,YAAc,KACdV,QAAQW,MAAMC,WAAa,WAG/BL,IAAIM,OAAS,UACLN,IAAIO,QAAU,KAAOP,IAAIO,OAAS,KAO/B,OACGC,IAAM,CACRC,KAAMT,IAAIO,OAAS,IAAMP,IAAIU,WAC7BC,QAASX,IAAIY,cAEjBnB,QAAQW,MAAMC,WAAa,eACZZ,QAAQoB,WAChBC,YAAYrB,SACb,IAAIsB,MAAMC,KAAKC,UAAUT,MAd/BU,YAAW,KACPzB,QAAQW,MAAMC,WAAa,SACZZ,QAAQoB,WAChBC,YAAYrB,WAEpB,MAaXO,IAAImB,QAAU,KACV1B,QAAQW,MAAMC,WAAa,eACZZ,QAAQoB,WAChBC,YAAYrB,SACb,IAAIsB,MAAM,2BAGpBf,IAAIoB,KAAK,OAAQ1B,KAAK,GACtBM,IAAIqB,iBAAiB,eAAgB,qCACrCrB,IAAIsB,KAAKxB,wDAGQR,OACjBiC,SAASC,iBAAiBrC,UAAUC,YAAYqC,SAAQ,SAASC,KAC7DA,IAAIC,iBAAiB,UAAU,eACvBC,IAAML,SAASM,cAAc,OAC7BC,KAAOP,SAASM,cAAc,QAClCD,IAAIG,UAAUC,IAAI,iBAAkB,qBACpCF,KAAKC,UAAUC,IAAI,WACnBJ,IAAIK,YAAYH,MAChBJ,IAAIQ,QAAQ,OAAOD,YAAYL,KAC/BvC,YAAYC,KAAMoC,IAAIS,MAAOT,IAAIU,QAASR"} \ No newline at end of file diff --git a/amd/build/studentlist.min.js b/amd/build/studentlist.min.js new file mode 100644 index 00000000..413e248b --- /dev/null +++ b/amd/build/studentlist.min.js @@ -0,0 +1,3 @@ +define("mod_scheduler/studentlist",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.toggleState=_exports.setState=_exports.init=_exports.CSS=void 0;const CSS={EXPANDED:"expanded",COLLAPSED:"collapsed"};_exports.CSS=CSS;const setState=(id,expanded)=>{var image=document.getElementById(id),content=document.getElementById("list"+id);expanded?(content.removeClass(CSS.COLLAPSED),content.addClass(CSS.EXPANDED),image.set("src",M.util.image_url("t/expanded"))):(content.removeClass(CSS.EXPANDED),content.addClass(CSS.COLLAPSED),image.set("src",M.util.image_url("t/collapsed")))};_exports.setState=setState;const toggleState=id=>{var isVisible=document.getElementById("list"+id).hasClass(CSS.EXPANDED);setState(id,!isVisible)};_exports.toggleState=toggleState;_exports.init=(imageid,expanded)=>{setState(imageid,expanded),document.getElementById(imageid).addEventListener("click",(()=>{toggleState(imageid)}))}})); + +//# sourceMappingURL=studentlist.min.js.map \ No newline at end of file diff --git a/amd/build/studentlist.min.js.map b/amd/build/studentlist.min.js.map new file mode 100644 index 00000000..480e5a24 --- /dev/null +++ b/amd/build/studentlist.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"studentlist.min.js","sources":["../src/studentlist.js"],"sourcesContent":["\nexport const CSS = {\n EXPANDED: 'expanded',\n COLLAPSED: 'collapsed'\n};\n\nexport const setState = (id, expanded) => {\n var image = document.getElementById(id);\n var content = document.getElementById('list' + id);\n if (expanded) {\n content.removeClass(CSS.COLLAPSED);\n content.addClass(CSS.EXPANDED);\n image.set('src', M.util.image_url('t/expanded'));\n } else {\n content.removeClass(CSS.EXPANDED);\n content.addClass(CSS.COLLAPSED);\n image.set('src', M.util.image_url('t/collapsed'));\n }\n};\n\nexport const toggleState = (id) => {\n var content = document.getElementById('list' + id);\n var isVisible = content.hasClass(CSS.EXPANDED);\n setState(id, !isVisible);\n};\n\nexport const init = (imageid, expanded) => {\n setState(imageid, expanded);\n document.getElementById(imageid).addEventListener('click', () => {\n toggleState(imageid);\n });\n};\n"],"names":["CSS","EXPANDED","COLLAPSED","setState","id","expanded","image","document","getElementById","content","removeClass","addClass","set","M","util","image_url","toggleState","isVisible","hasClass","imageid","addEventListener"],"mappings":"0MACaA,IAAM,CACfC,SAAU,WACVC,UAAW,oCAGFC,SAAW,CAACC,GAAIC,gBACrBC,MAAQC,SAASC,eAAeJ,IAChCK,QAAUF,SAASC,eAAe,OAASJ,IAC3CC,UACAI,QAAQC,YAAYV,IAAIE,WACxBO,QAAQE,SAASX,IAAIC,UACrBK,MAAMM,IAAI,MAAOC,EAAEC,KAAKC,UAAU,iBAElCN,QAAQC,YAAYV,IAAIC,UACxBQ,QAAQE,SAASX,IAAIE,WACrBI,MAAMM,IAAI,MAAOC,EAAEC,KAAKC,UAAU,mDAI7BC,YAAeZ,SAEpBa,UADUV,SAASC,eAAe,OAASJ,IACvBc,SAASlB,IAAIC,UACrCE,SAASC,IAAKa,2DAGE,CAACE,QAASd,YAC1BF,SAASgB,QAASd,UAClBE,SAASC,eAAeW,SAASC,iBAAiB,SAAS,KACvDJ,YAAYG"} \ No newline at end of file diff --git a/amd/src/delselected.js b/amd/src/delselected.js new file mode 100644 index 00000000..0a1779cd --- /dev/null +++ b/amd/src/delselected.js @@ -0,0 +1,62 @@ +// 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 . + +/** + * TODO describe module delselected + * + * @module mod_scheduler/delselected + * @copyright 2024 ISB Bayern + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Selectors used by the module. + */ +export const SELECTORS = { + DELACTION: 'div.commandbar a#delselected', + SELECTBOX: 'table#slotmanager input.slotselect', +}; + +/** + * Add event listener to the delete link. + * @param {*} baseurl + */ +export const init = (baseurl) => { + let link = document.querySelector(SELECTORS.DELACTION); + if (link !== null) { + link.addEventListener('click', function() { + collect_selection(link, baseurl); + }); + } +}; + +/** + * Copy the selected boxes into an input parameter of the respective form + * + * @param {String} link + * @param {String} baseurl + */ +export const collect_selection = (link, baseurl) => { + let sellist = ''; + document.querySelectorAll(SELECTORS.SELECTBOX).forEach(function(box) { + if (box.checked) { + if (sellist.length > 0) { + sellist += ','; + } + sellist += box.getAttribute('value'); + } + }); + link.setAttribute('href', baseurl + '&items=' + sellist); +}; diff --git a/amd/src/saveseen.js b/amd/src/saveseen.js new file mode 100644 index 00000000..361fc42d --- /dev/null +++ b/amd/src/saveseen.js @@ -0,0 +1,70 @@ + +export const SELECTORS = {CHECKBOXES: 'table#slotmanager form.studentselectform input.studentselect'}; +export const MOD = {}; + +/** + * Save the "seen" status. + * + * @param {Number} cmid the coursemodule id + * @param {Number} appid the id of the relevant appointment + * @param {Boolean} newseen + * @param {Object} spinner The spinner icon shown while saving + */ +export const save_status = (cmid, appid, newseen, spinner, ) => { + const url = M.cfg.wwwroot + '/mod/scheduler/ajax.php'; + // The request paramaters. + const params = 'action=saveseen&id='+cmid+'&appointmentid='+appid+'&seen='+newseen+'&sesskey='+M.cfg.sesskey; + const xhr = new XMLHttpRequest(); + + // 5 seconds of timeout. + xhr.timeout = 5000; + + xhr.onloadstart = () => { + spinner.style.visibility = 'visible'; + }; + + xhr.onload = () => { + if (xhr.status >= 200 && xhr.status < 300) { + setTimeout(() => { + spinner.style.visibility = 'hidden'; + const parent = spinner.parentNode; + parent.removeChild(spinner); + + }, 250); + } else { + const msg = { + name: xhr.status + ' ' + xhr.statusText, + message: xhr.responseText + }; + spinner.style.visibility = 'hidden'; + const parent = spinner.parentNode; + parent.removeChild(spinner); + throw new Error(JSON.stringify(msg)); + } + }; + + xhr.onerror = () => { + spinner.style.visibility = 'hidden'; + const parent = spinner.parentNode; + parent.removeChild(spinner); + throw new Error('Network request failed'); + }; + + xhr.open('POST', url, true); + xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + xhr.send(params); +}; + +export const init = (cmid) => { + document.querySelectorAll(SELECTORS.CHECKBOXES).forEach(function(box) { + box.addEventListener('change', function() { + var div = document.createElement('div'); + var span = document.createElement('span'); + div.classList.add('spinner-border', 'spinner-border-sm'); + span.classList.add('sr-only'); + div.appendChild(span); + box.closest('div').appendChild(div); + save_status(cmid, box.value, box.checked, div); + }); + }); +}; diff --git a/amd/src/studentlist.js b/amd/src/studentlist.js new file mode 100644 index 00000000..27369428 --- /dev/null +++ b/amd/src/studentlist.js @@ -0,0 +1,32 @@ + +export const CSS = { + EXPANDED: 'expanded', + COLLAPSED: 'collapsed' +}; + +export const setState = (id, expanded) => { + var image = document.getElementById(id); + var content = document.getElementById('list' + id); + if (expanded) { + content.removeClass(CSS.COLLAPSED); + content.addClass(CSS.EXPANDED); + image.set('src', M.util.image_url('t/expanded')); + } else { + content.removeClass(CSS.EXPANDED); + content.addClass(CSS.COLLAPSED); + image.set('src', M.util.image_url('t/collapsed')); + } +}; + +export const toggleState = (id) => { + var content = document.getElementById('list' + id); + var isVisible = content.hasClass(CSS.EXPANDED); + setState(id, !isVisible); +}; + +export const init = (imageid, expanded) => { + setState(imageid, expanded); + document.getElementById(imageid).addEventListener('click', () => { + toggleState(imageid); + }); +}; diff --git a/renderer.php b/renderer.php index fc9bca14..0698bfa1 100644 --- a/renderer.php +++ b/renderer.php @@ -519,9 +519,7 @@ public function render_scheduler_student_list(scheduler_student_list $studentlis $toggleid = html_writer::random_id('toggle'); if ($studentlist->expandable && count($studentlist->students) > 0) { - $this->page->requires->yui_module('moodle-mod_scheduler-studentlist', - 'M.mod_scheduler.studentlist.init', - array($toggleid, (boolean) $studentlist->expanded) ); + $this->page->requires->js_call_amd('mod_scheduler/studentlist', 'init', [$toggleid, (boolean) $studentlist->expanded]); $imgclass = 'studentlist-togglebutton'; $alttext = get_string('showparticipants', 'scheduler'); $o .= $this->output->pix_icon('t/switch', $alttext, 'moodle', @@ -708,8 +706,7 @@ public function render_scheduler_command_bar(scheduler_command_bar $commandbar) */ public function render_scheduler_slot_manager(scheduler_slot_manager $slotman) { - $this->page->requires->yui_module('moodle-mod_scheduler-saveseen', - 'M.mod_scheduler.saveseen.init', array($slotman->scheduler->cmid) ); + $this->page->requires->js_call_amd('mod_scheduler/saveseen', 'init', [$slotman->scheduler->cmid] ); $o = ''; diff --git a/teacherview.php b/teacherview.php index d4e7549d..eb75e4ee 100644 --- a/teacherview.php +++ b/teacherview.php @@ -468,8 +468,7 @@ function scheduler_print_schedulebox(scheduler $scheduler, $studentid, $groupid $delbuttons = array(); $delselectedurl = new moodle_url($actionurl, array('what' => 'deleteslots')); - $PAGE->requires->yui_module('moodle-mod_scheduler-delselected', 'M.mod_scheduler.delselected.init', - array($delselectedurl->out(false)) ); + $PAGE->requires->js_call_amd('mod_scheduler/delselected', 'init', [$delselectedurl->out(false)]); $delselected = $commandbar->action_link($delselectedurl, 'deleteselection', 't/delete', 'confirmdelete-selected', 'delselected'); $delselected->formid = 'delselected'; diff --git a/yui/build/moodle-mod_scheduler-delselected/moodle-mod_scheduler-delselected-debug.js b/yui/build/moodle-mod_scheduler-delselected/moodle-mod_scheduler-delselected-debug.js deleted file mode 100644 index 35ab9b19..00000000 --- a/yui/build/moodle-mod_scheduler-delselected/moodle-mod_scheduler-delselected-debug.js +++ /dev/null @@ -1,44 +0,0 @@ -YUI.add('moodle-mod_scheduler-delselected', function (Y, NAME) { - -// ESLint directives. -/* eslint-disable camelcase */ - -var SELECTORS = { - DELACTION: 'div.commandbar a#delselected', - SELECTBOX: 'table#slotmanager input.slotselect' -}, - MOD; - -M.mod_scheduler = M.mod_scheduler || {}; -MOD = M.mod_scheduler.delselected = {}; - -/** - * Copy the selected boexs into an input parameter of the respective form - * - * @param {String} link - * @param {String} baseurl - */ -MOD.collect_selection = function(link, baseurl) { - - var sellist = ''; - Y.all(SELECTORS.SELECTBOX).each(function(box) { - if (box.get('checked')) { - if (sellist.length > 0) { - sellist += ','; - } - sellist += box.get('value'); - } - }); - link.setAttribute('href', baseurl + '&items=' + sellist); -}; - -MOD.init = function(baseurl) { - var link = Y.one(SELECTORS.DELACTION); - if (link !== null) { - link.on('click', function() { - M.mod_scheduler.delselected.collect_selection(link, baseurl); - }); - } -}; - -}, '@VERSION@', {"requires": ["base", "node", "event"]}); diff --git a/yui/build/moodle-mod_scheduler-delselected/moodle-mod_scheduler-delselected-min.js b/yui/build/moodle-mod_scheduler-delselected/moodle-mod_scheduler-delselected-min.js deleted file mode 100644 index b6e08dfb..00000000 --- a/yui/build/moodle-mod_scheduler-delselected/moodle-mod_scheduler-delselected-min.js +++ /dev/null @@ -1 +0,0 @@ -YUI.add("moodle-mod_scheduler-delselected",function(c,e){var t="div.commandbar a#delselected",d="table#slotmanager input.slotselect";M.mod_scheduler=M.mod_scheduler||{},M.mod_scheduler.delselected={collect_selection:function(e,l){var t="";c.all(d).each(function(e){e.get("checked")&&(0 0) { - sellist += ','; - } - sellist += box.get('value'); - } - }); - link.setAttribute('href', baseurl + '&items=' + sellist); -}; - -MOD.init = function(baseurl) { - var link = Y.one(SELECTORS.DELACTION); - if (link !== null) { - link.on('click', function() { - M.mod_scheduler.delselected.collect_selection(link, baseurl); - }); - } -}; - -}, '@VERSION@', {"requires": ["base", "node", "event"]}); diff --git a/yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen-debug.js b/yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen-debug.js deleted file mode 100644 index bddee9d9..00000000 --- a/yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen-debug.js +++ /dev/null @@ -1,69 +0,0 @@ -YUI.add('moodle-mod_scheduler-saveseen', function (Y, NAME) { - -// ESLint directives. -/* eslint-disable camelcase */ - -var SELECTORS = { - CHECKBOXES: 'table#slotmanager form.studentselectform input.studentselect' -}, - MOD; - -M.mod_scheduler = M.mod_scheduler || {}; -MOD = M.mod_scheduler.saveseen = {}; - -/** - * Save the "seen" status. - * - * @param {Number} cmid the coursemodule id - * @param {Number} appid the id of the relevant appointment - * @param {Boolean} newseen - * @param {Object} spinner The spinner icon shown while saving - */ -MOD.save_status = function(cmid, appid, newseen, spinner) { - - Y.io(M.cfg.wwwroot + '/mod/scheduler/ajax.php', { - // The request paramaters. - data: { - action: 'saveseen', - id: cmid, - appointmentid: appid, - seen: newseen, - sesskey: M.cfg.sesskey - }, - - timeout: 5000, // 5 seconds of timeout. - - // Define the events. - on: { - start: function() { - spinner.show(); - }, - success: function() { - window.setTimeout(function() { - spinner.hide(); - }, 250); - }, - failure: function(transactionid, xhr) { - var msg = { - name: xhr.status + ' ' + xhr.statusText, - message: xhr.responseText - }; - spinner.hide(); - return new M.core.exception(msg); - } - }, - context: this - }); -}; - -MOD.init = function(cmid) { - Y.all(SELECTORS.CHECKBOXES).each(function(box) { - box.on('change', function() { - var spinner = M.util.add_spinner(Y, box.ancestor('div')); - M.mod_scheduler.saveseen.save_status(cmid, box.get('value'), box.get('checked'), spinner); - }); - }); -}; - - -}, '@VERSION@', {"requires": ["base", "node", "event"]}); diff --git a/yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen-min.js b/yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen-min.js deleted file mode 100644 index 450aed35..00000000 --- a/yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen-min.js +++ /dev/null @@ -1 +0,0 @@ -YUI.add("moodle-mod_scheduler-saveseen",function(o,e){var s="table#slotmanager form.studentselectform input.studentselect";M.mod_scheduler=M.mod_scheduler||{},M.mod_scheduler.saveseen={save_status:function(e,s,t,n){o.io(M.cfg.wwwroot+"/mod/scheduler/ajax.php",{data:{action:"saveseen",id:e,appointmentid:s,seen:t,sesskey:M.cfg.sesskey},timeout:5e3,on:{start:function(){n.show()},success:function(){window.setTimeout(function(){n.hide()},250)},failure:function(e,s){s={name:s.status+" "+s.statusText,message:s.responseText};return n.hide(),new M.core.exception(s)}},context:this})},init:function(t){o.all(s).each(function(s){s.on("change",function(){var e=M.util.add_spinner(o,s.ancestor("div"));M.mod_scheduler.saveseen.save_status(t,s.get("value"),s.get("checked"),e)})})}}},"@VERSION@",{requires:["base","node","event"]}); \ No newline at end of file diff --git a/yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen.js b/yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen.js deleted file mode 100644 index bddee9d9..00000000 --- a/yui/build/moodle-mod_scheduler-saveseen/moodle-mod_scheduler-saveseen.js +++ /dev/null @@ -1,69 +0,0 @@ -YUI.add('moodle-mod_scheduler-saveseen', function (Y, NAME) { - -// ESLint directives. -/* eslint-disable camelcase */ - -var SELECTORS = { - CHECKBOXES: 'table#slotmanager form.studentselectform input.studentselect' -}, - MOD; - -M.mod_scheduler = M.mod_scheduler || {}; -MOD = M.mod_scheduler.saveseen = {}; - -/** - * Save the "seen" status. - * - * @param {Number} cmid the coursemodule id - * @param {Number} appid the id of the relevant appointment - * @param {Boolean} newseen - * @param {Object} spinner The spinner icon shown while saving - */ -MOD.save_status = function(cmid, appid, newseen, spinner) { - - Y.io(M.cfg.wwwroot + '/mod/scheduler/ajax.php', { - // The request paramaters. - data: { - action: 'saveseen', - id: cmid, - appointmentid: appid, - seen: newseen, - sesskey: M.cfg.sesskey - }, - - timeout: 5000, // 5 seconds of timeout. - - // Define the events. - on: { - start: function() { - spinner.show(); - }, - success: function() { - window.setTimeout(function() { - spinner.hide(); - }, 250); - }, - failure: function(transactionid, xhr) { - var msg = { - name: xhr.status + ' ' + xhr.statusText, - message: xhr.responseText - }; - spinner.hide(); - return new M.core.exception(msg); - } - }, - context: this - }); -}; - -MOD.init = function(cmid) { - Y.all(SELECTORS.CHECKBOXES).each(function(box) { - box.on('change', function() { - var spinner = M.util.add_spinner(Y, box.ancestor('div')); - M.mod_scheduler.saveseen.save_status(cmid, box.get('value'), box.get('checked'), spinner); - }); - }); -}; - - -}, '@VERSION@', {"requires": ["base", "node", "event"]}); diff --git a/yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist-debug.js b/yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist-debug.js deleted file mode 100644 index b02622fd..00000000 --- a/yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist-debug.js +++ /dev/null @@ -1,43 +0,0 @@ -YUI.add('moodle-mod_scheduler-studentlist', function (Y, NAME) { - -// ESLint directives. -/* eslint-disable camelcase */ - -/* eslint-disable-next-line */ -var CSS = { - EXPANDED: 'expanded', - COLLAPSED: 'collapsed' -}; - -M.mod_scheduler = M.mod_scheduler || {}; -var MOD = M.mod_scheduler.studentlist = {}; - -MOD.setState = function(id, expanded) { - var image = Y.one('#' + id); - var content = Y.one('#list' + id); - if (expanded) { - content.removeClass(CSS.COLLAPSED); - content.addClass(CSS.EXPANDED); - image.set('src', M.util.image_url('t/expanded')); - } else { - content.removeClass(CSS.EXPANDED); - content.addClass(CSS.COLLAPSED); - image.set('src', M.util.image_url('t/collapsed')); - } -}; - -MOD.toggleState = function(id) { - var content = Y.one('#list' + id); - var isVisible = content.hasClass(CSS.EXPANDED); - this.setState(id, !isVisible); -}; - -MOD.init = function(imageid, expanded) { - this.setState(imageid, expanded); - Y.one('#' + imageid).on('click', function() { - M.mod_scheduler.studentlist.toggleState(imageid); - }); -}; - - -}, '@VERSION@', {"requires": ["base", "node", "event", "io"]}); diff --git a/yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist-min.js b/yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist-min.js deleted file mode 100644 index b62a7018..00000000 --- a/yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist-min.js +++ /dev/null @@ -1 +0,0 @@ -YUI.add("moodle-mod_scheduler-studentlist",function(d,e){var l="expanded",o="collapsed";M.mod_scheduler=M.mod_scheduler||{},M.mod_scheduler.studentlist={setState:function(e,t){var s=d.one("#"+e),e=d.one("#list"+e);t?(e.removeClass(o),e.addClass(l),s.set("src",M.util.image_url("t/expanded"))):(e.removeClass(l),e.addClass(o),s.set("src",M.util.image_url("t/collapsed")))},toggleState:function(e){var t=d.one("#list"+e),t=t.hasClass(l);this.setState(e,!t)},init:function(e,t){this.setState(e,t),d.one("#"+e).on("click",function(){M.mod_scheduler.studentlist.toggleState(e)})}}},"@VERSION@",{requires:["base","node","event","io"]}); \ No newline at end of file diff --git a/yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist.js b/yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist.js deleted file mode 100644 index b02622fd..00000000 --- a/yui/build/moodle-mod_scheduler-studentlist/moodle-mod_scheduler-studentlist.js +++ /dev/null @@ -1,43 +0,0 @@ -YUI.add('moodle-mod_scheduler-studentlist', function (Y, NAME) { - -// ESLint directives. -/* eslint-disable camelcase */ - -/* eslint-disable-next-line */ -var CSS = { - EXPANDED: 'expanded', - COLLAPSED: 'collapsed' -}; - -M.mod_scheduler = M.mod_scheduler || {}; -var MOD = M.mod_scheduler.studentlist = {}; - -MOD.setState = function(id, expanded) { - var image = Y.one('#' + id); - var content = Y.one('#list' + id); - if (expanded) { - content.removeClass(CSS.COLLAPSED); - content.addClass(CSS.EXPANDED); - image.set('src', M.util.image_url('t/expanded')); - } else { - content.removeClass(CSS.EXPANDED); - content.addClass(CSS.COLLAPSED); - image.set('src', M.util.image_url('t/collapsed')); - } -}; - -MOD.toggleState = function(id) { - var content = Y.one('#list' + id); - var isVisible = content.hasClass(CSS.EXPANDED); - this.setState(id, !isVisible); -}; - -MOD.init = function(imageid, expanded) { - this.setState(imageid, expanded); - Y.one('#' + imageid).on('click', function() { - M.mod_scheduler.studentlist.toggleState(imageid); - }); -}; - - -}, '@VERSION@', {"requires": ["base", "node", "event", "io"]}); diff --git a/yui/src/delselected/build.json b/yui/src/delselected/build.json deleted file mode 100644 index f4b97f01..00000000 --- a/yui/src/delselected/build.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "moodle-mod_scheduler-delselected", - "builds": { - "moodle-mod_scheduler-delselected": { - "jsfiles": [ - "delselected.js" - ] - } - } -} diff --git a/yui/src/delselected/js/delselected.js b/yui/src/delselected/js/delselected.js deleted file mode 100644 index 3f244173..00000000 --- a/yui/src/delselected/js/delselected.js +++ /dev/null @@ -1,40 +0,0 @@ -// ESLint directives. -/* eslint-disable camelcase */ - -var SELECTORS = { - DELACTION: 'div.commandbar a#delselected', - SELECTBOX: 'table#slotmanager input.slotselect' -}, - MOD; - -M.mod_scheduler = M.mod_scheduler || {}; -MOD = M.mod_scheduler.delselected = {}; - -/** - * Copy the selected boexs into an input parameter of the respective form - * - * @param {String} link - * @param {String} baseurl - */ -MOD.collect_selection = function(link, baseurl) { - - var sellist = ''; - Y.all(SELECTORS.SELECTBOX).each(function(box) { - if (box.get('checked')) { - if (sellist.length > 0) { - sellist += ','; - } - sellist += box.get('value'); - } - }); - link.setAttribute('href', baseurl + '&items=' + sellist); -}; - -MOD.init = function(baseurl) { - var link = Y.one(SELECTORS.DELACTION); - if (link !== null) { - link.on('click', function() { - M.mod_scheduler.delselected.collect_selection(link, baseurl); - }); - } -}; \ No newline at end of file diff --git a/yui/src/delselected/meta/delselected.json b/yui/src/delselected/meta/delselected.json deleted file mode 100644 index 87b1f1a3..00000000 --- a/yui/src/delselected/meta/delselected.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "moodle-mod_scheduler-delselected": { - "requires": [ - "base", "node", "event" - ] - } -} diff --git a/yui/src/saveseen/build.json b/yui/src/saveseen/build.json deleted file mode 100644 index 665cecea..00000000 --- a/yui/src/saveseen/build.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "moodle-mod_scheduler-saveseen", - "builds": { - "moodle-mod_scheduler-saveseen": { - "jsfiles": [ - "saveseen.js" - ] - } - } -} diff --git a/yui/src/saveseen/js/saveseen.js b/yui/src/saveseen/js/saveseen.js deleted file mode 100644 index 3eff0bb1..00000000 --- a/yui/src/saveseen/js/saveseen.js +++ /dev/null @@ -1,64 +0,0 @@ -// ESLint directives. -/* eslint-disable camelcase */ - -var SELECTORS = { - CHECKBOXES: 'table#slotmanager form.studentselectform input.studentselect' -}, - MOD; - -M.mod_scheduler = M.mod_scheduler || {}; -MOD = M.mod_scheduler.saveseen = {}; - -/** - * Save the "seen" status. - * - * @param {Number} cmid the coursemodule id - * @param {Number} appid the id of the relevant appointment - * @param {Boolean} newseen - * @param {Object} spinner The spinner icon shown while saving - */ -MOD.save_status = function(cmid, appid, newseen, spinner) { - - Y.io(M.cfg.wwwroot + '/mod/scheduler/ajax.php', { - // The request paramaters. - data: { - action: 'saveseen', - id: cmid, - appointmentid: appid, - seen: newseen, - sesskey: M.cfg.sesskey - }, - - timeout: 5000, // 5 seconds of timeout. - - // Define the events. - on: { - start: function() { - spinner.show(); - }, - success: function() { - window.setTimeout(function() { - spinner.hide(); - }, 250); - }, - failure: function(transactionid, xhr) { - var msg = { - name: xhr.status + ' ' + xhr.statusText, - message: xhr.responseText - }; - spinner.hide(); - return new M.core.exception(msg); - } - }, - context: this - }); -}; - -MOD.init = function(cmid) { - Y.all(SELECTORS.CHECKBOXES).each(function(box) { - box.on('change', function() { - var spinner = M.util.add_spinner(Y, box.ancestor('div')); - M.mod_scheduler.saveseen.save_status(cmid, box.get('value'), box.get('checked'), spinner); - }); - }); -}; diff --git a/yui/src/saveseen/meta/saveseen.json b/yui/src/saveseen/meta/saveseen.json deleted file mode 100644 index b5cd0404..00000000 --- a/yui/src/saveseen/meta/saveseen.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "moodle-mod_scheduler-saveseen": { - "requires": [ - "base", "node", "event" - ] - } -} diff --git a/yui/src/studentlist/build.json b/yui/src/studentlist/build.json deleted file mode 100644 index 73408998..00000000 --- a/yui/src/studentlist/build.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "moodle-mod_scheduler-studentlist", - "builds": { - "moodle-mod_scheduler-studentlist": { - "jsfiles": [ - "studentlist.js" - ] - } - } -} diff --git a/yui/src/studentlist/js/studentlist.js b/yui/src/studentlist/js/studentlist.js deleted file mode 100644 index acce41a2..00000000 --- a/yui/src/studentlist/js/studentlist.js +++ /dev/null @@ -1,38 +0,0 @@ -// ESLint directives. -/* eslint-disable camelcase */ - -/* eslint-disable-next-line */ -var CSS = { - EXPANDED: 'expanded', - COLLAPSED: 'collapsed' -}; - -M.mod_scheduler = M.mod_scheduler || {}; -var MOD = M.mod_scheduler.studentlist = {}; - -MOD.setState = function(id, expanded) { - var image = Y.one('#' + id); - var content = Y.one('#list' + id); - if (expanded) { - content.removeClass(CSS.COLLAPSED); - content.addClass(CSS.EXPANDED); - image.set('src', M.util.image_url('t/expanded')); - } else { - content.removeClass(CSS.EXPANDED); - content.addClass(CSS.COLLAPSED); - image.set('src', M.util.image_url('t/collapsed')); - } -}; - -MOD.toggleState = function(id) { - var content = Y.one('#list' + id); - var isVisible = content.hasClass(CSS.EXPANDED); - this.setState(id, !isVisible); -}; - -MOD.init = function(imageid, expanded) { - this.setState(imageid, expanded); - Y.one('#' + imageid).on('click', function() { - M.mod_scheduler.studentlist.toggleState(imageid); - }); -}; diff --git a/yui/src/studentlist/meta/studentlist.json b/yui/src/studentlist/meta/studentlist.json deleted file mode 100644 index d4c64dd6..00000000 --- a/yui/src/studentlist/meta/studentlist.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "moodle-mod_scheduler-studentlist": { - "requires": [ - "base", "node", "event", "io" - ] - } -} From 3b891cc25ceaf07cb8eb65e2c293555aecd776e2 Mon Sep 17 00:00:00 2001 From: "henning.bostelmann" Date: Thu, 25 Jul 2024 15:14:47 +0200 Subject: [PATCH 7/9] bumping version number and requirements --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index d1b81a41..d3546445 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ */ $plugin->component = 'mod_scheduler'; // Full name of the plugin (used for diagnostics). -$plugin->version = 2023052400; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2024072500; // The current module version (Date: YYYYMMDDXX). $plugin->release = '4.x dev'; // Human-friendly version name. -$plugin->requires = 2022041900; // Requires Moodle 4.0. +$plugin->requires = 2023100905; // Requires Moodle 4.3. $plugin->maturity = MATURITY_ALPHA; // Development release - not for production use. From 8f16575bdbb095d36722a02f378b0bc9216cda16 Mon Sep 17 00:00:00 2001 From: "henning.bostelmann" Date: Thu, 25 Jul 2024 15:49:21 +0200 Subject: [PATCH 8/9] CONTRIB-9504 fix behaviour on absent student note --- classes/model/appointment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/model/appointment.php b/classes/model/appointment.php index 977e23e9..9d61f6dd 100644 --- a/classes/model/appointment.php +++ b/classes/model/appointment.php @@ -132,7 +132,7 @@ public function is_attended() { * @return boolean */ public function has_studentnotes() { - return $this->get_scheduler()->uses_studentnotes() && + return $this->get_scheduler()->uses_studentnotes() && !empty($this->studentnote) && strlen(trim(strip_tags($this->studentnote))) > 0; } From e5bb8482e72f07456d7cc541211ce187d0528554 Mon Sep 17 00:00:00 2001 From: "henning.bostelmann" Date: Thu, 25 Jul 2024 16:48:01 +0200 Subject: [PATCH 9/9] CONTRIB-8369 fix calendar entry formatting when graphics are present --- classes/model/slot.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/classes/model/slot.php b/classes/model/slot.php index 3404d113..1c68c069 100644 --- a/classes/model/slot.php +++ b/classes/model/slot.php @@ -402,8 +402,9 @@ private function update_calendar() { $courseid = $scheduler->get_courseid(); $baseevent = new \stdClass(); - $baseevent->description = "$schedulername

$schedulerdescription"; - $baseevent->format = 1; + $baseevent->description = "$schedulername

" + .format_module_intro('scheduler', $scheduler, $scheduler->get_cmid(), false); + $baseevent->format = FORMAT_HTML; $baseevent->modulename = 'scheduler'; $baseevent->courseid = 0; $baseevent->instance = $this->get_parent_id();