diff --git a/blocks/calendar_upcoming/block_calendar_upcoming.php b/blocks/calendar_upcoming/block_calendar_upcoming.php
index 0bc46c91904..0d6fc79c132 100644
--- a/blocks/calendar_upcoming/block_calendar_upcoming.php
+++ b/blocks/calendar_upcoming/block_calendar_upcoming.php
@@ -61,7 +61,7 @@ class block_calendar_upcoming extends block_base {
$courses = [$course->id => $course];
}
$calendar = new calendar_information(0, 0, 0, time());
- $calendar->set_sources($course, $courses);
+ $calendar->set_sources($course, $courses, $this->page->category);
list($data, $template) = calendar_get_view($calendar, 'upcoming_mini');
@@ -78,5 +78,3 @@ class block_calendar_upcoming extends block_base {
return $this->content;
}
}
-
-
diff --git a/calendar/amd/build/calendar.min.js b/calendar/amd/build/calendar.min.js
index a21c4753d0f..ffa3f2ed8d5 100644
--- a/calendar/amd/build/calendar.min.js
+++ b/calendar/amd/build/calendar.min.js
@@ -1 +1 @@
-define(["jquery","core/ajax","core/str","core/templates","core/notification","core/custom_interaction_events","core/modal_events","core/modal_factory","core_calendar/modal_event_form","core_calendar/summary_modal","core_calendar/repository","core_calendar/events","core_calendar/view_manager","core_calendar/crud","core_calendar/selectors"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={ROOT:"[data-region='calendar']",DAY:"[data-region='day']",EVENT_ITEM:"[data-region='event-item']",EVENT_LINK:"[data-action='view-event']",NEW_EVENT_BUTTON:"[data-action='new-event-button']",DAY_CONTENT:"[data-region='day-content']",LOADING_ICON:".loading-icon",VIEW_DAY_LINK:"[data-action='view-day-link']",CALENDAR_MONTH_WRAPPER:".calendarwrapper",TODAY:".today"},q=function(a){var b="type"+a;return c.get_string(b,"core_calendar").then(function(a){return a})},r=function(a){switch(a){case"user":return"calendar_event_user";case"site":return"calendar_event_site";case"group":return"calendar_event_group";case"category":return"calendar_event_category";case"course":return"calendar_event_course";default:return"calendar_event_course"}},s=function(a){var b="";k.getEventById(a).then(function(c){if(!c.event)throw new Error("Error encountered while trying to fetch calendar event with ID: "+a);var d=c.event;return b=r(d.eventtype),q(d.eventtype).then(function(a){return d.eventtype=a,d})}).then(function(a){var c={title:a.name,type:j.TYPE,body:d.render("core_calendar/event_summary_body",a),templateContext:{canedit:a.canedit,candelete:a.candelete,headerclasses:b,isactionevent:a.isactionevent,url:a.url}};return h.create(c)}).done(function(a){a.getRoot().on(g.hidden,function(){a.destroy()}),a.show()}).fail(e.exception)},t=function(b,c,f,g){var h=null,i=g.attr("data-day-timestamp");f&&(h=f.attr("data-day-timestamp")),f&&h==i||d.render("core/loading",{}).then(function(a,b){g.find(p.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(g,a,b),f&&(f.find(p.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(f,a,b))}).then(function(){return k.updateEventStartDay(c,i)}).then(function(){a("body").trigger(l.eventMoved,[c,f,g])}).always(function(){var a=g.find(p.LOADING_ICON);if(g.find(p.DAY_CONTENT).removeClass("hidden"),d.replaceNode(a,"",""),f){var b=f.find(p.LOADING_ICON);f.find(p.DAY_CONTENT).removeClass("hidden"),d.replaceNode(b,"","")}}).fail(e.exception)},u=function(b,c){var d=a("body");d.on(l.created,function(){m.reloadCurrentMonth(b)}),d.on(l.deleted,function(){m.reloadCurrentMonth(b)}),d.on(l.updated,function(){m.reloadCurrentMonth(b)}),d.on(l.editActionEvent,function(a,b){window.location.assign(b)}),d.on(l.moveEvent,t),d.on(l.eventMoved,function(){m.reloadCurrentMonth(b)}),c.then(function(a){d.on(l.editEvent,function(c,d){var e=b.find(o.wrapper);a.setEventId(d),a.setContextId(e.data("contextId")),a.show()})}).fail(e.exception)},v=function(b){b.on("click",p.EVENT_ITEM,function(b){b.preventDefault(),b.stopPropagation();var c=a(b.target),d=null,e=c.closest(p.EVENT_LINK);d=e.length?e.data("eventId"):c.find(p.EVENT_LINK).data("eventId"),s(d)}),b.on("change",o.elements.courseSelector,function(){var c=a(this),d=c.val();m.reloadCurrentMonth(b,d,null).then(function(){return b.find(o.elements.courseSelector).val(d)}).fail(e.exception)});var c=n.registerEventFormModal(b);u(b,c),b.on("click",p.DAY,function(b){var d=a(b.target);if(!d.is(p.VIEW_DAY_LINK)){var f=a(this).attr("data-new-event-timestamp");c.then(function(a){var b=d.closest(o.wrapper);a.setCourseId(b.data("courseid"));var c=b.data("categoryid");"undefined"!=typeof c&&a.setCategoryId(c),a.setContextId(b.data("contextId")),a.setStartTime(f),a.show()}).fail(e.exception),b.preventDefault()}})};return{init:function(b){b=a(b),m.init(b),v(b)}}});
\ No newline at end of file
+define(["jquery","core/ajax","core/str","core/templates","core/notification","core/custom_interaction_events","core/modal_events","core/modal_factory","core_calendar/modal_event_form","core_calendar/summary_modal","core_calendar/repository","core_calendar/events","core_calendar/view_manager","core_calendar/crud","core_calendar/selectors"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={ROOT:"[data-region='calendar']",DAY:"[data-region='day']",NEW_EVENT_BUTTON:"[data-action='new-event-button']",DAY_CONTENT:"[data-region='day-content']",LOADING_ICON:".loading-icon",VIEW_DAY_LINK:"[data-action='view-day-link']",CALENDAR_MONTH_WRAPPER:".calendarwrapper",TODAY:".today"},q=function(b,c,f,g){var h=null,i=g.attr("data-day-timestamp");f&&(h=f.attr("data-day-timestamp")),f&&h==i||d.render("core/loading",{}).then(function(a,b){g.find(p.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(g,a,b),f&&(f.find(p.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(f,a,b))}).then(function(){return k.updateEventStartDay(c,i)}).then(function(){a("body").trigger(l.eventMoved,[c,f,g])}).always(function(){var a=g.find(p.LOADING_ICON);if(g.find(p.DAY_CONTENT).removeClass("hidden"),d.replaceNode(a,"",""),f){var b=f.find(p.LOADING_ICON);f.find(p.DAY_CONTENT).removeClass("hidden"),d.replaceNode(b,"","")}}).fail(e.exception)},r=function(b,c){var d=a("body");d.on(l.created,function(){m.reloadCurrentMonth(b)}),d.on(l.deleted,function(){m.reloadCurrentMonth(b)}),d.on(l.updated,function(){m.reloadCurrentMonth(b)}),d.on(l.editActionEvent,function(a,b){window.location.assign(b)}),d.on(l.moveEvent,q),d.on(l.eventMoved,function(){m.reloadCurrentMonth(b)}),n.registerEditListeners(b,c)},s=function(b){b.on("change",o.elements.courseSelector,function(){var c=a(this),d=c.val();m.reloadCurrentMonth(b,d,null).then(function(){return b.find(o.elements.courseSelector).val(d)}).fail(e.exception)});var c=n.registerEventFormModal(b);r(b,c),b.on("click",p.DAY,function(b){var d=a(b.target);if(!d.is(p.VIEW_DAY_LINK)){var f=a(this).attr("data-new-event-timestamp");c.then(function(a){var b=d.closest(o.wrapper);a.setCourseId(b.data("courseid"));var c=b.data("categoryid");"undefined"!=typeof c&&a.setCategoryId(c),a.setContextId(b.data("contextId")),a.setStartTime(f),a.show()}).fail(e.exception),b.preventDefault()}})};return{init:function(b){b=a(b),m.init(b),s(b)}}});
\ No newline at end of file
diff --git a/calendar/amd/build/calendar_view.min.js b/calendar/amd/build/calendar_view.min.js
index 9a1ec732d2c..18416c3e090 100644
--- a/calendar/amd/build/calendar_view.min.js
+++ b/calendar/amd/build/calendar_view.min.js
@@ -1 +1 @@
-define(["jquery","core/str","core/notification","core_calendar/selectors","core_calendar/events","core_calendar/view_manager","core_calendar/repository","core/modal_factory","core_calendar/modal_event_form","core/modal_events","core_calendar/crud"],function(a,b,c,d,e,f,g,h,i,j,k){var l=function(b,g){var h=a("body");k.registerEventFormModal(b),k.registerRemove(b);var i="reloadCurrent"+g.charAt(0).toUpperCase()+g.slice(1);h.on(e.created,function(){f[i](b)}),h.on(e.deleted,function(){f[i](b)}),h.on(e.updated,function(){f[i](b)}),b.on("change",d.courseSelector,function(){var e=a(this),g=e.val();f[i](b,g,null).then(function(){return b.find(d.courseSelector).val(g)}).fail(c.exception)}),h.on(e.filterChanged,function(a,c){var e=b.find(d.eventType[c.type]);1==c.hidden?e.addClass("hidden"):e.removeClass("hidden")})};return{init:function(b,c){b=a(b),f.init(b,c),l(b,c)}}});
\ No newline at end of file
+define(["jquery","core/str","core/notification","core_calendar/selectors","core_calendar/events","core_calendar/view_manager","core_calendar/repository","core/modal_factory","core_calendar/modal_event_form","core/modal_events","core_calendar/crud"],function(a,b,c,d,e,f,g,h,i,j,k){var l=function(b,g){var h=a("body");k.registerRemove(b);var i="reloadCurrent"+g.charAt(0).toUpperCase()+g.slice(1);h.on(e.created,function(){f[i](b)}),h.on(e.deleted,function(){f[i](b)}),h.on(e.updated,function(){f[i](b)}),b.on("change",d.courseSelector,function(){var e=a(this),g=e.val();f[i](b,g,null).then(function(){return b.find(d.courseSelector).val(g)}).then(function(){window.history.pushState({},"","?view=upcoming&course="+g)}).fail(c.exception)}),h.on(e.filterChanged,function(a,c){var e=b.find(d.eventType[c.type]);1==c.hidden?e.addClass("hidden"):e.removeClass("hidden")});var j=k.registerEventFormModal(b);k.registerEditListeners(b,j)};return{init:function(b,c){b=a(b),f.init(b,c),l(b,c)}}});
\ No newline at end of file
diff --git a/calendar/amd/build/crud.min.js b/calendar/amd/build/crud.min.js
index 7ba0606672e..57b54a4a182 100644
--- a/calendar/amd/build/crud.min.js
+++ b/calendar/amd/build/crud.min.js
@@ -1 +1 @@
-define(["jquery","core/str","core/notification","core/custom_interaction_events","core/modal","core/modal_registry","core/modal_factory","core/modal_events","core_calendar/modal_event_form","core_calendar/repository","core_calendar/events","core_calendar/modal_delete","core_calendar/selectors"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){function n(d,e,f){var i=[{key:"deleteevent",component:"calendar"}];f=parseInt(f,10);var m,n=f>1;n?(i.push({key:"confirmeventseriesdelete",component:"calendar",param:{name:e,count:f}}),m=g.create({type:l.TYPE})):(i.push({key:"confirmeventdelete",component:"calendar",param:e}),m=g.create({type:g.types.SAVE_CANCEL})),m.then(function(a){a.show()}).fail(c.exception);var o=b.get_strings(i),p=a.when(o,m).then(function(b,e){return e.setTitle(b[0]),e.setBody(b[1]),n||e.setSaveButtonText(b[0]),e.getRoot().on(h.save,function(){j.deleteEvent(d,!1).then(function(){a("body").trigger(k.deleted,[d,!1])})["catch"](c.exception)}),e.getRoot().on(k.deleteAll,function(){j.deleteEvent(d,!0).then(function(){a("body").trigger(k.deleted,[d,!0])})["catch"](c.exception)}),e}).fail(c.exception);return p}function o(b){b.on("click",m.actions.remove,function(b){var c=a(this).closest(m.eventItem),d=c.data("eventId"),e=c.data("eventTitle"),f=c.data("eventCount");n(d,e,f),b.preventDefault()})}var p=function(b){var d=g.create({type:i.TYPE,large:!0});return b.on("click",m.actions.create,function(a){d.then(function(a){var c=b.find(m.wrapper),d=c.data("categoryid");"undefined"!=typeof d&&a.setCategoryId(d);var e=b.find(m.today),f=b.find(m.day);!e.length&&f.length&&a.setStartTime(f.data("newEventTimestamp")),a.setContextId(c.data("contextId")),a.setCourseId(c.data("courseid")),a.show()}).fail(c.exception),a.preventDefault()}),b.on("click",m.actions.edit,function(b){b.preventDefault();var e=a(b.currentTarget),f=e.closest(m.wrapper),g=e.closest(m.eventItem);d.then(function(a){a.setEventId(g.data("eventId")),a.setContextId(f.data("contextId")),a.show()}).fail(c.exception)}),d};return{registerRemove:o,registerEventFormModal:p}});
\ No newline at end of file
+define(["jquery","core/str","core/notification","core/custom_interaction_events","core/modal","core/modal_registry","core/modal_factory","core/modal_events","core_calendar/modal_event_form","core_calendar/repository","core_calendar/events","core_calendar/modal_delete","core_calendar/selectors"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){function n(d,e,f){var i=[{key:"deleteevent",component:"calendar"}];f=parseInt(f,10);var m,n=f>1;n?(i.push({key:"confirmeventseriesdelete",component:"calendar",param:{name:e,count:f}}),m=g.create({type:l.TYPE})):(i.push({key:"confirmeventdelete",component:"calendar",param:e}),m=g.create({type:g.types.SAVE_CANCEL})),m.then(function(a){a.show()}).fail(c.exception);var o=b.get_strings(i),p=a.when(o,m).then(function(b,e){return e.setTitle(b[0]),e.setBody(b[1]),n||e.setSaveButtonText(b[0]),e.getRoot().on(h.save,function(){j.deleteEvent(d,!1).then(function(){a("body").trigger(k.deleted,[d,!1])})["catch"](c.exception)}),e.getRoot().on(k.deleteAll,function(){j.deleteEvent(d,!0).then(function(){a("body").trigger(k.deleted,[d,!0])})["catch"](c.exception)}),e}).fail(c.exception);return p}function o(b){b.on("click",m.actions.remove,function(b){var c=a(this).closest(m.eventItem),d=c.data("eventId"),e=c.data("eventTitle"),f=c.data("eventCount");n(d,e,f),b.preventDefault()})}function p(b,d){return d.then(function(c){a("body").on(k.editEvent,function(a,d){var e=b.find(m.wrapper);c.setEventId(d),c.setContextId(e.data("contextId")),c.show(),a.stopImmediatePropagation()})}).fail(c.exception),d}var q=function(b){var d=g.create({type:i.TYPE,large:!0});return b.on("click",m.actions.create,function(a){d.then(function(a){var c=b.find(m.wrapper),d=c.data("categoryid");"undefined"!=typeof d&&a.setCategoryId(d);var e=b.find(m.today),f=b.find(m.day);!e.length&&f.length&&a.setStartTime(f.data("newEventTimestamp")),a.setContextId(c.data("contextId")),a.setCourseId(c.data("courseid")),a.show()}).fail(c.exception),a.preventDefault()}),b.on("click",m.actions.edit,function(b){b.preventDefault();var e=a(b.currentTarget),f=e.closest(m.wrapper),g=e.closest(m.eventItem);d.then(function(a){a.setEventId(g.data("eventId")),a.setContextId(f.data("contextId")),a.show(),b.stopImmediatePropagation()}).fail(c.exception)}),d};return{registerRemove:o,registerEditListeners:p,registerEventFormModal:q}});
\ No newline at end of file
diff --git a/calendar/amd/build/repository.min.js b/calendar/amd/build/repository.min.js
index 388f46e6d95..2c8f751c1ab 100644
--- a/calendar/amd/build/repository.min.js
+++ b/calendar/amd/build/repository.min.js
@@ -1 +1 @@
-define(["jquery","core/ajax"],function(a,b){var c=function(a,c){"undefined"==typeof c&&(c=!1);var d={methodname:"core_calendar_delete_calendar_events",args:{events:[{eventid:a,repeat:c}]}};return b.call([d])[0]},d=function(a){var c={methodname:"core_calendar_get_calendar_event_by_id",args:{eventid:a}};return b.call([c])[0]},e=function(a){var c={methodname:"core_calendar_submit_create_update_form",args:{formdata:a}};return b.call([c])[0]},f=function(a,c,d,e,f){var g={methodname:"core_calendar_get_calendar_monthly_view",args:{year:a,month:c,courseid:d,categoryid:e,includenavigation:f}};return b.call([g])[0]},g=function(a,c,d,e,f){var g={methodname:"core_calendar_get_calendar_day_view",args:{year:a,month:c,day:d,courseid:e,categoryid:f}};return b.call([g])[0]},h=function(a,c){var d={methodname:"core_calendar_update_event_start_day",args:{eventid:a,daytimestamp:c}};return b.call([d])[0]},i=function(a){var c={methodname:"core_calendar_get_calendar_upcoming_view",args:{courseid:a}};return b.call([c])[0]};return{getEventById:d,deleteEvent:c,updateEventStartDay:h,submitCreateUpdateForm:e,getCalendarMonthData:f,getCalendarDayData:g,getCalendarUpcomingData:i}});
\ No newline at end of file
+define(["jquery","core/ajax"],function(a,b){var c=function(a,c){"undefined"==typeof c&&(c=!1);var d={methodname:"core_calendar_delete_calendar_events",args:{events:[{eventid:a,repeat:c}]}};return b.call([d])[0]},d=function(a){var c={methodname:"core_calendar_get_calendar_event_by_id",args:{eventid:a}};return b.call([c])[0]},e=function(a){var c={methodname:"core_calendar_submit_create_update_form",args:{formdata:a}};return b.call([c])[0]},f=function(a,c,d,e,f){var g={methodname:"core_calendar_get_calendar_monthly_view",args:{year:a,month:c,courseid:d,categoryid:e,includenavigation:f}};return b.call([g])[0]},g=function(a,c,d,e,f){var g={methodname:"core_calendar_get_calendar_day_view",args:{year:a,month:c,day:d,courseid:e,categoryid:f}};return b.call([g])[0]},h=function(a,c){var d={methodname:"core_calendar_update_event_start_day",args:{eventid:a,daytimestamp:c}};return b.call([d])[0]},i=function(a,c){var d={methodname:"core_calendar_get_calendar_upcoming_view",args:{courseid:a,categoryid:c}};return b.call([d])[0]};return{getEventById:d,deleteEvent:c,updateEventStartDay:h,submitCreateUpdateForm:e,getCalendarMonthData:f,getCalendarDayData:g,getCalendarUpcomingData:i}});
\ No newline at end of file
diff --git a/calendar/amd/build/selectors.min.js b/calendar/amd/build/selectors.min.js
index 278cd658d3f..5bb76436732 100644
--- a/calendar/amd/build/selectors.min.js
+++ b/calendar/amd/build/selectors.min.js
@@ -1 +1 @@
-define([],function(){return{eventFilterItem:"[data-action='filter-event-type']",eventType:{site:"[data-eventtype-site]",category:"[data-eventtype-category]",course:"[data-eventtype-course]",group:"[data-eventtype-group]",user:"[data-eventtype-user]"},popoverType:{site:"[data-popover-eventtype-site]",category:"[data-popover-eventtype-category]",course:"[data-popover-eventtype-course]",group:"[data-popover-eventtype-group]",user:"[data-popover-eventtype-user]"},calendarPeriods:{month:"[data-period='month']"},courseSelector:'select[name="course"]',actions:{create:'[data-action="new-event-button"]',edit:'[data-action="edit"]',remove:'[data-action="delete"]'},elements:{courseSelector:'select[name="course"]'},today:".today",day:'[data-region="day"]',wrapper:".calendarwrapper",eventItem:'[data-type="event"]'}});
\ No newline at end of file
+define([],function(){return{eventFilterItem:"[data-action='filter-event-type']",eventType:{site:"[data-eventtype-site]",category:"[data-eventtype-category]",course:"[data-eventtype-course]",group:"[data-eventtype-group]",user:"[data-eventtype-user]"},popoverType:{site:"[data-popover-eventtype-site]",category:"[data-popover-eventtype-category]",course:"[data-popover-eventtype-course]",group:"[data-popover-eventtype-group]",user:"[data-popover-eventtype-user]"},calendarPeriods:{month:"[data-period='month']"},courseSelector:'select[name="course"]',actions:{create:'[data-action="new-event-button"]',edit:'[data-action="edit"]',remove:'[data-action="delete"]',viewEvent:'[data-action="view-event"]'},elements:{courseSelector:'select[name="course"]'},today:".today",day:'[data-region="day"]',wrapper:".calendarwrapper",eventItem:'[data-type="event"]',links:{navLink:".calendarwrapper .arrow_link",eventLink:"[data-region='event-item']"},containers:{loadingIcon:'[data-region="overlay-icon-container"]'}}});
\ No newline at end of file
diff --git a/calendar/amd/build/view_manager.min.js b/calendar/amd/build/view_manager.min.js
index 5d76b1d11fc..7313a59bfdd 100644
--- a/calendar/amd/build/view_manager.min.js
+++ b/calendar/amd/build/view_manager.min.js
@@ -1 +1 @@
-define(["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events","core_calendar/selectors"],function(a,b,c,d,e,f){var g={CALENDAR_NAV_LINK:".calendarwrapper .arrow_link",LOADING_ICON_CONTAINER:'[data-region="overlay-icon-container"]'},h=function(b){b=a(b),b.on("click",g.CALENDAR_NAV_LINK,function(c){var d=b.find(f.wrapper),e=d.data("view"),g=d.data("courseid"),h=d.data("categoryid"),i=a(c.currentTarget);"month"===e?(j(b,i.attr("href"),i.data("year"),i.data("month"),g,h),c.preventDefault()):"day"===e&&(n(b,i.attr("href"),i.data("year"),i.data("month"),i.data("day"),g,h),c.preventDefault())})},i=function(g,h,i,j,k,l){o(g),l=l||g.find(f.wrapper),M.util.js_pending([g.get("id"),h,i,j].join("-"));var m=g.data("includenavigation");return d.getCalendarMonthData(h,i,j,k,m).then(function(a){return b.render(g.attr("data-template"),a)}).then(function(a,c){return b.replaceNode(l,a,c)}).then(function(){a("body").trigger(e.viewUpdated)}).always(function(){return M.util.js_complete([g.get("id"),h,i,j].join("-")),p(g)}).fail(c.exception)},j=function(b,c,d,f,g,h){return i(b,d,f,g,h).then(function(){return c.length&&"#"!==c&&window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(e.monthChanged,[d,f,g,h]),arguments})},k=function(a,b,c){var d=a.find(f.wrapper).data("year"),e=a.find(f.wrapper).data("month");return"undefined"==typeof b&&(b=a.find(f.wrapper).data("courseid")),"undefined"==typeof c&&(c=a.find(f.wrapper).data("categoryid")),i(a,d,e,b,c)},l=function(g,h,i,j,k,l,m){o(g),m=m||g.find(f.wrapper),M.util.js_pending([g.get("id"),h,i,j,k,l].join("-"));var n=g.data("includenavigation");return d.getCalendarDayData(h,i,j,k,l,n).then(function(a){return b.render(g.attr("data-template"),a)}).then(function(a,c){return b.replaceNode(m,a,c)}).then(function(){a("body").trigger(e.viewUpdated)}).always(function(){return M.util.js_complete([g.get("id"),h,i,j,k,l].join("-")),p(g)}).fail(c.exception)},m=function(a,b,c){var d=a.find(f.wrapper),e=d.data("year"),g=d.data("month"),h=d.data("day");return b||(b=a.find(f.wrapper).data("courseid")),"undefined"==typeof c&&(c=a.find(f.wrapper).data("categoryid")),l(a,e,g,h,b,c)},n=function(b,c,d,f,g,h,i){return l(b,d,f,g,h,i).then(function(){return c.length&&"#"!==c&&window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(e.dayChanged,[d,f,g,h,i]),arguments})},o=function(a){var b=a.find(g.LOADING_ICON_CONTAINER);b.removeClass("hidden")},p=function(a){var b=a.find(g.LOADING_ICON_CONTAINER);b.addClass("hidden")},q=function(g,h){o(g);var i=g.find(f.wrapper);return h||(h=g.find(f.wrapper).data("courseid")),d.getCalendarUpcomingData(h).then(function(a){return b.render(g.attr("data-template"),a)}).then(function(a,c){return window.history.replaceState(null,null,"?view=upcoming&course="+h),b.replaceNode(i,a,c)}).then(function(){a("body").trigger(e.viewUpdated)}).always(function(){return p(g)}).fail(c.exception)};return{init:function(a){h(a)},reloadCurrentMonth:k,changeMonth:j,refreshMonthContent:i,reloadCurrentDay:m,changeDay:n,refreshDayContent:l,reloadCurrentUpcoming:q}});
\ No newline at end of file
+define(["jquery","core/templates","core/str","core/notification","core_calendar/repository","core_calendar/events","core_calendar/selectors","core/modal_factory","core/modal_events","core_calendar/summary_modal"],function(a,b,c,d,e,f,g,h,i,j){var k=function(b){b=a(b),b.on("click",g.links.eventLink,function(b){var c,d=a(b.target),e=null;c=d.is(g.actions.viewEvent)?d:d.closest(g.actions.viewEvent),e=c.length?c.data("eventId"):d.find(g.actions.viewEvent).data("eventId"),e&&(b.preventDefault(),b.stopPropagation(),v(e))}),b.on("click",g.links.navLink,function(c){var d=b.find(g.wrapper),e=d.data("view"),f=d.data("courseid"),h=d.data("categoryid"),i=a(c.currentTarget);"month"===e?(m(b,i.attr("href"),i.data("year"),i.data("month"),f,h),c.preventDefault()):"day"===e&&(q(b,i.attr("href"),i.data("year"),i.data("month"),i.data("day"),f,h),c.preventDefault())})},l=function(c,h,i,j,k,l){r(c),l=l||c.find(g.wrapper),M.util.js_pending([c.get("id"),h,i,j].join("-"));var m=c.data("includenavigation");return e.getCalendarMonthData(h,i,j,k,m).then(function(a){return b.render(c.attr("data-template"),a)}).then(function(a,c){return b.replaceNode(l,a,c)}).then(function(){a("body").trigger(f.viewUpdated)}).always(function(){return M.util.js_complete([c.get("id"),h,i,j].join("-")),s(c)}).fail(d.exception)},m=function(b,c,d,e,g,h){return l(b,d,e,g,h).then(function(){return c.length&&"#"!==c&&window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(f.monthChanged,[d,e,g,h]),arguments})},n=function(a,b,c){var d=a.find(g.wrapper).data("year"),e=a.find(g.wrapper).data("month");return"undefined"==typeof b&&(b=a.find(g.wrapper).data("courseid")),"undefined"==typeof c&&(c=a.find(g.wrapper).data("categoryid")),l(a,d,e,b,c)},o=function(c,h,i,j,k,l,m){r(c),m=m||c.find(g.wrapper),M.util.js_pending([c.get("id"),h,i,j,k,l].join("-"));var n=c.data("includenavigation");return e.getCalendarDayData(h,i,j,k,l,n).then(function(a){return b.render(c.attr("data-template"),a)}).then(function(a,c){return b.replaceNode(m,a,c)}).then(function(){a("body").trigger(f.viewUpdated)}).always(function(){return M.util.js_complete([c.get("id"),h,i,j,k,l].join("-")),s(c)}).fail(d.exception)},p=function(a,b,c){var d=a.find(g.wrapper),e=d.data("year"),f=d.data("month"),h=d.data("day");return b||(b=a.find(g.wrapper).data("courseid")),"undefined"==typeof c&&(c=a.find(g.wrapper).data("categoryid")),o(a,e,f,h,b,c)},q=function(b,c,d,e,g,h,i){return o(b,d,e,g,h,i).then(function(){return c.length&&"#"!==c&&window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(f.dayChanged,[d,e,g,h,i]),arguments})},r=function(a){var b=a.find(g.containers.loadingIcon);b.removeClass("hidden")},s=function(a){var b=a.find(g.containers.loadingIcon);b.addClass("hidden")},t=function(c,h,i){r(c);var j=c.find(g.wrapper);return"undefined"==typeof h&&(h=c.find(g.wrapper).data("courseid")),"undefined"==typeof i&&(i=c.find(g.wrapper).data("categoryid")),e.getCalendarUpcomingData(h,i).then(function(a){return b.render(c.attr("data-template"),a)}).then(function(a,c){return b.replaceNode(j,a,c)}).then(function(){a("body").trigger(f.viewUpdated)}).always(function(){return s(c)}).fail(d.exception)},u=function(a){switch(a){case"user":return"calendar_event_user";case"site":return"calendar_event_site";case"group":return"calendar_event_group";case"category":return"calendar_event_category";case"course":return"calendar_event_course";default:return"calendar_event_course"}},v=function(a){var c="";e.getEventById(a).then(function(b){if(!b.event)throw new Error("Error encountered while trying to fetch calendar event with ID: "+a);var d=b.event;return c=u(d.eventtype),w(d.eventtype).then(function(a){return d.eventtype=a,d})}).then(function(a){var d={title:a.name,type:j.TYPE,body:b.render("core_calendar/event_summary_body",a),templateContext:{canedit:a.canedit,candelete:a.candelete,headerclasses:c,isactionevent:a.isactionevent,url:a.url}};return h.create(d)}).done(function(a){a.getRoot().on(i.hidden,function(){a.destroy()}),a.show()}).fail(d.exception)},w=function(a){var b="type"+a;return c.get_string(b,"core_calendar").then(function(a){return a})};return{init:function(a){k(a)},reloadCurrentMonth:n,changeMonth:m,refreshMonthContent:l,reloadCurrentDay:p,changeDay:q,refreshDayContent:o,reloadCurrentUpcoming:t}});
\ No newline at end of file
diff --git a/calendar/amd/src/calendar.js b/calendar/amd/src/calendar.js
index 4b25c1a5126..6102199622d 100644
--- a/calendar/amd/src/calendar.js
+++ b/calendar/amd/src/calendar.js
@@ -63,8 +63,6 @@ define([
var SELECTORS = {
ROOT: "[data-region='calendar']",
DAY: "[data-region='day']",
- EVENT_ITEM: "[data-region='event-item']",
- EVENT_LINK: "[data-action='view-event']",
NEW_EVENT_BUTTON: "[data-action='new-event-button']",
DAY_CONTENT: "[data-region='day-content']",
LOADING_ICON: '.loading-icon',
@@ -73,93 +71,6 @@ define([
TODAY: '.today',
};
- /**
- * Get the event type lang string.
- *
- * @param {String} eventType The event type.
- * @return {promise} The lang string promise.
- */
- var getEventType = function(eventType) {
- var lang = 'type' + eventType;
- return Str.get_string(lang, 'core_calendar').then(function(langStr) {
- return langStr;
- });
- };
-
- /**
- * Get the CSS class to apply for the given event type.
- *
- * @param {String} eventType The calendar event type
- * @return {String}
- */
- var getEventTypeClassFromType = function(eventType) {
- switch (eventType) {
- case 'user':
- return 'calendar_event_user';
- case 'site':
- return 'calendar_event_site';
- case 'group':
- return 'calendar_event_group';
- case 'category':
- return 'calendar_event_category';
- case 'course':
- return 'calendar_event_course';
- default:
- return 'calendar_event_course';
- }
- };
-
- /**
- * Render the event summary modal.
- *
- * @param {Number} eventId The calendar event id.
- */
- var renderEventSummaryModal = function(eventId) {
- var typeClass = '';
-
- // Calendar repository promise.
- CalendarRepository.getEventById(eventId).then(function(getEventResponse) {
- if (!getEventResponse.event) {
- throw new Error('Error encountered while trying to fetch calendar event with ID: ' + eventId);
- }
- var eventData = getEventResponse.event;
- typeClass = getEventTypeClassFromType(eventData.eventtype);
-
- return getEventType(eventData.eventtype).then(function(eventType) {
- eventData.eventtype = eventType;
- return eventData;
- });
- }).then(function(eventData) {
- // Build the modal parameters from the event data.
- var modalParams = {
- title: eventData.name,
- type: SummaryModal.TYPE,
- body: Templates.render('core_calendar/event_summary_body', eventData),
- templateContext: {
- canedit: eventData.canedit,
- candelete: eventData.candelete,
- headerclasses: typeClass,
- isactionevent: eventData.isactionevent,
- url: eventData.url
- }
- };
-
- // Create the modal.
- return ModalFactory.create(modalParams);
-
- }).done(function(modal) {
- // Handle hidden event.
- modal.getRoot().on(ModalEvents.hidden, function() {
- // Destroy when hidden.
- modal.destroy();
- });
-
- // Finally, render the modal!
- modal.show();
-
- }).fail(Notification.exception);
- };
-
/**
* Handler for the drag and drop move event. Provides a loading indicator
* while the request is sent to the server to update the event start date.
@@ -252,19 +163,7 @@ define([
CalendarViewManager.reloadCurrentMonth(root);
});
- eventFormModalPromise
- .then(function(modal) {
- // When something within the calendar tells us the user wants
- // to edit an event then show the event form modal.
- body.on(CalendarEvents.editEvent, function(e, eventId) {
- var calendarWrapper = root.find(CalendarSelectors.wrapper);
- modal.setEventId(eventId);
- modal.setContextId(calendarWrapper.data('contextId'));
- modal.show();
- });
- return;
- })
- .fail(Notification.exception);
+ CalendarCrud.registerEditListeners(root, eventFormModalPromise);
};
/**
@@ -273,27 +172,6 @@ define([
* @param {object} root The calendar root element
*/
var registerEventListeners = function(root) {
- // Bind click events to event links.
- root.on('click', SELECTORS.EVENT_ITEM, function(e) {
- e.preventDefault();
- // We've handled the event so stop it from bubbling
- // and causing the day click handler to fire.
- e.stopPropagation();
-
- var target = $(e.target);
- var eventId = null;
-
- var eventLink = target.closest(SELECTORS.EVENT_LINK);
-
- if (eventLink.length) {
- eventId = eventLink.data('eventId');
- } else {
- eventId = target.find(SELECTORS.EVENT_LINK).data('eventId');
- }
-
- renderEventSummaryModal(eventId);
- });
-
root.on('change', CalendarSelectors.elements.courseSelector, function() {
var selectElement = $(this);
var courseId = selectElement.val();
diff --git a/calendar/amd/src/calendar_view.js b/calendar/amd/src/calendar_view.js
index d4a2b3b80b8..5b4e589f8c9 100644
--- a/calendar/amd/src/calendar_view.js
+++ b/calendar/amd/src/calendar_view.js
@@ -51,7 +51,6 @@ define([
var registerEventListeners = function(root, type) {
var body = $('body');
- CalendarCrud.registerEventFormModal(root);
CalendarCrud.registerRemove(root);
var reloadFunction = 'reloadCurrent' + type.charAt(0).toUpperCase() + type.slice(1);
@@ -74,6 +73,11 @@ define([
// We need to get the selector again because the content has changed.
return root.find(CalendarSelectors.courseSelector).val(courseId);
})
+ .then(function() {
+ window.history.pushState({}, '', '?view=upcoming&course=' + courseId);
+
+ return;
+ })
.fail(Notification.exception);
});
@@ -85,6 +89,9 @@ define([
daysWithEvent.removeClass('hidden');
}
});
+
+ var eventFormPromise = CalendarCrud.registerEventFormModal(root);
+ CalendarCrud.registerEditListeners(root, eventFormPromise);
};
return {
diff --git a/calendar/amd/src/crud.js b/calendar/amd/src/crud.js
index d05afb75f67..b757df8bc1c 100644
--- a/calendar/amd/src/crud.js
+++ b/calendar/amd/src/crud.js
@@ -198,6 +198,8 @@ function(
modal.setContextId(calendarWrapper.data('contextId'));
modal.show();
+
+ e.stopImmediatePropagation();
return;
}).fail(Notification.exception);
});
@@ -223,8 +225,36 @@ function(
});
}
+ /**
+ * Register the listeners required to edit the event.
+ *
+ * @param {jQuery} root
+ * @param {Promise} eventFormModalPromise
+ * @returns {Promise}
+ */
+ function registerEditListeners(root, eventFormModalPromise) {
+ eventFormModalPromise
+ .then(function(modal) {
+ // When something within the calendar tells us the user wants
+ // to edit an event then show the event form modal.
+ $('body').on(CalendarEvents.editEvent, function(e, eventId) {
+ var calendarWrapper = root.find(CalendarSelectors.wrapper);
+ modal.setEventId(eventId);
+ modal.setContextId(calendarWrapper.data('contextId'));
+ modal.show();
+
+ e.stopImmediatePropagation();
+ });
+ return;
+ })
+ .fail(Notification.exception);
+
+ return eventFormModalPromise;
+ }
+
return {
registerRemove: registerRemove,
+ registerEditListeners: registerEditListeners,
registerEventFormModal: registerEventFormModal
};
});
diff --git a/calendar/amd/src/repository.js b/calendar/amd/src/repository.js
index 1115ba1d94c..e522bb259f2 100644
--- a/calendar/amd/src/repository.js
+++ b/calendar/amd/src/repository.js
@@ -164,13 +164,15 @@ define(['jquery', 'core/ajax'], function($, Ajax) {
*
* @method getCalendarUpcomingData
* @param {Number} courseid The course id.
+ * @param {Number} categoryid The category id.
* @return {promise} Resolved with the month view data.
*/
- var getCalendarUpcomingData = function(courseid) {
+ var getCalendarUpcomingData = function(courseid, categoryid) {
var request = {
methodname: 'core_calendar_get_calendar_upcoming_view',
args: {
courseid: courseid,
+ categoryid: categoryid,
}
};
diff --git a/calendar/amd/src/selectors.js b/calendar/amd/src/selectors.js
index 6a7021f051b..d8ead438a85 100644
--- a/calendar/amd/src/selectors.js
+++ b/calendar/amd/src/selectors.js
@@ -46,6 +46,7 @@ define([], function() {
create: '[data-action="new-event-button"]',
edit: '[data-action="edit"]',
remove: '[data-action="delete"]',
+ viewEvent: '[data-action="view-event"]',
},
elements: {
courseSelector: 'select[name="course"]',
@@ -54,5 +55,12 @@ define([], function() {
day: '[data-region="day"]',
wrapper: '.calendarwrapper',
eventItem: '[data-type="event"]',
+ links: {
+ navLink: '.calendarwrapper .arrow_link',
+ eventLink: "[data-region='event-item']",
+ },
+ containers: {
+ loadingIcon: '[data-region="overlay-icon-container"]',
+ },
};
});
diff --git a/calendar/amd/src/view_manager.js b/calendar/amd/src/view_manager.js
index 8b3d969e313..4c29f20a8e0 100644
--- a/calendar/amd/src/view_manager.js
+++ b/calendar/amd/src/view_manager.js
@@ -24,24 +24,27 @@
define([
'jquery',
'core/templates',
+ 'core/str',
'core/notification',
'core_calendar/repository',
'core_calendar/events',
'core_calendar/selectors',
+ 'core/modal_factory',
+ 'core/modal_events',
+ 'core_calendar/summary_modal',
], function(
$,
Templates,
+ Str,
Notification,
CalendarRepository,
CalendarEvents,
- CalendarSelectors
+ CalendarSelectors,
+ ModalFactory,
+ ModalEvents,
+ SummaryModal
) {
- var SELECTORS = {
- CALENDAR_NAV_LINK: ".calendarwrapper .arrow_link",
- LOADING_ICON_CONTAINER: '[data-region="overlay-icon-container"]'
- };
-
/**
* Register event listeners for the module.
*
@@ -50,7 +53,38 @@ define([
var registerEventListeners = function(root) {
root = $(root);
- root.on('click', SELECTORS.CALENDAR_NAV_LINK, function(e) {
+ // Bind click events to event links.
+ root.on('click', CalendarSelectors.links.eventLink, function(e) {
+ var target = $(e.target);
+ var eventId = null;
+
+ var eventLink;
+ if (target.is(CalendarSelectors.actions.viewEvent)) {
+ eventLink = target;
+ } else {
+ eventLink = target.closest(CalendarSelectors.actions.viewEvent);
+ }
+
+ if (eventLink.length) {
+ eventId = eventLink.data('eventId');
+ } else {
+ eventId = target.find(CalendarSelectors.actions.viewEvent).data('eventId');
+ }
+
+ if (eventId) {
+ // A link was found. Show the modal.
+
+ e.preventDefault();
+ // We've handled the event so stop it from bubbling
+ // and causing the day click handler to fire.
+ e.stopPropagation();
+
+ renderEventSummaryModal(eventId);
+ }
+ });
+
+
+ root.on('click', CalendarSelectors.links.navLink, function(e) {
var wrapper = root.find(CalendarSelectors.wrapper);
var view = wrapper.data('view');
var courseId = wrapper.data('courseid');
@@ -249,7 +283,7 @@ define([
* @method startLoading
*/
var startLoading = function(root) {
- var loadingIconContainer = root.find(SELECTORS.LOADING_ICON_CONTAINER);
+ var loadingIconContainer = root.find(CalendarSelectors.containers.loadingIcon);
loadingIconContainer.removeClass('hidden');
};
@@ -261,7 +295,7 @@ define([
* @method stopLoading
*/
var stopLoading = function(root) {
- var loadingIconContainer = root.find(SELECTORS.LOADING_ICON_CONTAINER);
+ var loadingIconContainer = root.find(CalendarSelectors.containers.loadingIcon);
loadingIconContainer.addClass('hidden');
};
@@ -271,23 +305,27 @@ define([
*
* @param {object} root The container element.
* @param {Number} courseId The course id.
+ * @param {Number} categoryId The id of the category whose events are shown
* @return {promise}
*/
- var reloadCurrentUpcoming = function(root, courseId) {
+ var reloadCurrentUpcoming = function(root, courseId, categoryId) {
startLoading(root);
var target = root.find(CalendarSelectors.wrapper);
- if (!courseId) {
+ if (typeof courseId === 'undefined') {
courseId = root.find(CalendarSelectors.wrapper).data('courseid');
}
- return CalendarRepository.getCalendarUpcomingData(courseId)
+ if (typeof categoryId === 'undefined') {
+ categoryId = root.find(CalendarSelectors.wrapper).data('categoryid');
+ }
+
+ return CalendarRepository.getCalendarUpcomingData(courseId, categoryId)
.then(function(context) {
return Templates.render(root.attr('data-template'), context);
})
.then(function(html, js) {
- window.history.replaceState(null, null, '?view=upcoming&course=' + courseId);
return Templates.replaceNode(target, html, js);
})
.then(function() {
@@ -300,6 +338,93 @@ define([
.fail(Notification.exception);
};
+ /**
+ * Get the CSS class to apply for the given event type.
+ *
+ * @param {String} eventType The calendar event type
+ * @return {String}
+ */
+ var getEventTypeClassFromType = function(eventType) {
+ switch (eventType) {
+ case 'user':
+ return 'calendar_event_user';
+ case 'site':
+ return 'calendar_event_site';
+ case 'group':
+ return 'calendar_event_group';
+ case 'category':
+ return 'calendar_event_category';
+ case 'course':
+ return 'calendar_event_course';
+ default:
+ return 'calendar_event_course';
+ }
+ };
+
+ /**
+ * Render the event summary modal.
+ *
+ * @param {Number} eventId The calendar event id.
+ */
+ var renderEventSummaryModal = function(eventId) {
+ var typeClass = '';
+
+ // Calendar repository promise.
+ CalendarRepository.getEventById(eventId).then(function(getEventResponse) {
+ if (!getEventResponse.event) {
+ throw new Error('Error encountered while trying to fetch calendar event with ID: ' + eventId);
+ }
+ var eventData = getEventResponse.event;
+ typeClass = getEventTypeClassFromType(eventData.eventtype);
+
+ return getEventType(eventData.eventtype).then(function(eventType) {
+ eventData.eventtype = eventType;
+ return eventData;
+ });
+ }).then(function(eventData) {
+ // Build the modal parameters from the event data.
+ var modalParams = {
+ title: eventData.name,
+ type: SummaryModal.TYPE,
+ body: Templates.render('core_calendar/event_summary_body', eventData),
+ templateContext: {
+ canedit: eventData.canedit,
+ candelete: eventData.candelete,
+ headerclasses: typeClass,
+ isactionevent: eventData.isactionevent,
+ url: eventData.url
+ }
+ };
+
+ // Create the modal.
+ return ModalFactory.create(modalParams);
+
+ }).done(function(modal) {
+ // Handle hidden event.
+ modal.getRoot().on(ModalEvents.hidden, function() {
+ // Destroy when hidden.
+ modal.destroy();
+ });
+
+ // Finally, render the modal!
+ modal.show();
+
+ }).fail(Notification.exception);
+ };
+
+ /**
+ * Get the event type lang string.
+ *
+ * @param {String} eventType The event type.
+ * @return {promise} The lang string promise.
+ */
+ var getEventType = function(eventType) {
+ var lang = 'type' + eventType;
+ return Str.get_string(lang, 'core_calendar').then(function(langStr) {
+ return langStr;
+ });
+ };
+
return {
init: function(root) {
registerEventListeners(root);
diff --git a/calendar/classes/external/calendar_upcoming_exporter.php b/calendar/classes/external/calendar_upcoming_exporter.php
index a7759c678cb..42fe7b923ec 100644
--- a/calendar/classes/external/calendar_upcoming_exporter.php
+++ b/calendar/classes/external/calendar_upcoming_exporter.php
@@ -82,6 +82,11 @@ class calendar_upcoming_exporter extends exporter {
'courseid' => [
'type' => PARAM_INT,
],
+ 'categoryid' => [
+ 'type' => PARAM_INT,
+ 'optional' => true,
+ 'default' => 0,
+ ],
];
}
@@ -127,6 +132,11 @@ class calendar_upcoming_exporter extends exporter {
}
$return['filter_selector'] = $this->get_course_filter_selector($output);
$return['courseid'] = $this->calendar->courseid;
+
+ if ($this->calendar->categoryid) {
+ $return['categoryid'] = $this->calendar->categoryid;
+ }
+
return $return;
}
diff --git a/calendar/externallib.php b/calendar/externallib.php
index 0c82f8aa223..0937d4c6be4 100644
--- a/calendar/externallib.php
+++ b/calendar/externallib.php
@@ -1154,12 +1154,26 @@ class core_calendar_external extends external_api {
// Parameter validation.
self::validate_parameters(self::get_calendar_upcoming_view_parameters(), [
'courseid' => $courseid,
+ 'categoryid' => $categoryid,
]);
+ $PAGE->set_url('/calendar/');
+ $category = null;
if ($courseid != SITEID && !empty($courseid)) {
// Course ID must be valid and existing.
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$courses = [$course->id => $course];
+ } else if (!empty($categoryid)) {
+ $course = get_site();
+ $courses = calendar_get_default_courses();
+
+ $category = \coursecat::get($categoryid);
+ $ids += $category->get_parents();
+ $categories = \coursecat::get_many($ids);
+ $courses = array_filter($courses, function($course) use ($categories) {
+ return array_search($course->category, $categories) !== false;
+ });
+ $category = $category->get_db_record();
} else {
$course = get_site();
$courses = calendar_get_default_courses();
@@ -1169,7 +1183,7 @@ class core_calendar_external extends external_api {
self::validate_context($context);
$calendar = new calendar_information(0, 0, 0, time());
- $calendar->set_sources($course, $courses);
+ $calendar->set_sources($course, $courses, $category);
list($data, $template) = calendar_get_view($calendar, 'upcoming');
@@ -1185,6 +1199,7 @@ class core_calendar_external extends external_api {
return new external_function_parameters(
[
'courseid' => new external_value(PARAM_INT, 'Course being viewed', VALUE_DEFAULT, SITEID, NULL_ALLOWED),
+ 'categoryid' => new external_value(PARAM_INT, 'Category being viewed', VALUE_DEFAULT, null, NULL_ALLOWED),
]
);
}
diff --git a/calendar/lib.php b/calendar/lib.php
index 8c20f9a34c0..b4b0c2c1a8d 100644
--- a/calendar/lib.php
+++ b/calendar/lib.php
@@ -3220,7 +3220,7 @@ function calendar_get_view(\calendar_information $calendar, $view, $includenavig
if ($view == "upcoming") {
$template = 'core_calendar/calendar_upcoming';
} else if ($view == "upcoming_mini") {
- $template = 'core_calendar/upcoming_mini';
+ $template = 'core_calendar/calendar_upcoming_mini';
}
}
diff --git a/calendar/templates/calendar_upcoming_mini.mustache b/calendar/templates/calendar_upcoming_mini.mustache
new file mode 100644
index 00000000000..8f276be1762
--- /dev/null
+++ b/calendar/templates/calendar_upcoming_mini.mustache
@@ -0,0 +1,41 @@
+{{!
+ 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