MDL-59940 calendar: Fix random behat fails when changing month
[moodle.git] / calendar / amd / src / view_manager.js
CommitLineData
695c5726
AN
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/>.
15
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 */
a4af4c96
SL
24define(['jquery', 'core/templates', 'core/notification', 'core_calendar/repository', 'core_calendar/events'],
25 function($, Templates, Notification, CalendarRepository, CalendarEvents) {
695c5726
AN
26
27 var SELECTORS = {
28 ROOT: "[data-region='calendar']",
a06b3a27 29 CALENDAR_NAV_LINK: ".calendarwrapper .arrow_link",
695c5726 30 CALENDAR_MONTH_WRAPPER: ".calendarwrapper",
b31a1695 31 LOADING_ICON_CONTAINER: '[data-region="overlay-icon-container"]'
695c5726
AN
32 };
33
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);
41
836aa3f6 42 root.on('click', SELECTORS.CALENDAR_NAV_LINK, function(e) {
695c5726
AN
43 var courseId = $(root).find(SELECTORS.CALENDAR_MONTH_WRAPPER).data('courseid');
44 var link = $(e.currentTarget);
f58424c7 45 changeMonth(root, link.attr('href'), link.data('year'), link.data('month'), courseId);
695c5726
AN
46
47 e.preventDefault();
48 });
49 };
50
516e7444
SL
51 /**
52 * Refresh the month content.
53 *
f58424c7
AN
54 * @param {object} root The root element.
55 * @param {Number} year Year
56 * @param {Number} month Month
516e7444 57 * @param {Number} courseid The id of the course whose events are shown
b0146885 58 * @param {object} target The element being replaced. If not specified, the calendarwrapper is used.
516e7444
SL
59 * @return {promise}
60 */
b0146885 61 var refreshMonthContent = function(root, year, month, courseid, target) {
b31a1695
SL
62 startLoading(root);
63
b0146885
AN
64 target = target || root.find(SELECTORS.CALENDAR_MONTH_WRAPPER);
65
529e8776 66 M.util.js_pending([root.get('id'), year, month, courseid].join('-'));
fee025ec
AN
67 var includenavigation = root.data('includenavigation');
68 return CalendarRepository.getCalendarMonthData(year, month, courseid, includenavigation)
516e7444 69 .then(function(context) {
2281a835 70 return Templates.render(root.attr('data-template'), context);
516e7444
SL
71 })
72 .then(function(html, js) {
b0146885 73 return Templates.replaceNode(target, html, js);
516e7444 74 })
c8b6e9ab
AN
75 .then(function() {
76 $('body').trigger(CalendarEvents.viewUpdated);
77 return;
78 })
b31a1695 79 .always(function() {
529e8776 80 M.util.js_complete([root.get('id'), year, month, courseid].join('-'));
b31a1695
SL
81 return stopLoading(root);
82 })
516e7444
SL
83 .fail(Notification.exception);
84 };
85
695c5726
AN
86 /**
87 * Handle changes to the current calendar view.
88 *
f58424c7 89 * @param {object} root The root element.
a4af4c96 90 * @param {String} url The calendar url to be shown
f58424c7
AN
91 * @param {Number} year Year
92 * @param {Number} month Month
695c5726 93 * @param {Number} courseid The id of the course whose events are shown
516e7444 94 * @return {promise}
695c5726 95 */
f58424c7
AN
96 var changeMonth = function(root, url, year, month, courseid) {
97 return refreshMonthContent(root, year, month, courseid)
516e7444 98 .then(function() {
41fa6a24
AN
99 if (url.length && url !== '#') {
100 window.history.pushState({}, '', url);
101 }
47b55dad 102 return arguments;
516e7444
SL
103 })
104 .then(function() {
f58424c7 105 $('body').trigger(CalendarEvents.monthChanged, [year, month, courseid]);
47b55dad 106 return arguments;
516e7444
SL
107 });
108 };
109
110 /**
111 * Reload the current month view data.
112 *
afa8c3da
SL
113 * @param {object} root The container element.
114 * @param {Number} courseId The course id.
516e7444
SL
115 * @return {promise}
116 */
afa8c3da 117 var reloadCurrentMonth = function(root, courseId) {
f58424c7
AN
118 var year = root.find(SELECTORS.CALENDAR_MONTH_WRAPPER).data('year');
119 var month = root.find(SELECTORS.CALENDAR_MONTH_WRAPPER).data('month');
516e7444 120
afa8c3da
SL
121 if (!courseId) {
122 courseId = root.find(SELECTORS.CALENDAR_MONTH_WRAPPER).data('courseid');
123 }
f58424c7 124 return refreshMonthContent(root, year, month, courseId);
695c5726
AN
125 };
126
b31a1695
SL
127 /**
128 * Set the element state to loading.
129 *
130 * @param {object} root The container element
131 * @method startLoading
132 */
133 var startLoading = function(root) {
134 var loadingIconContainer = root.find(SELECTORS.LOADING_ICON_CONTAINER);
135
136 loadingIconContainer.removeClass('hidden');
137 };
138
139 /**
140 * Remove the loading state from the element.
141 *
142 * @param {object} root The container element
143 * @method stopLoading
144 */
145 var stopLoading = function(root) {
146 var loadingIconContainer = root.find(SELECTORS.LOADING_ICON_CONTAINER);
147
148 loadingIconContainer.addClass('hidden');
149 };
150
695c5726 151 return {
6397ec54
AN
152 init: function(root) {
153 registerEventListeners(root);
516e7444
SL
154 },
155 reloadCurrentMonth: reloadCurrentMonth,
156 changeMonth: changeMonth,
157 refreshMonthContent: refreshMonthContent
695c5726
AN
158 };
159 });