Merge branch 'MDL-66893-master-3' of https://github.com/ryanwyllie/moodle
@ -61,19 +61,35 @@
|
||||
<form id="gradingform_guide-{{uniqid}}">
|
||||
<input type="hidden" name="instanceid" value="{{instanceid}}">
|
||||
{{#criterion}}
|
||||
<div data-gradingform-guide-role="criterion">
|
||||
<h5>
|
||||
{{name}}
|
||||
<a
|
||||
href="#gradingform_guide-{{uniqid}}-criteria-{{id}}-description"
|
||||
aria-controls="gradingform_guide-{{uniqid}}-criteria-{{id}}-description"
|
||||
aria-expanded="false"
|
||||
data-toggle="collapse"
|
||||
role="button"
|
||||
<div class="mb-3 criterion" data-gradingform-guide-role="criterion">
|
||||
<div class="d-flex align-items-center">
|
||||
<h5 class="description font-weight-bold mb-0">{{name}}</h5>
|
||||
<button
|
||||
class="btn btn-link px-1"
|
||||
aria-controls="gradingform_guide-{{uniqid}}-criteria-{{id}}-description"
|
||||
aria-expanded="false"
|
||||
data-target="#gradingform_guide-{{uniqid}}-criteria-{{id}}-description"
|
||||
data-toggle="collapse"
|
||||
type="button"
|
||||
>
|
||||
{{# pix }} info, gradingform_guide {{/ pix }}
|
||||
</a>
|
||||
</h5>
|
||||
</button>
|
||||
<button class="criterion-toggle btn btn-icon icon-no-margin text-reset p-0 font-weight-bold mb-0 ml-auto"
|
||||
type="button"
|
||||
data-toggle="collapse"
|
||||
data-target="#criteria-{{id}}"
|
||||
aria-expanded="true"
|
||||
aria-controls="criteria-{{id}}">
|
||||
<span class="collapsed-icon">
|
||||
{{#pix}} t/collapsed, core {{/pix}}
|
||||
<span class="sr-only">{{#str}} expandcriterion, core_grades {{/str}}</span>
|
||||
</span>
|
||||
<span class="expanded-icon">
|
||||
{{#pix}} t/expanded, core {{/pix}}
|
||||
<span class="sr-only">{{#str}} collapsecriterion, core_grades {{/str}}</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="collapse" id="gradingform_guide-{{uniqid}}-criteria-{{id}}-description">
|
||||
<div class="border p-3 mb-3 bg-white rounded">
|
||||
{{{description}}}
|
||||
@ -83,52 +99,59 @@
|
||||
{{/descriptionmarkers}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="gradingform_guide-{{uniqid}}-criteria-{{id}}-score">{{#str}}outof, gradingform_guide, {{maxscore}}{{/str}}</label>
|
||||
<input class="form-control" type="number" name="advancedgrading[criteria][{{id}}][score]" value="{{score}}"
|
||||
id="gradingform_guide-{{uniqid}}-criteria-{{id}}-score"
|
||||
aria-describedby="gradingform_guide-{{uniqid}}-help-{{id}}-score">
|
||||
<small id="gradingform_guide-{{uniqid}}-help-{{id}}-score" class="sr-only">{{#str}}grade_help, gradingform_guide{{/str}}</small>
|
||||
</div>
|
||||
<div class="form-group ">
|
||||
<label for="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark">{{#str}}additionalcomments, gradingform_guide{{/str}}</label>
|
||||
<div class="input-group mb-3 form-inset form-inset-right">
|
||||
<textarea class="form-control" type="text" name="advancedgrading[criteria][{{id}}][remark]"
|
||||
id="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark"
|
||||
aria-describedby="gradingform_guide-{{uniqid}}-help-{{id}}-remark"
|
||||
data-gradingform-guide-role="remark"
|
||||
>{{remark}}</textarea>
|
||||
{{#hascomments}}
|
||||
<a
|
||||
class="form-inset-item"
|
||||
href="#gradingform_guide-{{uniqid}}-criteria-{{id}}-remark-frequent-comments"
|
||||
aria-controls="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark-frequent-comments"
|
||||
aria-expanded="false"
|
||||
data-toggle="collapse"
|
||||
role="button"
|
||||
>
|
||||
{{#pix}}plus, gradingform_guide{{/pix}}
|
||||
</a>
|
||||
{{/hascomments}}
|
||||
<div class="collapse show" id="criteria-{{id}}">
|
||||
<div class="form-group">
|
||||
<label for="gradingform_guide-{{uniqid}}-criteria-{{id}}-score">{{#str}}outof, gradingform_guide, {{maxscore}}{{/str}}</label>
|
||||
<input class="form-control" type="number" name="advancedgrading[criteria][{{id}}][score]" value="{{score}}"
|
||||
id="gradingform_guide-{{uniqid}}-criteria-{{id}}-score"
|
||||
aria-describedby="gradingform_guide-{{uniqid}}-help-{{id}}-score">
|
||||
<small id="gradingform_guide-{{uniqid}}-help-{{id}}-score" class="sr-only">{{#str}}grade_help, gradingform_guide{{/str}}</small>
|
||||
</div>
|
||||
{{#hascomments}}
|
||||
<div class="collapse" id="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark-frequent-comments">
|
||||
<div data-gradingform_guide-frequent-comments="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark">
|
||||
<div class="list-group">
|
||||
{{#comments}}
|
||||
<button type="button" class="list-group-item list-group-item-action" data-gradingform_guide-role="frequent-comment">{{description}}</button>
|
||||
{{/comments}}
|
||||
<div class="form-group ">
|
||||
<label class="text-muted" for="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark">{{#str}}additionalcomments, gradingform_guide{{/str}}</label>
|
||||
<div class="input-group mb-3 form-inset form-inset-right">
|
||||
<textarea class="form-control" type="text" name="advancedgrading[criteria][{{id}}][remark]"
|
||||
id="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark"
|
||||
aria-describedby="gradingform_guide-{{uniqid}}-help-{{id}}-remark"
|
||||
data-gradingform-guide-role="remark"
|
||||
rows="2"
|
||||
data-max-rows="5"
|
||||
data-auto-rows
|
||||
>{{remark}}</textarea>
|
||||
{{#hascomments}}
|
||||
<button
|
||||
class="btn btn-icon form-inset-item icon-no-margin p-0 mt-1 mr-1 text-reset collapsed"
|
||||
aria-controls="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark-frequent-comments"
|
||||
aria-expanded="false"
|
||||
data-toggle="collapse"
|
||||
data-target="#gradingform_guide-{{uniqid}}-criteria-{{id}}-remark-frequent-comments"
|
||||
type="button"
|
||||
>
|
||||
{{#pix}}plus, gradingform_guide{{/pix}}
|
||||
</button>
|
||||
{{/hascomments}}
|
||||
</div>
|
||||
{{#hascomments}}
|
||||
<div class="collapse" id="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark-frequent-comments">
|
||||
<div data-gradingform_guide-frequent-comments="gradingform_guide-{{uniqid}}-criteria-{{id}}-remark">
|
||||
<h6>{{#str}}comments, gradingform_guide{{/str}}</h6>
|
||||
<div class="list-group">
|
||||
{{#comments}}
|
||||
<button type="button" class="list-group-item list-group-item-action" data-gradingform_guide-role="frequent-comment">{{description}}</button>
|
||||
{{/comments}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/hascomments}}
|
||||
<small id="gradingform_guide-{{uniqid}}-help-{{id}}-remark" class="sr-only">{{#str}}grade_help, gradingform_guide{{/str}}</small>
|
||||
{{/hascomments}}
|
||||
<small id="gradingform_guide-{{uniqid}}-help-{{id}}-remark" class="sr-only">{{#str}}grade_help, gradingform_guide{{/str}}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/criterion}}
|
||||
</form>
|
||||
{{#js}}
|
||||
require(['gradingform_guide/grades/grader/gradingpanel/comments'], function(Comments) {
|
||||
require(['gradingform_guide/grades/grader/gradingpanel/comments', 'core/auto_rows'], function(Comments, AutoRows) {
|
||||
Comments.init('gradingform_guide-{{uniqid}}');
|
||||
AutoRows.init(document.getElementById('gradingform_guide-{{uniqid}}'));
|
||||
});
|
||||
{{/js}}
|
||||
|
@ -57,49 +57,71 @@
|
||||
<input type="hidden" name="instanceid" value="{{instanceid}}">
|
||||
<div id="rubric-advancedgrading-{{uniqid}}" class="criterion">
|
||||
{{#criteria}}
|
||||
<div class="d-block mb-2">
|
||||
<h5 class="d-inline px-0 font-weight-bold mb-0">{{{description}}}</h5>
|
||||
<button class="d-inline btn p-0 font-weight-bold mb-0 pull-right collapse"
|
||||
type="button"
|
||||
data-toggle="collapse"
|
||||
data-target="#criteria-{{id}}"
|
||||
aria-expanded="true"
|
||||
aria-controls="criteria-{{id}}">
|
||||
</button>
|
||||
</div>
|
||||
<div class="collapse show" id="criteria-{{id}}">
|
||||
{{#levels}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input level"
|
||||
type="radio"
|
||||
name="advancedgrading[criteria][{{criterionid}}][levelid]"
|
||||
id="advancedgrading-criteria-{{criterionid}}-levels-{{id}}-definition"
|
||||
value="{{id}}"
|
||||
{{#checked}}
|
||||
aria-checked="true"
|
||||
tabindex="0"
|
||||
checked
|
||||
{{/checked}}
|
||||
{{^checked}}
|
||||
aria-checked="false"
|
||||
tabindex="-1"
|
||||
{{/checked}}
|
||||
>
|
||||
<label class="w-100" for="advancedgrading-criteria-{{criterionid}}-levels-{{id}}-definition">
|
||||
<label class="font-weight-bold">
|
||||
{{{definition}}}
|
||||
<div class="mb-3">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<h5 class="px-0 mb-0 description font-weight-bold">{{{description}}}</h5>
|
||||
<button class="criterion-toggle btn btn-icon icon-no-margin text-reset p-0 font-weight-bold mb-0 ml-auto"
|
||||
type="button"
|
||||
data-toggle="collapse"
|
||||
data-target="#criteria-{{id}}"
|
||||
aria-expanded="true"
|
||||
aria-controls="criteria-{{id}}">
|
||||
<span class="collapsed-icon">
|
||||
{{#pix}} t/collapsed, core {{/pix}}
|
||||
<span class="sr-only">{{#str}} expandcriterion, core_grades {{/str}}</span>
|
||||
</span>
|
||||
<span class="expanded-icon">
|
||||
{{#pix}} t/expanded, core {{/pix}}
|
||||
<span class="sr-only">{{#str}} collapsecriterion, core_grades {{/str}}</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="collapse show" id="criteria-{{id}}">
|
||||
{{#levels}}
|
||||
<div class="form-check">
|
||||
<input class="form-check-input level"
|
||||
type="radio"
|
||||
name="advancedgrading[criteria][{{criterionid}}][levelid]"
|
||||
id="advancedgrading-criteria-{{criterionid}}-levels-{{id}}-definition"
|
||||
value="{{id}}"
|
||||
{{#checked}}
|
||||
aria-checked="true"
|
||||
tabindex="0"
|
||||
checked
|
||||
{{/checked}}
|
||||
{{^checked}}
|
||||
aria-checked="false"
|
||||
tabindex="-1"
|
||||
{{/checked}}
|
||||
>
|
||||
<label class="w-100" for="advancedgrading-criteria-{{criterionid}}-levels-{{id}}-definition">
|
||||
<span>
|
||||
{{{definition}}}
|
||||
</span>
|
||||
<span class="pull-right">
|
||||
{{#str}}pointsvalue, gradingform_rubric, {{score}}{{/str}}
|
||||
</span>
|
||||
</label>
|
||||
<label class="pull-right font-weight-bold">
|
||||
{{#str}}pointsvalue, gradingform_rubric, {{score}}{{/str}}
|
||||
</label>
|
||||
</label>
|
||||
</div>
|
||||
{{/levels}}
|
||||
<div class="form-group">
|
||||
<label class="text-muted" for="advancedgrading-criteria-{{id}}-remark">{{#str}} additionalfeedback, core_grades {{/str}}</label>
|
||||
<textarea class="form-control"
|
||||
name="advancedgrading[criteria][{{id}}][remark]"
|
||||
id="advancedgrading-criteria-{{id}}-remark"
|
||||
cols="10"
|
||||
rows="1"
|
||||
data-max-rows="5"
|
||||
data-auto-rows="true"
|
||||
>{{{remark}}}</textarea>
|
||||
</div>
|
||||
{{/levels}}
|
||||
<div class="form-group">
|
||||
<label for="advancedgrading-criteria-{{id}}-remark">Additional feedback</label>
|
||||
<textarea class="form-control" name="advancedgrading[criteria][{{id}}][remark]" id="advancedgrading-criteria-{{id}}-remark" cols="10" rows="5">{{{remark}}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
{{/criteria}}
|
||||
</div>
|
||||
</form>
|
||||
{{#js}}
|
||||
require(['core/auto_rows'], function(AutoRows) {
|
||||
AutoRows.init(document.getElementById('gradingform_rubric-{{uniqid}}'));
|
||||
});
|
||||
{{/js}}
|
@ -30,6 +30,7 @@ $string['addfeedback'] = 'Add feedback';
|
||||
$string['addgradeletter'] = 'Add a grade letter';
|
||||
$string['addidnumbers'] = 'Add ID numbers';
|
||||
$string['additem'] = 'Add grade item';
|
||||
$string['additionalfeedback'] = 'Additional feedback';
|
||||
$string['addoutcome'] = 'Add an outcome';
|
||||
$string['addoutcomeitem'] = 'Add outcome item';
|
||||
$string['addscale'] = 'Add a scale';
|
||||
@ -118,6 +119,7 @@ $string['categoryname'] = 'Category name';
|
||||
$string['categorytotal'] = 'Category total';
|
||||
$string['categorytotalname'] = 'Category total name';
|
||||
$string['categorytotalfull'] = '{$a->category} total';
|
||||
$string['collapsecriterion'] = 'Collapse criterion';
|
||||
$string['combo'] = 'Tabs and drop-down menu';
|
||||
$string['compact'] = 'Compact';
|
||||
$string['componentcontrolsvisibility'] = 'Whether this grade item is hidden is controlled by the activity settings.';
|
||||
@ -207,6 +209,7 @@ $string['eventusergraded'] = 'User graded';
|
||||
$string['excluded'] = 'Excluded';
|
||||
$string['excluded_help'] = 'If ticked, the grade will not be included in any aggregation.';
|
||||
$string['expand'] = 'Expand category';
|
||||
$string['expandcriterion'] = 'Expand criterion';
|
||||
$string['export'] = 'Export';
|
||||
$string['exportalloutcomes'] = 'Export all outcomes';
|
||||
$string['exportfeedback'] = 'Include feedback in export';
|
||||
@ -354,6 +357,7 @@ $string['gradevaluetoobig'] = 'One of the grade values is larger than the allowe
|
||||
$string['gradeview'] = 'View grade';
|
||||
$string['gradewasmodifiedduringediting'] = 'The grade entered for {$a->itemname} for {$a->username} was ignored because it was more recently updated by someone else.';
|
||||
$string['gradeweighthelp'] = 'Grade weight help';
|
||||
$string['gradingmodulename'] = 'Grading ({$a})';
|
||||
$string['groupavg'] = 'Group average';
|
||||
$string['hidden'] = 'Hidden';
|
||||
$string['hidden_help'] = 'If ticked, grades are hidden from students. A hidden until date may be set if desired, to release grades after grading is completed.';
|
||||
|
2
lib/amd/build/modal.min.js
vendored
@ -343,9 +343,12 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
|
||||
this.bodyJS = js;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}.bind(this))
|
||||
.then(function(result) {
|
||||
Event.notifyFilterContentUpdated(body);
|
||||
this.getRoot().trigger(ModalEvents.bodyRendered, this);
|
||||
|
||||
return result;
|
||||
}.bind(this))
|
||||
.fail(Notification.exception)
|
||||
|
@ -195,6 +195,7 @@ class icon_system_fontawesome extends icon_system_font {
|
||||
'core:i/assignroles' => 'fa-user-plus',
|
||||
'core:i/backup' => 'fa-file-zip-o',
|
||||
'core:i/badge' => 'fa-shield',
|
||||
'core:i/breadcrumbdivider' => 'fa-angle-right',
|
||||
'core:i/calc' => 'fa-calculator',
|
||||
'core:i/calendar' => 'fa-calendar',
|
||||
'core:i/calendareventdescription' => 'fa-align-left',
|
||||
@ -241,6 +242,7 @@ class icon_system_fontawesome extends icon_system_font {
|
||||
'core:i/grade_incorrect' => 'fa-remove text-danger',
|
||||
'core:i/grade_partiallycorrect' => 'fa-check-square',
|
||||
'core:i/grades' => 'fa-table',
|
||||
'core:i/grading' => 'fa-magic',
|
||||
'core:i/groupevent' => 'fa-group',
|
||||
'core:i/groupn' => 'fa-user',
|
||||
'core:i/group' => 'fa-users',
|
||||
|
@ -33,9 +33,9 @@
|
||||
}}
|
||||
<div
|
||||
id="{{$drawerid}}drawer-{{uniqid}}{{/drawerid}}"
|
||||
class="{{$drawerclasses}}{{/drawerclasses}} drawer bg-white hidden"
|
||||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
class="{{$drawerclasses}}{{/drawerclasses}} drawer bg-white {{^show}}hidden{{/show}}"
|
||||
aria-expanded="{{#show}}true{{/show}}{{^show}}false{{/show}}"
|
||||
aria-hidden="{{#show}}false{{/show}}{{^show}}true{{/show}}"
|
||||
data-region="right-hand-drawer"
|
||||
role="region"
|
||||
tabindex="-1"
|
||||
|
@ -1,2 +1,2 @@
|
||||
define ("mod_forum/grades/expandconversation",["exports","./grader/selectors","mod_forum/repository","core/notification","core/templates","core/modal_factory","core/modal_events"],function(a,b,c,d,e,f,g){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.registerEventListeners=void 0;b=i(b);c=h(c);e=h(e);f=i(f);g=i(g);function h(a){return a&&a.__esModule?a:{default:a}}function i(a){if(a&&a.__esModule){return a}else{var b={};if(null!=a){for(var c in a){if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};if(d.get||d.set){Object.defineProperty(b,c,d)}else{b[c]=a[c]}}}}b.default=a;return b}}function j(a,b){return m(a)||l(a,b)||k()}function k(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function l(a,b){var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function m(a){if(Array.isArray(a))return a}function n(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function o(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){n(h,d,e,f,g,"next",a)}function g(a){n(h,d,e,f,g,"throw",a)}f(void 0)})}}var p=function(a){return a.closest(b.expandConversation)},q=function(){var a=o(regeneratorRuntime.mark(function a(b){var d,h,i,k,l,m,n,o,p;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d=b.dataset.postid;h=b.dataset.discussionid;i=b.dataset.name;a.next=5;return Promise.all([c.default.getDiscussionPosts(parseInt(h)),f.create({title:i,large:!0,type:f.types.CANCEL})]);case 5:k=a.sent;l=j(k,2);m=l[0];n=l[1];o=m.posts.map(function(a){a.subject=null;a.readonly=!0;a.html.rating=null;return a});n.getRoot().on(g.hidden,function(){n.destroy()});n.show();p=e.default.render("mod_forum/grades/grader/discussion/post_modal",o);n.setBody(p);p.then(function(){var a=n.getRoot()[0].querySelector("#p".concat(d));if(a){a.scrollIntoView({behavior:"smooth"})}return});case 15:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();a.registerEventListeners=function registerEventListeners(a){a.addEventListener("click",function(a){var b=p(a.target);if(b){a.preventDefault();try{q(b)}catch(a){(0,d.exception)(a)}}})}});
|
||||
define ("mod_forum/grades/expandconversation",["exports","./grader/selectors","mod_forum/repository","core/notification","core/templates","core/modal_factory","core/modal_events"],function(a,b,c,d,e,f,g){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.registerEventListeners=void 0;b=i(b);c=h(c);e=h(e);f=i(f);g=i(g);function h(a){return a&&a.__esModule?a:{default:a}}function i(a){if(a&&a.__esModule){return a}else{var b={};if(null!=a){for(var c in a){if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};if(d.get||d.set){Object.defineProperty(b,c,d)}else{b[c]=a[c]}}}}b.default=a;return b}}function j(a,b){return m(a)||l(a,b)||k()}function k(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function l(a,b){var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function m(a){if(Array.isArray(a))return a}function n(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function o(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){n(h,d,e,f,g,"next",a)}function g(a){n(h,d,e,f,g,"throw",a)}f(void 0)})}}var p=function(a){return a.closest(b.expandConversation)},q=function(){var a=o(regeneratorRuntime.mark(function a(b){var d,h,i,k,l,m,n,o,p,q,r;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d=b.dataset.postid;h=b.dataset.discussionid;i=b.dataset.name;k="1"==b.dataset.experimentalDisplayMode;a.next=6;return Promise.all([c.default.getDiscussionPosts(parseInt(h)),f.create({title:i,large:!0,type:f.types.CANCEL})]);case 6:l=a.sent;m=j(l,2);n=m[0];o=m[1];p=new Map(n.posts.map(function(a){a.readonly=!0;a.hasreplies=!1;a.replies=[];return[a.id,a]}));q=[];n.posts.forEach(function(a){if(a.parentid){var b=p.get(a.parentid);if(b){a.parentauthorname=b.author.fullname;b.hasreplies=!0;b.replies.push(a)}else{q.push(a)}}else{q.push(a)}});o.getRoot().on(g.hidden,function(){o.destroy()});o.getRoot().on(g.bodyRendered,function(){var a=o.getRoot()[0].querySelector("#p".concat(d));if(a){a.scrollIntoView({behavior:"smooth"})}});o.show();r=e.default.render("mod_forum/grades/grader/discussion/post_modal",{posts:q,experimentaldisplaymode:k});o.setBody(r);case 18:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();a.registerEventListeners=function registerEventListeners(a){a.addEventListener("click",function(a){var b=p(a.target);if(b){a.preventDefault();try{q(b)}catch(a){(0,d.exception)(a)}}})}});
|
||||
//# sourceMappingURL=expandconversation.min.js.map
|
||||
|
2
mod/forum/amd/build/grades/grader.min.js
vendored
@ -1,2 +1,2 @@
|
||||
define ("mod_forum/grades/grader",["exports","./grader/selectors","mod_forum/repository","core/templates","../local/grades/grader","core/notification","core_course/repository"],function(a,b,c,d,e,f,g){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.registerLaunchListeners=void 0;b=i(b);c=h(c);d=h(d);e=i(e);f=h(f);g=h(g);function h(a){return a&&a.__esModule?a:{default:a}}function i(a){if(a&&a.__esModule){return a}else{var b={};if(null!=a){for(var c in a){if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};if(d.get||d.set){Object.defineProperty(b,c,d)}else{b[c]=a[c]}}}}b.default=a;return b}}function j(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function k(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){j(h,d,e,f,g,"next",a)}function g(a){j(h,d,e,f,g,"throw",a)}f(void 0)})}}var l={contentRegion:"mod_forum/grades/grader/discussion/posts"},m=function(a){return function(b){return c.default.getDiscussionByUserID(b,a).then(function(a){a.discussions=a.discussions.map(p);return d.default.render(l.contentRegion,a)}).catch(f.default.exception)}},n=function(a,b){return k(regeneratorRuntime.mark(function c(){var d;return regeneratorRuntime.wrap(function(c){while(1){switch(c.prev=c.next){case 0:c.next=2;return g.default.getUsersFromCourseModuleID(a,b);case 2:d=c.sent;return c.abrupt("return",d.users);case 4:case"end":return c.stop();}}},c)}))},o=function(a){return a.closest(b.gradableItem)},p=function(a){var b=new Map;a.posts.parentposts.forEach(function(a){return b.set(a.id,a)});var c=a.posts.userposts.map(function(a){a.subject=null;a.readonly=!0;a.starter=!a.parentid;a.parent=b.get(a.parentid);a.html.rating=null;return a});return{id:a.id,name:a.name,posts:c}},q=function(){var a=k(regeneratorRuntime.mark(function a(b){var c,d,f;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:c=b.dataset;a.next=3;return e.getGradingPanelFunctions("mod_forum",c.contextid,c.gradingComponent,c.gradingComponentSubtype,c.gradableItemtype);case 3:d=a.sent;f=c.group?c.group:0;a.next=7;return e.launch(n(c.cmid,f),m(c.cmid),d.getter,d.setter,{groupid:c.groupid,initialUserId:c.initialuserid,moduleName:c.name});case 7:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();a.registerLaunchListeners=function registerLaunchListeners(){document.addEventListener("click",function(){var a=k(regeneratorRuntime.mark(function a(c){var d;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:if(!c.target.matches(b.launch)){a.next=17;break}d=o(c.target);if(d){a.next=4;break}throw Error("Unable to find a gradable item");case 4:if(!d.matches(b.gradableItems.wholeForum)){a.next=16;break}c.preventDefault();a.prev=6;a.next=9;return q(d);case 9:a.next=14;break;case 11:a.prev=11;a.t0=a["catch"](6);f.default.exception(a.t0);case 14:a.next=17;break;case 16:throw Error("Unable to find a valid gradable item");case 17:case"end":return a.stop();}}},a,null,[[6,11]])}));return function(){return a.apply(this,arguments)}}())}});
|
||||
define ("mod_forum/grades/grader",["exports","./grader/selectors","mod_forum/repository","core/templates","../local/grades/grader","core/notification","core_course/repository","core/url"],function(a,b,c,d,e,f,g,h){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.registerLaunchListeners=void 0;b=j(b);c=i(c);d=i(d);e=j(e);f=i(f);g=i(g);function i(a){return a&&a.__esModule?a:{default:a}}function j(a){if(a&&a.__esModule){return a}else{var b={};if(null!=a){for(var c in a){if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};if(d.get||d.set){Object.defineProperty(b,c,d)}else{b[c]=a[c]}}}}b.default=a;return b}}function k(a){for(var b=1;b<arguments.length;b++){var c=null!=arguments[b]?arguments[b]:{},d=Object.keys(c);if("function"==typeof Object.getOwnPropertySymbols){d=d.concat(Object.getOwnPropertySymbols(c).filter(function(a){return Object.getOwnPropertyDescriptor(c,a).enumerable}))}d.forEach(function(b){l(a,b,c[b])})}return a}function l(a,b,c){if(b in a){Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0})}else{a[b]=c}return a}function m(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function n(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){m(h,d,e,f,g,"next",a)}function g(a){m(h,d,e,f,g,"throw",a)}f(void 0)})}}var o={contentRegion:"mod_forum/grades/grader/discussion/posts"},p=function(a,b){return function(e){return c.default.getDiscussionByUserID(e,a).then(function(a){a.discussions=a.discussions.map(s);a.experimentaldisplaymode=b?!0:!1;return d.default.render(o.contentRegion,a)}).catch(f.default.exception)}},q=function(a,b){return n(regeneratorRuntime.mark(function c(){var d;return regeneratorRuntime.wrap(function(c){while(1){switch(c.prev=c.next){case 0:c.next=2;return g.default.getUsersFromCourseModuleID(a,b);case 2:d=c.sent;return c.abrupt("return",d.users);case 4:case"end":return c.stop();}}},c)}))},r=function(a){return a.closest(b.gradableItem)},s=function(a){var b=new Map;a.posts.parentposts.forEach(function(a){return b.set(a.id,a)});var c=a.posts.userposts.map(function(a){a.readonly=!0;a.hasreplies=!1;a.replies=[];var c=a.parentid?b.get(a.parentid):null;if(c){c.hasreplies=!1;c.replies=[];c.readonly=!0;a.parentauthorname=c.author.fullname}return{parent:c,post:a}});return k({},a,{posts:c})},t=function(){var a=n(regeneratorRuntime.mark(function a(b){var c,d,f;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:c=b.dataset;a.next=3;return e.getGradingPanelFunctions("mod_forum",c.contextid,c.gradingComponent,c.gradingComponentSubtype,c.gradableItemtype);case 3:d=a.sent;f=c.group?c.group:0;a.next=7;return e.launch(q(c.cmid,f),p(c.cmid,"1"==c.experimentalDisplayMode),d.getter,d.setter,{groupid:c.groupid,initialUserId:c.initialuserid,moduleName:c.name,courseName:c.courseName,courseUrl:(0,h.relativeUrl)("/course/view.php",{id:c.courseId})});case 7:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();a.registerLaunchListeners=function registerLaunchListeners(){document.addEventListener("click",function(){var a=n(regeneratorRuntime.mark(function a(c){var d;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:if(!c.target.matches(b.launch)){a.next=17;break}d=r(c.target);if(d){a.next=4;break}throw Error("Unable to find a gradable item");case 4:if(!d.matches(b.gradableItems.wholeForum)){a.next=16;break}c.preventDefault();a.prev=6;a.next=9;return t(d);case 9:a.next=14;break;case 11:a.prev=11;a.t0=a["catch"](6);f.default.exception(a.t0);case 14:a.next=17;break;case 16:throw Error("Unable to find a valid gradable item");case 17:case"end":return a.stop();}}},a,null,[[6,11]])}));return function(){return a.apply(this,arguments)}}())}});
|
||||
//# sourceMappingURL=grader.min.js.map
|
||||
|
@ -1,2 +1,2 @@
|
||||
define ("mod_forum/local/grades/local/grader/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;var b=function(a,b){return"[data-".concat(a,"=\"").concat(b,"\"]")},c={buttons:{toggleFullscreen:b("action","togglefullscreen"),closeGrader:b("action","closegrader"),saveGrade:b("action","savegrade")},regions:{moduleReplace:b("region","module_content"),pickerRegion:b("region","user_picker"),gradingPanel:b("region","grade"),gradingPanelErrors:b("region","grade-errors")}};a.default=c;return a.default});
|
||||
define ("mod_forum/local/grades/local/grader/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;var b=function(a,b){return"[data-".concat(a,"=\"").concat(b,"\"]")},c={buttons:{toggleFullscreen:b("action","togglefullscreen"),closeGrader:b("action","closegrader"),saveGrade:b("action","savegrade"),selectUser:b("action","select-user"),toggleSearch:b("action","toggle-search")},regions:{bodyContainer:b("region","body-container"),moduleReplace:b("region","module_content"),pickerRegion:b("region","user_picker"),gradingPanel:b("region","grade"),gradingPanelContainer:b("region","grading-panel-container"),gradingPanelErrors:b("region","grade-errors"),searchResultsContainer:b("region","search-results-container"),statusContainer:b("region","status-container"),userSearchContainer:b("region","user-search-container"),userSearchInput:b("region","user-search-input")}};a.default=c;return a.default});
|
||||
//# sourceMappingURL=selectors.min.js.map
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sources":["../../../../../src/local/grades/local/grader/selectors.js"],"names":["getDataSelector","name","value","buttons","toggleFullscreen","closeGrader","saveGrade","regions","moduleReplace","pickerRegion","gradingPanel","gradingPanelErrors"],"mappings":"kKA8BMA,CAAAA,CAAe,CAAG,SAACC,CAAD,CAAOC,CAAP,CAAiB,CACrC,sBAAgBD,CAAhB,eAAyBC,CAAzB,OACH,C,GAEc,CACXC,OAAO,CAAE,CACLC,gBAAgB,CAAEJ,CAAe,CAAC,QAAD,CAAW,kBAAX,CAD5B,CAELK,WAAW,CAAEL,CAAe,CAAC,QAAD,CAAW,aAAX,CAFvB,CAGLM,SAAS,CAAEN,CAAe,CAAC,QAAD,CAAW,WAAX,CAHrB,CADE,CAMXO,OAAO,CAAE,CACLC,aAAa,CAAER,CAAe,CAAC,QAAD,CAAW,gBAAX,CADzB,CAELS,YAAY,CAAET,CAAe,CAAC,QAAD,CAAW,aAAX,CAFxB,CAGLU,YAAY,CAAEV,CAAe,CAAC,QAAD,CAAW,OAAX,CAHxB,CAILW,kBAAkB,CAAEX,CAAe,CAAC,QAAD,CAAW,cAAX,CAJ9B,CANE,C","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 * Define all of the selectors we will be using on the grading interface.\n *\n * @module mod_forum/local/grades/local/grader/selectors\n * @package mod_forum\n * @copyright 2019 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * A small helper function to build queryable data selectors.\n * @param {String} name\n * @param {String} value\n * @return {string}\n */\nconst getDataSelector = (name, value) => {\n return `[data-${name}=\"${value}\"]`;\n};\n\nexport default {\n buttons: {\n toggleFullscreen: getDataSelector('action', 'togglefullscreen'),\n closeGrader: getDataSelector('action', 'closegrader'),\n saveGrade: getDataSelector('action', 'savegrade'),\n },\n regions: {\n moduleReplace: getDataSelector('region', 'module_content'),\n pickerRegion: getDataSelector('region', 'user_picker'),\n gradingPanel: getDataSelector('region', 'grade'),\n gradingPanelErrors: getDataSelector('region', 'grade-errors'),\n },\n};\n\n"],"file":"selectors.min.js"}
|
||||
{"version":3,"sources":["../../../../../src/local/grades/local/grader/selectors.js"],"names":["getDataSelector","name","value","buttons","toggleFullscreen","closeGrader","saveGrade","selectUser","toggleSearch","regions","bodyContainer","moduleReplace","pickerRegion","gradingPanel","gradingPanelContainer","gradingPanelErrors","searchResultsContainer","statusContainer","userSearchContainer","userSearchInput"],"mappings":"kKA8BMA,CAAAA,CAAe,CAAG,SAACC,CAAD,CAAOC,CAAP,CAAiB,CACrC,sBAAgBD,CAAhB,eAAyBC,CAAzB,OACH,C,GAEc,CACXC,OAAO,CAAE,CACLC,gBAAgB,CAAEJ,CAAe,CAAC,QAAD,CAAW,kBAAX,CAD5B,CAELK,WAAW,CAAEL,CAAe,CAAC,QAAD,CAAW,aAAX,CAFvB,CAGLM,SAAS,CAAEN,CAAe,CAAC,QAAD,CAAW,WAAX,CAHrB,CAILO,UAAU,CAAEP,CAAe,CAAC,QAAD,CAAW,aAAX,CAJtB,CAKLQ,YAAY,CAAER,CAAe,CAAC,QAAD,CAAW,eAAX,CALxB,CADE,CAQXS,OAAO,CAAE,CACLC,aAAa,CAAEV,CAAe,CAAC,QAAD,CAAW,gBAAX,CADzB,CAELW,aAAa,CAAEX,CAAe,CAAC,QAAD,CAAW,gBAAX,CAFzB,CAGLY,YAAY,CAAEZ,CAAe,CAAC,QAAD,CAAW,aAAX,CAHxB,CAILa,YAAY,CAAEb,CAAe,CAAC,QAAD,CAAW,OAAX,CAJxB,CAKLc,qBAAqB,CAAEd,CAAe,CAAC,QAAD,CAAW,yBAAX,CALjC,CAMLe,kBAAkB,CAAEf,CAAe,CAAC,QAAD,CAAW,cAAX,CAN9B,CAOLgB,sBAAsB,CAAEhB,CAAe,CAAC,QAAD,CAAW,0BAAX,CAPlC,CAQLiB,eAAe,CAAEjB,CAAe,CAAC,QAAD,CAAW,kBAAX,CAR3B,CASLkB,mBAAmB,CAAElB,CAAe,CAAC,QAAD,CAAW,uBAAX,CAT/B,CAULmB,eAAe,CAAEnB,CAAe,CAAC,QAAD,CAAW,mBAAX,CAV3B,CARE,C","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 * Define all of the selectors we will be using on the grading interface.\n *\n * @module mod_forum/local/grades/local/grader/selectors\n * @package mod_forum\n * @copyright 2019 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * A small helper function to build queryable data selectors.\n * @param {String} name\n * @param {String} value\n * @return {string}\n */\nconst getDataSelector = (name, value) => {\n return `[data-${name}=\"${value}\"]`;\n};\n\nexport default {\n buttons: {\n toggleFullscreen: getDataSelector('action', 'togglefullscreen'),\n closeGrader: getDataSelector('action', 'closegrader'),\n saveGrade: getDataSelector('action', 'savegrade'),\n selectUser: getDataSelector('action', 'select-user'),\n toggleSearch: getDataSelector('action', 'toggle-search')\n },\n regions: {\n bodyContainer: getDataSelector('region', 'body-container'),\n moduleReplace: getDataSelector('region', 'module_content'),\n pickerRegion: getDataSelector('region', 'user_picker'),\n gradingPanel: getDataSelector('region', 'grade'),\n gradingPanelContainer: getDataSelector('region', 'grading-panel-container'),\n gradingPanelErrors: getDataSelector('region', 'grade-errors'),\n searchResultsContainer: getDataSelector('region', 'search-results-container'),\n statusContainer: getDataSelector('region', 'status-container'),\n userSearchContainer: getDataSelector('region', 'user-search-container'),\n userSearchInput: getDataSelector('region', 'user-search-input')\n },\n};\n\n"],"file":"selectors.min.js"}
|
@ -1,2 +1,2 @@
|
||||
define ("mod_forum/local/grades/local/grader/user_picker/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;a.default={regions:{userRegion:"[data-region=\"user_picker/user\"]"},actions:{changeUser:"[data-action=\"change-user\"]",selectUser:"[data-action=\"select-user\"]",searchUserBox:"[data-action=\"search-user-box\"]",searchUserInput:"[data-action=\"search-user-input\"]"}};return a.default});
|
||||
define ("mod_forum/local/grades/local/grader/user_picker/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;a.default={regions:{userRegion:"[data-region=\"user_picker/user\"]"},actions:{changeUser:"[data-action=\"change-user\"]"}};return a.default});
|
||||
//# sourceMappingURL=selectors.min.js.map
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sources":["../../../../../../src/local/grades/local/grader/user_picker/selectors.js"],"names":["regions","userRegion","actions","changeUser","selectUser","searchUserBox","searchUserInput"],"mappings":"qLAwBe,CACXA,OAAO,CAAE,CACLC,UAAU,CAAE,oCADP,CADE,CAIXC,OAAO,CAAE,CACLC,UAAU,CAAE,+BADP,CAELC,UAAU,CAAE,+BAFP,CAGLC,aAAa,CAAE,mCAHV,CAILC,eAAe,CAAE,qCAJZ,CAJE,C","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 * Define all of the selectors we will be using on the grading interface.\n *\n * @module mod_forum/local/grades/local/grader/user_picker/selectors\n * @package mod_forum\n * @copyright 2019 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport default {\n regions: {\n userRegion: '[data-region=\"user_picker/user\"]',\n },\n actions: {\n changeUser: '[data-action=\"change-user\"]',\n selectUser: '[data-action=\"select-user\"]',\n searchUserBox: '[data-action=\"search-user-box\"]',\n searchUserInput: '[data-action=\"search-user-input\"]',\n }\n};\n\n"],"file":"selectors.min.js"}
|
||||
{"version":3,"sources":["../../../../../../src/local/grades/local/grader/user_picker/selectors.js"],"names":["regions","userRegion","actions","changeUser"],"mappings":"qLAwBe,CACXA,OAAO,CAAE,CACLC,UAAU,CAAE,oCADP,CADE,CAIXC,OAAO,CAAE,CACLC,UAAU,CAAE,+BADP,CAJE,C","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 * Define all of the selectors we will be using on the grading interface.\n *\n * @module mod_forum/local/grades/local/grader/user_picker/selectors\n * @package mod_forum\n * @copyright 2019 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport default {\n regions: {\n userRegion: '[data-region=\"user_picker/user\"]',\n },\n actions: {\n changeUser: '[data-action=\"change-user\"]',\n }\n};\n\n"],"file":"selectors.min.js"}
|
@ -45,6 +45,7 @@ const showPostInContext = async(rootNode) => {
|
||||
const postId = rootNode.dataset.postid;
|
||||
const discussionId = rootNode.dataset.discussionid;
|
||||
const discussionName = rootNode.dataset.name;
|
||||
const experimentalDisplayMode = rootNode.dataset.experimentalDisplayMode == "1";
|
||||
|
||||
const [
|
||||
allPosts,
|
||||
@ -58,12 +59,27 @@ const showPostInContext = async(rootNode) => {
|
||||
}),
|
||||
]);
|
||||
|
||||
const userPosts = allPosts.posts.map((post) => {
|
||||
post.subject = null;
|
||||
const postsById = new Map(allPosts.posts.map(post => {
|
||||
post.readonly = true;
|
||||
post.html.rating = null;
|
||||
post.hasreplies = false;
|
||||
post.replies = [];
|
||||
return [post.id, post];
|
||||
}));
|
||||
|
||||
return post;
|
||||
let posts = [];
|
||||
allPosts.posts.forEach(post => {
|
||||
if (post.parentid) {
|
||||
const parent = postsById.get(post.parentid);
|
||||
if (parent) {
|
||||
post.parentauthorname = parent.author.fullname;
|
||||
parent.hasreplies = true;
|
||||
parent.replies.push(post);
|
||||
} else {
|
||||
posts.push(post);
|
||||
}
|
||||
} else {
|
||||
posts.push(post);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle hidden event.
|
||||
@ -72,20 +88,21 @@ const showPostInContext = async(rootNode) => {
|
||||
modal.destroy();
|
||||
});
|
||||
|
||||
modal.show();
|
||||
|
||||
// Note: We do not use await here because it messes with the Modal transitions.
|
||||
const templatePromise = Templates.render('mod_forum/grades/grader/discussion/post_modal', userPosts);
|
||||
modal.setBody(templatePromise);
|
||||
// eslint-disable-next-line promise/catch-or-return
|
||||
templatePromise.then(() => {
|
||||
modal.getRoot().on(ModalEvents.bodyRendered, () => {
|
||||
const relevantPost = modal.getRoot()[0].querySelector(`#p${postId}`);
|
||||
if (relevantPost) {
|
||||
relevantPost.scrollIntoView({behavior: "smooth"});
|
||||
}
|
||||
|
||||
return;
|
||||
});
|
||||
|
||||
modal.show();
|
||||
|
||||
// Note: We do not use await here because it messes with the Modal transitions.
|
||||
const templatePromise = Templates.render('mod_forum/grades/grader/discussion/post_modal', {
|
||||
posts,
|
||||
experimentaldisplaymode: experimentalDisplayMode
|
||||
});
|
||||
modal.setBody(templatePromise);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,7 @@ import Templates from 'core/templates';
|
||||
import * as Grader from '../local/grades/grader';
|
||||
import Notification from 'core/notification';
|
||||
import CourseRepository from 'core_course/repository';
|
||||
import {relativeUrl} from 'core/url';
|
||||
|
||||
const templateNames = {
|
||||
contentRegion: 'mod_forum/grades/grader/discussion/posts',
|
||||
@ -36,9 +37,10 @@ const templateNames = {
|
||||
* Curried function with CMID set, this is then used in unified grader as a fetch a users content.
|
||||
*
|
||||
* @param {Number} cmid
|
||||
* @param {Bool} experimentalDisplayMode
|
||||
* @return {Function}
|
||||
*/
|
||||
const getContentForUserIdFunction = (cmid) => (userid) => {
|
||||
const getContentForUserIdFunction = (cmid, experimentalDisplayMode) => (userid) => {
|
||||
/**
|
||||
* Given the parent function is called with the second param set execute the partially executed function.
|
||||
*
|
||||
@ -48,6 +50,7 @@ const getContentForUserIdFunction = (cmid) => (userid) => {
|
||||
.then(context => {
|
||||
// Rebuild the returned data for the template.
|
||||
context.discussions = context.discussions.map(discussionPostMapper);
|
||||
context.experimentaldisplaymode = experimentalDisplayMode ? true : false;
|
||||
|
||||
return Templates.render(templateNames.contentRegion, context);
|
||||
})
|
||||
@ -82,18 +85,26 @@ const discussionPostMapper = (discussion) => {
|
||||
const parentMap = new Map();
|
||||
discussion.posts.parentposts.forEach(post => parentMap.set(post.id, post));
|
||||
const userPosts = discussion.posts.userposts.map(post => {
|
||||
post.subject = null;
|
||||
post.readonly = true;
|
||||
post.starter = !post.parentid;
|
||||
post.parent = parentMap.get(post.parentid);
|
||||
post.html.rating = null;
|
||||
post.hasreplies = false;
|
||||
post.replies = [];
|
||||
|
||||
return post;
|
||||
const parent = post.parentid ? parentMap.get(post.parentid) : null;
|
||||
if (parent) {
|
||||
parent.hasreplies = false;
|
||||
parent.replies = [];
|
||||
parent.readonly = true;
|
||||
post.parentauthorname = parent.author.fullname;
|
||||
}
|
||||
|
||||
return {
|
||||
parent,
|
||||
post
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
id: discussion.id,
|
||||
name: discussion.name,
|
||||
...discussion,
|
||||
posts: userPosts,
|
||||
};
|
||||
};
|
||||
@ -117,13 +128,15 @@ const launchWholeForumGrading = async(rootNode) => {
|
||||
|
||||
await Grader.launch(
|
||||
getUsersForCmidFunction(data.cmid, groupID),
|
||||
getContentForUserIdFunction(data.cmid),
|
||||
getContentForUserIdFunction(data.cmid, data.experimentalDisplayMode == "1"),
|
||||
gradingPanelFunctions.getter,
|
||||
gradingPanelFunctions.setter,
|
||||
{
|
||||
groupid: data.groupid,
|
||||
initialUserId: data.initialuserid,
|
||||
moduleName: data.name
|
||||
moduleName: data.name,
|
||||
courseName: data.courseName,
|
||||
courseUrl: relativeUrl('/course/view.php', {id: data.courseId})
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -30,6 +30,7 @@ import {add as addToast} from 'core/toast';
|
||||
import {get_string as getString} from 'core/str';
|
||||
import {failedUpdate} from 'core_grades/grades/grader/gradingpanel/normalise';
|
||||
import {addIconToContainerWithPromise} from 'core/loadingicon';
|
||||
import {debounce} from 'core/utils';
|
||||
|
||||
const templateNames = {
|
||||
grader: {
|
||||
@ -37,6 +38,8 @@ const templateNames = {
|
||||
gradingPanel: {
|
||||
error: 'mod_forum/local/grades/local/grader/gradingpanel/error',
|
||||
},
|
||||
searchResults: 'mod_forum/local/grades/local/grader/user_picker/user_search',
|
||||
status: 'mod_forum/local/grades/local/grader/status',
|
||||
},
|
||||
};
|
||||
|
||||
@ -72,8 +75,10 @@ const fetchContentFromRender = (html, js) => {
|
||||
* @return {Function}
|
||||
*/
|
||||
const getUpdateUserContentFunction = (root, getContentForUser, getGradeForUser) => {
|
||||
let firstLoad = true;
|
||||
|
||||
return async(user) => {
|
||||
const spinner = addIconToContainerWithPromise(root);
|
||||
const spinner = firstLoad ? null : addIconToContainerWithPromise(root);
|
||||
const [
|
||||
[html, js],
|
||||
userGrade,
|
||||
@ -87,20 +92,122 @@ const getUpdateUserContentFunction = (root, getContentForUser, getGradeForUser)
|
||||
gradingPanelHtml,
|
||||
gradingPanelJS
|
||||
] = await Templates.render(userGrade.templatename, userGrade.grade).then(fetchContentFromRender);
|
||||
Templates.replaceNodeContents(root.querySelector(Selectors.regions.gradingPanel), gradingPanelHtml, gradingPanelJS);
|
||||
spinner.resolve();
|
||||
const panelContainer = root.querySelector(Selectors.regions.gradingPanelContainer);
|
||||
const panel = panelContainer.querySelector(Selectors.regions.gradingPanel);
|
||||
Templates.replaceNodeContents(panel, gradingPanelHtml, gradingPanelJS);
|
||||
panelContainer.scrollTop = 0;
|
||||
firstLoad = false;
|
||||
|
||||
if (spinner) {
|
||||
spinner.resolve();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the search results container and hide the user picker and body content.
|
||||
*
|
||||
* @param {HTMLElement} bodyContainer The container element for the body content
|
||||
* @param {HTMLElement} userPickerContainer The container element for the user picker
|
||||
* @param {HTMLElement} searchResultsContainer The container element for the search results
|
||||
*/
|
||||
const showSearchResultContainer = (bodyContainer, userPickerContainer, searchResultsContainer) => {
|
||||
bodyContainer.classList.add('hidden');
|
||||
userPickerContainer.classList.add('hidden');
|
||||
searchResultsContainer.classList.remove('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the search results container and show the user picker and body content.
|
||||
*
|
||||
* @param {HTMLElement} bodyContainer The container element for the body content
|
||||
* @param {HTMLElement} userPickerContainer The container element for the user picker
|
||||
* @param {HTMLElement} searchResultsContainer The container element for the search results
|
||||
*/
|
||||
const hideSearchResultContainer = (bodyContainer, userPickerContainer, searchResultsContainer) => {
|
||||
bodyContainer.classList.remove('hidden');
|
||||
userPickerContainer.classList.remove('hidden');
|
||||
searchResultsContainer.classList.add('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggles the visibility of the user search.
|
||||
*
|
||||
* @param {HTMLElement} toggleSearchButton The button that toggles the search
|
||||
* @param {HTMLElement} searchContainer The container element for the user search
|
||||
* @param {HTMLElement} searchInput The input element for searching
|
||||
*/
|
||||
const showUserSearchInput = (toggleSearchButton, searchContainer, searchInput) => {
|
||||
searchContainer.classList.remove('collapsed');
|
||||
toggleSearchButton.setAttribute('aria-expanded', 'true');
|
||||
toggleSearchButton.classList.add('expand');
|
||||
toggleSearchButton.classList.remove('collapse');
|
||||
searchInput.focus();
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggles the visibility of the user search.
|
||||
*
|
||||
* @param {HTMLElement} toggleSearchButton The button that toggles the search
|
||||
* @param {HTMLElement} searchContainer The container element for the user search
|
||||
* @param {HTMLElement} searchInput The input element for searching
|
||||
*/
|
||||
const hideUserSearchInput = (toggleSearchButton, searchContainer, searchInput) => {
|
||||
searchContainer.classList.add('collapsed');
|
||||
toggleSearchButton.setAttribute('aria-expanded', 'false');
|
||||
toggleSearchButton.classList.add('collapse');
|
||||
toggleSearchButton.classList.remove('expand');
|
||||
toggleSearchButton.focus();
|
||||
searchInput.value = '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the list of users who's names include the given search term.
|
||||
*
|
||||
* @param {Array} userList List of users for the grader
|
||||
* @param {String} searchTerm The search term to match
|
||||
* @return {Array}
|
||||
*/
|
||||
const searchForUsers = (userList, searchTerm) => {
|
||||
if (searchTerm === '') {
|
||||
return userList;
|
||||
}
|
||||
|
||||
searchTerm = searchTerm.toLowerCase();
|
||||
|
||||
return userList.filter((user) => {
|
||||
return user.fullname.toLowerCase().includes(searchTerm);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the list of users in the search results area.
|
||||
*
|
||||
* @param {HTMLElement} searchResultsContainer The container element for search results
|
||||
* @param {Array} users The list of users to display
|
||||
*/
|
||||
const renderSearchResults = async (searchResultsContainer, users) => {
|
||||
const {html, js} = await Templates.renderForPromise(templateNames.grader.searchResults, {users});
|
||||
Templates.replaceNodeContents(searchResultsContainer, html, js);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add click handlers to the buttons in the header of the grading interface.
|
||||
*
|
||||
* @param {HTMLElement} graderLayout
|
||||
* @param {Object} userPicker
|
||||
* @param {Function} saveGradeFunction
|
||||
* @param {Array} userList List of users for the grader.
|
||||
*/
|
||||
const registerEventListeners = (graderLayout, userPicker, saveGradeFunction) => {
|
||||
const registerEventListeners = (graderLayout, userPicker, saveGradeFunction, userList) => {
|
||||
const graderContainer = graderLayout.getContainer();
|
||||
const toggleSearchButton = graderContainer.querySelector(Selectors.buttons.toggleSearch);
|
||||
const searchInputContainer = graderContainer.querySelector(Selectors.regions.userSearchContainer);
|
||||
const searchInput = searchInputContainer.querySelector(Selectors.regions.userSearchInput);
|
||||
const bodyContainer = graderContainer.querySelector(Selectors.regions.bodyContainer);
|
||||
const userPickerContainer = graderContainer.querySelector(Selectors.regions.pickerRegion);
|
||||
const searchResultsContainer = graderContainer.querySelector(Selectors.regions.searchResultsContainer);
|
||||
|
||||
graderContainer.addEventListener('click', (e) => {
|
||||
if (e.target.closest(Selectors.buttons.toggleFullscreen)) {
|
||||
e.stopImmediatePropagation();
|
||||
@ -122,7 +229,40 @@ const registerEventListeners = (graderLayout, userPicker, saveGradeFunction) =>
|
||||
if (e.target.closest(Selectors.buttons.saveGrade)) {
|
||||
saveGradeFunction(userPicker.currentUser);
|
||||
}
|
||||
|
||||
if (e.target.closest(Selectors.buttons.toggleSearch)) {
|
||||
if (toggleSearchButton.getAttribute('aria-expanded') === 'true') {
|
||||
// Search is open so let's close it.
|
||||
hideUserSearchInput(toggleSearchButton, searchInputContainer, searchInput);
|
||||
hideSearchResultContainer(bodyContainer, userPickerContainer, searchResultsContainer);
|
||||
searchResultsContainer.innerHTML = '';
|
||||
} else {
|
||||
// Search is closed so let's open it.
|
||||
showUserSearchInput(toggleSearchButton, searchInputContainer, searchInput);
|
||||
showSearchResultContainer(bodyContainer, userPickerContainer, searchResultsContainer);
|
||||
renderSearchResults(searchResultsContainer, userList);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const selectUserButton = e.target.closest(Selectors.buttons.selectUser);
|
||||
if (selectUserButton) {
|
||||
const userId = selectUserButton.getAttribute('data-userid');
|
||||
const user = userList.find(user => user.id == userId);
|
||||
userPicker.setUserId(userId);
|
||||
userPicker.showUser(user);
|
||||
hideUserSearchInput(toggleSearchButton, searchInputContainer, searchInput);
|
||||
hideSearchResultContainer(bodyContainer, userPickerContainer, searchResultsContainer);
|
||||
searchResultsContainer.innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
// Debounce the search input so that it only executes 300 milliseconds after the user has finished typing.
|
||||
searchInput.addEventListener('input', debounce(() => {
|
||||
const users = searchForUsers(userList, searchInput.value);
|
||||
renderSearchResults(searchResultsContainer, users);
|
||||
}, 300));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -182,31 +322,49 @@ const displayGradingError = async(root, user, err) => {
|
||||
* @param {Function} setGradeForUser A function to set the grade for a specific user
|
||||
*/
|
||||
export const launch = async(getListOfUsers, getContentForUser, getGradeForUser, setGradeForUser, {
|
||||
initialUserId = null, moduleName
|
||||
initialUserId = null, moduleName, courseName, courseUrl
|
||||
} = {}) => {
|
||||
|
||||
// We need all of these functions to be executed in series, if one step runs before another the interface
|
||||
// will not work.
|
||||
const [
|
||||
graderLayout,
|
||||
graderHTML,
|
||||
{html, js},
|
||||
userList,
|
||||
] = await Promise.all([
|
||||
createFullScreenWindow({fullscreen: false, showLoader: false}),
|
||||
Templates.render(templateNames.grader.app, {moduleName: moduleName}),
|
||||
Templates.renderForPromise(templateNames.grader.app, {
|
||||
moduleName,
|
||||
courseName,
|
||||
courseUrl,
|
||||
drawer: {show: true}
|
||||
}),
|
||||
getListOfUsers(),
|
||||
]);
|
||||
const graderContainer = graderLayout.getContainer();
|
||||
|
||||
const saveGradeFunction = getSaveUserGradeFunction(graderContainer, setGradeForUser);
|
||||
|
||||
Templates.replaceNodeContents(graderContainer, graderHTML, '');
|
||||
Templates.replaceNodeContents(graderContainer, html, js);
|
||||
const updateUserContent = getUpdateUserContentFunction(graderContainer, getContentForUser, getGradeForUser);
|
||||
|
||||
const userIds = userList.map(user => user.id);
|
||||
const statusContainer = graderContainer.querySelector(Selectors.regions.statusContainer);
|
||||
// Fetch the userpicker for display.
|
||||
const userPicker = await getUserPicker(
|
||||
userList,
|
||||
updateUserContent,
|
||||
user => {
|
||||
const renderContext = {
|
||||
status: null,
|
||||
index: userIds.indexOf(user.id) + 1,
|
||||
total: userList.length
|
||||
};
|
||||
Templates.render(templateNames.grader.status, renderContext).then(html => {
|
||||
statusContainer.innerHTML = html;
|
||||
return html;
|
||||
}).catch();
|
||||
updateUserContent(user);
|
||||
},
|
||||
saveGradeFunction,
|
||||
{
|
||||
initialUserId,
|
||||
@ -214,7 +372,7 @@ export const launch = async(getListOfUsers, getContentForUser, getGradeForUser,
|
||||
);
|
||||
|
||||
// Register all event listeners.
|
||||
registerEventListeners(graderLayout, userPicker, saveGradeFunction);
|
||||
registerEventListeners(graderLayout, userPicker, saveGradeFunction, userList);
|
||||
|
||||
// Display the newly created user picker.
|
||||
displayUserPicker(graderContainer, userPicker.rootNode);
|
||||
|
@ -37,12 +37,20 @@ export default {
|
||||
toggleFullscreen: getDataSelector('action', 'togglefullscreen'),
|
||||
closeGrader: getDataSelector('action', 'closegrader'),
|
||||
saveGrade: getDataSelector('action', 'savegrade'),
|
||||
selectUser: getDataSelector('action', 'select-user'),
|
||||
toggleSearch: getDataSelector('action', 'toggle-search')
|
||||
},
|
||||
regions: {
|
||||
bodyContainer: getDataSelector('region', 'body-container'),
|
||||
moduleReplace: getDataSelector('region', 'module_content'),
|
||||
pickerRegion: getDataSelector('region', 'user_picker'),
|
||||
gradingPanel: getDataSelector('region', 'grade'),
|
||||
gradingPanelContainer: getDataSelector('region', 'grading-panel-container'),
|
||||
gradingPanelErrors: getDataSelector('region', 'grade-errors'),
|
||||
searchResultsContainer: getDataSelector('region', 'search-results-container'),
|
||||
statusContainer: getDataSelector('region', 'status-container'),
|
||||
userSearchContainer: getDataSelector('region', 'user-search-container'),
|
||||
userSearchInput: getDataSelector('region', 'user-search-input')
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -79,10 +79,6 @@ class UserPicker {
|
||||
// Call the showUser function to show the first user immediately.
|
||||
await this.showUser(this.currentUser);
|
||||
|
||||
// Show a list of users under the user search box.
|
||||
await this.renderSearch(this.userList);
|
||||
|
||||
this.searchResultListener();
|
||||
// Ensure that the event listeners are all bound.
|
||||
this.registerEventListeners();
|
||||
}
|
||||
@ -123,7 +119,6 @@ class UserPicker {
|
||||
registerEventListeners() {
|
||||
this.root.addEventListener('click', async(e) => {
|
||||
const button = e.target.closest(Selectors.actions.changeUser);
|
||||
const input = e.target.closest(Selectors.actions.searchUserInput);
|
||||
|
||||
if (button) {
|
||||
const result = await this.preChangeUserCallback(this.currentUser);
|
||||
@ -133,87 +128,17 @@ class UserPicker {
|
||||
await this.showUser(this.currentUser);
|
||||
}
|
||||
}
|
||||
if (input) {
|
||||
|
||||
// Make the key up a seperate function.
|
||||
this.onKeyUp(input);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener for keyboard entry that'll search the user list for matching users.
|
||||
*
|
||||
* @param {Text} input User entered text of the user to search for.
|
||||
*/
|
||||
onKeyUp(input) {
|
||||
// Init a timeout variable to be used below
|
||||
let timeout = null;
|
||||
// Listen for keystroke events
|
||||
input.onkeyup = () => {
|
||||
// Clear the timeout if it has already been set.
|
||||
clearTimeout(timeout);
|
||||
// Make a new timeout set to go off in 300ms
|
||||
timeout = setTimeout(async(userList) => {
|
||||
const userInput = input.value;
|
||||
const results = userList.filter((user) => {
|
||||
return user.fullname.toLowerCase().includes(userInput.toLowerCase());
|
||||
});
|
||||
await this.renderSearch(results);
|
||||
this.searchResultListener();
|
||||
}, 300, this.userList);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the click handler for the users found in the user search area.
|
||||
*/
|
||||
searchResultListener() {
|
||||
this.root.querySelector(Selectors.actions.searchUserBox).addEventListener('click', async(e) => {
|
||||
e.preventDefault();
|
||||
const user = e.target.closest(Selectors.actions.selectUser);
|
||||
if (user !== null) {
|
||||
const foundUser = this.userList.findIndex(item => parseInt(item.id) === parseInt(user.dataset.userid));
|
||||
const result = await this.preChangeUserCallback(this.currentUser);
|
||||
|
||||
if (!result.failed) {
|
||||
this.updateIndex(0, parseInt(foundUser));
|
||||
await this.showUser(this.currentUser);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the user search results.
|
||||
*
|
||||
* @param {Array} results List of users
|
||||
*/
|
||||
async renderSearch(results) {
|
||||
const trimmedUsers = results.slice(0, 10);
|
||||
const overflowUsers = results.slice(10);
|
||||
const builtResults = {
|
||||
'expandedUsers': trimmedUsers,
|
||||
'hasCollapsed': overflowUsers.length > 0,
|
||||
'collapsedUsers': overflowUsers,
|
||||
};
|
||||
const {html, js} = await Templates.renderForPromise(`${templatePath}/user_picker/user_search`, builtResults);
|
||||
const searchUserRegion = this.root.querySelector(Selectors.actions.searchUserBox);
|
||||
Templates.replaceNode(searchUserRegion, html, js);
|
||||
}
|
||||
/**
|
||||
* Update the current user index.
|
||||
*
|
||||
* @param {Number} direction
|
||||
* @param {Number} specificIndex
|
||||
* @returns {Number}}
|
||||
*/
|
||||
updateIndex(direction, specificIndex = null) {
|
||||
if (specificIndex) {
|
||||
this.currentUserIndex = specificIndex;
|
||||
} else {
|
||||
this.currentUserIndex += direction;
|
||||
}
|
||||
updateIndex(direction) {
|
||||
this.currentUserIndex += direction;
|
||||
|
||||
// Loop around the edges.
|
||||
if (this.currentUserIndex < 0) {
|
||||
|
@ -28,9 +28,6 @@ export default {
|
||||
},
|
||||
actions: {
|
||||
changeUser: '[data-action="change-user"]',
|
||||
selectUser: '[data-action="select-user"]',
|
||||
searchUserBox: '[data-action="search-user-box"]',
|
||||
searchUserInput: '[data-action="search-user-input"]',
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -91,7 +91,7 @@ class forum_gradeitem extends component_gradeitem {
|
||||
* @return bool
|
||||
*/
|
||||
public function is_grading_enabled(): bool {
|
||||
return $this->forum->get_grade_for_forum() !== 0;
|
||||
return $this->forum->is_grading_enabled();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -363,6 +363,15 @@ class forum {
|
||||
return $this->gradeforum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether grading is enabled for this item.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_grading_enabled(): bool {
|
||||
return $this->get_grade_for_forum() !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum bytes.
|
||||
*
|
||||
|
@ -65,6 +65,7 @@ class forum extends exporter {
|
||||
'state' => [
|
||||
'type' => [
|
||||
'groupmode' => ['type' => PARAM_INT],
|
||||
'gradingenabled' => ['type' => PARAM_BOOL],
|
||||
],
|
||||
],
|
||||
'userstate' => [
|
||||
@ -77,6 +78,7 @@ class forum extends exporter {
|
||||
'viewdiscussions' => ['type' => PARAM_BOOL],
|
||||
'create' => ['type' => PARAM_BOOL],
|
||||
'subscribe' => ['type' => PARAM_BOOL],
|
||||
'grade' => ['type' => PARAM_BOOL],
|
||||
]
|
||||
],
|
||||
'urls' => [
|
||||
@ -120,6 +122,7 @@ class forum extends exporter {
|
||||
'name' => $this->forum->get_name(),
|
||||
'state' => [
|
||||
'groupmode' => $this->forum->get_effective_group_mode(),
|
||||
'gradingenabled' => $this->forum->is_grading_enabled()
|
||||
],
|
||||
'userstate' => [
|
||||
'tracked' => forum_tp_is_tracked($this->get_forum_record(), $this->related['user']),
|
||||
@ -129,6 +132,7 @@ class forum extends exporter {
|
||||
'create' => $capabilitymanager->can_create_discussions($user, $currentgroup),
|
||||
'selfenrol' => $capabilitymanager->can_self_enrol($user),
|
||||
'subscribe' => $capabilitymanager->can_subscribe_to_forum($user),
|
||||
'grade' => $capabilitymanager->can_grade($user),
|
||||
],
|
||||
'urls' => [
|
||||
'create' => $urlfactory->get_discussion_create_url($this->forum)->out(false),
|
||||
|
@ -144,12 +144,22 @@ class discussion_list {
|
||||
* @param int $sortorder The sort order to use when selecting the discussions in the list
|
||||
* @param int $pageno The zero-indexed page number to use
|
||||
* @param int $pagesize The number of discussions to show on the page
|
||||
* @param int $displaymode The discussion display mode
|
||||
* @return string The rendered content for display
|
||||
*/
|
||||
public function render(stdClass $user, \cm_info $cm, ?int $groupid, ?int $sortorder, ?int $pageno, ?int $pagesize) : string {
|
||||
public function render(
|
||||
stdClass $user,
|
||||
\cm_info $cm,
|
||||
?int $groupid,
|
||||
?int $sortorder,
|
||||
?int $pageno,
|
||||
?int $pagesize,
|
||||
int $displaymode = null
|
||||
) : string {
|
||||
global $PAGE;
|
||||
|
||||
$forum = $this->forum;
|
||||
$course = $forum->get_course_record();
|
||||
|
||||
$forumexporter = $this->exporterfactory->get_forum_exporter(
|
||||
$user,
|
||||
@ -176,6 +186,10 @@ class discussion_list {
|
||||
'forum' => (array) $forumexporter->export($this->renderer),
|
||||
'contextid' => $forum->get_context()->id,
|
||||
'cmid' => $cm->id,
|
||||
'name' => $forum->get_name(),
|
||||
'courseid' => $course->id,
|
||||
'coursename' => $course->shortname,
|
||||
'experimentaldisplaymode' => $displaymode == FORUM_MODE_NESTED_V2,
|
||||
'gradingcomponent' => $this->forumgradeitem->get_grading_component_name(),
|
||||
'gradingcomponentsubtype' => $this->forumgradeitem->get_grading_component_subtype(),
|
||||
'hasanyactions' => $hasanyactions,
|
||||
|
@ -2205,8 +2205,15 @@ class mod_forum_external extends external_api {
|
||||
$managerfactory = mod_forum\local\container::get_manager_factory();
|
||||
$capabilitymanager = $managerfactory->get_capability_manager($forum);
|
||||
|
||||
$discussionvault = $vaultfactory->get_discussion_vault();
|
||||
$discussions = $discussionvault->get_all_discussions_in_forum($forum, 'timemodified ASC, id ASC');
|
||||
$discussionsummariesvault = $vaultfactory->get_discussions_in_forum_vault();
|
||||
$discussionsummaries = $discussionsummariesvault->get_from_forum_id(
|
||||
$forum->get_id(),
|
||||
true,
|
||||
null,
|
||||
$discussionsummariesvault::SORTORDER_CREATED_ASC,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$postvault = $vaultfactory->get_post_vault();
|
||||
|
||||
@ -2214,7 +2221,8 @@ class mod_forum_external extends external_api {
|
||||
$postbuilder = $builderfactory->get_exported_posts_builder();
|
||||
|
||||
$builtdiscussions = [];
|
||||
foreach ($discussions as $id => $discussion) {
|
||||
foreach ($discussionsummaries as $discussionsummary) {
|
||||
$discussion = $discussionsummary->get_discussion();
|
||||
$posts = $postvault->get_posts_in_discussion_for_user_id(
|
||||
$discussion->get_id(),
|
||||
$user->id,
|
||||
@ -2239,9 +2247,14 @@ class mod_forum_external extends external_api {
|
||||
);
|
||||
}
|
||||
|
||||
$discussionauthor = $discussionsummary->get_first_post_author();
|
||||
$firstpost = $discussionsummary->get_first_post();
|
||||
|
||||
$builtdiscussions[] = [
|
||||
'name' => $discussion->get_name(),
|
||||
'id' => $discussion->get_id(),
|
||||
'timecreated' => $firstpost->get_time_created(),
|
||||
'authorfullname' => $discussionauthor->get_full_name(),
|
||||
'posts' => [
|
||||
'userposts' => $postbuilder->build($user, [$forum], [$discussion], $posts),
|
||||
'parentposts' => $parentposts,
|
||||
@ -2284,6 +2297,8 @@ class mod_forum_external extends external_api {
|
||||
new external_single_structure([
|
||||
'name' => new external_value(PARAM_RAW, 'Name of the discussion'),
|
||||
'id' => new external_value(PARAM_INT, 'ID of the discussion'),
|
||||
'timecreated' => new external_value(PARAM_INT, 'Timestamp of the discussion start'),
|
||||
'authorfullname' => new external_value(PARAM_RAW, 'Full name of the user that started the discussion'),
|
||||
'posts' => new external_single_structure([
|
||||
'userposts' => new external_multiple_structure(\mod_forum\local\exporters\post::get_read_structure()),
|
||||
'parentposts' => new external_multiple_structure(\mod_forum\local\exporters\post::get_read_structure()),
|
||||
|
@ -101,6 +101,7 @@ $string['clicktounsubscribe'] = 'You are subscribed to this discussion. Click to
|
||||
$string['clicktosubscribe'] = 'You are not subscribed to this discussion. Click to subscribe.';
|
||||
$string['clicktounfavourite'] = 'You have starred this discussion. Click to unstar.';
|
||||
$string['clicktofavourite'] = 'You have not starred this discussion. Click to star.';
|
||||
$string['close'] = 'Close';
|
||||
$string['completiondiscussions'] = 'Student must create discussions:';
|
||||
$string['completiondiscussionsdesc'] = 'Student must create at least {$a} discussion(s)';
|
||||
$string['completiondiscussionsgroup'] = 'Require discussions';
|
||||
@ -194,6 +195,7 @@ $string['discussionsubscription'] = 'Discussion subscription';
|
||||
$string['discussionsubscription_help'] = 'Subscribing to a discussion means you will receive notifications of new posts to that discussion.';
|
||||
$string['discussions'] = 'Discussions';
|
||||
$string['discussionsstartedby'] = 'Discussions started by {$a}';
|
||||
$string['discussionstartedby'] = 'Discussion started by {$a}';
|
||||
$string['discussionsstartedbyrecent'] = 'Discussions recently started by {$a}';
|
||||
$string['discussionsstartedbyuserincourse'] = 'Discussions started by {$a->fullname} in {$a->coursename}';
|
||||
$string['discussionunpin'] = 'Unpin';
|
||||
@ -333,7 +335,9 @@ $string['generalforum'] = 'Standard forum for general use';
|
||||
$string['generalforums'] = 'General forums';
|
||||
$string['gradeitem:forum'] = 'Forum';
|
||||
$string['hiddenforumpost'] = 'Hidden forum post';
|
||||
$string['hidegraderpanel'] = 'Hide grader panel';
|
||||
$string['hidepreviousrepliescount'] = 'Hide previous replies ({$a})';
|
||||
$string['hideusersearch'] = 'Hide user search';
|
||||
$string['indicator:cognitivedepth'] = 'Forum cognitive';
|
||||
$string['indicator:cognitivedepth_help'] = 'This indicator is based on the cognitive depth reached by the student in a Forum activity.';
|
||||
$string['indicator:cognitivedepthdef'] = 'Forum cognitive';
|
||||
@ -345,6 +349,7 @@ $string['indicator:socialbreadthdef'] = 'Forum social';
|
||||
$string['indicator:socialbreadthdef_help'] = 'The participant has reached this percentage of the social engagement offered by the Forum activities during this analysis interval (Levels = No participation, Participant alone, Participant with others)';
|
||||
$string['indicator:socialbreadthdef_link'] = 'Learning_analytics_indicators#Social_breadth';
|
||||
$string['starredonly'] = 'Search starred discussions only';
|
||||
$string['indexoutoftotal'] = '{$a->index} out of {$a->total}';
|
||||
$string['inforum'] = 'in {$a}';
|
||||
$string['inreplyto'] = 'In reply to {$a}';
|
||||
$string['introblog'] = 'The posts in this forum were copied here automatically from blogs of users in this course because those blog entries are no longer available';
|
||||
@ -436,6 +441,7 @@ $string['namenews_help'] = 'The course announcements forum is a special forum fo
|
||||
$string['namesocial'] = 'Social forum';
|
||||
$string['nameteacher'] = 'Teacher forum';
|
||||
$string['nextdiscussiona'] = 'Next discussion: {$a}';
|
||||
$string['nextuser'] = 'Next user';
|
||||
$string['newforumposts'] = 'New forum posts';
|
||||
$string['noattachments'] = 'There are no attachments to this post';
|
||||
$string['nodiscussions'] = 'There are no discussion topics yet in this forum';
|
||||
@ -514,6 +520,7 @@ $string['poststo'] = 'Posts to';
|
||||
$string['posttoforum'] = 'Post to forum';
|
||||
$string['postupdated'] = 'Your post was updated';
|
||||
$string['potentialsubscribers'] = 'Potential subscribers';
|
||||
$string['previoususer'] = 'Previous user';
|
||||
$string['privacy:digesttypenone'] = 'We do not hold any data relating to a preferred forum digest type for this forum.';
|
||||
$string['privacy:digesttypepreference'] = 'You have chosen to receive the following forum digest type: "{$a->type}".';
|
||||
$string['privacy:discussionsubscriptionpreference'] = 'You have chosen the following discussion subscription preference for this forum: "{$a->preference}"';
|
||||
@ -627,6 +634,7 @@ $string['searchresults'] = 'Search results';
|
||||
$string['searchsubject'] = 'These words should be in the subject';
|
||||
$string['searchtags'] = 'Is tagged with';
|
||||
$string['searchuser'] = 'This name should match the author';
|
||||
$string['searchusers'] = 'Search users';
|
||||
$string['searchuserid'] = 'The Moodle ID of the author';
|
||||
$string['searchwhichforums'] = 'Choose which forums to search';
|
||||
$string['searchwords'] = 'These words can appear anywhere in the post';
|
||||
@ -634,8 +642,10 @@ $string['seeallposts'] = 'See all posts made by this user';
|
||||
$string['settings'] = 'Settings';
|
||||
$string['shortpost'] = 'Short post';
|
||||
$string['showingcountoftotaldiscussions'] = 'Showing {$a->count} of {$a->total} discussions';
|
||||
$string['showgraderpanel'] = 'Show grader panel';
|
||||
$string['showpreviousrepliescount'] = 'Show previous replies ({$a})';
|
||||
$string['showsubscribers'] = 'Show/edit current subscribers';
|
||||
$string['showusersearch'] = 'Show user search';
|
||||
$string['singleforum'] = 'A single simple discussion';
|
||||
$string['smallmessage'] = '{$a->user} posted in {$a->forumname}';
|
||||
$string['smallmessagedigest'] = 'Forum digest containing {$a} messages';
|
||||
@ -677,6 +687,7 @@ $string['timedhidden'] = 'Timed status: Hidden from students';
|
||||
$string['timedposts'] = 'Timed posts';
|
||||
$string['timedvisible'] = 'Timed status: Visible to all users';
|
||||
$string['timestartenderror'] = 'Display end date cannot be earlier than the start date';
|
||||
$string['togglefullscreen'] = 'Toggle full screen';
|
||||
$string['togglesettingsdrawer'] = 'Toggle settings drawer';
|
||||
$string['trackforum'] = 'Track unread posts';
|
||||
$string['trackreadposts_header'] = 'Forum tracking';
|
||||
@ -710,8 +721,10 @@ $string['unsubscribed'] = 'Unsubscribed';
|
||||
$string['unsubscribeshort'] = 'Unsubscribe';
|
||||
$string['useexperimentalui'] = 'Use experimental nested discussion view';
|
||||
$string['usermarksread'] = 'Manual message read marking';
|
||||
$string['usernavigation'] = 'User navigation';
|
||||
$string['unpindiscussion'] = 'Unpin this discussion';
|
||||
$string['viewalldiscussions'] = 'View all discussions';
|
||||
$string['viewparentpost'] = 'View parent post';
|
||||
$string['viewthediscussion'] = 'View the discussion';
|
||||
$string['warnafter'] = 'Post threshold for warning';
|
||||
$string['warnafter_help'] = 'Students can be warned as they approach the maximum number of posts allowed in a given period. This setting specifies after how many posts they are warned. Users with the capability mod/forum:postwithoutthrottling are exempt from post limits.';
|
||||
|
BIN
mod/forum/pix/hide-grader-panel.png
Normal file
After Width: | Height: | Size: 585 B |
24
mod/forum/pix/hide-grader-panel.svg
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="23px" height="24px" viewBox="0 0 23 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>Group 3</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Grading" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Grading-Copy-4" transform="translate(-1072.000000, -21.000000)">
|
||||
<g id="Group-3" transform="translate(1072.000000, 21.500000)">
|
||||
<g id="left-arrow" transform="translate(0.000000, 6.795455)" fill="#000000" fill-rule="nonzero">
|
||||
<path d="M9.86688101,3.53622875 L9.8832003,3.5397986 L2.88749446,3.5397986 L5.08668884,1.33575942 C5.19437916,1.2281541 5.25345159,1.08238544 5.25345159,0.929392092 C5.25345159,0.776398744 5.19437916,0.631650037 5.08668884,0.523789727 L4.74449372,0.181424612 C4.6368884,0.0738192905 4.49349963,0.0143218773 4.34059128,0.0143218773 C4.18759793,0.0143218773 4.04412417,0.0733943089 3.93651885,0.18099963 L0.166677753,3.95050074 C0.0586474501,4.05853104 -0.000424981523,4.20242979 -2.27716707e-06,4.35550813 C-0.000424981523,4.50943644 0.0586474501,4.65342018 0.166677753,4.76128049 L3.93651885,8.53112158 C4.04412417,8.63864191 4.18751293,8.69779933 4.34059128,8.69779933 C4.49349963,8.69779933 4.6368884,8.63855691 4.74449372,8.53112158 L5.08668884,8.18875647 C5.19437916,8.08132114 5.25345159,7.93784738 5.25345159,7.78485403 C5.25345159,7.63194568 5.19437916,7.49603659 5.08668884,7.38851626 L2.86267554,5.17215262 L9.87470067,5.17215262 C10.189782,5.17215262 10.4545455,4.90058943 10.4545455,4.58567812 L10.4545455,4.10145418 C10.4545455,3.78654287 10.1819623,3.53622875 9.86688101,3.53622875 Z" id="Path"></path>
|
||||
</g>
|
||||
<g id="left-arrow" transform="translate(17.772727, 11.151515) rotate(180.000000) translate(-17.772727, -11.151515) translate(12.545455, 6.795455)" fill="#000000" fill-rule="nonzero">
|
||||
<path d="M9.86688101,3.53622875 L9.8832003,3.5397986 L2.88749446,3.5397986 L5.08668884,1.33575942 C5.19437916,1.2281541 5.25345159,1.08238544 5.25345159,0.929392092 C5.25345159,0.776398744 5.19437916,0.631650037 5.08668884,0.523789727 L4.74449372,0.181424612 C4.6368884,0.0738192905 4.49349963,0.0143218773 4.34059128,0.0143218773 C4.18759793,0.0143218773 4.04412417,0.0733943089 3.93651885,0.18099963 L0.166677753,3.95050074 C0.0586474501,4.05853104 -0.000424981523,4.20242979 -2.27716707e-06,4.35550813 C-0.000424981523,4.50943644 0.0586474501,4.65342018 0.166677753,4.76128049 L3.93651885,8.53112158 C4.04412417,8.63864191 4.18751293,8.69779933 4.34059128,8.69779933 C4.49349963,8.69779933 4.6368884,8.63855691 4.74449372,8.53112158 L5.08668884,8.18875647 C5.19437916,8.08132114 5.25345159,7.93784738 5.25345159,7.78485403 C5.25345159,7.63194568 5.19437916,7.49603659 5.08668884,7.38851626 L2.86267554,5.17215262 L9.87470067,5.17215262 C10.189782,5.17215262 10.4545455,4.90058943 10.4545455,4.58567812 L10.4545455,4.10145418 C10.4545455,3.78654287 10.1819623,3.53622875 9.86688101,3.53622875 Z" id="Path"></path>
|
||||
</g>
|
||||
<g id="Group-2" transform="translate(0.522727, 0.000000)" stroke="#000000" stroke-linecap="square" stroke-width="2">
|
||||
<path d="M0.522727273,0.522727273 L21.4318182,0.522727273 M0.522727273,0.522727273 L0.522727273,3.13636364 M21.4318182,0.522727273 L21.4318182,3.13636364" id="Combined-Shape"></path>
|
||||
</g>
|
||||
<g id="Group-2" transform="translate(11.500000, 21.431818) scale(1, -1) translate(-11.500000, -21.431818) translate(0.522727, 19.863636)" stroke="#000000" stroke-linecap="square" stroke-width="2">
|
||||
<path d="M0.522727273,0.522727273 L21.4318182,0.522727273 M0.522727273,0.522727273 L0.522727273,3.13636364 M21.4318182,0.522727273 L21.4318182,3.13636364" id="Combined-Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
BIN
mod/forum/pix/no-posts.png
Normal file
After Width: | Height: | Size: 25 KiB |
1
mod/forum/pix/no-posts.svg
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
mod/forum/pix/no-search-results.png
Normal file
After Width: | Height: | Size: 56 KiB |
1
mod/forum/pix/no-search-results.svg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
mod/forum/pix/show-grader-panel-rtl.png
Normal file
After Width: | Height: | Size: 595 B |
13
mod/forum/pix/show-grader-panel-rtl.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>show</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Grading" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Grading-Copy-4" transform="translate(-1070.000000, -21.000000)" fill="#000000" fill-rule="nonzero">
|
||||
<g id="show" transform="translate(1082.000000, 33.000000) rotate(180.000000) translate(-1082.000000, -33.000000) translate(1070.000000, 21.000000)">
|
||||
<path d="M3.75,13.7454044 L7.96875,13.7454044 L7.96875,15.6204044 L3.75,15.6204044 L3.75,13.7454044 Z M3.75,11.8760807 L7.96875,11.8760807 L7.96875,10.0010807 L3.75,10.0010807 L3.75,11.8760807 Z M3.75,6.39170569 L3.75,8.26670569 L7.96875,8.26670569 L7.96875,6.39170569 L3.75,6.39170569 Z M3.75,19.2297794 L7.96875,19.2297794 L7.96875,17.3547794 L3.75,17.3547794 L3.75,19.2297794 Z M24,2.8125 L24,21.1875 C24,22.7384033 22.7384033,24 21.1875,24 L2.8125,24 C1.26159666,24 0,22.7384033 0,21.1875 L0,2.8125 C0,1.26159666 1.26159666,0 2.8125,0 L21.1875,0 C22.7384033,0 24,1.26159666 24,2.8125 Z M2.8125,22.125 L9.84375,22.125 L9.84375,1.875 L2.8125,1.875 C2.29559325,1.875 1.875,2.29559325 1.875,2.8125 L1.875,21.1875 C1.875,21.7044068 2.29559325,22.125 2.8125,22.125 Z M22.125,2.8125 C22.125,2.29559325 21.7044067,1.875 21.1875,1.875 L11.71875,1.875 L11.71875,10.921875 L16.7678833,10.921875 L14.6116333,8.765625 L15.9375,7.43975831 L20.3571167,11.859375 L15.9375,16.2789917 L14.6116333,14.953125 L16.7678833,12.796875 L11.71875,12.796875 L11.71875,22.125 L21.1875,22.125 C21.7044067,22.125 22.125,21.7044068 22.125,21.1875 L22.125,2.8125 Z" id="Shape" transform="translate(12.000000, 12.000000) scale(-1, 1) translate(-12.000000, -12.000000) "></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
BIN
mod/forum/pix/show-grader-panel.png
Normal file
After Width: | Height: | Size: 612 B |
13
mod/forum/pix/show-grader-panel.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>show</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Grading" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Grading-Copy-4" transform="translate(-1028.000000, -21.000000)" fill="#000000" fill-rule="nonzero">
|
||||
<g id="show" transform="translate(1040.000000, 33.000000) rotate(180.000000) translate(-1040.000000, -33.000000) translate(1028.000000, 21.000000)">
|
||||
<path d="M3.75,13.7454044 L7.96875,13.7454044 L7.96875,15.6204044 L3.75,15.6204044 L3.75,13.7454044 Z M3.75,11.8760807 L7.96875,11.8760807 L7.96875,10.0010807 L3.75,10.0010807 L3.75,11.8760807 Z M3.75,6.39170569 L3.75,8.26670569 L7.96875,8.26670569 L7.96875,6.39170569 L3.75,6.39170569 Z M3.75,19.2297794 L7.96875,19.2297794 L7.96875,17.3547794 L3.75,17.3547794 L3.75,19.2297794 Z M24,2.8125 L24,21.1875 C24,22.7384033 22.7384033,24 21.1875,24 L2.8125,24 C1.26159666,24 0,22.7384033 0,21.1875 L0,2.8125 C0,1.26159666 1.26159666,0 2.8125,0 L21.1875,0 C22.7384033,0 24,1.26159666 24,2.8125 Z M2.8125,22.125 L9.84375,22.125 L9.84375,1.875 L2.8125,1.875 C2.29559325,1.875 1.875,2.29559325 1.875,2.8125 L1.875,21.1875 C1.875,21.7044068 2.29559325,22.125 2.8125,22.125 Z M22.125,2.8125 C22.125,2.29559325 21.7044067,1.875 21.1875,1.875 L11.71875,1.875 L11.71875,10.921875 L16.7678833,10.921875 L14.6116333,8.765625 L15.9375,7.43975831 L20.3571167,11.859375 L15.9375,16.2789917 L14.6116333,14.953125 L16.7678833,12.796875 L11.71875,12.796875 L11.71875,22.125 L21.1875,22.125 C21.7044067,22.125 22.125,21.7044068 22.125,21.1875 L22.125,2.8125 Z" id="Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
@ -49,29 +49,37 @@
|
||||
|
||||
{{{groupchangemenu}}}
|
||||
|
||||
{{#forum.capabilities.create}}
|
||||
<div class="p-t-1 p-b-1">
|
||||
|
||||
<div class="p-t-1 p-b-1">
|
||||
{{#forum.capabilities.create}}
|
||||
<a class="btn btn-primary" data-toggle="collapse" href="#collapseAddForm">
|
||||
{{$discussion_create_text}}
|
||||
{{#str}}addanewdiscussion, forum{{/str}}
|
||||
{{/discussion_create_text}}
|
||||
</a>
|
||||
<div class="collapse m-t-1" id="collapseAddForm">
|
||||
{{{newdiscussionhtml}}}
|
||||
</div>
|
||||
{{/forum.capabilities.create}}
|
||||
{{^forum.capabilities.create}}
|
||||
{{#forum.capabilities.selfenrol}}
|
||||
<div class="p-t-1 p-b-1">
|
||||
<a class="btn btn-primary" href="{{forum.urls.create}}">
|
||||
{{$discussion_create_text}}
|
||||
{{#str}}addanewdiscussion, forum{{/str}}
|
||||
{{/discussion_create_text}}
|
||||
</a>
|
||||
</div>
|
||||
{{/forum.capabilities.selfenrol}}
|
||||
{{/forum.capabilities.create}}
|
||||
{{#forum.capabilities.grade}}
|
||||
{{#forum.state.gradingenabled}}
|
||||
{{> mod_forum/grades/grade_button }}
|
||||
{{/forum.state.gradingenabled}}
|
||||
{{/forum.capabilities.grade}}
|
||||
</div>
|
||||
{{#forum.capabilities.create}}
|
||||
<div class="collapse m-t-1 p-b-1" id="collapseAddForm">
|
||||
{{{newdiscussionhtml}}}
|
||||
</div>
|
||||
{{/forum.capabilities.create}}
|
||||
{{^forum.capabilities.create}}
|
||||
{{#forum.capabilities.selfenrol}}
|
||||
<div class="p-t-1 p-b-1">
|
||||
<a class="btn btn-primary" href="{{forum.urls.create}}">
|
||||
{{$discussion_create_text}}
|
||||
{{#str}}addanewdiscussion, forum{{/str}}
|
||||
{{/discussion_create_text}}
|
||||
</a>
|
||||
</div>
|
||||
{{/forum.capabilities.selfenrol}}
|
||||
{{/forum.capabilities.create}}
|
||||
|
||||
{{#state.hasdiscussions}}
|
||||
{{$discussion_top_pagination}}
|
||||
@ -353,8 +361,4 @@
|
||||
var root = $('#discussion-list-{{uniqid}}');
|
||||
View.init(root);
|
||||
});
|
||||
|
||||
require(['mod_forum/grades/grader'], function(Grader) {
|
||||
Grader.registerLaunchListeners();
|
||||
});
|
||||
{{/js}}
|
||||
|
@ -47,7 +47,7 @@
|
||||
>
|
||||
{{#isfirstunread}}<a id="unread" aria-hidden="true"></a>{{/isfirstunread}}
|
||||
|
||||
<div class="author-image-container d-inline-block">
|
||||
<div class="author-image-container d-inline-block text-center">
|
||||
{{^isdeleted}}
|
||||
{{#author}}
|
||||
{{#urls.profileimage}}
|
||||
@ -73,7 +73,7 @@
|
||||
{{/unread}}
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column w-100" data-region-content="forum-post-core">
|
||||
<div class="forum-post-core d-flex flex-column w-100" data-region-content="forum-post-core">
|
||||
<header id="post-header-{{uniqid}}">
|
||||
{{^isdeleted}}
|
||||
<div class="d-flex flex-wrap align-items-center mb-1">
|
||||
@ -299,9 +299,11 @@
|
||||
{{/attachments}}
|
||||
|
||||
<div class="d-flex mt-3 align-items-center">
|
||||
{{#html.rating}}
|
||||
<div>{{{.}}}</div>
|
||||
{{/html.rating}}
|
||||
{{^readonly}}
|
||||
{{#html.rating}}
|
||||
<div>{{{.}}}</div>
|
||||
{{/html.rating}}
|
||||
{{/readonly}}
|
||||
<div class="ml-auto d-flex flex-column">
|
||||
{{#haswordcount}}
|
||||
<span class="ml-auto badge badge-light">
|
||||
|
@ -179,12 +179,12 @@
|
||||
{{/isimage}}
|
||||
{{/attachments}}
|
||||
|
||||
<div class="d-flex flex-wrap">
|
||||
{{#html.rating}}
|
||||
<div class="mt-2">{{{.}}}</div>
|
||||
{{/html.rating}}
|
||||
{{$actions}}
|
||||
{{^readonly}}
|
||||
{{^readonly}}
|
||||
<div class="d-flex flex-wrap">
|
||||
{{#html.rating}}
|
||||
<div class="mt-2">{{{.}}}</div>
|
||||
{{/html.rating}}
|
||||
{{$actions}}
|
||||
<div
|
||||
class="post-actions d-flex align-self-end justify-content-end flex-wrap ml-auto"
|
||||
data-region="post-actions-container"
|
||||
@ -303,9 +303,9 @@
|
||||
{{/export}}
|
||||
{{/capabilities}}
|
||||
</div>
|
||||
{{/readonly}}
|
||||
{{/actions}}
|
||||
</div>
|
||||
{{/actions}}
|
||||
</div>
|
||||
{{/readonly}}
|
||||
|
||||
{{$footer}}{{/footer}}
|
||||
{{/isdeleted}}
|
||||
|
@ -29,13 +29,25 @@
|
||||
{
|
||||
}
|
||||
}}
|
||||
<a class="btn btn-primary" href="" data-grade-action="launch" {{!
|
||||
}}data-contextid="{{contextid}}" {{!
|
||||
}}data-cmid="{{cmid}}" {{!
|
||||
}}data-name="{{name}}" {{!
|
||||
}}data-group="{{groupid}}" {{!
|
||||
}}data-grading-component="{{gradingcomponent}}" {{!
|
||||
}}data-grading-component-subtype="{{gradingcomponentsubtype}}" {{!
|
||||
}}data-gradable-itemtype="forum" {{!
|
||||
}}{{#firstgradeduserid}}data-initialuserid="{{firstgradeduserid}}" {{/firstgradeduserid}}{{!
|
||||
}}>{{#str}}gradeusers, forum{{/str}}</a>
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
type="button"
|
||||
data-grade-action="launch"
|
||||
data-contextid="{{contextid}}"
|
||||
data-cmid="{{cmid}}"
|
||||
data-name="{{name}}"
|
||||
data-course-id="{{courseid}}"
|
||||
data-course-name="{{coursename}}"
|
||||
data-experimental-display-mode="{{experimentaldisplaymode}}"
|
||||
data-group="{{groupid}}"
|
||||
data-grading-component="{{gradingcomponent}}"
|
||||
data-grading-component-subtype="{{gradingcomponentsubtype}}"
|
||||
data-gradable-itemtype="forum"
|
||||
>
|
||||
{{#str}}gradeusers, forum{{/str}}
|
||||
</button>
|
||||
{{#js}}
|
||||
require(['mod_forum/grades/grader'], function(Grader) {
|
||||
Grader.registerLaunchListeners();
|
||||
});
|
||||
{{/js}}
|
||||
|
@ -29,8 +29,9 @@
|
||||
{
|
||||
}
|
||||
}}
|
||||
<div data-region="posts-modal">
|
||||
{{#.}}
|
||||
{{> mod_forum/forum_discussion_nested_v2_post_reply }}
|
||||
{{/.}}
|
||||
<div class="{{#experimentaldisplaymode}}nested-v2-display-mode{{/experimentaldisplaymode}}" data-region="posts-modal">
|
||||
{{#posts}}
|
||||
{{#experimentaldisplaymode}}{{> mod_forum/forum_discussion_nested_v2_first_post }}{{/experimentaldisplaymode}}
|
||||
{{^experimentaldisplaymode}}{{> mod_forum/forum_discussion_nested_post }}{{/experimentaldisplaymode}}
|
||||
{{/posts}}
|
||||
</div>
|
||||
|
@ -29,48 +29,68 @@
|
||||
{
|
||||
}
|
||||
}}
|
||||
<div data-region="posts" id="post-region-{{uniqid}}">
|
||||
<div
|
||||
class="{{#experimentaldisplaymode}}nested-v2-display-mode{{/experimentaldisplaymode}}"
|
||||
data-region="posts"
|
||||
id="post-region-{{uniqid}}"
|
||||
>
|
||||
{{#discussions}}
|
||||
<div class="hr-sect mt-0">{{name}}</div>
|
||||
{{#posts}}
|
||||
{{#parent}}
|
||||
{{> mod_forum/forum_discussion_nested_v2_post_reply }}
|
||||
{{/parent}}
|
||||
{{#starter}}
|
||||
{{> mod_forum/forum_discussion_nested_v2_first_post }}
|
||||
<a class="btn btn-outline-dark"
|
||||
role="button"
|
||||
data-action="view-context"
|
||||
data-discussionid="{{discussionid}}"
|
||||
data-postid="{{id}}"
|
||||
data-name="{{name}}"
|
||||
href="#">
|
||||
{{#str}} viewconversation, forum {{/str}}
|
||||
</a>
|
||||
{{/starter}}
|
||||
{{^starter}}
|
||||
<div class="forum-post-container" data-region="replies-container">
|
||||
<div class="indent replies-container" data-region="replies-container">
|
||||
<div class="indent replies-container" data-region="replies-container">
|
||||
{{> mod_forum/forum_discussion_nested_v2_post_reply }}
|
||||
<a class="btn btn-outline-dark"
|
||||
role="button"
|
||||
data-action="view-context"
|
||||
data-discussionid="{{discussionid}}"
|
||||
data-postid="{{id}}"
|
||||
data-name="{{name}}"
|
||||
href="#">
|
||||
<div class="discussion-container">
|
||||
<div class="p-4">
|
||||
<h3 class="d-inline-block m-0 h6 font-weight-bold">{{#str}} discussionstartedby, mod_forum, {{authorfullname}} {{/str}}</h3>
|
||||
<p class="d-inline-block m-0 h6 font-weight-normal text-muted ml-1">
|
||||
{{#userdate}} {{timecreated}}, {{#str}} strftimedate, core_langconfig {{/str}} {{/userdate}}
|
||||
</p>
|
||||
<h2 class="mb-4 font-weight-bold">{{name}}</h2>
|
||||
|
||||
{{#posts}}
|
||||
<div class="posts-container">
|
||||
{{#parent}}
|
||||
<div class="parent-container">
|
||||
<button
|
||||
class="btn btn-link show-content-button collapsed"
|
||||
data-target="#parent-post-content-{{id}}"
|
||||
aria-expanded="false"
|
||||
aria-controls="parent-post-content-{{id}}"
|
||||
data-toggle="collapse"
|
||||
>
|
||||
{{#str}} viewparentpost, mod_forum {{/str}}
|
||||
</button>
|
||||
<div id="parent-post-content-{{id}}" class="content collapse">
|
||||
{{#experimentaldisplaymode}}{{> mod_forum/forum_discussion_nested_v2_first_post }}{{/experimentaldisplaymode}}
|
||||
{{^experimentaldisplaymode}}{{> mod_forum/forum_discussion_nested_post }}{{/experimentaldisplaymode}}
|
||||
</div>
|
||||
</div>
|
||||
{{/parent}}
|
||||
{{#post}}
|
||||
<div class="post-container">
|
||||
{{#experimentaldisplaymode}}{{> mod_forum/forum_discussion_nested_v2_first_post }}{{/experimentaldisplaymode}}
|
||||
{{^experimentaldisplaymode}}{{> mod_forum/forum_discussion_nested_post }}{{/experimentaldisplaymode}}
|
||||
</div>
|
||||
<button
|
||||
class="view-context-button btn btn-link border"
|
||||
type="button"
|
||||
data-action="view-context"
|
||||
data-discussionid="{{discussionid}}"
|
||||
data-postid="{{id}}"
|
||||
data-name="{{name}}"
|
||||
data-experimental-display-mode="{{experimentaldisplaymode}}"
|
||||
>
|
||||
{{#str}} viewconversation, forum {{/str}}
|
||||
</a>
|
||||
</div>
|
||||
</button>
|
||||
{{/post}}
|
||||
<hr class="w-75 mx-auto my-5">
|
||||
</div>
|
||||
</div>
|
||||
{{/starter}}
|
||||
{{/posts}}
|
||||
</div>
|
||||
<hr>
|
||||
{{/posts}}
|
||||
</div>
|
||||
{{/discussions}}
|
||||
{{^discussions}}
|
||||
<h3>{{#str}} noposts, forum {{/str}}</h3>
|
||||
<div class="no-post-container text-center p-5">
|
||||
{{#pix}} no-posts, mod_forum {{/pix}}
|
||||
<h2 class="mt-3 font-weight-bold">{{#str}} noposts, mod_forum {{/str}}</h2>
|
||||
</div>
|
||||
{{/discussions}}
|
||||
</div>
|
||||
{{#js}}
|
||||
|
@ -34,16 +34,41 @@
|
||||
"cmid": 1337
|
||||
}
|
||||
}}
|
||||
<div class="container-fluid"
|
||||
<div
|
||||
id="grader-container-{{uniqid}}"
|
||||
class="d-flex flex-column h-100 unified-grader"
|
||||
data-region="unified-grader"
|
||||
{{#userid}}data-first-userid="{{userid}}"{{/userid}}
|
||||
{{#userid}}data-first-userid="{{.}}"{{/userid}}
|
||||
data-cmid="{{cmid}}"
|
||||
>
|
||||
<div class="row-fluid">
|
||||
{{> mod_forum/local/grades/local/grader/navigation }}
|
||||
</div>
|
||||
<div class="row-fluid no-gutters">
|
||||
>
|
||||
{{> mod_forum/local/grades/local/grader/navigation }}
|
||||
|
||||
<div class="d-flex flex-grow-1 h-100 position-relative">
|
||||
{{#drawer}}{{> mod_forum/local/grades/local/grader/grading }}{{/drawer}}
|
||||
{{> mod_forum/local/grades/local/grader/content }}
|
||||
{{> mod_forum/local/grades/local/grader/grading }}
|
||||
</div>
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['jquery', 'core/drawer'], function($, Drawer) {
|
||||
var root = $('#grader-container-{{uniqid}}');
|
||||
var drawer = root.find('[data-region="right-hand-drawer"]');
|
||||
var expandButtons = root.find('[data-action="expand-grading-drawer"]');
|
||||
var collapseButtons = root.find('[data-action="collapse-grading-drawer"]');
|
||||
|
||||
expandButtons.click(function() {
|
||||
collapseButtons.removeClass('active');
|
||||
expandButtons.addClass('active');
|
||||
collapseButtons.attr('aria-expanded', true);
|
||||
expandButtons.attr('aria-expanded', true);
|
||||
Drawer.show(drawer);
|
||||
});
|
||||
|
||||
collapseButtons.click(function() {
|
||||
expandButtons.removeClass('active');
|
||||
collapseButtons.addClass('active');
|
||||
collapseButtons.attr('aria-expanded', false);
|
||||
expandButtons.attr('aria-expanded', false);
|
||||
Drawer.hide(drawer);
|
||||
});
|
||||
});
|
||||
{{/js}}
|
||||
|
@ -30,6 +30,8 @@
|
||||
{
|
||||
}
|
||||
}}
|
||||
<div class="grader-module-content col-sm-12 col-md-8 mb-3">
|
||||
<div data-region="module_content" class="grader-module-content-display col-sm-12"></div>
|
||||
<div class="grader-module-content w-100 h-100">
|
||||
<div data-region="module_content" class="grader-module-content-display">
|
||||
{{> mod_forum/local/grades/local/grader/module_content_placeholder }}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,14 +30,227 @@
|
||||
{
|
||||
}
|
||||
}}
|
||||
<div class="bg-pulse-grey w-25" style="height: 20px;"></div>
|
||||
<div class="bg-pulse-grey w-50 mt-1" style="height: 25px;"></div>
|
||||
|
||||
<div class="bg-pulse-grey w-25 mt-3" style="height: 20px;"></div>
|
||||
<div class="bg-pulse-grey w-50 mt-1" style="height: 25px;"></div>
|
||||
|
||||
<div class="bg-pulse-grey w-25 mt-3" style="height: 20px;"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-1" style="height: 25px;"></div>
|
||||
|
||||
<div class="bg-pulse-grey w-25 mt-3" style="height: 20px;"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-1" style="height: 25px;"></div>
|
||||
<div class="d-flex flex-column mb-3">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 36px">
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto mr-2" style="height: 16px; width: 16px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bg-pulse-grey mb-2" style="height: 22px; width: 150px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column mb-3">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 36px">
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto mr-2" style="height: 16px; width: 16px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bg-pulse-grey mb-2" style="height: 22px; width: 150px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column mb-3">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 36px">
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto mr-2" style="height: 16px; width: 16px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bg-pulse-grey mb-2" style="height: 22px; width: 150px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column mb-3">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 36px">
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto mr-2" style="height: 16px; width: 16px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bg-pulse-grey mb-2" style="height: 22px; width: 150px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column mb-3">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 36px">
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto mr-2" style="height: 16px; width: 16px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bg-pulse-grey mb-2" style="height: 22px; width: 150px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column mb-3">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 36px">
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto mr-2" style="height: 16px; width: 16px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bg-pulse-grey mb-2" style="height: 22px; width: 150px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column mb-3">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 36px">
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto mr-2" style="height: 16px; width: 16px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2" style="height: 22px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-1" style="height: 16px; width: 16px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 19px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey ml-auto" style="height: 19px; width: 50px"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bg-pulse-grey mb-2" style="height: 22px; width: 150px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -32,24 +32,76 @@
|
||||
{
|
||||
}
|
||||
}}
|
||||
<div class="grader-grading-panel border-left border-secondary col-md-4">
|
||||
<div class="col-md-12 bg-light px-2 py-3 mb-3">
|
||||
<!--TODO Manipulate grader panel-->
|
||||
<h4 class="d-inline font-weight-bold mb-0 fa fa-arrow-right" aria-label="Open or close grader panel" data-action="expandgrader"></h4>
|
||||
|
||||
<h4 class="d-inline font-weight-bold mb-0">{{#str}}grading, mod_forum{{/str}}</h4>
|
||||
</div>
|
||||
<div data-region="user_picker">
|
||||
{{> mod_forum/local/grades/local/grader/user_picker_placeholder }}
|
||||
<hr/>
|
||||
</div>
|
||||
<div class="grader-grading-panel-display col-sm-12">
|
||||
<h4 class="d-inline mb-0 fa fa-star-o"></h4>
|
||||
<h4 class="d-inline mb-0 ">{{#str}}grade, core_grades{{/str}}</h4>
|
||||
<div data-region="grade" class="col-md-12 mt-3">
|
||||
{{> mod_forum/local/grades/local/grader/grade_placeholder }}
|
||||
{{<core/drawer}}
|
||||
{{$drawerclasses}}grader-grading-panel flex-shrink-0{{/drawerclasses}}
|
||||
{{$drawercontent}}
|
||||
<div class="h-100 w-100 bg-white d-flex flex-column">
|
||||
<div class="flex-shrink-0 d-flex flex-column">
|
||||
<div class="header-container bg-light">
|
||||
<div
|
||||
id="searchbox-{{uniqid}}"
|
||||
class="user-search-container d-flex flex-grow-1 align-items-center collapsed"
|
||||
data-region="user-search-container"
|
||||
>
|
||||
<div class="search-input-container w-100">
|
||||
<span class="search-icon icon-no-margin d-flex align-items-center justify-content-center">
|
||||
{{#pix}} i/search, core {{/pix}}
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
data-region="user-search-input"
|
||||
class="form-control form-control-lg"
|
||||
placeholder="{{#str}} searchusers, mod_forum {{/str}}"
|
||||
>
|
||||
<button
|
||||
class="toggle-search-button btn btn-icon icon-no-margin"
|
||||
aria-expanded="false"
|
||||
aria-controls="searchbox-{{uniqid}}"
|
||||
data-action="toggle-search"
|
||||
>
|
||||
<div class="expanded-icon">
|
||||
<span aria-hidden="true">{{#pix}} e/cancel, core, {{#str}} hideusersearch, mod_forum {{/str}} {{/pix}}</span>
|
||||
<span class="sr-only">{{#str}} hideusersearch, mod_forum {{/str}}</span>
|
||||
</div>
|
||||
<div class="collapsed-icon">
|
||||
<span aria-hidden="true">{{#pix}} i/search, core, {{#str}} showusersearch, mod_forum {{/str}} {{/pix}}</span>
|
||||
<span class="sr-only">{{#str}} showusersearch, mod_forum {{/str}}</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-container d-flex align-items-center">
|
||||
<button
|
||||
class="btn btn-icon icon-size-3 icon-no-margin colour-inherit"
|
||||
data-action="collapse-grading-drawer"
|
||||
aria-controls="grading-drawer"
|
||||
aria-expanded="true"
|
||||
title="{{#str}} closebuttontitle, core {{/str}}"
|
||||
>
|
||||
<span class="dir-ltr-hide">{{#pix}} t/left, core {{/pix}}</span>
|
||||
<span class="dir-rtl-hide">{{#pix}} t/right, core {{/pix}}</span>
|
||||
</button>
|
||||
<div class="ml-auto mr-auto text-center" data-region="status-container">
|
||||
{{> mod_forum/local/grades/local/grader/status_placeholder }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-bottom px-3 pt-2" data-region="user_picker">
|
||||
{{> mod_forum/local/grades/local/grader/user_picker_placeholder }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-container position-relative d-flex flex-column overflow-auto" data-region="body-container">
|
||||
<div class="grader-grading-panel-display pt-3 overflow-auto" data-region="grading-panel-container">
|
||||
<h4 class="mb-0 h5 px-3 font-weight-normal">
|
||||
{{#pix}} i/grading, core {{/pix}}{{#str}} gradingmodulename, core_grades, {{moduleName}} {{/str}}
|
||||
</h4>
|
||||
<div data-region="grade" class="pt-3 px-3">
|
||||
{{> mod_forum/local/grades/local/grader/grade_placeholder }}
|
||||
</div>
|
||||
<div data-region="grade-errors" role="alert" aria-role="assertive"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden overflow-auto" data-region="search-results-container"></div>
|
||||
</div>
|
||||
<div data-region="grade-errors" role="alert" aria-role="assertive"></div>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
{{/drawercontent}}
|
||||
{{/core/drawer}}
|
||||
|
@ -0,0 +1,170 @@
|
||||
{{!
|
||||
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 mod_forum/local/grades/local/grader/module_content_placeholder
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
*
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
}}
|
||||
<div class="p-4">
|
||||
<div class="d-inline-block bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
|
||||
<div class="d-inline-block bg-pulse-grey ml-1 mb-1" style="height: 18px; width: 100px"></div>
|
||||
<div class="bg-pulse-grey mb-4" style="height: 36px; width: 500px"></div>
|
||||
|
||||
<div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
|
||||
</div>
|
||||
<div class="mb-2 p-2">
|
||||
<div class="d-flex mb-2">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="mb-3">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex w-100">
|
||||
<div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
|
||||
<hr class="w-75 mx-auto my-5">
|
||||
|
||||
<div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
|
||||
</div>
|
||||
<div class="mb-2 p-2">
|
||||
<div class="d-flex mb-2">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="mb-3">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex w-100">
|
||||
<div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
|
||||
<hr class="w-75 mx-auto my-5">
|
||||
|
||||
<div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
|
||||
</div>
|
||||
<div class="mb-2 p-2">
|
||||
<div class="d-flex mb-2">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="mb-3">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex w-100">
|
||||
<div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
|
||||
<hr class="w-75 mx-auto my-5">
|
||||
|
||||
<div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
|
||||
</div>
|
||||
<div class="mb-2 p-2">
|
||||
<div class="d-flex mb-2">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="mb-3">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex w-100">
|
||||
<div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
|
||||
<hr class="w-75 mx-auto my-5">
|
||||
|
||||
<div class="d-flex align-items-center mb-2 p-2" style="height: 63px">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="bg-pulse-grey" style="height: 15px; width: 150px"></div>
|
||||
</div>
|
||||
<div class="mb-2 p-2">
|
||||
<div class="d-flex mb-2">
|
||||
<div class="bg-pulse-grey rounded-circle mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="mb-3">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 200px"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 18px; width: 350px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex w-100">
|
||||
<div class="flex-shrink-0 mr-2" style="height: 45px; width: 45px"></div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 95%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 97%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 93%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 100%"></div>
|
||||
<div class="bg-pulse-grey mb-1" style="height: 15px; width: 75%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-pulse-grey" style="height: 36px; width: 150px"></div>
|
||||
</div>
|
@ -34,27 +34,78 @@
|
||||
"moduleName": "Chef the Forum"
|
||||
}
|
||||
}}
|
||||
<div class="grader-grading_navigation col-sm-12">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-8 py-3">
|
||||
<div class="d-block">
|
||||
<h6 class="d-inline btn px-0 font-weight-bold text-muted mb-0">{{moduleName}}</h6>
|
||||
<h6 class="d-inline btn px-0 font-weight-bold text-muted mb-0"> > </h6>
|
||||
<h6 class="d-inline btn px-0 font-weight-bold mb-0">{{#str}}grading, forum{{/str}}</h6>
|
||||
<nav id="nav-container-{{uniqid}}" class="grader-grading_navigation navbar">
|
||||
<div class="d-none d-sm-flex align-items-center">
|
||||
<a href="{{{courseUrl}}}" class="btn btn-link px-2 colour-inherit">
|
||||
<h5 class="d-inline px-0 mb-0">{{courseName}}</h5>
|
||||
</a>
|
||||
<span class="text-muted icon-no-margin">{{#pix}} i/breadcrumbdivider, core {{/pix}}</span>
|
||||
<button class="btn btn-link px-2 colour-inherit" data-action="closegrader">
|
||||
<h5 class="d-inline px-0 mb-0">{{moduleName}}</h5>
|
||||
</button>
|
||||
<span class="text-muted icon-no-margin">{{#pix}} i/breadcrumbdivider, core {{/pix}}</span>
|
||||
<h5 class="d-inline px-2 mb-0 font-weight-bold">{{#str}}grading, forum{{/str}}</h5>
|
||||
</div>
|
||||
|
||||
<div class="ml-auto">
|
||||
<button
|
||||
class="btn btn-icon icon-no-margin drawer-button mr-1 active"
|
||||
data-action="expand-grading-drawer"
|
||||
aria-controls="grading-drawer"
|
||||
aria-expanded="true"
|
||||
type="button"
|
||||
title="{{#str}} showgraderpanel, mod_forum {{/str}}"
|
||||
>
|
||||
<span class="dir-ltr-hide" aria-hidden="true">{{#pix}} show-grader-panel-rtl, mod_forum, {{#str}} showgraderpanel, mod_forum {{/str}} {{/pix}}</span>
|
||||
<span class="dir-rtl-hide" aria-hidden="true">{{#pix}} show-grader-panel, mod_forum, {{#str}} showgraderpanel, mod_forum {{/str}} {{/pix}}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-icon icon-no-margin drawer-button mr-1"
|
||||
aria-label="Open or close grader panel"
|
||||
data-action="collapse-grading-drawer"
|
||||
aria-controls="grading-drawer"
|
||||
aria-expanded="true"
|
||||
type="button"
|
||||
title="{{#str}} hidegraderpanel, mod_forum {{/str}}"
|
||||
>
|
||||
<span aria-hidden="true">{{#pix}} hide-grader-panel, mod_forum, {{#str}} hidegraderpanel, mod_forum {{/str}} {{/pix}}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary font-weight-bold ml-2 px-4"
|
||||
data-action="savegrade"
|
||||
>
|
||||
{{#str}} save {{/str}}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-secondary font-weight-bold ml-2 px-4"
|
||||
aria-label="{{#str}} closegrader, mod_forum {{/str}}"
|
||||
data-action="closegrader"
|
||||
type="button"
|
||||
>
|
||||
{{#str}} close, mod_forum {{/str}}
|
||||
</button>
|
||||
<div class="btn-group">
|
||||
<button
|
||||
class="btn btn-icon text-muted icon-no-margin icon-size-3 ml-2"
|
||||
type="button"
|
||||
id="grader-actions-menu-{{uniqid}}"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
aria-label="{{#str}} actionsforgraderinterface, mod_forum {{/str}}"
|
||||
>
|
||||
{{#pix}} i/menu, core {{/pix}}
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="grader-actions-menu-{{uniqid}}">
|
||||
<button
|
||||
class="dropdown-item"
|
||||
type="button"
|
||||
data-action="togglefullscreen"
|
||||
type="button"
|
||||
>
|
||||
{{#str}} togglefullscreen, mod_forum {{/str}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-4 py-3">
|
||||
|
||||
<a href="#" class="btn fa fa-arrows-alt float-right" aria-label="Toggle fullscreen" data-action="togglefullscreen"></a>
|
||||
|
||||
<a href="#" class="btn btn-secondary float-right" aria-label="Close grade interface" data-action="closegrader">Close</a>
|
||||
|
||||
<a href="#" role="button" class="btn btn-primary float-right" aria-label="Save and quit" data-action="savegrade">Save</a>
|
||||
|
||||
<!--TODO Manipulate grader panel see also Grading panel-->
|
||||
<a href="#" role="button" class="btn fa fa-check-circle float-right" aria-label="Open or close grader panel" data-action="expandgrader"></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
@ -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 mod_forum/local/grades/local/grader/status
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
*
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"status": "Graded",
|
||||
"index": 1,
|
||||
"total": 10
|
||||
}
|
||||
}}
|
||||
{{#status}}<h2 class="font-weight-bold h5 mb-0">{{.}}</h2>{{/status}}
|
||||
<div>{{#str}} indexoutoftotal, mod_forum, {"index": "{{index}}", "total":"{{total}}"}{{/str}}</div>
|
@ -0,0 +1,33 @@
|
||||
{{!
|
||||
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 mod_forum/local/grades/local/grader/status_placeholder
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
*
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
}}
|
||||
<div class="bg-pulse-grey mb-1" style="height: 22px; width: 75px"></div>
|
||||
<div class="bg-pulse-grey ml-auto mr-auto" style="height: 19px; width: 60px"></div>
|
@ -34,40 +34,39 @@
|
||||
{
|
||||
}
|
||||
}}
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div data-region="user_picker/user"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<ul class="pagination">
|
||||
<li class="page-item mr-3">
|
||||
<a class="page-link" href="#" aria-label="Previous" data-action="change-user" data-direction="-1">
|
||||
<span aria-hidden="true">⟨</span>
|
||||
<span class="sr-only">{{#str}} previous {{/str}}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item mr-3">
|
||||
<a class="page-link" href="#" aria-label="Next" data-action="change-user" data-direction="1">
|
||||
<span aria-hidden="true">⟩</span>
|
||||
<span class="sr-only">{{#str}} next {{/str}}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<button class="btn btn-icon icon-size-4 icon-no-margin colour-inherit" aria-label="{{#str}} search {{/str}}" data-target="#searchbox" aria-expanded="false" aria-controls="searchbox" data-toggle="collapse">
|
||||
<i class="icon fa fa-search fa-fw" aria-hidden="true"></i>
|
||||
<span class="sr-only">{{#str}} search {{/str}}</span>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<div class="d-flex align-items-center user-picker-container mb-2 py-2">
|
||||
<div class="d-flex align-items-center" data-region="user_picker/user"></div>
|
||||
<div class="ml-auto flex-shrink-0">
|
||||
<nav aria-label="{{#str}} usernavigation, mod_forum {{/str}}">
|
||||
<ul class="pagination mb-0">
|
||||
<li class="page-item">
|
||||
<a
|
||||
class="page-link icon-no-margin p-0 text-reset icon-size-3"
|
||||
href="#"
|
||||
aria-label="{{#str}} previous {{/str}}"
|
||||
data-action="change-user"
|
||||
data-direction="-1"
|
||||
title="{{#str}} previoususer, mod_forum {{/str}}"
|
||||
>
|
||||
<span class="dir-ltr-hide">{{#pix}} i/next, core {{/pix}}</span>
|
||||
<span class="dir-rtl-hide">{{#pix}} i/previous, core {{/pix}}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a
|
||||
class="page-link icon-no-margin p-0 text-reset icon-size-3 ml-2"
|
||||
href="#"
|
||||
aria-label="{{#str}} next {{/str}}"
|
||||
data-action="change-user"
|
||||
data-direction="1"
|
||||
title="{{#str}} nextuser, mod_forum {{/str}}"
|
||||
>
|
||||
<span class="dir-ltr-hide">{{#pix}} i/previous, core {{/pix}}</span>
|
||||
<span class="dir-rtl-hide">{{#pix}} i/next, core {{/pix}}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" class="col-md-12 collapse">
|
||||
<form action="" class="search-form my-3 w-100">
|
||||
<input type="text" data-action="search-user-input" class="form-control input-lg" placeholder="Search user">
|
||||
</form>
|
||||
<div data-action="search-user-box"></div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
@ -38,5 +38,21 @@
|
||||
"total": 7
|
||||
}
|
||||
}}
|
||||
<div class="d-block font-weight-bold" data-region="name" data-userid="{{id}}">{{fullname}}</div>
|
||||
<div class="d-block"><div class="d-inline" data-region="index">{{displayIndex}}</div>/{{total}}</div>
|
||||
{{#profileimage}}
|
||||
<img
|
||||
class="rounded-circle userpicture mr-2"
|
||||
src="{{.}}"
|
||||
alt="{{#str}}pictureof, moodle, {{fullname}}{{/str}}"
|
||||
title="{{#str}}pictureof, moodle, {{fullname}}{{/str}}"
|
||||
>
|
||||
{{/profileimage}}
|
||||
<div>
|
||||
<h5
|
||||
class="mb-0 font-weight-bold user-full-name text-truncate"
|
||||
data-region="name"
|
||||
data-userid="{{id}}"
|
||||
>
|
||||
{{fullname}}
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
|
@ -56,40 +56,20 @@
|
||||
]
|
||||
}
|
||||
}}
|
||||
<div data-action="search-user-box">
|
||||
{{#expandedUsers}}
|
||||
<div class="mt-2">
|
||||
<img class="rounded-circle userpicture" src="{{profileimage}}"
|
||||
alt="{{#str}}pictureof, moodle, {{fullname}}{{/str}}"
|
||||
title="{{#str}}pictureof, moodle, {{fullname}}{{/str}}" >
|
||||
<a href="#" class="font-weight-bold" data-action="select-user" data-userid="{{id}}">{{fullname}}</a>
|
||||
</div>
|
||||
{{/expandedUsers}}
|
||||
{{^expandedUsers}}
|
||||
<h5>{{#str}}nousersmatch, mod_forum{{/str}}</h5>
|
||||
{{/expandedUsers}}
|
||||
{{#hasCollapsed}}
|
||||
<div class="d-flex flex-column px-3 py-2" data-action="search-user-box">
|
||||
{{#users}}
|
||||
<button
|
||||
class="btn btn-icon mt-2 text-muted icon-no-margin icon-size-3"
|
||||
type="button"
|
||||
id="grader-users-menu-{{uniqid}}"
|
||||
aria-label="{{#str}} showmoreusers, mod_forum {{/str}}"
|
||||
data-toggle="collapse"
|
||||
data-target="#collapsed-users-{{uniqid}}"
|
||||
aria-expanded="false"
|
||||
aria-controls="collapsed-users-{{uniqid}}"
|
||||
class="btn btn-link text-reset p-0 mb-2 d-flex align-items-center"
|
||||
data-action="select-user"
|
||||
data-userid="{{id}}"
|
||||
>
|
||||
{{#pix}} i/moremenu {{/pix}}
|
||||
{{> mod_forum/local/grades/local/grader/user_picker/user }}
|
||||
</button>
|
||||
<div id="collapsed-users-{{uniqid}}" class="collapse" aria-labelledby="grader-users-menu-{{uniqid}}">
|
||||
{{#collapsedUsers}}
|
||||
<div class="mt-2">
|
||||
<img class="rounded-circle userpicture" src="{{profileimage}}"
|
||||
alt="{{#str}}pictureof, moodle, {{fullname}}{{/str}}"
|
||||
title="{{#str}}pictureof, moodle, {{fullname}}{{/str}}" >
|
||||
<a href="#" class="font-weight-bold" data-action="select-user" data-userid="{{id}}">{{fullname}}</a>
|
||||
</div>
|
||||
{{/collapsedUsers}}
|
||||
{{/users}}
|
||||
{{^users}}
|
||||
<div class="no-search-results-container text-center">
|
||||
{{#pix}} no-search-results, mod_forum {{/pix}}
|
||||
<h5 class="font-weight-bold mt-3">{{#str}}nousersmatch, mod_forum{{/str}}</h5>
|
||||
</div>
|
||||
{{/hasCollapsed}}
|
||||
{{/users}}
|
||||
</div>
|
||||
|
@ -30,29 +30,21 @@
|
||||
{
|
||||
}
|
||||
}}
|
||||
<div class="col-md-12 mt-3">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="bg-pulse-grey w-50" style="height: 20px;"></div>
|
||||
<div class="bg-pulse-grey w-25 mt-1" style="height: 15px;"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<ul class="pagination">
|
||||
<li class="page-item mr-3">
|
||||
<span class="btn bg-pulse-grey" aria-hidden="true">⟨</span>
|
||||
<span class="sr-only">{{#str}} previous {{/str}}</span>
|
||||
</li>
|
||||
<li class="page-item mr-3">
|
||||
<span class="btn bg-pulse-grey" aria-hidden="true">⟩</span>
|
||||
<span class="sr-only">{{#str}} next {{/str}}</span>
|
||||
|
||||
<div class="d-flex align-items-center user-picker-container mb-2 py-2">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-pulse-grey rounded-circle d-inline-block flex-shrink-0 userpicture mr-2"></div>
|
||||
<div class="bg-pulse-grey d-inline-block" style="height: 22px; width: 150px"></div>
|
||||
</div>
|
||||
<div class="ml-auto flex-shrink-0">
|
||||
<nav>
|
||||
<ul class="pagination mb-0">
|
||||
<li class="page-item">
|
||||
<a class="bg-pulse-grey border-0 page-link icon-no-margin p-0 icon-size-3" href="#"></a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<span class="btn bg-pulse-grey fa fa-search" aria-hidden="true"></span>
|
||||
<span class="sr-only">{{#str}} search {{/str}}</span>
|
||||
<a class="bg-pulse-grey border-0 page-link icon-no-margin p-0 icon-size-3 ml-2" href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -2664,17 +2664,21 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
|
||||
$record->course = $course1->id;
|
||||
$record->userid = $user1->id;
|
||||
$record->forum = $forum1->id;
|
||||
$record->timemodified = 1;
|
||||
$discussion1 = $forumgenerator->create_discussion($record);
|
||||
$discussion1firstpost = $postvault->get_first_post_for_discussion_ids([$discussion1->id]);
|
||||
$discussion1firstpostobject = $legacypostmapper->to_legacy_object($discussion1firstpost[$discussion1->firstpost]);
|
||||
$discussion1firstpost = $discussion1firstpost[$discussion1->firstpost];
|
||||
$discussion1firstpostobject = $legacypostmapper->to_legacy_object($discussion1firstpost);
|
||||
|
||||
$record = new stdClass();
|
||||
$record->course = $course1->id;
|
||||
$record->userid = $user1->id;
|
||||
$record->forum = $forum1->id;
|
||||
$record->timemodified = 2;
|
||||
$discussion2 = $forumgenerator->create_discussion($record);
|
||||
$discussion2firstpost = $postvault->get_first_post_for_discussion_ids([$discussion2->id]);
|
||||
$discussion2firstpostobject = $legacypostmapper->to_legacy_object($discussion2firstpost[$discussion2->firstpost]);
|
||||
$discussion2firstpost = $discussion2firstpost[$discussion2->firstpost];
|
||||
$discussion2firstpostobject = $legacypostmapper->to_legacy_object($discussion2firstpost);
|
||||
|
||||
// Add 1 reply to the discussion 1 from a different user.
|
||||
$record = new stdClass();
|
||||
@ -2733,6 +2737,8 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
|
||||
$expectedposts['discussions'][0] = [
|
||||
'name' => $discussion1->name,
|
||||
'id' => $discussion1->id,
|
||||
'timecreated' => $discussion1firstpost->get_time_created(),
|
||||
'authorfullname' => $user1entity->get_full_name(),
|
||||
'posts' => [
|
||||
'userposts' => [
|
||||
[
|
||||
@ -2864,6 +2870,8 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
|
||||
$expectedposts['discussions'][1] = [
|
||||
'name' => $discussion2->name,
|
||||
'id' => $discussion2->id,
|
||||
'timecreated' => $discussion2firstpost->get_time_created(),
|
||||
'authorfullname' => $user1entity->get_full_name(),
|
||||
'posts' => [
|
||||
'userposts' => [
|
||||
[
|
||||
|
@ -105,25 +105,7 @@ $PAGE->set_context($forum->get_context());
|
||||
$PAGE->set_title($forum->get_name());
|
||||
$PAGE->add_body_class('forumtype-' . $forum->get_type());
|
||||
$PAGE->set_heading($course->fullname);
|
||||
|
||||
$buttons = [];
|
||||
if ($capabilitymanager->can_grade($USER)) {
|
||||
$forumgradeitem = forum_gradeitem::load_from_forum_entity($forum);
|
||||
if ($forumgradeitem->is_grading_enabled()) {
|
||||
$groupid = groups_get_activity_group($cm, true) ?: null;
|
||||
$gradeobj = (object) [
|
||||
'contextid' => $forum->get_context()->id,
|
||||
'cmid' => $cmid,
|
||||
'name' => $forum->get_name(),
|
||||
'groupid' => $groupid,
|
||||
'gradingcomponent' => $forumgradeitem->get_grading_component_name(),
|
||||
'gradingcomponentsubtype' => $forumgradeitem->get_grading_component_subtype(),
|
||||
];
|
||||
$buttons[] = $OUTPUT->render_from_template('mod_forum/grades/grade_button', $gradeobj);
|
||||
}
|
||||
}
|
||||
$buttons[] = forum_search_form($course, $search);
|
||||
$PAGE->set_button(implode('', $buttons));
|
||||
$PAGE->set_button(forum_search_form($course, $search));
|
||||
|
||||
if ($istypesingle && $displaymode == FORUM_MODE_NESTED_V2) {
|
||||
$PAGE->add_body_class('reset-style');
|
||||
@ -189,6 +171,24 @@ $groupid = groups_get_activity_group($cm, true) ?: null;
|
||||
$rendererfactory = mod_forum\local\container::get_renderer_factory();
|
||||
switch ($forum->get_type()) {
|
||||
case 'single':
|
||||
if ($capabilitymanager->can_grade($USER)) {
|
||||
$forumgradeitem = forum_gradeitem::load_from_forum_entity($forum);
|
||||
if ($forumgradeitem->is_grading_enabled()) {
|
||||
$groupid = groups_get_activity_group($cm, true) ?: null;
|
||||
$gradeobj = (object) [
|
||||
'contextid' => $forum->get_context()->id,
|
||||
'cmid' => $cmid,
|
||||
'name' => $forum->get_name(),
|
||||
'courseid' => $course->id,
|
||||
'coursename' => $course->shortname,
|
||||
'experimentaldisplaymode' => $displaymode == FORUM_MODE_NESTED_V2,
|
||||
'groupid' => $groupid,
|
||||
'gradingcomponent' => $forumgradeitem->get_grading_component_name(),
|
||||
'gradingcomponentsubtype' => $forumgradeitem->get_grading_component_subtype(),
|
||||
];
|
||||
echo $OUTPUT->render_from_template('mod_forum/grades/grade_button', $gradeobj);
|
||||
}
|
||||
}
|
||||
$discussion = $discussionvault->get_last_discussion_in_forum($forum);
|
||||
$discussioncount = $discussionvault->get_count_discussions_in_forum($forum);
|
||||
$hasmultiplediscussions = $discussioncount > 1;
|
||||
@ -227,7 +227,7 @@ switch ($forum->get_type()) {
|
||||
break;
|
||||
default:
|
||||
$discussionsrenderer = $rendererfactory->get_discussion_list_renderer($forum);
|
||||
echo $discussionsrenderer->render($USER, $cm, $groupid, $sortorder, $pageno, $pagesize);
|
||||
echo $discussionsrenderer->render($USER, $cm, $groupid, $sortorder, $pageno, $pagesize, $displaymode);
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
@ -366,6 +366,7 @@ select[size="1"] {
|
||||
|
||||
textarea[data-auto-rows] {
|
||||
overflow-x: hidden;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
/** Display elements under labels in vertical forms regardless of the screen size. */
|
||||
|
@ -240,20 +240,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
.criterion button.collapse[aria-expanded="true"]:before {
|
||||
content: $fa-var-angle-down;
|
||||
margin-right: 0;
|
||||
@include fa-icon();
|
||||
font-size: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
.criterion {
|
||||
.description {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.criterion button.collapse[aria-expanded="false"]:before {
|
||||
content: $fa-var-angle-up;
|
||||
margin-right: 0;
|
||||
@include fa-icon();
|
||||
font-size: 16px;
|
||||
width: 16px;
|
||||
.criterion-toggle {
|
||||
.expanded-icon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.collapsed-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
.expanded-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapsed-icon {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set up grades layout.
|
||||
|
@ -1,17 +1,21 @@
|
||||
.layout {
|
||||
&.fullscreen {
|
||||
height: 100%;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: $zindex-modal-backdrop;
|
||||
overflow-x: hidden;
|
||||
transition: 0.5s;
|
||||
width: 100%;
|
||||
width: 100vw;
|
||||
margin: 0;
|
||||
opacity: 1;
|
||||
background-color: $modal-content-bg;
|
||||
|
||||
> div {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.loading-icon {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
@ -218,7 +218,7 @@ $author-image-margin-sm: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
#page-mod-forum-view [data-region="unified-grader"],
|
||||
.path-mod-forum .nested-v2-display-mode,
|
||||
.path-mod-forum.nested-v2-display-mode {
|
||||
.discussionsubscription {
|
||||
margin-top: 0;
|
||||
@ -426,6 +426,492 @@ $author-image-margin-sm: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
$grading-drawer-width: 430px !default;
|
||||
$grading-animation-duration: .3s !default;
|
||||
$grading-icon-button-size: 36px !default;
|
||||
$grading-search-button-padding-left: calc(#{map-get($spacers, 2)} + 8px) !default;
|
||||
$grading-search-input-padding-left: calc(#{map-get($spacers, 2)} + #{map-get($spacers, 2)} + #{$grading-icon-button-size - ($input-border-width * 2)}) !default; /* stylelint-disable-line max-line-length */
|
||||
$grading-search-input-padding-right: calc(#{map-get($spacers, 2)} + #{$grading-icon-button-size}) !default;
|
||||
$grading-nav-bar-active-drawer-button-bottom: calc(#{map-get($spacers, 2) * -1} - 1px) !default;
|
||||
$grading-content-show-content-button-padding-left: calc(#{map-get($spacers, 2) * 2} + 45px) !default;
|
||||
|
||||
@keyframes expandSearchButton {
|
||||
from {
|
||||
height: $grading-icon-button-size;
|
||||
width: $grading-icon-button-size;
|
||||
border-radius: $grading-icon-button-size / 2;
|
||||
background-color: $gray-200;
|
||||
}
|
||||
to {
|
||||
width: 100%;
|
||||
height: $input-height-lg;
|
||||
border-radius: 0;
|
||||
background-color: $input-bg;
|
||||
border-color: $input-border-color;
|
||||
padding-left: $grading-search-button-padding-left;
|
||||
padding-top: $input-padding-y-lg;
|
||||
padding-bottom: $input-padding-y-lg;
|
||||
@include font-size($input-font-size-lg);
|
||||
line-height: $input-line-height-lg;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes collapseSearchButton {
|
||||
from {
|
||||
width: 100%;
|
||||
height: $input-height-lg;
|
||||
border-radius: 0;
|
||||
background-color: $input-bg;
|
||||
border-color: $input-border-color;
|
||||
padding-left: $grading-search-button-padding-left;
|
||||
padding-top: $input-padding-y-lg;
|
||||
padding-bottom: $input-padding-y-lg;
|
||||
@include font-size($input-font-size-lg);
|
||||
line-height: $input-line-height-lg;
|
||||
right: 0;
|
||||
}
|
||||
to {
|
||||
height: $grading-icon-button-size;
|
||||
width: $grading-icon-button-size;
|
||||
border-radius: $grading-icon-button-size / 2;
|
||||
background-color: $gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
.path-mod-forum .unified-grader {
|
||||
.navbar {
|
||||
max-height: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.body-container {
|
||||
&.hidden {
|
||||
display: none !important; /* stylelint-disable-line declaration-no-important */
|
||||
}
|
||||
}
|
||||
|
||||
.userpicture {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.grader-grading-panel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
width: $grading-drawer-width;
|
||||
|
||||
&.hidden {
|
||||
right: ($grading-drawer-width * -1);
|
||||
}
|
||||
|
||||
.grading-icon {
|
||||
width: $grading-icon-button-size;
|
||||
}
|
||||
|
||||
.user-picker-container {
|
||||
.user-full-name {
|
||||
max-width: 240px;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
width: $grading-icon-button-size;
|
||||
height: $grading-icon-button-size;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.header-container {
|
||||
height: 65px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.info-container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: map-get($spacers, 2);
|
||||
padding-right: calc(#{$grading-icon-button-size} + #{map-get($spacers, 2)});
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition: left $grading-animation-duration ease-in-out;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.toggle-search-button {
|
||||
&.expand {
|
||||
animation-name: expandSearchButton;
|
||||
animation-duration: $grading-animation-duration;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
&.collapse {
|
||||
display: block;
|
||||
animation-name: collapseSearchButton;
|
||||
animation-duration: $grading-animation-duration;
|
||||
}
|
||||
}
|
||||
|
||||
.user-search-container {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
transform: translateY(-50%);
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
height: 100% !important; /* stylelint-disable-line declaration-no-important */
|
||||
padding: map-get($spacers, 2);
|
||||
|
||||
.search-input-container {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
input {
|
||||
padding-left: $grading-search-input-padding-left;
|
||||
padding-right: $grading-search-input-padding-right;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition:
|
||||
opacity 0s linear $grading-animation-duration,
|
||||
visibility 0s linear;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: map-get($spacers, 2);
|
||||
transform: translateY(-50%);
|
||||
color: $input-color;
|
||||
height: $grading-icon-button-size;
|
||||
width: $grading-icon-button-size - ($input-border-width * 2);
|
||||
background-color: $input-bg;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition:
|
||||
opacity 0s linear $grading-animation-duration,
|
||||
visibility 0s linear $grading-animation-duration;
|
||||
}
|
||||
|
||||
.toggle-search-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: map-get($spacers, 2);
|
||||
transform: translateY(-50%);
|
||||
z-index: 1;
|
||||
color: inherit;
|
||||
text-align: left;
|
||||
padding-left: 9px;
|
||||
transition: right 0s linear $grading-animation-duration;
|
||||
|
||||
.expanded-icon {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
max-width: 50px;
|
||||
max-height: 50px;
|
||||
transition:
|
||||
opacity 0s linear $grading-animation-duration,
|
||||
max-height 0s linear $grading-animation-duration,
|
||||
max-width 0s linear $grading-animation-duration,
|
||||
visibility 0s linear $grading-animation-duration;
|
||||
}
|
||||
|
||||
.collapsed-icon {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
max-height: 0;
|
||||
max-width: 0;
|
||||
overflow: hidden;
|
||||
transition:
|
||||
opacity 0s linear $grading-animation-duration,
|
||||
max-height 0s linear $grading-animation-duration,
|
||||
max-width 0s linear $grading-animation-duration,
|
||||
visibility 0s linear $grading-animation-duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
width: calc(#{$grading-icon-button-size} + #{map-get($spacers, 2)} + #{map-get($spacers, 2)});
|
||||
transition: width $grading-animation-duration ease-in-out;
|
||||
|
||||
.search-input-container {
|
||||
flex-wrap: nowrap;
|
||||
|
||||
input,
|
||||
.search-icon {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition:
|
||||
opacity 0s linear,
|
||||
visibility 0s linear;
|
||||
}
|
||||
|
||||
input {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.toggle-search-button {
|
||||
.expanded-icon {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
max-height: 0;
|
||||
max-width: 0;
|
||||
overflow: hidden;
|
||||
transition:
|
||||
opacity 0s linear,
|
||||
max-height 0s linear,
|
||||
max-width 0s linear,
|
||||
visibility 0s linear;
|
||||
}
|
||||
|
||||
.collapsed-icon {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
max-width: 50px;
|
||||
max-height: 50px;
|
||||
transition:
|
||||
opacity 0s linear,
|
||||
max-height 0s linear,
|
||||
max-width 0s linear,
|
||||
visibility 0s linear;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-search-container:not(.collapsed) + .info-container {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
left: calc(100% * -1);
|
||||
transition:
|
||||
left $grading-animation-duration ease-in-out,
|
||||
opacity 0s linear $grading-animation-duration,
|
||||
visibility 0s linear $grading-animation-duration,
|
||||
padding 0s linear $grading-animation-duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grader-module-content {
|
||||
overflow-y: auto;
|
||||
margin-right: $grading-drawer-width;
|
||||
@include transition(margin-right .2s ease-in-out);
|
||||
}
|
||||
|
||||
.grader-grading-panel.hidden + .grader-module-content {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.drawer-button {
|
||||
position: relative;
|
||||
|
||||
&.active::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: $grading-nav-bar-active-drawer-button-bottom;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background-color: map-get($theme-colors, 'primary');
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 20px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.grader-module-content-display {
|
||||
.discussion-container {
|
||||
&:last-of-type {
|
||||
> hr {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.posts-container {
|
||||
&:last-of-type {
|
||||
> hr {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.parent-container {
|
||||
position: relative;
|
||||
|
||||
.show-content-button {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding-left: $grading-content-show-content-button-padding-left;
|
||||
text-align: left;
|
||||
z-index: 1;
|
||||
|
||||
&:not(.collapsed) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: block;
|
||||
height: auto !important; /* stylelint-disable-line declaration-no-important */
|
||||
|
||||
.header {
|
||||
transition: margin-bottom $grading-animation-duration ease-in-out;
|
||||
|
||||
div + div {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
max-height: none;
|
||||
transition:
|
||||
opacity $grading-animation-duration linear,
|
||||
visibility 0s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.body-content-container {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
max-height: none;
|
||||
transition:
|
||||
opacity $grading-animation-duration linear,
|
||||
visibility 0s linear;
|
||||
}
|
||||
|
||||
.forum-post-core {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
max-height: none;
|
||||
transition:
|
||||
opacity $grading-animation-duration linear,
|
||||
visibility 0s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.show-content-button.collapsed + .content {
|
||||
opacity: .3;
|
||||
|
||||
.header {
|
||||
margin-bottom: 0 !important; /* stylelint-disable-line declaration-no-important */
|
||||
|
||||
div + div {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
max-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.body-content-container {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
max-height: 0;
|
||||
}
|
||||
|
||||
.forum-post-core {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
max-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.show-content-button.collapsed:hover + .content,
|
||||
.show-content-button.collapsed:focus + .content {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-post-container {
|
||||
.icon {
|
||||
height: 250px;
|
||||
width: 250px;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.nested-v2-display-mode {
|
||||
.discussion-container {
|
||||
.posts-container {
|
||||
.parent-container {
|
||||
.show-content-button {
|
||||
padding-left: $author-image-width + $author-image-margin;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-search-results-container {
|
||||
.icon {
|
||||
height: 250px;
|
||||
width: 250px;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.nested-v2-display-mode {
|
||||
.view-context-button {
|
||||
margin-left: $author-image-width + $author-image-margin;
|
||||
border-radius: $border-radius-lg;
|
||||
}
|
||||
|
||||
.parent-container {
|
||||
.author-image-container {
|
||||
position: relative;
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: calc(#{$author-image-width} + #{map-get($spacers, 2)});
|
||||
content: "";
|
||||
background-color: $gray-200;
|
||||
width: 2px;
|
||||
height: calc(100% - #{$author-image-width} + #{map-get($spacers, 2)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.parent-container + .post-container {
|
||||
.author-image-container {
|
||||
img {
|
||||
width: $author-image-width-sm !important; /* stylelint-disable-line declaration-no-important */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.path-mod-forum .unified-grader .nested-v2-display-mode,
|
||||
.path-mod-forum .modal .nested-v2-display-mode {
|
||||
.post-subject {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
.path-mod-forum .unified-grader {
|
||||
.grader-grading-panel {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End styling for mod_forum.
|
||||
|
||||
.maincalendar .calendarmonth td,
|
||||
|