From e1a35e19d32b71af088aac2ab78eb8a31f84be68 Mon Sep 17 00:00:00 2001 From: lameze Date: Tue, 16 Oct 2018 08:23:26 +0200 Subject: [PATCH 01/13] MDL-63064 block_starredcourses: create block structure --- .../starredcourses/block_starredcourses.php | 71 +++++++++++++++++++ blocks/starredcourses/db/access.php | 48 +++++++++++++ .../lang/en/block_starredcourses.php | 27 +++++++ blocks/starredcourses/version.php | 28 ++++++++ 4 files changed, 174 insertions(+) create mode 100644 blocks/starredcourses/block_starredcourses.php create mode 100644 blocks/starredcourses/db/access.php create mode 100644 blocks/starredcourses/lang/en/block_starredcourses.php create mode 100644 blocks/starredcourses/version.php diff --git a/blocks/starredcourses/block_starredcourses.php b/blocks/starredcourses/block_starredcourses.php new file mode 100644 index 00000000000..45c0b8f6d0b --- /dev/null +++ b/blocks/starredcourses/block_starredcourses.php @@ -0,0 +1,71 @@ +. + +/** + * Starred courses block. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Starred courses block definition class. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class block_starredcourses extends block_base { + + /** + * Initialises the block. + * + * @return void + */ + public function init() { + $this->title = get_string('pluginname', 'block_starredcourses'); + } + + /** + * Gets the block contents. + * + * @return string The block HTML. + */ + public function get_content() { + + if ($this->content !== null) { + return $this->content; + } + + $this->content = new stdClass(); + $this->content->footer = ''; + $this->content->text = ''; + + return $this->content; + } + + /** + * Locations where block can be displayed. + * + * @return array + */ + public function applicable_formats() { + return array('my' => true); + } +} diff --git a/blocks/starredcourses/db/access.php b/blocks/starredcourses/db/access.php new file mode 100644 index 00000000000..2f5e3653ce2 --- /dev/null +++ b/blocks/starredcourses/db/access.php @@ -0,0 +1,48 @@ +. + +/** + * Starred courses block capabilities. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$capabilities = array( + + 'block/starredcourses:myaddinstance' => array( + 'captype' => 'write', + 'contextlevel' => CONTEXT_SYSTEM, + 'archetypes' => array( + 'user' => CAP_ALLOW + ), + + 'clonepermissionsfrom' => 'moodle/my:manageblocks' + ), + + 'block/starredcourses:addinstance' => array( + 'captype' => 'write', + 'contextlevel' => CONTEXT_BLOCK, + 'archetypes' => array( + 'manager' => CAP_ALLOW + ), + + 'clonepermissionsfrom' => 'moodle/site:manageblocks' + ), +); diff --git a/blocks/starredcourses/lang/en/block_starredcourses.php b/blocks/starredcourses/lang/en/block_starredcourses.php new file mode 100644 index 00000000000..1e7bd6d7540 --- /dev/null +++ b/blocks/starredcourses/lang/en/block_starredcourses.php @@ -0,0 +1,27 @@ +. + +/** + * Starred courses block language strings. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['starredcourses:addinstance'] = 'Add a new instance of starred courses block'; +$string['starredcourses:myaddinstance'] = 'Add a new instance of starred block to Dashboard'; +$string['pluginname'] = 'Starred courses'; diff --git a/blocks/starredcourses/version.php b/blocks/starredcourses/version.php new file mode 100644 index 00000000000..81cb2351faa --- /dev/null +++ b/blocks/starredcourses/version.php @@ -0,0 +1,28 @@ +. + +/** + * Starred courses block version details. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +defined('MOODLE_INTERNAL') || die; + +$plugin->version = 2018051400; +$plugin->requires = 2018050800; +$plugin->component = 'block_starredcourses'; \ No newline at end of file From 0e033f6ee16480d83e686be6f942370891430eb4 Mon Sep 17 00:00:00 2001 From: lameze Date: Tue, 16 Oct 2018 09:08:43 +0200 Subject: [PATCH 02/13] MDL-63064 block_starredcourses: block functionality --- blocks/starredcourses/amd/build/main.min.js | 1 + .../amd/build/repository.min.js | 1 + blocks/starredcourses/amd/src/main.js | 111 ++++++++++++++++ blocks/starredcourses/amd/src/repository.js | 52 ++++++++ .../starredcourses/block_starredcourses.php | 10 +- blocks/starredcourses/classes/external.php | 125 ++++++++++++++++++ blocks/starredcourses/classes/output/main.php | 59 +++++++++ .../classes/output/renderer.php | 48 +++++++ blocks/starredcourses/db/services.php | 38 ++++++ .../lang/en/block_starredcourses.php | 4 +- blocks/starredcourses/pix/courses.svg | 49 +++++++ .../starredcourses/templates/courses.mustache | 55 ++++++++ blocks/starredcourses/templates/main.mustache | 35 +++++ .../templates/no-courses.mustache | 28 ++++ .../templates/placeholder-course.mustache | 26 ++++ .../templates/view-cards.mustache | 45 +++++++ blocks/starredcourses/templates/view.mustache | 39 ++++++ blocks/starredcourses/version.php | 2 +- theme/boost/scss/moodle/blocks.scss | 61 +++++++++ theme/boost/style/moodle.css | 50 +++++++ 20 files changed, 834 insertions(+), 5 deletions(-) create mode 100644 blocks/starredcourses/amd/build/main.min.js create mode 100644 blocks/starredcourses/amd/build/repository.min.js create mode 100644 blocks/starredcourses/amd/src/main.js create mode 100644 blocks/starredcourses/amd/src/repository.js create mode 100644 blocks/starredcourses/classes/external.php create mode 100644 blocks/starredcourses/classes/output/main.php create mode 100644 blocks/starredcourses/classes/output/renderer.php create mode 100644 blocks/starredcourses/db/services.php create mode 100644 blocks/starredcourses/pix/courses.svg create mode 100644 blocks/starredcourses/templates/courses.mustache create mode 100644 blocks/starredcourses/templates/main.mustache create mode 100644 blocks/starredcourses/templates/no-courses.mustache create mode 100644 blocks/starredcourses/templates/placeholder-course.mustache create mode 100644 blocks/starredcourses/templates/view-cards.mustache create mode 100644 blocks/starredcourses/templates/view.mustache diff --git a/blocks/starredcourses/amd/build/main.min.js b/blocks/starredcourses/amd/build/main.min.js new file mode 100644 index 00000000000..ca3581539ae --- /dev/null +++ b/blocks/starredcourses/amd/build/main.min.js @@ -0,0 +1 @@ +define(["jquery","core/notification","block_starredcourses/repository","core/paged_content_factory","core/templates"],function(a,b,c,d,e){var f={STARRED_COURSES_REGION:'[data-region="starred-courses-view-content"]'},g=5,h=function(a,b){if(b.length>0)return e.render("block_starredcourses/view-cards",{courses:b});var c=a.attr("data-nocoursesimg");return e.render("block_starredcourses/no-courses",{nocoursesimg:c})},i=function(b,i){i=a(i);var j=a(f.STARRED_COURSES_REGION);d.createWithLimit(g,function(a,d){var e=[];return a.forEach(function(a){var f={limit:g,offset:a.offset,userid:b},j=c.getStarredCourses(f).then(function(b){return b.length>0?h(i,b):(d.allItemsLoaded(a.pageNumber),h(i,b))});e.push(j)}),e}).then(function(a,b){e.replaceNodeContents(j,a,b)})};return{init:i}}); \ No newline at end of file diff --git a/blocks/starredcourses/amd/build/repository.min.js b/blocks/starredcourses/amd/build/repository.min.js new file mode 100644 index 00000000000..7c886009989 --- /dev/null +++ b/blocks/starredcourses/amd/build/repository.min.js @@ -0,0 +1 @@ +define(["jquery","core/ajax","core/notification"],function(a,b,c){var d=function(a){var d={methodname:"block_starredcourses_get_starred_courses",args:a},e=b.call([d])[0];return e.fail(c.exception),e};return{getStarredCourses:d}}); \ No newline at end of file diff --git a/blocks/starredcourses/amd/src/main.js b/blocks/starredcourses/amd/src/main.js new file mode 100644 index 00000000000..a1a68b0ab68 --- /dev/null +++ b/blocks/starredcourses/amd/src/main.js @@ -0,0 +1,111 @@ +// 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 . + +/** + * Javascript to initialise the starred courses block. + * + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +define( +[ + 'jquery', + 'core/notification', + 'block_starredcourses/repository', + 'core/paged_content_factory', + 'core/templates' +], +function( + $, + Notification, + Repository, + PagedContentFactory, + Templates +) { + + var SELECTORS = { + STARRED_COURSES_REGION: '[data-region="starred-courses-view-content"]' + }; + + var NUM_COURSES_TOTAL = 5; + + /** + * Render the starred courses. + * + * @method renderCourses + * @param {object} root The root element for the starred view. + * @param {array} courses containing array of returned courses. + * @return {promise} Resolved with HTML and JS strings + */ + var renderCourses = function(root, courses) { + if (courses.length > 0) { + return Templates.render('block_starredcourses/view-cards', { + courses: courses + }); + } else { + var nocoursesimg = root.attr('data-nocoursesimg'); + return Templates.render('block_starredcourses/no-courses', { + nocoursesimg: nocoursesimg + }); + } + }; + + /** + * Initialise all of the modules for the starred courses block. + * + * @param {object} root The root element for the block. + * @param {Number} userid The user id. + */ + var init = function(userid, root) { + root = $(root); + var content = $(SELECTORS.STARRED_COURSES_REGION); + + PagedContentFactory.createWithLimit( + NUM_COURSES_TOTAL, + function(pagesData, actions) { + var promises = []; + + pagesData.forEach(function(pageData) { + var args = { + limit: NUM_COURSES_TOTAL, + offset: pageData.offset, + userid: userid + }; + + // Load the page data. + var pagePromise = Repository.getStarredCourses(args).then(function (courses) { + if (courses.length > 0) { + return renderCourses(root, courses); + } else { + actions.allItemsLoaded(pageData.pageNumber); + return renderCourses(root, courses); + } + + }); + + promises.push(pagePromise); + }); + + return promises; + }).then(function (html, js) { + Templates.replaceNodeContents(content, html, js); + }); + }; + + return { + init: init + }; +}); diff --git a/blocks/starredcourses/amd/src/repository.js b/blocks/starredcourses/amd/src/repository.js new file mode 100644 index 00000000000..778516cc81f --- /dev/null +++ b/blocks/starredcourses/amd/src/repository.js @@ -0,0 +1,52 @@ +// 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 . + +/** + * A javascript module to retrieve user's starred courses. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notification) { + + /** + * Retrieve a list of starred courses. + * + * Valid args are: + * int limit number of records to retrieve + * + * @method getStarredCourses + * @param {object} args The request arguments + * @return {promise} Resolved with an array of courses + */ + var getStarredCourses = function(args) { + + var request = { + methodname: 'block_starredcourses_get_starred_courses', + args: args + }; + + var promise = Ajax.call([request])[0]; + + promise.fail(Notification.exception); + + return promise; + }; + + return { + getStarredCourses: getStarredCourses + }; +}); \ No newline at end of file diff --git a/blocks/starredcourses/block_starredcourses.php b/blocks/starredcourses/block_starredcourses.php index 45c0b8f6d0b..2da98ce2ebd 100644 --- a/blocks/starredcourses/block_starredcourses.php +++ b/blocks/starredcourses/block_starredcourses.php @@ -53,9 +53,13 @@ class block_starredcourses extends block_base { return $this->content; } - $this->content = new stdClass(); - $this->content->footer = ''; - $this->content->text = ''; + $renderable = new \block_starredcourses\output\main(); + $renderer = $this->page->get_renderer('block_starredcourses'); + + $this->content = (object) [ + 'text' => $renderer->render($renderable), + 'footer' => '' + ]; return $this->content; } diff --git a/blocks/starredcourses/classes/external.php b/blocks/starredcourses/classes/external.php new file mode 100644 index 00000000000..baae1d1f8db --- /dev/null +++ b/blocks/starredcourses/classes/external.php @@ -0,0 +1,125 @@ +. +/** + * Starred courses block external API + * + * @package block_starredcourses + * @category external + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +defined('MOODLE_INTERNAL') || die; + +require_once($CFG->libdir . '/externallib.php'); + +require_once($CFG->dirroot . '/course/lib.php'); +require_once($CFG->dirroot . '/course/externallib.php'); + +use \core_course\external\course_summary_exporter; + +/** + * Starred courses block external functions. + * + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class block_starredcourses_external extends core_course_external { + + /** + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 3.6 + */ + public static function get_starred_courses_parameters() { + return new external_function_parameters([ + 'limit' => new external_value(PARAM_INT, 'Limit', VALUE_DEFAULT, 0), + 'offset' => new external_value(PARAM_INT, 'Offset', VALUE_DEFAULT, 0), + 'userid' => new external_value(PARAM_INT, 'id of user, empty for current user', VALUE_DEFAULT, 0) + ]); + } + + /** + * Get users starred courses appending additional course information like images. + * + * @param int $limit Limit + * @param int $offset Offset + * @param int|null $userid The user's userid to fetch the favourite courses. + * @return array list of courses and warnings + */ + public static function get_starred_courses($limit, $offset, $userid = null) { + global $USER, $PAGE; + + if (!$userid) { + $userid = $USER->id; + } + + $params = self::validate_parameters(self::get_starred_courses_parameters(), [ + 'limit' => $limit, + 'offset' => $offset, + 'userid' => $userid + ]); + + $userid = $params['userid']; + $limit = $params['limit']; + $offset = $params['offset']; + + $usercontext = context_user::instance($userid); + + self::validate_context($usercontext); + $PAGE->set_context($usercontext); + $output = $PAGE->get_renderer('block_starredcourses'); + + // Get the user favourites service, scoped to a single user (their favourites only). + $userservice = \core_favourites\service_factory::get_service_for_user_context($usercontext); + + // Get the favourites, by type, for the user. + $favourites = $userservice->find_favourites_by_type('core_course', 'courses', $offset, $limit); + + $results = []; + foreach ($favourites as $favourite) { + $courseid = $favourite->itemid; + if (!isset($results[$courseid])) { + $exporter = new course_summary_exporter(get_course($courseid), + ['context' => \context_course::instance($courseid)]); + $courseinlist = new \core_course_list_element(get_course($courseid)); + foreach ($courseinlist->get_course_overviewfiles() as $file) { + if ($file->is_valid_image()) { + $url = new moodle_url("/pluginfile.php".'/'.$file->get_contextid(). '/'. $file->get_component(). '/'. + $file->get_filearea(). $file->get_filepath(). $file->get_filename()); + $courseimage = $url->__toString(); + } + } + $results[$courseid] = $exporter->export($output); + if (!empty($courseimage)) { + $results[$courseid]['courseimage'] = $courseimage; + } + } + } + + return $results; + } + + /** + * Returns description of method result value + * + * @return external_description + * @since Moodle 3.6 + */ + public static function get_starred_courses_returns() { + return new external_multiple_structure(course_summary_exporter::get_read_structure()); + } +} diff --git a/blocks/starredcourses/classes/output/main.php b/blocks/starredcourses/classes/output/main.php new file mode 100644 index 00000000000..6b7d4272e10 --- /dev/null +++ b/blocks/starredcourses/classes/output/main.php @@ -0,0 +1,59 @@ +. + +/** + * Class containing data for starred courses block. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace block_starredcourses\output; +defined('MOODLE_INTERNAL') || die(); + +use renderable; +use renderer_base; +use templatable; +use core_course\external\course_summary_exporter; + +require_once($CFG->dirroot . '/course/lib.php'); +require_once($CFG->libdir . '/completionlib.php'); + +/** + * Class containing data for starred courses block. + * + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class main implements renderable, templatable { + + /** + * Export this data so it can be used as the context for a mustache template. + * + * @param \renderer_base $output + * @return array + */ + public function export_for_template(renderer_base $output) { + global $USER; + + $nocoursesurl = $output->image_url('courses', 'block_starredcourses')->out(); + + return [ + 'userid' => $USER->id, + 'nocoursesimg' => $nocoursesurl + ]; + } +} diff --git a/blocks/starredcourses/classes/output/renderer.php b/blocks/starredcourses/classes/output/renderer.php new file mode 100644 index 00000000000..9fc1a272854 --- /dev/null +++ b/blocks/starredcourses/classes/output/renderer.php @@ -0,0 +1,48 @@ +. + +/** + * Starred courses block renderer. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace block_starredcourses\output; +defined('MOODLE_INTERNAL') || die; + +use plugin_renderer_base; + +/** + * Starred courses block renderer. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class renderer extends plugin_renderer_base { + + /** + * Return the main content for the block. + * + * @param main $main The main renderable + * @return string HTML string + */ + public function render_main(main $main) { + return $this->render_from_template('block_starredcourses/main', + $main->export_for_template($this)); + } +} diff --git a/blocks/starredcourses/db/services.php b/blocks/starredcourses/db/services.php new file mode 100644 index 00000000000..fc3ebb9ab05 --- /dev/null +++ b/blocks/starredcourses/db/services.php @@ -0,0 +1,38 @@ +. + +/** + * File description. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$functions = array( + + 'block_starredcourses_get_starred_courses' => array( + 'classpath' => 'block/starredcourses/classes/external.php', + 'classname' => 'block_starredcourses_external', + 'methodname' => 'get_starred_courses', + 'description' => 'Get users starred courses.', + 'type' => 'read', + 'ajax' => true, + ), +); + diff --git a/blocks/starredcourses/lang/en/block_starredcourses.php b/blocks/starredcourses/lang/en/block_starredcourses.php index 1e7bd6d7540..38cc042ded7 100644 --- a/blocks/starredcourses/lang/en/block_starredcourses.php +++ b/blocks/starredcourses/lang/en/block_starredcourses.php @@ -22,6 +22,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +$string['nocourses'] = 'No starred courses'; +$string['pluginname'] = 'Starred courses'; $string['starredcourses:addinstance'] = 'Add a new instance of starred courses block'; $string['starredcourses:myaddinstance'] = 'Add a new instance of starred block to Dashboard'; -$string['pluginname'] = 'Starred courses'; + diff --git a/blocks/starredcourses/pix/courses.svg b/blocks/starredcourses/pix/courses.svg new file mode 100644 index 00000000000..edc3e6d12e0 --- /dev/null +++ b/blocks/starredcourses/pix/courses.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blocks/starredcourses/templates/courses.mustache b/blocks/starredcourses/templates/courses.mustache new file mode 100644 index 00000000000..88a5a5c8c01 --- /dev/null +++ b/blocks/starredcourses/templates/courses.mustache @@ -0,0 +1,55 @@ +{{! + 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 Licensebllsdsadfasfd + along with Moodle. If not, see . +}} +{{! + @template block_recentcourses/view-cards + + This template renders the carousel for the recentcourses block. + + Example context (json): + { + "courses": [ + { + "name": "Assignment due 1", + "viewurl": "https://moodlesite/course/view.php?id=2", + "courseimage": "https://moodlesite/pluginfile/123/course/overviewfiles/123.jpg", + "fullname": "course 3" + } + ] + } +}} +
+ {{#courses}} + + {{/courses}} +
diff --git a/blocks/starredcourses/templates/main.mustache b/blocks/starredcourses/templates/main.mustache new file mode 100644 index 00000000000..fab929f4ed1 --- /dev/null +++ b/blocks/starredcourses/templates/main.mustache @@ -0,0 +1,35 @@ +{{! + 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 . +}} +{{! + @template block_starredcourses/main + + This template renders the main content area for the starred courses block. + + Example context (json): + {} +}} + +
+
+ {{> block_starredcourses/view }} +
+
+{{#js}} +require(['block_starredcourses/main'], function(Main) { + Main.init('#block-starredcourses-{{uniqid}}'); +}); +{{/js}} diff --git a/blocks/starredcourses/templates/no-courses.mustache b/blocks/starredcourses/templates/no-courses.mustache new file mode 100644 index 00000000000..1b749648f8d --- /dev/null +++ b/blocks/starredcourses/templates/no-courses.mustache @@ -0,0 +1,28 @@ +{{! + 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 . +}} +{{! + @template block_starredcourses/no-courses + This template renders the no courses message. + Example context (json): + { + "nocoursesimg": "https://moodlesite/theme/image.php/boost/block_recentcourses/1535727318/courses" + } +}} +
+ {{#str}} nocourses, block_starredcourses {{/str}} +

{{#str}} nocourses, block_starredcourses {{/str}}

+
diff --git a/blocks/starredcourses/templates/placeholder-course.mustache b/blocks/starredcourses/templates/placeholder-course.mustache new file mode 100644 index 00000000000..f9c3198e8da --- /dev/null +++ b/blocks/starredcourses/templates/placeholder-course.mustache @@ -0,0 +1,26 @@ +{{! + 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 . +}} +{{! + @template block_starredcourses/placeholder-course + This template renders an course card item loading placeholder for the starred courses block. + Example context (json): + {} +}} +
+
+
+
+
+
+
diff --git a/blocks/starredcourses/templates/view-cards.mustache b/blocks/starredcourses/templates/view-cards.mustache new file mode 100644 index 00000000000..7919c7f1bc6 --- /dev/null +++ b/blocks/starredcourses/templates/view-cards.mustache @@ -0,0 +1,45 @@ +{{! + 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 Licensebllsdsadfasfd + along with Moodle. If not, see . +}} +{{! + @template block_starredcourses/view-cards + This template renders the carousel for the starredcourses block. + Example context (json): + { + "courses": [ + { + "name": "Assignment due 1", + "viewurl": "https://moodlesite/course/view.php?id=2", + "courseimage": "https://moodlesite/pluginfile/123/course/overviewfiles/123.jpg", + "fullname": "course 3" + } + ] + } +}} +
+ {{#courses}} + +
+
+
+
+
+
+ {{{fullname}}} +
+
+
+
+
+ {{/courses}} +
diff --git a/blocks/starredcourses/templates/view.mustache b/blocks/starredcourses/templates/view.mustache new file mode 100644 index 00000000000..372760ad3c8 --- /dev/null +++ b/blocks/starredcourses/templates/view.mustache @@ -0,0 +1,39 @@ +{{! + 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 . +}} +{{! + @template block_starredcourses/view + + This template renders the view for the starred courses block. + + Example context (json): + { + "nocoursesimg": "https://moodlesite/theme/image.php/boost/block_starredcourses/1535727318/courses" + } +}} +
+
+
+
+ {{> block_starredcourses/placeholder-course }} + {{> block_starredcourses/placeholder-course }} + {{> block_starredcourses/placeholder-course }} +
+
+
+
diff --git a/blocks/starredcourses/version.php b/blocks/starredcourses/version.php index 81cb2351faa..6514e19378d 100644 --- a/blocks/starredcourses/version.php +++ b/blocks/starredcourses/version.php @@ -23,6 +23,6 @@ */ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2018051400; +$plugin->version = 2018051402; $plugin->requires = 2018050800; $plugin->component = 'block_starredcourses'; \ No newline at end of file diff --git a/theme/boost/scss/moodle/blocks.scss b/theme/boost/scss/moodle/blocks.scss index c4cc09b048a..67a9d185afc 100644 --- a/theme/boost/scss/moodle/blocks.scss +++ b/theme/boost/scss/moodle/blocks.scss @@ -237,3 +237,64 @@ body.drawer-open-left #region-main.has-blocks { margin-right: 2px; } } +$card-gutter : $card-deck-margin * 2; +.block_starredcourses { + [data-region="starredcoursess-view-content"] { + overflow-x: hidden; + } + .card-deck { + flex-wrap: nowrap; + } + .starredcoursessimg { + height: 7rem; + background-position: center; + background-size: cover; + } + .starredcourses-info-container { + padding: 0.8rem; + .card-title { + max-width: 100%; + a { + max-width: 100%; + } + } + } + .empty-placeholder-image-lg { + height: 125px; + } +} + +$card-gutter : $card-deck-margin * 2; +.block_starredcourses { + [data-region="starred-courses-view-content"] { + overflow-x: hidden; + } + .starred-course-card { + flex-basis: auto; + height: 150px; + width: 200px; + flex-shrink: 0; + } + .course-card-container { + height: 150px; + overflow: hidden; + flex-wrap: wrap; + } + .starred-course-img { + height: 7rem; + background-position: center; + background-size: cover; + } + .starred-course-info-container { + padding: 0.8rem; + .card-title { + max-width: 100%; + a { + max-width: 100%; + } + } + } + .empty-placeholder-image-lg { + height: 125px; + } +} \ No newline at end of file diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index a0e4db7f006..49534fc14fc 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -11251,6 +11251,56 @@ div.editor_atto_toolbar button .icon { .block_settings .block_tree p.hasicon .icon { margin-right: 2px; } +.block_starredcourses [data-region="starredcoursess-view-content"] { + overflow-x: hidden; } + +.block_starredcourses .card-deck { + flex-wrap: nowrap; } + +.block_starredcourses .starredcoursessimg { + height: 7rem; + background-position: center; + background-size: cover; } + +.block_starredcourses .starredcourses-info-container { + padding: 0.8rem; } + .block_starredcourses .starredcourses-info-container .card-title { + max-width: 100%; } + .block_starredcourses .starredcourses-info-container .card-title a { + max-width: 100%; } + +.block_starredcourses .empty-placeholder-image-lg { + height: 125px; } + +.block_starredcourses [data-region="starred-courses-view-content"] { + overflow-x: hidden; } + +.block_starredcourses .starred-course-card { + flex-basis: auto; + height: 150px; + width: 200px; + flex-shrink: 0; } + +.block_starredcourses .course-card-container { + height: 150px; + overflow: hidden; + flex-wrap: wrap; } + +.block_starredcourses .starred-course-img { + height: 7rem; + background-position: center; + background-size: cover; } + +.block_starredcourses .starred-course-info-container { + padding: 0.8rem; } + .block_starredcourses .starred-course-info-container .card-title { + max-width: 100%; } + .block_starredcourses .starred-course-info-container .card-title a { + max-width: 100%; } + +.block_starredcourses .empty-placeholder-image-lg { + height: 125px; } + .navbar { max-height: 50px; } From b9c56f82a17dddd31000304ac32eb9f504b57a3c Mon Sep 17 00:00:00 2001 From: lameze Date: Fri, 19 Oct 2018 07:19:26 -0400 Subject: [PATCH 03/13] MDL-63064 block_starredcourses: implement null provider --- .../classes/privacy/provider.php | 45 +++++++++++++++++++ .../lang/en/block_starredcourses.php | 1 + 2 files changed, 46 insertions(+) create mode 100644 blocks/starredcourses/classes/privacy/provider.php diff --git a/blocks/starredcourses/classes/privacy/provider.php b/blocks/starredcourses/classes/privacy/provider.php new file mode 100644 index 00000000000..c5e8c879654 --- /dev/null +++ b/blocks/starredcourses/classes/privacy/provider.php @@ -0,0 +1,45 @@ +. + +/** + * Privacy Subsystem implementation for block_starredcourses. + * + * @package block_starredcourses + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace block_starredcourses\privacy; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Privacy Subsystem for block_starredcourses. + * + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class provider implements \core_privacy\local\metadata\null_provider { + + /** + * Get the language string identifier with the component's language + * file to explain why this plugin stores no data. + * + * @return string + */ + public static function get_reason() : string { + return 'privacy:metadata'; + } +} diff --git a/blocks/starredcourses/lang/en/block_starredcourses.php b/blocks/starredcourses/lang/en/block_starredcourses.php index 38cc042ded7..8d7d7f1b9a5 100644 --- a/blocks/starredcourses/lang/en/block_starredcourses.php +++ b/blocks/starredcourses/lang/en/block_starredcourses.php @@ -24,6 +24,7 @@ $string['nocourses'] = 'No starred courses'; $string['pluginname'] = 'Starred courses'; +$string['privacy:metadata'] = 'The starred courses block does not store any personal data.'; $string['starredcourses:addinstance'] = 'Add a new instance of starred courses block'; $string['starredcourses:myaddinstance'] = 'Add a new instance of starred block to Dashboard'; From 115ce6babf22c03cb78f59e299adad7dc6e666b5 Mon Sep 17 00:00:00 2001 From: lameze Date: Thu, 25 Oct 2018 23:56:29 -0400 Subject: [PATCH 04/13] MDL-63064 core: add starred courses block to plugin list --- lib/classes/plugin_manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/classes/plugin_manager.php b/lib/classes/plugin_manager.php index ca16fd4b8f8..8dc20af2b62 100644 --- a/lib/classes/plugin_manager.php +++ b/lib/classes/plugin_manager.php @@ -1721,7 +1721,7 @@ class core_plugin_manager { 'private_files', 'quiz_results', 'recent_activity', 'rss_client', 'search_forums', 'section_links', 'selfcompletion', 'settings', 'site_main_menu', - 'social_activities', 'tag_flickr', 'tag_youtube', 'tags', 'timeline' + 'social_activities', 'starredcourses', 'tag_flickr', 'tag_youtube', 'tags', 'timeline' ), 'booktool' => array( From 0bb6f0b719866556cfd43a9de5a31a97182075d7 Mon Sep 17 00:00:00 2001 From: lameze Date: Mon, 29 Oct 2018 21:33:14 -0400 Subject: [PATCH 05/13] MDL-63064 block_myoverview: trigger event when course is starred --- blocks/myoverview/amd/build/view.min.js | 2 +- blocks/myoverview/amd/src/view.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/blocks/myoverview/amd/build/view.min.js b/blocks/myoverview/amd/build/view.min.js index 5f3fb07be37..c4d08acef86 100644 --- a/blocks/myoverview/amd/build/view.min.js +++ b/blocks/myoverview/amd/build/view.min.js @@ -1 +1 @@ -define(["jquery","block_myoverview/repository","core/paged_content_factory","core/custom_interaction_events","core/notification","core/templates"],function(a,b,c,d,e,f){var g={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"]',PAGED_CONTENT_CONTAINER:'[data-region="page-container"]'},h={COURSES_CARDS:"block_myoverview/view-cards",COURSES_LIST:"block_myoverview/view-list",COURSES_SUMMARY:"block_myoverview/view-summary",NOCOURSES:"block_myoverview/no-courses"},i=[12,24,48],j=[],k=function(a){var b={};return b.display=a.attr("data-display"),b.grouping=a.attr("data-grouping"),b.sort=a.attr("data-sort"),b},l={ignoreControlWhileLoading:!0,controlPlacementBottom:!0},m=function(a,c,d){return b.getEnrolledCoursesByTimeline({offset:d*c,limit:c,classification:a.grouping,sort:a.sort})},n=function(a,b){return a.find(g.FAVOURITE_ICON+'[data-course-id="'+b+'"]')},o=function(a,b){return a.find('[data-region="paged-content-page"][data-page="'+b+'"]')},p=function(a){return a.attr("data-course-id")},q=function(a,b){var c=n(a,b),d=c.find(g.ICON_IS_FAVOURITE);d.addClass("hidden"),d.attr("aria-hidden",!0);var e=c.find(g.ICON_NOT_FAVOURITE);e.removeClass("hidden"),e.attr("aria-hidden",!1)},r=function(a,b){var c=n(a,b),d=c.find(g.ICON_IS_FAVOURITE);d.removeClass("hidden"),d.attr("aria-hidden",!1);var e=c.find(g.ICON_NOT_FAVOURITE);e.addClass("hidden"),e.attr("aria-hidden",!0)},s=function(a,b){return a.find('[data-action="add-favourite"][data-course-id="'+b+'"]')},t=function(a,b){return a.find('[data-action="remove-favourite"][data-course-id="'+b+'"]')},u=function(a,b){var c=t(a,b),d=s(a,b);w(b,!0).then(function(f){f?(c.removeClass("hidden"),d.addClass("hidden"),r(a,b)):e.alert("Starring course failed","Could not change favourite state")})["catch"](e.exception)},v=function(a,b){var c=t(a,b),d=s(a,b);w(b,!1).then(function(f){f?(c.addClass("hidden"),d.removeClass("hidden"),q(a,b)):e.alert("Starring course failed","Could not change favourite state")})["catch"](e.exception)},w=function(a,c){return b.setFavouriteCourses({courses:[{id:a,favourite:c}]}).then(function(b){return 0==b.warnings.length&&(j.forEach(function(b){b.courses.forEach(function(d,e){d.id==a&&(b.courses[e].isfavourite=c)})}),!0)})["catch"](e.exception)},x=function(a,b){var c=k(a),d="";if(d="cards"==c.display?h.COURSES_CARDS:"list"==c.display?h.COURSES_LIST:h.COURSES_SUMMARY,b.courses.length)return f.render(d,{courses:b.courses});var e=a.attr("data-nocoursesimg");return f.render(h.NOCOURSES,{nocoursesimg:e})},y=function(b,d){b=a(b),b.attr("data-init")||(z(b),b.attr("data-init",!0));var g=k(b),h=c.createWithLimit(i,function(a,c){var d=[];return a.forEach(function(a){var f=a.pageNumber,h=a.pageNumber-1,i=m(g,a.limit,h).then(function(d){return d.courses.length0?j.forEach(function(b,c){var d=o(a,c);x(a,b).then(function(a,b){return f.replaceNodeContents(d,a,b)})["catch"](e.exception)}):y(a,b)};return{init:y,reset:A}}); \ No newline at end of file +define(["jquery","block_myoverview/repository","core/paged_content_factory","core/custom_interaction_events","core/notification","core/templates"],function(a,b,c,d,e,f){var g={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"]',PAGED_CONTENT_CONTAINER:'[data-region="page-container"]'},h={COURSES_CARDS:"block_myoverview/view-cards",COURSES_LIST:"block_myoverview/view-list",COURSES_SUMMARY:"block_myoverview/view-summary",NOCOURSES:"block_myoverview/no-courses"},i=[12,24,48],j=[],k=function(a){var b={};return b.display=a.attr("data-display"),b.grouping=a.attr("data-grouping"),b.sort=a.attr("data-sort"),b},l={ignoreControlWhileLoading:!0,controlPlacementBottom:!0},m=function(a,c,d){return b.getEnrolledCoursesByTimeline({offset:d*c,limit:c,classification:a.grouping,sort:a.sort})},n=function(a,b){return a.find(g.FAVOURITE_ICON+'[data-course-id="'+b+'"]')},o=function(a,b){return a.find('[data-region="paged-content-page"][data-page="'+b+'"]')},p=function(a){return a.attr("data-course-id")},q=function(a,b){var c=n(a,b),d=c.find(g.ICON_IS_FAVOURITE);d.addClass("hidden"),d.attr("aria-hidden",!0);var e=c.find(g.ICON_NOT_FAVOURITE);e.removeClass("hidden"),e.attr("aria-hidden",!1)},r=function(a,b){var c=n(a,b),d=c.find(g.ICON_IS_FAVOURITE);d.removeClass("hidden"),d.attr("aria-hidden",!1);var e=c.find(g.ICON_NOT_FAVOURITE);e.addClass("hidden"),e.attr("aria-hidden",!0)},s=function(a,b){return a.find('[data-action="add-favourite"][data-course-id="'+b+'"]')},t=function(a,b){return a.find('[data-action="remove-favourite"][data-course-id="'+b+'"]')},u=function(b,c){var d=t(b,c),f=s(b,c);w(c,!0).then(function(g){g?(a("body").trigger("myoverview-events:course_starred",[c]),d.removeClass("hidden"),f.addClass("hidden"),r(b,c)):e.alert("Starring course failed","Could not change favourite state")})["catch"](e.exception)},v=function(b,c){var d=t(b,c),f=s(b,c);w(c,!1).then(function(g){g?(a("body").trigger("myoverview-events:course_unstarred",[c]),d.addClass("hidden"),f.removeClass("hidden"),q(b,c)):e.alert("Starring course failed","Could not change favourite state")})["catch"](e.exception)},w=function(a,c){return b.setFavouriteCourses({courses:[{id:a,favourite:c}]}).then(function(b){return 0==b.warnings.length&&(j.forEach(function(b){b.courses.forEach(function(d,e){d.id==a&&(b.courses[e].isfavourite=c)})}),!0)})["catch"](e.exception)},x=function(a,b){var c=k(a),d="";if(d="cards"==c.display?h.COURSES_CARDS:"list"==c.display?h.COURSES_LIST:h.COURSES_SUMMARY,b.courses.length)return f.render(d,{courses:b.courses});var e=a.attr("data-nocoursesimg");return f.render(h.NOCOURSES,{nocoursesimg:e})},y=function(b,d){b=a(b),b.attr("data-init")||(z(b),b.attr("data-init",!0));var g=k(b),h=c.createWithLimit(i,function(a,c){var d=[];return a.forEach(function(a){var f=a.pageNumber,h=a.pageNumber-1,i=m(g,a.limit,h).then(function(d){return d.courses.length0?j.forEach(function(b,c){var d=o(a,c);x(a,b).then(function(a,b){return f.replaceNodeContents(d,a,b)})["catch"](e.exception)}):y(a,b)};return{init:y,reset:A}}); \ No newline at end of file diff --git a/blocks/myoverview/amd/src/view.js b/blocks/myoverview/amd/src/view.js index f4304fadb36..9e9de76c6c6 100644 --- a/blocks/myoverview/amd/src/view.js +++ b/blocks/myoverview/amd/src/view.js @@ -197,6 +197,9 @@ function( setCourseFavouriteState(courseId, true).then(function(success) { if (success) { + // Trigger a JS event so the starred courses block can refresh the list of courses. + $('body').trigger('myoverview-events:course_starred', [courseId]); + removeAction.removeClass('hidden'); addAction.addClass('hidden'); showFavouriteIcon(root, courseId); @@ -219,6 +222,7 @@ function( setCourseFavouriteState(courseId, false).then(function(success) { if (success) { + $('body').trigger('myoverview-events:course_unstarred', [courseId]); removeAction.addClass('hidden'); addAction.removeClass('hidden'); hideFavouriteIcon(root, courseId); From d5d7699b87f5967a7e85a154612f2aa7c5638329 Mon Sep 17 00:00:00 2001 From: lameze Date: Mon, 29 Oct 2018 21:36:38 -0400 Subject: [PATCH 06/13] MDL-63064 block_starredcourses: reload the content when a course is starred --- blocks/starredcourses/amd/build/main.min.js | 2 +- blocks/starredcourses/amd/src/main.js | 58 ++++++++++++++++----- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/blocks/starredcourses/amd/build/main.min.js b/blocks/starredcourses/amd/build/main.min.js index ca3581539ae..2ed5f97a45b 100644 --- a/blocks/starredcourses/amd/build/main.min.js +++ b/blocks/starredcourses/amd/build/main.min.js @@ -1 +1 @@ -define(["jquery","core/notification","block_starredcourses/repository","core/paged_content_factory","core/templates"],function(a,b,c,d,e){var f={STARRED_COURSES_REGION:'[data-region="starred-courses-view-content"]'},g=5,h=function(a,b){if(b.length>0)return e.render("block_starredcourses/view-cards",{courses:b});var c=a.attr("data-nocoursesimg");return e.render("block_starredcourses/no-courses",{nocoursesimg:c})},i=function(b,i){i=a(i);var j=a(f.STARRED_COURSES_REGION);d.createWithLimit(g,function(a,d){var e=[];return a.forEach(function(a){var f={limit:g,offset:a.offset,userid:b},j=c.getStarredCourses(f).then(function(b){return b.length>0?h(i,b):(d.allItemsLoaded(a.pageNumber),h(i,b))});e.push(j)}),e}).then(function(a,b){e.replaceNodeContents(j,a,b)})};return{init:i}}); \ No newline at end of file +define(["jquery","core/notification","block_starredcourses/repository","core/paged_content_factory","core/templates"],function(a,b,c,d,e){var f={STARRED_COURSES_REGION_VIEW:'[data-region="starred-courses-view"]',STARRED_COURSES_REGION:'[data-region="starred-courses-view-content"]'},g=5,h=function(b,c){if(c.length>0)return e.render("block_starredcourses/view-cards",{courses:c});var d=a(f.STARRED_COURSES_REGION_VIEW).attr("data-nocoursesimg");return e.render("block_starredcourses/no-courses",{nocoursesimg:d})},i=function(a,i){var j=a.find(f.STARRED_COURSES_REGION);d.createWithLimit(g,function(b,d){var e=[];return b.forEach(function(b){var f={limit:g,offset:b.offset,userid:i},j=c.getStarredCourses(f).then(function(c){return c.length>0?h(a,c):(d.allItemsLoaded(b.pageNumber),h(a,c))});e.push(j)}),e}).then(function(a,b){return e.replaceNodeContents(j,a,b)})["catch"](b.exception)},j=function(b,c){var d=a("body");d.on("myoverview-events:course_starred",function(){i(b,c)}),d.on("myoverview-events:course_unstarred",function(){i(b,c)})},k=function(b){b=a(b);var c=b.data("userid");j(b,c),i(b,c)};return{init:k}}); \ No newline at end of file diff --git a/blocks/starredcourses/amd/src/main.js b/blocks/starredcourses/amd/src/main.js index a1a68b0ab68..30975975b7d 100644 --- a/blocks/starredcourses/amd/src/main.js +++ b/blocks/starredcourses/amd/src/main.js @@ -37,6 +37,7 @@ function( ) { var SELECTORS = { + STARRED_COURSES_REGION_VIEW: '[data-region="starred-courses-view"]', STARRED_COURSES_REGION: '[data-region="starred-courses-view-content"]' }; @@ -56,7 +57,7 @@ function( courses: courses }); } else { - var nocoursesimg = root.attr('data-nocoursesimg'); + var nocoursesimg = $(SELECTORS.STARRED_COURSES_REGION_VIEW).attr('data-nocoursesimg'); return Templates.render('block_starredcourses/no-courses', { nocoursesimg: nocoursesimg }); @@ -64,14 +65,13 @@ function( }; /** - * Initialise all of the modules for the starred courses block. + * Fetch user's starred courses and reload the content of the block. * - * @param {object} root The root element for the block. + * @param {object} root The root element for the starred view. * @param {Number} userid The user id. */ - var init = function(userid, root) { - root = $(root); - var content = $(SELECTORS.STARRED_COURSES_REGION); + var reloadContent = function(root, userid) { + var content = root.find(SELECTORS.STARRED_COURSES_REGION); PagedContentFactory.createWithLimit( NUM_COURSES_TOTAL, @@ -80,29 +80,59 @@ function( pagesData.forEach(function(pageData) { var args = { - limit: NUM_COURSES_TOTAL, - offset: pageData.offset, - userid: userid - }; + limit: NUM_COURSES_TOTAL, + offset: pageData.offset, + userid: userid + }; // Load the page data. - var pagePromise = Repository.getStarredCourses(args).then(function (courses) { + var pagePromise = Repository.getStarredCourses(args).then(function(courses) { if (courses.length > 0) { return renderCourses(root, courses); } else { actions.allItemsLoaded(pageData.pageNumber); return renderCourses(root, courses); } - }); promises.push(pagePromise); }); return promises; - }).then(function (html, js) { - Templates.replaceNodeContents(content, html, js); + }).then(function(html, js) { + return Templates.replaceNodeContents(content, html, js); + }).catch(Notification.exception); + }; + + /** + * Register event listeners for the block. + * + * @param {object} root The calendar root element + * @param {Number} userid The user id. + */ + var registerEventListeners = function(root, userid) { + var body = $('body'); + + body.on('myoverview-events:course_starred', function() { + reloadContent(root, userid); }); + + body.on('myoverview-events:course_unstarred', function() { + reloadContent(root, userid); + }); + }; + + /** + * Initialise all of the modules for the starred courses block. + * + * @param {object} root The root element for the block. + */ + var init = function(root) { + root = $(root); + var userid = root.data('userid'); + + registerEventListeners(root, userid); + reloadContent(root, userid); }; return { From 07fdb5a0a321a9bfb8b2ca7c00101c4025a8282b Mon Sep 17 00:00:00 2001 From: lameze Date: Tue, 30 Oct 2018 00:03:02 -0400 Subject: [PATCH 07/13] MDL-63064 block_starredcourses: change events to use pubsub --- blocks/myoverview/amd/build/view.min.js | 2 +- blocks/myoverview/amd/src/view.js | 12 +++++---- blocks/starredcourses/amd/build/main.min.js | 2 +- blocks/starredcourses/amd/src/main.js | 14 +++++----- course/amd/build/events.min.js | 1 + course/amd/src/events.js | 29 +++++++++++++++++++++ 6 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 course/amd/build/events.min.js create mode 100644 course/amd/src/events.js diff --git a/blocks/myoverview/amd/build/view.min.js b/blocks/myoverview/amd/build/view.min.js index c4d08acef86..a278dcb212e 100644 --- a/blocks/myoverview/amd/build/view.min.js +++ b/blocks/myoverview/amd/build/view.min.js @@ -1 +1 @@ -define(["jquery","block_myoverview/repository","core/paged_content_factory","core/custom_interaction_events","core/notification","core/templates"],function(a,b,c,d,e,f){var g={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"]',PAGED_CONTENT_CONTAINER:'[data-region="page-container"]'},h={COURSES_CARDS:"block_myoverview/view-cards",COURSES_LIST:"block_myoverview/view-list",COURSES_SUMMARY:"block_myoverview/view-summary",NOCOURSES:"block_myoverview/no-courses"},i=[12,24,48],j=[],k=function(a){var b={};return b.display=a.attr("data-display"),b.grouping=a.attr("data-grouping"),b.sort=a.attr("data-sort"),b},l={ignoreControlWhileLoading:!0,controlPlacementBottom:!0},m=function(a,c,d){return b.getEnrolledCoursesByTimeline({offset:d*c,limit:c,classification:a.grouping,sort:a.sort})},n=function(a,b){return a.find(g.FAVOURITE_ICON+'[data-course-id="'+b+'"]')},o=function(a,b){return a.find('[data-region="paged-content-page"][data-page="'+b+'"]')},p=function(a){return a.attr("data-course-id")},q=function(a,b){var c=n(a,b),d=c.find(g.ICON_IS_FAVOURITE);d.addClass("hidden"),d.attr("aria-hidden",!0);var e=c.find(g.ICON_NOT_FAVOURITE);e.removeClass("hidden"),e.attr("aria-hidden",!1)},r=function(a,b){var c=n(a,b),d=c.find(g.ICON_IS_FAVOURITE);d.removeClass("hidden"),d.attr("aria-hidden",!1);var e=c.find(g.ICON_NOT_FAVOURITE);e.addClass("hidden"),e.attr("aria-hidden",!0)},s=function(a,b){return a.find('[data-action="add-favourite"][data-course-id="'+b+'"]')},t=function(a,b){return a.find('[data-action="remove-favourite"][data-course-id="'+b+'"]')},u=function(b,c){var d=t(b,c),f=s(b,c);w(c,!0).then(function(g){g?(a("body").trigger("myoverview-events:course_starred",[c]),d.removeClass("hidden"),f.addClass("hidden"),r(b,c)):e.alert("Starring course failed","Could not change favourite state")})["catch"](e.exception)},v=function(b,c){var d=t(b,c),f=s(b,c);w(c,!1).then(function(g){g?(a("body").trigger("myoverview-events:course_unstarred",[c]),d.addClass("hidden"),f.removeClass("hidden"),q(b,c)):e.alert("Starring course failed","Could not change favourite state")})["catch"](e.exception)},w=function(a,c){return b.setFavouriteCourses({courses:[{id:a,favourite:c}]}).then(function(b){return 0==b.warnings.length&&(j.forEach(function(b){b.courses.forEach(function(d,e){d.id==a&&(b.courses[e].isfavourite=c)})}),!0)})["catch"](e.exception)},x=function(a,b){var c=k(a),d="";if(d="cards"==c.display?h.COURSES_CARDS:"list"==c.display?h.COURSES_LIST:h.COURSES_SUMMARY,b.courses.length)return f.render(d,{courses:b.courses});var e=a.attr("data-nocoursesimg");return f.render(h.NOCOURSES,{nocoursesimg:e})},y=function(b,d){b=a(b),b.attr("data-init")||(z(b),b.attr("data-init",!0));var g=k(b),h=c.createWithLimit(i,function(a,c){var d=[];return a.forEach(function(a){var f=a.pageNumber,h=a.pageNumber-1,i=m(g,a.limit,h).then(function(d){return d.courses.length0?j.forEach(function(b,c){var d=o(a,c);x(a,b).then(function(a,b){return f.replaceNodeContents(d,a,b)})["catch"](e.exception)}):y(a,b)};return{init:y,reset:A}}); \ No newline at end of file +define(["jquery","block_myoverview/repository","core/paged_content_factory","core/pubsub","core/custom_interaction_events","core/notification","core/templates","core_course/events"],function(a,b,c,d,e,f,g,h){var i={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"]',PAGED_CONTENT_CONTAINER:'[data-region="page-container"]'},j={COURSES_CARDS:"block_myoverview/view-cards",COURSES_LIST:"block_myoverview/view-list",COURSES_SUMMARY:"block_myoverview/view-summary",NOCOURSES:"block_myoverview/no-courses"},k=[12,24,48],l=[],m=function(a){var b={};return b.display=a.attr("data-display"),b.grouping=a.attr("data-grouping"),b.sort=a.attr("data-sort"),b},n={ignoreControlWhileLoading:!0,controlPlacementBottom:!0},o=function(a,c,d){return b.getEnrolledCoursesByTimeline({offset:d*c,limit:c,classification:a.grouping,sort:a.sort})},p=function(a,b){return a.find(i.FAVOURITE_ICON+'[data-course-id="'+b+'"]')},q=function(a,b){return a.find('[data-region="paged-content-page"][data-page="'+b+'"]')},r=function(a){return a.attr("data-course-id")},s=function(a,b){var c=p(a,b),d=c.find(i.ICON_IS_FAVOURITE);d.addClass("hidden"),d.attr("aria-hidden",!0);var e=c.find(i.ICON_NOT_FAVOURITE);e.removeClass("hidden"),e.attr("aria-hidden",!1)},t=function(a,b){var c=p(a,b),d=c.find(i.ICON_IS_FAVOURITE);d.removeClass("hidden"),d.attr("aria-hidden",!1);var e=c.find(i.ICON_NOT_FAVOURITE);e.addClass("hidden"),e.attr("aria-hidden",!0)},u=function(a,b){return a.find('[data-action="add-favourite"][data-course-id="'+b+'"]')},v=function(a,b){return a.find('[data-action="remove-favourite"][data-course-id="'+b+'"]')},w=function(a,b){var c=v(a,b),e=u(a,b);y(b,!0).then(function(g){g?(d.publish(h.favourited),c.removeClass("hidden"),e.addClass("hidden"),t(a,b)):f.alert("Starring course failed","Could not change favourite state")})["catch"](f.exception)},x=function(a,b){var c=v(a,b),e=u(a,b);y(b,!1).then(function(g){g?(d.publish(h.unfavorited),c.addClass("hidden"),e.removeClass("hidden"),s(a,b)):f.alert("Starring course failed","Could not change favourite state")})["catch"](f.exception)},y=function(a,c){return b.setFavouriteCourses({courses:[{id:a,favourite:c}]}).then(function(b){return 0==b.warnings.length&&(l.forEach(function(b){b.courses.forEach(function(d,e){d.id==a&&(b.courses[e].isfavourite=c)})}),!0)})["catch"](f.exception)},z=function(a,b){var c=m(a),d="";if(d="cards"==c.display?j.COURSES_CARDS:"list"==c.display?j.COURSES_LIST:j.COURSES_SUMMARY,b.courses.length)return g.render(d,{courses:b.courses});var e=a.attr("data-nocoursesimg");return g.render(j.NOCOURSES,{nocoursesimg:e})},A=function(b,d){b=a(b),b.attr("data-init")||(B(b),b.attr("data-init",!0));var e=m(b),h=c.createWithLimit(k,function(a,c){var d=[];return a.forEach(function(a){var g=a.pageNumber,h=a.pageNumber-1,i=o(e,a.limit,h).then(function(d){return d.courses.length0?l.forEach(function(b,c){var d=q(a,c);z(a,b).then(function(a,b){return g.replaceNodeContents(d,a,b)})["catch"](f.exception)}):A(a,b)};return{init:A,reset:C}}); \ No newline at end of file diff --git a/blocks/myoverview/amd/src/view.js b/blocks/myoverview/amd/src/view.js index 9e9de76c6c6..49a0b92249e 100644 --- a/blocks/myoverview/amd/src/view.js +++ b/blocks/myoverview/amd/src/view.js @@ -26,17 +26,21 @@ define( 'jquery', 'block_myoverview/repository', 'core/paged_content_factory', + 'core/pubsub', 'core/custom_interaction_events', 'core/notification', 'core/templates', + 'core_course/events' ], function( $, Repository, PagedContentFactory, + PubSub, CustomEvents, Notification, - Templates + Templates, + CourseEvents ) { var SELECTORS = { @@ -197,9 +201,7 @@ function( setCourseFavouriteState(courseId, true).then(function(success) { if (success) { - // Trigger a JS event so the starred courses block can refresh the list of courses. - $('body').trigger('myoverview-events:course_starred', [courseId]); - + PubSub.publish(CourseEvents.favourited); removeAction.removeClass('hidden'); addAction.addClass('hidden'); showFavouriteIcon(root, courseId); @@ -222,7 +224,7 @@ function( setCourseFavouriteState(courseId, false).then(function(success) { if (success) { - $('body').trigger('myoverview-events:course_unstarred', [courseId]); + PubSub.publish(CourseEvents.unfavorited); removeAction.addClass('hidden'); addAction.removeClass('hidden'); hideFavouriteIcon(root, courseId); diff --git a/blocks/starredcourses/amd/build/main.min.js b/blocks/starredcourses/amd/build/main.min.js index 2ed5f97a45b..3de7137912e 100644 --- a/blocks/starredcourses/amd/build/main.min.js +++ b/blocks/starredcourses/amd/build/main.min.js @@ -1 +1 @@ -define(["jquery","core/notification","block_starredcourses/repository","core/paged_content_factory","core/templates"],function(a,b,c,d,e){var f={STARRED_COURSES_REGION_VIEW:'[data-region="starred-courses-view"]',STARRED_COURSES_REGION:'[data-region="starred-courses-view-content"]'},g=5,h=function(b,c){if(c.length>0)return e.render("block_starredcourses/view-cards",{courses:c});var d=a(f.STARRED_COURSES_REGION_VIEW).attr("data-nocoursesimg");return e.render("block_starredcourses/no-courses",{nocoursesimg:d})},i=function(a,i){var j=a.find(f.STARRED_COURSES_REGION);d.createWithLimit(g,function(b,d){var e=[];return b.forEach(function(b){var f={limit:g,offset:b.offset,userid:i},j=c.getStarredCourses(f).then(function(c){return c.length>0?h(a,c):(d.allItemsLoaded(b.pageNumber),h(a,c))});e.push(j)}),e}).then(function(a,b){return e.replaceNodeContents(j,a,b)})["catch"](b.exception)},j=function(b,c){var d=a("body");d.on("myoverview-events:course_starred",function(){i(b,c)}),d.on("myoverview-events:course_unstarred",function(){i(b,c)})},k=function(b){b=a(b);var c=b.data("userid");j(b,c),i(b,c)};return{init:k}}); \ No newline at end of file +define(["jquery","core/notification","block_starredcourses/repository","core/paged_content_factory","core/pubsub","core/templates","core_course/events"],function(a,b,c,d,e,f,g){var h={STARRED_COURSES_REGION_VIEW:'[data-region="starred-courses-view"]',STARRED_COURSES_REGION:'[data-region="starred-courses-view-content"]'},i=5,j=function(b,c){if(c.length>0)return f.render("block_starredcourses/view-cards",{courses:c});var d=a(h.STARRED_COURSES_REGION_VIEW).attr("data-nocoursesimg");return f.render("block_starredcourses/no-courses",{nocoursesimg:d})},k=function(a,e){var g=a.find(h.STARRED_COURSES_REGION);d.createWithLimit(i,function(b,d){var f=[];return b.forEach(function(b){var g={limit:i,offset:b.offset,userid:e},h=c.getStarredCourses(g).then(function(c){return c.length>0?j(a,c):(d.allItemsLoaded(b.pageNumber),j(a,c))});f.push(h)}),f}).then(function(a,b){return f.replaceNodeContents(g,a,b)})["catch"](b.exception)},l=function(a,b){e.subscribe(g.favourited,function(){k(a,b)}),e.subscribe(g.unfavorited,function(){k(a,b)})},m=function(b){b=a(b);var c=b.data("userid");l(b,c),k(b,c)};return{init:m}}); \ No newline at end of file diff --git a/blocks/starredcourses/amd/src/main.js b/blocks/starredcourses/amd/src/main.js index 30975975b7d..a581a3d6c01 100644 --- a/blocks/starredcourses/amd/src/main.js +++ b/blocks/starredcourses/amd/src/main.js @@ -26,14 +26,18 @@ define( 'core/notification', 'block_starredcourses/repository', 'core/paged_content_factory', - 'core/templates' + 'core/pubsub', + 'core/templates', + 'core_course/events' ], function( $, Notification, Repository, PagedContentFactory, - Templates + PubSub, + Templates, + CourseEvents ) { var SELECTORS = { @@ -111,13 +115,11 @@ function( * @param {Number} userid The user id. */ var registerEventListeners = function(root, userid) { - var body = $('body'); - - body.on('myoverview-events:course_starred', function() { + PubSub.subscribe(CourseEvents.favourited, function() { reloadContent(root, userid); }); - body.on('myoverview-events:course_unstarred', function() { + PubSub.subscribe(CourseEvents.unfavorited, function() { reloadContent(root, userid); }); }; diff --git a/course/amd/build/events.min.js b/course/amd/build/events.min.js new file mode 100644 index 00000000000..4ea5c9e3db4 --- /dev/null +++ b/course/amd/build/events.min.js @@ -0,0 +1 @@ +define([],function(){return{favourited:"core_course:favourited",unfavorited:"core_course:unfavorited"}}); \ No newline at end of file diff --git a/course/amd/src/events.js b/course/amd/src/events.js new file mode 100644 index 00000000000..7609702c34a --- /dev/null +++ b/course/amd/src/events.js @@ -0,0 +1,29 @@ +// 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 . + +/** + * Contain the events the course component can trigger. + * + * @module core_course/events + * @package core_course + * @copyright 2018 Simey Lameze + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define([], function() { + return { + favourited: 'core_course:favourited', + unfavorited: 'core_course:unfavorited', + }; +}); \ No newline at end of file From 8730c0619cffdb800a715d0e49e53f97b801a954 Mon Sep 17 00:00:00 2001 From: lameze Date: Tue, 30 Oct 2018 22:16:43 -0400 Subject: [PATCH 08/13] MDL-63064 block_starredcourses: remove pagination from main module This commit also removes the userid attribute handling on templates, JS and from the webservices setting the logged user as user id on the webservice side. --- blocks/starredcourses/amd/build/main.min.js | 2 +- blocks/starredcourses/amd/src/main.js | 51 ++++++--------------- blocks/starredcourses/amd/src/repository.js | 1 + blocks/starredcourses/classes/external.php | 23 ++-------- 4 files changed, 21 insertions(+), 56 deletions(-) diff --git a/blocks/starredcourses/amd/build/main.min.js b/blocks/starredcourses/amd/build/main.min.js index 3de7137912e..cbad491a979 100644 --- a/blocks/starredcourses/amd/build/main.min.js +++ b/blocks/starredcourses/amd/build/main.min.js @@ -1 +1 @@ -define(["jquery","core/notification","block_starredcourses/repository","core/paged_content_factory","core/pubsub","core/templates","core_course/events"],function(a,b,c,d,e,f,g){var h={STARRED_COURSES_REGION_VIEW:'[data-region="starred-courses-view"]',STARRED_COURSES_REGION:'[data-region="starred-courses-view-content"]'},i=5,j=function(b,c){if(c.length>0)return f.render("block_starredcourses/view-cards",{courses:c});var d=a(h.STARRED_COURSES_REGION_VIEW).attr("data-nocoursesimg");return f.render("block_starredcourses/no-courses",{nocoursesimg:d})},k=function(a,e){var g=a.find(h.STARRED_COURSES_REGION);d.createWithLimit(i,function(b,d){var f=[];return b.forEach(function(b){var g={limit:i,offset:b.offset,userid:e},h=c.getStarredCourses(g).then(function(c){return c.length>0?j(a,c):(d.allItemsLoaded(b.pageNumber),j(a,c))});f.push(h)}),f}).then(function(a,b){return f.replaceNodeContents(g,a,b)})["catch"](b.exception)},l=function(a,b){e.subscribe(g.favourited,function(){k(a,b)}),e.subscribe(g.unfavorited,function(){k(a,b)})},m=function(b){b=a(b);var c=b.data("userid");l(b,c),k(b,c)};return{init:m}}); \ No newline at end of file +define(["jquery","core/notification","block_starredcourses/repository","core/pubsub","core/templates","core_course/events"],function(a,b,c,d,e,f){var g={STARRED_COURSES_REGION_VIEW:'[data-region="starred-courses-view"]',STARRED_COURSES_REGION:'[data-region="starred-courses-view-content"]'},h=5,i=function(a,b){if(b.length>0)return e.render("block_starredcourses/view-cards",{courses:b});var c=a.find(g.STARRED_COURSES_REGION_VIEW).attr("data-nocoursesimg");return e.render("block_starredcourses/no-courses",{nocoursesimg:c})},j=function(a){var d=a.find(g.STARRED_COURSES_REGION),f={limit:h,offset:0};return c.getStarredCourses(f).then(function(b){return i(a,b)}).then(function(a,b){return e.replaceNodeContents(d,a,b)})["catch"](b.exception)},k=function(a){d.subscribe(f.favourited,function(){j(a)}),d.subscribe(f.unfavorited,function(){j(a)})},l=function(b){b=a(b),k(b),j(b)};return{init:l}}); \ No newline at end of file diff --git a/blocks/starredcourses/amd/src/main.js b/blocks/starredcourses/amd/src/main.js index a581a3d6c01..93428faa802 100644 --- a/blocks/starredcourses/amd/src/main.js +++ b/blocks/starredcourses/amd/src/main.js @@ -25,7 +25,6 @@ define( 'jquery', 'core/notification', 'block_starredcourses/repository', - 'core/paged_content_factory', 'core/pubsub', 'core/templates', 'core_course/events' @@ -34,7 +33,6 @@ function( $, Notification, Repository, - PagedContentFactory, PubSub, Templates, CourseEvents @@ -61,7 +59,7 @@ function( courses: courses }); } else { - var nocoursesimg = $(SELECTORS.STARRED_COURSES_REGION_VIEW).attr('data-nocoursesimg'); + var nocoursesimg =root.find(SELECTORS.STARRED_COURSES_REGION_VIEW).attr('data-nocoursesimg'); return Templates.render('block_starredcourses/no-courses', { nocoursesimg: nocoursesimg }); @@ -72,37 +70,18 @@ function( * Fetch user's starred courses and reload the content of the block. * * @param {object} root The root element for the starred view. - * @param {Number} userid The user id. */ - var reloadContent = function(root, userid) { + var reloadContent = function(root) { var content = root.find(SELECTORS.STARRED_COURSES_REGION); - PagedContentFactory.createWithLimit( - NUM_COURSES_TOTAL, - function(pagesData, actions) { - var promises = []; + var args = { + limit: NUM_COURSES_TOTAL, + offset: 0, + }; - pagesData.forEach(function(pageData) { - var args = { - limit: NUM_COURSES_TOTAL, - offset: pageData.offset, - userid: userid - }; - - // Load the page data. - var pagePromise = Repository.getStarredCourses(args).then(function(courses) { - if (courses.length > 0) { - return renderCourses(root, courses); - } else { - actions.allItemsLoaded(pageData.pageNumber); - return renderCourses(root, courses); - } - }); - - promises.push(pagePromise); - }); - - return promises; + return Repository.getStarredCourses(args) + .then(function(courses) { + return renderCourses(root, courses); }).then(function(html, js) { return Templates.replaceNodeContents(content, html, js); }).catch(Notification.exception); @@ -112,15 +91,14 @@ function( * Register event listeners for the block. * * @param {object} root The calendar root element - * @param {Number} userid The user id. */ - var registerEventListeners = function(root, userid) { + var registerEventListeners = function(root) { PubSub.subscribe(CourseEvents.favourited, function() { - reloadContent(root, userid); + reloadContent(root); }); PubSub.subscribe(CourseEvents.unfavorited, function() { - reloadContent(root, userid); + reloadContent(root); }); }; @@ -131,10 +109,9 @@ function( */ var init = function(root) { root = $(root); - var userid = root.data('userid'); - registerEventListeners(root, userid); - reloadContent(root, userid); + registerEventListeners(root); + reloadContent(root); }; return { diff --git a/blocks/starredcourses/amd/src/repository.js b/blocks/starredcourses/amd/src/repository.js index 778516cc81f..7de121ec335 100644 --- a/blocks/starredcourses/amd/src/repository.js +++ b/blocks/starredcourses/amd/src/repository.js @@ -27,6 +27,7 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat * * Valid args are: * int limit number of records to retrieve + * int offset the offset of records to retrieve * * @method getStarredCourses * @param {object} args The request arguments diff --git a/blocks/starredcourses/classes/external.php b/blocks/starredcourses/classes/external.php index baae1d1f8db..55a0813e663 100644 --- a/blocks/starredcourses/classes/external.php +++ b/blocks/starredcourses/classes/external.php @@ -53,19 +53,17 @@ class block_starredcourses_external extends core_course_external { } /** - * Get users starred courses appending additional course information like images. + * Get users starred courses. * - * @param int $limit Limit + * @param int $limit Limit * @param int $offset Offset - * @param int|null $userid The user's userid to fetch the favourite courses. + * * @return array list of courses and warnings */ - public static function get_starred_courses($limit, $offset, $userid = null) { + public static function get_starred_courses($limit, $offset) { global $USER, $PAGE; - if (!$userid) { - $userid = $USER->id; - } + $userid = $USER->id; $params = self::validate_parameters(self::get_starred_courses_parameters(), [ 'limit' => $limit, @@ -95,18 +93,7 @@ class block_starredcourses_external extends core_course_external { if (!isset($results[$courseid])) { $exporter = new course_summary_exporter(get_course($courseid), ['context' => \context_course::instance($courseid)]); - $courseinlist = new \core_course_list_element(get_course($courseid)); - foreach ($courseinlist->get_course_overviewfiles() as $file) { - if ($file->is_valid_image()) { - $url = new moodle_url("/pluginfile.php".'/'.$file->get_contextid(). '/'. $file->get_component(). '/'. - $file->get_filearea(). $file->get_filepath(). $file->get_filename()); - $courseimage = $url->__toString(); - } - } $results[$courseid] = $exporter->export($output); - if (!empty($courseimage)) { - $results[$courseid]['courseimage'] = $courseimage; - } } } From 51437e5f6d23332abb4b675cd056fd911a5ae260 Mon Sep 17 00:00:00 2001 From: lameze Date: Tue, 30 Oct 2018 22:35:55 -0400 Subject: [PATCH 09/13] MDL-63064 block_starredcourses: make starred block style consistent This commit remove an unused template and some custom css that has been added previously and now is no longer necessary. --- .../starredcourses/templates/courses.mustache | 55 ----------------- blocks/starredcourses/templates/main.mustache | 2 +- .../templates/placeholder-course.mustache | 4 +- .../templates/view-cards.mustache | 33 +++++----- blocks/starredcourses/templates/view.mustache | 2 +- theme/boost/scss/moodle/blocks.scss | 61 ------------------- theme/boost/style/moodle.css | 50 --------------- 7 files changed, 23 insertions(+), 184 deletions(-) delete mode 100644 blocks/starredcourses/templates/courses.mustache diff --git a/blocks/starredcourses/templates/courses.mustache b/blocks/starredcourses/templates/courses.mustache deleted file mode 100644 index 88a5a5c8c01..00000000000 --- a/blocks/starredcourses/templates/courses.mustache +++ /dev/null @@ -1,55 +0,0 @@ -{{! - 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 Licensebllsdsadfasfd - along with Moodle. If not, see . -}} -{{! - @template block_recentcourses/view-cards - - This template renders the carousel for the recentcourses block. - - Example context (json): - { - "courses": [ - { - "name": "Assignment due 1", - "viewurl": "https://moodlesite/course/view.php?id=2", - "courseimage": "https://moodlesite/pluginfile/123/course/overviewfiles/123.jpg", - "fullname": "course 3" - } - ] - } -}} -
- {{#courses}} - - {{/courses}} -
diff --git a/blocks/starredcourses/templates/main.mustache b/blocks/starredcourses/templates/main.mustache index fab929f4ed1..b12dc66b356 100644 --- a/blocks/starredcourses/templates/main.mustache +++ b/blocks/starredcourses/templates/main.mustache @@ -23,7 +23,7 @@ {} }} -
+
{{> block_starredcourses/view }}
diff --git a/blocks/starredcourses/templates/placeholder-course.mustache b/blocks/starredcourses/templates/placeholder-course.mustache index f9c3198e8da..0e35afe39ae 100644 --- a/blocks/starredcourses/templates/placeholder-course.mustache +++ b/blocks/starredcourses/templates/placeholder-course.mustache @@ -17,10 +17,10 @@ Example context (json): {} }} -
+
-
+
diff --git a/blocks/starredcourses/templates/view-cards.mustache b/blocks/starredcourses/templates/view-cards.mustache index 7919c7f1bc6..424f696fd26 100644 --- a/blocks/starredcourses/templates/view-cards.mustache +++ b/blocks/starredcourses/templates/view-cards.mustache @@ -26,20 +26,25 @@ ] } }} -
- {{#courses}} - -
-
-
-
-
-
- {{{fullname}}} -
-
-
+
diff --git a/blocks/starredcourses/templates/view.mustache b/blocks/starredcourses/templates/view.mustache index 372760ad3c8..8492cfb8731 100644 --- a/blocks/starredcourses/templates/view.mustache +++ b/blocks/starredcourses/templates/view.mustache @@ -29,7 +29,7 @@ data-nocoursesimg="{{nocoursesimg}}">
-
+
{{> block_starredcourses/placeholder-course }} {{> block_starredcourses/placeholder-course }} {{> block_starredcourses/placeholder-course }} diff --git a/theme/boost/scss/moodle/blocks.scss b/theme/boost/scss/moodle/blocks.scss index 67a9d185afc..c4cc09b048a 100644 --- a/theme/boost/scss/moodle/blocks.scss +++ b/theme/boost/scss/moodle/blocks.scss @@ -237,64 +237,3 @@ body.drawer-open-left #region-main.has-blocks { margin-right: 2px; } } -$card-gutter : $card-deck-margin * 2; -.block_starredcourses { - [data-region="starredcoursess-view-content"] { - overflow-x: hidden; - } - .card-deck { - flex-wrap: nowrap; - } - .starredcoursessimg { - height: 7rem; - background-position: center; - background-size: cover; - } - .starredcourses-info-container { - padding: 0.8rem; - .card-title { - max-width: 100%; - a { - max-width: 100%; - } - } - } - .empty-placeholder-image-lg { - height: 125px; - } -} - -$card-gutter : $card-deck-margin * 2; -.block_starredcourses { - [data-region="starred-courses-view-content"] { - overflow-x: hidden; - } - .starred-course-card { - flex-basis: auto; - height: 150px; - width: 200px; - flex-shrink: 0; - } - .course-card-container { - height: 150px; - overflow: hidden; - flex-wrap: wrap; - } - .starred-course-img { - height: 7rem; - background-position: center; - background-size: cover; - } - .starred-course-info-container { - padding: 0.8rem; - .card-title { - max-width: 100%; - a { - max-width: 100%; - } - } - } - .empty-placeholder-image-lg { - height: 125px; - } -} \ No newline at end of file diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index 49534fc14fc..a0e4db7f006 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -11251,56 +11251,6 @@ div.editor_atto_toolbar button .icon { .block_settings .block_tree p.hasicon .icon { margin-right: 2px; } -.block_starredcourses [data-region="starredcoursess-view-content"] { - overflow-x: hidden; } - -.block_starredcourses .card-deck { - flex-wrap: nowrap; } - -.block_starredcourses .starredcoursessimg { - height: 7rem; - background-position: center; - background-size: cover; } - -.block_starredcourses .starredcourses-info-container { - padding: 0.8rem; } - .block_starredcourses .starredcourses-info-container .card-title { - max-width: 100%; } - .block_starredcourses .starredcourses-info-container .card-title a { - max-width: 100%; } - -.block_starredcourses .empty-placeholder-image-lg { - height: 125px; } - -.block_starredcourses [data-region="starred-courses-view-content"] { - overflow-x: hidden; } - -.block_starredcourses .starred-course-card { - flex-basis: auto; - height: 150px; - width: 200px; - flex-shrink: 0; } - -.block_starredcourses .course-card-container { - height: 150px; - overflow: hidden; - flex-wrap: wrap; } - -.block_starredcourses .starred-course-img { - height: 7rem; - background-position: center; - background-size: cover; } - -.block_starredcourses .starred-course-info-container { - padding: 0.8rem; } - .block_starredcourses .starred-course-info-container .card-title { - max-width: 100%; } - .block_starredcourses .starred-course-info-container .card-title a { - max-width: 100%; } - -.block_starredcourses .empty-placeholder-image-lg { - height: 125px; } - .navbar { max-height: 50px; } From f6c6f215beb6b33843c0854980ca599550aee5ef Mon Sep 17 00:00:00 2001 From: Bas Brands Date: Wed, 31 Oct 2018 11:05:51 +0100 Subject: [PATCH 10/13] MDL-63064 block_starredcourses: move favouriteicon template --- blocks/starredcourses/classes/external.php | 2 +- .../templates/view-cards.mustache | 6 +-- course/templates/favouriteicon.mustache | 49 +++++++++++++++++++ theme/boost/scss/moodle/blocks.scss | 3 +- theme/boost/style/moodle.css | 44 ++++++++++++++--- 5 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 course/templates/favouriteicon.mustache diff --git a/blocks/starredcourses/classes/external.php b/blocks/starredcourses/classes/external.php index 55a0813e663..8ee6be6657d 100644 --- a/blocks/starredcourses/classes/external.php +++ b/blocks/starredcourses/classes/external.php @@ -92,7 +92,7 @@ class block_starredcourses_external extends core_course_external { $courseid = $favourite->itemid; if (!isset($results[$courseid])) { $exporter = new course_summary_exporter(get_course($courseid), - ['context' => \context_course::instance($courseid)]); + ['context' => \context_course::instance($courseid), 'isfavourite' => true]); $results[$courseid] = $exporter->export($output); } } diff --git a/blocks/starredcourses/templates/view-cards.mustache b/blocks/starredcourses/templates/view-cards.mustache index 424f696fd26..7e54752b3a2 100644 --- a/blocks/starredcourses/templates/view-cards.mustache +++ b/blocks/starredcourses/templates/view-cards.mustache @@ -31,15 +31,15 @@
- {{#str}}aria:courseimage, block_myoverview{{/str}} - {{> block_myoverview/favourite-icon }} + {{#str}}aria:courseimage, core_course{{/str}} + {{>core_course/favouriteicon }}
diff --git a/course/templates/favouriteicon.mustache b/course/templates/favouriteicon.mustache new file mode 100644 index 00000000000..3b4831666e5 --- /dev/null +++ b/course/templates/favouriteicon.mustache @@ -0,0 +1,49 @@ +{{! + 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 . +}} +{{! + @template core_course/favouriteicon + + This template renders the favourite icon for a course. + + Example context (json): + { + "id": 3, + "isfavourite": true + } +}} +
+ +
diff --git a/theme/boost/scss/moodle/blocks.scss b/theme/boost/scss/moodle/blocks.scss index c4cc09b048a..1a4a68b27e9 100644 --- a/theme/boost/scss/moodle/blocks.scss +++ b/theme/boost/scss/moodle/blocks.scss @@ -77,7 +77,8 @@ $blocks-plus-gutter: $blocks-column-width + ( $grid-gutter-width / 2 ); $card-gutter : $card-deck-margin * 2; -.block_myoverview { +.block_myoverview, +.block_starredcourses { .empty-placeholder-image-lg { height: 125px; } diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index a0e4db7f006..84c410eb76f 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -11134,32 +11134,60 @@ div.editor_atto_toolbar button .icon { [data-region="blocks-column"] { width: 100%; } } -.block_myoverview .empty-placeholder-image-lg { +.block_myoverview .empty-placeholder-image-lg, +.block_starredcourses .empty-placeholder-image-lg { height: 125px; } -.block_myoverview .course-info-container { +.block_myoverview .course-info-container, +.block_starredcourses .course-info-container { padding: 0.8rem; } -.block_myoverview .progress { +.block_myoverview .progress, +.block_starredcourses .progress { height: 0.5rem; } -.block_myoverview .course-summaryitem { +.block_myoverview .course-summaryitem, +.block_starredcourses .course-summaryitem { border: 1px solid #dee2e6; background-color: #fff; } -.block_myoverview .icon { +.block_myoverview .icon, +.block_starredcourses .icon { margin-right: 0; } .block_myoverview a, -.block_myoverview .btn-link { +.block_myoverview .btn-link, +.block_starredcourses a, +.block_starredcourses .btn-link { color: inherit; } -.block_myoverview .btn.btn-link.btn-icon, .block_myoverview #page-grade-grading-manage .actions .btn-link.btn-icon.action, #page-grade-grading-manage .actions .block_myoverview .btn-link.btn-icon.action, .block_myoverview #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon, #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_myoverview input.btn-link.btn-icon, .block_myoverview #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion, #rubric-rubric.gradingform_rubric .block_myoverview .btn-link.btn-icon.addcriterion { +.block_myoverview .btn.btn-link.btn-icon, .block_myoverview #page-grade-grading-manage .actions .btn-link.btn-icon.action, #page-grade-grading-manage .actions .block_myoverview .btn-link.btn-icon.action, .block_myoverview #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon, #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_myoverview input.btn-link.btn-icon, .block_myoverview #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion, #rubric-rubric.gradingform_rubric .block_myoverview .btn-link.btn-icon.addcriterion, +.block_starredcourses .btn.btn-link.btn-icon, +.block_starredcourses #page-grade-grading-manage .actions .btn-link.btn-icon.action, +#page-grade-grading-manage .actions .block_starredcourses .btn-link.btn-icon.action, +.block_starredcourses #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon, +#rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_starredcourses input.btn-link.btn-icon, +.block_starredcourses #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion, +#rubric-rubric.gradingform_rubric .block_starredcourses .btn-link.btn-icon.addcriterion { height: 36px; width: 36px; padding: 0; border-radius: 50%; } - .block_myoverview .btn.btn-link.btn-icon:hover, .block_myoverview #page-grade-grading-manage .actions .btn-link.btn-icon.action:hover, #page-grade-grading-manage .actions .block_myoverview .btn-link.btn-icon.action:hover, .block_myoverview #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:hover, #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_myoverview input.btn-link.btn-icon:hover, .block_myoverview #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:hover, #rubric-rubric.gradingform_rubric .block_myoverview .btn-link.btn-icon.addcriterion:hover, .block_myoverview .btn.btn-link.btn-icon:focus, .block_myoverview #page-grade-grading-manage .actions .btn-link.btn-icon.action:focus, #page-grade-grading-manage .actions .block_myoverview .btn-link.btn-icon.action:focus, .block_myoverview #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:focus, #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_myoverview input.btn-link.btn-icon:focus, .block_myoverview #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:focus, #rubric-rubric.gradingform_rubric .block_myoverview .btn-link.btn-icon.addcriterion:focus { + .block_myoverview .btn.btn-link.btn-icon:hover, .block_myoverview #page-grade-grading-manage .actions .btn-link.btn-icon.action:hover, #page-grade-grading-manage .actions .block_myoverview .btn-link.btn-icon.action:hover, .block_myoverview #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:hover, #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_myoverview input.btn-link.btn-icon:hover, .block_myoverview #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:hover, #rubric-rubric.gradingform_rubric .block_myoverview .btn-link.btn-icon.addcriterion:hover, .block_myoverview .btn.btn-link.btn-icon:focus, .block_myoverview #page-grade-grading-manage .actions .btn-link.btn-icon.action:focus, #page-grade-grading-manage .actions .block_myoverview .btn-link.btn-icon.action:focus, .block_myoverview #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:focus, #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_myoverview input.btn-link.btn-icon:focus, .block_myoverview #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:focus, #rubric-rubric.gradingform_rubric .block_myoverview .btn-link.btn-icon.addcriterion:focus, + .block_starredcourses .btn.btn-link.btn-icon:hover, + .block_starredcourses #page-grade-grading-manage .actions .btn-link.btn-icon.action:hover, + #page-grade-grading-manage .actions .block_starredcourses .btn-link.btn-icon.action:hover, + .block_starredcourses #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:hover, + #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_starredcourses input.btn-link.btn-icon:hover, + .block_starredcourses #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:hover, + #rubric-rubric.gradingform_rubric .block_starredcourses .btn-link.btn-icon.addcriterion:hover, + .block_starredcourses .btn.btn-link.btn-icon:focus, + .block_starredcourses #page-grade-grading-manage .actions .btn-link.btn-icon.action:focus, + #page-grade-grading-manage .actions .block_starredcourses .btn-link.btn-icon.action:focus, + .block_starredcourses #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel input.btn-link.btn-icon:focus, + #rubric-rubric.gradingform_rubric #rubric-criteria .criterion .addlevel .block_starredcourses input.btn-link.btn-icon:focus, + .block_starredcourses #rubric-rubric.gradingform_rubric .btn-link.btn-icon.addcriterion:focus, + #rubric-rubric.gradingform_rubric .block_starredcourses .btn-link.btn-icon.addcriterion:focus { background-color: #e9ecef; } .summaryimage { From 5c6db8d956a85a1925d26922d13206cb4c1989b3 Mon Sep 17 00:00:00 2001 From: Bas Brands Date: Wed, 31 Oct 2018 11:18:07 +0100 Subject: [PATCH 11/13] MDL-63064 block_starredcourses: move lang strings to core_course AMOS BEGIN MOV [aria:courseimage,block_myoverview],[aria:courseimage,core_course] MOV [aria:coursename,block_myoverview],[aria:coursename,core_course] MOV [aria:favourite,block_myoverview],[aria:favourite,core_course] MOV [favourite,block_myoverview],[favourite,core_course] MOV [notfavourite,block_myoverview],[notfavourite,core_course] AMOS END --- blocks/myoverview/lang/en/block_myoverview.php | 5 ----- lang/en/course.php | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/blocks/myoverview/lang/en/block_myoverview.php b/blocks/myoverview/lang/en/block_myoverview.php index 95006568ca2..de95d3caf26 100644 --- a/blocks/myoverview/lang/en/block_myoverview.php +++ b/blocks/myoverview/lang/en/block_myoverview.php @@ -29,12 +29,9 @@ $string['aria:allcourses'] = 'All courses'; $string['aria:card'] = 'Switch to card view'; $string['aria:controls'] = 'Course overview controls'; $string['aria:courseactions'] = 'Actions for current course'; -$string['aria:courseimage'] = 'Course image:'; -$string['aria:coursename'] = 'Course name:'; $string['aria:coursesummary'] = 'Course summary text:'; $string['aria:courseprogress'] = 'Course progress:'; $string['aria:displaydropdown'] = 'Display dropdown'; -$string['aria:favourite'] = 'Course is starred'; $string['aria:favourites'] = 'Show starred courses'; $string['aria:future'] = 'Show future courses'; $string['aria:groupingdropdown'] = 'Grouping dropdown'; @@ -49,11 +46,9 @@ $string['aria:sortingdropdown'] = 'Sorting dropdown'; $string['card'] = 'Card'; $string['cards'] = 'Cards'; $string['complete'] = 'Complete'; -$string['favourite'] = 'Starred course'; $string['favourites'] = 'Starred'; $string['future'] = 'Future'; $string['inprogress'] = 'In progress'; -$string['notfavourite'] = 'Not starred'; $string['lastaccessed'] = 'Last accessed'; $string['list'] = 'List'; $string['myoverview:addinstance'] = 'Add a new course overview block'; diff --git a/lang/en/course.php b/lang/en/course.php index bd1a9923ce7..511efd8cc96 100644 --- a/lang/en/course.php +++ b/lang/en/course.php @@ -22,6 +22,11 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +$string['aria:courseimage'] = 'Course image:'; +$string['aria:coursename'] = 'Course name:'; +$string['aria:favourite'] = 'Course is starred'; +$string['favourite'] = 'Starred course'; +$string['notfavourite'] = 'Not starred'; $string['privacy:perpage'] = 'The number of courses to show per page.'; $string['privacy:completionpath'] = 'Course completion'; $string['privacy:metadata:completionsummary'] = 'The course contains completion information about the user.'; From bdde16014dec25215a09dd156a6ead418c49053e Mon Sep 17 00:00:00 2001 From: lameze Date: Wed, 31 Oct 2018 09:02:06 -0400 Subject: [PATCH 12/13] MDL-63064 block_starredcourses: fix linting issues --- blocks/starredcourses/amd/src/main.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/blocks/starredcourses/amd/src/main.js b/blocks/starredcourses/amd/src/main.js index 93428faa802..1c51cbeb5d3 100644 --- a/blocks/starredcourses/amd/src/main.js +++ b/blocks/starredcourses/amd/src/main.js @@ -51,7 +51,7 @@ function( * @method renderCourses * @param {object} root The root element for the starred view. * @param {array} courses containing array of returned courses. - * @return {promise} Resolved with HTML and JS strings + * @returns {promise} Resolved with HTML and JS strings */ var renderCourses = function(root, courses) { if (courses.length > 0) { @@ -59,7 +59,7 @@ function( courses: courses }); } else { - var nocoursesimg =root.find(SELECTORS.STARRED_COURSES_REGION_VIEW).attr('data-nocoursesimg'); + var nocoursesimg = root.find(SELECTORS.STARRED_COURSES_REGION_VIEW).attr('data-nocoursesimg'); return Templates.render('block_starredcourses/no-courses', { nocoursesimg: nocoursesimg }); @@ -70,6 +70,7 @@ function( * Fetch user's starred courses and reload the content of the block. * * @param {object} root The root element for the starred view. + * @returns {promise} The updated content for the block. */ var reloadContent = function(root) { var content = root.find(SELECTORS.STARRED_COURSES_REGION); From 0ec602615d3b85156d8b40174427371ee35ee707 Mon Sep 17 00:00:00 2001 From: Bas Brands Date: Wed, 31 Oct 2018 16:39:58 +0100 Subject: [PATCH 13/13] MDL-63064 block_starredcourses: horizontal scroll, load all courses --- .../templates/course-action-menu.mustache | 2 +- .../templates/favourite-icon.mustache | 49 ------------------- .../myoverview/templates/view-cards.mustache | 6 +-- .../myoverview/templates/view-list.mustache | 4 +- .../templates/view-summary.mustache | 6 +-- blocks/starredcourses/amd/build/main.min.js | 2 +- blocks/starredcourses/amd/src/main.js | 4 +- blocks/starredcourses/classes/external.php | 37 +++++++------- .../templates/view-cards.mustache | 2 +- theme/boost/scss/moodle/blocks.scss | 14 ++++-- theme/boost/style/moodle.css | 7 ++- theme/bootstrapbase/less/moodle/blocks.less | 10 +++- theme/bootstrapbase/style/moodle.css | 15 +++++- 13 files changed, 69 insertions(+), 89 deletions(-) delete mode 100644 blocks/myoverview/templates/favourite-icon.mustache diff --git a/blocks/myoverview/templates/course-action-menu.mustache b/blocks/myoverview/templates/course-action-menu.mustache index 027bdab3ded..17085d471c2 100644 --- a/blocks/myoverview/templates/course-action-menu.mustache +++ b/blocks/myoverview/templates/course-action-menu.mustache @@ -41,7 +41,7 @@ data-course-id="{{id}}" aria-controls="favorite-icon-{{ id }}" > - {{#pix}} i/star, core, {{#str}} favourite, block_myoverview {{/str}} {{/pix}} + {{#pix}} i/star, core, {{#str}} favourites, block_myoverview {{/str}} {{/pix}} {{#str}} addtofavourites, block_myoverview {{/str}}
{{#str}} aria:addtofavourites, block_myoverview {{/str}} {{{fullname}}} diff --git a/blocks/myoverview/templates/favourite-icon.mustache b/blocks/myoverview/templates/favourite-icon.mustache deleted file mode 100644 index 4cb204bb3eb..00000000000 --- a/blocks/myoverview/templates/favourite-icon.mustache +++ /dev/null @@ -1,49 +0,0 @@ -{{! - 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 . -}} -{{! - @template block_myoverview/favourite-icon - - This template renders the favourite icon for a course. - - Example context (json): - { - "id": 3, - "isfavourite": true - } -}} -
- -
diff --git a/blocks/myoverview/templates/view-cards.mustache b/blocks/myoverview/templates/view-cards.mustache index ce97c1f410d..352d2ede467 100644 --- a/blocks/myoverview/templates/view-cards.mustache +++ b/blocks/myoverview/templates/view-cards.mustache @@ -39,15 +39,15 @@
- {{#str}}aria:courseimage, block_myoverview{{/str}} - {{> block_myoverview/favourite-icon }} + {{#str}}aria:courseimage, core_course{{/str}} + {{> core_course/favouriteicon }}
diff --git a/blocks/myoverview/templates/view-list.mustache b/blocks/myoverview/templates/view-list.mustache index 389036b1055..e39dafd1536 100644 --- a/blocks/myoverview/templates/view-list.mustache +++ b/blocks/myoverview/templates/view-list.mustache @@ -40,9 +40,9 @@
diff --git a/blocks/myoverview/templates/view-summary.mustache b/blocks/myoverview/templates/view-summary.mustache index 0470ca45042..7ee3737091d 100644 --- a/blocks/myoverview/templates/view-summary.mustache +++ b/blocks/myoverview/templates/view-summary.mustache @@ -40,16 +40,16 @@
- {{> block_myoverview/favourite-icon }} + {{> core_course/favouriteicon }}
- {{#str}}aria:courseimage, block_myoverview{{/str}} + {{#str}}aria:courseimage, core_course{{/str}}
- {{#str}}aria:coursename, block_myoverview{{/str}} + {{#str}}aria:coursename, core_course{{/str}}

{{{fullname}}}

{{> block_myoverview/course-action-menu }} diff --git a/blocks/starredcourses/amd/build/main.min.js b/blocks/starredcourses/amd/build/main.min.js index cbad491a979..8ebbc6867ba 100644 --- a/blocks/starredcourses/amd/build/main.min.js +++ b/blocks/starredcourses/amd/build/main.min.js @@ -1 +1 @@ -define(["jquery","core/notification","block_starredcourses/repository","core/pubsub","core/templates","core_course/events"],function(a,b,c,d,e,f){var g={STARRED_COURSES_REGION_VIEW:'[data-region="starred-courses-view"]',STARRED_COURSES_REGION:'[data-region="starred-courses-view-content"]'},h=5,i=function(a,b){if(b.length>0)return e.render("block_starredcourses/view-cards",{courses:b});var c=a.find(g.STARRED_COURSES_REGION_VIEW).attr("data-nocoursesimg");return e.render("block_starredcourses/no-courses",{nocoursesimg:c})},j=function(a){var d=a.find(g.STARRED_COURSES_REGION),f={limit:h,offset:0};return c.getStarredCourses(f).then(function(b){return i(a,b)}).then(function(a,b){return e.replaceNodeContents(d,a,b)})["catch"](b.exception)},k=function(a){d.subscribe(f.favourited,function(){j(a)}),d.subscribe(f.unfavorited,function(){j(a)})},l=function(b){b=a(b),k(b),j(b)};return{init:l}}); \ No newline at end of file +define(["jquery","core/notification","block_starredcourses/repository","core/pubsub","core/templates","core_course/events"],function(a,b,c,d,e,f){var g={STARRED_COURSES_REGION_VIEW:'[data-region="starred-courses-view"]',STARRED_COURSES_REGION:'[data-region="starred-courses-view-content"]'},h=function(a,b){if(b.length>0)return e.render("block_starredcourses/view-cards",{courses:b});var c=a.find(g.STARRED_COURSES_REGION_VIEW).attr("data-nocoursesimg");return e.render("block_starredcourses/no-courses",{nocoursesimg:c})},i=function(a){var d=a.find(g.STARRED_COURSES_REGION),f={limit:0,offset:0};return c.getStarredCourses(f).then(function(b){return h(a,b)}).then(function(a,b){return e.replaceNodeContents(d,a,b)})["catch"](b.exception)},j=function(a){d.subscribe(f.favourited,function(){i(a)}),d.subscribe(f.unfavorited,function(){i(a)})},k=function(b){b=a(b),j(b),i(b)};return{init:k}}); \ No newline at end of file diff --git a/blocks/starredcourses/amd/src/main.js b/blocks/starredcourses/amd/src/main.js index 1c51cbeb5d3..81d413003e1 100644 --- a/blocks/starredcourses/amd/src/main.js +++ b/blocks/starredcourses/amd/src/main.js @@ -43,8 +43,6 @@ function( STARRED_COURSES_REGION: '[data-region="starred-courses-view-content"]' }; - var NUM_COURSES_TOTAL = 5; - /** * Render the starred courses. * @@ -76,7 +74,7 @@ function( var content = root.find(SELECTORS.STARRED_COURSES_REGION); var args = { - limit: NUM_COURSES_TOTAL, + limit: 0, offset: 0, }; diff --git a/blocks/starredcourses/classes/external.php b/blocks/starredcourses/classes/external.php index 8ee6be6657d..f5cb1c2c04d 100644 --- a/blocks/starredcourses/classes/external.php +++ b/blocks/starredcourses/classes/external.php @@ -47,8 +47,7 @@ class block_starredcourses_external extends core_course_external { public static function get_starred_courses_parameters() { return new external_function_parameters([ 'limit' => new external_value(PARAM_INT, 'Limit', VALUE_DEFAULT, 0), - 'offset' => new external_value(PARAM_INT, 'Offset', VALUE_DEFAULT, 0), - 'userid' => new external_value(PARAM_INT, 'id of user, empty for current user', VALUE_DEFAULT, 0) + 'offset' => new external_value(PARAM_INT, 'Offset', VALUE_DEFAULT, 0) ]); } @@ -63,23 +62,19 @@ class block_starredcourses_external extends core_course_external { public static function get_starred_courses($limit, $offset) { global $USER, $PAGE; - $userid = $USER->id; - $params = self::validate_parameters(self::get_starred_courses_parameters(), [ 'limit' => $limit, - 'offset' => $offset, - 'userid' => $userid + 'offset' => $offset ]); - $userid = $params['userid']; $limit = $params['limit']; $offset = $params['offset']; - $usercontext = context_user::instance($userid); + $usercontext = context_user::instance($USER->id); self::validate_context($usercontext); $PAGE->set_context($usercontext); - $output = $PAGE->get_renderer('block_starredcourses'); + $renderer = $PAGE->get_renderer('core'); // Get the user favourites service, scoped to a single user (their favourites only). $userservice = \core_favourites\service_factory::get_service_for_user_context($usercontext); @@ -87,17 +82,21 @@ class block_starredcourses_external extends core_course_external { // Get the favourites, by type, for the user. $favourites = $userservice->find_favourites_by_type('core_course', 'courses', $offset, $limit); - $results = []; - foreach ($favourites as $favourite) { - $courseid = $favourite->itemid; - if (!isset($results[$courseid])) { - $exporter = new course_summary_exporter(get_course($courseid), - ['context' => \context_course::instance($courseid), 'isfavourite' => true]); - $results[$courseid] = $exporter->export($output); - } - } + // Sort the favourites getting last added first. + usort($favourites, function($a, $b) { + if ($a->timemodified == $b->timemodified) return 0; + return ($a->timemodified > $b->timemodified) ? -1 : 1; + }); - return $results; + $formattedcourses = array_map(function($favourite) use ($renderer) { + $course = get_course($favourite->itemid); + $context = \context_course::instance($favourite->itemid); + + $exporter = new course_summary_exporter($course, ['context' => $context, 'isfavourite' => true]); + return $exporter->export($renderer); + }, $favourites); + + return $formattedcourses; } /** diff --git a/blocks/starredcourses/templates/view-cards.mustache b/blocks/starredcourses/templates/view-cards.mustache index 7e54752b3a2..05d672a2485 100644 --- a/blocks/starredcourses/templates/view-cards.mustache +++ b/blocks/starredcourses/templates/view-cards.mustache @@ -28,7 +28,7 @@ }}
{{#courses}} -
+
{{#str}}aria:courseimage, core_course{{/str}} diff --git a/theme/boost/scss/moodle/blocks.scss b/theme/boost/scss/moodle/blocks.scss index 1a4a68b27e9..80df6e23e4d 100644 --- a/theme/boost/scss/moodle/blocks.scss +++ b/theme/boost/scss/moodle/blocks.scss @@ -77,11 +77,12 @@ $blocks-plus-gutter: $blocks-column-width + ( $grid-gutter-width / 2 ); $card-gutter : $card-deck-margin * 2; +.block .empty-placeholder-image-lg { + height: 125px; +} + .block_myoverview, .block_starredcourses { - .empty-placeholder-image-lg { - height: 125px; - } .course-info-container { padding: 0.8rem; } @@ -111,6 +112,13 @@ $card-gutter : $card-deck-margin * 2; } } +.block_starredcourses { + .dashboard-card-deck { + flex-flow: nowrap; + overflow-y: scroll; + } +} + .summaryimage { height: 7rem; background-position: center; diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index 84c410eb76f..564b9eb7dbc 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -11134,8 +11134,7 @@ div.editor_atto_toolbar button .icon { [data-region="blocks-column"] { width: 100%; } } -.block_myoverview .empty-placeholder-image-lg, -.block_starredcourses .empty-placeholder-image-lg { +.block .empty-placeholder-image-lg { height: 125px; } .block_myoverview .course-info-container, @@ -11190,6 +11189,10 @@ div.editor_atto_toolbar button .icon { #rubric-rubric.gradingform_rubric .block_starredcourses .btn-link.btn-icon.addcriterion:focus { background-color: #e9ecef; } +.block_starredcourses .dashboard-card-deck { + flex-flow: nowrap; + overflow-y: scroll; } + .summaryimage { height: 7rem; background-position: center; diff --git a/theme/bootstrapbase/less/moodle/blocks.less b/theme/bootstrapbase/less/moodle/blocks.less index 10c58a62a0f..e8df3e6b8dc 100644 --- a/theme/bootstrapbase/less/moodle/blocks.less +++ b/theme/bootstrapbase/less/moodle/blocks.less @@ -340,6 +340,7 @@ } } +.block_starredcourses, .block_myoverview { .empty-placeholder-image-lg { @@ -387,6 +388,13 @@ } } +.block_starredcourses { + .dashboard-card-deck { + flex-flow: nowrap; + overflow-y: scroll; + } +} + .dashboard-card-deck { box-sizing: border-box; *, @@ -419,7 +427,7 @@ @media (min-width: 1200px) { .dashboard-card { - flex-basis: ~"calc(33% - 0.5rem)"; + flex-basis: ~"calc(33.333% - 0.5rem)"; } } } diff --git a/theme/bootstrapbase/style/moodle.css b/theme/bootstrapbase/style/moodle.css index 2fd008a2856..61ae121d9c2 100644 --- a/theme/bootstrapbase/style/moodle.css +++ b/theme/bootstrapbase/style/moodle.css @@ -16546,13 +16546,16 @@ body { height: 35px; width: 35px; } +.block_starredcourses .empty-placeholder-image-lg, .block_myoverview .empty-placeholder-image-lg { height: 125px; } +.block_starredcourses .course-info-container, .block_myoverview .course-info-container { flex: 1 1 auto; padding: 0.8rem; } +.block_starredcourses .dashboard-card-footer, .block_myoverview .dashboard-card-footer { padding: 0.8rem; background-color: #f5f5f5; @@ -16564,13 +16567,16 @@ body { -moz-border-radius-bottomleft: 4px; border-bottom-left-radius: 4px; } +.block_starredcourses .progress, .block_myoverview .progress { height: 0.5rem; margin-bottom: 0; } +.block_starredcourses .list-group, .block_myoverview .list-group { margin: 0; } +.block_starredcourses .course-listitem, .block_myoverview .course-listitem { display: block; padding: 0.75rem 1.25rem; @@ -16581,6 +16587,7 @@ body { -moz-border-radius: 4px; border-radius: 4px; } +.block_starredcourses .course-summaryitem, .block_myoverview .course-summaryitem { padding: 0.5rem; background-color: #fff; @@ -16589,14 +16596,20 @@ body { -moz-border-radius: 4px; border-radius: 4px; } +.block_starredcourses .summary img, .block_myoverview .summary img { max-width: 100%; } @media (max-width: 576px) { + .block_starredcourses .summaryimage, .block_myoverview .summaryimage { max-height: 7rem; } } +.block_starredcourses .dashboard-card-deck { + flex-flow: nowrap; + overflow-y: scroll; +} .dashboard-card-deck { box-sizing: border-box; display: flex; @@ -16630,7 +16643,7 @@ body { } @media (min-width: 1200px) { .dashboard-card-deck .dashboard-card { - flex-basis: calc(33% - 0.5rem); + flex-basis: calc(33.333% - 0.5rem); } } @media (min-width: 768px) {