Merge branch 'MDL-70821-311-5' of git://github.com/junpataleta/moodle into MOODLE_311_STABLE
This commit is contained in:
@@ -52,5 +52,5 @@ Feature: availability_completion
|
||||
Then I should not see "Page 2" in the "region-main" "region"
|
||||
|
||||
# Mark page 1 complete
|
||||
When I click on ".togglecompletion .icon" "css_element"
|
||||
When I toggle the manual completion state of "Page 1"
|
||||
Then I should see "Page 2" in the "region-main" "region"
|
||||
|
||||
@@ -242,7 +242,7 @@ Feature: Award badges
|
||||
And I click on "Course 1" "link" in the "region-main" "region"
|
||||
Then I should not see "badges"
|
||||
And I am on "Course 1" course homepage
|
||||
And I click on "Not completed: Test assignment name" "icon"
|
||||
And I toggle the manual completion state of "Test assignment name"
|
||||
And I follow "Profile" in the user menu
|
||||
And I click on "Course 1" "link" in the "region-main" "region"
|
||||
Then I should see "Course Badge"
|
||||
@@ -296,7 +296,7 @@ Feature: Award badges
|
||||
And I click on "Course 1" "link" in the "region-main" "region"
|
||||
Then I should not see "badges"
|
||||
And I am on "Course 1" course homepage
|
||||
And I click on "Not completed: Test assignment name" "icon"
|
||||
And I toggle the manual completion state of "Test assignment name"
|
||||
And I log out
|
||||
# Completion cron won't mark the whole course completed unless the
|
||||
# individual criteria was marked completed more than a second ago. So
|
||||
|
||||
@@ -53,7 +53,8 @@ Feature: Award badges based on activity completion
|
||||
Scenario: Student earns a badge using activity completion, but does not get passing grade
|
||||
When I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And the "Test quiz name" "quiz" activity with "auto" completion should be marked as not complete
|
||||
And the "Receive a grade" completion condition of "Test quiz name" is displayed as "failed"
|
||||
And the "Receive a pass grade or complete all available attempts" completion condition of "Test quiz name" is displayed as "todo"
|
||||
And I follow "Test quiz name"
|
||||
And I press "Re-attempt quiz"
|
||||
And I set the field "False" to "1"
|
||||
|
||||
@@ -153,6 +153,162 @@ class behat_completion extends behat_base {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the activity with specified name is maked as complete.
|
||||
*
|
||||
* @Given /^the "(?P<conditionname>(?:[^"]|\\")*)" completion condition of "(?P<activityname>(?:[^"]|\\")*)" is displayed as "(?P<completionstatus>(?:[^"]|\\")*)"$/
|
||||
* @param string $conditionname The completion condition text.
|
||||
* @param string $activityname The activity name.
|
||||
* @param string $completionstatus The completion status. Must be either of the following: 'todo', 'done', 'failed'.
|
||||
*/
|
||||
public function activity_completion_condition_displayed_as(string $conditionname, string $activityname,
|
||||
string $completionstatus): void {
|
||||
|
||||
if (!in_array($completionstatus, ['todo', 'done', 'failed'])) {
|
||||
throw new coding_exception('Invalid completion status. It must be of type "todo", "done", or "failed".');
|
||||
}
|
||||
|
||||
$text = get_string("completion_automatic:$completionstatus", 'core_course') . ' ' . $conditionname;
|
||||
|
||||
$conditionslistlabel = get_string('completionrequirements', 'core_course', $activityname);
|
||||
$selector = "div[aria-label='$conditionslistlabel']";
|
||||
|
||||
$this->execute("behat_general::assert_element_contains_text", [$text, $selector, "css_element"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the activity with specified name is maked as complete.
|
||||
*
|
||||
* @Given /^the "(?P<conditionname>(?:[^"]|\\")*)" completion condition of "(?P<activityname>(?:[^"]|\\")*)" overridden by "(?P<username>(?:[^"]|\\")*)" is displayed as "(?P<completionstatus>(?:[^"]|\\")*)"$/
|
||||
* @param string $conditionname The completion condition text.
|
||||
* @param string $activityname The activity name.
|
||||
* @param string $username The full name of the user overriding the student's activity completion.
|
||||
* @param string $completionstatus The override completion status. Must be either of the following: 'todo', 'done'.
|
||||
*/
|
||||
public function overridden_activity_completion_condition_displayed_as(string $conditionname, string $activityname,
|
||||
string $username, string $completionstatus): void {
|
||||
if (!in_array($completionstatus, ['todo', 'done'])) {
|
||||
throw new coding_exception('Invalid override completion status. It must be of type "todo" or "done".');
|
||||
}
|
||||
|
||||
$conditionlabel = get_string('completion_setby:auto:' . $completionstatus, 'core_course', (object)[
|
||||
'condition' => $conditionname,
|
||||
'setby' => $username,
|
||||
]);
|
||||
$conditionbadge = "span[aria-label='$conditionlabel']";
|
||||
|
||||
$conditionslistlabel = get_string('completionrequirements', 'core_course', $activityname);
|
||||
$completionconditions = "div[aria-label='$conditionslistlabel']";
|
||||
|
||||
$params = [$conditionbadge, 'css_element', $completionconditions, 'css_element'];
|
||||
$this->execute("behat_general::should_exist_in_the", $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the manual completion state of an activity.
|
||||
*
|
||||
* @Given /^the manual completion button of "(?P<activityname>(?:[^"]|\\")*)" is displayed as "(?P<completionstatus>(?:[^"]|\\")*)"$/
|
||||
* @param string $activityname The activity name.
|
||||
* @param string $completionstatus The completion status shown on the manual completion button.
|
||||
* Must be either 'Mark as done' or 'Done'.
|
||||
*/
|
||||
public function manual_completion_button_displayed_as(string $activityname, string $completionstatus): void {
|
||||
if (!in_array($completionstatus, ['Mark as done', 'Done'])) {
|
||||
throw new coding_exception('Invalid completion status. It must be "Mark as done" or "Done".');
|
||||
}
|
||||
|
||||
$langstringkey = $completionstatus === 'Done' ? 'done' : 'markdone';
|
||||
$conditionslistlabel = get_string('completion_manual:aria:' . $langstringkey, 'core_course', $activityname);
|
||||
$selector = "button[aria-label='$conditionslistlabel']";
|
||||
|
||||
$this->execute("behat_general::assert_element_contains_text", [$completionstatus, $selector, "css_element"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the manual completion state of an activity.
|
||||
*
|
||||
* @Given /^the manual completion button of "(?P<activityname>(?:[^"]|\\")*)" overridden by "(?P<username>(?:[^"]|\\")*)" is displayed as "(?P<completionstatus>(?:[^"]|\\")*)"$/
|
||||
* @param string $activityname The activity name.
|
||||
* @param string $username The full name of the user overriding the student's activity completion.
|
||||
* @param string $completionstatus The completion status shown on the manual completion button.
|
||||
* Must be either 'Mark as done' or 'Done'.
|
||||
*/
|
||||
public function overridden_manual_completion_button_displayed_as(string $activityname, string $username,
|
||||
string $completionstatus): void {
|
||||
if (!in_array($completionstatus, ['Mark as done', 'Done'])) {
|
||||
throw new coding_exception('Invalid completion status. It must be "Mark as done" or "Done".');
|
||||
}
|
||||
|
||||
$langstringkey = $completionstatus === 'Done' ? 'done' : 'markdone';
|
||||
$conditionslistlabel = get_string('completion_setby:manual:' . $langstringkey, 'core_course', (object)[
|
||||
'activityname' => $activityname,
|
||||
'setby' => $username,
|
||||
]);
|
||||
$selector = "button[aria-label='$conditionslistlabel']";
|
||||
|
||||
$this->execute("behat_general::assert_element_contains_text", [$completionstatus, $selector, "css_element"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the manual completion button for a given activity.
|
||||
*
|
||||
* @Given /^I toggle the manual completion state of "(?P<activityname>(?:[^"]|\\")*)"$/
|
||||
* @param string $activityname The activity name.
|
||||
*/
|
||||
public function toggle_the_manual_completion_state(string $activityname): void {
|
||||
$selector = "button[data-action=toggle-manual-completion][data-activityname='{$activityname}']";
|
||||
|
||||
$this->execute("behat_general::i_click_on", [$selector, "css_element"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the activity does show completion information.
|
||||
*
|
||||
* @Given /^there should be no completion information shown for "(?P<activityname>(?:[^"]|\\")*)"$/
|
||||
* @param string $activityname The activity name.
|
||||
*/
|
||||
public function there_should_be_no_completion_for_activity(string $activityname): void {
|
||||
$containerselector = "div[data-region=activity-information][data-activityname='$activityname']";
|
||||
try {
|
||||
$this->find('css_element', $containerselector);
|
||||
} catch (ElementNotFoundException $e) {
|
||||
// If activity information container does not exist (activity dates not shown, completion info not shown), all good.
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, ensure that the completion information does not exist.
|
||||
$elementselector = "div[data-region=completion-info]";
|
||||
$params = [$elementselector, "css_element", $containerselector, "css_element"];
|
||||
$this->execute("behat_general::should_not_exist_in_the", $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the manual completion button for the activity is disabled.
|
||||
*
|
||||
* @Given /^the manual completion button for "(?P<activityname>(?:[^"]|\\")*)" should be disabled$/
|
||||
* @param string $activityname The activity name.
|
||||
*/
|
||||
public function the_manual_completion_button_for_activity_should_be_disabled(string $activityname): void {
|
||||
$selector = "div[data-activityname='$activityname'] button";
|
||||
|
||||
$params = [$selector, "css_element"];
|
||||
$this->execute("behat_general::the_element_should_be_disabled", $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the activity has the given automatic completion condition.
|
||||
*
|
||||
* @Given /^"(?P<activityname>(?:[^"]|\\")*)" should have the "(?P<conditionname>(?:[^"]|\\")*)" completion condition$/
|
||||
* @param string $activityname The activity name.
|
||||
* @param string $conditionname The automatic condition name.
|
||||
*/
|
||||
public function activity_should_have_the_completion_condition(string $activityname, string $conditionname): void {
|
||||
$containerselector = "div[data-region=activity-information][data-activityname='$activityname']";
|
||||
|
||||
$params = [$conditionname, $containerselector, 'css_element'];
|
||||
$this->execute("behat_general::assert_element_contains_text", $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the activity with specified name shows a information completion checkbox (i.e. showing the completion tracking
|
||||
* configuration).
|
||||
|
||||
+13
-13
@@ -2,7 +2,7 @@
|
||||
Feature: Show activity completion status or activity completion configuration on the course page
|
||||
In order to understand the configuration or status of an activity's completion
|
||||
As a user
|
||||
I want to see an appropriate checkbox icon besides the activity
|
||||
I need to see the appropriate completion information for each activity in the course homepage
|
||||
|
||||
Background:
|
||||
Given the following "courses" exist:
|
||||
@@ -39,27 +39,27 @@ Feature: Show activity completion status or activity completion configuration on
|
||||
Given I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
Then I should see "Your progress"
|
||||
And the "Test forum name" "Forum" activity with "manual" completion shows a status completion checkbox
|
||||
And the "Test assignment name" "Assign" activity with "auto" completion shows a status completion checkbox
|
||||
And the "Test quiz name" "Quiz" activity does not show any completion checkbox
|
||||
And the manual completion button of "Test forum name" is displayed as "Mark as done"
|
||||
And the "View" completion condition of "Test assignment name" is displayed as "todo"
|
||||
And there should be no completion information shown for "Test quiz name"
|
||||
|
||||
Scenario: Show completion configuration to editing teachers
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
Then I should not see "Your progress"
|
||||
And the "Test forum name" "Forum" activity with "manual" completion shows a configuration completion checkbox
|
||||
And the "Test assignment name" "Assign" activity with "auto" completion shows a configuration completion checkbox
|
||||
And the "Test quiz name" "Quiz" activity does not show any completion checkbox
|
||||
And the manual completion button for "Test forum name" should be disabled
|
||||
And "Test assignment name" should have the "View" completion condition
|
||||
And there should be no completion information shown for "Test quiz name"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I should not see "Your progress"
|
||||
And the "Test forum name" "Forum" activity with "manual" completion shows a configuration completion checkbox
|
||||
And the "Test assignment name" "Assign" activity with "auto" completion shows a configuration completion checkbox
|
||||
And the "Test quiz name" "Quiz" activity does not show any completion checkbox
|
||||
And the manual completion button for "Test forum name" should be disabled
|
||||
And "Test assignment name" should have the "View" completion condition
|
||||
And there should be no completion information shown for "Test quiz name"
|
||||
|
||||
Scenario: Show completion configuration to non-editing teachers
|
||||
Given I log in as "teacher2"
|
||||
And I am on "Course 1" course homepage
|
||||
Then I should not see "Your progress"
|
||||
And the "Test forum name" "Forum" activity with "manual" completion shows a configuration completion checkbox
|
||||
And the "Test assignment name" "Assign" activity with "auto" completion shows a configuration completion checkbox
|
||||
And the "Test quiz name" "Quiz" activity does not show any completion checkbox
|
||||
And the manual completion button for "Test forum name" should be disabled
|
||||
And "Test assignment name" should have the "View" completion condition
|
||||
And there should be no completion information shown for "Test quiz name"
|
||||
@@ -31,8 +31,8 @@ Feature: Allow students to manually mark an activity as complete
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
When I click on "Not completed: Test forum name. Select to mark as complete." "icon"
|
||||
Then the "Test forum name" "forum" activity with "manual" completion should be marked as complete
|
||||
When I toggle the manual completion state of "Test forum name"
|
||||
Then the manual completion button of "Test forum name" is displayed as "Done"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
|
||||
@@ -45,7 +45,7 @@ Feature: Restrict sections availability through completion or grade conditions
|
||||
And I am on "Course 1" course homepage
|
||||
Then I should see "Not available unless: The activity Test label is marked complete"
|
||||
And I should not see "Test page name"
|
||||
And I click on "Not completed: Test label. Select to mark as complete." "icon"
|
||||
And I toggle the manual completion state of "Test label"
|
||||
And I should see "Test page name"
|
||||
And I should not see "Not available unless: The activity Test label is marked complete"
|
||||
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
This files describes API changes in /completion/* - completion,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 3.11 ===
|
||||
* New Behat steps for activity completion in the behat_completion class:
|
||||
- activity_completion_condition_displayed_as()
|
||||
- Given the "<Completion condition>" completion condition of "<Activity name>" is displayed as "<Status>"
|
||||
- activity_should_have_the_completion_condition()
|
||||
- Given "<Activity name>" should have the "<Condition name>" completion condition
|
||||
- manual_completion_button_displayed_as()
|
||||
- Given the manual completion button of "<Activity name>" is displayed as "<Status>"
|
||||
- the_manual_completion_button_for_activity_should_be_disabled()
|
||||
- Given the manual completion button for "<Activity name>" should be disabled
|
||||
- there_should_be_no_completion_for_activity()
|
||||
- Given there should be no completion information shown for "<Activity name>"
|
||||
- toggle_the_manual_completion_state()
|
||||
- Given I toggle the manual completion state of "<Activity name>"
|
||||
- overridden_manual_completion_button_displayed_as
|
||||
- Given the manual completion button of "<Activity name>" overridden by "<User>" is displayed as "<Status>"
|
||||
- overridden_activity_completion_condition_displayed_as
|
||||
- Given the "<Completion condition>" completion condition of "<Activity name>" overridden by "<User>" is displayed as "<Status>"
|
||||
|
||||
=== 3.7 ===
|
||||
* External function core_completion_external::get_activities_completion_status new returns the following additional field:
|
||||
- valueused (indicates whether the completion state affects the availability of other content)
|
||||
|
||||
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("core_course/events",[],function(){return{favourited:"core_course:favourited",unfavorited:"core_course:unfavorited"}});
|
||||
define ("core_course/events",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;a.default={favourited:"core_course:favourited",unfavorited:"core_course:unfavorited",manualCompletionToggled:"core_course:manualcompletiontoggled"};return a.default});
|
||||
//# sourceMappingURL=events.min.js.map
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sources":["../src/events.js"],"names":["define","favourited","unfavorited"],"mappings":"AAuBAA,OAAM,sBAAC,EAAD,CAAK,UAAW,CAClB,MAAO,CACHC,UAAU,CAAE,wBADT,CAEHC,WAAW,CAAE,yBAFV,CAIV,CALK,CAAN","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 * Contain the events the course component can trigger.\n *\n * @module core_course/events\n * @package core_course\n * @copyright 2018 Simey Lameze <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([], function() {\n return {\n favourited: 'core_course:favourited',\n unfavorited: 'core_course:unfavorited',\n };\n});"],"file":"events.min.js"}
|
||||
{"version":3,"sources":["../src/events.js"],"names":["favourited","unfavorited","manualCompletionToggled"],"mappings":"8IAuBe,CACXA,UAAU,CAAE,wBADD,CAEXC,WAAW,CAAE,yBAFF,CAGXC,uBAAuB,CAAE,qCAHd,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 * Contain the events the course component can trigger.\n *\n * @module core_course/events\n * @package core_course\n * @copyright 2018 Simey Lameze <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nexport default {\n favourited: 'core_course:favourited',\n unfavorited: 'core_course:unfavorited',\n manualCompletionToggled: 'core_course:manualcompletiontoggled',\n};\n"],"file":"events.min.js"}
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("core_course/manual_completion_toggle",["exports","core/templates","core/notification","core_course/repository"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=e(b);c=e(c);function e(a){return a&&a.__esModule?a:{default:a}}function f(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 g(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var i=a.apply(b,c);function g(a){f(i,d,e,g,h,"next",a)}function h(a){f(i,d,e,g,h,"throw",a)}g(void 0)})}}var h={MANUAL_TOGGLE:"button[data-action=toggle-manual-completion]"},i={TOGGLE_MARK_DONE:"manual:mark-done",TOGGLE_UNDO:"manual:undo"},j=!1,k=function(){if(j){return}document.addEventListener("click",function(a){var b=a.target.closest(h.MANUAL_TOGGLE);if(b){a.preventDefault();l(b).catch(c.default.exception)}});j=!0};a.init=k;var l=function(){var a=g(regeneratorRuntime.mark(function a(e){var f,g,h,j,k,l,m,n;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:f=e.innerHTML;e.setAttribute("disabled","disabled");g=e.getAttribute("data-toggletype");h=e.getAttribute("data-cmid");j=e.getAttribute("data-activityname");k=g===i.TOGGLE_MARK_DONE;a.next=8;return b.default.render("core/loading",{});case 8:l=a.sent;a.next=11;return b.default.replaceNodeContents(e,l,"");case 11:a.prev=11;a.next=14;return(0,d.toggleManualCompletion)(h,k);case 14:m={cmid:h,activityname:j,overallcomplete:k,overallincomplete:!k,istrackeduser:!0};a.next=17;return b.default.renderForPromise("core_course/completion_manual",m);case 17:n=a.sent;a.next=20;return b.default.replaceNode(e,n.html,n.js);case 20:a.next=27;break;case 22:a.prev=22;a.t0=a["catch"](11);e.removeAttribute("disabled");e.innerHTML=f;c.default.exception(a.t0);case 27:case"end":return a.stop();}}},a,null,[[11,22]])}));return function(){return a.apply(this,arguments)}}()});
|
||||
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core_course/manual_completion_toggle",["exports","core/templates","core/notification","core_course/repository","core_course/events"],function(a,b,c,d,e){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=h(b);c=h(c);e=g(e);function f(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;f=function(){return a};return a}function g(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=f();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var g=d?Object.getOwnPropertyDescriptor(a,e):null;if(g&&(g.get||g.set)){Object.defineProperty(c,e,g)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function h(a){return a&&a.__esModule?a:{default:a}}function i(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 j(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){i(h,d,e,f,g,"next",a)}function g(a){i(h,d,e,f,g,"throw",a)}f(void 0)})}}var k={MANUAL_TOGGLE:"button[data-action=toggle-manual-completion]"},l={TOGGLE_MARK_DONE:"manual:mark-done",TOGGLE_UNDO:"manual:undo"},m=!1,n=function(){if(m){return}document.addEventListener("click",function(a){var b=a.target.closest(k.MANUAL_TOGGLE);if(b){a.preventDefault();o(b).catch(c.default.exception)}});m=!0};a.init=n;var o=function(){var a=j(regeneratorRuntime.mark(function a(f){var g,h,i,j,k,m,n,o,p,q,r,s;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:g=f.innerHTML;f.setAttribute("disabled","disabled");h=f.getAttribute("data-toggletype");i=f.getAttribute("data-cmid");j=f.getAttribute("data-activityname");k=h===l.TOGGLE_MARK_DONE;a.next=8;return b.default.render("core/loading",{});case 8:m=a.sent;a.next=11;return b.default.replaceNodeContents(f,m,"");case 11:a.prev=11;a.next=14;return(0,d.toggleManualCompletion)(i,k);case 14:n={cmid:i,activityname:j,overallcomplete:k,overallincomplete:!k,istrackeduser:!0};a.next=17;return b.default.renderForPromise("core_course/completion_manual",n);case 17:o=a.sent;a.next=20;return b.default.replaceNode(f,o.html,o.js);case 20:p=a.sent;q=p.pop();r=f.getAttribute("data-withavailability");s=new CustomEvent(e.manualCompletionToggled,{bubbles:!0,detail:{cmid:i,activityname:j,completed:k,withAvailability:r}});q.dispatchEvent(s);a.next=32;break;case 27:a.prev=27;a.t0=a["catch"](11);f.removeAttribute("disabled");f.innerHTML=g;c.default.exception(a.t0);case 32:case"end":return a.stop();}}},a,null,[[11,27]])}));return function(){return a.apply(this,arguments)}}()});
|
||||
//# sourceMappingURL=manual_completion_toggle.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core_course/view",["exports","core_course/events"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=d(b);function c(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;c=function(){return a};return a}function d(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=c();if(b&&b.has(a)){return b.get(a)}var d={},e=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var f in a){if(Object.prototype.hasOwnProperty.call(a,f)){var g=e?Object.getOwnPropertyDescriptor(a,f):null;if(g&&(g.get||g.set)){Object.defineProperty(d,f,g)}else{d[f]=a[f]}}}d.default=a;if(b){b.set(a,d)}return d}var e=!1,f=function(){if(e){return}document.addEventListener(b.manualCompletionToggled,function(a){var b=parseInt(a.detail.withAvailability);if(b){window.location.reload()}});e=!0};a.init=f});
|
||||
//# sourceMappingURL=view.min.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/view.js"],"names":["registered","init","document","addEventListener","CourseEvents","manualCompletionToggled","e","withAvailability","parseInt","detail","window","location","reload"],"mappings":"ybAwBA,O,yiBAOIA,CAAAA,CAAU,G,CAKDC,CAAI,CAAG,UAAM,CACtB,GAAID,CAAJ,CAAgB,CACZ,MACH,CAEDE,QAAQ,CAACC,gBAAT,CAA0BC,CAAY,CAACC,uBAAvC,CAAgE,SAACC,CAAD,CAAO,CACnE,GAAMC,CAAAA,CAAgB,CAAGC,QAAQ,CAACF,CAAC,CAACG,MAAF,CAASF,gBAAV,CAAjC,CACA,GAAIA,CAAJ,CAAsB,CAElBG,MAAM,CAACC,QAAP,CAAgBC,MAAhB,EACH,CACJ,CAND,EAOAZ,CAAU,GACb,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 * JS module for the course homepage.\n *\n * @module core_course/view\n * @package core_course\n * @copyright 2021 Jun Pataleta <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as CourseEvents from 'core_course/events';\n\n/**\n * Whether the event listener has already been registered for this module.\n *\n * @type {boolean}\n */\nlet registered = false;\n\n/**\n * Function to intialise and register event listeners for this module.\n */\nexport const init = () => {\n if (registered) {\n return;\n }\n // Listen for toggled manual completion states of activities.\n document.addEventListener(CourseEvents.manualCompletionToggled, (e) => {\n const withAvailability = parseInt(e.detail.withAvailability);\n if (withAvailability) {\n // Reload the page when the toggled manual completion button has availability conditions linked to it.\n window.location.reload();\n }\n });\n registered = true;\n};\n"],"file":"view.min.js"}
|
||||
@@ -21,9 +21,8 @@
|
||||
* @copyright 2018 Simey Lameze <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define([], function() {
|
||||
return {
|
||||
favourited: 'core_course:favourited',
|
||||
unfavorited: 'core_course:unfavorited',
|
||||
};
|
||||
});
|
||||
export default {
|
||||
favourited: 'core_course:favourited',
|
||||
unfavorited: 'core_course:unfavorited',
|
||||
manualCompletionToggled: 'core_course:manualcompletiontoggled',
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
import Templates from 'core/templates';
|
||||
import Notification from 'core/notification';
|
||||
import {toggleManualCompletion} from 'core_course/repository';
|
||||
import * as CourseEvents from 'core_course/events';
|
||||
|
||||
/**
|
||||
* Selectors in the manual completion template.
|
||||
@@ -109,7 +110,22 @@ const toggleManualCompletionState = async(toggleButton) => {
|
||||
const renderObject = await Templates.renderForPromise('core_course/completion_manual', templateContext);
|
||||
|
||||
// Replace the toggle button with the newly loaded template.
|
||||
await Templates.replaceNode(toggleButton, renderObject.html, renderObject.js);
|
||||
const replacedNode = await Templates.replaceNode(toggleButton, renderObject.html, renderObject.js);
|
||||
const newToggleButton = replacedNode.pop();
|
||||
|
||||
// Build manualCompletionToggled custom event.
|
||||
const withAvailability = toggleButton.getAttribute('data-withavailability');
|
||||
const toggledEvent = new CustomEvent(CourseEvents.manualCompletionToggled, {
|
||||
bubbles: true,
|
||||
detail: {
|
||||
cmid,
|
||||
activityname,
|
||||
completed,
|
||||
withAvailability,
|
||||
}
|
||||
});
|
||||
// Dispatch the manualCompletionToggled custom event.
|
||||
newToggleButton.dispatchEvent(toggledEvent);
|
||||
|
||||
} catch (exception) {
|
||||
// In case of an error, revert the original state and appearance of the button.
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* JS module for the course homepage.
|
||||
*
|
||||
* @module core_course/view
|
||||
* @package core_course
|
||||
* @copyright 2021 Jun Pataleta <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import * as CourseEvents from 'core_course/events';
|
||||
|
||||
/**
|
||||
* Whether the event listener has already been registered for this module.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
let registered = false;
|
||||
|
||||
/**
|
||||
* Function to intialise and register event listeners for this module.
|
||||
*/
|
||||
export const init = () => {
|
||||
if (registered) {
|
||||
return;
|
||||
}
|
||||
// Listen for toggled manual completion states of activities.
|
||||
document.addEventListener(CourseEvents.manualCompletionToggled, (e) => {
|
||||
const withAvailability = parseInt(e.detail.withAvailability);
|
||||
if (withAvailability) {
|
||||
// Reload the page when the toggled manual completion button has availability conditions linked to it.
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
registered = true;
|
||||
};
|
||||
@@ -29,6 +29,7 @@ use cm_info;
|
||||
use completion_info;
|
||||
use context;
|
||||
use core\activity_dates;
|
||||
use core_availability\info;
|
||||
use core_completion\cm_completion_details;
|
||||
use core_user;
|
||||
use core_user\fields;
|
||||
@@ -80,6 +81,7 @@ class activity_information implements renderable, templatable {
|
||||
$data->cmid = $this->cminfo->id;
|
||||
$data->activityname = $this->cminfo->name;
|
||||
$data->activitydates = $this->activitydates;
|
||||
$data->hasdates = !empty($this->activitydates);
|
||||
|
||||
return $data;
|
||||
}
|
||||
@@ -90,6 +92,8 @@ class activity_information implements renderable, templatable {
|
||||
* @return stdClass
|
||||
*/
|
||||
protected function build_completion_data(): stdClass {
|
||||
global $CFG;
|
||||
|
||||
$data = new stdClass();
|
||||
|
||||
$data->hascompletion = $this->cmcompletion->has_completion();
|
||||
@@ -124,6 +128,19 @@ class activity_information implements renderable, templatable {
|
||||
$data->accessibledescription = get_string($setbylangkey, 'course', $setbydata);
|
||||
}
|
||||
|
||||
// Whether the completion of this activity controls the availability of other activities/sections in the course.
|
||||
$data->withavailability = false;
|
||||
$course = $this->cminfo->get_course();
|
||||
// An activity with manual completion tracking which is used to enable access to other activities/sections in
|
||||
// the course needs to refresh the page after having its completion state toggled. This withavailability flag will enable
|
||||
// this functionality on the course homepage. Otherwise, the completion toggling will just happen normally via ajax.
|
||||
if ($this->cmcompletion->has_completion() && !$this->cmcompletion->is_automatic()) {
|
||||
$data->withavailability = !empty($CFG->enableavailability) && info::completion_value_used($course, $this->cminfo->id);
|
||||
}
|
||||
|
||||
// Whether this activity is visible to the user. If not, completion information will not be shown.
|
||||
$data->uservisible = $this->cminfo->uservisible;
|
||||
|
||||
// Build automatic completion details.
|
||||
$details = [];
|
||||
foreach ($this->cmcompletion->get_details() as $key => $detail) {
|
||||
@@ -139,7 +156,8 @@ class activity_information implements renderable, templatable {
|
||||
'condition' => $detail->description,
|
||||
'setby' => $data->overrideby,
|
||||
];
|
||||
$detail->accessibledescription = get_string('completion_setby:auto', 'course', $setbydata);
|
||||
$overridestatus = $detail->statuscomplete ? 'done' : 'todo';
|
||||
$detail->accessibledescription = get_string('completion_setby:auto:' . $overridestatus, 'course', $setbydata);
|
||||
}
|
||||
|
||||
// We don't need the status in the template.
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
|
||||
M.core_completion = {};
|
||||
|
||||
M.core_completion.init = function(Y) {
|
||||
// Check the reload-forcing
|
||||
var changeDetector = Y.one('#completion_dynamic_change');
|
||||
if (changeDetector.get('value') > 0) {
|
||||
changeDetector.set('value', 0);
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
|
||||
var handle_success = function(id, o, args) {
|
||||
Y.one('#completion_dynamic_change').set('value', 1);
|
||||
|
||||
if (o.responseText != 'OK') {
|
||||
alert('An error occurred when attempting to save your tick mark.\n\n('+o.responseText+'.)'); //TODO: localize
|
||||
|
||||
} else {
|
||||
var current = args.state.get('value');
|
||||
var modulename = args.modulename.get('value'),
|
||||
altstr,
|
||||
iconkey,
|
||||
button = args.image.get('parentNode');
|
||||
|
||||
if (current == 1) {
|
||||
altstr = M.util.get_string('completion-alt-manual-y', 'completion', modulename);
|
||||
iconkey = 'i/completion-manual-y';
|
||||
args.state.set('value', 0);
|
||||
} else {
|
||||
altstr = M.util.get_string('completion-alt-manual-n', 'completion', modulename);
|
||||
iconkey = 'i/completion-manual-n';
|
||||
args.state.set('value', 1);
|
||||
}
|
||||
|
||||
require(['core/templates', 'core/notification'], function(Templates, Notification) {
|
||||
Templates.renderPix(iconkey, 'core', altstr).then(function(html) {
|
||||
var id = button.get('id'),
|
||||
postFocus = '$(document.getElementById("' + id + '")).focus();';
|
||||
|
||||
Templates.replaceNode(args.image.getDOMNode(), html, postFocus);
|
||||
}).catch(Notification.exception);
|
||||
});
|
||||
}
|
||||
|
||||
args.ajax.remove();
|
||||
};
|
||||
|
||||
var handle_failure = function(id, o, args) {
|
||||
alert('An error occurred when attempting to save your tick mark.\n\n('+o.responseText+'.)'); //TODO: localize
|
||||
args.ajax.remove();
|
||||
};
|
||||
|
||||
var toggle = function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var form = e.target;
|
||||
var cmid = 0;
|
||||
var completionstate = 0;
|
||||
var state = null;
|
||||
var image = null;
|
||||
var modulename = null;
|
||||
|
||||
var inputs = Y.Node.getDOMNode(form).getElementsByTagName('input');
|
||||
for (var i=0; i<inputs.length; i++) {
|
||||
switch (inputs[i].name) {
|
||||
case 'id':
|
||||
cmid = inputs[i].value;
|
||||
break;
|
||||
case 'completionstate':
|
||||
completionstate = inputs[i].value;
|
||||
state = Y.one(inputs[i]);
|
||||
break;
|
||||
case 'modulename':
|
||||
modulename = Y.one(inputs[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
image = form.one('button .icon');
|
||||
|
||||
// start spinning the ajax indicator
|
||||
var ajax = Y.Node.create('<div class="ajaxworking" />');
|
||||
form.append(ajax);
|
||||
|
||||
var cfg = {
|
||||
method: "POST",
|
||||
data: 'id='+cmid+'&completionstate='+completionstate+'&fromajax=1&sesskey='+M.cfg.sesskey,
|
||||
on: {
|
||||
success: handle_success,
|
||||
failure: handle_failure
|
||||
},
|
||||
arguments: {state: state, image: image, ajax: ajax, modulename: modulename}
|
||||
};
|
||||
|
||||
Y.use('io-base', function(Y) {
|
||||
Y.io(M.cfg.wwwroot+'/course/togglecompletion.php', cfg);
|
||||
});
|
||||
};
|
||||
|
||||
// register submit handlers on manual tick completion forms
|
||||
Y.all('form.togglecompletion').each(function(form) {
|
||||
if (!form.hasClass('preventjs')) {
|
||||
Y.on('submit', toggle, form);
|
||||
}
|
||||
});
|
||||
|
||||
// hide the help if there are no completion toggles or icons
|
||||
var help = Y.one('#completionprogressid');
|
||||
if (help && !(Y.one('form.togglecompletion') || Y.one('.autocompletion'))) {
|
||||
help.setStyle('display', 'none');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+20
-4
@@ -425,6 +425,10 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
* If completion is manual, returns a form (with an icon inside) that allows user to
|
||||
* toggle completion
|
||||
*
|
||||
* @deprecated since Moodle 3.11
|
||||
* @todo MDL-71183 Final deprecation in Moodle 4.3.
|
||||
* @see \core_renderer::activity_information
|
||||
*
|
||||
* @param stdClass $course course object
|
||||
* @param completion_info $completioninfo completion info for the course, it is recommended
|
||||
* to fetch once for all modules in course/section for performance
|
||||
@@ -434,6 +438,10 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
*/
|
||||
public function course_section_cm_completion($course, &$completioninfo, cm_info $mod, $displayoptions = array()) {
|
||||
global $CFG, $DB, $USER;
|
||||
|
||||
debugging(__FUNCTION__ . ' is deprecated and is being replaced by the activity_information output component.',
|
||||
DEBUG_DEVELOPER);
|
||||
|
||||
$output = '';
|
||||
|
||||
$istrackeduser = $completioninfo->is_tracked_user($USER->id);
|
||||
@@ -828,7 +836,12 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
public function course_section_cm_list_item($course, &$completioninfo, cm_info $mod, $sectionreturn, $displayoptions = array()) {
|
||||
$output = '';
|
||||
if ($modulehtml = $this->course_section_cm($course, $completioninfo, $mod, $sectionreturn, $displayoptions)) {
|
||||
$modclasses = 'activity ' . $mod->modname . ' modtype_' . $mod->modname . ' ' . $mod->extraclasses;
|
||||
$infoclass = '';
|
||||
if (($course->showcompletionconditions == COMPLETION_SHOW_CONDITIONS) || !empty($course->showactivitydates)) {
|
||||
// This will apply styles to the course homepage when the activity information output component is displayed.
|
||||
$infoclass = 'hasinfo';
|
||||
}
|
||||
$modclasses = 'activity ' . $mod->modname . ' modtype_' . $mod->modname . ' ' . $mod->extraclasses . ' ' . $infoclass;
|
||||
$output .= html_writer::tag('li', $modulehtml, array('class' => $modclasses, 'id' => 'module-' . $mod->id));
|
||||
}
|
||||
return $output;
|
||||
@@ -844,7 +857,6 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
* {@link core_course_renderer::course_section_cm_name()}
|
||||
* {@link core_course_renderer::course_section_cm_text()}
|
||||
* {@link core_course_renderer::course_section_cm_availability()}
|
||||
* {@link core_course_renderer::course_section_cm_completion()}
|
||||
* {@link course_get_cm_edit_actions()}
|
||||
* {@link core_course_renderer::course_section_cm_edit_actions()}
|
||||
*
|
||||
@@ -856,6 +868,8 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
* @return string
|
||||
*/
|
||||
public function course_section_cm($course, &$completioninfo, cm_info $mod, $sectionreturn, $displayoptions = array()) {
|
||||
global $USER;
|
||||
|
||||
$output = '';
|
||||
// We return empty string (because course module will not be displayed at all)
|
||||
// if:
|
||||
@@ -925,12 +939,14 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
$modicons .= $mod->afterediticons;
|
||||
}
|
||||
|
||||
$modicons .= $this->course_section_cm_completion($course, $completioninfo, $mod, $displayoptions);
|
||||
|
||||
if (!empty($modicons)) {
|
||||
$output .= html_writer::div($modicons, 'actions');
|
||||
}
|
||||
|
||||
$completiondetails = \core_completion\cm_completion_details::get_instance($mod, $USER->id);
|
||||
$activitydates = \core\activity_dates::get_dates_for_module($mod, $USER->id);
|
||||
$output .= $this->output->activity_information($mod, $completiondetails, $activitydates);
|
||||
|
||||
// Show availability info (if module is not available).
|
||||
$output .= $this->course_section_cm_availability($mod, $displayoptions);
|
||||
|
||||
|
||||
@@ -24,7 +24,10 @@
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"activityname": "Course announcements",
|
||||
"hascompletion": true,
|
||||
"uservisible": true,
|
||||
"hasdates": true,
|
||||
"isautomatic": true,
|
||||
"istrackeduser": true,
|
||||
"activitydates": [
|
||||
@@ -45,24 +48,28 @@
|
||||
]
|
||||
}
|
||||
}}
|
||||
<div data-region="activity-information" class="activity-information">
|
||||
<div class="mb-1">
|
||||
<div data-region="activity-information" data-activityname="{{activityname}}" class="activity-information">
|
||||
{{#hasdates}}
|
||||
<div data-region="activity-dates" class="mb-1">
|
||||
{{#activitydates}}
|
||||
{{>core_course/activity_date}}
|
||||
{{/activitydates}}
|
||||
</div>
|
||||
<div>
|
||||
{{#hascompletion}}
|
||||
{{#isautomatic}}
|
||||
<div class="automatic-completion-conditions" data-region ="completionrequirements" role="list" aria-label="{{#str}}completionrequirements, core_course{{/str}}">
|
||||
{{#completiondetails}}
|
||||
{{> core_course/completion_automatic }}
|
||||
{{/completiondetails}}
|
||||
</div>
|
||||
{{/isautomatic}}
|
||||
{{^isautomatic}}
|
||||
{{> core_course/completion_manual }}
|
||||
{{/isautomatic}}
|
||||
{{/hascompletion}}
|
||||
</div>
|
||||
{{/hasdates}}
|
||||
{{#hascompletion}}
|
||||
{{#uservisible}}
|
||||
<div data-region="completion-info">
|
||||
{{#isautomatic}}
|
||||
<div class="automatic-completion-conditions" data-region ="completionrequirements" role="list" aria-label="{{#str}}completionrequirements, core_course, {{activityname}}{{/str}}">
|
||||
{{#completiondetails}}
|
||||
{{> core_course/completion_automatic }}
|
||||
{{/completiondetails}}
|
||||
</div>
|
||||
{{/isautomatic}}
|
||||
{{^isautomatic}}
|
||||
{{> core_course/completion_manual }}
|
||||
{{/isautomatic}}
|
||||
</div>
|
||||
{{/uservisible}}
|
||||
{{/hascompletion}}
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
}}
|
||||
{{#istrackeduser}}
|
||||
{{#overallcomplete}}
|
||||
<button class="btn btn-outline-success" data-action="toggle-manual-completion" data-toggletype="manual:undo" data-cmid="{{cmid}}" data-activityname="{{activityname}}" {{!
|
||||
<button class="btn btn-outline-success" data-action="toggle-manual-completion" data-toggletype="manual:undo" data-cmid="{{cmid}}" data-activityname="{{activityname}}" data-withavailability="{{withavailability}}" {{!
|
||||
}}{{#accessibledescription}}{{!
|
||||
}}title="{{.}}" {{!
|
||||
}}aria-label="{{.}}" {{!
|
||||
@@ -41,7 +41,7 @@
|
||||
</button>
|
||||
{{/overallcomplete}}
|
||||
{{#overallincomplete}}
|
||||
<button class="btn btn-outline-secondary" data-action="toggle-manual-completion" data-toggletype="manual:mark-done" data-cmid="{{cmid}}" data-activityname="{{activityname}}" {{!
|
||||
<button class="btn btn-outline-secondary" data-action="toggle-manual-completion" data-toggletype="manual:mark-done" data-cmid="{{cmid}}" data-activityname="{{activityname}}" data-withavailability="{{withavailability}}" {{!
|
||||
}}{{#accessibledescription}}{{!
|
||||
}}title="{{.}}" {{!
|
||||
}}aria-label="{{.}}" {{!
|
||||
|
||||
@@ -2035,4 +2035,53 @@ class behat_course extends behat_base {
|
||||
$node = $this->get_selected_node('xpath_element', '//div[@data-region="modules"]');
|
||||
$this->ensure_node_is_visible($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the presence of the given text in the activity's displayed dates.
|
||||
*
|
||||
* @Given /^the activity date in "(?P<activityname>(?:[^"]|\\")*)" should contain "(?P<text>(?:[^"]|\\")*)"$/
|
||||
* @param string $activityname The activity name.
|
||||
* @param string $text The text to be searched in the activity date.
|
||||
*/
|
||||
public function activity_date_in_activity_should_contain_text(string $activityname, string $text): void {
|
||||
$containerselector = "//div[@data-region='activity-information'][@data-activityname='$activityname']";
|
||||
$containerselector .= " /div[@data-region='activity-dates']";
|
||||
|
||||
$params = [$text, $containerselector, 'xpath_element'];
|
||||
$this->execute("behat_general::assert_element_contains_text", $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the presence of activity dates information in the activity information output component.
|
||||
*
|
||||
* @Given /^the activity date information in "(?P<activityname>(?:[^"]|\\")*)" should exist$/
|
||||
* @param string $activityname The activity name.
|
||||
*/
|
||||
public function activity_dates_information_in_activity_should_exist(string $activityname): void {
|
||||
$containerselector = "//div[@data-region='activity-information'][@data-activityname='$activityname']";
|
||||
$elementselector = "/div[@data-region='activity-dates']";
|
||||
$params = [$elementselector, "xpath_element", $containerselector, "xpath_element"];
|
||||
$this->execute("behat_general::should_exist_in_the", $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the absence of activity dates information in the activity information output component.
|
||||
*
|
||||
* @Given /^the activity date information in "(?P<activityname>(?:[^"]|\\")*)" should not exist$/
|
||||
* @param string $activityname The activity name.
|
||||
*/
|
||||
public function activity_dates_information_in_activity_should_not_exist(string $activityname): void {
|
||||
$containerselector = "//div[@data-region='activity-information'][@data-activityname='$activityname']";
|
||||
try {
|
||||
$this->find('xpath_element', $containerselector);
|
||||
} catch (ElementNotFoundException $e) {
|
||||
// If activity information container does not exist (activity dates not shown, completion info not shown), all good.
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, ensure that the completion information does not exist.
|
||||
$elementselector = "//div[@data-region='activity-dates']";
|
||||
$params = [$elementselector, "xpath_element", $containerselector, "xpath_element"];
|
||||
$this->execute("behat_general::should_not_exist_in_the", $params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ Feature: Allow teachers to edit the visibility of activity dates in a course
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | timeopen | timeclose |
|
||||
| choice | C1 | choice1 | Test choice 1 | Test choice description | ##yesterday## | ##tomorrow## |
|
||||
| choice | C1 | choice1 | Test choice | Test choice description | ##yesterday## | ##tomorrow## |
|
||||
|
||||
Scenario: Activity dates setting can be enabled to display activity dates in a course
|
||||
Given I log in as "teacher1"
|
||||
@@ -26,11 +26,16 @@ Feature: Allow teachers to edit the visibility of activity dates in a course
|
||||
| Show activity dates | Yes |
|
||||
And I click on "Save and display" "button"
|
||||
And I follow "Test choice"
|
||||
Then I should see "Opened:" in the "[data-region=activity-information]" "css_element"
|
||||
And I should see "Closes:" in the "[data-region=activity-information]" "css_element"
|
||||
# TODO MDL-70821: Check activity dates display on course homepage.
|
||||
Then the activity date information in "Test choice" should exist
|
||||
And the activity date in "Test choice" should contain "Opened:"
|
||||
And the activity date in "Test choice" should contain "Closes:"
|
||||
And I am on "Course 1" course homepage
|
||||
# When showactivitydates is enabled, activity dates should be shown on the course homepage.
|
||||
And the activity date information in "Test choice" should exist
|
||||
And the activity date in "Test choice" should contain "Opened:"
|
||||
And the activity date in "Test choice" should contain "Closes:"
|
||||
|
||||
Scenario: Activity dates setting can be disabled to hidden activity dates in a course
|
||||
Scenario: Activity dates setting can be disabled to hide activity dates in a course
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I navigate to "Edit settings" in current page administration
|
||||
@@ -39,11 +44,12 @@ Feature: Allow teachers to edit the visibility of activity dates in a course
|
||||
And I click on "Save and display" "button"
|
||||
And I follow "Test choice"
|
||||
# Activity dates are always shown in the module's view page.
|
||||
Then I should see "Opened:"
|
||||
And I should see "Closes:"
|
||||
Then the activity date information in "Test choice" should exist
|
||||
And the activity date in "Test choice" should contain "Opened:"
|
||||
And the activity date in "Test choice" should contain "Closes:"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should not see "Opened:"
|
||||
And I should not see "Closes:"
|
||||
# When showactivitydates is disabled, activity dates should not be shown on the course homepage.
|
||||
And the activity date information in "Test choice" should not exist
|
||||
|
||||
Scenario: Default activity dates setting default value can changed to No
|
||||
Given I log in as "admin"
|
||||
|
||||
@@ -119,9 +119,7 @@ if ($courseid) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$targetstate = required_param('completionstate', PARAM_INT);
|
||||
$fromajax = optional_param('fromajax', 0, PARAM_INT);
|
||||
|
||||
$PAGE->set_url('/course/togglecompletion.php', array('id'=>$cmid, 'completionstate'=>$targetstate));
|
||||
|
||||
@@ -158,33 +156,15 @@ if (!$completion->is_enabled()) {
|
||||
|
||||
// Check completion state is manual
|
||||
if($cm->completion != COMPLETION_TRACKING_MANUAL) {
|
||||
error_or_ajax('cannotmanualctrack', $fromajax);
|
||||
throw new moodle_exception('cannotmanualctrack');
|
||||
}
|
||||
|
||||
$completion->update_state($cm, $targetstate);
|
||||
|
||||
// And redirect back to course
|
||||
if ($fromajax) {
|
||||
print 'OK';
|
||||
// In case of use in other areas of code we allow a 'backto' parameter, otherwise go back to course page.
|
||||
if ($backto = optional_param('backto', null, PARAM_URL)) {
|
||||
redirect($backto);
|
||||
} else {
|
||||
// In case of use in other areas of code we allow a 'backto' parameter,
|
||||
// otherwise go back to course page
|
||||
|
||||
if ($backto = optional_param('backto', null, PARAM_URL)) {
|
||||
redirect($backto);
|
||||
} else {
|
||||
redirect(course_get_url($course, $cm->sectionnum));
|
||||
}
|
||||
}
|
||||
|
||||
// utility functions
|
||||
|
||||
function error_or_ajax($message, $fromajax) {
|
||||
if ($fromajax) {
|
||||
print get_string($message, 'error');
|
||||
exit;
|
||||
} else {
|
||||
print_error($message);
|
||||
}
|
||||
redirect(course_get_url($course, $cm->sectionnum));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,15 @@ information provided here is intended especially for developers.
|
||||
|
||||
=== 3.11 ===
|
||||
* A new callback xxx_coursemodule_definition_after_data that allows plugins to extend activity forms after the data is set.
|
||||
* \core_course_renderer::course_section_cm_completion() has been deprecated. It is not being used anymore and is being replaced by
|
||||
\core_renderer::activity_information().
|
||||
* New Behat steps for checking activity date information in the \behat_course class:
|
||||
- activity_date_in_activity_should_contain_text()
|
||||
- Given the activity date in "<ActivityName>" should contain "<Text>"
|
||||
- activity_dates_information_in_activity_should_exist()
|
||||
- Given the activity date information in "<ActivityName>" should exist
|
||||
- activity_dates_information_in_activity_should_not_exist()
|
||||
- Given the activity date information in "<ActivityName>" should not exist
|
||||
|
||||
=== 3.10 ===
|
||||
|
||||
|
||||
+6
-21
@@ -215,14 +215,6 @@
|
||||
redirect($CFG->wwwroot .'/');
|
||||
}
|
||||
|
||||
$completion = new completion_info($course);
|
||||
if ($completion->is_enabled()) {
|
||||
$PAGE->requires->string_for_js('completion-alt-manual-y', 'completion');
|
||||
$PAGE->requires->string_for_js('completion-alt-manual-n', 'completion');
|
||||
|
||||
$PAGE->requires->js_init_call('M.core_completion.init');
|
||||
}
|
||||
|
||||
// Determine whether the user has permission to download course content.
|
||||
$candownloadcourse = \core\content::can_export_context($context, $USER);
|
||||
|
||||
@@ -262,19 +254,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
if ($completion->is_enabled()) {
|
||||
// This value tracks whether there has been a dynamic change to the page.
|
||||
// It is used so that if a user does this - (a) set some tickmarks, (b)
|
||||
// go to another page, (c) clicks Back button - the page will
|
||||
// automatically reload. Otherwise it would start with the wrong tick
|
||||
// values.
|
||||
echo html_writer::start_tag('form', array('action'=>'.', 'method'=>'get'));
|
||||
echo html_writer::start_tag('div');
|
||||
echo html_writer::empty_tag('input', array('type'=>'hidden', 'id'=>'completion_dynamic_change', 'name'=>'completion_dynamic_change', 'value'=>'0'));
|
||||
echo html_writer::end_tag('div');
|
||||
echo html_writer::end_tag('form');
|
||||
}
|
||||
|
||||
// Course wrapper start.
|
||||
echo html_writer::start_tag('div', array('class'=>'course-content'));
|
||||
|
||||
@@ -314,4 +293,10 @@
|
||||
$PAGE->requires->js_call_amd('core_course/downloadcontent', 'init');
|
||||
}
|
||||
|
||||
// Load the view JS module if completion tracking is enabled for this course.
|
||||
$completion = new completion_info($course);
|
||||
if ($completion->is_enabled()) {
|
||||
$PAGE->requires->js_call_amd('core_course/view', 'init');
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
+3
-2
@@ -53,10 +53,11 @@ $string['completion_manual:aria:done'] = '{$a} is marked as done. Press to undo.
|
||||
$string['completion_manual:aria:markdone'] = 'Mark {$a} as done';
|
||||
$string['completion_manual:done'] = 'Done';
|
||||
$string['completion_manual:markdone'] = 'Mark as done';
|
||||
$string['completion_setby:auto'] = 'Done: {$a->condition} (set by {$a->setby})';
|
||||
$string['completion_setby:auto:done'] = 'Done: {$a->condition} (set by {$a->setby})';
|
||||
$string['completion_setby:auto:todo'] = 'To do: {$a->condition} (set by {$a->setby})';
|
||||
$string['completion_setby:manual:done'] = '{$a->activityname} is marked by {$a->setby} as done. Press to undo.';
|
||||
$string['completion_setby:manual:markdone'] = '{$a->activityname} is marked by {$a->setby} as not done. Press to mark as done.';
|
||||
$string['completionrequirements'] = 'Completion requirements for this activity';
|
||||
$string['completionrequirements'] = 'Completion requirements for {$a}';
|
||||
$string['coursealreadyfinished'] = 'Course already finished';
|
||||
$string['coursenotyetstarted'] = 'The course has not yet started';
|
||||
$string['coursenotyetfinished'] = 'The course has not yet finished';
|
||||
|
||||
@@ -787,8 +787,6 @@ class page_requirements_manager {
|
||||
'requires' => array('node', 'cookie'));
|
||||
break;
|
||||
case 'core_completion':
|
||||
$module = array('name' => 'core_completion',
|
||||
'fullpath' => '/course/completion.js');
|
||||
break;
|
||||
case 'core_message':
|
||||
$module = array('name' => 'core_message',
|
||||
|
||||
@@ -33,7 +33,7 @@ Feature: Set a certain number of discussions as a completion condition for a for
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
Then the "Test forum name" "forum" activity with "auto" completion should be marked as not complete
|
||||
And the "Start discussions: 2" completion condition of "Test forum name" is displayed as "todo"
|
||||
And I add a new discussion to "Test forum name" forum with:
|
||||
| Subject | Post 1 subject |
|
||||
| Message | Body 1 content |
|
||||
@@ -41,7 +41,7 @@ Feature: Set a certain number of discussions as a completion condition for a for
|
||||
| Subject | Post 2 subject |
|
||||
| Message | Body 2 content |
|
||||
And I am on "Course 1" course homepage
|
||||
Then the "Test forum name" "forum" activity with "auto" completion should be marked as complete
|
||||
Then the "Start discussions: 2" completion condition of "Test forum name" is displayed as "done"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
|
||||
@@ -48,11 +48,11 @@ Feature: Set end of lesson reached as a completion condition for a lesson
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
Then the "Test lesson" "lesson" activity with "auto" completion should be marked as not complete
|
||||
Then the "Go through the activity to the end" completion condition of "Test lesson" is displayed as "todo"
|
||||
And I follow "Test lesson"
|
||||
And I press "Next page"
|
||||
And I am on "Course 1" course homepage
|
||||
Then the "Test lesson" "lesson" activity with "auto" completion should be marked as not complete
|
||||
And the "Go through the activity to the end" completion condition of "Test lesson" is displayed as "todo"
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Test lesson"
|
||||
And I should see "You have seen more than one page of this lesson already."
|
||||
@@ -61,7 +61,7 @@ Feature: Set end of lesson reached as a completion condition for a lesson
|
||||
And I press "Next page"
|
||||
And I press "Next page"
|
||||
And I am on "Course 1" course homepage
|
||||
Then the "Test lesson" "lesson" activity with "auto" completion should be marked as complete
|
||||
And the "Go through the activity to the end" completion condition of "Test lesson" is displayed as "done"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
|
||||
@@ -50,7 +50,7 @@ Feature: Set time spent as a completion condition for a lesson
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
Then the "Test lesson" "lesson" activity with "auto" completion should be marked as not complete
|
||||
Then the "Spend at least 10 secs on this activity" completion condition of "Test lesson" is displayed as "todo"
|
||||
And I follow "Test lesson"
|
||||
And I press "Next page"
|
||||
# Add 1 sec delay so lesson knows a valid attempt has been made in past.
|
||||
@@ -59,7 +59,7 @@ Feature: Set time spent as a completion condition for a lesson
|
||||
And I should see "You completed this lesson in"
|
||||
And I should see ", which is less than the required time of 10 secs. You might need to attempt the lesson again."
|
||||
And I am on "Course 1" course homepage
|
||||
And the "Test lesson" "lesson" activity with "auto" completion should be marked as not complete
|
||||
And the "Spend at least 10 secs on this activity" completion condition of "Test lesson" is displayed as "todo"
|
||||
And I am on "Course 1" course homepage
|
||||
And I follow "Test lesson"
|
||||
And I press "Next page"
|
||||
@@ -67,7 +67,7 @@ Feature: Set time spent as a completion condition for a lesson
|
||||
And I press "Next page"
|
||||
And I should not see "You might need to attempt the lesson again."
|
||||
And I am on "Course 1" course homepage
|
||||
And the "Test lesson" "lesson" activity with "auto" completion should be marked as complete
|
||||
And the "Spend at least 10 secs on this activity" completion condition of "Test lesson" is displayed as "done"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
|
||||
@@ -37,14 +37,16 @@ Feature: Set a quiz to be marked complete when the student uses all attempts all
|
||||
Scenario: student1 uses up both attempts without passing
|
||||
When I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And the "Test quiz name" "quiz" activity with "auto" completion should be marked as not complete
|
||||
And the "Receive a grade" completion condition of "Test quiz name" is displayed as "failed"
|
||||
And the "Receive a pass grade or complete all available attempts" completion condition of "Test quiz name" is displayed as "todo"
|
||||
And I follow "Test quiz name"
|
||||
And I press "Re-attempt quiz"
|
||||
And I set the field "False" to "1"
|
||||
And I press "Finish attempt ..."
|
||||
And I press "Submit all and finish"
|
||||
And I am on "Course 1" course homepage
|
||||
Then "Completed: Test quiz name" "icon" should exist in the "li.modtype_quiz" "css_element"
|
||||
Then the "Receive a grade" completion condition of "Test quiz name" is displayed as "failed"
|
||||
And the "Receive a pass grade or complete all available attempts" completion condition of "Test quiz name" is displayed as "done"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
|
||||
@@ -41,14 +41,14 @@ Feature: Set a quiz to be marked complete when the student completes a minimum a
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And the "Test quiz name" "quiz" activity with "auto" completion should be marked as not complete
|
||||
And the "Make attempts: 2" completion condition of "Test quiz name" is displayed as "todo"
|
||||
And I follow "Test quiz name"
|
||||
And I press "Re-attempt quiz"
|
||||
And I set the field "False" to "1"
|
||||
And I press "Finish attempt ..."
|
||||
And I press "Submit all and finish"
|
||||
And I am on "Course 1" course homepage
|
||||
Then "Completed: Test quiz name" "icon" should exist in the "Test quiz name" "list_item"
|
||||
Then the "Make attempts: 2" completion condition of "Test quiz name" is displayed as "done"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
|
||||
@@ -34,12 +34,14 @@ Feature: Set a quiz to be marked complete when the student passes
|
||||
Scenario: student1 passes on the first try
|
||||
When I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And the "Test quiz name" "quiz" activity with "auto" completion should be marked as not complete
|
||||
And the "Receive a grade" completion condition of "Test quiz name" is displayed as "todo"
|
||||
And the "Receive a pass grade" completion condition of "Test quiz name" is displayed as "todo"
|
||||
And user "student1" has attempted "Test quiz name" with responses:
|
||||
| slot | response |
|
||||
| 1 | True |
|
||||
And I am on "Course 1" course homepage
|
||||
Then "Completed: Test quiz name" "icon" should exist in the "li.modtype_quiz" "css_element"
|
||||
Then the "Receive a grade" completion condition of "Test quiz name" is displayed as "done"
|
||||
And the "Receive a pass grade" completion condition of "Test quiz name" is displayed as "done"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
|
||||
@@ -30,10 +30,10 @@ Feature: A teacher can use activity completion to track a student progress
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And the "Test survey name" "survey" activity with "auto" completion should be marked as not complete
|
||||
And the "View" completion condition of "Test survey name" is displayed as "todo"
|
||||
And I follow "Test survey name"
|
||||
And I am on "Course 1" course homepage
|
||||
Then the "Test survey name" "survey" activity with "auto" completion should be marked as complete
|
||||
Then the "View" completion condition of "Test survey name" is displayed as "done"
|
||||
|
||||
Scenario: Require survey submission
|
||||
Given I add a "Survey" to section "1" and I fill the form with:
|
||||
@@ -45,8 +45,8 @@ Feature: A teacher can use activity completion to track a student progress
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And the "Test survey name" "survey" activity with "auto" completion should be marked as not complete
|
||||
And the "View" completion condition of "Test survey name" is displayed as "todo"
|
||||
And I follow "Test survey name"
|
||||
And I press "Click here to continue"
|
||||
And I am on "Course 1" course homepage
|
||||
Then the "Test survey name" "survey" activity with "auto" completion should be marked as complete
|
||||
And the "View" completion condition of "Test survey name" is displayed as "done"
|
||||
|
||||
@@ -30,13 +30,12 @@ Feature: Teacher can view and override users' activity completion data via the p
|
||||
# Student completes the activities, manual and automatic completion.
|
||||
Given I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And "Not completed: my assignment. Select to mark as complete." "icon" should exist in the "my assignment" "list_item"
|
||||
And "Not completed: my assignment 2" "icon" should exist in the "my assignment 2" "list_item"
|
||||
And I click on "Not completed: my assignment. Select to mark as complete." "icon"
|
||||
And "Completed: my assignment. Select to mark as not complete." "icon" should exist in the "my assignment" "list_item"
|
||||
And the manual completion button of "my assignment" is displayed as "Mark as done"
|
||||
And I toggle the manual completion state of "my assignment"
|
||||
And the manual completion button of "my assignment" is displayed as "Done"
|
||||
And I click on "my assignment 2" "link"
|
||||
And I am on "Course 1" course homepage
|
||||
And "Completed: my assignment 2" "icon" should exist in the "my assignment 2" "list_item"
|
||||
And the "View" completion condition of "my assignment 2" is displayed as "done"
|
||||
And I log out
|
||||
# Teacher overrides the activity completion statuses to incomplete.
|
||||
When I log in as "teacher1"
|
||||
@@ -54,13 +53,13 @@ Feature: Teacher can view and override users' activity completion data via the p
|
||||
# Student can now complete the activities again, via normal means.
|
||||
Then I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And "Not completed: my assignment (set by Teacher One). Select to mark as complete." "icon" should exist in the "my assignment" "list_item"
|
||||
And "Not completed: my assignment 2 (set by Teacher One)" "icon" should exist in the "my assignment 2" "list_item"
|
||||
And I click on "Not completed: my assignment (set by Teacher One). Select to mark as complete." "icon"
|
||||
And "Completed: my assignment. Select to mark as not complete." "icon" should exist in the "my assignment" "list_item"
|
||||
And the manual completion button of "my assignment" overridden by "Teacher One" is displayed as "Mark as done"
|
||||
And the "View" completion condition of "my assignment 2" overridden by "Teacher One" is displayed as "todo"
|
||||
And I toggle the manual completion state of "my assignment"
|
||||
And the manual completion button of "my assignment" is displayed as "Done"
|
||||
And I click on "my assignment 2" "link"
|
||||
And I am on "Course 1" course homepage
|
||||
And "Completed: my assignment 2" "icon" should exist in the "my assignment 2" "list_item"
|
||||
And the "View" completion condition of "my assignment 2" is displayed as "done"
|
||||
And I log out
|
||||
# And the activity completion report should show the same.
|
||||
When I log in as "teacher1"
|
||||
@@ -90,7 +89,7 @@ Feature: Teacher can view and override users' activity completion data via the p
|
||||
# Then as a student, confirm that automatic completion checks are no longer triggered (such as after an assign submission).
|
||||
Then I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
And "Completed: my assignment 3 (set by Teacher One)" "icon" should exist in the "my assignment 3" "list_item"
|
||||
And the "Receive a grade" completion condition of "my assignment 3" overridden by "Teacher One" is displayed as "done"
|
||||
And I click on "my assignment 3" "link"
|
||||
And I press "Add submission"
|
||||
And I set the following fields to these values:
|
||||
@@ -98,10 +97,9 @@ Feature: Teacher can view and override users' activity completion data via the p
|
||||
And I press "Save changes"
|
||||
And I should see "Submitted for grading"
|
||||
And I am on "Course 1" course homepage
|
||||
And "Completed: my assignment 3 (set by Teacher One)" "icon" should exist in the "my assignment 3" "list_item"
|
||||
And the "Receive a grade" completion condition of "my assignment 3" overridden by "Teacher One" is displayed as "done"
|
||||
# And Confirm that manual completion changes are still allowed.
|
||||
And I am on "Course 1" course homepage
|
||||
And "Completed: my assignment (set by Teacher One). Select to mark as not complete." "icon" should exist in the "my assignment" "list_item"
|
||||
And I click on "Completed: my assignment (set by Teacher One). Select to mark as not complete." "icon"
|
||||
And "Not completed: my assignment. Select to mark as complete." "icon" should exist in the "my assignment" "list_item"
|
||||
And I log out
|
||||
And the manual completion button of "my assignment" overridden by "Teacher One" is displayed as "Done"
|
||||
And I toggle the manual completion state of "my assignment"
|
||||
And the manual completion button of "my assignment" is displayed as "Mark as done"
|
||||
|
||||
@@ -207,6 +207,17 @@ body:not(.editing) .sitetopic ul.section {
|
||||
.section li.activity {
|
||||
padding: .2em;
|
||||
clear: both;
|
||||
|
||||
&.hasinfo {
|
||||
border-bottom: $border-width solid $table-border-color;
|
||||
padding-top: map-get($spacers, 3);
|
||||
padding-bottom: map-get($spacers, 3);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section .activity .activityinstance .groupinglabel {
|
||||
|
||||
@@ -13377,6 +13377,13 @@ body:not(.editing) .sitetopic ul.section {
|
||||
.section li.activity {
|
||||
padding: .2em;
|
||||
clear: both; }
|
||||
.section li.activity.hasinfo {
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem; }
|
||||
.section li.activity.hasinfo:last-child {
|
||||
border-bottom: 0;
|
||||
padding-bottom: 0; }
|
||||
|
||||
.section .activity .activityinstance .groupinglabel {
|
||||
padding-left: 30px; }
|
||||
|
||||
@@ -13591,6 +13591,13 @@ body:not(.editing) .sitetopic ul.section {
|
||||
.section li.activity {
|
||||
padding: .2em;
|
||||
clear: both; }
|
||||
.section li.activity.hasinfo {
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem; }
|
||||
.section li.activity.hasinfo:last-child {
|
||||
border-bottom: 0;
|
||||
padding-bottom: 0; }
|
||||
|
||||
.section .activity .activityinstance .groupinglabel {
|
||||
padding-left: 30px; }
|
||||
|
||||
Reference in New Issue
Block a user