mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 14:03:52 +01:00
MDL-74977 core_courseformat: add expanded section update actions
This also fix the Random "Course content preferences" Behat failure
This commit is contained in:
parent
a18c0b7c8b
commit
037a7d5d6c
2
course/format/amd/build/local/content.min.js
vendored
2
course/format/amd/build/local/content.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -173,15 +173,12 @@ export default class Component extends BaseComponent {
|
||||
const toggler = section.querySelector(this.selectors.COLLAPSE);
|
||||
const isCollapsed = toggler?.classList.contains(this.classes.COLLAPSED) ?? false;
|
||||
|
||||
if (isChevron || isCollapsed) {
|
||||
// Update the state.
|
||||
const sectionId = section.getAttribute('data-id');
|
||||
this.reactive.dispatch(
|
||||
'sectionContentCollapsed',
|
||||
[sectionId],
|
||||
!isCollapsed
|
||||
);
|
||||
}
|
||||
const sectionId = section.getAttribute('data-id');
|
||||
this.reactive.dispatch(
|
||||
'sectionContentCollapsed',
|
||||
[sectionId],
|
||||
!isCollapsed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,12 +473,16 @@ export default class {
|
||||
* @param {boolean} collapsed the new collapsed value
|
||||
*/
|
||||
async sectionIndexCollapsed(stateManager, sectionIds, collapsed) {
|
||||
const collapsedIds = this._updateStateSectionPreference(stateManager, 'indexcollapsed', sectionIds, collapsed);
|
||||
if (!collapsedIds) {
|
||||
const affectedSections = this._updateStateSectionPreference(stateManager, 'indexcollapsed', sectionIds, collapsed);
|
||||
if (!affectedSections) {
|
||||
return;
|
||||
}
|
||||
const course = stateManager.get('course');
|
||||
await this._callEditWebservice('section_index_collapsed', course.id, collapsedIds);
|
||||
let actionName = 'section_index_collapsed';
|
||||
if (!collapsed) {
|
||||
actionName = 'section_index_expanded';
|
||||
}
|
||||
await this._callEditWebservice(actionName, course.id, affectedSections);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -489,12 +493,16 @@ export default class {
|
||||
* @param {boolean} collapsed the new collapsed value
|
||||
*/
|
||||
async sectionContentCollapsed(stateManager, sectionIds, collapsed) {
|
||||
const collapsedIds = this._updateStateSectionPreference(stateManager, 'contentcollapsed', sectionIds, collapsed);
|
||||
if (!collapsedIds) {
|
||||
const affectedSections = this._updateStateSectionPreference(stateManager, 'contentcollapsed', sectionIds, collapsed);
|
||||
if (!affectedSections) {
|
||||
return;
|
||||
}
|
||||
const course = stateManager.get('course');
|
||||
await this._callEditWebservice('section_content_collapsed', course.id, collapsedIds);
|
||||
let actionName = 'section_content_collapsed';
|
||||
if (!collapsed) {
|
||||
actionName = 'section_content_expanded';
|
||||
}
|
||||
await this._callEditWebservice(actionName, course.id, affectedSections);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -508,32 +516,22 @@ export default class {
|
||||
*/
|
||||
_updateStateSectionPreference(stateManager, preferenceName, sectionIds, preferenceValue) {
|
||||
stateManager.setReadOnly(false);
|
||||
const affectedSections = new Set();
|
||||
const affectedSections = [];
|
||||
// Check if we need to update preferences.
|
||||
sectionIds.forEach(sectionId => {
|
||||
const section = stateManager.get('section', sectionId);
|
||||
if (section === undefined) {
|
||||
stateManager.setReadOnly(true);
|
||||
return null;
|
||||
}
|
||||
const newValue = preferenceValue ?? section[preferenceName];
|
||||
if (section[preferenceName] != newValue) {
|
||||
section[preferenceName] = newValue;
|
||||
affectedSections.add(section.id);
|
||||
affectedSections.push(section.id);
|
||||
}
|
||||
});
|
||||
stateManager.setReadOnly(true);
|
||||
if (affectedSections.size == 0) {
|
||||
return null;
|
||||
}
|
||||
// Get all collapsed section ids.
|
||||
const collapsedSectionIds = [];
|
||||
const state = stateManager.state;
|
||||
state.section.forEach(section => {
|
||||
if (section[preferenceName]) {
|
||||
collapsedSectionIds.push(section.id);
|
||||
}
|
||||
});
|
||||
return collapsedSectionIds;
|
||||
return affectedSections;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -131,9 +131,16 @@ export default class Component extends BaseComponent {
|
||||
const toggler = section.querySelector(this.selectors.COLLAPSE);
|
||||
const isCollapsed = toggler?.classList.contains(this.classes.COLLAPSED) ?? false;
|
||||
|
||||
if (isChevron || isCollapsed) {
|
||||
// Update the state.
|
||||
const sectionId = section.getAttribute('data-id');
|
||||
// Update the state.
|
||||
const sectionId = section.getAttribute('data-id');
|
||||
if ((!sectionlink)) {
|
||||
this.reactive.dispatch(
|
||||
'sectionIndexCollapsed',
|
||||
[sectionId],
|
||||
!isCollapsed
|
||||
);
|
||||
} else if (isCollapsed) {
|
||||
// Always expand the section when clicking on section name.
|
||||
this.reactive.dispatch(
|
||||
'sectionIndexCollapsed',
|
||||
[sectionId],
|
||||
|
@ -617,8 +617,9 @@ abstract class base {
|
||||
global $USER;
|
||||
$course = $this->get_course();
|
||||
try {
|
||||
$sectionpreferences = (array) json_decode(
|
||||
get_user_preferences("coursesectionspreferences_{$course->id}", '', $USER->id)
|
||||
$sectionpreferences = json_decode(
|
||||
get_user_preferences("coursesectionspreferences_{$course->id}", '', $USER->id),
|
||||
true
|
||||
);
|
||||
if (empty($sectionpreferences)) {
|
||||
$sectionpreferences = [];
|
||||
@ -637,10 +638,65 @@ abstract class base {
|
||||
*
|
||||
*/
|
||||
public function set_sections_preference(string $preferencename, array $sectionids) {
|
||||
global $USER;
|
||||
$course = $this->get_course();
|
||||
$sectionpreferences = $this->get_sections_preferences_by_preference();
|
||||
$sectionpreferences[$preferencename] = $sectionids;
|
||||
$this->persist_to_user_preference($sectionpreferences);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add section preference ids.
|
||||
*
|
||||
* @param string $preferencename preference name
|
||||
* @param array $sectionids affected section ids
|
||||
*/
|
||||
public function add_section_preference_ids(
|
||||
string $preferencename,
|
||||
array $sectionids
|
||||
): void {
|
||||
$sectionpreferences = $this->get_sections_preferences_by_preference();
|
||||
if (!isset($sectionpreferences[$preferencename])) {
|
||||
$sectionpreferences[$preferencename] = [];
|
||||
}
|
||||
foreach ($sectionids as $sectionid) {
|
||||
if (!in_array($sectionid, $sectionpreferences[$preferencename])) {
|
||||
$sectionpreferences[$preferencename][] = $sectionid;
|
||||
}
|
||||
}
|
||||
$this->persist_to_user_preference($sectionpreferences);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove section preference ids.
|
||||
*
|
||||
* @param string $preferencename preference name
|
||||
* @param array $sectionids affected section ids
|
||||
*/
|
||||
public function remove_section_preference_ids(
|
||||
string $preferencename,
|
||||
array $sectionids
|
||||
): void {
|
||||
$sectionpreferences = $this->get_sections_preferences_by_preference();
|
||||
if (!isset($sectionpreferences[$preferencename])) {
|
||||
$sectionpreferences[$preferencename] = [];
|
||||
}
|
||||
foreach ($sectionids as $sectionid) {
|
||||
if (($key = array_search($sectionid, $sectionpreferences[$preferencename])) !== false) {
|
||||
unset($sectionpreferences[$preferencename][$key]);
|
||||
}
|
||||
}
|
||||
$this->persist_to_user_preference($sectionpreferences);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist the section preferences to the user preferences.
|
||||
*
|
||||
* @param array $sectionpreferences the section preferences
|
||||
*/
|
||||
private function persist_to_user_preference(
|
||||
array $sectionpreferences
|
||||
): void {
|
||||
global $USER;
|
||||
$course = $this->get_course();
|
||||
set_user_preference('coursesectionspreferences_' . $course->id, json_encode($sectionpreferences), $USER->id);
|
||||
// Invalidate section preferences cache.
|
||||
$coursesectionscache = cache::make('core', 'coursesectionspreferences');
|
||||
|
@ -531,7 +531,7 @@ class stateactions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the course content section collapsed value.
|
||||
* Update the course content section state to collapse.
|
||||
*
|
||||
* @param stateupdates $updates the affected course elements track
|
||||
* @param stdClass $course the course object
|
||||
@ -550,11 +550,34 @@ class stateactions {
|
||||
$this->validate_sections($course, $ids, __FUNCTION__);
|
||||
}
|
||||
$format = course_get_format($course->id);
|
||||
$format->set_sections_preference('contentcollapsed', $ids);
|
||||
$format->add_section_preference_ids('contentcollapsed', $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the course index section collapsed value.
|
||||
* Update the course content section state to expand.
|
||||
*
|
||||
* @param stateupdates $updates the affected course elements track
|
||||
* @param stdClass $course the course object
|
||||
* @param int[] $ids the collapsed section ids
|
||||
* @param int|null $targetsectionid not used
|
||||
* @param int|null $targetcmid not used
|
||||
*/
|
||||
public function section_content_expanded(
|
||||
stateupdates $updates,
|
||||
stdClass $course,
|
||||
array $ids = [],
|
||||
?int $targetsectionid = null,
|
||||
?int $targetcmid = null
|
||||
): void {
|
||||
if (!empty($ids)) {
|
||||
$this->validate_sections($course, $ids, __FUNCTION__);
|
||||
}
|
||||
$format = course_get_format($course->id);
|
||||
$format->remove_section_preference_ids('contentcollapsed', $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the course index section state to collapse.
|
||||
*
|
||||
* @param stateupdates $updates the affected course elements track
|
||||
* @param stdClass $course the course object
|
||||
@ -573,7 +596,30 @@ class stateactions {
|
||||
$this->validate_sections($course, $ids, __FUNCTION__);
|
||||
}
|
||||
$format = course_get_format($course->id);
|
||||
$format->set_sections_preference('indexcollapsed', $ids);
|
||||
$format->add_section_preference_ids('indexcollapsed', $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the course index section state to expand.
|
||||
*
|
||||
* @param stateupdates $updates the affected course elements track
|
||||
* @param stdClass $course the course object
|
||||
* @param int[] $ids the collapsed section ids
|
||||
* @param int $targetsectionid not used
|
||||
* @param int $targetcmid not used
|
||||
*/
|
||||
public function section_index_expanded(
|
||||
stateupdates $updates,
|
||||
stdClass $course,
|
||||
array $ids = [],
|
||||
?int $targetsectionid = null,
|
||||
?int $targetcmid = null
|
||||
): void {
|
||||
if (!empty($ids)) {
|
||||
$this->validate_sections($course, $ids, __FUNCTION__);
|
||||
}
|
||||
$format = course_get_format($course->id);
|
||||
$format->remove_section_preference_ids('indexcollapsed', $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -347,6 +347,73 @@ class base_test extends advanced_testcase {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add_section_preference_ids() method.
|
||||
*
|
||||
* @covers \core_courseformat\base::persist_to_user_preference
|
||||
*/
|
||||
public function test_add_section_preference_ids(): void {
|
||||
$this->resetAfterTest();
|
||||
// Create initial data.
|
||||
$generator = $this->getDataGenerator();
|
||||
$course = $generator->create_course();
|
||||
$user = $generator->create_and_enrol($course);
|
||||
// Get the course format.
|
||||
$format = course_get_format($course);
|
||||
// Login as the user.
|
||||
$this->setUser($user);
|
||||
|
||||
// Add section preference ids.
|
||||
$format->add_section_preference_ids('pref1', [1, 2]);
|
||||
$format->add_section_preference_ids('pref1', [3]);
|
||||
$format->add_section_preference_ids('pref2', [1]);
|
||||
|
||||
// Get section preferences.
|
||||
$sectionpreferences = $format->get_sections_preferences_by_preference();
|
||||
$this->assertCount(3, $sectionpreferences['pref1']);
|
||||
$this->assertContains(1, $sectionpreferences['pref1']);
|
||||
$this->assertContains(2, $sectionpreferences['pref1']);
|
||||
$this->assertContains(3, $sectionpreferences['pref1']);
|
||||
$this->assertCount(1, $sectionpreferences['pref2']);
|
||||
$this->assertContains(1, $sectionpreferences['pref1']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test remove_section_preference_ids() method.
|
||||
*
|
||||
* @covers \core_courseformat\base::persist_to_user_preference
|
||||
*/
|
||||
public function test_remove_section_preference_ids(): void {
|
||||
$this->resetAfterTest();
|
||||
// Create initial data.
|
||||
$generator = $this->getDataGenerator();
|
||||
$course = $generator->create_course();
|
||||
$user = $generator->create_and_enrol($course);
|
||||
// Get the course format.
|
||||
$format = course_get_format($course);
|
||||
// Login as the user.
|
||||
$this->setUser($user);
|
||||
// Set initial preferences.
|
||||
$format->set_sections_preference('pref1', [1, 2, 3]);
|
||||
$format->set_sections_preference('pref2', [1]);
|
||||
|
||||
// Remove section with id = 3 out of the pref1.
|
||||
$format->remove_section_preference_ids('pref1', [3]);
|
||||
// Get section preferences.
|
||||
$sectionpreferences = $format->get_sections_preferences_by_preference();
|
||||
$this->assertCount(2, $sectionpreferences['pref1']);
|
||||
$this->assertCount(1, $sectionpreferences['pref2']);
|
||||
|
||||
// Remove section with id = 2 out of the pref1.
|
||||
$format->remove_section_preference_ids('pref1', [2]);
|
||||
// Remove section with id = 1 out of the pref2.
|
||||
$format->remove_section_preference_ids('pref2', [1]);
|
||||
// Get section preferences.
|
||||
$sectionpreferences = $format->get_sections_preferences_by_preference();
|
||||
$this->assertCount(1, $sectionpreferences['pref1']);
|
||||
$this->assertEmpty($sectionpreferences['pref2']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that retrieving last section number for a course
|
||||
*
|
||||
|
@ -2,6 +2,10 @@ This files describes API changes for course formats
|
||||
|
||||
Overview of this plugin type at https://moodledev.io/docs/apis/plugintypes/format
|
||||
|
||||
=== 4.1.10 ===
|
||||
* New core_courseformat\base::add_section_preference_ids() to add the section ids to course format preferences.
|
||||
* New core_courseformat\base::remove_section_preference_ids() to remove the section ids out of course format preferences.
|
||||
|
||||
=== 4.1 ===
|
||||
* New \core_courseformat\stateupdates methods add_section_remove() and add_cm_remove() have been added to replace
|
||||
the deprecated methods add_section_delete() and add_cm_delete().
|
||||
|
Loading…
x
Reference in New Issue
Block a user