From 49a1d1d80624423a6bcd8744c72ddff5e1f93463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 16 Dec 2021 13:29:50 +0100 Subject: [PATCH] MOBILE-3833 course: Merge Course Module with calculated data types --- .../services/handlers/module.ts | 4 +- .../mod/book/services/handlers/prefetch.ts | 5 +- .../mod/data/components/action/action.ts | 4 +- src/addons/mod/data/components/index/index.ts | 4 +- src/addons/mod/data/pages/edit/edit.ts | 6 +- src/addons/mod/data/pages/entry/entry.ts | 8 +- src/addons/mod/feedback/pages/form/form.ts | 6 +- .../mod/folder/services/handlers/prefetch.ts | 5 +- .../mod/forum/services/handlers/module.ts | 4 +- .../mod/imscp/services/handlers/prefetch.ts | 4 +- src/addons/mod/imscp/services/imscp.ts | 4 +- .../mod/label/services/handlers/module.ts | 4 +- .../mod/lti/services/handlers/module.ts | 6 +- src/addons/mod/lti/services/lti-helper.ts | 8 +- .../mod/page/services/handlers/prefetch.ts | 5 +- .../mod/resource/services/handlers/module.ts | 14 +-- .../resource/services/handlers/prefetch.ts | 5 +- .../mod/resource/services/resource-helper.ts | 14 +-- .../mod/url/services/handlers/module.ts | 16 ++-- .../components/assessment/assessment.ts | 4 +- .../components/submission/submission.ts | 4 +- .../pages/edit-submission/edit-submission.ts | 6 +- .../workshop/pages/submission/submission.ts | 6 +- .../pages/course-storage/course-storage.ts | 8 +- .../course/classes/main-resource-component.ts | 7 +- .../course/classes/module-base-handler.ts | 8 +- .../classes/resource-prefetch-handler.ts | 13 +-- .../course/components/format/format.ts | 4 +- .../components/module-info/module-info.ts | 4 +- .../module-navigation/module-navigation.ts | 14 +-- .../course/components/module/module.ts | 4 +- .../unsupported-module/unsupported-module.ts | 5 +- .../directives/download-module-main-file.ts | 6 +- .../features/course/pages/index/index.page.ts | 8 +- .../module-preview/module-preview.page.ts | 8 +- .../features/course/services/course-helper.ts | 86 ++++++++++--------- src/core/features/course/services/course.ts | 59 +++++++++---- .../services/handlers/default-module.ts | 8 +- .../course/services/module-delegate.ts | 28 +++--- .../services/module-prefetch-delegate.ts | 29 ++++--- .../features/sitehome/pages/index/index.ts | 14 ++- .../classes/handlers/module-handler.ts | 12 +-- .../components/module-index/module-index.ts | 4 +- .../pages/module-index/module-index.ts | 4 +- 44 files changed, 255 insertions(+), 224 deletions(-) diff --git a/src/addons/mod/bigbluebuttonbn/services/handlers/module.ts b/src/addons/mod/bigbluebuttonbn/services/handlers/module.ts index 85956b4ed..3cab8b60f 100644 --- a/src/addons/mod/bigbluebuttonbn/services/handlers/module.ts +++ b/src/addons/mod/bigbluebuttonbn/services/handlers/module.ts @@ -15,7 +15,7 @@ import { CoreConstants } from '@/core/constants'; import { Injectable, Type } from '@angular/core'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreSitePluginsModuleHandler } from '@features/siteplugins/classes/handlers/module-handler'; import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins'; @@ -72,7 +72,7 @@ export class AddonModBBBModuleHandlerService extends CoreModuleHandlerBase imple * @inheritdoc */ async getData( - module: CoreCourseModule, + module: CoreCourseModuleData, courseId: number, sectionId?: number, forCoursePage?: boolean, diff --git a/src/addons/mod/book/services/handlers/prefetch.ts b/src/addons/mod/book/services/handlers/prefetch.ts index 75dff4a32..c4c127821 100644 --- a/src/addons/mod/book/services/handlers/prefetch.ts +++ b/src/addons/mod/book/services/handlers/prefetch.ts @@ -14,7 +14,8 @@ import { Injectable } from '@angular/core'; import { CoreCourseResourcePrefetchHandlerBase } from '@features/course/classes/resource-prefetch-handler'; -import { CoreCourseAnyModuleData, CoreCourseWSModule } from '@features/course/services/course'; +import { CoreCourseAnyModuleData } from '@features/course/services/course'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreUtils } from '@services/utils/utils'; import { CoreWSFile } from '@services/ws'; import { makeSingleton } from '@singletons'; @@ -39,7 +40,7 @@ export class AddonModBookPrefetchHandlerService extends CoreCourseResourcePrefet * @param prefetch True to prefetch, false to download right away. * @return Promise resolved when all content is downloaded. Data returned is not reliable. */ - async downloadOrPrefetch(module: CoreCourseWSModule, courseId: number, prefetch?: boolean): Promise { + async downloadOrPrefetch(module: CoreCourseModuleData, courseId: number, prefetch?: boolean): Promise { const promises: Promise[] = []; promises.push(super.downloadOrPrefetch(module, courseId, prefetch)); diff --git a/src/addons/mod/data/components/action/action.ts b/src/addons/mod/data/components/action/action.ts index b10d9fe6a..e5b2ca7ab 100644 --- a/src/addons/mod/data/components/action/action.ts +++ b/src/addons/mod/data/components/action/action.ts @@ -14,7 +14,7 @@ import { Component, OnInit, Input } from '@angular/core'; import { Params } from '@angular/router'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreTag } from '@features/tag/services/tag'; import { CoreUser } from '@features/user/services/user'; import { CoreNavigator } from '@services/navigator'; @@ -44,7 +44,7 @@ export class AddonModDataActionComponent implements OnInit { @Input() action!: AddonModDataAction; // The field to render. @Input() entry!: AddonModDataEntry; // The value of the field. @Input() database!: AddonModDataData; // Database object. - @Input() module!: CoreCourseModule; // Module object. + @Input() module!: CoreCourseModuleData; // Module object. @Input() group = 0; // Module object. @Input() offset?: number; // Offset of the entry. diff --git a/src/addons/mod/data/components/index/index.ts b/src/addons/mod/data/components/index/index.ts index df7ca92aa..111571bdb 100644 --- a/src/addons/mod/data/components/index/index.ts +++ b/src/addons/mod/data/components/index/index.ts @@ -17,9 +17,9 @@ import { Component, OnDestroy, OnInit, Optional, Type } from '@angular/core'; import { Params } from '@angular/router'; import { CoreCommentsProvider } from '@features/comments/services/comments'; import { CoreCourseModuleMainActivityComponent } from '@features/course/classes/main-activity-component'; -import { CoreCourseModule } from '@features/course/course.module'; import { CoreCourseContentsPage } from '@features/course/pages/contents/contents'; import { CoreCourse } from '@features/course/services/course'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreRatingProvider } from '@features/rating/services/rating'; import { CoreRatingSyncProvider } from '@features/rating/services/rating-sync'; import { IonContent } from '@ionic/angular'; @@ -95,7 +95,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp fields: Record; entries: Record; database: AddonModDataData; - module: CoreCourseModule; + module: CoreCourseModuleData; group: number; gotoEntry: (a: number) => void; }; diff --git a/src/addons/mod/data/pages/edit/edit.ts b/src/addons/mod/data/pages/edit/edit.ts index 74f60c73f..3be6b6dbc 100644 --- a/src/addons/mod/data/pages/edit/edit.ts +++ b/src/addons/mod/data/pages/edit/edit.ts @@ -15,7 +15,7 @@ import { Component, OnInit, ViewChild, ElementRef, Type } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { CoreError } from '@classes/errors/error'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreFileUploader } from '@features/fileuploader/services/fileuploader'; import { CoreTag } from '@features/tag/services/tag'; import { IonContent } from '@ionic/angular'; @@ -66,7 +66,7 @@ export class AddonModDataEditPage implements OnInit { entry?: AddonModDataEntry; fields: Record = {}; courseId!: number; - module!: CoreCourseModule; + module!: CoreCourseModuleData; database?: AddonModDataData; title = ''; component = AddonModDataProvider.COMPONENT; @@ -97,7 +97,7 @@ export class AddonModDataEditPage implements OnInit { */ ngOnInit(): void { try { - this.module = CoreNavigator.getRequiredRouteParam('module'); + this.module = CoreNavigator.getRequiredRouteParam('module'); this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined; this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId'); this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0; diff --git a/src/addons/mod/data/pages/entry/entry.ts b/src/addons/mod/data/pages/entry/entry.ts index df8ebb5be..fb707ad10 100644 --- a/src/addons/mod/data/pages/entry/entry.ts +++ b/src/addons/mod/data/pages/entry/entry.ts @@ -16,7 +16,7 @@ import { Component, OnDestroy, ViewChild, ChangeDetectorRef, OnInit, Type } from import { CoreCommentsCommentsComponent } from '@features/comments/components/comments/comments'; import { CoreComments } from '@features/comments/services/comments'; import { CoreCourse } from '@features/course/services/course'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreRatingInfo } from '@features/rating/services/rating'; import { IonContent, IonRefresher } from '@ionic/angular'; import { CoreGroups, CoreGroupInfo } from '@services/groups'; @@ -57,7 +57,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy { protected fields: Record = {}; protected fieldsArray: AddonModDataField[] = []; - module!: CoreCourseModule; + module!: CoreCourseModuleData; courseId!: number; offset?: number; title = ''; @@ -82,7 +82,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy { fields: Record; entries: Record; database: AddonModDataData; - module: CoreCourseModule; + module: CoreCourseModuleData; group: number; }; @@ -133,7 +133,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy { */ async ngOnInit(): Promise { try { - this.module = CoreNavigator.getRequiredRouteParam('module'); + this.module = CoreNavigator.getRequiredRouteParam('module'); this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined; this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId'); this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0; diff --git a/src/addons/mod/feedback/pages/form/form.ts b/src/addons/mod/feedback/pages/form/form.ts index 1a11ebb21..5807d7e3e 100644 --- a/src/addons/mod/feedback/pages/form/form.ts +++ b/src/addons/mod/feedback/pages/form/form.ts @@ -15,8 +15,8 @@ import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { CoreSite } from '@classes/site'; import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper'; -import { CoreCourse, CoreCourseCommonModWSOptions, CoreCourseWSModule } from '@features/course/services/course'; -import { CoreCourseHelper } from '@features/course/services/course-helper'; +import { CoreCourse, CoreCourseCommonModWSOptions } from '@features/course/services/course'; +import { CoreCourseHelper, CoreCourseModuleData } from '@features/course/services/course-helper'; import { CanLeave } from '@guards/can-leave'; import { IonContent } from '@ionic/angular'; import { CoreApp } from '@services/app'; @@ -51,7 +51,7 @@ export class AddonModFeedbackFormPage implements OnInit, OnDestroy, CanLeave { @ViewChild(IonContent) content?: IonContent; - protected module?: CoreCourseWSModule; + protected module?: CoreCourseModuleData; protected currentPage?: number; protected siteAfterSubmit?: string; protected onlineObserver: Subscription; diff --git a/src/addons/mod/folder/services/handlers/prefetch.ts b/src/addons/mod/folder/services/handlers/prefetch.ts index 5081cd5d5..33535bfb3 100644 --- a/src/addons/mod/folder/services/handlers/prefetch.ts +++ b/src/addons/mod/folder/services/handlers/prefetch.ts @@ -14,7 +14,8 @@ import { Injectable } from '@angular/core'; import { CoreCourseResourcePrefetchHandlerBase } from '@features/course/classes/resource-prefetch-handler'; -import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '@features/course/services/course'; +import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { makeSingleton } from '@singletons'; import { AddonModFolder, AddonModFolderProvider } from '../folder'; @@ -31,7 +32,7 @@ export class AddonModFolderPrefetchHandlerService extends CoreCourseResourcePref /** * @inheritdoc */ - async downloadOrPrefetch(module: CoreCourseWSModule, courseId: number, prefetch?: boolean): Promise { + async downloadOrPrefetch(module: CoreCourseModuleData, courseId: number, prefetch?: boolean): Promise { const promises: Promise[] = []; promises.push(super.downloadOrPrefetch(module, courseId, prefetch)); diff --git a/src/addons/mod/forum/services/handlers/module.ts b/src/addons/mod/forum/services/handlers/module.ts index 98b81258b..f4ad76e60 100644 --- a/src/addons/mod/forum/services/handlers/module.ts +++ b/src/addons/mod/forum/services/handlers/module.ts @@ -22,7 +22,7 @@ import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/ import { CoreConstants } from '@/core/constants'; import { AddonModForumIndexComponent } from '../../components/index'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; /** * Handler to support forum modules. @@ -53,7 +53,7 @@ export class AddonModForumModuleHandlerService extends CoreModuleHandlerBase imp /** * @inheritdoc */ - async getData(module: CoreCourseModule, courseId: number): Promise { + async getData(module: CoreCourseModuleData, courseId: number): Promise { const data = await super.getData(module, courseId); if ('afterlink' in module && !!module.afterlink) { diff --git a/src/addons/mod/imscp/services/handlers/prefetch.ts b/src/addons/mod/imscp/services/handlers/prefetch.ts index 4f8aca282..667603fed 100644 --- a/src/addons/mod/imscp/services/handlers/prefetch.ts +++ b/src/addons/mod/imscp/services/handlers/prefetch.ts @@ -18,8 +18,8 @@ import { CoreCourse, CoreCourseAnyModuleData, CoreCourseModuleContentFile, - CoreCourseWSModule, } from '@features/course/services/course'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreFilepool } from '@services/filepool'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreUtils } from '@services/utils/utils'; @@ -40,7 +40,7 @@ export class AddonModImscpPrefetchHandlerService extends CoreCourseResourcePrefe /** * @inheritdoc */ - async downloadOrPrefetch(module: CoreCourseWSModule, courseId: number, prefetch?: boolean): Promise { + async downloadOrPrefetch(module: CoreCourseModuleData, courseId: number, prefetch?: boolean): Promise { const siteId = CoreSites.getCurrentSiteId(); const dirPath = await CoreFilepool.getPackageDirPathByUrl(siteId, module.url!); diff --git a/src/addons/mod/imscp/services/imscp.ts b/src/addons/mod/imscp/services/imscp.ts index 3783cf37d..88cae637e 100644 --- a/src/addons/mod/imscp/services/imscp.ts +++ b/src/addons/mod/imscp/services/imscp.ts @@ -16,7 +16,7 @@ import { Injectable } from '@angular/core'; import { CoreError } from '@classes/errors/error'; import { CoreSite, CoreSiteWSPreSets } from '@classes/site'; import { CoreCourse, CoreCourseModuleContentFile } from '@features/course/services/course'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseLogHelper } from '@features/course/services/log-helper'; import { CoreApp } from '@services/app'; import { CoreFilepool } from '@services/filepool'; @@ -171,7 +171,7 @@ export class AddonModImscpProvider { * @param itemHref Href of item to get. If not defined, gets src of main item. * @return Promise resolved with the item src. */ - async getIframeSrc(module: CoreCourseModule, itemHref?: string): Promise { + async getIframeSrc(module: CoreCourseModuleData, itemHref?: string): Promise { const contents = await CoreCourse.getModuleContents(module); if (!itemHref) { diff --git a/src/addons/mod/label/services/handlers/module.ts b/src/addons/mod/label/services/handlers/module.ts index 495e9cd51..f7cc33d6a 100644 --- a/src/addons/mod/label/services/handlers/module.ts +++ b/src/addons/mod/label/services/handlers/module.ts @@ -15,7 +15,7 @@ import { CoreConstants } from '@/core/constants'; import { Injectable } from '@angular/core'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { makeSingleton } from '@singletons'; @@ -45,7 +45,7 @@ export class AddonModLabelModuleHandlerService extends CoreModuleHandlerBase imp /** * @inheritdoc */ - async getData(module: CoreCourseModule): Promise { + async getData(module: CoreCourseModuleData): Promise { // Remove the description from the module so it isn't rendered twice. const title = module.description || ''; module.description = ''; diff --git a/src/addons/mod/lti/services/handlers/module.ts b/src/addons/mod/lti/services/handlers/module.ts index 1692ec173..7dcf9b6ee 100644 --- a/src/addons/mod/lti/services/handlers/module.ts +++ b/src/addons/mod/lti/services/handlers/module.ts @@ -16,7 +16,7 @@ import { Injectable, Type } from '@angular/core'; import { CoreConstants } from '@/core/constants'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { makeSingleton } from '@singletons'; import { AddonModLtiHelper } from '../lti-helper'; import { AddonModLtiIndexComponent } from '../../components/index'; @@ -49,7 +49,7 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple * @inheritdoc */ async getData( - module: CoreCourseModule, + module: CoreCourseModuleData, courseId: number, sectionId?: number, forCoursePage?: boolean, @@ -63,7 +63,7 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple data.buttons = [{ icon: 'fas-external-link-alt', label: 'addon.mod_lti.launchactivity', - action: (event: Event, module: CoreCourseModule, courseId: number): void => { + action: (event: Event, module: CoreCourseModuleData, courseId: number): void => { // Launch the LTI. AddonModLtiHelper.getDataAndLaunch(courseId, module); }, diff --git a/src/addons/mod/lti/services/lti-helper.ts b/src/addons/mod/lti/services/lti-helper.ts index 1dbf19578..74d28a689 100644 --- a/src/addons/mod/lti/services/lti-helper.ts +++ b/src/addons/mod/lti/services/lti-helper.ts @@ -15,7 +15,7 @@ import { Injectable } from '@angular/core'; import { CoreCourse } from '@features/course/services/course'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { makeSingleton, Platform } from '@singletons'; @@ -28,7 +28,7 @@ import { AddonModLti, AddonModLtiLti } from './lti'; @Injectable({ providedIn: 'root' }) export class AddonModLtiHelperProvider { - protected pendingCheckCompletion: {[moduleId: string]: {courseId: number; module: CoreCourseModule}} = {}; + protected pendingCheckCompletion: {[moduleId: string]: {courseId: number; module: CoreCourseModuleData}} = {}; constructor() { // Clear pending completion on logout. @@ -57,7 +57,7 @@ export class AddonModLtiHelperProvider { * @param siteId Site ID. If not defined, current site. * @return Promise resolved when done. */ - async getDataAndLaunch(courseId: number, module: CoreCourseModule, lti?: AddonModLtiLti, siteId?: string): Promise { + async getDataAndLaunch(courseId: number, module: CoreCourseModuleData, lti?: AddonModLtiLti, siteId?: string): Promise { siteId = siteId || CoreSites.getCurrentSiteId(); const modal = await CoreDomUtils.showModalLoading(); @@ -108,7 +108,7 @@ export class AddonModLtiHelperProvider { */ async logViewAndCheckCompletion( courseId: number, - module: CoreCourseModule, + module: CoreCourseModuleData, ltiId: number, name?: string, siteId?: string, diff --git a/src/addons/mod/page/services/handlers/prefetch.ts b/src/addons/mod/page/services/handlers/prefetch.ts index fdbb6f721..c7b6f3958 100644 --- a/src/addons/mod/page/services/handlers/prefetch.ts +++ b/src/addons/mod/page/services/handlers/prefetch.ts @@ -14,7 +14,8 @@ import { Injectable } from '@angular/core'; import { CoreCourseResourcePrefetchHandlerBase } from '@features/course/classes/resource-prefetch-handler'; -import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '@features/course/services/course'; +import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreUtils } from '@services/utils/utils'; import { makeSingleton } from '@singletons'; import { AddonModPage, AddonModPageProvider } from '../page'; @@ -38,7 +39,7 @@ export class AddonModPagePrefetchHandlerService extends CoreCourseResourcePrefet * @param prefetch True to prefetch, false to download right away. * @return Promise resolved when all content is downloaded. Data returned is not reliable. */ - async downloadOrPrefetch(module: CoreCourseWSModule, courseId: number, prefetch?: boolean): Promise { + async downloadOrPrefetch(module: CoreCourseModuleData, courseId: number, prefetch?: boolean): Promise { const promises: Promise[] = []; promises.push(super.downloadOrPrefetch(module, courseId, prefetch)); diff --git a/src/addons/mod/resource/services/handlers/module.ts b/src/addons/mod/resource/services/handlers/module.ts index 275ea61f7..965b062dc 100644 --- a/src/addons/mod/resource/services/handlers/module.ts +++ b/src/addons/mod/resource/services/handlers/module.ts @@ -15,8 +15,8 @@ import { CoreConstants } from '@/core/constants'; import { Injectable, Type } from '@angular/core'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler'; -import { CoreCourse, CoreCourseWSModule } from '@features/course/services/course'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourse } from '@features/course/services/course'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; import { CoreFileHelper } from '@services/file-helper'; @@ -63,7 +63,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase * @inheritdoc */ async getData( - module: CoreCourseModule, + module: CoreCourseModuleData, courseId: number, sectionId?: number, forCoursePage?: boolean, @@ -84,7 +84,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase hidden: true, icon: openWithPicker ? 'fas-share-square' : 'fas-file', label: module.name + ': ' + Translate.instant(openWithPicker ? 'core.openwith' : 'addon.mod_resource.openthefile'), - action: async (event: Event, module: CoreCourseModule, courseId: number): Promise => { + action: async (event: Event, module: CoreCourseModuleData, courseId: number): Promise => { const hide = await this.hideOpenButton(module, courseId); if (!hide) { AddonModResourceHelper.openModuleFile(module, courseId); @@ -112,7 +112,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase * @param courseId The course ID. * @return Resolved when done. */ - protected async hideOpenButton(module: CoreCourseModule, courseId: number): Promise { + protected async hideOpenButton(module: CoreCourseModuleData, courseId: number): Promise { if (!('contentsinfo' in module) || !module.contentsinfo) { await CoreCourse.loadModuleContents(module, courseId, undefined, false, false, undefined, this.modName); } @@ -130,7 +130,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase * @return Resource data. */ protected async getResourceData( - module: CoreCourseModule, + module: CoreCourseModuleData, courseId: number, handlerData: CoreCourseModuleHandlerData, ): Promise { @@ -229,7 +229,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase /** * @inheritdoc */ - async getIconSrc(module?: CoreCourseWSModule): Promise { + async getIconSrc(module?: CoreCourseModuleData): Promise { if (!module) { return; } diff --git a/src/addons/mod/resource/services/handlers/prefetch.ts b/src/addons/mod/resource/services/handlers/prefetch.ts index 696922b78..3342cc474 100644 --- a/src/addons/mod/resource/services/handlers/prefetch.ts +++ b/src/addons/mod/resource/services/handlers/prefetch.ts @@ -15,7 +15,8 @@ import { CoreConstants } from '@/core/constants'; import { Injectable } from '@angular/core'; import { CoreCourseResourcePrefetchHandlerBase } from '@features/course/classes/resource-prefetch-handler'; -import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '@features/course/services/course'; +import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreFilepool } from '@services/filepool'; import { CoreSites } from '@services/sites'; import { makeSingleton } from '@singletons'; @@ -57,7 +58,7 @@ export class AddonModResourcePrefetchHandlerService extends CoreCourseResourcePr /** * @inheritdoc */ - async downloadOrPrefetch(module: CoreCourseWSModule, courseId: number, prefetch?: boolean): Promise { + async downloadOrPrefetch(module: CoreCourseModuleData, courseId: number, prefetch?: boolean): Promise { let dirPath: string | undefined; if (AddonModResourceHelper.isDisplayedInIframe(module)) { diff --git a/src/addons/mod/resource/services/resource-helper.ts b/src/addons/mod/resource/services/resource-helper.ts index 4cb2ccad1..c3f577847 100644 --- a/src/addons/mod/resource/services/resource-helper.ts +++ b/src/addons/mod/resource/services/resource-helper.ts @@ -15,8 +15,8 @@ import { CoreConstants } from '@/core/constants'; import { Injectable } from '@angular/core'; import { CoreError } from '@classes/errors/error'; -import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '@features/course/services/course'; -import { CoreCourseHelper } from '@features/course/services/course-helper'; +import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; +import { CoreCourseHelper, CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreApp } from '@services/app'; import { CoreFile } from '@services/file'; import { CoreFileHelper } from '@services/file-helper'; @@ -42,7 +42,7 @@ export class AddonModResourceHelperProvider { * @param courseId The course ID. * @return Promise resolved with the HTML. */ - async getEmbeddedHtml(module: CoreCourseWSModule, courseId: number): Promise { + async getEmbeddedHtml(module: CoreCourseModuleData, courseId: number): Promise { const contents = await CoreCourse.getModuleContents(module, courseId); const result = await CoreCourseHelper.downloadModuleWithMainFileIfNeeded( @@ -62,7 +62,7 @@ export class AddonModResourceHelperProvider { * @param module The module object. * @return Promise resolved with the iframe src. */ - async getIframeSrc(module: CoreCourseWSModule): Promise { + async getIframeSrc(module: CoreCourseModuleData): Promise { if (!module.contents?.length) { throw new CoreError('No contents available in module'); } @@ -97,7 +97,7 @@ export class AddonModResourceHelperProvider { * @param display The display mode (if available). * @return Whether the resource should be displayed embeded. */ - isDisplayedEmbedded(module: CoreCourseWSModule, display: number): boolean { + isDisplayedEmbedded(module: CoreCourseModuleData, display: number): boolean { const currentSite = CoreSites.getCurrentSite(); if (!CoreFile.isAvailable() || @@ -150,7 +150,7 @@ export class AddonModResourceHelperProvider { * @param siteId Site ID. If not defined, current site. * @return Promise resolved with boolean: whether main file is downloadable. */ - async isMainFileDownloadable(module: CoreCourseWSModule, siteId?: string): Promise { + async isMainFileDownloadable(module: CoreCourseModuleData, siteId?: string): Promise { const contents = await CoreCourse.getModuleContents(module); if (!contents.length) { throw new CoreError(Translate.instant('core.filenotfound')); @@ -186,7 +186,7 @@ export class AddonModResourceHelperProvider { * @param options Options to open the file. * @return Resolved when done. */ - async openModuleFile(module: CoreCourseWSModule, courseId: number, options: CoreUtilsOpenFileOptions = {}): Promise { + async openModuleFile(module: CoreCourseModuleData, courseId: number, options: CoreUtilsOpenFileOptions = {}): Promise { const modal = await CoreDomUtils.showModalLoading(); try { diff --git a/src/addons/mod/url/services/handlers/module.ts b/src/addons/mod/url/services/handlers/module.ts index 69c7d2c4b..eeea17039 100644 --- a/src/addons/mod/url/services/handlers/module.ts +++ b/src/addons/mod/url/services/handlers/module.ts @@ -17,7 +17,7 @@ import { Injectable, Type } from '@angular/core'; import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler'; import { CoreCourse } from '@features/course/services/course'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreNavigationOptions } from '@services/navigator'; import { CoreDomUtils } from '@services/utils/dom'; @@ -54,7 +54,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple /** * @inheritdoc */ - async getData(module: CoreCourseModule, courseId: number): Promise { + async getData(module: CoreCourseModuleData, courseId: number): Promise { /** * Open the URL. @@ -62,7 +62,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple * @param module The module object. * @param courseId The course ID. */ - const openUrl = async (module: CoreCourseModule, courseId: number): Promise => { + const openUrl = async (module: CoreCourseModuleData, courseId: number): Promise => { try { if (module.instance) { await AddonModUrl.logView(module.instance, module.name); @@ -81,7 +81,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple title: module.name, class: 'addon-mod_url-handler', showDownloadButton: false, - action: async (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => { + action: async (event: Event, module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions) => { const modal = await CoreDomUtils.showModalLoading(); try { @@ -100,7 +100,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple hidden: true, // Hide it until we calculate if it should be displayed or not. icon: 'fas-link', label: 'core.openmodinbrowser', - action: (event: Event, module: CoreCourseModule, courseId: number): void => { + action: (event: Event, module: CoreCourseModuleData, courseId: number): void => { openUrl(module, courseId); }, }], @@ -135,7 +135,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple * @param courseId The course ID. * @return Resolved when done. */ - protected async hideLinkButton(module: CoreCourseModule, courseId: number): Promise { + protected async hideLinkButton(module: CoreCourseModuleData, courseId: number): Promise { try { const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName); @@ -160,7 +160,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple * @param courseId Course ID. * @return Promise resolved with boolean. */ - protected async shouldOpenLink(module: CoreCourseModule, courseId?: number): Promise { + protected async shouldOpenLink(module: CoreCourseModuleData, courseId?: number): Promise { try { const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName); @@ -186,7 +186,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple /** * @inheritdoc */ - manualCompletionAlwaysShown(module: CoreCourseModule): Promise { + manualCompletionAlwaysShown(module: CoreCourseModuleData): Promise { return this.shouldOpenLink(module, module.course); } diff --git a/src/addons/mod/workshop/components/assessment/assessment.ts b/src/addons/mod/workshop/components/assessment/assessment.ts index f165e0105..5ca172f55 100644 --- a/src/addons/mod/workshop/components/assessment/assessment.ts +++ b/src/addons/mod/workshop/components/assessment/assessment.ts @@ -14,7 +14,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { Params } from '@angular/router'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreUser, CoreUserProfile } from '@features/user/services/user'; import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; @@ -41,7 +41,7 @@ export class AddonModWorkshopAssessmentComponent implements OnInit { @Input() workshop!: AddonModWorkshopData; @Input() access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse; @Input() submission!: AddonModWorkshopSubmissionDataWithOfflineData; - @Input() module!: CoreCourseModule; + @Input() module!: CoreCourseModuleData; canViewAssessment = false; canSelfAssess = false; diff --git a/src/addons/mod/workshop/components/submission/submission.ts b/src/addons/mod/workshop/components/submission/submission.ts index ef3a0cf4d..fc05e97b3 100644 --- a/src/addons/mod/workshop/components/submission/submission.ts +++ b/src/addons/mod/workshop/components/submission/submission.ts @@ -14,7 +14,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { Params } from '@angular/router'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreUser, CoreUserProfile } from '@features/user/services/user'; import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; @@ -44,7 +44,7 @@ import { AddonModWorkshopOffline } from '../../services/workshop-offline'; export class AddonModWorkshopSubmissionComponent implements OnInit { @Input() submission!: AddonModWorkshopSubmissionDataWithOfflineData; - @Input() module!: CoreCourseModule; + @Input() module!: CoreCourseModuleData; @Input() workshop!: AddonModWorkshopData; @Input() access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse; @Input() courseId!: number; diff --git a/src/addons/mod/workshop/pages/edit-submission/edit-submission.ts b/src/addons/mod/workshop/pages/edit-submission/edit-submission.ts index c91033454..9fdb9af26 100644 --- a/src/addons/mod/workshop/pages/edit-submission/edit-submission.ts +++ b/src/addons/mod/workshop/pages/edit-submission/edit-submission.ts @@ -15,7 +15,7 @@ import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { CoreError } from '@classes/errors/error'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreFileUploader, CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader'; import { CanLeave } from '@guards/can-leave'; import { CoreFile } from '@services/file'; @@ -51,7 +51,7 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy, Ca @ViewChild('editFormEl') formElement!: ElementRef; - module!: CoreCourseModule; + module!: CoreCourseModuleData; courseId!: number; access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse; submission?: AddonModWorkshopSubmissionDataWithOfflineData; @@ -100,7 +100,7 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy, Ca */ ngOnInit(): void { try { - this.module = CoreNavigator.getRequiredRouteParam('module'); + this.module = CoreNavigator.getRequiredRouteParam('module'); this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId'); this.access = CoreNavigator.getRequiredRouteParam('access'); this.submissionId = CoreNavigator.getRouteNumberParam('submissionId') || 0; diff --git a/src/addons/mod/workshop/pages/submission/submission.ts b/src/addons/mod/workshop/pages/submission/submission.ts index dee18605e..a131065af 100644 --- a/src/addons/mod/workshop/pages/submission/submission.ts +++ b/src/addons/mod/workshop/pages/submission/submission.ts @@ -16,7 +16,7 @@ import { Component, OnInit, OnDestroy, Optional, ViewChild, ElementRef } from '@ import { FormGroup, FormBuilder } from '@angular/forms'; import { Params } from '@angular/router'; import { CoreCourse } from '@features/course/services/course'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreGradesHelper, CoreGradesMenuItem } from '@features/grades/services/grades-helper'; import { CoreUser, CoreUserProfile } from '@features/user/services/user'; import { CanLeave } from '@guards/can-leave'; @@ -61,7 +61,7 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy, CanLea @ViewChild('feedbackFormEl') formElement?: ElementRef; - module!: CoreCourseModule; + module!: CoreCourseModuleData; workshop!: AddonModWorkshopData; access!: AddonModWorkshopGetWorkshopAccessInformationWSResponse; assessment?: AddonModWorkshopSubmissionAssessmentWithFormData; @@ -132,7 +132,7 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy, CanLea async ngOnInit(): Promise { try { this.submissionId = CoreNavigator.getRequiredRouteNumberParam('submissionId'); - this.module = CoreNavigator.getRequiredRouteParam('module'); + this.module = CoreNavigator.getRequiredRouteParam('module'); this.workshop = CoreNavigator.getRequiredRouteParam('workshop'); this.access = CoreNavigator.getRequiredRouteParam('access'); this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId'); diff --git a/src/addons/storagemanager/pages/course-storage/course-storage.ts b/src/addons/storagemanager/pages/course-storage/course-storage.ts index e52ddb0e0..80e28b258 100644 --- a/src/addons/storagemanager/pages/course-storage/course-storage.ts +++ b/src/addons/storagemanager/pages/course-storage/course-storage.ts @@ -15,7 +15,7 @@ import { CoreConstants } from '@/core/constants'; import { Component, OnInit } from '@angular/core'; import { CoreCourse } from '@features/course/services/course'; -import { CoreCourseHelper, CoreCourseModule, CoreCourseSection } from '@features/course/services/course-helper'; +import { CoreCourseHelper, CoreCourseModuleData, CoreCourseSection } from '@features/course/services/course-helper'; import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; import { CoreEnrolledCourseData } from '@features/courses/services/courses'; import { CoreNavigator } from '@services/navigator'; @@ -52,8 +52,8 @@ export class AddonStorageManagerCourseStoragePage implements OnInit { return; } - this.sections = await CoreCourse.getSections(this.course.id, false, true); - CoreCourseHelper.addHandlerDataForModules(this.sections, this.course.id); + const sections = await CoreCourse.getSections(this.course.id, false, true); + this.sections = CoreCourseHelper.addHandlerDataForModules(sections, this.course.id).sections; this.totalSize = 0; @@ -231,7 +231,7 @@ type AddonStorageManagerCourseSection = Omit & { modules: AddonStorageManagerModule[]; }; -type AddonStorageManagerModule = CoreCourseModule & { +type AddonStorageManagerModule = CoreCourseModuleData & { parentSection?: AddonStorageManagerCourseSection; totalSize?: number; }; diff --git a/src/core/features/course/classes/main-resource-component.ts b/src/core/features/course/classes/main-resource-component.ts index 24572a903..a6ea91223 100644 --- a/src/core/features/course/classes/main-resource-component.ts +++ b/src/core/features/course/classes/main-resource-component.ts @@ -30,7 +30,7 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreLogger } from '@singletons/logger'; import { CoreCourseContentsPage } from '../pages/contents/contents'; import { CoreCourse } from '../services/course'; -import { CoreCourseHelper, CoreCourseModule } from '../services/course-helper'; +import { CoreCourseHelper, CoreCourseModuleData } from '../services/course-helper'; import { CoreCourseModuleDelegate, CoreCourseModuleMainComponent } from '../services/module-delegate'; import { CoreCourseModulePrefetchDelegate } from '../services/module-prefetch-delegate'; @@ -50,7 +50,7 @@ export type CoreCourseResourceDownloadResult = { }) export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, CoreCourseModuleMainComponent { - @Input() module!: CoreCourseModule; // The module of the component. + @Input() module!: CoreCourseModuleData; // The module of the component. @Input() courseId!: number; // Course ID the component belongs to. @Output() dataRetrieved = new EventEmitter(); // Called to notify changes the index page from the main component. @@ -100,7 +100,6 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, this.showCompletion = !!CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('3.11'); if (this.showCompletion) { - CoreCourseHelper.calculateModuleCompletionData(this.module); CoreCourseHelper.loadModuleOfflineCompletion(this.courseId, this.module); this.completionObserver = CoreEvents.on(CoreEvents.COMPLETION_MODULE_VIEWED, async (data) => { @@ -428,8 +427,6 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, protected async fetchModule(): Promise { const module = await CoreCourse.getModule(this.module.id, this.courseId); - CoreCourseHelper.calculateModuleCompletionData(module); - await CoreCourseHelper.loadModuleOfflineCompletion(this.courseId, module); this.module = module; diff --git a/src/core/features/course/classes/module-base-handler.ts b/src/core/features/course/classes/module-base-handler.ts index 3d59a9d00..0950a8d2a 100644 --- a/src/core/features/course/classes/module-base-handler.ts +++ b/src/core/features/course/classes/module-base-handler.ts @@ -14,7 +14,7 @@ import { CoreNavigationOptions, CoreNavigator } from '@services/navigator'; import { CoreCourse } from '../services/course'; -import { CoreCourseModule } from '../services/course-helper'; +import { CoreCourseModuleData } from '../services/course-helper'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../services/module-delegate'; /** @@ -35,7 +35,7 @@ export class CoreModuleHandlerBase implements Partial { * @inheritdoc */ async getData( - module: CoreCourseModule, + module: CoreCourseModuleData, courseId: number, // eslint-disable-line @typescript-eslint/no-unused-vars sectionId?: number, // eslint-disable-line @typescript-eslint/no-unused-vars forCoursePage?: boolean, // eslint-disable-line @typescript-eslint/no-unused-vars @@ -47,7 +47,7 @@ export class CoreModuleHandlerBase implements Partial { showDownloadButton: true, action: async ( event: Event, - module: CoreCourseModule, + module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions, ): Promise => { @@ -64,7 +64,7 @@ export class CoreModuleHandlerBase implements Partial { * @param options Options for the navigation. * @return Promise resolved when done. */ - async openActivityPage(module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): Promise { + async openActivityPage(module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions): Promise { if (!CoreCourse.moduleHasView(module)) { return; } diff --git a/src/core/features/course/classes/resource-prefetch-handler.ts b/src/core/features/course/classes/resource-prefetch-handler.ts index a11108d27..7eb2119df 100644 --- a/src/core/features/course/classes/resource-prefetch-handler.ts +++ b/src/core/features/course/classes/resource-prefetch-handler.ts @@ -18,7 +18,8 @@ import { CoreApp } from '@services/app'; import { CoreFilepool } from '@services/filepool'; import { CoreSites } from '@services/sites'; import { CoreWSFile } from '@services/ws'; -import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '../services/course'; +import { CoreCourse, CoreCourseAnyModuleData } from '../services/course'; +import { CoreCourseModuleData } from '../services/course-helper'; import { CoreCourseModulePrefetchHandlerBase } from './module-prefetch-handler'; /** @@ -40,7 +41,7 @@ export class CoreCourseResourcePrefetchHandlerBase extends CoreCourseModulePrefe * @param dirPath Path of the directory where to store all the content files. * @return Promise resolved when all content is downloaded. */ - download(module: CoreCourseWSModule, courseId: number, dirPath?: string): Promise { + download(module: CoreCourseModuleData, courseId: number, dirPath?: string): Promise { return this.downloadOrPrefetch(module, courseId, false, dirPath); } @@ -55,7 +56,7 @@ export class CoreCourseResourcePrefetchHandlerBase extends CoreCourseModulePrefe * in the filepool root folder. * @return Promise resolved when all content is downloaded. */ - async downloadOrPrefetch(module: CoreCourseWSModule, courseId: number, prefetch?: boolean, dirPath?: string): Promise { + async downloadOrPrefetch(module: CoreCourseModuleData, courseId: number, prefetch?: boolean, dirPath?: string): Promise { if (!CoreApp.isOnline()) { // Cannot download in offline. throw new CoreNetworkError(); @@ -85,7 +86,7 @@ export class CoreCourseResourcePrefetchHandlerBase extends CoreCourseModulePrefe */ protected async performDownloadOrPrefetch( siteId: string, - module: CoreCourseWSModule, + module: CoreCourseModuleData, courseId: number, prefetch: boolean, dirPath?: string, @@ -143,7 +144,7 @@ export class CoreCourseResourcePrefetchHandlerBase extends CoreCourseModulePrefe * @return Promise resolved with the list of files. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars - async getFiles(module: CoreCourseWSModule, courseId: number, single?: boolean): Promise { + async getFiles(module: CoreCourseModuleData, courseId: number, single?: boolean): Promise { // Load module contents if needed. await this.loadContents(module, courseId); @@ -190,7 +191,7 @@ export class CoreCourseResourcePrefetchHandlerBase extends CoreCourseModulePrefe * @param dirPath Path of the directory where to store all the content files. * @return Promise resolved when done. */ - prefetch(module: CoreCourseWSModule, courseId: number, single?: boolean, dirPath?: string): Promise { + prefetch(module: CoreCourseModuleData, courseId: number, single?: boolean, dirPath?: string): Promise { return this.downloadOrPrefetch(module, courseId, true, dirPath); } diff --git a/src/core/features/course/components/format/format.ts b/src/core/features/course/components/format/format.ts index 32932b687..683eb061e 100644 --- a/src/core/features/course/components/format/format.ts +++ b/src/core/features/course/components/format/format.ts @@ -38,7 +38,7 @@ import { } from '@features/course/services/course'; import { CoreCourseHelper, - CoreCourseModule, + CoreCourseModuleData, CoreCourseModuleCompletionData, CoreCourseSection, CoreCourseSectionWithStatus, @@ -637,7 +637,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy { } // If the completion value is not used, the page won't be reloaded, so update the progress bar. - const completionModules = ( []) + const completionModules = ( []) .concat(...this.sections!.map((section) => section.modules)) .map((module) => module.completion && module.completion > 0 ? 1 : module.completion) .reduce((accumulator, currentValue) => (accumulator || 0) + (currentValue || 0), 0); diff --git a/src/core/features/course/components/module-info/module-info.ts b/src/core/features/course/components/module-info/module-info.ts index 2c958c99f..43fbe8ec4 100644 --- a/src/core/features/course/components/module-info/module-info.ts +++ b/src/core/features/course/components/module-info/module-info.ts @@ -14,7 +14,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { CoreCourse } from '@features/course/services/course'; -import { CoreCourseModule, CoreCourseModuleCompletionData } from '@features/course/services/course-helper'; +import { CoreCourseModuleData, CoreCourseModuleCompletionData } from '@features/course/services/course-helper'; import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate'; import { CoreSites } from '@services/sites'; @@ -35,7 +35,7 @@ import { CoreSites } from '@services/sites'; }) export class CoreCourseModuleInfoComponent implements OnInit { - @Input() module!: CoreCourseModule; // The module to render. + @Input() module!: CoreCourseModuleData; // The module to render. @Input() showManualCompletion = true; // Whether to show manual completion, true by default. @Input() courseId!: number; // The courseId the module belongs to. diff --git a/src/core/features/course/components/module-navigation/module-navigation.ts b/src/core/features/course/components/module-navigation/module-navigation.ts index c6cc18ae9..fa326b1c7 100644 --- a/src/core/features/course/components/module-navigation/module-navigation.ts +++ b/src/core/features/course/components/module-navigation/module-navigation.ts @@ -14,7 +14,7 @@ import { Component, ElementRef, Input, OnDestroy, OnInit } from '@angular/core'; import { CoreCourse, CoreCourseProvider, CoreCourseWSSection } from '@features/course/services/course'; -import { CoreCourseModule, CoreCourseSection } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate'; import { IonContent } from '@ionic/angular'; import { ScrollDetail } from '@ionic/core'; @@ -41,10 +41,10 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy { @Input() courseId!: number; // Course ID. @Input() currentModuleId!: number; // Current module ID. - nextModule?: CoreCourseModule; - previousModule?: CoreCourseModule; - nextModuleSection?: CoreCourseSection; - previousModuleSection?: CoreCourseSection; + nextModule?: CoreCourseModuleData; + previousModule?: CoreCourseModuleData; + nextModuleSection?: CoreCourseWSSection; + previousModuleSection?: CoreCourseWSSection; loaded = false; protected element: HTMLElement; @@ -184,7 +184,7 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy { return false; } - currentModuleIndex = section.modules.findIndex((module: CoreCourseModule) => module.id == this.currentModuleId); + currentModuleIndex = section.modules.findIndex((module: CoreCourseModuleData) => module.id == this.currentModuleId); return currentModuleIndex >= 0; }); @@ -250,7 +250,7 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy { * @param module Module to check. * @return Wether the module is available to the user or not. */ - protected async isModuleAvailable(module: CoreCourseModule): Promise { + protected async isModuleAvailable(module: CoreCourseModuleData): Promise { return CoreCourse.instance.moduleHasView(module); } diff --git a/src/core/features/course/components/module/module.ts b/src/core/features/course/components/module/module.ts index b077bd66f..fc2265acb 100644 --- a/src/core/features/course/components/module/module.ts +++ b/src/core/features/course/components/module/module.ts @@ -19,7 +19,7 @@ import { CoreDomUtils } from '@services/utils/dom'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreCourseHelper, - CoreCourseModule, + CoreCourseModuleData, CoreCourseModuleCompletionData, CoreCourseSection, } from '@features/course/services/course-helper'; @@ -44,7 +44,7 @@ import { }) export class CoreCourseModuleComponent implements OnInit, OnDestroy { - @Input() module!: CoreCourseModule; // The module to render. + @Input() module!: CoreCourseModuleData; // The module to render. @Input() courseId?: number; // The course the module belongs to. @Input() section?: CoreCourseSection; // The section the module belongs to. @Input() showActivityDates = false; // Whether to show activity dates. diff --git a/src/core/features/course/components/unsupported-module/unsupported-module.ts b/src/core/features/course/components/unsupported-module/unsupported-module.ts index b8be27123..5df40ab8f 100644 --- a/src/core/features/course/components/unsupported-module/unsupported-module.ts +++ b/src/core/features/course/components/unsupported-module/unsupported-module.ts @@ -14,7 +14,8 @@ import { Component, Input, OnInit } from '@angular/core'; -import { CoreCourse, CoreCourseWSModule } from '@features/course/services/course'; +import { CoreCourse } from '@features/course/services/course'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate'; /** @@ -27,7 +28,7 @@ import { CoreCourseModuleDelegate } from '@features/course/services/module-deleg export class CoreCourseUnsupportedModuleComponent implements OnInit { @Input() courseId?: number; // The course to module belongs to. - @Input() module?: CoreCourseWSModule; // The module to render. + @Input() module?: CoreCourseModuleData; // The module to render. isDisabledInSite?: boolean; isSupportedByTheApp?: boolean; diff --git a/src/core/features/course/directives/download-module-main-file.ts b/src/core/features/course/directives/download-module-main-file.ts index 2756f916f..e004e3eb5 100644 --- a/src/core/features/course/directives/download-module-main-file.ts +++ b/src/core/features/course/directives/download-module-main-file.ts @@ -15,8 +15,8 @@ import { Directive, Input, OnInit, ElementRef } from '@angular/core'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreCourse, CoreCourseModuleContentFile, CoreCourseWSModule } from '@features/course/services/course'; -import { CoreCourseHelper } from '@features/course/services/course-helper'; +import { CoreCourse, CoreCourseModuleContentFile } from '@features/course/services/course'; +import { CoreCourseHelper, CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreUtilsOpenFileOptions } from '@services/utils/utils'; /** @@ -31,7 +31,7 @@ import { CoreUtilsOpenFileOptions } from '@services/utils/utils'; }) export class CoreCourseDownloadModuleMainFileDirective implements OnInit { - @Input() module?: CoreCourseWSModule; // The module. + @Input() module?: CoreCourseModuleData; // The module. @Input() moduleId?: string | number; // The module ID. Required if module is not supplied. @Input() courseId?: string | number; // The course ID. @Input() component?: string; // Component to link the file to. diff --git a/src/core/features/course/pages/index/index.page.ts b/src/core/features/course/pages/index/index.page.ts index 98dd85dd1..68ae06832 100644 --- a/src/core/features/course/pages/index/index.page.ts +++ b/src/core/features/course/pages/index/index.page.ts @@ -20,8 +20,8 @@ import { CoreCourseFormatDelegate } from '../../services/format-delegate'; import { CoreCourseOptionsDelegate } from '../../services/course-options-delegate'; import { CoreCourseAnyCourseData } from '@features/courses/services/courses'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; -import { CoreCourse, CoreCourseWSModule } from '@features/course/services/course'; -import { CoreCourseHelper } from '@features/course/services/course-helper'; +import { CoreCourse } from '@features/course/services/course'; +import { CoreCourseHelper, CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreUtils } from '@services/utils/utils'; import { CoreTextUtils } from '@services/utils/text'; import { CoreNavigator } from '@services/navigator'; @@ -46,7 +46,7 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy { protected currentPagePath = ''; protected selectTabObserver: CoreEventObserver; protected firstTabName?: string; - protected module?: CoreCourseWSModule; + protected module?: CoreCourseModuleData; protected modParams?: Params; protected isGuest?: boolean; protected contentsTab: CoreTabsOutletTab = { @@ -90,7 +90,7 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy { // Get params. this.course = CoreNavigator.getRouteParam('course'); this.firstTabName = CoreNavigator.getRouteParam('selectedTab'); - this.module = CoreNavigator.getRouteParam('module'); + this.module = CoreNavigator.getRouteParam('module'); this.modParams = CoreNavigator.getRouteParam('modParams'); this.isGuest = CoreNavigator.getRouteBooleanParam('isGuest'); diff --git a/src/core/features/course/pages/module-preview/module-preview.page.ts b/src/core/features/course/pages/module-preview/module-preview.page.ts index 01b58cbe6..620b1f981 100644 --- a/src/core/features/course/pages/module-preview/module-preview.page.ts +++ b/src/core/features/course/pages/module-preview/module-preview.page.ts @@ -14,7 +14,7 @@ import { Component, OnInit } from '@angular/core'; import { CoreCourse } from '@features/course/services/course'; -import { CoreCourseHelper, CoreCourseModule, CoreCourseSection } from '@features/course/services/course-helper'; +import { CoreCourseHelper, CoreCourseModuleData, CoreCourseSection } from '@features/course/services/course-helper'; import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate'; import { IonRefresher } from '@ionic/angular'; import { CoreNavigator } from '@services/navigator'; @@ -31,7 +31,7 @@ import { CoreUtils } from '@services/utils/utils'; export class CoreCourseModulePreviewPage implements OnInit { title!: string; - module!: CoreCourseModule; + module!: CoreCourseModuleData; section?: CoreCourseSection; // The section the module belongs to. courseId!: number; loaded = false; @@ -45,7 +45,7 @@ export class CoreCourseModulePreviewPage implements OnInit { */ async ngOnInit(): Promise { try { - this.module = CoreNavigator.getRequiredRouteParam('module'); + this.module = CoreNavigator.getRequiredRouteParam('module'); this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId'); this.section = CoreNavigator.getRouteParam('section'); } catch (error) { @@ -73,8 +73,6 @@ export class CoreCourseModulePreviewPage implements OnInit { this.module = await CoreCourse.getModule(this.module.id, this.courseId); } - CoreCourseHelper.calculateModuleCompletionData(this.module); - await CoreCourseHelper.loadModuleOfflineCompletion(this.courseId, this.module); this.unsupported = !CoreCourseModuleDelegate.getHandlerName(this.module.modname); diff --git a/src/core/features/course/services/course-helper.ts b/src/core/features/course/services/course-helper.ts index e254f5b2f..733d4a843 100644 --- a/src/core/features/course/services/course-helper.ts +++ b/src/core/features/course/services/course-helper.ts @@ -22,11 +22,11 @@ import { CoreCourseCompletionActivityStatus, CoreCourseModuleWSCompletionData, CoreCourseModuleContentFile, - CoreCourseWSModule, CoreCourseProvider, CoreCourseWSSection, CoreCourseModuleCompletionTracking, CoreCourseModuleCompletionStatus, + CoreCourseGetContentsWSModule, } from './course'; import { CoreConstants } from '@/core/constants'; import { CoreLogger } from '@singletons/logger'; @@ -176,18 +176,16 @@ export class CoreCourseHelperProvider { forCoursePage = false, ): { hasContent: boolean; sections: CoreCourseSection[] } { - const formattedSections: CoreCourseSection[] = sections; let hasContent = false; - formattedSections.forEach((section) => { - if (!section || !section.modules) { - return; - } - - section.hasContent = this.sectionHasContent(section); + const formattedSections = sections.map((courseSection) => { + const section = { + ...courseSection, + hasContent: this.sectionHasContent(courseSection), + }; if (!section.hasContent) { - return; + return section; } hasContent = true; @@ -201,9 +199,7 @@ export class CoreCourseHelperProvider { forCoursePage, ); - if (module.completiondata) { - this.calculateModuleCompletionData(module, undefined, courseName); - } else if (completionStatus && completionStatus[module.id] !== undefined) { + if (!module.completiondata && completionStatus && completionStatus[module.id] !== undefined) { // Should not happen on > 3.6. Check if activity has completions and if it's marked. const activityStatus = completionStatus[module.id]; @@ -222,6 +218,8 @@ export class CoreCourseHelperProvider { // Check if the module is stealth. module.isStealth = module.visibleoncoursepage === 0 || (!!module.visible && !section.visible); }); + + return section; }); return { hasContent, sections: formattedSections }; @@ -230,11 +228,10 @@ export class CoreCourseHelperProvider { /** * Calculate completion data of a module. * + * @deprecated since 4.0. * @param module Module. - * @param courseId Not used since 4.0 - * @param courseName Course name. */ - calculateModuleCompletionData(module: CoreCourseModule, courseId?: number, courseName?: string): void { + calculateModuleCompletionData(module: CoreCourseModuleData): void { if (!module.completiondata || !module.completion) { return; } @@ -242,7 +239,6 @@ export class CoreCourseHelperProvider { module.completiondata.courseId = module.course; module.completiondata.tracking = module.completion; module.completiondata.cmid = module.id; - module.completiondata.courseName = courseName; } /** @@ -497,7 +493,7 @@ export class CoreCourseHelperProvider { * @param done Function to call when done. It will close the context menu. * @return Promise resolved when done. */ - async confirmAndRemoveFiles(module: CoreCourseWSModule, courseId: number, done?: () => void): Promise { + async confirmAndRemoveFiles(module: CoreCourseModuleData, courseId: number, done?: () => void): Promise { let modal: CoreIonLoadingElement | undefined; try { @@ -586,7 +582,7 @@ export class CoreCourseHelperProvider { */ async contextMenuPrefetch( instance: ComponentWithContextMenu, - module: CoreCourseWSModule, + module: CoreCourseModuleData, courseId: number, done?: () => void, ): Promise { @@ -718,7 +714,7 @@ export class CoreCourseHelperProvider { * @return Resolved on success. */ async downloadModuleAndOpenFile( - module: CoreCourseWSModule, + module: CoreCourseModuleData, courseId: number, component?: string, componentId?: string | number, @@ -810,7 +806,7 @@ export class CoreCourseHelperProvider { protected async openModuleFileInBrowser( fileUrl: string, site: CoreSite, - module: CoreCourseWSModule, + module: CoreCourseModuleData, courseId: number, component?: string, componentId?: string | number, @@ -861,7 +857,7 @@ export class CoreCourseHelperProvider { * @return Promise resolved when done. */ async downloadModuleWithMainFileIfNeeded( - module: CoreCourseWSModule, + module: CoreCourseModuleData, courseId: number, component: string, componentId?: string | number, @@ -944,7 +940,7 @@ export class CoreCourseHelperProvider { * @return Promise resolved when done. */ protected async downloadModuleWithMainFile( - module: CoreCourseWSModule, + module: CoreCourseModuleData, courseId: number, fixedUrl: string, files: CoreCourseModuleContentFile[], @@ -1009,7 +1005,7 @@ export class CoreCourseHelperProvider { * @return Promise resolved when done. */ async downloadModule( - module: CoreCourseWSModule, + module: CoreCourseModuleData, courseId: number, component?: string, componentId?: string | number, @@ -1047,7 +1043,7 @@ export class CoreCourseHelperProvider { */ async fillContextMenu( instance: ComponentWithContextMenu, - module: CoreCourseWSModule, + module: CoreCourseModuleData, courseId: number, invalidateCache?: boolean, component?: string, @@ -1230,7 +1226,7 @@ export class CoreCourseHelperProvider { * @param siteId Site ID. If not defined, current site. * @return Promise resolved when done. */ - async loadOfflineCompletion(courseId: number, sections: CoreCourseSection[], siteId?: string): Promise { + async loadOfflineCompletion(courseId: number, sections: CoreCourseWSSection[], siteId?: string): Promise { const offlineCompletions = await CoreCourseOffline.getCourseManualCompletions(courseId, siteId); if (!offlineCompletions || !offlineCompletions.length) { @@ -1278,7 +1274,7 @@ export class CoreCourseHelperProvider { * @param siteId Site ID. If not defined, current site. * @return Promise resolved when done. */ - async loadModuleOfflineCompletion(courseId: number, module: CoreCourseModule, siteId?: string): Promise { + async loadModuleOfflineCompletion(courseId: number, module: CoreCourseModuleData, siteId?: string): Promise { if (!module.completiondata) { return; } @@ -1464,7 +1460,7 @@ export class CoreCourseHelperProvider { * @return Promise resolved with the info. */ async getModulePrefetchInfo( - module: CoreCourseWSModule, + module: CoreCourseModuleData, courseId: number, invalidateCache?: boolean, component?: string, @@ -1634,7 +1630,7 @@ export class CoreCourseHelperProvider { const site = await CoreSites.getSite(siteId); // Get the module. - const module = + const module = await CoreCourse.getModule(moduleId, courseId, sectionId, false, false, siteId, modName); if (CoreSites.getCurrentSiteId() == site.getId()) { @@ -1693,7 +1689,7 @@ export class CoreCourseHelperProvider { * @param modParams Params to pass to the module * @param True if module can be opened, false otherwise. */ - async openModule(module: CoreCourseModule, courseId: number, sectionId?: number, modParams?: Params): Promise { + async openModule(module: CoreCourseModuleData, courseId: number, sectionId?: number, modParams?: Params): Promise { if (!module.handlerData) { module.handlerData = await CoreCourseModuleDelegate.getModuleDataFor( module.modname, @@ -1749,7 +1745,7 @@ export class CoreCourseHelperProvider { const promises: Promise[] = []; // Prefetch all the sections. If the first section is "All sections", use it. Otherwise, use a fake "All sections". - let allSectionsSection: CoreCourseSection = sections[0]; + let allSectionsSection: CoreCourseWSSection = sections[0]; if (sections[0].id != CoreCourseProvider.ALL_SECTIONS_ID) { allSectionsSection = this.createAllSectionsSection(); } @@ -1806,7 +1802,7 @@ export class CoreCourseHelperProvider { */ async prefetchModule( handler: CoreCourseModulePrefetchHandler, - module: CoreCourseWSModule, + module: CoreCourseModuleData, size: CoreFileSizeSum, courseId: number, refresh?: boolean, @@ -1984,6 +1980,10 @@ export class CoreCourseHelperProvider { * @return Whether the section has content. */ sectionHasContent(section: CoreCourseWSSection): boolean { + if (!section.modules) { + return false; + } + if (section.hiddenbynumsections) { return false; } @@ -2042,7 +2042,7 @@ export class CoreCourseHelperProvider { * @param courseId Course ID the module belongs to. * @return Promise resolved when done. */ - async removeModuleStoredData(module: CoreCourseWSModule, courseId: number): Promise { + async removeModuleStoredData(module: CoreCourseModuleData, courseId: number): Promise { const promises: Promise[] = []; promises.push(CoreCourseModulePrefetchDelegate.removeModuleFiles(module, courseId)); @@ -2088,7 +2088,7 @@ export class CoreCourseHelperProvider { const response = await CoreCourse.markCompletedManually( completion.cmid, completion.state === CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE, - completion.courseId!, + completion.courseId, ); if (response.offline) { @@ -2115,9 +2115,8 @@ export const CoreCourseHelper = makeSingleton(CoreCourseHelperProvider); /** * Section with calculated data. */ -export type CoreCourseSection = Omit & { +export type CoreCourseSection = CoreCourseWSSection & { hasContent?: boolean; - modules: CoreCourseModule[]; }; /** @@ -2135,20 +2134,27 @@ export type CoreCourseSectionWithStatus = CoreCourseSection & { /** * Module with calculated data. */ -export type CoreCourseModule = Omit & { +export type CoreCourseModuleData = Omit & { + course: number; // The course id. isStealth?: boolean; handlerData?: CoreCourseModuleHandlerData; completiondata?: CoreCourseModuleCompletionData; }; +/** + * Module with calculated data. + * + * @deprecated since 4.0. Use CoreCourseModuleData instead. + */ +export type CoreCourseModule = CoreCourseModuleData; + /** * Module completion with calculated data. */ export type CoreCourseModuleCompletionData = CoreCourseModuleWSCompletionData & { - courseId?: number; - courseName?: string; - tracking?: CoreCourseModuleCompletionTracking; - cmid?: number; + courseId: number; + tracking: CoreCourseModuleCompletionTracking; + cmid: number; offline?: boolean; }; diff --git a/src/core/features/course/services/course.ts b/src/core/features/course/services/course.ts index c8da4ec5f..55e848c58 100644 --- a/src/core/features/course/services/course.ts +++ b/src/core/features/course/services/course.ts @@ -36,7 +36,7 @@ import { import { CoreDomUtils } from '@services/utils/dom'; import { CoreWSError } from '@classes/errors/wserror'; import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications'; -import { CoreCourseHelper, CoreCourseModuleCompletionData } from './course-helper'; +import { CoreCourseHelper, CoreCourseModuleData, CoreCourseModuleCompletionData } from './course-helper'; import { CoreCourseFormatDelegate } from './format-delegate'; import { CoreCronDelegate } from '@services/cron'; import { CoreCourseLogCronHandler } from './handlers/log-cron'; @@ -431,7 +431,7 @@ export class CoreCourseProvider { ignoreCache: boolean = false, siteId?: string, modName?: string, - ): Promise { + ): Promise { siteId = siteId || CoreSites.getCurrentSiteId(); // Helper function to do the WS request without processing the result. @@ -544,15 +544,43 @@ export class CoreCourseProvider { }); if (foundSection && foundModule) { - return { - ...foundModule, - course: courseId, - }; + return this.addAdditionalModuleData(foundModule, courseId); } throw new CoreError(Translate.instant('core.course.modulenotfound')); } + /** + * Add some additional info to course module. + * + * @param module Module. + * @param courseId Course ID of the module. + * @return Module with additional info. + */ + protected addAdditionalModuleData( + module: CoreCourseGetContentsWSModule, + courseId: number, + ): CoreCourseModuleData { + let completionData: CoreCourseModuleCompletionData | undefined = undefined; + + if (module.completiondata && module.completion) { + completionData = { + ...module.completiondata, + tracking: module.completion, + cmid: module.id, + courseId, + }; + } + + const moduleWithCourse: CoreCourseModuleData = { + ...module, + course: courseId, + completiondata: completionData, + }; + + return moduleWithCourse; + } + /** * Gets a module basic info by module ID. * @@ -808,10 +836,7 @@ export class CoreCourseProvider { // Add course to all modules. return sections.map((section) => ({ ...section, - modules: section.modules.map((module) => ({ - ...module, - course: courseId, - })), + modules: section.modules.map((module) => this.addAdditionalModuleData(module, courseId)), })); } @@ -831,12 +856,12 @@ export class CoreCourseProvider { * @param sections Sections. * @return Modules. */ - getSectionsModules(sections: CoreCourseWSSection[]): CoreCourseWSModule[] { + getSectionsModules(sections: CoreCourseWSSection[]): CoreCourseModuleData[] { if (!sections || !sections.length) { return []; } - return sections.reduce((previous: CoreCourseWSModule[], section) => previous.concat(section.modules || []), []); + return sections.reduce((previous: CoreCourseModuleData[], section) => previous.concat(section.modules || []), []); } /** @@ -1103,7 +1128,7 @@ export class CoreCourseProvider { * @param module The module object. * @return Whether the module has a view page. */ - moduleHasView(module: CoreCourseModuleSummary | CoreCourseWSModule): boolean { + moduleHasView(module: CoreCourseModuleSummary | CoreCourseModuleData): boolean { if ('modname' in module) { // noviewlink was introduced in 3.8.5, use supports feature as a fallback. if (module.noviewlink || @@ -1503,7 +1528,7 @@ type CoreCourseGetContentsWSSection = { /** * Module data returned by core_course_get_contents WS. */ -type CoreCourseGetContentsWSModule = { +export type CoreCourseGetContentsWSModule = { id: number; // Activity id. url?: string; // Activity url. name: string; // Activity module name. @@ -1544,7 +1569,7 @@ type CoreCourseGetContentsWSModule = { * Data returned by core_course_get_contents WS. */ export type CoreCourseWSSection = Omit & { - modules: CoreCourseWSModule[]; // List of module. + modules: CoreCourseModuleData[]; // List of module. }; /** @@ -1572,6 +1597,8 @@ type CoreCourseGetCourseModuleWSResponse = { /** * Course module data returned by the WS with course added. + * + * @deprecated since 4.0. Use CoreCourseModuleData instead. */ export type CoreCourseWSModule = CoreCourseGetContentsWSModule & { course: number; // The course id. @@ -1703,6 +1730,6 @@ type CoreCompletionUpdateActivityCompletionStatusManuallyWSParams = { /** * Any of the possible module WS data. */ -export type CoreCourseAnyModuleData = CoreCourseWSModule | CoreCourseModuleBasicInfo & { +export type CoreCourseAnyModuleData = CoreCourseModuleData | CoreCourseModuleBasicInfo & { contents?: CoreCourseModuleContentFile[]; // If needed, calculated in the app in loadModuleContents. }; diff --git a/src/core/features/course/services/handlers/default-module.ts b/src/core/features/course/services/handlers/default-module.ts index 6e8cb25d6..13f40a844 100644 --- a/src/core/features/course/services/handlers/default-module.ts +++ b/src/core/features/course/services/handlers/default-module.ts @@ -17,7 +17,7 @@ import { Injectable, Type } from '@angular/core'; import { CoreSites } from '@services/sites'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../module-delegate'; import { CoreCourse } from '../course'; -import { CoreCourseModule } from '../course-helper'; +import { CoreCourseModuleData } from '../course-helper'; import { CoreCourseUnsupportedModuleComponent } from '@features/course/components/unsupported-module/unsupported-module'; import { CoreNavigationOptions, CoreNavigator } from '@services/navigator'; @@ -42,14 +42,14 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler { * @inheritdoc */ async getData( - module: CoreCourseModule, + module: CoreCourseModuleData, ): Promise { // Return the default data. const defaultData: CoreCourseModuleHandlerData = { icon: await CoreCourse.getModuleIconSrc(module.modname, module.modicon), title: module.name, class: 'core-course-default-handler core-course-module-' + module.modname + '-handler', - action: async (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => { + action: async (event: Event, module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions) => { event.preventDefault(); event.stopPropagation(); @@ -92,7 +92,7 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler { /** * @inheritdoc */ - async openActivityPage(module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): Promise { + async openActivityPage(module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions): Promise { options = options || {}; options.params = options.params || {}; Object.assign(options.params, { module }); diff --git a/src/core/features/course/services/module-delegate.ts b/src/core/features/course/services/module-delegate.ts index 2776043ff..d32c1be3e 100644 --- a/src/core/features/course/services/module-delegate.ts +++ b/src/core/features/course/services/module-delegate.ts @@ -20,10 +20,10 @@ import { CoreSite } from '@classes/site'; import { CoreCourseModuleDefaultHandler } from './handlers/default-module'; import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate'; import { CoreCourseAnyCourseData } from '@features/courses/services/courses'; -import { CoreCourse, CoreCourseWSModule } from './course'; +import { CoreCourse } from './course'; import { CoreSites } from '@services/sites'; import { makeSingleton } from '@singletons'; -import { CoreCourseModule } from './course-helper'; +import { CoreCourseModuleData } from './course-helper'; import { CoreNavigationOptions } from '@services/navigator'; /** @@ -52,7 +52,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler { * @return Data to render the module. */ getData( - module: CoreCourseModule, + module: CoreCourseModuleData, courseId: number, sectionId?: number, forCoursePage?: boolean, @@ -67,7 +67,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler { * @param module The module object. * @return Promise resolved with component to use, undefined if not found. */ - getMainComponent(course: CoreCourseAnyCourseData, module: CoreCourseWSModule): Promise | undefined>; + getMainComponent(course: CoreCourseAnyCourseData, module: CoreCourseModuleData): Promise | undefined>; /** * Whether to display the course refresher in single activity course format. If it returns false, a refresher must be @@ -83,7 +83,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler { * @param module: Module to get the icon from. * @return The icon src. */ - getIconSrc?(module?: CoreCourseWSModule): Promise | string | undefined; + getIconSrc?(module?: CoreCourseModuleData): Promise | string | undefined; /** * Check if this type of module supports a certain feature. @@ -101,7 +101,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler { * @param module Module. * @return Promise resolved with boolean: whether the manual completion should always be displayed. */ - manualCompletionAlwaysShown?(module: CoreCourseModule): Promise; + manualCompletionAlwaysShown?(module: CoreCourseModuleData): Promise; /** * Opens the activity page. @@ -111,7 +111,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler { * @param options Options for the navigation. * @return Promise resolved when done. */ - openActivityPage(module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): Promise; + openActivityPage(module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions): Promise; } /** @@ -179,7 +179,7 @@ export interface CoreCourseModuleHandlerData { * @param options Options for the navigation. * @return Promise resolved when done. */ - action?(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): Promise | void; + action?(event: Event, module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions): Promise | void; /** * Updates the status of the module. @@ -250,7 +250,7 @@ export interface CoreCourseModuleHandlerButton { * @param options Options for the navigation. * @return Promise resolved when done. */ - action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): Promise | void; + action(event: Event, module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions): Promise | void; } /** @@ -273,7 +273,7 @@ export class CoreCourseModuleDelegateService extends CoreDelegate | undefined> { + async getMainComponent(course: CoreCourseAnyCourseData, module: CoreCourseModuleData): Promise | undefined> { try { return await this.executeFunctionOnEnabled>(module.modname, 'getMainComponent', [course, module]); } catch (error) { @@ -293,7 +293,7 @@ export class CoreCourseModuleDelegateService extends CoreDelegate { @@ -381,7 +381,7 @@ export class CoreCourseModuleDelegateService extends CoreDelegate { + async getModuleIconSrc(modname: string, modicon?: string, module?: CoreCourseModuleData): Promise { const icon = await this.executeFunctionOnEnabled>(modname, 'getIconSrc', [module]); return icon || await CoreCourse.getModuleIconSrc(modname, modicon) || ''; @@ -419,7 +419,7 @@ export class CoreCourseModuleDelegateService extends CoreDelegate { + async manualCompletionAlwaysShown(module: CoreCourseModuleData): Promise { const result = await this.executeFunctionOnEnabled(module.modname, 'manualCompletionAlwaysShown', [module]); return !!result; diff --git a/src/core/features/course/services/module-prefetch-delegate.ts b/src/core/features/course/services/module-prefetch-delegate.ts index e1166739b..d1250decb 100644 --- a/src/core/features/course/services/module-prefetch-delegate.ts +++ b/src/core/features/course/services/module-prefetch-delegate.ts @@ -22,7 +22,7 @@ import { CoreFilepool } from '@services/filepool'; import { CoreSites } from '@services/sites'; import { CoreTimeUtils } from '@services/utils/time'; import { CoreUtils } from '@services/utils/utils'; -import { CoreCourse, CoreCourseAnyModuleData, CoreCourseModuleContentFile, CoreCourseWSModule } from './course'; +import { CoreCourse, CoreCourseAnyModuleData, CoreCourseModuleContentFile } from './course'; import { CoreCache } from '@classes/cache'; import { CoreSiteWSPreSets } from '@classes/site'; import { CoreConstants } from '@/core/constants'; @@ -33,6 +33,7 @@ import { CoreError } from '@classes/errors/error'; import { CoreWSFile, CoreWSExternalWarning } from '@services/ws'; import { CHECK_UPDATES_TIMES_TABLE, CoreCourseCheckUpdatesDBRecord } from './database/module-prefetch'; import { CoreFileSizeSum } from '@services/plugin-file-delegate'; +import { CoreCourseModuleData } from './course-helper'; const ROOT_CACHE_KEY = 'mmCourse:'; @@ -123,7 +124,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { + protected async createToCheckList(modules: CoreCourseModuleData[], courseId: number): Promise { const result: ToCheckList = { toCheck: [], cannotUse: [], @@ -221,7 +222,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { + async getCourseUpdates(modules: CoreCourseModuleData[], courseId: number): Promise { // Check if there's already a getCourseUpdates in progress. const id = Md5.hashAsciiStr(courseId + '#' + JSON.stringify(modules)); const siteId = CoreSites.getCurrentSiteId(); @@ -253,7 +254,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { @@ -351,7 +352,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { + async getDownloadSize(modules: CoreCourseModuleData[], courseId: number): Promise { // Get the status of each module. const data = await this.getModulesStatus(modules, courseId); @@ -683,7 +684,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { + async invalidateModules(modules: CoreCourseModuleData[], courseId: number): Promise { const promises = modules.map(async (module) => { const handler = this.getPrefetchHandlerFor(module); @@ -1049,7 +1050,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { + syncModules(modules: CoreCourseModuleData[], courseId: number): Promise { return Promise.all(modules.map(async (module) => { await this.syncModule(module, courseId); @@ -1091,7 +1092,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { @@ -1512,7 +1513,7 @@ export interface CoreCourseModulePrefetchHandler extends CoreDelegateHandler { type ToCheckList = { toCheck: CheckUpdatesToCheckWSParam[]; - cannotUse: CoreCourseWSModule[]; + cannotUse: CoreCourseModuleData[]; }; /** @@ -1526,10 +1527,10 @@ type CourseUpdates = Record; export type CoreCourseModulesStatus = { total: number; // Number of modules. status: string; // Status of the list of modules. - [CoreConstants.NOT_DOWNLOADED]: CoreCourseWSModule[]; // Modules with state NOT_DOWNLOADED. - [CoreConstants.DOWNLOADED]: CoreCourseWSModule[]; // Modules with state DOWNLOADED. - [CoreConstants.DOWNLOADING]: CoreCourseWSModule[]; // Modules with state DOWNLOADING. - [CoreConstants.OUTDATED]: CoreCourseWSModule[]; // Modules with state OUTDATED. + [CoreConstants.NOT_DOWNLOADED]: CoreCourseModuleData[]; // Modules with state NOT_DOWNLOADED. + [CoreConstants.DOWNLOADED]: CoreCourseModuleData[]; // Modules with state DOWNLOADED. + [CoreConstants.DOWNLOADING]: CoreCourseModuleData[]; // Modules with state DOWNLOADING. + [CoreConstants.OUTDATED]: CoreCourseModuleData[]; // Modules with state OUTDATED. }; /** diff --git a/src/core/features/sitehome/pages/index/index.ts b/src/core/features/sitehome/pages/index/index.ts index eae6406f8..8e9a4d6e7 100644 --- a/src/core/features/sitehome/pages/index/index.ts +++ b/src/core/features/sitehome/pages/index/index.ts @@ -17,14 +17,14 @@ import { IonRefresher } from '@ionic/angular'; import { Params } from '@angular/router'; import { CoreSite, CoreSiteConfig } from '@classes/site'; -import { CoreCourse, CoreCourseWSModule, CoreCourseWSSection } from '@features/course/services/course'; +import { CoreCourse, CoreCourseWSSection } from '@features/course/services/course'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreSites } from '@services/sites'; import { CoreSiteHome } from '@features/sitehome/services/sitehome'; import { CoreCourses, CoreCoursesProvider } from '@features//courses/services/courses'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; -import { CoreCourseHelper, CoreCourseModule } from '@features/course/services/course-helper'; -import { CoreCourseModuleDelegate, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; +import { CoreCourseHelper, CoreCourseModuleData } from '@features/course/services/course-helper'; +import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate'; import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; import { CoreNavigator } from '@services/navigator'; import { CoreBlockHelper } from '@features/block/services/block-helper'; @@ -52,7 +52,7 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { searchEnabled = false; displayEnableDownload = false; downloadEnabled = false; - newsForumModule?: NewsForum; + newsForumModule?: CoreCourseModuleData; protected updateSiteObserver: CoreEventObserver; protected downloadEnabledObserver: CoreEventObserver; @@ -79,7 +79,7 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { this.currentSite = CoreSites.getRequiredCurrentSite(); this.siteHomeId = CoreSites.getCurrentSiteHomeId(); - const module = CoreNavigator.getRouteParam('module'); + const module = CoreNavigator.getRouteParam('module'); if (module) { const modParams = CoreNavigator.getRouteParam('modParams'); CoreCourseHelper.openModule(module, this.siteHomeId, undefined, modParams); @@ -235,7 +235,3 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { } } - -type NewsForum = CoreCourseWSModule & { - handlerData?: CoreCourseModuleHandlerData; -}; diff --git a/src/core/features/siteplugins/classes/handlers/module-handler.ts b/src/core/features/siteplugins/classes/handlers/module-handler.ts index 9a945b48a..8e0e95d9b 100644 --- a/src/core/features/siteplugins/classes/handlers/module-handler.ts +++ b/src/core/features/siteplugins/classes/handlers/module-handler.ts @@ -15,8 +15,8 @@ import { Type } from '@angular/core'; import { CoreConstants } from '@/core/constants'; -import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '@features/course/services/course'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreSitePluginsModuleIndexComponent } from '@features/siteplugins/components/module-index/module-index'; import { @@ -94,7 +94,7 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp // There is a method, add an action. handlerData.action = async ( event: Event, - module: CoreCourseModule, + module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions, ) => { @@ -190,7 +190,7 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp // Use the html returned. handlerData.title = result.templates[0]?.html ?? ''; - ( module).description = ''; + ( module).description = ''; } catch (error) { this.logger.error('Error calling course page method:', error); } finally { @@ -215,7 +215,7 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp /** * @inheritdoc */ - async manualCompletionAlwaysShown(module: CoreCourseModule): Promise { + async manualCompletionAlwaysShown(module: CoreCourseModuleData): Promise { if (this.handlerSchema.manualcompletionalwaysshown !== undefined) { return this.handlerSchema.manualcompletionalwaysshown; } @@ -231,7 +231,7 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp /** * @inheritdoc */ - async openActivityPage(module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): Promise { + async openActivityPage(module: CoreCourseModuleData, courseId: number, options?: CoreNavigationOptions): Promise { if (!CoreCourse.moduleHasView(module)) { return; } diff --git a/src/core/features/siteplugins/components/module-index/module-index.ts b/src/core/features/siteplugins/components/module-index/module-index.ts index 499458d36..7858a0db1 100644 --- a/src/core/features/siteplugins/components/module-index/module-index.ts +++ b/src/core/features/siteplugins/components/module-index/module-index.ts @@ -16,7 +16,7 @@ import { CoreConstants } from '@/core/constants'; import { Component, OnInit, OnDestroy, Input, ViewChild } from '@angular/core'; import { CoreSiteWSPreSets } from '@classes/site'; -import { CoreCourseHelper, CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseHelper, CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseModuleDelegate, CoreCourseModuleMainComponent, @@ -44,7 +44,7 @@ import { CoreSitePluginsPluginContentComponent } from '../plugin-content/plugin- }) export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, CoreCourseModuleMainComponent { - @Input() module!: CoreCourseModule; // The module. + @Input() module!: CoreCourseModuleData; // The module. @Input() courseId!: number; // Course ID the module belongs to. @Input() pageTitle?: string; // Current page title. It can be used by the "new-content" directives. diff --git a/src/core/features/siteplugins/pages/module-index/module-index.ts b/src/core/features/siteplugins/pages/module-index/module-index.ts index 5a8c07f4d..653d88a1e 100644 --- a/src/core/features/siteplugins/pages/module-index/module-index.ts +++ b/src/core/features/siteplugins/pages/module-index/module-index.ts @@ -15,7 +15,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { IonRefresher } from '@ionic/angular'; -import { CoreCourseModule } from '@features/course/services/course-helper'; +import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CanLeave } from '@guards/can-leave'; import { CoreNavigator } from '@services/navigator'; import { CoreSitePluginsModuleIndexComponent } from '../../components/module-index/module-index'; @@ -32,7 +32,7 @@ export class CoreSitePluginsModuleIndexPage implements OnInit, CanLeave { @ViewChild(CoreSitePluginsModuleIndexComponent) content?: CoreSitePluginsModuleIndexComponent; title?: string; // Page title. - module?: CoreCourseModule; + module?: CoreCourseModuleData; courseId?: number; /**