diff --git a/blocks/myoverview/amd/build/view.min.js b/blocks/myoverview/amd/build/view.min.js index 5f3fb07be37..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(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/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 f4304fadb36..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,6 +201,7 @@ function( setCourseFavouriteState(courseId, true).then(function(success) { if (success) { + PubSub.publish(CourseEvents.favourited); removeAction.removeClass('hidden'); addAction.addClass('hidden'); showFavouriteIcon(root, courseId); @@ -219,6 +224,7 @@ function( setCourseFavouriteState(courseId, false).then(function(success) { if (success) { + PubSub.publish(CourseEvents.unfavorited); removeAction.addClass('hidden'); addAction.removeClass('hidden'); hideFavouriteIcon(root, courseId); 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/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/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 new file mode 100644 index 00000000000..8ebbc6867ba --- /dev/null +++ b/blocks/starredcourses/amd/build/main.min.js @@ -0,0 +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=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/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..81d413003e1 --- /dev/null +++ b/blocks/starredcourses/amd/src/main.js @@ -0,0 +1,119 @@ +// 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/pubsub', + 'core/templates', + 'core_course/events' +], +function( + $, + Notification, + Repository, + PubSub, + Templates, + CourseEvents +) { + + var SELECTORS = { + STARRED_COURSES_REGION_VIEW: '[data-region="starred-courses-view"]', + STARRED_COURSES_REGION: '[data-region="starred-courses-view-content"]' + }; + + /** + * Render the starred courses. + * + * @method renderCourses + * @param {object} root The root element for the starred view. + * @param {array} courses containing array of returned courses. + * @returns {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.find(SELECTORS.STARRED_COURSES_REGION_VIEW).attr('data-nocoursesimg'); + return Templates.render('block_starredcourses/no-courses', { + nocoursesimg: nocoursesimg + }); + } + }; + + /** + * 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); + + var args = { + limit: 0, + offset: 0, + }; + + return Repository.getStarredCourses(args) + .then(function(courses) { + return renderCourses(root, courses); + }).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 + */ + var registerEventListeners = function(root) { + PubSub.subscribe(CourseEvents.favourited, function() { + reloadContent(root); + }); + + PubSub.subscribe(CourseEvents.unfavorited, function() { + reloadContent(root); + }); + }; + + /** + * 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); + + registerEventListeners(root); + reloadContent(root); + }; + + 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..7de121ec335 --- /dev/null +++ b/blocks/starredcourses/amd/src/repository.js @@ -0,0 +1,53 @@ +// 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 + * int offset the offset 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 new file mode 100644 index 00000000000..2da98ce2ebd --- /dev/null +++ b/blocks/starredcourses/block_starredcourses.php @@ -0,0 +1,75 @@ +. + +/** + * 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; + } + + $renderable = new \block_starredcourses\output\main(); + $renderer = $this->page->get_renderer('block_starredcourses'); + + $this->content = (object) [ + 'text' => $renderer->render($renderable), + 'footer' => '' + ]; + + return $this->content; + } + + /** + * Locations where block can be displayed. + * + * @return array + */ + public function applicable_formats() { + return array('my' => true); + } +} diff --git a/blocks/starredcourses/classes/external.php b/blocks/starredcourses/classes/external.php new file mode 100644 index 00000000000..f5cb1c2c04d --- /dev/null +++ b/blocks/starredcourses/classes/external.php @@ -0,0 +1,111 @@ +. +/** + * 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) + ]); + } + + /** + * Get users starred courses. + * + * @param int $limit Limit + * @param int $offset Offset + * + * @return array list of courses and warnings + */ + public static function get_starred_courses($limit, $offset) { + global $USER, $PAGE; + + $params = self::validate_parameters(self::get_starred_courses_parameters(), [ + 'limit' => $limit, + 'offset' => $offset + ]); + + $limit = $params['limit']; + $offset = $params['offset']; + + $usercontext = context_user::instance($USER->id); + + self::validate_context($usercontext); + $PAGE->set_context($usercontext); + $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); + + // Get the favourites, by type, for the user. + $favourites = $userservice->find_favourites_by_type('core_course', 'courses', $offset, $limit); + + // 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; + }); + + $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; + } + + /** + * 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/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/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/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 new file mode 100644 index 00000000000..8d7d7f1b9a5 --- /dev/null +++ b/blocks/starredcourses/lang/en/block_starredcourses.php @@ -0,0 +1,30 @@ +. + +/** + * 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['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'; + 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/main.mustache b/blocks/starredcourses/templates/main.mustache new file mode 100644 index 00000000000..b12dc66b356 --- /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..0e35afe39ae --- /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..05d672a2485 --- /dev/null +++ b/blocks/starredcourses/templates/view-cards.mustache @@ -0,0 +1,50 @@ +{{! + This file is part of Moodle - http://moodle.org/ + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public 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" + } + ] + } +}} + diff --git a/blocks/starredcourses/templates/view.mustache b/blocks/starredcourses/templates/view.mustache new file mode 100644 index 00000000000..8492cfb8731 --- /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 new file mode 100644 index 00000000000..6514e19378d --- /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 = 2018051402; +$plugin->requires = 2018050800; +$plugin->component = 'block_starredcourses'; \ No newline at end of file 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 diff --git a/blocks/myoverview/templates/favourite-icon.mustache b/course/templates/favouriteicon.mustache similarity index 82% rename from blocks/myoverview/templates/favourite-icon.mustache rename to course/templates/favouriteicon.mustache index 4cb204bb3eb..3b4831666e5 100644 --- a/blocks/myoverview/templates/favourite-icon.mustache +++ b/course/templates/favouriteicon.mustache @@ -15,7 +15,7 @@ along with Moodle. If not, see . }} {{! - @template block_myoverview/favourite-icon + @template core_course/favouriteicon This template renders the favourite icon for a course. @@ -35,15 +35,15 @@ data-region="is-favourite" aria-hidden="{{^isfavourite}}true{{/isfavourite}}{{#isfavourite}}false{{/isfavourite}}" > - {{#pix}} i/star, core, {{#str}} favourite, block_myoverview {{/str}} {{/pix}} - {{#str}} aria:favourite, block_myoverview {{/str}} + {{#pix}} i/star, core, {{#str}} favourite, core_course {{/str}} {{/pix}} + {{#str}} aria:favourite, core_course {{/str}} - {{#pix}} i/empty, core, {{#str}} notfavourite, block_myoverview {{/str}} {{/pix}} + {{#pix}} i/empty, core, {{#str}} notfavourite, core_course {{/str}} {{/pix}}
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.'; diff --git a/lib/classes/plugin_manager.php b/lib/classes/plugin_manager.php index 6abf53d833e..ca1f30831ee 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( diff --git a/theme/boost/scss/moodle/blocks.scss b/theme/boost/scss/moodle/blocks.scss index c4cc09b048a..80df6e23e4d 100644 --- a/theme/boost/scss/moodle/blocks.scss +++ b/theme/boost/scss/moodle/blocks.scss @@ -77,10 +77,12 @@ $blocks-plus-gutter: $blocks-column-width + ( $grid-gutter-width / 2 ); $card-gutter : $card-deck-margin * 2; -.block_myoverview { - .empty-placeholder-image-lg { - height: 125px; - } +.block .empty-placeholder-image-lg { + height: 125px; +} + +.block_myoverview, +.block_starredcourses { .course-info-container { padding: 0.8rem; } @@ -110,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 94feba3fdee..7dcd40610f8 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -11137,34 +11137,65 @@ div.editor_atto_toolbar button .icon { [data-region="blocks-column"] { width: 100%; } } -.block_myoverview .empty-placeholder-image-lg { +.block .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; } +.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) {