MDL-59751 core_calendar: make upcoming view use AJAX
authorSimey Lameze <simey@moodle.com>
Fri, 29 Sep 2017 04:59:24 +0000 (12:59 +0800)
committerSimey Lameze <simey@moodle.com>
Thu, 5 Oct 2017 06:23:02 +0000 (14:23 +0800)
12 files changed:
calendar/amd/build/calendar_view.min.js [new file with mode: 0644]
calendar/amd/build/repository.min.js
calendar/amd/build/selectors.min.js
calendar/amd/build/view_manager.min.js
calendar/amd/src/calendar_view.js [new file with mode: 0644]
calendar/amd/src/repository.js
calendar/amd/src/selectors.js
calendar/amd/src/view_manager.js
calendar/lib.php
calendar/templates/event_item.mustache
calendar/templates/event_list.mustache
calendar/view.php

diff --git a/calendar/amd/build/calendar_view.min.js b/calendar/amd/build/calendar_view.min.js
new file mode 100644 (file)
index 0000000..b973e41
Binary files /dev/null and b/calendar/amd/build/calendar_view.min.js differ
index 57dbe97..2d393c8 100644 (file)
Binary files a/calendar/amd/build/repository.min.js and b/calendar/amd/build/repository.min.js differ
index ed31fd7..686cb80 100644 (file)
Binary files a/calendar/amd/build/selectors.min.js and b/calendar/amd/build/selectors.min.js differ
index 04dc7f6..4fc3d9e 100644 (file)
Binary files a/calendar/amd/build/view_manager.min.js and b/calendar/amd/build/view_manager.min.js differ
diff --git a/calendar/amd/src/calendar_view.js b/calendar/amd/src/calendar_view.js
new file mode 100644 (file)
index 0000000..369f92c
--- /dev/null
@@ -0,0 +1,123 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This module is responsible for handle calendar day and upcoming view.
+ *
+ * @module     core_calendar/calendar
+ * @package    core_calendar
+ * @copyright  2017 Simey Lameze <simey@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define([
+        'jquery',
+        'core/str',
+        'core/notification',
+        'core_calendar/selectors',
+        'core_calendar/events',
+        'core_calendar/view_manager',
+        'core_calendar/repository',
+        'core/modal_factory',
+        'core_calendar/modal_event_form',
+        'core/modal_events',
+        'core_calendar/crud'
+    ],
+    function(
+        $,
+        Str,
+        Notification,
+        CalendarSelectors,
+        CalendarEvents,
+        CalendarViewManager,
+        CalendarRepository,
+        ModalFactory,
+        ModalEventForm,
+        ModalEvents,
+        CalendarCrud
+    ) {
+
+        var registerEventListeners = function(root) {
+            var body = $('body'),
+                deleteLink = $(CalendarSelectors.deleteLink),
+                newEventButton = $(CalendarSelectors.newEventButton),
+                courseId = root.data('courseid');
+
+            var eventFormPromise = CalendarCrud.registerEventFormModal(root, newEventButton);
+
+            CalendarCrud.registerRemove(deleteLink);
+
+            root.on('click', CalendarSelectors.deleteLink, function(e) {
+                e.preventDefault();
+
+                var target = $(e.currentTarget),
+                    eventId = target.data('event-id'),
+                    eventTitle = target.data('title'),
+                    eventCount = target.data('event-event-count');
+
+                CalendarCrud.confirmDeletion(eventId, eventTitle, eventCount).then(function(deleteModalPromise) {
+                    body.on(CalendarEvents.deleted, function() {
+                        // Close the dialogue on delete.
+                        deleteModalPromise.hide();
+                        CalendarViewManager.reloadCurrentUpcoming(root, courseId);
+                    }.bind(this));
+                });
+            });
+
+            root.on('click', CalendarSelectors.editLink, function(e) {
+                e.preventDefault();
+                var target = $(e.currentTarget);
+
+                eventFormPromise.then(function(modal) {
+                    // When something within the calendar tells us the user wants
+                    // to edit an event then show the event form modal.
+                    var eventId = target.data('event-id');
+                    if (eventId) {
+                        modal.setEventId(eventId);
+                    }
+                    modal.show();
+                    return;
+                }).fail(Notification.exception);
+            });
+
+            root.on('change', CalendarSelectors.courseSelector, function() {
+                var selectElement = $(this);
+                var courseId = selectElement.val();
+                CalendarViewManager.reloadCurrentUpcoming(root, courseId)
+                    .then(function() {
+                        // We need to get the selector again because the content has changed.
+                        return root.find(CalendarSelectors.courseSelector).val(courseId);
+                    })
+                    .fail(Notification.exception);
+            });
+
+            body.on(CalendarEvents.filterChanged, function(e, data) {
+                var daysWithEvent = root.find(CalendarSelectors.eventType[data.type]);
+                if (data.hidden == true) {
+                    daysWithEvent.addClass('hidden');
+                } else {
+                    daysWithEvent.removeClass('hidden');
+                }
+            });
+        };
+
+        return {
+            init: function(root) {
+                root = $(root);
+
+                CalendarViewManager.init(root);
+                registerEventListeners(root);
+            }
+        };
+    });
index 0b59073..a5951e8 100644 (file)
@@ -133,11 +133,30 @@ define(['jquery', 'core/ajax'], function($, Ajax) {
         return Ajax.call([request])[0];
     };
 
+    /**
+     * Get calendar upcoming data.
+     *
+     * @method getCalendarUpcomingData
+     * @param {Number} courseid The course id.
+     * @return {promise} Resolved with the month view data.
+     */
+    var getCalendarUpcomingData = function(courseid) {
+        var request = {
+            methodname: 'core_calendar_get_calendar_upcoming_view',
+            args: {
+                courseid: courseid,
+            }
+        };
+
+        return Ajax.call([request])[0];
+    };
+
     return {
         getEventById: getEventById,
         deleteEvent: deleteEvent,
         updateEventStartDay: updateEventStartDay,
         submitCreateUpdateForm: submitCreateUpdateForm,
-        getCalendarMonthData: getCalendarMonthData
+        getCalendarMonthData: getCalendarMonthData,
+        getCalendarUpcomingData: getCalendarUpcomingData
     };
 });
index ef7e52f..2e05b44 100644 (file)
@@ -41,5 +41,13 @@ define([], function() {
         calendarPeriods: {
             month: "[data-period='month']",
         },
+        editLink: 'a[data-action="edit"]',
+        deleteLink: 'a[data-action="delete"]',
+        courseSelector: 'select[name="course"]',
+        newEventButton: 'button[data-action="new-event-button"]',
+        actions: {
+            edit: '[data-action="edit"]',
+            remove: '[data-action="delete"]',
+        },
     };
 });
index 1ed771a..038a9d5 100644 (file)
@@ -159,12 +159,43 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito
             loadingIconContainer.addClass('hidden');
         };
 
+        /**
+         * Reload the current month view data.
+         *
+         * @param {object} root The container element.
+         * @param {Number} courseId The course id.
+         * @return {promise}
+         */
+        var reloadCurrentUpcoming = function(root, courseId) {
+            startLoading(root);
+
+            var target = root.find(SELECTORS.CALENDAR_MONTH_WRAPPER);
+
+            return CalendarRepository.getCalendarUpcomingData(courseId)
+                .then(function(context) {
+                    return Templates.render(root.attr('data-template'), context);
+                })
+                .then(function(html, js) {
+                    window.history.replaceState(null, null, '?view=upcoming&course=' + courseId);
+                    return Templates.replaceNode(target, html, js);
+                })
+                .then(function() {
+                    $('body').trigger(CalendarEvents.viewUpdated);
+                    return;
+                })
+                .always(function() {
+                    return stopLoading(root);
+                })
+                .fail(Notification.exception);
+        };
+
         return {
             init: function(root) {
                 registerEventListeners(root);
             },
             reloadCurrentMonth: reloadCurrentMonth,
             changeMonth: changeMonth,
-            refreshMonthContent: refreshMonthContent
+            refreshMonthContent: refreshMonthContent,
+            reloadCurrentUpcoming: reloadCurrentUpcoming
         };
     });
index 1039d23..ddc9b03 100644 (file)
@@ -3157,8 +3157,9 @@ function calendar_get_view(\calendar_information $calendar, $view, $includenavig
         } else {
             $defaultlookahead = CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD;
         }
-        $tstart = $type->convert_to_timestamp($date['year'], $date['mon'], 1);
-        $tend = $tstart + get_user_preferences('calendar_lookahead', $defaultlookahead);
+
+        $tstart = $type->convert_to_timestamp($date['year'], $date['mon'], $date['mday'], $date['hours']);
+        $tend = usergetmidnight($tstart + DAYSECS * $defaultlookahead + 3 * HOURSECS) - 1;
     } else {
         $tstart = $type->convert_to_timestamp($date['year'], $date['mon'], 1);
         $monthdays = $type->get_num_days_in_month($date['year'], $date['mon']);
@@ -3238,6 +3239,10 @@ function calendar_get_view(\calendar_information $calendar, $view, $includenavig
         $day = new \core_calendar\external\day_exporter($calendar, $daydata, $related);
         $data = $day->export($renderer);
         $template = 'core_calendar/day_detailed';
+    } else if ($view == "upcoming") {
+        $upcoming = new \core_calendar\external\calendar_upcoming_exporter($calendar, $related);
+        $data = $upcoming->export($renderer);
+        $template = 'core_calendar/calendar_upcoming';
     }
 
     return [$data, $template];
index 3f4f31a..922363a 100644 (file)
     {
     }
 }}
-<div class="event">
+<div class="event" data-eventtype-{{calendareventtype}}="1" data-event-event-count="{{eventcount}}">
     <div class="card">
         <div class="box card-header clearfix p-y-1">
             <div class="commands pull-xs-right">
                 {{#canedit}}
                     {{#candelete}}
-                        <a href="{{deleteurl}}">
+                        <a href="{{deleteurl}}" data-event-id="{{id}}" data-action="delete" data-event-id="{{id}}" data-title="{{name}}" data-event-event-count="{{eventcount}}">
                             {{#pix}}t/delete, core, {{#str}}delete{{/str}}{{/pix}}
                         </a>
                     {{/candelete}}
-                    <a href="{{editurl}}">
+                    <a href="{{editurl}}" data-event-id="{{id}}" data-action="edit" data-event-id="{{id}}" data-title="{{name}}">
                         {{#pix}}t/edit, core, {{#str}}edit{{/str}}{{/pix}}
                     </a>
                 {{/canedit}}
index dec4fa2..7b6f28d 100644 (file)
@@ -31,7 +31,7 @@
     {
     }
 }}
-<div class="eventlist">
+<div class="eventlist m-y-1">
     {{#events}}
         {{> core_calendar/event_item }}
     {{/events}}
index 9265b19..52a713b 100644 (file)
@@ -144,18 +144,8 @@ if ($view == 'day' || $view == 'upcoming') {
             echo $renderer->render_from_template($template, $data);
         break;
         case 'upcoming':
-            $defaultlookahead = CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD;
-            if (isset($CFG->calendar_lookahead)) {
-                $defaultlookahead = intval($CFG->calendar_lookahead);
-            }
-            $lookahead = get_user_preferences('calendar_lookahead', $defaultlookahead);
-
-            $defaultmaxevents = CALENDAR_DEFAULT_UPCOMING_MAXEVENTS;
-            if (isset($CFG->calendar_maxevents)) {
-                $defaultmaxevents = intval($CFG->calendar_maxevents);
-            }
-            $maxevents = get_user_preferences('calendar_maxevents', $defaultmaxevents);
-            echo $renderer->show_upcoming_events($calendar, $lookahead, $maxevents);
+            list($data, $template) = calendar_get_view($calendar, $view);
+            echo $renderer->render_from_template($template, $data);
         break;
     }
 } else if ($view == 'month') {