From 0bb2f25f2036bbec51b5246a802ae881f1ba8486 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 5 Jun 2018 12:19:43 +0200 Subject: [PATCH] MOBILE-2163 core: Fix ngc warnings when compiling --- .../assign/classes/base-feedback-handler.ts | 178 +++++++++++++ .../assign/classes/base-submission-handler.ts | 235 ++++++++++++++++++ .../providers/default-feedback-handler.ts | 156 +----------- .../providers/default-submission-handler.ts | 215 +--------------- src/classes/delegate.ts | 2 - .../classes/base-behaviour-handler.ts | 69 +++++ .../question/classes/base-question-handler.ts | 136 ++++++++++ .../providers/default-behaviour-handler.ts | 49 +--- .../providers/default-question-handler.ts | 113 +-------- .../handlers/assign-feedback-handler.ts | 4 +- .../handlers/assign-submission-handler.ts | 4 +- .../handlers/question-behaviour-handler.ts | 4 +- .../classes/handlers/question-handler.ts | 4 +- .../handlers/quiz-access-rule-handler.ts | 7 +- 14 files changed, 649 insertions(+), 527 deletions(-) create mode 100644 src/addon/mod/assign/classes/base-feedback-handler.ts create mode 100644 src/addon/mod/assign/classes/base-submission-handler.ts create mode 100644 src/core/question/classes/base-behaviour-handler.ts create mode 100644 src/core/question/classes/base-question-handler.ts diff --git a/src/addon/mod/assign/classes/base-feedback-handler.ts b/src/addon/mod/assign/classes/base-feedback-handler.ts new file mode 100644 index 000000000..61b9addbc --- /dev/null +++ b/src/addon/mod/assign/classes/base-feedback-handler.ts @@ -0,0 +1,178 @@ +// (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 { AddonModAssignFeedbackHandler } from '../providers/feedback-delegate'; + +/** + * Base handler for feedback plugins. + * + * This class is needed because parent classes cannot have @Injectable in Angular v6, so the default handler cannot be a + * parent class. + */ +export class AddonModAssignBaseFeedbackHandler implements AddonModAssignFeedbackHandler { + name = 'AddonModAssignBaseFeedbackHandler'; + type = 'base'; + + 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} If the function is async, it should return a Promise resolved when done. + */ + discardDraft(assignId: number, userId: number, siteId?: string): void | Promise { + // 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} The component (or promise resolved with component) to use, undefined if not found. + */ + getComponent(injector: Injector, plugin: any): any | Promise { + // 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} Data (or promise resolved with the data). + */ + getDraft(assignId: number, userId: number, siteId?: string): any | Promise { + // Nothing to do. + } + + /** + * Get files used by this plugin. + * The files returned by this function will be prefetched when the user prefetches the assign. + * + * @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 {any[]|Promise} The files (or promise resolved with the files). + */ + getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise { + return []; + } + + /** + * 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 = 'addon.mod_assign_feedback_' + plugin.type + '.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; + } + } + + /** + * Check if the feedback data has changed for this plugin. + * + * @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 feedback. + * @return {boolean|Promise} Boolean (or promise resolved with boolean): whether the data has changed. + */ + hasDataChanged(assign: any, submission: any, plugin: any, inputData: any): boolean | Promise { + return false; + } + + /** + * Check whether the plugin has draft data stored. + * + * @param {number} assignId The assignment ID. + * @param {number} userId User ID. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {boolean|Promise} Boolean or promise resolved with boolean: whether the plugin has draft data. + */ + hasDraftData(assignId: number, userId: number, siteId?: string): boolean | Promise { + return false; + } + + /** + * Whether or not the handler is enabled on a site level. + * + * @return {boolean|Promise} True or promise resolved with true if enabled. + */ + isEnabled(): boolean | Promise { + 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} Promise resolved when done. + */ + prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise { + 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} 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 { + // 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} 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 { + // Nothing to do. + } +} diff --git a/src/addon/mod/assign/classes/base-submission-handler.ts b/src/addon/mod/assign/classes/base-submission-handler.ts new file mode 100644 index 000000000..7f3d52bdf --- /dev/null +++ b/src/addon/mod/assign/classes/base-submission-handler.ts @@ -0,0 +1,235 @@ +// (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 { AddonModAssignSubmissionHandler } from '../providers/submission-delegate'; + +/** + * Base handler for submission plugins. + * + * This class is needed because parent classes cannot have @Injectable in Angular v6, so the default handler cannot be a + * parent class. + */ +export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmissionHandler { + name = 'AddonModAssignBaseSubmissionHandler'; + type = 'base'; + + constructor(protected translate: TranslateService) { } + + /** + * Whether the plugin can be edited in offline for existing submissions. In general, this should return false if the + * plugin uses Moodle filters. The reason is that the app only prefetches filtered data, and the user should edit + * unfiltered data. + * + * @param {any} assign The assignment. + * @param {any} submission The submission. + * @param {any} plugin The plugin object. + * @return {boolean|Promise} Boolean or promise resolved with boolean: whether it can be edited in offline. + */ + canEditOffline(assign: any, submission: any, plugin: any): boolean | Promise { + 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} 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 { + // 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} 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 { + // 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} The component (or promise resolved with component) to use, undefined if not found. + */ + getComponent(injector: Injector, plugin: any, edit?: boolean): any | Promise { + // Nothing to do. + } + + /** + * Get files used by this plugin. + * The files returned by this function will be prefetched when the user prefetches the assign. + * + * @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 {any[]|Promise} The files (or promise resolved with the files). + */ + getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise { + return []; + } + + /** + * 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 = 'addon.mod_assign_submission_' + plugin.type + '.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; + } + } + + /** + * Get the size of data (in bytes) this plugin will send to copy a previous submission. + * + * @param {any} assign The assignment. + * @param {any} plugin The plugin object. + * @return {number|Promise} The size (or promise resolved with size). + */ + getSizeForCopy(assign: any, plugin: any): number | Promise { + return 0; + } + + /** + * Get the size of data (in bytes) this plugin will send to add or edit a submission. + * + * @param {any} assign The assignment. + * @param {any} plugin The plugin object. + * @return {number|Promise} The size (or promise resolved with size). + */ + getSizeForEdit(assign: any, plugin: any): number | Promise { + return 0; + } + + /** + * Check if the submission data has changed for this plugin. + * + * @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. + * @return {boolean|Promise} Boolean (or promise resolved with boolean): whether the data has changed. + */ + hasDataChanged(assign: any, submission: any, plugin: any, inputData: any): boolean | Promise { + return false; + } + + /** + * Whether or not the handler is enabled on a site level. + * + * @return {boolean|Promise} True or promise resolved with true if enabled. + */ + isEnabled(): boolean | Promise { + return true; + } + + /** + * Whether or not the handler is enabled for edit on a site level. + * @return {boolean|Promise} Whether or not the handler is enabled for edit on a site level. + */ + isEnabledForEdit(): boolean | Promise { + 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} Promise resolved when done. + */ + prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise { + 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} 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 { + // 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} 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 { + // Nothing to do. + } +} diff --git a/src/addon/mod/assign/providers/default-feedback-handler.ts b/src/addon/mod/assign/providers/default-feedback-handler.ts index 0c3d03852..cbc95c88a 100644 --- a/src/addon/mod/assign/providers/default-feedback-handler.ts +++ b/src/addon/mod/assign/providers/default-feedback-handler.ts @@ -12,165 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; -import { AddonModAssignFeedbackHandler } from './feedback-delegate'; +import { AddonModAssignBaseFeedbackHandler } from '../classes/base-feedback-handler'; /** * Default handler used when a feedback plugin doesn't have a specific implementation. */ @Injectable() -export class AddonModAssignDefaultFeedbackHandler implements AddonModAssignFeedbackHandler { +export class AddonModAssignDefaultFeedbackHandler extends AddonModAssignBaseFeedbackHandler { name = 'AddonModAssignDefaultFeedbackHandler'; type = 'default'; - 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} If the function is async, it should return a Promise resolved when done. - */ - discardDraft(assignId: number, userId: number, siteId?: string): void | Promise { - // 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} The component (or promise resolved with component) to use, undefined if not found. - */ - getComponent(injector: Injector, plugin: any): any | Promise { - // 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} Data (or promise resolved with the data). - */ - getDraft(assignId: number, userId: number, siteId?: string): any | Promise { - // Nothing to do. - } - - /** - * Get files used by this plugin. - * The files returned by this function will be prefetched when the user prefetches the assign. - * - * @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 {any[]|Promise} The files (or promise resolved with the files). - */ - getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise { - return []; - } - - /** - * 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 = 'addon.mod_assign_feedback_' + plugin.type + '.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; - } - } - - /** - * Check if the feedback data has changed for this plugin. - * - * @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 feedback. - * @return {boolean|Promise} Boolean (or promise resolved with boolean): whether the data has changed. - */ - hasDataChanged(assign: any, submission: any, plugin: any, inputData: any): boolean | Promise { - return false; - } - - /** - * Check whether the plugin has draft data stored. - * - * @param {number} assignId The assignment ID. - * @param {number} userId User ID. - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {boolean|Promise} Boolean or promise resolved with boolean: whether the plugin has draft data. - */ - hasDraftData(assignId: number, userId: number, siteId?: string): boolean | Promise { - return false; - } - - /** - * Whether or not the handler is enabled on a site level. - * - * @return {boolean|Promise} True or promise resolved with true if enabled. - */ - isEnabled(): boolean | Promise { - 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} Promise resolved when done. - */ - prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise { - 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} 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 { - // 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} 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 { - // Nothing to do. + constructor(protected translate: TranslateService) { + super(translate); } } diff --git a/src/addon/mod/assign/providers/default-submission-handler.ts b/src/addon/mod/assign/providers/default-submission-handler.ts index aa1f84056..c18c71982 100644 --- a/src/addon/mod/assign/providers/default-submission-handler.ts +++ b/src/addon/mod/assign/providers/default-submission-handler.ts @@ -12,222 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; -import { AddonModAssignSubmissionHandler } from './submission-delegate'; +import { AddonModAssignBaseSubmissionHandler } from '../classes/base-submission-handler'; /** * Default handler used when a submission plugin doesn't have a specific implementation. */ @Injectable() -export class AddonModAssignDefaultSubmissionHandler implements AddonModAssignSubmissionHandler { +export class AddonModAssignDefaultSubmissionHandler extends AddonModAssignBaseSubmissionHandler { name = 'AddonModAssignDefaultSubmissionHandler'; type = 'default'; - constructor(protected translate: TranslateService) { } - - /** - * Whether the plugin can be edited in offline for existing submissions. In general, this should return false if the - * plugin uses Moodle filters. The reason is that the app only prefetches filtered data, and the user should edit - * unfiltered data. - * - * @param {any} assign The assignment. - * @param {any} submission The submission. - * @param {any} plugin The plugin object. - * @return {boolean|Promise} Boolean or promise resolved with boolean: whether it can be edited in offline. - */ - canEditOffline(assign: any, submission: any, plugin: any): boolean | Promise { - 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} 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 { - // 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} 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 { - // 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} The component (or promise resolved with component) to use, undefined if not found. - */ - getComponent(injector: Injector, plugin: any, edit?: boolean): any | Promise { - // Nothing to do. - } - - /** - * Get files used by this plugin. - * The files returned by this function will be prefetched when the user prefetches the assign. - * - * @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 {any[]|Promise} The files (or promise resolved with the files). - */ - getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise { - return []; - } - - /** - * 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 = 'addon.mod_assign_submission_' + plugin.type + '.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; - } - } - - /** - * Get the size of data (in bytes) this plugin will send to copy a previous submission. - * - * @param {any} assign The assignment. - * @param {any} plugin The plugin object. - * @return {number|Promise} The size (or promise resolved with size). - */ - getSizeForCopy(assign: any, plugin: any): number | Promise { - return 0; - } - - /** - * Get the size of data (in bytes) this plugin will send to add or edit a submission. - * - * @param {any} assign The assignment. - * @param {any} plugin The plugin object. - * @return {number|Promise} The size (or promise resolved with size). - */ - getSizeForEdit(assign: any, plugin: any): number | Promise { - return 0; - } - - /** - * Check if the submission data has changed for this plugin. - * - * @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. - * @return {boolean|Promise} Boolean (or promise resolved with boolean): whether the data has changed. - */ - hasDataChanged(assign: any, submission: any, plugin: any, inputData: any): boolean | Promise { - return false; - } - - /** - * Whether or not the handler is enabled on a site level. - * - * @return {boolean|Promise} True or promise resolved with true if enabled. - */ - isEnabled(): boolean | Promise { - return true; - } - - /** - * Whether or not the handler is enabled for edit on a site level. - * @return {boolean|Promise} Whether or not the handler is enabled for edit on a site level. - */ - isEnabledForEdit(): boolean | Promise { - 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} Promise resolved when done. - */ - prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise { - 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} 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 { - // 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} 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 { - // Nothing to do. - } + constructor(protected translate: TranslateService) { + super(translate); + } // Nothing to do. } diff --git a/src/classes/delegate.ts b/src/classes/delegate.ts index b95626153..36ce33710 100644 --- a/src/classes/delegate.ts +++ b/src/classes/delegate.ts @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable } from '@angular/core'; import { CoreLoggerProvider } from '@providers/logger'; import { CoreSitesProvider } from '@providers/sites'; import { CoreEventsProvider } from '@providers/events'; @@ -35,7 +34,6 @@ export interface CoreDelegateHandler { /** * Superclass to help creating delegates */ -@Injectable() export class CoreDelegate { /** diff --git a/src/core/question/classes/base-behaviour-handler.ts b/src/core/question/classes/base-behaviour-handler.ts new file mode 100644 index 000000000..8da0309ac --- /dev/null +++ b/src/core/question/classes/base-behaviour-handler.ts @@ -0,0 +1,69 @@ +// (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 { CoreQuestionBehaviourHandler } from '../providers/behaviour-delegate'; +import { CoreQuestionProvider, CoreQuestionState } from '@core/question/providers/question'; + +/** + * Base handler for question behaviours. + * + * This class is needed because parent classes cannot have @Injectable in Angular v6, so the default handler cannot be a + * parent class. + */ +export class CoreQuestionBehaviourBaseHandler implements CoreQuestionBehaviourHandler { + name = 'CoreQuestionBehaviourBase'; + type = 'base'; + + constructor(protected questionProvider: CoreQuestionProvider) { } + + /** + * Determine a question new state based on its answer(s). + * + * @param {string} component Component the question belongs to. + * @param {number} attemptId Attempt ID the question belongs to. + * @param {any} question The question. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {CoreQuestionState|Promise} New state (or promise resolved with state). + */ + determineNewState(component: string, attemptId: number, question: any, siteId?: string) + : CoreQuestionState | Promise { + // Return the current state. + return this.questionProvider.getState(question.state); + } + + /** + * 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} 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 { + // Nothing to do. + return; + } + + /** + * Whether or not the handler is enabled on a site level. + * + * @return {boolean|Promise} True or promise resolved with true if enabled. + */ + isEnabled(): boolean | Promise { + return true; + } +} diff --git a/src/core/question/classes/base-question-handler.ts b/src/core/question/classes/base-question-handler.ts new file mode 100644 index 000000000..e7782c2fb --- /dev/null +++ b/src/core/question/classes/base-question-handler.ts @@ -0,0 +1,136 @@ +// (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 { CoreQuestionHandler } from '../providers/delegate'; + +/** + * Base handler for question types. + * + * This class is needed because parent classes cannot have @Injectable in Angular v6, so the default handler cannot be a + * parent class. + */ +export class CoreQuestionBaseHandler implements CoreQuestionHandler { + name = 'CoreQuestionBase'; + type = 'base'; + + constructor() { + // Nothing to do. + } + + /** + * Whether or not the handler is enabled on a site level. + * + * @return {boolean|Promise} True or promise resolved with true if enabled. + */ + isEnabled(): boolean | Promise { + return true; + } + + /** + * 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} The component (or promise resolved with component) to use, undefined if not found. + */ + getComponent(injector: Injector, question: any): any | Promise { + // There is no default component for questions. + } + + /** + * Return the name of the behaviour to use for the question. + * If the question should use the default behaviour you shouldn't implement this function. + * + * @param {any} question The question. + * @param {string} behaviour The default behaviour. + * @return {string} The behaviour to use. + */ + getBehaviour(question: any, behaviour: string): string { + return behaviour; + } + + /** + * Check if a question can be submitted. + * If a question cannot be submitted it should return a message explaining why (translated or not). + * + * @param {any} question The question. + * @return {string} Prevent submit message. Undefined or empty if can be submitted. + */ + getPreventSubmitMessage(question: any): string { + // Never prevent by default. + return ''; + } + + /** + * Check if a response is complete. + * + * @param {any} question The question. + * @param {any} answers Object with the question answers (without prefix). + * @return {number} 1 if complete, 0 if not complete, -1 if cannot determine. + */ + isCompleteResponse(question: any, answers: any): number { + return -1; + } + + /** + * Check if a student has provided enough of an answer for the question to be graded automatically, + * or whether it must be considered aborted. + * + * @param {any} question The question. + * @param {any} answers Object with the question answers (without prefix). + * @return {number} 1 if gradable, 0 if not gradable, -1 if cannot determine. + */ + isGradableResponse(question: any, answers: any): number { + return -1; + } + + /** + * Check if two responses are the same. + * + * @param {any} question Question. + * @param {any} prevAnswers Object with the previous question answers. + * @param {any} newAnswers Object with the new question answers. + * @return {boolean} Whether they're the same. + */ + isSameResponse(question: any, prevAnswers: any, newAnswers: any): boolean { + return false; + } + + /** + * Prepare and add to answers the data to send to server based in the input. Return promise if async. + * + * @param {any} question Question. + * @param {any} answers The answers retrieved from the form. Prepared answers must be stored in this object. + * @param {boolean} [offline] Whether the data should be saved in offline. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {void|Promise} Return a promise resolved when done if async, void if sync. + */ + prepareAnswers(question: any, answers: any, offline: boolean, siteId?: string): void | Promise { + // Nothing to do. + } + + /** + * Validate if an offline sequencecheck is valid compared with the online one. + * This function only needs to be implemented if a specific compare is required. + * + * @param {any} question The question. + * @param {string} offlineSequenceCheck Sequence check stored in offline. + * @return {boolean} Whether sequencecheck is valid. + */ + validateSequenceCheck(question: any, offlineSequenceCheck: string): boolean { + return question.sequencecheck == offlineSequenceCheck; + } +} diff --git a/src/core/question/providers/default-behaviour-handler.ts b/src/core/question/providers/default-behaviour-handler.ts index c26be4549..6609f033a 100644 --- a/src/core/question/providers/default-behaviour-handler.ts +++ b/src/core/question/providers/default-behaviour-handler.ts @@ -12,56 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreQuestionBehaviourHandler } from './behaviour-delegate'; -import { CoreQuestionProvider, CoreQuestionState } from '@core/question/providers/question'; +import { Injectable } from '@angular/core'; +import { CoreQuestionBehaviourBaseHandler } from '../classes/base-behaviour-handler'; +import { CoreQuestionProvider } from '@core/question/providers/question'; /** * Default handler used when the question behaviour doesn't have a specific implementation. */ @Injectable() -export class CoreQuestionBehaviourDefaultHandler implements CoreQuestionBehaviourHandler { +export class CoreQuestionBehaviourDefaultHandler extends CoreQuestionBehaviourBaseHandler { name = 'CoreQuestionBehaviourDefault'; type = 'default'; - constructor(private questionProvider: CoreQuestionProvider) { } - - /** - * Determine a question new state based on its answer(s). - * - * @param {string} component Component the question belongs to. - * @param {number} attemptId Attempt ID the question belongs to. - * @param {any} question The question. - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {CoreQuestionState|Promise} New state (or promise resolved with state). - */ - determineNewState(component: string, attemptId: number, question: any, siteId?: string) - : CoreQuestionState | Promise { - // Return the current state. - return this.questionProvider.getState(question.state); - } - - /** - * 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} 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 { - // Nothing to do. - return; - } - - /** - * Whether or not the handler is enabled on a site level. - * - * @return {boolean|Promise} True or promise resolved with true if enabled. - */ - isEnabled(): boolean | Promise { - return true; + constructor(protected questionProvider: CoreQuestionProvider) { + super(questionProvider); } } diff --git a/src/core/question/providers/default-question-handler.ts b/src/core/question/providers/default-question-handler.ts index e6688eaa0..9aa3688f1 100644 --- a/src/core/question/providers/default-question-handler.ts +++ b/src/core/question/providers/default-question-handler.ts @@ -12,123 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreQuestionHandler } from './delegate'; +import { Injectable } from '@angular/core'; +import { CoreQuestionBaseHandler } from '../classes/base-question-handler'; /** * Default handler used when the question type doesn't have a specific implementation. */ @Injectable() -export class CoreQuestionDefaultHandler implements CoreQuestionHandler { +export class CoreQuestionDefaultHandler extends CoreQuestionBaseHandler { name = 'CoreQuestionDefault'; type = 'default'; constructor() { - // Nothing to do. - } - - /** - * Whether or not the handler is enabled on a site level. - * - * @return {boolean|Promise} True or promise resolved with true if enabled. - */ - isEnabled(): boolean | Promise { - return true; - } - - /** - * 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} The component (or promise resolved with component) to use, undefined if not found. - */ - getComponent(injector: Injector, question: any): any | Promise { - // There is no default component for questions. - } - - /** - * Return the name of the behaviour to use for the question. - * If the question should use the default behaviour you shouldn't implement this function. - * - * @param {any} question The question. - * @param {string} behaviour The default behaviour. - * @return {string} The behaviour to use. - */ - getBehaviour(question: any, behaviour: string): string { - return behaviour; - } - - /** - * Check if a question can be submitted. - * If a question cannot be submitted it should return a message explaining why (translated or not). - * - * @param {any} question The question. - * @return {string} Prevent submit message. Undefined or empty if can be submitted. - */ - getPreventSubmitMessage(question: any): string { - // Never prevent by default. - return ''; - } - - /** - * Check if a response is complete. - * - * @param {any} question The question. - * @param {any} answers Object with the question answers (without prefix). - * @return {number} 1 if complete, 0 if not complete, -1 if cannot determine. - */ - isCompleteResponse(question: any, answers: any): number { - return -1; - } - - /** - * Check if a student has provided enough of an answer for the question to be graded automatically, - * or whether it must be considered aborted. - * - * @param {any} question The question. - * @param {any} answers Object with the question answers (without prefix). - * @return {number} 1 if gradable, 0 if not gradable, -1 if cannot determine. - */ - isGradableResponse(question: any, answers: any): number { - return -1; - } - - /** - * Check if two responses are the same. - * - * @param {any} question Question. - * @param {any} prevAnswers Object with the previous question answers. - * @param {any} newAnswers Object with the new question answers. - * @return {boolean} Whether they're the same. - */ - isSameResponse(question: any, prevAnswers: any, newAnswers: any): boolean { - return false; - } - - /** - * Prepare and add to answers the data to send to server based in the input. Return promise if async. - * - * @param {any} question Question. - * @param {any} answers The answers retrieved from the form. Prepared answers must be stored in this object. - * @param {boolean} [offline] Whether the data should be saved in offline. - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {void|Promise} Return a promise resolved when done if async, void if sync. - */ - prepareAnswers(question: any, answers: any, offline: boolean, siteId?: string): void | Promise { - // Nothing to do. - } - - /** - * Validate if an offline sequencecheck is valid compared with the online one. - * This function only needs to be implemented if a specific compare is required. - * - * @param {any} question The question. - * @param {string} offlineSequenceCheck Sequence check stored in offline. - * @return {boolean} Whether sequencecheck is valid. - */ - validateSequenceCheck(question: any, offlineSequenceCheck: string): boolean { - return question.sequencecheck == offlineSequenceCheck; + super(); } } diff --git a/src/core/siteplugins/classes/handlers/assign-feedback-handler.ts b/src/core/siteplugins/classes/handlers/assign-feedback-handler.ts index 04b64049f..0948c0c8c 100644 --- a/src/core/siteplugins/classes/handlers/assign-feedback-handler.ts +++ b/src/core/siteplugins/classes/handlers/assign-feedback-handler.ts @@ -14,13 +14,13 @@ import { Injector } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; -import { AddonModAssignDefaultFeedbackHandler } from '@addon/mod/assign/providers/default-feedback-handler'; +import { AddonModAssignBaseFeedbackHandler } from '@addon/mod/assign/classes/base-feedback-handler'; import { CoreSitePluginsAssignFeedbackComponent } from '../../components/assign-feedback/assign-feedback'; /** * Handler to display an assign feedback site plugin. */ -export class CoreSitePluginsAssignFeedbackHandler extends AddonModAssignDefaultFeedbackHandler { +export class CoreSitePluginsAssignFeedbackHandler extends AddonModAssignBaseFeedbackHandler { constructor(translate: TranslateService, public name: string, public type: string, protected prefix: string) { super(translate); diff --git a/src/core/siteplugins/classes/handlers/assign-submission-handler.ts b/src/core/siteplugins/classes/handlers/assign-submission-handler.ts index c02a3cd7d..9658a370e 100644 --- a/src/core/siteplugins/classes/handlers/assign-submission-handler.ts +++ b/src/core/siteplugins/classes/handlers/assign-submission-handler.ts @@ -14,13 +14,13 @@ import { Injector } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; -import { AddonModAssignDefaultSubmissionHandler } from '@addon/mod/assign/providers/default-submission-handler'; +import { AddonModAssignBaseSubmissionHandler } from '@addon/mod/assign/classes/base-submission-handler'; import { CoreSitePluginsAssignSubmissionComponent } from '../../components/assign-submission/assign-submission'; /** * Handler to display an assign submission site plugin. */ -export class CoreSitePluginsAssignSubmissionHandler extends AddonModAssignDefaultSubmissionHandler { +export class CoreSitePluginsAssignSubmissionHandler extends AddonModAssignBaseSubmissionHandler { constructor(translate: TranslateService, public name: string, public type: string, protected prefix: string) { super(translate); diff --git a/src/core/siteplugins/classes/handlers/question-behaviour-handler.ts b/src/core/siteplugins/classes/handlers/question-behaviour-handler.ts index 5352f6a67..1b7a8372f 100644 --- a/src/core/siteplugins/classes/handlers/question-behaviour-handler.ts +++ b/src/core/siteplugins/classes/handlers/question-behaviour-handler.ts @@ -13,14 +13,14 @@ // limitations under the License. import { Injector } from '@angular/core'; -import { CoreQuestionBehaviourDefaultHandler } from '@core/question/providers/default-behaviour-handler'; +import { CoreQuestionBehaviourBaseHandler } from '@core/question/classes/base-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 { +export class CoreSitePluginsQuestionBehaviourHandler extends CoreQuestionBehaviourBaseHandler { constructor(questionProvider: CoreQuestionProvider, public name: string, public type: string, public hasTemplate: boolean) { super(questionProvider); diff --git a/src/core/siteplugins/classes/handlers/question-handler.ts b/src/core/siteplugins/classes/handlers/question-handler.ts index 7e9b128c7..b0be9ed6a 100644 --- a/src/core/siteplugins/classes/handlers/question-handler.ts +++ b/src/core/siteplugins/classes/handlers/question-handler.ts @@ -13,13 +13,13 @@ // limitations under the License. import { Injector } from '@angular/core'; -import { CoreQuestionDefaultHandler } from '@core/question/providers/default-question-handler'; +import { CoreQuestionBaseHandler } from '@core/question/classes/base-question-handler'; import { CoreSitePluginsQuestionComponent } from '../../components/question/question'; /** * Handler to display a question site plugin. */ -export class CoreSitePluginsQuestionHandler extends CoreQuestionDefaultHandler { +export class CoreSitePluginsQuestionHandler extends CoreQuestionBaseHandler { constructor(public name: string, public type: string) { super(); diff --git a/src/core/siteplugins/classes/handlers/quiz-access-rule-handler.ts b/src/core/siteplugins/classes/handlers/quiz-access-rule-handler.ts index e877c9a28..5ddf618f3 100644 --- a/src/core/siteplugins/classes/handlers/quiz-access-rule-handler.ts +++ b/src/core/siteplugins/classes/handlers/quiz-access-rule-handler.ts @@ -13,17 +13,14 @@ // 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 { +export class CoreSitePluginsQuizAccessRuleHandler { - constructor(public name: string, public ruleName: string, public hasTemplate: boolean) { - super(); - } + constructor(public name: string, public ruleName: string, public hasTemplate: boolean) { } /** * Whether the rule requires a preflight check when prefetch/start/continue an attempt.