calendar/amd/src/crud.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/>.
  15. /**
  16. * A module to handle CRUD operations within the UI.
  17. *
  18. * @module core_calendar/crud
  19. * @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
  20. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  21. */
  22. define([
  23. 'jquery',
  24. 'core/str',
  25. 'core/notification',
  26. 'core/modal_events',
  27. 'core_calendar/modal_event_form',
  28. 'core_calendar/repository',
  29. 'core_calendar/events',
  30. 'core_calendar/modal_delete',
  31. 'core_calendar/selectors',
  32. 'core/pending',
  33. 'core/modal_save_cancel',
  34. 'core/config',
  35. ],
  36. function(
  37. $,
  38. Str,
  39. Notification,
  40. ModalEvents,
  41. ModalEventForm,
  42. CalendarRepository,
  43. CalendarEvents,
  44. CalendarModalDelete,
  45. CalendarSelectors,
  46. Pending,
  47. ModalSaveCancel,
  48. Config,
  49. ) {
  50. /**
  51. * Prepares the action for the summary modal's delete action.
  52. *
  53. * @param {Number} eventId The ID of the event.
  54. * @param {string} eventTitle The event title.
  55. * @param {Number} eventCount The number of events in the series.
  56. * @return {Promise}
  57. */
  58. function confirmDeletion(eventId, eventTitle, eventCount) {
  59. var pendingPromise = new Pending('core_calendar/crud:confirmDeletion');
  60. var deleteStrings = [
  61. {
  62. key: 'deleteevent',
  63. component: 'calendar'
  64. },
  65. ];
  66. eventCount = parseInt(eventCount, 10);
  67. var deletePromise;
  68. var isRepeatedEvent = eventCount > 1;
  69. if (isRepeatedEvent) {
  70. deleteStrings.push({
  71. key: 'confirmeventseriesdelete',
  72. component: 'calendar',
  73. param: {
  74. name: eventTitle,
  75. count: eventCount,
  76. },
  77. });
  78. deletePromise = CalendarModalDelete.create();
  79. } else {
  80. deleteStrings.push({
  81. key: 'confirmeventdelete',
  82. component: 'calendar',
  83. param: eventTitle
  84. });
  85. deletePromise = ModalSaveCancel.create();
  86. }
  87. var stringsPromise = Str.get_strings(deleteStrings);
  88. var finalPromise = $.when(stringsPromise, deletePromise)
  89. .then(function(strings, deleteModal) {
  90. deleteModal.setRemoveOnClose(true);
  91. deleteModal.setTitle(strings[0]);
  92. deleteModal.setBody(strings[1]);
  93. if (!isRepeatedEvent) {
  94. deleteModal.setSaveButtonText(strings[0]);
  95. }
  96. deleteModal.show();
  97. deleteModal.getRoot().on(ModalEvents.save, function() {
  98. var pendingPromise = new Pending('calendar/crud:initModal:deletedevent');
  99. CalendarRepository.deleteEvent(eventId, false)
  100. .then(function() {
  101. $('body').trigger(CalendarEvents.deleted, [eventId, false]);
  102. return;
  103. })
  104. .then(pendingPromise.resolve)
  105. .catch(Notification.exception);
  106. });
  107. deleteModal.getRoot().on(CalendarEvents.deleteAll, function() {
  108. var pendingPromise = new Pending('calendar/crud:initModal:deletedallevent');
  109. CalendarRepository.deleteEvent(eventId, true)
  110. .then(function() {
  111. $('body').trigger(CalendarEvents.deleted, [eventId, true]);
  112. return;
  113. })
  114. .then(pendingPromise.resolve)
  115. .catch(Notification.exception);
  116. });
  117. return deleteModal;
  118. })
  119. .then(function(modal) {
  120. pendingPromise.resolve();
  121. return modal;
  122. })
  123. .catch(Notification.exception);
  124. return finalPromise;
  125. }
  126. /**
  127. * Create the event form modal for creating new events and
  128. * editing existing events.
  129. *
  130. * @method registerEventFormModal
  131. * @param {object} root The calendar root element
  132. * @return {object} The create modal promise
  133. */
  134. var registerEventFormModal = function(root) {
  135. var eventFormPromise = ModalEventForm.create();
  136. // Bind click event on the new event button.
  137. root.on('click', CalendarSelectors.actions.create, function(e) {
  138. eventFormPromise.then(function(modal) {
  139. var wrapper = root.find(CalendarSelectors.wrapper);
  140. var categoryId = wrapper.data('categoryid');
  141. const courseId = wrapper.data('courseid');
  142. if (typeof categoryId !== 'undefined' && courseId != Config.siteId) {
  143. modal.setCategoryId(categoryId);
  144. }
  145. // Attempt to find the cell for today.
  146. // If it can't be found, then use the start time of the first day on the calendar.
  147. var today = root.find(CalendarSelectors.today);
  148. var firstDay = root.find(CalendarSelectors.day);
  149. if (!today.length && firstDay.length) {
  150. modal.setStartTime(firstDay.data('newEventTimestamp'));
  151. }
  152. modal.setContextId(wrapper.data('contextId'));
  153. modal.setCourseId(wrapper.data('courseid'));
  154. modal.show();
  155. return;
  156. })
  157. .catch(Notification.exception);
  158. e.preventDefault();
  159. });
  160. root.on('click', CalendarSelectors.actions.edit, function(e) {
  161. e.preventDefault();
  162. var target = $(e.currentTarget),
  163. calendarWrapper = target.closest(CalendarSelectors.wrapper),
  164. eventWrapper = target.closest(CalendarSelectors.eventItem);
  165. eventFormPromise.then(function(modal) {
  166. // When something within the calendar tells us the user wants
  167. // to edit an event then show the event form modal.
  168. modal.setEventId(eventWrapper.data('eventId'));
  169. modal.setContextId(calendarWrapper.data('contextId'));
  170. modal.setCourseId(eventWrapper.data('courseId'));
  171. modal.show();
  172. e.stopImmediatePropagation();
  173. return;
  174. }).catch(Notification.exception);
  175. });
  176. return eventFormPromise;
  177. };
  178. /**
  179. * Register the listeners required to remove the event.
  180. *
  181. * @param {jQuery} root
  182. */
  183. function registerRemove(root) {
  184. root.on('click', CalendarSelectors.actions.remove, function(e) {
  185. // Fetch the event title, count, and pass them into the new dialogue.
  186. var eventSource = $(this).closest(CalendarSelectors.eventItem);
  187. var eventId = eventSource.data('eventId'),
  188. eventTitle = eventSource.data('eventTitle'),
  189. eventCount = eventSource.data('eventCount');
  190. confirmDeletion(eventId, eventTitle, eventCount);
  191. e.preventDefault();
  192. });
  193. }
  194. /**
  195. * Register the listeners required to edit the event.
  196. *
  197. * @param {jQuery} root
  198. * @param {Promise} eventFormModalPromise
  199. * @returns {Promise}
  200. */
  201. function registerEditListeners(root, eventFormModalPromise) {
  202. var pendingPromise = new Pending('core_calendar/crud:registerEditListeners');
  203. return eventFormModalPromise
  204. .then(function(modal) {
  205. // When something within the calendar tells us the user wants
  206. // to edit an event then show the event form modal.
  207. $('body').on(CalendarEvents.editEvent, function(e, eventId) {
  208. var target = root.find(`[data-event-id=${eventId}]`),
  209. calendarWrapper = root.find(CalendarSelectors.wrapper);
  210. modal.setEventId(eventId);
  211. modal.setContextId(calendarWrapper.data('contextId'));
  212. modal.setReturnElement(target);
  213. modal.show();
  214. e.stopImmediatePropagation();
  215. });
  216. return modal;
  217. })
  218. .then(function(modal) {
  219. pendingPromise.resolve();
  220. return modal;
  221. })
  222. .catch(Notification.exception);
  223. }
  224. return {
  225. registerRemove: registerRemove,
  226. registerEditListeners: registerEditListeners,
  227. registerEventFormModal: registerEventFormModal
  228. };
  229. });