MOBILE-3659 course: Implement list mod type page

main
Dani Palou 2021-01-25 10:15:03 +01:00
parent 84a8c6bfea
commit 83dc2ba39e
5 changed files with 219 additions and 9 deletions

View File

@ -16,6 +16,7 @@ import { CoreContentLinksHandlerBase } from './base-handler';
import { Translate } from '@singletons';
import { Params } from '@angular/router';
import { CoreContentLinksAction } from '../services/contentlinks-delegate';
import { CoreNavigator } from '@services/navigator';
/**
* Handler to handle URLs pointing to a list of a certain type of modules.
@ -55,16 +56,15 @@ export class CoreContentLinksModuleListHandler extends CoreContentLinksHandlerBa
getActions(siteIds: string[], url: string, params: Params): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
return [{
// eslint-disable-next-line @typescript-eslint/no-unused-vars
action: (siteId): void => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const stateParams = {
courseId: params.id,
modName: this.modName,
title: this.title || Translate.instance.instant('addon.mod_' + this.modName + '.modulenameplural'),
};
// @todo CoreNavigator.instance.goInSite('CoreCourseListModTypePage', stateParams, siteId);
CoreNavigator.instance.navigateToSitePath('course/list-mod-type', {
params: {
courseId: params.id,
modName: this.modName,
title: this.title || Translate.instance.instant('addon.mod_' + this.modName + '.modulenameplural'),
},
siteId,
});
},
}];
}

View File

@ -30,6 +30,10 @@ const routes: Routes = [
loadChildren: () => import('./pages/unsupported-module/unsupported-module.module')
.then( m => m.CoreCourseUnsupportedModulePageModule),
},
{
path: 'list-mod-type',
loadChildren: () => import('./pages/list-mod-type/list-mod-type').then( m => m.CoreCourseListModTypePage),
},
];
@NgModule({

View File

@ -0,0 +1,28 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
</ion-buttons>
<ion-title>{{ title }}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshData($event)">
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher>
<core-loading [hideUntil]="loaded">
<core-empty-box *ngIf="!sections || !sections.length" icon="qr-scanner"
[message]="'core.course.nocontentavailable' | translate">
</core-empty-box>
<ion-list>
<ng-container *ngFor="let section of sections" >
<ng-container *ngFor="let module of section.modules">
<core-course-module *ngIf="module.visibleoncoursepage !== 0" [module]="module" [section]="section"
[courseId]="courseId" [downloadEnabled]="downloadEnabled">
</core-course-module>
</ng-container>
</ng-container>
</ion-list>
</core-loading>
</ion-content>

View File

@ -0,0 +1,46 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { IonicModule } from '@ionic/angular';
import { TranslateModule } from '@ngx-translate/core';
import { CoreSharedModule } from '@/core/shared.module';
import { CoreCourseListModTypePage } from './list-mod-type';
import { CoreCourseComponentsModule } from '@features/course/components/components.module';
const routes: Routes = [
{
path: '',
component: CoreCourseListModTypePage,
},
];
@NgModule({
declarations: [
CoreCourseListModTypePage,
],
imports: [
RouterModule.forChild(routes),
CommonModule,
IonicModule,
TranslateModule.forChild(),
CoreSharedModule,
CoreCourseComponentsModule,
],
exports: [RouterModule],
})
export class CoreCourseListModTypePageModule {}

View File

@ -0,0 +1,132 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, OnInit } from '@angular/core';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
import { CoreCourseHelper, CoreCourseSection } from '@features/course/services/course-helper';
import { CoreNavigator } from '@services/navigator';
import { CoreConstants } from '@/core/constants';
import { IonRefresher } from '@ionic/angular';
import { CoreUtils } from '@services/utils/utils';
/**
* Page that displays all modules of a certain type in a course.
*/
@Component({
selector: 'page-core-course-list-mod-type',
templateUrl: 'list-mod-type.html',
})
export class CoreCourseListModTypePage implements OnInit {
sections: CoreCourseSection[] = [];
title = '';
loaded = false;
downloadEnabled = false;
courseId?: number;
protected modName?: string;
protected archetypes: Record<string, number> = {}; // To speed up the check of modules.
/**
* @inheritdoc
*/
async ngOnInit(): Promise<void> {
this.title = CoreNavigator.instance.getRouteParam('title') || '';
this.courseId = CoreNavigator.instance.getRouteParam('courseId');
this.modName = CoreNavigator.instance.getRouteParam('modName');
this.downloadEnabled = !CoreSites.instance.getCurrentSite()?.isOfflineDisabled();
try {
await this.fetchData();
} finally {
this.loaded = true;
}
}
/**
* Fetches the data.
*
* @return Resolved when done.
*/
protected async fetchData(): Promise<void> {
if (!this.courseId) {
return;
}
try {
// Get all the modules in the course.
let sections = await CoreCourse.instance.getSections(this.courseId, false, true);
sections = sections.filter((section) => {
if (!section.modules) {
return false;
}
section.modules = section.modules.filter((mod) => {
if (mod.uservisible === false || !CoreCourse.instance.moduleHasView(mod)) {
// Ignore this module.
return false;
}
if (this.modName === 'resources') {
// Check that the module is a resource.
if (typeof this.archetypes[mod.modname] == 'undefined') {
this.archetypes[mod.modname] = CoreCourseModuleDelegate.instance.supportsFeature<number>(
mod.modname,
CoreConstants.FEATURE_MOD_ARCHETYPE,
CoreConstants.MOD_ARCHETYPE_OTHER,
);
}
if (this.archetypes[mod.modname] == CoreConstants.MOD_ARCHETYPE_RESOURCE) {
return true;
}
} else if (mod.modname == this.modName) {
return true;
}
});
return section.modules.length > 0;
});
const result = CoreCourseHelper.instance.addHandlerDataForModules(sections, this.courseId);
this.sections = result.sections;
} catch (error) {
CoreDomUtils.instance.showErrorModalDefault(error, 'Error getting data');
}
}
/**
* Refresh the data.
*
* @param refresher Refresher.
* @return Promise resolved when done.
*/
async refreshData(refresher: CustomEvent<IonRefresher>): Promise<void> {
await CoreUtils.instance.ignoreErrors(CoreCourse.instance.invalidateSections(this.courseId || 0));
try {
await this.fetchData();
} finally {
refresher.detail.complete();
}
}
}