MDL-82541 core_courseformat: fix orphaned sections display
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -300,6 +300,9 @@ export default class Component extends BaseComponent {
|
||||
_refreshSectionCmlist({element}) {
|
||||
const cmlist = element.cmlist ?? [];
|
||||
const listparent = this.getElement(this.selectors.SECTION_CMLIST, element.id);
|
||||
if (!listparent) {
|
||||
return;
|
||||
}
|
||||
this._fixOrder(listparent, cmlist, this.cms);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace core_courseformat\output\local;
|
||||
use core\output\named_templatable;
|
||||
use core_courseformat\base as course_format;
|
||||
use course_modinfo;
|
||||
use section_info;
|
||||
use renderable;
|
||||
|
||||
/**
|
||||
@@ -142,7 +143,7 @@ class content implements named_templatable, renderable {
|
||||
/**
|
||||
* Export sections array data.
|
||||
*
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
* @return array data context for a mustache template
|
||||
*/
|
||||
protected function export_sections(\renderer_base $output): array {
|
||||
@@ -154,7 +155,6 @@ class content implements named_templatable, renderable {
|
||||
// Generate section list.
|
||||
$sections = [];
|
||||
$stealthsections = [];
|
||||
$numsections = $format->get_last_section_number();
|
||||
foreach ($this->get_sections_to_display($modinfo) as $sectionnum => $thissection) {
|
||||
// The course/view.php check the section existence but the output can be called
|
||||
// from other parts so we need to check it.
|
||||
@@ -163,9 +163,14 @@ class content implements named_templatable, renderable {
|
||||
format_string($course->fullname));
|
||||
}
|
||||
|
||||
if (!$format->is_section_visible($thissection)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var \core_courseformat\output\local\content\section $section */
|
||||
$section = new $this->sectionclass($format, $thissection);
|
||||
|
||||
if ($sectionnum > $numsections) {
|
||||
if ($section->is_stealth()) {
|
||||
// Activities inside this section are 'orphaned', this section will be printed as 'stealth' below.
|
||||
if (!empty($modinfo->sections[$sectionnum])) {
|
||||
$stealthsections[] = $section->export_for_template($output);
|
||||
@@ -173,10 +178,6 @@ class content implements named_templatable, renderable {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$format->is_section_visible($thissection)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sections[] = $section->export_for_template($output);
|
||||
}
|
||||
if (!empty($stealthsections)) {
|
||||
|
||||
@@ -95,9 +95,7 @@ class section implements named_templatable, renderable {
|
||||
$this->format = $format;
|
||||
$this->section = $section;
|
||||
|
||||
if ($section->section > $format->get_last_section_number()) {
|
||||
$this->isstealth = true;
|
||||
}
|
||||
$this->isstealth = $section->is_orphan();
|
||||
|
||||
// Load output classes names from format.
|
||||
$this->headerclass = $format->get_output_classname('content\\section\\header');
|
||||
@@ -110,6 +108,15 @@ class section implements named_templatable, renderable {
|
||||
$this->visibilityclass = $format->get_output_classname('content\\section\\visibility');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the section is considered stealth.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_stealth(): bool {
|
||||
return $this->isstealth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the section title.
|
||||
*
|
||||
|
||||
@@ -98,7 +98,7 @@ class controlmenu extends basecontrolmenu {
|
||||
$usecomponents = $format->supports_components();
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
$numsections = $format->get_last_section_number();
|
||||
$isstealth = $section->section > $numsections;
|
||||
$isstealth = $section->is_orphan();
|
||||
|
||||
$baseurl = course_get_url($course, $sectionreturn);
|
||||
$baseurl->param('sesskey', sesskey());
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
}
|
||||
}}
|
||||
{{#hasmenu}}
|
||||
<div class="section_action_menu bulk-hidden ms-auto" data-sectionid="{{id}}">
|
||||
<div class="section_action_menu bulk-hidden ms-auto" data-sectionid="{{id}}" data-region="sectionactionsmmenu">
|
||||
{{{menu}}}
|
||||
</div>
|
||||
{{/hasmenu}}
|
||||
|
||||
@@ -50,6 +50,9 @@ class behat_courseformat extends behat_base {
|
||||
new behat_component_named_selector('Section visibility', [
|
||||
".//*[@data-sectionname=%locator%]//*[@data-region='sectionvisibility']",
|
||||
]),
|
||||
new behat_component_named_selector('Section actions menu', [
|
||||
".//*[@data-sectionname=%locator%]//*[@data-for='section_title']//*[@data-region='sectionactionsmmenu']",
|
||||
]),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,12 +55,16 @@ class controlmenu extends controlmenu_base {
|
||||
$section = $this->section;
|
||||
$coursecontext = $format->get_context();
|
||||
|
||||
$controls = [];
|
||||
if ($section->section && has_capability('moodle/course:setcurrentsection', $coursecontext)) {
|
||||
$controls['highlight'] = $this->get_highlight_control();
|
||||
$parentcontrols = parent::section_control_items();
|
||||
|
||||
if ($section->is_orphan() || !$section->section) {
|
||||
return $parentcontrols;
|
||||
}
|
||||
|
||||
$parentcontrols = parent::section_control_items();
|
||||
$controls = [];
|
||||
if (has_capability('moodle/course:setcurrentsection', $coursecontext)) {
|
||||
$controls['highlight'] = $this->get_highlight_control();
|
||||
}
|
||||
|
||||
// If the edit key exists, we are going to insert our controls after it.
|
||||
if (array_key_exists("edit", $parentcontrols)) {
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
@mod @mod_subsection
|
||||
Feature: Courses should not lose subsection contents when mod_subsection is disabled
|
||||
In order to disable subsections
|
||||
As an admin
|
||||
Courses needs to be usable with mod_subsection disabled
|
||||
|
||||
Background:
|
||||
Given I enable "subsection" "mod" plugin
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname |
|
||||
| teacher1 | Teacher | 1 |
|
||||
| student1 | Student | 1 |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | numsections | initsections |
|
||||
| Course 1 | C1 | 0 | 2 | 1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber | section |
|
||||
| forum | Activity Sample | C1 | forum1 | 1 |
|
||||
| subsection | Subsection1 | C1 | Subsection1 | 1 |
|
||||
| data | Subactivity | C1 | data1 | 3 |
|
||||
And I disable "subsection" "mod" plugin
|
||||
|
||||
Scenario: Teachers should see subsections as orphaned
|
||||
When I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I should see "Activity Sample" in the "Section 1" "section"
|
||||
And I should not see "Subsection1" in the "Section 1" "section"
|
||||
And I should see "Subsection1" in the "page-content" "region"
|
||||
Then I should see "Subactivity" in the "Subsection1" "section"
|
||||
And "Section 2" "section" should appear before "Subsection1" "section"
|
||||
And "Edit settings" "link" should not exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "Duplicate" "link" should not exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "Hide" "link" should not exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "Move" "link" should not exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "View" "link" should exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "Delete" "link" should exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
|
||||
Scenario: Students should not see orphaned subsections
|
||||
When I log in as "student1"
|
||||
And I am on "Course 1" course homepage
|
||||
Then I should see "Activity Sample" in the "page-content" "region"
|
||||
And I should not see "Subsection1" in the "page-content" "region"
|
||||
And I should not see "Subactivity" in the "page-content" "region"
|
||||
|
||||
Scenario: Enabling again subsections should show the course as before
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should see "Activity Sample" in the "Section 1" "section"
|
||||
And I should not see "Subsection1" in the "Section 1" "section"
|
||||
And I should see "Subsection1" in the "page-content" "region"
|
||||
And I should see "Subactivity" in the "Subsection1" "section"
|
||||
And "Section 2" "section" should appear before "Subsection1" "section"
|
||||
When I enable "subsection" "mod" plugin
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
Then I should see "Activity Sample" in the "Section 1" "section"
|
||||
And I should see "Subsection1" in the "Section 1" "section"
|
||||
And I should see "Subactivity" in the "Subsection1" "section"
|
||||
And "Subsection1" "section" should appear before "Section 2" "section"
|
||||
And "Edit settings" "link" should exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "Duplicate" "link" should not exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "Hide" "link" should exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "Move" "link" should exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "View" "link" should exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
And "Delete" "link" should exist in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
|
||||
@javascript
|
||||
Scenario: Deleting the subsections with mod_subsection disabled should not break the course
|
||||
Given I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
# Perform teacher actions instead of fast steps to validate delete
|
||||
# an orphaned subsection does not break the course.
|
||||
And I click on "Edit" "icon" in the "Subsection1" "core_courseformat > Section actions menu"
|
||||
When I choose "Delete" in the open action menu
|
||||
And I click on "Delete" "button" in the "Delete section?" "dialogue"
|
||||
Then I enable "subsection" "mod" plugin
|
||||
And I am on "Course 1" course homepage
|
||||
And I should see "Activity Sample" in the "Section 1" "section"
|
||||
And I should see "Subsection1" in the "page-content" "region"
|
||||
And I should not see "Subactivity" in the "page-content" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Access restrictions are restored when a subsection is deleted while mod_subsection is disabled
|
||||
Given I enable "subsection" "mod" plugin
|
||||
And the following "groups" exist:
|
||||
| course | name | idnumber |
|
||||
| C1 | G1 | GI1 |
|
||||
And the following "group members" exist:
|
||||
| user | group |
|
||||
| student1 | GI1 |
|
||||
And the following "groupings" exist:
|
||||
| name | course | idnumber |
|
||||
| GX1 | C1 | GXI1 |
|
||||
And the following "grouping groups" exist:
|
||||
| grouping | group |
|
||||
| GXI1 | GI1 |
|
||||
And I log in as "teacher1"
|
||||
And I am on the "C1 > Subsection1" "course > section settings" page
|
||||
And I set the following fields to these values:
|
||||
| Access restrictions | Grouping: GX1 |
|
||||
And I press "Save changes"
|
||||
And I should see "Not available unless: You belong to a group in GX1"
|
||||
And I disable "subsection" "mod" plugin
|
||||
When I am on the "C1 > Subsection1" "course > section" page
|
||||
And I turn editing mode on
|
||||
And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element"
|
||||
And I choose "Delete" in the open action menu
|
||||
And I click on "Delete" "button" in the "Delete section?" "dialogue"
|
||||
And I enable "subsection" "mod" plugin
|
||||
Then I am on "Course 1" course homepage
|
||||
And I should see "Not available unless: You belong to a group in GX1"
|
||||
|
||||
@javascript
|
||||
Scenario: Visibility is restored when a subsection is deleted while mod_subsection is disabled
|
||||
Given I enable "subsection" "mod" plugin
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber | section | visible |
|
||||
| subsection | Subsection2 | C1 | Subsection2 | 1 | 0 |
|
||||
And I log in as "teacher1"
|
||||
And I disable "subsection" "mod" plugin
|
||||
When I am on the "C1 > Subsection2" "course > section" page
|
||||
And I turn editing mode on
|
||||
And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element"
|
||||
And I choose "Delete" in the open action menu
|
||||
And I click on "Delete" "button" in the "Delete section?" "dialogue"
|
||||
And I enable "subsection" "mod" plugin
|
||||
Then I am on "Course 1" course homepage
|
||||
And I should see "Hidden from students"
|
||||
@@ -1150,7 +1150,8 @@ $divider-hover-color: $primary !default;
|
||||
@include border-radius($activity-border-radius);
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
&.hidden,
|
||||
&.orphaned {
|
||||
.section-item {
|
||||
background-color: $gray-100;
|
||||
}
|
||||
|
||||
@@ -29065,7 +29065,7 @@ span.editinstructions .alert-link {
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
.course-section.hidden .section-item {
|
||||
.course-section.hidden .section-item, .course-section.orphaned .section-item {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
.course-section .sectionname > a {
|
||||
|
||||
@@ -29065,7 +29065,7 @@ span.editinstructions .alert-link {
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
.course-section.hidden .section-item {
|
||||
.course-section.hidden .section-item, .course-section.orphaned .section-item {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
.course-section .sectionname > a {
|
||||
|
||||
Reference in New Issue
Block a user