b1f37e79d6983cb427b6130cd2efcb4d68e87f5d
[moodle.git] / calendar / amd / src / calendar.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  * 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.
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  */
28 define([
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',
40             'core_calendar/events',
41             'core_calendar/view_manager'
42         ],
43         function(
44             $,
45             Ajax,
46             Str,
47             Templates,
48             Notification,
49             CustomEvents,
50             ModalEvents,
51             ModalFactory,
52             ModalEventForm,
53             SummaryModal,
54             CalendarRepository,
55             CalendarEvents,
56             CalendarViewManager
57         ) {
59     var SELECTORS = {
60         ROOT: "[data-region='calendar']",
61         EVENT_LINK: "[data-action='view-event']",
62         NEW_EVENT_BUTTON: "[data-action='new-event-button']"
63     };
65     /**
66      * Get the event type lang string.
67      *
68      * @param {String} eventType The event type.
69      * @return {promise} The lang string promise.
70      */
71     var getEventType = function(eventType) {
72         var lang = 'type' + eventType;
73         return Str.get_string(lang, 'core_calendar').then(function(langStr) {
74             return langStr;
75         });
76     };
78     /**
79      * Get the event source.
80      *
81      * @param {Object} subscription The event subscription object.
82      * @return {promise} The lang string promise.
83      */
84     var getEventSource = function(subscription) {
85         return Str.get_string('subsource', 'core_calendar', subscription).then(function(langStr) {
86             if (subscription.url) {
87                 return '<a href="' + subscription.url + '">' + langStr + '</a>';
88             }
89             return langStr;
90         });
91     };
93     /**
94      * Render the event summary modal.
95      *
96      * @param {Number} eventId The calendar event id.
97      */
98     var renderEventSummaryModal = function(eventId) {
99         // Calendar repository promise.
100         CalendarRepository.getEventById(eventId).then(function(getEventResponse) {
101             if (!getEventResponse.event) {
102                 throw new Error('Error encountered while trying to fetch calendar event with ID: ' + eventId);
103             }
104             var eventData = getEventResponse.event;
105             var eventTypePromise = getEventType(eventData.eventtype);
107             // If the calendar event has event source, get the source's language string/link.
108             if (eventData.displayeventsource) {
109                 eventData.subscription = JSON.parse(eventData.subscription);
110                 var eventSourceParams = {
111                     url: eventData.subscription.url,
112                     name: eventData.subscription.name
113                 };
114                 var eventSourcePromise = getEventSource(eventSourceParams);
116                 // Return event data with event type and event source info.
117                 return $.when(eventTypePromise, eventSourcePromise).then(function(eventType, eventSource) {
118                     eventData.eventtype = eventType;
119                     eventData.source = eventSource;
120                     return eventData;
121                 });
122             }
124             // Return event data with event type info.
125             return eventTypePromise.then(function(eventType) {
126                 eventData.eventtype = eventType;
127                 return eventData;
128             });
130         }).then(function(eventData) {
131             // Build the modal parameters from the event data.
132             var modalParams = {
133                 title: eventData.name,
134                 type: SummaryModal.TYPE,
135                 body: Templates.render('core_calendar/event_summary_body', eventData),
136                 templateContext: {
137                     canedit: eventData.canedit,
138                     candelete: eventData.candelete
139                 }
140             };
142             // Create the modal.
143             return ModalFactory.create(modalParams);
145         }).done(function(modal) {
146             // Handle hidden event.
147             modal.getRoot().on(ModalEvents.hidden, function() {
148                 // Destroy when hidden.
149                 modal.destroy();
150             });
152             // Finally, render the modal!
153             modal.show();
155         }).fail(Notification.exception);
156     };
158     /**
159      * Create the event form modal for creating new events and
160      * editing existing events.
161      *
162      * @method registerEventFormModal
163      * @param {object} root The calendar root element
164      * @return {object} The create modal promise
165      */
166     var registerEventFormModal = function(root) {
167         var newEventButton = root.find(SELECTORS.NEW_EVENT_BUTTON);
168         var contextId = newEventButton.attr('data-context-id');
170         return ModalFactory.create(
171             {
172                 type: ModalEventForm.TYPE,
173                 large: true,
174                 templateContext: {
175                     contextid: contextId
176                 }
177             },
178             [root, SELECTORS.NEW_EVENT_BUTTON]
179         );
180     };
182     /**
183      * Listen to and handle any calendar events fired by the calendar UI.
184      *
185      * @method registerCalendarEventListeners
186      * @param {object} root The calendar root element
187      * @param {object} eventFormModalPromise A promise reolved with the event form modal
188      */
189     var registerCalendarEventListeners = function(root, eventFormModalPromise) {
190         var body = $('body');
192         // TODO: Replace these with actual logic to update
193         // the UI without having to force a page reload.
194         body.on(CalendarEvents.created, function() {
195             window.location.reload();
196         });
197         body.on(CalendarEvents.deleted, function() {
198             CalendarViewManager.reloadCurrentMonth();
199         });
200         body.on(CalendarEvents.updated, function() {
201             window.location.reload();
202         });
203         body.on(CalendarEvents.editActionEvent, function(e, url) {
204             // Action events needs to be edit directly on the course module.
205             window.location.assign(url);
206         });
208         eventFormModalPromise.then(function(modal) {
209             // When something within the calendar tells us the user wants
210             // to edit an event then show the event form modal.
211             body.on(CalendarEvents.editEvent, function(e, eventId) {
212                 modal.setEventId(eventId);
213                 modal.show();
214             });
216             return;
217         });
218     };
220     /**
221      * Register event listeners for the module.
222      */
223     var registerEventListeners = function() {
224         var root = $(SELECTORS.ROOT);
226         // Bind click events to event links.
227         root.on('click', SELECTORS.EVENT_LINK, function(e) {
228             e.preventDefault();
229             var eventId = $(this).attr('data-event-id');
230             renderEventSummaryModal(eventId);
231         });
233         var eventFormPromise = registerEventFormModal(root);
234         registerCalendarEventListeners(root, eventFormPromise);
235     };
237     return {
238         init: function() {
239             CalendarViewManager.init();
240             registerEventListeners();
241         }
242     };
243 });