MOBILE-3833 course: Collapse sections in downloads page
This commit is contained in:
		
							parent
							
								
									37af8e3c69
								
							
						
					
					
						commit
						0298273fc4
					
				@ -47,7 +47,13 @@
 | 
				
			|||||||
        <ng-container *ngFor="let section of sections">
 | 
					        <ng-container *ngFor="let section of sections">
 | 
				
			||||||
            <ion-card class="section" *ngIf="section.modules.length > 0">
 | 
					            <ion-card class="section" *ngIf="section.modules.length > 0">
 | 
				
			||||||
                <ion-card-header>
 | 
					                <ion-card-header>
 | 
				
			||||||
                    <ion-item class="ion-no-padding" lines="full">
 | 
					                    <ion-item class="ion-no-padding" [lines]="section.expanded ? 'full' : 'none'" button detail="false"
 | 
				
			||||||
 | 
					                        (click)="toggleExpand($event, section)" [class.core-course-storage-section-expanded]="section.expanded"
 | 
				
			||||||
 | 
					                        [attr.aria-label]="(section.expanded ? 'core.collapse' : 'core.expand') | translate"
 | 
				
			||||||
 | 
					                        [attr.aria-expanded]="section.expanded" [attr.aria-controls]="'core-course-storage-section-' + section.id">
 | 
				
			||||||
 | 
					                        <ion-icon name="fas-chevron-right" flip-rtl slot="start" class="expandable-status-icon"
 | 
				
			||||||
 | 
					                            [class.expandable-status-icon-expanded]="section.expanded">
 | 
				
			||||||
 | 
					                        </ion-icon>
 | 
				
			||||||
                        <ion-label>
 | 
					                        <ion-label>
 | 
				
			||||||
                            <p class="item-heading ion-text-wrap">
 | 
					                            <p class="item-heading ion-text-wrap">
 | 
				
			||||||
                                <core-format-text [text]="section.name" contextLevel="course" [contextInstanceId]="section.course"
 | 
					                                <core-format-text [text]="section.name" contextLevel="course" [contextInstanceId]="section.course"
 | 
				
			||||||
@ -93,44 +99,46 @@
 | 
				
			|||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                    </ion-item>
 | 
					                    </ion-item>
 | 
				
			||||||
                </ion-card-header>
 | 
					                </ion-card-header>
 | 
				
			||||||
                <ion-card-content>
 | 
					                <ion-card-content id="core-course-storage-section-{{section.id}}">
 | 
				
			||||||
                    <ng-container *ngFor="let module of section.modules">
 | 
					                    <ng-container *ngIf="section.expanded">
 | 
				
			||||||
                        <ion-item class="ion-no-padding core-course-storage-activity"
 | 
					                        <ng-container *ngFor="let module of section.modules">
 | 
				
			||||||
                            *ngIf="downloadEnabled || (!module.calculatingSize && module.totalSize > 0)">
 | 
					                            <ion-item class="ion-no-padding core-course-storage-activity"
 | 
				
			||||||
                            <core-mod-icon slot="start" *ngIf="module.handlerData.icon" [modicon]="module.handlerData.icon"
 | 
					                                *ngIf="downloadEnabled || (!module.calculatingSize && module.totalSize > 0)">
 | 
				
			||||||
                                [modname]="module.modname" [componentId]="module.instance">
 | 
					                                <core-mod-icon slot="start" *ngIf="module.handlerData.icon" [modicon]="module.handlerData.icon"
 | 
				
			||||||
                            </core-mod-icon>
 | 
					                                    [modname]="module.modname" [componentId]="module.instance">
 | 
				
			||||||
                            <ion-label class="ion-text-wrap">
 | 
					                                </core-mod-icon>
 | 
				
			||||||
                                <h3 class="{{module.handlerData!.class}} addon-storagemanager-module-size">
 | 
					                                <ion-label class="ion-text-wrap">
 | 
				
			||||||
                                    <core-format-text [text]="module.handlerData.title" [courseId]="module.course" contextLevel="module"
 | 
					                                    <h3 class="{{module.handlerData!.class}} addon-storagemanager-module-size">
 | 
				
			||||||
                                        [contextInstanceId]="module.id" [adaptImg]="false">
 | 
					                                        <core-format-text [text]="module.handlerData.title" [courseId]="module.course" contextLevel="module"
 | 
				
			||||||
                                    </core-format-text>
 | 
					                                            [contextInstanceId]="module.id" [adaptImg]="false">
 | 
				
			||||||
                                </h3>
 | 
					                                        </core-format-text>
 | 
				
			||||||
                                <ion-badge [color]="module.downloadStatus == statusDownloaded ? 'success' : 'light'"
 | 
					                                    </h3>
 | 
				
			||||||
                                    *ngIf="!module.calculatingSize && module.totalSize > 0">
 | 
					                                    <ion-badge [color]="module.downloadStatus == statusDownloaded ? 'success' : 'light'"
 | 
				
			||||||
                                    <ion-icon name="fam-cloud-done" *ngIf="module.downloadStatus == statusDownloaded"
 | 
					                                        *ngIf="!module.calculatingSize && module.totalSize > 0">
 | 
				
			||||||
                                        [attr.aria-label]="'core.downloaded' | translate">
 | 
					                                        <ion-icon name="fam-cloud-done" *ngIf="module.downloadStatus == statusDownloaded"
 | 
				
			||||||
                                    </ion-icon>{{ module.totalSize | coreBytesToSize }}
 | 
					                                            [attr.aria-label]="'core.downloaded' | translate">
 | 
				
			||||||
                                </ion-badge>
 | 
					                                        </ion-icon>{{ module.totalSize | coreBytesToSize }}
 | 
				
			||||||
                                <ion-badge color="light" *ngIf="module.calculatingSize">
 | 
					                                    </ion-badge>
 | 
				
			||||||
                                    {{ 'core.calculating' | translate }}
 | 
					                                    <ion-badge color="light" *ngIf="module.calculatingSize">
 | 
				
			||||||
                                </ion-badge>
 | 
					                                        {{ 'core.calculating' | translate }}
 | 
				
			||||||
                            </ion-label>
 | 
					                                    </ion-badge>
 | 
				
			||||||
 | 
					                                </ion-label>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            <div class="storage-buttons" slot="end">
 | 
					                                <div class="storage-buttons" slot="end">
 | 
				
			||||||
                                <core-download-refresh *ngIf="downloadEnabled && module.handlerData?.showDownloadButton &&
 | 
					                                    <core-download-refresh *ngIf="downloadEnabled && module.handlerData?.showDownloadButton &&
 | 
				
			||||||
                                    module.downloadStatus != statusDownloaded" [status]="module.downloadStatus" [enabled]="true"
 | 
					                                        module.downloadStatus != statusDownloaded" [status]="module.downloadStatus" [enabled]="true"
 | 
				
			||||||
                                    [canTrustDownload]="true" [loading]="module.spinner || module.handlerData.spinner"
 | 
					                                        [canTrustDownload]="true" [loading]="module.spinner || module.handlerData.spinner"
 | 
				
			||||||
                                    (action)="prefetchModule(module, section)">
 | 
					                                        (action)="prefetchModule(module, section)">
 | 
				
			||||||
                                </core-download-refresh>
 | 
					                                    </core-download-refresh>
 | 
				
			||||||
                                <ion-button fill="clear" (click)="deleteForModule(module, section)"
 | 
					                                    <ion-button fill="clear" (click)="deleteForModule(module, section)"
 | 
				
			||||||
                                    *ngIf="!module.calculatingSize && module.totalSize > 0" color="danger">
 | 
					                                        *ngIf="!module.calculatingSize && module.totalSize > 0" color="danger">
 | 
				
			||||||
                                    <ion-icon name="fas-trash" slot="icon-only"
 | 
					                                        <ion-icon name="fas-trash" slot="icon-only"
 | 
				
			||||||
                                        [attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate: { name: module.name }">
 | 
					                                            [attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate: { name: module.name }">
 | 
				
			||||||
                                    </ion-icon>
 | 
					                                        </ion-icon>
 | 
				
			||||||
                                </ion-button>
 | 
					                                    </ion-button>
 | 
				
			||||||
                            </div>
 | 
					                                </div>
 | 
				
			||||||
                        </ion-item>
 | 
					                            </ion-item>
 | 
				
			||||||
 | 
					                        </ng-container>
 | 
				
			||||||
                    </ng-container>
 | 
					                    </ng-container>
 | 
				
			||||||
                </ion-card-content>
 | 
					                </ion-card-content>
 | 
				
			||||||
            </ion-card>
 | 
					            </ion-card>
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,7 @@
 | 
				
			|||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { CoreConstants } from '@/core/constants';
 | 
					import { CoreConstants } from '@/core/constants';
 | 
				
			||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
 | 
					import { Component, ElementRef, OnDestroy, OnInit } from '@angular/core';
 | 
				
			||||||
import { CoreCourse, CoreCourseProvider } from '@features/course/services/course';
 | 
					import { CoreCourse, CoreCourseProvider } from '@features/course/services/course';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    CoreCourseHelper,
 | 
					    CoreCourseHelper,
 | 
				
			||||||
@ -30,6 +30,7 @@ import { CoreSites } from '@services/sites';
 | 
				
			|||||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
					import { CoreDomUtils } from '@services/utils/dom';
 | 
				
			||||||
import { CoreUtils } from '@services/utils/utils';
 | 
					import { CoreUtils } from '@services/utils/utils';
 | 
				
			||||||
import { Translate } from '@singletons';
 | 
					import { Translate } from '@singletons';
 | 
				
			||||||
 | 
					import { CoreDom } from '@singletons/dom';
 | 
				
			||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
 | 
					import { CoreEventObserver, CoreEvents } from '@singletons/events';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -62,6 +63,7 @@ export class AddonStorageManagerCourseStoragePage implements OnInit, OnDestroy {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    statusDownloaded = CoreConstants.DOWNLOADED;
 | 
					    statusDownloaded = CoreConstants.DOWNLOADED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected initialSectionId?: number;
 | 
				
			||||||
    protected siteUpdatedObserver?: CoreEventObserver;
 | 
					    protected siteUpdatedObserver?: CoreEventObserver;
 | 
				
			||||||
    protected courseStatusObserver?: CoreEventObserver;
 | 
					    protected courseStatusObserver?: CoreEventObserver;
 | 
				
			||||||
    protected sectionStatusObserver?: CoreEventObserver;
 | 
					    protected sectionStatusObserver?: CoreEventObserver;
 | 
				
			||||||
@ -69,7 +71,7 @@ export class AddonStorageManagerCourseStoragePage implements OnInit, OnDestroy {
 | 
				
			|||||||
    protected isDestroyed = false;
 | 
					    protected isDestroyed = false;
 | 
				
			||||||
    protected isGuest = false;
 | 
					    protected isGuest = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor() {
 | 
					    constructor(protected elementRef: ElementRef) {
 | 
				
			||||||
        // Refresh the enabled flags if site is updated.
 | 
					        // Refresh the enabled flags if site is updated.
 | 
				
			||||||
        this.siteUpdatedObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => {
 | 
					        this.siteUpdatedObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => {
 | 
				
			||||||
            this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
 | 
					            this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
 | 
				
			||||||
@ -100,16 +102,19 @@ export class AddonStorageManagerCourseStoragePage implements OnInit, OnDestroy {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.isGuest = !!CoreNavigator.getRouteBooleanParam('isGuest');
 | 
					        this.isGuest = !!CoreNavigator.getRouteBooleanParam('isGuest');
 | 
				
			||||||
 | 
					        this.initialSectionId = CoreNavigator.getRouteNumberParam('sectionId');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
 | 
					        this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
 | 
				
			||||||
        this.downloadEnabled = !CoreSites.getRequiredCurrentSite().isOfflineDisabled();
 | 
					        this.downloadEnabled = !CoreSites.getRequiredCurrentSite().isOfflineDisabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const sections = await CoreCourse.getSections(this.courseId, false, true);
 | 
					        const sections = (await CoreCourse.getSections(this.courseId, false, true))
 | 
				
			||||||
 | 
					            .filter((section) => !CoreCourseHelper.isSectionStealth(section));
 | 
				
			||||||
        this.sections = (await CoreCourseHelper.addHandlerDataForModules(sections, this.courseId)).sections
 | 
					        this.sections = (await CoreCourseHelper.addHandlerDataForModules(sections, this.courseId)).sections
 | 
				
			||||||
            .map(section => ({
 | 
					            .map(section => ({
 | 
				
			||||||
                ...section,
 | 
					                ...section,
 | 
				
			||||||
                totalSize: 0,
 | 
					                totalSize: 0,
 | 
				
			||||||
                calculatingSize: true,
 | 
					                calculatingSize: true,
 | 
				
			||||||
 | 
					                expanded: section.id === this.initialSectionId,
 | 
				
			||||||
                modules: section.modules.map(module => ({
 | 
					                modules: section.modules.map(module => ({
 | 
				
			||||||
                    ...module,
 | 
					                    ...module,
 | 
				
			||||||
                    calculatingSize: true,
 | 
					                    calculatingSize: true,
 | 
				
			||||||
@ -118,6 +123,12 @@ export class AddonStorageManagerCourseStoragePage implements OnInit, OnDestroy {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        this.loaded = true;
 | 
					        this.loaded = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CoreDom.scrollToElement(
 | 
				
			||||||
 | 
					            this.elementRef.nativeElement,
 | 
				
			||||||
 | 
					            '.core-course-storage-section-expanded',
 | 
				
			||||||
 | 
					            { addYAxis: -10 },
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await Promise.all([
 | 
					        await Promise.all([
 | 
				
			||||||
            this.initSizes(),
 | 
					            this.initSizes(),
 | 
				
			||||||
            this.initCoursePrefetch(),
 | 
					            this.initCoursePrefetch(),
 | 
				
			||||||
@ -641,6 +652,18 @@ export class AddonStorageManagerCourseStoragePage implements OnInit, OnDestroy {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Toggle expand status.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param event Event object.
 | 
				
			||||||
 | 
					     * @param section Section to expand / collapse.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    toggleExpand(event: Event, section: AddonStorageManagerCourseSection): void {
 | 
				
			||||||
 | 
					        section.expanded = !section.expanded;
 | 
				
			||||||
 | 
					        event.stopPropagation();
 | 
				
			||||||
 | 
					        event.preventDefault();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @inheritdoc
 | 
					     * @inheritdoc
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@ -663,6 +686,7 @@ export class AddonStorageManagerCourseStoragePage implements OnInit, OnDestroy {
 | 
				
			|||||||
type AddonStorageManagerCourseSection = Omit<CoreCourseSectionWithStatus, 'modules'> & {
 | 
					type AddonStorageManagerCourseSection = Omit<CoreCourseSectionWithStatus, 'modules'> & {
 | 
				
			||||||
    totalSize: number;
 | 
					    totalSize: number;
 | 
				
			||||||
    calculatingSize: boolean;
 | 
					    calculatingSize: boolean;
 | 
				
			||||||
 | 
					    expanded: boolean;
 | 
				
			||||||
    modules: AddonStorageManagerModule[];
 | 
					    modules: AddonStorageManagerModule[];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,8 @@
 | 
				
			|||||||
 | 
					<core-navbar-buttons slot="end" prepend>
 | 
				
			||||||
 | 
					    <ion-button fill="clear" (click)="gotoCourseDownloads()" [attr.aria-label]="'addon.storagemanager.coursedownloads' | translate">
 | 
				
			||||||
 | 
					        <ion-icon name="fas-cloud-download-alt" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
				
			||||||
 | 
					    </ion-button>
 | 
				
			||||||
 | 
					</core-navbar-buttons>
 | 
				
			||||||
<core-dynamic-component [component]="courseFormatComponent" [data]="data">
 | 
					<core-dynamic-component [component]="courseFormatComponent" [data]="data">
 | 
				
			||||||
    <!-- Default course format. -->
 | 
					    <!-- Default course format. -->
 | 
				
			||||||
    <core-loading [hideUntil]="loaded">
 | 
					    <core-loading [hideUntil]="loaded">
 | 
				
			||||||
 | 
				
			|||||||
@ -391,29 +391,38 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get selected section ID. If viewing all sections, use current scrolled section.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Section ID, undefined if not found.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected async getSelectedSectionId(): Promise<number | undefined> {
 | 
				
			||||||
 | 
					        if (this.selectedSection?.id !== this.allSectionsId) {
 | 
				
			||||||
 | 
					            return this.selectedSection?.id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Check current scrolled section.
 | 
				
			||||||
 | 
					        const allSectionElements: NodeListOf<HTMLElement> =
 | 
				
			||||||
 | 
					            this.elementRef.nativeElement.querySelectorAll('section.core-course-module-list-wrapper');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const scroll = await this.content.getScrollElement();
 | 
				
			||||||
 | 
					        const containerTop = scroll.getBoundingClientRect().top;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const element = Array.from(allSectionElements).find((element) => {
 | 
				
			||||||
 | 
					            const position = element.getBoundingClientRect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // The bottom is inside the container or lower.
 | 
				
			||||||
 | 
					            return position.bottom >= containerTop;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Number(element?.getAttribute('id')) || undefined;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Display the course index modal.
 | 
					     * Display the course index modal.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    async openCourseIndex(): Promise<void> {
 | 
					    async openCourseIndex(): Promise<void> {
 | 
				
			||||||
        let selectedId = this.selectedSection?.id;
 | 
					        const selectedId = await this.getSelectedSectionId();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (selectedId == this.allSectionsId) {
 | 
					 | 
				
			||||||
            // Check current scrolled section.
 | 
					 | 
				
			||||||
            const allSectionElements: NodeListOf<HTMLElement> =
 | 
					 | 
				
			||||||
                this.elementRef.nativeElement.querySelectorAll('section.section-wrapper');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            const scroll = await this.content.getScrollElement();
 | 
					 | 
				
			||||||
            const containerTop = scroll.getBoundingClientRect().top;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            const element = Array.from(allSectionElements).find((element) => {
 | 
					 | 
				
			||||||
                const position = element.getBoundingClientRect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // The bottom is inside the container or lower.
 | 
					 | 
				
			||||||
                return position.bottom >= containerTop;
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            selectedId = Number(element?.getAttribute('id')) || undefined;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const data = await CoreDomUtils.openModal<CoreCourseIndexSectionWithModule>({
 | 
					        const data = await CoreDomUtils.openModal<CoreCourseIndexSectionWithModule>({
 | 
				
			||||||
            component: CoreCourseCourseIndexComponent,
 | 
					            component: CoreCourseCourseIndexComponent,
 | 
				
			||||||
@ -453,6 +462,23 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
        this.moduleId = data.moduleId;
 | 
					        this.moduleId = data.moduleId;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Open course downloads page.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async gotoCourseDownloads(): Promise<void> {
 | 
				
			||||||
 | 
					        const selectedId = await this.getSelectedSectionId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CoreNavigator.navigateToSitePath(
 | 
				
			||||||
 | 
					            `storage/${this.course.id}`,
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                params: {
 | 
				
			||||||
 | 
					                    title: this.course.fullname,
 | 
				
			||||||
 | 
					                    sectionId: selectedId,
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Function called when selected section changes.
 | 
					     * Function called when selected section changes.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
@ -48,34 +48,36 @@
 | 
				
			|||||||
                    <ion-icon name="fas-eye-slash" *ngIf="!section.visible && section.uservisible" slot="end" class="restricted"
 | 
					                    <ion-icon name="fas-eye-slash" *ngIf="!section.visible && section.uservisible" slot="end" class="restricted"
 | 
				
			||||||
                        [attr.aria-label]="'core.course.hiddenfromstudents' | translate"></ion-icon>
 | 
					                        [attr.aria-label]="'core.course.hiddenfromstudents' | translate"></ion-icon>
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
                <ng-container *ngIf="section.expanded">
 | 
					                <div id="core-course-index-section-{{section.id}}">
 | 
				
			||||||
                    <ng-container *ngFor="let module of section.modules">
 | 
					                    <ng-container *ngIf="section.expanded">
 | 
				
			||||||
                        <ion-item class="module" [class.item-dimmed]="!module.visible" [class.item-hightlighted]="section.highlighted"
 | 
					                        <ng-container *ngFor="let module of section.modules">
 | 
				
			||||||
                            (click)="selectSectionOrModule($event, section.id, module.id)" button>
 | 
					                            <ion-item class="module" [class.item-dimmed]="!module.visible" [class.item-hightlighted]="section.highlighted"
 | 
				
			||||||
                            <ion-icon class="completioninfo completion_none" name="" *ngIf="module.completionStatus === undefined"
 | 
					                                (click)="selectSectionOrModule($event, section.id, module.id)" button>
 | 
				
			||||||
                                slot="start" aria-hidden="true"></ion-icon>
 | 
					                                <ion-icon class="completioninfo completion_none" name="" *ngIf="module.completionStatus === undefined"
 | 
				
			||||||
                            <ion-icon class="completioninfo completion_incomplete" name="far-circle" *ngIf="module.completionStatus === 0"
 | 
					                                    slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                                slot="start" [attr.aria-label]="'core.course.todo' | translate">
 | 
					                                <ion-icon class="completioninfo completion_incomplete" name="far-circle"
 | 
				
			||||||
                            </ion-icon>
 | 
					                                    *ngIf="module.completionStatus === 0" slot="start" [attr.aria-label]="'core.course.todo' | translate">
 | 
				
			||||||
                            <ion-icon class="completioninfo completion_complete" name="fas-circle"
 | 
					                                </ion-icon>
 | 
				
			||||||
                                *ngIf="module.completionStatus === 1 || module.completionStatus === 2" color="success" slot="start"
 | 
					                                <ion-icon class="completioninfo completion_complete" name="fas-circle"
 | 
				
			||||||
                                [attr.aria-label]="'core.course.done' | translate">
 | 
					                                    *ngIf="module.completionStatus === 1 || module.completionStatus === 2" color="success" slot="start"
 | 
				
			||||||
                            </ion-icon>
 | 
					                                    [attr.aria-label]="'core.course.done' | translate">
 | 
				
			||||||
                            <ion-icon class="completioninfo completion_fail" name="fas-circle" *ngIf="module.completionStatus === 3"
 | 
					                                </ion-icon>
 | 
				
			||||||
                                color="danger" slot="start" [attr.aria-label]="'core.course.failed' | translate">
 | 
					                                <ion-icon class="completioninfo completion_fail" name="fas-circle" *ngIf="module.completionStatus === 3"
 | 
				
			||||||
                            </ion-icon>
 | 
					                                    color="danger" slot="start" [attr.aria-label]="'core.course.failed' | translate">
 | 
				
			||||||
                            <ion-label>
 | 
					                                </ion-icon>
 | 
				
			||||||
                                <p class="item-heading">
 | 
					                                <ion-label>
 | 
				
			||||||
                                    <core-format-text [text]="module.name" contextLevel="module" [contextInstanceId]="module.id"
 | 
					                                    <p class="item-heading">
 | 
				
			||||||
                                        [courseId]="module.course">
 | 
					                                        <core-format-text [text]="module.name" contextLevel="module" [contextInstanceId]="module.id"
 | 
				
			||||||
                                    </core-format-text>
 | 
					                                            [courseId]="module.course">
 | 
				
			||||||
                                </p>
 | 
					                                        </core-format-text>
 | 
				
			||||||
                            </ion-label>
 | 
					                                    </p>
 | 
				
			||||||
                            <ion-icon name="fas-lock" *ngIf="!module.uservisible" slot="end" class="restricted"
 | 
					                                </ion-label>
 | 
				
			||||||
                                [attr.aria-label]="'core.restricted' | translate"></ion-icon>
 | 
					                                <ion-icon name="fas-lock" *ngIf="!module.uservisible" slot="end" class="restricted"
 | 
				
			||||||
                        </ion-item>
 | 
					                                    [attr.aria-label]="'core.restricted' | translate"></ion-icon>
 | 
				
			||||||
 | 
					                            </ion-item>
 | 
				
			||||||
 | 
					                        </ng-container>
 | 
				
			||||||
                    </ng-container>
 | 
					                    </ng-container>
 | 
				
			||||||
                </ng-container>
 | 
					                </div>
 | 
				
			||||||
            </ng-container>
 | 
					            </ng-container>
 | 
				
			||||||
        </ng-container>
 | 
					        </ng-container>
 | 
				
			||||||
    </ion-list>
 | 
					    </ion-list>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,3 @@
 | 
				
			|||||||
<core-navbar-buttons slot="end" prepend>
 | 
					 | 
				
			||||||
    <ion-button fill="clear" (click)="gotoCourseDownloads()" [attr.aria-label]="'addon.storagemanager.coursedownloads' | translate">
 | 
					 | 
				
			||||||
        <ion-icon name="fas-cloud-download-alt" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
					 | 
				
			||||||
    </ion-button>
 | 
					 | 
				
			||||||
</core-navbar-buttons>
 | 
					 | 
				
			||||||
<ion-content>
 | 
					<ion-content>
 | 
				
			||||||
    <ion-refresher slot="fixed" [disabled]="!dataLoaded || !displayRefresher" (ionRefresh)="doRefresh($event.target)">
 | 
					    <ion-refresher slot="fixed" [disabled]="!dataLoaded || !displayRefresher" (ionRefresh)="doRefresh($event.target)">
 | 
				
			||||||
        <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
					        <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
				
			||||||
 | 
				
			|||||||
@ -366,14 +366,6 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gotoCourseDownloads(): void {
 | 
					 | 
				
			||||||
        CoreNavigator.navigateToSitePath(
 | 
					 | 
				
			||||||
            `storage/${this.course.id}`,
 | 
					 | 
				
			||||||
            { params: { title: this.course.fullname } },
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @inheritdoc
 | 
					     * @inheritdoc
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user