MOBILE-3915 course: Implement new course index
This commit is contained in:
		
							parent
							
								
									1dd5eba1de
								
							
						
					
					
						commit
						86365d260d
					
				@ -20,7 +20,7 @@ import { CoreCourseFormatComponent } from './format/format';
 | 
				
			|||||||
import { CoreCourseModuleComponent } from './module/module';
 | 
					import { CoreCourseModuleComponent } from './module/module';
 | 
				
			||||||
import { CoreCourseModuleCompletionComponent } from './module-completion/module-completion';
 | 
					import { CoreCourseModuleCompletionComponent } from './module-completion/module-completion';
 | 
				
			||||||
import { CoreCourseModuleDescriptionComponent } from './module-description/module-description';
 | 
					import { CoreCourseModuleDescriptionComponent } from './module-description/module-description';
 | 
				
			||||||
import { CoreCourseSectionSelectorComponent } from './section-selector/section-selector';
 | 
					import { CoreCourseCourseIndexComponent } from './course-index/course-index';
 | 
				
			||||||
import { CoreCourseTagAreaComponent } from './tag-area/tag-area';
 | 
					import { CoreCourseTagAreaComponent } from './tag-area/tag-area';
 | 
				
			||||||
import { CoreCourseUnsupportedModuleComponent } from './unsupported-module/unsupported-module';
 | 
					import { CoreCourseUnsupportedModuleComponent } from './unsupported-module/unsupported-module';
 | 
				
			||||||
import { CoreCourseModuleCompletionLegacyComponent } from './module-completion-legacy/module-completion-legacy';
 | 
					import { CoreCourseModuleCompletionLegacyComponent } from './module-completion-legacy/module-completion-legacy';
 | 
				
			||||||
@ -37,7 +37,7 @@ import { CoreCourseModuleNavigationComponent } from './module-navigation/module-
 | 
				
			|||||||
        CoreCourseModuleDescriptionComponent,
 | 
					        CoreCourseModuleDescriptionComponent,
 | 
				
			||||||
        CoreCourseModuleInfoComponent,
 | 
					        CoreCourseModuleInfoComponent,
 | 
				
			||||||
        CoreCourseModuleManualCompletionComponent,
 | 
					        CoreCourseModuleManualCompletionComponent,
 | 
				
			||||||
        CoreCourseSectionSelectorComponent,
 | 
					        CoreCourseCourseIndexComponent,
 | 
				
			||||||
        CoreCourseTagAreaComponent,
 | 
					        CoreCourseTagAreaComponent,
 | 
				
			||||||
        CoreCourseUnsupportedModuleComponent,
 | 
					        CoreCourseUnsupportedModuleComponent,
 | 
				
			||||||
        CoreCourseModuleNavigationComponent,
 | 
					        CoreCourseModuleNavigationComponent,
 | 
				
			||||||
@ -54,7 +54,7 @@ import { CoreCourseModuleNavigationComponent } from './module-navigation/module-
 | 
				
			|||||||
        CoreCourseModuleDescriptionComponent,
 | 
					        CoreCourseModuleDescriptionComponent,
 | 
				
			||||||
        CoreCourseModuleInfoComponent,
 | 
					        CoreCourseModuleInfoComponent,
 | 
				
			||||||
        CoreCourseModuleManualCompletionComponent,
 | 
					        CoreCourseModuleManualCompletionComponent,
 | 
				
			||||||
        CoreCourseSectionSelectorComponent,
 | 
					        CoreCourseCourseIndexComponent,
 | 
				
			||||||
        CoreCourseTagAreaComponent,
 | 
					        CoreCourseTagAreaComponent,
 | 
				
			||||||
        CoreCourseUnsupportedModuleComponent,
 | 
					        CoreCourseUnsupportedModuleComponent,
 | 
				
			||||||
        CoreCourseModuleNavigationComponent,
 | 
					        CoreCourseModuleNavigationComponent,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
<ion-header>
 | 
					<ion-header>
 | 
				
			||||||
    <ion-toolbar>
 | 
					    <ion-toolbar>
 | 
				
			||||||
        <ion-title>
 | 
					        <ion-title>
 | 
				
			||||||
            <h2 id="core-course-section-selector-label">{{ 'core.course.sections' | translate }}</h2>
 | 
					            <h2 id="core-course-section-selector-label">{{ 'core.course.courseindex' | translate }}</h2>
 | 
				
			||||||
        </ion-title>
 | 
					        </ion-title>
 | 
				
			||||||
        <ion-buttons slot="end">
 | 
					        <ion-buttons slot="end">
 | 
				
			||||||
            <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
					            <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
				
			||||||
@ -13,10 +13,10 @@
 | 
				
			|||||||
<ion-content>
 | 
					<ion-content>
 | 
				
			||||||
    <ion-list id="core-course-section-selector" role="listbox" aria-labelledby="core-course-section-selector-label">
 | 
					    <ion-list id="core-course-section-selector" role="listbox" aria-labelledby="core-course-section-selector-label">
 | 
				
			||||||
        <ng-container *ngFor="let section of sections">
 | 
					        <ng-container *ngFor="let section of sections">
 | 
				
			||||||
            <ion-item *ngIf="!section.hiddenbynumsections && section.id != stealthModulesSectionId" class="ion-text-wrap"
 | 
					            <ion-item-divider *ngIf="!section.hiddenbynumsections && section.id != stealthModulesSectionId" class="ion-text-wrap"
 | 
				
			||||||
                (click)="selectSection(section)" [attr.aria-current]="selected?.id == section.id ? 'page' : 'false'"
 | 
					                (click)="selectSection(section)" [attr.aria-current]="selected?.id == section.id ? 'page' : 'false'"
 | 
				
			||||||
                [class.item-dimmed]="section.visible === 0 || section.uservisible === false" detail="false"
 | 
					                [class.item-dimmed]="section.visible === 0 || section.uservisible === false" detail="false"
 | 
				
			||||||
                [attr.aria-hidden]="section.uservisible === false" button>
 | 
					                [attr.aria-hidden]="section.uservisible === false" button sticky="true">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <ion-icon name="fas-folder" slot="start" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-folder" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                <ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
@ -39,7 +39,24 @@
 | 
				
			|||||||
                        </core-format-text>
 | 
					                        </core-format-text>
 | 
				
			||||||
                    </ion-badge>
 | 
					                    </ion-badge>
 | 
				
			||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
 | 
					            </ion-item-divider>
 | 
				
			||||||
 | 
					            <ng-container *ngFor="let module of section.modules">
 | 
				
			||||||
 | 
					                <ion-item *ngIf="module.visibleoncoursepage !== 0" class="ion-text-wrap">
 | 
				
			||||||
 | 
					                    <!-- TODO Add Aria, styles when disabled, etc. -->
 | 
				
			||||||
 | 
					                    <ion-icon name="" *ngIf="module.completionStatus === undefined" slot="start"></ion-icon>
 | 
				
			||||||
 | 
					                    <ion-icon name="far-circle" *ngIf="module.completionStatus === 0" slot="start"></ion-icon>
 | 
				
			||||||
 | 
					                    <ion-icon name="fas-circle" *ngIf="module.completionStatus === 1" color="success" slot="start"></ion-icon>
 | 
				
			||||||
 | 
					                    <ion-icon name="fas-circle" *ngIf="module.completionStatus === 2" color="success" slot="start"></ion-icon>
 | 
				
			||||||
 | 
					                    <ion-icon name="fas-circle" *ngIf="module.completionStatus === 3" color="danger" slot="start"></ion-icon>
 | 
				
			||||||
 | 
					                    <ion-label>
 | 
				
			||||||
 | 
					                        <p class="item-heading">
 | 
				
			||||||
 | 
					                            <core-format-text [text]="module.name" contextLevel="module" [contextInstanceId]="module.id"
 | 
				
			||||||
 | 
					                                [courseId]="module.courseid">
 | 
				
			||||||
 | 
					                            </core-format-text>
 | 
				
			||||||
 | 
					                        </p>
 | 
				
			||||||
 | 
					                    </ion-label>
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
            </ng-container>
 | 
					            </ng-container>
 | 
				
			||||||
 | 
					        </ng-container>
 | 
				
			||||||
    </ion-list>
 | 
					    </ion-list>
 | 
				
			||||||
</ion-content>
 | 
					</ion-content>
 | 
				
			||||||
@ -14,7 +14,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { Component, Input, OnInit } from '@angular/core';
 | 
					import { Component, Input, OnInit } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { CoreCourseSection } from '@features/course/services/course-helper';
 | 
					import { CoreCourseModuleData, CoreCourseSection, CoreCourseSectionWithStatus } from '@features/course/services/course-helper';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    CoreCourseModuleCompletionStatus,
 | 
					    CoreCourseModuleCompletionStatus,
 | 
				
			||||||
    CoreCourseModuleCompletionTracking,
 | 
					    CoreCourseModuleCompletionTracking,
 | 
				
			||||||
@ -25,14 +25,14 @@ import { CoreUtils } from '@services/utils/utils';
 | 
				
			|||||||
import { ModalController } from '@singletons';
 | 
					import { ModalController } from '@singletons';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Component to display course section selector in a modal.
 | 
					 * Component to display course index modal.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
    selector: 'core-course-section-selector',
 | 
					    selector: 'core-course-course-index',
 | 
				
			||||||
    templateUrl: 'section-selector.html',
 | 
					    templateUrl: 'course-index.html',
 | 
				
			||||||
    styleUrls: ['section-selector.scss'],
 | 
					    styleUrls: ['course-index.scss'],
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class CoreCourseSectionSelectorComponent implements OnInit {
 | 
					export class CoreCourseCourseIndexComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Input() sections?: SectionWithProgress[];
 | 
					    @Input() sections?: SectionWithProgress[];
 | 
				
			||||||
    @Input() selected?: CoreCourseSection;
 | 
					    @Input() selected?: CoreCourseSection;
 | 
				
			||||||
@ -41,7 +41,7 @@ export class CoreCourseSectionSelectorComponent implements OnInit {
 | 
				
			|||||||
    stealthModulesSectionId = CoreCourseProvider.STEALTH_MODULES_SECTION_ID;
 | 
					    stealthModulesSectionId = CoreCourseProvider.STEALTH_MODULES_SECTION_ID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Component being initialized.
 | 
					     * @inheritdoc
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    ngOnInit(): void {
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -52,7 +52,7 @@ export class CoreCourseSectionSelectorComponent implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        const formatOptions = CoreUtils.objectToKeyValueMap(this.course.courseformatoptions, 'name', 'value');
 | 
					        const formatOptions = CoreUtils.objectToKeyValueMap(this.course.courseformatoptions, 'name', 'value');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!formatOptions || formatOptions.coursedisplay != 1 || formatOptions.completionusertracked === false) {
 | 
					        if (!formatOptions || formatOptions.completionusertracked === false) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,11 +60,16 @@ export class CoreCourseSectionSelectorComponent implements OnInit {
 | 
				
			|||||||
            let complete = 0;
 | 
					            let complete = 0;
 | 
				
			||||||
            let total = 0;
 | 
					            let total = 0;
 | 
				
			||||||
            section.modules.forEach((module) => {
 | 
					            section.modules.forEach((module) => {
 | 
				
			||||||
 | 
					                console.error(module);
 | 
				
			||||||
                if (!module.uservisible || module.completiondata === undefined ||
 | 
					                if (!module.uservisible || module.completiondata === undefined ||
 | 
				
			||||||
                        module.completiondata.tracking == CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_NONE) {
 | 
					                        module.completiondata.tracking == CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_NONE) {
 | 
				
			||||||
 | 
					                    module.completionStatus = undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                module.completionStatus = module.completiondata.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                total++;
 | 
					                total++;
 | 
				
			||||||
                if (module.completiondata.state == CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE ||
 | 
					                if (module.completiondata.state == CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE ||
 | 
				
			||||||
                        module.completiondata.state == CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_PASS) {
 | 
					                        module.completiondata.state == CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_PASS) {
 | 
				
			||||||
@ -98,6 +103,9 @@ export class CoreCourseSectionSelectorComponent implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SectionWithProgress = CoreCourseSection & {
 | 
					type SectionWithProgress = Omit<CoreCourseSectionWithStatus, 'modules'> & {
 | 
				
			||||||
    progress?: number;
 | 
					    progress?: number;
 | 
				
			||||||
 | 
					    modules: (CoreCourseModuleData & {
 | 
				
			||||||
 | 
					        completionStatus?: CoreCourseModuleCompletionStatus;
 | 
				
			||||||
 | 
					    })[];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
<!-- Buttons to add to the header. *ngIf is needed, otherwise the component is executed too soon and doesn't find the header. -->
 | 
					<!-- Buttons to add to the header. *ngIf is needed, otherwise the component is executed too soon and doesn't find the header. -->
 | 
				
			||||||
<core-navbar-buttons slot="end" *ngIf="loaded">
 | 
					<core-navbar-buttons slot="end" *ngIf="loaded">
 | 
				
			||||||
    <core-context-menu>
 | 
					    <core-context-menu>
 | 
				
			||||||
        <core-context-menu-item [hidden]="!displaySectionSelector || !sections || !sections.length" [priority]="500"
 | 
					        <core-context-menu-item [hidden]="!displayCourseIndex || !sections || !sections.length" [priority]="500"
 | 
				
			||||||
            [content]="'core.course.sections' | translate" (action)="showSectionSelector()" iconAction="menu">
 | 
					            [content]="'core.course.courseindex' | translate" (action)="openCourseIndex()" iconAction="menu">
 | 
				
			||||||
        </core-context-menu-item>
 | 
					        </core-context-menu-item>
 | 
				
			||||||
    </core-context-menu>
 | 
					    </core-context-menu>
 | 
				
			||||||
</core-navbar-buttons>
 | 
					</core-navbar-buttons>
 | 
				
			||||||
@ -32,46 +32,6 @@
 | 
				
			|||||||
                    <ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
					                    <ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                </ion-button>
 | 
					                </ion-button>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
            <ion-item *ngIf="selectedSection && selectedSection.id != allSectionsId" class="ion-text-wrap">
 | 
					 | 
				
			||||||
                <ion-icon name="fas-folder" aria-label="hidden" slot="start"></ion-icon>
 | 
					 | 
				
			||||||
                <ion-label>
 | 
					 | 
				
			||||||
                    <p class="item-heading">
 | 
					 | 
				
			||||||
                        <core-format-text *ngIf="selectedSection" [text]="selectedSection.name" contextLevel="course"
 | 
					 | 
				
			||||||
                            [contextInstanceId]="course.id" [clean]="true" [singleLine]="true">
 | 
					 | 
				
			||||||
                        </core-format-text>
 | 
					 | 
				
			||||||
                    </p>
 | 
					 | 
				
			||||||
                    <ion-badge color="info" class="ion-text-wrap"
 | 
					 | 
				
			||||||
                        *ngIf="selectedSection.visible === 0 && selectedSection.uservisible !== false">
 | 
					 | 
				
			||||||
                        {{ 'core.course.hiddenfromstudents' | translate }}
 | 
					 | 
				
			||||||
                    </ion-badge>
 | 
					 | 
				
			||||||
                    <ion-badge color="info" class="ion-text-wrap"
 | 
					 | 
				
			||||||
                        *ngIf="selectedSection.visible === 0 && selectedSection.uservisible === false">
 | 
					 | 
				
			||||||
                        {{ 'core.notavailable' | translate }}
 | 
					 | 
				
			||||||
                    </ion-badge>
 | 
					 | 
				
			||||||
                    <ion-badge color="info" class="ion-text-wrap" *ngIf="selectedSection.availabilityinfo">
 | 
					 | 
				
			||||||
                        <core-format-text [text]="selectedSection.availabilityinfo" contextLevel="course" [contextInstanceId]="course.id">
 | 
					 | 
				
			||||||
                        </core-format-text>
 | 
					 | 
				
			||||||
                    </ion-badge>
 | 
					 | 
				
			||||||
                </ion-label>
 | 
					 | 
				
			||||||
            </ion-item>
 | 
					 | 
				
			||||||
        </core-dynamic-component>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <!-- Section selector. -->
 | 
					 | 
				
			||||||
        <core-dynamic-component [component]="sectionSelectorComponent" [data]="data">
 | 
					 | 
				
			||||||
            <div *ngIf="displaySectionSelector && sections && hasSeveralSections"
 | 
					 | 
				
			||||||
                class="ion-text-wrap ion-justify-content-between ion-align-items-center core-button-selector-row">
 | 
					 | 
				
			||||||
                <core-combobox [modalOptions]="sectionSelectorModalOptions" interface="modal" listboxId="core-course-section-button"
 | 
					 | 
				
			||||||
                    icon="fas-folder" [label]="'core.course.section' | translate"
 | 
					 | 
				
			||||||
                    [selection]="selectedSection ? selectedSection.name : 'core.course.sections' | translate"
 | 
					 | 
				
			||||||
                    (onChange)="sectionChanged($event)">
 | 
					 | 
				
			||||||
                    <span slot="text">
 | 
					 | 
				
			||||||
                        <core-format-text *ngIf="selectedSection" [text]="selectedSection.name" contextLevel="course"
 | 
					 | 
				
			||||||
                            [contextInstanceId]="course.id" [clean]="true" [singleLine]="true">
 | 
					 | 
				
			||||||
                        </core-format-text>
 | 
					 | 
				
			||||||
                        <ng-container *ngIf="!selectedSection">{{ 'core.course.sections' | translate }}</ng-container>
 | 
					 | 
				
			||||||
                    </span>
 | 
					 | 
				
			||||||
                </core-combobox>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </core-dynamic-component>
 | 
					        </core-dynamic-component>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <!-- Single section. -->
 | 
					        <!-- Single section. -->
 | 
				
			||||||
@ -98,7 +58,7 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <ion-buttons class="ion-padding core-course-section-nav-buttons safe-area-padding-horizontal"
 | 
					        <ion-buttons class="ion-padding core-course-section-nav-buttons safe-area-padding-horizontal"
 | 
				
			||||||
            *ngIf="displaySectionSelector && sections?.length">
 | 
					            *ngIf="displayCourseIndex && sections?.length">
 | 
				
			||||||
            <ion-button *ngIf="previousSection" (click)="sectionChanged(previousSection)" fill="outline" color="primary"
 | 
					            <ion-button *ngIf="previousSection" (click)="sectionChanged(previousSection)" fill="outline" color="primary"
 | 
				
			||||||
                [attr.aria-label]="('core.previous' | translate) + ': ' + previousSection.name">
 | 
					                [attr.aria-label]="('core.previous' | translate) + ': ' + previousSection.name">
 | 
				
			||||||
                <ion-icon name="fas-chevron-left" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-chevron-left" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
				
			||||||
@ -115,17 +75,25 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        <core-block-side-blocks-button *ngIf="course && displayBlocks && hasBlocks" [courseId]="course.id">
 | 
					        <core-block-side-blocks-button *ngIf="course && displayBlocks && hasBlocks" [courseId]="course.id">
 | 
				
			||||||
        </core-block-side-blocks-button>
 | 
					        </core-block-side-blocks-button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </core-loading>
 | 
					    </core-loading>
 | 
				
			||||||
</core-dynamic-component>
 | 
					</core-dynamic-component>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- Course Index button. -->
 | 
				
			||||||
 | 
					<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="displayCourseIndex">
 | 
				
			||||||
 | 
					    <ion-fab-button (click)="openCourseIndex()" [attr.aria-label]="'core.course.courseindex' | translate">
 | 
				
			||||||
 | 
					        <ion-icon name="fas-list-ul" aria-hidden="true"></ion-icon>
 | 
				
			||||||
 | 
					        <span class="sr-only">{{'core.course.courseindex' | translate }}</span>
 | 
				
			||||||
 | 
					    </ion-fab-button>
 | 
				
			||||||
 | 
					</ion-fab>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- Template to render a section. -->
 | 
					<!-- Template to render a section. -->
 | 
				
			||||||
<ng-template #sectionTemplate let-section="section">
 | 
					<ng-template #sectionTemplate let-section="section">
 | 
				
			||||||
    <section *ngIf="!section.hiddenbynumsections && section.id != allSectionsId && section.id != stealthModulesSectionId">
 | 
					    <section *ngIf="!section.hiddenbynumsections && section.id != allSectionsId && section.id != stealthModulesSectionId">
 | 
				
			||||||
        <!-- Title is only displayed when viewing all sections. -->
 | 
					        <ion-item-divider class="ion-text-wrap" color="light" [class.item-dimmed]="section.visible === 0 || section.uservisible === false">
 | 
				
			||||||
        <ion-item-divider *ngIf="selectedSection?.id == allSectionsId && section.name" class="ion-text-wrap" color="light"
 | 
					            <ion-icon name="fas-folder" aria-label="hidden" slot="start"></ion-icon>
 | 
				
			||||||
            [class.item-dimmed]="section.visible === 0 || section.uservisible === false">
 | 
					 | 
				
			||||||
            <ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
                <h2>
 | 
					                <h2 *ngIf="section.name">
 | 
				
			||||||
                    <core-format-text [text]="section.name" contextLevel="course" [contextInstanceId]="course.id">
 | 
					                    <core-format-text [text]="section.name" contextLevel="course" [contextInstanceId]="course.id">
 | 
				
			||||||
                    </core-format-text>
 | 
					                    </core-format-text>
 | 
				
			||||||
                </h2>
 | 
					                </h2>
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,6 @@ import {
 | 
				
			|||||||
    Type,
 | 
					    Type,
 | 
				
			||||||
    ElementRef,
 | 
					    ElementRef,
 | 
				
			||||||
} from '@angular/core';
 | 
					} from '@angular/core';
 | 
				
			||||||
import { ModalOptions } from '@ionic/core';
 | 
					 | 
				
			||||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
					import { CoreDomUtils } from '@services/utils/dom';
 | 
				
			||||||
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
 | 
					import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
 | 
				
			||||||
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
 | 
					import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
 | 
				
			||||||
@ -45,7 +44,7 @@ import { CoreCourseFormatDelegate } from '@features/course/services/format-deleg
 | 
				
			|||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
 | 
					import { CoreEventObserver, CoreEvents } from '@singletons/events';
 | 
				
			||||||
import { IonContent, IonRefresher } from '@ionic/angular';
 | 
					import { IonContent, IonRefresher } from '@ionic/angular';
 | 
				
			||||||
import { CoreUtils } from '@services/utils/utils';
 | 
					import { CoreUtils } from '@services/utils/utils';
 | 
				
			||||||
import { CoreCourseSectionSelectorComponent } from '../section-selector/section-selector';
 | 
					import { CoreCourseCourseIndexComponent } from '../course-index/course-index';
 | 
				
			||||||
import { CoreBlockHelper } from '@features/block/services/block-helper';
 | 
					import { CoreBlockHelper } from '@features/block/services/block-helper';
 | 
				
			||||||
import { CoreNavigator } from '@services/navigator';
 | 
					import { CoreNavigator } from '@services/navigator';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -80,7 +79,6 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
    // All the possible component classes.
 | 
					    // All the possible component classes.
 | 
				
			||||||
    courseFormatComponent?: Type<unknown>;
 | 
					    courseFormatComponent?: Type<unknown>;
 | 
				
			||||||
    courseSummaryComponent?: Type<unknown>;
 | 
					    courseSummaryComponent?: Type<unknown>;
 | 
				
			||||||
    sectionSelectorComponent?: Type<unknown>;
 | 
					 | 
				
			||||||
    singleSectionComponent?: Type<unknown>;
 | 
					    singleSectionComponent?: Type<unknown>;
 | 
				
			||||||
    allSectionsComponent?: Type<unknown>;
 | 
					    allSectionsComponent?: Type<unknown>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -88,7 +86,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
    showSectionId = 0;
 | 
					    showSectionId = 0;
 | 
				
			||||||
    data: Record<string, unknown> = {}; // Data to pass to the components.
 | 
					    data: Record<string, unknown> = {}; // Data to pass to the components.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    displaySectionSelector = false;
 | 
					    displayCourseIndex = false;
 | 
				
			||||||
    displayBlocks = false;
 | 
					    displayBlocks = false;
 | 
				
			||||||
    hasBlocks = false;
 | 
					    hasBlocks = false;
 | 
				
			||||||
    selectedSection?: CoreCourseSection;
 | 
					    selectedSection?: CoreCourseSection;
 | 
				
			||||||
@ -97,17 +95,11 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
    allSectionsId: number = CoreCourseProvider.ALL_SECTIONS_ID;
 | 
					    allSectionsId: number = CoreCourseProvider.ALL_SECTIONS_ID;
 | 
				
			||||||
    stealthModulesSectionId: number = CoreCourseProvider.STEALTH_MODULES_SECTION_ID;
 | 
					    stealthModulesSectionId: number = CoreCourseProvider.STEALTH_MODULES_SECTION_ID;
 | 
				
			||||||
    loaded = false;
 | 
					    loaded = false;
 | 
				
			||||||
    hasSeveralSections?: boolean;
 | 
					 | 
				
			||||||
    imageThumb?: string;
 | 
					    imageThumb?: string;
 | 
				
			||||||
    progress?: number;
 | 
					    progress?: number;
 | 
				
			||||||
    sectionSelectorModalOptions: ModalOptions = {
 | 
					 | 
				
			||||||
        component: CoreCourseSectionSelectorComponent,
 | 
					 | 
				
			||||||
        componentProps: {},
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected selectTabObserver?: CoreEventObserver;
 | 
					    protected selectTabObserver?: CoreEventObserver;
 | 
				
			||||||
    protected lastCourseFormat?: string;
 | 
					    protected lastCourseFormat?: string;
 | 
				
			||||||
    protected sectionSelectorExpanded = false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(
 | 
					    constructor(
 | 
				
			||||||
        protected content: IonContent,
 | 
					        protected content: IonContent,
 | 
				
			||||||
@ -154,14 +146,12 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    async ngOnChanges(changes: { [name: string]: SimpleChange }): Promise<void> {
 | 
					    async ngOnChanges(changes: { [name: string]: SimpleChange }): Promise<void> {
 | 
				
			||||||
        this.setInputData();
 | 
					        this.setInputData();
 | 
				
			||||||
        this.sectionSelectorModalOptions.componentProps!.course = this.course;
 | 
					 | 
				
			||||||
        this.sectionSelectorModalOptions.componentProps!.sections = this.sections;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (changes.course && this.course) {
 | 
					        if (changes.course && this.course) {
 | 
				
			||||||
            // Course has changed, try to get the components.
 | 
					            // Course has changed, try to get the components.
 | 
				
			||||||
            this.getComponents();
 | 
					            this.getComponents();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.displaySectionSelector = CoreCourseFormatDelegate.displaySectionSelector(this.course);
 | 
					            this.displayCourseIndex = CoreCourseFormatDelegate.displaySectionSelector(this.course);
 | 
				
			||||||
            this.displayBlocks = CoreCourseFormatDelegate.displayBlocks(this.course);
 | 
					            this.displayBlocks = CoreCourseFormatDelegate.displayBlocks(this.course);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.hasBlocks = await CoreBlockHelper.hasCourseBlocks(this.course.id);
 | 
					            this.hasBlocks = await CoreBlockHelper.hasCourseBlocks(this.course.id);
 | 
				
			||||||
@ -174,7 +164,6 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (changes.sections && this.sections) {
 | 
					        if (changes.sections && this.sections) {
 | 
				
			||||||
            this.sectionSelectorModalOptions.componentProps!.sections = this.sections;
 | 
					 | 
				
			||||||
            this.treatSections(this.sections);
 | 
					            this.treatSections(this.sections);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -205,7 +194,6 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
        await Promise.all([
 | 
					        await Promise.all([
 | 
				
			||||||
            this.loadCourseFormatComponent(),
 | 
					            this.loadCourseFormatComponent(),
 | 
				
			||||||
            this.loadCourseSummaryComponent(),
 | 
					            this.loadCourseSummaryComponent(),
 | 
				
			||||||
            this.loadSectionSelectorComponent(),
 | 
					 | 
				
			||||||
            this.loadSingleSectionComponent(),
 | 
					            this.loadSingleSectionComponent(),
 | 
				
			||||||
            this.loadAllSectionsComponent(),
 | 
					            this.loadAllSectionsComponent(),
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
@ -229,15 +217,6 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
        this.courseSummaryComponent = await CoreCourseFormatDelegate.getCourseSummaryComponent(this.course);
 | 
					        this.courseSummaryComponent = await CoreCourseFormatDelegate.getCourseSummaryComponent(this.course);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Load section selector component.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return Promise resolved when done.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected async loadSectionSelectorComponent(): Promise<void> {
 | 
					 | 
				
			||||||
        this.sectionSelectorComponent = await CoreCourseFormatDelegate.getSectionSelectorComponent(this.course);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Load single section component.
 | 
					     * Load single section component.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -264,7 +243,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    protected async treatSections(sections: CoreCourseSection[]): Promise<void> {
 | 
					    protected async treatSections(sections: CoreCourseSection[]): Promise<void> {
 | 
				
			||||||
        const hasAllSections = sections[0].id == CoreCourseProvider.ALL_SECTIONS_ID;
 | 
					        const hasAllSections = sections[0].id == CoreCourseProvider.ALL_SECTIONS_ID;
 | 
				
			||||||
        this.hasSeveralSections = sections.length > 2 || (sections.length == 2 && !hasAllSections);
 | 
					        const hasSeveralSections = sections.length > 2 || (sections.length == 2 && !hasAllSections);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this.selectedSection) {
 | 
					        if (this.selectedSection) {
 | 
				
			||||||
            // We have a selected section, but the list has changed. Search the section in the list.
 | 
					            // We have a selected section, but the list has changed. Search the section in the list.
 | 
				
			||||||
@ -281,7 +260,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // There is no selected section yet, calculate which one to load.
 | 
					        // There is no selected section yet, calculate which one to load.
 | 
				
			||||||
        if (!this.hasSeveralSections) {
 | 
					        if (!hasSeveralSections) {
 | 
				
			||||||
            // Always load "All sections" to display the section title. If it isn't there just load the section.
 | 
					            // Always load "All sections" to display the section title. If it isn't there just load the section.
 | 
				
			||||||
            this.loaded = true;
 | 
					            this.loaded = true;
 | 
				
			||||||
            this.sectionChanged(sections[0]);
 | 
					            this.sectionChanged(sections[0]);
 | 
				
			||||||
@ -309,18 +288,18 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Display the section selector modal.
 | 
					     * Display the course index modal.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    async showSectionSelector(): Promise<void> {
 | 
					    async openCourseIndex(): Promise<void> {
 | 
				
			||||||
        if (this.sectionSelectorExpanded) {
 | 
					        const data = await CoreDomUtils.openModal<CoreCourseSection>({
 | 
				
			||||||
            return;
 | 
					            component: CoreCourseCourseIndexComponent,
 | 
				
			||||||
        }
 | 
					            componentProps: {
 | 
				
			||||||
 | 
					                course: this.course,
 | 
				
			||||||
 | 
					                sections: this.sections,
 | 
				
			||||||
 | 
					                selected: this.selectedSection,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.sectionSelectorExpanded = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const data = await CoreDomUtils.openModal<CoreCourseSection>(this.sectionSelectorModalOptions);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this.sectionSelectorExpanded = false;
 | 
					 | 
				
			||||||
        if (data) {
 | 
					        if (data) {
 | 
				
			||||||
            this.sectionChanged(data);
 | 
					            this.sectionChanged(data);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -334,7 +313,6 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
    sectionChanged(newSection: CoreCourseSection): void {
 | 
					    sectionChanged(newSection: CoreCourseSection): void {
 | 
				
			||||||
        const previousValue = this.selectedSection;
 | 
					        const previousValue = this.selectedSection;
 | 
				
			||||||
        this.selectedSection = newSection;
 | 
					        this.selectedSection = newSection;
 | 
				
			||||||
        this.sectionSelectorModalOptions.componentProps!.selected = this.selectedSection;
 | 
					 | 
				
			||||||
        this.data.section = this.selectedSection;
 | 
					        this.data.section = this.selectedSection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (newSection.id != this.allSectionsId) {
 | 
					        if (newSection.id != this.allSectionsId) {
 | 
				
			||||||
 | 
				
			|||||||
@ -52,31 +52,29 @@ export class CoreCourseModuleCompletionLegacyComponent extends CoreCourseModuleC
 | 
				
			|||||||
        let langKey: string | undefined;
 | 
					        let langKey: string | undefined;
 | 
				
			||||||
        let image: string | undefined;
 | 
					        let image: string | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_MANUAL &&
 | 
					        if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_MANUAL) {
 | 
				
			||||||
                this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE) {
 | 
					            if (this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE) {
 | 
				
			||||||
                image = 'completion-manual-n';
 | 
					                image = 'completion-manual-n';
 | 
				
			||||||
                langKey = 'core.completion-alt-manual-n';
 | 
					                langKey = 'core.completion-alt-manual-n';
 | 
				
			||||||
        } else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_MANUAL &&
 | 
					            } else if (this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE) {
 | 
				
			||||||
                this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE) {
 | 
					 | 
				
			||||||
                image = 'completion-manual-y';
 | 
					                image = 'completion-manual-y';
 | 
				
			||||||
                langKey = 'core.completion-alt-manual-y';
 | 
					                langKey = 'core.completion-alt-manual-y';
 | 
				
			||||||
        } else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC &&
 | 
					            }
 | 
				
			||||||
                this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE) {
 | 
					        } else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC) {
 | 
				
			||||||
 | 
					            if (this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE) {
 | 
				
			||||||
                image = 'completion-auto-n';
 | 
					                image = 'completion-auto-n';
 | 
				
			||||||
                langKey = 'core.completion-alt-auto-n';
 | 
					                langKey = 'core.completion-alt-auto-n';
 | 
				
			||||||
        } else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC &&
 | 
					            } else if (this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE) {
 | 
				
			||||||
                this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE) {
 | 
					 | 
				
			||||||
                image = 'completion-auto-y';
 | 
					                image = 'completion-auto-y';
 | 
				
			||||||
                langKey = 'core.completion-alt-auto-y';
 | 
					                langKey = 'core.completion-alt-auto-y';
 | 
				
			||||||
        } else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC &&
 | 
					            } else if (this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_PASS) {
 | 
				
			||||||
                this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_PASS) {
 | 
					 | 
				
			||||||
                image = 'completion-auto-pass';
 | 
					                image = 'completion-auto-pass';
 | 
				
			||||||
                langKey = 'core.completion-alt-auto-pass';
 | 
					                langKey = 'core.completion-alt-auto-pass';
 | 
				
			||||||
        } else if (this.completion.tracking === CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC &&
 | 
					            } else if (this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_FAIL) {
 | 
				
			||||||
                this.completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_FAIL) {
 | 
					 | 
				
			||||||
                image = 'completion-auto-fail';
 | 
					                image = 'completion-auto-fail';
 | 
				
			||||||
                langKey = 'core.completion-alt-auto-fail';
 | 
					                langKey = 'core.completion-alt-auto-fail';
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (image) {
 | 
					        if (image) {
 | 
				
			||||||
            if (this.completion.overrideby && this.completion.overrideby > 0) {
 | 
					            if (this.completion.overrideby && this.completion.overrideby > 0) {
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,7 @@
 | 
				
			|||||||
    "confirmdownloadzerosize": "You are about to start downloading.{{availableSpace}} Are you sure you want to continue?",
 | 
					    "confirmdownloadzerosize": "You are about to start downloading.{{availableSpace}} Are you sure you want to continue?",
 | 
				
			||||||
    "confirmpartialdownloadsize": "You are about to download <strong>at least</strong> {{size}}.{{availableSpace}} Are you sure you want to continue?",
 | 
					    "confirmpartialdownloadsize": "You are about to download <strong>at least</strong> {{size}}.{{availableSpace}} Are you sure you want to continue?",
 | 
				
			||||||
    "confirmlimiteddownload": "You are not currently connected to Wi-Fi. ",
 | 
					    "confirmlimiteddownload": "You are not currently connected to Wi-Fi. ",
 | 
				
			||||||
 | 
					    "courseindex": "Course index",
 | 
				
			||||||
    "gotonextactivity": "Continue to next activity",
 | 
					    "gotonextactivity": "Continue to next activity",
 | 
				
			||||||
    "gotonextactivitynotfound": "Next activity not found. It's possible that it has been hidden or deleted.",
 | 
					    "gotonextactivitynotfound": "Next activity not found. It's possible that it has been hidden or deleted.",
 | 
				
			||||||
    "gotopreviousactivity": "Continue to previous activity",
 | 
					    "gotopreviousactivity": "Continue to previous activity",
 | 
				
			||||||
@ -49,7 +50,6 @@
 | 
				
			|||||||
    "overriddennotice": "Your final grade from this activity was manually adjusted.",
 | 
					    "overriddennotice": "Your final grade from this activity was manually adjusted.",
 | 
				
			||||||
    "refreshcourse": "Refresh course",
 | 
					    "refreshcourse": "Refresh course",
 | 
				
			||||||
    "section": "Section",
 | 
					    "section": "Section",
 | 
				
			||||||
    "sections": "Sections",
 | 
					 | 
				
			||||||
    "useactivityonbrowser": "You can still use it using your device's web browser.",
 | 
					    "useactivityonbrowser": "You can still use it using your device's web browser.",
 | 
				
			||||||
    "warningmanualcompletionmodified": "The manual completion of an activity was modified on the site.",
 | 
					    "warningmanualcompletionmodified": "The manual completion of an activity was modified on the site.",
 | 
				
			||||||
    "warningofflinemanualcompletiondeleted": "Some offline manual completion of course '{{name}}' has been deleted. {{error}}"
 | 
					    "warningofflinemanualcompletiondeleted": "Some offline manual completion of course '{{name}}' has been deleted. {{error}}"
 | 
				
			||||||
 | 
				
			|||||||
@ -62,7 +62,7 @@ declare module '@singletons/events' {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Completion status valid values.
 | 
					 * Course Module completion status enumeration.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export enum CoreCourseModuleCompletionStatus {
 | 
					export enum CoreCourseModuleCompletionStatus {
 | 
				
			||||||
    COMPLETION_INCOMPLETE = 0,
 | 
					    COMPLETION_INCOMPLETE = 0,
 | 
				
			||||||
 | 
				
			|||||||
@ -125,15 +125,6 @@ export interface CoreCourseFormatHandler extends CoreDelegateHandler {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    getCourseSummaryComponent?(course: CoreCourseAnyCourseData): Promise<Type<unknown> | undefined>;
 | 
					    getCourseSummaryComponent?(course: CoreCourseAnyCourseData): Promise<Type<unknown> | undefined>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Return the Component to use to display the section selector inside the default course format.
 | 
					 | 
				
			||||||
     * It's recommended to return the class of the component, but you can also return an instance of the component.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param course The course to render.
 | 
					 | 
				
			||||||
     * @return Promise resolved with component to use, undefined if not found.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    getSectionSelectorComponent?(course: CoreCourseAnyCourseData): Promise<Type<unknown> | undefined>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Return the Component to use to display a single section. This component will only be used if the user is viewing a
 | 
					     * Return the Component to use to display a single section. This component will only be used if the user is viewing a
 | 
				
			||||||
     * single section. If all the sections are displayed at once then it won't be used.
 | 
					     * single section. If all the sections are displayed at once then it won't be used.
 | 
				
			||||||
@ -302,20 +293,6 @@ export class CoreCourseFormatDelegateService extends CoreDelegate<CoreCourseForm
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Get the component to use to display the section selector inside the default course format.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param course The course to render.
 | 
					 | 
				
			||||||
     * @return Promise resolved with component to use, undefined if not found.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    async getSectionSelectorComponent(course: CoreCourseAnyCourseData): Promise<Type<unknown> | undefined> {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            return await this.executeFunctionOnEnabled<Type<unknown>>(course.format || '', 'getSectionSelectorComponent', [course]);
 | 
					 | 
				
			||||||
        } catch (error) {
 | 
					 | 
				
			||||||
            this.logger.error('Error getting section selector component', error);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get the component to use to display a single section. This component will only be used if the user is viewing
 | 
					     * Get the component to use to display a single section. This component will only be used if the user is viewing
 | 
				
			||||||
     * a single section. If all the sections are displayed at once then it won't be used.
 | 
					     * a single section. If all the sections are displayed at once then it won't be used.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user