MOBILE-3095 core: Make easier to support label site plugins
parent
ec2a93adc1
commit
82eded5e5f
|
@ -69,7 +69,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
|
||||||
future: 'show',
|
future: 'show',
|
||||||
favourite: 'show',
|
favourite: 'show',
|
||||||
hidden: 'show',
|
hidden: 'show',
|
||||||
custom: 'hidden', // True or false to show or hide.
|
custom: 'hidden',
|
||||||
};
|
};
|
||||||
showFilter = false;
|
showFilter = false;
|
||||||
showSelectorFilter = false;
|
showSelectorFilter = false;
|
||||||
|
|
|
@ -82,7 +82,7 @@ export class AddonBlockSiteMainMenuComponent extends CoreBlockBaseComponent impl
|
||||||
|
|
||||||
if (this.mainMenuBlock) {
|
if (this.mainMenuBlock) {
|
||||||
this.mainMenuBlock.hasContent = this.courseHelper.sectionHasContent(this.mainMenuBlock);
|
this.mainMenuBlock.hasContent = this.courseHelper.sectionHasContent(this.mainMenuBlock);
|
||||||
this.courseHelper.addHandlerDataForModules([this.mainMenuBlock], this.siteHomeId);
|
this.courseHelper.addHandlerDataForModules([this.mainMenuBlock], this.siteHomeId, undefined, undefined, true);
|
||||||
|
|
||||||
// Check if Site Home displays announcements. If so, remove it from the main menu block.
|
// Check if Site Home displays announcements. If so, remove it from the main menu block.
|
||||||
const currentSite = this.sitesProvider.getCurrentSite(),
|
const currentSite = this.sitesProvider.getCurrentSite(),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<ion-item *ngIf="module && module.visibleoncoursepage !== 0" text-wrap id="core-course-module-{{module.id}}" class="core-course-module-handler {{module.handlerData.class}}" (click)="moduleClicked($event)" [ngClass]="{'item-media': module.handlerData.icon, 'core-not-clickable': !module.handlerData.action || module.uservisible === false, 'item-dimmed': module.visible === 0 || module.uservisible === false}" [title]="module.handlerData.a11yTitle" detail-none>
|
<ion-item *ngIf="module && module.visibleoncoursepage !== 0 && !module.handlerData.loading" text-wrap id="core-course-module-{{module.id}}" class="core-course-module-handler {{module.handlerData.class}}" (click)="moduleClicked($event)" [ngClass]="{'item-media': module.handlerData.icon, 'core-not-clickable': !module.handlerData.action || module.uservisible === false, 'item-dimmed': module.visible === 0 || module.uservisible === false}" [title]="module.handlerData.a11yTitle" detail-none>
|
||||||
|
|
||||||
<img item-start *ngIf="module.handlerData.icon" [src]="module.handlerData.icon" [alt]="module.modnametranslated" class="core-module-icon">
|
<img item-start *ngIf="module.handlerData.icon" [src]="module.handlerData.icon" [alt]="module.modnametranslated" class="core-module-icon">
|
||||||
<div class="core-module-title">
|
<div class="core-module-title">
|
||||||
|
@ -33,3 +33,8 @@
|
||||||
</div>
|
</div>
|
||||||
<core-format-text class="core-module-description" *ngIf="module.description" maxHeight="80" [text]="module.description" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text>
|
<core-format-text class="core-module-description" *ngIf="module.description" maxHeight="80" [text]="module.description" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
|
<!-- Loading. -->
|
||||||
|
<ion-item *ngIf="module && module.visibleoncoursepage !== 0 && module.handlerData.loading" role="status" text-wrap id="core-course-module-{{module.id}}" [ngClass]="['core-course-module-handler', 'core-module-loading', module.handlerData.class]" [title]="module.handlerData.a11yTitle" detail-none>
|
||||||
|
<ion-spinner></ion-spinner>
|
||||||
|
</ion-item>
|
||||||
|
|
|
@ -87,6 +87,16 @@ ion-app.app-root core-course-module {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.core-module-loading {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
clear: both;
|
||||||
|
@include darkmode() {
|
||||||
|
color: $core-dark-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@include darkmode() {
|
@include darkmode() {
|
||||||
.item.core-course-module-handler {
|
.item.core-course-module-handler {
|
||||||
background: $core-dark-item-bg-color;
|
background: $core-dark-item-bg-color;
|
||||||
|
|
|
@ -259,7 +259,8 @@ export class CoreCourseSectionPage implements OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise.then((completionStatus) => {
|
return promise.then((completionStatus) => {
|
||||||
this.courseHelper.addHandlerDataForModules(sections, this.course.id, completionStatus, this.course.fullname);
|
this.courseHelper.addHandlerDataForModules(sections, this.course.id, completionStatus, this.course.fullname,
|
||||||
|
true);
|
||||||
|
|
||||||
// Format the name of each section and check if it has content.
|
// Format the name of each section and check if it has content.
|
||||||
this.sections = sections.map((section) => {
|
this.sections = sections.map((section) => {
|
||||||
|
|
|
@ -143,9 +143,12 @@ export class CoreCourseHelperProvider {
|
||||||
* @param courseId Course ID of the modules.
|
* @param courseId Course ID of the modules.
|
||||||
* @param completionStatus List of completion status.
|
* @param completionStatus List of completion status.
|
||||||
* @param courseName Course name. Recommended if completionStatus is supplied.
|
* @param courseName Course name. Recommended if completionStatus is supplied.
|
||||||
|
* @param forCoursePage Whether the data will be used to render the course page.
|
||||||
* @return Whether the sections have content.
|
* @return Whether the sections have content.
|
||||||
*/
|
*/
|
||||||
addHandlerDataForModules(sections: any[], courseId: number, completionStatus?: any, courseName?: string): boolean {
|
addHandlerDataForModules(sections: any[], courseId: number, completionStatus?: any, courseName?: string,
|
||||||
|
forCoursePage?: boolean): boolean {
|
||||||
|
|
||||||
let hasContent = false;
|
let hasContent = false;
|
||||||
|
|
||||||
sections.forEach((section) => {
|
sections.forEach((section) => {
|
||||||
|
@ -156,7 +159,8 @@ export class CoreCourseHelperProvider {
|
||||||
hasContent = true;
|
hasContent = true;
|
||||||
|
|
||||||
section.modules.forEach((module) => {
|
section.modules.forEach((module) => {
|
||||||
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, courseId, section.id);
|
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, courseId, section.id,
|
||||||
|
forCoursePage);
|
||||||
|
|
||||||
if (module.completiondata && module.completion > 0) {
|
if (module.completiondata && module.completion > 0) {
|
||||||
module.completiondata.courseId = courseId;
|
module.completiondata.courseId = courseId;
|
||||||
|
@ -1197,7 +1201,7 @@ export class CoreCourseHelperProvider {
|
||||||
// Get the module.
|
// Get the module.
|
||||||
return this.courseProvider.getModule(moduleId, courseId, sectionId, false, false, siteId, modName);
|
return this.courseProvider.getModule(moduleId, courseId, sectionId, false, false, siteId, modName);
|
||||||
}).then((module) => {
|
}).then((module) => {
|
||||||
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, courseId, sectionId);
|
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, courseId, sectionId, false);
|
||||||
|
|
||||||
if (navCtrl && module.handlerData && module.handlerData.action) {
|
if (navCtrl && module.handlerData && module.handlerData.action) {
|
||||||
// If the link handler for this module passed through navCtrl, we can use the module's handler to navigate cleanly.
|
// If the link handler for this module passed through navCtrl, we can use the module's handler to navigate cleanly.
|
||||||
|
@ -1246,7 +1250,7 @@ export class CoreCourseHelperProvider {
|
||||||
*/
|
*/
|
||||||
openModule(navCtrl: NavController, module: any, courseId: number, sectionId?: number, modParams?: any): boolean {
|
openModule(navCtrl: NavController, module: any, courseId: number, sectionId?: number, modParams?: any): boolean {
|
||||||
if (!module.handlerData) {
|
if (!module.handlerData) {
|
||||||
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, courseId, sectionId);
|
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, courseId, sectionId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module.handlerData && module.handlerData.action) {
|
if (module.handlerData && module.handlerData.action) {
|
||||||
|
|
|
@ -45,9 +45,10 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler {
|
||||||
* @param module The module object.
|
* @param module The module object.
|
||||||
* @param courseId The course ID.
|
* @param courseId The course ID.
|
||||||
* @param sectionId The section 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.
|
* @return Data to render the module.
|
||||||
*/
|
*/
|
||||||
getData(module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData;
|
getData(module: any, courseId: number, sectionId: number, forCoursePage: boolean): CoreCourseModuleHandlerData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
* Get the component to render the module. This is needed to support singleactivity course format.
|
||||||
|
@ -133,10 +134,15 @@ export interface CoreCourseModuleHandlerData {
|
||||||
buttons?: CoreCourseModuleHandlerButton[];
|
buttons?: CoreCourseModuleHandlerButton[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to display a spinner in the module item.
|
* Whether to display a spinner where the download button is displayed. The module icon, title, etc. will be displayed.
|
||||||
*/
|
*/
|
||||||
spinner?: boolean;
|
spinner?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the data is being loaded. If true, it will display a spinner in the whole module, nothing else will be shown.
|
||||||
|
*/
|
||||||
|
loading?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to perform when the module is clicked.
|
* Action to perform when the module is clicked.
|
||||||
*
|
*
|
||||||
|
@ -251,10 +257,12 @@ export class CoreCourseModuleDelegate extends CoreDelegate {
|
||||||
* @param module The module object.
|
* @param module The module object.
|
||||||
* @param courseId The course ID.
|
* @param courseId The course ID.
|
||||||
* @param sectionId The section 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.
|
* @return Data to render the module.
|
||||||
*/
|
*/
|
||||||
getModuleDataFor(modname: string, module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData {
|
getModuleDataFor(modname: string, module: any, courseId: number, sectionId: number, forCoursePage?: boolean)
|
||||||
return this.executeFunctionOnEnabled(modname, 'getData', [module, courseId, sectionId]);
|
: CoreCourseModuleHandlerData {
|
||||||
|
return this.executeFunctionOnEnabled(modname, 'getData', [module, courseId, sectionId, forCoursePage]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -134,7 +134,8 @@ export class CoreSiteHomeIndexComponent implements OnInit {
|
||||||
this.section = config.numsections ? sections.find((section) => section.section == 1) : false;
|
this.section = config.numsections ? sections.find((section) => section.section == 1) : false;
|
||||||
if (this.section) {
|
if (this.section) {
|
||||||
this.section.hasContent = this.courseHelper.sectionHasContent(this.section);
|
this.section.hasContent = this.courseHelper.sectionHasContent(this.section);
|
||||||
this.hasContent = this.courseHelper.addHandlerDataForModules([this.section], this.siteHomeId) || this.hasContent;
|
this.hasContent = this.courseHelper.addHandlerDataForModules([this.section], this.siteHomeId, undefined,
|
||||||
|
undefined, true) || this.hasContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add log in Moodle.
|
// Add log in Moodle.
|
||||||
|
|
|
@ -53,7 +53,7 @@ export class CoreSiteHomeNewsComponent implements OnInit {
|
||||||
return this.courseProvider.getModuleBasicInfo(forum.cmid).then((module) => {
|
return this.courseProvider.getModuleBasicInfo(forum.cmid).then((module) => {
|
||||||
this.show = true;
|
this.show = true;
|
||||||
this.module = module;
|
this.module = module;
|
||||||
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, siteHomeId, module.section);
|
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, siteHomeId, module.section, true);
|
||||||
});
|
});
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
|
|
|
@ -14,9 +14,11 @@
|
||||||
|
|
||||||
import { Injector } from '@angular/core';
|
import { Injector } from '@angular/core';
|
||||||
import { NavController, NavOptions } from 'ionic-angular';
|
import { NavController, NavOptions } from 'ionic-angular';
|
||||||
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate';
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate';
|
||||||
import { CoreSitePluginsBaseHandler } from './base-handler';
|
import { CoreSitePluginsBaseHandler } from './base-handler';
|
||||||
import { CoreSitePluginsModuleIndexComponent } from '../../components/module-index/module-index';
|
import { CoreSitePluginsModuleIndexComponent } from '../../components/module-index/module-index';
|
||||||
|
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to support a module using a site plugin.
|
* Handler to support a module using a site plugin.
|
||||||
|
@ -26,9 +28,18 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp
|
||||||
supportedFeatures: {[name: string]: any};
|
supportedFeatures: {[name: string]: any};
|
||||||
supportsFeature: (feature: string) => any;
|
supportsFeature: (feature: string) => any;
|
||||||
|
|
||||||
constructor(name: string, public modName: string, protected handlerSchema: any, protected initResult: any) {
|
protected logger: any;
|
||||||
|
|
||||||
|
constructor(name: string,
|
||||||
|
public modName: string,
|
||||||
|
protected plugin: any,
|
||||||
|
protected handlerSchema: any,
|
||||||
|
protected initResult: any,
|
||||||
|
protected sitePluginsProvider: CoreSitePluginsProvider,
|
||||||
|
loggerProvider: CoreLoggerProvider) {
|
||||||
super(name);
|
super(name);
|
||||||
|
|
||||||
|
this.logger = loggerProvider.getInstance('CoreSitePluginsModuleHandler');
|
||||||
this.supportedFeatures = handlerSchema.supportedfeatures;
|
this.supportedFeatures = handlerSchema.supportedfeatures;
|
||||||
|
|
||||||
if (initResult && initResult.jsResult && initResult.jsResult.supportsFeature) {
|
if (initResult && initResult.jsResult && initResult.jsResult.supportsFeature) {
|
||||||
|
@ -43,18 +54,38 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp
|
||||||
* @param module The module object.
|
* @param module The module object.
|
||||||
* @param courseId The course ID.
|
* @param courseId The course ID.
|
||||||
* @param sectionId The section 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.
|
* @return Data to render the module.
|
||||||
*/
|
*/
|
||||||
getData(module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData {
|
getData(module: any, courseId: number, sectionId: number, forCoursePage: boolean): CoreCourseModuleHandlerData {
|
||||||
const hasOffline = !!(this.handlerSchema.offlinefunctions && Object.keys(this.handlerSchema.offlinefunctions).length),
|
const callMethod = forCoursePage && this.handlerSchema.coursepagemethod;
|
||||||
showDowloadButton = this.handlerSchema.downloadbutton;
|
|
||||||
|
if (module.noviewlink && !callMethod) {
|
||||||
|
// The module doesn't link to a new page (similar to label). Only display the description.
|
||||||
|
const title = module.description;
|
||||||
|
module.description = '';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
icon: this.handlerSchema.displaydata.icon,
|
||||||
|
title: title,
|
||||||
|
a11yTitle: '',
|
||||||
|
class: this.handlerSchema.displaydata.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasOffline = !!(this.handlerSchema.offlinefunctions && Object.keys(this.handlerSchema.offlinefunctions).length),
|
||||||
|
showDowloadButton = this.handlerSchema.downloadbutton,
|
||||||
|
handlerData: CoreCourseModuleHandlerData = {
|
||||||
title: module.name,
|
title: module.name,
|
||||||
icon: this.handlerSchema.displaydata.icon,
|
icon: this.handlerSchema.displaydata.icon,
|
||||||
class: this.handlerSchema.displaydata.class,
|
class: this.handlerSchema.displaydata.class,
|
||||||
showDownloadButton: typeof showDowloadButton != 'undefined' ? showDowloadButton : hasOffline,
|
showDownloadButton: typeof showDowloadButton != 'undefined' ? showDowloadButton : hasOffline,
|
||||||
action: (event: Event, navCtrl: NavController, module: any, courseId: number, options: NavOptions): void => {
|
};
|
||||||
|
|
||||||
|
if (this.handlerSchema.method) {
|
||||||
|
// There is a method, add an action.
|
||||||
|
handlerData.action = (event: Event, navCtrl: NavController, module: any, courseId: number, options: NavOptions)
|
||||||
|
: void => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
|
@ -63,10 +94,32 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp
|
||||||
module: module,
|
module: module,
|
||||||
courseId: courseId
|
courseId: courseId
|
||||||
}, options);
|
}, options);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (callMethod && module.visibleoncoursepage !== 0) {
|
||||||
|
// Call the method to get the course page template.
|
||||||
|
handlerData.loading = true;
|
||||||
|
|
||||||
|
const args = {
|
||||||
|
courseid: courseId,
|
||||||
|
cmid: module.id
|
||||||
|
};
|
||||||
|
|
||||||
|
this.sitePluginsProvider.getContent(this.plugin.component, this.handlerSchema.coursepagemethod, args).then((result) => {
|
||||||
|
// Use the html returned.
|
||||||
|
handlerData.title = result.templates && result.templates[0] ? result.templates[0].html : '';
|
||||||
|
module.description = '';
|
||||||
|
}).catch((error) => {
|
||||||
|
this.logger.error('Error calling course page method:', error);
|
||||||
|
}).finally(() => {
|
||||||
|
handlerData.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return handlerData;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the icon src for the module.
|
* Get the icon src for the module.
|
||||||
*
|
*
|
||||||
|
|
|
@ -85,7 +85,7 @@ export class CoreSitePluginsHelperProvider {
|
||||||
protected logger;
|
protected logger;
|
||||||
protected courseRestrictHandlers = {};
|
protected courseRestrictHandlers = {};
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider,
|
constructor(protected loggerProvider: CoreLoggerProvider,
|
||||||
private sitesProvider: CoreSitesProvider,
|
private sitesProvider: CoreSitesProvider,
|
||||||
private domUtils: CoreDomUtilsProvider,
|
private domUtils: CoreDomUtilsProvider,
|
||||||
private mainMenuDelegate: CoreMainMenuDelegate,
|
private mainMenuDelegate: CoreMainMenuDelegate,
|
||||||
|
@ -119,7 +119,7 @@ export class CoreSitePluginsHelperProvider {
|
||||||
private blockDelegate: CoreBlockDelegate,
|
private blockDelegate: CoreBlockDelegate,
|
||||||
private filterHelper: CoreFilterHelperProvider) {
|
private filterHelper: CoreFilterHelperProvider) {
|
||||||
|
|
||||||
this.logger = logger.getInstance('CoreSitePluginsHelperProvider');
|
this.logger = loggerProvider.getInstance('CoreSitePluginsHelperProvider');
|
||||||
|
|
||||||
// Fetch the plugins on login.
|
// Fetch the plugins on login.
|
||||||
eventsProvider.on(CoreEventsProvider.LOGIN, (data) => {
|
eventsProvider.on(CoreEventsProvider.LOGIN, (data) => {
|
||||||
|
@ -834,7 +834,8 @@ export class CoreSitePluginsHelperProvider {
|
||||||
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
|
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
|
||||||
modName = (handlerSchema.moodlecomponent || plugin.component).replace('mod_', '');
|
modName = (handlerSchema.moodlecomponent || plugin.component).replace('mod_', '');
|
||||||
|
|
||||||
this.moduleDelegate.registerHandler(new CoreSitePluginsModuleHandler(uniqueName, modName, handlerSchema, initResult));
|
this.moduleDelegate.registerHandler(new CoreSitePluginsModuleHandler(uniqueName, modName, plugin, handlerSchema,
|
||||||
|
initResult, this.sitePluginsProvider, this.loggerProvider));
|
||||||
|
|
||||||
if (handlerSchema.offlinefunctions && Object.keys(handlerSchema.offlinefunctions).length) {
|
if (handlerSchema.offlinefunctions && Object.keys(handlerSchema.offlinefunctions).length) {
|
||||||
// Register the prefetch handler.
|
// Register the prefetch handler.
|
||||||
|
|
Loading…
Reference in New Issue