diff --git a/course/amd/build/activitychooser.min.js b/course/amd/build/activitychooser.min.js index 114a575af80..56f63748ec5 100644 --- a/course/amd/build/activitychooser.min.js +++ b/course/amd/build/activitychooser.min.js @@ -1,2 +1,2 @@ -define ("core_course/activitychooser",["exports","core_course/local/activitychooser/dialogue","core_course/local/activitychooser/repository","core_course/local/activitychooser/selectors","core/custom_interaction_events","core/templates","core/modal_factory","core/str","core/pending"],function(a,b,c,d,e,f,g,h,i){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=k(b);c=k(c);d=j(d);e=j(e);f=k(f);g=k(g);i=j(i);function j(a){return a&&a.__esModule?a:{default:a}}function k(a){if(a&&a.__esModule){return a}else{var b={};if(null!=a){for(var c in a){if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};if(d.get||d.set){Object.defineProperty(b,c,d)}else{b[c]=a[c]}}}}b.default=a;return b}}function l(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 m(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){l(h,d,e,f,g,"next",a)}function g(a){l(h,d,e,f,g,"throw",a)}f(void 0)})}}var n=function(a){var b=new i.default;o(a);b.resolve()};a.init=n;var o=function(a){var f=["click",e.default.events.activate,e.default.events.keyboardActivate],g=function(){var b=null;return function(){if(!b){b=new Promise(function(b){b(c.activityModules(a))})}return b}}();e.default.define(document,f);f.forEach(function(a){document.addEventListener(a,function(){var a=m(regeneratorRuntime.mark(function a(c){var e,f,h,i,j;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:if(!c.target.closest(d.default.elements.sectionmodchooser)){a.next=11;break}a.next=3;return g();case 3:e=a.sent;f=c.target.closest(d.default.elements.sectionmodchooser);h=u(e,f.dataset.sectionid);i=p(e,f.dataset.sectionid);a.next=9;return q(i);case 9:j=a.sent;b.displayChooser(f,j,i,h);case 11:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}())})},p=function(a,b){var c=JSON.parse(JSON.stringify(a));c.content_items.forEach(function(a){a.link+="§ion="+b});return c.content_items},q=function(a){return s(r(a))},r=function(a){var b=a.filter(function(a){return!0===a.favourite}),c=a.filter(function(a){return!0===a.recommended}),d=!!b.length,e=!!(c.length&&!1===d);return{default:a,favourites:b,recommended:c,favouritesFirst:d,recommendedFirst:e,fallback:!1===d&&!1===e}},s=function(a){return g.create({type:g.types.DEFAULT,title:(0,h.get_string)("addresourceoractivity"),body:f.render("core_course/chooser",a),large:!0,templateContext:{classes:"modchooser"}})},t=function(a,b){a.classList.add("d-none");if(a.classList.contains("active")){a.classList.remove("active");var f=b.querySelector(d.default.regions.favouriteTab);f.classList.remove("active");var c=b.querySelector(d.default.regions.recommendedTabNav),e=b.querySelector(d.default.regions.defaultTabNav);if(!1===c.classList.contains("d-none")){c.classList.add("active");var g=b.querySelector(d.default.regions.recommendedTab);g.classList.add("active")}else{e.classList.add("active");var h=b.querySelector(d.default.regions.defaultTab);h.classList.add("active")}}},u=function(a,b){return function(){var c=m(regeneratorRuntime.mark(function c(e,g,h){var i,j,k,l,m,n,o,q,r,s,u;return regeneratorRuntime.wrap(function(c){while(1){switch(c.prev=c.next){case 0:i=h.querySelector(d.default.render.favourites);j=h.querySelectorAll("[data-internal=\"".concat(e,"\"] ").concat(d.default.actions.optionActions.manageFavourite));k=h.querySelector(d.default.regions.favouriteTabNav);l=a.content_items.find(function(a){var b=a.name;return b===e});m={};if(!l){c.next=27;break}if(!g){c.next=21;break}l.favourite=!0;m.content_items=a.content_items.filter(function(a){return!0===a.favourite});n=p(m,b);c.next=12;return f.renderForPromise("core_course/chooser_favourites",{favourites:n});case 12:o=c.sent;q=o.html;r=o.js;c.next=17;return f.replaceNodeContents(i,q,r);case 17:Array.from(j).forEach(function(a){a.classList.remove("text-muted");a.classList.add("text-primary");a.dataset.favourited="true";a.setAttribute("aria-pressed",!0);a.firstElementChild.classList.remove("fa-star-o");a.firstElementChild.classList.add("fa-star")});k.classList.remove("d-none");c.next=27;break;case 21:l.favourite=!1;s=i.querySelector("[data-internal=\"".concat(e,"\"]"));s.parentNode.removeChild(s);Array.from(j).forEach(function(a){a.classList.add("text-muted");a.classList.remove("text-primary");a.dataset.favourited="false";a.setAttribute("aria-pressed",!1);a.firstElementChild.classList.remove("fa-star");a.firstElementChild.classList.add("fa-star-o")});u=a.content_items.filter(function(a){return!0===a.favourite});if(0===u.length){t(k,h)}case 27:case"end":return c.stop();}}},c)}));return function(){return c.apply(this,arguments)}}()}}); +define ("core_course/activitychooser",["exports","core_course/local/activitychooser/dialogue","core_course/local/activitychooser/repository","core_course/local/activitychooser/selectors","core/custom_interaction_events","core/templates","core/modal_factory","core/str","core/pending"],function(a,b,c,d,e,f,g,h,i){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=k(b);c=k(c);d=j(d);e=j(e);f=k(f);g=k(g);i=j(i);function j(a){return a&&a.__esModule?a:{default:a}}function k(a){if(a&&a.__esModule){return a}else{var b={};if(null!=a){for(var c in a){if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};if(d.get||d.set){Object.defineProperty(b,c,d)}else{b[c]=a[c]}}}}b.default=a;return b}}function l(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 m(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){l(h,d,e,f,g,"next",a)}function g(a){l(h,d,e,f,g,"throw",a)}f(void 0)})}}var n=function(a){var b=new i.default;o(a);b.resolve()};a.init=n;var o=function(a){var f=["click",e.default.events.activate,e.default.events.keyboardActivate],g=function(){var b=null;return function(){if(!b){b=new Promise(function(b){b(c.activityModules(a))})}return b}}();e.default.define(document,f);f.forEach(function(a){document.addEventListener(a,function(){var a=m(regeneratorRuntime.mark(function a(c){var e,f,h,i,j;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:if(!c.target.closest(d.default.elements.sectionmodchooser)){a.next=11;break}a.next=3;return g();case 3:e=a.sent;f=c.target.closest(d.default.elements.sectionmodchooser);h=u(e,f.dataset.sectionid);i=p(e,f.dataset.sectionid);a.next=9;return q(i);case 9:j=a.sent;b.displayChooser(f,j,i,h);case 11:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}())})},p=function(a,b){var c=JSON.parse(JSON.stringify(a));c.content_items.forEach(function(a){a.link+="§ion="+b});return c.content_items},q=function(a){return s(r(a))},r=function(a){var b=a.filter(function(a){return!0===a.favourite}),c=a.filter(function(a){return!0===a.recommended}),d=!!b.length,e=!!(c.length&&!1===d);return{default:a,favourites:b,recommended:c,favouritesFirst:d,recommendedFirst:e,fallback:!1===d&&!1===e}},s=function(a){return g.create({type:g.types.DEFAULT,title:(0,h.get_string)("addresourceoractivity"),body:f.render("core_course/activitychooser",a),large:!0,templateContext:{classes:"modchooser"}})},t=function(a,b){a.classList.add("d-none");if(a.classList.contains("active")){a.classList.remove("active");var f=b.querySelector(d.default.regions.favouriteTab);f.classList.remove("active");var c=b.querySelector(d.default.regions.recommendedTabNav),e=b.querySelector(d.default.regions.defaultTabNav);if(!1===c.classList.contains("d-none")){c.classList.add("active");var g=b.querySelector(d.default.regions.recommendedTab);g.classList.add("active")}else{e.classList.add("active");var h=b.querySelector(d.default.regions.defaultTab);h.classList.add("active")}}},u=function(a,b){return function(){var c=m(regeneratorRuntime.mark(function c(e,g,h){var i,j,k,l,m,n,o,q,r,s,u;return regeneratorRuntime.wrap(function(c){while(1){switch(c.prev=c.next){case 0:i=h.querySelector(d.default.render.favourites);j=h.querySelectorAll("[data-internal=\"".concat(e,"\"] ").concat(d.default.actions.optionActions.manageFavourite));k=h.querySelector(d.default.regions.favouriteTabNav);l=a.content_items.find(function(a){var b=a.name;return b===e});m={};if(!l){c.next=27;break}if(!g){c.next=21;break}l.favourite=!0;m.content_items=a.content_items.filter(function(a){return!0===a.favourite});n=p(m,b);c.next=12;return f.renderForPromise("core_course/local/activitychooser/favourites",{favourites:n});case 12:o=c.sent;q=o.html;r=o.js;c.next=17;return f.replaceNodeContents(i,q,r);case 17:Array.from(j).forEach(function(a){a.classList.remove("text-muted");a.classList.add("text-primary");a.dataset.favourited="true";a.setAttribute("aria-pressed",!0);a.firstElementChild.classList.remove("fa-star-o");a.firstElementChild.classList.add("fa-star")});k.classList.remove("d-none");c.next=27;break;case 21:l.favourite=!1;s=i.querySelector("[data-internal=\"".concat(e,"\"]"));s.parentNode.removeChild(s);Array.from(j).forEach(function(a){a.classList.add("text-muted");a.classList.remove("text-primary");a.dataset.favourited="false";a.setAttribute("aria-pressed",!1);a.firstElementChild.classList.remove("fa-star");a.firstElementChild.classList.add("fa-star-o")});u=a.content_items.filter(function(a){return!0===a.favourite});if(0===u.length){t(k,h)}case 27:case"end":return c.stop();}}},c)}));return function(){return c.apply(this,arguments)}}()}}); //# sourceMappingURL=activitychooser.min.js.map diff --git a/course/amd/build/activitychooser.min.js.map b/course/amd/build/activitychooser.min.js.map index 5dc3ca7857b..9201790ed32 100644 --- a/course/amd/build/activitychooser.min.js.map +++ b/course/amd/build/activitychooser.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/activitychooser.js"],"names":["init","courseId","pendingPromise","Pending","registerListenerEvents","resolve","events","CustomEvents","activate","keyboardActivate","fetchModuleData","innerPromise","Promise","Repository","activityModules","define","document","forEach","event","addEventListener","e","target","closest","selectors","elements","sectionmodchooser","data","caller","favouriteFunction","partiallyAppliedFavouriteManager","dataset","sectionid","builtModuleData","sectionIdMapper","modalBuilder","sectionModal","ChooserDialogue","displayChooser","webServiceData","id","newData","JSON","parse","stringify","content_items","module","link","buildModal","templateDataBuilder","favourites","filter","mod","favourite","recommended","favouritesFirst","length","recommendedFirst","fallback","ModalFactory","create","type","types","DEFAULT","title","body","Templates","render","large","templateContext","classes","nullFavouriteDomManager","favouriteTabNav","modalBody","classList","add","contains","remove","favouriteTab","querySelector","regions","recommendedTabNav","defaultTabNav","recommendedTab","defaultTab","moduleData","sectionId","internal","favouriteArea","favouriteButtons","querySelectorAll","actions","optionActions","manageFavourite","result","find","name","newFaves","builtFaves","renderForPromise","html","js","replaceNodeContents","Array","from","element","favourited","setAttribute","firstElementChild","nodeToRemove","parentNode","removeChild"],"mappings":"qYAwBA,OACA,OACA,OACA,OACA,OACA,OAEA,O,grBAQO,GAAMA,CAAAA,CAAI,CAAG,SAAAC,CAAQ,CAAI,CAC5B,GAAMC,CAAAA,CAAc,CAAG,GAAIC,UAA3B,CAEAC,CAAsB,CAACH,CAAD,CAAtB,CAEAC,CAAc,CAACG,OAAf,EACH,CANM,C,YAcDD,CAAAA,CAAsB,CAAG,SAACH,CAAD,CAAc,IACnCK,CAAAA,CAAM,CAAG,CACX,OADW,CAEXC,UAAaD,MAAb,CAAoBE,QAFT,CAGXD,UAAaD,MAAb,CAAoBG,gBAHT,CAD0B,CAOnCC,CAAe,CAAI,UAAM,CAC3B,GAAIC,CAAAA,CAAY,CAAG,IAAnB,CAEA,MAAO,WAAM,CACT,GAAI,CAACA,CAAL,CAAmB,CACfA,CAAY,CAAG,GAAIC,CAAAA,OAAJ,CAAY,SAACP,CAAD,CAAa,CACpCA,CAAO,CAACQ,CAAU,CAACC,eAAX,CAA2Bb,CAA3B,CAAD,CACV,CAFc,CAGlB,CAED,MAAOU,CAAAA,CACV,CACJ,CAZuB,EAPiB,CAqBzCJ,UAAaQ,MAAb,CAAoBC,QAApB,CAA8BV,CAA9B,EAGAA,CAAM,CAACW,OAAP,CAAe,SAACC,CAAD,CAAW,CACtBF,QAAQ,CAACG,gBAAT,CAA0BD,CAA1B,4CAAiC,WAAME,CAAN,qGACzBA,CAAC,CAACC,MAAF,CAASC,OAAT,CAAiBC,UAAUC,QAAV,CAAmBC,iBAApC,CADyB,iCAENf,CAAAA,CAAe,EAFT,QAEnBgB,CAFmB,QAGnBC,CAHmB,CAGVP,CAAC,CAACC,MAAF,CAASC,OAAT,CAAiBC,UAAUC,QAAV,CAAmBC,iBAApC,CAHU,CAInBG,CAJmB,CAICC,CAAgC,CAACH,CAAD,CAAOC,CAAM,CAACG,OAAP,CAAeC,SAAtB,CAJjC,CAKnBC,CALmB,CAKDC,CAAe,CAACP,CAAD,CAAOC,CAAM,CAACG,OAAP,CAAeC,SAAtB,CALd,gBAMEG,CAAAA,CAAY,CAACF,CAAD,CANd,QAMnBG,CANmB,QAQzBC,CAAe,CAACC,cAAhB,CAA+BV,CAA/B,CAAuCQ,CAAvC,CAAqDH,CAArD,CAAsEJ,CAAtE,EARyB,yCAAjC,wDAWH,CAZD,CAaH,C,CAWKK,CAAe,CAAG,SAACK,CAAD,CAAiBC,CAAjB,CAAwB,CAE5C,GAAMC,CAAAA,CAAO,CAAGC,IAAI,CAACC,KAAL,CAAWD,IAAI,CAACE,SAAL,CAAeL,CAAf,CAAX,CAAhB,CACAE,CAAO,CAACI,aAAR,CAAsB3B,OAAtB,CAA8B,SAAC4B,CAAD,CAAY,CACtCA,CAAM,CAACC,IAAP,EAAe,YAAcP,CAChC,CAFD,EAGA,MAAOC,CAAAA,CAAO,CAACI,aAClB,C,CASKV,CAAY,CAAG,SAAAR,CAAI,QAAIqB,CAAAA,CAAU,CAACC,CAAmB,CAACtB,CAAD,CAApB,CAAd,C,CASnBsB,CAAmB,CAAG,SAACtB,CAAD,CAAU,IAE5BuB,CAAAA,CAAU,CAAGvB,CAAI,CAACwB,MAAL,CAAY,SAAAC,CAAG,QAAI,KAAAA,CAAG,CAACC,SAAR,CAAf,CAFe,CAG5BC,CAAW,CAAG3B,CAAI,CAACwB,MAAL,CAAY,SAAAC,CAAG,QAAI,KAAAA,CAAG,CAACE,WAAR,CAAf,CAHc,CAQ5BC,CAAe,CAAG,CAAC,CAACL,CAAU,CAACM,MARH,CAU5BC,CAAgB,CAAG,CAAC,EAAEH,CAAW,CAACE,MAAZ,EAAsB,KAAAD,CAAxB,CAVQ,CAclC,MAAO,CACH,QAAW5B,CADR,CAEHuB,UAAU,CAAEA,CAFT,CAGHI,WAAW,CAAEA,CAHV,CAIHC,eAAe,CAAEA,CAJd,CAKHE,gBAAgB,CAAEA,CALf,CAMHC,QAAQ,CARK,KAAAH,CAAe,EAAc,KAAAE,CAEvC,CAQV,C,CASKT,CAAU,CAAG,SAAArB,CAAI,CAAI,CACvB,MAAOgC,CAAAA,CAAY,CAACC,MAAb,CAAoB,CACvBC,IAAI,CAAEF,CAAY,CAACG,KAAb,CAAmBC,OADF,CAEvBC,KAAK,CAAE,iBAAU,uBAAV,CAFgB,CAGvBC,IAAI,CAAEC,CAAS,CAACC,MAAV,CAAiB,qBAAjB,CAAwCxC,CAAxC,CAHiB,CAIvByC,KAAK,GAJkB,CAKvBC,eAAe,CAAE,CACbC,OAAO,CAAE,YADI,CALM,CAApB,CASV,C,CAUKC,CAAuB,CAAG,SAACC,CAAD,CAAkBC,CAAlB,CAAgC,CAC5DD,CAAe,CAACE,SAAhB,CAA0BC,GAA1B,CAA8B,QAA9B,EAEA,GAAIH,CAAe,CAACE,SAAhB,CAA0BE,QAA1B,CAAmC,QAAnC,CAAJ,CAAkD,CAC9CJ,CAAe,CAACE,SAAhB,CAA0BG,MAA1B,CAAiC,QAAjC,EACA,GAAMC,CAAAA,CAAY,CAAGL,CAAS,CAACM,aAAV,CAAwBvD,UAAUwD,OAAV,CAAkBF,YAA1C,CAArB,CACAA,CAAY,CAACJ,SAAb,CAAuBG,MAAvB,CAA8B,QAA9B,EAH8C,GAIxCI,CAAAA,CAAiB,CAAGR,CAAS,CAACM,aAAV,CAAwBvD,UAAUwD,OAAV,CAAkBC,iBAA1C,CAJoB,CAKxCC,CAAa,CAAGT,CAAS,CAACM,aAAV,CAAwBvD,UAAUwD,OAAV,CAAkBE,aAA1C,CALwB,CAM9C,GAAI,KAAAD,CAAiB,CAACP,SAAlB,CAA4BE,QAA5B,CAAqC,QAArC,CAAJ,CAA8D,CAC1DK,CAAiB,CAACP,SAAlB,CAA4BC,GAA5B,CAAgC,QAAhC,EACA,GAAMQ,CAAAA,CAAc,CAAGV,CAAS,CAACM,aAAV,CAAwBvD,UAAUwD,OAAV,CAAkBG,cAA1C,CAAvB,CACAA,CAAc,CAACT,SAAf,CAAyBC,GAAzB,CAA6B,QAA7B,CACH,CAJD,IAIO,CACHO,CAAa,CAACR,SAAd,CAAwBC,GAAxB,CAA4B,QAA5B,EACA,GAAMS,CAAAA,CAAU,CAAGX,CAAS,CAACM,aAAV,CAAwBvD,UAAUwD,OAAV,CAAkBI,UAA1C,CAAnB,CACAA,CAAU,CAACV,SAAX,CAAqBC,GAArB,CAAyB,QAAzB,CACH,CAEJ,CACJ,C,CAWK7C,CAAgC,CAAG,SAACuD,CAAD,CAAaC,CAAb,CAA2B,CAQhE,kDAAO,WAAMC,CAAN,CAAgBlC,CAAhB,CAA2BoB,CAA3B,6GACGe,CADH,CACmBf,CAAS,CAACM,aAAV,CAAwBvD,UAAU2C,MAAV,CAAiBjB,UAAzC,CADnB,CAIGuC,CAJH,CAIsBhB,CAAS,CAACiB,gBAAV,4BAA8CH,CAA9C,gBAA4D/D,UAAUmE,OAAV,CAAkBC,aAAlB,CAAgCC,eAA5F,EAJtB,CAKGrB,CALH,CAKqBC,CAAS,CAACM,aAAV,CAAwBvD,UAAUwD,OAAV,CAAkBR,eAA1C,CALrB,CAMGsB,CANH,CAMYT,CAAU,CAACxC,aAAX,CAAyBkD,IAAzB,CAA8B,eAAEC,CAAAA,CAAF,GAAEA,IAAF,OAAYA,CAAAA,CAAI,GAAKT,CAArB,CAA9B,CANZ,CAOGU,CAPH,CAOc,EAPd,KAQCH,CARD,sBASKzC,CATL,kBAUKyC,CAAM,CAACzC,SAAP,IAEA4C,CAAQ,CAACpD,aAAT,CAAyBwC,CAAU,CAACxC,aAAX,CAAyBM,MAAzB,CAAgC,SAAAC,CAAG,QAAI,KAAAA,CAAG,CAACC,SAAR,CAAnC,CAAzB,CAEM6C,CAdX,CAcwBhE,CAAe,CAAC+D,CAAD,CAAWX,CAAX,CAdvC,iBAgB8BpB,CAAAA,CAAS,CAACiC,gBAAV,CAA2B,gCAA3B,CAA6D,CAACjD,UAAU,CAAEgD,CAAb,CAA7D,CAhB9B,kBAgBYE,CAhBZ,GAgBYA,IAhBZ,CAgBkBC,CAhBlB,GAgBkBA,EAhBlB,iBAkBWnC,CAAAA,CAAS,CAACoC,mBAAV,CAA8Bd,CAA9B,CAA6CY,CAA7C,CAAmDC,CAAnD,CAlBX,SAoBKE,KAAK,CAACC,IAAN,CAAWf,CAAX,EAA6BvE,OAA7B,CAAqC,SAACuF,CAAD,CAAa,CAC9CA,CAAO,CAAC/B,SAAR,CAAkBG,MAAlB,CAAyB,YAAzB,EACA4B,CAAO,CAAC/B,SAAR,CAAkBC,GAAlB,CAAsB,cAAtB,EACA8B,CAAO,CAAC1E,OAAR,CAAgB2E,UAAhB,CAA6B,MAA7B,CACAD,CAAO,CAACE,YAAR,CAAqB,cAArB,KACAF,CAAO,CAACG,iBAAR,CAA0BlC,SAA1B,CAAoCG,MAApC,CAA2C,WAA3C,EACA4B,CAAO,CAACG,iBAAR,CAA0BlC,SAA1B,CAAoCC,GAApC,CAAwC,SAAxC,CACH,CAPD,EASAH,CAAe,CAACE,SAAhB,CAA0BG,MAA1B,CAAiC,QAAjC,EA7BL,wBA+BKiB,CAAM,CAACzC,SAAP,IAEMwD,CAjCX,CAiC0BrB,CAAa,CAACT,aAAd,4BAA+CQ,CAA/C,QAjC1B,CAmCKsB,CAAY,CAACC,UAAb,CAAwBC,WAAxB,CAAoCF,CAApC,EAEAN,KAAK,CAACC,IAAN,CAAWf,CAAX,EAA6BvE,OAA7B,CAAqC,SAACuF,CAAD,CAAa,CAC9CA,CAAO,CAAC/B,SAAR,CAAkBC,GAAlB,CAAsB,YAAtB,EACA8B,CAAO,CAAC/B,SAAR,CAAkBG,MAAlB,CAAyB,cAAzB,EACA4B,CAAO,CAAC1E,OAAR,CAAgB2E,UAAhB,CAA6B,OAA7B,CACAD,CAAO,CAACE,YAAR,CAAqB,cAArB,KACAF,CAAO,CAACG,iBAAR,CAA0BlC,SAA1B,CAAoCG,MAApC,CAA2C,SAA3C,EACA4B,CAAO,CAACG,iBAAR,CAA0BlC,SAA1B,CAAoCC,GAApC,CAAwC,WAAxC,CACH,CAPD,EAQMsB,CA7CX,CA6CsBZ,CAAU,CAACxC,aAAX,CAAyBM,MAAzB,CAAgC,SAAAC,CAAG,QAAI,KAAAA,CAAG,CAACC,SAAR,CAAnC,CA7CtB,CA+CK,GAAwB,CAApB,GAAA4C,CAAQ,CAACzC,MAAb,CAA2B,CACvBe,CAAuB,CAACC,CAAD,CAAkBC,CAAlB,CAC1B,CAjDN,yCAAP,uDAqDH,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 * A type of dialogue used as for choosing modules in a course.\n *\n * @module core_course/activitychooser\n * @package core_course\n * @copyright 2020 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as ChooserDialogue from 'core_course/local/activitychooser/dialogue';\nimport * as Repository from 'core_course/local/activitychooser/repository';\nimport selectors from 'core_course/local/activitychooser/selectors';\nimport CustomEvents from 'core/custom_interaction_events';\nimport * as Templates from 'core/templates';\nimport * as ModalFactory from 'core/modal_factory';\nimport {get_string as getString} from 'core/str';\nimport Pending from 'core/pending';\n\n/**\n * Set up the activity chooser.\n *\n * @method init\n * @param {Number} courseId Course ID to use later on in fetchModules()\n */\nexport const init = courseId => {\n const pendingPromise = new Pending();\n\n registerListenerEvents(courseId);\n\n pendingPromise.resolve();\n};\n\n/**\n * Once a selection has been made make the modal & module information and pass it along\n *\n * @method registerListenerEvents\n * @param {Number} courseId\n */\nconst registerListenerEvents = (courseId) => {\n const events = [\n 'click',\n CustomEvents.events.activate,\n CustomEvents.events.keyboardActivate\n ];\n\n const fetchModuleData = (() => {\n let innerPromise = null;\n\n return () => {\n if (!innerPromise) {\n innerPromise = new Promise((resolve) => {\n resolve(Repository.activityModules(courseId));\n });\n }\n\n return innerPromise;\n };\n })();\n\n CustomEvents.define(document, events);\n\n // Display module chooser event listeners.\n events.forEach((event) => {\n document.addEventListener(event, async(e) => {\n if (e.target.closest(selectors.elements.sectionmodchooser)) {\n const data = await fetchModuleData();\n const caller = e.target.closest(selectors.elements.sectionmodchooser);\n const favouriteFunction = partiallyAppliedFavouriteManager(data, caller.dataset.sectionid);\n const builtModuleData = sectionIdMapper(data, caller.dataset.sectionid);\n const sectionModal = await modalBuilder(builtModuleData);\n\n ChooserDialogue.displayChooser(caller, sectionModal, builtModuleData, favouriteFunction);\n }\n });\n });\n};\n\n/**\n * Given the web service data and an ID we want to make a deep copy\n * of the WS data then add on the section ID to the addoption URL\n *\n * @method sectionIdMapper\n * @param {Object} webServiceData Our original data from the Web service call\n * @param {Array} id The ID of the section we need to append to the links\n * @return {Array} [modules] with URL's built\n */\nconst sectionIdMapper = (webServiceData, id) => {\n // We need to take a fresh deep copy of the original data as an object is a reference type.\n const newData = JSON.parse(JSON.stringify(webServiceData));\n newData.content_items.forEach((module) => {\n module.link += '§ion=' + id;\n });\n return newData.content_items;\n};\n\n/**\n * Build a modal for each section ID and store it into a map for quick access\n *\n * @method modalBuilder\n * @param {Map} data our map of section ID's & modules to generate modals for\n * @return {Object} Our modal that we are going to show the user\n */\nconst modalBuilder = data => buildModal(templateDataBuilder(data));\n\n/**\n * Given an array of modules we want to figure out where & how to place them into our template object\n *\n * @method templateDataBuilder\n * @param {Array} data our modules to manipulate into a Templatable object\n * @return {Object} Our built object ready to render out\n */\nconst templateDataBuilder = (data) => {\n // Filter the incoming data to find favourite & recommended modules.\n const favourites = data.filter(mod => mod.favourite === true);\n const recommended = data.filter(mod => mod.recommended === true);\n\n // Given the results of the above filters lets figure out what tab to set active.\n\n // We have some favourites.\n const favouritesFirst = !!favourites.length;\n // Check if we have no favourites but have some recommended.\n const recommendedFirst = !!(recommended.length && favouritesFirst === false);\n // We have nothing fallback to show all modules.\n const fallback = favouritesFirst === false && recommendedFirst === false;\n\n return {\n 'default': data,\n favourites: favourites,\n recommended: recommended,\n favouritesFirst: favouritesFirst,\n recommendedFirst: recommendedFirst,\n fallback: fallback,\n };\n};\n\n/**\n * Given an object we want to prebuild a modal ready to store into a map\n *\n * @method buildModal\n * @param {Object} data The template data which contains arrays of modules\n * @return {Object} The modal for the calling section with everything already set up\n */\nconst buildModal = data => {\n return ModalFactory.create({\n type: ModalFactory.types.DEFAULT,\n title: getString('addresourceoractivity'),\n body: Templates.render('core_course/chooser', data),\n large: true,\n templateContext: {\n classes: 'modchooser'\n }\n });\n};\n\n/**\n * A small helper function to handle the case where there are no more favourites\n * and we need to mess a bit with the available tabs in the chooser\n *\n * @method nullFavouriteDomManager\n * @param {HTMLElement} favouriteTabNav Dom node of the favourite tab nav\n * @param {HTMLElement} modalBody Our current modals' body\n */\nconst nullFavouriteDomManager = (favouriteTabNav, modalBody) => {\n favouriteTabNav.classList.add('d-none');\n // Need to set active to an available tab.\n if (favouriteTabNav.classList.contains('active')) {\n favouriteTabNav.classList.remove('active');\n const favouriteTab = modalBody.querySelector(selectors.regions.favouriteTab);\n favouriteTab.classList.remove('active');\n const recommendedTabNav = modalBody.querySelector(selectors.regions.recommendedTabNav);\n const defaultTabNav = modalBody.querySelector(selectors.regions.defaultTabNav);\n if (recommendedTabNav.classList.contains('d-none') === false) {\n recommendedTabNav.classList.add('active');\n const recommendedTab = modalBody.querySelector(selectors.regions.recommendedTab);\n recommendedTab.classList.add('active');\n } else {\n defaultTabNav.classList.add('active');\n const defaultTab = modalBody.querySelector(selectors.regions.defaultTab);\n defaultTab.classList.add('active');\n }\n\n }\n};\n\n/**\n * Export a curried function where the builtModules has been applied.\n * We have our array of modules so we can rerender the favourites area and have all of the items sorted.\n *\n * @method partiallyAppliedFavouriteManager\n * @param {Array} moduleData This is our raw WS data that we need to manipulate\n * @param {Number} sectionId We need this to add the sectionID to the URL's in the faves area after rerender\n * @return {Function} partially applied function so we can manipulate DOM nodes easily & update our internal array\n */\nconst partiallyAppliedFavouriteManager = (moduleData, sectionId) => {\n /**\n * Curried function that is being returned.\n *\n * @param {String} internal Internal name of the module to manage\n * @param {Boolean} favourite Is the caller adding a favourite or removing one?\n * @param {HTMLElement} modalBody What we need to update whilst we are here\n */\n return async(internal, favourite, modalBody) => {\n const favouriteArea = modalBody.querySelector(selectors.render.favourites);\n\n // eslint-disable-next-line max-len\n const favouriteButtons = modalBody.querySelectorAll(`[data-internal=\"${internal}\"] ${selectors.actions.optionActions.manageFavourite}`);\n const favouriteTabNav = modalBody.querySelector(selectors.regions.favouriteTabNav);\n const result = moduleData.content_items.find(({name}) => name === internal);\n const newFaves = {};\n if (result) {\n if (favourite) {\n result.favourite = true;\n\n newFaves.content_items = moduleData.content_items.filter(mod => mod.favourite === true);\n\n const builtFaves = sectionIdMapper(newFaves, sectionId);\n\n const {html, js} = await Templates.renderForPromise('core_course/chooser_favourites', {favourites: builtFaves});\n\n await Templates.replaceNodeContents(favouriteArea, html, js);\n\n Array.from(favouriteButtons).forEach((element) => {\n element.classList.remove('text-muted');\n element.classList.add('text-primary');\n element.dataset.favourited = 'true';\n element.setAttribute('aria-pressed', true);\n element.firstElementChild.classList.remove('fa-star-o');\n element.firstElementChild.classList.add('fa-star');\n });\n\n favouriteTabNav.classList.remove('d-none');\n } else {\n result.favourite = false;\n\n const nodeToRemove = favouriteArea.querySelector(`[data-internal=\"${internal}\"]`);\n\n nodeToRemove.parentNode.removeChild(nodeToRemove);\n\n Array.from(favouriteButtons).forEach((element) => {\n element.classList.add('text-muted');\n element.classList.remove('text-primary');\n element.dataset.favourited = 'false';\n element.setAttribute('aria-pressed', false);\n element.firstElementChild.classList.remove('fa-star');\n element.firstElementChild.classList.add('fa-star-o');\n });\n const newFaves = moduleData.content_items.filter(mod => mod.favourite === true);\n\n if (newFaves.length === 0) {\n nullFavouriteDomManager(favouriteTabNav, modalBody);\n }\n }\n }\n };\n};\n"],"file":"activitychooser.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/activitychooser.js"],"names":["init","courseId","pendingPromise","Pending","registerListenerEvents","resolve","events","CustomEvents","activate","keyboardActivate","fetchModuleData","innerPromise","Promise","Repository","activityModules","define","document","forEach","event","addEventListener","e","target","closest","selectors","elements","sectionmodchooser","data","caller","favouriteFunction","partiallyAppliedFavouriteManager","dataset","sectionid","builtModuleData","sectionIdMapper","modalBuilder","sectionModal","ChooserDialogue","displayChooser","webServiceData","id","newData","JSON","parse","stringify","content_items","module","link","buildModal","templateDataBuilder","favourites","filter","mod","favourite","recommended","favouritesFirst","length","recommendedFirst","fallback","ModalFactory","create","type","types","DEFAULT","title","body","Templates","render","large","templateContext","classes","nullFavouriteDomManager","favouriteTabNav","modalBody","classList","add","contains","remove","favouriteTab","querySelector","regions","recommendedTabNav","defaultTabNav","recommendedTab","defaultTab","moduleData","sectionId","internal","favouriteArea","favouriteButtons","querySelectorAll","actions","optionActions","manageFavourite","result","find","name","newFaves","builtFaves","renderForPromise","html","js","replaceNodeContents","Array","from","element","favourited","setAttribute","firstElementChild","nodeToRemove","parentNode","removeChild"],"mappings":"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","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 * A type of dialogue used as for choosing modules in a course.\n *\n * @module core_course/activitychooser\n * @package core_course\n * @copyright 2020 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as ChooserDialogue from 'core_course/local/activitychooser/dialogue';\nimport * as Repository from 'core_course/local/activitychooser/repository';\nimport selectors from 'core_course/local/activitychooser/selectors';\nimport CustomEvents from 'core/custom_interaction_events';\nimport * as Templates from 'core/templates';\nimport * as ModalFactory from 'core/modal_factory';\nimport {get_string as getString} from 'core/str';\nimport Pending from 'core/pending';\n\n/**\n * Set up the activity chooser.\n *\n * @method init\n * @param {Number} courseId Course ID to use later on in fetchModules()\n */\nexport const init = courseId => {\n const pendingPromise = new Pending();\n\n registerListenerEvents(courseId);\n\n pendingPromise.resolve();\n};\n\n/**\n * Once a selection has been made make the modal & module information and pass it along\n *\n * @method registerListenerEvents\n * @param {Number} courseId\n */\nconst registerListenerEvents = (courseId) => {\n const events = [\n 'click',\n CustomEvents.events.activate,\n CustomEvents.events.keyboardActivate\n ];\n\n const fetchModuleData = (() => {\n let innerPromise = null;\n\n return () => {\n if (!innerPromise) {\n innerPromise = new Promise((resolve) => {\n resolve(Repository.activityModules(courseId));\n });\n }\n\n return innerPromise;\n };\n })();\n\n CustomEvents.define(document, events);\n\n // Display module chooser event listeners.\n events.forEach((event) => {\n document.addEventListener(event, async(e) => {\n if (e.target.closest(selectors.elements.sectionmodchooser)) {\n const data = await fetchModuleData();\n const caller = e.target.closest(selectors.elements.sectionmodchooser);\n const favouriteFunction = partiallyAppliedFavouriteManager(data, caller.dataset.sectionid);\n const builtModuleData = sectionIdMapper(data, caller.dataset.sectionid);\n const sectionModal = await modalBuilder(builtModuleData);\n\n ChooserDialogue.displayChooser(caller, sectionModal, builtModuleData, favouriteFunction);\n }\n });\n });\n};\n\n/**\n * Given the web service data and an ID we want to make a deep copy\n * of the WS data then add on the section ID to the addoption URL\n *\n * @method sectionIdMapper\n * @param {Object} webServiceData Our original data from the Web service call\n * @param {Array} id The ID of the section we need to append to the links\n * @return {Array} [modules] with URL's built\n */\nconst sectionIdMapper = (webServiceData, id) => {\n // We need to take a fresh deep copy of the original data as an object is a reference type.\n const newData = JSON.parse(JSON.stringify(webServiceData));\n newData.content_items.forEach((module) => {\n module.link += '§ion=' + id;\n });\n return newData.content_items;\n};\n\n/**\n * Build a modal on demand to save page load times\n *\n * @method modalBuilder\n * @param {Array} data our array of modules with section ID's applied in the URL field\n * @return {Object} Our modal that we are going to show the user\n */\nconst modalBuilder = data => buildModal(templateDataBuilder(data));\n\n/**\n * Given an array of modules we want to figure out where & how to place them into our template object\n *\n * @method templateDataBuilder\n * @param {Array} data our modules to manipulate into a Templatable object\n * @return {Object} Our built object ready to render out\n */\nconst templateDataBuilder = (data) => {\n // Filter the incoming data to find favourite & recommended modules.\n const favourites = data.filter(mod => mod.favourite === true);\n const recommended = data.filter(mod => mod.recommended === true);\n\n // Given the results of the above filters lets figure out what tab to set active.\n\n // We have some favourites.\n const favouritesFirst = !!favourites.length;\n // Check if we have no favourites but have some recommended.\n const recommendedFirst = !!(recommended.length && favouritesFirst === false);\n // We have nothing fallback to show all modules.\n const fallback = favouritesFirst === false && recommendedFirst === false;\n\n return {\n 'default': data,\n favourites: favourites,\n recommended: recommended,\n favouritesFirst: favouritesFirst,\n recommendedFirst: recommendedFirst,\n fallback: fallback,\n };\n};\n\n/**\n * Given an object we want to build a modal ready to show\n *\n * @method buildModal\n * @param {Object} data The template data which contains arrays of modules\n * @return {Object} The modal for the calling section with everything already set up\n */\nconst buildModal = data => {\n return ModalFactory.create({\n type: ModalFactory.types.DEFAULT,\n title: getString('addresourceoractivity'),\n body: Templates.render('core_course/activitychooser', data),\n large: true,\n templateContext: {\n classes: 'modchooser'\n }\n });\n};\n\n/**\n * A small helper function to handle the case where there are no more favourites\n * and we need to mess a bit with the available tabs in the chooser\n *\n * @method nullFavouriteDomManager\n * @param {HTMLElement} favouriteTabNav Dom node of the favourite tab nav\n * @param {HTMLElement} modalBody Our current modals' body\n */\nconst nullFavouriteDomManager = (favouriteTabNav, modalBody) => {\n favouriteTabNav.classList.add('d-none');\n // Need to set active to an available tab.\n if (favouriteTabNav.classList.contains('active')) {\n favouriteTabNav.classList.remove('active');\n const favouriteTab = modalBody.querySelector(selectors.regions.favouriteTab);\n favouriteTab.classList.remove('active');\n const recommendedTabNav = modalBody.querySelector(selectors.regions.recommendedTabNav);\n const defaultTabNav = modalBody.querySelector(selectors.regions.defaultTabNav);\n if (recommendedTabNav.classList.contains('d-none') === false) {\n recommendedTabNav.classList.add('active');\n const recommendedTab = modalBody.querySelector(selectors.regions.recommendedTab);\n recommendedTab.classList.add('active');\n } else {\n defaultTabNav.classList.add('active');\n const defaultTab = modalBody.querySelector(selectors.regions.defaultTab);\n defaultTab.classList.add('active');\n }\n\n }\n};\n\n/**\n * Export a curried function where the builtModules has been applied.\n * We have our array of modules so we can rerender the favourites area and have all of the items sorted.\n *\n * @method partiallyAppliedFavouriteManager\n * @param {Array} moduleData This is our raw WS data that we need to manipulate\n * @param {Number} sectionId We need this to add the sectionID to the URL's in the faves area after rerender\n * @return {Function} partially applied function so we can manipulate DOM nodes easily & update our internal array\n */\nconst partiallyAppliedFavouriteManager = (moduleData, sectionId) => {\n /**\n * Curried function that is being returned.\n *\n * @param {String} internal Internal name of the module to manage\n * @param {Boolean} favourite Is the caller adding a favourite or removing one?\n * @param {HTMLElement} modalBody What we need to update whilst we are here\n */\n return async(internal, favourite, modalBody) => {\n const favouriteArea = modalBody.querySelector(selectors.render.favourites);\n\n // eslint-disable-next-line max-len\n const favouriteButtons = modalBody.querySelectorAll(`[data-internal=\"${internal}\"] ${selectors.actions.optionActions.manageFavourite}`);\n const favouriteTabNav = modalBody.querySelector(selectors.regions.favouriteTabNav);\n const result = moduleData.content_items.find(({name}) => name === internal);\n const newFaves = {};\n if (result) {\n if (favourite) {\n result.favourite = true;\n\n newFaves.content_items = moduleData.content_items.filter(mod => mod.favourite === true);\n\n const builtFaves = sectionIdMapper(newFaves, sectionId);\n\n const {html, js} = await Templates.renderForPromise('core_course/local/activitychooser/favourites',\n {favourites: builtFaves});\n\n await Templates.replaceNodeContents(favouriteArea, html, js);\n\n Array.from(favouriteButtons).forEach((element) => {\n element.classList.remove('text-muted');\n element.classList.add('text-primary');\n element.dataset.favourited = 'true';\n element.setAttribute('aria-pressed', true);\n element.firstElementChild.classList.remove('fa-star-o');\n element.firstElementChild.classList.add('fa-star');\n });\n\n favouriteTabNav.classList.remove('d-none');\n } else {\n result.favourite = false;\n\n const nodeToRemove = favouriteArea.querySelector(`[data-internal=\"${internal}\"]`);\n\n nodeToRemove.parentNode.removeChild(nodeToRemove);\n\n Array.from(favouriteButtons).forEach((element) => {\n element.classList.add('text-muted');\n element.classList.remove('text-primary');\n element.dataset.favourited = 'false';\n element.setAttribute('aria-pressed', false);\n element.firstElementChild.classList.remove('fa-star');\n element.firstElementChild.classList.add('fa-star-o');\n });\n const newFaves = moduleData.content_items.filter(mod => mod.favourite === true);\n\n if (newFaves.length === 0) {\n nullFavouriteDomManager(favouriteTabNav, modalBody);\n }\n }\n }\n };\n};\n"],"file":"activitychooser.min.js"} \ No newline at end of file diff --git a/course/amd/build/local/activitychooser/dialogue.min.js b/course/amd/build/local/activitychooser/dialogue.min.js index 042132f99e2..65c611fffe2 100644 --- a/course/amd/build/local/activitychooser/dialogue.min.js +++ b/course/amd/build/local/activitychooser/dialogue.min.js @@ -1,2 +1,2 @@ -define ("core_course/local/activitychooser/dialogue",["exports","jquery","core/modal_events","core_course/local/activitychooser/selectors","core/templates","core/key_codes","core/loadingicon","core_course/local/activitychooser/repository","core/notification","core/utils"],function(a,b,c,d,e,f,g,h,i,j){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.displayChooser=void 0;b=l(b);c=k(c);d=l(d);e=k(e);h=k(h);i=l(i);function k(a){if(a&&a.__esModule){return a}else{var b={};if(null!=a){for(var c in a){if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};if(d.get||d.set){Object.defineProperty(b,c,d)}else{b[c]=a[c]}}}}b.default=a;return b}}function l(a){return a&&a.__esModule?a:{default:a}}function m(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 n(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){m(h,d,e,f,g,"next",a)}function g(a){m(h,d,e,f,g,"throw",a)}f(void 0)})}}function o(a,b){return r(a)||q(a,b)||p()}function p(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function q(a,b){var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function r(a){if(Array.isArray(a))return a}var s=function(a,b){var c=a.find(d.default.regions.help)[0];c.innerHTML="";var f=(0,g.addIconToContainer)(c),h=null,j=new Promise(function(a){h=a}),k=e.renderForPromise("core_course/chooser_help",b);Promise.all([k,f,j]).then(function(a){var b=o(a,1),d=b[0],f=d.html,g=d.js;return e.replaceNodeContents(c,f,g)}).then(function(){c.querySelector(d.default.regions.chooserSummary.description).focus();return c}).catch(i.default.exception);a.one("slid.bs.carousel",function(){h()});a.carousel("next")},t=function(){var a=n(regeneratorRuntime.mark(function a(b,c,d){var e,f,g,i;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:e=c.dataset.favourited;f=c.dataset.id;g=c.dataset.name;i=c.dataset.internal;if(!("true"===e)){a.next=10;break}a.next=7;return h.unfavouriteModule(g,f);case 7:d(i,!1,b);a.next=13;break;case 10:a.next=12;return h.favouriteModule(g,f);case 12:d(i,!0,b);case 13:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),u=function(a,c,f){var g=function(g){if(g.target.closest(d.default.actions.optionActions.showSummary)){var e=(0,b.default)(a.getBody()[0].querySelector(d.default.regions.carousel)),h=g.target.closest(d.default.regions.chooserOption.container),i=h.dataset.modname,j=c.get(i);s(e,j)}if(g.target.closest(d.default.actions.optionActions.manageFavourite)){var k=g.target.closest(d.default.actions.optionActions.manageFavourite);t(a.getBody()[0],k,f)}if(g.target.matches(d.default.actions.closeOption)){var l=(0,b.default)(a.getBody()[0].querySelector(d.default.regions.carousel));l.carousel("prev");l.on("slid.bs.carousel",function(){var b=a.getBody()[0].querySelector(d.default.regions.modules),c=b.querySelector(d.default.regions.getModuleSelector(g.target.dataset.modname));c.focus()})}if(g.target.closest(d.default.actions.clearSearch)){var m=a.getBody()[0].querySelector(d.default.actions.search);m.value="";m.focus();B(a.getBody()[0],c,m.value)}};a.getBodyPromise().then(function(a){return a[0]}).then(function(a){(0,b.default)(a.querySelector(d.default.regions.carousel)).carousel({interval:!1,pause:!0,keyboard:!1});return a}).then(function(a){a.addEventListener("click",g);return a}).then(function(a){var b=a.querySelector(d.default.actions.search);b.addEventListener("input",(0,j.debounce)(function(){B(a,c,b.value)},300));return a}).then(function(a){var b=a.querySelector(d.default.elements.activetab).getAttribute("href"),e=a.querySelector(d.default.regions.getSectionChooserOptions(b)),f=e.querySelector(d.default.regions.chooserOption.container);y(f,!0);v(a);w(a,c,e);return a}).catch()},v=function(a){var b=a.querySelector(d.default.regions.favouriteTabNav),c=a.querySelector(d.default.regions.recommendedTabNav),e=a.querySelector(d.default.regions.defaultTabNav);[b,c,e].forEach(function(a){return a.addEventListener("keyup",function(a){var b=a.target.parentElement.parentElement.firstElementChild.firstElementChild,c=a.target.parentElement.parentElement.lastElementChild.firstElementChild;if(a.keyCode===f.arrowRight){var d=a.target.parentElement.nextElementSibling;if(null===d){a.srcElement.tabIndex=-1;b.tabIndex=0;b.focus()}else if(d.firstElementChild.classList.contains("d-none")){a.srcElement.tabIndex=-1;c.tabIndex=0;c.focus()}else{a.srcElement.tabIndex=-1;d.firstElementChild.tabIndex=0;d.firstElementChild.focus()}}if(a.keyCode===f.arrowLeft){var e=a.target.parentElement.previousElementSibling;if(null===e){a.srcElement.tabIndex=-1;c.tabIndex=0;c.focus()}else if(e.firstElementChild.classList.contains("d-none")){a.srcElement.tabIndex=-1;b.tabIndex=0;b.focus()}else{a.srcElement.tabIndex=-1;e.firstElementChild.tabIndex=0;e.firstElementChild.focus()}}if(a.keyCode===f.home){a.srcElement.tabIndex=-1;b.tabIndex=0;b.focus()}if(a.keyCode===f.end){a.srcElement.tabIndex=-1;c.tabIndex=0;c.focus()}if(a.keyCode===f.space){a.preventDefault();a.target.click()}})})},w=function(a,c,g){var h=g.querySelectorAll(d.default.regions.chooserOption.container);Array.from(h).forEach(function(e){return e.addEventListener("keyup",function(h){if(h.keyCode===f.enter||h.keyCode===f.space){if(h.target.matches(d.default.actions.optionActions.showSummary)){h.preventDefault();var e=h.target.closest(d.default.regions.chooserOption.container),i=e.dataset.modname,j=c.get(i),k=(0,b.default)(a.querySelector(d.default.regions.carousel));k.carousel({interval:!1,pause:!0,keyboard:!1});s(k,j)}}if(h.keyCode===f.arrowRight){h.preventDefault();var l=h.target.closest(d.default.regions.chooserOption.container),m=l.nextElementSibling,n=g.firstElementChild,o=z(m,n);x(o,l)}if(h.keyCode===f.arrowLeft){h.preventDefault();var p=h.target.closest(d.default.regions.chooserOption.container),q=p.previousElementSibling,r=g.lastElementChild,t=z(q,r);x(t,p)}if(h.keyCode===f.home){h.preventDefault();var u=h.target.closest(d.default.regions.chooserOption.container),v=g.firstElementChild;x(v,u)}if(h.keyCode===f.end){h.preventDefault();var w=h.target.closest(d.default.regions.chooserOption.container),y=g.lastElementChild;x(y,w)}})})},x=function(a){var b=1.\n\n/**\n * A type of dialogue used as for choosing options.\n *\n * @module core_course/local/chooser/dialogue\n * @package core\n * @copyright 2019 Mihail Geshoski \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport * as ModalEvents from 'core/modal_events';\nimport selectors from 'core_course/local/activitychooser/selectors';\nimport * as Templates from 'core/templates';\nimport {end, arrowLeft, arrowRight, home, enter, space} from 'core/key_codes';\nimport {addIconToContainer} from 'core/loadingicon';\nimport * as Repository from 'core_course/local/activitychooser/repository';\nimport Notification from 'core/notification';\nimport {debounce} from 'core/utils';\n\n/**\n * Given an event from the main module 'page' navigate to it's help section via a carousel.\n *\n * @method showModuleHelp\n * @param {jQuery} carousel Our initialized carousel to manipulate\n * @param {Object} moduleData Data of the module to carousel to\n */\nconst showModuleHelp = (carousel, moduleData) => {\n const help = carousel.find(selectors.regions.help)[0];\n help.innerHTML = '';\n\n // Add a spinner.\n const spinnerPromise = addIconToContainer(help);\n\n // Used later...\n let transitionPromiseResolver = null;\n const transitionPromise = new Promise(resolve => {\n transitionPromiseResolver = resolve;\n });\n\n // Build up the html & js ready to place into the help section.\n const contentPromise = Templates.renderForPromise('core_course/chooser_help', moduleData);\n\n // Wait for the content to be ready, and for the transition to be complet.\n Promise.all([contentPromise, spinnerPromise, transitionPromise])\n .then(([{html, js}]) => Templates.replaceNodeContents(help, html, js))\n .then(() => {\n help.querySelector(selectors.regions.chooserSummary.description).focus();\n return help;\n })\n .catch(Notification.exception);\n\n // Move to the next slide, and resolve the transition promise when it's done.\n carousel.one('slid.bs.carousel', () => {\n transitionPromiseResolver();\n });\n // Trigger the transition between 'pages'.\n carousel.carousel('next');\n};\n\n/**\n * Given a user wants to change the favourite state of a module we either add or remove the status.\n * We also propergate this change across our map of modals.\n *\n * @method manageFavouriteState\n * @param {HTMLElement} modalBody The DOM node of the modal to manipulate\n * @param {HTMLElement} caller\n * @param {Function} partialFavourite Partially applied function we need to manage favourite status\n */\nconst manageFavouriteState = async(modalBody, caller, partialFavourite) => {\n const isFavourite = caller.dataset.favourited;\n const id = caller.dataset.id;\n const name = caller.dataset.name;\n const internal = caller.dataset.internal;\n // Switch on fave or not.\n if (isFavourite === 'true') {\n await Repository.unfavouriteModule(name, id);\n\n partialFavourite(internal, false, modalBody);\n } else {\n await Repository.favouriteModule(name, id);\n\n partialFavourite(internal, true, modalBody);\n }\n\n};\n\n/**\n * Register chooser related event listeners.\n *\n * @method registerListenerEvents\n * @param {Promise} modal Our modal that we are working with\n * @param {Map} mappedModules A map of all of the modules we are working with with K: mod_name V: {Object}\n * @param {Function} partialFavourite Partially applied function we need to manage favourite status\n */\nconst registerListenerEvents = (modal, mappedModules, partialFavourite) => {\n const bodyClickListener = e => {\n if (e.target.closest(selectors.actions.optionActions.showSummary)) {\n const carousel = $(modal.getBody()[0].querySelector(selectors.regions.carousel));\n\n const module = e.target.closest(selectors.regions.chooserOption.container);\n const moduleName = module.dataset.modname;\n const moduleData = mappedModules.get(moduleName);\n showModuleHelp(carousel, moduleData);\n }\n\n if (e.target.closest(selectors.actions.optionActions.manageFavourite)) {\n const caller = e.target.closest(selectors.actions.optionActions.manageFavourite);\n manageFavouriteState(modal.getBody()[0], caller, partialFavourite);\n }\n\n // From the help screen go back to the module overview.\n if (e.target.matches(selectors.actions.closeOption)) {\n const carousel = $(modal.getBody()[0].querySelector(selectors.regions.carousel));\n\n // Trigger the transition between 'pages'.\n carousel.carousel('prev');\n carousel.on('slid.bs.carousel', () => {\n const allModules = modal.getBody()[0].querySelector(selectors.regions.modules);\n const caller = allModules.querySelector(selectors.regions.getModuleSelector(e.target.dataset.modname));\n caller.focus();\n });\n }\n\n // The \"clear search\" button is triggered.\n if (e.target.closest(selectors.actions.clearSearch)) {\n // Clear the entered search query in the search bar and hide the search results container.\n const searchInput = modal.getBody()[0].querySelector(selectors.actions.search);\n searchInput.value = \"\";\n searchInput.focus();\n toggleSearchResultsView(modal.getBody()[0], mappedModules, searchInput.value);\n }\n };\n\n modal.getBodyPromise()\n\n // The return value of getBodyPromise is a jquery object containing the body NodeElement.\n .then(body => body[0])\n\n // Set up the carousel.\n .then(body => {\n $(body.querySelector(selectors.regions.carousel))\n .carousel({\n interval: false,\n pause: true,\n keyboard: false\n });\n\n return body;\n })\n\n // Add the listener for clicks on the body.\n .then(body => {\n body.addEventListener('click', bodyClickListener);\n return body;\n })\n\n // Add a listener for an input change in the activity chooser's search bar.\n .then(body => {\n const searchInput = body.querySelector(selectors.actions.search);\n // The search input is triggered.\n searchInput.addEventListener('input', debounce(() => {\n // Display the search results.\n toggleSearchResultsView(body, mappedModules, searchInput.value);\n }, 300));\n return body;\n })\n\n // Register event listeners related to the keyboard navigation controls.\n .then(body => {\n // Get the active chooser options section.\n const activeSectionId = body.querySelector(selectors.elements.activetab).getAttribute(\"href\");\n const sectionChooserOptions = body.querySelector(selectors.regions.getSectionChooserOptions(activeSectionId));\n const firstChooserOption = sectionChooserOptions.querySelector(selectors.regions.chooserOption.container);\n toggleFocusableChooserOption(firstChooserOption, true);\n initTabsKeyboardNavigation(body);\n initChooserOptionsKeyboardNavigation(body, mappedModules, sectionChooserOptions);\n return body;\n })\n .catch();\n\n};\n\n/**\n * Initialise the keyboard navigation controls for the tab list items.\n *\n * @method initTabsKeyboardNavigation\n * @param {HTMLElement} body Our modal that we are working with\n */\nconst initTabsKeyboardNavigation = (body) => {\n // Set up the tab handlers.\n const favTabNav = body.querySelector(selectors.regions.favouriteTabNav);\n const recommendedTabNav = body.querySelector(selectors.regions.recommendedTabNav);\n const defaultTabNav = body.querySelector(selectors.regions.defaultTabNav);\n const tabNavArray = [favTabNav, recommendedTabNav, defaultTabNav];\n tabNavArray.forEach((element) => {\n return element.addEventListener('keyup', (e) => {\n const firstLink = e.target.parentElement.parentElement.firstElementChild.firstElementChild;\n const lastLink = e.target.parentElement.parentElement.lastElementChild.firstElementChild;\n\n if (e.keyCode === arrowRight) {\n const nextLink = e.target.parentElement.nextElementSibling;\n if (nextLink === null) {\n e.srcElement.tabIndex = -1;\n firstLink.tabIndex = 0;\n firstLink.focus();\n } else if (nextLink.firstElementChild.classList.contains('d-none')) {\n e.srcElement.tabIndex = -1;\n lastLink.tabIndex = 0;\n lastLink.focus();\n } else {\n e.srcElement.tabIndex = -1;\n nextLink.firstElementChild.tabIndex = 0;\n nextLink.firstElementChild.focus();\n }\n }\n if (e.keyCode === arrowLeft) {\n const previousLink = e.target.parentElement.previousElementSibling;\n if (previousLink === null) {\n e.srcElement.tabIndex = -1;\n lastLink.tabIndex = 0;\n lastLink.focus();\n } else if (previousLink.firstElementChild.classList.contains('d-none')) {\n e.srcElement.tabIndex = -1;\n firstLink.tabIndex = 0;\n firstLink.focus();\n } else {\n e.srcElement.tabIndex = -1;\n previousLink.firstElementChild.tabIndex = 0;\n previousLink.firstElementChild.focus();\n }\n }\n if (e.keyCode === home) {\n e.srcElement.tabIndex = -1;\n firstLink.tabIndex = 0;\n firstLink.focus();\n }\n if (e.keyCode === end) {\n e.srcElement.tabIndex = -1;\n lastLink.tabIndex = 0;\n lastLink.focus();\n }\n if (e.keyCode === space) {\n e.preventDefault();\n e.target.click();\n }\n });\n });\n};\n\n/**\n * Initialise the keyboard navigation controls for the chooser options.\n *\n * @method initChooserOptionsKeyboardNavigation\n * @param {HTMLElement} body Our modal that we are working with\n * @param {Map} mappedModules A map of all of the modules we are working with with K: mod_name V: {Object}\n * @param {HTMLElement} chooserOptionsContainer The section that contains the chooser items\n */\nconst initChooserOptionsKeyboardNavigation = (body, mappedModules, chooserOptionsContainer) => {\n const chooserOptions = chooserOptionsContainer.querySelectorAll(selectors.regions.chooserOption.container);\n\n Array.from(chooserOptions).forEach((element) => {\n return element.addEventListener('keyup', (e) => {\n\n // Check for enter/ space triggers for showing the help.\n if (e.keyCode === enter || e.keyCode === space) {\n if (e.target.matches(selectors.actions.optionActions.showSummary)) {\n e.preventDefault();\n const module = e.target.closest(selectors.regions.chooserOption.container);\n const moduleName = module.dataset.modname;\n const moduleData = mappedModules.get(moduleName);\n const carousel = $(body.querySelector(selectors.regions.carousel));\n carousel.carousel({\n interval: false,\n pause: true,\n keyboard: false\n });\n showModuleHelp(carousel, moduleData);\n }\n }\n\n // Next.\n if (e.keyCode === arrowRight) {\n e.preventDefault();\n const currentOption = e.target.closest(selectors.regions.chooserOption.container);\n const nextOption = currentOption.nextElementSibling;\n const firstOption = chooserOptionsContainer.firstElementChild;\n const toFocusOption = clickErrorHandler(nextOption, firstOption);\n focusChooserOption(toFocusOption, currentOption);\n }\n\n // Previous.\n if (e.keyCode === arrowLeft) {\n e.preventDefault();\n const currentOption = e.target.closest(selectors.regions.chooserOption.container);\n const previousOption = currentOption.previousElementSibling;\n const lastOption = chooserOptionsContainer.lastElementChild;\n const toFocusOption = clickErrorHandler(previousOption, lastOption);\n focusChooserOption(toFocusOption, currentOption);\n }\n\n if (e.keyCode === home) {\n e.preventDefault();\n const currentOption = e.target.closest(selectors.regions.chooserOption.container);\n const firstOption = chooserOptionsContainer.firstElementChild;\n focusChooserOption(firstOption, currentOption);\n }\n\n if (e.keyCode === end) {\n e.preventDefault();\n const currentOption = e.target.closest(selectors.regions.chooserOption.container);\n const lastOption = chooserOptionsContainer.lastElementChild;\n focusChooserOption(lastOption, currentOption);\n }\n });\n });\n};\n\n/**\n * Focus on a chooser option element and remove the previous chooser element from the focus order\n *\n * @method focusChooserOption\n * @param {HTMLElement} currentChooserOption The current chooser option element that we want to focus\n * @param {HTMLElement|null} previousChooserOption The previous focused option element\n */\nconst focusChooserOption = (currentChooserOption, previousChooserOption = null) => {\n if (previousChooserOption !== null) {\n toggleFocusableChooserOption(previousChooserOption, false);\n }\n\n toggleFocusableChooserOption(currentChooserOption, true);\n currentChooserOption.focus();\n};\n\n/**\n * Add or remove a chooser option from the focus order.\n *\n * @method toggleFocusableChooserOption\n * @param {HTMLElement} chooserOption The chooser option element which should be added or removed from the focus order\n * @param {Boolean} isFocusable Whether the chooser element is focusable or not\n */\nconst toggleFocusableChooserOption = (chooserOption, isFocusable) => {\n const chooserOptionLink = chooserOption.querySelector(selectors.actions.addChooser);\n const chooserOptionHelp = chooserOption.querySelector(selectors.actions.optionActions.showSummary);\n const chooserOptionFavourite = chooserOption.querySelector(selectors.actions.optionActions.manageFavourite);\n\n if (isFocusable) {\n // Set tabindex to 0 to add current chooser option element to the focus order.\n chooserOption.tabIndex = 0;\n chooserOptionLink.tabIndex = 0;\n chooserOptionHelp.tabIndex = 0;\n chooserOptionFavourite.tabIndex = 0;\n } else {\n // Set tabindex to -1 to remove the previous chooser option element from the focus order.\n chooserOption.tabIndex = -1;\n chooserOptionLink.tabIndex = -1;\n chooserOptionHelp.tabIndex = -1;\n chooserOptionFavourite.tabIndex = -1;\n }\n};\n\n/**\n * Small error handling function to make sure the navigated to object exists\n *\n * @method clickErrorHandler\n * @param {HTMLElement} item What we want to check exists\n * @param {HTMLElement} fallback If we dont match anything fallback the focus\n * @return {HTMLElement}\n */\nconst clickErrorHandler = (item, fallback) => {\n if (item !== null) {\n return item;\n } else {\n return fallback;\n }\n};\n\n/**\n * Render the search results in a defined container\n *\n * @method renderSearchResults\n * @param {HTMLElement} searchResultsContainer The container where the data should be rendered\n * @param {Object} searchResultsData Data containing the module items that satisfy the search criteria\n */\nconst renderSearchResults = async(searchResultsContainer, searchResultsData) => {\n const templateData = {\n 'searchresultsnumber': searchResultsData.length,\n 'searchresults': searchResultsData\n };\n // Build up the html & js ready to place into the help section.\n const {html, js} = await Templates.renderForPromise('core_course/chooser_search_results', templateData);\n await Templates.replaceNodeContents(searchResultsContainer, html, js);\n};\n\n/**\n * Toggle (display/hide) the search results depending on the value of the search query\n *\n * @method toggleSearchResultsView\n * @param {HTMLElement} modalBody The body of the created modal for the section\n * @param {Map} mappedModules A map of all of the modules we are working with with K: mod_name V: {Object}\n * @param {String} searchQuery The search query\n */\nconst toggleSearchResultsView = async(modalBody, mappedModules, searchQuery) => {\n const searchResultsContainer = modalBody.querySelector(selectors.regions.searchResults);\n const chooserContainer = modalBody.querySelector(selectors.regions.chooser);\n const clearSearchButton = modalBody.querySelector(selectors.elements.clearsearch);\n const searchIcon = modalBody.querySelector(selectors.elements.searchicon);\n\n if (searchQuery.length > 0) { // Search query is present.\n const searchResultsData = searchModules(mappedModules, searchQuery);\n await renderSearchResults(searchResultsContainer, searchResultsData);\n const searchResultItemsContainer = searchResultsContainer.querySelector(selectors.regions.searchResultItems);\n const firstSearchResultItem = searchResultItemsContainer.querySelector(selectors.regions.chooserOption.container);\n if (firstSearchResultItem) {\n // Set the first result item to be focusable.\n toggleFocusableChooserOption(firstSearchResultItem, true);\n // Register keyboard events on the created search result items.\n initChooserOptionsKeyboardNavigation(modalBody, mappedModules, searchResultItemsContainer);\n }\n // Display the \"clear\" search button in the activity chooser search bar.\n searchIcon.classList.add('d-none');\n clearSearchButton.classList.remove('d-none');\n // Hide the default chooser options container.\n chooserContainer.setAttribute('hidden', 'hidden');\n // Display the search results container.\n searchResultsContainer.removeAttribute('hidden');\n } else { // Search query is not present.\n // Hide the \"clear\" search button in the activity chooser search bar.\n clearSearchButton.classList.add('d-none');\n searchIcon.classList.remove('d-none');\n // Hide the search results container.\n searchResultsContainer.setAttribute('hidden', 'hidden');\n // Display the default chooser options container.\n chooserContainer.removeAttribute('hidden');\n }\n};\n\n/**\n * Return the list of modules which have a name or description that matches the given search term.\n *\n * @method searchModules\n * @param {Array} modules List of available modules\n * @param {String} searchTerm The search term to match\n * @return {Array}\n */\nconst searchModules = (modules, searchTerm) => {\n if (searchTerm === '') {\n return modules;\n }\n searchTerm = searchTerm.toLowerCase();\n const searchResults = [];\n modules.forEach((activity) => {\n const activityName = activity.title.toLowerCase();\n const activityDesc = activity.help.toLowerCase();\n if (activityName.includes(searchTerm) || activityDesc.includes(searchTerm)) {\n searchResults.push(activity);\n }\n });\n\n return searchResults;\n};\n\n/**\n * Disable the focus of all chooser options in a specific container (section).\n *\n * @method disableFocusAllChooserOptions\n * @param {HTMLElement} sectionChooserOptions The section that contains the chooser items\n */\nconst disableFocusAllChooserOptions = (sectionChooserOptions) => {\n const allChooserOptions = sectionChooserOptions.querySelectorAll(selectors.regions.chooserOption.container);\n allChooserOptions.forEach((chooserOption) => {\n toggleFocusableChooserOption(chooserOption, false);\n });\n};\n\n/**\n * Display the module chooser.\n *\n * @method displayChooser\n * @param {HTMLElement} origin The calling button\n * @param {Object} modal Our created modal for the section\n * @param {Array} sectionModules An array of all of the built module information\n * @param {Function} partialFavourite Partially applied function we need to manage favourite status\n */\nexport const displayChooser = (origin, modal, sectionModules, partialFavourite) => {\n\n // Make a map so we can quickly fetch a specific module's object for either rendering or searching.\n const mappedModules = new Map();\n sectionModules.forEach((module) => {\n mappedModules.set(module.componentname + '_' + module.link, module);\n });\n\n // Register event listeners.\n registerListenerEvents(modal, mappedModules, partialFavourite);\n\n // We want to focus on the action select when the dialog is closed.\n modal.getRoot().on(ModalEvents.hidden, () => {\n modal.destroy();\n });\n\n // We want to focus on the first chooser option element as soon as the modal is opened.\n modal.getRoot().on(ModalEvents.shown, () => {\n modal.getModal()[0].tabIndex = -1;\n\n modal.getBodyPromise()\n .then(body => {\n $(selectors.elements.tab).on('shown.bs.tab', (e) => {\n const activeSectionId = e.target.getAttribute(\"href\");\n const activeSectionChooserOptions = body[0]\n .querySelector(selectors.regions.getSectionChooserOptions(activeSectionId));\n const firstChooserOption = activeSectionChooserOptions\n .querySelector(selectors.regions.chooserOption.container);\n const prevActiveSectionId = e.relatedTarget.getAttribute(\"href\");\n const prevActiveSectionChooserOptions = body[0]\n .querySelector(selectors.regions.getSectionChooserOptions(prevActiveSectionId));\n\n // Disable the focus of every chooser option in the previous active section.\n disableFocusAllChooserOptions(prevActiveSectionChooserOptions);\n // Enable the focus of the first chooser option in the current active section.\n toggleFocusableChooserOption(firstChooserOption, true);\n initChooserOptionsKeyboardNavigation(body[0], mappedModules, activeSectionChooserOptions);\n });\n return;\n })\n .catch(Notification.exception);\n });\n\n modal.show();\n};\n"],"file":"dialogue.min.js"} \ No newline at end of file +{"version":3,"sources":["../../../src/local/activitychooser/dialogue.js"],"names":["showModuleHelp","carousel","moduleData","help","find","selectors","regions","innerHTML","spinnerPromise","transitionPromiseResolver","transitionPromise","Promise","resolve","contentPromise","Templates","renderForPromise","all","then","html","js","replaceNodeContents","querySelector","chooserSummary","header","focus","catch","Notification","exception","one","manageFavouriteState","modalBody","caller","partialFavourite","isFavourite","dataset","favourited","id","name","internal","Repository","unfavouriteModule","favouriteModule","registerListenerEvents","modal","mappedModules","bodyClickListener","e","target","closest","actions","optionActions","showSummary","getBody","module","chooserOption","container","moduleName","modname","get","manageFavourite","matches","closeOption","on","allModules","modules","getModuleSelector","clearSearch","searchInput","search","value","toggleSearchResultsView","getBodyPromise","body","interval","pause","keyboard","addEventListener","activeSectionId","elements","activetab","getAttribute","sectionChooserOptions","getSectionChooserOptions","firstChooserOption","toggleFocusableChooserOption","initTabsKeyboardNavigation","initChooserOptionsKeyboardNavigation","favTabNav","favouriteTabNav","recommendedTabNav","defaultTabNav","forEach","element","firstLink","parentElement","firstElementChild","lastLink","lastElementChild","keyCode","arrowRight","nextLink","nextElementSibling","srcElement","tabIndex","classList","contains","arrowLeft","previousLink","previousElementSibling","home","end","space","preventDefault","click","chooserOptionsContainer","chooserOptions","querySelectorAll","Array","from","enter","currentOption","nextOption","firstOption","toFocusOption","clickErrorHandler","focusChooserOption","previousOption","lastOption","currentChooserOption","previousChooserOption","isFocusable","chooserOptionLink","addChooser","chooserOptionHelp","chooserOptionFavourite","item","fallback","renderSearchResults","searchResultsContainer","searchResultsData","templateData","length","searchQuery","searchResults","chooserContainer","chooser","clearSearchButton","clearsearch","searchIcon","searchicon","searchModules","searchResultItemsContainer","searchResultItems","firstSearchResultItem","add","remove","setAttribute","removeAttribute","searchTerm","toLowerCase","activity","activityName","title","activityDesc","includes","push","disableFocusAllChooserOptions","allChooserOptions","displayChooser","origin","sectionModules","Map","set","componentname","link","getRoot","ModalEvents","hidden","destroy","shown","getModal","tab","activeSectionChooserOptions","prevActiveSectionId","relatedTarget","prevActiveSectionChooserOptions","show"],"mappings":"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","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 * A type of dialogue used as for choosing options.\n *\n * @module core_course/local/chooser/dialogue\n * @package core\n * @copyright 2019 Mihail Geshoski \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport * as ModalEvents from 'core/modal_events';\nimport selectors from 'core_course/local/activitychooser/selectors';\nimport * as Templates from 'core/templates';\nimport {end, arrowLeft, arrowRight, home, enter, space} from 'core/key_codes';\nimport {addIconToContainer} from 'core/loadingicon';\nimport * as Repository from 'core_course/local/activitychooser/repository';\nimport Notification from 'core/notification';\nimport {debounce} from 'core/utils';\n\n/**\n * Given an event from the main module 'page' navigate to it's help section via a carousel.\n *\n * @method showModuleHelp\n * @param {jQuery} carousel Our initialized carousel to manipulate\n * @param {Object} moduleData Data of the module to carousel to\n */\nconst showModuleHelp = (carousel, moduleData) => {\n const help = carousel.find(selectors.regions.help)[0];\n help.innerHTML = '';\n\n // Add a spinner.\n const spinnerPromise = addIconToContainer(help);\n\n // Used later...\n let transitionPromiseResolver = null;\n const transitionPromise = new Promise(resolve => {\n transitionPromiseResolver = resolve;\n });\n\n // Build up the html & js ready to place into the help section.\n const contentPromise = Templates.renderForPromise('core_course/local/activitychooser/help', moduleData);\n\n // Wait for the content to be ready, and for the transition to be complet.\n Promise.all([contentPromise, spinnerPromise, transitionPromise])\n .then(([{html, js}]) => Templates.replaceNodeContents(help, html, js))\n .then(() => {\n help.querySelector(selectors.regions.chooserSummary.header).focus();\n return help;\n })\n .catch(Notification.exception);\n\n // Move to the next slide, and resolve the transition promise when it's done.\n carousel.one('slid.bs.carousel', () => {\n transitionPromiseResolver();\n });\n // Trigger the transition between 'pages'.\n carousel.carousel('next');\n};\n\n/**\n * Given a user wants to change the favourite state of a module we either add or remove the status.\n * We also propergate this change across our map of modals.\n *\n * @method manageFavouriteState\n * @param {HTMLElement} modalBody The DOM node of the modal to manipulate\n * @param {HTMLElement} caller\n * @param {Function} partialFavourite Partially applied function we need to manage favourite status\n */\nconst manageFavouriteState = async(modalBody, caller, partialFavourite) => {\n const isFavourite = caller.dataset.favourited;\n const id = caller.dataset.id;\n const name = caller.dataset.name;\n const internal = caller.dataset.internal;\n // Switch on fave or not.\n if (isFavourite === 'true') {\n await Repository.unfavouriteModule(name, id);\n\n partialFavourite(internal, false, modalBody);\n } else {\n await Repository.favouriteModule(name, id);\n\n partialFavourite(internal, true, modalBody);\n }\n\n};\n\n/**\n * Register chooser related event listeners.\n *\n * @method registerListenerEvents\n * @param {Promise} modal Our modal that we are working with\n * @param {Map} mappedModules A map of all of the modules we are working with with K: mod_name V: {Object}\n * @param {Function} partialFavourite Partially applied function we need to manage favourite status\n */\nconst registerListenerEvents = (modal, mappedModules, partialFavourite) => {\n const bodyClickListener = e => {\n if (e.target.closest(selectors.actions.optionActions.showSummary)) {\n const carousel = $(modal.getBody()[0].querySelector(selectors.regions.carousel));\n\n const module = e.target.closest(selectors.regions.chooserOption.container);\n const moduleName = module.dataset.modname;\n const moduleData = mappedModules.get(moduleName);\n showModuleHelp(carousel, moduleData);\n }\n\n if (e.target.closest(selectors.actions.optionActions.manageFavourite)) {\n const caller = e.target.closest(selectors.actions.optionActions.manageFavourite);\n manageFavouriteState(modal.getBody()[0], caller, partialFavourite);\n }\n\n // From the help screen go back to the module overview.\n if (e.target.matches(selectors.actions.closeOption)) {\n const carousel = $(modal.getBody()[0].querySelector(selectors.regions.carousel));\n\n // Trigger the transition between 'pages'.\n carousel.carousel('prev');\n carousel.on('slid.bs.carousel', () => {\n const allModules = modal.getBody()[0].querySelector(selectors.regions.modules);\n const caller = allModules.querySelector(selectors.regions.getModuleSelector(e.target.dataset.modname));\n caller.focus();\n });\n }\n\n // The \"clear search\" button is triggered.\n if (e.target.closest(selectors.actions.clearSearch)) {\n // Clear the entered search query in the search bar and hide the search results container.\n const searchInput = modal.getBody()[0].querySelector(selectors.actions.search);\n searchInput.value = \"\";\n searchInput.focus();\n toggleSearchResultsView(modal.getBody()[0], mappedModules, searchInput.value);\n }\n };\n\n modal.getBodyPromise()\n\n // The return value of getBodyPromise is a jquery object containing the body NodeElement.\n .then(body => body[0])\n\n // Set up the carousel.\n .then(body => {\n $(body.querySelector(selectors.regions.carousel))\n .carousel({\n interval: false,\n pause: true,\n keyboard: false\n });\n\n return body;\n })\n\n // Add the listener for clicks on the body.\n .then(body => {\n body.addEventListener('click', bodyClickListener);\n return body;\n })\n\n // Add a listener for an input change in the activity chooser's search bar.\n .then(body => {\n const searchInput = body.querySelector(selectors.actions.search);\n // The search input is triggered.\n searchInput.addEventListener('input', debounce(() => {\n // Display the search results.\n toggleSearchResultsView(body, mappedModules, searchInput.value);\n }, 300));\n return body;\n })\n\n // Register event listeners related to the keyboard navigation controls.\n .then(body => {\n // Get the active chooser options section.\n const activeSectionId = body.querySelector(selectors.elements.activetab).getAttribute(\"href\");\n const sectionChooserOptions = body.querySelector(selectors.regions.getSectionChooserOptions(activeSectionId));\n const firstChooserOption = sectionChooserOptions.querySelector(selectors.regions.chooserOption.container);\n toggleFocusableChooserOption(firstChooserOption, true);\n initTabsKeyboardNavigation(body);\n initChooserOptionsKeyboardNavigation(body, mappedModules, sectionChooserOptions);\n return body;\n })\n .catch();\n\n};\n\n/**\n * Initialise the keyboard navigation controls for the tab list items.\n *\n * @method initTabsKeyboardNavigation\n * @param {HTMLElement} body Our modal that we are working with\n */\nconst initTabsKeyboardNavigation = (body) => {\n // Set up the tab handlers.\n const favTabNav = body.querySelector(selectors.regions.favouriteTabNav);\n const recommendedTabNav = body.querySelector(selectors.regions.recommendedTabNav);\n const defaultTabNav = body.querySelector(selectors.regions.defaultTabNav);\n const tabNavArray = [favTabNav, recommendedTabNav, defaultTabNav];\n tabNavArray.forEach((element) => {\n return element.addEventListener('keyup', (e) => {\n const firstLink = e.target.parentElement.parentElement.firstElementChild.firstElementChild;\n const lastLink = e.target.parentElement.parentElement.lastElementChild.firstElementChild;\n\n if (e.keyCode === arrowRight) {\n const nextLink = e.target.parentElement.nextElementSibling;\n if (nextLink === null) {\n e.srcElement.tabIndex = -1;\n firstLink.tabIndex = 0;\n firstLink.focus();\n } else if (nextLink.firstElementChild.classList.contains('d-none')) {\n e.srcElement.tabIndex = -1;\n lastLink.tabIndex = 0;\n lastLink.focus();\n } else {\n e.srcElement.tabIndex = -1;\n nextLink.firstElementChild.tabIndex = 0;\n nextLink.firstElementChild.focus();\n }\n }\n if (e.keyCode === arrowLeft) {\n const previousLink = e.target.parentElement.previousElementSibling;\n if (previousLink === null) {\n e.srcElement.tabIndex = -1;\n lastLink.tabIndex = 0;\n lastLink.focus();\n } else if (previousLink.firstElementChild.classList.contains('d-none')) {\n e.srcElement.tabIndex = -1;\n firstLink.tabIndex = 0;\n firstLink.focus();\n } else {\n e.srcElement.tabIndex = -1;\n previousLink.firstElementChild.tabIndex = 0;\n previousLink.firstElementChild.focus();\n }\n }\n if (e.keyCode === home) {\n e.srcElement.tabIndex = -1;\n firstLink.tabIndex = 0;\n firstLink.focus();\n }\n if (e.keyCode === end) {\n e.srcElement.tabIndex = -1;\n lastLink.tabIndex = 0;\n lastLink.focus();\n }\n if (e.keyCode === space) {\n e.preventDefault();\n e.target.click();\n }\n });\n });\n};\n\n/**\n * Initialise the keyboard navigation controls for the chooser options.\n *\n * @method initChooserOptionsKeyboardNavigation\n * @param {HTMLElement} body Our modal that we are working with\n * @param {Map} mappedModules A map of all of the modules we are working with with K: mod_name V: {Object}\n * @param {HTMLElement} chooserOptionsContainer The section that contains the chooser items\n */\nconst initChooserOptionsKeyboardNavigation = (body, mappedModules, chooserOptionsContainer) => {\n const chooserOptions = chooserOptionsContainer.querySelectorAll(selectors.regions.chooserOption.container);\n\n Array.from(chooserOptions).forEach((element) => {\n return element.addEventListener('keyup', (e) => {\n\n // Check for enter/ space triggers for showing the help.\n if (e.keyCode === enter || e.keyCode === space) {\n if (e.target.matches(selectors.actions.optionActions.showSummary)) {\n e.preventDefault();\n const module = e.target.closest(selectors.regions.chooserOption.container);\n const moduleName = module.dataset.modname;\n const moduleData = mappedModules.get(moduleName);\n const carousel = $(body.querySelector(selectors.regions.carousel));\n carousel.carousel({\n interval: false,\n pause: true,\n keyboard: false\n });\n showModuleHelp(carousel, moduleData);\n }\n }\n\n // Next.\n if (e.keyCode === arrowRight) {\n e.preventDefault();\n const currentOption = e.target.closest(selectors.regions.chooserOption.container);\n const nextOption = currentOption.nextElementSibling;\n const firstOption = chooserOptionsContainer.firstElementChild;\n const toFocusOption = clickErrorHandler(nextOption, firstOption);\n focusChooserOption(toFocusOption, currentOption);\n }\n\n // Previous.\n if (e.keyCode === arrowLeft) {\n e.preventDefault();\n const currentOption = e.target.closest(selectors.regions.chooserOption.container);\n const previousOption = currentOption.previousElementSibling;\n const lastOption = chooserOptionsContainer.lastElementChild;\n const toFocusOption = clickErrorHandler(previousOption, lastOption);\n focusChooserOption(toFocusOption, currentOption);\n }\n\n if (e.keyCode === home) {\n e.preventDefault();\n const currentOption = e.target.closest(selectors.regions.chooserOption.container);\n const firstOption = chooserOptionsContainer.firstElementChild;\n focusChooserOption(firstOption, currentOption);\n }\n\n if (e.keyCode === end) {\n e.preventDefault();\n const currentOption = e.target.closest(selectors.regions.chooserOption.container);\n const lastOption = chooserOptionsContainer.lastElementChild;\n focusChooserOption(lastOption, currentOption);\n }\n });\n });\n};\n\n/**\n * Focus on a chooser option element and remove the previous chooser element from the focus order\n *\n * @method focusChooserOption\n * @param {HTMLElement} currentChooserOption The current chooser option element that we want to focus\n * @param {HTMLElement|null} previousChooserOption The previous focused option element\n */\nconst focusChooserOption = (currentChooserOption, previousChooserOption = null) => {\n if (previousChooserOption !== null) {\n toggleFocusableChooserOption(previousChooserOption, false);\n }\n\n toggleFocusableChooserOption(currentChooserOption, true);\n currentChooserOption.focus();\n};\n\n/**\n * Add or remove a chooser option from the focus order.\n *\n * @method toggleFocusableChooserOption\n * @param {HTMLElement} chooserOption The chooser option element which should be added or removed from the focus order\n * @param {Boolean} isFocusable Whether the chooser element is focusable or not\n */\nconst toggleFocusableChooserOption = (chooserOption, isFocusable) => {\n const chooserOptionLink = chooserOption.querySelector(selectors.actions.addChooser);\n const chooserOptionHelp = chooserOption.querySelector(selectors.actions.optionActions.showSummary);\n const chooserOptionFavourite = chooserOption.querySelector(selectors.actions.optionActions.manageFavourite);\n\n if (isFocusable) {\n // Set tabindex to 0 to add current chooser option element to the focus order.\n chooserOption.tabIndex = 0;\n chooserOptionLink.tabIndex = 0;\n chooserOptionHelp.tabIndex = 0;\n chooserOptionFavourite.tabIndex = 0;\n } else {\n // Set tabindex to -1 to remove the previous chooser option element from the focus order.\n chooserOption.tabIndex = -1;\n chooserOptionLink.tabIndex = -1;\n chooserOptionHelp.tabIndex = -1;\n chooserOptionFavourite.tabIndex = -1;\n }\n};\n\n/**\n * Small error handling function to make sure the navigated to object exists\n *\n * @method clickErrorHandler\n * @param {HTMLElement} item What we want to check exists\n * @param {HTMLElement} fallback If we dont match anything fallback the focus\n * @return {HTMLElement}\n */\nconst clickErrorHandler = (item, fallback) => {\n if (item !== null) {\n return item;\n } else {\n return fallback;\n }\n};\n\n/**\n * Render the search results in a defined container\n *\n * @method renderSearchResults\n * @param {HTMLElement} searchResultsContainer The container where the data should be rendered\n * @param {Object} searchResultsData Data containing the module items that satisfy the search criteria\n */\nconst renderSearchResults = async(searchResultsContainer, searchResultsData) => {\n const templateData = {\n 'searchresultsnumber': searchResultsData.length,\n 'searchresults': searchResultsData\n };\n // Build up the html & js ready to place into the help section.\n const {html, js} = await Templates.renderForPromise('core_course/local/activitychooser/search_results', templateData);\n await Templates.replaceNodeContents(searchResultsContainer, html, js);\n};\n\n/**\n * Toggle (display/hide) the search results depending on the value of the search query\n *\n * @method toggleSearchResultsView\n * @param {HTMLElement} modalBody The body of the created modal for the section\n * @param {Map} mappedModules A map of all of the modules we are working with with K: mod_name V: {Object}\n * @param {String} searchQuery The search query\n */\nconst toggleSearchResultsView = async(modalBody, mappedModules, searchQuery) => {\n const searchResultsContainer = modalBody.querySelector(selectors.regions.searchResults);\n const chooserContainer = modalBody.querySelector(selectors.regions.chooser);\n const clearSearchButton = modalBody.querySelector(selectors.elements.clearsearch);\n const searchIcon = modalBody.querySelector(selectors.elements.searchicon);\n\n if (searchQuery.length > 0) { // Search query is present.\n const searchResultsData = searchModules(mappedModules, searchQuery);\n await renderSearchResults(searchResultsContainer, searchResultsData);\n const searchResultItemsContainer = searchResultsContainer.querySelector(selectors.regions.searchResultItems);\n const firstSearchResultItem = searchResultItemsContainer.querySelector(selectors.regions.chooserOption.container);\n if (firstSearchResultItem) {\n // Set the first result item to be focusable.\n toggleFocusableChooserOption(firstSearchResultItem, true);\n // Register keyboard events on the created search result items.\n initChooserOptionsKeyboardNavigation(modalBody, mappedModules, searchResultItemsContainer);\n }\n // Display the \"clear\" search button in the activity chooser search bar.\n searchIcon.classList.add('d-none');\n clearSearchButton.classList.remove('d-none');\n // Hide the default chooser options container.\n chooserContainer.setAttribute('hidden', 'hidden');\n // Display the search results container.\n searchResultsContainer.removeAttribute('hidden');\n } else { // Search query is not present.\n // Hide the \"clear\" search button in the activity chooser search bar.\n clearSearchButton.classList.add('d-none');\n searchIcon.classList.remove('d-none');\n // Hide the search results container.\n searchResultsContainer.setAttribute('hidden', 'hidden');\n // Display the default chooser options container.\n chooserContainer.removeAttribute('hidden');\n }\n};\n\n/**\n * Return the list of modules which have a name or description that matches the given search term.\n *\n * @method searchModules\n * @param {Array} modules List of available modules\n * @param {String} searchTerm The search term to match\n * @return {Array}\n */\nconst searchModules = (modules, searchTerm) => {\n if (searchTerm === '') {\n return modules;\n }\n searchTerm = searchTerm.toLowerCase();\n const searchResults = [];\n modules.forEach((activity) => {\n const activityName = activity.title.toLowerCase();\n const activityDesc = activity.help.toLowerCase();\n if (activityName.includes(searchTerm) || activityDesc.includes(searchTerm)) {\n searchResults.push(activity);\n }\n });\n\n return searchResults;\n};\n\n/**\n * Disable the focus of all chooser options in a specific container (section).\n *\n * @method disableFocusAllChooserOptions\n * @param {HTMLElement} sectionChooserOptions The section that contains the chooser items\n */\nconst disableFocusAllChooserOptions = (sectionChooserOptions) => {\n const allChooserOptions = sectionChooserOptions.querySelectorAll(selectors.regions.chooserOption.container);\n allChooserOptions.forEach((chooserOption) => {\n toggleFocusableChooserOption(chooserOption, false);\n });\n};\n\n/**\n * Display the module chooser.\n *\n * @method displayChooser\n * @param {HTMLElement} origin The calling button\n * @param {Object} modal Our created modal for the section\n * @param {Array} sectionModules An array of all of the built module information\n * @param {Function} partialFavourite Partially applied function we need to manage favourite status\n */\nexport const displayChooser = (origin, modal, sectionModules, partialFavourite) => {\n\n // Make a map so we can quickly fetch a specific module's object for either rendering or searching.\n const mappedModules = new Map();\n sectionModules.forEach((module) => {\n mappedModules.set(module.componentname + '_' + module.link, module);\n });\n\n // Register event listeners.\n registerListenerEvents(modal, mappedModules, partialFavourite);\n\n // We want to focus on the action select when the dialog is closed.\n modal.getRoot().on(ModalEvents.hidden, () => {\n modal.destroy();\n });\n\n // We want to focus on the first chooser option element as soon as the modal is opened.\n modal.getRoot().on(ModalEvents.shown, () => {\n modal.getModal()[0].tabIndex = -1;\n\n modal.getBodyPromise()\n .then(body => {\n $(selectors.elements.tab).on('shown.bs.tab', (e) => {\n const activeSectionId = e.target.getAttribute(\"href\");\n const activeSectionChooserOptions = body[0]\n .querySelector(selectors.regions.getSectionChooserOptions(activeSectionId));\n const firstChooserOption = activeSectionChooserOptions\n .querySelector(selectors.regions.chooserOption.container);\n const prevActiveSectionId = e.relatedTarget.getAttribute(\"href\");\n const prevActiveSectionChooserOptions = body[0]\n .querySelector(selectors.regions.getSectionChooserOptions(prevActiveSectionId));\n\n // Disable the focus of every chooser option in the previous active section.\n disableFocusAllChooserOptions(prevActiveSectionChooserOptions);\n // Enable the focus of the first chooser option in the current active section.\n toggleFocusableChooserOption(firstChooserOption, true);\n initChooserOptionsKeyboardNavigation(body[0], mappedModules, activeSectionChooserOptions);\n });\n return;\n })\n .catch(Notification.exception);\n });\n\n modal.show();\n};\n"],"file":"dialogue.min.js"} \ No newline at end of file diff --git a/course/amd/build/local/activitychooser/selectors.min.js b/course/amd/build/local/activitychooser/selectors.min.js index 0aee2dcf3e4..37df2739d51 100644 --- a/course/amd/build/local/activitychooser/selectors.min.js +++ b/course/amd/build/local/activitychooser/selectors.min.js @@ -1,2 +1,2 @@ -define ("core_course/local/activitychooser/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;var b=function(a,b){return"[data-".concat(a,"=\"").concat(b,"\"]")},c={regions:{chooser:b("region","chooser-container"),getSectionChooserOptions:function getSectionChooserOptions(a){return"".concat(a," ").concat(b("region","chooser-options-container"))},chooserOption:{container:b("region","chooser-option-container"),actions:b("region","chooser-option-actions-container"),info:b("region","chooser-option-info-container")},chooserSummary:{container:b("region","chooser-option-summary-container"),content:b("region","chooser-option-summary-content-container"),description:b("region","summary-description"),actions:b("region","chooser-option-summary-actions-container")},carousel:b("region","carousel"),help:b("region","help"),modules:b("region","modules"),favouriteTabNav:b("region","favourite-tab-nav"),recommendedTabNav:b("region","recommended-tab-nav"),defaultTabNav:b("region","default-tab-nav"),favouriteTab:b("region","favourites"),recommendedTab:b("region","recommended"),defaultTab:b("region","default"),getModuleSelector:function getModuleSelector(a){return"[role=\"menuitem\"][data-modname=\"".concat(a,"\"]")},searchResults:b("region","search-results-container"),searchResultItems:b("region","search-result-items-container")},actions:{optionActions:{showSummary:b("action","show-option-summary"),manageFavourite:b("action","manage-module-favourite")},addChooser:b("action","add-chooser-option"),closeOption:b("action","close-chooser-option-summary"),hide:b("action","hide"),search:b("action","search"),clearSearch:b("action","clearsearch")},render:{favourites:b("render","favourites-area")},elements:{section:".section",sectionmodchooser:"button.section-modchooser-link",sitemenu:".block_site_main_menu",sitetopic:"div.sitetopic",tab:"a[data-toggle=\"tab\"]",activetab:"a[data-toggle=\"tab\"][aria-selected=\"true\"]",searchicon:".searchbar-append .search-icon",clearsearch:".searchbar-append .clear"}};a.default=c;return a.default}); +define ("core_course/local/activitychooser/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;var b=function(a,b){return"[data-".concat(a,"=\"").concat(b,"\"]")},c={regions:{chooser:b("region","chooser-container"),getSectionChooserOptions:function getSectionChooserOptions(a){return"".concat(a," ").concat(b("region","chooser-options-container"))},chooserOption:{container:b("region","chooser-option-container"),actions:b("region","chooser-option-actions-container"),info:b("region","chooser-option-info-container")},chooserSummary:{container:b("region","chooser-option-summary-container"),content:b("region","chooser-option-summary-content-container"),header:b("region","summary-header"),actions:b("region","chooser-option-summary-actions-container")},carousel:b("region","carousel"),help:b("region","help"),modules:b("region","modules"),favouriteTabNav:b("region","favourite-tab-nav"),recommendedTabNav:b("region","recommended-tab-nav"),defaultTabNav:b("region","default-tab-nav"),favouriteTab:b("region","favourites"),recommendedTab:b("region","recommended"),defaultTab:b("region","default"),getModuleSelector:function getModuleSelector(a){return"[role=\"menuitem\"][data-modname=\"".concat(a,"\"]")},searchResults:b("region","search-results-container"),searchResultItems:b("region","search-result-items-container")},actions:{optionActions:{showSummary:b("action","show-option-summary"),manageFavourite:b("action","manage-module-favourite")},addChooser:b("action","add-chooser-option"),closeOption:b("action","close-chooser-option-summary"),hide:b("action","hide"),search:b("action","search"),clearSearch:b("action","clearsearch")},render:{favourites:b("render","favourites-area")},elements:{section:".section",sectionmodchooser:"button.section-modchooser-link",sitemenu:".block_site_main_menu",sitetopic:"div.sitetopic",tab:"a[data-toggle=\"tab\"]",activetab:"a[data-toggle=\"tab\"][aria-selected=\"true\"]",searchicon:".searchbar-append .search-icon",clearsearch:".searchbar-append .clear"}};a.default=c;return a.default}); //# sourceMappingURL=selectors.min.js.map diff --git a/course/amd/build/local/activitychooser/selectors.min.js.map b/course/amd/build/local/activitychooser/selectors.min.js.map index da656df5c5a..75707c60def 100644 --- a/course/amd/build/local/activitychooser/selectors.min.js.map +++ b/course/amd/build/local/activitychooser/selectors.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../../src/local/activitychooser/selectors.js"],"names":["getDataSelector","name","value","regions","chooser","getSectionChooserOptions","containerid","chooserOption","container","actions","info","chooserSummary","content","description","carousel","help","modules","favouriteTabNav","recommendedTabNav","defaultTabNav","favouriteTab","recommendedTab","defaultTab","getModuleSelector","modname","searchResults","searchResultItems","optionActions","showSummary","manageFavourite","addChooser","closeOption","hide","search","clearSearch","render","favourites","elements","section","sectionmodchooser","sitemenu","sitetopic","tab","activetab","searchicon","clearsearch"],"mappings":"gKA+BMA,CAAAA,CAAe,CAAG,SAACC,CAAD,CAAOC,CAAP,CAAiB,CACrC,sBAAgBD,CAAhB,eAAyBC,CAAzB,OACH,C,GAEc,CACXC,OAAO,CAAE,CACLC,OAAO,CAAEJ,CAAe,CAAC,QAAD,CAAW,mBAAX,CADnB,CAELK,wBAAwB,CAAE,kCAAAC,CAAW,kBAAOA,CAAP,aAAsBN,CAAe,CAAC,QAAD,CAAW,2BAAX,CAArC,EAFhC,CAGLO,aAAa,CAAE,CACXC,SAAS,CAAER,CAAe,CAAC,QAAD,CAAW,0BAAX,CADf,CAEXS,OAAO,CAAET,CAAe,CAAC,QAAD,CAAW,kCAAX,CAFb,CAGXU,IAAI,CAAEV,CAAe,CAAC,QAAD,CAAW,+BAAX,CAHV,CAHV,CAQLW,cAAc,CAAE,CACZH,SAAS,CAAER,CAAe,CAAC,QAAD,CAAW,kCAAX,CADd,CAEZY,OAAO,CAAEZ,CAAe,CAAC,QAAD,CAAW,0CAAX,CAFZ,CAGZa,WAAW,CAAEb,CAAe,CAAC,QAAD,CAAW,qBAAX,CAHhB,CAIZS,OAAO,CAAET,CAAe,CAAC,QAAD,CAAW,0CAAX,CAJZ,CARX,CAcLc,QAAQ,CAAEd,CAAe,CAAC,QAAD,CAAW,UAAX,CAdpB,CAeLe,IAAI,CAAEf,CAAe,CAAC,QAAD,CAAW,MAAX,CAfhB,CAgBLgB,OAAO,CAAEhB,CAAe,CAAC,QAAD,CAAW,SAAX,CAhBnB,CAiBLiB,eAAe,CAAEjB,CAAe,CAAC,QAAD,CAAW,mBAAX,CAjB3B,CAkBLkB,iBAAiB,CAAElB,CAAe,CAAC,QAAD,CAAW,qBAAX,CAlB7B,CAmBLmB,aAAa,CAAEnB,CAAe,CAAC,QAAD,CAAW,iBAAX,CAnBzB,CAoBLoB,YAAY,CAAEpB,CAAe,CAAC,QAAD,CAAW,YAAX,CApBxB,CAqBLqB,cAAc,CAAErB,CAAe,CAAC,QAAD,CAAW,aAAX,CArB1B,CAsBLsB,UAAU,CAAEtB,CAAe,CAAC,QAAD,CAAW,SAAX,CAtBtB,CAuBLuB,iBAAiB,CAAE,2BAAAC,CAAO,qDAAuCA,CAAvC,QAvBrB,CAwBLC,aAAa,CAAEzB,CAAe,CAAC,QAAD,CAAW,0BAAX,CAxBzB,CAyBL0B,iBAAiB,CAAE1B,CAAe,CAAC,QAAD,CAAW,+BAAX,CAzB7B,CADE,CA4BXS,OAAO,CAAE,CACLkB,aAAa,CAAE,CACXC,WAAW,CAAE5B,CAAe,CAAC,QAAD,CAAW,qBAAX,CADjB,CAEX6B,eAAe,CAAE7B,CAAe,CAAC,QAAD,CAAW,yBAAX,CAFrB,CADV,CAKL8B,UAAU,CAAE9B,CAAe,CAAC,QAAD,CAAW,oBAAX,CALtB,CAML+B,WAAW,CAAE/B,CAAe,CAAC,QAAD,CAAW,8BAAX,CANvB,CAOLgC,IAAI,CAAEhC,CAAe,CAAC,QAAD,CAAW,MAAX,CAPhB,CAQLiC,MAAM,CAAEjC,CAAe,CAAC,QAAD,CAAW,QAAX,CARlB,CASLkC,WAAW,CAAElC,CAAe,CAAC,QAAD,CAAW,aAAX,CATvB,CA5BE,CAuCXmC,MAAM,CAAE,CACJC,UAAU,CAAEpC,CAAe,CAAC,QAAD,CAAW,iBAAX,CADvB,CAvCG,CA0CXqC,QAAQ,CAAE,CACNC,OAAO,CAAE,UADH,CAENC,iBAAiB,CAAE,gCAFb,CAGNC,QAAQ,CAAE,uBAHJ,CAINC,SAAS,CAAE,eAJL,CAKNC,GAAG,CAAE,wBALC,CAMNC,SAAS,CAAE,gDANL,CAONC,UAAU,CAAE,gCAPN,CAQNC,WAAW,CAAE,0BARP,CA1CC,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 * Define all of the selectors we will be using on the grading interface.\n *\n * @module core_course/local/chooser/selectors\n * @package core_course\n * @copyright 2019 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * A small helper function to build queryable data selectors.\n * @method getDataSelector\n * @param {String} name\n * @param {String} value\n * @return {string}\n */\nconst getDataSelector = (name, value) => {\n return `[data-${name}=\"${value}\"]`;\n};\n\nexport default {\n regions: {\n chooser: getDataSelector('region', 'chooser-container'),\n getSectionChooserOptions: containerid => `${containerid} ${getDataSelector('region', 'chooser-options-container')}`,\n chooserOption: {\n container: getDataSelector('region', 'chooser-option-container'),\n actions: getDataSelector('region', 'chooser-option-actions-container'),\n info: getDataSelector('region', 'chooser-option-info-container'),\n },\n chooserSummary: {\n container: getDataSelector('region', 'chooser-option-summary-container'),\n content: getDataSelector('region', 'chooser-option-summary-content-container'),\n description: getDataSelector('region', 'summary-description'),\n actions: getDataSelector('region', 'chooser-option-summary-actions-container'),\n },\n carousel: getDataSelector('region', 'carousel'),\n help: getDataSelector('region', 'help'),\n modules: getDataSelector('region', 'modules'),\n favouriteTabNav: getDataSelector('region', 'favourite-tab-nav'),\n recommendedTabNav: getDataSelector('region', 'recommended-tab-nav'),\n defaultTabNav: getDataSelector('region', 'default-tab-nav'),\n favouriteTab: getDataSelector('region', 'favourites'),\n recommendedTab: getDataSelector('region', 'recommended'),\n defaultTab: getDataSelector('region', 'default'),\n getModuleSelector: modname => `[role=\"menuitem\"][data-modname=\"${modname}\"]`,\n searchResults: getDataSelector('region', 'search-results-container'),\n searchResultItems: getDataSelector('region', 'search-result-items-container'),\n },\n actions: {\n optionActions: {\n showSummary: getDataSelector('action', 'show-option-summary'),\n manageFavourite: getDataSelector('action', 'manage-module-favourite'),\n },\n addChooser: getDataSelector('action', 'add-chooser-option'),\n closeOption: getDataSelector('action', 'close-chooser-option-summary'),\n hide: getDataSelector('action', 'hide'),\n search: getDataSelector('action', 'search'),\n clearSearch: getDataSelector('action', 'clearsearch'),\n },\n render: {\n favourites: getDataSelector('render', 'favourites-area'),\n },\n elements: {\n section: '.section',\n sectionmodchooser: 'button.section-modchooser-link',\n sitemenu: '.block_site_main_menu',\n sitetopic: 'div.sitetopic',\n tab: 'a[data-toggle=\"tab\"]',\n activetab: 'a[data-toggle=\"tab\"][aria-selected=\"true\"]',\n searchicon: '.searchbar-append .search-icon',\n clearsearch: '.searchbar-append .clear'\n },\n};\n"],"file":"selectors.min.js"} \ No newline at end of file +{"version":3,"sources":["../../../src/local/activitychooser/selectors.js"],"names":["getDataSelector","name","value","regions","chooser","getSectionChooserOptions","containerid","chooserOption","container","actions","info","chooserSummary","content","header","carousel","help","modules","favouriteTabNav","recommendedTabNav","defaultTabNav","favouriteTab","recommendedTab","defaultTab","getModuleSelector","modname","searchResults","searchResultItems","optionActions","showSummary","manageFavourite","addChooser","closeOption","hide","search","clearSearch","render","favourites","elements","section","sectionmodchooser","sitemenu","sitetopic","tab","activetab","searchicon","clearsearch"],"mappings":"gKA+BMA,CAAAA,CAAe,CAAG,SAACC,CAAD,CAAOC,CAAP,CAAiB,CACrC,sBAAgBD,CAAhB,eAAyBC,CAAzB,OACH,C,GAEc,CACXC,OAAO,CAAE,CACLC,OAAO,CAAEJ,CAAe,CAAC,QAAD,CAAW,mBAAX,CADnB,CAELK,wBAAwB,CAAE,kCAAAC,CAAW,kBAAOA,CAAP,aAAsBN,CAAe,CAAC,QAAD,CAAW,2BAAX,CAArC,EAFhC,CAGLO,aAAa,CAAE,CACXC,SAAS,CAAER,CAAe,CAAC,QAAD,CAAW,0BAAX,CADf,CAEXS,OAAO,CAAET,CAAe,CAAC,QAAD,CAAW,kCAAX,CAFb,CAGXU,IAAI,CAAEV,CAAe,CAAC,QAAD,CAAW,+BAAX,CAHV,CAHV,CAQLW,cAAc,CAAE,CACZH,SAAS,CAAER,CAAe,CAAC,QAAD,CAAW,kCAAX,CADd,CAEZY,OAAO,CAAEZ,CAAe,CAAC,QAAD,CAAW,0CAAX,CAFZ,CAGZa,MAAM,CAAEb,CAAe,CAAC,QAAD,CAAW,gBAAX,CAHX,CAIZS,OAAO,CAAET,CAAe,CAAC,QAAD,CAAW,0CAAX,CAJZ,CARX,CAcLc,QAAQ,CAAEd,CAAe,CAAC,QAAD,CAAW,UAAX,CAdpB,CAeLe,IAAI,CAAEf,CAAe,CAAC,QAAD,CAAW,MAAX,CAfhB,CAgBLgB,OAAO,CAAEhB,CAAe,CAAC,QAAD,CAAW,SAAX,CAhBnB,CAiBLiB,eAAe,CAAEjB,CAAe,CAAC,QAAD,CAAW,mBAAX,CAjB3B,CAkBLkB,iBAAiB,CAAElB,CAAe,CAAC,QAAD,CAAW,qBAAX,CAlB7B,CAmBLmB,aAAa,CAAEnB,CAAe,CAAC,QAAD,CAAW,iBAAX,CAnBzB,CAoBLoB,YAAY,CAAEpB,CAAe,CAAC,QAAD,CAAW,YAAX,CApBxB,CAqBLqB,cAAc,CAAErB,CAAe,CAAC,QAAD,CAAW,aAAX,CArB1B,CAsBLsB,UAAU,CAAEtB,CAAe,CAAC,QAAD,CAAW,SAAX,CAtBtB,CAuBLuB,iBAAiB,CAAE,2BAAAC,CAAO,qDAAuCA,CAAvC,QAvBrB,CAwBLC,aAAa,CAAEzB,CAAe,CAAC,QAAD,CAAW,0BAAX,CAxBzB,CAyBL0B,iBAAiB,CAAE1B,CAAe,CAAC,QAAD,CAAW,+BAAX,CAzB7B,CADE,CA4BXS,OAAO,CAAE,CACLkB,aAAa,CAAE,CACXC,WAAW,CAAE5B,CAAe,CAAC,QAAD,CAAW,qBAAX,CADjB,CAEX6B,eAAe,CAAE7B,CAAe,CAAC,QAAD,CAAW,yBAAX,CAFrB,CADV,CAKL8B,UAAU,CAAE9B,CAAe,CAAC,QAAD,CAAW,oBAAX,CALtB,CAML+B,WAAW,CAAE/B,CAAe,CAAC,QAAD,CAAW,8BAAX,CANvB,CAOLgC,IAAI,CAAEhC,CAAe,CAAC,QAAD,CAAW,MAAX,CAPhB,CAQLiC,MAAM,CAAEjC,CAAe,CAAC,QAAD,CAAW,QAAX,CARlB,CASLkC,WAAW,CAAElC,CAAe,CAAC,QAAD,CAAW,aAAX,CATvB,CA5BE,CAuCXmC,MAAM,CAAE,CACJC,UAAU,CAAEpC,CAAe,CAAC,QAAD,CAAW,iBAAX,CADvB,CAvCG,CA0CXqC,QAAQ,CAAE,CACNC,OAAO,CAAE,UADH,CAENC,iBAAiB,CAAE,gCAFb,CAGNC,QAAQ,CAAE,uBAHJ,CAINC,SAAS,CAAE,eAJL,CAKNC,GAAG,CAAE,wBALC,CAMNC,SAAS,CAAE,gDANL,CAONC,UAAU,CAAE,gCAPN,CAQNC,WAAW,CAAE,0BARP,CA1CC,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 * Define all of the selectors we will be using on the grading interface.\n *\n * @module core_course/local/chooser/selectors\n * @package core_course\n * @copyright 2019 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * A small helper function to build queryable data selectors.\n * @method getDataSelector\n * @param {String} name\n * @param {String} value\n * @return {string}\n */\nconst getDataSelector = (name, value) => {\n return `[data-${name}=\"${value}\"]`;\n};\n\nexport default {\n regions: {\n chooser: getDataSelector('region', 'chooser-container'),\n getSectionChooserOptions: containerid => `${containerid} ${getDataSelector('region', 'chooser-options-container')}`,\n chooserOption: {\n container: getDataSelector('region', 'chooser-option-container'),\n actions: getDataSelector('region', 'chooser-option-actions-container'),\n info: getDataSelector('region', 'chooser-option-info-container'),\n },\n chooserSummary: {\n container: getDataSelector('region', 'chooser-option-summary-container'),\n content: getDataSelector('region', 'chooser-option-summary-content-container'),\n header: getDataSelector('region', 'summary-header'),\n actions: getDataSelector('region', 'chooser-option-summary-actions-container'),\n },\n carousel: getDataSelector('region', 'carousel'),\n help: getDataSelector('region', 'help'),\n modules: getDataSelector('region', 'modules'),\n favouriteTabNav: getDataSelector('region', 'favourite-tab-nav'),\n recommendedTabNav: getDataSelector('region', 'recommended-tab-nav'),\n defaultTabNav: getDataSelector('region', 'default-tab-nav'),\n favouriteTab: getDataSelector('region', 'favourites'),\n recommendedTab: getDataSelector('region', 'recommended'),\n defaultTab: getDataSelector('region', 'default'),\n getModuleSelector: modname => `[role=\"menuitem\"][data-modname=\"${modname}\"]`,\n searchResults: getDataSelector('region', 'search-results-container'),\n searchResultItems: getDataSelector('region', 'search-result-items-container'),\n },\n actions: {\n optionActions: {\n showSummary: getDataSelector('action', 'show-option-summary'),\n manageFavourite: getDataSelector('action', 'manage-module-favourite'),\n },\n addChooser: getDataSelector('action', 'add-chooser-option'),\n closeOption: getDataSelector('action', 'close-chooser-option-summary'),\n hide: getDataSelector('action', 'hide'),\n search: getDataSelector('action', 'search'),\n clearSearch: getDataSelector('action', 'clearsearch'),\n },\n render: {\n favourites: getDataSelector('render', 'favourites-area'),\n },\n elements: {\n section: '.section',\n sectionmodchooser: 'button.section-modchooser-link',\n sitemenu: '.block_site_main_menu',\n sitetopic: 'div.sitetopic',\n tab: 'a[data-toggle=\"tab\"]',\n activetab: 'a[data-toggle=\"tab\"][aria-selected=\"true\"]',\n searchicon: '.searchbar-append .search-icon',\n clearsearch: '.searchbar-append .clear'\n },\n};\n"],"file":"selectors.min.js"} \ No newline at end of file diff --git a/course/amd/src/activitychooser.js b/course/amd/src/activitychooser.js index 6565e721aac..cb58e9fbd2d 100644 --- a/course/amd/src/activitychooser.js +++ b/course/amd/src/activitychooser.js @@ -109,10 +109,10 @@ const sectionIdMapper = (webServiceData, id) => { }; /** - * Build a modal for each section ID and store it into a map for quick access + * Build a modal on demand to save page load times * * @method modalBuilder - * @param {Map} data our map of section ID's & modules to generate modals for + * @param {Array} data our array of modules with section ID's applied in the URL field * @return {Object} Our modal that we are going to show the user */ const modalBuilder = data => buildModal(templateDataBuilder(data)); @@ -149,7 +149,7 @@ const templateDataBuilder = (data) => { }; /** - * Given an object we want to prebuild a modal ready to store into a map + * Given an object we want to build a modal ready to show * * @method buildModal * @param {Object} data The template data which contains arrays of modules @@ -159,7 +159,7 @@ const buildModal = data => { return ModalFactory.create({ type: ModalFactory.types.DEFAULT, title: getString('addresourceoractivity'), - body: Templates.render('core_course/chooser', data), + body: Templates.render('core_course/activitychooser', data), large: true, templateContext: { classes: 'modchooser' @@ -230,7 +230,8 @@ const partiallyAppliedFavouriteManager = (moduleData, sectionId) => { const builtFaves = sectionIdMapper(newFaves, sectionId); - const {html, js} = await Templates.renderForPromise('core_course/chooser_favourites', {favourites: builtFaves}); + const {html, js} = await Templates.renderForPromise('core_course/local/activitychooser/favourites', + {favourites: builtFaves}); await Templates.replaceNodeContents(favouriteArea, html, js); diff --git a/course/amd/src/local/activitychooser/dialogue.js b/course/amd/src/local/activitychooser/dialogue.js index 9429ee68c40..9f803c38ecd 100644 --- a/course/amd/src/local/activitychooser/dialogue.js +++ b/course/amd/src/local/activitychooser/dialogue.js @@ -53,13 +53,13 @@ const showModuleHelp = (carousel, moduleData) => { }); // Build up the html & js ready to place into the help section. - const contentPromise = Templates.renderForPromise('core_course/chooser_help', moduleData); + const contentPromise = Templates.renderForPromise('core_course/local/activitychooser/help', moduleData); // Wait for the content to be ready, and for the transition to be complet. Promise.all([contentPromise, spinnerPromise, transitionPromise]) .then(([{html, js}]) => Templates.replaceNodeContents(help, html, js)) .then(() => { - help.querySelector(selectors.regions.chooserSummary.description).focus(); + help.querySelector(selectors.regions.chooserSummary.header).focus(); return help; }) .catch(Notification.exception); @@ -402,7 +402,7 @@ const renderSearchResults = async(searchResultsContainer, searchResultsData) => 'searchresults': searchResultsData }; // Build up the html & js ready to place into the help section. - const {html, js} = await Templates.renderForPromise('core_course/chooser_search_results', templateData); + const {html, js} = await Templates.renderForPromise('core_course/local/activitychooser/search_results', templateData); await Templates.replaceNodeContents(searchResultsContainer, html, js); }; diff --git a/course/amd/src/local/activitychooser/selectors.js b/course/amd/src/local/activitychooser/selectors.js index dc653bf6251..a072a1ef344 100644 --- a/course/amd/src/local/activitychooser/selectors.js +++ b/course/amd/src/local/activitychooser/selectors.js @@ -45,7 +45,7 @@ export default { chooserSummary: { container: getDataSelector('region', 'chooser-option-summary-container'), content: getDataSelector('region', 'chooser-option-summary-content-container'), - description: getDataSelector('region', 'summary-description'), + header: getDataSelector('region', 'summary-header'), actions: getDataSelector('region', 'chooser-option-summary-actions-container'), }, carousel: getDataSelector('region', 'carousel'), diff --git a/course/templates/chooser.mustache b/course/templates/activitychooser.mustache similarity index 90% rename from course/templates/chooser.mustache rename to course/templates/activitychooser.mustache index 3c00b543e24..7bd4b3d7d41 100644 --- a/course/templates/chooser.mustache +++ b/course/templates/activitychooser.mustache @@ -35,13 +35,13 @@