weekly release 3.5dev
[moodle.git] / calendar / amd / src / calendar.js
CommitLineData
3b0738f0
SL
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/**
aa091225
RW
17 * This module is the highest level module for the calendar. It is
18 * responsible for initialising all of the components required for
19 * the calendar to run. It also coordinates the interaction between
20 * components by listening for and responding to different events
21 * triggered within the calendar UI.
3b0738f0
SL
22 *
23 * @module core_calendar/calendar
24 * @package core_calendar
25 * @copyright 2017 Simey Lameze <simey@moodle.com>
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 */
aa091225
RW
28define([
29 'jquery',
30 'core/ajax',
31 'core/str',
32 'core/templates',
33 'core/notification',
34 'core/custom_interaction_events',
35 'core/modal_events',
36 'core/modal_factory',
37 'core_calendar/modal_event_form',
38 'core_calendar/summary_modal',
39 'core_calendar/repository',
695c5726 40 'core_calendar/events',
001366a8
SL
41 'core_calendar/view_manager',
42 'core_calendar/crud',
43 'core_calendar/selectors',
aa091225
RW
44 ],
45 function(
46 $,
47 Ajax,
48 Str,
49 Templates,
50 Notification,
51 CustomEvents,
52 ModalEvents,
53 ModalFactory,
54 ModalEventForm,
55 SummaryModal,
56 CalendarRepository,
695c5726 57 CalendarEvents,
001366a8
SL
58 CalendarViewManager,
59 CalendarCrud,
60 CalendarSelectors
aa091225
RW
61 ) {
62
63 var SELECTORS = {
64 ROOT: "[data-region='calendar']",
f6e8cc83 65 DAY: "[data-region='day']",
5ca142dc
RW
66 NEW_EVENT_BUTTON: "[data-action='new-event-button']",
67 DAY_CONTENT: "[data-region='day-content']",
68 LOADING_ICON: '.loading-icon',
29158c8b 69 VIEW_DAY_LINK: "[data-action='view-day-link']",
afa8c3da 70 CALENDAR_MONTH_WRAPPER: ".calendarwrapper",
bc2cca3a 71 TODAY: '.today',
aa091225
RW
72 };
73
5ca142dc
RW
74 /**
75 * Handler for the drag and drop move event. Provides a loading indicator
76 * while the request is sent to the server to update the event start date.
77 *
78 * Triggers a eventMoved calendar javascript event if the event was successfully
79 * updated.
80 *
81 * @param {event} e The calendar move event
aefb2950
RW
82 * @param {int} eventId The event id being moved
83 * @param {object|null} originElement The jQuery element for where the event is moving from
5ca142dc
RW
84 * @param {object} destinationElement The jQuery element for where the event is moving to
85 */
aefb2950
RW
86 var handleMoveEvent = function(e, eventId, originElement, destinationElement) {
87 var originTimestamp = null;
5ca142dc
RW
88 var destinationTimestamp = destinationElement.attr('data-day-timestamp');
89
aefb2950
RW
90 if (originElement) {
91 originTimestamp = originElement.attr('data-day-timestamp');
92 }
93
5ca142dc 94 // If the event has actually changed day.
aefb2950 95 if (!originElement || originTimestamp != destinationTimestamp) {
5ca142dc
RW
96 Templates.render('core/loading', {})
97 .then(function(html, js) {
98 // First we show some loading icons in each of the days being affected.
5ca142dc 99 destinationElement.find(SELECTORS.DAY_CONTENT).addClass('hidden');
5ca142dc 100 Templates.appendNodeContents(destinationElement, html, js);
aefb2950
RW
101
102 if (originElement) {
103 originElement.find(SELECTORS.DAY_CONTENT).addClass('hidden');
104 Templates.appendNodeContents(originElement, html, js);
105 }
5ca142dc
RW
106 return;
107 })
108 .then(function() {
109 // Send a request to the server to make the change.
110 return CalendarRepository.updateEventStartDay(eventId, destinationTimestamp);
111 })
112 .then(function() {
113 // If the update was successful then broadcast an event letting the calendar
114 // know that an event has been moved.
aefb2950 115 $('body').trigger(CalendarEvents.eventMoved, [eventId, originElement, destinationElement]);
5ca142dc
RW
116 return;
117 })
118 .always(function() {
119 // Always remove the loading icons regardless of whether the update
120 // request was successful or not.
5ca142dc 121 var destinationLoadingElement = destinationElement.find(SELECTORS.LOADING_ICON);
5ca142dc 122 destinationElement.find(SELECTORS.DAY_CONTENT).removeClass('hidden');
5ca142dc 123 Templates.replaceNode(destinationLoadingElement, '', '');
aefb2950
RW
124
125 if (originElement) {
126 var originLoadingElement = originElement.find(SELECTORS.LOADING_ICON);
127 originElement.find(SELECTORS.DAY_CONTENT).removeClass('hidden');
128 Templates.replaceNode(originLoadingElement, '', '');
129 }
5ca142dc
RW
130 return;
131 })
132 .fail(Notification.exception);
133 }
134 };
135
aa091225
RW
136 /**
137 * Listen to and handle any calendar events fired by the calendar UI.
138 *
139 * @method registerCalendarEventListeners
140 * @param {object} root The calendar root element
141 * @param {object} eventFormModalPromise A promise reolved with the event form modal
142 */
143 var registerCalendarEventListeners = function(root, eventFormModalPromise) {
d097bfdd 144 var body = $('body');
aa091225 145
d6942fb5 146 body.on(CalendarEvents.created, function() {
b31a1695 147 CalendarViewManager.reloadCurrentMonth(root);
d6942fb5
RW
148 });
149 body.on(CalendarEvents.deleted, function() {
b31a1695 150 CalendarViewManager.reloadCurrentMonth(root);
d6942fb5
RW
151 });
152 body.on(CalendarEvents.updated, function() {
b31a1695 153 CalendarViewManager.reloadCurrentMonth(root);
d6942fb5 154 });
c34e2002
SL
155 body.on(CalendarEvents.editActionEvent, function(e, url) {
156 // Action events needs to be edit directly on the course module.
157 window.location.assign(url);
158 });
5ca142dc
RW
159 // Handle the event fired by the drag and drop code.
160 body.on(CalendarEvents.moveEvent, handleMoveEvent);
161 // When an event is successfully moved we should updated the UI.
162 body.on(CalendarEvents.eventMoved, function() {
aefb2950 163 CalendarViewManager.reloadCurrentMonth(root);
5ca142dc 164 });
a43ec9eb 165
8242027d 166 CalendarCrud.registerEditListeners(root, eventFormModalPromise);
aa091225
RW
167 };
168
169 /**
170 * Register event listeners for the module.
abf00dad
AN
171 *
172 * @param {object} root The calendar root element
aa091225 173 */
6397ec54 174 var registerEventListeners = function(root) {
80e4426a 175 root.on('change', CalendarSelectors.elements.courseSelector, function() {
afa8c3da
SL
176 var selectElement = $(this);
177 var courseId = selectElement.val();
d0e56d84 178 CalendarViewManager.reloadCurrentMonth(root, courseId, null)
afa8c3da
SL
179 .then(function() {
180 // We need to get the selector again because the content has changed.
80e4426a 181 return root.find(CalendarSelectors.elements.courseSelector).val(courseId);
afa8c3da
SL
182 })
183 .fail(Notification.exception);
184 });
185
e00aed51 186 var eventFormPromise = CalendarCrud.registerEventFormModal(root);
aa091225 187 registerCalendarEventListeners(root, eventFormPromise);
f6e8cc83
RW
188
189 // Bind click events to calendar days.
190 root.on('click', SELECTORS.DAY, function(e) {
e00aed51 191
f6e8cc83
RW
192 var target = $(e.target);
193
194 if (!target.is(SELECTORS.VIEW_DAY_LINK)) {
195 var startTime = $(this).attr('data-new-event-timestamp');
196 eventFormPromise.then(function(modal) {
e00aed51 197 var wrapper = target.closest(CalendarSelectors.wrapper);
d097bfdd
AN
198 modal.setCourseId(wrapper.data('courseid'));
199
200 var categoryId = wrapper.data('categoryid');
201 if (typeof categoryId !== 'undefined') {
202 modal.setCategoryId(categoryId);
203 }
204
e00aed51 205 modal.setContextId(wrapper.data('contextId'));
f6e8cc83
RW
206 modal.setStartTime(startTime);
207 modal.show();
208 return;
abf00dad
AN
209 })
210 .fail(Notification.exception);
f6e8cc83
RW
211
212 e.preventDefault();
213 }
214 });
aa091225
RW
215 };
216
217 return {
6397ec54
AN
218 init: function(root) {
219 root = $(root);
6397ec54
AN
220 CalendarViewManager.init(root);
221 registerEventListeners(root);
aa091225
RW
222 }
223 };
224});