MOBILE-3109 assign: Add return types to assign
This commit is contained in:
		
							parent
							
								
									346c8a42ff
								
							
						
					
					
						commit
						7fc1c96b03
					
				| @ -15,6 +15,7 @@ | |||||||
| import { Injector } from '@angular/core'; | import { Injector } from '@angular/core'; | ||||||
| import { TranslateService } from '@ngx-translate/core'; | import { TranslateService } from '@ngx-translate/core'; | ||||||
| import { AddonModAssignFeedbackHandler } from '../providers/feedback-delegate'; | import { AddonModAssignFeedbackHandler } from '../providers/feedback-delegate'; | ||||||
|  | import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin } from '../providers/assign'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Base handler for feedback plugins. |  * Base handler for feedback plugins. | ||||||
| @ -48,7 +49,7 @@ export class AddonModAssignBaseFeedbackHandler implements AddonModAssignFeedback | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent(injector: Injector, plugin: any): any | Promise<any> { |     getComponent(injector: Injector, plugin: AddonModAssignPlugin): any | Promise<any> { | ||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -74,7 +75,8 @@ export class AddonModAssignBaseFeedbackHandler implements AddonModAssignFeedback | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The files (or promise resolved with the files). |      * @return The files (or promise resolved with the files). | ||||||
|      */ |      */ | ||||||
|     getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]> { |     getPluginFiles(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): any[] | Promise<any[]> { | ||||||
|         return []; |         return []; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -84,7 +86,7 @@ export class AddonModAssignBaseFeedbackHandler implements AddonModAssignFeedback | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The plugin name. |      * @return The plugin name. | ||||||
|      */ |      */ | ||||||
|     getPluginName(plugin: any): string { |     getPluginName(plugin: AddonModAssignPlugin): string { | ||||||
|         // Check if there's a translated string for the plugin.
 |         // Check if there's a translated string for the plugin.
 | ||||||
|         const translationId = 'addon.mod_assign_feedback_' + plugin.type + '.pluginname', |         const translationId = 'addon.mod_assign_feedback_' + plugin.type + '.pluginname', | ||||||
|             translation = this.translate.instant(translationId); |             translation = this.translate.instant(translationId); | ||||||
| @ -109,7 +111,8 @@ export class AddonModAssignBaseFeedbackHandler implements AddonModAssignFeedback | |||||||
|      * @param inputData Data entered by the user for the feedback. |      * @param inputData Data entered by the user for the feedback. | ||||||
|      * @return Boolean (or promise resolved with boolean): whether the data has changed. |      * @return Boolean (or promise resolved with boolean): whether the data has changed. | ||||||
|      */ |      */ | ||||||
|     hasDataChanged(assign: any, submission: any, plugin: any, inputData: any): boolean | Promise<boolean> { |     hasDataChanged(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any, userId: number): boolean | Promise<boolean> { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -144,7 +147,8 @@ export class AddonModAssignBaseFeedbackHandler implements AddonModAssignFeedback | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise<any> { |     prefetch(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): Promise<any> { | ||||||
|         return Promise.resolve(); |         return Promise.resolve(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -158,7 +162,8 @@ export class AddonModAssignBaseFeedbackHandler implements AddonModAssignFeedback | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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> { |     prepareFeedbackData(assignId: number, userId: number, plugin: AddonModAssignPlugin, pluginData: any, | ||||||
|  |             siteId?: string): void | Promise<any> { | ||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -172,7 +177,8 @@ export class AddonModAssignBaseFeedbackHandler implements AddonModAssignFeedback | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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> { |     saveDraft(assignId: number, userId: number, plugin: AddonModAssignPlugin, data: any, siteId?: string) | ||||||
|  |             : void | Promise<any> { | ||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -15,6 +15,7 @@ | |||||||
| import { Injector } from '@angular/core'; | import { Injector } from '@angular/core'; | ||||||
| import { TranslateService } from '@ngx-translate/core'; | import { TranslateService } from '@ngx-translate/core'; | ||||||
| import { AddonModAssignSubmissionHandler } from '../providers/submission-delegate'; | import { AddonModAssignSubmissionHandler } from '../providers/submission-delegate'; | ||||||
|  | import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin } from '../providers/assign'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Base handler for submission plugins. |  * Base handler for submission plugins. | ||||||
| @ -38,7 +39,8 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. |      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. | ||||||
|      */ |      */ | ||||||
|     canEditOffline(assign: any, submission: any, plugin: any): boolean | Promise<boolean> { |     canEditOffline(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin): boolean | Promise<boolean> { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -50,7 +52,8 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      */ |      */ | ||||||
|     clearTmpData(assign: any, submission: any, plugin: any, inputData: any): void { |     clearTmpData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): void { | ||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -65,7 +68,8 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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> { |     copySubmissionData(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin, pluginData: any, | ||||||
|  |             userId?: number, siteId?: string): void | Promise<any> { | ||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -79,7 +83,8 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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> { |     deleteOfflineData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, offlineData: any, siteId?: string): void | Promise<any> { | ||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -92,7 +97,7 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param edit Whether the user is editing. |      * @param edit Whether the user is editing. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent(injector: Injector, plugin: any, edit?: boolean): any | Promise<any> { |     getComponent(injector: Injector, plugin: AddonModAssignPlugin, edit?: boolean): any | Promise<any> { | ||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -106,7 +111,8 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The files (or promise resolved with the files). |      * @return The files (or promise resolved with the files). | ||||||
|      */ |      */ | ||||||
|     getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]> { |     getPluginFiles(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): any[] | Promise<any[]> { | ||||||
|         return []; |         return []; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -116,7 +122,7 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The plugin name. |      * @return The plugin name. | ||||||
|      */ |      */ | ||||||
|     getPluginName(plugin: any): string { |     getPluginName(plugin: AddonModAssignPlugin): string { | ||||||
|         // Check if there's a translated string for the plugin.
 |         // Check if there's a translated string for the plugin.
 | ||||||
|         const translationId = 'addon.mod_assign_submission_' + plugin.type + '.pluginname', |         const translationId = 'addon.mod_assign_submission_' + plugin.type + '.pluginname', | ||||||
|             translation = this.translate.instant(translationId); |             translation = this.translate.instant(translationId); | ||||||
| @ -139,7 +145,7 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The size (or promise resolved with size). |      * @return The size (or promise resolved with size). | ||||||
|      */ |      */ | ||||||
|     getSizeForCopy(assign: any, plugin: any): number | Promise<number> { |     getSizeForCopy(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin): number | Promise<number> { | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -147,10 +153,12 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * Get the size of data (in bytes) this plugin will send to add or edit a submission. |      * Get the size of data (in bytes) this plugin will send to add or edit a submission. | ||||||
|      * |      * | ||||||
|      * @param assign The assignment. |      * @param assign The assignment. | ||||||
|  |      * @param submission The submission. | ||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The size (or promise resolved with size). |      * @return The size (or promise resolved with size). | ||||||
|      */ |      */ | ||||||
|     getSizeForEdit(assign: any, plugin: any): number | Promise<number> { |     getSizeForEdit(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): number | Promise<number> { | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -163,7 +171,8 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      * @return Boolean (or promise resolved with boolean): whether the data has changed. |      * @return Boolean (or promise resolved with boolean): whether the data has changed. | ||||||
|      */ |      */ | ||||||
|     hasDataChanged(assign: any, submission: any, plugin: any, inputData: any): boolean | Promise<boolean> { |     hasDataChanged(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): boolean | Promise<boolean> { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -194,7 +203,8 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise<any> { |     prefetch?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): Promise<any> { | ||||||
|         return Promise.resolve(); |         return Promise.resolve(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -211,7 +221,8 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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, |     prepareSubmissionData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any, pluginData: any, offline?: boolean, | ||||||
|             userId?: number, siteId?: string): void | Promise<any> { |             userId?: number, siteId?: string): void | Promise<any> { | ||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| @ -228,8 +239,8 @@ export class AddonModAssignBaseSubmissionHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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) |     prepareSyncData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|             : void | Promise<any> { |             plugin: AddonModAssignPlugin, offlineData: any, pluginData: any, siteId?: string): void | Promise<any> { | ||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -14,14 +14,15 @@ | |||||||
| 
 | 
 | ||||||
| import { Input } from '@angular/core'; | import { Input } from '@angular/core'; | ||||||
| import { ModalController } from 'ionic-angular'; | import { ModalController } from 'ionic-angular'; | ||||||
|  | import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin } from '../providers/assign'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Base class for component to render a feedback plugin. |  * Base class for component to render a feedback plugin. | ||||||
|  */ |  */ | ||||||
| export class AddonModAssignFeedbackPluginComponentBase { | export class AddonModAssignFeedbackPluginComponentBase { | ||||||
|     @Input() assign: any; // The assignment.
 |     @Input() assign: AddonModAssignAssign; // The assignment.
 | ||||||
|     @Input() submission: any; // The submission.
 |     @Input() submission: AddonModAssignSubmission; // The submission.
 | ||||||
|     @Input() plugin: any; // The plugin object.
 |     @Input() plugin: AddonModAssignPlugin; // The plugin object.
 | ||||||
|     @Input() userId: number; // The user ID of the submission.
 |     @Input() userId: number; // The user ID of the submission.
 | ||||||
|     @Input() configs: any; // The configs for the plugin.
 |     @Input() configs: any; // The configs for the plugin.
 | ||||||
|     @Input() canEdit: boolean; // Whether the user can edit.
 |     @Input() canEdit: boolean; // Whether the user can edit.
 | ||||||
|  | |||||||
| @ -13,15 +13,16 @@ | |||||||
| // limitations under the License.
 | // limitations under the License.
 | ||||||
| 
 | 
 | ||||||
| import { Input } from '@angular/core'; | import { Input } from '@angular/core'; | ||||||
|  | import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin } from '../providers/assign'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Base class for component to render a submission plugin. |  * Base class for component to render a submission plugin. | ||||||
|  */ |  */ | ||||||
| export class AddonModAssignSubmissionPluginComponent { | export class AddonModAssignSubmissionPluginComponent { | ||||||
|     @Input() assign: any; // The assignment.
 |     @Input() assign: AddonModAssignAssign; // The assignment.
 | ||||||
|     @Input() submission: any; // The submission.
 |     @Input() submission: AddonModAssignSubmission; // The submission.
 | ||||||
|     @Input() plugin: any; // The plugin object.
 |     @Input() plugin: AddonModAssignPlugin; // The plugin object.
 | ||||||
|     @Input() configs: any; // The configs for the plugin.
 |     @Input() configs: {[name: string]: string}; // The configs for the plugin.
 | ||||||
|     @Input() edit: boolean; // Whether the user is editing.
 |     @Input() edit: boolean; // Whether the user is editing.
 | ||||||
|     @Input() allowOffline: boolean; // Whether to allow offline.
 |     @Input() allowOffline: boolean; // Whether to allow offline.
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -13,7 +13,9 @@ | |||||||
| // limitations under the License.
 | // limitations under the License.
 | ||||||
| 
 | 
 | ||||||
| import { Component, Input, OnInit, Injector, ViewChild } from '@angular/core'; | import { Component, Input, OnInit, Injector, ViewChild } from '@angular/core'; | ||||||
| import { AddonModAssignProvider } from '../../providers/assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin | ||||||
|  | } from '../../providers/assign'; | ||||||
| import { AddonModAssignHelperProvider } from '../../providers/helper'; | import { AddonModAssignHelperProvider } from '../../providers/helper'; | ||||||
| import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegate'; | import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegate'; | ||||||
| import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component'; | import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component'; | ||||||
| @ -28,9 +30,9 @@ import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-comp | |||||||
| export class AddonModAssignFeedbackPluginComponent implements OnInit { | export class AddonModAssignFeedbackPluginComponent implements OnInit { | ||||||
|     @ViewChild(CoreDynamicComponent) dynamicComponent: CoreDynamicComponent; |     @ViewChild(CoreDynamicComponent) dynamicComponent: CoreDynamicComponent; | ||||||
| 
 | 
 | ||||||
|     @Input() assign: any; // The assignment.
 |     @Input() assign: AddonModAssignAssign; // The assignment.
 | ||||||
|     @Input() submission: any; // The submission.
 |     @Input() submission: AddonModAssignSubmission; // The submission.
 | ||||||
|     @Input() plugin: any; // The plugin object.
 |     @Input() plugin: AddonModAssignPlugin; // The plugin object.
 | ||||||
|     @Input() userId: number; // The user ID of the submission.
 |     @Input() userId: number; // The user ID of the submission.
 | ||||||
|     @Input() canEdit: boolean | string; // Whether the user can edit.
 |     @Input() canEdit: boolean | string; // Whether the user can edit.
 | ||||||
|     @Input() edit: boolean | string; // Whether the user is editing.
 |     @Input() edit: boolean | string; // Whether the user is editing.
 | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ import { Content, NavController } from 'ionic-angular'; | |||||||
| import { CoreGroupsProvider, CoreGroupInfo } from '@providers/groups'; | import { CoreGroupsProvider, CoreGroupInfo } from '@providers/groups'; | ||||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||||
| import { CoreCourseModuleMainActivityComponent } from '@core/course/classes/main-activity-component'; | import { CoreCourseModuleMainActivityComponent } from '@core/course/classes/main-activity-component'; | ||||||
| import { AddonModAssignProvider } from '../../providers/assign'; | import { AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmissionGradingSummary } from '../../providers/assign'; | ||||||
| import { AddonModAssignHelperProvider } from '../../providers/helper'; | import { AddonModAssignHelperProvider } from '../../providers/helper'; | ||||||
| import { AddonModAssignOfflineProvider } from '../../providers/assign-offline'; | import { AddonModAssignOfflineProvider } from '../../providers/assign-offline'; | ||||||
| import { AddonModAssignSyncProvider } from '../../providers/assign-sync'; | import { AddonModAssignSyncProvider } from '../../providers/assign-sync'; | ||||||
| @ -36,13 +36,13 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo | |||||||
|     component = AddonModAssignProvider.COMPONENT; |     component = AddonModAssignProvider.COMPONENT; | ||||||
|     moduleName = 'assign'; |     moduleName = 'assign'; | ||||||
| 
 | 
 | ||||||
|     assign: any; // The assign object.
 |     assign: AddonModAssignAssign; // The assign object.
 | ||||||
|     canViewAllSubmissions: boolean; // Whether the user can view all submissions.
 |     canViewAllSubmissions: boolean; // Whether the user can view all submissions.
 | ||||||
|     canViewOwnSubmission: boolean; // Whether the user can view their own submission.
 |     canViewOwnSubmission: boolean; // Whether the user can view their own submission.
 | ||||||
|     timeRemaining: string; // Message about time remaining to submit.
 |     timeRemaining: string; // Message about time remaining to submit.
 | ||||||
|     lateSubmissions: string; // Message about late submissions.
 |     lateSubmissions: string; // Message about late submissions.
 | ||||||
|     showNumbers = true; // Whether to show number of submissions with each status.
 |     showNumbers = true; // Whether to show number of submissions with each status.
 | ||||||
|     summary: any; // The summary.
 |     summary: AddonModAssignSubmissionGradingSummary; // The grading summary.
 | ||||||
|     needsGradingAvalaible: boolean; // Whether we can see the submissions that need grading.
 |     needsGradingAvalaible: boolean; // Whether we can see the submissions that need grading.
 | ||||||
| 
 | 
 | ||||||
|     groupInfo: CoreGroupInfo = { |     groupInfo: CoreGroupInfo = { | ||||||
| @ -153,7 +153,7 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo | |||||||
|             this.assign = assignData; |             this.assign = assignData; | ||||||
| 
 | 
 | ||||||
|             this.dataRetrieved.emit(this.assign); |             this.dataRetrieved.emit(this.assign); | ||||||
|             this.description = this.assign.intro || this.description; |             this.description = this.assign.intro; | ||||||
| 
 | 
 | ||||||
|             if (sync) { |             if (sync) { | ||||||
|                 // Try to synchronize the assign.
 |                 // Try to synchronize the assign.
 | ||||||
|  | |||||||
| @ -13,7 +13,9 @@ | |||||||
| // limitations under the License.
 | // limitations under the License.
 | ||||||
| 
 | 
 | ||||||
| import { Component, Input, OnInit, Injector, ViewChild } from '@angular/core'; | import { Component, Input, OnInit, Injector, ViewChild } from '@angular/core'; | ||||||
| import { AddonModAssignProvider } from '../../providers/assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin | ||||||
|  | } from '../../providers/assign'; | ||||||
| import { AddonModAssignHelperProvider } from '../../providers/helper'; | import { AddonModAssignHelperProvider } from '../../providers/helper'; | ||||||
| import { AddonModAssignSubmissionDelegate } from '../../providers/submission-delegate'; | import { AddonModAssignSubmissionDelegate } from '../../providers/submission-delegate'; | ||||||
| import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component'; | import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component'; | ||||||
| @ -28,9 +30,9 @@ import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-comp | |||||||
| export class AddonModAssignSubmissionPluginComponent implements OnInit { | export class AddonModAssignSubmissionPluginComponent implements OnInit { | ||||||
|     @ViewChild(CoreDynamicComponent) dynamicComponent: CoreDynamicComponent; |     @ViewChild(CoreDynamicComponent) dynamicComponent: CoreDynamicComponent; | ||||||
| 
 | 
 | ||||||
|     @Input() assign: any; // The assignment.
 |     @Input() assign: AddonModAssignAssign; // The assignment.
 | ||||||
|     @Input() submission: any; // The submission.
 |     @Input() submission: AddonModAssignSubmission; // The submission.
 | ||||||
|     @Input() plugin: any; // The plugin object.
 |     @Input() plugin: AddonModAssignPlugin; // The plugin object.
 | ||||||
|     @Input() edit: boolean | string; // Whether the user is editing.
 |     @Input() edit: boolean | string; // Whether the user is editing.
 | ||||||
|     @Input() allowOffline: boolean | string; // Whether to allow offline.
 |     @Input() allowOffline: boolean | string; // Whether to allow offline.
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -29,7 +29,10 @@ import { CoreCourseProvider } from '@core/course/providers/course'; | |||||||
| import { CoreFileUploaderHelperProvider } from '@core/fileuploader/providers/helper'; | import { CoreFileUploaderHelperProvider } from '@core/fileuploader/providers/helper'; | ||||||
| import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; | import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; | ||||||
| import { CoreUserProvider } from '@core/user/providers/user'; | import { CoreUserProvider } from '@core/user/providers/user'; | ||||||
| import { AddonModAssignProvider } from '../../providers/assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmissionFeedback, AddonModAssignSubmission, | ||||||
|  |     AddonModAssignSubmissionAttempt, AddonModAssignSubmissionPreviousAttempt, AddonModAssignPlugin | ||||||
|  | } from '../../providers/assign'; | ||||||
| import { AddonModAssignHelperProvider } from '../../providers/helper'; | import { AddonModAssignHelperProvider } from '../../providers/helper'; | ||||||
| import { AddonModAssignOfflineProvider } from '../../providers/assign-offline'; | import { AddonModAssignOfflineProvider } from '../../providers/assign-offline'; | ||||||
| import { CoreTabsComponent } from '@components/tabs/tabs'; | import { CoreTabsComponent } from '@components/tabs/tabs'; | ||||||
| @ -55,11 +58,11 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
| 
 | 
 | ||||||
|     loaded: boolean; // Whether data has been loaded.
 |     loaded: boolean; // Whether data has been loaded.
 | ||||||
|     selectedTab: number; // Tab selected on start.
 |     selectedTab: number; // Tab selected on start.
 | ||||||
|     assign: any; // The assignment the submission belongs to.
 |     assign: AddonModAssignAssign; // The assignment the submission belongs to.
 | ||||||
|     userSubmission: any; // The submission object.
 |     userSubmission: AddonModAssignSubmission; // The submission object.
 | ||||||
|     isSubmittedForGrading: boolean; // Whether the submission has been submitted for grading.
 |     isSubmittedForGrading: boolean; // Whether the submission has been submitted for grading.
 | ||||||
|     submitModel: any = {}; // Model where to store the data to submit (for grading).
 |     submitModel: any = {}; // Model where to store the data to submit (for grading).
 | ||||||
|     feedback: any; // The feedback.
 |     feedback: AddonModAssignSubmissionFeedbackFormatted; // The feedback.
 | ||||||
|     hasOffline: boolean; // Whether there is offline data.
 |     hasOffline: boolean; // Whether there is offline data.
 | ||||||
|     submittedOffline: boolean; // Whether it was submitted in offline.
 |     submittedOffline: boolean; // Whether it was submitted in offline.
 | ||||||
|     fromDate: string; // Readable date when the assign started accepting submissions.
 |     fromDate: string; // Readable date when the assign started accepting submissions.
 | ||||||
| @ -67,7 +70,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|     maxAttemptsText: string; // The text for maximum attempts.
 |     maxAttemptsText: string; // The text for maximum attempts.
 | ||||||
|     blindMarking: boolean; // Whether blind marking is enabled.
 |     blindMarking: boolean; // Whether blind marking is enabled.
 | ||||||
|     user: any; // The user.
 |     user: any; // The user.
 | ||||||
|     lastAttempt: any; // The last attempt.
 |     lastAttempt: AddonModAssignSubmissionAttemptFormatted; // The last attempt.
 | ||||||
|     membersToSubmit: any[]; // Team members that need to submit the assignment.
 |     membersToSubmit: any[]; // Team members that need to submit the assignment.
 | ||||||
|     canSubmit: boolean; // Whether the user can submit for grading.
 |     canSubmit: boolean; // Whether the user can submit for grading.
 | ||||||
|     canEdit: boolean; // Whether the user can edit the submission.
 |     canEdit: boolean; // Whether the user can edit the submission.
 | ||||||
| @ -77,7 +80,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|     gradingStatusTranslationId: string; // Key of the text to display for the grading status.
 |     gradingStatusTranslationId: string; // Key of the text to display for the grading status.
 | ||||||
|     gradingColor: string; // Color to apply to the grading status.
 |     gradingColor: string; // Color to apply to the grading status.
 | ||||||
|     workflowStatusTranslationId: string; // Key of the text to display for the workflow status.
 |     workflowStatusTranslationId: string; // Key of the text to display for the workflow status.
 | ||||||
|     submissionPlugins: string[]; // List of submission plugins names.
 |     submissionPlugins: AddonModAssignPlugin[]; // List of submission plugins.
 | ||||||
|     timeRemaining: string; // Message about time remaining.
 |     timeRemaining: string; // Message about time remaining.
 | ||||||
|     timeRemainingClass: string; // Class to apply to time remaining message.
 |     timeRemainingClass: string; // Class to apply to time remaining message.
 | ||||||
|     statusTranslated: string; // Status.
 |     statusTranslated: string; // Status.
 | ||||||
| @ -99,7 +102,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
| 
 | 
 | ||||||
|     protected siteId: string; // Current site ID.
 |     protected siteId: string; // Current site ID.
 | ||||||
|     protected currentUserId: number; // Current user ID.
 |     protected currentUserId: number; // Current user ID.
 | ||||||
|     protected previousAttempt: any; // The previous attempt.
 |     protected previousAttempt: AddonModAssignSubmissionPreviousAttempt; // The previous attempt.
 | ||||||
|     protected submissionStatusAvailable: boolean; // Whether we were able to retrieve the submission status.
 |     protected submissionStatusAvailable: boolean; // Whether we were able to retrieve the submission status.
 | ||||||
|     protected originalGrades: any = {}; // Object with the original grade data, to check for changes.
 |     protected originalGrades: any = {}; // Object with the original grade data, to check for changes.
 | ||||||
|     protected isDestroyed: boolean; // Whether the component has been destroyed.
 |     protected isDestroyed: boolean; // Whether the component has been destroyed.
 | ||||||
| @ -209,7 +212,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|             return this.goToEdit(); |             return this.goToEdit(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const previousSubmission = this.assignProvider.getSubmissionObjectFromAttempt(this.assign, this.previousAttempt); |         const previousSubmission = this.previousAttempt.submission; | ||||||
|         let modal = this.domUtils.showModalLoading(); |         let modal = this.domUtils.showModalLoading(); | ||||||
| 
 | 
 | ||||||
|         this.assignHelper.getSubmissionSizeForCopy(this.assign, previousSubmission).catch(() => { |         this.assignHelper.getSubmissionSizeForCopy(this.assign, previousSubmission).catch(() => { | ||||||
| @ -303,7 +306,8 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (this.feedback && this.feedback.plugins) { |         if (this.feedback && this.feedback.plugins) { | ||||||
|             return this.assignHelper.hasFeedbackDataChanged(this.assign, this.submitId, this.feedback).catch(() => { |             return this.assignHelper.hasFeedbackDataChanged(this.assign, this.userSubmission, this.feedback, this.submitId) | ||||||
|  |                     .catch(() => { | ||||||
|                 // Error ocurred, consider there are no changes.
 |                 // Error ocurred, consider there are no changes.
 | ||||||
|                 return false; |                 return false; | ||||||
|             }); |             }); | ||||||
| @ -438,7 +442,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|             // Check if there's any unsupported plugin for editing.
 |             // Check if there's any unsupported plugin for editing.
 | ||||||
|             if (!this.userSubmission || !this.userSubmission.plugins) { |             if (!this.userSubmission || !this.userSubmission.plugins) { | ||||||
|                 // Submission not created yet, we have to use assign configs to detect the plugins used.
 |                 // Submission not created yet, we have to use assign configs to detect the plugins used.
 | ||||||
|                 this.userSubmission = {}; |                 this.userSubmission = this.assignHelper.createEmptySubmission(); | ||||||
|                 this.userSubmission.plugins = this.assignHelper.getPluginsEnabled(this.assign, 'assignsubmission'); |                 this.userSubmission.plugins = this.assignHelper.getPluginsEnabled(this.assign, 'assignsubmission'); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -461,7 +465,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|      * @param feedback The feedback data from the submission status. |      * @param feedback The feedback data from the submission status. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     protected loadFeedback(feedback: any): Promise<any> { |     protected loadFeedback(feedback: AddonModAssignSubmissionFeedback): Promise<any> { | ||||||
|         this.grade = { |         this.grade = { | ||||||
|             method: false, |             method: false, | ||||||
|             grade: false, |             grade: false, | ||||||
| @ -571,7 +575,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
| 
 | 
 | ||||||
|             if (!this.feedback || !this.feedback.plugins) { |             if (!this.feedback || !this.feedback.plugins) { | ||||||
|                 // Feedback plugins not present, we have to use assign configs to detect the plugins used.
 |                 // Feedback plugins not present, we have to use assign configs to detect the plugins used.
 | ||||||
|                 this.feedback = {}; |                 this.feedback = this.assignHelper.createEmptyFeedback(); | ||||||
|                 this.feedback.plugins = this.assignHelper.getPluginsEnabled(this.assign, 'assignfeedback'); |                 this.feedback.plugins = this.assignHelper.getPluginsEnabled(this.assign, 'assignfeedback'); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -885,7 +889,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|         // Show error if submission statement should be shown but it couldn't be retrieved.
 |         // Show error if submission statement should be shown but it couldn't be retrieved.
 | ||||||
|         this.showErrorStatementEdit = submissionStatementMissing && !this.assign.submissiondrafts && |         this.showErrorStatementEdit = submissionStatementMissing && !this.assign.submissiondrafts && | ||||||
|                 this.submitId == this.currentUserId; |                 this.submitId == this.currentUserId; | ||||||
|         this.showErrorStatementSubmit = submissionStatementMissing && this.assign.submissiondrafts; |         this.showErrorStatementSubmit = submissionStatementMissing && !!this.assign.submissiondrafts; | ||||||
| 
 | 
 | ||||||
|         this.userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(this.assign, response.lastattempt); |         this.userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(this.assign, response.lastattempt); | ||||||
| 
 | 
 | ||||||
| @ -954,3 +958,17 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Submission attempt with some calculated data. | ||||||
|  |  */ | ||||||
|  | type AddonModAssignSubmissionAttemptFormatted = AddonModAssignSubmissionAttempt & { | ||||||
|  |     submissiongroupname?: string; // Calculated in the app. Group name the attempt belongs to.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Feedback of an assign submission with some calculated data. | ||||||
|  |  */ | ||||||
|  | type AddonModAssignSubmissionFeedbackFormatted = AddonModAssignSubmissionFeedback & { | ||||||
|  |     advancedgrade?: boolean; // Calculated in the app. Whether it uses advanced grading.
 | ||||||
|  | }; | ||||||
|  | |||||||
| @ -16,7 +16,9 @@ | |||||||
| import { Injectable, Injector } from '@angular/core'; | import { Injectable, Injector } from '@angular/core'; | ||||||
| import { CoreSitesProvider } from '@providers/sites'; | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||||
| import { AddonModAssignProvider } from '../../../providers/assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin | ||||||
|  | } from '../../../providers/assign'; | ||||||
| import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline'; | import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline'; | ||||||
| import { AddonModAssignFeedbackHandler } from '../../../providers/feedback-delegate'; | import { AddonModAssignFeedbackHandler } from '../../../providers/feedback-delegate'; | ||||||
| import { AddonModAssignFeedbackCommentsComponent } from '../component/comments'; | import { AddonModAssignFeedbackCommentsComponent } from '../component/comments'; | ||||||
| @ -50,14 +52,14 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Return the Component to use to display the plugin data, either in read or in edit mode. |      * 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. |      * It's recommended to return the class of the component, but you can also return an instance of the component. | ||||||
|      * |      * | ||||||
|      * @param injector Injector. |      * @param injector Injector. | ||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent(injector: Injector, plugin: any): any | Promise<any> { |     getComponent(injector: Injector, plugin: AddonModAssignPlugin): any | Promise<any> { | ||||||
|         return AddonModAssignFeedbackCommentsComponent; |         return AddonModAssignFeedbackCommentsComponent; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -101,7 +103,8 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The files (or promise resolved with the files). |      * @return The files (or promise resolved with the files). | ||||||
|      */ |      */ | ||||||
|     getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]> { |     getPluginFiles(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): any[] | Promise<any[]> { | ||||||
|         return this.assignProvider.getSubmissionPluginAttachments(plugin); |         return this.assignProvider.getSubmissionPluginAttachments(plugin); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -135,7 +138,9 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed | |||||||
|      * @param userId User ID of the submission. |      * @param userId User ID of the submission. | ||||||
|      * @return Boolean (or promise resolved with boolean): whether the data has changed. |      * @return Boolean (or promise resolved with boolean): whether the data has changed. | ||||||
|      */ |      */ | ||||||
|     hasDataChanged(assign: any, submission: any, plugin: any, inputData: any, userId: number): boolean | Promise<boolean> { |     hasDataChanged(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any, userId: number): boolean | Promise<boolean> { | ||||||
|  | 
 | ||||||
|         // Get it from plugin or offline.
 |         // Get it from plugin or offline.
 | ||||||
|         return this.assignOfflineProvider.getSubmissionGrade(assign.id, userId).catch(() => { |         return this.assignOfflineProvider.getSubmissionGrade(assign.id, userId).catch(() => { | ||||||
|             // No offline data found.
 |             // No offline data found.
 | ||||||
| @ -191,7 +196,9 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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> { |     prepareFeedbackData(assignId: number, userId: number, plugin: AddonModAssignPlugin, pluginData: any, | ||||||
|  |             siteId?: string): void | Promise<any> { | ||||||
|  | 
 | ||||||
|         const draft = this.getDraft(assignId, userId, siteId); |         const draft = this.getDraft(assignId, userId, siteId); | ||||||
| 
 | 
 | ||||||
|         if (draft) { |         if (draft) { | ||||||
| @ -212,7 +219,9 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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> { |     saveDraft(assignId: number, userId: number, plugin: AddonModAssignPlugin, data: any, siteId?: string) | ||||||
|  |             : void | Promise<any> { | ||||||
|  | 
 | ||||||
|         if (data) { |         if (data) { | ||||||
|             this.drafts[this.getDraftId(assignId, userId, siteId)] = data; |             this.drafts[this.getDraftId(assignId, userId, siteId)] = data; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -14,7 +14,9 @@ | |||||||
| // limitations under the License.
 | // limitations under the License.
 | ||||||
| 
 | 
 | ||||||
| import { Injectable, Injector } from '@angular/core'; | import { Injectable, Injector } from '@angular/core'; | ||||||
| import { AddonModAssignProvider } from '../../../providers/assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin | ||||||
|  | } from '../../../providers/assign'; | ||||||
| import { AddonModAssignFeedbackHandler } from '../../../providers/feedback-delegate'; | import { AddonModAssignFeedbackHandler } from '../../../providers/feedback-delegate'; | ||||||
| import { AddonModAssignFeedbackEditPdfComponent } from '../component/editpdf'; | import { AddonModAssignFeedbackEditPdfComponent } from '../component/editpdf'; | ||||||
| 
 | 
 | ||||||
| @ -29,14 +31,14 @@ export class AddonModAssignFeedbackEditPdfHandler implements AddonModAssignFeedb | |||||||
|     constructor(private assignProvider: AddonModAssignProvider) { } |     constructor(private assignProvider: AddonModAssignProvider) { } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Return the Component to use to display the plugin data, either in read or in edit mode. |      * 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. |      * It's recommended to return the class of the component, but you can also return an instance of the component. | ||||||
|      * |      * | ||||||
|      * @param injector Injector. |      * @param injector Injector. | ||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent(injector: Injector, plugin: any): any | Promise<any> { |     getComponent(injector: Injector, plugin: AddonModAssignPlugin): any | Promise<any> { | ||||||
|         return AddonModAssignFeedbackEditPdfComponent; |         return AddonModAssignFeedbackEditPdfComponent; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -50,7 +52,8 @@ export class AddonModAssignFeedbackEditPdfHandler implements AddonModAssignFeedb | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The files (or promise resolved with the files). |      * @return The files (or promise resolved with the files). | ||||||
|      */ |      */ | ||||||
|     getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]> { |     getPluginFiles(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): any[] | Promise<any[]> { | ||||||
|         return this.assignProvider.getSubmissionPluginAttachments(plugin); |         return this.assignProvider.getSubmissionPluginAttachments(plugin); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,7 +14,9 @@ | |||||||
| // limitations under the License.
 | // limitations under the License.
 | ||||||
| 
 | 
 | ||||||
| import { Injectable, Injector } from '@angular/core'; | import { Injectable, Injector } from '@angular/core'; | ||||||
| import { AddonModAssignProvider } from '../../../providers/assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin | ||||||
|  | } from '../../../providers/assign'; | ||||||
| import { AddonModAssignFeedbackHandler } from '../../../providers/feedback-delegate'; | import { AddonModAssignFeedbackHandler } from '../../../providers/feedback-delegate'; | ||||||
| import { AddonModAssignFeedbackFileComponent } from '../component/file'; | import { AddonModAssignFeedbackFileComponent } from '../component/file'; | ||||||
| 
 | 
 | ||||||
| @ -29,14 +31,14 @@ export class AddonModAssignFeedbackFileHandler implements AddonModAssignFeedback | |||||||
|     constructor(private assignProvider: AddonModAssignProvider) { } |     constructor(private assignProvider: AddonModAssignProvider) { } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Return the Component to use to display the plugin data, either in read or in edit mode. |      * 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. |      * It's recommended to return the class of the component, but you can also return an instance of the component. | ||||||
|      * |      * | ||||||
|      * @param injector Injector. |      * @param injector Injector. | ||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent(injector: Injector, plugin: any): any | Promise<any> { |     getComponent(injector: Injector, plugin: AddonModAssignPlugin): any | Promise<any> { | ||||||
|         return AddonModAssignFeedbackFileComponent; |         return AddonModAssignFeedbackFileComponent; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -50,7 +52,8 @@ export class AddonModAssignFeedbackFileHandler implements AddonModAssignFeedback | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The files (or promise resolved with the files). |      * @return The files (or promise resolved with the files). | ||||||
|      */ |      */ | ||||||
|     getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]> { |     getPluginFiles(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): any[] | Promise<any[]> { | ||||||
|         return this.assignProvider.getSubmissionPluginAttachments(plugin); |         return this.assignProvider.getSubmissionPluginAttachments(plugin); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -17,6 +17,9 @@ import { IonicPage, ViewController, NavParams } from 'ionic-angular'; | |||||||
| import { TranslateService } from '@ngx-translate/core'; | import { TranslateService } from '@ngx-translate/core'; | ||||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||||
| import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegate'; | import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegate'; | ||||||
|  | import { | ||||||
|  |     AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin | ||||||
|  | } from '../../providers/assign'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Modal that allows editing a feedback plugin. |  * Modal that allows editing a feedback plugin. | ||||||
| @ -28,9 +31,9 @@ import { AddonModAssignFeedbackDelegate } from '../../providers/feedback-delegat | |||||||
| }) | }) | ||||||
| export class AddonModAssignEditFeedbackModalPage { | export class AddonModAssignEditFeedbackModalPage { | ||||||
| 
 | 
 | ||||||
|     @Input() assign: any; // The assignment.
 |     @Input() assign: AddonModAssignAssign; // The assignment.
 | ||||||
|     @Input() submission: any; // The submission.
 |     @Input() submission: AddonModAssignSubmission; // The submission.
 | ||||||
|     @Input() plugin: any; // The plugin object.
 |     @Input() plugin: AddonModAssignPlugin; // The plugin object.
 | ||||||
|     @Input() userId: number; // The user ID of the submission.
 |     @Input() userId: number; // The user ID of the submission.
 | ||||||
| 
 | 
 | ||||||
|     protected forceLeave = false; // To allow leaving the page without checking for changes.
 |     protected forceLeave = false; // To allow leaving the page without checking for changes.
 | ||||||
| @ -99,8 +102,8 @@ export class AddonModAssignEditFeedbackModalPage { | |||||||
|      * @return Promise resolved with boolean: whether the data has changed. |      * @return Promise resolved with boolean: whether the data has changed. | ||||||
|      */ |      */ | ||||||
|     protected hasDataChanged(): Promise<boolean> { |     protected hasDataChanged(): Promise<boolean> { | ||||||
|         return this.feedbackDelegate.hasPluginDataChanged(this.assign, this.userId, this.plugin, this.getInputData(), this.userId) |         return this.feedbackDelegate.hasPluginDataChanged(this.assign, this.submission, this.plugin, this.getInputData(), | ||||||
|                 .catch(() => { |                 this.userId).catch(() => { | ||||||
|             // Ignore errors.
 |             // Ignore errors.
 | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ import { CoreSitesProvider } from '@providers/sites'; | |||||||
| import { CoreSyncProvider } from '@providers/sync'; | import { CoreSyncProvider } from '@providers/sync'; | ||||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||||
| import { CoreFileUploaderHelperProvider } from '@core/fileuploader/providers/helper'; | import { CoreFileUploaderHelperProvider } from '@core/fileuploader/providers/helper'; | ||||||
| import { AddonModAssignProvider } from '../../providers/assign'; | import { AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission } from '../../providers/assign'; | ||||||
| import { AddonModAssignOfflineProvider } from '../../providers/assign-offline'; | import { AddonModAssignOfflineProvider } from '../../providers/assign-offline'; | ||||||
| import { AddonModAssignSyncProvider } from '../../providers/assign-sync'; | import { AddonModAssignSyncProvider } from '../../providers/assign-sync'; | ||||||
| import { AddonModAssignHelperProvider } from '../../providers/helper'; | import { AddonModAssignHelperProvider } from '../../providers/helper'; | ||||||
| @ -35,9 +35,9 @@ import { AddonModAssignHelperProvider } from '../../providers/helper'; | |||||||
| }) | }) | ||||||
| export class AddonModAssignEditPage implements OnInit, OnDestroy { | export class AddonModAssignEditPage implements OnInit, OnDestroy { | ||||||
|     title: string; // Title to display.
 |     title: string; // Title to display.
 | ||||||
|     assign: any; // Assignment.
 |     assign: AddonModAssignAssign; // Assignment.
 | ||||||
|     courseId: number; // Course ID the assignment belongs to.
 |     courseId: number; // Course ID the assignment belongs to.
 | ||||||
|     userSubmission: any; // The user submission.
 |     userSubmission: AddonModAssignSubmission; // The user submission.
 | ||||||
|     allowOffline: boolean; // Whether offline is allowed.
 |     allowOffline: boolean; // Whether offline is allowed.
 | ||||||
|     submissionStatement: string; // The submission statement.
 |     submissionStatement: string; // The submission statement.
 | ||||||
|     submissionStatementAccepted: boolean; // Whether submission statement is accepted.
 |     submissionStatementAccepted: boolean; // Whether submission statement is accepted.
 | ||||||
| @ -129,7 +129,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy { | |||||||
|                     const userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(this.assign, response.lastattempt); |                     const userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(this.assign, response.lastattempt); | ||||||
| 
 | 
 | ||||||
|                     // Check if the user can edit it in offline.
 |                     // Check if the user can edit it in offline.
 | ||||||
|                     return this.assignHelper.canEditSubmissionOffline(this.assign, userSubmission).then((canEditOffline) => { |                     return this.assignHelper.canEditSubmissionOffline(this.assign, userSubmission).then((canEditOffline): any => { | ||||||
|                         if (canEditOffline) { |                         if (canEditOffline) { | ||||||
|                             return response; |                             return response; | ||||||
|                         } |                         } | ||||||
| @ -301,7 +301,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy { | |||||||
|                 } else { |                 } else { | ||||||
|                     // Try to send it to server.
 |                     // Try to send it to server.
 | ||||||
|                     promise = this.assignProvider.saveSubmission(this.assign.id, this.courseId, pluginData, this.allowOffline, |                     promise = this.assignProvider.saveSubmission(this.assign.id, this.courseId, pluginData, this.allowOffline, | ||||||
|                             this.userSubmission.timemodified, this.assign.submissiondrafts, this.userId); |                             this.userSubmission.timemodified, !!this.assign.submissiondrafts, this.userId); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 return promise.then(() => { |                 return promise.then(() => { | ||||||
|  | |||||||
| @ -19,9 +19,11 @@ import { CoreEventsProvider } from '@providers/events'; | |||||||
| import { CoreSitesProvider } from '@providers/sites'; | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||||
| import { CoreGroupsProvider, CoreGroupInfo } from '@providers/groups'; | import { CoreGroupsProvider, CoreGroupInfo } from '@providers/groups'; | ||||||
| import { AddonModAssignProvider } from '../../providers/assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignGrade, AddonModAssignSubmission | ||||||
|  | } from '../../providers/assign'; | ||||||
| import { AddonModAssignOfflineProvider } from '../../providers/assign-offline'; | import { AddonModAssignOfflineProvider } from '../../providers/assign-offline'; | ||||||
| import { AddonModAssignHelperProvider } from '../../providers/helper'; | import { AddonModAssignHelperProvider, AddonModAssignSubmissionFormatted } from '../../providers/helper'; | ||||||
| import { CoreSplitViewComponent } from '@components/split-view/split-view'; | import { CoreSplitViewComponent } from '@components/split-view/split-view'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -36,7 +38,7 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy { | |||||||
|     @ViewChild(CoreSplitViewComponent) splitviewCtrl: CoreSplitViewComponent; |     @ViewChild(CoreSplitViewComponent) splitviewCtrl: CoreSplitViewComponent; | ||||||
| 
 | 
 | ||||||
|     title: string; // Title to display.
 |     title: string; // Title to display.
 | ||||||
|     assign: any; // Assignment.
 |     assign: AddonModAssignAssign; // Assignment.
 | ||||||
|     submissions: any[]; // List of submissions
 |     submissions: any[]; // List of submissions
 | ||||||
|     loaded: boolean; // Whether data has been loaded.
 |     loaded: boolean; // Whether data has been loaded.
 | ||||||
|     haveAllParticipants: boolean; // Whether all participants have been loaded.
 |     haveAllParticipants: boolean; // Whether all participants have been loaded.
 | ||||||
| @ -53,7 +55,7 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy { | |||||||
|     protected courseId: number; // Course ID the assignment belongs to.
 |     protected courseId: number; // Course ID the assignment belongs to.
 | ||||||
|     protected selectedStatus: string; // The status to see.
 |     protected selectedStatus: string; // The status to see.
 | ||||||
|     protected gradedObserver; // Observer to refresh data when a grade changes.
 |     protected gradedObserver; // Observer to refresh data when a grade changes.
 | ||||||
|     protected submissionsData: any; |     protected submissionsData: {canviewsubmissions: boolean, submissions?: AddonModAssignSubmission[]}; | ||||||
| 
 | 
 | ||||||
|     constructor(navParams: NavParams, protected sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, |     constructor(navParams: NavParams, protected sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, | ||||||
|             protected domUtils: CoreDomUtilsProvider, protected translate: TranslateService, |             protected domUtils: CoreDomUtilsProvider, protected translate: TranslateService, | ||||||
| @ -161,14 +163,14 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy { | |||||||
|             !this.assign.markingworkflow ? this.assignProvider.getAssignmentGrades(this.assign.id) : Promise.resolve(null), |             !this.assign.markingworkflow ? this.assignProvider.getAssignmentGrades(this.assign.id) : Promise.resolve(null), | ||||||
|         ]; |         ]; | ||||||
| 
 | 
 | ||||||
|         return Promise.all(promises).then(([submissions, grades]) => { |         return Promise.all(promises).then(([submissions, grades]: [AddonModAssignSubmissionFormatted[], AddonModAssignGrade[]]) => { | ||||||
|             // Filter the submissions to get only the ones with the right status and add some extra data.
 |             // Filter the submissions to get only the ones with the right status and add some extra data.
 | ||||||
|             const getNeedGrading = this.selectedStatus == AddonModAssignProvider.NEED_GRADING, |             const getNeedGrading = this.selectedStatus == AddonModAssignProvider.NEED_GRADING, | ||||||
|                 searchStatus = getNeedGrading ? AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED : this.selectedStatus, |                 searchStatus = getNeedGrading ? AddonModAssignProvider.SUBMISSION_STATUS_SUBMITTED : this.selectedStatus, | ||||||
|                 promises = [], |                 promises = [], | ||||||
|                 showSubmissions = []; |                 showSubmissions = []; | ||||||
| 
 | 
 | ||||||
|             submissions.forEach((submission) => { |             submissions.forEach((submission: AddonModAssignSubmissionForList) => { | ||||||
|                 if (!searchStatus || searchStatus == submission.status) { |                 if (!searchStatus || searchStatus == submission.status) { | ||||||
|                     promises.push(this.assignOfflineProvider.getSubmissionGrade(this.assign.id, submission.userid).catch(() => { |                     promises.push(this.assignOfflineProvider.getSubmissionGrade(this.assign.id, submission.userid).catch(() => { | ||||||
|                         // Ignore errors.
 |                         // Ignore errors.
 | ||||||
| @ -213,7 +215,7 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy { | |||||||
|                                 submission.statusTranslated = this.translate.instant('addon.mod_assign.submissionstatus_' + |                                 submission.statusTranslated = this.translate.instant('addon.mod_assign.submissionstatus_' + | ||||||
|                                     submission.status); |                                     submission.status); | ||||||
|                             } else { |                             } else { | ||||||
|                                 submission.statusTranslated = false; |                                 submission.statusTranslated = ''; | ||||||
|                             } |                             } | ||||||
| 
 | 
 | ||||||
|                             if (notSynced) { |                             if (notSynced) { | ||||||
| @ -224,7 +226,7 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy { | |||||||
|                                 submission.gradingStatusTranslationId = |                                 submission.gradingStatusTranslationId = | ||||||
|                                     this.assignProvider.getSubmissionGradingStatusTranslationId(submission.gradingstatus); |                                     this.assignProvider.getSubmissionGradingStatusTranslationId(submission.gradingstatus); | ||||||
|                             } else { |                             } else { | ||||||
|                                 submission.gradingStatusTranslationId = false; |                                 submission.gradingStatusTranslationId = ''; | ||||||
|                             } |                             } | ||||||
| 
 | 
 | ||||||
|                             showSubmissions.push(submission); |                             showSubmissions.push(submission); | ||||||
| @ -299,3 +301,13 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy { | |||||||
|         this.gradedObserver && this.gradedObserver.off(); |         this.gradedObserver && this.gradedObserver.off(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Calculated data for an assign submission. | ||||||
|  |  */ | ||||||
|  | type AddonModAssignSubmissionForList = AddonModAssignSubmissionFormatted & { | ||||||
|  |     statusColor?: string; // Calculated in the app. Color of the submission status.
 | ||||||
|  |     gradingColor?: string; // Calculated in the app. Color of the submission grading status.
 | ||||||
|  |     statusTranslated?: string; // Calculated in the app. Translated text of the submission status.
 | ||||||
|  |     gradingStatusTranslationId?: string; // Calculated in the app. Key of the text of the submission grading status.
 | ||||||
|  | }; | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ import { IonicPage, NavController, NavParams } from 'ionic-angular'; | |||||||
| import { CoreAppProvider } from '@providers/app'; | import { CoreAppProvider } from '@providers/app'; | ||||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||||
| import { CoreCourseProvider } from '@core/course/providers/course'; | import { CoreCourseProvider } from '@core/course/providers/course'; | ||||||
| import { AddonModAssignProvider } from '../../providers/assign'; | import { AddonModAssignProvider, AddonModAssignAssign } from '../../providers/assign'; | ||||||
| import { AddonModAssignSubmissionComponent } from '../../components/submission/submission'; | import { AddonModAssignSubmissionComponent } from '../../components/submission/submission'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -40,7 +40,7 @@ export class AddonModAssignSubmissionReviewPage implements OnInit { | |||||||
|     loaded: boolean; // Whether data has been loaded.
 |     loaded: boolean; // Whether data has been loaded.
 | ||||||
|     canSaveGrades: boolean; // Whether the user can save grades.
 |     canSaveGrades: boolean; // Whether the user can save grades.
 | ||||||
| 
 | 
 | ||||||
|     protected assign: any; // The assignment the submission belongs to.
 |     protected assign: AddonModAssignAssign; // The assignment the submission belongs to.
 | ||||||
|     protected blindMarking: boolean; // Whether it uses blind marking.
 |     protected blindMarking: boolean; // Whether it uses blind marking.
 | ||||||
|     protected forceLeave = false; // To allow leaving the page without checking for changes.
 |     protected forceLeave = false; // To allow leaving the page without checking for changes.
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -26,7 +26,7 @@ import { CoreCourseProvider } from '@core/course/providers/course'; | |||||||
| import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper'; | import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper'; | ||||||
| import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; | import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; | ||||||
| import { CoreSyncBaseProvider } from '@classes/base-sync'; | import { CoreSyncBaseProvider } from '@classes/base-sync'; | ||||||
| import { AddonModAssignProvider } from './assign'; | import { AddonModAssignProvider, AddonModAssignAssign } from './assign'; | ||||||
| import { AddonModAssignOfflineProvider } from './assign-offline'; | import { AddonModAssignOfflineProvider } from './assign-offline'; | ||||||
| import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | ||||||
| 
 | 
 | ||||||
| @ -169,14 +169,14 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { | |||||||
|     syncAssign(assignId: number, siteId?: string): Promise<AddonModAssignSyncResult> { |     syncAssign(assignId: number, siteId?: string): Promise<AddonModAssignSyncResult> { | ||||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); |         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||||
| 
 | 
 | ||||||
|         const promises = [], |         const promises: Promise<any>[] = [], | ||||||
|             result: AddonModAssignSyncResult = { |             result: AddonModAssignSyncResult = { | ||||||
|                 warnings: [], |                 warnings: [], | ||||||
|                 updated: false |                 updated: false | ||||||
|             }; |             }; | ||||||
|         let assign, |         let assign: AddonModAssignAssign, | ||||||
|             courseId, |             courseId: number, | ||||||
|             syncPromise; |             syncPromise: Promise<any>; | ||||||
| 
 | 
 | ||||||
|         if (this.isSyncing(assignId, siteId)) { |         if (this.isSyncing(assignId, siteId)) { | ||||||
|             // There's already a sync ongoing for this assign, return the promise.
 |             // There's already a sync ongoing for this assign, return the promise.
 | ||||||
| @ -269,7 +269,7 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved if success, rejected otherwise. |      * @return Promise resolved if success, rejected otherwise. | ||||||
|      */ |      */ | ||||||
|     protected syncSubmission(assign: any, offlineData: any, warnings: string[], siteId?: string): Promise<any> { |     protected syncSubmission(assign: AddonModAssignAssign, offlineData: any, warnings: string[], siteId?: string): Promise<any> { | ||||||
|         const userId = offlineData.userid, |         const userId = offlineData.userid, | ||||||
|             pluginData = {}; |             pluginData = {}; | ||||||
|         let discardError, |         let discardError, | ||||||
| @ -358,8 +358,8 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved if success, rejected otherwise. |      * @return Promise resolved if success, rejected otherwise. | ||||||
|      */ |      */ | ||||||
|     protected syncSubmissionGrade(assign: any, offlineData: any, warnings: string[], courseId: number, siteId?: string) |     protected syncSubmissionGrade(assign: AddonModAssignAssign, offlineData: any, warnings: string[], courseId: number, | ||||||
|             : Promise<any> { |             siteId?: string): Promise<any> { | ||||||
| 
 | 
 | ||||||
|         const userId = offlineData.userid; |         const userId = offlineData.userid; | ||||||
|         let discardError; |         let discardError; | ||||||
|  | |||||||
| @ -27,6 +27,7 @@ import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | |||||||
| import { AddonModAssignOfflineProvider } from './assign-offline'; | import { AddonModAssignOfflineProvider } from './assign-offline'; | ||||||
| import { CoreSite, CoreSiteWSPreSets } from '@classes/site'; | import { CoreSite, CoreSiteWSPreSets } from '@classes/site'; | ||||||
| import { CoreInterceptor } from '@classes/interceptor'; | import { CoreInterceptor } from '@classes/interceptor'; | ||||||
|  | import { CoreWSExternalWarning, CoreWSExternalFile } from '@providers/ws'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Service that provides some functions for assign. |  * Service that provides some functions for assign. | ||||||
| @ -123,7 +124,7 @@ export class AddonModAssignProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved with the assignment. |      * @return Promise resolved with the assignment. | ||||||
|      */ |      */ | ||||||
|     getAssignment(courseId: number, cmId: number, ignoreCache?: boolean, siteId?: string): Promise<any> { |     getAssignment(courseId: number, cmId: number, ignoreCache?: boolean, siteId?: string): Promise<AddonModAssignAssign> { | ||||||
|         return this.getAssignmentByField(courseId, 'cmid', cmId, ignoreCache, siteId); |         return this.getAssignmentByField(courseId, 'cmid', cmId, ignoreCache, siteId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -138,7 +139,7 @@ export class AddonModAssignProvider { | |||||||
|      * @return Promise resolved when the assignment is retrieved. |      * @return Promise resolved when the assignment is retrieved. | ||||||
|      */ |      */ | ||||||
|     protected getAssignmentByField(courseId: number, key: string, value: any, ignoreCache?: boolean, siteId?: string) |     protected getAssignmentByField(courseId: number, key: string, value: any, ignoreCache?: boolean, siteId?: string) | ||||||
|             : Promise<any> { |             : Promise<AddonModAssignAssign> { | ||||||
| 
 | 
 | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             const params = { |             const params = { | ||||||
| @ -161,7 +162,7 @@ export class AddonModAssignProvider { | |||||||
|                 delete params.includenotenrolledcourses; |                 delete params.includenotenrolledcourses; | ||||||
| 
 | 
 | ||||||
|                 return site.read('mod_assign_get_assignments', params, preSets); |                 return site.read('mod_assign_get_assignments', params, preSets); | ||||||
|             }).then((response) => { |             }).then((response: AddonModAssignGetAssignmentsResult): any => { | ||||||
|                 // Search the assignment to return.
 |                 // Search the assignment to return.
 | ||||||
|                 if (response.courses && response.courses.length) { |                 if (response.courses && response.courses.length) { | ||||||
|                     const assignments = response.courses[0].assignments; |                     const assignments = response.courses[0].assignments; | ||||||
| @ -187,7 +188,7 @@ export class AddonModAssignProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved with the assignment. |      * @return Promise resolved with the assignment. | ||||||
|      */ |      */ | ||||||
|     getAssignmentById(courseId: number, id: number, ignoreCache?: boolean, siteId?: string): Promise<any> { |     getAssignmentById(courseId: number, id: number, ignoreCache?: boolean, siteId?: string): Promise<AddonModAssignAssign> { | ||||||
|         return this.getAssignmentByField(courseId, 'id', id, ignoreCache, siteId); |         return this.getAssignmentByField(courseId, 'id', id, ignoreCache, siteId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -225,7 +226,9 @@ export class AddonModAssignProvider { | |||||||
|                 preSets.emergencyCache = false; |                 preSets.emergencyCache = false; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return site.read('mod_assign_get_user_mappings', params, preSets).then((response) => { |             return site.read('mod_assign_get_user_mappings', params, preSets) | ||||||
|  |                     .then((response: AddonModAssignGetUserMappingsResult): any => { | ||||||
|  | 
 | ||||||
|                 // Search the user.
 |                 // Search the user.
 | ||||||
|                 if (response.assignments && response.assignments.length) { |                 if (response.assignments && response.assignments.length) { | ||||||
|                     if (!userId || userId < 0) { |                     if (!userId || userId < 0) { | ||||||
| @ -271,7 +274,7 @@ export class AddonModAssignProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Resolved with requested info when done. |      * @return Resolved with requested info when done. | ||||||
|      */ |      */ | ||||||
|     getAssignmentGrades(assignId: number, ignoreCache?: boolean, siteId?: string): Promise<any> { |     getAssignmentGrades(assignId: number, ignoreCache?: boolean, siteId?: string): Promise<AddonModAssignGrade[]> { | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             const params = { |             const params = { | ||||||
|                     assignmentids: [assignId] |                     assignmentids: [assignId] | ||||||
| @ -285,7 +288,7 @@ export class AddonModAssignProvider { | |||||||
|                 preSets.emergencyCache = false; |                 preSets.emergencyCache = false; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return site.read('mod_assign_get_grades', params, preSets).then((response) => { |             return site.read('mod_assign_get_grades', params, preSets).then((response: AddonModAssignGetGradesResult): any => { | ||||||
|                 // Search the assignment.
 |                 // Search the assignment.
 | ||||||
|                 if (response.assignments && response.assignments.length) { |                 if (response.assignments && response.assignments.length) { | ||||||
|                     const assignment = response.assignments[0]; |                     const assignment = response.assignments[0]; | ||||||
| @ -294,7 +297,7 @@ export class AddonModAssignProvider { | |||||||
|                         return assignment.grades; |                         return assignment.grades; | ||||||
|                     } |                     } | ||||||
|                 } else if (response.warnings && response.warnings.length) { |                 } else if (response.warnings && response.warnings.length) { | ||||||
|                     if (response.warnings[0].warningcode == 3) { |                     if (response.warnings[0].warningcode == '3') { | ||||||
|                         // No grades found.
 |                         // No grades found.
 | ||||||
|                         return []; |                         return []; | ||||||
|                     } |                     } | ||||||
| @ -362,7 +365,9 @@ export class AddonModAssignProvider { | |||||||
|      * @param attempt Attempt. |      * @param attempt Attempt. | ||||||
|      * @return Submission object or null. |      * @return Submission object or null. | ||||||
|      */ |      */ | ||||||
|     getSubmissionObjectFromAttempt(assign: any, attempt: any): any { |     getSubmissionObjectFromAttempt(assign: AddonModAssignAssign, attempt: AddonModAssignSubmissionAttempt) | ||||||
|  |             : AddonModAssignSubmission { | ||||||
|  | 
 | ||||||
|         if (!attempt) { |         if (!attempt) { | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
| @ -432,7 +437,7 @@ export class AddonModAssignProvider { | |||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     getSubmissions(assignId: number, ignoreCache?: boolean, siteId?: string) |     getSubmissions(assignId: number, ignoreCache?: boolean, siteId?: string) | ||||||
|             : Promise<{canviewsubmissions: boolean, submissions?: any[]}> { |             : Promise<{canviewsubmissions: boolean, submissions?: AddonModAssignSubmission[]}> { | ||||||
| 
 | 
 | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             const params = { |             const params = { | ||||||
| @ -448,9 +453,11 @@ export class AddonModAssignProvider { | |||||||
|                 preSets.emergencyCache = false; |                 preSets.emergencyCache = false; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return site.read('mod_assign_get_submissions', params, preSets).then((response): any => { |             return site.read('mod_assign_get_submissions', params, preSets) | ||||||
|  |                     .then((response: AddonModAssignGetSubmissionsResult): any => { | ||||||
|  | 
 | ||||||
|                 // Check if we can view submissions, with enough permissions.
 |                 // Check if we can view submissions, with enough permissions.
 | ||||||
|                 if (response.warnings.length > 0 && response.warnings[0].warningcode == 1) { |                 if (response.warnings.length > 0 && response.warnings[0].warningcode == '1') { | ||||||
|                     return {canviewsubmissions: false}; |                     return {canviewsubmissions: false}; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
| @ -489,7 +496,7 @@ export class AddonModAssignProvider { | |||||||
|      * @return Promise always resolved with the user submission status. |      * @return Promise always resolved with the user submission status. | ||||||
|      */ |      */ | ||||||
|     getSubmissionStatus(assignId: number, userId?: number, groupId?: number, isBlind?: boolean, filter: boolean = true, |     getSubmissionStatus(assignId: number, userId?: number, groupId?: number, isBlind?: boolean, filter: boolean = true, | ||||||
|             ignoreCache?: boolean, siteId?: string): Promise<any> { |             ignoreCache?: boolean, siteId?: string): Promise<AddonModAssignGetSubmissionStatusResult> { | ||||||
| 
 | 
 | ||||||
|         userId = userId || 0; |         userId = userId || 0; | ||||||
| 
 | 
 | ||||||
| @ -540,7 +547,7 @@ export class AddonModAssignProvider { | |||||||
|      * @return Promise always resolved with the user submission status. |      * @return Promise always resolved with the user submission status. | ||||||
|      */ |      */ | ||||||
|     getSubmissionStatusWithRetry(assign: any, userId?: number, groupId?: number, isBlind?: boolean, filter: boolean = true, |     getSubmissionStatusWithRetry(assign: any, userId?: number, groupId?: number, isBlind?: boolean, filter: boolean = true, | ||||||
|             ignoreCache?: boolean, siteId?: string): Promise<any> { |             ignoreCache?: boolean, siteId?: string): Promise<AddonModAssignGetSubmissionStatusResult> { | ||||||
| 
 | 
 | ||||||
|         return this.getSubmissionStatus(assign.id, userId, groupId, isBlind, filter, ignoreCache, siteId).then((response) => { |         return this.getSubmissionStatus(assign.id, userId, groupId, isBlind, filter, ignoreCache, siteId).then((response) => { | ||||||
|             const userSubmission = this.getSubmissionObjectFromAttempt(assign, response.lastattempt); |             const userSubmission = this.getSubmissionObjectFromAttempt(assign, response.lastattempt); | ||||||
| @ -630,7 +637,9 @@ export class AddonModAssignProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved with the list of participants and summary of submissions. |      * @return Promise resolved with the list of participants and summary of submissions. | ||||||
|      */ |      */ | ||||||
|     listParticipants(assignId: number, groupId?: number, ignoreCache?: boolean, siteId?: string): Promise<any[]> { |     listParticipants(assignId: number, groupId?: number, ignoreCache?: boolean, siteId?: string) | ||||||
|  |             : Promise<AddonModAssignParticipant[]> { | ||||||
|  | 
 | ||||||
|         groupId = groupId || 0; |         groupId = groupId || 0; | ||||||
| 
 | 
 | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
| @ -1051,14 +1060,14 @@ export class AddonModAssignProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when saved, rejected otherwise. |      * @return Promise resolved when saved, rejected otherwise. | ||||||
|      */ |      */ | ||||||
|     saveSubmissionOnline(assignId: number, pluginData: any, siteId?: string): Promise<any> { |     saveSubmissionOnline(assignId: number, pluginData: any, siteId?: string): Promise<void> { | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             const params = { |             const params = { | ||||||
|                 assignmentid: assignId, |                 assignmentid: assignId, | ||||||
|                 plugindata: pluginData |                 plugindata: pluginData | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             return site.write('mod_assign_save_submission', params).then((warnings) => { |             return site.write('mod_assign_save_submission', params).then((warnings: CoreWSExternalWarning[]) => { | ||||||
|                 if (warnings && warnings.length) { |                 if (warnings && warnings.length) { | ||||||
|                     // The WebService returned warnings, reject.
 |                     // The WebService returned warnings, reject.
 | ||||||
|                     return Promise.reject(warnings[0]); |                     return Promise.reject(warnings[0]); | ||||||
| @ -1120,14 +1129,14 @@ export class AddonModAssignProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when submitted, rejected otherwise. |      * @return Promise resolved when submitted, rejected otherwise. | ||||||
|      */ |      */ | ||||||
|     submitForGradingOnline(assignId: number, acceptStatement: boolean, siteId?: string): Promise<any> { |     submitForGradingOnline(assignId: number, acceptStatement: boolean, siteId?: string): Promise<void> { | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             const params = { |             const params = { | ||||||
|                 assignmentid: assignId, |                 assignmentid: assignId, | ||||||
|                 acceptsubmissionstatement: acceptStatement ? 1 : 0 |                 acceptsubmissionstatement: acceptStatement ? 1 : 0 | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             return site.write('mod_assign_submit_for_grading', params).then((warnings) => { |             return site.write('mod_assign_submit_for_grading', params).then((warnings: CoreWSExternalWarning[]) => { | ||||||
|                 if (warnings && warnings.length) { |                 if (warnings && warnings.length) { | ||||||
|                     // The WebService returned warnings, reject.
 |                     // The WebService returned warnings, reject.
 | ||||||
|                     return Promise.reject(warnings[0]); |                     return Promise.reject(warnings[0]); | ||||||
| @ -1169,7 +1178,10 @@ export class AddonModAssignProvider { | |||||||
|         return this.isGradingOfflineEnabled(siteId).then((enabled) => { |         return this.isGradingOfflineEnabled(siteId).then((enabled) => { | ||||||
|             if (!enabled) { |             if (!enabled) { | ||||||
|                 return this.submitGradingFormOnline(assignId, userId, grade, attemptNumber, addAttempt, workflowState, |                 return this.submitGradingFormOnline(assignId, userId, grade, attemptNumber, addAttempt, workflowState, | ||||||
|                         applyToAll, outcomes, pluginData, siteId); |                         applyToAll, outcomes, pluginData, siteId).then(() => { | ||||||
|  | 
 | ||||||
|  |                     return true; | ||||||
|  |                 }); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (!this.appProvider.isOnline()) { |             if (!this.appProvider.isOnline()) { | ||||||
| @ -1212,7 +1224,7 @@ export class AddonModAssignProvider { | |||||||
|      * @return Promise resolved when submitted, rejected otherwise. |      * @return Promise resolved when submitted, rejected otherwise. | ||||||
|      */ |      */ | ||||||
|     submitGradingFormOnline(assignId: number, userId: number, grade: number, attemptNumber: number, addAttempt: boolean, |     submitGradingFormOnline(assignId: number, userId: number, grade: number, attemptNumber: number, addAttempt: boolean, | ||||||
|             workflowState: string, applyToAll: boolean, outcomes: any, pluginData: any, siteId?: string): Promise<any> { |             workflowState: string, applyToAll: boolean, outcomes: any, pluginData: any, siteId?: string): Promise<void | null> { | ||||||
| 
 | 
 | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             userId = userId || site.getUserId(); |             userId = userId || site.getUserId(); | ||||||
| @ -1243,7 +1255,7 @@ export class AddonModAssignProvider { | |||||||
|                         jsonformdata: JSON.stringify(serialized) |                         jsonformdata: JSON.stringify(serialized) | ||||||
|                     }; |                     }; | ||||||
| 
 | 
 | ||||||
|                 return site.write('mod_assign_submit_grading_form', params).then((warnings) => { |                 return site.write('mod_assign_submit_grading_form', params).then((warnings: CoreWSExternalWarning[]) => { | ||||||
|                     if (warnings && warnings.length) { |                     if (warnings && warnings.length) { | ||||||
|                         // The WebService returned warnings, reject.
 |                         // The WebService returned warnings, reject.
 | ||||||
|                         return Promise.reject(warnings[0]); |                         return Promise.reject(warnings[0]); | ||||||
| @ -1271,3 +1283,285 @@ export class AddonModAssignProvider { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Assign data returned by mod_assign_get_assignments. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignAssign = { | ||||||
|  |     id: number; // Assignment id.
 | ||||||
|  |     cmid: number; // Course module id.
 | ||||||
|  |     course: number; // Course id.
 | ||||||
|  |     name: string; // Assignment name.
 | ||||||
|  |     nosubmissions: number; // No submissions.
 | ||||||
|  |     submissiondrafts: number; // Submissions drafts.
 | ||||||
|  |     sendnotifications: number; // Send notifications.
 | ||||||
|  |     sendlatenotifications: number; // Send notifications.
 | ||||||
|  |     sendstudentnotifications: number; // Send student notifications (default).
 | ||||||
|  |     duedate: number; // Assignment due date.
 | ||||||
|  |     allowsubmissionsfromdate: number; // Allow submissions from date.
 | ||||||
|  |     grade: number; // Grade type.
 | ||||||
|  |     timemodified: number; // Last time assignment was modified.
 | ||||||
|  |     completionsubmit: number; // If enabled, set activity as complete following submission.
 | ||||||
|  |     cutoffdate: number; // Date after which submission is not accepted without an extension.
 | ||||||
|  |     gradingduedate?: number; // @since 3.3. The expected date for marking the submissions.
 | ||||||
|  |     teamsubmission: number; // If enabled, students submit as a team.
 | ||||||
|  |     requireallteammemberssubmit: number; // If enabled, all team members must submit.
 | ||||||
|  |     teamsubmissiongroupingid: number; // The grouping id for the team submission groups.
 | ||||||
|  |     blindmarking: number; // If enabled, hide identities until reveal identities actioned.
 | ||||||
|  |     hidegrader?: number; // @since 3.7. If enabled, hide grader to student.
 | ||||||
|  |     revealidentities: number; // Show identities for a blind marking assignment.
 | ||||||
|  |     attemptreopenmethod: string; // Method used to control opening new attempts.
 | ||||||
|  |     maxattempts: number; // Maximum number of attempts allowed.
 | ||||||
|  |     markingworkflow: number; // Enable marking workflow.
 | ||||||
|  |     markingallocation: number; // Enable marking allocation.
 | ||||||
|  |     requiresubmissionstatement: number; // Student must accept submission statement.
 | ||||||
|  |     preventsubmissionnotingroup?: number; // @since 3.2. Prevent submission not in group.
 | ||||||
|  |     submissionstatement?: string; // @since 3.2. Submission statement formatted.
 | ||||||
|  |     submissionstatementformat?: number; // @since 3.2. Submissionstatement format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
 | ||||||
|  |     configs: AddonModAssignConfig[]; // Configuration settings.
 | ||||||
|  |     intro?: string; // Assignment intro, not allways returned because it deppends on the activity configuration.
 | ||||||
|  |     introformat?: number; // Intro format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
 | ||||||
|  |     introfiles?: CoreWSExternalFile[]; // @since 3.2.
 | ||||||
|  |     introattachments?: CoreWSExternalFile[]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Config setting in an assign. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignConfig = { | ||||||
|  |     id?: number; // Assign_plugin_config id.
 | ||||||
|  |     assignment?: number; // Assignment id.
 | ||||||
|  |     plugin: string; // Plugin.
 | ||||||
|  |     subtype: string; // Subtype.
 | ||||||
|  |     name: string; // Name.
 | ||||||
|  |     value: string; // Value.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Grade of an assign, returned by mod_assign_get_grades. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignGrade = { | ||||||
|  |     id: number; // Grade id.
 | ||||||
|  |     assignment?: number; // Assignment id.
 | ||||||
|  |     userid: number; // Student id.
 | ||||||
|  |     attemptnumber: number; // Attempt number.
 | ||||||
|  |     timecreated: number; // Grade creation time.
 | ||||||
|  |     timemodified: number; // Grade last modified time.
 | ||||||
|  |     grader: number; // Grader, -1 if grader is hidden.
 | ||||||
|  |     grade: string; // Grade.
 | ||||||
|  |     gradefordisplay?: string; // Grade rendered into a format suitable for display.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Assign submission returned by mod_assign_get_submissions. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignSubmission = { | ||||||
|  |     id: number; // Submission id.
 | ||||||
|  |     userid: number; // Student id.
 | ||||||
|  |     attemptnumber: number; // Attempt number.
 | ||||||
|  |     timecreated: number; // Submission creation time.
 | ||||||
|  |     timemodified: number; // Submission last modified time.
 | ||||||
|  |     status: string; // Submission status.
 | ||||||
|  |     groupid: number; // Group id.
 | ||||||
|  |     assignment?: number; // Assignment id.
 | ||||||
|  |     latest?: number; // Latest attempt.
 | ||||||
|  |     plugins?: AddonModAssignPlugin[]; // Plugins.
 | ||||||
|  |     gradingstatus?: string; // @since 3.2. Grading status.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Assign plugin. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignPlugin = { | ||||||
|  |     type: string; // Submission plugin type.
 | ||||||
|  |     name: string; // Submission plugin name.
 | ||||||
|  |     fileareas?: { // Fileareas.
 | ||||||
|  |         area: string; // File area.
 | ||||||
|  |         files?: CoreWSExternalFile[]; | ||||||
|  |     }[]; | ||||||
|  |     editorfields?: { // Editorfields.
 | ||||||
|  |         name: string; // Field name.
 | ||||||
|  |         description: string; // Field description.
 | ||||||
|  |         text: string; // Field value.
 | ||||||
|  |         format: number; // Text format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
 | ||||||
|  |     }[]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Grading summary of an assign submission. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignSubmissionGradingSummary = { | ||||||
|  |     participantcount: number; // Number of users who can submit.
 | ||||||
|  |     submissiondraftscount: number; // Number of submissions in draft status.
 | ||||||
|  |     submissionsenabled: boolean; // Whether submissions are enabled or not.
 | ||||||
|  |     submissionssubmittedcount: number; // Number of submissions in submitted status.
 | ||||||
|  |     submissionsneedgradingcount: number; // Number of submissions that need grading.
 | ||||||
|  |     warnofungroupedusers: string; // Whether we need to warn people about groups.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Attempt of an assign submission. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignSubmissionAttempt = { | ||||||
|  |     submission?: AddonModAssignSubmission; // Submission info.
 | ||||||
|  |     teamsubmission?: AddonModAssignSubmission; // Submission info.
 | ||||||
|  |     submissiongroup?: number; // The submission group id (for group submissions only).
 | ||||||
|  |     submissiongroupmemberswhoneedtosubmit?: number[]; // List of users who still need to submit (for group submissions only).
 | ||||||
|  |     submissionsenabled: boolean; // Whether submissions are enabled or not.
 | ||||||
|  |     locked: boolean; // Whether new submissions are locked.
 | ||||||
|  |     graded: boolean; // Whether the submission is graded.
 | ||||||
|  |     canedit: boolean; // Whether the user can edit the current submission.
 | ||||||
|  |     caneditowner?: boolean; // @since 3.2. Whether the owner of the submission can edit it.
 | ||||||
|  |     cansubmit: boolean; // Whether the user can submit.
 | ||||||
|  |     extensionduedate: number; // Extension due date.
 | ||||||
|  |     blindmarking: boolean; // Whether blind marking is enabled.
 | ||||||
|  |     gradingstatus: string; // Grading status.
 | ||||||
|  |     usergroups: number[]; // User groups in the course.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Previous attempt of an assign submission. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignSubmissionPreviousAttempt = { | ||||||
|  |     attemptnumber: number; // Attempt number.
 | ||||||
|  |     submission?: AddonModAssignSubmission; // Submission info.
 | ||||||
|  |     grade?: AddonModAssignGrade; // Grade information.
 | ||||||
|  |     feedbackplugins?: AddonModAssignPlugin[]; // Feedback info.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Feedback of an assign submission. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignSubmissionFeedback = { | ||||||
|  |     grade: AddonModAssignGrade; // Grade information.
 | ||||||
|  |     gradefordisplay: string; // Grade rendered into a format suitable for display.
 | ||||||
|  |     gradeddate: number; // The date the user was graded.
 | ||||||
|  |     plugins?: AddonModAssignPlugin[]; // Plugins info.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Participant returned by mod_assign_list_participants. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignParticipant = { | ||||||
|  |     id: number; // ID of the user.
 | ||||||
|  |     username?: string; // The username.
 | ||||||
|  |     firstname?: string; // The first name(s) of the user.
 | ||||||
|  |     lastname?: string; // The family name of the user.
 | ||||||
|  |     fullname: string; // The fullname of the user.
 | ||||||
|  |     email?: string; // Email address.
 | ||||||
|  |     address?: string; // Postal address.
 | ||||||
|  |     phone1?: string; // Phone 1.
 | ||||||
|  |     phone2?: string; // Phone 2.
 | ||||||
|  |     icq?: string; // Icq number.
 | ||||||
|  |     skype?: string; // Skype id.
 | ||||||
|  |     yahoo?: string; // Yahoo id.
 | ||||||
|  |     aim?: string; // Aim id.
 | ||||||
|  |     msn?: string; // Msn number.
 | ||||||
|  |     department?: string; // Department.
 | ||||||
|  |     institution?: string; // Institution.
 | ||||||
|  |     idnumber?: string; // The idnumber of the user.
 | ||||||
|  |     interests?: string; // User interests (separated by commas).
 | ||||||
|  |     firstaccess?: number; // First access to the site (0 if never).
 | ||||||
|  |     lastaccess?: number; // Last access to the site (0 if never).
 | ||||||
|  |     suspended?: boolean; // @since 3.2. Suspend user account, either false to enable user login or true to disable it.
 | ||||||
|  |     description?: string; // User profile description.
 | ||||||
|  |     descriptionformat?: number; // Int format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
 | ||||||
|  |     city?: string; // Home city of the user.
 | ||||||
|  |     url?: string; // URL of the user.
 | ||||||
|  |     country?: string; // Home country code of the user, such as AU or CZ.
 | ||||||
|  |     profileimageurlsmall?: string; // User image profile URL - small version.
 | ||||||
|  |     profileimageurl?: string; // User image profile URL - big version.
 | ||||||
|  |     customfields?: { // User custom fields (also known as user profile fields).
 | ||||||
|  |         type: string; // The type of the custom field - text field, checkbox...
 | ||||||
|  |         value: string; // The value of the custom field.
 | ||||||
|  |         name: string; // The name of the custom field.
 | ||||||
|  |         shortname: string; // The shortname of the custom field - to be able to build the field class in the code.
 | ||||||
|  |     }[]; | ||||||
|  |     preferences?: { // Users preferences.
 | ||||||
|  |         name: string; // The name of the preferences.
 | ||||||
|  |         value: string; // The value of the preference.
 | ||||||
|  |     }[]; | ||||||
|  |     recordid?: number; // @since 3.7. Record id.
 | ||||||
|  |     groups?: { // User groups.
 | ||||||
|  |         id: number; // Group id.
 | ||||||
|  |         name: string; // Group name.
 | ||||||
|  |         description: string; // Group description.
 | ||||||
|  |     }[]; | ||||||
|  |     roles?: { // User roles.
 | ||||||
|  |         roleid: number; // Role id.
 | ||||||
|  |         name: string; // Role name.
 | ||||||
|  |         shortname: string; // Role shortname.
 | ||||||
|  |         sortorder: number; // Role sortorder.
 | ||||||
|  |     }[]; | ||||||
|  |     enrolledcourses?: { // Courses where the user is enrolled - limited by which courses the user is able to see.
 | ||||||
|  |         id: number; // Id of the course.
 | ||||||
|  |         fullname: string; // Fullname of the course.
 | ||||||
|  |         shortname: string; // Shortname of the course.
 | ||||||
|  |     }[]; | ||||||
|  |     submitted: boolean; // Have they submitted their assignment.
 | ||||||
|  |     requiregrading: boolean; // Is their submission waiting for grading.
 | ||||||
|  |     grantedextension?: boolean; // @since 3.3. Have they been granted an extension.
 | ||||||
|  |     groupid?: number; // For group assignments this is the group id.
 | ||||||
|  |     groupname?: string; // For group assignments this is the group name.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Result of WS mod_assign_get_assignments. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignGetAssignmentsResult = { | ||||||
|  |     courses: { // List of courses.
 | ||||||
|  |         id: number; // Course id.
 | ||||||
|  |         fullname: string; // Course full name.
 | ||||||
|  |         shortname: string; // Course short name.
 | ||||||
|  |         timemodified: number; // Last time modified.
 | ||||||
|  |         assignments: AddonModAssignAssign[]; // Assignment info.
 | ||||||
|  |     }[]; | ||||||
|  |     warnings?: CoreWSExternalWarning[]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Result of WS mod_assign_get_user_mappings. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignGetUserMappingsResult = { | ||||||
|  |     assignments: { // List of assign user mapping data.
 | ||||||
|  |         assignmentid: number; // Assignment id.
 | ||||||
|  |         mappings: { | ||||||
|  |             id: number; // User mapping id.
 | ||||||
|  |             userid: number; // Student id.
 | ||||||
|  |         }[]; | ||||||
|  |     }[]; | ||||||
|  |     warnings?: CoreWSExternalWarning[]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Result of WS mod_assign_get_grades. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignGetGradesResult = { | ||||||
|  |     assignments: { // List of assignment grade information.
 | ||||||
|  |         assignmentid: number; // Assignment id.
 | ||||||
|  |         grades: AddonModAssignGrade[]; | ||||||
|  |     }[]; | ||||||
|  |     warnings?: CoreWSExternalWarning[]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Result of WS mod_assign_get_submissions. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignGetSubmissionsResult = { | ||||||
|  |     assignments: { // Assignment submissions.
 | ||||||
|  |         assignmentid: number; // Assignment id.
 | ||||||
|  |         submissions: AddonModAssignSubmission[]; | ||||||
|  |     }[]; | ||||||
|  |     warnings?: CoreWSExternalWarning[]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Result of WS mod_assign_get_submission_status. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignGetSubmissionStatusResult = { | ||||||
|  |     gradingsummary?: AddonModAssignSubmissionGradingSummary; // Grading information.
 | ||||||
|  |     lastattempt?: AddonModAssignSubmissionAttempt; // Last attempt information.
 | ||||||
|  |     feedback?: AddonModAssignSubmissionFeedback; // Feedback for the last attempt.
 | ||||||
|  |     previousattempts?: AddonModAssignSubmissionPreviousAttempt[]; // List all the previous attempts did by the user.
 | ||||||
|  |     warnings?: CoreWSExternalWarning[]; | ||||||
|  | }; | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ import { CoreEventsProvider } from '@providers/events'; | |||||||
| import { CoreSitesProvider } from '@providers/sites'; | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate'; | import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate'; | ||||||
| import { AddonModAssignDefaultFeedbackHandler } from './default-feedback-handler'; | import { AddonModAssignDefaultFeedbackHandler } from './default-feedback-handler'; | ||||||
|  | import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin } from './assign'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Interface that all feedback handlers must implement. |  * Interface that all feedback handlers must implement. | ||||||
| @ -47,7 +48,7 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent?(injector: Injector, plugin: any): any | Promise<any>; |     getComponent?(injector: Injector, plugin: AddonModAssignPlugin): any | Promise<any>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Return the draft saved data of the feedback plugin. |      * Return the draft saved data of the feedback plugin. | ||||||
| @ -69,7 +70,8 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The files (or promise resolved with the files). |      * @return The files (or promise resolved with the files). | ||||||
|      */ |      */ | ||||||
|     getPluginFiles?(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]>; |     getPluginFiles?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): any[] | Promise<any[]>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Get a readable name to use for the plugin. |      * Get a readable name to use for the plugin. | ||||||
| @ -77,7 +79,7 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The plugin name. |      * @return The plugin name. | ||||||
|      */ |      */ | ||||||
|     getPluginName?(plugin: any): string; |     getPluginName?(plugin: AddonModAssignPlugin): string; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Check if the feedback data has changed for this plugin. |      * Check if the feedback data has changed for this plugin. | ||||||
| @ -89,7 +91,8 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { | |||||||
|      * @param userId User ID of the submission. |      * @param userId User ID of the submission. | ||||||
|      * @return Boolean (or promise resolved with boolean): whether the data has changed. |      * @return Boolean (or promise resolved with boolean): whether the data has changed. | ||||||
|      */ |      */ | ||||||
|     hasDataChanged?(assign: any, submission: any, plugin: any, inputData: any, userId: number): boolean | Promise<boolean>; |     hasDataChanged?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any, userId: number): boolean | Promise<boolean>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Check whether the plugin has draft data stored. |      * Check whether the plugin has draft data stored. | ||||||
| @ -111,7 +114,8 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     prefetch?(assign: any, submission: any, plugin: any, siteId?: string): Promise<any>; |     prefetch?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): Promise<any>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Prepare and add to pluginData the data to send to the server based on the draft data saved. |      * Prepare and add to pluginData the data to send to the server based on the draft data saved. | ||||||
| @ -123,7 +127,8 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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>; |     prepareFeedbackData?(assignId: number, userId: number, plugin: AddonModAssignPlugin, pluginData: any, | ||||||
|  |             siteId?: string): void | Promise<any>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Save draft data of the feedback plugin. |      * Save draft data of the feedback plugin. | ||||||
| @ -135,7 +140,8 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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>; |     saveDraft?(assignId: number, userId: number, plugin: AddonModAssignPlugin, data: any, siteId?: string) | ||||||
|  |             : void | Promise<any>; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -160,7 +166,8 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     discardPluginFeedbackData(assignId: number, userId: number, plugin: any, siteId?: string): Promise<any> { |     discardPluginFeedbackData(assignId: number, userId: number, plugin: AddonModAssignPlugin, siteId?: string) | ||||||
|  |             : Promise<any> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'discardDraft', [assignId, userId, siteId])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'discardDraft', [assignId, userId, siteId])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -171,7 +178,7 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return Promise resolved with the component to use, undefined if not found. |      * @return Promise resolved with the component to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponentForPlugin(injector: Injector, plugin: any): Promise<any> { |     getComponentForPlugin(injector: Injector, plugin: AddonModAssignPlugin): Promise<any> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getComponent', [injector, plugin])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getComponent', [injector, plugin])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -184,7 +191,8 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved with the draft data. |      * @return Promise resolved with the draft data. | ||||||
|      */ |      */ | ||||||
|     getPluginDraftData(assignId: number, userId: number, plugin: any, siteId?: string): Promise<any> { |     getPluginDraftData(assignId: number, userId: number, plugin: AddonModAssignPlugin, siteId?: string) | ||||||
|  |             : Promise<any> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getDraft', [assignId, userId, siteId])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getDraft', [assignId, userId, siteId])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -198,7 +206,8 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved with the files. |      * @return Promise resolved with the files. | ||||||
|      */ |      */ | ||||||
|     getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): Promise<any[]> { |     getPluginFiles(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): Promise<any[]> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getPluginFiles', [assign, submission, plugin, siteId])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getPluginFiles', [assign, submission, plugin, siteId])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -208,7 +217,7 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param plugin Plugin to get the name for. |      * @param plugin Plugin to get the name for. | ||||||
|      * @return Human readable name. |      * @return Human readable name. | ||||||
|      */ |      */ | ||||||
|     getPluginName(plugin: any): string { |     getPluginName(plugin: AddonModAssignPlugin): string { | ||||||
|         return this.executeFunctionOnEnabled(plugin.type, 'getPluginName', [plugin]); |         return this.executeFunctionOnEnabled(plugin.type, 'getPluginName', [plugin]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -222,7 +231,8 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param userId User ID of the submission. |      * @param userId User ID of the submission. | ||||||
|      * @return Promise resolved with true if data has changed, resolved with false otherwise. |      * @return Promise resolved with true if data has changed, resolved with false otherwise. | ||||||
|      */ |      */ | ||||||
|     hasPluginDataChanged(assign: any, submission: any, plugin: any, inputData: any, userId: number): Promise<boolean> { |     hasPluginDataChanged(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any, userId: number): Promise<boolean> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'hasDataChanged', |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'hasDataChanged', | ||||||
|                 [assign, submission, plugin, inputData, userId])); |                 [assign, submission, plugin, inputData, userId])); | ||||||
|     } |     } | ||||||
| @ -236,7 +246,8 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved with true if it has draft data. |      * @return Promise resolved with true if it has draft data. | ||||||
|      */ |      */ | ||||||
|     hasPluginDraftData(assignId: number, userId: number, plugin: any, siteId?: string): Promise<boolean> { |     hasPluginDraftData(assignId: number, userId: number, plugin: AddonModAssignPlugin, siteId?: string) | ||||||
|  |             : Promise<boolean> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'hasDraftData', [assignId, userId, siteId])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'hasDraftData', [assignId, userId, siteId])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -259,7 +270,8 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise<any> { |     prefetch(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, plugin: AddonModAssignPlugin, | ||||||
|  |             siteId?: string): Promise<any> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prefetch', [assign, submission, plugin, siteId])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prefetch', [assign, submission, plugin, siteId])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -273,7 +285,8 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when data has been gathered. |      * @return Promise resolved when data has been gathered. | ||||||
|      */ |      */ | ||||||
|     preparePluginFeedbackData(assignId: number, userId: number, plugin: any, pluginData: any, siteId?: string): Promise<any> { |     preparePluginFeedbackData(assignId: number, userId: number, plugin: AddonModAssignPlugin, pluginData: any, | ||||||
|  |             siteId?: string): Promise<any> { | ||||||
| 
 | 
 | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prepareFeedbackData', |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prepareFeedbackData', | ||||||
|                 [assignId, userId, plugin, pluginData, siteId])); |                 [assignId, userId, plugin, pluginData, siteId])); | ||||||
| @ -289,7 +302,8 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when data has been saved. |      * @return Promise resolved when data has been saved. | ||||||
|      */ |      */ | ||||||
|     saveFeedbackDraft(assignId: number, userId: number, plugin: any, inputData: any, siteId?: string): Promise<any> { |     saveFeedbackDraft(assignId: number, userId: number, plugin: AddonModAssignPlugin, inputData: any, | ||||||
|  |             siteId?: string): Promise<any> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'saveDraft', |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'saveDraft', | ||||||
|                 [assignId, userId, plugin, inputData, siteId])); |                 [assignId, userId, plugin, inputData, siteId])); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -21,7 +21,10 @@ import { CoreUtilsProvider } from '@providers/utils/utils'; | |||||||
| import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; | import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; | ||||||
| import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; | import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; | ||||||
| import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | ||||||
| import { AddonModAssignProvider } from './assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignParticipant, | ||||||
|  |     AddonModAssignSubmissionFeedback | ||||||
|  | } from './assign'; | ||||||
| import { AddonModAssignOfflineProvider } from './assign-offline'; | import { AddonModAssignOfflineProvider } from './assign-offline'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -46,7 +49,7 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param submission Submission. |      * @param submission Submission. | ||||||
|      * @return Whether it can be edited offline. |      * @return Whether it can be edited offline. | ||||||
|      */ |      */ | ||||||
|     canEditSubmissionOffline(assign: any, submission: any): Promise<boolean> { |     canEditSubmissionOffline(assign: AddonModAssignAssign, submission: AddonModAssignSubmission): Promise<boolean> { | ||||||
|         if (!submission) { |         if (!submission) { | ||||||
|             return Promise.resolve(false); |             return Promise.resolve(false); | ||||||
|         } |         } | ||||||
| @ -81,7 +84,7 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param submission Submission to clear the data for. |      * @param submission Submission to clear the data for. | ||||||
|      * @param inputData Data entered in the submission form. |      * @param inputData Data entered in the submission form. | ||||||
|      */ |      */ | ||||||
|     clearSubmissionPluginTmpData(assign: any, submission: any, inputData: any): void { |     clearSubmissionPluginTmpData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, inputData: any): void { | ||||||
|         submission.plugins.forEach((plugin) => { |         submission.plugins.forEach((plugin) => { | ||||||
|             this.submissionDelegate.clearTmpData(assign, submission, plugin, inputData); |             this.submissionDelegate.clearTmpData(assign, submission, plugin, inputData); | ||||||
|         }); |         }); | ||||||
| @ -95,7 +98,7 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param previousSubmission Submission to copy. |      * @param previousSubmission Submission to copy. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     copyPreviousAttempt(assign: any, previousSubmission: any): Promise<any> { |     copyPreviousAttempt(assign: AddonModAssignAssign, previousSubmission: AddonModAssignSubmission): Promise<any> { | ||||||
|         const pluginData = {}, |         const pluginData = {}, | ||||||
|             promises = []; |             promises = []; | ||||||
| 
 | 
 | ||||||
| @ -112,6 +115,36 @@ export class AddonModAssignHelperProvider { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Create an empty feedback object. | ||||||
|  |      * | ||||||
|  |      * @return Feedback. | ||||||
|  |      */ | ||||||
|  |     createEmptyFeedback(): AddonModAssignSubmissionFeedback { | ||||||
|  |         return { | ||||||
|  |             grade: undefined, | ||||||
|  |             gradefordisplay: undefined, | ||||||
|  |             gradeddate: undefined | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Create an empty submission object. | ||||||
|  |      * | ||||||
|  |      * @return Submission. | ||||||
|  |      */ | ||||||
|  |     createEmptySubmission(): AddonModAssignSubmissionFormatted { | ||||||
|  |         return { | ||||||
|  |             id: undefined, | ||||||
|  |             userid: undefined, | ||||||
|  |             attemptnumber: undefined, | ||||||
|  |             timecreated: undefined, | ||||||
|  |             timemodified: undefined, | ||||||
|  |             status: undefined, | ||||||
|  |             groupid: undefined | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Delete stored submission files for a plugin. See storeSubmissionFiles. |      * Delete stored submission files for a plugin. See storeSubmissionFiles. | ||||||
|      * |      * | ||||||
| @ -136,7 +169,9 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     discardFeedbackPluginData(assignId: number, userId: number, feedback: any, siteId?: string): Promise<any> { |     discardFeedbackPluginData(assignId: number, userId: number, feedback: AddonModAssignSubmissionFeedback, | ||||||
|  |             siteId?: string): Promise<any> { | ||||||
|  | 
 | ||||||
|         const promises = []; |         const promises = []; | ||||||
| 
 | 
 | ||||||
|         feedback.plugins.forEach((plugin) => { |         feedback.plugins.forEach((plugin) => { | ||||||
| @ -155,7 +190,9 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved with the list of participants and summary of submissions. |      * @return Promise resolved with the list of participants and summary of submissions. | ||||||
|      */ |      */ | ||||||
|     getParticipants(assign: any, groupId?: number, ignoreCache?: boolean, siteId?: string): Promise<any[]> { |     getParticipants(assign: AddonModAssignAssign, groupId?: number, ignoreCache?: boolean, siteId?: string) | ||||||
|  |             : Promise<AddonModAssignParticipant[]> { | ||||||
|  | 
 | ||||||
|         groupId = groupId || 0; |         groupId = groupId || 0; | ||||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); |         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||||
| 
 | 
 | ||||||
| @ -167,7 +204,7 @@ export class AddonModAssignHelperProvider { | |||||||
|             // If no participants returned and all groups specified, get participants by groups.
 |             // If no participants returned and all groups specified, get participants by groups.
 | ||||||
|             return this.groupsProvider.getActivityGroupInfo(assign.cmid, false, undefined, siteId).then((info) => { |             return this.groupsProvider.getActivityGroupInfo(assign.cmid, false, undefined, siteId).then((info) => { | ||||||
|                 const promises = [], |                 const promises = [], | ||||||
|                     participants = {}; |                     participants: {[id: number]: AddonModAssignParticipant} = {}; | ||||||
| 
 | 
 | ||||||
|                 info.groups.forEach((userGroup) => { |                 info.groups.forEach((userGroup) => { | ||||||
|                     promises.push(this.assignProvider.listParticipants(assign.id, userGroup.id, ignoreCache, siteId) |                     promises.push(this.assignProvider.listParticipants(assign.id, userGroup.id, ignoreCache, siteId) | ||||||
| @ -194,8 +231,8 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param type Name of the subplugin. |      * @param type Name of the subplugin. | ||||||
|      * @return Object containing all configurations of the subplugin selected. |      * @return Object containing all configurations of the subplugin selected. | ||||||
|      */ |      */ | ||||||
|     getPluginConfig(assign: any, subtype: string, type: string): any { |     getPluginConfig(assign: AddonModAssignAssign, subtype: string, type: string): {[name: string]: string} { | ||||||
|         const configs = {}; |         const configs: {[name: string]: string} = {}; | ||||||
| 
 | 
 | ||||||
|         assign.configs.forEach((config) => { |         assign.configs.forEach((config) => { | ||||||
|             if (config.subtype == subtype && config.plugin == type) { |             if (config.subtype == subtype && config.plugin == type) { | ||||||
| @ -213,7 +250,7 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param subtype Subtype name (assignsubmission or assignfeedback) |      * @param subtype Subtype name (assignsubmission or assignfeedback) | ||||||
|      * @return List of enabled plugins for the assign. |      * @return List of enabled plugins for the assign. | ||||||
|      */ |      */ | ||||||
|     getPluginsEnabled(assign: any, subtype: string): any[] { |     getPluginsEnabled(assign: AddonModAssignAssign, subtype: string): any[] { | ||||||
|         const enabled = []; |         const enabled = []; | ||||||
| 
 | 
 | ||||||
|         assign.configs.forEach((config) => { |         assign.configs.forEach((config) => { | ||||||
| @ -250,7 +287,7 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param previousSubmission Submission to copy. |      * @param previousSubmission Submission to copy. | ||||||
|      * @return Promise resolved with the size. |      * @return Promise resolved with the size. | ||||||
|      */ |      */ | ||||||
|     getSubmissionSizeForCopy(assign: any, previousSubmission: any): Promise<number> { |     getSubmissionSizeForCopy(assign: AddonModAssignAssign, previousSubmission: AddonModAssignSubmission): Promise<number> { | ||||||
|         const promises = []; |         const promises = []; | ||||||
|         let totalSize = 0; |         let totalSize = 0; | ||||||
| 
 | 
 | ||||||
| @ -273,7 +310,8 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param inputData Data entered in the submission form. |      * @param inputData Data entered in the submission form. | ||||||
|      * @return Promise resolved with the size. |      * @return Promise resolved with the size. | ||||||
|      */ |      */ | ||||||
|     getSubmissionSizeForEdit(assign: any, submission: any, inputData: any): Promise<number> { |     getSubmissionSizeForEdit(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, inputData: any): Promise<number> { | ||||||
|  | 
 | ||||||
|         const promises = []; |         const promises = []; | ||||||
|         let totalSize = 0; |         let totalSize = 0; | ||||||
| 
 | 
 | ||||||
| @ -298,14 +336,14 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param siteId Site id (empty for current site). |      * @param siteId Site id (empty for current site). | ||||||
|      * @return Promise always resolved. Resolve param is the formatted submissions. |      * @return Promise always resolved. Resolve param is the formatted submissions. | ||||||
|      */ |      */ | ||||||
|     getSubmissionsUserData(assign: any, submissions: any[], groupId?: number, ignoreCache?: boolean, siteId?: string): |     getSubmissionsUserData(assign: AddonModAssignAssign, submissions: AddonModAssignSubmissionFormatted[], groupId?: number, | ||||||
|             Promise<any[]> { |             ignoreCache?: boolean, siteId?: string): Promise<AddonModAssignSubmissionFormatted[]> { | ||||||
|         return this.getParticipants(assign, groupId).then((participants) => { | 
 | ||||||
|  |         return this.getParticipants(assign, groupId).then((parts) => { | ||||||
|             const blind = assign.blindmarking && !assign.revealidentities; |             const blind = assign.blindmarking && !assign.revealidentities; | ||||||
|             const promises = []; |             const promises = []; | ||||||
|             const result = []; |             const result: AddonModAssignSubmissionFormatted[] = []; | ||||||
| 
 |             const participants: {[id: number]: AddonModAssignParticipant} = this.utils.arrayToObject(parts, 'id'); | ||||||
|             participants = this.utils.arrayToObject(participants, 'id'); |  | ||||||
| 
 | 
 | ||||||
|             submissions.forEach((submission) => { |             submissions.forEach((submission) => { | ||||||
|                 submission.submitid = submission.userid > 0 ? submission.userid : submission.blindid; |                 submission.submitid = submission.userid > 0 ? submission.userid : submission.blindid; | ||||||
| @ -356,10 +394,10 @@ export class AddonModAssignHelperProvider { | |||||||
| 
 | 
 | ||||||
|             return Promise.all(promises).then(() => { |             return Promise.all(promises).then(() => { | ||||||
|                 // Create a submission for each participant left in the list (the participants already treated were removed).
 |                 // Create a submission for each participant left in the list (the participants already treated were removed).
 | ||||||
|                 this.utils.objectToArray(participants).forEach((participant) => { |                 this.utils.objectToArray(participants).forEach((participant: AddonModAssignParticipant) => { | ||||||
|                     const submission: any = { |                     const submission = this.createEmptySubmission(); | ||||||
|                         submitid: participant.id | 
 | ||||||
|                     }; |                     submission.submitid = participant.id; | ||||||
| 
 | 
 | ||||||
|                     if (!blind) { |                     if (!blind) { | ||||||
|                         submission.userid = participant.id; |                         submission.userid = participant.id; | ||||||
| @ -390,17 +428,20 @@ export class AddonModAssignHelperProvider { | |||||||
|      * Check if the feedback data has changed for a certain submission and assign. |      * Check if the feedback data has changed for a certain submission and assign. | ||||||
|      * |      * | ||||||
|      * @param assign Assignment. |      * @param assign Assignment. | ||||||
|      * @param userId User Id. |      * @param submission The submission. | ||||||
|      * @param feedback Feedback data. |      * @param feedback Feedback data. | ||||||
|  |      * @param userId The user ID. | ||||||
|      * @return Promise resolved with true if data has changed, resolved with false otherwise. |      * @return Promise resolved with true if data has changed, resolved with false otherwise. | ||||||
|      */ |      */ | ||||||
|     hasFeedbackDataChanged(assign: any, userId: number, feedback: any): Promise<boolean> { |     hasFeedbackDataChanged(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             feedback: AddonModAssignSubmissionFeedback, userId: number): Promise<boolean> { | ||||||
|  | 
 | ||||||
|         const promises = []; |         const promises = []; | ||||||
|         let hasChanged = false; |         let hasChanged = false; | ||||||
| 
 | 
 | ||||||
|         feedback.plugins.forEach((plugin) => { |         feedback.plugins.forEach((plugin) => { | ||||||
|             promises.push(this.prepareFeedbackPluginData(assign.id, userId, feedback).then((inputData) => { |             promises.push(this.prepareFeedbackPluginData(assign.id, userId, feedback).then((inputData) => { | ||||||
|                 return this.feedbackDelegate.hasPluginDataChanged(assign, userId, plugin, inputData, userId).then((changed) => { |                 return this.feedbackDelegate.hasPluginDataChanged(assign, submission, plugin, inputData, userId).then((changed) => { | ||||||
|                     if (changed) { |                     if (changed) { | ||||||
|                         hasChanged = true; |                         hasChanged = true; | ||||||
|                     } |                     } | ||||||
| @ -423,7 +464,9 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param inputData Data entered in the submission form. |      * @param inputData Data entered in the submission form. | ||||||
|      * @return Promise resolved with true if data has changed, resolved with false otherwise. |      * @return Promise resolved with true if data has changed, resolved with false otherwise. | ||||||
|      */ |      */ | ||||||
|     hasSubmissionDataChanged(assign: any, submission: any, inputData: any): Promise<boolean> { |     hasSubmissionDataChanged(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, inputData: any) | ||||||
|  |             : Promise<boolean> { | ||||||
|  | 
 | ||||||
|         const promises = []; |         const promises = []; | ||||||
|         let hasChanged = false; |         let hasChanged = false; | ||||||
| 
 | 
 | ||||||
| @ -451,7 +494,9 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved with plugin data to send to server. |      * @return Promise resolved with plugin data to send to server. | ||||||
|      */ |      */ | ||||||
|     prepareFeedbackPluginData(assignId: number, userId: number, feedback: any, siteId?: string): Promise<any> { |     prepareFeedbackPluginData(assignId: number, userId: number, feedback: AddonModAssignSubmissionFeedback, siteId?: string) | ||||||
|  |             : Promise<any> { | ||||||
|  | 
 | ||||||
|         const pluginData = {}, |         const pluginData = {}, | ||||||
|             promises = []; |             promises = []; | ||||||
| 
 | 
 | ||||||
| @ -473,7 +518,9 @@ export class AddonModAssignHelperProvider { | |||||||
|      * @param offline True to prepare the data for an offline submission, false otherwise. |      * @param offline True to prepare the data for an offline submission, false otherwise. | ||||||
|      * @return Promise resolved with plugin data to send to server. |      * @return Promise resolved with plugin data to send to server. | ||||||
|      */ |      */ | ||||||
|     prepareSubmissionPluginData(assign: any, submission: any, inputData: any, offline?: boolean): Promise<any> { |     prepareSubmissionPluginData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, inputData: any, | ||||||
|  |             offline?: boolean): Promise<any> { | ||||||
|  | 
 | ||||||
|         const pluginData = {}, |         const pluginData = {}, | ||||||
|             promises = []; |             promises = []; | ||||||
| 
 | 
 | ||||||
| @ -553,3 +600,16 @@ export class AddonModAssignHelperProvider { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Assign submission with some calculated data. | ||||||
|  |  */ | ||||||
|  | export type AddonModAssignSubmissionFormatted = AddonModAssignSubmission & { | ||||||
|  |     blindid?: number; // Calculated in the app. Blindid of the user that did the submission.
 | ||||||
|  |     submitid?: number; // Calculated in the app. Userid or blindid of the user that did the submission.
 | ||||||
|  |     userfullname?: string; // Calculated in the app. Full name of the user that did the submission.
 | ||||||
|  |     userprofileimageurl?: string; // Calculated in the app. Avatar of the user that did the submission.
 | ||||||
|  |     manyGroups?: boolean; // Calculated in the app. Whether the user belongs to more than 1 group.
 | ||||||
|  |     noGroups?: boolean; // Calculated in the app. Whether the user doesn't belong to any group.
 | ||||||
|  |     groupname?: string; // Calculated in the app. Name of the group the submission belongs to.
 | ||||||
|  | }; | ||||||
|  | |||||||
| @ -26,8 +26,8 @@ import { CoreCourseProvider } from '@core/course/providers/course'; | |||||||
| import { CoreCourseHelperProvider } from '@core/course/providers/helper'; | import { CoreCourseHelperProvider } from '@core/course/providers/helper'; | ||||||
| import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; | import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; | ||||||
| import { CoreUserProvider } from '@core/user/providers/user'; | import { CoreUserProvider } from '@core/user/providers/user'; | ||||||
| import { AddonModAssignProvider } from './assign'; | import { AddonModAssignProvider, AddonModAssignGetSubmissionStatusResult, AddonModAssignSubmission } from './assign'; | ||||||
| import { AddonModAssignHelperProvider } from './helper'; | import { AddonModAssignHelperProvider, AddonModAssignSubmissionFormatted } from './helper'; | ||||||
| import { AddonModAssignSyncProvider } from './assign-sync'; | import { AddonModAssignSyncProvider } from './assign-sync'; | ||||||
| import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; | import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; | ||||||
| import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | ||||||
| @ -106,7 +106,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan | |||||||
|                 if (data.canviewsubmissions) { |                 if (data.canviewsubmissions) { | ||||||
|                     // Teacher, get all submissions.
 |                     // Teacher, get all submissions.
 | ||||||
|                     return this.assignHelper.getSubmissionsUserData(assign, data.submissions, 0, false, siteId) |                     return this.assignHelper.getSubmissionsUserData(assign, data.submissions, 0, false, siteId) | ||||||
|                             .then((submissions) => { |                             .then((submissions: AddonModAssignSubmissionFormatted[]) => { | ||||||
| 
 | 
 | ||||||
|                         const promises = []; |                         const promises = []; | ||||||
| 
 | 
 | ||||||
| @ -161,9 +161,10 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan | |||||||
|         return this.assignProvider.getSubmissionStatusWithRetry(assign, submitId, undefined, blindMarking, true, false, siteId) |         return this.assignProvider.getSubmissionStatusWithRetry(assign, submitId, undefined, blindMarking, true, false, siteId) | ||||||
|                 .then((response) => { |                 .then((response) => { | ||||||
|             const promises = []; |             const promises = []; | ||||||
|  |             let userSubmission: AddonModAssignSubmission; | ||||||
| 
 | 
 | ||||||
|             if (response.lastattempt) { |             if (response.lastattempt) { | ||||||
|                 const userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(assign, response.lastattempt); |                 userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(assign, response.lastattempt); | ||||||
|                 if (userSubmission && userSubmission.plugins) { |                 if (userSubmission && userSubmission.plugins) { | ||||||
|                     // Add submission plugin files.
 |                     // Add submission plugin files.
 | ||||||
|                     userSubmission.plugins.forEach((plugin) => { |                     userSubmission.plugins.forEach((plugin) => { | ||||||
| @ -175,7 +176,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan | |||||||
|             if (response.feedback && response.feedback.plugins) { |             if (response.feedback && response.feedback.plugins) { | ||||||
|                 // Add feedback plugin files.
 |                 // Add feedback plugin files.
 | ||||||
|                 response.feedback.plugins.forEach((plugin) => { |                 response.feedback.plugins.forEach((plugin) => { | ||||||
|                     promises.push(this.feedbackDelegate.getPluginFiles(assign, response, plugin, siteId)); |                     promises.push(this.feedbackDelegate.getPluginFiles(assign, userSubmission, plugin, siteId)); | ||||||
|                 }); |                 }); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -303,7 +304,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan | |||||||
| 
 | 
 | ||||||
|                     groupInfo.groups.forEach((group) => { |                     groupInfo.groups.forEach((group) => { | ||||||
|                         groupProms.push(this.assignHelper.getSubmissionsUserData(assign, data.submissions, group.id, true, siteId) |                         groupProms.push(this.assignHelper.getSubmissionsUserData(assign, data.submissions, group.id, true, siteId) | ||||||
|                                 .then((submissions) => { |                                 .then((submissions: AddonModAssignSubmissionFormatted[]) => { | ||||||
| 
 | 
 | ||||||
|                             const subPromises = []; |                             const subPromises = []; | ||||||
| 
 | 
 | ||||||
| @ -327,7 +328,8 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan | |||||||
|                             } |                             } | ||||||
| 
 | 
 | ||||||
|                             // Prefetch the submission of the current user even if it does not exist, this will be create it.
 |                             // Prefetch the submission of the current user even if it does not exist, this will be create it.
 | ||||||
|                             if (!data.submissions || !data.submissions.find((subm) => subm.submitid == userId)) { |                             if (!data.submissions || | ||||||
|  |                                     !data.submissions.find((subm: AddonModAssignSubmissionFormatted) => subm.submitid == userId)) { | ||||||
|                                 subPromises.push(this.assignProvider.getSubmissionStatusWithRetry(assign, userId, group.id, |                                 subPromises.push(this.assignProvider.getSubmissionStatusWithRetry(assign, userId, group.id, | ||||||
|                                         false, true, true, siteId).then((subm) => { |                                         false, true, true, siteId).then((subm) => { | ||||||
|                                     return this.prefetchSubmission(assign, courseId, moduleId, subm, userId, siteId); |                                     return this.prefetchSubmission(assign, courseId, moduleId, subm, userId, siteId); | ||||||
| @ -385,15 +387,16 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when prefetched, rejected otherwise. |      * @return Promise resolved when prefetched, rejected otherwise. | ||||||
|      */ |      */ | ||||||
|     protected prefetchSubmission(assign: any, courseId: number, moduleId: number, submission: any, userId?: number, |     protected prefetchSubmission(assign: any, courseId: number, moduleId: number, | ||||||
|             siteId?: string): Promise<any> { |             submission: AddonModAssignGetSubmissionStatusResult, userId?: number, siteId?: string): Promise<any> { | ||||||
| 
 | 
 | ||||||
|         const promises = [], |         const promises = [], | ||||||
|             blindMarking = assign.blindmarking && !assign.revealidentities; |             blindMarking = assign.blindmarking && !assign.revealidentities; | ||||||
|         let userIds = []; |         let userIds = [], | ||||||
|  |             userSubmission: AddonModAssignSubmission; | ||||||
| 
 | 
 | ||||||
|         if (submission.lastattempt) { |         if (submission.lastattempt) { | ||||||
|             const userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(assign, submission.lastattempt); |             userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(assign, submission.lastattempt); | ||||||
| 
 | 
 | ||||||
|             // Get IDs of the members who need to submit.
 |             // Get IDs of the members who need to submit.
 | ||||||
|             if (!blindMarking && submission.lastattempt.submissiongroupmemberswhoneedtosubmit) { |             if (!blindMarking && submission.lastattempt.submissiongroupmemberswhoneedtosubmit) { | ||||||
| @ -440,10 +443,10 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan | |||||||
|             if (submission.feedback.plugins) { |             if (submission.feedback.plugins) { | ||||||
|                 submission.feedback.plugins.forEach((plugin) => { |                 submission.feedback.plugins.forEach((plugin) => { | ||||||
|                     // Prefetch the plugin WS data.
 |                     // Prefetch the plugin WS data.
 | ||||||
|                     promises.push(this.feedbackDelegate.prefetch(assign, submission, plugin, siteId)); |                     promises.push(this.feedbackDelegate.prefetch(assign, userSubmission, plugin, siteId)); | ||||||
| 
 | 
 | ||||||
|                     // Prefetch the plugin files.
 |                     // Prefetch the plugin files.
 | ||||||
|                     promises.push(this.feedbackDelegate.getPluginFiles(assign, submission, plugin, siteId).then((files) => { |                     promises.push(this.feedbackDelegate.getPluginFiles(assign, userSubmission, plugin, siteId).then((files) => { | ||||||
|                         return this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id); |                         return this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id); | ||||||
|                     }).catch(() => { |                     }).catch(() => { | ||||||
|                         // Ignore errors.
 |                         // Ignore errors.
 | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ import { CoreEventsProvider } from '@providers/events'; | |||||||
| import { CoreSitesProvider } from '@providers/sites'; | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate'; | import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate'; | ||||||
| import { AddonModAssignDefaultSubmissionHandler } from './default-submission-handler'; | import { AddonModAssignDefaultSubmissionHandler } from './default-submission-handler'; | ||||||
|  | import { AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin } from './assign'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Interface that all submission handlers must implement. |  * Interface that all submission handlers must implement. | ||||||
| @ -39,7 +40,8 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. |      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. | ||||||
|      */ |      */ | ||||||
|     canEditOffline?(assign: any, submission: any, plugin: any): boolean | Promise<boolean>; |     canEditOffline?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin): boolean | Promise<boolean>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Should clear temporary data for a cancelled submission. |      * Should clear temporary data for a cancelled submission. | ||||||
| @ -49,7 +51,8 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      */ |      */ | ||||||
|     clearTmpData?(assign: any, submission: any, plugin: any, inputData: any): void; |     clearTmpData?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): void; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * This function will be called when the user wants to create a new submission based on the previous one. |      * This function will be called when the user wants to create a new submission based on the previous one. | ||||||
| @ -62,7 +65,8 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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>; |     copySubmissionData?(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin, pluginData: any, | ||||||
|  |             userId?: number, siteId?: string): void | Promise<any>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Delete any stored data for the plugin and submission. |      * Delete any stored data for the plugin and submission. | ||||||
| @ -74,7 +78,8 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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>; |     deleteOfflineData?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, offlineData: any, siteId?: string): void | Promise<any>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Return the Component to use to display the plugin data, either in read or in edit mode. |      * Return the Component to use to display the plugin data, either in read or in edit mode. | ||||||
| @ -85,7 +90,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param edit Whether the user is editing. |      * @param edit Whether the user is editing. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent?(injector: Injector, plugin: any, edit?: boolean): any | Promise<any>; |     getComponent?(injector: Injector, plugin: AddonModAssignPlugin, edit?: boolean): any | Promise<any>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Get files used by this plugin. |      * Get files used by this plugin. | ||||||
| @ -97,7 +102,8 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The files (or promise resolved with the files). |      * @return The files (or promise resolved with the files). | ||||||
|      */ |      */ | ||||||
|     getPluginFiles?(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]>; |     getPluginFiles?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): any[] | Promise<any[]>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Get a readable name to use for the plugin. |      * Get a readable name to use for the plugin. | ||||||
| @ -105,7 +111,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The plugin name. |      * @return The plugin name. | ||||||
|      */ |      */ | ||||||
|     getPluginName?(plugin: any): string; |     getPluginName?(plugin: AddonModAssignPlugin): string; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Get the size of data (in bytes) this plugin will send to copy a previous submission. |      * Get the size of data (in bytes) this plugin will send to copy a previous submission. | ||||||
| @ -114,7 +120,7 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The size (or promise resolved with size). |      * @return The size (or promise resolved with size). | ||||||
|      */ |      */ | ||||||
|     getSizeForCopy?(assign: any, plugin: any): number | Promise<number>; |     getSizeForCopy?(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin): number | Promise<number>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Get the size of data (in bytes) this plugin will send to add or edit a submission. |      * Get the size of data (in bytes) this plugin will send to add or edit a submission. | ||||||
| @ -125,7 +131,8 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      * @return The size (or promise resolved with size). |      * @return The size (or promise resolved with size). | ||||||
|      */ |      */ | ||||||
|     getSizeForEdit?(assign: any, submission: any, plugin: any, inputData: any): number | Promise<number>; |     getSizeForEdit?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): number | Promise<number>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Check if the submission data has changed for this plugin. |      * Check if the submission data has changed for this plugin. | ||||||
| @ -136,7 +143,8 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      * @return Boolean (or promise resolved with boolean): whether the data has changed. |      * @return Boolean (or promise resolved with boolean): whether the data has changed. | ||||||
|      */ |      */ | ||||||
|     hasDataChanged?(assign: any, submission: any, plugin: any, inputData: any): boolean | Promise<boolean>; |     hasDataChanged?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): boolean | Promise<boolean>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Whether or not the handler is enabled for edit on a site level. |      * Whether or not the handler is enabled for edit on a site level. | ||||||
| @ -155,7 +163,8 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     prefetch?(assign: any, submission: any, plugin: any, siteId?: string): Promise<any>; |     prefetch?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): Promise<any>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Prepare and add to pluginData the data to send to the server based on the input data. |      * Prepare and add to pluginData the data to send to the server based on the input data. | ||||||
| @ -170,8 +179,9 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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, |     prepareSubmissionData?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|         userId?: number, siteId?: string): void | Promise<any>; |             plugin: AddonModAssignPlugin, inputData: any, pluginData: any, offline?: boolean, | ||||||
|  |             userId?: number, siteId?: string): void | Promise<any>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Prepare and add to pluginData the data to send to the server based on the offline data stored. |      * Prepare and add to pluginData the data to send to the server based on the offline data stored. | ||||||
| @ -185,8 +195,8 @@ export interface AddonModAssignSubmissionHandler extends CoreDelegateHandler { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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) |     prepareSyncData?(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|         : void | Promise<any>; |             plugin: AddonModAssignPlugin, offlineData: any, pluginData: any, siteId?: string): void | Promise<any>; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -210,7 +220,8 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return Promise resolved with boolean: whether it can be edited in offline. |      * @return Promise resolved with boolean: whether it can be edited in offline. | ||||||
|      */ |      */ | ||||||
|     canPluginEditOffline(assign: any, submission: any, plugin: any): Promise<boolean> { |     canPluginEditOffline(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin): Promise<boolean> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'canEditOffline', [assign, submission, plugin])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'canEditOffline', [assign, submission, plugin])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -222,7 +233,8 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      */ |      */ | ||||||
|     clearTmpData(assign: any, submission: any, plugin: any, inputData: any): void { |     clearTmpData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): void { | ||||||
|         return this.executeFunctionOnEnabled(plugin.type, 'clearTmpData', [assign, submission, plugin, inputData]); |         return this.executeFunctionOnEnabled(plugin.type, 'clearTmpData', [assign, submission, plugin, inputData]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -236,7 +248,8 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when the data has been copied. |      * @return Promise resolved when the data has been copied. | ||||||
|      */ |      */ | ||||||
|     copyPluginSubmissionData(assign: any, plugin: any, pluginData: any, userId?: number, siteId?: string): void | Promise<any> { |     copyPluginSubmissionData(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin, pluginData: any, | ||||||
|  |             userId?: number, siteId?: string): void | Promise<any> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'copySubmissionData', |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'copySubmissionData', | ||||||
|                 [assign, plugin, pluginData, userId, siteId])); |                 [assign, plugin, pluginData, userId, siteId])); | ||||||
|     } |     } | ||||||
| @ -251,7 +264,8 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     deletePluginOfflineData(assign: any, submission: any, plugin: any, offlineData: any, siteId?: string): Promise<any> { |     deletePluginOfflineData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, offlineData: any, siteId?: string): Promise<any> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'deleteOfflineData', |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'deleteOfflineData', | ||||||
|                 [assign, submission, plugin, offlineData, siteId])); |                 [assign, submission, plugin, offlineData, siteId])); | ||||||
|     } |     } | ||||||
| @ -264,7 +278,7 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param edit Whether the user is editing. |      * @param edit Whether the user is editing. | ||||||
|      * @return Promise resolved with the component to use, undefined if not found. |      * @return Promise resolved with the component to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponentForPlugin(injector: Injector, plugin: any, edit?: boolean): Promise<any> { |     getComponentForPlugin(injector: Injector, plugin: AddonModAssignPlugin, edit?: boolean): Promise<any> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getComponent', [injector, plugin, edit])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getComponent', [injector, plugin, edit])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -278,7 +292,8 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved with the files. |      * @return Promise resolved with the files. | ||||||
|      */ |      */ | ||||||
|     getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): Promise<any[]> { |     getPluginFiles(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): Promise<any[]> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getPluginFiles', [assign, submission, plugin, siteId])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getPluginFiles', [assign, submission, plugin, siteId])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -288,7 +303,7 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param plugin Plugin to get the name for. |      * @param plugin Plugin to get the name for. | ||||||
|      * @return Human readable name. |      * @return Human readable name. | ||||||
|      */ |      */ | ||||||
|     getPluginName(plugin: any): string { |     getPluginName(plugin: AddonModAssignPlugin): string { | ||||||
|         return this.executeFunctionOnEnabled(plugin.type, 'getPluginName', [plugin]); |         return this.executeFunctionOnEnabled(plugin.type, 'getPluginName', [plugin]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -299,7 +314,7 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return Promise resolved with size. |      * @return Promise resolved with size. | ||||||
|      */ |      */ | ||||||
|     getPluginSizeForCopy(assign: any, plugin: any): Promise<number> { |     getPluginSizeForCopy(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin): Promise<number> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getSizeForCopy', [assign, plugin])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getSizeForCopy', [assign, plugin])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -312,7 +327,8 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      * @return Promise resolved with size. |      * @return Promise resolved with size. | ||||||
|      */ |      */ | ||||||
|     getPluginSizeForEdit(assign: any, submission: any, plugin: any, inputData: any): Promise<number> { |     getPluginSizeForEdit(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): Promise<number> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getSizeForEdit', |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'getSizeForEdit', | ||||||
|                 [assign, submission, plugin, inputData])); |                 [assign, submission, plugin, inputData])); | ||||||
|     } |     } | ||||||
| @ -326,7 +342,8 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      * @return Promise resolved with true if data has changed, resolved with false otherwise. |      * @return Promise resolved with true if data has changed, resolved with false otherwise. | ||||||
|      */ |      */ | ||||||
|     hasPluginDataChanged(assign: any, submission: any, plugin: any, inputData: any): Promise<boolean> { |     hasPluginDataChanged(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): Promise<boolean> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'hasDataChanged', |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'hasDataChanged', | ||||||
|                 [assign, submission, plugin, inputData])); |                 [assign, submission, plugin, inputData])); | ||||||
|     } |     } | ||||||
| @ -360,7 +377,8 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise<any> { |     prefetch(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, plugin: AddonModAssignPlugin, | ||||||
|  |             siteId?: string): Promise<any> { | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prefetch', [assign, submission, plugin, siteId])); |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prefetch', [assign, submission, plugin, siteId])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -377,8 +395,9 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when data has been gathered. |      * @return Promise resolved when data has been gathered. | ||||||
|      */ |      */ | ||||||
|     preparePluginSubmissionData(assign: any, submission: any, plugin: any, inputData: any, pluginData: any, offline?: boolean, |     preparePluginSubmissionData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|             userId?: number, siteId?: string): Promise<any> { |             plugin: AddonModAssignPlugin, inputData: any, pluginData: any, offline?: boolean, userId?: number, | ||||||
|  |             siteId?: string): Promise<any> { | ||||||
| 
 | 
 | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prepareSubmissionData', |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prepareSubmissionData', | ||||||
|                 [assign, submission, plugin, inputData, pluginData, offline, userId, siteId])); |                 [assign, submission, plugin, inputData, pluginData, offline, userId, siteId])); | ||||||
| @ -395,8 +414,8 @@ export class AddonModAssignSubmissionDelegate extends CoreDelegate { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when data has been gathered. |      * @return Promise resolved when data has been gathered. | ||||||
|      */ |      */ | ||||||
|     preparePluginSyncData(assign: any, submission: any, plugin: any, offlineData: any, pluginData: any, siteId?: string) |     preparePluginSyncData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|             : Promise<any> { |             plugin: AddonModAssignPlugin, offlineData: any, pluginData: any, siteId?: string): Promise<any> { | ||||||
| 
 | 
 | ||||||
|         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prepareSyncData', |         return Promise.resolve(this.executeFunctionOnEnabled(plugin.type, 'prepareSyncData', | ||||||
|                 [assign, submission, plugin, offlineData, pluginData, siteId])); |                 [assign, submission, plugin, offlineData, pluginData, siteId])); | ||||||
|  | |||||||
| @ -17,6 +17,9 @@ import { Injectable, Injector } from '@angular/core'; | |||||||
| import { CoreCommentsProvider } from '@core/comments/providers/comments'; | import { CoreCommentsProvider } from '@core/comments/providers/comments'; | ||||||
| import { AddonModAssignSubmissionHandler } from '../../../providers/submission-delegate'; | import { AddonModAssignSubmissionHandler } from '../../../providers/submission-delegate'; | ||||||
| import { AddonModAssignSubmissionCommentsComponent } from '../component/comments'; | import { AddonModAssignSubmissionCommentsComponent } from '../component/comments'; | ||||||
|  | import { | ||||||
|  |     AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin | ||||||
|  | } from '../../../providers/assign'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Handler for comments submission plugin. |  * Handler for comments submission plugin. | ||||||
| @ -38,7 +41,8 @@ export class AddonModAssignSubmissionCommentsHandler implements AddonModAssignSu | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. |      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. | ||||||
|      */ |      */ | ||||||
|     canEditOffline(assign: any, submission: any, plugin: any): boolean | Promise<boolean> { |     canEditOffline(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin): boolean | Promise<boolean> { | ||||||
|         // This plugin is read only, but return true to prevent blocking the edition.
 |         // This plugin is read only, but return true to prevent blocking the edition.
 | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| @ -52,7 +56,7 @@ export class AddonModAssignSubmissionCommentsHandler implements AddonModAssignSu | |||||||
|      * @param edit Whether the user is editing. |      * @param edit Whether the user is editing. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent(injector: Injector, plugin: any, edit?: boolean): any | Promise<any> { |     getComponent(injector: Injector, plugin: AddonModAssignPlugin, edit?: boolean): any | Promise<any> { | ||||||
|         return edit ? undefined : AddonModAssignSubmissionCommentsComponent; |         return edit ? undefined : AddonModAssignSubmissionCommentsComponent; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -84,7 +88,9 @@ export class AddonModAssignSubmissionCommentsHandler implements AddonModAssignSu | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     prefetch(assign: any, submission: any, plugin: any, siteId?: string): Promise<any> { |     prefetch(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): Promise<any> { | ||||||
|  | 
 | ||||||
|         return this.commentsProvider.getComments('module', assign.cmid, 'assignsubmission_comments', submission.id, |         return this.commentsProvider.getComments('module', assign.cmid, 'assignsubmission_comments', submission.id, | ||||||
|                 'submission_comments', 0, siteId).catch(() => { |                 'submission_comments', 0, siteId).catch(() => { | ||||||
|             // Fail silently (Moodle < 3.1.1, 3.2)
 |             // Fail silently (Moodle < 3.1.1, 3.2)
 | ||||||
|  | |||||||
| @ -21,7 +21,9 @@ import { CoreSitesProvider } from '@providers/sites'; | |||||||
| import { CoreWSProvider } from '@providers/ws'; | import { CoreWSProvider } from '@providers/ws'; | ||||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||||
| import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; | import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; | ||||||
| import { AddonModAssignProvider } from '../../../providers/assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin | ||||||
|  | } from '../../../providers/assign'; | ||||||
| import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline'; | import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline'; | ||||||
| import { AddonModAssignHelperProvider } from '../../../providers/helper'; | import { AddonModAssignHelperProvider } from '../../../providers/helper'; | ||||||
| import { AddonModAssignSubmissionHandler } from '../../../providers/submission-delegate'; | import { AddonModAssignSubmissionHandler } from '../../../providers/submission-delegate'; | ||||||
| @ -53,7 +55,8 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. |      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. | ||||||
|      */ |      */ | ||||||
|     canEditOffline(assign: any, submission: any, plugin: any): boolean | Promise<boolean> { |     canEditOffline(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin): boolean | Promise<boolean> { | ||||||
|         // This plugin doesn't use Moodle filters, it can be edited in offline.
 |         // This plugin doesn't use Moodle filters, it can be edited in offline.
 | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| @ -66,7 +69,8 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      */ |      */ | ||||||
|     clearTmpData(assign: any, submission: any, plugin: any, inputData: any): void { |     clearTmpData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): void { | ||||||
|         const files = this.fileSessionProvider.getFiles(AddonModAssignProvider.COMPONENT, assign.id); |         const files = this.fileSessionProvider.getFiles(AddonModAssignProvider.COMPONENT, assign.id); | ||||||
| 
 | 
 | ||||||
|         // Clear the files in session for this assign.
 |         // Clear the files in session for this assign.
 | ||||||
| @ -87,7 +91,9 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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> { |     copySubmissionData(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin, pluginData: any, | ||||||
|  |             userId?: number, siteId?: string): void | Promise<any> { | ||||||
|  | 
 | ||||||
|         // We need to re-upload all the existing files.
 |         // We need to re-upload all the existing files.
 | ||||||
|         const files = this.assignProvider.getSubmissionPluginAttachments(plugin); |         const files = this.assignProvider.getSubmissionPluginAttachments(plugin); | ||||||
| 
 | 
 | ||||||
| @ -105,7 +111,7 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param edit Whether the user is editing. |      * @param edit Whether the user is editing. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent(injector: Injector, plugin: any, edit?: boolean): any | Promise<any> { |     getComponent(injector: Injector, plugin: AddonModAssignPlugin, edit?: boolean): any | Promise<any> { | ||||||
|         return AddonModAssignSubmissionFileComponent; |         return AddonModAssignSubmissionFileComponent; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -119,7 +125,9 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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> { |     deleteOfflineData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, offlineData: any, siteId?: string): void | Promise<any> { | ||||||
|  | 
 | ||||||
|         return this.assignHelper.deleteStoredSubmissionFiles(assign.id, AddonModAssignSubmissionFileHandler.FOLDER_NAME, |         return this.assignHelper.deleteStoredSubmissionFiles(assign.id, AddonModAssignSubmissionFileHandler.FOLDER_NAME, | ||||||
|                 submission.userid, siteId).catch(() => { |                 submission.userid, siteId).catch(() => { | ||||||
|             // Ignore errors, maybe the folder doesn't exist.
 |             // Ignore errors, maybe the folder doesn't exist.
 | ||||||
| @ -136,7 +144,8 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The files (or promise resolved with the files). |      * @return The files (or promise resolved with the files). | ||||||
|      */ |      */ | ||||||
|     getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]> { |     getPluginFiles(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): any[] | Promise<any[]> { | ||||||
|         return this.assignProvider.getSubmissionPluginAttachments(plugin); |         return this.assignProvider.getSubmissionPluginAttachments(plugin); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -147,7 +156,7 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The size (or promise resolved with size). |      * @return The size (or promise resolved with size). | ||||||
|      */ |      */ | ||||||
|     getSizeForCopy(assign: any, plugin: any): number | Promise<number> { |     getSizeForCopy(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin): number | Promise<number> { | ||||||
|         const files = this.assignProvider.getSubmissionPluginAttachments(plugin), |         const files = this.assignProvider.getSubmissionPluginAttachments(plugin), | ||||||
|             promises = []; |             promises = []; | ||||||
|         let totalSize = 0; |         let totalSize = 0; | ||||||
| @ -177,7 +186,8 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      * @return The size (or promise resolved with size). |      * @return The size (or promise resolved with size). | ||||||
|      */ |      */ | ||||||
|     getSizeForEdit(assign: any, submission: any, plugin: any, inputData: any): number | Promise<number> { |     getSizeForEdit(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): number | Promise<number> { | ||||||
|         const siteId = this.sitesProvider.getCurrentSiteId(); |         const siteId = this.sitesProvider.getCurrentSiteId(); | ||||||
| 
 | 
 | ||||||
|         // Check if there's any change.
 |         // Check if there's any change.
 | ||||||
| @ -232,7 +242,9 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      * @return Boolean (or promise resolved with boolean): whether the data has changed. |      * @return Boolean (or promise resolved with boolean): whether the data has changed. | ||||||
|      */ |      */ | ||||||
|     hasDataChanged(assign: any, submission: any, plugin: any, inputData: any): boolean | Promise<boolean> { |     hasDataChanged(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): boolean | Promise<boolean> { | ||||||
|  | 
 | ||||||
|         // Check if there's any offline data.
 |         // Check if there's any offline data.
 | ||||||
|         return this.assignOfflineProvider.getSubmission(assign.id, submission.userid).catch(() => { |         return this.assignOfflineProvider.getSubmission(assign.id, submission.userid).catch(() => { | ||||||
|             // No offline data found.
 |             // No offline data found.
 | ||||||
| @ -299,7 +311,8 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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, |     prepareSubmissionData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any, pluginData: any, offline?: boolean, | ||||||
|             userId?: number, siteId?: string): void | Promise<any> { |             userId?: number, siteId?: string): void | Promise<any> { | ||||||
| 
 | 
 | ||||||
|         if (this.hasDataChanged(assign, submission, plugin, inputData)) { |         if (this.hasDataChanged(assign, submission, plugin, inputData)) { | ||||||
| @ -330,8 +343,8 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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) |     prepareSyncData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|             : void | Promise<any> { |             plugin: AddonModAssignPlugin, offlineData: any, pluginData: any, siteId?: string): void | Promise<any> { | ||||||
| 
 | 
 | ||||||
|         const filesData = offlineData && offlineData.plugindata && offlineData.plugindata.files_filemanager; |         const filesData = offlineData && offlineData.plugindata && offlineData.plugindata.files_filemanager; | ||||||
|         if (filesData) { |         if (filesData) { | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ | |||||||
| <!-- Edit --> | <!-- Edit --> | ||||||
| <div *ngIf="edit && loaded"> | <div *ngIf="edit && loaded"> | ||||||
|     <ion-item-divider text-wrap>{{ plugin.name }}</ion-item-divider> |     <ion-item-divider text-wrap>{{ plugin.name }}</ion-item-divider> | ||||||
|     <ion-item text-wrap *ngIf="configs.wordlimitenabled && words >= 0"> |     <ion-item text-wrap *ngIf="wordLimitEnabled && words >= 0"> | ||||||
|         <h2>{{ 'addon.mod_assign.wordlimit' | translate }}</h2> |         <h2>{{ 'addon.mod_assign.wordlimit' | translate }}</h2> | ||||||
|         <p>{{ 'core.numwords' | translate: {'$a': words + ' / ' + configs.wordlimit} }}</p> |         <p>{{ 'core.numwords' | translate: {'$a': words + ' / ' + configs.wordlimit} }}</p> | ||||||
|     </ion-item> |     </ion-item> | ||||||
|  | |||||||
| @ -34,6 +34,7 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS | |||||||
|     component = AddonModAssignProvider.COMPONENT; |     component = AddonModAssignProvider.COMPONENT; | ||||||
|     text: string; |     text: string; | ||||||
|     loaded: boolean; |     loaded: boolean; | ||||||
|  |     wordLimitEnabled: boolean; | ||||||
| 
 | 
 | ||||||
|     protected wordCountTimeout: any; |     protected wordCountTimeout: any; | ||||||
|     protected element: HTMLElement; |     protected element: HTMLElement; | ||||||
| @ -61,9 +62,7 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS | |||||||
|             // No offline data found, return online text.
 |             // No offline data found, return online text.
 | ||||||
|             return this.assignProvider.getSubmissionPluginText(this.plugin); |             return this.assignProvider.getSubmissionPluginText(this.plugin); | ||||||
|         }).then((text) => { |         }).then((text) => { | ||||||
|             // We receive them as strings, convert to int.
 |             this.wordLimitEnabled = !!parseInt(this.configs.wordlimitenabled, 10); | ||||||
|             this.configs.wordlimit = parseInt(this.configs.wordlimit, 10); |  | ||||||
|             this.configs.wordlimitenabled = parseInt(this.configs.wordlimitenabled, 10); |  | ||||||
| 
 | 
 | ||||||
|             // Set the text.
 |             // Set the text.
 | ||||||
|             this.text = text; |             this.text = text; | ||||||
| @ -85,7 +84,7 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Calculate initial words.
 |             // Calculate initial words.
 | ||||||
|             if (this.configs.wordlimitenabled) { |             if (this.wordLimitEnabled) { | ||||||
|                 this.words = this.textUtils.countWords(text); |                 this.words = this.textUtils.countWords(text); | ||||||
|             } |             } | ||||||
|         }).finally(() => { |         }).finally(() => { | ||||||
| @ -100,7 +99,7 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS | |||||||
|      */ |      */ | ||||||
|     onChange(text: string): void { |     onChange(text: string): void { | ||||||
|         // Count words if needed.
 |         // Count words if needed.
 | ||||||
|         if (this.configs.wordlimitenabled) { |         if (this.wordLimitEnabled) { | ||||||
|             // Cancel previous wait.
 |             // Cancel previous wait.
 | ||||||
|             clearTimeout(this.wordCountTimeout); |             clearTimeout(this.wordCountTimeout); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,7 +18,9 @@ import { TranslateService } from '@ngx-translate/core'; | |||||||
| import { CoreSitesProvider } from '@providers/sites'; | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| import { CoreWSProvider } from '@providers/ws'; | import { CoreWSProvider } from '@providers/ws'; | ||||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||||
| import { AddonModAssignProvider } from '../../../providers/assign'; | import { | ||||||
|  |     AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin | ||||||
|  | } from '../../../providers/assign'; | ||||||
| import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline'; | import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline'; | ||||||
| import { AddonModAssignHelperProvider } from '../../../providers/helper'; | import { AddonModAssignHelperProvider } from '../../../providers/helper'; | ||||||
| import { AddonModAssignSubmissionHandler } from '../../../providers/submission-delegate'; | import { AddonModAssignSubmissionHandler } from '../../../providers/submission-delegate'; | ||||||
| @ -46,7 +48,8 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. |      * @return Boolean or promise resolved with boolean: whether it can be edited in offline. | ||||||
|      */ |      */ | ||||||
|     canEditOffline(assign: any, submission: any, plugin: any): boolean | Promise<boolean> { |     canEditOffline(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin): boolean | Promise<boolean> { | ||||||
|         // This plugin uses Moodle filters, it cannot be edited in offline.
 |         // This plugin uses Moodle filters, it cannot be edited in offline.
 | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| @ -62,7 +65,9 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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> { |     copySubmissionData(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin, pluginData: any, | ||||||
|  |             userId?: number, siteId?: string): void | Promise<any> { | ||||||
|  | 
 | ||||||
|         const text = this.assignProvider.getSubmissionPluginText(plugin, true), |         const text = this.assignProvider.getSubmissionPluginText(plugin, true), | ||||||
|             files = this.assignProvider.getSubmissionPluginAttachments(plugin); |             files = this.assignProvider.getSubmissionPluginAttachments(plugin); | ||||||
|         let promise; |         let promise; | ||||||
| @ -93,7 +98,7 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign | |||||||
|      * @param edit Whether the user is editing. |      * @param edit Whether the user is editing. | ||||||
|      * @return The component (or promise resolved with component) to use, undefined if not found. |      * @return The component (or promise resolved with component) to use, undefined if not found. | ||||||
|      */ |      */ | ||||||
|     getComponent(injector: Injector, plugin: any, edit?: boolean): any | Promise<any> { |     getComponent(injector: Injector, plugin: AddonModAssignPlugin, edit?: boolean): any | Promise<any> { | ||||||
|         return AddonModAssignSubmissionOnlineTextComponent; |         return AddonModAssignSubmissionOnlineTextComponent; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -107,7 +112,8 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The files (or promise resolved with the files). |      * @return The files (or promise resolved with the files). | ||||||
|      */ |      */ | ||||||
|     getPluginFiles(assign: any, submission: any, plugin: any, siteId?: string): any[] | Promise<any[]> { |     getPluginFiles(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, siteId?: string): any[] | Promise<any[]> { | ||||||
|         return this.assignProvider.getSubmissionPluginAttachments(plugin); |         return this.assignProvider.getSubmissionPluginAttachments(plugin); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -118,7 +124,7 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign | |||||||
|      * @param plugin The plugin object. |      * @param plugin The plugin object. | ||||||
|      * @return The size (or promise resolved with size). |      * @return The size (or promise resolved with size). | ||||||
|      */ |      */ | ||||||
|     getSizeForCopy(assign: any, plugin: any): number | Promise<number> { |     getSizeForCopy(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin): number | Promise<number> { | ||||||
|         const text = this.assignProvider.getSubmissionPluginText(plugin, true), |         const text = this.assignProvider.getSubmissionPluginText(plugin, true), | ||||||
|             files = this.assignProvider.getSubmissionPluginAttachments(plugin), |             files = this.assignProvider.getSubmissionPluginAttachments(plugin), | ||||||
|             promises = []; |             promises = []; | ||||||
| @ -153,7 +159,8 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign | |||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      * @return The size (or promise resolved with size). |      * @return The size (or promise resolved with size). | ||||||
|      */ |      */ | ||||||
|     getSizeForEdit(assign: any, submission: any, plugin: any, inputData: any): number | Promise<number> { |     getSizeForEdit(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): number | Promise<number> { | ||||||
|         const text = this.assignProvider.getSubmissionPluginText(plugin, true); |         const text = this.assignProvider.getSubmissionPluginText(plugin, true); | ||||||
| 
 | 
 | ||||||
|         return text.length; |         return text.length; | ||||||
| @ -182,7 +189,9 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign | |||||||
|      * @param inputData Data entered by the user for the submission. |      * @param inputData Data entered by the user for the submission. | ||||||
|      * @return Boolean (or promise resolved with boolean): whether the data has changed. |      * @return Boolean (or promise resolved with boolean): whether the data has changed. | ||||||
|      */ |      */ | ||||||
|     hasDataChanged(assign: any, submission: any, plugin: any, inputData: any): boolean | Promise<boolean> { |     hasDataChanged(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any): boolean | Promise<boolean> { | ||||||
|  | 
 | ||||||
|         // Get the original text from plugin or offline.
 |         // Get the original text from plugin or offline.
 | ||||||
|         return this.assignOfflineProvider.getSubmission(assign.id, submission.userid).catch(() => { |         return this.assignOfflineProvider.getSubmission(assign.id, submission.userid).catch(() => { | ||||||
|             // No offline data found.
 |             // No offline data found.
 | ||||||
| @ -234,7 +243,8 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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, |     prepareSubmissionData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|  |             plugin: AddonModAssignPlugin, inputData: any, pluginData: any, offline?: boolean, | ||||||
|             userId?: number, siteId?: string): void | Promise<any> { |             userId?: number, siteId?: string): void | Promise<any> { | ||||||
| 
 | 
 | ||||||
|         let text = this.getTextToSubmit(plugin, inputData); |         let text = this.getTextToSubmit(plugin, inputData); | ||||||
| @ -274,8 +284,8 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return If the function is async, it should return a Promise resolved when done. |      * @return 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) |     prepareSyncData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, | ||||||
|             : void | Promise<any> { |             plugin: AddonModAssignPlugin, offlineData: any, pluginData: any, siteId?: string): void | Promise<any> { | ||||||
| 
 | 
 | ||||||
|         const textData = offlineData && offlineData.plugindata && offlineData.plugindata.onlinetext_editor; |         const textData = offlineData && offlineData.plugindata && offlineData.plugindata.onlinetext_editor; | ||||||
|         if (textData) { |         if (textData) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user