MDL-68464 enrol_manual: Reload participants table after enroling
authorAndrew Nicols <andrew@nicols.co.uk>
Mon, 20 Apr 2020 03:24:26 +0000 (11:24 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Tue, 19 May 2020 04:37:21 +0000 (12:37 +0800)
enrol/manual/ajax.php
enrol/manual/amd/build/quickenrolment.min.js
enrol/manual/amd/build/quickenrolment.min.js.map
enrol/manual/amd/src/quickenrolment.js
user/index.php

index ba73f21..29cb40e 100644 (file)
@@ -58,6 +58,7 @@ $outcome = new stdClass();
 $outcome->success = true;
 $outcome->response = new stdClass();
 $outcome->error = '';
+$outcome->count = 0;
 
 $searchanywhere = get_user_preferences('userselector_searchanywhere', false);
 
@@ -157,14 +158,10 @@ switch ($action) {
             foreach ($users as $user) {
                 $plugin->enrol_user($instance, $user->id, $roleid, $timestart, $timeend, null, $recovergrades);
             }
-            $counter = count($users);
+            $outcome->count += count($users);
             foreach ($cohorts as $cohort) {
                 $totalenrolledusers = $plugin->enrol_cohort($instance, $cohort->id, $roleid, $timestart, $timeend, null, $recovergrades);
-                $counter += $totalenrolledusers;
-            }
-            // Display a notification message after the bulk user enrollment.
-            if ($counter > 0) {
-                \core\notification::info(get_string('totalenrolledusers', 'enrol', $counter));
+                $outcome->count += $totalenrolledusers;
             }
         } else {
             throw new enrol_ajax_exception('enrolnotpermitted');
index d5d24a5..ee9d82b 100644 (file)
Binary files a/enrol/manual/amd/build/quickenrolment.min.js and b/enrol/manual/amd/build/quickenrolment.min.js differ
index 4c4e5c8..a413c22 100644 (file)
Binary files a/enrol/manual/amd/build/quickenrolment.min.js.map and b/enrol/manual/amd/build/quickenrolment.min.js.map differ
index afcfc3f..087e4c4 100644 (file)
  * @copyright  2016 Damyon Wiese <damyon@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-import jQuery from 'jquery';
+import * as DynamicTable from 'core_table/dynamic';
 import * as Str from 'core/str';
+import * as Toast from 'core/toast';
+import Config from 'core/config';
 import Fragment from 'core/fragment';
 import ModalEvents from 'core/modal_events';
 import ModalFactory from 'core/modal_factory';
 import Notification from 'core/notification';
-import Templates from 'core/templates';
-import Config from 'core/config';
-import Pending from 'core/pending';
+import jQuery from 'jquery';
+import Prefetch from 'core/prefetch';
 
 const Selectors = {
     cohortSelector: "#id_cohortlist",
     triggerButtons: ".enrolusersbutton.enrol_manual_plugin [type='submit']",
-    unwantedHiddenFields: ":input[value='_qf__force_multiselect_submission']"
+    unwantedHiddenFields: "input[value='_qf__force_multiselect_submission']",
+    buttonWrapper: '[data-region="wrapper"]',
+};
+
+/**
+ * Get the content of the body for the specified context.
+ *
+ * @param {Number} contextId
+ * @returns {Promise}
+ */
+const getBodyForContext = contextId => {
+    return Fragment.loadFragment('enrol_manual', 'enrol_users_form', contextId, {});
 };
 
-const QuickEnrolment = class {
-    constructor(contextId) {
-        this.contextId = contextId;
-
-        this.initModal();
-    }
-
-    /**
-     * Private method
-     *
-     * @method initModal
-     * @private
-     */
-    initModal() {
-        var triggerButtons = jQuery(Selectors.triggerButtons);
-
-        jQuery.when(
-            Str.get_strings([
-                {key: 'enroluserscohorts', component: 'enrol_manual'},
-                {key: 'enrolusers', component: 'enrol_manual'},
-            ]),
-            ModalFactory.create({
-                type: ModalFactory.types.SAVE_CANCEL,
-                large: true,
-            }, triggerButtons)
-        )
-        .then(function(strings, modal) {
-            this.modal = modal;
-
-            modal.setTitle(strings[1]);
-            modal.setSaveButtonText(strings[1]);
-
-            modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));
-            modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));
-
-            // We want the reset the form every time it is opened.
-            modal.getRoot().on(ModalEvents.hidden, function() {
-                modal.setBody('');
-            });
-
-            modal.getRoot().on(ModalEvents.shown, function() {
-                var pendingPromise = new Pending('enrol_manual/quickenrolment:initModal:shown');
-                var bodyPromise = this.getBody();
-                bodyPromise.then(function(html) {
-                    var stringIndex = jQuery(html).find(Selectors.cohortSelector).length ? 0 : 1;
-                    modal.setSaveButtonText(strings[stringIndex]);
-
-                    return;
-                })
-                .then(pendingPromise.resolve)
-                .catch(Notification.exception);
-
-                modal.setBody(bodyPromise);
-            }.bind(this));
+/**
+ * Get the dynamic table for the button.
+ *
+ * @param {HTMLElement} element
+ * @returns {HTMLElement}
+ */
+const getDynamicTableForElement = element => {
+    const wrapper = element.closest(Selectors.buttonWrapper);
+
+    return DynamicTable.getTableFromId(wrapper.dataset.tableUniqueid);
+};
+
+/**
+ * Register the event listeners for this contextid.
+ *
+ * @param {Number} contextId
+ */
+const registerEventListeners = contextId => {
+    document.addEventListener('click', e => {
+        if (e.target.closest(Selectors.triggerButtons)) {
+            e.preventDefault();
+
+            showModal(getDynamicTableForElement(e.target), contextId);
 
             return;
-        }.bind(this))
-        .fail(Notification.exception);
-
-    }
-
-    /**
-     * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.
-     *
-     * @method submitForm
-     * @param {Event} e Form submission event.
-     * @private
-     */
-    submitForm(e) {
-        e.preventDefault();
-        this.modal.getRoot().find('form').submit();
-    }
-
-    /**
-     * Private method
-     *
-     * @method submitForm
-     * @private
-     * @param {Event} e Form submission event.
-     */
-    submitFormAjax(e) {
-        // We don't want to do a real form submission.
-        e.preventDefault();
-
-        var form = this.modal.getRoot().find('form');
-
-        // Before send the data through AJAX, we need to parse and remove some unwanted hidden fields.
-        // This hidden fields are added automatically by mforms and when it reaches the AJAX we get an error.
-        var hidden = form.find(Selectors.unwantedHiddenFields);
-        hidden.each(function() {
-            jQuery(this).remove();
+        }
+    });
+};
+
+/**
+ * Display the modal for this contextId.
+ *
+ * @param {HTMLElement} dynamicTable The table to beb refreshed when changes are made
+ * @param {Number} contextId
+ * @returns {Promise}
+ */
+const showModal = (dynamicTable, contextId) => {
+    return ModalFactory.create({
+        type: ModalFactory.types.SAVE_CANCEL,
+        large: true,
+        title: Str.get_string('enrolusers', 'enrol_manual'),
+        body: getBodyForContext(contextId),
+    })
+    .then(modal => {
+        modal.getRoot().on(ModalEvents.save, e => {
+            // Trigger a form submission, so that any mform elements can do final tricks before the form submission
+            // is processed.
+            // The actual submit even tis captured in the next handler.
+
+            e.preventDefault();
+            modal.getRoot().find('form').submit();
+        });
+
+        modal.getRoot().on('submit', 'form', e => {
+            e.preventDefault();
+
+            submitFormAjax(dynamicTable, modal);
+        });
+
+        modal.getRoot().on(ModalEvents.hidden, () => {
+            modal.destroy();
         });
 
-        var formData = form.serialize();
+        return modal;
+    })
+    .then(modal => {
+        modal.show();
+
+        return modal;
+    })
+    .then(modal => {
+        modal.setSaveButtonText(Str.get_string('enrolusers', 'enrol_manual'));
+
+        modal.getBodyPromise().then(body => {
+            if (body.get(0).querySelector(Selectors.cohortSelector)) {
+                modal.setSaveButtonText(Str.get_string('enroluserscohorts', 'enrol_manual'));
+            }
+
+            return body;
+        })
+        .catch();
+
+        return modal;
+    })
+    .catch(Notification.exception);
+};
+
+/**
+ * Submit the form via ajax.
+ *
+ * @param {HTMLElement} dynamicTable
+ * @param {Object} modal
+ */
+const submitFormAjax = (dynamicTable, modal) => {
+    // Note: We use a jQuery object here so that we can use its serialize functionality.
+    const form = modal.getRoot().find('form');
+
+    // Before send the data through AJAX, we need to parse and remove some unwanted hidden fields.
+    // This hidden fields are added automatically by mforms and when it reaches the AJAX we get an error.
+    form.get(0).querySelectorAll(Selectors.unwantedHiddenFields).forEach(hiddenField => hiddenField.remove());
 
-        this.modal.hide();
+    modal.hide();
+    modal.destroy();
 
-        var settings = {
+    jQuery.ajax(
+        `${Config.wwwroot}/enrol/manual/ajax.php?${form.serialize()}`,
+        {
             type: 'GET',
             processData: false,
-            contentType: "application/json"
-        };
-
-        var script = Config.wwwroot + '/enrol/manual/ajax.php?' + formData;
-        jQuery.ajax(script, settings)
-            .then(function(response) {
-
-                if (response.error) {
-                    Notification.addNotification({
-                        message: response.error,
-                        type: "error"
-                    });
-                } else {
-                    // Reload the page, don't show changed data warnings.
-                    if (typeof window.M.core_formchangechecker !== "undefined") {
-                        window.M.core_formchangechecker.reset_form_dirty_state();
-                    }
-                    window.location.reload();
-                }
-                return;
-            })
-            .fail(Notification.exception);
-    }
-
-    /**
-     * Private method
-     *
-     * @method getBody
-     * @private
-     * @return {Promise}
-     */
-    getBody() {
-        return Fragment.loadFragment('enrol_manual', 'enrol_users_form', this.contextId, {}).fail(Notification.exception);
-    }
-
-    /**
-     * Private method
-     *
-     * @method getFooter
-     * @private
-     * @return {Promise}
-     */
-    getFooter() {
-        return Templates.render('enrol_manual/enrol_modal_footer', {});
-    }
+            contentType: "application/json",
+        }
+    )
+    .then(response => {
+        if (response.error) {
+            throw new Error(response.error);
+        }
+
+        DynamicTable.refreshTableContent(dynamicTable);
+        return Str.get_string('totalenrolledusers', 'enrol', response.count);
+    })
+    .then(notificationBody => Toast.add(notificationBody))
+    .catch(error => {
+        Notification.addNotification({
+            message: error.message,
+            type: 'error',
+        });
+    });
 };
 
+/**
+ * Set up quick enrolment for the manual enrolment plugin.
+ *
+ * @param {Number} contextid The context id to setup for
+ */
 export const init = ({contextid}) => {
-    new QuickEnrolment(contextid);
+    registerEventListeners(contextid);
+
+    Prefetch.prefetchStrings('enrol_manual', [
+        'enrolusers',
+        'enroluserscohorts',
+    ]);
+
+    Prefetch.prefetchString('enrol', 'totalenrolledusers');
 };
index 92f81e2..26e5f20 100644 (file)
@@ -224,6 +224,16 @@ if ($groupid > 0 && ($course->groupmode != SEPARATEGROUPS || $canaccessallgroups
     echo $grouprenderer->group_details($groupdetailpage);
 }
 
+// Should use this variable so that we don't break stuff every time a variable is added or changed.
+$baseurl = new moodle_url('/user/index.php', array(
+        'contextid' => $context->id,
+        'id' => $course->id,
+        'perpage' => $perpage));
+
+$participanttable = new \core_user\table\participants("user-index-participants-{$course->id}");
+$participanttable->set_selectall($selectall);
+$participanttable->define_baseurl($baseurl);
+
 // Manage enrolments.
 $manager = new course_enrolment_manager($PAGE, $course);
 $enrolbuttons = $manager->get_manual_enrol_buttons();
@@ -232,13 +242,10 @@ $enrolbuttonsout = '';
 foreach ($enrolbuttons as $enrolbutton) {
     $enrolbuttonsout .= $enrolrenderer->render($enrolbutton);
 }
-echo html_writer::div($enrolbuttonsout, 'float-right');
-
-// Should use this variable so that we don't break stuff every time a variable is added or changed.
-$baseurl = new moodle_url('/user/index.php', array(
-        'contextid' => $context->id,
-        'id' => $course->id,
-        'perpage' => $perpage));
+echo html_writer::div($enrolbuttonsout, 'float-right', [
+    'data-region' => 'wrapper',
+    'data-table-uniqueid' => $participanttable->uniqueid,
+]);
 
 // Render the unified filter.
 $renderer = $PAGE->get_renderer('core_user');
@@ -275,13 +282,9 @@ if (count($keywordfilter)) {
     $filterset->add_filter($keywordfilter);
 }
 
-$participanttable = new \core_user\table\participants("user-index-participants-{$course->id}");
-$participanttable->set_selectall($selectall);
-$participanttable->set_filterset($filterset);
-$participanttable->define_baseurl($baseurl);
-
 // Do this so we can get the total number of rows.
 ob_start();
+$participanttable->set_filterset($filterset);
 $participanttable->out($perpage, true);
 $participanttablehtml = ob_get_contents();
 ob_end_clean();