MOBILE-3659 course: Implement list mod type page
parent
84a8c6bfea
commit
83dc2ba39e
|
@ -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,
|
||||
});
|
||||
},
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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>
|
|
@ -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 {}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue