MDL-75362 gradereport_user: Roll in zero state work for user report

This commit is contained in:
Mathew May 2022-09-16 16:14:22 +02:00
parent 7973d6b11c
commit e7c1c2841d
51 changed files with 1027 additions and 98 deletions

View File

@ -0,0 +1,10 @@
define("core_grades/searchwidget/basewidget",["exports","core/modal_factory","core/modal_events","core/utils","core/templates"],(function(_exports,ModalFactory,ModalEvents,_utils,Templates){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}
/**
* A small modal to search users or grade items within the gradebook.
*
* @module core_grades/searchwidget/basewidget
* @copyright 2022 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.promisesAndResolvers=_exports.init=void 0,ModalFactory=_interopRequireWildcard(ModalFactory),ModalEvents=_interopRequireWildcard(ModalEvents),Templates=_interopRequireWildcard(Templates);_exports.init=function(bodyPromise,data,searchFunc,modalTitle){let unsearchableContent=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null;const modal=buildModal(bodyPromise,modalTitle);registerListenerEvents(modal,data,searchFunc,unsearchableContent)};const registerListenerEvents=(modal,data,searchFunc,unsearchableContent)=>{modal.then((modal=>{modal.getRoot().on(ModalEvents.hidden,(()=>{modal.destroy()})),modal.getBodyPromise().then((body=>body[0])).then((body=>{const searchInput=body.querySelector('input[data-action="search"]'),searchResultsContainer=body.querySelector('[data-region="search-results-container-widget"]');if(renderSearchResults(searchResultsContainer,data),unsearchableContent){body.querySelector('[data-region="unsearchable-content-container-widget"]').innerHTML+=unsearchableContent}return searchInput.addEventListener("input",(0,_utils.debounce)((()=>{renderSearchResults(searchResultsContainer,debounceCallee(searchInput.value,data,searchFunc()))}),300)),body})).catch()})).catch()},buildModal=(bodyPromise,modalTitle)=>ModalFactory.create({type:ModalFactory.types.DEFAULT,title:modalTitle,body:bodyPromise,small:!0,scrollable:!1,templateContext:{classes:"reportdatasearch modal-sm"}}).then((modal=>(modal.show(),modal))),debounceCallee=(searchValue,data,searchFunction)=>searchValue.length>0?searchFunction(data,searchValue):data,renderSearchResults=async(searchResultsContainer,searchResultsData)=>{const templateData={searchresults:searchResultsData},{html:html,js:js}=await Templates.renderForPromise("core_grades/searchwidget/searchresults",templateData);await Templates.replaceNodeContents(searchResultsContainer,html,js)};_exports.promisesAndResolvers=()=>{let bodyPromiseResolver;const bodyPromise=new Promise((resolve=>{bodyPromiseResolver=resolve}));return{bodyPromiseResolver:bodyPromiseResolver,bodyPromise:bodyPromise}}}));
//# sourceMappingURL=basewidget.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
define("core_grades/searchwidget/repository",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* A repo for the search widget.
*
* @module core_grades/searchwidget/repository
* @copyright 2022 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.userFetch=_exports.gradeitemFetch=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.userFetch=(courseid,actionBaseUrl)=>{const request={methodname:"core_grades_get_enrolled_users_for_search_widget",args:{courseid:courseid,actionbaseurl:actionBaseUrl}};return _ajax.default.call([request])[0]};_exports.gradeitemFetch=courseid=>{const request={methodname:"gradereport_singleview_get_grade_items_for_search_widget",args:{courseid:courseid}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=repository.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"repository.min.js","sources":["../../src/searchwidget/repository.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * A repo for the search widget.\n *\n * @module core_grades/searchwidget/repository\n * @copyright 2022 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ajax from 'core/ajax';\n\n/**\n * Given a course ID, we want to fetch the enrolled learners, so we may fetch their reports.\n *\n * @method userFetch\n * @param {int} courseid ID of the course to fetch the users of.\n * @param {string} actionBaseUrl The base URL for the user option.\n * @return {object} jQuery promise\n */\nexport const userFetch = (courseid, actionBaseUrl) => {\n const request = {\n methodname: 'core_grades_get_enrolled_users_for_search_widget',\n args: {\n courseid: courseid,\n actionbaseurl: actionBaseUrl,\n },\n };\n return ajax.call([request])[0];\n};\n\n/**\n * Given a course ID, we want to fetch the gradable items, so we may fetch reports based on activity items.\n * Note: This will be worked upon in the single view issue.\n *\n * @method gradeitemFetch\n * @param {int} courseid ID of the course to fetch the users of.\n * @return {object} jQuery promise\n */\nexport const gradeitemFetch = (courseid) => {\n const request = {\n methodname: 'gradereport_singleview_get_grade_items_for_search_widget',\n args: {\n courseid: courseid,\n },\n };\n return ajax.call([request])[0];\n};\n"],"names":["courseid","actionBaseUrl","request","methodname","args","actionbaseurl","ajax","call"],"mappings":";;;;;;;sLAiCyB,CAACA,SAAUC,uBAC1BC,QAAU,CACZC,WAAY,mDACZC,KAAM,CACFJ,SAAUA,SACVK,cAAeJ,uBAGhBK,cAAKC,KAAK,CAACL,UAAU,4BAWDF,iBACrBE,QAAU,CACZC,WAAY,2DACZC,KAAM,CACFJ,SAAUA,kBAGXM,cAAKC,KAAK,CAACL,UAAU"}

View File

@ -0,0 +1,164 @@
// 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/>.
/**
* A small modal to search users or grade items within the gradebook.
*
* @module core_grades/searchwidget/basewidget
* @copyright 2022 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import * as ModalFactory from 'core/modal_factory';
import * as ModalEvents from 'core/modal_events';
import {debounce} from 'core/utils';
import * as Templates from 'core/templates';
/**
* Build the base searching widget.
*
* @method init
* @param {Promise} bodyPromise The promise from the callee of the contents to place in the modal body.
* @param {Array} data An array of all the data generated by the callee.
* @param {Function} searchFunc Partially applied function we need to manage search the passed dataset.
* @param {string} modalTitle The name of the search widget.
* @param {string|null} unsearchableContent The content rendered in a non-searchable area.
*/
export const init = (bodyPromise, data, searchFunc, modalTitle, unsearchableContent = null) => {
const modal = buildModal(bodyPromise, modalTitle);
registerListenerEvents(modal, data, searchFunc, unsearchableContent);
};
/**
* Register chooser related event listeners.
*
* @method registerListenerEvents
* @param {Promise} modal Our modal that we are working with.
* @param {Array} data An array of all the data generated by the callee.
* @param {Function} searchFunc Partially applied function we need to manage search the passed dataset.
* @param {string|null} unsearchableContent The content rendered in a non-searchable area.
*/
const registerListenerEvents = (modal, data, searchFunc, unsearchableContent) => {
modal.then(modal => {
// We want to destroy this when the dialog is closed.
modal.getRoot().on(ModalEvents.hidden, () => {
modal.destroy();
});
// Once the body of the modal has been resolved, add more features.
modal.getBodyPromise()
// The return value of getBodyPromise is a jquery object containing the body NodeElement.
.then(body => body[0])
.then(body => {
const searchInput = body.querySelector('input[data-action="search"]');
const searchResultsContainer = body.querySelector('[data-region="search-results-container-widget"]');
renderSearchResults(searchResultsContainer, data);
if (unsearchableContent) {
const unsearchableContentContainer = body.querySelector(
'[data-region="unsearchable-content-container-widget"]');
unsearchableContentContainer.innerHTML += unsearchableContent;
}
// The search input is triggered.
searchInput.addEventListener('input', debounce(() => {
// Display the search results.
renderSearchResults(
searchResultsContainer,
debounceCallee(
searchInput.value,
data,
searchFunc()
)
);
}, 300));
return body;
}).catch();
}).catch();
};
/**
* Given an object we want to build a modal ready to show.
*
* @method buildModal
* @param {Promise} bodyPromise Body promise that the caller should resolve.
* @param {string} modalTitle The name of the search widget.
* @return {Object} The modal ready to display immediately and render body in later.
*/
const buildModal = (bodyPromise, modalTitle) => {
return ModalFactory.create({
type: ModalFactory.types.DEFAULT,
// TODO: Make this defined by the interface.
title: modalTitle,
body: bodyPromise,
small: true,
scrollable: false,
templateContext: {
classes: 'reportdatasearch modal-sm'
}
}).then(modal => {
modal.show();
return modal;
});
};
/**
* We have a small helper that'll call the curried search function allowing callers to filter
* the data set however we want rather than defining how data must be filtered.
*
* @method debounceCallee
* @param {String} searchValue The input from the user that we'll search against.
* @param {Array} data An array of all the data generated by the callee.
* @param {Function} searchFunction Partially applied function we need to manage search the passed dataset.
* @return {Array} The filtered subset of the provided data that we'll then render into the results.
*/
const debounceCallee = (searchValue, data, searchFunction) => {
if (searchValue.length > 0) { // Search query is present.
return searchFunction(data, searchValue);
}
return data;
};
/**
* Given the output of the callers' search function, render out the results into the modal.
*
* @method renderSearchResults
* @param {HTMLElement} searchResultsContainer The DOM node of the widget where we'll render the provided results.
* @param {Array} searchResultsData The filtered subset of the provided data that we'll then render into the results.
*/
const renderSearchResults = async(searchResultsContainer, searchResultsData) => {
const templateData = {
'searchresults': searchResultsData,
};
// Build up the html & js ready to place into the help section.
const {html, js} = await Templates.renderForPromise('core_grades/searchwidget/searchresults', templateData);
await Templates.replaceNodeContents(searchResultsContainer, html, js);
};
/**
* We want to create the basic promises and hooks that the caller will implement, so we can build modals
* ahead of time and allow the caller to resolve their promises once complete.
*
* @method promisesAndResolvers
* @returns {{bodyPromise: Promise, bodyPromiseResolver}}
*/
export const promisesAndResolvers = () => {
// We want to show the modal instantly but loading whilst waiting for our data.
let bodyPromiseResolver;
const bodyPromise = new Promise(resolve => {
bodyPromiseResolver = resolve;
});
return {bodyPromiseResolver, bodyPromise};
};

View File

@ -0,0 +1,61 @@
// 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/>.
/**
* A repo for the search widget.
*
* @module core_grades/searchwidget/repository
* @copyright 2022 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import ajax from 'core/ajax';
/**
* Given a course ID, we want to fetch the enrolled learners, so we may fetch their reports.
*
* @method userFetch
* @param {int} courseid ID of the course to fetch the users of.
* @param {string} actionBaseUrl The base URL for the user option.
* @return {object} jQuery promise
*/
export const userFetch = (courseid, actionBaseUrl) => {
const request = {
methodname: 'core_grades_get_enrolled_users_for_search_widget',
args: {
courseid: courseid,
actionbaseurl: actionBaseUrl,
},
};
return ajax.call([request])[0];
};
/**
* Given a course ID, we want to fetch the gradable items, so we may fetch reports based on activity items.
* Note: This will be worked upon in the single view issue.
*
* @method gradeitemFetch
* @param {int} courseid ID of the course to fetch the users of.
* @return {object} jQuery promise
*/
export const gradeitemFetch = (courseid) => {
const request = {
methodname: 'gradereport_singleview_get_grade_items_for_search_widget',
args: {
courseid: courseid,
},
};
return ajax.call([request])[0];
};

View File

@ -0,0 +1,157 @@
<?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/>.
namespace core_grades\external;
use external_api;
use external_function_parameters;
use external_value;
use external_single_structure;
use external_multiple_structure;
use moodle_url;
use core_user;
defined('MOODLE_INTERNAL') || die;
require_once($CFG->dirroot.'/grade/lib.php');
/**
* Get the enrolled users within and map some fields to the returned array of user objects.
*
* @package core_grades
* @copyright 2022 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 4.1
*/
class get_enrolled_users_for_search_widget extends external_api {
/**
* Returns description of method parameters.
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters (
[
'courseid' => new external_value(PARAM_INT, 'Course Id', VALUE_REQUIRED),
'actionbaseurl' => new external_value(PARAM_URL, 'The base URL for the user option', VALUE_REQUIRED),
'groupid' => new external_value(PARAM_INT, 'Group Id', VALUE_DEFAULT, 0)
]
);
}
/**
* Given a course ID find the enrolled users within and map some fields to the returned array of user objects.
*
* @param int $courseid
* @param string $actionbaseurl The base URL for the user option.
* @param int|null $groupid
* @return array Users and warnings to pass back to the calling widget.
* @throws coding_exception
* @throws invalid_parameter_exception
* @throws moodle_exception
* @throws restricted_context_exception
*/
public static function execute(int $courseid, string $actionbaseurl, ?int $groupid = 0): array {
global $DB, $PAGE;
$params = self::validate_parameters(
self::execute_parameters(),
[
'courseid' => $courseid,
'actionbaseurl' => $actionbaseurl,
'groupid' => $groupid
]
);
$warnings = [];
$coursecontext = \context_course::instance($params['courseid']);
parent::validate_context($coursecontext);
require_capability('moodle/course:viewparticipants', $coursecontext);
$course = $DB->get_record('course', ['id' => $params['courseid']]);
// Create a graded_users_iterator because it will properly check the groups etc.
$defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
$showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
$showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $coursecontext);
$gui = new \graded_users_iterator($course, null, $params['groupid']);
$gui->require_active_enrolment($showonlyactiveenrol);
$gui->init();
$users = [];
while ($userdata = $gui->next_user()) {
$guiuser = $userdata->user;
$user = new \stdClass();
$user->fullname = fullname($guiuser);
$user->id = $guiuser->id;
$user->url = (new moodle_url($actionbaseurl, ['id' => $courseid, 'userid' => $guiuser->id]))->out(false);
$userpicture = new \user_picture($guiuser);
$userpicture->size = 1;
$user->profileimage = $userpicture->get_url($PAGE)->out(false);
$user->email = $guiuser->email;
$users[] = $user;
}
$gui->close();
return [
'users' => $users,
'warnings' => $warnings,
];
}
/**
* Returns description of method result value.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([
'users' => new external_multiple_structure(self::user_description()),
'warnings' => new \external_warnings(),
]);
}
/**
* Create user return value description.
*
* @return \external_description
*/
public static function user_description(): \external_description {
$userfields = [
'id' => new external_value(core_user::get_property_type('id'), 'ID of the user'),
'profileimage' => new external_value(
PARAM_URL,
'The location of the users larger image',
VALUE_OPTIONAL
),
'url' => new external_value(
PARAM_URL,
'The link to the user report',
VALUE_OPTIONAL
),
'fullname' => new external_value(PARAM_TEXT, 'The full name of the user', VALUE_OPTIONAL),
'email' => new external_value(
core_user::get_property_type('email'),
'An email address - allow email as root@localhost',
VALUE_OPTIONAL),
];
return new external_single_structure($userfields);
}
}

View File

@ -2959,7 +2959,7 @@ abstract class grade_helper {
}
$pluginstr = get_string('pluginname', 'gradereport_'.$plugin);
$url = new moodle_url('/grade/report/'.$plugin.'/index.php', array('id' => $courseid));
$url = new moodle_url('/grade/report/'.$plugin.'/index.php', array('id'=>$courseid));
$gradereports[$plugin] = new grade_plugin_info($plugin, $url, $pluginstr);
// Add link to preferences tab if such a page exists

10
grade/report/user/amd/build/user.min.js vendored Normal file
View File

@ -0,0 +1,10 @@
define("gradereport_user/user",["exports","core/pending","core/templates","core/custom_interaction_events","core_grades/searchwidget/repository","core_grades/searchwidget/basewidget","core/str","core/url"],(function(_exports,_pending,Templates,_custom_interaction_events,Repository,WidgetBase,_str,_url){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* A small modal to search users within the gradebook.
*
* @module gradereport_user/user
* @copyright 2022 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_pending=_interopRequireDefault(_pending),Templates=_interopRequireWildcard(Templates),_custom_interaction_events=_interopRequireDefault(_custom_interaction_events),Repository=_interopRequireWildcard(Repository),WidgetBase=_interopRequireWildcard(WidgetBase),_url=_interopRequireDefault(_url);_exports.init=()=>{const pendingPromise=new _pending.default;registerListenerEvents(),pendingPromise.resolve()};const registerListenerEvents=()=>{const events=["click",_custom_interaction_events.default.events.activate,_custom_interaction_events.default.events.keyboardActivate];_custom_interaction_events.default.define(document,events);let{bodyPromiseResolver:bodyPromiseResolver,bodyPromise:bodyPromise}=WidgetBase.promisesAndResolvers();events.forEach((event=>{document.addEventListener(event,(async e=>{const trigger=e.target.closest(".userwidget");if(trigger){const courseID=trigger.dataset.courseid;e.preventDefault();const actionBaseUrl=_url.default.relativeUrl("/grade/report/user/index.php",{},!1),data=await Repository.userFetch(courseID,actionBaseUrl).catch((async e=>{const errorTemplateData={errormessage:e.message};bodyPromiseResolver(await Templates.render("core_grades/searchwidget/error",errorTemplateData))}));if(data===[])return;const allUsersOptionName=await(0,_str.get_string)("allusersnum","gradereport_user",data.users.length),allUsersOption=await Templates.render("core_grades/searchwidget/searchitem",{id:0,name:allUsersOptionName,url:_url.default.relativeUrl("/grade/report/user/index.php",{id:courseID,userid:0},!1)});WidgetBase.init(bodyPromise,data.users,searchUsers(),(0,_str.get_string)("selectauser","gradereport_user"),allUsersOption)}}))})),bodyPromiseResolver(Templates.render("core_grades/searchwidget/user/usersearch_body",{displayunsearchablecontent:!0}))},searchUsers=()=>()=>(users,searchTerm)=>{if(""===searchTerm)return users;searchTerm=searchTerm.toLowerCase();const searchResults=[];return users.forEach((user=>{user.fullname.toLowerCase().includes(searchTerm)&&searchResults.push(user)})),searchResults}}));
//# sourceMappingURL=user.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,130 @@
// 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/>.
/**
* A small modal to search users within the gradebook.
*
* @module gradereport_user/user
* @copyright 2022 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Pending from 'core/pending';
import * as Templates from 'core/templates';
import CustomEvents from "core/custom_interaction_events";
import * as Repository from 'core_grades/searchwidget/repository';
import * as WidgetBase from 'core_grades/searchwidget/basewidget';
import {get_string as getString} from 'core/str';
import Url from 'core/url';
/**
* Our entry point into starting to build the search widget.
* It'll eventually, based upon the listeners, open the search widget and allow filtering.
*
* @method init
*/
export const init = () => {
const pendingPromise = new Pending();
registerListenerEvents();
pendingPromise.resolve();
};
/**
* Register user search widget related event listeners.
*
* @method registerListenerEvents
*/
const registerListenerEvents = () => {
const events = [
'click',
CustomEvents.events.activate,
CustomEvents.events.keyboardActivate
];
CustomEvents.define(document, events);
let {bodyPromiseResolver, bodyPromise} = WidgetBase.promisesAndResolvers();
// Register events.
events.forEach((event) => {
document.addEventListener(event, async(e) => {
const trigger = e.target.closest('.userwidget');
if (trigger) {
const courseID = trigger.dataset.courseid;
e.preventDefault();
const actionBaseUrl = Url.relativeUrl('/grade/report/user/index.php', {}, false);
// If an error occurs while fetching the data, display the error within the modal.
const data = await Repository.userFetch(courseID, actionBaseUrl).catch(async(e) => {
const errorTemplateData = {
'errormessage': e.message
};
bodyPromiseResolver(
await Templates.render('core_grades/searchwidget/error', errorTemplateData)
);
});
// Early return if there is no module data.
if (data === []) {
return;
}
// The HTML for the 'All users' option which will be rendered in the non-searchable content are of the widget.
const allUsersOptionName = await getString('allusersnum', 'gradereport_user', data.users.length);
const allUsersOption = await Templates.render('core_grades/searchwidget/searchitem', {
id: 0,
name: allUsersOptionName,
url: Url.relativeUrl('/grade/report/user/index.php', {id: courseID, userid: 0}, false),
});
WidgetBase.init(
bodyPromise,
data.users,
searchUsers(),
getString('selectauser', 'gradereport_user'),
allUsersOption
);
}
});
});
// Resolvers for passed functions in the modal creation.
bodyPromiseResolver(Templates.render(
'core_grades/searchwidget/user/usersearch_body', {displayunsearchablecontent: true}
));
};
/**
* Define how we want to search and filter users when the user decides to input a search value.
*
* @method registerListenerEvents
* @returns {function(): function(*, *): (*)}
*/
const searchUsers = () => {
return () => {
return (users, searchTerm) => {
if (searchTerm === '') {
return users;
}
searchTerm = searchTerm.toLowerCase();
const searchResults = [];
users.forEach((user) => {
const userName = user.fullname.toLowerCase();
if (userName.includes(searchTerm)) {
searchResults.push(user);
}
});
return searchResults;
};
};
};

View File

@ -35,6 +35,7 @@ use gradereport_user\report\user as user_report;
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir.'/externallib.php');
require_once($CFG->dirroot.'/grade/lib.php');
/**
* External grade report API implementation

View File

@ -1220,6 +1220,19 @@ class user extends grade_report {
}
}
/**
* Build the html for the zero state of the user report.
* @return string HTML to display
*/
public function output_report_zerostate(): string {
global $OUTPUT, $COURSE;
$context = [
'courseid' => $COURSE->id,
'imglink' => new \moodle_url('/pix/f/clip-353 1.png'),
];
return $OUTPUT->render_from_template('gradereport_user/zero_state', $context);
}
/**
* Trigger the grade_report_viewed event
*

View File

@ -48,5 +48,5 @@ $functions = [
'type' => 'read',
'capabilities' => 'gradereport/user:view',
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
]
],
];

View File

@ -27,11 +27,14 @@ require_once $CFG->libdir.'/gradelib.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/user/lib.php';
use gradereport_user\report\user as reportbase;
$courseid = required_param('id', PARAM_INT);
$userid = optional_param('userid', $USER->id, PARAM_INT);
$userid = optional_param('userid', null, PARAM_INT);
$userview = optional_param('userview', 0, PARAM_INT);
$PAGE->set_url(new moodle_url('/grade/report/user/index.php', ['id' => $courseid]));
$PAGE->requires->js_call_amd('gradereport_user/user', 'init');
if ($userview == 0) {
$userview = get_user_preferences('gradereport_user_view_user', GRADE_REPORT_USER_VIEW_USER);
@ -49,9 +52,9 @@ $PAGE->set_pagelayout('report');
$context = context_course::instance($course->id);
require_capability('gradereport/user:view', $context);
if (empty($userid)) {
if ($userid === 0 || is_null($userid)) {
require_capability('moodle/grade:viewall', $context);
} else {
} else if ($userid) {
if (!$DB->get_record('user', ['id' => $userid, 'deleted' => 0]) || isguestuser($userid)) {
throw new \moodle_exception('invaliduser');
}
@ -61,7 +64,7 @@ $access = false;
if (has_capability('moodle/grade:viewall', $context)) {
// User can view all course grades.
$access = true;
} else if ($userid == $USER->id && has_capability('moodle/grade:view', $context) && $course->showgrades) {
} else if (($userid == $USER->id || is_null($userid)) && has_capability('moodle/grade:view', $context) && $course->showgrades) {
// User can view own grades.
$access = true;
} else if (has_capability('moodle/grade:viewall', context_user::instance($userid)) && $course->showgrades) {
@ -89,7 +92,7 @@ grade_regrade_final_grades_if_required($course);
// Teachers will see all student reports.
if (has_capability('moodle/grade:viewall', $context)) {
// Verify if we are using groups or not.
$groupmode = groups_get_course_groupmode($course);
$groupmode = groups_get_course_groupmode($course);
$currentgroup = $gpr->groupid;
// To make some other functions work better later.
@ -119,13 +122,25 @@ if (has_capability('moodle/grade:viewall', $context)) {
$viewasuser = false;
}
if (empty($userid)) {
if (is_null($userid)) {
$report = new reportbase($courseid, $gpr, $context, $USER->id);
if (isset($report)) {
// Trigger report viewed event.
$report->viewed();
}
// Print header.
print_grade_page_head($course->id, 'report', 'user', ' ', false);
echo $report->output_report_zerostate();
} else if (empty($userid)) {
$gui = new graded_users_iterator($course, null, $currentgroup);
$gui->require_active_enrolment($showonlyactiveenrol);
$gui->init();
// Add tabs.
print_grade_page_head($courseid, 'report', 'user');
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, ['userid' => 0]));
groups_print_course_menu($course, $gpr->get_return_url('index.php?id=' . $courseid, ['userid' => 0]));
if ($user_selector) {
echo $renderer->graded_users_selector('user', $course, $userid, $currentgroup, true);
@ -147,7 +162,7 @@ if (has_capability('moodle/grade:viewall', $context)) {
echo $OUTPUT->heading($studentnamelink);
if ($report->fill_table()) {
echo '<br />'.$report->print_table(true);
echo '<br />' . $report->print_table(true);
}
echo "<p style = 'page-break-after: always;'></p>";
}
@ -163,10 +178,11 @@ if (has_capability('moodle/grade:viewall', $context)) {
),
fullname($report->user)
);
print_grade_page_head($courseid, 'report', 'user', get_string('pluginname', 'gradereport_user') . ' - ' . $studentnamelink,
false, false, true, null, null, $report->user);
print_grade_page_head($courseid, 'report', 'user',
get_string('pluginname', 'gradereport_user') . ' - ' . $studentnamelink,
false, false, true, null, null, $report->user);
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, ['userid' => 0]));
groups_print_course_menu($course, $gpr->get_return_url('index.php?id=' . $courseid, ['userid' => 0]));
if ($user_selector) {
$showallusersoptions = true;
@ -179,20 +195,21 @@ if (has_capability('moodle/grade:viewall', $context)) {
echo $OUTPUT->notification(get_string('groupusernotmember', 'error'));
} else {
if ($report->fill_table()) {
echo '<br />'.$report->print_table(true);
echo '<br />' . $report->print_table(true);
}
}
}
} else {
// Students will see just their own report.
// Create a report instance.
$report = new gradereport_user\report\user($courseid, $gpr, $context, $userid);
$report = new gradereport_user\report\user($courseid, $gpr, $context, $userid ?? $USER->id);
// Print the page.
print_grade_page_head($courseid, 'report', 'user', get_string('pluginname', 'gradereport_user'). ' - '.fullname($report->user));
print_grade_page_head($courseid, 'report', 'user',
get_string('pluginname', 'gradereport_user') . ' - ' . fullname($report->user));
if ($report->fill_table()) {
echo '<br />'.$report->print_table(true);
echo '<br />' . $report->print_table(true);
}
}

View File

@ -24,11 +24,16 @@
defined('MOODLE_INTERNAL') || die();
$string['allusersnum'] = 'All users ({$a})';
$string['eventgradereportviewed'] = 'Grade user report viewed';
$string['pluginname'] = 'User report';
$string['user:view'] = 'View your own grade report';
$string['myself'] = 'Myself';
$string['otheruser'] = 'User';
$string['privacy:metadata:preference:gradereport_user_view_user'] = 'Whether to view report as current user or another user in the gradebook reports';
$string['selectauser'] = 'Select a user';
$string['selectuser'] = 'Select a user to view their grades';
$string['selectuserinstructions'] = 'By selecting a user you can view the grades by activity';
$string['selectuserlink'] = 'Click to select user';
$string['tablesummary'] = 'The table is arranged as a list of graded items including categories of graded items. When items are in a category they will be indicated as such.';
$string['viewas'] = 'View report as';

View File

@ -39,12 +39,12 @@ class gradereport_user_renderer extends plugin_renderer_base {
* @param string $report
* @param stdClass $course
* @param int $userid
* @param int $groupid
* @param null|int $groupid
* @param bool $includeall
* @return string The raw HTML to render.
* @throws coding_exception
*/
public function graded_users_selector(string $report, stdClass $course, int $userid, int $groupid, bool $includeall): string {
public function graded_users_selector(string $report, stdClass $course, int $userid, ?int $groupid, bool $includeall): string {
$select = grade_get_graded_users_select($report, $course, $userid, $groupid, $includeall);
$output = html_writer::tag('div', $this->output->render($select), ['id' => 'graded_users_selector']);

View File

@ -0,0 +1,37 @@
{{!
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 gradereport_user/zero_state
The zero state of the user report that contains the image and trigger for the search widget.
Example context (json):
{
"imglink": "http://foo.bar/gradereport/?userid=25",
"courseid": "2"
}
}}
<div class="mx-auto w-50 text-center">
<img src="{{imglink}}" alt="Temp" class="w-50 h-50 mb-4">
<h3>{{#str}}selectuser, gradereport_user{{/str}}</h3>
<p>{{#str}}selectuserinstructions, gradereport_user{{/str}}</p>
<a href="#"
class="btn btn-light border-secondary userwidget"
data-courseid={{courseid}}
data-searchtype="user"
>{{#str}}selectuserlink, gradereport_user{{/str}}</a>
</div>

View File

@ -49,7 +49,7 @@ Feature: View the user report as the student will see it
Scenario: View the report as the teacher themselves
When I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And I select "Myself" from the "View report as" singleselect
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
@ -65,7 +65,7 @@ Feature: View the user report as the student will see it
Scenario: View the report as the student from both the teachers and students perspective
When I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And I select "User" from the "View report as" singleselect
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
@ -107,7 +107,7 @@ Feature: View the user report as the student will see it
And I set the field with xpath "//select[@name='report_user_showtotalsifcontainhidden']" to "Show totals excluding hidden items"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
When I select "Student 1" from the "Select all or one user" singleselect
When I click on "Student 1" in the "user" search widget
And I select "User" from the "View report as" singleselect
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
@ -145,7 +145,7 @@ Feature: View the user report as the student will see it
And I set the field with xpath "//select[@name='report_user_showtotalsifcontainhidden']" to "Show totals including hidden items"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
When I select "Student 1" from the "Select all or one user" singleselect
When I click on "Student 1" in the "user" search widget
And I select "User" from the "View report as" singleselect
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
@ -191,7 +191,7 @@ Feature: View the user report as the student will see it
And I set the field with xpath "//select[@name='report_user_showtotalsifcontainhidden']" to "Show totals excluding hidden items"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
When I select "Student 1" from the "Select all or one user" singleselect
When I click on "Student 1" in the "user" search widget
And I select "User" from the "View report as" singleselect
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |

View File

@ -0,0 +1,33 @@
@core @core_grades @gradereport_user @javascript
Feature: Within the User report, a teacher can search for users.
Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | t1 |
| student1 | Student | 1 | student1@example.com | s1 |
| student2 | Student | 2 | student2@example.com | s2 |
| student32 | Student | 32 | student32@example.com | s32 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student32 | C1 | student |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I change window size to "large"
Scenario: A teacher can search for and find a user to view
When I navigate to "View > User report" in the course gradebook
And I click on "Click to select user" "link"
And I confirm "Student 1" in "Select a user" search within the gradebook widget exists
And I confirm "Student 2" in "Select a user" search within the gradebook widget exists
And I confirm "Student 32" in "Select a user" search within the gradebook widget exists
And I set the field "searchinput" to "2"
And I wait "1" seconds
Then I confirm "Student 2" in "Select a user" search within the gradebook widget exists
And I confirm "Student 32" in "Select a user" search within the gradebook widget exists
And I confirm "Student 1" in "Select a user" search within the gradebook widget does not exist

View File

@ -13,5 +13,5 @@ Feature: We can use the user report
Given I log in as "admin"
And I am on "Course 1" course homepage
And I navigate to "View > User report" in the course gradebook
And I select "All users (0)" from the "Select all or one user" singleselect
And I click on "All users (0)" in the "user" search widget
Then I should see "There are no students enrolled in this course."

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2022041901; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2022041902; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2022041200; // Requires this Moodle version.
$plugin->component = 'gradereport_user'; // Full name of the plugin (used for diagnostics)

View File

@ -0,0 +1,39 @@
{{!
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_grades/searchwidget/error
Chooser error template.
Variables required for this template:
* errormessage - The error message
Example context (json):
{
"errormessage": "Error"
}
}}
<div class="p-2 px-sm-5 py-sm-4">
<div class="alert alert-danger" role="alert">
<h5 class="alert-heading">
<i class="fa fa-exclamation-circle fa-fw text-danger"></i>
{{#str}} error, error {{/str}}
</h5>
<hr>
<p class="text-break">{{{errormessage}}}</p>
</div>
</div>

View File

@ -0,0 +1,48 @@
{{!
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_grades/searchwidget/searchitem
Search result line items.
Example context (json):
{
"id": "1",
"name": "Quiz 1",
"url": "http://foo.bar/gradereport/?userid=25",
"fullname": "Cameron Greeve"
}
}}
<div class="w-100 result-row" role="row" id="result-row-{{id}}">
{{#name}}
<a role="option" id="result-item-{{id}}x{{id}}" href="{{url}}" class="d-flex px-2 py-1">
<span class="w-50 pull-left result-cell text-truncate text-body mr-2">
{{name}}
</span>
</a>
{{/name}}
{{^name}}
<a role="option" id="user-{{id}}" href="{{url}}" class="d-flex px-2 py-1">
<span class="w-50 pull-left result-cell text-truncate text-body mr-2">
{{fullname}}
</span>
<span class="w-50 pull-left result-cell text-truncate text-muted">
<span id="email-user-{{id}}" role="gridcell">{{email}}</span>
</span>
</a>
{{/name}}
</div>

View File

@ -0,0 +1,46 @@
{{!
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_grades/searchwidget/searchresults
The wrapper in which our search results will be rendered
Example context (json):
{
"searchresults": [
{
"id": "1",
"name": "Quiz 1",
"url": "http://foo.bar/gradereport/?userid=25",
"fullname": "Cameron Greeve",
"sendmessage": "http://foo.bar/message/index.php?id=25",
"addcontact": "http://foo.bar/message/index.php?user1=2&user2=14&addcontact=14&sesskey=XXXXX",
"currentuser": "2"
}
]
}
}}
<div class="searchresultitemscontainer-wrapper">
<div class="searchresultitemscontainer d-flex flex-column mw-100 position-relative py-2" role="listbox" data-region="search-result-items-container">
{{#searchresults}}
{{>core_grades/searchwidget/searchitem}}
{{/searchresults}}
{{^searchresults}}
<p>{{#str}} resultsfound, core, 0 {{/str}}</p>
{{/searchresults}}
</div>
</div>

View File

@ -0,0 +1,36 @@
{{!
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_grades/searchwidget/user/usersearch_body
The body of the user widget.
Example context (json):
{
"displayunsearchablecontent": true
}
}}
{{< core/search_input_auto }}
{{$label}}{{#str}}
searchusers, core_grades
{{/str}}{{/label}}
{{$placeholder}}{{#str}}
searchusers, core_grades
{{/str}}{{/placeholder}}
{{/ core/search_input_auto }}
<div class="searchresultscontainer" data-region="search-results-container-widget" aria-live="polite"></div>
{{#displayunsearchablecontent}}
<div class="unsearchablecontentcontainer" data-region="unsearchable-content-container-widget" aria-live="polite"></div>
{{/displayunsearchablecontent}}

View File

@ -421,4 +421,59 @@ class behat_grade extends behat_base {
"#{$formid}", 'css_element']);
}
}
/**
* Confirm if a value is within the search widget within the gradebook.
*
* Examples:
* - I confirm "User1" in "User" search within the gradebook widget exists
*
* @Given /^I confirm "(?P<needle>(?:[^"]|\\")*)" in "(?P<haystack>(?:[^"]|\\")*)" search within the gradebook widget exists$/
* @param string $needle The value to search for.
* @param string $haystack The selector to use within the zero state.
*/
public function i_confirm_in_search_within_the_gradebook_widget_exists($needle, $haystack) {
$this->execute("behat_general::wait_until_exists", [$haystack, "dialogue"]);
$this->execute("behat_general::assert_element_contains_text", [$needle, $haystack, "dialogue"]);
}
/**
* Confirm if a value is not within the search widget within the gradebook.
*
* Examples:
* - I confirm "User1" in "User" search within the gradebook widget does not exist
*
* @Given /^I confirm "(?P<needle>(?:[^"]|\\")*)" in "(?P<haystack>(?:[^"]|\\")*)" search within the gradebook widget does not exist$/
* @param string $needle The value to search for.
* @param string $haystack The selector to use within the zero state.
*/
public function i_confirm_in_search_within_the_gradebook_widget_does_not_exist($needle, $haystack) {
$this->execute("behat_general::wait_until_exists", [$haystack, "dialogue"]);
$this->execute("behat_general::assert_element_not_contains_text", [$needle, $haystack, "dialogue"]);
}
/**
* Clicks on an option from the specified search widget in the current gradebook page.
*
* Examples:
* - I click on "Student1" in the "user" search widget
* - I click on "Group1" in the "group" search widget
*
* @Given /^I click on "(?P<needle>(?:[^"]|\\")*)" in the "(?P<haystack>(?:[^"]|\\")*)" search widget$/
* @param string $needle The value to search for.
* @param string $haystack The type of the search widget.
*/
public function i_click_on_in_search_widget(string $needle, string $haystack) {
$this->execute("behat_general::wait_until_the_page_is_ready");
if ($haystack === 'user') {
$this->execute("behat_general::i_click_on", ['.userwidget', "css_element"]);
$dialoguetitle = 'Select a user';
} else {
$this->execute("behat_general::i_click_on", ['.groupwidget', "css_element"]);
$dialoguetitle = 'Select a grade item';
}
$this->execute("behat_general::wait_until_exists", [$dialoguetitle, "dialogue"]);
$this->execute('behat_general::i_click_on_in_the', [$needle, "link", $dialoguetitle, 'dialogue']);
}
}

View File

@ -53,6 +53,7 @@ Feature: We can use calculated grade totals
And I give the grade "10.00" to the user "Student 1" for the grade item "Test assignment eight"
And I give the grade "5.00" to the user "Student 1" for the grade item "Test assignment nine"
And I press "Save changes"
And I change window size to "large"
And I set the following settings for grade item "Test assignment two":
| Hidden | 1 |
And I set the following settings for grade item "Test assignment five":
@ -349,8 +350,8 @@ Feature: We can use calculated grade totals
And I set the field "Show weightings" to "Show"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I click on "Student 1" in the "user" search widget
And I select "Myself" from the "View report as" singleselect
And I select "Student 1" from the "Select all or one user" singleselect
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Contribution to course total |
| Test assignment five | 28.57 % | 10.00 (50.00 %) | 020 | 1.03 % |
@ -541,8 +542,8 @@ Feature: We can use calculated grade totals
And I navigate to "View > Grader report" in the course gradebook
Then I should see "75.00 (16.85 %)" in the ".course" "css_element"
And I navigate to "View > User report" in the course gradebook
And I click on "Student 1" in the "user" search widget
And I select "Myself" from the "View report as" singleselect
And I select "Student 1" from the "Select all or one user" singleselect
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Contribution to course total |
| Test assignment five | 57.14 % | 10.00 (50.00 %) | 2.25 % |

View File

@ -42,7 +42,7 @@ Feature: Calculated grade items can be used in the gradebook
And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | - | 75.00 | 0100 | 75.00 % | - |
@ -69,7 +69,7 @@ Feature: Calculated grade items can be used in the gradebook
And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | - | 75.00 | 0100 | 75.00 % | - |
@ -82,7 +82,7 @@ Feature: Calculated grade items can be used in the gradebook
And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
When I select "Student 1" from the "Select all or one user" singleselect
When I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | - | 75.00 | 0100 | 75.00 % | - |
@ -99,7 +99,7 @@ Feature: Calculated grade items can be used in the gradebook
| Min and max grades used in calculation | Initial min and max grades |
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | - | 75.00 | 0100 | 75.00 % | - |
@ -135,7 +135,7 @@ Feature: Calculated grade items can be used in the gradebook
And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
When I select "Student 1" from the "Select all or one user" singleselect
When I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | 66.67 % | 75.00 | 0100 | 75.00 % | 50.00 % |
@ -149,7 +149,7 @@ Feature: Calculated grade items can be used in the gradebook
And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | 71.43 % | 75.00 | 0100 | 75.00 % | 53.57 % |

View File

@ -43,7 +43,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506
And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | - | 75.00 | 0100 | 75.00 % | - |
@ -70,7 +70,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506
And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | - | 75.00 | 0100 | 75.00 % | - |
@ -83,7 +83,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506
And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
When I select "Student 1" from the "Select all or one user" singleselect
When I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | - | 75.00 | 0100 | 75.00 % | - |
@ -100,7 +100,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506
| Min and max grades used in calculation | Initial min and max grades |
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | - | 75.00 | 0100 | 75.00 % | - |
@ -136,7 +136,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506
And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
When I select "Student 1" from the "Select all or one user" singleselect
When I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | 50.00 % | 75.00 | 0100 | 75.00 % | 37.50 % |
@ -150,7 +150,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506
And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| grade item 1 | 50.00 % | 75.00 | 0100 | 75.00 % | 37.50 % |

View File

@ -62,7 +62,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "Course 1":
| Aggregation | Mean of grades |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:
@ -87,7 +87,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "EN Sub category":
| Item weight | 1.0 |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:
@ -108,7 +108,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "EN Test assignment three":
| Extra credit | 1 |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:
@ -127,7 +127,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "EN Test assignment three":
| Extra credit weight | 1.0 |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:
@ -144,7 +144,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "Course 1":
| Aggregation | Median of grades |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:
@ -161,7 +161,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "Course 1":
| Aggregation | Lowest grade |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:
@ -178,7 +178,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "Course 1":
| Aggregation | Highest grade |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:
@ -195,7 +195,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "Course 1":
| Aggregation | Mode of grades |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:
@ -216,7 +216,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "EN Test assignment three":
| Extra credit | 1 |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:
@ -235,7 +235,7 @@ Feature: We can understand the gradebook user report
And I set the following settings for grade item "EN Test assignment three":
| Extra credit | 1 |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
# Check the values in the weights column.
Then the following should exist in the "user-grade" table:

View File

@ -64,7 +64,7 @@ Feature: Extra credit contributions are normalised when going out of bounds
And I set the following settings for grade item "Manual item 4":
| Extra credit | 1 |
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Contribution to course total |
| Manual item 1 | <m1w> | 80.00 | <m1c> |

View File

@ -48,7 +48,7 @@ Feature: We can change the maximum and minimum number of points for manual items
| Maximum grade | 10 |
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Contribution to course total |
| Manual item 1 | 100.00 % | 10.00 | 100.00 % |
@ -64,7 +64,7 @@ Feature: We can change the maximum and minimum number of points for manual items
| Maximum grade | 20 |
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Contribution to course total |
| Manual item 1 | 100.00 % | 20.00 | 100.00 % |

View File

@ -55,8 +55,8 @@ Feature: Student and teacher's view of aggregated grade items is consistent when
And I press "Save changes"
And I am on "Course 1" course homepage
And I navigate to "View > User report" in the course gradebook
And I click on "Student 1" in the "user" search widget
And I select "Myself" from the "View report as" singleselect
And I select "Student 1" from the "Select all or one user" singleselect
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 100.00 % | 50.00 | 0100 | 50.00 % | 25.00 % |

View File

@ -47,8 +47,8 @@ Feature: Hidden grade items should be hidden when grade category is locked, but
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "View > User report" in the course gradebook
And I click on "Student 1" in the "user" search widget
And I select "Myself" from the "View report as" singleselect
When I select "Student 1" from the "Select all or one user" singleselect
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test locked category total | 100.00 % | 50.00 | 0100 | 50.00 % | - |

View File

@ -100,7 +100,7 @@ Feature: We can use a minimum grade different than zero
And I give the grade "0.00" to the user "Student 2" for the grade item "Manual item 6"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Contribution to course total |
| Manual item 1 | 18.18 % | -25.00 | -4.55 % |

View File

@ -76,7 +76,7 @@ Feature: We can choose what min or max grade to use when aggregating grades.
And I give the grade "10.00" to the user "Student 2" for the grade item "MI 3"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| MI 1 | 20.00 % | 75.00 | 0100 | 75.00 % | 15.00 % |
@ -106,7 +106,7 @@ Feature: We can choose what min or max grade to use when aggregating grades.
| Maximum grade | 50.00 |
| Minimum grade | 5.00 |
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| MI 1 | 12.50 % | 75.00 | 550 | 100.00 % | 18.75 % |
@ -131,7 +131,7 @@ Feature: We can choose what min or max grade to use when aggregating grades.
| Rescale existing grades | No |
| Maximum grade | 200.00 |
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| MI 5 | 40.00 % | 150.00 | 0200 | 75.00 % | 30.00 % |
@ -145,7 +145,7 @@ Feature: We can choose what min or max grade to use when aggregating grades.
When I set the field "Min and max grades used in calculation" to "Initial min and max grades"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| MI 1 | 16.67 % | 75.00 | 0100 | 75.00 % | 12.50 % |

View File

@ -42,7 +42,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 28.57 % | 80.00 | 0100 | 80.00 % | 22.86 % |
@ -63,7 +63,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 66.67 % | 80.00 | 0100 | 80.00 % | 53.33 % |
@ -82,7 +82,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 0.00 %( Empty ) | - | 0100 | - | 0.00 % |
@ -109,7 +109,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 0.00 %( Extra credit ) | 80.00 | 0100 | 80.00 % | 0.00 % |
@ -134,7 +134,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 50.00 % | 80.00 | 0100 | 80.00 % | 40.00 % |
@ -158,7 +158,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 83.33 % | 80.00 | 0100 | 80.00 % | 66.67 % |
@ -180,7 +180,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 0.00 %( Empty ) | - | 0100 | - | 0.00 % |
@ -207,7 +207,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 50.00 % | 80.00 | 0100 | 80.00 % | 40.00 % |
@ -233,7 +233,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 83.33 % | 80.00 | 0100 | 80.00 % | 66.67 % |
@ -257,7 +257,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 0.00 %( Empty ) | - | 0100 | - | 0.00 % |

View File

@ -43,7 +43,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 28.57 % | 80.00 | 0100 | 80.00 % | 22.86 % |
@ -64,7 +64,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 66.67 % | 80.00 | 0100 | 80.00 % | 53.33 % |
@ -83,7 +83,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 0.00 %( Empty ) | - | 0100 | - | 0.00 % |
@ -110,7 +110,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 0.00 %( Extra credit ) | 80.00 | 0100 | 80.00 % | 0.00 % |
@ -135,7 +135,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 50.00 % | 80.00 | 0100 | 80.00 % | 40.00 % |
@ -160,7 +160,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 83.33 % | 80.00 | 0100 | 80.00 % | 66.67 % |
@ -183,7 +183,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 0.00 %( Empty ) | - | 0100 | - | 0.00 % |
@ -210,7 +210,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 50.00 % | 80.00 | 0100 | 80.00 % | 40.00 % |
@ -237,7 +237,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 83.33 % | 80.00 | 0100 | 80.00 % | 66.67 % |
@ -262,7 +262,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619
And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)"
And I press "Save changes"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | 0.00 %( Empty ) | - | 0100 | - | 0.00 % |

View File

@ -86,7 +86,7 @@ Feature: View gradebook when scales are used
| Range | FA | 0.005.00 | 0.005.00 |
| Overall average | C | 3.00 | 3.00 |
And I navigate to "View > User report" in the course gradebook
And I select "Student 3" from the "Select all or one user" singleselect
And I click on "Student 3" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | C | FA | 50.00 % | 60.00 % |
@ -132,7 +132,7 @@ Feature: View gradebook when scales are used
| Range | FA | 1.005.00 | 0.00100.00 |
| Overall average | C | 3.00 | <overallavg> |
And I navigate to "View > User report" in the course gradebook
And I select "Student 3" from the "Select all or one user" singleselect
And I click on "Student 3" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Percentage | Contribution to course total |
| Test assignment one | C | FA | 50.00 % | <contrib3> |

View File

@ -47,7 +47,7 @@ Feature: Control the aggregation of the scales
And I set the following settings for grade item "Course 1":
| Aggregation | <aggregation> |
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Percentage | Contribution to course total |
| Grade me | 10.00 | 10.00 % | <gradecontrib> |
@ -61,7 +61,7 @@ Feature: Control the aggregation of the scales
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Grade | Percentage | Contribution to course total |
| Grade me | 10.00 | 10.00 % | <gradecontrib2> |

View File

@ -66,7 +66,7 @@ Feature: View gradebook when single item scales are used
| Range | Ace!Ace! | 0.001.00 | 0.001.00 |
| Overall average | Ace! | 1.00 | 1.00 |
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Contribution to course total |
| Test assignment one | Ace! | Ace!Ace! | 100.00 % |
@ -104,7 +104,7 @@ Feature: View gradebook when single item scales are used
| Range | Ace!Ace! | 0.00100.0 | 0.00100.00 |
| Overall average | Ace! | <catavg> | <overallavg> |
And I navigate to "View > User report" in the course gradebook
And I select "Student 1" from the "Select all or one user" singleselect
And I click on "Student 1" in the "user" search widget
And the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Contribution to course total |
| Test assignment one | Ace! | Ace!Ace! | <contrib1> |

View File

@ -71,7 +71,7 @@ Feature: We can enter in grades and view reports from the gradebook
Scenario: Grade a grade item and ensure the results display correctly in the gradebook
When I navigate to "View > User report" in the course gradebook
And the "Gradebook navigation menu" select menu should contain "Grader report"
And the "Select all or one user" select box should contain "All users (1)"
And I click on "All users (1)" in the "user" search widget
And I log out
And I log in as "student1"
And I follow "Grades" in the user menu

View File

@ -725,6 +725,7 @@ $string['savechanges'] = 'Save changes';
$string['savepreferences'] = 'Save preferences';
$string['scaleconfirmdelete'] = 'Are you sure you wish to delete the scale "{$a}"?';
$string['scaledpct'] = 'Scaled %';
$string['searchusers'] = 'Search users';
$string['seeallcoursegrades'] = 'See all course grades';
$string['select'] = 'Select {$a}';
$string['selectalloroneuser'] = 'Select all or one user';

View File

@ -956,6 +956,13 @@ $functions = array(
'type' => 'write',
'capabilities' => 'moodle/grade:manage',
),
'core_grades_get_enrolled_users_for_search_widget' => array (
'classname' => 'core_grades\external\get_enrolled_users_for_search_widget',
'description' => 'Returns the enrolled users within and map some fields to the returned array of user objects.',
'type' => 'read',
'ajax' => true,
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
),
'core_grading_get_definitions' => array(
'classname' => 'core_grading_external',
'methodname' => 'get_definitions',

View File

@ -45,7 +45,7 @@ Feature: Change grading options in an H5P activity
Scenario: Default grading is max attempt grade
Given I am on the "Course 1" course page logged in as teacher1
When I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Percentage |
| Awesome H5P package | 100.00 | 100.00 % |
@ -57,7 +57,7 @@ Feature: Change grading options in an H5P activity
| Grading method | First attempt |
And I click on "Save and return to course" "button"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Percentage |
| Awesome H5P package | 0.00 | 0.00 % |
@ -69,7 +69,7 @@ Feature: Change grading options in an H5P activity
| Grading method | Last attempt |
And I click on "Save and return to course" "button"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Percentage |
| Awesome H5P package | 0.00 | 0.00 % |
@ -81,7 +81,7 @@ Feature: Change grading options in an H5P activity
| Grading method | Average grade |
And I click on "Save and return to course" "button"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Percentage |
| Awesome H5P package | 33.33 | 33.33 % |
@ -93,7 +93,7 @@ Feature: Change grading options in an H5P activity
| Grading method | Don't calculate a grade |
And I click on "Save and return to course" "button"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Percentage |
| Awesome H5P package | - | - |
@ -105,7 +105,7 @@ Feature: Change grading options in an H5P activity
| Enable attempt tracking | No |
And I click on "Save and return to course" "button"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Percentage |
| Awesome H5P package | - | - |
@ -118,7 +118,7 @@ Feature: Change grading options in an H5P activity
| Grading method | Average grade |
And I click on "Save and return to course" "button"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Percentage |
| Awesome H5P package | 33.33 | 0100 | 33.33 % |
@ -130,7 +130,7 @@ Feature: Change grading options in an H5P activity
| Maximum grade | 50 |
And I click on "Save and return to course" "button"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Percentage |
| Awesome H5P package | 16.67 | 050 | 33.33 % |
@ -143,7 +143,7 @@ Feature: Change grading options in an H5P activity
| Grading method | Average grade |
And I click on "Save and return to course" "button"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Percentage |
| Awesome H5P package | 33.33 | 0100 | 33.33 % |
@ -155,7 +155,7 @@ Feature: Change grading options in an H5P activity
| Maximum grade | 50 |
And I click on "Save and return to course" "button"
And I navigate to "View > User report" in the course gradebook
And I set the field "Select all or one user" to "Student 1"
And I click on "Student 1" in the "user" search widget
Then the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Percentage |
| Awesome H5P package | 33.33 | 050 | 66.67 % |

BIN
pix/f/clip-353 1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -513,3 +513,22 @@
.path-grade-report-singleview input[name^="finalgrade"] {
width: 80px;
}
.searchresultitemscontainer {
max-height: 150px;
overflow: auto;
a:hover {
background-color: $gray-100;
}
.focused-cell {
outline-style: dotted;
outline-color: green;
}
}
.unsearchablecontentcontainer {
border-top: 1px solid #dee2e6;
padding-top: 10px;
}

View File

@ -19696,6 +19696,19 @@ p.arrow_button {
.path-grade-report-singleview input[name^="finalgrade"] {
width: 80px; }
.searchresultitemscontainer {
max-height: 150px;
overflow: auto; }
.searchresultitemscontainer a:hover {
background-color: #f8f9fa; }
.searchresultitemscontainer .focused-cell {
outline-style: dotted;
outline-color: green; }
.unsearchablecontentcontainer {
border-top: 1px solid #dee2e6;
padding-top: 10px; }
.columns-autoflow-1to1to1 {
column-count: 3; }

View File

@ -19696,6 +19696,19 @@ p.arrow_button {
.path-grade-report-singleview input[name^="finalgrade"] {
width: 80px; }
.searchresultitemscontainer {
max-height: 150px;
overflow: auto; }
.searchresultitemscontainer a:hover {
background-color: #f8f9fa; }
.searchresultitemscontainer .focused-cell {
outline-style: dotted;
outline-color: green; }
.unsearchablecontentcontainer {
border-top: 1px solid #dee2e6;
padding-top: 10px; }
.columns-autoflow-1to1to1 {
column-count: 3; }

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2022101400.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2022101400.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.1dev+ (Build: 20221014)'; // Human-friendly version name