Merge branch 'MDL-73538-master' of https://github.com/ferranrecio/moodle

This commit is contained in:
Shamim Rezaie
2022-02-03 15:24:04 +11:00
7 changed files with 113 additions and 6 deletions
@@ -0,0 +1,2 @@
define ("core_courseformat/local/content/activity_header",["exports","core/reactive","core_courseformat/courseeditor","core_course/events"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;d=f(d);function e(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;e=function(){return a};return a}function f(a){if(a&&a.__esModule){return a}if(null===a||"object"!==g(a)&&"function"!=typeof a){return{default:a}}var b=e();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var f in a){if(Object.prototype.hasOwnProperty.call(a,f)){var h=d?Object.getOwnPropertyDescriptor(a,f):null;if(h&&(h.get||h.set)){Object.defineProperty(c,f,h)}else{c[f]=a[f]}}}c.default=a;if(b){b.set(a,c)}return c}function g(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){g=function(a){return typeof a}}else{g=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return g(a)}function h(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function i(a,b){for(var c=0,d;c<b.length;c++){d=b[c];d.enumerable=d.enumerable||!1;d.configurable=!0;if("value"in d)d.writable=!0;Object.defineProperty(a,d.key,d)}}function j(a,b,c){if(b)i(a.prototype,b);if(c)i(a,c);return a}function k(a,b){if("function"!=typeof b&&null!==b){throw new TypeError("Super expression must either be null or a function")}a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,writable:!0,configurable:!0}});if(b)l(a,b)}function l(a,b){l=Object.setPrototypeOf||function(a,b){a.__proto__=b;return a};return l(a,b)}function m(a){return function(){var b=q(a),c;if(p()){var d=q(this).constructor;c=Reflect.construct(b,arguments,d)}else{c=b.apply(this,arguments)}return n(this,c)}}function n(a,b){if(b&&("object"===g(b)||"function"==typeof b)){return b}return o(a)}function o(a){if(void 0===a){throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}return a}function p(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{Date.prototype.toString.call(Reflect.construct(Date,[],function(){}));return!0}catch(a){return!1}}function q(a){q=Object.setPrototypeOf?Object.getPrototypeOf:function(a){return a.__proto__||Object.getPrototypeOf(a)};return q(a)}var r={ACTIVITY_HEADER:"[data-for='page-activity-header']"},s=function(a){k(b,a);var e=m(b);function b(){h(this,b);return e.apply(this,arguments)}j(b,[{key:"create",value:function create(){this.name="activity_header"}},{key:"stateReady",value:function stateReady(){this.addEventListener(this.element,d.manualCompletionToggled,this._completionHandler)}},{key:"_completionHandler",value:function _completionHandler(a){var b=a.detail;if(b===void 0){return}this.reactive.dispatch("cmCompletion",[b.cmid],b.completed)}}],[{key:"init",value:function init(a,d){var e=a?a:r.ACTIVITY_HEADER;return new b({element:document.querySelector(e),reactive:(0,c.getCurrentCourseEditor)(),selectors:d})}}]);return b}(b.BaseComponent);a.default=s;return a.default});
//# sourceMappingURL=activity_header.min.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/local/content/activity_header.js"],"names":["SELECTORS","ACTIVITY_HEADER","Component","name","addEventListener","element","CourseEvents","manualCompletionToggled","_completionHandler","detail","reactive","dispatch","cmid","completed","target","selectors","elementselector","document","querySelector","BaseComponent"],"mappings":"6OA0BA,O,+pEAGMA,CAAAA,CAAS,CAAG,CACdC,eAAe,oCADD,C,CAIGC,C,+HAKR,CAEL,KAAKC,IAAL,CAAY,iBACf,C,+CAqBY,CAET,KAAKC,gBAAL,CACI,KAAKC,OADT,CAEIC,CAAY,CAACC,uBAFjB,CAGI,KAAKC,kBAHT,CAKH,C,gEAQ4B,IAATC,CAAAA,CAAS,GAATA,MAAS,CACzB,GAAIA,CAAM,SAAV,CAA0B,CACtB,MACH,CACD,KAAKC,QAAL,CAAcC,QAAd,CAAuB,cAAvB,CAAuC,CAACF,CAAM,CAACG,IAAR,CAAvC,CAAsDH,CAAM,CAACI,SAA7D,CACH,C,oCAhCWC,C,CAAQC,C,CAAW,CAC3B,GAAMC,CAAAA,CAAe,CAAIF,CAAD,CAAWA,CAAX,CAAoBd,CAAS,CAACC,eAAtD,CACA,MAAO,IAAIC,CAAAA,CAAJ,CAAc,CACjBG,OAAO,CAAEY,QAAQ,CAACC,aAAT,CAAuBF,CAAvB,CADQ,CAEjBN,QAAQ,CAAE,8BAFO,CAGjBK,SAAS,CAATA,CAHiB,CAAd,CAKV,C,cAxBkCI,e","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 * The activity header component.\n *\n * @module core_courseformat/local/content/activity_header\n * @class core_courseformat/local/content/activity_header\n * @copyright 2021 Ferran Recio <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {BaseComponent} from 'core/reactive';\nimport {getCurrentCourseEditor} from 'core_courseformat/courseeditor';\nimport * as CourseEvents from 'core_course/events';\n\n// Global page selectors.\nconst SELECTORS = {\n ACTIVITY_HEADER: `[data-for='page-activity-header']`,\n};\n\nexport default class Component extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'activity_header';\n }\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {string} target optional altentative DOM main element CSS selector\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n const elementselector = (target) ? target : SELECTORS.ACTIVITY_HEADER;\n return new Component({\n element: document.querySelector(elementselector),\n reactive: getCurrentCourseEditor(),\n selectors\n });\n }\n\n /**\n * Initial state ready method.\n */\n stateReady() {\n // Capture completion events.\n this.addEventListener(\n this.element,\n CourseEvents.manualCompletionToggled,\n this._completionHandler\n );\n }\n\n /**\n * Activity manual completion listener.\n *\n * @param {Event} event the custom event\n * @param {object} event.detail the event details\n */\n _completionHandler({detail}) {\n if (detail === undefined) {\n return;\n }\n this.reactive.dispatch('cmCompletion', [detail.cmid], detail.completed);\n }\n}\n"],"file":"activity_header.min.js"}
@@ -0,0 +1,84 @@
// 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/>.
/**
* The activity header component.
*
* @module core_courseformat/local/content/activity_header
* @class core_courseformat/local/content/activity_header
* @copyright 2021 Ferran Recio <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {BaseComponent} from 'core/reactive';
import {getCurrentCourseEditor} from 'core_courseformat/courseeditor';
import * as CourseEvents from 'core_course/events';
// Global page selectors.
const SELECTORS = {
ACTIVITY_HEADER: `[data-for='page-activity-header']`,
};
export default class Component extends BaseComponent {
/**
* Constructor hook.
*/
create() {
// Optional component name for debugging.
this.name = 'activity_header';
}
/**
* Static method to create a component instance form the mustache template.
*
* @param {string} target optional altentative DOM main element CSS selector
* @param {object} selectors optional css selector overrides
* @return {Component}
*/
static init(target, selectors) {
const elementselector = (target) ? target : SELECTORS.ACTIVITY_HEADER;
return new Component({
element: document.querySelector(elementselector),
reactive: getCurrentCourseEditor(),
selectors
});
}
/**
* Initial state ready method.
*/
stateReady() {
// Capture completion events.
this.addEventListener(
this.element,
CourseEvents.manualCompletionToggled,
this._completionHandler
);
}
/**
* Activity manual completion listener.
*
* @param {Event} event the custom event
* @param {object} event.detail the event details
*/
_completionHandler({detail}) {
if (detail === undefined) {
return;
}
this.reactive.dispatch('cmCompletion', [detail.cmid], detail.completed);
}
}
@@ -40,7 +40,7 @@ Feature: Course index completion icons
And "To do" "icon" should exist in the "courseindex-content" "region"
@javascript
Scenario: Manual completion shoudl update the course index completion
Scenario: Manual completion should update the course index completion
Given I am on the "C1" "Course" page logged in as "student1"
And "To do" "icon" should exist in the "courseindex-content" "region"
When I press "Mark as done"
@@ -50,6 +50,17 @@ Feature: Course index completion icons
And I wait until "Mark as done" "button" exists
And "To do" "icon" should exist in the "courseindex-content" "region"
@javascript
Scenario: Manual completion in an activity page should update the course index
Given I am on the "sample1" "Activity" page logged in as "student1"
And "To do" "icon" should exist in the "courseindex-content" "region"
When I press "Mark as done"
And I wait until "Done" "button" exists
Then "Done" "icon" should exist in the "courseindex-content" "region"
And I press "Done"
And I wait until "Mark as done" "button" exists
And "To do" "icon" should exist in the "courseindex-content" "region"
@javascript
Scenario: Refresh the page should keep the completion consistent
Given I am on the "C1" "Course" page logged in as "student1"
+8
View File
@@ -174,6 +174,14 @@ class activity_header implements \renderable, \templatable {
$completion = $output->activity_information($this->page->cm, $completiondetails, $activitydates);
}
$format = course_get_format($this->page->course);
if ($format->supports_components()) {
$this->page->requires->js_call_amd(
'core_courseformat/local/content/activity_header',
'init'
);
}
return [
'title' => $this->title,
'description' => $this->description,
+5 -4
View File
@@ -1041,11 +1041,12 @@ class page_requirements_manager {
public function js_call_amd($fullmodule, $func = null, $params = array()) {
global $CFG;
list($component, $module) = explode('/', $fullmodule, 2);
$modulepath = explode('/', $fullmodule);
$component = clean_param($component, PARAM_COMPONENT);
$module = clean_param($module, PARAM_ALPHANUMEXT);
$modname = "{$component}/{$module}";
$modname = clean_param(array_shift($modulepath), PARAM_COMPONENT);
foreach ($modulepath as $module) {
$modname .= '/' . clean_param($module, PARAM_ALPHANUMEXT);
}
$functioncode = [];
if ($func !== null) {
+1 -1
View File
@@ -70,7 +70,7 @@
{{#title}}
<h2>{{{title}}}</h2>
{{/title}}
<div class="activity-header">
<div class="activity-header" data-for="page-activity-header">
{{#completion}}
<span class="sr-only">{{#str}} overallaggregation, completion {{/str}}</span>
{{{completion}}}