MOBILE-3833 mod: Create a base module to remove duplicated getData func

This commit is contained in:
Pau Ferrer Ocaña 2021-09-08 14:40:20 +02:00
parent 337b92aed6
commit d5d8962766
27 changed files with 228 additions and 737 deletions

View File

@ -14,23 +14,22 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { AddonModAssignIndexComponent } from '../../components/index'; import { AddonModAssignIndexComponent } from '../../components/index';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
/** /**
* Handler to support assign modules. * Handler to support assign modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModAssignModuleHandlerService implements CoreCourseModuleHandler { export class AddonModAssignModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_assign'; static readonly PAGE_NAME = 'mod_assign';
name = 'AddonModAssign'; name = 'AddonModAssign';
modName = 'assign'; modName = 'assign';
protected pageName = AddonModAssignModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -48,42 +47,7 @@ export class AddonModAssignModuleHandlerService implements CoreCourseModuleHandl
}; };
/** /**
* Check if the handler is enabled on a site level. * @inheritdoc
*
* @return Whether or not the handler is enabled on a site level.
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* Get the data required to display the module in the course contents view.
*
* @param module The module object.
* @return Data to render the module.
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_assign-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModAssignModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/**
* Get the component to render the module. This is needed to support singleactivity course format.
* The component returned must implement CoreCourseModuleMainComponent.
*
* @return The component to use, undefined if not found.
*/ */
async getMainComponent(): Promise<Type<unknown> | undefined> { async getMainComponent(): Promise<Type<unknown> | undefined> {
return AddonModAssignIndexComponent; return AddonModAssignIndexComponent;

View File

@ -15,23 +15,22 @@
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { AddonModBookIndexComponent } from '../../components/index'; import { AddonModBookIndexComponent } from '../../components/index';
import { AddonModBook } from '../book'; import { AddonModBook } from '../book';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
/** /**
* Handler to support book modules. * Handler to support book modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModBookModuleHandlerService implements CoreCourseModuleHandler { export class AddonModBookModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_book'; static readonly PAGE_NAME = 'mod_book';
name = 'AddonModBook'; name = 'AddonModBook';
modName = 'book'; modName = 'book';
protected pageName = AddonModBookModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE, [CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
@ -46,45 +45,14 @@ export class AddonModBookModuleHandlerService implements CoreCourseModuleHandler
}; };
/** /**
* Check if the handler is enabled on a site level. * @inheritdoc
*
* @return Whether or not the handler is enabled on a site level.
*/ */
isEnabled(): Promise<boolean> { isEnabled(): Promise<boolean> {
return AddonModBook.isPluginEnabled(); return AddonModBook.isPluginEnabled();
} }
/** /**
* Get the data required to display the module in the course contents view. * @inheritdoc
*
* @param module The module object.
* @param courseId The course ID.
* @param sectionId The section ID.
* @return Data to render the module.
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_book-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModBookModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/**
* Get the component to render the module. This is needed to support singleactivity course format.
* The component returned must implement CoreCourseModuleMainComponent.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
async getMainComponent(): Promise<Type<unknown> | undefined> { async getMainComponent(): Promise<Type<unknown> | undefined> {
return AddonModBookIndexComponent; return AddonModBookIndexComponent;

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModChatIndexComponent } from '../../components/index'; import { AddonModChatIndexComponent } from '../../components/index';
@ -25,12 +23,13 @@ import { AddonModChatIndexComponent } from '../../components/index';
* Handler to support chat modules. * Handler to support chat modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModChatModuleHandlerService implements CoreCourseModuleHandler { export class AddonModChatModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_chat'; static readonly PAGE_NAME = 'mod_chat';
name = 'AddonModChat'; name = 'AddonModChat';
modName = 'chat'; modName = 'chat';
protected pageName = AddonModChatModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -43,35 +42,6 @@ export class AddonModChatModuleHandlerService implements CoreCourseModuleHandler
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
const data: CoreCourseModuleHandlerData = {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_chat-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModChatModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
return data;
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModChoiceIndexComponent } from '../../components/index'; import { AddonModChoiceIndexComponent } from '../../components/index';
@ -25,12 +23,13 @@ import { AddonModChoiceIndexComponent } from '../../components/index';
* Handler to support choice modules. * Handler to support choice modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModChoiceModuleHandlerService implements CoreCourseModuleHandler { export class AddonModChoiceModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_choice'; static readonly PAGE_NAME = 'mod_choice';
name = 'AddonModChoice'; name = 'AddonModChoice';
modName = 'choice'; modName = 'choice';
protected pageName = AddonModChoiceModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -44,33 +43,6 @@ export class AddonModChoiceModuleHandlerService implements CoreCourseModuleHandl
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_choice-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModChoiceModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModDataIndexComponent } from '../../components/index'; import { AddonModDataIndexComponent } from '../../components/index';
@ -25,12 +23,13 @@ import { AddonModDataIndexComponent } from '../../components/index';
* Handler to support data modules. * Handler to support data modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModDataModuleHandlerService implements CoreCourseModuleHandler { export class AddonModDataModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_data'; static readonly PAGE_NAME = 'mod_data';
name = 'AddonModData'; name = 'AddonModData';
modName = 'data'; modName = 'data';
protected pageName = AddonModDataModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -46,33 +45,6 @@ export class AddonModDataModuleHandlerService implements CoreCourseModuleHandler
[CoreConstants.FEATURE_COMMENT]: true, [CoreConstants.FEATURE_COMMENT]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_data-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModDataModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -14,23 +14,22 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModFeedbackIndexComponent } from '../../components/index'; import { AddonModFeedbackIndexComponent } from '../../components/index';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
/** /**
* Handler to support feedback modules. * Handler to support feedback modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModFeedbackModuleHandlerService implements CoreCourseModuleHandler { export class AddonModFeedbackModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_feedback'; static readonly PAGE_NAME = 'mod_feedback';
name = 'AddonModFeedback'; name = 'AddonModFeedback';
modName = 'feedback'; modName = 'feedback';
protected pageName = AddonModFeedbackModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -44,33 +43,6 @@ export class AddonModFeedbackModuleHandlerService implements CoreCourseModuleHan
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_feedback-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModFeedbackModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModFolderIndexComponent } from '../../components/index'; import { AddonModFolderIndexComponent } from '../../components/index';
@ -25,12 +23,13 @@ import { AddonModFolderIndexComponent } from '../../components/index';
* Handler to support folder modules. * Handler to support folder modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModFolderModuleHandlerService implements CoreCourseModuleHandler { export class AddonModFolderModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_folder'; static readonly PAGE_NAME = 'mod_folder';
name = 'AddonModFolder'; name = 'AddonModFolder';
modName = 'folder'; modName = 'folder';
protected pageName = AddonModFolderModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE, [CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
@ -44,33 +43,6 @@ export class AddonModFolderModuleHandlerService implements CoreCourseModuleHandl
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_folder-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModFolderModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -14,9 +14,7 @@
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { AddonModForum, AddonModForumProvider } from '../forum'; import { AddonModForum, AddonModForumProvider } from '../forum';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
@ -24,17 +22,19 @@ import { CoreUtils } from '@services/utils/utils';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { AddonModForumIndexComponent } from '../../components/index'; import { AddonModForumIndexComponent } from '../../components/index';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
/** /**
* Handler to support forum modules. * Handler to support forum modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModForumModuleHandlerService implements CoreCourseModuleHandler { export class AddonModForumModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_forum'; static readonly PAGE_NAME = 'mod_forum';
name = 'AddonModForum'; name = 'AddonModForum';
modName = 'forum'; modName = 'forum';
protected pageName = AddonModForumModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -51,39 +51,10 @@ export class AddonModForumModuleHandlerService implements CoreCourseModuleHandle
}; };
/** /**
* Check if the handler is enabled on a site level. * @inheritdoc
*
* @return Whether or not the handler is enabled on a site level.
*/
isEnabled(): Promise<boolean> {
return Promise.resolve(true);
}
/**
* Get the data required to display the module in the course contents view.
*
* @param module The module object.
* @param courseId The course ID.
* @param sectionId The section ID.
* @return Data to render the module.
*/ */
getData(module: CoreCourseAnyModuleData, courseId: number): CoreCourseModuleHandlerData { getData(module: CoreCourseAnyModuleData, courseId: number): CoreCourseModuleHandlerData {
const data: CoreCourseModuleHandlerData = { const data = super.getData(module, courseId);
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_forum-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
CoreNavigator.navigateToSitePath(
`${AddonModForumModuleHandlerService.PAGE_NAME}/${courseId}/${module.id}`,
options,
);
},
};
if ('afterlink' in module && !!module.afterlink) { if ('afterlink' in module && !!module.afterlink) {
data.extraBadgeColor = ''; data.extraBadgeColor = '';
@ -111,20 +82,14 @@ export class AddonModForumModuleHandlerService implements CoreCourseModuleHandle
} }
/** /**
* Get the component to render the module. This is needed to support singleactivity course format. * @inheritdoc
* The component returned must implement CoreCourseModuleMainComponent.
*
* @return The component to use, undefined if not found.
*/ */
async getMainComponent(): Promise<Type<unknown> | undefined> { async getMainComponent(): Promise<Type<unknown> | undefined> {
return AddonModForumIndexComponent; return AddonModForumIndexComponent;
} }
/** /**
* Whether to display the course refresher in single activity course format. If it returns false, a refresher must be * @inheritdoc
* included in the template that calls the doRefresh method of the component. Defaults to true.
*
* @return Whether the refresher should be displayed.
*/ */
displayRefresherInSingleActivity(): boolean { displayRefresherInSingleActivity(): boolean {
return false; return false;
@ -161,7 +126,7 @@ export class AddonModForumModuleHandlerService implements CoreCourseModuleHandle
{ $a : forum.unreadpostscount }, { $a : forum.unreadpostscount },
) )
: ''; : '';
} catch (error) { } catch {
// Ignore errors. // Ignore errors.
data.extraBadgeColor = ''; data.extraBadgeColor = '';
data.extraBadge = ''; data.extraBadge = '';

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModGlossaryIndexComponent } from '../../components/index/index'; import { AddonModGlossaryIndexComponent } from '../../components/index/index';
@ -25,12 +23,13 @@ import { AddonModGlossaryIndexComponent } from '../../components/index/index';
* Handler to support glossary modules. * Handler to support glossary modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModGlossaryModuleHandlerService implements CoreCourseModuleHandler { export class AddonModGlossaryModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_glossary'; static readonly PAGE_NAME = 'mod_glossary';
name = 'AddonModGlossary'; name = 'AddonModGlossary';
modName = 'glossary'; modName = 'glossary';
protected pageName = AddonModGlossaryModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: false, [CoreConstants.FEATURE_GROUPS]: false,
@ -46,33 +45,6 @@ export class AddonModGlossaryModuleHandlerService implements CoreCourseModuleHan
[CoreConstants.FEATURE_PLAGIARISM]: true, [CoreConstants.FEATURE_PLAGIARISM]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_glossary-handler',
showDownloadButton: true,
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModGlossaryModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModH5PActivityIndexComponent } from '../../components/index'; import { AddonModH5PActivityIndexComponent } from '../../components/index';
import { AddonModH5PActivity } from '../h5pactivity'; import { AddonModH5PActivity } from '../h5pactivity';
@ -26,12 +24,13 @@ import { AddonModH5PActivity } from '../h5pactivity';
* Handler to support H5P activities. * Handler to support H5P activities.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModH5PActivityModuleHandlerService implements CoreCourseModuleHandler { export class AddonModH5PActivityModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_h5pactivity'; static readonly PAGE_NAME = 'mod_h5pactivity';
name = 'AddonModH5PActivity'; name = 'AddonModH5PActivity';
modName = 'h5pactivity'; modName = 'h5pactivity';
protected pageName = AddonModH5PActivityModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -52,27 +51,6 @@ export class AddonModH5PActivityModuleHandlerService implements CoreCourseModule
return AddonModH5PActivity.isPluginEnabled(); return AddonModH5PActivity.isPluginEnabled();
} }
/**
* @inheritdoc
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_h5pactivity-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModH5PActivityModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModImscpIndexComponent } from '../../components/index'; import { AddonModImscpIndexComponent } from '../../components/index';
import { AddonModImscp } from '../imscp'; import { AddonModImscp } from '../imscp';
@ -26,12 +24,13 @@ import { AddonModImscp } from '../imscp';
* Handler to support IMSCP modules. * Handler to support IMSCP modules.
*/ */
@Injectable( { providedIn: 'root' }) @Injectable( { providedIn: 'root' })
export class AddonModImscpModuleHandlerService implements CoreCourseModuleHandler { export class AddonModImscpModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_imscp'; static readonly PAGE_NAME = 'mod_imscp';
name = 'AddonModImscp'; name = 'AddonModImscp';
modName = 'imscp'; modName = 'imscp';
protected pageName = AddonModImscpModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE, [CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
@ -55,27 +54,7 @@ export class AddonModImscpModuleHandlerService implements CoreCourseModuleHandle
/** /**
* @inheritdoc * @inheritdoc
*/ */
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData { async getMainComponent(): Promise<Type<unknown>> {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_imscp-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModImscpModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/**
* @inheritdoc
*/
async getMainComponent(): Promise<Type<unknown> | undefined> {
return AddonModImscpIndexComponent; return AddonModImscpIndexComponent;
} }

View File

@ -14,6 +14,7 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseWSModule } from '@features/course/services/course'; import { CoreCourseWSModule } from '@features/course/services/course';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
@ -22,7 +23,7 @@ import { makeSingleton } from '@singletons';
* Handler to support label modules. * Handler to support label modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModLabelModuleHandlerService implements CoreCourseModuleHandler { export class AddonModLabelModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
name = 'AddonModLabel'; name = 'AddonModLabel';
modName = 'label'; modName = 'label';
@ -40,13 +41,6 @@ export class AddonModLabelModuleHandlerService implements CoreCourseModuleHandle
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/** /**
* @inheritdoc * @inheritdoc
*/ */
@ -57,7 +51,7 @@ export class AddonModLabelModuleHandlerService implements CoreCourseModuleHandle
return { return {
icon: '', icon: '',
title: title, title,
a11yTitle: '', a11yTitle: '',
class: 'addon-mod-label-handler', class: 'addon-mod-label-handler',
}; };

View File

@ -15,24 +15,22 @@
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { AddonModLessonIndexComponent } from '../../components/index'; import { AddonModLessonIndexComponent } from '../../components/index';
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
/** /**
* Handler to support quiz modules. * Handler to support lesson modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModLessonModuleHandlerService implements CoreCourseModuleHandler { export class AddonModLessonModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_lesson'; static readonly PAGE_NAME = 'mod_lesson';
name = 'AddonModLesson'; name = 'AddonModLesson';
modName = 'lesson'; modName = 'lesson';
protected pageName = AddonModLessonModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -47,55 +45,9 @@ export class AddonModLessonModuleHandlerService implements CoreCourseModuleHandl
}; };
/** /**
* Check if the handler is enabled on a site level. * @inheritdoc
*
* @return Promise resolved with boolean: whether or not the handler is enabled on a site level.
*/ */
async isEnabled(): Promise<boolean> { async getMainComponent(): Promise<Type<unknown>> {
return true;
}
/**
* Get the data required to display the module in the course contents view.
*
* @param module The module object.
* @param courseId The course ID.
* @param sectionId The section ID.
* @param forCoursePage Whether the data will be used to render the course page.
* @return Data to render the module.
*/
getData(
module: CoreCourseAnyModuleData,
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
): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_lesson-handler',
showDownloadButton: true,
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModLessonModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/**
* Get the component to render the module. This is needed to support singleactivity course format.
* The component returned must implement CoreCourseModuleMainComponent.
*
* @param course The course object.
* @param module The module object.
* @return The component to use, undefined if not found.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async getMainComponent(course: CoreCourseAnyCourseData, module: CoreCourseWSModule): Promise<Type<unknown> | undefined> {
return AddonModLessonIndexComponent; return AddonModLessonIndexComponent;
} }

View File

@ -16,28 +16,29 @@ import { Injectable, Type } from '@angular/core';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreApp } from '@services/app'; import { CoreApp } from '@services/app';
import { CoreFilepool } from '@services/filepool'; import { CoreFilepool } from '@services/filepool';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { DomSanitizer, makeSingleton } from '@singletons'; import { DomSanitizer, makeSingleton } from '@singletons';
import { AddonModLtiHelper } from '../lti-helper'; import { AddonModLtiHelper } from '../lti-helper';
import { AddonModLti, AddonModLtiProvider } from '../lti'; import { AddonModLti, AddonModLtiProvider } from '../lti';
import { AddonModLtiIndexComponent } from '../../components/index'; import { AddonModLtiIndexComponent } from '../../components/index';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
/** /**
* Handler to support LTI modules. * Handler to support LTI modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler { export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_lti'; static readonly PAGE_NAME = 'mod_lti';
name = 'AddonModLti'; name = 'AddonModLti';
modName = 'lti'; modName = 'lti';
protected pageName = AddonModLtiModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: false, [CoreConstants.FEATURE_GROUPS]: false,
@ -50,42 +51,26 @@ export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/** /**
* @inheritdoc * @inheritdoc
*/ */
getData( getData(
module: CoreCourseAnyModuleData, module: CoreCourseAnyModuleData,
courseId: number, courseId: number,
sectionId?: number,
forCoursePage?: boolean,
): CoreCourseModuleHandlerData { ): CoreCourseModuleHandlerData {
const data = super.getData(module, courseId, sectionId, forCoursePage);
data.showDownloadButton = false;
const data: CoreCourseModuleHandlerData = { data.buttons = [{
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined), icon: 'fas-external-link-alt',
title: module.name, label: 'addon.mod_lti.launchactivity',
class: 'addon-mod_lti-handler', action: (event: Event, module: CoreCourseModule, courseId: number): void => {
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void { // Launch the LTI.
options = options || {}; AddonModLtiHelper.getDataAndLaunch(courseId, module);
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModLtiModuleHandlerService.PAGE_NAME + routeParams, options);
}, },
buttons: [{ }];
icon: 'fas-external-link-alt',
label: 'addon.mod_lti.launchactivity',
action: (event: Event, module: CoreCourseModule, courseId: number): void => {
// Launch the LTI.
AddonModLtiHelper.getDataAndLaunch(courseId, module);
},
}],
};
// Handle custom icons. // Handle custom icons.
CoreUtils.ignoreErrors(this.loadCustomIcon(module, courseId, data)); CoreUtils.ignoreErrors(this.loadCustomIcon(module, courseId, data));
@ -133,7 +118,7 @@ export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler
/** /**
* @inheritdoc * @inheritdoc
*/ */
async getMainComponent(): Promise<Type<unknown> | undefined> { async getMainComponent(): Promise<Type<unknown>> {
return AddonModLtiIndexComponent; return AddonModLtiIndexComponent;
} }

View File

@ -14,24 +14,23 @@
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { AddonModPage } from '../page'; import { AddonModPage } from '../page';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { AddonModPageIndexComponent } from '../../components/index'; import { AddonModPageIndexComponent } from '../../components/index';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
/** /**
* Handler to support page modules. * Handler to support page modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModPageModuleHandlerService implements CoreCourseModuleHandler { export class AddonModPageModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_page'; static readonly PAGE_NAME = 'mod_page';
name = 'AddonModPage'; name = 'AddonModPage';
modName = 'page'; modName = 'page';
protected pageName = AddonModPageModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE, [CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
@ -46,46 +45,16 @@ export class AddonModPageModuleHandlerService implements CoreCourseModuleHandler
}; };
/** /**
* Check if the handler is enabled on a site level. * @inheritdoc
*
* @return Whether or not the handler is enabled on a site level.
*/ */
isEnabled(): Promise<boolean> { isEnabled(): Promise<boolean> {
return AddonModPage.isPluginEnabled(); return AddonModPage.isPluginEnabled();
} }
/** /**
* Get the data required to display the module in the course contents view. * @inheritdoc
*
* @param module The module object.
* @return Data to render the module.
*/ */
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData { async getMainComponent(): Promise<Type<unknown>> {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_page-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModPageModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/**
* Get the component to render the module. This is needed to support singleactivity course format.
* The component returned must implement CoreCourseModuleMainComponent.
*
* @param course The course object.
* @param module The module object.
* @return The component to use, undefined if not found.
*/
async getMainComponent(): Promise<Type<unknown> | undefined> {
return AddonModPageIndexComponent; return AddonModPageIndexComponent;
} }

View File

@ -15,23 +15,22 @@
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { AddonModQuizIndexComponent } from '../../components/index'; import { AddonModQuizIndexComponent } from '../../components/index';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
/** /**
* Handler to support quiz modules. * Handler to support quiz modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModQuizModuleHandlerService implements CoreCourseModuleHandler { export class AddonModQuizModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_quiz'; static readonly PAGE_NAME = 'mod_quiz';
name = 'AddonModQuiz'; name = 'AddonModQuiz';
modName = 'quiz'; modName = 'quiz';
protected pageName = AddonModQuizModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -48,46 +47,7 @@ export class AddonModQuizModuleHandlerService implements CoreCourseModuleHandler
}; };
/** /**
* Check if the handler is enabled on a site level. * @inheritdoc
*
* @return Whether or not the handler is enabled on a site level.
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* Get the data required to display the module in the course contents view.
*
* @param module The module object.
* @param courseId The course ID.
* @param sectionId The section ID.
* @return Data to render the module.
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_quiz-handler',
showDownloadButton: true,
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModQuizModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/**
* Get the component to render the module. This is needed to support singleactivity course format.
* The component returned must implement CoreCourseModuleMainComponent.
*
* @param course The course object.
* @param module The module object.
* @return The component to use, undefined if not found.
*/ */
async getMainComponent(): Promise<Type<unknown>> { async getMainComponent(): Promise<Type<unknown>> {
return AddonModQuizIndexComponent; return AddonModQuizIndexComponent;

View File

@ -14,12 +14,12 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseModuleContentFile } from '@features/course/services/course'; import { CoreCourse, CoreCourseAnyModuleData, CoreCourseModuleContentFile } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate';
import { CoreFileHelper } from '@services/file-helper'; import { CoreFileHelper } from '@services/file-helper';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { CoreMimetypeUtils } from '@services/utils/mimetype'; import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
@ -33,12 +33,13 @@ import { AddonModResourceHelper } from '../resource-helper';
* Handler to support resource modules. * Handler to support resource modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModResourceModuleHandlerService implements CoreCourseModuleHandler { export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_resource'; static readonly PAGE_NAME = 'mod_resource';
name = 'AddonModResource'; name = 'AddonModResource';
modName = 'resource'; modName = 'resource';
protected pageName = AddonModResourceModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE, [CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
@ -60,46 +61,37 @@ export class AddonModResourceModuleHandlerService implements CoreCourseModuleHan
} }
/** /**
* Get the data required to display the module in the course contents view. * @inheritdoc
*
* @param module The module object.
* @param courseId The course ID.
* @param sectionId The section ID.
* @return Data to render the module.
*/ */
getData(module: CoreCourseAnyModuleData, courseId: number): CoreCourseModuleHandlerData { getData(
module: CoreCourseAnyModuleData,
courseId: number,
sectionId?: number,
forCoursePage?: boolean,
): CoreCourseModuleHandlerData {
const updateStatus = (status: string): void => { const updateStatus = (status: string): void => {
handlerData.buttons![0].hidden = status !== CoreConstants.DOWNLOADED || if (!handlerData.buttons) {
return;
}
handlerData.buttons[0].hidden = status !== CoreConstants.DOWNLOADED ||
AddonModResourceHelper.isDisplayedInIframe(module); AddonModResourceHelper.isDisplayedInIframe(module);
}; };
const openWithPicker = CoreFileHelper.defaultIsOpenWithPicker(); const openWithPicker = CoreFileHelper.defaultIsOpenWithPicker();
const handlerData: CoreCourseModuleHandlerData = { const handlerData = super.getData(module, courseId, sectionId, forCoursePage);
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined), handlerData.updateStatus = updateStatus.bind(this);
title: module.name, handlerData.buttons = [{
class: 'addon-mod_resource-handler', hidden: true,
showDownloadButton: true, icon: openWithPicker ? 'fas-share-square' : 'fas-file',
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void { label: module.name + ': ' + Translate.instant(openWithPicker ? 'core.openwith' : 'addon.mod_resource.openthefile'),
options = options || {}; action: async (event: Event, module: CoreCourseModule, courseId: number): Promise<void> => {
options.params = options.params || {}; const hide = await this.hideOpenButton(module, courseId);
Object.assign(options.params, { module }); if (!hide) {
const routeParams = '/' + courseId + '/' + module.id; AddonModResourceHelper.openModuleFile(module, courseId);
}
CoreNavigator.navigateToSitePath(AddonModResourceModuleHandlerService.PAGE_NAME + routeParams, options);
}, },
updateStatus: updateStatus.bind(this), }];
buttons: [{
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<void> => {
const hide = await this.hideOpenButton(module, courseId);
if (!hide) {
AddonModResourceHelper.openModuleFile(module, courseId);
}
},
}],
};
this.getResourceData(module, courseId, handlerData).then((data) => { this.getResourceData(module, courseId, handlerData).then((data) => {
handlerData.icon = data.icon; handlerData.icon = data.icon;
@ -149,7 +141,11 @@ export class AddonModResourceModuleHandlerService implements CoreCourseModuleHan
// Check if the button needs to be shown or not. // Check if the button needs to be shown or not.
promises.push(this.hideOpenButton(module, courseId).then((hideOpenButton) => { promises.push(this.hideOpenButton(module, courseId).then((hideOpenButton) => {
handlerData.buttons![0].hidden = hideOpenButton; if (!handlerData.buttons) {
return;
}
handlerData.buttons[0].hidden = hideOpenButton;
return; return;
})); }));
@ -237,7 +233,7 @@ export class AddonModResourceModuleHandlerService implements CoreCourseModuleHan
// No previously set, just set the icon. // No previously set, just set the icon.
if (resourceData.icon == '') { if (resourceData.icon == '') {
resourceData.icon = CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined); resourceData.icon = CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined);
} }
return resourceData; return resourceData;
@ -246,7 +242,7 @@ export class AddonModResourceModuleHandlerService implements CoreCourseModuleHan
/** /**
* @inheritdoc * @inheritdoc
*/ */
async getMainComponent(): Promise<Type<unknown> | undefined> { async getMainComponent(): Promise<Type<unknown>> {
return AddonModResourceIndexComponent; return AddonModResourceIndexComponent;
} }

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModScormIndexComponent } from '../../components/index'; import { AddonModScormIndexComponent } from '../../components/index';
@ -25,12 +23,13 @@ import { AddonModScormIndexComponent } from '../../components/index';
* Handler to support SCORM modules. * Handler to support SCORM modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModScormModuleHandlerService implements CoreCourseModuleHandler { export class AddonModScormModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_scorm'; static readonly PAGE_NAME = 'mod_scorm';
name = 'AddonModScorm'; name = 'AddonModScorm';
modName = 'scorm'; modName = 'scorm';
protected pageName = AddonModScormModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -44,33 +43,6 @@ export class AddonModScormModuleHandlerService implements CoreCourseModuleHandle
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_scorm-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModScormModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModSurveyIndexComponent } from '../../components/index'; import { AddonModSurveyIndexComponent } from '../../components/index';
@ -25,12 +23,13 @@ import { AddonModSurveyIndexComponent } from '../../components/index';
* Handler to support survey modules. * Handler to support survey modules.
*/ */
@Injectable( { providedIn: 'root' }) @Injectable( { providedIn: 'root' })
export class AddonModSurveyModuleHandlerService implements CoreCourseModuleHandler { export class AddonModSurveyModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_survey'; static readonly PAGE_NAME = 'mod_survey';
name = 'AddonModSurvey'; name = 'AddonModSurvey';
modName = 'survey'; modName = 'survey';
protected pageName = AddonModSurveyModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -44,35 +43,6 @@ export class AddonModSurveyModuleHandlerService implements CoreCourseModuleHandl
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(
module: CoreCourseAnyModuleData,
): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_survey-handler',
showDownloadButton: true,
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModSurveyModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -15,6 +15,7 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper'; import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
@ -30,12 +31,13 @@ import { AddonModUrlHelper } from '../url-helper';
* Handler to support url modules. * Handler to support url modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler { export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_url'; static readonly PAGE_NAME = 'mod_url';
name = 'AddonModUrl'; name = 'AddonModUrl';
modName = 'url'; modName = 'url';
protected pageName = AddonModUrlModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE, [CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
@ -49,13 +51,6 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/** /**
* @inheritdoc * @inheritdoc
*/ */
@ -82,7 +77,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
}; };
const handlerData: CoreCourseModuleHandlerData = { const handlerData: CoreCourseModuleHandlerData = {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined), icon: CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined),
title: module.name, title: module.name,
class: 'addon-mod_url-handler', class: 'addon-mod_url-handler',
showDownloadButton: false, showDownloadButton: false,
@ -117,12 +112,16 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
}; };
this.hideLinkButton(module, courseId).then((hideButton) => { this.hideLinkButton(module, courseId).then((hideButton) => {
handlerData.buttons![0]!.hidden = hideButton; if (!handlerData.buttons) {
return;
}
handlerData.buttons[0].hidden = hideButton;
if (module.contents && module.contents[0]) { if (module.contents && module.contents[0]) {
// Calculate the icon to use. // Calculate the icon to use.
handlerData.icon = AddonModUrl.guessIcon(module.contents[0].fileurl) || handlerData.icon = AddonModUrl.guessIcon(module.contents[0].fileurl) ||
CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined); CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined);
} }
return; return;
@ -154,7 +153,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
/** /**
* @inheritdoc * @inheritdoc
*/ */
async getMainComponent(): Promise<Type<unknown> | undefined> { async getMainComponent(): Promise<Type<unknown>> {
return AddonModUrlIndexComponent; return AddonModUrlIndexComponent;
} }
@ -165,7 +164,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
* @param courseId Course ID. * @param courseId Course ID.
* @return Promise resolved with boolean. * @return Promise resolved with boolean.
*/ */
protected async shouldOpenLink(module: CoreCourseModule, courseId: number): Promise<boolean> { protected async shouldOpenLink(module: CoreCourseModule, courseId?: number): Promise<boolean> {
try { try {
const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName); const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
@ -177,7 +176,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
return true; return true;
} else { } else {
// Not handled by the app, check the display type. // Not handled by the app, check the display type.
const url = await CoreUtils.ignoreErrors(AddonModUrl.getUrl(courseId, module.id)); const url = courseId ? await CoreUtils.ignoreErrors(AddonModUrl.getUrl(courseId, module.id)) : undefined;
const displayType = AddonModUrl.getFinalDisplayType(url); const displayType = AddonModUrl.getFinalDisplayType(url);
return displayType == CoreConstants.RESOURCELIB_DISPLAY_OPEN || return displayType == CoreConstants.RESOURCELIB_DISPLAY_OPEN ||
@ -192,7 +191,7 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
* @inheritdoc * @inheritdoc
*/ */
manualCompletionAlwaysShown(module: CoreCourseModule): Promise<boolean> { manualCompletionAlwaysShown(module: CoreCourseModule): Promise<boolean> {
return this.shouldOpenLink(module, module.course!); return this.shouldOpenLink(module, module.course);
} }
} }

View File

@ -14,6 +14,7 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
@ -25,12 +26,13 @@ import { AddonModWikiIndexComponent } from '../../components/index';
* Handler to support wiki modules. * Handler to support wiki modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModWikiModuleHandlerService implements CoreCourseModuleHandler { export class AddonModWikiModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_wiki'; static readonly PAGE_NAME = 'mod_wiki';
name = 'AddonModWiki'; name = 'AddonModWiki';
modName = 'wiki'; modName = 'wiki';
protected pageName = AddonModWikiModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -45,13 +47,6 @@ export class AddonModWikiModuleHandlerService implements CoreCourseModuleHandler
[CoreConstants.FEATURE_COMMENT]: true, [CoreConstants.FEATURE_COMMENT]: true,
}; };
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/** /**
* @inheritdoc * @inheritdoc
*/ */

View File

@ -14,10 +14,8 @@
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course'; import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
import { CoreCourseModule } from '@features/course/services/course-helper'; import { CoreCourseModuleHandler } from '@features/course/services/module-delegate';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModWorkshopIndexComponent } from '../../components/index'; import { AddonModWorkshopIndexComponent } from '../../components/index';
@ -25,12 +23,13 @@ import { AddonModWorkshopIndexComponent } from '../../components/index';
* Handler to support workshop modules. * Handler to support workshop modules.
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonModWorkshopModuleHandlerService implements CoreCourseModuleHandler { export class AddonModWorkshopModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
static readonly PAGE_NAME = 'mod_workshop'; static readonly PAGE_NAME = 'mod_workshop';
name = 'AddonModWorkshop'; name = 'AddonModWorkshop';
modName = 'workshop'; modName = 'workshop';
protected pageName = AddonModWorkshopModuleHandlerService.PAGE_NAME;
supportedFeatures = { supportedFeatures = {
[CoreConstants.FEATURE_GROUPS]: true, [CoreConstants.FEATURE_GROUPS]: true,
@ -46,30 +45,6 @@ export class AddonModWorkshopModuleHandlerService implements CoreCourseModuleHan
/** /**
* @inheritdoc * @inheritdoc
*/ */
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_workshop-handler',
showDownloadButton: true,
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(AddonModWorkshopModuleHandlerService.PAGE_NAME + routeParams, options);
},
};
}
async getMainComponent(): Promise<Type<unknown>> { async getMainComponent(): Promise<Type<unknown>> {
return AddonModWorkshopIndexComponent; return AddonModWorkshopIndexComponent;
} }

View File

@ -0,0 +1,59 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
import { CoreCourse, CoreCourseAnyModuleData } from '../services/course';
import { CoreCourseModule } from '../services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../services/module-delegate';
/**
* Base module handler to be registered.
*/
export class CoreModuleHandlerBase implements Partial<CoreCourseModuleHandler> {
protected pageName = '';
/**
* @inheritdoc
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* @inheritdoc
*/
getData(
module: CoreCourseAnyModuleData,
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
): CoreCourseModuleHandlerData {
return {
icon: CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined),
title: module.name,
class: 'addon-mod_' + module.modname + '-handler',
showDownloadButton: true,
action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void => {
options = options || {};
options.params = options.params || {};
Object.assign(options.params, { module });
const routeParams = '/' + courseId + '/' + module.id;
CoreNavigator.navigateToSitePath(this.pageName + routeParams, options);
},
};
}
}

View File

@ -1616,7 +1616,7 @@ export class CoreCourseHelperProvider {
this.logger.warn('navCtrl was not passed to navigateToModule by the link handler for ' + module.modname); this.logger.warn('navCtrl was not passed to navigateToModule by the link handler for ' + module.modname);
const params = { const params: Params = {
course: { id: courseId }, course: { id: courseId },
module: module, module: module,
sectionId: sectionId, sectionId: sectionId,

View File

@ -633,9 +633,6 @@ export class CoreCourseProvider {
* @return The IMG src. * @return The IMG src.
*/ */
getModuleIconSrc(moduleName: string, modicon?: string): string { getModuleIconSrc(moduleName: string, modicon?: string): string {
// @TODO: Check modicon url theme to apply other theme icons.
// Use default icon on core themes.
if (this.CORE_MODULES.indexOf(moduleName) < 0) { if (this.CORE_MODULES.indexOf(moduleName) < 0) {
if (modicon) { if (modicon) {
return modicon; return modicon;
@ -644,6 +641,7 @@ export class CoreCourseProvider {
moduleName = 'external-tool'; moduleName = 'external-tool';
} }
// Use default icon on core modules.
return 'assets/img/mod/' + moduleName + '.svg'; return 'assets/img/mod/' + moduleName + '.svg';
} }

View File

@ -16,8 +16,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../module-delegate'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../module-delegate';
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '../course'; import { CoreCourse, CoreCourseAnyModuleData } from '../course';
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
import { CoreCourseModule } from '../course-helper'; import { CoreCourseModule } from '../course-helper';
import { CoreCourseUnsupportedModuleComponent } from '@features/course/components/unsupported-module/unsupported-module'; import { CoreCourseUnsupportedModuleComponent } from '@features/course/components/unsupported-module/unsupported-module';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator'; import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
@ -30,29 +29,20 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
name = 'CoreCourseModuleDefault'; name = 'CoreCourseModuleDefault';
modName = 'default'; modName = 'default';
protected pageName = '';
/** /**
* Whether or not the handler is enabled on a site level. * @inheritdoc
*
* @return True or promise resolved with true if enabled.
*/ */
async isEnabled(): Promise<boolean> { async isEnabled(): Promise<boolean> {
return true; return true;
} }
/** /**
* Get the data required to display the module in the course contents view. * @inheritdoc
*
* @param module The module object.
* @param courseId The course ID.
* @param sectionId The section ID.
* @return Data to render the module.
*/ */
getData( getData(
module: CoreCourseAnyModuleData, module: CoreCourseAnyModuleData,
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
): CoreCourseModuleHandlerData { ): CoreCourseModuleHandlerData {
// Return the default data. // Return the default data.
const defaultData: CoreCourseModuleHandlerData = { const defaultData: CoreCourseModuleHandlerData = {
@ -71,6 +61,8 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
}; };
if ('url' in module && module.url) { if ('url' in module && module.url) {
const url = module.url;
defaultData.buttons = [{ defaultData.buttons = [{
icon: 'fas-external-link-alt', icon: 'fas-external-link-alt',
label: 'core.openinbrowser', label: 'core.openinbrowser',
@ -78,7 +70,7 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
CoreSites.getCurrentSite()!.openInBrowserWithAutoLoginIfSameSite(module.url!); CoreSites.requireCurrentSite().openInBrowserWithAutoLoginIfSameSite(url);
}, },
}]; }];
} }
@ -87,24 +79,14 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
} }
/** /**
* Get the component to render the module. This is needed to support singleactivity course format. * @inheritdoc
* The component returned must implement CoreCourseModuleMainComponent.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @param course The course object.
* @param module The module object.
* @return The component (or promise resolved with component) to use, undefined if not found.
*/ */
// eslint-disable-next-line @typescript-eslint/no-unused-vars async getMainComponent(): Promise<Type<unknown>> {
async getMainComponent(course: CoreCourseAnyCourseData, module: CoreCourseWSModule): Promise<Type<unknown> | undefined> {
return CoreCourseUnsupportedModuleComponent; return CoreCourseUnsupportedModuleComponent;
} }
/** /**
* Whether to display the course refresher in single activity course format. If it returns false, a refresher must be * @inheritdoc
* included in the template that calls the doRefresh method of the component. Defaults to true.
*
* @return Whether the refresher should be displayed.
*/ */
displayRefresherInSingleActivity(): boolean { displayRefresherInSingleActivity(): boolean {
return true; return true;

View File

@ -345,9 +345,10 @@ export class CoreCourseModuleDelegateService extends CoreDelegate<CoreCourseModu
* @param modicon The mod icon string. * @param modicon The mod icon string.
* @return The icon src. * @return The icon src.
*/ */
getModuleIconSrc(modname: string, modicon?: string): string | undefined { getModuleIconSrc(modname: string, modicon?: string): string {
return this.executeFunctionOnEnabled<string>(modname, 'getIconSrc') || return this.executeFunctionOnEnabled<string>(modname, 'getIconSrc') ||
CoreCourse.getModuleIconSrc(modname, modicon); CoreCourse.getModuleIconSrc(modname, modicon) ||
'';
} }
/** /**