MDL-59759 core_calendar: Use SAVE_CANCEL modal for delete dialog
[moodle.git] / calendar / amd / src / summary_modal.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 handle summary modal.
18  *
19  * @module     core_calendar/summary_modal
20  * @package    core_calendar
21  * @copyright  2017 Simey Lameze <simey@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
24 define(['jquery', 'core/str', 'core/notification', 'core/custom_interaction_events', 'core/modal',
25     'core/modal_registry', 'core/modal_factory', 'core/modal_events', 'core_calendar/repository',
26     'core_calendar/events'],
27     function($, Str, Notification, CustomEvents, Modal, ModalRegistry, ModalFactory, ModalEvents, CalendarRepository,
28              CalendarEvents) {
30     var registered = false;
31     var SELECTORS = {
32         ROOT: "[data-region='summary-modal-container']",
33         EDIT_BUTTON: '[data-action="edit"]',
34         DELETE_BUTTON: '[data-action="delete"]',
35     };
37     /**
38      * Constructor for the Modal.
39      *
40      * @param {object} root The root jQuery element for the modal
41      */
42     var ModalEventSummary = function(root) {
43         Modal.call(this, root);
44     };
46     ModalEventSummary.TYPE = 'core_calendar-event_summary';
47     ModalEventSummary.prototype = Object.create(Modal.prototype);
48     ModalEventSummary.prototype.constructor = ModalEventSummary;
50     /**
51      * Get the edit button element from the footer. The button is cached
52      * as it's not expected to change.
53      *
54      * @method getEditButton
55      * @return {object} button element
56      */
57     ModalEventSummary.prototype.getEditButton = function() {
58         if (typeof this.editButton == 'undefined') {
59             this.editButton = this.getFooter().find(SELECTORS.EDIT_BUTTON);
60         }
62         return this.editButton;
63     };
65     /**
66      * Get the delete button element from the footer. The button is cached
67      * as it's not expected to change.
68      *
69      * @method getDeleteButton
70      * @return {object} button element
71      */
72     ModalEventSummary.prototype.getDeleteButton = function() {
73         if (typeof this.deleteButton == 'undefined') {
74             this.deleteButton = this.getFooter().find(SELECTORS.DELETE_BUTTON);
75         }
77         return this.deleteButton;
78     };
80     /**
81      * Get the id for the event being shown in this modal. This value is
82      * not cached because it will change depending on which event is
83      * being displayed.
84      *
85      * @method getEventId
86      * @return {int}
87      */
88     ModalEventSummary.prototype.getEventId = function() {
89         return this.getBody().find(SELECTORS.ROOT).attr('data-event-id');
90     };
92     /**
93      * Get the url for the event being shown in this modal.
94      *
95      * @method getEventUrl
96      * @return {String}
97      */
98     ModalEventSummary.prototype.getEditUrl = function() {
99         return this.getBody().find(SELECTORS.ROOT).attr('data-edit-url');
100     };
102     /**
103      * Is this an action event.
104      *
105      * @method getEventUrl
106      * @return {String}
107      */
108     ModalEventSummary.prototype.isActionEvent = function() {
109         return (this.getBody().find(SELECTORS.ROOT).attr('data-action-event') == 'true');
110     };
112     /**
113      * Set up all of the event handling for the modal.
114      *
115      * @method registerEventListeners
116      */
117     ModalEventSummary.prototype.registerEventListeners = function() {
118         // Apply parent event listeners.
119         Modal.prototype.registerEventListeners.call(this);
121         // We have to wait for the modal to finish rendering in order to ensure that
122         // the data-event-title property is available to use as the modal title.
123         this.getRoot().on(ModalEvents.bodyRendered, function() {
124             var eventTitle = this.getBody().find(SELECTORS.ROOT).attr('data-event-title');
125             prepareDeleteAction(this, eventTitle);
126         }.bind(this));
128         CustomEvents.define(this.getEditButton(), [
129             CustomEvents.events.activate
130         ]);
132         this.getEditButton().on(CustomEvents.events.activate, function(e, data) {
134             if (this.isActionEvent()) {
135                 // Action events cannot be edited on the event form and must be redirected to the module UI.
136                 $('body').trigger(CalendarEvents.editActionEvent, [this.getEditUrl()]);
137             } else {
138                 // When the edit button is clicked we fire an event for the calendar UI to handle.
139                 // We don't care how the UI chooses to handle it.
140                 $('body').trigger(CalendarEvents.editEvent, [this.getEventId()]);
141             }
143             // There is nothing else for us to do so let's hide.
144             this.hide();
146             // We've handled this event so no need to propagate it.
147             e.preventDefault();
148             e.stopPropagation();
149             data.originalEvent.preventDefault();
150             data.originalEvent.stopPropagation();
151         }.bind(this));
152     };
154     /**
155      * Prepares the action for the summary modal's delete action.
156      *
157      * @param {ModalEventSummary} summaryModal The summary modal instance.
158      * @param {string} eventTitle The event title.
159      */
160     function prepareDeleteAction(summaryModal, eventTitle) {
161         var deleteStrings = [
162             {
163                 key: 'deleteevent',
164                 component: 'calendar'
165             },
166             {
167                 key: 'confirmeventdelete',
168                 component: 'calendar',
169                 param: eventTitle
170             }
171         ];
172         var eventId = summaryModal.getEventId();
173         var stringsPromise = Str.get_strings(deleteStrings);
174         var deletePromise = ModalFactory.create(
175             {
176                 type: ModalFactory.types.SAVE_CANCEL
177             },
178             summaryModal.getDeleteButton()
179         );
181         $.when(stringsPromise, deletePromise).then(function(strings, deleteModal) {
182             deleteModal.setTitle(strings[0]);
183             deleteModal.setBody(strings[1]);
184             deleteModal.setSaveButtonText(strings[0]);
185             deleteModal.getRoot().on(ModalEvents.save, function() {
186                 CalendarRepository.deleteEvent(eventId).then(function() {
187                     $('body').trigger(CalendarEvents.deleted, [eventId]);
188                     summaryModal.hide();
189                     return;
190                 }).catch(Notification.exception);
191             });
192             return deleteModal;
193         }).fail(Notification.exception);
194     }
196     // Automatically register with the modal registry the first time this module is imported so that you can create modals
197     // of this type using the modal factory.
198     if (!registered) {
199         ModalRegistry.register(ModalEventSummary.TYPE, ModalEventSummary, 'core_calendar/event_summary_modal');
200         registered = true;
201     }
203     return ModalEventSummary;
204 });