MDL-59392 calendar: Stop polluting history with useless URLs
[moodle.git] / calendar / amd / src / view_manager.js
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16 /**
17  * A javascript module to handler calendar view changes.
18  *
19  * @module     core_calendar/view_manager
20  * @package    core_calendar
21  * @copyright  2017 Andrew Nicols <andrew@nicols.co.uk>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
24 define(['jquery', 'core/templates', 'core/notification', 'core_calendar/repository', 'core_calendar/events'],
25     function($, Templates, Notification, CalendarRepository, CalendarEvents) {
27         var SELECTORS = {
28             ROOT: "[data-region='calendar']",
29             CALENDAR_NAV_LINK: ".calendarwrapper .arrow_link",
30             CALENDAR_MONTH_WRAPPER: ".calendarwrapper",
31             LOADING_ICON_CONTAINER: '[data-region="overlay-icon-container"]'
32         };
34         /**
35          * Register event listeners for the module.
36          *
37          * @param {object} root The root element.
38          */
39         var registerEventListeners = function(root) {
40             root = $(root);
42             root.on('click', SELECTORS.CALENDAR_NAV_LINK, function(e) {
43                 var courseId = $(root).find(SELECTORS.CALENDAR_MONTH_WRAPPER).data('courseid');
44                 var link = $(e.currentTarget);
45                 changeMonth(root, link.attr('href'), link.data('time'), courseId);
47                 e.preventDefault();
48             });
49         };
51         /**
52          * Refresh the month content.
53          *
54          * @param {Number} time The calendar time to be shown
55          * @param {Number} courseid The id of the course whose events are shown
56          * @return {promise}
57          */
58         var refreshMonthContent = function(root, time, courseid) {
59             startLoading(root);
61             return CalendarRepository.getCalendarMonthData(time, courseid)
62                 .then(function(context) {
63                     return Templates.render(root.attr('data-template'), context);
64                 })
65                 .then(function(html, js) {
66                     return Templates.replaceNode(root.find(SELECTORS.CALENDAR_MONTH_WRAPPER), html, js);
67                 })
68                 .always(function() {
69                     return stopLoading(root);
70                 })
71                 .fail(Notification.exception);
72         };
74         /**
75          * Handle changes to the current calendar view.
76          *
77          * @param {String} url The calendar url to be shown
78          * @param {Number} time The calendar time to be shown
79          * @param {Number} courseid The id of the course whose events are shown
80          * @return {promise}
81          */
82         var changeMonth = function(root, url, time, courseid) {
83             return refreshMonthContent(root, time, courseid)
84                 .then(function() {
85                     if (url.length && url !== '#') {
86                         window.history.pushState({}, '', url);
87                     }
88                     return arguments;
89                 })
90                 .then(function() {
91                     $('body').trigger(CalendarEvents.monthChanged, [time, courseid]);
92                     return arguments;
93                 });
94         };
96         /**
97          * Reload the current month view data.
98          *
99          * @param {object} root The container element.
100          * @param {Number} courseId The course id.
101          * @return {promise}
102          */
103         var reloadCurrentMonth = function(root, courseId) {
104             var time = root.find(SELECTORS.CALENDAR_MONTH_WRAPPER).data('current-time');
106             if (!courseId) {
107                 courseId = root.find(SELECTORS.CALENDAR_MONTH_WRAPPER).data('courseid');
108             }
109             return refreshMonthContent(root, time, courseId);
110         };
112         /**
113          * Set the element state to loading.
114          *
115          * @param {object} root The container element
116          * @method startLoading
117          */
118         var startLoading = function(root) {
119             var loadingIconContainer = root.find(SELECTORS.LOADING_ICON_CONTAINER);
121             loadingIconContainer.removeClass('hidden');
122         };
124         /**
125          * Remove the loading state from the element.
126          *
127          * @param {object} root The container element
128          * @method stopLoading
129          */
130         var stopLoading = function(root) {
131             var loadingIconContainer = root.find(SELECTORS.LOADING_ICON_CONTAINER);
133             loadingIconContainer.addClass('hidden');
134         };
136         return {
137             init: function(root) {
138                 registerEventListeners(root);
139             },
140             reloadCurrentMonth: reloadCurrentMonth,
141             changeMonth: changeMonth,
142             refreshMonthContent: refreshMonthContent
143         };
144     });