commit
bc71bbbdfc
|
@ -82,7 +82,7 @@ export interface AddonMessageOutputHandlerData {
|
|||
|
||||
constructor(protected loggerProvider: CoreLoggerProvider, protected sitesProvider: CoreSitesProvider,
|
||||
protected eventsProvider: CoreEventsProvider) {
|
||||
super('CoreSettingsDelegate', loggerProvider, sitesProvider, eventsProvider);
|
||||
super('AddonMessageOutputDelegate', loggerProvider, sitesProvider, eventsProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -129,7 +129,7 @@ export class AddonMessagesMainMenuHandler implements CoreMainMenuHandler, CoreCr
|
|||
*/
|
||||
execute(siteId?: string): Promise<any> {
|
||||
if (this.sitesProvider.isCurrentSite(siteId)) {
|
||||
this.eventsProvider.trigger(AddonMessagesProvider.READ_CRON_EVENT, undefined, siteId);
|
||||
this.eventsProvider.trigger(AddonMessagesProvider.READ_CRON_EVENT, {}, siteId);
|
||||
}
|
||||
|
||||
if (this.appProvider.isDesktop() && this.localNotificationsProvider.isAvailable()) {
|
||||
|
|
|
@ -58,11 +58,12 @@ export class AddonMessagesSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
/**
|
||||
* Get all messages pending to be sent in the site.
|
||||
* @param {boolean} [onlyDeviceOffline=false] True to only sync discussions that failed because device was offline,
|
||||
* @param {string} [siteId] Site ID to sync. If not defined, sync all sites.
|
||||
* @param {Promise<any>} Promise resolved if sync is successful, rejected if sync fails.
|
||||
*
|
||||
* @param {string} [siteId] Site ID to sync. If not defined, sync all sites.
|
||||
* @param {boolean} [onlyDeviceOffline=false] True to only sync discussions that failed because device was offline.
|
||||
* @param {Promise<any>} Promise resolved if sync is successful, rejected if sync fails.
|
||||
*/
|
||||
protected syncAllDiscussionsFunc(onlyDeviceOffline: boolean = false, siteId?: string): Promise<any> {
|
||||
protected syncAllDiscussionsFunc(siteId?: string, onlyDeviceOffline: boolean = false): Promise<any> {
|
||||
const promise = onlyDeviceOffline ?
|
||||
this.messagesOffline.getAllDeviceOfflineMessages(siteId) :
|
||||
this.messagesOffline.getAllMessages(siteId);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModAssignFeedbackHandler } from './feedback-delegate';
|
||||
|
||||
|
@ -24,7 +24,43 @@ export class AddonModAssignDefaultFeedbackHandler implements AddonModAssignFeedb
|
|||
name = 'AddonModAssignDefaultFeedbackHandler';
|
||||
type = 'default';
|
||||
|
||||
constructor(private translate: TranslateService) { }
|
||||
constructor(protected translate: TranslateService) { }
|
||||
|
||||
/**
|
||||
* Discard the draft data of the feedback plugin.
|
||||
*
|
||||
* @param {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
discardDraft(assignId: number, userId: number, siteId?: string): void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any): any | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the draft saved data of the feedback plugin.
|
||||
*
|
||||
* @param {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {any|Promise<any>} Data (or promise resolved with the data).
|
||||
*/
|
||||
getDraft(assignId: number, userId: number, siteId?: string): any | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files used by this plugin.
|
||||
|
@ -95,4 +131,46 @@ export class AddonModAssignDefaultFeedbackHandler implements AddonModAssignFeedb
|
|||
isEnabled(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch any required data for the plugin.
|
||||
* This should NOT prefetch files. Files to be prefetched should be returned by the getPluginFiles function.
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} submission The submission.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and add to pluginData the data to send to the server based on the draft data saved.
|
||||
*
|
||||
* @param {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} pluginData Object where to store the data to send.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
prepareFeedbackData(assignId: number, userId: number, plugin: any, pluginData: any, siteId?: string): void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Save draft data of the feedback plugin.
|
||||
*
|
||||
* @param {number} assignId The assignment ID.
|
||||
* @param {number} userId User ID.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} data The data to save.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
saveDraft(assignId: number, userId: number, plugin: any, data: any, siteId?: string): void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModAssignSubmissionHandler } from './submission-delegate';
|
||||
|
||||
|
@ -24,7 +24,7 @@ export class AddonModAssignDefaultSubmissionHandler implements AddonModAssignSub
|
|||
name = 'AddonModAssignDefaultSubmissionHandler';
|
||||
type = 'default';
|
||||
|
||||
constructor(private translate: TranslateService) { }
|
||||
constructor(protected translate: TranslateService) { }
|
||||
|
||||
/**
|
||||
* Whether the plugin can be edited in offline for existing submissions. In general, this should return false if the
|
||||
|
@ -40,6 +40,60 @@ export class AddonModAssignDefaultSubmissionHandler implements AddonModAssignSub
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should clear temporary data for a cancelled submission.
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} submission The submission.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} inputData Data entered by the user for the submission.
|
||||
*/
|
||||
clearTmpData(assign: any, submission: any, plugin: any, inputData: any): void {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will be called when the user wants to create a new submission based on the previous one.
|
||||
* It should add to pluginData the data to send to server based in the data in plugin (previous attempt).
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} pluginData Object where to store the data to send.
|
||||
* @param {number} [userId] User ID. If not defined, site's current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
copySubmissionData(assign: any, plugin: any, pluginData: any, userId?: number, siteId?: string): void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete any stored data for the plugin and submission.
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} submission The submission.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} offlineData Offline data stored.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
deleteOfflineData(assign: any, submission: any, plugin: any, offlineData: any, siteId?: string): void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data, either in read or in edit mode.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {boolean} [edit] Whether the user is editing.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any, edit?: boolean): any | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files used by this plugin.
|
||||
* The files returned by this function will be prefetched when the user prefetches the assign.
|
||||
|
@ -127,4 +181,53 @@ export class AddonModAssignDefaultSubmissionHandler implements AddonModAssignSub
|
|||
isEnabledForEdit(): boolean | Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch any required data for the plugin.
|
||||
* This should NOT prefetch files. Files to be prefetched should be returned by the getPluginFiles function.
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} submission The submission.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and add to pluginData the data to send to the server based on the input data.
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} submission The submission.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} inputData Data entered by the user for the submission.
|
||||
* @param {any} pluginData Object where to store the data to send.
|
||||
* @param {boolean} [offline] Whether the user is editing in offline.
|
||||
* @param {number} [userId] User ID. If not defined, site's current user.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
prepareSubmissionData?(assign: any, submission: any, plugin: any, inputData: any, pluginData: any, offline?: boolean,
|
||||
userId?: number, siteId?: string): void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and add to pluginData the data to send to the server based on the offline data stored.
|
||||
* This will be used when performing a synchronization.
|
||||
*
|
||||
* @param {any} assign The assignment.
|
||||
* @param {any} submission The submission.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {any} offlineData Offline data stored.
|
||||
* @param {any} pluginData Object where to store the data to send.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} If the function is async, it should return a Promise resolved when done.
|
||||
*/
|
||||
prepareSyncData?(assign: any, submission: any, plugin: any, offlineData: any, pluginData: any, siteId?: string)
|
||||
: void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import { FormGroup, FormBuilder } from '@angular/forms';
|
|||
})
|
||||
export class AddonModQuizAccessOfflineAttemptsComponent implements OnInit {
|
||||
|
||||
@Input() rule: string; // The name of the rule.
|
||||
@Input() quiz: any; // The quiz the rule belongs to.
|
||||
@Input() attempt: any; // The attempt being started/continued.
|
||||
@Input() prefetch: boolean; // Whether the user is prefetching the quiz.
|
||||
|
|
|
@ -24,6 +24,7 @@ import { FormGroup, FormBuilder } from '@angular/forms';
|
|||
})
|
||||
export class AddonModQuizAccessPasswordComponent implements OnInit {
|
||||
|
||||
@Input() rule: string; // The name of the rule.
|
||||
@Input() quiz: any; // The quiz the rule belongs to.
|
||||
@Input() attempt: any; // The attempt being started/continued.
|
||||
@Input() prefetch: boolean; // Whether the user is prefetching the quiz.
|
||||
|
|
|
@ -24,6 +24,7 @@ import { FormGroup } from '@angular/forms';
|
|||
})
|
||||
export class AddonModQuizAccessTimeLimitComponent {
|
||||
|
||||
@Input() rule: string; // The name of the rule.
|
||||
@Input() quiz: any; // The quiz the rule belongs to.
|
||||
@Input() attempt: any; // The attempt being started/continued.
|
||||
@Input() prefetch: boolean; // Whether the user is prefetching the quiz.
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
<core-loading [hideUntil]="loaded">
|
||||
<form ion-list [formGroup]="preflightForm" (ngSubmit)="sendData()">
|
||||
<!-- Access rules. -->
|
||||
<ng-container *ngFor="let componentClass of accessRulesComponent; let last = last">
|
||||
<core-dynamic-component [component]="componentClass" [data]="data">
|
||||
<ng-container *ngFor="let data of accessRulesData; let last = last">
|
||||
<core-dynamic-component [component]="data.component" [data]="data.data">
|
||||
<p padding>Couldn't find the directive to render this access rule.</p>
|
||||
</core-dynamic-component>
|
||||
<ion-item-divider color="light" *ngIf="!last"></ion-item-divider>
|
||||
|
|
|
@ -34,8 +34,7 @@ export class AddonModQuizPreflightModalPage implements OnInit {
|
|||
|
||||
preflightForm: FormGroup;
|
||||
title: string;
|
||||
accessRulesComponent: any[] = [];
|
||||
data: any;
|
||||
accessRulesData: {component: any, data: any}[] = []; // Components and data for each access rule.
|
||||
loaded: boolean;
|
||||
|
||||
protected quiz: any;
|
||||
|
@ -43,7 +42,6 @@ export class AddonModQuizPreflightModalPage implements OnInit {
|
|||
protected prefetch: boolean;
|
||||
protected siteId: string;
|
||||
protected rules: string[];
|
||||
protected renderedRules: string[] = [];
|
||||
|
||||
constructor(params: NavParams, fb: FormBuilder, translate: TranslateService, sitesProvider: CoreSitesProvider,
|
||||
protected viewCtrl: ViewController, protected accessRuleDelegate: AddonModQuizAccessRuleDelegate,
|
||||
|
@ -58,15 +56,6 @@ export class AddonModQuizPreflightModalPage implements OnInit {
|
|||
|
||||
// Create an empty form group. The controls will be added by the access rules components.
|
||||
this.preflightForm = fb.group({});
|
||||
|
||||
// Create the data to pass to the access rules components.
|
||||
this.data = {
|
||||
quiz: this.quiz,
|
||||
attempt: this.attempt,
|
||||
prefetch: this.prefetch,
|
||||
form: this.preflightForm,
|
||||
siteId: this.siteId
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,8 +72,17 @@ export class AddonModQuizPreflightModalPage implements OnInit {
|
|||
if (required) {
|
||||
return this.accessRuleDelegate.getPreflightComponent(rule, this.injector).then((component) => {
|
||||
if (component) {
|
||||
this.renderedRules.push(rule);
|
||||
this.accessRulesComponent.push(component);
|
||||
this.accessRulesData.push({
|
||||
component: component,
|
||||
data: {
|
||||
rule: rule,
|
||||
quiz: this.quiz,
|
||||
attempt: this.attempt,
|
||||
prefetch: this.prefetch,
|
||||
form: this.preflightForm,
|
||||
siteId: this.siteId
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -264,6 +264,11 @@ export class AddonPushNotificationsProvider {
|
|||
return previous + parseInt(counter, 10);
|
||||
}, 0);
|
||||
|
||||
if (!this.appProvider.isDesktop() && !this.appProvider.isMobile()) {
|
||||
// Browser doesn't have an app badge, stop.
|
||||
return total;
|
||||
}
|
||||
|
||||
// Set the app badge.
|
||||
return this.badge.set(total).then(() => {
|
||||
return total;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourHandler } from '@core/question/providers/behaviour-delegate';
|
||||
import { CoreQuestionHelperProvider } from '@core/question/providers/helper';
|
||||
|
||||
|
@ -34,11 +34,12 @@ export class AddonQbehaviourAdaptiveHandler implements CoreQuestionBehaviourHand
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(question: any): any[] | Promise<any[]> {
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
// Just extract the button, it doesn't need any specific component.
|
||||
this.questionHelper.extractQbehaviourButtons(question);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourHandler } from '@core/question/providers/behaviour-delegate';
|
||||
import { CoreQuestionHelperProvider } from '@core/question/providers/helper';
|
||||
|
||||
|
@ -34,11 +34,12 @@ export class AddonQbehaviourAdaptiveNoPenaltyHandler implements CoreQuestionBeha
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(question: any): any[] | Promise<any[]> {
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
// Just extract the button, it doesn't need any specific component.
|
||||
this.questionHelper.extractQbehaviourButtons(question);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input, EventEmitter } from '@angular/core';
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Component to render the deferred CBM in a question.
|
||||
|
@ -27,8 +27,8 @@ export class AddonQbehaviourDeferredCBMComponent {
|
|||
@Input() componentId: number; // ID of the component the question belongs to.
|
||||
@Input() attemptId: number; // Attempt ID.
|
||||
@Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
|
||||
@Input() buttonClicked: EventEmitter<any>; // Should emit an event when a behaviour button is clicked.
|
||||
@Input() onAbort: EventEmitter<void>; // Should emit an event if the question should be aborted.
|
||||
@Output() buttonClicked: EventEmitter<any>; // Should emit an event when a behaviour button is clicked.
|
||||
@Output() onAbort: EventEmitter<void>; // Should emit an event if the question should be aborted.
|
||||
|
||||
constructor() {
|
||||
// Nothing to do.
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourHandler } from '@core/question/providers/behaviour-delegate';
|
||||
import { CoreQuestionDelegate } from '@core/question/providers/delegate';
|
||||
import { CoreQuestionState } from '@core/question/providers/question';
|
||||
|
@ -55,11 +55,12 @@ export class AddonQbehaviourDeferredCBMHandler implements CoreQuestionBehaviourH
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(question: any): any[] | Promise<any[]> {
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
if (this.questionHelper.extractQbehaviourCBM(question)) {
|
||||
return [AddonQbehaviourDeferredCBMComponent];
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourHandler } from '@core/question/providers/behaviour-delegate';
|
||||
import { CoreQuestionHelperProvider } from '@core/question/providers/helper';
|
||||
import { AddonQbehaviourDeferredCBMComponent } from '@addon/qbehaviour/deferredcbm/component/deferredcbm';
|
||||
|
@ -35,11 +35,12 @@ export class AddonQbehaviourImmediateCBMHandler implements CoreQuestionBehaviour
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(question: any): any[] | Promise<any[]> {
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
// Just extract the button, it doesn't need any specific component.
|
||||
this.questionHelper.extractQbehaviourButtons(question);
|
||||
if (this.questionHelper.extractQbehaviourCBM(question)) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourHandler } from '@core/question/providers/behaviour-delegate';
|
||||
import { CoreQuestionHelperProvider } from '@core/question/providers/helper';
|
||||
|
||||
|
@ -34,11 +34,12 @@ export class AddonQbehaviourImmediateFeedbackHandler implements CoreQuestionBeha
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(question: any): any[] | Promise<any[]> {
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
// Just extract the button, it doesn't need any specific component.
|
||||
this.questionHelper.extractQbehaviourButtons(question);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input, EventEmitter } from '@angular/core';
|
||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Component to render a "seen" hidden input for informationitem question behaviour.
|
||||
|
@ -27,8 +27,8 @@ export class AddonQbehaviourInformationItemComponent {
|
|||
@Input() componentId: number; // ID of the component the question belongs to.
|
||||
@Input() attemptId: number; // Attempt ID.
|
||||
@Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
|
||||
@Input() buttonClicked: EventEmitter<any>; // Should emit an event when a behaviour button is clicked.
|
||||
@Input() onAbort: EventEmitter<void>; // Should emit an event if the question should be aborted.
|
||||
@Output() buttonClicked: EventEmitter<any>; // Should emit an event when a behaviour button is clicked.
|
||||
@Output() onAbort: EventEmitter<void>; // Should emit an event if the question should be aborted.
|
||||
|
||||
constructor() {
|
||||
// Nothing to do.
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourHandler } from '@core/question/providers/behaviour-delegate';
|
||||
import { CoreQuestionProvider, CoreQuestionState } from '@core/question/providers/question';
|
||||
import { CoreQuestionHelperProvider } from '@core/question/providers/helper';
|
||||
|
@ -52,11 +52,12 @@ export class AddonQbehaviourInformationItemHandler implements CoreQuestionBehavi
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(question: any): any[] | Promise<any[]> {
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
if (this.questionHelper.extractQbehaviourSeenInput(question)) {
|
||||
return [AddonQbehaviourInformationItemComponent];
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourHandler } from '@core/question/providers/behaviour-delegate';
|
||||
import { CoreQuestionHelperProvider } from '@core/question/providers/helper';
|
||||
|
||||
|
@ -34,11 +34,12 @@ export class AddonQbehaviourInteractiveHandler implements CoreQuestionBehaviourH
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(question: any): any[] | Promise<any[]> {
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
// Just extract the button, it doesn't need any specific component.
|
||||
this.questionHelper.extractQbehaviourButtons(question);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourHandler } from '@core/question/providers/behaviour-delegate';
|
||||
import { CoreQuestionHelperProvider } from '@core/question/providers/helper';
|
||||
|
||||
|
@ -34,11 +34,12 @@ export class AddonQbehaviourInteractiveCountbackHandler implements CoreQuestionB
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(question: any): any[] | Promise<any[]> {
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
// Just extract the button, it doesn't need any specific component.
|
||||
this.questionHelper.extractQbehaviourButtons(question);
|
||||
|
||||
|
|
|
@ -133,24 +133,26 @@ export class AddonRemoteThemesProvider {
|
|||
* Get remote styles of a certain site.
|
||||
*
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<{fileUrl: string, styles: string}>} Promise resolved with the styles and the URL of the CSS file.
|
||||
* @return {Promise<{fileUrl: string, styles: string}>} Promise resolved with the styles and the URL of the CSS file,
|
||||
* resolved with undefined if no styles to load.
|
||||
*/
|
||||
get(siteId?: string): Promise<{fileUrl: string, styles: string}> {
|
||||
siteId = siteId || this.sitesProvider.getCurrentSiteId();
|
||||
|
||||
let fileUrl;
|
||||
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
const infos = site.getInfo();
|
||||
let promise,
|
||||
fileUrl;
|
||||
|
||||
if (infos && infos.mobilecssurl) {
|
||||
fileUrl = infos.mobilecssurl;
|
||||
|
||||
if (this.fileProvider.isAvailable()) {
|
||||
// The file system is available. Download the file and remove old CSS files if needed.
|
||||
return this.downloadFileAndRemoveOld(siteId, fileUrl);
|
||||
promise = this.downloadFileAndRemoveOld(siteId, fileUrl);
|
||||
} else {
|
||||
// Return the online URL.
|
||||
return fileUrl;
|
||||
promise = Promise.resolve(fileUrl);
|
||||
}
|
||||
} else {
|
||||
if (infos && infos.mobilecssurl === '') {
|
||||
|
@ -158,20 +160,22 @@ export class AddonRemoteThemesProvider {
|
|||
this.filepoolProvider.removeFilesByComponent(siteId, AddonRemoteThemesProvider.COMPONENT, 1);
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
return;
|
||||
}
|
||||
}).then((url) => {
|
||||
this.logger.debug('Loading styles from: ', url);
|
||||
|
||||
// Get the CSS content using HTTP because we will treat the styles before saving them in the file.
|
||||
return this.http.get(url).toPromise();
|
||||
}).then((response): any => {
|
||||
const text = response && response.text();
|
||||
if (typeof text == 'string') {
|
||||
return {fileUrl: fileUrl, styles: this.get35Styles(text)};
|
||||
} else {
|
||||
return Promise.reject(null);
|
||||
}
|
||||
return promise.then((url) => {
|
||||
this.logger.debug('Loading styles from: ', url);
|
||||
|
||||
// Get the CSS content using HTTP because we will treat the styles before saving them in the file.
|
||||
return this.http.get(url).toPromise();
|
||||
}).then((response): any => {
|
||||
const text = response && response.text();
|
||||
if (typeof text == 'string') {
|
||||
return {fileUrl: fileUrl, styles: this.get35Styles(text)};
|
||||
} else {
|
||||
return Promise.reject(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -208,6 +212,11 @@ export class AddonRemoteThemesProvider {
|
|||
this.disableElement(this.stylesEls[siteId].element, disabled);
|
||||
|
||||
return this.get(siteId).then((data) => {
|
||||
if (typeof data == 'undefined') {
|
||||
// Nothing to load.
|
||||
return;
|
||||
}
|
||||
|
||||
const hash = <string> Md5.hashAsciiStr(data.styles);
|
||||
|
||||
// Update the styles only if they have changed.
|
||||
|
@ -271,6 +280,8 @@ export class AddonRemoteThemesProvider {
|
|||
preloadCurrentSite(): Promise<any> {
|
||||
return this.sitesProvider.getStoredCurrentSiteId().then((siteId) => {
|
||||
return this.addSite(siteId);
|
||||
}, () => {
|
||||
// No current site stored.
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -14,11 +14,10 @@
|
|||
|
||||
import {
|
||||
Component, Input, OnInit, OnChanges, OnDestroy, ViewContainerRef, ViewChild, ComponentRef, SimpleChange, ChangeDetectorRef,
|
||||
ElementRef, Optional
|
||||
ElementRef, Optional, Output, EventEmitter
|
||||
} from '@angular/core';
|
||||
import { NavController } from 'ionic-angular';
|
||||
import { CoreCompileProvider } from '../../providers/compile';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
/**
|
||||
* This component has a behaviour similar to $compile for AngularJS. Given an HTML code, it will compile it so all its
|
||||
|
@ -42,19 +41,18 @@ import { BehaviorSubject } from 'rxjs';
|
|||
export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
||||
@Input() text: string; // The HTML text to display.
|
||||
@Input() javascript: string; // The Javascript to execute in the component.
|
||||
@Input() jsData; // Data to pass to the fake component.
|
||||
@Input() jsData: any; // Data to pass to the fake component.
|
||||
@Output() created: EventEmitter<any> = new EventEmitter(); // Will emit an event when the component is instantiated.
|
||||
|
||||
// Get the container where to put the content.
|
||||
@ViewChild('dynamicComponent', { read: ViewContainerRef }) container: ViewContainerRef;
|
||||
|
||||
protected componentRef: ComponentRef<any>;
|
||||
protected element;
|
||||
componentObservable: BehaviorSubject<any>; // An observable to notify observers when the component is instantiated.
|
||||
|
||||
constructor(protected compileProvider: CoreCompileProvider, protected cdr: ChangeDetectorRef, element: ElementRef,
|
||||
@Optional() protected navCtrl: NavController) {
|
||||
this.element = element.nativeElement;
|
||||
this.componentObservable = new BehaviorSubject<any>(null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,7 +68,7 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
|||
if (factory) {
|
||||
// Create the component.
|
||||
this.componentRef = this.container.createComponent(factory);
|
||||
this.componentObservable.next(this.componentRef.instance);
|
||||
this.created.emit(this.componentRef.instance);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -98,13 +96,13 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy {
|
|||
// If there is some javascript to run, prepare the instance.
|
||||
if (compileInstance.javascript) {
|
||||
compileInstance.compileProvider.injectLibraries(this);
|
||||
|
||||
// Add some more components and classes.
|
||||
this['ChangeDetectorRef'] = compileInstance.cdr;
|
||||
this['NavController'] = compileInstance.navCtrl;
|
||||
this['componentContainer'] = compileInstance.element;
|
||||
}
|
||||
|
||||
// Always add these elements, they could be needed on component init (componentObservable).
|
||||
this['ChangeDetectorRef'] = compileInstance.cdr;
|
||||
this['NavController'] = compileInstance.navCtrl;
|
||||
this['componentContainer'] = compileInstance.element;
|
||||
|
||||
// Add the data passed to the component.
|
||||
for (const name in compileInstance.jsData) {
|
||||
this[name] = compileInstance.jsData[name];
|
||||
|
|
|
@ -75,6 +75,12 @@ import { CoreCourseFormatSingleActivityComponent } from '@core/course/formats/si
|
|||
import { CoreSitePluginsModuleIndexComponent } from '@core/siteplugins/components/module-index/module-index';
|
||||
import { CoreSitePluginsCourseOptionComponent } from '@core/siteplugins/components/course-option/course-option';
|
||||
import { CoreSitePluginsCourseFormatComponent } from '@core/siteplugins/components/course-format/course-format';
|
||||
import { CoreSitePluginsQuestionComponent } from '@core/siteplugins/components/question/question';
|
||||
import { CoreSitePluginsQuestionBehaviourComponent } from '@core/siteplugins/components/question-behaviour/question-behaviour';
|
||||
import { CoreSitePluginsUserProfileFieldComponent } from '@core/siteplugins/components/user-profile-field/user-profile-field';
|
||||
import { CoreSitePluginsQuizAccessRuleComponent } from '@core/siteplugins/components/quiz-access-rule/quiz-access-rule';
|
||||
import { CoreSitePluginsAssignFeedbackComponent } from '@core/siteplugins/components/assign-feedback/assign-feedback';
|
||||
import { CoreSitePluginsAssignSubmissionComponent } from '@core/siteplugins/components/assign-submission/assign-submission';
|
||||
|
||||
/**
|
||||
* Service to provide functionalities regarding compiling dynamic HTML and Javascript.
|
||||
|
@ -203,6 +209,12 @@ export class CoreCompileProvider {
|
|||
instance['CoreSitePluginsModuleIndexComponent'] = CoreSitePluginsModuleIndexComponent;
|
||||
instance['CoreSitePluginsCourseOptionComponent'] = CoreSitePluginsCourseOptionComponent;
|
||||
instance['CoreSitePluginsCourseFormatComponent'] = CoreSitePluginsCourseFormatComponent;
|
||||
instance['CoreSitePluginsQuestionComponent'] = CoreSitePluginsQuestionComponent;
|
||||
instance['CoreSitePluginsQuestionBehaviourComponent'] = CoreSitePluginsQuestionBehaviourComponent;
|
||||
instance['CoreSitePluginsUserProfileFieldComponent'] = CoreSitePluginsUserProfileFieldComponent;
|
||||
instance['CoreSitePluginsQuizAccessRuleComponent'] = CoreSitePluginsQuizAccessRuleComponent;
|
||||
instance['CoreSitePluginsAssignFeedbackComponent'] = CoreSitePluginsAssignFeedbackComponent;
|
||||
instance['CoreSitePluginsAssignSubmissionComponent'] = CoreSitePluginsAssignSubmissionComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Input, EventEmitter, Injector } from '@angular/core';
|
||||
import { Input, Output, EventEmitter, Injector } from '@angular/core';
|
||||
import { CoreLoggerProvider } from '@providers/logger';
|
||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
|
@ -27,8 +27,8 @@ export class CoreQuestionBaseComponent {
|
|||
@Input() componentId: number; // ID of the component the question belongs to.
|
||||
@Input() attemptId: number; // Attempt ID.
|
||||
@Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
|
||||
@Input() buttonClicked: EventEmitter<any>; // Should emit an event when a behaviour button is clicked.
|
||||
@Input() onAbort: EventEmitter<void>; // Should emit an event if the question should be aborted.
|
||||
@Output() buttonClicked: EventEmitter<any>; // Should emit an event when a behaviour button is clicked.
|
||||
@Output() onAbort: EventEmitter<void>; // Should emit an event if the question should be aborted.
|
||||
|
||||
protected logger;
|
||||
protected questionHelper: CoreQuestionHelperProvider;
|
||||
|
|
|
@ -123,11 +123,15 @@ export class CoreQuestionComponent implements OnInit {
|
|||
|
||||
promise.then(() => {
|
||||
// Handle behaviour.
|
||||
this.behaviourDelegate.handleQuestion(this.question.preferredBehaviour, this.question).then((comps) => {
|
||||
this.behaviourDelegate.handleQuestion(this.injector, this.question.preferredBehaviour, this.question)
|
||||
.then((comps) => {
|
||||
this.behaviourComponents = comps;
|
||||
}).finally(() => {
|
||||
this.question.html = this.domUtils.removeElementFromHtml(this.question.html, '.im-controls');
|
||||
this.loaded = true;
|
||||
});
|
||||
|
||||
this.questionHelper.extractQbehaviourRedoButton(this.question);
|
||||
this.question.html = this.domUtils.removeElementFromHtml(this.question.html, '.im-controls');
|
||||
|
||||
// Extract the validation error of the question.
|
||||
this.question.validationError = this.questionHelper.getValidationErrorFromHtml(this.question.html);
|
||||
|
@ -138,8 +142,6 @@ export class CoreQuestionComponent implements OnInit {
|
|||
// Try to extract the feedback and comment for the question.
|
||||
this.questionHelper.extractQuestionFeedback(this.question);
|
||||
this.questionHelper.extractQuestionComment(this.question);
|
||||
|
||||
this.loaded = true;
|
||||
});
|
||||
}
|
||||
}).catch(() => {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreLoggerProvider } from '@providers/logger';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
import { CoreSitesProvider } from '@providers/sites';
|
||||
|
@ -48,11 +48,12 @@ export interface CoreQuestionBehaviourHandler extends CoreDelegateHandler {
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion?(question: any): any[] | Promise<any[]>;
|
||||
handleQuestion?(injector: Injector, question: any): any[] | Promise<any[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,14 +91,15 @@ export class CoreQuestionBehaviourDelegate extends CoreDelegate {
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return a directive to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {string} behaviour Default behaviour.
|
||||
* @param {any} question The question.
|
||||
* @return {Promise<any[]>} Promise resolved with components to render some extra data in the question.
|
||||
*/
|
||||
handleQuestion(behaviour: string, question: any): Promise<any[]> {
|
||||
handleQuestion(injector: Injector, behaviour: string, question: any): Promise<any[]> {
|
||||
behaviour = this.questionDelegate.getBehaviourForQuestion(question, behaviour);
|
||||
|
||||
return Promise.resolve(this.executeFunctionOnEnabled(behaviour, 'handleQuestion', [question]));
|
||||
return Promise.resolve(this.executeFunctionOnEnabled(behaviour, 'handleQuestion', [injector, question]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourHandler } from './behaviour-delegate';
|
||||
import { CoreQuestionProvider, CoreQuestionState } from '@core/question/providers/question';
|
||||
|
||||
|
@ -46,11 +46,12 @@ export class CoreQuestionBehaviourDefaultHandler implements CoreQuestionBehaviou
|
|||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(question: any): any[] | Promise<any[]> {
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CoreSitePluginsProvider } from '../providers/siteplugins';
|
||||
|
||||
/**
|
||||
* Base class for components that will display a component using core-compile-html and want to call a
|
||||
* componentInit function returned by the handler JS.
|
||||
*/
|
||||
export class CoreSitePluginsCompileInitComponent {
|
||||
content = ''; // Content.
|
||||
jsData: any; // Data to pass to the component.
|
||||
protected handlerSchema: any; // The handler data.
|
||||
|
||||
constructor(protected sitePluginsProvider: CoreSitePluginsProvider) { }
|
||||
|
||||
/**
|
||||
* Function called when the component is created.
|
||||
*
|
||||
* @param {any} instance The component instance.
|
||||
*/
|
||||
componentCreated(instance: any): void {
|
||||
// Check if the JS defined an init function.
|
||||
if (instance && this.handlerSchema && this.handlerSchema.methodJSResult &&
|
||||
this.handlerSchema.methodJSResult.componentInit) {
|
||||
this.handlerSchema.methodJSResult.componentInit.apply(instance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the handler data.
|
||||
*
|
||||
* @param {string} name The name of the handler.
|
||||
*/
|
||||
getHandlerData(name: string): void {
|
||||
// Retrieve the handler data.
|
||||
const handler = this.sitePluginsProvider.getSitePluginHandler(name);
|
||||
|
||||
this.handlerSchema = handler && handler.handlerSchema;
|
||||
|
||||
if (this.handlerSchema) {
|
||||
// Load first template.
|
||||
if (this.handlerSchema.methodTemplates && this.handlerSchema.methodTemplates.length) {
|
||||
this.content = handler.handlerSchema.methodTemplates[0].html;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModAssignDefaultFeedbackHandler } from '@addon/mod/assign/providers/default-feedback-handler';
|
||||
import { CoreSitePluginsAssignFeedbackComponent } from '../../components/assign-feedback/assign-feedback';
|
||||
|
||||
/**
|
||||
* Handler to display an assign feedback site plugin.
|
||||
*/
|
||||
export class CoreSitePluginsAssignFeedbackHandler extends AddonModAssignDefaultFeedbackHandler {
|
||||
|
||||
constructor(translate: TranslateService, public name: string, public type: string, protected prefix: string) {
|
||||
super(translate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data, either in read or in edit mode.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {boolean} [edit] Whether the user is editing.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any, edit?: boolean): any | Promise<any> {
|
||||
return CoreSitePluginsAssignFeedbackComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a readable name to use for the plugin.
|
||||
*
|
||||
* @param {any} plugin The plugin object.
|
||||
* @return {string} The plugin name.
|
||||
*/
|
||||
getPluginName(plugin: any): string {
|
||||
// Check if there's a translated string for the plugin.
|
||||
const translationId = this.prefix + 'pluginname',
|
||||
translation = this.translate.instant(translationId);
|
||||
|
||||
if (translationId != translation) {
|
||||
// Translation found, use it.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// Fallback to WS string.
|
||||
if (plugin.name) {
|
||||
return plugin.name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AddonModAssignDefaultSubmissionHandler } from '@addon/mod/assign/providers/default-submission-handler';
|
||||
import { CoreSitePluginsAssignSubmissionComponent } from '../../components/assign-submission/assign-submission';
|
||||
|
||||
/**
|
||||
* Handler to display an assign submission site plugin.
|
||||
*/
|
||||
export class CoreSitePluginsAssignSubmissionHandler extends AddonModAssignDefaultSubmissionHandler {
|
||||
|
||||
constructor(translate: TranslateService, public name: string, public type: string, protected prefix: string) {
|
||||
super(translate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the plugin data, either in read or in edit mode.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} plugin The plugin object.
|
||||
* @param {boolean} [edit] Whether the user is editing.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector, plugin: any, edit?: boolean): any | Promise<any> {
|
||||
return CoreSitePluginsAssignSubmissionComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a readable name to use for the plugin.
|
||||
*
|
||||
* @param {any} plugin The plugin object.
|
||||
* @return {string} The plugin name.
|
||||
*/
|
||||
getPluginName(plugin: any): string {
|
||||
// Check if there's a translated string for the plugin.
|
||||
const translationId = this.prefix + 'pluginname',
|
||||
translation = this.translate.instant(translationId);
|
||||
|
||||
if (translationId != translation) {
|
||||
// Translation found, use it.
|
||||
return translation;
|
||||
}
|
||||
|
||||
// Fallback to WS string.
|
||||
if (plugin.name) {
|
||||
return plugin.name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled for edit on a site level.
|
||||
*
|
||||
* @return {boolean|Promise<boolean>} Whether or not the handler is enabled for edit on a site level.
|
||||
*/
|
||||
isEnabledForEdit(): boolean | Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
import { Injector } from '@angular/core';
|
||||
import { CoreCourseFormatHandler } from '@core/course/providers/format-delegate';
|
||||
import { CoreSitePluginsBaseHandler } from './base-handler';
|
||||
import { CoreSitePluginsCourseFormatComponent } from '../components/course-format/course-format';
|
||||
import { CoreSitePluginsCourseFormatComponent } from '../../components/course-format/course-format';
|
||||
|
||||
/**
|
||||
* Handler to support a course format using a site plugin.
|
|
@ -13,10 +13,10 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Injector } from '@angular/core';
|
||||
import { CoreSitePluginsProvider } from '../providers/siteplugins';
|
||||
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '@core/course/providers/options-delegate';
|
||||
import { CoreSitePluginsBaseHandler } from './base-handler';
|
||||
import { CoreSitePluginsCourseOptionComponent } from '../components/course-option/course-option';
|
||||
import { CoreSitePluginsCourseOptionComponent } from '../../components/course-option/course-option';
|
||||
|
||||
/**
|
||||
* Handler to display a site plugin in course options.
|
|
@ -25,7 +25,8 @@ export class CoreSitePluginsMainMenuHandler extends CoreSitePluginsBaseHandler i
|
|||
protected initResult: any) {
|
||||
super(name);
|
||||
|
||||
this.priority = handlerSchema.priority;
|
||||
// Set 699 as max priority so site plugins are always shown in the More tab (700 is Notifications tab).
|
||||
this.priority = Math.min(handlerSchema.priority, 699);
|
||||
}
|
||||
|
||||
/**
|
|
@ -0,0 +1,47 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { AddonMessageOutputHandler, AddonMessageOutputHandlerData } from '@addon/messageoutput/providers/delegate';
|
||||
import { CoreSitePluginsBaseHandler } from './base-handler';
|
||||
|
||||
/**
|
||||
* Handler to display a message output settings option.
|
||||
*/
|
||||
export class CoreSitePluginsMessageOutputHandler extends CoreSitePluginsBaseHandler implements AddonMessageOutputHandler {
|
||||
|
||||
constructor(name: string, public processorName: string, protected title: string, protected plugin: any,
|
||||
protected handlerSchema: any, protected initResult: any) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @return {AddonMessageOutputHandlerData} Data.
|
||||
*/
|
||||
getDisplayData(): AddonMessageOutputHandlerData {
|
||||
return {
|
||||
priority: this.handlerSchema.priority,
|
||||
label: this.title,
|
||||
icon: this.handlerSchema.displaydata.icon,
|
||||
page: 'CoreSitePluginsPluginPage',
|
||||
pageParams: {
|
||||
title: this.title,
|
||||
component: this.plugin.component,
|
||||
method: this.handlerSchema.method,
|
||||
initResult: this.initResult
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ import { Injector } from '@angular/core';
|
|||
import { NavController, NavOptions } from 'ionic-angular';
|
||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate';
|
||||
import { CoreSitePluginsBaseHandler } from './base-handler';
|
||||
import { CoreSitePluginsModuleIndexComponent } from '../components/module-index/module-index';
|
||||
import { CoreSitePluginsModuleIndexComponent } from '../../components/module-index/module-index';
|
||||
|
||||
/**
|
||||
* Handler to support a module using a site plugin.
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Injector } from '@angular/core';
|
||||
import { CoreSitePluginsProvider } from '../providers/siteplugins';
|
||||
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
|
||||
|
||||
/**
|
|
@ -0,0 +1,44 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector } from '@angular/core';
|
||||
import { CoreQuestionBehaviourDefaultHandler } from '@core/question/providers/default-behaviour-handler';
|
||||
import { CoreSitePluginsQuestionBehaviourComponent } from '../../components/question-behaviour/question-behaviour';
|
||||
import { CoreQuestionProvider } from '@core/question/providers/question';
|
||||
|
||||
/**
|
||||
* Handler to display a question behaviour site plugin.
|
||||
*/
|
||||
export class CoreSitePluginsQuestionBehaviourHandler extends CoreQuestionBehaviourDefaultHandler {
|
||||
|
||||
constructor(questionProvider: CoreQuestionProvider, public name: string, public type: string, public hasTemplate: boolean) {
|
||||
super(questionProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a question behaviour.
|
||||
* If the behaviour requires a submit button, it should add it to question.behaviourButtons.
|
||||
* If the behaviour requires to show some extra data, it should return the components to render it.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question.
|
||||
* @return {any[]|Promise<any[]>} Components (or promise resolved with components) to render some extra data in the question
|
||||
* (e.g. certainty options). Don't return anything if no extra data is required.
|
||||
*/
|
||||
handleQuestion(injector: Injector, question: any): any[] | Promise<any[]> {
|
||||
if (this.hasTemplate) {
|
||||
return [CoreSitePluginsQuestionBehaviourComponent];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector } from '@angular/core';
|
||||
import { CoreQuestionDefaultHandler } from '@core/question/providers/default-question-handler';
|
||||
import { CoreSitePluginsQuestionComponent } from '../../components/question/question';
|
||||
|
||||
/**
|
||||
* Handler to display a question site plugin.
|
||||
*/
|
||||
export class CoreSitePluginsQuestionHandler extends CoreQuestionDefaultHandler {
|
||||
|
||||
constructor(public name: string, public type: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the question.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @param {any} question The question to render.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getComponent(injector: Injector): any | Promise<any> {
|
||||
return CoreSitePluginsQuestionComponent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { Injector } from '@angular/core';
|
||||
import { CoreQuestionDefaultHandler } from '@core/question/providers/default-question-handler';
|
||||
import { CoreSitePluginsQuizAccessRuleComponent } from '../../components/quiz-access-rule/quiz-access-rule';
|
||||
|
||||
/**
|
||||
* Handler to display a quiz access rule site plugin.
|
||||
*/
|
||||
export class CoreSitePluginsQuizAccessRuleHandler extends CoreQuestionDefaultHandler {
|
||||
|
||||
constructor(public name: string, public ruleName: string, public hasTemplate: boolean) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the rule requires a preflight check when prefetch/start/continue an attempt.
|
||||
*
|
||||
* @param {any} quiz The quiz the rule belongs to.
|
||||
* @param {any} [attempt] The attempt started/continued. If not supplied, user is starting a new attempt.
|
||||
* @param {boolean} [prefetch] Whether the user is prefetching the quiz.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {boolean|Promise<boolean>} Whether the rule requires a preflight check.
|
||||
*/
|
||||
isPreflightCheckRequired(quiz: any, attempt?: any, prefetch?: boolean, siteId?: string): boolean | Promise<boolean> {
|
||||
return this.hasTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add preflight data that doesn't require user interaction. The data should be added to the preflightData param.
|
||||
*
|
||||
* @param {any} quiz The quiz the rule belongs to.
|
||||
* @param {any} preflightData Object where to add the preflight data.
|
||||
* @param {any} [attempt] The attempt started/continued. If not supplied, user is starting a new attempt.
|
||||
* @param {boolean} [prefetch] Whether the user is prefetching the quiz.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} Promise resolved when done if async, void if it's synchronous.
|
||||
*/
|
||||
getFixedPreflightData(quiz: any, preflightData: any, attempt?: any, prefetch?: boolean, siteId?: string): void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Component to use to display the access rule preflight.
|
||||
* Implement this if your access rule requires a preflight check with user interaction.
|
||||
* It's recommended to return the class of the component, but you can also return an instance of the component.
|
||||
*
|
||||
* @param {Injector} injector Injector.
|
||||
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
|
||||
*/
|
||||
getPreflightComponent(injector: Injector): any | Promise<any> {
|
||||
if (this.hasTemplate) {
|
||||
return CoreSitePluginsQuizAccessRuleComponent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function called when the preflight check has passed. This is a chance to record that fact in some way.
|
||||
*
|
||||
* @param {any} quiz The quiz the rule belongs to.
|
||||
* @param {any} attempt The attempt started/continued.
|
||||
* @param {any} preflightData Preflight data gathered.
|
||||
* @param {boolean} [prefetch] Whether the user is prefetching the quiz.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} Promise resolved when done if async, void if it's synchronous.
|
||||
*/
|
||||
notifyPreflightCheckPassed(quiz: any, attempt: any, preflightData: any, prefetch?: boolean, siteId?: string)
|
||||
: void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Function called when the preflight check fails. This is a chance to record that fact in some way.
|
||||
*
|
||||
* @param {any} quiz The quiz the rule belongs to.
|
||||
* @param {any} attempt The attempt started/continued.
|
||||
* @param {any} preflightData Preflight data gathered.
|
||||
* @param {boolean} [prefetch] Whether the user is prefetching the quiz.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {void|Promise<any>} Promise resolved when done if async, void if it's synchronous.
|
||||
*/
|
||||
notifyPreflightCheckFailed(quiz: any, attempt: any, preflightData: any, prefetch?: boolean, siteId?: string)
|
||||
: void | Promise<any> {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the time left of an attempt should be displayed.
|
||||
*
|
||||
* @param {any} attempt The attempt.
|
||||
* @param {number} endTime The attempt end time (in seconds).
|
||||
* @param {number} timeNow The current time in seconds.
|
||||
* @return {boolean} Whether it should be displayed.
|
||||
*/
|
||||
shouldShowTimeLeft(attempt: any, endTime: number, timeNow: number): boolean {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// 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 { CoreSettingsHandler, CoreSettingsHandlerData } from '@core/settings/providers/delegate';
|
||||
import { CoreSitePluginsBaseHandler } from './base-handler';
|
||||
|
||||
/**
|
||||
* Handler to display a site plugin in the settings.
|
||||
*/
|
||||
export class CoreSitePluginsSettingsHandler extends CoreSitePluginsBaseHandler implements CoreSettingsHandler {
|
||||
priority: number;
|
||||
|
||||
constructor(name: string, protected title: string, protected plugin: any, protected handlerSchema: any,
|
||||
protected initResult: any) {
|
||||
super(name);
|
||||
|
||||
this.priority = handlerSchema.priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data needed to render the handler.
|
||||
*
|
||||
* @return {CoreSettingsHandlerData} Data.
|
||||
*/
|
||||
getDisplayData(): CoreSettingsHandlerData {
|
||||
return {
|
||||
title: this.title,
|
||||
icon: this.handlerSchema.displaydata.icon,
|
||||
class: this.handlerSchema.displaydata.class,
|
||||
page: 'CoreSitePluginsPluginPage',
|
||||
params: {
|
||||
title: this.title,
|
||||
component: this.plugin.component,
|
||||
method: this.handlerSchema.method,
|
||||
initResult: this.initResult
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
import { NavController } from 'ionic-angular';
|
||||
import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@core/user/providers/user-delegate';
|
||||
import { CoreSitePluginsProvider } from '../providers/siteplugins';
|
||||
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||
import { CoreSitePluginsBaseHandler } from './base-handler';
|
||||
|
||||
/**
|
|
@ -15,7 +15,7 @@
|
|||
import { Injector } from '@angular/core';
|
||||
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '@core/user/providers/user-profile-field-delegate';
|
||||
import { CoreSitePluginsBaseHandler } from './base-handler';
|
||||
import { CoreSitePluginsUserProfileFieldComponent } from '../components/user-profile-field/user-profile-field';
|
||||
import { CoreSitePluginsUserProfileFieldComponent } from '../../components/user-profile-field/user-profile-field';
|
||||
|
||||
/**
|
||||
* Handler to display a site plugin in the user profile.
|
|
@ -0,0 +1 @@
|
|||
<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
|
|
@ -0,0 +1,67 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||
import { CoreSitePluginsCompileInitComponent } from '../../classes/compile-init-component';
|
||||
|
||||
/**
|
||||
* Component that displays an assign feedback plugin created using a site plugin.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-site-plugins-assign-feedback',
|
||||
templateUrl: 'assign-feedback.html',
|
||||
})
|
||||
export class CoreSitePluginsAssignFeedbackComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
|
||||
@Input() assign: any; // The assignment.
|
||||
@Input() submission: any; // The submission.
|
||||
@Input() plugin: any; // The plugin object.
|
||||
@Input() userId: number; // The user ID of the submission.
|
||||
@Input() configs: any; // The configs for the plugin.
|
||||
@Input() canEdit: boolean; // Whether the user can edit.
|
||||
@Input() edit: boolean; // Whether the user is editing.
|
||||
|
||||
constructor(sitePluginsProvider: CoreSitePluginsProvider) {
|
||||
super(sitePluginsProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
// Pass the input and output data to the component.
|
||||
this.jsData = {
|
||||
assign: this.assign,
|
||||
submission: this.submission,
|
||||
plugin: this.plugin,
|
||||
userId: this.userId,
|
||||
configs: this.configs,
|
||||
edit: this.edit,
|
||||
canEdit: this.canEdit
|
||||
};
|
||||
|
||||
if (this.plugin) {
|
||||
this.getHandlerData('assignfeedback_' + this.plugin.type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the data.
|
||||
*
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
invalidate(): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
|
|
@ -0,0 +1,65 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||
import { CoreSitePluginsCompileInitComponent } from '../../classes/compile-init-component';
|
||||
|
||||
/**
|
||||
* Component that displays an assign submission plugin created using a site plugin.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-site-plugins-assign-submission',
|
||||
templateUrl: 'assign-submission.html',
|
||||
})
|
||||
export class CoreSitePluginsAssignSubmissionComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
|
||||
@Input() assign: any; // The assignment.
|
||||
@Input() submission: any; // The submission.
|
||||
@Input() plugin: any; // The plugin object.
|
||||
@Input() configs: any; // The configs for the plugin.
|
||||
@Input() edit: boolean; // Whether the user is editing.
|
||||
@Input() allowOffline: boolean; // Whether to allow offline.
|
||||
|
||||
constructor(sitePluginsProvider: CoreSitePluginsProvider) {
|
||||
super(sitePluginsProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
// Pass the input and output data to the component.
|
||||
this.jsData = {
|
||||
assign: this.assign,
|
||||
submission: this.submission,
|
||||
plugin: this.plugin,
|
||||
configs: this.configs,
|
||||
edit: this.edit,
|
||||
allowOffline: this.allowOffline
|
||||
};
|
||||
|
||||
if (this.plugin) {
|
||||
this.getHandlerData('assignsubmission_' + this.plugin.type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the data.
|
||||
*
|
||||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
invalidate(): Promise<any> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
|
@ -23,6 +23,11 @@ import { CoreSitePluginsModuleIndexComponent } from './module-index/module-index
|
|||
import { CoreSitePluginsCourseOptionComponent } from './course-option/course-option';
|
||||
import { CoreSitePluginsCourseFormatComponent } from './course-format/course-format';
|
||||
import { CoreSitePluginsUserProfileFieldComponent } from './user-profile-field/user-profile-field';
|
||||
import { CoreSitePluginsQuestionComponent } from './question/question';
|
||||
import { CoreSitePluginsQuestionBehaviourComponent } from './question-behaviour/question-behaviour';
|
||||
import { CoreSitePluginsQuizAccessRuleComponent } from './quiz-access-rule/quiz-access-rule';
|
||||
import { CoreSitePluginsAssignFeedbackComponent } from './assign-feedback/assign-feedback';
|
||||
import { CoreSitePluginsAssignSubmissionComponent } from './assign-submission/assign-submission';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -30,7 +35,12 @@ import { CoreSitePluginsUserProfileFieldComponent } from './user-profile-field/u
|
|||
CoreSitePluginsModuleIndexComponent,
|
||||
CoreSitePluginsCourseOptionComponent,
|
||||
CoreSitePluginsCourseFormatComponent,
|
||||
CoreSitePluginsUserProfileFieldComponent
|
||||
CoreSitePluginsUserProfileFieldComponent,
|
||||
CoreSitePluginsQuestionComponent,
|
||||
CoreSitePluginsQuestionBehaviourComponent,
|
||||
CoreSitePluginsQuizAccessRuleComponent,
|
||||
CoreSitePluginsAssignFeedbackComponent,
|
||||
CoreSitePluginsAssignSubmissionComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
@ -46,13 +56,23 @@ import { CoreSitePluginsUserProfileFieldComponent } from './user-profile-field/u
|
|||
CoreSitePluginsModuleIndexComponent,
|
||||
CoreSitePluginsCourseOptionComponent,
|
||||
CoreSitePluginsCourseFormatComponent,
|
||||
CoreSitePluginsUserProfileFieldComponent
|
||||
CoreSitePluginsUserProfileFieldComponent,
|
||||
CoreSitePluginsQuestionComponent,
|
||||
CoreSitePluginsQuestionBehaviourComponent,
|
||||
CoreSitePluginsQuizAccessRuleComponent,
|
||||
CoreSitePluginsAssignFeedbackComponent,
|
||||
CoreSitePluginsAssignSubmissionComponent
|
||||
],
|
||||
entryComponents: [
|
||||
CoreSitePluginsModuleIndexComponent,
|
||||
CoreSitePluginsCourseOptionComponent,
|
||||
CoreSitePluginsCourseFormatComponent,
|
||||
CoreSitePluginsUserProfileFieldComponent
|
||||
CoreSitePluginsUserProfileFieldComponent,
|
||||
CoreSitePluginsQuestionComponent,
|
||||
CoreSitePluginsQuestionBehaviourComponent,
|
||||
CoreSitePluginsQuizAccessRuleComponent,
|
||||
CoreSitePluginsAssignFeedbackComponent,
|
||||
CoreSitePluginsAssignSubmissionComponent
|
||||
]
|
||||
})
|
||||
export class CoreSitePluginsComponentsModule {}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
|
|
@ -0,0 +1,58 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||
import { CoreSitePluginsCompileInitComponent } from '../../classes/compile-init-component';
|
||||
|
||||
/**
|
||||
* Component that displays a question behaviour created using a site plugin.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-site-plugins-question-behaviour',
|
||||
templateUrl: 'question-behaviour.html',
|
||||
})
|
||||
export class CoreSitePluginsQuestionBehaviourComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
|
||||
@Input() question: any; // The question where the behaviour will be rendered.
|
||||
@Input() component: string; // The component the question belongs to.
|
||||
@Input() componentId: number; // ID of the component the question belongs to.
|
||||
@Input() attemptId: number; // Attempt ID.
|
||||
@Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
|
||||
@Output() buttonClicked: EventEmitter<any>; // Should emit an event when a behaviour button is clicked.
|
||||
@Output() onAbort: EventEmitter<void>; // Should emit an event if the question should be aborted.
|
||||
|
||||
constructor(sitePluginsProvider: CoreSitePluginsProvider) {
|
||||
super(sitePluginsProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
// Pass the input and output data to the component.
|
||||
this.jsData = {
|
||||
question: this.question,
|
||||
component: this.component,
|
||||
componentId: this.componentId,
|
||||
attemptId: this.attemptId,
|
||||
offlineEnabled: this.offlineEnabled,
|
||||
buttonClicked: this.buttonClicked,
|
||||
onAbort: this.onAbort
|
||||
};
|
||||
|
||||
if (this.question) {
|
||||
this.getHandlerData('qbehaviour_' + this.question.preferredBehaviour);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
|
|
@ -0,0 +1,58 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||
import { CoreSitePluginsCompileInitComponent } from '../../classes/compile-init-component';
|
||||
|
||||
/**
|
||||
* Component that displays a question created using a site plugin.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-site-plugins-question',
|
||||
templateUrl: 'question.html',
|
||||
})
|
||||
export class CoreSitePluginsQuestionComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
|
||||
@Input() question: any; // The question to render.
|
||||
@Input() component: string; // The component the question belongs to.
|
||||
@Input() componentId: number; // ID of the component the question belongs to.
|
||||
@Input() attemptId: number; // Attempt ID.
|
||||
@Input() offlineEnabled?: boolean | string; // Whether the question can be answered in offline.
|
||||
@Output() buttonClicked: EventEmitter<any>; // Should emit an event when a behaviour button is clicked.
|
||||
@Output() onAbort: EventEmitter<void>; // Should emit an event if the question should be aborted.
|
||||
|
||||
constructor(sitePluginsProvider: CoreSitePluginsProvider) {
|
||||
super(sitePluginsProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
// Pass the input and output data to the component.
|
||||
this.jsData = {
|
||||
question: this.question,
|
||||
component: this.component,
|
||||
componentId: this.componentId,
|
||||
attemptId: this.attemptId,
|
||||
offlineEnabled: this.offlineEnabled,
|
||||
buttonClicked: this.buttonClicked,
|
||||
onAbort: this.onAbort
|
||||
};
|
||||
|
||||
if (this.question) {
|
||||
this.getHandlerData('qtype_' + this.question.type);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
|
|
@ -0,0 +1,57 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||
import { CoreSitePluginsCompileInitComponent } from '../../classes/compile-init-component';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
|
||||
/**
|
||||
* Component that displays a quiz access rule created using a site plugin.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'core-site-plugins-quiz-access-rule',
|
||||
templateUrl: 'quiz-access-rule.html',
|
||||
})
|
||||
export class CoreSitePluginsQuizAccessRuleComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
|
||||
@Input() rule: string; // The name of the rule.
|
||||
@Input() quiz: any; // The quiz the rule belongs to.
|
||||
@Input() attempt: any; // The attempt being started/continued.
|
||||
@Input() prefetch: boolean; // Whether the user is prefetching the quiz.
|
||||
@Input() siteId: string; // Site ID.
|
||||
@Input() form: FormGroup; // Form where to add the form control.
|
||||
|
||||
constructor(sitePluginsProvider: CoreSitePluginsProvider) {
|
||||
super(sitePluginsProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
// Pass the input and output data to the component.
|
||||
this.jsData = {
|
||||
rule: this.rule,
|
||||
quiz: this.quiz,
|
||||
attempt: this.attempt,
|
||||
prefetch: this.prefetch,
|
||||
siteId: this.siteId,
|
||||
form: this.form
|
||||
};
|
||||
|
||||
if (this.rule) {
|
||||
this.getHandlerData(this.rule);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
<core-compile-html [text]="content" [jsData]="jsData"></core-compile-html>
|
||||
<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>
|
||||
|
|
|
@ -12,10 +12,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit, Input, ViewChild, OnDestroy } from '@angular/core';
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
|
||||
import { CoreCompileHtmlComponent } from '@core/compile/components/compile-html/compile-html';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { CoreSitePluginsCompileInitComponent } from '../../classes/compile-init-component';
|
||||
|
||||
/**
|
||||
* Component that displays a user profile field created using a site plugin.
|
||||
|
@ -24,20 +23,16 @@ import { Subscription } from 'rxjs';
|
|||
selector: 'core-site-plugins-user-profile-field',
|
||||
templateUrl: 'user-profile-field.html',
|
||||
})
|
||||
export class CoreSitePluginsUserProfileFieldComponent implements OnInit, OnDestroy {
|
||||
export class CoreSitePluginsUserProfileFieldComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
|
||||
@Input() field: any; // The profile field to be rendered.
|
||||
@Input() signup = false; // True if editing the field in signup. Defaults to false.
|
||||
@Input() edit = false; // True if editing the field. Defaults to false.
|
||||
@Input() form?: any; // Form where to add the form control. Required if edit=true or signup=true.
|
||||
@Input() registerAuth?: string; // Register auth method. E.g. 'email'.
|
||||
|
||||
@ViewChild(CoreCompileHtmlComponent) compileComponent: CoreCompileHtmlComponent;
|
||||
|
||||
content = ''; // Content.
|
||||
jsData;
|
||||
protected componentObserver: Subscription;
|
||||
|
||||
constructor(protected sitePluginsProvider: CoreSitePluginsProvider) { }
|
||||
constructor(sitePluginsProvider: CoreSitePluginsProvider) {
|
||||
super(sitePluginsProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
|
@ -54,34 +49,7 @@ export class CoreSitePluginsUserProfileFieldComponent implements OnInit, OnDestr
|
|||
};
|
||||
|
||||
if (this.field) {
|
||||
// Retrieve the handler data.
|
||||
const handler = this.sitePluginsProvider.getSitePluginHandler(this.field.type || this.field.datatype),
|
||||
handlerSchema = handler && handler.handlerSchema;
|
||||
|
||||
if (handlerSchema) {
|
||||
// Load first template.
|
||||
if (handlerSchema.methodTemplates && handlerSchema.methodTemplates.length) {
|
||||
this.content = handler.handlerSchema.methodTemplates[0].html;
|
||||
}
|
||||
|
||||
// Wait for the instance to be created.
|
||||
if (this.compileComponent && this.compileComponent.componentObservable &&
|
||||
handlerSchema.methodJSResult && handlerSchema.methodJSResult.componentInit) {
|
||||
this.componentObserver = this.compileComponent.componentObservable.subscribe((instance) => {
|
||||
if (instance) {
|
||||
// Instance created, call component init.
|
||||
handlerSchema.methodJSResult.componentInit.apply(instance);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
this.getHandlerData('profilefield_' + (this.field.type || this.field.datatype));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Component destroyed.
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.componentObserver && this.componentObserver.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
import { CoreFilepoolProvider } from '@providers/filepool';
|
||||
import { CoreLangProvider } from '@providers/lang';
|
||||
|
@ -25,6 +26,7 @@ import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
|||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreSitePluginsProvider } from './siteplugins';
|
||||
import { CoreCompileProvider } from '@core/compile/providers/compile';
|
||||
import { CoreQuestionProvider } from '@core/question/providers/question';
|
||||
|
||||
// Delegates
|
||||
import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate';
|
||||
|
@ -34,15 +36,29 @@ import { CoreCourseOptionsDelegate } from '@core/course/providers/options-delega
|
|||
import { CoreCourseFormatDelegate } from '@core/course/providers/format-delegate';
|
||||
import { CoreUserDelegate } from '@core/user/providers/user-delegate';
|
||||
import { CoreUserProfileFieldDelegate } from '@core/user/providers/user-profile-field-delegate';
|
||||
import { CoreSettingsDelegate } from '@core/settings/providers/delegate';
|
||||
import { CoreQuestionDelegate } from '@core/question/providers/delegate';
|
||||
import { CoreQuestionBehaviourDelegate } from '@core/question/providers/behaviour-delegate';
|
||||
import { AddonMessageOutputDelegate } from '@addon/messageoutput/providers/delegate';
|
||||
import { AddonModQuizAccessRuleDelegate } from '@addon/mod/quiz/providers/access-rules-delegate';
|
||||
import { AddonModAssignFeedbackDelegate } from '@addon/mod/assign/providers/feedback-delegate';
|
||||
import { AddonModAssignSubmissionDelegate } from '@addon/mod/assign/providers/submission-delegate';
|
||||
|
||||
// Handler classes.
|
||||
import { CoreSitePluginsCourseFormatHandler } from '../classes/course-format-handler';
|
||||
import { CoreSitePluginsCourseOptionHandler } from '../classes/course-option-handler';
|
||||
import { CoreSitePluginsModuleHandler } from '../classes/module-handler';
|
||||
import { CoreSitePluginsModulePrefetchHandler } from '../classes/module-prefetch-handler';
|
||||
import { CoreSitePluginsMainMenuHandler } from '../classes/main-menu-handler';
|
||||
import { CoreSitePluginsUserProfileHandler } from '../classes/user-handler';
|
||||
import { CoreSitePluginsUserProfileFieldHandler } from '../classes/user-profile-field-handler';
|
||||
import { CoreSitePluginsCourseFormatHandler } from '../classes/handlers/course-format-handler';
|
||||
import { CoreSitePluginsCourseOptionHandler } from '../classes/handlers/course-option-handler';
|
||||
import { CoreSitePluginsModuleHandler } from '../classes/handlers/module-handler';
|
||||
import { CoreSitePluginsModulePrefetchHandler } from '../classes/handlers/module-prefetch-handler';
|
||||
import { CoreSitePluginsMainMenuHandler } from '../classes/handlers/main-menu-handler';
|
||||
import { CoreSitePluginsUserProfileHandler } from '../classes/handlers/user-handler';
|
||||
import { CoreSitePluginsUserProfileFieldHandler } from '../classes/handlers/user-profile-field-handler';
|
||||
import { CoreSitePluginsSettingsHandler } from '../classes/handlers/settings-handler';
|
||||
import { CoreSitePluginsQuestionHandler } from '../classes/handlers/question-handler';
|
||||
import { CoreSitePluginsQuestionBehaviourHandler } from '../classes/handlers/question-behaviour-handler';
|
||||
import { CoreSitePluginsMessageOutputHandler } from '../classes/handlers/message-output-handler';
|
||||
import { CoreSitePluginsQuizAccessRuleHandler } from '../classes/handlers/quiz-access-rule-handler';
|
||||
import { CoreSitePluginsAssignFeedbackHandler } from '../classes/handlers/assign-feedback-handler';
|
||||
import { CoreSitePluginsAssignSubmissionHandler } from '../classes/handlers/assign-submission-handler';
|
||||
|
||||
/**
|
||||
* Helper service to provide functionalities regarding site plugins. It basically has the features to load and register site
|
||||
|
@ -64,7 +80,13 @@ export class CoreSitePluginsHelperProvider {
|
|||
private compileProvider: CoreCompileProvider, private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider,
|
||||
private courseOptionsDelegate: CoreCourseOptionsDelegate, eventsProvider: CoreEventsProvider,
|
||||
private courseFormatDelegate: CoreCourseFormatDelegate, private profileFieldDelegate: CoreUserProfileFieldDelegate,
|
||||
private textUtils: CoreTextUtilsProvider, private filepoolProvider: CoreFilepoolProvider) {
|
||||
private textUtils: CoreTextUtilsProvider, private filepoolProvider: CoreFilepoolProvider,
|
||||
private settingsDelegate: CoreSettingsDelegate, private questionDelegate: CoreQuestionDelegate,
|
||||
private questionBehaviourDelegate: CoreQuestionBehaviourDelegate, private questionProvider: CoreQuestionProvider,
|
||||
private messageOutputDelegate: AddonMessageOutputDelegate, private accessRulesDelegate: AddonModQuizAccessRuleDelegate,
|
||||
private assignSubmissionDelegate: AddonModAssignSubmissionDelegate, private translate: TranslateService,
|
||||
private assignFeedbackDelegate: AddonModAssignFeedbackDelegate) {
|
||||
|
||||
this.logger = logger.getInstance('CoreSitePluginsHelperProvider');
|
||||
|
||||
// Fetch the plugins on login.
|
||||
|
@ -414,7 +436,7 @@ export class CoreSitePluginsHelperProvider {
|
|||
break;
|
||||
|
||||
case 'CoreCourseModuleDelegate':
|
||||
promise = Promise.resolve(this.registerModuleHandler(plugin, handlerName, handlerSchema, result));
|
||||
promise = Promise.resolve(this.registerModuleHandler(plugin, handlerName, handlerSchema));
|
||||
break;
|
||||
|
||||
case 'CoreUserDelegate':
|
||||
|
@ -426,11 +448,39 @@ export class CoreSitePluginsHelperProvider {
|
|||
break;
|
||||
|
||||
case 'CoreCourseFormatDelegate':
|
||||
promise = Promise.resolve(this.registerCourseFormatHandler(plugin, handlerName, handlerSchema, result));
|
||||
promise = Promise.resolve(this.registerCourseFormatHandler(plugin, handlerName, handlerSchema));
|
||||
break;
|
||||
|
||||
case 'CoreUserProfileFieldDelegate':
|
||||
promise = Promise.resolve(this.registerUserProfileFieldHandler(plugin, handlerName, handlerSchema, result));
|
||||
promise = Promise.resolve(this.registerUserProfileFieldHandler(plugin, handlerName, handlerSchema));
|
||||
break;
|
||||
|
||||
case 'CoreSettingsDelegate':
|
||||
promise = Promise.resolve(this.registerSettingsHandler(plugin, handlerName, handlerSchema, result));
|
||||
break;
|
||||
|
||||
case 'CoreQuestionDelegate':
|
||||
promise = Promise.resolve(this.registerQuestionHandler(plugin, handlerName, handlerSchema));
|
||||
break;
|
||||
|
||||
case 'CoreQuestionBehaviourDelegate':
|
||||
promise = Promise.resolve(this.registerQuestionBehaviourHandler(plugin, handlerName, handlerSchema));
|
||||
break;
|
||||
|
||||
case 'AddonMessageOutputDelegate':
|
||||
promise = Promise.resolve(this.registerMessageOutputHandler(plugin, handlerName, handlerSchema, result));
|
||||
break;
|
||||
|
||||
case 'AddonModQuizAccessRuleDelegate':
|
||||
promise = Promise.resolve(this.registerQuizAccessRuleHandler(plugin, handlerName, handlerSchema));
|
||||
break;
|
||||
|
||||
case 'AddonModAssignFeedbackDelegate':
|
||||
promise = Promise.resolve(this.registerAssignFeedbackHandler(plugin, handlerName, handlerSchema));
|
||||
break;
|
||||
|
||||
case 'AddonModAssignSubmissionDelegate':
|
||||
promise = Promise.resolve(this.registerAssignSubmissionHandler(plugin, handlerName, handlerSchema));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -454,17 +504,107 @@ export class CoreSitePluginsHelperProvider {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler that relies in a "componentInit" function in a certain delegate.
|
||||
* These type of handlers will return a generic template and its JS in the main method, so it will be called
|
||||
* before registering the handler.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
|
||||
*/
|
||||
protected registerComponentInitHandler(plugin: any, handlerName: string, handlerSchema: any, delegate: any,
|
||||
createHandlerFn: (uniqueName: string, result: any) => any): string | Promise<string> {
|
||||
|
||||
if (!handlerSchema.method) {
|
||||
// Required data not provided, stop.
|
||||
this.logger.warn('Ignore site plugin because it doesn\'t provide method', plugin, handlerSchema);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.debug('Register site plugin', plugin, handlerSchema);
|
||||
|
||||
// Execute the main method and its JS. The template returned will be used in the right component.
|
||||
return this.executeMethodAndJS(plugin, handlerSchema.method).then((result) => {
|
||||
|
||||
// Create and register the handler.
|
||||
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
|
||||
handler = createHandlerFn(uniqueName, result);
|
||||
|
||||
// Store in handlerSchema some data required by the component.
|
||||
handlerSchema.methodTemplates = result.templates;
|
||||
handlerSchema.methodJSResult = result.jsResult;
|
||||
|
||||
if (result && result.jsResult) {
|
||||
// Override default handler functions with the result of the method JS.
|
||||
for (const property in handler) {
|
||||
if (property != 'constructor' && typeof handler[property] == 'function' &&
|
||||
typeof result.jsResult[property] == 'function') {
|
||||
handler[property] = result.jsResult[property].bind(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delegate.registerHandler(handler);
|
||||
|
||||
return plugin.component;
|
||||
}).catch((err) => {
|
||||
this.logger.error('Error executing main method', plugin.component, handlerSchema.method, err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a handler in a plugin, register it in the assign feedback delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
|
||||
*/
|
||||
protected registerAssignFeedbackHandler(plugin: any, handlerName: string, handlerSchema: any): string | Promise<string> {
|
||||
|
||||
return this.registerComponentInitHandler(plugin, handlerName, handlerSchema, this.assignFeedbackDelegate,
|
||||
(uniqueName: string, result: any) => {
|
||||
|
||||
const type = plugin.component.replace('assignfeedback_', ''),
|
||||
prefix = this.getPrefixForStrings(plugin.addon);
|
||||
|
||||
return new CoreSitePluginsAssignFeedbackHandler(this.translate, uniqueName, type, prefix);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a handler in a plugin, register it in the assign submission delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
|
||||
*/
|
||||
protected registerAssignSubmissionHandler(plugin: any, handlerName: string, handlerSchema: any): string | Promise<string> {
|
||||
|
||||
return this.registerComponentInitHandler(plugin, handlerName, handlerSchema, this.assignSubmissionDelegate,
|
||||
(uniqueName: string, result: any) => {
|
||||
|
||||
const type = plugin.component.replace('assignsubmission_', ''),
|
||||
prefix = this.getPrefixForStrings(plugin.addon);
|
||||
|
||||
return new CoreSitePluginsAssignSubmissionHandler(this.translate, uniqueName, type, prefix);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a handler in a plugin, register it in the course format delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @param {any} initResult Result of the init WS call.
|
||||
* @return {string} A string to identify the handler.
|
||||
*/
|
||||
protected registerCourseFormatHandler(plugin: any, handlerName: string, handlerSchema: any, initResult: any): string {
|
||||
this.logger.debug('Register site plugin in course format delegate:', plugin, handlerSchema, initResult);
|
||||
protected registerCourseFormatHandler(plugin: any, handlerName: string, handlerSchema: any): string {
|
||||
this.logger.debug('Register site plugin in course format delegate:', plugin, handlerSchema);
|
||||
|
||||
// Create and register the handler.
|
||||
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
|
||||
|
@ -475,7 +615,7 @@ export class CoreSitePluginsHelperProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Given a handler in an plugin, register it in the course options delegate.
|
||||
* Given a handler in a plugin, register it in the course options delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
|
@ -504,7 +644,7 @@ export class CoreSitePluginsHelperProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Given a handler in an plugin, register it in the main menu delegate.
|
||||
* Given a handler in a plugin, register it in the main menu delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
|
@ -533,7 +673,7 @@ export class CoreSitePluginsHelperProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Given a handler in an plugin, register it in the module delegate.
|
||||
* Given a handler in a plugin, register it in the message output delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
|
@ -541,7 +681,7 @@ export class CoreSitePluginsHelperProvider {
|
|||
* @param {any} initResult Result of the init WS call.
|
||||
* @return {string} A string to identify the handler.
|
||||
*/
|
||||
protected registerModuleHandler(plugin: any, handlerName: string, handlerSchema: any, initResult: any): string {
|
||||
protected registerMessageOutputHandler(plugin: any, handlerName: string, handlerSchema: any, initResult: any): string {
|
||||
if (!handlerSchema.displaydata) {
|
||||
// Required data not provided, stop.
|
||||
this.logger.warn('Ignore site plugin because it doesn\'t provide displaydata', plugin, handlerSchema);
|
||||
|
@ -549,7 +689,36 @@ export class CoreSitePluginsHelperProvider {
|
|||
return;
|
||||
}
|
||||
|
||||
this.logger.debug('Register site plugin in module delegate:', plugin, handlerSchema, initResult);
|
||||
this.logger.debug('Register site plugin in message output delegate:', plugin, handlerSchema, initResult);
|
||||
|
||||
// Create and register the handler.
|
||||
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
|
||||
prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title),
|
||||
processorName = plugin.component.replace('message_', '');
|
||||
|
||||
this.messageOutputDelegate.registerHandler(new CoreSitePluginsMessageOutputHandler(uniqueName, processorName,
|
||||
prefixedTitle, plugin, handlerSchema, initResult));
|
||||
|
||||
return uniqueName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a handler in a plugin, register it in the module delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @return {string} A string to identify the handler.
|
||||
*/
|
||||
protected registerModuleHandler(plugin: any, handlerName: string, handlerSchema: any): string {
|
||||
if (!handlerSchema.displaydata) {
|
||||
// Required data not provided, stop.
|
||||
this.logger.warn('Ignore site plugin because it doesn\'t provide displaydata', plugin, handlerSchema);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.debug('Register site plugin in module delegate:', plugin, handlerSchema);
|
||||
|
||||
// Create and register the handler.
|
||||
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
|
||||
|
@ -567,7 +736,89 @@ export class CoreSitePluginsHelperProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Given a handler in an plugin, register it in the user profile delegate.
|
||||
* Given a handler in a plugin, register it in the question delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
|
||||
*/
|
||||
protected registerQuestionHandler(plugin: any, handlerName: string, handlerSchema: any): string | Promise<string> {
|
||||
|
||||
return this.registerComponentInitHandler(plugin, handlerName, handlerSchema, this.questionDelegate,
|
||||
(uniqueName: string, result: any) => {
|
||||
|
||||
return new CoreSitePluginsQuestionHandler(uniqueName, plugin.component);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a handler in a plugin, register it in the question behaviour delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
|
||||
*/
|
||||
protected registerQuestionBehaviourHandler(plugin: any, handlerName: string, handlerSchema: any): string | Promise<string> {
|
||||
|
||||
return this.registerComponentInitHandler(plugin, handlerName, handlerSchema, this.questionBehaviourDelegate,
|
||||
(uniqueName: string, result: any) => {
|
||||
|
||||
const type = plugin.component.replace('qbehaviour_', '');
|
||||
|
||||
return new CoreSitePluginsQuestionBehaviourHandler(this.questionProvider, uniqueName, type, result.templates.length);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a handler in a plugin, register it in the quiz access rule delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
|
||||
*/
|
||||
protected registerQuizAccessRuleHandler(plugin: any, handlerName: string, handlerSchema: any): string | Promise<string> {
|
||||
|
||||
return this.registerComponentInitHandler(plugin, handlerName, handlerSchema, this.accessRulesDelegate,
|
||||
(uniqueName: string, result: any) => {
|
||||
|
||||
return new CoreSitePluginsQuizAccessRuleHandler(uniqueName, plugin.component, result.templates.length);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a handler in a plugin, register it in the settings delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @param {any} initResult Result of the init WS call.
|
||||
* @return {string} A string to identify the handler.
|
||||
*/
|
||||
protected registerSettingsHandler(plugin: any, handlerName: string, handlerSchema: any, initResult: any): string {
|
||||
if (!handlerSchema.displaydata) {
|
||||
// Required data not provided, stop.
|
||||
this.logger.warn('Ignore site plugin because it doesn\'t provide displaydata', plugin, handlerSchema);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.debug('Register site plugin in settings delegate:', plugin, handlerSchema, initResult);
|
||||
|
||||
// Create and register the handler.
|
||||
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
|
||||
prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title);
|
||||
|
||||
this.settingsDelegate.registerHandler(
|
||||
new CoreSitePluginsSettingsHandler(uniqueName, prefixedTitle, plugin, handlerSchema, initResult));
|
||||
|
||||
return uniqueName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a handler in a plugin, register it in the user profile delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
|
@ -596,51 +847,21 @@ export class CoreSitePluginsHelperProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Given a handler in an plugin, register it in the user profile field delegate.
|
||||
* Given a handler in a plugin, register it in the user profile field delegate.
|
||||
*
|
||||
* @param {any} plugin Data of the plugin.
|
||||
* @param {string} handlerName Name of the handler in the plugin.
|
||||
* @param {any} handlerSchema Data about the handler.
|
||||
* @param {any} initResult Result of the init WS call.
|
||||
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
|
||||
*/
|
||||
protected registerUserProfileFieldHandler(plugin: any, handlerName: string, handlerSchema: any, initResult: any)
|
||||
: string | Promise<string> {
|
||||
if (!handlerSchema.method) {
|
||||
// Required data not provided, stop.
|
||||
this.logger.warn('Ignore site plugin because it doesn\'t provide method', plugin, handlerSchema);
|
||||
protected registerUserProfileFieldHandler(plugin: any, handlerName: string, handlerSchema: any): string | Promise<string> {
|
||||
|
||||
return;
|
||||
}
|
||||
return this.registerComponentInitHandler(plugin, handlerName, handlerSchema, this.profileFieldDelegate,
|
||||
(uniqueName: string, result: any) => {
|
||||
|
||||
this.logger.debug('Register site plugin in user profile field delegate:', plugin, handlerSchema, initResult);
|
||||
const fieldType = plugin.component.replace('profilefield_', '');
|
||||
|
||||
// Execute the main method and its JS. The template returned will be used in the profile field component.
|
||||
return this.executeMethodAndJS(plugin, handlerSchema.method).then((result) => {
|
||||
// Create and register the handler.
|
||||
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
|
||||
fieldType = plugin.component.replace('profilefield_', ''),
|
||||
fieldHandler = new CoreSitePluginsUserProfileFieldHandler(uniqueName, fieldType);
|
||||
|
||||
// Store in handlerSchema some data required by the component.
|
||||
handlerSchema.methodTemplates = result.templates;
|
||||
handlerSchema.methodJSResult = result.jsResult;
|
||||
|
||||
if (result && result.jsResult) {
|
||||
// Override default handler functions with the result of the method JS.
|
||||
for (const property in fieldHandler) {
|
||||
if (property != 'constructor' && typeof fieldHandler[property] == 'function' &&
|
||||
typeof result.jsResult[property] == 'function') {
|
||||
fieldHandler[property] = result.jsResult[property].bind(fieldHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.profileFieldDelegate.registerHandler(fieldHandler);
|
||||
|
||||
return fieldType;
|
||||
}).catch((err) => {
|
||||
this.logger.error('Error executing main method', handlerSchema.method, err);
|
||||
return new CoreSitePluginsUserProfileFieldHandler(uniqueName, fieldType);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,9 +184,9 @@ export class CoreCronDelegate {
|
|||
return this.setHandlerLastExecutionTime(name, Date.now()).then(() => {
|
||||
this.scheduleNextExecution(name);
|
||||
});
|
||||
}, () => {
|
||||
}, (error) => {
|
||||
// Handler call failed. Retry soon.
|
||||
this.logger.debug(`Execution of handler '${name}' failed.`);
|
||||
this.logger.error(`Execution of handler '${name}' failed.`, error);
|
||||
this.scheduleNextExecution(name, CoreCronDelegate.MIN_INTERVAL);
|
||||
|
||||
return Promise.reject(null);
|
||||
|
@ -440,7 +440,9 @@ export class CoreCronDelegate {
|
|||
|
||||
this.handlers[name].timeout = setTimeout(() => {
|
||||
delete this.handlers[name].timeout;
|
||||
this.checkAndExecuteHandler(name);
|
||||
this.checkAndExecuteHandler(name).catch(() => {
|
||||
// Ignore errors.
|
||||
});
|
||||
}, nextExecution);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -918,7 +918,9 @@ export class CoreFileProvider {
|
|||
* @return {Promise<any>} Promise resolved when done.
|
||||
*/
|
||||
clearTmpFolder(): Promise<any> {
|
||||
return this.removeDir(CoreFileProvider.TMPFOLDER);
|
||||
return this.removeDir(CoreFileProvider.TMPFOLDER).catch(() => {
|
||||
// Ignore errors because the folder might not exist.
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -975,6 +975,8 @@ export class CoreSitesProvider {
|
|||
this.logger.debug(`Restore session in site ${siteId}`);
|
||||
|
||||
return this.loadSite(siteId);
|
||||
}).catch(() => {
|
||||
// No current session.
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue