Merge branch 'MDL-63064-master' of git://github.com/lameze/moodle

This commit is contained in:
Andrew Nicols 2018-11-01 09:16:39 +08:00
commit 2badbd52a0
35 changed files with 1015 additions and 35 deletions

View File

@ -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.length<a.limit&&c.allItemsLoaded(a.pageNumber),j[f]=d,x(b,d)})["catch"](e.exception);d.push(i)}),d},l);h.then(function(a,b){return f.replaceNodeContents(d,a,b)})["catch"](e.exception)},z=function(b){d.define(b,[d.events.activate]),b.on(d.events.activate,g.ACTION_ADD_FAVOURITE,function(c,d){var e=a(c.target).closest(g.ACTION_ADD_FAVOURITE),f=p(e);u(b,f),d.originalEvent.preventDefault()}),b.on(d.events.activate,g.ACTION_REMOVE_FAVOURITE,function(c,d){var e=a(c.target).closest(g.ACTION_REMOVE_FAVOURITE),f=p(e);v(b,f),d.originalEvent.preventDefault()}),b.on(d.events.activate,g.FAVOURITE_ICON,function(a,b){b.originalEvent.preventDefault()})},A=function(a,b){j.length>0?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}});
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.length<a.limit&&c.allItemsLoaded(a.pageNumber),l[g]=d,z(b,d)})["catch"](f.exception);d.push(i)}),d},n);h.then(function(a,b){return g.replaceNodeContents(d,a,b)})["catch"](f.exception)},B=function(b){e.define(b,[e.events.activate]),b.on(e.events.activate,i.ACTION_ADD_FAVOURITE,function(c,d){var e=a(c.target).closest(i.ACTION_ADD_FAVOURITE),f=r(e);w(b,f),d.originalEvent.preventDefault()}),b.on(e.events.activate,i.ACTION_REMOVE_FAVOURITE,function(c,d){var e=a(c.target).closest(i.ACTION_REMOVE_FAVOURITE),f=r(e);x(b,f),d.originalEvent.preventDefault()}),b.on(e.events.activate,i.FAVOURITE_ICON,function(a,b){b.originalEvent.preventDefault()})},C=function(a,b){l.length>0?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}});

View File

@ -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);

View File

@ -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';

View File

@ -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}}
<div class="sr-only">
{{#str}} aria:addtofavourites, block_myoverview {{/str}} {{{fullname}}}

View File

@ -39,15 +39,15 @@
<div class="card dashboard-card" role="listitem">
<a href="{{viewurl}}" tabindex="-1">
<div class="card-img dashboard-card-img" style='background-image: url("{{{courseimage}}}");'>
<span class="sr-only">{{#str}}aria:courseimage, block_myoverview{{/str}}</span>
{{> block_myoverview/favourite-icon }}
<span class="sr-only">{{#str}}aria:courseimage, core_course{{/str}}</span>
{{> core_course/favouriteicon }}
</div>
</a>
<div class="card-body pr-1 course-info-container" id="course-info-container-{{id}}">
<div class="d-flex align-items-start">
<div class="card-title mr-2">
<a href="{{viewurl}}">
<span class="sr-only">{{#str}}aria:coursename, block_myoverview{{/str}}</span>
<span class="sr-only">{{#str}}aria:coursename, core_course{{/str}}</span>
{{#shortentext}}40, {{{fullname}}} {{/shortentext}}
</a>
</div>

View File

@ -40,9 +40,9 @@
<div class="row-fluid">
<div class="{{#hasprogress}}col-6 span6{{/hasprogress}}{{^hasprogress}}col-11 span11{{/hasprogress}} p-l-0">
<div class="d-flex align-items-center">
{{> block_myoverview/favourite-icon }}
{{> core_course/favouriteicon }}
<a href="{{viewurl}}">
<span class="sr-only">{{#str}}aria:coursename, block_myoverview{{/str}}</span>
<span class="sr-only">{{#str}}aria:coursename, core_course{{/str}}</span>
{{{fullname}}}
</a>
</div>

View File

@ -40,16 +40,16 @@
<div class="row-fluid d-flex">
<a href="{{viewurl}}" class="col-sm-4 col-xl-3 span4 position-relative" tabindex="-1">
<div class="position-absolute">
{{> block_myoverview/favourite-icon }}
{{> core_course/favouriteicon }}
</div>
<div class="card-img-top summaryimage" style='background-image: url("{{{courseimage}}}");'>
<span class="sr-only">{{#str}}aria:courseimage, block_myoverview{{/str}}</span>
<span class="sr-only">{{#str}}aria:courseimage, core_course{{/str}}</span>
</div>
</a>
<div class="col-sm-8 col-xl-9 span8 align-self-stretch d-flex flex-column">
<div class="d-flex">
<a href="{{viewurl}}">
<span class="sr-only">{{#str}}aria:coursename, block_myoverview{{/str}}</span>
<span class="sr-only">{{#str}}aria:coursename, core_course{{/str}}</span>
<h4>{{{fullname}}}</h4>
</a>
{{> block_myoverview/course-action-menu }}

View File

@ -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}});

View File

@ -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}});

View File

@ -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 <http://www.gnu.org/licenses/>.
/**
* Javascript to initialise the starred courses block.
*
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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
};
});

View File

@ -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 <http://www.gnu.org/licenses/>.
/**
* A javascript module to retrieve user's starred courses.
*
* @package block_starredcourses
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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
};
});

View File

@ -0,0 +1,75 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Starred courses block.
*
* @package block_starredcourses
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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 <simey@moodle.com>
* @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);
}
}

View File

@ -0,0 +1,111 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Starred courses block external API
*
* @package block_starredcourses
* @category external
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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 <simey@moodle.com>
* @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());
}
}

View File

@ -0,0 +1,59 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class containing data for starred courses block.
*
* @package block_starredcourses
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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 <simey@moodle.com>
* @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
];
}
}

View File

@ -0,0 +1,48 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Starred courses block renderer.
*
* @package block_starredcourses
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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 <simey@moodle.com>
* @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));
}
}

View File

@ -0,0 +1,45 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy Subsystem implementation for block_starredcourses.
*
* @package block_starredcourses
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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 <simey@moodle.com>
* @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';
}
}

View File

@ -0,0 +1,48 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Starred courses block capabilities.
*
* @package block_starredcourses
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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'
),
);

View File

@ -0,0 +1,38 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* File description.
*
* @package block_starredcourses
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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,
),
);

View File

@ -0,0 +1,30 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Starred courses block language strings.
*
* @package block_starredcourses
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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';

View File

@ -0,0 +1,49 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="157 -1305 148 125" preserveAspectRatio="xMinYMid meet">
<defs>
<style>
.cls-1 {
clip-path: url(#clip-Courses);
}
.cls-2 {
fill: #eee;
}
.cls-3 {
fill: #c4c8cc;
}
.cls-4 {
fill: #fff;
}
</style>
<clipPath id="clip-Courses">
<rect x="157" y="-1305" width="148" height="125"/>
</clipPath>
</defs>
<g id="Courses" class="cls-1">
<g id="Group_44" data-name="Group 44" transform="translate(-268 -1781)">
<ellipse id="Ellipse_41" data-name="Ellipse 41" class="cls-2" cx="74" cy="14.785" rx="74" ry="14.785" transform="translate(425 571.43)"/>
<rect id="Rectangle_87" data-name="Rectangle 87" class="cls-3" width="95.097" height="110.215" transform="translate(451.909 476)"/>
<g id="Group_43" data-name="Group 43" transform="translate(464.04 494)">
<rect id="Rectangle_88" data-name="Rectangle 88" class="cls-4" width="31.043" height="34" transform="translate(0)"/>
<rect id="Rectangle_89" data-name="Rectangle 89" class="cls-4" width="31.043" height="34" transform="translate(0 42)"/>
<rect id="Rectangle_90" data-name="Rectangle 90" class="cls-4" width="31.067" height="34" transform="translate(39.005)"/>
<rect id="Rectangle_91" data-name="Rectangle 91" class="cls-4" width="31.067" height="34" transform="translate(39.005 42)"/>
<rect id="Rectangle_92" data-name="Rectangle 92" class="cls-3" width="23.023" height="3.18" transform="translate(3.081 16.549)"/>
<rect id="Rectangle_93" data-name="Rectangle 93" class="cls-3" width="23.023" height="3.18" transform="translate(3.081 58.549)"/>
<rect id="Rectangle_94" data-name="Rectangle 94" class="cls-3" width="23.023" height="3.18" transform="translate(43.122 16.549)"/>
<rect id="Rectangle_95" data-name="Rectangle 95" class="cls-3" width="23.023" height="3.18" transform="translate(43.122 58.549)"/>
<rect id="Rectangle_96" data-name="Rectangle 96" class="cls-3" width="14.014" height="3.18" transform="translate(3.081 21.825)"/>
<rect id="Rectangle_97" data-name="Rectangle 97" class="cls-3" width="18.845" height="3.18" transform="translate(3.081 26.825)"/>
<rect id="Rectangle_98" data-name="Rectangle 98" class="cls-3" width="14.014" height="3.18" transform="translate(3.081 63.825)"/>
<rect id="Rectangle_99" data-name="Rectangle 99" class="cls-3" width="18.845" height="3.18" transform="translate(3.081 68.825)"/>
<rect id="Rectangle_100" data-name="Rectangle 100" class="cls-3" width="14.014" height="3.18" transform="translate(43.122 21.825)"/>
<rect id="Rectangle_101" data-name="Rectangle 101" class="cls-3" width="18.845" height="3.18" transform="translate(43.122 26.825)"/>
<rect id="Rectangle_102" data-name="Rectangle 102" class="cls-3" width="14.014" height="3.18" transform="translate(43.122 63.825)"/>
<rect id="Rectangle_103" data-name="Rectangle 103" class="cls-3" width="18.845" height="3.18" transform="translate(43.122 68.825)"/>
<ellipse id="Ellipse_42" data-name="Ellipse 42" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(3.003 3.55)"/>
<ellipse id="Ellipse_43" data-name="Ellipse 43" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(3.003 45.55)"/>
<ellipse id="Ellipse_44" data-name="Ellipse 44" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(43.044 3.55)"/>
<ellipse id="Ellipse_45" data-name="Ellipse 45" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(43.044 45.55)"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@template block_starredcourses/main
This template renders the main content area for the starred courses block.
Example context (json):
{}
}}
<div id="block-starredcourses-{{uniqid}}" class="block-starredcourses" data-region="starred-courses">
<div class="container-fluid p-0">
{{> block_starredcourses/view }}
</div>
</div>
{{#js}}
require(['block_starredcourses/main'], function(Main) {
Main.init('#block-starredcourses-{{uniqid}}');
});
{{/js}}

View File

@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@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"
}
}}
<div class="text-xs-center text-center m-t-3" data-region="empty-message">
<img class="empty-placeholder-image-lg"
src="{{nocoursesimg}}"
alt="{{#str}} nocourses, block_starredcourses {{/str}}"
role="presentation">
<p class="text-muted mt-3">{{#str}} nocourses, block_starredcourses {{/str}}</p>
</div>

View File

@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@template block_starredcourses/placeholder-course
This template renders an course card item loading placeholder for the starred courses block.
Example context (json):
{}
}}
<div class="card dashboard-card border-0">
<div class="card-img-top bg-pulse-grey w-100" style="height: 7rem">
</div>
<div class="card-body recent-course-info-container">
<div class="bg-pulse-grey w-100 m-b-3" style="height: 1rem"></div>
</div>
</div>

View File

@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@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"
}
]
}
}}
<div class="card-deck dashboard-card-deck" role="list">
{{#courses}}
<div class="card dashboard-card m-b-1" role="listitem">
<a href="{{viewurl}}" tabindex="-1">
<div class="card-img dashboard-card-img" style='background-image: url("{{{courseimage}}}");'>
<span class="sr-only">{{#str}}aria:courseimage, core_course{{/str}}</span>
{{>core_course/favouriteicon }}
</div>
</a>
<div class="card-body pr-1 course-info-container" id="course-info-container-{{id}}">
<div class="d-flex align-items-start">
<div class="card-title mr-2">
<a href="{{viewurl}}">
<span class="sr-only">{{#str}}aria:coursename, core_course{{/str}}</span>
{{#shortentext}}40, {{{fullname}}} {{/shortentext}}
</a>
</div>
</div>
</div>
</div>
{{/courses}}
</div>

View File

@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@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"
}
}}
<div id="starred-courses-view-{{uniqid}}"
data-region="starred-courses-view"
data-nocoursesimg="{{nocoursesimg}}">
<div data-region="starred-courses-view-content">
<div data-region="starred-courses-loading-placeholder">
<div class="card-deck dashboard-card-deck">
{{> block_starredcourses/placeholder-course }}
{{> block_starredcourses/placeholder-course }}
{{> block_starredcourses/placeholder-course }}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,28 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Starred courses block version details.
*
* @package block_starredcourses
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @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';

1
course/amd/build/events.min.js vendored Normal file
View File

@ -0,0 +1 @@
define([],function(){return{favourited:"core_course:favourited",unfavorited:"core_course:unfavorited"}});

29
course/amd/src/events.js Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
/**
* Contain the events the course component can trigger.
*
* @module core_course/events
* @package core_course
* @copyright 2018 Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define([], function() {
return {
favourited: 'core_course:favourited',
unfavorited: 'core_course:unfavorited',
};
});

View File

@ -15,7 +15,7 @@
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@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}}
<span class="sr-only">{{#str}} aria:favourite, block_myoverview {{/str}}</span>
{{#pix}} i/star, core, {{#str}} favourite, core_course {{/str}} {{/pix}}
<span class="sr-only">{{#str}} aria:favourite, core_course {{/str}}</span>
</span>
<span
{{#isfavourite}}class="hidden"{{/isfavourite}}
data-region="not-favourite"
aria-hidden="{{^isfavourite}}false{{/isfavourite}}{{#isfavourite}}true{{/isfavourite}}"
>
{{#pix}} i/empty, core, {{#str}} notfavourite, block_myoverview {{/str}} {{/pix}}
{{#pix}} i/empty, core, {{#str}} notfavourite, core_course {{/str}} {{/pix}}
</span>
</div>
</div>

View File

@ -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.';

View File

@ -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(

View File

@ -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;

View File

@ -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;

View File

@ -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)";
}
}
}

View File

@ -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) {