diff --git a/course/amd/build/manual_completion_toggle.min.js b/course/amd/build/manual_completion_toggle.min.js index 0bd933bdf6b..2dce9b36bfa 100644 --- a/course/amd/build/manual_completion_toggle.min.js +++ b/course/amd/build/manual_completion_toggle.min.js @@ -1,2 +1,2 @@ -function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core_course/manual_completion_toggle",["exports","core/templates","core/notification","core_course/repository","core_course/events"],function(a,b,c,d,e){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=h(b);c=h(c);e=g(e);function f(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;f=function(){return a};return a}function g(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=f();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var g=d?Object.getOwnPropertyDescriptor(a,e):null;if(g&&(g.get||g.set)){Object.defineProperty(c,e,g)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function h(a){return a&&a.__esModule?a:{default:a}}function i(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function j(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){i(h,d,e,f,g,"next",a)}function g(a){i(h,d,e,f,g,"throw",a)}f(void 0)})}}var k={MANUAL_TOGGLE:"button[data-action=toggle-manual-completion]"},l={TOGGLE_MARK_DONE:"manual:mark-done",TOGGLE_UNDO:"manual:undo"},m=!1,n=function(){if(m){return}document.addEventListener("click",function(a){var b=a.target.closest(k.MANUAL_TOGGLE);if(b){a.preventDefault();o(b).catch(c.default.exception)}});m=!0};a.init=n;var o=function(){var a=j(regeneratorRuntime.mark(function a(f){var g,h,i,j,k,m,n,o,p,q,r;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:g=f.innerHTML;f.setAttribute("disabled","disabled");h=f.getAttribute("data-toggletype");i=f.getAttribute("data-cmid");j=f.getAttribute("data-activityname");k=h===l.TOGGLE_MARK_DONE;a.next=8;return b.default.render("core/loading",{});case 8:m=a.sent;a.next=11;return b.default.replaceNodeContents(f,m,"");case 11:a.prev=11;a.next=14;return(0,d.toggleManualCompletion)(i,k);case 14:n={cmid:i,activityname:j,overallcomplete:k,overallincomplete:!k,istrackeduser:!0};a.next=17;return b.default.renderForPromise("core_course/completion_manual",n);case 17:o=a.sent;a.next=20;return b.default.replaceNode(f,o.html,o.js);case 20:p=a.sent;q=p.pop();r=new CustomEvent(e.manualCompletionToggled,{bubbles:!0,detail:{cmid:i,activityname:j,completed:k}});q.dispatchEvent(r);a.next=31;break;case 26:a.prev=26;a.t0=a["catch"](11);f.removeAttribute("disabled");f.innerHTML=g;c.default.exception(a.t0);case 31:case"end":return a.stop();}}},a,null,[[11,26]])}));return function(){return a.apply(this,arguments)}}()}); +function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core_course/manual_completion_toggle",["exports","core/templates","core/notification","core_course/repository","core_course/events"],function(a,b,c,d,e){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=h(b);c=h(c);e=g(e);function f(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;f=function(){return a};return a}function g(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=f();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var g=d?Object.getOwnPropertyDescriptor(a,e):null;if(g&&(g.get||g.set)){Object.defineProperty(c,e,g)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function h(a){return a&&a.__esModule?a:{default:a}}function i(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function j(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){i(h,d,e,f,g,"next",a)}function g(a){i(h,d,e,f,g,"throw",a)}f(void 0)})}}var k={MANUAL_TOGGLE:"button[data-action=toggle-manual-completion]"},l={TOGGLE_MARK_DONE:"manual:mark-done",TOGGLE_UNDO:"manual:undo"},m=!1,n=function(){if(m){return}document.addEventListener("click",function(a){var b=a.target.closest(k.MANUAL_TOGGLE);if(b){a.preventDefault();o(b).catch(c.default.exception)}});m=!0};a.init=n;var o=function(){var a=j(regeneratorRuntime.mark(function a(f){var g,h,i,j,k,m,n,o,p,q,r,s;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:g=f.innerHTML;f.setAttribute("disabled","disabled");h=f.getAttribute("data-toggletype");i=f.getAttribute("data-cmid");j=f.getAttribute("data-activityname");k=h===l.TOGGLE_MARK_DONE;a.next=8;return b.default.render("core/loading",{});case 8:m=a.sent;a.next=11;return b.default.replaceNodeContents(f,m,"");case 11:a.prev=11;a.next=14;return(0,d.toggleManualCompletion)(i,k);case 14:n={cmid:i,activityname:j,overallcomplete:k,overallincomplete:!k,istrackeduser:!0};a.next=17;return b.default.renderForPromise("core_course/completion_manual",n);case 17:o=a.sent;a.next=20;return b.default.replaceNode(f,o.html,o.js);case 20:p=a.sent;q=p.pop();r=f.getAttribute("data-withavailability");s=new CustomEvent(e.manualCompletionToggled,{bubbles:!0,detail:{cmid:i,activityname:j,completed:k,withAvailability:r}});q.dispatchEvent(s);a.next=32;break;case 27:a.prev=27;a.t0=a["catch"](11);f.removeAttribute("disabled");f.innerHTML=g;c.default.exception(a.t0);case 32:case"end":return a.stop();}}},a,null,[[11,27]])}));return function(){return a.apply(this,arguments)}}()}); //# sourceMappingURL=manual_completion_toggle.min.js.map diff --git a/course/amd/build/manual_completion_toggle.min.js.map b/course/amd/build/manual_completion_toggle.min.js.map index a82ad987a34..a9a8ec8915a 100644 --- a/course/amd/build/manual_completion_toggle.min.js.map +++ b/course/amd/build/manual_completion_toggle.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/manual_completion_toggle.js"],"names":["SELECTORS","MANUAL_TOGGLE","TOGGLE_TYPES","TOGGLE_MARK_DONE","TOGGLE_UNDO","registered","init","document","addEventListener","e","toggleButton","target","closest","preventDefault","toggleManualCompletionState","catch","Notification","exception","originalInnerHtml","innerHTML","setAttribute","toggleType","getAttribute","cmid","activityname","completed","Templates","render","loadingHtml","replaceNodeContents","templateContext","overallcomplete","overallincomplete","istrackeduser","renderForPromise","renderObject","replaceNode","html","js","replacedNode","newToggleButton","pop","toggledEvent","CustomEvent","CourseEvents","manualCompletionToggled","bubbles","detail","dispatchEvent","removeAttribute"],"mappings":"ihBAyBA,OACA,OAEA,O,25BAOMA,CAAAA,CAAS,CAAG,CACdC,aAAa,CAAE,8CADD,C,CASZC,CAAY,CAAG,CACjBC,gBAAgB,CAAE,kBADD,CAEjBC,WAAW,CAAE,aAFI,C,CAUjBC,CAAU,G,CAKDC,CAAI,CAAG,UAAM,CACtB,GAAID,CAAJ,CAAgB,CACZ,MACH,CACDE,QAAQ,CAACC,gBAAT,CAA0B,OAA1B,CAAmC,SAACC,CAAD,CAAO,CACtC,GAAMC,CAAAA,CAAY,CAAGD,CAAC,CAACE,MAAF,CAASC,OAAT,CAAiBZ,CAAS,CAACC,aAA3B,CAArB,CACA,GAAIS,CAAJ,CAAkB,CACdD,CAAC,CAACI,cAAF,GACAC,CAA2B,CAACJ,CAAD,CAA3B,CAA0CK,KAA1C,CAAgDC,UAAaC,SAA7D,CACH,CACJ,CAND,EAOAZ,CAAU,GACb,C,UAQD,GAAMS,CAAAA,CAA2B,4CAAG,WAAMJ,CAAN,6GAE1BQ,CAF0B,CAENR,CAAY,CAACS,SAFP,CAKhCT,CAAY,CAACU,YAAb,CAA0B,UAA1B,CAAsC,UAAtC,EAGMC,CAR0B,CAQbX,CAAY,CAACY,YAAb,CAA0B,iBAA1B,CARa,CAS1BC,CAT0B,CASnBb,CAAY,CAACY,YAAb,CAA0B,WAA1B,CATmB,CAU1BE,CAV0B,CAUXd,CAAY,CAACY,YAAb,CAA0B,mBAA1B,CAVW,CAY1BG,CAZ0B,CAYdJ,CAAU,GAAKnB,CAAY,CAACC,gBAZd,gBAeNuB,WAAUC,MAAV,CAAiB,cAAjB,CAAiC,EAAjC,CAfM,QAe1BC,CAf0B,wBAgB1BF,WAAUG,mBAAV,CAA8BnB,CAA9B,CAA4CkB,CAA5C,CAAyD,EAAzD,CAhB0B,mCAoBtB,6BAAuBL,CAAvB,CAA6BE,CAA7B,CApBsB,SAuBtBK,CAvBsB,CAuBJ,CACpBP,IAAI,CAAEA,CADc,CAEpBC,YAAY,CAAEA,CAFM,CAGpBO,eAAe,CAAEN,CAHG,CAIpBO,iBAAiB,CAAE,CAACP,CAJA,CAKpBQ,aAAa,GALO,CAvBI,iBA8BDP,WAAUQ,gBAAV,CAA2B,+BAA3B,CAA4DJ,CAA5D,CA9BC,SA8BtBK,CA9BsB,wBAiCDT,WAAUU,WAAV,CAAsB1B,CAAtB,CAAoCyB,CAAY,CAACE,IAAjD,CAAuDF,CAAY,CAACG,EAApE,CAjCC,SAiCtBC,CAjCsB,QAkCtBC,CAlCsB,CAkCJD,CAAY,CAACE,GAAb,EAlCI,CAqCtBC,CArCsB,CAqCP,GAAIC,CAAAA,WAAJ,CAAgBC,CAAY,CAACC,uBAA7B,CAAsD,CACvEC,OAAO,GADgE,CAEvEC,MAAM,CAAE,CACJxB,IAAI,CAAJA,CADI,CAEJC,YAAY,CAAZA,CAFI,CAGJC,SAAS,CAATA,CAHI,CAF+D,CAAtD,CArCO,CA8C5Be,CAAe,CAACQ,aAAhB,CAA8BN,CAA9B,EA9C4B,sDAkD5BhC,CAAY,CAACuC,eAAb,CAA6B,UAA7B,EACAvC,CAAY,CAACS,SAAb,CAAyBD,CAAzB,CAGAF,UAAaC,SAAb,OAtD4B,wDAAH,uD","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 * Provides the functionality for toggling the manual completion state of a course module through\n * the manual completion button.\n *\n * @module core_course/manual_completion_toggle\n * @package core_course\n * @copyright 2021 Jun Pataleta \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport Notification from 'core/notification';\nimport {toggleManualCompletion} from 'core_course/repository';\nimport * as CourseEvents from 'core_course/events';\n\n/**\n * Selectors in the manual completion template.\n *\n * @type {{MANUAL_TOGGLE: string}}\n */\nconst SELECTORS = {\n MANUAL_TOGGLE: 'button[data-action=toggle-manual-completion]',\n};\n\n/**\n * Toggle type values for the data-toggletype attribute in the core_course/completion_manual template.\n *\n * @type {{TOGGLE_UNDO: string, TOGGLE_MARK_DONE: string}}\n */\nconst TOGGLE_TYPES = {\n TOGGLE_MARK_DONE: 'manual:mark-done',\n TOGGLE_UNDO: 'manual:undo',\n};\n\n/**\n * Whether the event listener has already been registered for this module.\n *\n * @type {boolean}\n */\nlet registered = false;\n\n/**\n * Registers the click event listener for the manual completion toggle button.\n */\nexport const init = () => {\n if (registered) {\n return;\n }\n document.addEventListener('click', (e) => {\n const toggleButton = e.target.closest(SELECTORS.MANUAL_TOGGLE);\n if (toggleButton) {\n e.preventDefault();\n toggleManualCompletionState(toggleButton).catch(Notification.exception);\n }\n });\n registered = true;\n};\n\n/**\n * Toggles the manual completion state of the module for the given user.\n *\n * @param {HTMLElement} toggleButton\n * @returns {Promise}\n */\nconst toggleManualCompletionState = async(toggleButton) => {\n // Make a copy of the original content of the button.\n const originalInnerHtml = toggleButton.innerHTML;\n\n // Disable the button to prevent double clicks.\n toggleButton.setAttribute('disabled', 'disabled');\n\n // Get button data.\n const toggleType = toggleButton.getAttribute('data-toggletype');\n const cmid = toggleButton.getAttribute('data-cmid');\n const activityname = toggleButton.getAttribute('data-activityname');\n // Get the target completion state.\n const completed = toggleType === TOGGLE_TYPES.TOGGLE_MARK_DONE;\n\n // Replace the button contents with the loading icon.\n const loadingHtml = await Templates.render('core/loading', {});\n await Templates.replaceNodeContents(toggleButton, loadingHtml, '');\n\n try {\n // Call the webservice to update the manual completion status.\n await toggleManualCompletion(cmid, completed);\n\n // All good so far. Refresh the manual completion button to reflect its new state by re-rendering the template.\n const templateContext = {\n cmid: cmid,\n activityname: activityname,\n overallcomplete: completed,\n overallincomplete: !completed,\n istrackeduser: true, // We know that we're tracking completion for this user given the presence of this button.\n };\n const renderObject = await Templates.renderForPromise('core_course/completion_manual', templateContext);\n\n // Replace the toggle button with the newly loaded template.\n const replacedNode = await Templates.replaceNode(toggleButton, renderObject.html, renderObject.js);\n const newToggleButton = replacedNode.pop();\n\n // Build manualCompletionToggled custom event.\n const toggledEvent = new CustomEvent(CourseEvents.manualCompletionToggled, {\n bubbles: true,\n detail: {\n cmid,\n activityname,\n completed,\n }\n });\n // Dispatch the manualCompletionToggled custom event.\n newToggleButton.dispatchEvent(toggledEvent);\n\n } catch (exception) {\n // In case of an error, revert the original state and appearance of the button.\n toggleButton.removeAttribute('disabled');\n toggleButton.innerHTML = originalInnerHtml;\n\n // Show the exception.\n Notification.exception(exception);\n }\n};\n"],"file":"manual_completion_toggle.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/manual_completion_toggle.js"],"names":["SELECTORS","MANUAL_TOGGLE","TOGGLE_TYPES","TOGGLE_MARK_DONE","TOGGLE_UNDO","registered","init","document","addEventListener","e","toggleButton","target","closest","preventDefault","toggleManualCompletionState","catch","Notification","exception","originalInnerHtml","innerHTML","setAttribute","toggleType","getAttribute","cmid","activityname","completed","Templates","render","loadingHtml","replaceNodeContents","templateContext","overallcomplete","overallincomplete","istrackeduser","renderForPromise","renderObject","replaceNode","html","js","replacedNode","newToggleButton","pop","withAvailability","toggledEvent","CustomEvent","CourseEvents","manualCompletionToggled","bubbles","detail","dispatchEvent","removeAttribute"],"mappings":"ihBAyBA,OACA,OAEA,O,25BAOMA,CAAAA,CAAS,CAAG,CACdC,aAAa,CAAE,8CADD,C,CASZC,CAAY,CAAG,CACjBC,gBAAgB,CAAE,kBADD,CAEjBC,WAAW,CAAE,aAFI,C,CAUjBC,CAAU,G,CAKDC,CAAI,CAAG,UAAM,CACtB,GAAID,CAAJ,CAAgB,CACZ,MACH,CACDE,QAAQ,CAACC,gBAAT,CAA0B,OAA1B,CAAmC,SAACC,CAAD,CAAO,CACtC,GAAMC,CAAAA,CAAY,CAAGD,CAAC,CAACE,MAAF,CAASC,OAAT,CAAiBZ,CAAS,CAACC,aAA3B,CAArB,CACA,GAAIS,CAAJ,CAAkB,CACdD,CAAC,CAACI,cAAF,GACAC,CAA2B,CAACJ,CAAD,CAA3B,CAA0CK,KAA1C,CAAgDC,UAAaC,SAA7D,CACH,CACJ,CAND,EAOAZ,CAAU,GACb,C,UAQD,GAAMS,CAAAA,CAA2B,4CAAG,WAAMJ,CAAN,+GAE1BQ,CAF0B,CAENR,CAAY,CAACS,SAFP,CAKhCT,CAAY,CAACU,YAAb,CAA0B,UAA1B,CAAsC,UAAtC,EAGMC,CAR0B,CAQbX,CAAY,CAACY,YAAb,CAA0B,iBAA1B,CARa,CAS1BC,CAT0B,CASnBb,CAAY,CAACY,YAAb,CAA0B,WAA1B,CATmB,CAU1BE,CAV0B,CAUXd,CAAY,CAACY,YAAb,CAA0B,mBAA1B,CAVW,CAY1BG,CAZ0B,CAYdJ,CAAU,GAAKnB,CAAY,CAACC,gBAZd,gBAeNuB,WAAUC,MAAV,CAAiB,cAAjB,CAAiC,EAAjC,CAfM,QAe1BC,CAf0B,wBAgB1BF,WAAUG,mBAAV,CAA8BnB,CAA9B,CAA4CkB,CAA5C,CAAyD,EAAzD,CAhB0B,mCAoBtB,6BAAuBL,CAAvB,CAA6BE,CAA7B,CApBsB,SAuBtBK,CAvBsB,CAuBJ,CACpBP,IAAI,CAAEA,CADc,CAEpBC,YAAY,CAAEA,CAFM,CAGpBO,eAAe,CAAEN,CAHG,CAIpBO,iBAAiB,CAAE,CAACP,CAJA,CAKpBQ,aAAa,GALO,CAvBI,iBA8BDP,WAAUQ,gBAAV,CAA2B,+BAA3B,CAA4DJ,CAA5D,CA9BC,SA8BtBK,CA9BsB,wBAiCDT,WAAUU,WAAV,CAAsB1B,CAAtB,CAAoCyB,CAAY,CAACE,IAAjD,CAAuDF,CAAY,CAACG,EAApE,CAjCC,SAiCtBC,CAjCsB,QAkCtBC,CAlCsB,CAkCJD,CAAY,CAACE,GAAb,EAlCI,CAqCtBC,CArCsB,CAqCHhC,CAAY,CAACY,YAAb,CAA0B,uBAA1B,CArCG,CAsCtBqB,CAtCsB,CAsCP,GAAIC,CAAAA,WAAJ,CAAgBC,CAAY,CAACC,uBAA7B,CAAsD,CACvEC,OAAO,GADgE,CAEvEC,MAAM,CAAE,CACJzB,IAAI,CAAJA,CADI,CAEJC,YAAY,CAAZA,CAFI,CAGJC,SAAS,CAATA,CAHI,CAIJiB,gBAAgB,CAAhBA,CAJI,CAF+D,CAAtD,CAtCO,CAgD5BF,CAAe,CAACS,aAAhB,CAA8BN,CAA9B,EAhD4B,sDAoD5BjC,CAAY,CAACwC,eAAb,CAA6B,UAA7B,EACAxC,CAAY,CAACS,SAAb,CAAyBD,CAAzB,CAGAF,UAAaC,SAAb,OAxD4B,wDAAH,uD","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 * Provides the functionality for toggling the manual completion state of a course module through\n * the manual completion button.\n *\n * @module core_course/manual_completion_toggle\n * @package core_course\n * @copyright 2021 Jun Pataleta \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport Notification from 'core/notification';\nimport {toggleManualCompletion} from 'core_course/repository';\nimport * as CourseEvents from 'core_course/events';\n\n/**\n * Selectors in the manual completion template.\n *\n * @type {{MANUAL_TOGGLE: string}}\n */\nconst SELECTORS = {\n MANUAL_TOGGLE: 'button[data-action=toggle-manual-completion]',\n};\n\n/**\n * Toggle type values for the data-toggletype attribute in the core_course/completion_manual template.\n *\n * @type {{TOGGLE_UNDO: string, TOGGLE_MARK_DONE: string}}\n */\nconst TOGGLE_TYPES = {\n TOGGLE_MARK_DONE: 'manual:mark-done',\n TOGGLE_UNDO: 'manual:undo',\n};\n\n/**\n * Whether the event listener has already been registered for this module.\n *\n * @type {boolean}\n */\nlet registered = false;\n\n/**\n * Registers the click event listener for the manual completion toggle button.\n */\nexport const init = () => {\n if (registered) {\n return;\n }\n document.addEventListener('click', (e) => {\n const toggleButton = e.target.closest(SELECTORS.MANUAL_TOGGLE);\n if (toggleButton) {\n e.preventDefault();\n toggleManualCompletionState(toggleButton).catch(Notification.exception);\n }\n });\n registered = true;\n};\n\n/**\n * Toggles the manual completion state of the module for the given user.\n *\n * @param {HTMLElement} toggleButton\n * @returns {Promise}\n */\nconst toggleManualCompletionState = async(toggleButton) => {\n // Make a copy of the original content of the button.\n const originalInnerHtml = toggleButton.innerHTML;\n\n // Disable the button to prevent double clicks.\n toggleButton.setAttribute('disabled', 'disabled');\n\n // Get button data.\n const toggleType = toggleButton.getAttribute('data-toggletype');\n const cmid = toggleButton.getAttribute('data-cmid');\n const activityname = toggleButton.getAttribute('data-activityname');\n // Get the target completion state.\n const completed = toggleType === TOGGLE_TYPES.TOGGLE_MARK_DONE;\n\n // Replace the button contents with the loading icon.\n const loadingHtml = await Templates.render('core/loading', {});\n await Templates.replaceNodeContents(toggleButton, loadingHtml, '');\n\n try {\n // Call the webservice to update the manual completion status.\n await toggleManualCompletion(cmid, completed);\n\n // All good so far. Refresh the manual completion button to reflect its new state by re-rendering the template.\n const templateContext = {\n cmid: cmid,\n activityname: activityname,\n overallcomplete: completed,\n overallincomplete: !completed,\n istrackeduser: true, // We know that we're tracking completion for this user given the presence of this button.\n };\n const renderObject = await Templates.renderForPromise('core_course/completion_manual', templateContext);\n\n // Replace the toggle button with the newly loaded template.\n const replacedNode = await Templates.replaceNode(toggleButton, renderObject.html, renderObject.js);\n const newToggleButton = replacedNode.pop();\n\n // Build manualCompletionToggled custom event.\n const withAvailability = toggleButton.getAttribute('data-withavailability');\n const toggledEvent = new CustomEvent(CourseEvents.manualCompletionToggled, {\n bubbles: true,\n detail: {\n cmid,\n activityname,\n completed,\n withAvailability,\n }\n });\n // Dispatch the manualCompletionToggled custom event.\n newToggleButton.dispatchEvent(toggledEvent);\n\n } catch (exception) {\n // In case of an error, revert the original state and appearance of the button.\n toggleButton.removeAttribute('disabled');\n toggleButton.innerHTML = originalInnerHtml;\n\n // Show the exception.\n Notification.exception(exception);\n }\n};\n"],"file":"manual_completion_toggle.min.js"} \ No newline at end of file diff --git a/course/amd/build/view.min.js b/course/amd/build/view.min.js new file mode 100644 index 00000000000..4add734de96 --- /dev/null +++ b/course/amd/build/view.min.js @@ -0,0 +1,2 @@ +function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core_course/view",["exports","core_course/events"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=d(b);function c(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;c=function(){return a};return a}function d(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=c();if(b&&b.has(a)){return b.get(a)}var d={},e=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var f in a){if(Object.prototype.hasOwnProperty.call(a,f)){var g=e?Object.getOwnPropertyDescriptor(a,f):null;if(g&&(g.get||g.set)){Object.defineProperty(d,f,g)}else{d[f]=a[f]}}}d.default=a;if(b){b.set(a,d)}return d}var e=!1,f=function(){if(e){return}document.addEventListener(b.manualCompletionToggled,function(a){var b=parseInt(a.detail.withAvailability);if(b){window.location.reload()}});e=!0};a.init=f}); +//# sourceMappingURL=view.min.js.map diff --git a/course/amd/build/view.min.js.map b/course/amd/build/view.min.js.map new file mode 100644 index 00000000000..49e5e62c599 --- /dev/null +++ b/course/amd/build/view.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/view.js"],"names":["registered","init","document","addEventListener","CourseEvents","manualCompletionToggled","e","withAvailability","parseInt","detail","window","location","reload"],"mappings":"ybAwBA,O,yiBAOIA,CAAAA,CAAU,G,CAKDC,CAAI,CAAG,UAAM,CACtB,GAAID,CAAJ,CAAgB,CACZ,MACH,CAEDE,QAAQ,CAACC,gBAAT,CAA0BC,CAAY,CAACC,uBAAvC,CAAgE,SAACC,CAAD,CAAO,CACnE,GAAMC,CAAAA,CAAgB,CAAGC,QAAQ,CAACF,CAAC,CAACG,MAAF,CAASF,gBAAV,CAAjC,CACA,GAAIA,CAAJ,CAAsB,CAElBG,MAAM,CAACC,QAAP,CAAgBC,MAAhB,EACH,CACJ,CAND,EAOAZ,CAAU,GACb,C","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 * JS module for the course homepage.\n *\n * @module core_course/view\n * @package core_course\n * @copyright 2021 Jun Pataleta \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as CourseEvents from 'core_course/events';\n\n/**\n * Whether the event listener has already been registered for this module.\n *\n * @type {boolean}\n */\nlet registered = false;\n\n/**\n * Function to intialise and register event listeners for this module.\n */\nexport const init = () => {\n if (registered) {\n return;\n }\n // Listen for toggled manual completion states of activities.\n document.addEventListener(CourseEvents.manualCompletionToggled, (e) => {\n const withAvailability = parseInt(e.detail.withAvailability);\n if (withAvailability) {\n // Reload the page when the toggled manual completion button has availability conditions linked to it.\n window.location.reload();\n }\n });\n registered = true;\n};\n"],"file":"view.min.js"} \ No newline at end of file diff --git a/course/amd/src/manual_completion_toggle.js b/course/amd/src/manual_completion_toggle.js index 4429bee2d75..20506de5fcd 100644 --- a/course/amd/src/manual_completion_toggle.js +++ b/course/amd/src/manual_completion_toggle.js @@ -114,12 +114,14 @@ const toggleManualCompletionState = async(toggleButton) => { const newToggleButton = replacedNode.pop(); // Build manualCompletionToggled custom event. + const withAvailability = toggleButton.getAttribute('data-withavailability'); const toggledEvent = new CustomEvent(CourseEvents.manualCompletionToggled, { bubbles: true, detail: { cmid, activityname, completed, + withAvailability, } }); // Dispatch the manualCompletionToggled custom event. diff --git a/course/amd/src/view.js b/course/amd/src/view.js new file mode 100644 index 00000000000..721067ddc60 --- /dev/null +++ b/course/amd/src/view.js @@ -0,0 +1,50 @@ +// 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 . + +/** + * JS module for the course homepage. + * + * @module core_course/view + * @package core_course + * @copyright 2021 Jun Pataleta + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +import * as CourseEvents from 'core_course/events'; + +/** + * Whether the event listener has already been registered for this module. + * + * @type {boolean} + */ +let registered = false; + +/** + * Function to intialise and register event listeners for this module. + */ +export const init = () => { + if (registered) { + return; + } + // Listen for toggled manual completion states of activities. + document.addEventListener(CourseEvents.manualCompletionToggled, (e) => { + const withAvailability = parseInt(e.detail.withAvailability); + if (withAvailability) { + // Reload the page when the toggled manual completion button has availability conditions linked to it. + window.location.reload(); + } + }); + registered = true; +}; diff --git a/course/classes/output/activity_information.php b/course/classes/output/activity_information.php index 2d281c31b22..6847ca7b65a 100644 --- a/course/classes/output/activity_information.php +++ b/course/classes/output/activity_information.php @@ -29,6 +29,7 @@ use cm_info; use completion_info; use context; use core\activity_dates; +use core_availability\info; use core_completion\cm_completion_details; use core_user; use core_user\fields; @@ -90,6 +91,8 @@ class activity_information implements renderable, templatable { * @return stdClass */ protected function build_completion_data(): stdClass { + global $CFG; + $data = new stdClass(); $data->hascompletion = $this->cmcompletion->has_completion(); @@ -124,6 +127,16 @@ class activity_information implements renderable, templatable { $data->accessibledescription = get_string($setbylangkey, 'course', $setbydata); } + // Whether the completion of this activity controls the availability of other activities/sections in the course. + $data->withavailability = false; + $course = $this->cminfo->get_course(); + // An activity with manual completion tracking which is used to enable access to other activities/sections in + // the course needs to refresh the page after having its completion state toggled. This withavailability flag will enable + // this functionality on the course homepage. Otherwise, the completion toggling will just happen normally via ajax. + if ($this->cmcompletion->has_completion() && !$this->cmcompletion->is_automatic()) { + $data->withavailability = !empty($CFG->enableavailability) && info::completion_value_used($course, $this->cminfo->id); + } + // Build automatic completion details. $details = []; foreach ($this->cmcompletion->get_details() as $key => $detail) { diff --git a/course/templates/completion_manual.mustache b/course/templates/completion_manual.mustache index c8b38b1ac37..fd1f57b28e9 100644 --- a/course/templates/completion_manual.mustache +++ b/course/templates/completion_manual.mustache @@ -28,7 +28,7 @@ }} {{#istrackeduser}} {{#overallcomplete}} -