MDL-59758 core_user: Replace old bulk actions
The participants page has some clunky multi page forms for bulk actions. Replaces it with an ajax alternative.
This commit is contained in:
@@ -159,3 +159,7 @@ privacy,core_hub
|
||||
privacy_help,core_hub
|
||||
configloginhttps,core_admin
|
||||
loginhttps,core_admin
|
||||
groupaddnewnote,core_notes
|
||||
selectnotestate,core_notes
|
||||
extendenrol,core
|
||||
groupextendenrol,core
|
||||
|
||||
@@ -111,6 +111,8 @@ $string['send'] = 'Send';
|
||||
$string['sendingvia'] = 'Sending "{$a->provider}" via "{$a->processor}"';
|
||||
$string['sendingviawhen'] = 'Sending "{$a->provider}" via "{$a->processor}" when {$a->state}';
|
||||
$string['sendmessage'] = 'Send message';
|
||||
$string['sendbulkmessage'] = 'Send message to {$a} people';
|
||||
$string['sendbulkmessagesent'] = 'Message sent to {$a} people.';
|
||||
$string['sendmessageto'] = 'Send message to {$a}';
|
||||
$string['sendmessagetopopup'] = 'Send message to {$a} - new window';
|
||||
$string['settings'] = 'Settings';
|
||||
|
||||
+2
-2
@@ -793,7 +793,6 @@ $string['expand'] = 'Expand';
|
||||
$string['expandall'] = 'Expand all';
|
||||
$string['expandcategory'] = 'Expand {$a}';
|
||||
$string['explanation'] = 'Explanation';
|
||||
$string['extendenrol'] = 'Extend enrolment (individual)';
|
||||
$string['extendperiod'] = 'Extended period';
|
||||
$string['failedloginattempts'] = '{$a->attempts} failed logins since your last login';
|
||||
$string['feedback'] = 'Feedback';
|
||||
@@ -904,7 +903,6 @@ $string['gravatarenabled'] = '<a href="http://www.gravatar.com/">Gravatar</a> ha
|
||||
$string['group'] = 'Group';
|
||||
$string['groupadd'] = 'Add new group';
|
||||
$string['groupaddusers'] = 'Add selected to group';
|
||||
$string['groupextendenrol'] = 'Extend enrolment (common)';
|
||||
$string['groupfor'] = 'for group';
|
||||
$string['groupinfo'] = 'Info about selected group';
|
||||
$string['groupinfoedit'] = 'Edit group settings';
|
||||
@@ -2165,3 +2163,5 @@ $string['sectionusedefaultname'] = 'Use default section name';
|
||||
|
||||
// Deprecated since Moodle 3.4.
|
||||
$string['publish'] = 'Publish';
|
||||
$string['extendenrol'] = 'Extend enrolment (individual)';
|
||||
$string['groupextendenrol'] = 'Extend enrolment (common)';
|
||||
|
||||
+5
-2
@@ -24,6 +24,8 @@
|
||||
*/
|
||||
|
||||
$string['addnewnote'] = 'Add a new note';
|
||||
$string['addbulknote'] = 'Add a new note to {$a} people';
|
||||
$string['addbulknotedone'] = 'Note added to {$a} people';
|
||||
$string['addnewnoteselect'] = 'Select users to write notes about';
|
||||
$string['bynameondate'] = 'by {$a->name} - {$a->date}';
|
||||
$string['configenablenotes'] = 'Enable storing of notes about individual users.';
|
||||
@@ -39,7 +41,6 @@ $string['eventnotecreated'] = 'Note created';
|
||||
$string['eventnoteupdated'] = 'Note updated';
|
||||
$string['eventnotedeleted'] = 'Note deleted';
|
||||
$string['eventnotesviewed'] = 'Notes viewed';
|
||||
$string['groupaddnewnote'] = 'Add a common note';
|
||||
$string['invalidid'] = 'Invalid note ID specified';
|
||||
$string['invaliduserid'] = 'Invalid user id: {$a}';
|
||||
$string['myprofileownnotes'] = 'My notes';
|
||||
@@ -61,8 +62,10 @@ $string['publishstate_help'] = 'A note\'s context determines who can see the not
|
||||
* Personal - The note will be visible only to you
|
||||
* Course - The note will be visible to teachers in this course
|
||||
* Site - The note will be visible to teachers in all courses';
|
||||
$string['selectnotestate'] = "Select note state";
|
||||
$string['site'] = 'site';
|
||||
$string['sitenotes'] = 'Site notes';
|
||||
$string['unknown'] = 'unknown';
|
||||
|
||||
// Deprecated since Moodle 3.4
|
||||
$string['groupaddnewnote'] = 'Add a common note';
|
||||
$string['selectnotestate'] = "Select note state";
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
define(["jquery"],function(a){var b={ELEMENT:"[data-auto-rows]"},c={ROW_CHANGE:"autorows:rowchange"},d=function(a){var b=a.attr("rows"),c=a.data("min-rows"),d=a.attr("data-max-rows"),e=a.height(),f=a.innerHeight(),g=f-e;a.height("1px");var h=a[0].scrollHeight,i=(h-g)/(e/b);return a.css("height",""),i<c?c:d&&i>=d?d:i},e=function(b,e){var f=a(e.target),g=f.data("min-rows"),h=f.attr("rows");"undefined"==typeof g&&f.data("min-rows",h);var i=d(f);i!=h&&(f.attr("rows",i),f.trigger(c.ROW_CHANGE))},f=function(c){a(c).data("auto-rows")?a(c).on("input propertychange",e.bind(this,c)):a(c).on("input propertychange",b.ELEMENT,e.bind(this,c))};return{init:f,events:c}});
|
||||
define(["jquery"],function(a){var b={ELEMENT:"[data-auto-rows]"},c={ROW_CHANGE:"autorows:rowchange"},d=function(a){var b=a.attr("rows"),c=a.data("min-rows"),d=a.attr("data-max-rows"),e=a.height(),f=a.innerHeight(),g=f-e;a.height("1px");var h=a[0].scrollHeight,i=(h-g)/(e/b);return a.css("height",""),i<c?c:d&&i>=d?d:i},e=function(b){var e=a(b.target),f=e.data("min-rows"),g=e.attr("rows");"undefined"==typeof f&&e.data("min-rows",g);var h=d(e);h!=g&&(e.attr("rows",h),e.trigger(c.ROW_CHANGE))},f=function(c){a(c).data("auto-rows")?a(c).on("input propertychange",e.bind(this)):a(c).on("input propertychange",b.ELEMENT,e.bind(this))};return{init:f,events:c}});
|
||||
@@ -75,7 +75,7 @@ define(['jquery'], function($) {
|
||||
* @param {Event} e The triggered event.
|
||||
* @private
|
||||
*/
|
||||
var changeListener = function(root, e) {
|
||||
var changeListener = function(e) {
|
||||
var element = $(e.target);
|
||||
var minRows = element.data('min-rows');
|
||||
var currentRows = element.attr('rows');
|
||||
@@ -100,9 +100,9 @@ define(['jquery'], function($) {
|
||||
*/
|
||||
var init = function(root) {
|
||||
if ($(root).data('auto-rows')) {
|
||||
$(root).on('input propertychange', changeListener.bind(this, root));
|
||||
$(root).on('input propertychange', changeListener.bind(this));
|
||||
} else {
|
||||
$(root).on('input propertychange', SELECTORS.ELEMENT, changeListener.bind(this, root));
|
||||
$(root).on('input propertychange', SELECTORS.ELEMENT, changeListener.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1034,6 +1034,7 @@ $functions = array(
|
||||
'classpath' => 'notes/externallib.php',
|
||||
'description' => 'Create notes',
|
||||
'type' => 'write',
|
||||
'ajax' => true,
|
||||
'capabilities' => 'moodle/notes:manage',
|
||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||
),
|
||||
|
||||
@@ -113,6 +113,11 @@ function note_save(&$note) {
|
||||
if (empty($note->publishstate)) {
|
||||
$note->publishstate = NOTES_STATE_PUBLIC;
|
||||
}
|
||||
|
||||
if (empty(trim($note->content))) {
|
||||
// Don't save empty notes.
|
||||
return false;
|
||||
}
|
||||
// Save data.
|
||||
if (empty($note->id)) {
|
||||
// Insert new note.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@core @core_notes
|
||||
@core @core_notes @javascript
|
||||
Feature: Add notes to course participants
|
||||
In order to share information with other staff
|
||||
As a teacher
|
||||
@@ -34,15 +34,19 @@ Feature: Add notes to course participants
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Participants"
|
||||
And I set the field with xpath "//tr[contains(normalize-space(.), 'Student 1')]//input[@type='checkbox']" to "1"
|
||||
And I choose "Add a new note" from the participants page bulk action menu
|
||||
And I set the field "bulk-note" to "Student 1 needs to pick up his game"
|
||||
And I press "Add a new note to 1 people"
|
||||
And I set the field with xpath "//tr[contains(normalize-space(.), 'Student 1')]//input[@type='checkbox']" to "0"
|
||||
And I set the field with xpath "//tr[contains(normalize-space(.), 'Student 2')]//input[@type='checkbox']" to "1"
|
||||
And I choose "Add a new note" from the participants page bulk action menu
|
||||
And I set the field "bulk-note" to ""
|
||||
And I press "Add a new note to 1 people"
|
||||
And I set the field with xpath "//tr[contains(normalize-space(.), 'Student 2')]//input[@type='checkbox']" to "0"
|
||||
And I set the field with xpath "//tr[contains(normalize-space(.), 'Student 3')]//input[@type='checkbox']" to "1"
|
||||
And I set the field "With selected users..." to "Add a new note"
|
||||
And I press "OK"
|
||||
# Add a note to student 1, but leave student 2 empty and student 3 with space.
|
||||
When I set the field with xpath "//tr[contains(normalize-space(.), 'Student 1')]//textarea" to "Student 1 needs to pick up his game"
|
||||
And I set the field with xpath "//tr[contains(normalize-space(.), 'Student 2')]//textarea" to ""
|
||||
And I set the field with xpath "//tr[contains(normalize-space(.), 'Student 3')]//textarea" to " "
|
||||
And I press "Save changes"
|
||||
And I choose "Add a new note" from the participants page bulk action menu
|
||||
And I set the field "bulk-note" to " "
|
||||
And I press "Add a new note to 1 people"
|
||||
And I follow "Student 1"
|
||||
And I follow "Notes"
|
||||
# Student 1 has note from Teacher
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
require('../../config.php');
|
||||
require_once($CFG->dirroot.'/lib/tablelib.php');
|
||||
require_once($CFG->dirroot.'/notes/lib.php');
|
||||
require_once($CFG->dirroot.'/report/participation/locallib.php');
|
||||
|
||||
define('DEFAULT_PAGE_SIZE', 20);
|
||||
@@ -336,7 +337,7 @@ if (!empty($instanceid) && !empty($roleid)) {
|
||||
echo '<h2>'.get_string('counteditems', '', $a).'</h2>'."\n";
|
||||
|
||||
if (!empty($CFG->messaging)) {
|
||||
echo '<form action="'.$CFG->wwwroot.'/user/action_redir.php" method="post" id="studentsform">'."\n";
|
||||
echo '<form action="'.$CFG->wwwroot.'/user/action_redir.php" method="post" id="participantsform">'."\n";
|
||||
echo '<div>'."\n";
|
||||
echo '<input type="hidden" name="id" value="'.$id.'" />'."\n";
|
||||
echo '<input type="hidden" name="returnto" value="'. s($PAGE->url) .'" />'."\n";
|
||||
@@ -372,23 +373,25 @@ if (!empty($instanceid) && !empty($roleid)) {
|
||||
if (!empty($CFG->messaging)) {
|
||||
$buttonclasses = 'btn btn-secondary';
|
||||
echo '<div class="selectbuttons btn-group">';
|
||||
echo '<input type="button" id="checkall" value="'.get_string('selectall').'" class="'. $buttonclasses .'"> '."\n";
|
||||
echo '<input type="button" id="checkallonpage" value="'.get_string('selectall').'" class="'. $buttonclasses .'"> '."\n";
|
||||
echo '<input type="button" id="checknone" value="'.get_string('deselectall').'" class="'. $buttonclasses .'"> '."\n";
|
||||
if ($perpage >= $matchcount) {
|
||||
echo '<input type="button" id="checknos" value="'.get_string('selectnos').'" class="'. $buttonclasses .'">'."\n";
|
||||
echo '<input type="button" id="checkallnos" value="'.get_string('selectnos').'" class="'. $buttonclasses .'">'."\n";
|
||||
}
|
||||
echo '</div>';
|
||||
echo '<div class="p-y-1">';
|
||||
echo html_writer::label(get_string('withselectedusers'), 'formactionselect');
|
||||
$displaylist['messageselect.php'] = get_string('messageselectadd');
|
||||
echo html_writer::select($displaylist, 'formaction', '', array('' => 'choosedots'), array('id' => 'formactionselect'));
|
||||
echo $OUTPUT->help_icon('withselectedusers');
|
||||
echo '<input type="submit" value="' . get_string('ok') . '" class="'. $buttonclasses .'"/>'."\n";
|
||||
$displaylist['#messageselect'] = get_string('messageselectadd');
|
||||
echo html_writer::select($displaylist, 'formaction', '', array('' => 'choosedots'), array('id' => 'formactionid'));
|
||||
echo '</div>';
|
||||
echo '</div>'."\n";
|
||||
echo '</form>'."\n";
|
||||
|
||||
$PAGE->requires->js_init_call('M.report_participation.init');
|
||||
$options = new stdClass();
|
||||
$options->courseid = $course->id;
|
||||
$options->noteStateNames = note_get_state_names();
|
||||
$options->stateHelpIcon = $OUTPUT->help_icon('publishstate', 'notes');
|
||||
$PAGE->requires->js_call_amd('core_user/participants', 'init', [$options]);
|
||||
}
|
||||
echo '</div>'."\n";
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
M.report_participation = {};
|
||||
|
||||
M.report_participation.init = function(Y) {
|
||||
|
||||
Y.on('submit', function(e) {
|
||||
Y.one('#formactionselect').get('options').each(function() {
|
||||
if (this.get('selected') && this.get('value') == '') {
|
||||
// no action selected
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
var ok = false;
|
||||
Y.all('input.usercheckbox').each(function() {
|
||||
if (this.get('checked')) {
|
||||
ok = true;
|
||||
}
|
||||
});
|
||||
if (!ok) {
|
||||
// no checkbox selected
|
||||
e.preventDefault();
|
||||
}
|
||||
}, '#studentsform');
|
||||
|
||||
Y.on('click', function(e) {
|
||||
Y.all('input.usercheckbox').each(function() {
|
||||
this.set('checked', 'checked');
|
||||
});
|
||||
}, '#checkall');
|
||||
|
||||
Y.on('click', function(e) {
|
||||
Y.all('input.usercheckbox').each(function() {
|
||||
this.set('checked', '');
|
||||
});
|
||||
}, '#checknone');
|
||||
|
||||
Y.on('click', function(e) {
|
||||
Y.all('input.usercheckbox').each(function() {
|
||||
if (this.get('value') == 0) {
|
||||
this.set('checked', 'checked');
|
||||
}
|
||||
});
|
||||
}, '#checknos');
|
||||
};
|
||||
@@ -46,12 +46,8 @@ Feature: Use the particiaption report to message groups of students
|
||||
And I should see "No" in the "Student 2" "table_row"
|
||||
And I should see "No" in the "Student 3" "table_row"
|
||||
When I press "Select all 'No'"
|
||||
And I set the field "With selected users..." to "Send a message"
|
||||
And I press "OK"
|
||||
Then I should see "Added 2 new recipients"
|
||||
And I should see "Student 2" in the "Currently selected users" "table"
|
||||
And I should see "Student 3" in the "Currently selected users" "table"
|
||||
And I should not see "Student 1" in the "Currently selected users" "table"
|
||||
And I choose "Send a message" from the participants page bulk action menu
|
||||
Then I should see "Send message to 2 people"
|
||||
|
||||
Scenario: Ensure no message options when messaging is disabled
|
||||
Given I log in as "admin"
|
||||
|
||||
@@ -30,13 +30,8 @@ $id = required_param('id', PARAM_INT);
|
||||
$PAGE->set_url('/user/action_redir.php', array('formaction' => $formaction, 'id' => $id));
|
||||
list($formaction) = explode('?', $formaction, 2);
|
||||
|
||||
// Add every page will be redirected by this script.
|
||||
$actions = array(
|
||||
'messageselect.php',
|
||||
'addnote.php',
|
||||
'groupaddnote.php',
|
||||
'bulkchange.php'
|
||||
);
|
||||
// This page now only handles the bulk enrolment change actions, other actions are done with ajax.
|
||||
$actions = array('bulkchange.php');
|
||||
|
||||
if (array_search($formaction, $actions) === false) {
|
||||
print_error('unknownuseraction');
|
||||
@@ -175,5 +170,5 @@ if ($formaction == 'bulkchange.php') {
|
||||
exit();
|
||||
|
||||
} else {
|
||||
require_once($formaction);
|
||||
throw new coding_exception('invalidaction');
|
||||
}
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
<?php
|
||||
// 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 file allows you to add a note for a user
|
||||
*
|
||||
* @copyright 1999 Martin Dougiamas http://dougiamas.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @package core_user
|
||||
*/
|
||||
|
||||
require_once("../config.php");
|
||||
require_once($CFG->dirroot .'/notes/lib.php');
|
||||
|
||||
$id = required_param('id', PARAM_INT); // Course id.
|
||||
$users = optional_param_array('userid', array(), PARAM_INT); // Array of user id.
|
||||
$contents = optional_param_array('contents', array(), PARAM_RAW); // Array of user notes.
|
||||
$states = optional_param_array('states', array(), PARAM_ALPHA); // Array of notes states.
|
||||
$PAGE->set_url('/user/addnote.php', array('id' => $id));
|
||||
|
||||
if (! $course = $DB->get_record('course', array('id' => $id))) {
|
||||
print_error('invalidcourseid');
|
||||
}
|
||||
|
||||
$context = context_course::instance($id);
|
||||
require_login($course);
|
||||
|
||||
// To create notes the current user needs a capability.
|
||||
require_capability('moodle/notes:manage', $context);
|
||||
|
||||
if (empty($CFG->enablenotes)) {
|
||||
print_error('notesdisabled', 'notes');
|
||||
}
|
||||
|
||||
if (!empty($users) && confirm_sesskey()) {
|
||||
if (count($users) != count($contents) || count($users) != count($states)) {
|
||||
print_error('invalidformdata', '', $CFG->wwwroot.'/user/index.php?id='.$id);
|
||||
}
|
||||
|
||||
$note = new stdClass();
|
||||
$note->courseid = $id;
|
||||
$note->format = FORMAT_PLAIN;
|
||||
foreach ($users as $k => $v) {
|
||||
$user = $DB->get_record('user', array('id' => $v));
|
||||
$content = trim($contents[$k]);
|
||||
if (!$user || empty($content)) {
|
||||
continue;
|
||||
}
|
||||
$note->id = 0;
|
||||
$note->content = $content;
|
||||
$note->publishstate = $states[$k];
|
||||
$note->userid = $v;
|
||||
note_save($note);
|
||||
}
|
||||
redirect("$CFG->wwwroot/user/index.php?id=$id");
|
||||
}
|
||||
|
||||
// Print headers.
|
||||
$straddnote = get_string('addnewnote', 'notes');
|
||||
|
||||
$PAGE->navbar->add($straddnote);
|
||||
$PAGE->set_title("$course->shortname: ".get_string('extendenrol'));
|
||||
$PAGE->set_heading($course->fullname);
|
||||
|
||||
echo $OUTPUT->header();
|
||||
// This will contain all available the based On select options, but we'll disable some on them on a per user basis.
|
||||
echo $OUTPUT->heading($straddnote);
|
||||
echo '<form method="post" action="addnote.php">';
|
||||
echo '<fieldset class="invisiblefieldset">';
|
||||
echo '<input type="hidden" name="id" value="'.$course->id.'" />';
|
||||
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
|
||||
echo '</fieldset>';
|
||||
$table = new html_table();
|
||||
$table->head = array (get_string('fullnameuser'),
|
||||
get_string('content', 'notes'),
|
||||
get_string('publishstate', 'notes') . $OUTPUT->help_icon('publishstate', 'notes'),
|
||||
);
|
||||
$table->align = array ('left', 'center', 'center');
|
||||
$statenames = note_get_state_names();
|
||||
|
||||
// The first time list hack.
|
||||
if (empty($users) and $post = data_submitted()) {
|
||||
foreach ($post as $k => $v) {
|
||||
if (preg_match('/^user(\d+)$/', $k, $m)) {
|
||||
$users[] = $m[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($users as $k => $v) {
|
||||
if (!$user = $DB->get_record('user', array('id' => $v))) {
|
||||
continue;
|
||||
}
|
||||
$checkbox = html_writer::label(get_string('selectnotestate', 'notes'), 'menustates_'.$v, false, array('class' => 'accesshide'));
|
||||
$checkbox .= html_writer::select($statenames, 'states[' . $k . ']',
|
||||
empty($states[$k]) ? NOTES_STATE_PUBLIC : $states[$k], false, array('id' => 'menustates_'.$v));
|
||||
$table->data[] = array(
|
||||
'<input type="hidden" name="userid['.$k.']" value="'.$v.'" />'. fullname($user, true),
|
||||
'<textarea name="contents['. $k . ']" rows="2" cols="40" spellcheck="true">' . strip_tags(@$contents[$k]) . '</textarea>',
|
||||
$checkbox
|
||||
);
|
||||
}
|
||||
echo html_writer::table($table);
|
||||
echo '<div style="width:100%;text-align:center;"><input type="submit" value="' . get_string('savechanges'). '" /></div></form>';
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
define(["jquery","core/str","core/modal_factory","core/modal_events","core/templates","core/notification","core/ajax"],function(a,b,c,d,e,f,g){var h={BULKACTIONSELECT:"#formactionid",BULKUSERCHECKBOXES:"input.usercheckbox",BULKUSERNOSCHECKBOXES:"input.usercheckbox[value='0']",BULKUSERSELECTEDCHECKBOXES:"input.usercheckbox:checked",BULKACTIONFORM:"#participantsform",CHECKALLBUTTON:"#checkall",CHECKALLNOSBUTTON:"#checkallnos",CHECKALLONPAGEBUTTON:"#checkallonpage",CHECKNONEBUTTON:"#checknone"},i=function(a){this.courseId=a.courseid,this.noteStateNames=a.noteStateNames,this.stateHelpIcon=a.stateHelpIcon,this.attachEventListeners()};return i.prototype.modal=null,i.prototype.courseId=-1,i.prototype.noteStateNames={},i.prototype.stateHelpIcon="",i.prototype.attachEventListeners=function(){a(h.BULKACTIONSELECT).on("change",function(b){var c=a(b.target).val();if(c.indexOf("#")!==-1){b.preventDefault();var d=[];a(h.BULKUSERSELECTEDCHECKBOXES).each(function(b,c){var e=a(c).attr("name"),f=e.replace("user","");d.push(f)}),"#messageselect"==c?this.showSendMessage(d).fail(f.exception):"#addgroupnote"==c&&this.showAddNote(d).fail(f.exception),a(h.BULKACTIONSELECT+' option[value=""]').prop("selected","selected")}else""!==c&&(a(h.BULKUSERSELECTEDCHECKBOXES).length>0?a(h.BULKACTIONFORM).submit():a(h.BULKACTIONSELECT+' option[value=""]').prop("selected","selected"))}.bind(this)),a(h.CHECKALLBUTTON).on("click",function(){var b=a(this).data("showallink");b&&(window.location=b)}),a(h.CHECKALLNOSBUTTON).on("click",function(){a(h.BULKUSERNOSCHECKBOXES).prop("checked",!0)}),a(h.CHECKALLONPAGEBUTTON).on("click",function(){a(h.BULKUSERCHECKBOXES).prop("checked",!0)}),a(h.CHECKNONEBUTTON).on("click",function(){a(h.BULKUSERCHECKBOXES).prop("checked",!1)})},i.prototype.showAddNote=function(f){if(0==f.length)return a.Deferred().resolve().promise();var g=[];for(var i in this.noteStateNames)g.push({value:i,label:this.noteStateNames[i]});var j={stateNames:g,stateHelpIcon:this.stateHelpIcon};return a.when(c.create({type:c.types.SAVE_CANCEL,body:e.render("core_user/add_bulk_note",j)}),b.get_string("addbulknote","core_notes",f.length)).then(function(b,c){return this.modal=b,this.modal.setTitle(c),this.modal.setSaveButtonText(c),this.modal.getRoot().on(d.hidden,function(){var b=a("#user-notifications [role=alert]");b.length?b.focus():a(h.BULKACTIONSELECT).focus(),this.modal.getRoot().remove()}.bind(this)),this.modal.getRoot().on(d.save,this.submitAddNote.bind(this,f)),this.modal.show(),this.modal}.bind(this))},i.prototype.submitAddNote=function(a){var c=this.modal.getRoot().find("form textarea").val(),d=this.modal.getRoot().find("form select").val(),e=[],h=0;for(h=0;h<a.length;h++)e.push({userid:a[h],text:c,courseid:this.courseId,publishstate:d});return g.call([{methodname:"core_notes_create_notes",args:{notes:e}}])[0].then(function(a){return b.get_string("addbulknotedone","core_notes",a.length)}).then(function(a){return f.addNotification({message:a,type:"success"}),!0})["catch"](f.exception)},i.prototype.showSendMessage=function(f){if(0==f.length)return a.Deferred().resolve().promise();var g=e.render("core_user/send_bulk_message",{});return a.when(c.create({type:c.types.SAVE_CANCEL,body:g}),b.get_string("sendbulkmessage","core_message",f.length)).then(function(b,c){return this.modal=b,this.modal.setTitle(c),this.modal.setSaveButtonText(c),this.modal.getRoot().on(d.hidden,function(){a(h.BULKACTIONSELECT).focus(),this.modal.getRoot().remove()}.bind(this)),this.modal.getRoot().on(d.save,this.submitSendMessage.bind(this,f)),this.modal.show(),this.modal}.bind(this))},i.prototype.submitSendMessage=function(a){var c=this.modal.getRoot().find("form textarea").val(),d=[],e=0;for(e=0;e<a.length;e++)d.push({touserid:a[e],text:c});return g.call([{methodname:"core_message_send_instant_messages",args:{messages:d}}])[0].then(function(a){return b.get_string("sendbulkmessagesent","core_message",a.length)}).then(function(a){return f.addNotification({message:a,type:"success"}),!0})["catch"](f.exception)},{init:function(a){return new i(a)}}});
|
||||
@@ -0,0 +1,309 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Some UI stuff for participants page.
|
||||
* This is also used by the report/participants/index.php because it has the same functionality.
|
||||
*
|
||||
* @module core_user/participants
|
||||
* @package core_user
|
||||
* @copyright 2017 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/templates', 'core/notification', 'core/ajax'],
|
||||
function($, Str, ModalFactory, ModalEvents, Templates, Notification, Ajax) {
|
||||
|
||||
var SELECTORS = {
|
||||
BULKACTIONSELECT: "#formactionid",
|
||||
BULKUSERCHECKBOXES: "input.usercheckbox",
|
||||
BULKUSERNOSCHECKBOXES: "input.usercheckbox[value='0']",
|
||||
BULKUSERSELECTEDCHECKBOXES: "input.usercheckbox:checked",
|
||||
BULKACTIONFORM: "#participantsform",
|
||||
CHECKALLBUTTON: "#checkall",
|
||||
CHECKALLNOSBUTTON: "#checkallnos",
|
||||
CHECKALLONPAGEBUTTON: "#checkallonpage",
|
||||
CHECKNONEBUTTON: "#checknone"
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {Object} options Object containing options. Contextid is required.
|
||||
* Each call to templates.render gets it's own instance of this class.
|
||||
*/
|
||||
var Participants = function(options) {
|
||||
|
||||
this.courseId = options.courseid;
|
||||
this.noteStateNames = options.noteStateNames;
|
||||
this.stateHelpIcon = options.stateHelpIcon;
|
||||
|
||||
this.attachEventListeners();
|
||||
};
|
||||
// Class variables and functions.
|
||||
|
||||
/**
|
||||
* @var {Modal} modal
|
||||
* @private
|
||||
*/
|
||||
Participants.prototype.modal = null;
|
||||
|
||||
/**
|
||||
* @var {int} courseId
|
||||
* @private
|
||||
*/
|
||||
Participants.prototype.courseId = -1;
|
||||
|
||||
/**
|
||||
* @var {Object} noteStateNames
|
||||
* @private
|
||||
*/
|
||||
Participants.prototype.noteStateNames = {};
|
||||
|
||||
/**
|
||||
* @var {String} stateHelpIcon
|
||||
* @private
|
||||
*/
|
||||
Participants.prototype.stateHelpIcon = "";
|
||||
|
||||
/**
|
||||
* Private method
|
||||
*
|
||||
* @method attachEventListeners
|
||||
* @private
|
||||
*/
|
||||
Participants.prototype.attachEventListeners = function() {
|
||||
$(SELECTORS.BULKACTIONSELECT).on('change', function(e) {
|
||||
var action = $(e.target).val();
|
||||
if (action.indexOf('#') !== -1) {
|
||||
e.preventDefault();
|
||||
|
||||
var ids = [];
|
||||
$(SELECTORS.BULKUSERSELECTEDCHECKBOXES).each(function(index, ele) {
|
||||
var name = $(ele).attr('name');
|
||||
var id = name.replace('user', '');
|
||||
ids.push(id);
|
||||
});
|
||||
|
||||
if (action == '#messageselect') {
|
||||
this.showSendMessage(ids).fail(Notification.exception);
|
||||
} else if (action == '#addgroupnote') {
|
||||
this.showAddNote(ids).fail(Notification.exception);
|
||||
}
|
||||
$(SELECTORS.BULKACTIONSELECT + ' option[value=""]').prop('selected', 'selected');
|
||||
} else if (action !== '') {
|
||||
if ($(SELECTORS.BULKUSERSELECTEDCHECKBOXES).length > 0) {
|
||||
$(SELECTORS.BULKACTIONFORM).submit();
|
||||
} else {
|
||||
$(SELECTORS.BULKACTIONSELECT + ' option[value=""]').prop('selected', 'selected');
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
$(SELECTORS.CHECKALLBUTTON).on('click', function() {
|
||||
var showallink = $(this).data('showallink');
|
||||
if (showallink) {
|
||||
window.location = showallink;
|
||||
}
|
||||
});
|
||||
|
||||
$(SELECTORS.CHECKALLNOSBUTTON).on('click', function() {
|
||||
$(SELECTORS.BULKUSERNOSCHECKBOXES).prop('checked', true);
|
||||
});
|
||||
$(SELECTORS.CHECKALLONPAGEBUTTON).on('click', function() {
|
||||
$(SELECTORS.BULKUSERCHECKBOXES).prop('checked', true);
|
||||
});
|
||||
|
||||
$(SELECTORS.CHECKNONEBUTTON).on('click', function() {
|
||||
$(SELECTORS.BULKUSERCHECKBOXES).prop('checked', false);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the add note popup
|
||||
*
|
||||
* @method showAddNote
|
||||
* @private
|
||||
* @param {int[]} users
|
||||
* @return {Promise}
|
||||
*/
|
||||
Participants.prototype.showAddNote = function(users) {
|
||||
|
||||
if (users.length == 0) {
|
||||
// Nothing to do.
|
||||
return $.Deferred().resolve().promise();
|
||||
}
|
||||
|
||||
var states = [];
|
||||
for (var key in this.noteStateNames) {
|
||||
states.push({value: key, label: this.noteStateNames[key]});
|
||||
}
|
||||
|
||||
var context = {stateNames: states, stateHelpIcon: this.stateHelpIcon};
|
||||
|
||||
return $.when(
|
||||
ModalFactory.create({
|
||||
type: ModalFactory.types.SAVE_CANCEL,
|
||||
body: Templates.render('core_user/add_bulk_note', context)
|
||||
}),
|
||||
Str.get_string('addbulknote', 'core_notes', users.length)
|
||||
).then(function(modal, title) {
|
||||
// Keep a reference to the modal.
|
||||
this.modal = modal;
|
||||
this.modal.setTitle(title);
|
||||
this.modal.setSaveButtonText(title);
|
||||
|
||||
// We want to focus on the action select when the dialog is closed.
|
||||
this.modal.getRoot().on(ModalEvents.hidden, function() {
|
||||
var notification = $('#user-notifications [role=alert]');
|
||||
if (notification.length) {
|
||||
notification.focus();
|
||||
} else {
|
||||
$(SELECTORS.BULKACTIONSELECT).focus();
|
||||
}
|
||||
this.modal.getRoot().remove();
|
||||
}.bind(this));
|
||||
|
||||
this.modal.getRoot().on(ModalEvents.save, this.submitAddNote.bind(this, users));
|
||||
|
||||
this.modal.show();
|
||||
|
||||
return this.modal;
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a note to this list of users.
|
||||
*
|
||||
* @method submitAddNote
|
||||
* @private
|
||||
* @param {int[]} users
|
||||
* @return {Promise}
|
||||
*/
|
||||
Participants.prototype.submitAddNote = function(users) {
|
||||
var noteText = this.modal.getRoot().find('form textarea').val();
|
||||
var publishState = this.modal.getRoot().find('form select').val();
|
||||
var notes = [],
|
||||
i = 0;
|
||||
|
||||
for (i = 0; i < users.length; i++) {
|
||||
notes.push({userid: users[i], text: noteText, courseid: this.courseId, publishstate: publishState});
|
||||
}
|
||||
|
||||
return Ajax.call([{
|
||||
methodname: 'core_notes_create_notes',
|
||||
args: {notes: notes}
|
||||
}])[0].then(function(noteIds) {
|
||||
return Str.get_string('addbulknotedone', 'core_notes', noteIds.length);
|
||||
}).then(function(msg) {
|
||||
Notification.addNotification({
|
||||
message: msg,
|
||||
type: "success"
|
||||
});
|
||||
return true;
|
||||
}).catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the send message popup.
|
||||
*
|
||||
* @method showSendMessage
|
||||
* @private
|
||||
* @param {int[]} users
|
||||
* @return {Promise}
|
||||
*/
|
||||
Participants.prototype.showSendMessage = function(users) {
|
||||
|
||||
if (users.length == 0) {
|
||||
// Nothing to do.
|
||||
return $.Deferred().resolve().promise();
|
||||
}
|
||||
var bodyPromise = Templates.render('core_user/send_bulk_message', {});
|
||||
|
||||
return $.when(
|
||||
ModalFactory.create({
|
||||
type: ModalFactory.types.SAVE_CANCEL,
|
||||
body: bodyPromise
|
||||
}),
|
||||
Str.get_string('sendbulkmessage', 'core_message', users.length)
|
||||
).then(function(modal, title) {
|
||||
// Keep a reference to the modal.
|
||||
this.modal = modal;
|
||||
|
||||
this.modal.setTitle(title);
|
||||
this.modal.setSaveButtonText(title);
|
||||
|
||||
// We want to focus on the action select when the dialog is closed.
|
||||
this.modal.getRoot().on(ModalEvents.hidden, function() {
|
||||
$(SELECTORS.BULKACTIONSELECT).focus();
|
||||
this.modal.getRoot().remove();
|
||||
}.bind(this));
|
||||
|
||||
this.modal.getRoot().on(ModalEvents.save, this.submitSendMessage.bind(this, users));
|
||||
|
||||
this.modal.show();
|
||||
|
||||
return this.modal;
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a message to these users.
|
||||
*
|
||||
* @method submitSendMessage
|
||||
* @private
|
||||
* @param {int[]} users
|
||||
* @param {Event} e Form submission event.
|
||||
* @return {Promise}
|
||||
*/
|
||||
Participants.prototype.submitSendMessage = function(users) {
|
||||
|
||||
var messageText = this.modal.getRoot().find('form textarea').val();
|
||||
|
||||
var messages = [],
|
||||
i = 0;
|
||||
|
||||
for (i = 0; i < users.length; i++) {
|
||||
messages.push({touserid: users[i], text: messageText});
|
||||
}
|
||||
|
||||
return Ajax.call([{
|
||||
methodname: 'core_message_send_instant_messages',
|
||||
args: {messages: messages}
|
||||
}])[0].then(function(messageIds) {
|
||||
return Str.get_string('sendbulkmessagesent', 'core_message', messageIds.length);
|
||||
}).then(function(msg) {
|
||||
Notification.addNotification({
|
||||
message: msg,
|
||||
type: "success"
|
||||
});
|
||||
return true;
|
||||
}).catch(Notification.exception);
|
||||
};
|
||||
|
||||
return /** @alias module:core_user/participants */ {
|
||||
// Public variables and functions.
|
||||
|
||||
/**
|
||||
* Initialise the unified user filter.
|
||||
*
|
||||
* @method init
|
||||
* @param {Object} options - List of options.
|
||||
* @return {Participants}
|
||||
*/
|
||||
'init': function(options) {
|
||||
return new Participants(options);
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,123 +0,0 @@
|
||||
<?php
|
||||
// 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 file is part of the User section Moodle
|
||||
*
|
||||
* @copyright 1999 Martin Dougiamas http://dougiamas.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @package core_user
|
||||
*/
|
||||
|
||||
require_once("../config.php");
|
||||
require_once($CFG->dirroot .'/notes/lib.php');
|
||||
|
||||
$id = required_param('id', PARAM_INT); // Course id.
|
||||
$users = optional_param_array('userid', array(), PARAM_INT); // Array of user id.
|
||||
$content = optional_param('content', '', PARAM_RAW); // Note content.
|
||||
$state = optional_param('state', '', PARAM_ALPHA); // Note publish state.
|
||||
|
||||
$url = new moodle_url('/user/groupaddnote.php', array('id' => $id));
|
||||
if ($content !== '') {
|
||||
$url->param('content', $content);
|
||||
}
|
||||
if ($state !== '') {
|
||||
$url->param('state', $state);
|
||||
}
|
||||
$PAGE->set_url($url);
|
||||
|
||||
if (! $course = $DB->get_record('course', array('id' => $id))) {
|
||||
print_error('invalidcourseid');
|
||||
}
|
||||
|
||||
$context = context_course::instance($id);
|
||||
require_login($course);
|
||||
|
||||
// To create notes the current user needs a capability.
|
||||
require_capability('moodle/notes:manage', $context);
|
||||
|
||||
if (empty($CFG->enablenotes)) {
|
||||
print_error('notesdisabled', 'notes');
|
||||
}
|
||||
|
||||
if (!empty($users) && !empty($content) && confirm_sesskey()) {
|
||||
$note = new stdClass();
|
||||
$note->courseid = $id;
|
||||
$note->format = FORMAT_PLAIN;
|
||||
$note->content = $content;
|
||||
$note->publishstate = $state;
|
||||
foreach ($users as $k => $v) {
|
||||
if (!$user = $DB->get_record('user', array('id' => $v))) {
|
||||
continue;
|
||||
}
|
||||
$note->id = 0;
|
||||
$note->userid = $v;
|
||||
note_save($note);
|
||||
}
|
||||
|
||||
redirect("$CFG->wwwroot/user/index.php?id=$id");
|
||||
}
|
||||
|
||||
$straddnote = get_string('groupaddnewnote', 'notes');
|
||||
|
||||
$PAGE->navbar->add($straddnote);
|
||||
$PAGE->set_title("$course->shortname: ".get_string('extendenrol'));
|
||||
$PAGE->set_heading($course->fullname);
|
||||
|
||||
// Print headers.
|
||||
echo $OUTPUT->header();
|
||||
|
||||
// This will contain all available the based On select options, but we'll disable some on them on a per user basis.
|
||||
|
||||
echo $OUTPUT->heading($straddnote);
|
||||
echo '<form method="post" action="groupaddnote.php" >';
|
||||
echo '<div style="width:100%;text-align:center;">';
|
||||
echo '<input type="hidden" name="id" value="'.$course->id.'" />';
|
||||
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
|
||||
$statenames = note_get_state_names();
|
||||
|
||||
// The first time list hack.
|
||||
if (empty($users) and $post = data_submitted()) {
|
||||
foreach ($post as $k => $v) {
|
||||
if (preg_match('/^user(\d+)$/', $k, $m)) {
|
||||
$users[] = $m[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$userlist = array();
|
||||
foreach ($users as $k => $v) {
|
||||
if (!$user = $DB->get_record('user', array('id' => $v))) {
|
||||
continue;
|
||||
}
|
||||
echo '<input type="hidden" name="userid['.$k.']" value="'.$v.'" />';
|
||||
$userlist[] = fullname($user, true);
|
||||
}
|
||||
echo '<p>';
|
||||
echo get_string('users'). ': ' . implode(', ', $userlist) . '.';
|
||||
echo '</p>';
|
||||
|
||||
echo '<p>' . get_string('content', 'notes');
|
||||
echo '<br /><textarea name="content" rows="5" cols="50" spellcheck="true">' . strip_tags(@$content) . '</textarea></p>';
|
||||
|
||||
echo '<p>';
|
||||
echo html_writer::label(get_string('publishstate', 'notes'), 'menustate');
|
||||
echo $OUTPUT->help_icon('publishstate', 'notes');
|
||||
echo html_writer::select($statenames, 'state', empty($state) ? NOTES_STATE_PUBLIC : $state, false);
|
||||
echo '</p>';
|
||||
|
||||
echo '<input type="submit" value="' . get_string('savechanges'). '" /></div></form>';
|
||||
echo $OUTPUT->footer();
|
||||
+8
-5
@@ -25,6 +25,7 @@
|
||||
require_once('../config.php');
|
||||
require_once($CFG->dirroot.'/user/lib.php');
|
||||
require_once($CFG->dirroot.'/course/lib.php');
|
||||
require_once($CFG->dirroot.'/notes/lib.php');
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
require_once($CFG->libdir.'/filelib.php');
|
||||
require_once($CFG->dirroot.'/enrol/locallib.php');
|
||||
@@ -292,10 +293,9 @@ if ($bulkoperations) {
|
||||
'value' => get_string('deselectall')));
|
||||
echo html_writer::end_tag('div');
|
||||
$displaylist = array();
|
||||
$displaylist['messageselect.php'] = get_string('messageselectadd');
|
||||
$displaylist['#messageselect'] = get_string('messageselectadd');
|
||||
if (!empty($CFG->enablenotes) && has_capability('moodle/notes:manage', $context) && $context->id != $frontpagectx->id) {
|
||||
$displaylist['addnote.php'] = get_string('addnewnote', 'notes');
|
||||
$displaylist['groupaddnote.php'] = get_string('groupaddnewnote', 'notes');
|
||||
$displaylist['#addgroupnote'] = get_string('addnewnote', 'notes');
|
||||
}
|
||||
|
||||
if ($context->id != $frontpagectx->id) {
|
||||
@@ -333,8 +333,11 @@ if ($bulkoperations) {
|
||||
echo '</div></div>';
|
||||
echo '</form>';
|
||||
|
||||
$module = array('name' => 'core_user', 'fullpath' => '/user/module.js');
|
||||
$PAGE->requires->js_init_call('M.core_user.init_participation', null, false, $module);
|
||||
$options = new stdClass();
|
||||
$options->courseid = $course->id;
|
||||
$options->noteStateNames = note_get_state_names();
|
||||
$options->stateHelpIcon = $OUTPUT->help_icon('publishstate', 'notes');
|
||||
$PAGE->requires->js_call_amd('core_user/participants', 'init', [$options]);
|
||||
}
|
||||
|
||||
echo '</div>'; // Userlist.
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
M.core_user = {};
|
||||
|
||||
M.core_user.init_participation = function(Y) {
|
||||
Y.on('change', function() {
|
||||
var action = Y.one('#formactionid');
|
||||
if (action.get('value') == '') {
|
||||
return;
|
||||
}
|
||||
var ok = false;
|
||||
Y.all('input.usercheckbox').each(function() {
|
||||
if (this.get('checked')) {
|
||||
ok = true;
|
||||
}
|
||||
});
|
||||
if (!ok) {
|
||||
// no checkbox selected
|
||||
return;
|
||||
}
|
||||
Y.one('#participantsform').submit();
|
||||
}, '#formactionid');
|
||||
|
||||
Y.on('click', function(e) {
|
||||
// Presence of a show all link indicates we should redirect to
|
||||
// a page with all users listed and checked, otherwise just check
|
||||
// those already shown.
|
||||
var showallink = this.getAttribute('data-showallink');
|
||||
if (showallink) {
|
||||
window.location = showallink;
|
||||
}
|
||||
Y.all('input.usercheckbox').each(function() {
|
||||
this.set('checked', 'checked');
|
||||
});
|
||||
}, '#checkall, #checkallonpage');
|
||||
|
||||
Y.on('click', function(e) {
|
||||
Y.all('input.usercheckbox').each(function() {
|
||||
this.set('checked', '');
|
||||
});
|
||||
}, '#checknone');
|
||||
};
|
||||
|
||||
M.core_user.init_tree = function(Y, expand_all, htmlid) {
|
||||
Y.use('yui2-treeview', function(Y) {
|
||||
var tree = new Y.YUI2.widget.TreeView(htmlid);
|
||||
|
||||
tree.subscribe("clickEvent", function(node, event) {
|
||||
// we want normal clicking which redirects to url
|
||||
return false;
|
||||
});
|
||||
|
||||
if (expand_all) {
|
||||
tree.expandAll();
|
||||
}
|
||||
|
||||
tree.render();
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_user/add_bulk_note
|
||||
|
||||
Template for the add bulk note modal.
|
||||
|
||||
Context variables required for this template:
|
||||
* stateNames array - List of value / label pairs of valid publish states for notes.
|
||||
* stateHelpIcon string - Rendered help icon for the publish state.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"stateNames": [ { "value": 0, "label": "State 1"}, { "value": 1, "label": "State 2"} ],
|
||||
"stateHelpIcon": "(help me)"
|
||||
}
|
||||
}}
|
||||
<form>
|
||||
<p>
|
||||
<label for="bulk-state" class="m-r-2">
|
||||
{{#str}}publishstate, core_notes{{/str}}
|
||||
</label>
|
||||
<select name="state" id="bulk-state" class="custom-select">
|
||||
{{#stateNames}}
|
||||
<option value="{{value}}">{{label}}</option>
|
||||
{{/stateNames}}
|
||||
</select>
|
||||
{{{stateHelpIcon}}}
|
||||
</p>
|
||||
<p>
|
||||
<label for="bulk-note">
|
||||
<span class="sr-only">{{#str}}note, core_note{{/str}}</span>
|
||||
</label>
|
||||
<textarea id="bulk-note" rows="3" data-max-rows="10" data-auto-rows="true" cols="30" class="form-control"></textarea>
|
||||
</p>
|
||||
</form>
|
||||
{{#js}}
|
||||
require(['core/auto_rows'], function(AutoRows) {
|
||||
AutoRows.init(document.getElementById('bulk-note'));
|
||||
});
|
||||
{{/js}}
|
||||
@@ -0,0 +1,41 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_user/send_bulk_message
|
||||
|
||||
Template for the send bulk message modal.
|
||||
|
||||
Context variables required for this template:
|
||||
None
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
}
|
||||
}}
|
||||
<form>
|
||||
<p>
|
||||
<label for="bulk-message">
|
||||
<span class="sr-only">{{#str}}message, core_message{{/str}}</span>
|
||||
</label>
|
||||
<textarea id="bulk-message" rows="3" data-max-rows="10" data-auto-rows="true" cols="30" class="form-control"></textarea>
|
||||
</p>
|
||||
</form>
|
||||
{{#js}}
|
||||
require(['core/auto_rows'], function(AutoRows) {
|
||||
AutoRows.init(document.getElementById('bulk-message'));
|
||||
});
|
||||
{{/js}}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* User steps definition.
|
||||
*
|
||||
* @package core_user
|
||||
* @category test
|
||||
* @copyright 2017 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
|
||||
|
||||
require_once(__DIR__ . '/../../../lib/behat/behat_base.php');
|
||||
|
||||
/**
|
||||
* Steps definitions for users.
|
||||
*
|
||||
* @package core_user
|
||||
* @category test
|
||||
* @copyright 2017 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_user extends behat_base {
|
||||
|
||||
/**
|
||||
* Choose from the bulk action menu.
|
||||
*
|
||||
* @Given /^I choose "(?P<nodetext_string>(?:[^"]|\\")*)" from the participants page bulk action menu$/
|
||||
* @param string $nodetext The menu item to select.
|
||||
*/
|
||||
public function i_choose_from_the_participants_page_bulk_action_menu($nodetext) {
|
||||
$nodetext = behat_context_helper::escape($nodetext);
|
||||
|
||||
// Open the select.
|
||||
$this->execute("behat_general::i_click_on", array("//select[@id='formactionid']", "xpath_element"));
|
||||
|
||||
// Click on the option.
|
||||
$this->execute("behat_general::i_click_on", array("//select[@id='formactionid']" .
|
||||
"/option[contains(., " . $nodetext . ")]", "xpath_element"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user