mirror of
https://github.com/moodle/moodle.git
synced 2025-04-14 13:02:07 +02:00
Merge branch 'MDL-77029-master' of https://github.com/ilyatregubov/moodle
This commit is contained in:
commit
ad15209e1f
@ -2215,7 +2215,7 @@ class grade_structure {
|
||||
*/
|
||||
public function get_locking_link(array $element, object $gpr, array $langstrings): ?string {
|
||||
|
||||
if (has_capability('moodle/grade:manage', $this->context)) {
|
||||
if (has_capability('moodle/grade:manage', $this->context) && isset($element['object'])) {
|
||||
$title = '';
|
||||
$url = new moodle_url('/grade/edit/tree/action.php',
|
||||
['id' => $this->courseid, 'sesskey' => sesskey(), 'eid' => $element['eid']]);
|
||||
@ -2311,7 +2311,7 @@ class grade_structure {
|
||||
public function get_edit_calculation_link(array $element, object $gpr,
|
||||
string $editcalculationstrings): ?string {
|
||||
|
||||
if (has_capability('moodle/grade:manage', $this->context)) {
|
||||
if (has_capability('moodle/grade:manage', $this->context) && isset($element['object'])) {
|
||||
$object = $element['object'];
|
||||
$isscale = $object->gradetype == GRADE_TYPE_SCALE;
|
||||
$isvalue = $object->gradetype == GRADE_TYPE_VALUE;
|
||||
@ -2345,6 +2345,24 @@ class grade_structure {
|
||||
return html_writer::link($urlnew, $title,
|
||||
['class' => 'dropdown-item', 'aria-label' => $title, 'aria-current' => $active, 'role' => 'menuitem']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns link to sort grade item column
|
||||
*
|
||||
* @param moodle_url $sortlink A base link for sorting
|
||||
* @param object $gpr A grade_plugin_return object
|
||||
* @param string $title Language string
|
||||
* @param string $direction Direction od sorting
|
||||
* @return string
|
||||
*/
|
||||
public function get_sorting_link(moodle_url $sortlink, object $gpr, string $title, string $direction = 'asc'): string {
|
||||
|
||||
$sortlink->param('sort', $direction);
|
||||
$gpr->add_url_params($sortlink);
|
||||
return html_writer::link($sortlink, $title,
|
||||
['class' => 'dropdown-item', 'aria-label' => $title, 'role' => 'menuitem']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,6 +6,6 @@ define("gradereport_grader/stickycolspan",["exports"],(function(_exports){Object
|
||||
* @copyright 2022 Bas Brands <bas@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
const SELECTORS_GRADEPARENT=".gradeparent",SELECTORS_STUDENTHEADER="#studentheader",SELECTORS_TABLEHEADER="th.header",SELECTORS_BEHAT="body.behat-site";_exports.init=()=>{if(document.querySelector(SELECTORS_BEHAT))return;const grader=document.querySelector(SELECTORS_GRADEPARENT),studentHeader=grader.querySelector(SELECTORS_STUDENTHEADER),leftOffset=getComputedStyle(studentHeader).getPropertyValue("left"),rightOffset=getComputedStyle(studentHeader).getPropertyValue("right"),tableHeaders=grader.querySelectorAll(SELECTORS_TABLEHEADER);for(let i=0;i<tableHeaders.length;i++)if(tableHeaders[i].colSpan>1){const addOffset=tableHeaders[i].offsetWidth-studentHeader.offsetWidth;window.right_to_left()?tableHeaders[i].style.right="calc("+rightOffset+" - "+addOffset+"px )":tableHeaders[i].style.left="calc("+leftOffset+" - "+addOffset+"px )"}else tableHeaders[i].style.zIndex=tableHeaders.length-i}}));
|
||||
const SELECTORS_GRADEPARENT=".gradeparent",SELECTORS_STUDENTHEADER="#studentheader",SELECTORS_TABLEHEADER="th.header",SELECTORS_BEHAT="body.behat-site",SELECTORS_TABLEHEADING="tr.heading";_exports.init=()=>{if(document.querySelector(SELECTORS_BEHAT))return;const grader=document.querySelector(SELECTORS_GRADEPARENT),studentHeader=grader.querySelector(SELECTORS_STUDENTHEADER),leftOffset=getComputedStyle(studentHeader).getPropertyValue("left"),rightOffset=getComputedStyle(studentHeader).getPropertyValue("right"),tableHeaders=grader.querySelectorAll(SELECTORS_TABLEHEADER);let i=0;tableHeaders.forEach((tableHeader=>{if(tableHeader.colSpan>1){const addOffset=tableHeader.offsetWidth-studentHeader.offsetWidth;window.right_to_left()?tableHeader.style.right="calc("+rightOffset+" - "+addOffset+"px )":tableHeader.style.left="calc("+leftOffset+" - "+addOffset+"px )"}else tableHeader.style.zIndex=tableHeaders.length-i;i++})),grader.querySelector(SELECTORS_TABLEHEADING).style.zIndex=tableHeaders.length+1}}));
|
||||
|
||||
//# sourceMappingURL=stickycolspan.min.js.map
|
@ -1 +1 @@
|
||||
{"version":3,"file":"stickycolspan.min.js","sources":["../src/stickycolspan.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 * Javascript module for fixing the position of sticky headers with multiple colspans\n *\n * @module gradereport_grader/stickycolspan\n * @copyright 2022 Bas Brands <bas@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst SELECTORS = {\n GRADEPARENT: '.gradeparent',\n STUDENTHEADER: '#studentheader',\n TABLEHEADER: 'th.header',\n BEHAT: 'body.behat-site',\n AVERAGEROW: 'tr.lastrow',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n if (document.querySelector(SELECTORS.BEHAT)) {\n return;\n }\n const grader = document.querySelector(SELECTORS.GRADEPARENT);\n const studentHeader = grader.querySelector(SELECTORS.STUDENTHEADER);\n const leftOffset = getComputedStyle(studentHeader).getPropertyValue('left');\n const rightOffset = getComputedStyle(studentHeader).getPropertyValue('right');\n\n const tableHeaders = grader.querySelectorAll(SELECTORS.TABLEHEADER);\n\n for (let i = 0; i < tableHeaders.length; i++) {\n if (tableHeaders[i].colSpan > 1) {\n const addOffset = (tableHeaders[i].offsetWidth - studentHeader.offsetWidth);\n if (window.right_to_left()) {\n tableHeaders[i].style.right = 'calc(' + rightOffset + ' - ' + addOffset + 'px )';\n } else {\n tableHeaders[i].style.left = 'calc(' + leftOffset + ' - ' + addOffset + 'px )';\n }\n } else {\n tableHeaders[i].style.zIndex = tableHeaders.length - i;\n }\n }\n\n};\n"],"names":["SELECTORS","document","querySelector","grader","studentHeader","leftOffset","getComputedStyle","getPropertyValue","rightOffset","tableHeaders","querySelectorAll","i","length","colSpan","addOffset","offsetWidth","window","right_to_left","style","right","left","zIndex"],"mappings":";;;;;;;;MAuBMA,sBACW,eADXA,wBAEa,iBAFbA,sBAGW,YAHXA,gBAIK,gCAOS,QACZC,SAASC,cAAcF,8BAGrBG,OAASF,SAASC,cAAcF,uBAChCI,cAAgBD,OAAOD,cAAcF,yBACrCK,WAAaC,iBAAiBF,eAAeG,iBAAiB,QAC9DC,YAAcF,iBAAiBF,eAAeG,iBAAiB,SAE/DE,aAAeN,OAAOO,iBAAiBV,2BAExC,IAAIW,EAAI,EAAGA,EAAIF,aAAaG,OAAQD,OACjCF,aAAaE,GAAGE,QAAU,EAAG,OACvBC,UAAaL,aAAaE,GAAGI,YAAcX,cAAcW,YAC3DC,OAAOC,gBACPR,aAAaE,GAAGO,MAAMC,MAAQ,QAAUX,YAAc,MAAQM,UAAY,OAE1EL,aAAaE,GAAGO,MAAME,KAAO,QAAUf,WAAa,MAAQS,UAAY,YAG5EL,aAAaE,GAAGO,MAAMG,OAASZ,aAAaG,OAASD"}
|
||||
{"version":3,"file":"stickycolspan.min.js","sources":["../src/stickycolspan.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 * Javascript module for fixing the position of sticky headers with multiple colspans\n *\n * @module gradereport_grader/stickycolspan\n * @copyright 2022 Bas Brands <bas@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst SELECTORS = {\n GRADEPARENT: '.gradeparent',\n STUDENTHEADER: '#studentheader',\n TABLEHEADER: 'th.header',\n BEHAT: 'body.behat-site',\n AVERAGEROW: 'tr.lastrow',\n TABLEHEADING: 'tr.heading',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n if (document.querySelector(SELECTORS.BEHAT)) {\n return;\n }\n const grader = document.querySelector(SELECTORS.GRADEPARENT);\n const studentHeader = grader.querySelector(SELECTORS.STUDENTHEADER);\n const leftOffset = getComputedStyle(studentHeader).getPropertyValue('left');\n const rightOffset = getComputedStyle(studentHeader).getPropertyValue('right');\n\n const tableHeaders = grader.querySelectorAll(SELECTORS.TABLEHEADER);\n let i = 0;\n tableHeaders.forEach((tableHeader) => {\n if (tableHeader.colSpan > 1) {\n const addOffset = (tableHeader.offsetWidth - studentHeader.offsetWidth);\n if (window.right_to_left()) {\n tableHeader.style.right = 'calc(' + rightOffset + ' - ' + addOffset + 'px )';\n } else {\n tableHeader.style.left = 'calc(' + leftOffset + ' - ' + addOffset + 'px )';\n }\n } else {\n tableHeader.style.zIndex = tableHeaders.length - i;\n }\n i++;\n });\n\n let tableHeader = grader.querySelector(SELECTORS.TABLEHEADING);\n tableHeader.style.zIndex = tableHeaders.length + 1;\n\n\n};\n"],"names":["SELECTORS","document","querySelector","grader","studentHeader","leftOffset","getComputedStyle","getPropertyValue","rightOffset","tableHeaders","querySelectorAll","i","forEach","tableHeader","colSpan","addOffset","offsetWidth","window","right_to_left","style","right","left","zIndex","length"],"mappings":";;;;;;;;MAuBMA,sBACW,eADXA,wBAEa,iBAFbA,sBAGW,YAHXA,gBAIK,kBAJLA,uBAMY,2BAME,QACZC,SAASC,cAAcF,8BAGrBG,OAASF,SAASC,cAAcF,uBAChCI,cAAgBD,OAAOD,cAAcF,yBACrCK,WAAaC,iBAAiBF,eAAeG,iBAAiB,QAC9DC,YAAcF,iBAAiBF,eAAeG,iBAAiB,SAE/DE,aAAeN,OAAOO,iBAAiBV,2BACzCW,EAAI,EACRF,aAAaG,SAASC,iBACdA,YAAYC,QAAU,EAAG,OACnBC,UAAaF,YAAYG,YAAcZ,cAAcY,YACvDC,OAAOC,gBACPL,YAAYM,MAAMC,MAAQ,QAAUZ,YAAc,MAAQO,UAAY,OAEtEF,YAAYM,MAAME,KAAO,QAAUhB,WAAa,MAAQU,UAAY,YAGxEF,YAAYM,MAAMG,OAASb,aAAac,OAASZ,EAErDA,OAGcR,OAAOD,cAAcF,wBAC3BmB,MAAMG,OAASb,aAAac,OAAS"}
|
@ -27,6 +27,7 @@ const SELECTORS = {
|
||||
TABLEHEADER: 'th.header',
|
||||
BEHAT: 'body.behat-site',
|
||||
AVERAGEROW: 'tr.lastrow',
|
||||
TABLEHEADING: 'tr.heading',
|
||||
};
|
||||
|
||||
/**
|
||||
@ -42,18 +43,23 @@ export const init = () => {
|
||||
const rightOffset = getComputedStyle(studentHeader).getPropertyValue('right');
|
||||
|
||||
const tableHeaders = grader.querySelectorAll(SELECTORS.TABLEHEADER);
|
||||
|
||||
for (let i = 0; i < tableHeaders.length; i++) {
|
||||
if (tableHeaders[i].colSpan > 1) {
|
||||
const addOffset = (tableHeaders[i].offsetWidth - studentHeader.offsetWidth);
|
||||
let i = 0;
|
||||
tableHeaders.forEach((tableHeader) => {
|
||||
if (tableHeader.colSpan > 1) {
|
||||
const addOffset = (tableHeader.offsetWidth - studentHeader.offsetWidth);
|
||||
if (window.right_to_left()) {
|
||||
tableHeaders[i].style.right = 'calc(' + rightOffset + ' - ' + addOffset + 'px )';
|
||||
tableHeader.style.right = 'calc(' + rightOffset + ' - ' + addOffset + 'px )';
|
||||
} else {
|
||||
tableHeaders[i].style.left = 'calc(' + leftOffset + ' - ' + addOffset + 'px )';
|
||||
tableHeader.style.left = 'calc(' + leftOffset + ' - ' + addOffset + 'px )';
|
||||
}
|
||||
} else {
|
||||
tableHeaders[i].style.zIndex = tableHeaders.length - i;
|
||||
tableHeader.style.zIndex = tableHeaders.length - i;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
});
|
||||
|
||||
let tableHeader = grader.querySelector(SELECTORS.TABLEHEADING);
|
||||
tableHeader.style.zIndex = tableHeaders.length + 1;
|
||||
|
||||
|
||||
};
|
||||
|
@ -33,6 +33,7 @@ $page = optional_param('page', 0, PARAM_INT); // active page
|
||||
$edit = optional_param('edit', -1, PARAM_BOOL); // sticky editting mode
|
||||
|
||||
$sortitemid = optional_param('sortitemid', 0, PARAM_ALPHANUMEXT);
|
||||
$sort = optional_param('sort', '', PARAM_TEXT);
|
||||
$action = optional_param('action', 0, PARAM_ALPHAEXT);
|
||||
$move = optional_param('move', 0, PARAM_INT);
|
||||
$type = optional_param('type', 0, PARAM_ALPHA);
|
||||
@ -120,7 +121,10 @@ grade_regrade_final_grades_if_required($course);
|
||||
|
||||
//Initialise the grader report object that produces the table
|
||||
//the class grade_report_grader_ajax was removed as part of MDL-21562
|
||||
$report = new grade_report_grader($courseid, $gpr, $context, $page, $sortitemid);
|
||||
if ($sort) {
|
||||
$sort = strtoupper($sort);
|
||||
}
|
||||
$report = new grade_report_grader($courseid, $gpr, $context, $page, $sortitemid, $sort);
|
||||
$numusers = $report->get_numusers(true, true);
|
||||
|
||||
$actionbar = new \gradereport_grader\output\action_bar($context, $report, $numusers);
|
||||
|
@ -121,8 +121,9 @@ class grade_report_grader extends grade_report {
|
||||
* @param string $context
|
||||
* @param int $page The current page being viewed (when report is paged)
|
||||
* @param int $sortitemid The id of the grade_item by which to sort the table
|
||||
* @param string $sort Sorting direction
|
||||
*/
|
||||
public function __construct($courseid, $gpr, $context, $page=null, $sortitemid=null) {
|
||||
public function __construct($courseid, $gpr, $context, $page=null, $sortitemid=null, string $sort = '') {
|
||||
global $CFG;
|
||||
parent::__construct($courseid, $gpr, $context, $page);
|
||||
|
||||
@ -161,7 +162,7 @@ class grade_report_grader extends grade_report {
|
||||
|
||||
$this->setup_groups();
|
||||
$this->setup_users();
|
||||
$this->setup_sortitemid();
|
||||
$this->setup_sortitemid($sort);
|
||||
|
||||
$this->overridecat = (bool)get_config('moodle', 'grade_overridecat');
|
||||
}
|
||||
@ -330,8 +331,10 @@ class grade_report_grader extends grade_report {
|
||||
* Setting the sort order, this depends on last state
|
||||
* all this should be in the new table class that we might need to use
|
||||
* for displaying grades.
|
||||
|
||||
* @param string $sort sorting direction
|
||||
*/
|
||||
private function setup_sortitemid() {
|
||||
private function setup_sortitemid(string $sort = '') {
|
||||
|
||||
global $SESSION;
|
||||
|
||||
@ -342,7 +345,7 @@ class grade_report_grader extends grade_report {
|
||||
if ($this->sortitemid) {
|
||||
if (!isset($SESSION->gradeuserreport->sort)) {
|
||||
$this->sortorder = $SESSION->gradeuserreport->sort = 'ASC';
|
||||
} else {
|
||||
} else if (!$sort) {
|
||||
// this is the first sort, i.e. by last name
|
||||
if (!isset($SESSION->gradeuserreport->sortitemid)) {
|
||||
$this->sortorder = $SESSION->gradeuserreport->sort = 'ASC';
|
||||
@ -373,6 +376,12 @@ class grade_report_grader extends grade_report {
|
||||
$this->sortorder = 'ASC';
|
||||
}
|
||||
}
|
||||
|
||||
// If explicit sorting direction exists.
|
||||
if ($sort) {
|
||||
$this->sortorder = $sort;
|
||||
$SESSION->gradeuserreport->sort = $sort;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -411,7 +420,13 @@ class grade_report_grader extends grade_report {
|
||||
$this->groupwheresql_params, $enrolledparams, $relatedctxparams);
|
||||
|
||||
$sortjoin = "LEFT JOIN {grade_grades} g ON g.userid = u.id AND g.itemid = $this->sortitemid";
|
||||
$sort = "g.finalgrade $this->sortorder, u.idnumber, u.lastname, u.firstname, u.email";
|
||||
|
||||
if ($this->sortorder == 'ASC') {
|
||||
$sort = $DB->sql_order_by_null('g.finalgrade');
|
||||
} else {
|
||||
$sort = $DB->sql_order_by_null('g.finalgrade', SORT_DESC);
|
||||
}
|
||||
$sort .= ", u.idnumber, u.lastname, u.firstname, u.email";
|
||||
} else {
|
||||
$sortjoin = '';
|
||||
|
||||
@ -639,7 +654,9 @@ class grade_report_grader extends grade_report {
|
||||
$studentheader->scope = 'col';
|
||||
$studentheader->header = true;
|
||||
$studentheader->id = 'studentheader';
|
||||
$studentheader->text = $arrows['studentname'];
|
||||
$element = ['type' => 'userfield', 'name' => 'fullname'];
|
||||
$studentheader->text = $arrows['studentname'] . $this->get_cell_action_menu($element, 'gradeitem');
|
||||
|
||||
$headerrow->cells[] = $studentheader;
|
||||
|
||||
foreach ($extrafields as $field) {
|
||||
@ -647,7 +664,8 @@ class grade_report_grader extends grade_report {
|
||||
$fieldheader->attributes['class'] = 'userfield user' . $field;
|
||||
$fieldheader->scope = 'col';
|
||||
$fieldheader->header = true;
|
||||
$fieldheader->text = $arrows[$field];
|
||||
$element = ['type' => 'userfield', 'name' => $field];
|
||||
$fieldheader->text = $arrows[$field] . $this->get_cell_action_menu($element, 'gradeitem');
|
||||
$headerrow->cells[] = $fieldheader;
|
||||
}
|
||||
|
||||
@ -731,7 +749,6 @@ class grade_report_grader extends grade_report {
|
||||
$numusers = count($this->users);
|
||||
$gradetabindex = 1;
|
||||
$strgrade = $this->get_lang_string('gradenoun');
|
||||
$this->get_sort_arrows();
|
||||
|
||||
// Get preferences once.
|
||||
$quickgrading = $this->get_pref('quickgrading');
|
||||
@ -803,9 +820,9 @@ class grade_report_grader extends grade_report {
|
||||
$arrow = '';
|
||||
if ($element['object']->id == $this->sortitemid) {
|
||||
if ($this->sortorder == 'ASC') {
|
||||
$arrow = $this->get_sort_arrow('up', $sortlink);
|
||||
} else {
|
||||
$arrow = $this->get_sort_arrow('down', $sortlink);
|
||||
} else {
|
||||
$arrow = $this->get_sort_arrow('up', $sortlink);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1639,6 +1656,9 @@ class grade_report_grader extends grade_report {
|
||||
|
||||
$gradeanalysisstring = $this->get_lang_string('gradeanalysis', 'grades');
|
||||
|
||||
$titleasc = $this->get_lang_string('asc');
|
||||
$titledesc = $this->get_lang_string('desc');
|
||||
|
||||
if ($element['type'] == 'grade') {
|
||||
$item = $element['object']->grade_item;
|
||||
if ($item->is_course_item() || $item->is_category_item()) {
|
||||
@ -1656,7 +1676,8 @@ class grade_report_grader extends grade_report {
|
||||
$context->gradeanalysisurl = $this->gtree->get_grade_analysis_link($element['object'], $gradeanalysisstring);
|
||||
} else if (($element['type'] == 'item') ||
|
||||
($element['type'] == 'categoryitem') ||
|
||||
($element['type'] == 'courseitem')) {
|
||||
($element['type'] == 'courseitem') ||
|
||||
($element['type'] == 'userfield')) {
|
||||
|
||||
if ($element['type'] == 'item') {
|
||||
foreach ($this->get_report_links($this->context, $this->courseid, $element, $this->gpr, $mode)
|
||||
@ -1667,9 +1688,14 @@ class grade_report_grader extends grade_report {
|
||||
$context->advancedgradingurl = $this->gtree->get_advanced_grading_link($element, $this->gpr);
|
||||
}
|
||||
|
||||
if ($element['type'] == 'item') {
|
||||
$context->divider1 = true;
|
||||
}
|
||||
if (!empty($USER->editing)) {
|
||||
$context->divider = true;
|
||||
|
||||
if ($element['type'] !== 'userfield') {
|
||||
$context->divider1 = true;
|
||||
$context->divider2 = true;
|
||||
}
|
||||
if ($element['type'] == 'item') {
|
||||
$context->editurl = $this->gtree->get_edit_link($element, $this->gpr, $editstrings);
|
||||
}
|
||||
@ -1677,12 +1703,36 @@ class grade_report_grader extends grade_report {
|
||||
$context->editcalculationurl =
|
||||
$this->gtree->get_edit_calculation_link($element, $this->gpr, $editcalculationstrings);
|
||||
|
||||
$object = $element['object'];
|
||||
if ($object->itemmodule !== 'quiz') {
|
||||
$context->hideurl = $this->gtree->get_hiding_link($element, $this->gpr, $hidestrings);
|
||||
if (isset($element['object'])) {
|
||||
$object = $element['object'];
|
||||
if ($object->itemmodule !== 'quiz') {
|
||||
$context->hideurl = $this->gtree->get_hiding_link($element, $this->gpr, $hidestrings);
|
||||
}
|
||||
}
|
||||
$context->lockurl = $this->gtree->get_locking_link($element, $this->gpr, $lockstrings);
|
||||
}
|
||||
|
||||
// Sorting item.
|
||||
$sortlink = clone($this->baseurl);
|
||||
if (isset($element['object']->id)) {
|
||||
$sortlink->param('sortitemid', $element['object']->id);
|
||||
} else if ($element['type'] == 'userfield') {
|
||||
$sortlink->param('sortitemid', $element['name']);
|
||||
}
|
||||
|
||||
if (($element['type'] == 'userfield') && ($element['name'] == 'fullname')) {
|
||||
$sortlink->param('sortitemid', 'firstname');
|
||||
$context->ascendingfirstnameurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titleasc);
|
||||
$context->descendingfirstnameurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titledesc, 'desc');
|
||||
|
||||
$sortlink->param('sortitemid', 'lastname');
|
||||
$context->ascendinglastnameurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titleasc);
|
||||
$context->descendinglastnameurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titledesc, 'desc');
|
||||
} else {
|
||||
$context->ascendingurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titleasc);
|
||||
$context->descendingurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titledesc, 'desc');
|
||||
}
|
||||
|
||||
} else if ($element['type'] == 'category') {
|
||||
$categoryid = $element['object']->id;
|
||||
|
||||
@ -1712,7 +1762,7 @@ class grade_report_grader extends grade_report {
|
||||
$this->gtree->get_category_view_mode_link($url, $strswitchwhole, 'switch_whole', $fullmode);
|
||||
|
||||
if (!empty($USER->editing)) {
|
||||
$context->divider = true;
|
||||
$context->divider1 = true;
|
||||
$context->editurl = $this->gtree->get_edit_link($element, $this->gpr, $editstrings);
|
||||
$context->hideurl = $this->gtree->get_hiding_link($element, $this->gpr, $hidestrings);
|
||||
$context->lockurl = $this->gtree->get_locking_link($element, $this->gpr, $lockstrings);
|
||||
@ -1720,7 +1770,11 @@ class grade_report_grader extends grade_report {
|
||||
|
||||
}
|
||||
|
||||
$context->dataid = $element['object']->id;
|
||||
if (isset($element['object'])) {
|
||||
$context->dataid = $element['object']->id;
|
||||
} else if ($element['type'] == 'userfield') {
|
||||
$context->dataid = $element['name'];
|
||||
}
|
||||
} else if ($mode == 'user') {
|
||||
foreach ($this->get_report_links($this->context, $this->courseid, $element, $this->gpr, $mode)
|
||||
as $count => $reportlink) {
|
||||
@ -1731,7 +1785,8 @@ class grade_report_grader extends grade_report {
|
||||
}
|
||||
|
||||
if (!empty($USER->editing) || isset($context->gradeanalysisurl) || isset($context->gradesonlyurl)
|
||||
|| isset($context->aggregatesonlyurl) || isset($context->fullmodeurl) || isset($context->reporturl0)) {
|
||||
|| isset($context->aggregatesonlyurl) || isset($context->fullmodeurl) || isset($context->reporturl0)
|
||||
|| isset($context->ascendingurl) || isset($context->ascendingfirstnameurl)) {
|
||||
return $OUTPUT->render_from_template('gradereport_grader/cellmenu', $context);
|
||||
}
|
||||
return '';
|
||||
@ -1949,13 +2004,9 @@ class grade_report_grader extends grade_report {
|
||||
* @return array An associative array of HTML sorting links+arrows
|
||||
*/
|
||||
public function get_sort_arrows(array $extrafields = array()) {
|
||||
global $OUTPUT, $CFG;
|
||||
global $CFG;
|
||||
$arrows = array();
|
||||
|
||||
$strsortasc = $this->get_lang_string('sortasc', 'grades');
|
||||
$strsortdesc = $this->get_lang_string('sortdesc', 'grades');
|
||||
$iconasc = $OUTPUT->pix_icon('t/sort_asc', $strsortasc, '', array('class' => 'iconsmall sorticon'));
|
||||
$icondesc = $OUTPUT->pix_icon('t/sort_desc', $strsortdesc, '', array('class' => 'iconsmall sorticon'));
|
||||
$sortlink = clone($this->baseurl);
|
||||
|
||||
// Sourced from tablelib.php
|
||||
// Check the full name display for sortable fields.
|
||||
@ -1977,7 +2028,13 @@ class grade_report_grader extends grade_report {
|
||||
new moodle_url($this->baseurl, array('sortitemid' => $name)), $this->get_lang_string($name)
|
||||
);
|
||||
if ($this->sortitemid == $name) {
|
||||
$arrows['studentname'] .= $this->sortorder == 'ASC' ? $iconasc : $icondesc;
|
||||
$sortlink->param('sortitemid', $name);
|
||||
if ($this->sortorder == 'ASC') {
|
||||
$sorticon = $this->get_sort_arrow('down', $sortlink);
|
||||
} else {
|
||||
$sorticon = $this->get_sort_arrow('up', $sortlink);
|
||||
}
|
||||
$arrows['studentname'] .= $sorticon;
|
||||
}
|
||||
$arrows['studentname'] .= ' / ';
|
||||
}
|
||||
@ -1991,11 +2048,14 @@ class grade_report_grader extends grade_report {
|
||||
$arrows[$field] = $fieldlink;
|
||||
|
||||
if ($field == $this->sortitemid) {
|
||||
$sortlink->param('sortitemid', $field);
|
||||
|
||||
if ($this->sortorder == 'ASC') {
|
||||
$arrows[$field] .= $iconasc;
|
||||
$sorticon = $this->get_sort_arrow('down', $sortlink);
|
||||
} else {
|
||||
$arrows[$field] .= $icondesc;
|
||||
$sorticon = $this->get_sort_arrow('up', $sortlink);
|
||||
}
|
||||
$arrows[$field] .= $sorticon;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,9 @@
|
||||
}
|
||||
|
||||
.path-grade-report-grader .gradeparent .sorticon {
|
||||
margin-left: 3px;
|
||||
margin-left: 5px;
|
||||
vertical-align: middle;
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
.path-grade-report-grader .gradeparent .gradevalue {
|
||||
@ -214,10 +216,6 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.path-grade-report-grader .action-menu {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.path-grade-report-grader .dropdown-menu {
|
||||
width: max-content;
|
||||
}
|
||||
|
@ -23,7 +23,15 @@
|
||||
"editurl": "<a class='dropdown-item' aria-label='Edit grade' role='menuitem' href='grade/edit/tree/grade.php?courseid=13&itemid=608&userid=85&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>Edit grade</a>",
|
||||
"hideurl": "<a class='dropdown-item' aria-label='Hide' role='menuitem' href='grade/edit/tree/action.php?id=13&sesskey=sMAOMLAAN5&eid=n608u85&gpr_type=report&gpr_plugin=grader&gpr_courseid=13&action=hide'>Hide</a>",
|
||||
"reporturl0": "<a class='dropdown-item' aria-label='Single view for this user' role='menuitem' href='grade/report/singleview/index.php?id=13&itemid=39&item=user&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>Single view for this user</a>",
|
||||
"reporturl1": "<a class='dropdown-item' aria-label='User report' role='menuitem' href='grade/report/user/index.php?userid=39&id=13&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>User report</a>"
|
||||
"reporturl1": "<a class='dropdown-item' aria-label='User report' role='menuitem' href='grade/report/user/index.php?userid=39&id=13&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>User report</a>",
|
||||
"ascendingurl": "<a class='dropdown-item' aria-label='Ascending' role='menuitem' href='index.php?id=13&sortitemid=email&sort=asc&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>Ascending</a>",
|
||||
"descendingurl": "<a class='dropdown-item' aria-label='Descending' role='menuitem' href='index.php?id=13&sortitemid=email&sort=desc&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>Descending</a>",
|
||||
"ascendingfirstnameurl": "<a class='dropdown-item' aria-label='Ascending' role='menuitem' href='index.php?id=13&sortitemid=firstname&sort=asc&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>Ascending</a>",
|
||||
"descendingfirstnameurl": "<a class='dropdown-item' aria-label='Descending' role='menuitem' href='index.php?id=13&sortitemid=firstname&sort=desc&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>Descending</a>",
|
||||
"ascendinglastnameurl": "<a class='dropdown-item' aria-label='Ascending' role='menuitem' href='index.php?id=13&sortitemid=lastname&sort=asc&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>Ascending</a>",
|
||||
"descendinglastnameurl": "<a class='dropdown-item' aria-label='Descending' role='menuitem' href='index.php?id=13&sortitemid=lastname&sort=desc&gpr_type=report&gpr_plugin=grader&gpr_courseid=13'>Descending</a>",
|
||||
"divider1": "true",
|
||||
"divider2": "true"
|
||||
}
|
||||
}}
|
||||
<div class="action-menu mb-1 moodle-actionmenu grader">
|
||||
@ -43,9 +51,25 @@
|
||||
{{#gradesonlyurl}}{{{gradesonlyurl}}}{{/gradesonlyurl}}
|
||||
{{#aggregatesonlyurl}}{{{aggregatesonlyurl}}}{{/aggregatesonlyurl}}
|
||||
{{#fullmodeurl}}{{{fullmodeurl}}}{{/fullmodeurl}}
|
||||
{{#divider}}
|
||||
{{#advancedgradingurl}}{{{advancedgradingurl}}}{{/advancedgradingurl}}
|
||||
{{#divider1}}
|
||||
<div class="dropdown-divider" role="separator"></div>
|
||||
{{/divider}}
|
||||
{{/divider1}}
|
||||
{{#ascendingfirstnameurl}}
|
||||
<h6 class="dropdown-header">{{#str}} firstname, moodle {{/str}}</h6>
|
||||
{{{ascendingfirstnameurl}}}
|
||||
{{{descendingfirstnameurl}}}
|
||||
<h6 class="dropdown-header">{{#str}} lastname, moodle {{/str}}</h6>
|
||||
{{{ascendinglastnameurl}}}
|
||||
{{{descendinglastnameurl}}}
|
||||
{{/ascendingfirstnameurl}}
|
||||
{{#ascendingurl}}
|
||||
{{{ascendingurl}}}
|
||||
{{{descendingurl}}}
|
||||
{{/ascendingurl}}
|
||||
{{#divider2}}
|
||||
<div class="dropdown-divider" role="separator"></div>
|
||||
{{/divider2}}
|
||||
{{#hideurl}}{{{hideurl}}}{{/hideurl}}
|
||||
{{#lockurl}}{{{lockurl}}}{{/lockurl}}
|
||||
</div>
|
||||
|
@ -242,4 +242,16 @@ class behat_gradereport_grader extends behat_base {
|
||||
return "//table[@id='user-grades']//*[@data-id='" . $userid . "']";
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks on given user profile field menu.
|
||||
*
|
||||
* @Given /^I click on user profile field menu "([^"]*)"$/
|
||||
* @param string $field
|
||||
*/
|
||||
public function i_click_on_user_profile_field_menu(string $field) {
|
||||
|
||||
$xpath = "//table[@id='user-grades']//*[@data-id='" . $field . "']";
|
||||
$this->execute("behat_general::i_click_on", array($this->escape($xpath), "xpath_element"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
@gradereport @gradereport_grader
|
||||
Feature: We can sort grades/user fields on the grader report
|
||||
In order to manage grades on grader report
|
||||
As a teacher
|
||||
I need to be able to sort grades or user fields.
|
||||
|
||||
Background:
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | topics |
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| student1 | StudentA | 2 | d@example.com |
|
||||
| student2 | StudentB | 4 | a@example.com |
|
||||
| student3 | StudentC | 3 | c@example.com |
|
||||
| student4 | StudentD | 1 | b@example.com |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
| student2 | C1 | student |
|
||||
| student3 | C1 | student |
|
||||
| student4 | C1 | student |
|
||||
And the following "activities" exist:
|
||||
| activity | course | section | name | intro | assignsubmission_onlinetext_enabled | submissiondrafts |
|
||||
| assign | C1 | 1 | Test assignment name 1 | Submit your online text | 1 | 0 |
|
||||
And the following "mod_assign > submissions" exist:
|
||||
| assign | user | onlinetext |
|
||||
| Test assignment name 1 | student1 | This is a submission for assignment 1 |
|
||||
| Test assignment name 1 | student2 | This is a submission for assignment 1 |
|
||||
| Test assignment name 1 | student3 | This is a submission for assignment 1 |
|
||||
| Test assignment name 1 | student4 | This is a submission for assignment 1 |
|
||||
And the following "grade items" exist:
|
||||
| itemname | grademin | grademax | course |
|
||||
| Manual grade | 20 | 40 | C1 |
|
||||
And the following "grade grades" exist:
|
||||
| gradeitem | user | grade |
|
||||
| Test assignment name 1 | student1 | 80 |
|
||||
| Test assignment name 1 | student2 | 40 |
|
||||
| Test assignment name 1 | student3 | 60 |
|
||||
And I log in as "teacher1"
|
||||
|
||||
@javascript
|
||||
Scenario: Sort grades or user fields on grader report
|
||||
When I am on "Course 1" course homepage with editing mode on
|
||||
And I navigate to "View > Grader report" in the course gradebook
|
||||
# Default sorting is lastname ascending.
|
||||
And "StudentD 1" "table_row" should appear before "StudentA 2" "table_row"
|
||||
And "StudentA 2" "table_row" should appear before "StudentC 3" "table_row"
|
||||
And "StudentC 3" "table_row" should appear before "StudentB 4" "table_row"
|
||||
# Sort by grades in descending order.
|
||||
And I click on grade item menu "Test assignment name 1"
|
||||
And I choose "Descending" in the open action menu
|
||||
And I wait until the page is ready
|
||||
Then "StudentA 2" "table_row" should appear before "StudentC 3" "table_row"
|
||||
And "StudentC 3" "table_row" should appear before "StudentB 4" "table_row"
|
||||
And "StudentB 4" "table_row" should appear before "StudentD 1" "table_row"
|
||||
# Sort by grades in ascending order.
|
||||
And I click on grade item menu "Test assignment name 1"
|
||||
And I choose "Ascending" in the open action menu
|
||||
And I wait until the page is ready
|
||||
Then "StudentD 1" "table_row" should appear before "StudentB 4" "table_row"
|
||||
And "StudentB 4" "table_row" should appear before "StudentC 3" "table_row"
|
||||
And "StudentC 3" "table_row" should appear before "StudentA 2" "table_row"
|
||||
# Sort by email in ascending order.
|
||||
And I click on user profile field menu "email"
|
||||
And I choose "Ascending" in the open action menu
|
||||
And I wait until the page is ready
|
||||
Then "StudentB 4" "table_row" should appear before "StudentD 1" "table_row"
|
||||
And "StudentD 1" "table_row" should appear before "StudentC 3" "table_row"
|
||||
And "StudentC 3" "table_row" should appear before "StudentA 2" "table_row"
|
||||
And I click on user profile field menu "email"
|
||||
# Sort by email in descending order.
|
||||
And I choose "Descending" in the open action menu
|
||||
And I wait until the page is ready
|
||||
Then "StudentA 2" "table_row" should appear before "StudentC 3" "table_row"
|
||||
And "StudentC 3" "table_row" should appear before "StudentD 1" "table_row"
|
||||
And "StudentD 1" "table_row" should appear before "StudentB 4" "table_row"
|
||||
# Sort by firstname in ascending order.
|
||||
And I click on "First name" "link"
|
||||
And I wait until the page is ready
|
||||
Then "StudentA 2" "table_row" should appear before "StudentB 4" "table_row"
|
||||
And "StudentB 4" "table_row" should appear before "StudentC 3" "table_row"
|
||||
And "StudentC 3" "table_row" should appear before "StudentD 1" "table_row"
|
||||
# Sort by firstname in descending order.
|
||||
And I click on "First name" "link"
|
||||
And I wait until the page is ready
|
||||
Then "StudentD 1" "table_row" should appear before "StudentC 3" "table_row"
|
||||
And "StudentC 3" "table_row" should appear before "StudentB 4" "table_row"
|
||||
And "StudentB 4" "table_row" should appear before "StudentA 2" "table_row"
|
||||
# Sort by lastname in ascending order.
|
||||
And I click on "Last name" "link"
|
||||
And I wait until the page is ready
|
||||
Then "StudentD 1" "table_row" should appear before "StudentA 2" "table_row"
|
||||
And "StudentA 2" "table_row" should appear before "StudentC 3" "table_row"
|
||||
And "StudentC 3" "table_row" should appear before "StudentB 4" "table_row"
|
@ -443,7 +443,6 @@ abstract class grade_report {
|
||||
$pix = ['up' => 't/sort_desc', 'down' => 't/sort_asc'];
|
||||
$matrix = ['up' => 'desc', 'down' => 'asc'];
|
||||
$strsort = $this->get_lang_string($matrix[$direction], 'moodle');
|
||||
|
||||
$arrow = $OUTPUT->pix_icon($pix[$direction], '', '', ['class' => 'sorticon']);
|
||||
return html_writer::link($sortlink, $arrow, ['title' => $strsort, 'aria-label' => $strsort]);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user