This commit is contained in:
Huong Nguyen 2024-07-25 09:20:14 +07:00
commit 0079197827
No known key found for this signature in database
GPG Key ID: 40D88AB693A3E72A
11 changed files with 145 additions and 23 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -40,6 +40,7 @@ import Pending from 'core/pending';
import ContentTree from 'core_courseformat/local/courseeditor/contenttree';
// The jQuery module is only used for interacting with Boostrap 4. It can we removed when MDL-71979 is integrated.
import jQuery from 'jquery';
import Notification from "core/notification";
// Load global strings.
prefetchStrings('core', ['movecoursesection', 'movecoursemodule', 'confirm', 'delete']);
@ -82,11 +83,15 @@ export default class extends BaseComponent {
ACTIONMENUTOGGLER: `[data-toggle="dropdown"]`,
// Availability modal selectors.
OPTIONSRADIO: `[type='radio']`,
COURSEADDSECTION: `#course-addsection`,
MAXSECTIONSWARNING: `[data-region='max-sections-warning']`,
ADDSECTIONREGION: `[data-region='section-addsection']`,
};
// Component css classes.
this.classes = {
DISABLED: `disabled`,
ITALIC: `font-italic`,
DISPLAYNONE: `d-none`,
};
}
@ -719,12 +724,28 @@ export default class extends BaseComponent {
* @param {boolean} locked the new locked value.
*/
_setAddSectionLocked(locked) {
const targets = this.getElements(this.selectors.ADDSECTION);
const targets = this.getElements(this.selectors.ADDSECTIONREGION);
targets.forEach(element => {
element.classList.toggle(this.classes.DISABLED, locked);
element.classList.toggle(this.classes.ITALIC, locked);
this.setElementLocked(element, locked);
const addSectionElement = element.querySelector(this.selectors.ADDSECTION);
addSectionElement.classList.toggle(this.classes.DISABLED, locked);
this.setElementLocked(addSectionElement, locked);
// We tweak the element to show a tooltip as a title attribute.
if (locked) {
getString('sectionaddmax', 'core_courseformat')
.then((text) => addSectionElement.setAttribute('title', text))
.catch(Notification.exception);
addSectionElement.style.pointerEvents = null; // Unlocks the pointer events.
addSectionElement.style.userSelect = null; // Unlocks the pointer events.
} else {
addSectionElement.setAttribute('title', addSectionElement.dataset.addSections);
}
});
const courseAddSection = this.getElement(this.selectors.COURSEADDSECTION);
const addSection = courseAddSection.querySelector(this.selectors.ADDSECTION);
addSection.classList.toggle(this.classes.DISPLAYNONE, locked);
const noMoreSections = courseAddSection.querySelector(this.selectors.MAXSECTIONSWARNING);
noMoreSections.classList.toggle(this.classes.DISPLAYNONE, !locked);
}
/**

View File

@ -153,11 +153,11 @@ class addsection implements named_templatable, renderable {
if ($singlesection) {
$params['sectionreturn'] = $singlesection;
}
$data->addsections = (object) [
'url' => new moodle_url('/course/changenumsections.php', $params),
'title' => $addstring,
'newsection' => $maxsections - $lastsection,
'canaddsection' => $lastsection < $maxsections,
];
return $data;
}

View File

@ -51,18 +51,24 @@
</a>
{{/decrease}}
{{#addsections}}
<a href="{{{url}}}"
class="btn add-section d-flex justify-content-center align-items-center p-3"
data-add-sections="{{title}}"
data-new-sections="{{newsection}}"
data-action="addSection"
{{#insertafter}} data-id="{{id}}" {{/insertafter}}
>
{{#pix}} t/add, core {{/pix}}
{{title}}
</a>
<a href="{{{url}}}"
class="w-100 btn add-section justify-content-center align-items-center p-3"
data-add-sections="{{title}}"
data-new-sections="{{newsection}}"
data-action="addSection"
{{#insertafter}} data-id="{{id}}" {{/insertafter}}
>
{{#pix}} t/add, core {{/pix}}
{{title}}
</a>
<div class="d-none p-3 max-section-alert" data-region="max-sections-warning">
<div class="w-100 text-center">
{{#pix}}t/block, moodle{{/pix}}
</div>
<div class="w-100 font-italic text-center">
{{#str}}maxsectionaddmessage, core_courseformat{{/str}}
</div>
</div>
{{/addsections}}
</div>
{{/showaddsection}}

View File

@ -33,21 +33,21 @@
}
}}
{{#showaddsection}}
<div class="changenumsections bulk-hidden" data-region="section-addsection">
<div class="changenumsections bulk-hidden {{^canaddsection}}disabled{{/canaddsection}}" data-region="section-addsection">
{{#addsections}}
{{< core_courseformat/local/content/divider}}
{{$extraclasses}}always-hidden mt-2{{/extraclasses}}
{{$content}}
<a href="{{{url}}}"
class="btn add-content section-modchooser section-modchooser-link activitychooser-button d-flex justify-content-center align-items-center p-1 icon-no-margin"
class="btn add-content section-modchooser section-modchooser-link activitychooser-button d-flex justify-content-center align-items-center p-1 icon-no-margin
{{^canaddsection}}disabled{{/canaddsection}}"
data-add-sections="{{title}}"
data-new-sections="{{newsection}}"
data-action="addSection"
{{#insertafter}} data-id="{{id}}" {{/insertafter}}
title="{{title}}"
title="{{#canaddsection}}{{title}}{{/canaddsection}}{{^canaddsection}}{{#str}}sectionaddmax, core_courseformat{{/str}}{{/canaddsection}}"
>
{{#pix}} t/add, core {{/pix}}
<span class="sr-only">{{title}}</span>
</a>
{{/content}}
{{/ core_courseformat/local/content/divider}}

View File

@ -381,3 +381,17 @@ Feature: Course index depending on role
And I turn editing mode on
When I set the field "Edit section name" in the "page-header" "region" to "Custom section name"
Then I should see "Custom section name" in the "courseindex-content" "region"
@javascript
Scenario: We cannot add a section when the number of section reaches maxsections but as soon as we reach under the limit we can add a section again.
Given the following config values are set as admin:
| maxsections | 4 | moodlecourse|
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
Then I should see "Section 1" in the "courseindex-content" "region"
And ".disabled" "css_element" should exist in the "[data-action='addSection']" "css_element"
And I should see "You have reached the maximum number of sections allowed for a course."
And I delete section "4"
And I click on "Delete" "button" in the ".modal" "css_element"
And ".disabled" "css_element" should not exist in the "[data-action='addSection']" "css_element"
And I should not see "You have reached the maximum number of sections allowed for a course."

View File

@ -63,6 +63,7 @@ $string['cmsmove_title'] = 'Move selected activities';
$string['cmsmove_info'] = 'Move {$a} activities after';
$string['courseindex'] = 'Course index';
$string['courseindexoptions'] = 'Course index options';
$string['maxsectionaddmessage'] = 'You have reached the maximum number of sections allowed for a course.';
$string['nobulkaction'] = 'No bulk actions available';
$string['preference:coursesectionspreferences'] = 'Section user preferences for course {$a}';
$string['privacy:metadata:preference:coursesectionspreferences'] = 'Section user preferences like collapsed and expanded.';
@ -72,6 +73,7 @@ $string['section_show_feedback'] = 'Course section {$a->name} shown.';
$string['section_show_feedback_batch'] = 'Selected {$a->count} course sections shown.';
$string['section_delete_feedback'] = 'Course section {$a->name} deleted.';
$string['section_delete_feedback_batch'] = 'Selected {$a->count} course sections deleted.';
$string['sectionaddmax'] = 'You have reached the maximum number of sections allowed for a course...';
$string['sectionavailability_title'] = 'Section availability';
$string['sectiondelete_info'] = 'This will delete {$a->name} and all the activities it contains.';
$string['sectiondelete_title'] = 'Delete section?';

View File

@ -1256,6 +1256,13 @@ $divider-hover-color: $primary !default;
}
}
.max-section-alert {
border-top: $divider-width dashed $border-color;
font-size: $font-size-sm;
font-weight: normal;
color: $gray-500;
}
/* Single section page specific styles */
.single-section {
@ -1549,6 +1556,9 @@ $divider-hover-color: $primary !default;
width: 100%;
margin: map-get($spacers, 2) map-get($spacers, 1);
border-top: $divider-width dashed $divider-color;
.changenumsections.disabled & {
border-top: $divider-width dashed $divider-color;
}
}
.divider-content {
opacity: 0;
@ -1588,6 +1598,9 @@ $divider-hover-color: $primary !default;
&:has(.btn.add-content:hover) {
hr {
border-color: $divider-hover-color;
.changenumsections.disabled & {
border-color: $gray-200;
}
}
}
}
@ -1625,6 +1638,20 @@ $divider-hover-color: $primary !default;
height: 14px;
font-size: 14px;
}
.changenumsections.disabled & {
color: $gray-500;
background-color: $gray-200;
outline: none;
box-shadow: none;
&:hover,
&:focus {
color: $gray-500;
background-color: $gray-200;
outline: none;
box-shadow: none;
}
pointer-events: auto; // Restore pointer events for the disabled button so we can see the tooltip.
}
}
/* Bulk editing */

View File

@ -29098,6 +29098,13 @@ span.editinstructions .alert-link {
color: #0f6cbf;
}
.max-section-alert {
border-top: 2px dashed #dee2e6;
font-size: 0.8203125rem;
font-weight: normal;
color: #8f959e;
}
/* Single section page specific styles */
.single-section > ul > .course-section.hidden .section-item {
background-color: inherit;
@ -29757,6 +29764,9 @@ span.editinstructions .alert-link {
margin: 0.5rem 0.25rem;
border-top: 2px dashed #dee2e6;
}
.changenumsections.disabled .divider hr {
border-top: 2px dashed #dee2e6;
}
.divider .divider-content {
opacity: 0;
visibility: hidden;
@ -29786,6 +29796,9 @@ span.editinstructions .alert-link {
.divider:has(.btn.add-content:hover) hr {
border-color: #0f6cbf;
}
.changenumsections.disabled .divider:has(.btn.add-content:hover) hr {
border-color: #e9ecef;
}
.activity:focus-within + .activity .divider .divider-content,
.course-section-header:focus-within + .content .section .activity:first-child .divider .divider-content,
@ -29816,6 +29829,19 @@ span.editinstructions .alert-link {
height: 14px;
font-size: 14px;
}
.changenumsections.disabled .btn.add-content {
color: #8f959e;
background-color: #e9ecef;
outline: none;
box-shadow: none;
pointer-events: auto;
}
.changenumsections.disabled .btn.add-content:hover, .changenumsections.disabled .btn.add-content:focus {
color: #8f959e;
background-color: #e9ecef;
outline: none;
box-shadow: none;
}
/* Bulk editing */
.bulkenabled .bulk-hidden {

View File

@ -29098,6 +29098,13 @@ span.editinstructions .alert-link {
color: #0f6cbf;
}
.max-section-alert {
border-top: 2px dashed #dee2e6;
font-size: 0.8203125rem;
font-weight: normal;
color: #8f959e;
}
/* Single section page specific styles */
.single-section > ul > .course-section.hidden .section-item {
background-color: inherit;
@ -29757,6 +29764,9 @@ span.editinstructions .alert-link {
margin: 0.5rem 0.25rem;
border-top: 2px dashed #dee2e6;
}
.changenumsections.disabled .divider hr {
border-top: 2px dashed #dee2e6;
}
.divider .divider-content {
opacity: 0;
visibility: hidden;
@ -29786,6 +29796,9 @@ span.editinstructions .alert-link {
.divider:has(.btn.add-content:hover) hr {
border-color: #0f6cbf;
}
.changenumsections.disabled .divider:has(.btn.add-content:hover) hr {
border-color: #e9ecef;
}
.activity:focus-within + .activity .divider .divider-content,
.course-section-header:focus-within + .content .section .activity:first-child .divider .divider-content,
@ -29816,6 +29829,19 @@ span.editinstructions .alert-link {
height: 14px;
font-size: 14px;
}
.changenumsections.disabled .btn.add-content {
color: #8f959e;
background-color: #e9ecef;
outline: none;
box-shadow: none;
pointer-events: auto;
}
.changenumsections.disabled .btn.add-content:hover, .changenumsections.disabled .btn.add-content:focus {
color: #8f959e;
background-color: #e9ecef;
outline: none;
box-shadow: none;
}
/* Bulk editing */
.bulkenabled .bulk-hidden {