MDL-68464 enrol_manual: Reload participants table after enroling

This commit is contained in:
Andrew Nicols 2020-04-20 11:24:26 +08:00
parent c50f5af248
commit e0e7b19f9c
5 changed files with 162 additions and 156 deletions

View 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');

View File

@ -1,2 +1,2 @@
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("enrol_manual/quickenrolment",["exports","jquery","core/str","core/fragment","core/modal_events","core/modal_factory","core/notification","core/templates","core/config","core/pending"],function(a,b,c,d,e,f,g,h,i,j){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=m(b);c=l(c);d=m(d);e=m(e);f=m(f);g=m(g);h=m(h);i=m(i);j=m(j);function k(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;k=function(){return a};return a}function l(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=k();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function m(a){return a&&a.__esModule?a:{default:a}}function n(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function o(a,b){for(var c=0,d;c<b.length;c++){d=b[c];d.enumerable=d.enumerable||!1;d.configurable=!0;if("value"in d)d.writable=!0;Object.defineProperty(a,d.key,d)}}function p(a,b,c){if(b)o(a.prototype,b);if(c)o(a,c);return a}var q={cohortSelector:"#id_cohortlist",triggerButtons:".enrolusersbutton.enrol_manual_plugin [type='submit']",unwantedHiddenFields:":input[value='_qf__force_multiselect_submission']"},r=function(){function a(b){n(this,a);this.contextId=b;this.initModal()}p(a,[{key:"initModal",value:function initModal(){var a=(0,b.default)(q.triggerButtons);b.default.when(c.get_strings([{key:"enroluserscohorts",component:"enrol_manual"},{key:"enrolusers",component:"enrol_manual"}]),f.default.create({type:f.default.types.SAVE_CANCEL,large:!0},a)).then(function(a,c){this.modal=c;c.setTitle(a[1]);c.setSaveButtonText(a[1]);c.getRoot().on(e.default.save,this.submitForm.bind(this));c.getRoot().on("submit","form",this.submitFormAjax.bind(this));c.getRoot().on(e.default.hidden,function(){c.setBody("")});c.getRoot().on(e.default.shown,function(){var d=new j.default("enrol_manual/quickenrolment:initModal:shown"),e=this.getBody();e.then(function(d){var e=(0,b.default)(d).find(q.cohortSelector).length?0:1;c.setSaveButtonText(a[e])}).then(d.resolve).catch(g.default.exception);c.setBody(e)}.bind(this))}.bind(this)).fail(g.default.exception)}},{key:"submitForm",value:function submitForm(a){a.preventDefault();this.modal.getRoot().find("form").submit()}},{key:"submitFormAjax",value:function submitFormAjax(a){a.preventDefault();var c=this.modal.getRoot().find("form"),d=c.find(q.unwantedHiddenFields);d.each(function(){(0,b.default)(this).remove()});var e=c.serialize();this.modal.hide();var f=i.default.wwwroot+"/enrol/manual/ajax.php?"+e;b.default.ajax(f,{type:"GET",processData:!1,contentType:"application/json"}).then(function(a){if(a.error){g.default.addNotification({message:a.error,type:"error"})}else{if("undefined"!=typeof window.M.core_formchangechecker){window.M.core_formchangechecker.reset_form_dirty_state()}window.location.reload()}}).fail(g.default.exception)}},{key:"getBody",value:function getBody(){return d.default.loadFragment("enrol_manual","enrol_users_form",this.contextId,{}).fail(g.default.exception)}},{key:"getFooter",value:function getFooter(){return h.default.render("enrol_manual/enrol_modal_footer",{})}}]);return a}();a.init=function init(a){var b=a.contextid;new r(b)}});
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("enrol_manual/quickenrolment",["exports","core_table/dynamic","core/str","core/toast","core/config","core/fragment","core/modal_events","core/modal_factory","core/notification","jquery","core/prefetch"],function(a,b,c,d,e,f,g,h,i,j,k){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=n(b);c=n(c);d=n(d);e=l(e);f=l(f);g=l(g);h=l(h);i=l(i);j=l(j);k=l(k);function l(a){return a&&a.__esModule?a:{default:a}}function m(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;m=function(){return a};return a}function n(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=m();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}var o={cohortSelector:"#id_cohortlist",triggerButtons:".enrolusersbutton.enrol_manual_plugin [type='submit']",unwantedHiddenFields:"input[value='_qf__force_multiselect_submission']",buttonWrapper:"[data-region=\"wrapper\"]"},p=function(a){return f.default.loadFragment("enrol_manual","enrol_users_form",a,{})},q=function(a){var c=a.closest(o.buttonWrapper);return b.getTableFromId(c.dataset.tableUniqueid)},r=function(a){document.addEventListener("click",function(b){if(b.target.closest(o.triggerButtons)){b.preventDefault();s(q(b.target),a)}})},s=function(a,b){return h.default.create({type:h.default.types.SAVE_CANCEL,large:!0,title:c.get_string("enrolusers","enrol_manual"),body:p(b)}).then(function(b){b.getRoot().on(g.default.save,function(a){a.preventDefault();b.getRoot().find("form").submit()});b.getRoot().on("submit","form",function(c){c.preventDefault();t(a,b)});b.getRoot().on(g.default.hidden,function(){b.destroy()});return b}).then(function(a){a.show();return a}).then(function(a){a.setSaveButtonText(c.get_string("enrolusers","enrol_manual"));a.getBodyPromise().then(function(b){if(b.get(0).querySelector(o.cohortSelector)){a.setSaveButtonText(c.get_string("enroluserscohorts","enrol_manual"))}return b}).catch();return a}).catch(i.default.exception)},t=function(a,f){var g=f.getRoot().find("form");g.get(0).querySelectorAll(o.unwantedHiddenFields).forEach(function(a){return a.remove()});f.hide();f.destroy();j.default.ajax("".concat(e.default.wwwroot,"/enrol/manual/ajax.php?").concat(g.serialize()),{type:"GET",processData:!1,contentType:"application/json"}).then(function(d){if(d.error){throw new Error(d.error)}b.refreshTableContent(a);return c.get_string("totalenrolledusers","enrol",d.count)}).then(function(a){return d.add(a)}).catch(function(a){i.default.addNotification({message:a.message,type:"error"})})},u=function(a){var b=a.contextid;r(b);k.default.prefetchStrings("enrol_manual",["enrolusers","enroluserscohorts"]);k.default.prefetchString("enrol","totalenrolledusers")};a.init=u});
//# sourceMappingURL=quickenrolment.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -20,169 +20,175 @@
* @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"]',
};
const QuickEnrolment = class {
constructor(contextId) {
this.contextId = contextId;
/**
* 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, {});
};
this.initModal();
}
/**
* Get the dynamic table for the button.
*
* @param {HTMLElement} element
* @returns {HTMLElement}
*/
const getDynamicTableForElement = element => {
const wrapper = element.closest(Selectors.buttonWrapper);
/**
* Private method
*
* @method initModal
* @private
*/
initModal() {
var triggerButtons = jQuery(Selectors.triggerButtons);
return DynamicTable.getTableFromId(wrapper.dataset.tableUniqueid);
};
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;
/**
* 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();
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));
showModal(getDynamicTableForElement(e.target), contextId);
return;
}.bind(this))
.fail(Notification.exception);
}
});
};
}
/**
* 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.
/**
* 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();
e.preventDefault();
modal.getRoot().find('form').submit();
});
var formData = form.serialize();
modal.getRoot().on('submit', 'form', e => {
e.preventDefault();
this.modal.hide();
submitFormAjax(dynamicTable, modal);
});
var settings = {
modal.getRoot().on(ModalEvents.hidden, () => {
modal.destroy();
});
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());
modal.hide();
modal.destroy();
jQuery.ajax(
`${Config.wwwroot}/enrol/manual/ajax.php?${form.serialize()}`,
{
type: 'GET',
processData: false,
contentType: "application/json"
};
contentType: "application/json",
}
)
.then(response => {
if (response.error) {
throw new Error(response.error);
}
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', {});
}
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');
};

View 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();