mirror of
https://github.com/moodle/moodle.git
synced 2025-04-24 18:04:43 +02:00
Merge branch 'MDL-58579' of https://github.com/Chocolate-lightning/moodle
This commit is contained in:
commit
c5183622d6
2
blocks/myoverview/amd/build/main.min.js
vendored
2
blocks/myoverview/amd/build/main.min.js
vendored
@ -1,2 +1,2 @@
|
||||
define ("block_myoverview/main",["jquery","block_myoverview/view","block_myoverview/view_nav"],function(a,b,c){return{init:function init(d){d=a(d);c.init(d);b.init(d)}}});
|
||||
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("block_myoverview/main",["exports","block_myoverview/view","block_myoverview/view_nav"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=e(b);c=e(c);function d(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;d=function(){return a};return a}function e(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=d();if(b&&b.has(a)){return b.get(a)}var c={},e=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var f in a){if(Object.prototype.hasOwnProperty.call(a,f)){var g=e?Object.getOwnPropertyDescriptor(a,f):null;if(g&&(g.get||g.set)){Object.defineProperty(c,f,g)}else{c[f]=a[f]}}}c.default=a;if(b){b.set(a,c)}return c}var f=function(a){c.init(a);b.init(a)};a.init=f});
|
||||
//# sourceMappingURL=main.min.js.map
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sources":["../src/main.js"],"names":["define","$","View","ViewNav","init","root"],"mappings":"AAsBAA,OAAM,yBACN,CACI,QADJ,CAEI,uBAFJ,CAGI,2BAHJ,CADM,CAMN,SACIC,CADJ,CAEIC,CAFJ,CAGIC,CAHJ,CAIE,CAcE,MAAO,CACHC,IAAI,CATG,QAAPA,CAAAA,IAAO,CAASC,CAAT,CAAe,CACtBA,CAAI,CAAGJ,CAAC,CAACI,CAAD,CAAR,CAEAF,CAAO,CAACC,IAAR,CAAaC,CAAb,EAEAH,CAAI,CAACE,IAAL,CAAUC,CAAV,CACH,CAEM,CAGV,CA3BK,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript to initialise the myoverview block.\n *\n * @copyright 2018 Bas Brands <bas@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n[\n 'jquery',\n 'block_myoverview/view',\n 'block_myoverview/view_nav'\n],\nfunction(\n $,\n View,\n ViewNav\n) {\n /**\n * Initialise all of the modules for the overview block.\n *\n * @param {object} root The root element for the overview block.\n */\n var init = function(root) {\n root = $(root);\n // Initialise the course navigation elements.\n ViewNav.init(root);\n // Initialise the courses view modules.\n View.init(root);\n };\n\n return {\n init: init\n };\n});\n"],"file":"main.min.js"}
|
||||
{"version":3,"sources":["../src/main.js"],"names":["init","root","ViewNav","View"],"mappings":"+dAsBA,OACA,O,siBAOO,GAAMA,CAAAA,CAAI,CAAG,SAACC,CAAD,CAAU,CAE1BC,CAAO,CAACF,IAAR,CAAaC,CAAb,EAEAE,CAAI,CAACH,IAAL,CAAUC,CAAV,CACH,CALM,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 <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript to initialise the myoverview block.\n *\n * @copyright 2018 Bas Brands <bas@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as View from 'block_myoverview/view';\nimport * as ViewNav from 'block_myoverview/view_nav';\n\n/**\n * Initialise all of the modules for the overview block.\n *\n * @param {object} root The root element for the overview block.\n */\nexport const init = (root) => {\n // Initialise the course navigation elements.\n ViewNav.init(root);\n // Initialise the courses view modules.\n View.init(root);\n};\n"],"file":"main.min.js"}
|
@ -1,2 +1,2 @@
|
||||
define ("block_myoverview/repository",["core/ajax","core/notification"],function(a,b){return{getEnrolledCoursesByTimeline:function getEnrolledCoursesByTimeline(b){var c=a.call([{methodname:"core_course_get_enrolled_courses_by_timeline_classification",args:b}])[0];return c},setFavouriteCourses:function setFavouriteCourses(b){var c=a.call([{methodname:"core_course_set_favourite_courses",args:b}])[0];return c},updateUserPreferences:function updateUserPreferences(c){a.call([{methodname:"core_user_update_user_preferences",args:c}])[0].fail(b.exception)}}});
|
||||
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("block_myoverview/repository",["exports","core/ajax","core/notification"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.updateUserPreferences=a.setFavouriteCourses=a.getEnrolledCoursesByTimeline=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);c=e(c);function d(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;d=function(){return a};return a}function e(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=d();if(b&&b.has(a)){return b.get(a)}var c={},e=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var f in a){if(Object.prototype.hasOwnProperty.call(a,f)){var g=e?Object.getOwnPropertyDescriptor(a,f):null;if(g&&(g.get||g.set)){Object.defineProperty(c,f,g)}else{c[f]=a[f]}}}c.default=a;if(b){b.set(a,c)}return c}var f=function(a){return b.default.call([{methodname:"core_course_get_enrolled_courses_by_timeline_classification",args:a}])[0]};a.getEnrolledCoursesByTimeline=f;var g=function(a){return b.default.call([{methodname:"core_course_set_favourite_courses",args:a}])[0]};a.setFavouriteCourses=g;var h=function(a){b.default.call([{methodname:"core_user_update_user_preferences",args:a}])[0].fail(c.exception)};a.updateUserPreferences=h});
|
||||
//# sourceMappingURL=repository.min.js.map
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sources":["../src/repository.js"],"names":["define","Ajax","Notification","getEnrolledCoursesByTimeline","args","promise","call","methodname","setFavouriteCourses","updateUserPreferences","fail","exception"],"mappings":"AAsBAA,OAAM,+BAAC,CAAC,WAAD,CAAc,mBAAd,CAAD,CAAqC,SAASC,CAAT,CAAeC,CAAf,CAA6B,CAyEpE,MAAO,CACHC,4BAA4B,CA3DG,QAA/BA,CAAAA,4BAA+B,CAASC,CAAT,CAAe,IAO1CC,CAAAA,CAAO,CAAGJ,CAAI,CAACK,IAAL,CAAU,CALV,CACVC,UAAU,CAAE,6DADF,CAEVH,IAAI,CAAEA,CAFI,CAKU,CAAV,EAAqB,CAArB,CAPgC,CAS9C,MAAOC,CAAAA,CACV,CAgDM,CAEHG,mBAAmB,CAvCG,QAAtBA,CAAAA,mBAAsB,CAASJ,CAAT,CAAe,IAOjCC,CAAAA,CAAO,CAAGJ,CAAI,CAACK,IAAL,CAAU,CALV,CACVC,UAAU,CAAE,mCADF,CAEVH,IAAI,CAAEA,CAFI,CAKU,CAAV,EAAqB,CAArB,CAPuB,CASrC,MAAOC,CAAAA,CACV,CA2BM,CAGHI,qBAAqB,CAbG,QAAxBA,CAAAA,qBAAwB,CAASL,CAAT,CAAe,CAMvCH,CAAI,CAACK,IAAL,CAAU,CALI,CACVC,UAAU,CAAE,mCADF,CAEVH,IAAI,CAAEA,CAFI,CAKJ,CAAV,EAAqB,CAArB,EACKM,IADL,CACUR,CAAY,CAACS,SADvB,CAEH,CAEM,CAKV,CA9EK,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * A javascript module to retrieve enrolled coruses from the server.\n *\n * @module block_myoverview/repository\n * @copyright 2018 Bas Brands <base@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n\n /**\n * Retrieve a list of enrolled courses.\n *\n * Valid args are:\n * string classification future, inprogress, past\n * int limit number of records to retreive\n * int Offset offset for pagination\n * int sort sort by lastaccess or name\n *\n * @method getEnrolledCoursesByTimeline\n * @param {object} args The request arguments\n * @return {promise} Resolved with an array of courses\n */\n var getEnrolledCoursesByTimeline = function(args) {\n\n var request = {\n methodname: 'core_course_get_enrolled_courses_by_timeline_classification',\n args: args\n };\n\n var promise = Ajax.call([request])[0];\n\n return promise;\n };\n\n /**\n * Set the favourite state on a list of courses.\n *\n * Valid args are:\n * Array courses list of course id numbers.\n *\n * @param {Object} args Arguments send to the webservice.\n * @return {Promise} Resolve with warnings.\n */\n var setFavouriteCourses = function(args) {\n\n var request = {\n methodname: 'core_course_set_favourite_courses',\n args: args\n };\n\n var promise = Ajax.call([request])[0];\n\n return promise;\n };\n\n /**\n * Update the user preferences.\n *\n * @param {Object} args Arguments send to the webservice.\n *\n * Sample args:\n * {\n * preferences: [\n * {\n * type: 'block_example_user_sort_preference'\n * value: 'title'\n * }\n * ]\n * }\n */\n var updateUserPreferences = function(args) {\n var request = {\n methodname: 'core_user_update_user_preferences',\n args: args\n };\n\n Ajax.call([request])[0]\n .fail(Notification.exception);\n };\n\n return {\n getEnrolledCoursesByTimeline: getEnrolledCoursesByTimeline,\n setFavouriteCourses: setFavouriteCourses,\n updateUserPreferences: updateUserPreferences\n };\n});\n"],"file":"repository.min.js"}
|
||||
{"version":3,"sources":["../src/repository.js"],"names":["getEnrolledCoursesByTimeline","args","Ajax","call","methodname","setFavouriteCourses","updateUserPreferences","fail","Notification","exception"],"mappings":"uhBAuBA,uDACA,O,siBAeO,GAAMA,CAAAA,CAA4B,CAAG,SAAAC,CAAI,CAAI,CAMhD,MAAOC,WAAKC,IAAL,CAAU,CALD,CACZC,UAAU,CAAE,6DADA,CAEZH,IAAI,CAAEA,CAFM,CAKC,CAAV,EAAqB,CAArB,CACV,CAPM,C,iCAkBA,GAAMI,CAAAA,CAAmB,CAAG,SAAAJ,CAAI,CAAI,CAMvC,MAAOC,WAAKC,IAAL,CAAU,CALD,CACZC,UAAU,CAAE,mCADA,CAEZH,IAAI,CAAEA,CAFM,CAKC,CAAV,EAAqB,CAArB,CACV,CAPM,C,wBAwBA,GAAMK,CAAAA,CAAqB,CAAG,SAAAL,CAAI,CAAI,CAMzCC,UAAKC,IAAL,CAAU,CALM,CACZC,UAAU,CAAE,mCADA,CAEZH,IAAI,CAAEA,CAFM,CAKN,CAAV,EAAqB,CAArB,EACKM,IADL,CACUC,CAAY,CAACC,SADvB,CAEH,CARM,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 <http://www.gnu.org/licenses/>.\n\n/**\n * A javascript module to retrieve enrolled coruses from the server.\n *\n * @module block_myoverview/repository\n * @copyright 2018 Bas Brands <base@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport * as Notification from 'core/notification';\n\n/**\n * Retrieve a list of enrolled courses.\n *\n * Valid args are:\n * string classification future, inprogress, past\n * int limit number of records to retreive\n * int Offset offset for pagination\n * int sort sort by lastaccess or name\n *\n * @method getEnrolledCoursesByTimeline\n * @param {object} args The request arguments\n * @return {promise} Resolved with an array of courses\n */\nexport const getEnrolledCoursesByTimeline = args => {\n const request = {\n methodname: 'core_course_get_enrolled_courses_by_timeline_classification',\n args: args\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Set the favourite state on a list of courses.\n *\n * Valid args are:\n * Array courses list of course id numbers.\n *\n * @param {Object} args Arguments send to the webservice.\n * @return {Promise} Resolve with warnings.\n */\nexport const setFavouriteCourses = args => {\n const request = {\n methodname: 'core_course_set_favourite_courses',\n args: args\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Update the user preferences.\n *\n * @param {Object} args Arguments send to the webservice.\n *\n * Sample args:\n * {\n * preferences: [\n * {\n * type: 'block_example_user_sort_preference'\n * value: 'title'\n * }\n * ]\n * }\n */\nexport const updateUserPreferences = args => {\n const request = {\n methodname: 'core_user_update_user_preferences',\n args: args\n };\n\n Ajax.call([request])[0]\n .fail(Notification.exception);\n};\n"],"file":"repository.min.js"}
|
2
blocks/myoverview/amd/build/selectors.min.js
vendored
2
blocks/myoverview/amd/build/selectors.min.js
vendored
@ -1,2 +1,2 @@
|
||||
define ("block_myoverview/selectors",[],function(){return{courseView:{region:"[data-region=\"courses-view\"]",regionContent:"[data-region=\"course-view-content\"]"}}});
|
||||
define ("block_myoverview/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;a.default={courseView:{region:"[data-region=\"courses-view\"]",regionContent:"[data-region=\"course-view-content\"]"},FILTERS:"[data-region=\"filter\"]",FILTER_OPTION:"[data-filter]",DISPLAY_OPTION:"[data-display-option]",ACTION_HIDE_COURSE:"[data-action=\"hide-course\"]",ACTION_SHOW_COURSE:"[data-action=\"show-course\"]",ACTION_ADD_FAVOURITE:"[data-action=\"add-favourite\"]",ACTION_REMOVE_FAVOURITE:"[data-action=\"remove-favourite\"]",FAVOURITE_ICON:"[data-region=\"favourite-icon\"]",ICON_IS_FAVOURITE:"[data-region=\"is-favourite\"]",ICON_NOT_FAVOURITE:"[data-region=\"not-favourite\"]",region:{selectBlock:"[data-region=\"myoverview\"]",clearIcon:"[data-region=\"clear-icon\"]",searchIcon:"[data-region=\"search-icon\"]",searchInput:"[data-region=\"search-input\"]"}};return a.default});
|
||||
//# sourceMappingURL=selectors.min.js.map
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sources":["../src/selectors.js"],"names":["define","courseView","region","regionContent"],"mappings":"AAsBAA,OAAM,8BAAC,EAAD,CAAK,UAAW,CAClB,MAAO,CACHC,UAAU,CAAE,CACRC,MAAM,CAAE,gCADA,CAERC,aAAa,CAAE,uCAFP,CADT,CAMV,CAPK,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript to initialise the selectors for the myoverview block.\n *\n * @copyright 2018 Peter Dias <peter@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine([], function() {\n return {\n courseView: {\n region: '[data-region=\"courses-view\"]',\n regionContent: '[data-region=\"course-view-content\"]'\n }\n };\n});\n"],"file":"selectors.min.js"}
|
||||
{"version":3,"sources":["../src/selectors.js"],"names":["courseView","region","regionContent","FILTERS","FILTER_OPTION","DISPLAY_OPTION","ACTION_HIDE_COURSE","ACTION_SHOW_COURSE","ACTION_ADD_FAVOURITE","ACTION_REMOVE_FAVOURITE","FAVOURITE_ICON","ICON_IS_FAVOURITE","ICON_NOT_FAVOURITE","selectBlock","clearIcon","searchIcon","searchInput"],"mappings":"sJAsBe,CACXA,UAAU,CAAE,CACRC,MAAM,CAAE,gCADA,CAERC,aAAa,CAAE,uCAFP,CADD,CAKXC,OAAO,CAAE,0BALE,CAMXC,aAAa,CAAE,eANJ,CAOXC,cAAc,CAAE,uBAPL,CAQXC,kBAAkB,CAAE,+BART,CASXC,kBAAkB,CAAE,+BATT,CAUXC,oBAAoB,CAAE,iCAVX,CAWXC,uBAAuB,CAAE,oCAXd,CAYXC,cAAc,CAAE,kCAZL,CAaXC,iBAAiB,CAAE,gCAbR,CAcXC,kBAAkB,CAAE,iCAdT,CAeXX,MAAM,CAAE,CACJY,WAAW,CAAE,8BADT,CAEJC,SAAS,CAAE,8BAFP,CAGJC,UAAU,CAAE,+BAHR,CAIJC,WAAW,CAAE,gCAJT,CAfG,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 <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript to initialise the selectors for the myoverview block.\n *\n * @copyright 2018 Peter Dias <peter@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport default {\n courseView: {\n region: '[data-region=\"courses-view\"]',\n regionContent: '[data-region=\"course-view-content\"]'\n },\n FILTERS: '[data-region=\"filter\"]',\n FILTER_OPTION: '[data-filter]',\n DISPLAY_OPTION: '[data-display-option]',\n ACTION_HIDE_COURSE: '[data-action=\"hide-course\"]',\n ACTION_SHOW_COURSE: '[data-action=\"show-course\"]',\n ACTION_ADD_FAVOURITE: '[data-action=\"add-favourite\"]',\n ACTION_REMOVE_FAVOURITE: '[data-action=\"remove-favourite\"]',\n FAVOURITE_ICON: '[data-region=\"favourite-icon\"]',\n ICON_IS_FAVOURITE: '[data-region=\"is-favourite\"]',\n ICON_NOT_FAVOURITE: '[data-region=\"not-favourite\"]',\n region: {\n selectBlock: '[data-region=\"myoverview\"]',\n clearIcon: '[data-region=\"clear-icon\"]',\n searchIcon: '[data-region=\"search-icon\"]',\n searchInput: '[data-region=\"search-input\"]',\n },\n};\n"],"file":"selectors.min.js"}
|
2
blocks/myoverview/amd/build/view.min.js
vendored
2
blocks/myoverview/amd/build/view.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
blocks/myoverview/amd/build/view_nav.min.js
vendored
2
blocks/myoverview/amd/build/view_nav.min.js
vendored
@ -1,2 +1,2 @@
|
||||
define ("block_myoverview/view_nav",["jquery","core/custom_interaction_events","block_myoverview/repository","block_myoverview/view","block_myoverview/selectors"],function(a,b,c,d,f){var g={FILTERS:"[data-region=\"filter\"]",FILTER_OPTION:"[data-filter]",DISPLAY_OPTION:"[data-display-option]"},h=function(a,b){var d=null;if("display"==a){d="block_myoverview_user_view_preference"}else if("sort"==a){d="block_myoverview_user_sort_preference"}else if("customfieldvalue"==a){d="block_myoverview_user_grouping_customfieldvalue_preference"}else{d="block_myoverview_user_grouping_preference"}c.updateUserPreferences({preferences:[{type:d,value:b}]})},i=function(c){var e=c.find(g.FILTERS);b.define(e,[b.events.activate]);e.on(b.events.activate,g.FILTER_OPTION,function(b,e){var g=a(b.target);if(g.hasClass("active")){return}var i=g.attr("data-filter"),j=g.attr("data-pref"),k=g.attr("data-customfieldvalue");c.find(f.courseView.region).attr("data-"+i,g.attr("data-value"));h(i,j);if(k){c.find(f.courseView.region).attr("data-customfieldvalue",k);h("customfieldvalue",k)}d.init(c);e.originalEvent.preventDefault()});b.define(e,[b.events.activate]);e.on(b.events.activate,g.DISPLAY_OPTION,function(b,e){var g=a(b.target);if(g.hasClass("active")){return}var i=g.attr("data-display-option"),j=g.attr("data-pref");c.find(f.courseView.region).attr("data-display",g.attr("data-value"));h(i,j);d.reset(c);e.originalEvent.preventDefault()})};return{init:function init(b){b=a(b);i(b)}}});
|
||||
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("block_myoverview/view_nav",["exports","jquery","core/custom_interaction_events","block_myoverview/repository","block_myoverview/view","block_myoverview/selectors"],function(a,b,c,d,f,g){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=j(b);c=i(c);d=i(d);f=i(f);g=j(g);function h(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;h=function(){return a};return a}function i(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=h();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function j(a){return a&&a.__esModule?a:{default:a}}var k=function(a,b){var c=null;if("display"===a){c="block_myoverview_user_view_preference"}else if("sort"===a){c="block_myoverview_user_sort_preference"}else if("customfieldvalue"===a){c="block_myoverview_user_grouping_customfieldvalue_preference"}else{c="block_myoverview_user_grouping_preference"}d.updateUserPreferences({preferences:[{type:c,value:b}]})},l=function(a){var d=a.find(g.default.FILTERS);c.define(d,[c.events.activate]);d.on(c.events.activate,g.default.FILTER_OPTION,function(c,d){var e=(0,b.default)(c.target);if(e.hasClass("active")){return}var h=e.attr("data-filter"),i=e.attr("data-pref"),j=e.attr("data-customfieldvalue");a.find(g.default.courseView.region).attr("data-"+h,e.attr("data-value"));k(h,i);if(j){a.find(g.default.courseView.region).attr("data-customfieldvalue",j);k("customfieldvalue",j)}var l=document.querySelector(g.default.region.selectBlock),m=l.querySelector(g.default.region.searchInput);if(""!==m.value){var n=l.querySelector(g.default.region.clearIcon),o=l.querySelector(g.default.region.searchIcon);m.value="";f.clearSearch(o,n,a)}else{f.init(a)}d.originalEvent.preventDefault()});d.on(c.events.activate,g.default.DISPLAY_OPTION,function(c,d){var e=(0,b.default)(c.target);if(e.hasClass("active")){return}var h=e.attr("data-display-option"),i=e.attr("data-pref");a.find(g.default.courseView.region).attr("data-display",e.attr("data-value"));k(h,i);f.reset(a);d.originalEvent.preventDefault()})},m=function(a){a=(0,b.default)(a);l(a)};a.init=m});
|
||||
//# sourceMappingURL=view_nav.min.js.map
|
||||
|
File diff suppressed because one or more lines are too long
@ -20,31 +20,17 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'block_myoverview/view',
|
||||
'block_myoverview/view_nav'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
View,
|
||||
ViewNav
|
||||
) {
|
||||
/**
|
||||
* Initialise all of the modules for the overview block.
|
||||
*
|
||||
* @param {object} root The root element for the overview block.
|
||||
*/
|
||||
var init = function(root) {
|
||||
root = $(root);
|
||||
// Initialise the course navigation elements.
|
||||
ViewNav.init(root);
|
||||
// Initialise the courses view modules.
|
||||
View.init(root);
|
||||
};
|
||||
import * as View from 'block_myoverview/view';
|
||||
import * as ViewNav from 'block_myoverview/view_nav';
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
});
|
||||
/**
|
||||
* Initialise all of the modules for the overview block.
|
||||
*
|
||||
* @param {object} root The root element for the overview block.
|
||||
*/
|
||||
export const init = (root) => {
|
||||
// Initialise the course navigation elements.
|
||||
ViewNav.init(root);
|
||||
// Initialise the courses view modules.
|
||||
View.init(root);
|
||||
};
|
||||
|
@ -20,82 +20,71 @@
|
||||
* @copyright 2018 Bas Brands <base@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['core/ajax', 'core/notification'], function(Ajax, Notification) {
|
||||
|
||||
/**
|
||||
* Retrieve a list of enrolled courses.
|
||||
*
|
||||
* Valid args are:
|
||||
* string classification future, inprogress, past
|
||||
* int limit number of records to retreive
|
||||
* int Offset offset for pagination
|
||||
* int sort sort by lastaccess or name
|
||||
*
|
||||
* @method getEnrolledCoursesByTimeline
|
||||
* @param {object} args The request arguments
|
||||
* @return {promise} Resolved with an array of courses
|
||||
*/
|
||||
var getEnrolledCoursesByTimeline = function(args) {
|
||||
import Ajax from 'core/ajax';
|
||||
import * as Notification from 'core/notification';
|
||||
|
||||
var request = {
|
||||
methodname: 'core_course_get_enrolled_courses_by_timeline_classification',
|
||||
args: args
|
||||
};
|
||||
|
||||
var promise = Ajax.call([request])[0];
|
||||
|
||||
return promise;
|
||||
/**
|
||||
* Retrieve a list of enrolled courses.
|
||||
*
|
||||
* Valid args are:
|
||||
* string classification future, inprogress, past
|
||||
* int limit number of records to retreive
|
||||
* int Offset offset for pagination
|
||||
* int sort sort by lastaccess or name
|
||||
*
|
||||
* @method getEnrolledCoursesByTimeline
|
||||
* @param {object} args The request arguments
|
||||
* @return {promise} Resolved with an array of courses
|
||||
*/
|
||||
export const getEnrolledCoursesByTimeline = args => {
|
||||
const request = {
|
||||
methodname: 'core_course_get_enrolled_courses_by_timeline_classification',
|
||||
args: args
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the favourite state on a list of courses.
|
||||
*
|
||||
* Valid args are:
|
||||
* Array courses list of course id numbers.
|
||||
*
|
||||
* @param {Object} args Arguments send to the webservice.
|
||||
* @return {Promise} Resolve with warnings.
|
||||
*/
|
||||
var setFavouriteCourses = function(args) {
|
||||
return Ajax.call([request])[0];
|
||||
};
|
||||
|
||||
var request = {
|
||||
methodname: 'core_course_set_favourite_courses',
|
||||
args: args
|
||||
};
|
||||
|
||||
var promise = Ajax.call([request])[0];
|
||||
|
||||
return promise;
|
||||
/**
|
||||
* Set the favourite state on a list of courses.
|
||||
*
|
||||
* Valid args are:
|
||||
* Array courses list of course id numbers.
|
||||
*
|
||||
* @param {Object} args Arguments send to the webservice.
|
||||
* @return {Promise} Resolve with warnings.
|
||||
*/
|
||||
export const setFavouriteCourses = args => {
|
||||
const request = {
|
||||
methodname: 'core_course_set_favourite_courses',
|
||||
args: args
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the user preferences.
|
||||
*
|
||||
* @param {Object} args Arguments send to the webservice.
|
||||
*
|
||||
* Sample args:
|
||||
* {
|
||||
* preferences: [
|
||||
* {
|
||||
* type: 'block_example_user_sort_preference'
|
||||
* value: 'title'
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
var updateUserPreferences = function(args) {
|
||||
var request = {
|
||||
methodname: 'core_user_update_user_preferences',
|
||||
args: args
|
||||
};
|
||||
return Ajax.call([request])[0];
|
||||
};
|
||||
|
||||
Ajax.call([request])[0]
|
||||
.fail(Notification.exception);
|
||||
/**
|
||||
* Update the user preferences.
|
||||
*
|
||||
* @param {Object} args Arguments send to the webservice.
|
||||
*
|
||||
* Sample args:
|
||||
* {
|
||||
* preferences: [
|
||||
* {
|
||||
* type: 'block_example_user_sort_preference'
|
||||
* value: 'title'
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
export const updateUserPreferences = args => {
|
||||
const request = {
|
||||
methodname: 'core_user_update_user_preferences',
|
||||
args: args
|
||||
};
|
||||
|
||||
return {
|
||||
getEnrolledCoursesByTimeline: getEnrolledCoursesByTimeline,
|
||||
setFavouriteCourses: setFavouriteCourses,
|
||||
updateUserPreferences: updateUserPreferences
|
||||
};
|
||||
});
|
||||
Ajax.call([request])[0]
|
||||
.fail(Notification.exception);
|
||||
};
|
||||
|
@ -20,11 +20,25 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define([], function() {
|
||||
return {
|
||||
courseView: {
|
||||
region: '[data-region="courses-view"]',
|
||||
regionContent: '[data-region="course-view-content"]'
|
||||
}
|
||||
};
|
||||
});
|
||||
export default {
|
||||
courseView: {
|
||||
region: '[data-region="courses-view"]',
|
||||
regionContent: '[data-region="course-view-content"]'
|
||||
},
|
||||
FILTERS: '[data-region="filter"]',
|
||||
FILTER_OPTION: '[data-filter]',
|
||||
DISPLAY_OPTION: '[data-display-option]',
|
||||
ACTION_HIDE_COURSE: '[data-action="hide-course"]',
|
||||
ACTION_SHOW_COURSE: '[data-action="show-course"]',
|
||||
ACTION_ADD_FAVOURITE: '[data-action="add-favourite"]',
|
||||
ACTION_REMOVE_FAVOURITE: '[data-action="remove-favourite"]',
|
||||
FAVOURITE_ICON: '[data-region="favourite-icon"]',
|
||||
ICON_IS_FAVOURITE: '[data-region="is-favourite"]',
|
||||
ICON_NOT_FAVOURITE: '[data-region="not-favourite"]',
|
||||
region: {
|
||||
selectBlock: '[data-region="myoverview"]',
|
||||
clearIcon: '[data-region="clear-icon"]',
|
||||
searchIcon: '[data-region="search-icon"]',
|
||||
searchInput: '[data-region="search-input"]',
|
||||
},
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,130 +20,120 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/custom_interaction_events',
|
||||
'block_myoverview/repository',
|
||||
'block_myoverview/view',
|
||||
'block_myoverview/selectors'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
CustomEvents,
|
||||
Repository,
|
||||
View,
|
||||
Selectors
|
||||
) {
|
||||
import $ from 'jquery';
|
||||
import * as CustomEvents from 'core/custom_interaction_events';
|
||||
import * as Repository from 'block_myoverview/repository';
|
||||
import * as View from 'block_myoverview/view';
|
||||
import SELECTORS from 'block_myoverview/selectors';
|
||||
|
||||
var SELECTORS = {
|
||||
FILTERS: '[data-region="filter"]',
|
||||
FILTER_OPTION: '[data-filter]',
|
||||
DISPLAY_OPTION: '[data-display-option]'
|
||||
};
|
||||
/**
|
||||
* Update the user preference for the block.
|
||||
*
|
||||
* @param {String} filter The type of filter: display/sort/grouping.
|
||||
* @param {String} value The current preferred value.
|
||||
*/
|
||||
const updatePreferences = (filter, value) => {
|
||||
let type = null;
|
||||
if (filter === 'display') {
|
||||
type = 'block_myoverview_user_view_preference';
|
||||
} else if (filter === 'sort') {
|
||||
type = 'block_myoverview_user_sort_preference';
|
||||
} else if (filter === 'customfieldvalue') {
|
||||
type = 'block_myoverview_user_grouping_customfieldvalue_preference';
|
||||
} else {
|
||||
type = 'block_myoverview_user_grouping_preference';
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the user preference for the block.
|
||||
*
|
||||
* @param {String} filter The type of filter: display/sort/grouping.
|
||||
* @param {String} value The current preferred value.
|
||||
*/
|
||||
var updatePreferences = function(filter, value) {
|
||||
var type = null;
|
||||
if (filter == 'display') {
|
||||
type = 'block_myoverview_user_view_preference';
|
||||
} else if (filter == 'sort') {
|
||||
type = 'block_myoverview_user_sort_preference';
|
||||
} else if (filter == 'customfieldvalue') {
|
||||
type = 'block_myoverview_user_grouping_customfieldvalue_preference';
|
||||
} else {
|
||||
type = 'block_myoverview_user_grouping_preference';
|
||||
}
|
||||
Repository.updateUserPreferences({
|
||||
preferences: [
|
||||
{
|
||||
type: type,
|
||||
value: value
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
Repository.updateUserPreferences({
|
||||
preferences: [
|
||||
{
|
||||
type: type,
|
||||
value: value
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Event listener for the Display filter (cards, list).
|
||||
*
|
||||
* @param {object} root The root element for the overview block
|
||||
*/
|
||||
const registerSelector = root => {
|
||||
|
||||
/**
|
||||
* Event listener for the Display filter (cards, list).
|
||||
*
|
||||
* @param {object} root The root element for the overview block
|
||||
*/
|
||||
var registerSelector = function(root) {
|
||||
const Selector = root.find(SELECTORS.FILTERS);
|
||||
|
||||
var Selector = root.find(SELECTORS.FILTERS);
|
||||
CustomEvents.define(Selector, [CustomEvents.events.activate]);
|
||||
Selector.on(
|
||||
CustomEvents.events.activate,
|
||||
SELECTORS.FILTER_OPTION,
|
||||
(e, data) => {
|
||||
const option = $(e.target);
|
||||
|
||||
CustomEvents.define(Selector, [CustomEvents.events.activate]);
|
||||
Selector.on(
|
||||
CustomEvents.events.activate,
|
||||
SELECTORS.FILTER_OPTION,
|
||||
function(e, data) {
|
||||
var option = $(e.target);
|
||||
if (option.hasClass('active')) {
|
||||
// If it's already active then we don't need to do anything.
|
||||
return;
|
||||
}
|
||||
|
||||
if (option.hasClass('active')) {
|
||||
// If it's already active then we don't need to do anything.
|
||||
return;
|
||||
}
|
||||
const filter = option.attr('data-filter');
|
||||
const pref = option.attr('data-pref');
|
||||
const customfieldvalue = option.attr('data-customfieldvalue');
|
||||
|
||||
var filter = option.attr('data-filter');
|
||||
var pref = option.attr('data-pref');
|
||||
var customfieldvalue = option.attr('data-customfieldvalue');
|
||||
root.find(SELECTORS.courseView.region).attr('data-' + filter, option.attr('data-value'));
|
||||
updatePreferences(filter, pref);
|
||||
|
||||
root.find(Selectors.courseView.region).attr('data-' + filter, option.attr('data-value'));
|
||||
updatePreferences(filter, pref);
|
||||
if (customfieldvalue) {
|
||||
root.find(SELECTORS.courseView.region).attr('data-customfieldvalue', customfieldvalue);
|
||||
updatePreferences('customfieldvalue', customfieldvalue);
|
||||
}
|
||||
|
||||
if (customfieldvalue) {
|
||||
root.find(Selectors.courseView.region).attr('data-customfieldvalue', customfieldvalue);
|
||||
updatePreferences('customfieldvalue', customfieldvalue);
|
||||
}
|
||||
// Reset the views.
|
||||
|
||||
// Reset the views.
|
||||
// Check if the user is currently in a searching state, if so we'll reset it.
|
||||
const page = document.querySelector(SELECTORS.region.selectBlock);
|
||||
const input = page.querySelector(SELECTORS.region.searchInput);
|
||||
if (input.value !== '') {
|
||||
const clearIcon = page.querySelector(SELECTORS.region.clearIcon);
|
||||
const searchIcon = page.querySelector(SELECTORS.region.searchIcon);
|
||||
input.value = '';
|
||||
// Triggers the init so wont need to call it again.
|
||||
View.clearSearch(searchIcon, clearIcon, root);
|
||||
} else {
|
||||
View.init(root);
|
||||
|
||||
data.originalEvent.preventDefault();
|
||||
}
|
||||
);
|
||||
|
||||
CustomEvents.define(Selector, [CustomEvents.events.activate]);
|
||||
Selector.on(
|
||||
CustomEvents.events.activate,
|
||||
SELECTORS.DISPLAY_OPTION,
|
||||
function(e, data) {
|
||||
var option = $(e.target);
|
||||
data.originalEvent.preventDefault();
|
||||
}
|
||||
);
|
||||
|
||||
if (option.hasClass('active')) {
|
||||
return;
|
||||
}
|
||||
Selector.on(
|
||||
CustomEvents.events.activate,
|
||||
SELECTORS.DISPLAY_OPTION,
|
||||
(e, data) => {
|
||||
const option = $(e.target);
|
||||
|
||||
var filter = option.attr('data-display-option');
|
||||
var pref = option.attr('data-pref');
|
||||
|
||||
root.find(Selectors.courseView.region).attr('data-display', option.attr('data-value'));
|
||||
updatePreferences(filter, pref);
|
||||
View.reset(root);
|
||||
data.originalEvent.preventDefault();
|
||||
if (option.hasClass('active')) {
|
||||
return;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise the timeline view navigation by adding event listeners to
|
||||
* the navigation elements.
|
||||
*
|
||||
* @param {object} root The root element for the myoverview block
|
||||
*/
|
||||
var init = function(root) {
|
||||
root = $(root);
|
||||
registerSelector(root);
|
||||
};
|
||||
const filter = option.attr('data-display-option');
|
||||
const pref = option.attr('data-pref');
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
});
|
||||
root.find(SELECTORS.courseView.region).attr('data-display', option.attr('data-value'));
|
||||
updatePreferences(filter, pref);
|
||||
View.reset(root);
|
||||
data.originalEvent.preventDefault();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise the timeline view navigation by adding event listeners to
|
||||
* the navigation elements.
|
||||
*
|
||||
* @param {object} root The root element for the myoverview block
|
||||
*/
|
||||
export const init = root => {
|
||||
root = $(root);
|
||||
registerSelector(root);
|
||||
};
|
||||
|
@ -51,6 +51,7 @@ $string['availablegroupings'] = 'Available filters';
|
||||
$string['availablegroupings_desc'] = 'Course filters which are available for selection by users. If none are selected, all courses will be displayed.';
|
||||
$string['card'] = 'Card';
|
||||
$string['cards'] = 'Cards';
|
||||
$string['clearsearch'] = "Clear search";
|
||||
$string['courseprogress'] = 'Course progress:';
|
||||
$string['completepercent'] = '{$a}% complete';
|
||||
$string['customfield'] = 'Custom field';
|
||||
@ -74,6 +75,7 @@ $string['privacy:metadata:overviewviewpreference'] = 'The Course overview block
|
||||
$string['privacy:metadata:overviewgroupingpreference'] = 'The Course overview block grouping preference.';
|
||||
$string['privacy:metadata:overviewpagingpreference'] = 'The Course overview block paging preference.';
|
||||
$string['removefromfavourites'] = 'Unstar this course';
|
||||
$string['searchcourses'] = "Search courses";
|
||||
$string['shortname'] = 'Short name';
|
||||
$string['summary'] = 'Summary';
|
||||
$string['title'] = 'Course name';
|
||||
|
@ -77,4 +77,4 @@
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,14 +25,17 @@
|
||||
|
||||
<div id="block-myoverview-{{uniqid}}" class="block-myoverview block-cards" data-region="myoverview" role="navigation">
|
||||
|
||||
<div data-region="filter" class="d-flex align-items-center flex-wrap" aria-label="{{#str}} aria:controls, block_myoverview {{/str}}">
|
||||
{{> block_myoverview/nav-grouping-selector }}
|
||||
<div data-region="filter" class="d-flex align-items-center flex-wrap" aria-label="{{#str}} aria:controls, block_myoverview {{/str}}">
|
||||
{{> block_myoverview/nav-grouping-selector }}
|
||||
|
||||
{{> block_myoverview/nav-sort-selector }}
|
||||
{{#displaydropdown}}
|
||||
{{> block_myoverview/nav-display-selector }}
|
||||
{{/displaydropdown}}
|
||||
</div>
|
||||
{{> block_myoverview/nav-search-widget }}
|
||||
|
||||
{{> block_myoverview/nav-sort-selector }}
|
||||
|
||||
{{#displaydropdown}}
|
||||
{{> block_myoverview/nav-display-selector }}
|
||||
{{/displaydropdown}}
|
||||
</div>
|
||||
|
||||
<div class="container-fluid p-0">
|
||||
{{> block_myoverview/courses-view }}
|
||||
|
48
blocks/myoverview/templates/nav-search-widget.mustache
Normal file
48
blocks/myoverview/templates/nav-search-widget.mustache
Normal file
@ -0,0 +1,48 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template block_myoverview/nav-search-widget
|
||||
|
||||
This template renders the search input within the filters area.
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
}}
|
||||
<div class="searchbar input-group mb-1 mr-1 p-0 col-lg-3 col-md-6 col-sm-8 col-12" role="search">
|
||||
<label for="searchinput">
|
||||
<span class="sr-only">{{#str}} searchcourses, block_myoverview {{/str}}</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
data-region="search-input"
|
||||
id="searchinput"
|
||||
class="form-control searchinput border-right-0 h-100 px-3 py-2"
|
||||
placeholder="{{#str}} search, core {{/str}}"
|
||||
name="search"
|
||||
autocomplete="off"
|
||||
>
|
||||
<div class="input-group-append">
|
||||
<div data-region="search-icon" class="input-group-text">
|
||||
{{#pix}} a/search, core {{/pix}}
|
||||
</div>
|
||||
<div class="clear input-group-text d-none">
|
||||
<button class="btn p-0" data-region="clear-icon">
|
||||
<span class="d-flex" aria-hidden="true">{{#pix}} e/cancel, core {{/pix}}</span>
|
||||
<span class="sr-only">{{#str}} clearsearch, block_myoverview {{/str}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -37,55 +37,55 @@
|
||||
}}
|
||||
|
||||
<ul class="list-group">
|
||||
{{#courses}}
|
||||
<li class="list-group-item course-listitem"
|
||||
data-region="course-content"
|
||||
data-course-id="{{{id}}}">
|
||||
<div class="row">
|
||||
<div class="{{#hasprogress}}col-md-6{{/hasprogress}}{{^hasprogress}}col-md-11 col-md-11{{/hasprogress}} d-flex align-items-center">
|
||||
<div>
|
||||
<div class="text-muted muted d-flex flex-wrap">
|
||||
{{#showcoursecategory}}
|
||||
<span class="sr-only">
|
||||
{{#str}}aria:coursecategory, core_course{{/str}}
|
||||
</span>
|
||||
<span class="categoryname">
|
||||
{{{coursecategory}}}
|
||||
</span>
|
||||
{{/showcoursecategory}}
|
||||
{{#showshortname}}
|
||||
{{#courses}}
|
||||
<li class="list-group-item course-listitem"
|
||||
data-region="course-content"
|
||||
data-course-id="{{{id}}}">
|
||||
<div class="row">
|
||||
<div class="{{#hasprogress}}col-md-6{{/hasprogress}}{{^hasprogress}}col-md-11 col-md-11{{/hasprogress}} d-flex align-items-center">
|
||||
<div>
|
||||
<div class="text-muted muted d-flex flex-wrap">
|
||||
{{#showcoursecategory}}
|
||||
<div class="pl-1 pr-1">|</div>
|
||||
<span class="sr-only">
|
||||
{{#str}}aria:coursecategory, core_course{{/str}}
|
||||
</span>
|
||||
<span class="categoryname">
|
||||
{{{coursecategory}}}
|
||||
</span>
|
||||
{{/showcoursecategory}}
|
||||
<span class="sr-only">
|
||||
{{#str}}aria:courseshortname, core_course{{/str}}
|
||||
</span>
|
||||
<div>{{{shortname}}}</div>
|
||||
{{/showshortname}}
|
||||
</div>
|
||||
<a href="{{viewurl}}" class="aalink coursename">
|
||||
{{> core_course/favouriteicon }}
|
||||
<span class="sr-only">
|
||||
{{#str}}aria:coursename, core_course{{/str}}
|
||||
</span>
|
||||
{{{fullname}}}
|
||||
</a>
|
||||
{{^visible}}
|
||||
<div class="d-flex flex-wrap">
|
||||
<span class="badge badge-info">{{#str}} hiddenfromstudents {{/str}}</span>
|
||||
{{#showshortname}}
|
||||
{{#showcoursecategory}}
|
||||
<div class="pl-1 pr-1">|</div>
|
||||
{{/showcoursecategory}}
|
||||
<span class="sr-only">
|
||||
{{#str}}aria:courseshortname, core_course{{/str}}
|
||||
</span>
|
||||
<div>{{{shortname}}}</div>
|
||||
{{/showshortname}}
|
||||
</div>
|
||||
{{/visible}}
|
||||
<a href="{{viewurl}}" class="aalink coursename">
|
||||
{{> core_course/favouriteicon }}
|
||||
<span class="sr-only">
|
||||
{{#str}}aria:coursename, core_course{{/str}}
|
||||
</span>
|
||||
{{{fullname}}}
|
||||
</a>
|
||||
{{^visible}}
|
||||
<div class="d-flex flex-wrap">
|
||||
<span class="badge badge-info">{{#str}} hiddenfromstudents {{/str}}</span>
|
||||
</div>
|
||||
{{/visible}}
|
||||
</div>
|
||||
</div>
|
||||
{{#hasprogress}}
|
||||
<div class="col-md-5 pt-1">
|
||||
{{> block_myoverview/progress-bar}}
|
||||
</div>
|
||||
{{/hasprogress}}
|
||||
<div class="col-md-1 p-0 d-flex">
|
||||
{{> block_myoverview/course-action-menu }}
|
||||
</div>
|
||||
</div>
|
||||
{{#hasprogress}}
|
||||
<div class="col-md-5 pt-1">
|
||||
{{> block_myoverview/progress-bar}}
|
||||
</div>
|
||||
{{/hasprogress}}
|
||||
<div class="col-md-1 p-0 d-flex">
|
||||
{{> block_myoverview/course-action-menu }}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{/courses}}
|
||||
</li>
|
||||
{{/courses}}
|
||||
</ul>
|
||||
|
@ -0,0 +1,63 @@
|
||||
@block @block_myoverview @javascript
|
||||
Feature: My overview block searching
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email | idnumber |
|
||||
| student1 | Student | X | student1@example.com | S1 |
|
||||
| student2 | Student | Y | student2@example.com | S2 |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 01 | C1 | 0 |
|
||||
| Course 02 | C2 | 0 |
|
||||
| Course 03 | C3 | 0 |
|
||||
| Course 04 | C4 | 0 |
|
||||
| Course 05 | C5 | 0 |
|
||||
| Course 06 | C6 | 0 |
|
||||
| Course 07 | C7 | 0 |
|
||||
| Course 08 | C8 | 0 |
|
||||
| Course 09 | C9 | 0 |
|
||||
| Course 10 | C10 | 0 |
|
||||
| Course 11 | C11 | 0 |
|
||||
| Course 12 | C12 | 0 |
|
||||
| Course 13 | C13 | 0 |
|
||||
| Fake example | Fake | 0 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C1 | student |
|
||||
| student1 | C2 | student |
|
||||
| student1 | C3 | student |
|
||||
| student1 | C4 | student |
|
||||
| student1 | C5 | student |
|
||||
| student1 | C6 | student |
|
||||
| student1 | C7 | student |
|
||||
| student1 | C8 | student |
|
||||
| student1 | C9 | student |
|
||||
| student1 | C10 | student |
|
||||
| student1 | C11 | student |
|
||||
| student1 | C12 | student |
|
||||
| student1 | C13 | student |
|
||||
|
||||
Scenario: The search should return no courses if I am not enrolled in any
|
||||
When I log in as "student2"
|
||||
Then I should see "No courses" in the "Course overview" "block"
|
||||
And I set the field "Search courses" to "Fake example"
|
||||
And I should see "No courses" in the "Course overview" "block"
|
||||
And I log out
|
||||
|
||||
Scenario: Single page search
|
||||
Given I log in as "student1"
|
||||
And I set the field "Search courses" to "Course 0"
|
||||
Then I should see "Course 01" in the "Course overview" "block"
|
||||
And I should not see "Course 13" in the "Course overview" "block"
|
||||
And I log out
|
||||
|
||||
Scenario: Paginated search
|
||||
Given I log in as "student1"
|
||||
And I set the field "Search courses" to "Course"
|
||||
And I should see "Course 01" in the "Course overview" "block"
|
||||
And I should not see "Course 13" in the "Course overview" "block"
|
||||
And I click on "[data-control='next']" "css_element" in the "Course overview" "block"
|
||||
And I wait until ".block_myoverview [data-control='next']" "css_element" exists
|
||||
Then I should see "Course 13" in the "Course overview" "block"
|
||||
And I should not see "Course 01" in the "Course overview" "block"
|
@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2021052500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2021052503; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2021052500; // Requires this Moodle version.
|
||||
$plugin->component = 'block_myoverview'; // Full name of the plugin (used for diagnostics).
|
||||
|
@ -3755,6 +3755,8 @@ class core_course_external extends external_api {
|
||||
VALUE_DEFAULT, null),
|
||||
'customfieldvalue' => new external_value(PARAM_RAW, 'Used when classification = customfield',
|
||||
VALUE_DEFAULT, null),
|
||||
'searchvalue' => new external_value(PARAM_TEXT, 'The value a user wishes to search against',
|
||||
VALUE_DEFAULT, null),
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -3779,6 +3781,7 @@ class core_course_external extends external_api {
|
||||
* @param string $sort SQL sort string for results
|
||||
* @param string $customfieldname
|
||||
* @param string $customfieldvalue
|
||||
* @param string $searchvalue
|
||||
* @return array list of courses and warnings
|
||||
* @throws invalid_parameter_exception
|
||||
*/
|
||||
@ -3788,7 +3791,8 @@ class core_course_external extends external_api {
|
||||
int $offset = 0,
|
||||
string $sort = null,
|
||||
string $customfieldname = null,
|
||||
string $customfieldvalue = null
|
||||
string $customfieldvalue = null,
|
||||
string $searchvalue = null
|
||||
) {
|
||||
global $CFG, $PAGE, $USER;
|
||||
require_once($CFG->dirroot . '/course/lib.php');
|
||||
@ -3800,6 +3804,7 @@ class core_course_external extends external_api {
|
||||
'offset' => $offset,
|
||||
'sort' => $sort,
|
||||
'customfieldvalue' => $customfieldvalue,
|
||||
'searchvalue' => $searchvalue,
|
||||
)
|
||||
);
|
||||
|
||||
@ -3808,6 +3813,7 @@ class core_course_external extends external_api {
|
||||
$offset = $params['offset'];
|
||||
$sort = $params['sort'];
|
||||
$customfieldvalue = $params['customfieldvalue'];
|
||||
$searchvalue = $params['searchvalue'];
|
||||
|
||||
switch($classification) {
|
||||
case COURSE_TIMELINE_ALLINCLUDINGHIDDEN:
|
||||
@ -3824,6 +3830,8 @@ class core_course_external extends external_api {
|
||||
break;
|
||||
case COURSE_TIMELINE_HIDDEN:
|
||||
break;
|
||||
case COURSE_TIMELINE_SEARCH:
|
||||
break;
|
||||
case COURSE_CUSTOMFIELD:
|
||||
break;
|
||||
default:
|
||||
@ -3847,6 +3855,19 @@ class core_course_external extends external_api {
|
||||
COURSE_DB_QUERY_LIMIT, $hiddencourses);
|
||||
|
||||
// Otherwise get the requested courses and exclude the hidden courses.
|
||||
} else if ($classification == COURSE_TIMELINE_SEARCH) {
|
||||
// Prepare the search API options.
|
||||
$searchcriteria['search'] = $searchvalue;
|
||||
$options = ['idonly' => true];
|
||||
$courses = course_get_enrolled_courses_for_logged_in_user_from_search(
|
||||
0,
|
||||
$offset,
|
||||
$sort,
|
||||
$fields,
|
||||
COURSE_DB_QUERY_LIMIT,
|
||||
$searchcriteria,
|
||||
$options
|
||||
);
|
||||
} else {
|
||||
$courses = course_get_enrolled_courses_for_logged_in_user(0, $offset, $sort, $fields,
|
||||
COURSE_DB_QUERY_LIMIT, [], $hiddencourses);
|
||||
@ -3886,6 +3907,9 @@ class core_course_external extends external_api {
|
||||
|
||||
$renderer = $PAGE->get_renderer('core');
|
||||
$formattedcourses = array_map(function($course) use ($renderer, $favouritecourseids) {
|
||||
if ($course == null) {
|
||||
return;
|
||||
}
|
||||
context_helper::preload_from_record($course);
|
||||
$context = context_course::instance($course->id);
|
||||
$isfavourite = false;
|
||||
@ -3896,6 +3920,12 @@ class core_course_external extends external_api {
|
||||
return $exporter->export($renderer);
|
||||
}, $filteredcourses);
|
||||
|
||||
$formattedcourses = array_filter($formattedcourses, function($course) {
|
||||
if ($course != null) {
|
||||
return $course;
|
||||
}
|
||||
});
|
||||
|
||||
return [
|
||||
'courses' => $formattedcourses,
|
||||
'nextoffset' => $offset + $processedcount
|
||||
|
@ -63,6 +63,7 @@ define('COURSE_TIMELINE_ALL', 'all');
|
||||
define('COURSE_TIMELINE_PAST', 'past');
|
||||
define('COURSE_TIMELINE_INPROGRESS', 'inprogress');
|
||||
define('COURSE_TIMELINE_FUTURE', 'future');
|
||||
define('COURSE_TIMELINE_SEARCH', 'search');
|
||||
define('COURSE_FAVOURITES', 'favourites');
|
||||
define('COURSE_TIMELINE_HIDDEN', 'hidden');
|
||||
define('COURSE_CUSTOMFIELD', 'customfield');
|
||||
@ -4347,6 +4348,58 @@ function course_get_enrolled_courses_for_logged_in_user(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of enrolled courses the current user searched for.
|
||||
*
|
||||
* This function returns a Generator. The courses will be loaded from the database
|
||||
* in chunks rather than a single query.
|
||||
*
|
||||
* @param int $limit Restrict result set to this amount
|
||||
* @param int $offset Skip this number of records from the start of the result set
|
||||
* @param string|null $sort SQL string for sorting
|
||||
* @param string|null $fields SQL string for fields to be returned
|
||||
* @param int $dbquerylimit The number of records to load per DB request
|
||||
* @param array $searchcriteria contains search criteria
|
||||
* @param array $options display options, same as in get_courses() except 'recursive' is ignored -
|
||||
* search is always category-independent
|
||||
* @return Generator
|
||||
*/
|
||||
function course_get_enrolled_courses_for_logged_in_user_from_search(
|
||||
int $limit = 0,
|
||||
int $offset = 0,
|
||||
string $sort = null,
|
||||
string $fields = null,
|
||||
int $dbquerylimit = COURSE_DB_QUERY_LIMIT,
|
||||
array $searchcriteria = [],
|
||||
array $options = []
|
||||
) : Generator {
|
||||
|
||||
$haslimit = !empty($limit);
|
||||
$recordsloaded = 0;
|
||||
$querylimit = (!$haslimit || $limit > $dbquerylimit) ? $dbquerylimit : $limit;
|
||||
$ids = core_course_category::search_courses($searchcriteria, $options);
|
||||
|
||||
// If no courses were found matching the criteria return back.
|
||||
if (empty($ids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
while ($courses = enrol_get_my_courses($fields, $sort, $querylimit, $ids, false, $offset)) {
|
||||
yield from $courses;
|
||||
|
||||
$recordsloaded += $querylimit;
|
||||
|
||||
if (count($courses) < $querylimit) {
|
||||
break;
|
||||
}
|
||||
if ($haslimit && $recordsloaded >= $limit) {
|
||||
break;
|
||||
}
|
||||
|
||||
$offset += $querylimit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the given $courses for any that match the given $classification up to the specified
|
||||
* $limit.
|
||||
@ -4370,9 +4423,9 @@ function course_filter_courses_by_timeline_classification(
|
||||
|
||||
if (!in_array($classification,
|
||||
[COURSE_TIMELINE_ALLINCLUDINGHIDDEN, COURSE_TIMELINE_ALL, COURSE_TIMELINE_PAST, COURSE_TIMELINE_INPROGRESS,
|
||||
COURSE_TIMELINE_FUTURE, COURSE_TIMELINE_HIDDEN])) {
|
||||
COURSE_TIMELINE_FUTURE, COURSE_TIMELINE_HIDDEN, COURSE_TIMELINE_SEARCH])) {
|
||||
$message = 'Classification must be one of COURSE_TIMELINE_ALLINCLUDINGHIDDEN, COURSE_TIMELINE_ALL, COURSE_TIMELINE_PAST, '
|
||||
. 'COURSE_TIMELINE_INPROGRESS or COURSE_TIMELINE_FUTURE';
|
||||
. 'COURSE_TIMELINE_INPROGRESS, COURSE_TIMELINE_SEARCH or COURSE_TIMELINE_FUTURE';
|
||||
throw new moodle_exception($message);
|
||||
}
|
||||
|
||||
@ -4386,6 +4439,7 @@ function course_filter_courses_by_timeline_classification(
|
||||
|
||||
// Added as of MDL-63457 toggle viewability for each user.
|
||||
if ($classification == COURSE_TIMELINE_ALLINCLUDINGHIDDEN || ($classification == COURSE_TIMELINE_HIDDEN && $pref) ||
|
||||
$classification == COURSE_TIMELINE_SEARCH||
|
||||
(($classification == COURSE_TIMELINE_ALL || $classification == course_classify_for_timeline($course)) && !$pref)) {
|
||||
$filteredcourses[] = $course;
|
||||
$filtermatches++;
|
||||
|
@ -4831,6 +4831,104 @@ class core_course_courselib_testcase extends advanced_testcase {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the course_get_enrolled_courses_for_logged_in_user_from_search function.
|
||||
*/
|
||||
public function test_course_get_enrolled_courses_for_logged_in_user_from_search() {
|
||||
global $DB;
|
||||
|
||||
// Set up.
|
||||
|
||||
$this->resetAfterTest();
|
||||
$generator = $this->getDataGenerator();
|
||||
$student = $generator->create_user();
|
||||
|
||||
$cat1 = core_course_category::create(['name' => 'Cat1']);
|
||||
$cat2 = core_course_category::create(['name' => 'Cat2', 'parent' => $cat1->id]);
|
||||
$c1 = $this->getDataGenerator()->create_course(['category' => $cat1->id, 'fullname' => 'Test 3', 'summary' => 'Magic', 'idnumber' => 'ID3']);
|
||||
$c2 = $this->getDataGenerator()->create_course(['category' => $cat1->id, 'fullname' => 'Test 1', 'summary' => 'Magic']);
|
||||
$c3 = $this->getDataGenerator()->create_course(['category' => $cat1->id, 'fullname' => 'Математика', 'summary' => ' Test Magic']);
|
||||
$c4 = $this->getDataGenerator()->create_course(['category' => $cat1->id, 'fullname' => 'Test 4', 'summary' => 'Magic', 'idnumber' => 'ID4']);
|
||||
|
||||
$c5 = $this->getDataGenerator()->create_course(['category' => $cat2->id, 'fullname' => 'Test 5', 'summary' => 'Magic']);
|
||||
$c6 = $this->getDataGenerator()->create_course(['category' => $cat2->id, 'fullname' => 'Дискретная Математика', 'summary' => 'Magic']);
|
||||
$c7 = $this->getDataGenerator()->create_course(['category' => $cat2->id, 'fullname' => 'Test 7', 'summary' => 'Magic']);
|
||||
$c8 = $this->getDataGenerator()->create_course(['category' => $cat2->id, 'fullname' => 'Test 8', 'summary' => 'Magic']);
|
||||
|
||||
for ($i = 1; $i < 9; $i++) {
|
||||
$generator->enrol_user($student->id, ${"c$i"}->id, 'student');
|
||||
}
|
||||
|
||||
$this->setUser($student);
|
||||
|
||||
$returnedcourses = course_get_enrolled_courses_for_logged_in_user_from_search(
|
||||
0,
|
||||
0,
|
||||
'id ASC',
|
||||
null,
|
||||
COURSE_DB_QUERY_LIMIT,
|
||||
['search' => 'test'],
|
||||
['idonly' => true]
|
||||
);
|
||||
|
||||
$actualresult = array_map(function($course) {
|
||||
return $course->id;
|
||||
}, iterator_to_array($returnedcourses, false));
|
||||
|
||||
$this->assertEquals([$c1->id, $c2->id, $c3->id, $c4->id, $c5->id, $c7->id, $c8->id], $actualresult);
|
||||
|
||||
// Test no courses matching the search.
|
||||
$returnedcourses = course_get_enrolled_courses_for_logged_in_user_from_search(
|
||||
0,
|
||||
0,
|
||||
'id ASC',
|
||||
null,
|
||||
COURSE_DB_QUERY_LIMIT,
|
||||
['search' => 'foobar'],
|
||||
['idonly' => true]
|
||||
);
|
||||
|
||||
$actualresult = array_map(function($course) {
|
||||
return $course->id;
|
||||
}, iterator_to_array($returnedcourses, false));
|
||||
|
||||
$this->assertEquals([], $actualresult);
|
||||
|
||||
// Test returning all courses that have a mutual summary.
|
||||
$returnedcourses = course_get_enrolled_courses_for_logged_in_user_from_search(
|
||||
0,
|
||||
0,
|
||||
'id ASC',
|
||||
null,
|
||||
COURSE_DB_QUERY_LIMIT,
|
||||
['search' => 'Magic'],
|
||||
['idonly' => true]
|
||||
);
|
||||
|
||||
$actualresult = array_map(function($course) {
|
||||
return $course->id;
|
||||
}, iterator_to_array($returnedcourses, false));
|
||||
|
||||
$this->assertEquals([$c1->id, $c2->id, $c3->id, $c4->id, $c5->id, $c6->id, $c7->id, $c8->id], $actualresult);
|
||||
|
||||
// Test returning a unique course.
|
||||
$returnedcourses = course_get_enrolled_courses_for_logged_in_user_from_search(
|
||||
0,
|
||||
0,
|
||||
'id ASC',
|
||||
null,
|
||||
COURSE_DB_QUERY_LIMIT,
|
||||
['search' => 'Дискретная'],
|
||||
['idonly' => true]
|
||||
);
|
||||
|
||||
$actualresult = array_map(function($course) {
|
||||
return $course->id;
|
||||
}, iterator_to_array($returnedcourses, false));
|
||||
|
||||
$this->assertEquals([$c6->id], $actualresult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the course_filter_courses_by_timeline_classification function.
|
||||
*
|
||||
|
@ -37,7 +37,8 @@ require_once($CFG->dirroot . '/webservice/tests/helpers.php');
|
||||
* @copyright 2012 Jerome Mouneyrac
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
class externallib_test extends externallib_advanced_testcase {
|
||||
//core_course_externallib_testcase
|
||||
|
||||
/**
|
||||
* Tests set up
|
||||
@ -3068,7 +3069,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'offset' => 0,
|
||||
'sort' => 'shortname ASC',
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0
|
||||
'expectednextoffset' => 0,
|
||||
],
|
||||
// COURSE_TIMELINE_FUTURE.
|
||||
'future not limit no offset' => [
|
||||
@ -3078,7 +3079,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'offset' => 0,
|
||||
'sort' => 'shortname ASC',
|
||||
'expectedcourses' => ['afuture', 'bfuture', 'cfuture', 'dfuture', 'efuture'],
|
||||
'expectednextoffset' => 15
|
||||
'expectednextoffset' => 15,
|
||||
],
|
||||
'future no offset' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3087,7 +3088,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'offset' => 0,
|
||||
'sort' => 'shortname ASC',
|
||||
'expectedcourses' => ['afuture', 'bfuture'],
|
||||
'expectednextoffset' => 4
|
||||
'expectednextoffset' => 4,
|
||||
],
|
||||
'future offset' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3096,7 +3097,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'offset' => 2,
|
||||
'sort' => 'shortname ASC',
|
||||
'expectedcourses' => ['bfuture', 'cfuture'],
|
||||
'expectednextoffset' => 7
|
||||
'expectednextoffset' => 7,
|
||||
],
|
||||
'future exact limit' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3105,7 +3106,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'offset' => 0,
|
||||
'sort' => 'shortname ASC',
|
||||
'expectedcourses' => ['afuture', 'bfuture', 'cfuture', 'dfuture', 'efuture'],
|
||||
'expectednextoffset' => 13
|
||||
'expectednextoffset' => 13,
|
||||
],
|
||||
'future limit less results' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3114,7 +3115,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'offset' => 0,
|
||||
'sort' => 'shortname ASC',
|
||||
'expectedcourses' => ['afuture', 'bfuture', 'cfuture', 'dfuture', 'efuture'],
|
||||
'expectednextoffset' => 15
|
||||
'expectednextoffset' => 15,
|
||||
],
|
||||
'future limit less results with offset' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3123,7 +3124,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'offset' => 5,
|
||||
'sort' => 'shortname ASC',
|
||||
'expectedcourses' => ['cfuture', 'dfuture', 'efuture'],
|
||||
'expectednextoffset' => 15
|
||||
'expectednextoffset' => 15,
|
||||
],
|
||||
'all no limit or offset' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3148,7 +3149,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'einprogress',
|
||||
'epast'
|
||||
],
|
||||
'expectednextoffset' => 15
|
||||
'expectednextoffset' => 15,
|
||||
],
|
||||
'all limit no offset' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3163,7 +3164,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'bfuture',
|
||||
'binprogress'
|
||||
],
|
||||
'expectednextoffset' => 5
|
||||
'expectednextoffset' => 5,
|
||||
],
|
||||
'all limit and offset' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3178,7 +3179,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'cpast',
|
||||
'dfuture'
|
||||
],
|
||||
'expectednextoffset' => 10
|
||||
'expectednextoffset' => 10,
|
||||
],
|
||||
'all offset past result set' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3187,7 +3188,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'offset' => 50,
|
||||
'sort' => 'shortname ASC',
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 50
|
||||
'expectednextoffset' => 50,
|
||||
],
|
||||
'all limit and offset with sort ul.timeaccess desc' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3202,7 +3203,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'dinprogress',
|
||||
'einprogress'
|
||||
],
|
||||
'expectednextoffset' => 15
|
||||
'expectednextoffset' => 15,
|
||||
],
|
||||
'all limit and offset with sort sql injection for sort or 1==1' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3212,7 +3213,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => 'ul.timeaccess desc or 1==1',
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with sql injection of sort a custom one' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3222,7 +3223,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => "ul.timeaccess LIMIT 1--",
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong sort direction' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3232,7 +3233,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => "ul.timeaccess abcdasc",
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid sort direction in $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid sort direction in $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong sort direction' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3242,7 +3243,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => "ul.timeaccess.foo ascd",
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid sort direction in $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid sort direction in $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong sort param' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3252,7 +3253,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => "foobar",
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong field name' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3262,7 +3263,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => "ul.foobar",
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong field separator' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3272,7 +3273,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => "ul.timeaccess.foo",
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong field separator #' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3282,7 +3283,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => "ul#timeaccess",
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong field separator $' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3292,7 +3293,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => 'ul$timeaccess',
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with wrong field name' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3302,7 +3303,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'sort' => 'timeaccess123',
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()'
|
||||
'expectedexception' => 'Invalid $sort parameter in enrol_get_my_courses()',
|
||||
],
|
||||
'all limit and offset with no sort direction for ul' => [
|
||||
'coursedata' => $coursedata,
|
||||
@ -3340,6 +3341,50 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
'expectedcourses' => ['bpast', 'cpast', 'dfuture', 'dpast', 'efuture'],
|
||||
'expectednextoffset' => 10,
|
||||
],
|
||||
'Search courses for courses containing bfut' => [
|
||||
'coursedata' => $coursedata,
|
||||
'classification' => 'search',
|
||||
'limit' => 0,
|
||||
'offset' => 0,
|
||||
'sort' => null,
|
||||
'expectedcourses' => ['bfuture'],
|
||||
'expectednextoffset' => 1,
|
||||
'expectedexception' => null,
|
||||
'searchvalue' => 'bfut',
|
||||
],
|
||||
'Search courses for courses containing inp' => [
|
||||
'coursedata' => $coursedata,
|
||||
'classification' => 'search',
|
||||
'limit' => 0,
|
||||
'offset' => 0,
|
||||
'sort' => null,
|
||||
'expectedcourses' => ['ainprogress', 'binprogress', 'cinprogress', 'dinprogress', 'einprogress'],
|
||||
'expectednextoffset' => 5,
|
||||
'expectedexception' => null,
|
||||
'searchvalue' => 'inp',
|
||||
],
|
||||
'Search courses for courses containing fail' => [
|
||||
'coursedata' => $coursedata,
|
||||
'classification' => 'search',
|
||||
'limit' => 0,
|
||||
'offset' => 0,
|
||||
'sort' => null,
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => null,
|
||||
'searchvalue' => 'fail',
|
||||
],
|
||||
'Search courses for courses containing !`~[]C' => [
|
||||
'coursedata' => $coursedata,
|
||||
'classification' => 'search',
|
||||
'limit' => 0,
|
||||
'offset' => 0,
|
||||
'sort' => null,
|
||||
'expectedcourses' => [],
|
||||
'expectednextoffset' => 0,
|
||||
'expectedexception' => null,
|
||||
'searchvalue' => '!`~[]C',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -3355,6 +3400,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
* @param array $expectedcourses Expected courses in result
|
||||
* @param int $expectednextoffset Expected next offset value in result
|
||||
* @param string|null $expectedexception Expected exception string
|
||||
* @param string|null $searchvalue If we are searching, what do we need to look for?
|
||||
*/
|
||||
public function test_get_enrolled_courses_by_timeline_classification(
|
||||
$coursedata,
|
||||
@ -3364,7 +3410,8 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
$sort,
|
||||
$expectedcourses,
|
||||
$expectednextoffset,
|
||||
$expectedexception = null
|
||||
$expectedexception = null,
|
||||
$searchvalue = null
|
||||
) {
|
||||
$this->resetAfterTest();
|
||||
$generator = $this->getDataGenerator();
|
||||
@ -3394,7 +3441,10 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
$classification,
|
||||
$limit,
|
||||
$offset,
|
||||
$sort
|
||||
$sort,
|
||||
null,
|
||||
null,
|
||||
$searchvalue
|
||||
);
|
||||
$result = external_api::clean_returnvalue(
|
||||
core_course_external::get_enrolled_courses_by_timeline_classification_returns(),
|
||||
|
@ -54,6 +54,8 @@ course formats don't have their own renderer.
|
||||
available inside event observers via `$event->get_record_snapshot`
|
||||
* New include_course_editor() function to include and configure course editor modules.
|
||||
* New core_course_drawer() function to render the message drawer in the top of the body of each page.
|
||||
* New course_get_enrolled_courses_for_logged_in_user_from_search which hooks in with external\get_enrolled_courses_by_timeline_classification
|
||||
given COURSE_TIMELINE_SEARCH is set then get_enrolled_courses_by_timeline_classification will deviate to use a string search of enrolled courses.
|
||||
|
||||
=== 3.11 ===
|
||||
* A new callback xxx_coursemodule_definition_after_data that allows plugins to extend activity forms after the data is set.
|
||||
|
Loading…
x
Reference in New Issue
Block a user