forked from CIT/Vmeda.Online
		
	MOBILE-3449 assign: Convert some functions to async/await
This commit is contained in:
		
							parent
							
								
									88ac2e0c5c
								
							
						
					
					
						commit
						d2db79ebea
					
				| @ -372,7 +372,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|      * |      * | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     protected loadData(): Promise<any> { |     protected async loadData(): Promise<any> { | ||||||
|         let isBlind = !!this.blindId; |         let isBlind = !!this.blindId; | ||||||
| 
 | 
 | ||||||
|         this.previousAttempt = undefined; |         this.previousAttempt = undefined; | ||||||
| @ -383,44 +383,34 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|             isBlind = false; |             isBlind = false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         try { | ||||||
|             // Get the assignment.
 |             // Get the assignment.
 | ||||||
|         return this.assignProvider.getAssignment(this.courseId, this.moduleId).then((assign) => { |             this.assign = await this.assignProvider.getAssignment(this.courseId, this.moduleId); | ||||||
|             const time = this.timeUtils.timestamp(), |  | ||||||
|                 promises = []; |  | ||||||
| 
 | 
 | ||||||
|             this.assign = assign; |             const time = this.timeUtils.timestamp(); | ||||||
|  |             let promises = []; | ||||||
| 
 | 
 | ||||||
|             if (assign.allowsubmissionsfromdate && assign.allowsubmissionsfromdate >= time) { |             if (this.assign.allowsubmissionsfromdate && this.assign.allowsubmissionsfromdate >= time) { | ||||||
|                 this.fromDate = this.timeUtils.userDate(assign.allowsubmissionsfromdate * 1000); |                 this.fromDate = this.timeUtils.userDate(this.assign.allowsubmissionsfromdate * 1000); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             this.currentAttempt = 0; |             this.currentAttempt = 0; | ||||||
|             this.maxAttemptsText = this.translate.instant('addon.mod_assign.unlimitedattempts'); |             this.maxAttemptsText = this.translate.instant('addon.mod_assign.unlimitedattempts'); | ||||||
|             this.blindMarking = this.isSubmittedForGrading && assign.blindmarking && !assign.revealidentities; |             this.blindMarking = this.isSubmittedForGrading && this.assign.blindmarking && !this.assign.revealidentities; | ||||||
| 
 | 
 | ||||||
|             if (!this.blindMarking && this.submitId != this.currentUserId) { |             if (!this.blindMarking && this.submitId != this.currentUserId) { | ||||||
|                 promises.push(this.userProvider.getProfile(this.submitId, this.courseId).then((profile) => { |                 promises.push(this.loadSubmissionUserProfile()); | ||||||
|                     this.user = profile; |  | ||||||
|                 })); |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Check if there's any offline data for this submission.
 |             // Check if there's any offline data for this submission.
 | ||||||
|             promises.push(this.assignOfflineProvider.getSubmission(assign.id, this.submitId).then((data) => { |             promises.push(this.loadSubmissionOfflineData()); | ||||||
|                 this.hasOffline = data && data.plugindata && Object.keys(data.plugindata).length > 0; | 
 | ||||||
|                 this.submittedOffline = data && data.submitted; |             await Promise.all(promises); | ||||||
|             }).catch(() => { |  | ||||||
|                 // No offline data found.
 |  | ||||||
|                 this.hasOffline = false; |  | ||||||
|                 this.submittedOffline = false; |  | ||||||
|             })); |  | ||||||
| 
 | 
 | ||||||
|             return Promise.all(promises); |  | ||||||
|         }).then(() => { |  | ||||||
|             // Get submission status.
 |             // Get submission status.
 | ||||||
|             return this.assignProvider.getSubmissionStatusWithRetry(this.assign, this.submitId, undefined, isBlind); |             const response = await this.assignProvider.getSubmissionStatusWithRetry(this.assign, this.submitId, undefined, isBlind); | ||||||
|         }).then((response) => { |  | ||||||
| 
 | 
 | ||||||
|             const promises = []; |             promises = []; | ||||||
| 
 | 
 | ||||||
|             this.submissionStatusAvailable = true; |             this.submissionStatusAvailable = true; | ||||||
|             this.lastAttempt = response.lastattempt; |             this.lastAttempt = response.lastattempt; | ||||||
| @ -452,16 +442,41 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Get the submission plugins that don't support editing.
 |             // Get the submission plugins that don't support editing.
 | ||||||
|             promises.push(this.assignProvider.getUnsupportedEditPlugins(this.userSubmission.plugins).then((list) => { |             promises.push(this.loadUnsupportedPlugins()); | ||||||
|                 this.unsupportedEditPlugins = list; |  | ||||||
|             })); |  | ||||||
| 
 | 
 | ||||||
|             return Promise.all(promises); |             await Promise.all(promises); | ||||||
|         }).catch((error) => { |         } catch (error) { | ||||||
|             this.domUtils.showErrorModalDefault(error, 'Error getting assigment data.'); |             this.domUtils.showErrorModalDefault(error, 'Error getting assigment data.'); | ||||||
|         }).finally(() => { |         } finally { | ||||||
|             this.loaded = true; |             this.loaded = true; | ||||||
|         }); |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Load profile of submission's user. | ||||||
|  |      * | ||||||
|  |      * @return Promise resolved when done. | ||||||
|  |      */ | ||||||
|  |     protected async loadSubmissionUserProfile(): Promise<void> { | ||||||
|  |         this.user = await this.userProvider.getProfile(this.submitId, this.courseId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Load offline data for the submission (not the submission grade). | ||||||
|  |      * | ||||||
|  |      * @return Promise resolved when done. | ||||||
|  |      */ | ||||||
|  |     protected async loadSubmissionOfflineData(): Promise<void> { | ||||||
|  |         try { | ||||||
|  |             const data = await this.assignOfflineProvider.getSubmission(this.assign.id, this.submitId); | ||||||
|  | 
 | ||||||
|  |             this.hasOffline = data && data.plugindata && Object.keys(data.plugindata).length > 0; | ||||||
|  |             this.submittedOffline = data && data.submitted; | ||||||
|  |         } catch (error) { | ||||||
|  |             // No offline data found.
 | ||||||
|  |             this.hasOffline = false; | ||||||
|  |             this.submittedOffline = false; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -624,6 +639,15 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the submission plugins that don't support editing. | ||||||
|  |      * | ||||||
|  |      * @return Promise resolved when done. | ||||||
|  |      */ | ||||||
|  |     protected async loadUnsupportedPlugins(): Promise<void> { | ||||||
|  |         this.unsupportedEditPlugins = await this.assignProvider.getUnsupportedEditPlugins(this.userSubmission.plugins); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Set the submission status name and class. |      * Set the submission status name and class. | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -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, AddonModAssignAssign } from './assign'; | import { AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission } from './assign'; | ||||||
| import { AddonModAssignOfflineProvider } from './assign-offline'; | import { AddonModAssignOfflineProvider } from './assign-offline'; | ||||||
| import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | ||||||
| import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; | import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; | ||||||
| @ -134,7 +134,7 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { | |||||||
|      * @param force Wether to force sync not depending on last execution. |      * @param force Wether to force sync not depending on last execution. | ||||||
|      * @return Promise resolved if sync is successful, rejected if sync fails. |      * @return Promise resolved if sync is successful, rejected if sync fails. | ||||||
|      */ |      */ | ||||||
|     syncAllAssignments(siteId?: string, force?: boolean): Promise<any> { |     syncAllAssignments(siteId?: string, force?: boolean): Promise<void> { | ||||||
|         return this.syncOnSites('all assignments', this.syncAllAssignmentsFunc.bind(this), [force], siteId); |         return this.syncOnSites('all assignments', this.syncAllAssignmentsFunc.bind(this), [force], siteId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -145,26 +145,24 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { | |||||||
|      * @param force Wether to force sync not depending on last execution. |      * @param force Wether to force sync not depending on last execution. | ||||||
|      * @param Promise resolved if sync is successful, rejected if sync fails. |      * @param Promise resolved if sync is successful, rejected if sync fails. | ||||||
|      */ |      */ | ||||||
|     protected syncAllAssignmentsFunc(siteId?: string, force?: boolean): Promise<any> { |     protected async syncAllAssignmentsFunc(siteId?: string, force?: boolean): Promise<void> { | ||||||
|         // Get all assignments that have offline data.
 |         // Get all assignments that have offline data.
 | ||||||
|         return this.assignOfflineProvider.getAllAssigns(siteId).then((assignIds) => { |         const assignIds = await this.assignOfflineProvider.getAllAssigns(siteId); | ||||||
|             // Sync all assignments that haven't been synced for a while.
 | 
 | ||||||
|             const promises = assignIds.map((assignId) => { |         // Try to sync all assignments.
 | ||||||
|                 const promise = force ? this.syncAssign(assignId, siteId) : this.syncAssignIfNeeded(assignId, siteId); |         await Promise.all(assignIds.map(async (assignId) => { | ||||||
|  |             const data = force ? await this.syncAssign(assignId, siteId) : await this.syncAssignIfNeeded(assignId, siteId); | ||||||
|  | 
 | ||||||
|  |             if (!data || !data.updated) { | ||||||
|  |                 // Not updated.
 | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|                 return promise.then((data) => { |  | ||||||
|                     if (data && data.updated) { |  | ||||||
|                         // Sync done. Send event.
 |  | ||||||
|             this.eventsProvider.trigger(AddonModAssignSyncProvider.AUTO_SYNCED, { |             this.eventsProvider.trigger(AddonModAssignSyncProvider.AUTO_SYNCED, { | ||||||
|                 assignId: assignId, |                 assignId: assignId, | ||||||
|                             warnings: data.warnings |                 warnings: data.warnings, | ||||||
|             }, siteId); |             }, siteId); | ||||||
|                     } |         })); | ||||||
|                 }); |  | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|             return Promise.all(promises); |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -174,12 +172,12 @@ 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 when the assign is synced or it doesn't need to be synced. |      * @return Promise resolved when the assign is synced or it doesn't need to be synced. | ||||||
|      */ |      */ | ||||||
|     syncAssignIfNeeded(assignId: number, siteId?: string): Promise<void | AddonModAssignSyncResult> { |     async syncAssignIfNeeded(assignId: number, siteId?: string): Promise<void | AddonModAssignSyncResult> { | ||||||
|         return this.isSyncNeeded(assignId, siteId).then((needed) => { |         const needed = await this.isSyncNeeded(assignId, siteId); | ||||||
|  | 
 | ||||||
|         if (needed) { |         if (needed) { | ||||||
|             return this.syncAssign(assignId, siteId); |             return this.syncAssign(assignId, siteId); | ||||||
|         } |         } | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -189,18 +187,9 @@ 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 in success. |      * @return Promise resolved in success. | ||||||
|      */ |      */ | ||||||
|     syncAssign(assignId: number, siteId?: string): Promise<AddonModAssignSyncResult> { |     async syncAssign(assignId: number, siteId?: string): Promise<AddonModAssignSyncResult> { | ||||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); |         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||||
| 
 | 
 | ||||||
|         const promises: Promise<any>[] = [], |  | ||||||
|             result: AddonModAssignSyncResult = { |  | ||||||
|                 warnings: [], |  | ||||||
|                 updated: false |  | ||||||
|             }; |  | ||||||
|         let assign: AddonModAssignAssign, |  | ||||||
|             courseId: number, |  | ||||||
|             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.
 | ||||||
|             return this.getOngoingSync(assignId, siteId); |             return this.getOngoingSync(assignId, siteId); | ||||||
| @ -208,79 +197,116 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { | |||||||
| 
 | 
 | ||||||
|         // Verify that assign isn't blocked.
 |         // Verify that assign isn't blocked.
 | ||||||
|         if (this.syncProvider.isBlocked(AddonModAssignProvider.COMPONENT, assignId, siteId)) { |         if (this.syncProvider.isBlocked(AddonModAssignProvider.COMPONENT, assignId, siteId)) { | ||||||
|             this.logger.debug('Cannot sync assign ' + assignId + ' because it is blocked.'); |             this.logger.error('Cannot sync assign ' + assignId + ' because it is blocked.'); | ||||||
| 
 | 
 | ||||||
|             return Promise.reject(this.translate.instant('core.errorsyncblocked', {$a: this.componentTranslate})); |             throw new Error(this.translate.instant('core.errorsyncblocked', {$a: this.componentTranslate})); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         this.logger.debug('Try to sync assign ' + assignId + ' in site ' + siteId); |         return this.addOngoingSync(assignId, this.performSyncAssign(assignId, siteId), siteId); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         // Get offline submissions to be sent.
 |     /** | ||||||
|         promises.push(this.assignOfflineProvider.getAssignSubmissions(assignId, siteId).catch(() => { |      * Perform the assign submission. | ||||||
|             // No offline data found, return empty array.
 |      * | ||||||
|             return []; |      * @param assignId Assign ID. | ||||||
|         })); |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise resolved in success. | ||||||
|  |      */ | ||||||
|  |     protected async performSyncAssign(assignId: number, siteId?: string): Promise<AddonModAssignSyncResult> { | ||||||
| 
 | 
 | ||||||
|         // Get offline submission grades to be sent.
 |         this.logger.error('Try to sync assign ' + assignId + ' in site ' + siteId); | ||||||
|         promises.push(this.assignOfflineProvider.getAssignSubmissionsGrade(assignId, siteId).catch(() => { |  | ||||||
|             // No offline data found, return empty array.
 |  | ||||||
|             return []; |  | ||||||
|         })); |  | ||||||
| 
 | 
 | ||||||
|         // Sync offline logs.
 |         const result: AddonModAssignSyncResult = { | ||||||
|         promises.push(this.logHelper.syncIfNeeded(AddonModAssignProvider.COMPONENT, assignId, siteId)); |             warnings: [], | ||||||
|  |             updated: false, | ||||||
|  |         }; | ||||||
| 
 | 
 | ||||||
|         syncPromise = Promise.all(promises).then((results) => { |         // Load offline data and sync offline logs.
 | ||||||
|             const submissions = results[0], |         const promisesResults = await Promise.all([ | ||||||
|                 grades = results[1]; |             this.getOfflineSubmissions(assignId, siteId), | ||||||
|  |             this.getOfflineGrades(assignId, siteId), | ||||||
|  |             this.logHelper.syncIfNeeded(AddonModAssignProvider.COMPONENT, assignId, siteId), | ||||||
|  |         ]); | ||||||
|  | 
 | ||||||
|  |         const submissions = promisesResults[0]; | ||||||
|  |         const grades = promisesResults[1]; | ||||||
| 
 | 
 | ||||||
|         if (!submissions.length && !grades.length) { |         if (!submissions.length && !grades.length) { | ||||||
|             // Nothing to sync.
 |             // Nothing to sync.
 | ||||||
|                 return; |             await this.utils.ignoreErrors(this.setSyncTime(assignId, siteId)); | ||||||
|  | 
 | ||||||
|  |             return result; | ||||||
|         } else if (!this.appProvider.isOnline()) { |         } else if (!this.appProvider.isOnline()) { | ||||||
|             // Cannot sync in offline.
 |             // Cannot sync in offline.
 | ||||||
|                 return Promise.reject(null); |             throw new Error(this.translate.instant('core.cannotconnect')); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|             courseId = submissions.length > 0 ? submissions[0].courseid : grades[0].courseid; |         const courseId = submissions.length > 0 ? submissions[0].courseid : grades[0].courseid; | ||||||
| 
 | 
 | ||||||
|             return this.assignProvider.getAssignmentById(courseId, assignId, false, siteId).then((assignData) => { |         const assign = await this.assignProvider.getAssignmentById(courseId, assignId, false, siteId); | ||||||
|                 assign = assignData; |  | ||||||
| 
 | 
 | ||||||
|                 const promises = []; |         let promises = []; | ||||||
|  | 
 | ||||||
|  |         promises = promises.concat(submissions.map(async (submission) => { | ||||||
|  |             await this.syncSubmission(assign, submission, result.warnings, siteId); | ||||||
| 
 | 
 | ||||||
|                 submissions.forEach((submission) => { |  | ||||||
|                     promises.push(this.syncSubmission(assign, submission, result.warnings, siteId).then(() => { |  | ||||||
|             result.updated = true; |             result.updated = true; | ||||||
|         })); |         })); | ||||||
|                 }); |  | ||||||
| 
 | 
 | ||||||
|                 grades.forEach((grade) => { |         promises = promises.concat(grades.map(async (grade) => { | ||||||
|                     promises.push(this.syncSubmissionGrade(assign, grade, result.warnings, courseId, siteId).then(() => { |             await this.syncSubmissionGrade(assign, grade, result.warnings, courseId, siteId); | ||||||
|  | 
 | ||||||
|             result.updated = true; |             result.updated = true; | ||||||
|         })); |         })); | ||||||
|                 }); |  | ||||||
| 
 | 
 | ||||||
|                 return Promise.all(promises); |         await Promise.all(promises); | ||||||
|             }).then(() => { | 
 | ||||||
|         if (result.updated) { |         if (result.updated) { | ||||||
|             // Data has been sent to server. Now invalidate the WS calls.
 |             // Data has been sent to server. Now invalidate the WS calls.
 | ||||||
|                     return this.assignProvider.invalidateContent(assign.cmid, courseId, siteId).catch(() => { |             await this.utils.ignoreErrors(this.assignProvider.invalidateContent(assign.cmid, courseId, siteId)); | ||||||
|                         // Ignore errors.
 |  | ||||||
|                     }); |  | ||||||
|         } |         } | ||||||
|             }); | 
 | ||||||
|         }).then(() => { |  | ||||||
|         // Sync finished, set sync time.
 |         // Sync finished, set sync time.
 | ||||||
|             return this.setSyncTime(assignId, siteId).catch(() => { |         await this.utils.ignoreErrors(this.setSyncTime(assignId, siteId)); | ||||||
|                 // Ignore errors.
 | 
 | ||||||
|             }); |  | ||||||
|         }).then(() => { |  | ||||||
|         // All done, return the result.
 |         // All done, return the result.
 | ||||||
|         return result; |         return result; | ||||||
|         }); |     } | ||||||
| 
 | 
 | ||||||
|         return this.addOngoingSync(assignId, syncPromise, siteId); |     /** | ||||||
|  |      * Get offline grades to be sent. | ||||||
|  |      * | ||||||
|  |      * @param assignId Assign ID. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise with grades. | ||||||
|  |      */ | ||||||
|  |     protected async getOfflineGrades(assignId: number, siteId: string): Promise<any[]> { | ||||||
|  |         try { | ||||||
|  |             const submissions = await this.assignOfflineProvider.getAssignSubmissionsGrade(assignId, siteId); | ||||||
|  | 
 | ||||||
|  |             return submissions; | ||||||
|  |         } catch (error) { | ||||||
|  |             // No offline data found, return empty array.
 | ||||||
|  |             return []; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get offline submissions to be sent. | ||||||
|  |      * | ||||||
|  |      * @param assignId Assign ID. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise with submissions. | ||||||
|  |      */ | ||||||
|  |     protected async getOfflineSubmissions(assignId: number, siteId: string): Promise<any[]> { | ||||||
|  |         try { | ||||||
|  |             const submissions = await this.assignOfflineProvider.getAssignSubmissions(assignId, siteId); | ||||||
|  | 
 | ||||||
|  |             return submissions; | ||||||
|  |         } catch (error) { | ||||||
|  |             // No offline data found, return empty array.
 | ||||||
|  |             return []; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -292,83 +318,76 @@ 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: AddonModAssignAssign, offlineData: any, warnings: string[], siteId?: string): Promise<any> { |     protected async syncSubmission(assign: AddonModAssignAssign, offlineData: any, warnings: string[], siteId?: string) | ||||||
|         const userId = offlineData.userid, |             : Promise<void> { | ||||||
|             pluginData = {}; |  | ||||||
|         let discardError, |  | ||||||
|             submission; |  | ||||||
| 
 | 
 | ||||||
|         return this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId).then((status) => { |         const userId = offlineData.userid; | ||||||
|             const promises = []; |         const pluginData = {}; | ||||||
| 
 | 
 | ||||||
|             submission = this.assignProvider.getSubmissionObjectFromAttempt(assign, status.lastattempt); |         const status = await this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId); | ||||||
|  | 
 | ||||||
|  |         const submission = this.assignProvider.getSubmissionObjectFromAttempt(assign, status.lastattempt); | ||||||
| 
 | 
 | ||||||
|         if (submission.timemodified != offlineData.onlinetimemodified) { |         if (submission.timemodified != offlineData.onlinetimemodified) { | ||||||
|             // The submission was modified in Moodle, discard the submission.
 |             // The submission was modified in Moodle, discard the submission.
 | ||||||
|                 discardError = this.translate.instant('addon.mod_assign.warningsubmissionmodified'); |             this.addOfflineDataDeletedWarning(warnings, this.componentTranslate, assign.name, | ||||||
|  |                     this.translate.instant('addon.mod_assign.warningsubmissionmodified')); | ||||||
| 
 | 
 | ||||||
|                 return; |             return this.deleteSubmissionData(assign, submission, offlineData, siteId); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|             submission.plugins.forEach((plugin) => { |         try { | ||||||
|                 promises.push(this.submissionDelegate.preparePluginSyncData(assign, submission, plugin, offlineData, pluginData, |             // Prepare plugins data.
 | ||||||
|                         siteId)); |             await Promise.all(submission.plugins.map(async (plugin) => { | ||||||
|             }); |                 await this.submissionDelegate.preparePluginSyncData(assign, submission, plugin, offlineData, pluginData, siteId); | ||||||
|  |             })); | ||||||
| 
 | 
 | ||||||
|             return Promise.all(promises).then(() => { |  | ||||||
|             // Now save the submission.
 |             // Now save the submission.
 | ||||||
|                 let promise; |             if (Object.keys(pluginData).length > 0) { | ||||||
| 
 |                 await this.assignProvider.saveSubmissionOnline(assign.id, pluginData, siteId); | ||||||
|                 if (!Object.keys(pluginData).length) { |  | ||||||
|                     // Nothing to save.
 |  | ||||||
|                     promise = Promise.resolve(); |  | ||||||
|                 } else { |  | ||||||
|                     promise = this.assignProvider.saveSubmissionOnline(assign.id, pluginData, siteId); |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|                 return promise.then(() => { |  | ||||||
|             if (assign.submissiondrafts && offlineData.submitted) { |             if (assign.submissiondrafts && offlineData.submitted) { | ||||||
|                 // The user submitted the assign manually. Submit it for grading.
 |                 // The user submitted the assign manually. Submit it for grading.
 | ||||||
|                         return this.assignProvider.submitForGradingOnline(assign.id, offlineData.submissionstatement, siteId); |                 await this.assignProvider.submitForGradingOnline(assign.id, offlineData.submissionstatement, siteId); | ||||||
|             } |             } | ||||||
|                 }).then(() => { | 
 | ||||||
|             // Submission data sent, update cached data. No need to block the user for this.
 |             // Submission data sent, update cached data. No need to block the user for this.
 | ||||||
|             this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId); |             this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId); | ||||||
|                 }); |         } catch (error) { | ||||||
|             }).catch((error) => { |             if (!error || !this.utils.isWebServiceError(error)) { | ||||||
|                 if (error && this.utils.isWebServiceError(error)) { |                 // Local error, reject.
 | ||||||
|  |                 throw error; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             // A WebService has thrown an error, this means it cannot be submitted. Discard the submission.
 |             // A WebService has thrown an error, this means it cannot be submitted. Discard the submission.
 | ||||||
|                     discardError = this.textUtils.getErrorMessageFromError(error); |             this.addOfflineDataDeletedWarning(warnings, this.componentTranslate, assign.name, | ||||||
|                 } else { |                 this.textUtils.getErrorMessageFromError(error)); | ||||||
|                     // Couldn't connect to server, reject.
 |  | ||||||
|                     return Promise.reject(error); |  | ||||||
|         } |         } | ||||||
|             }); | 
 | ||||||
|         }).then(() => { |  | ||||||
|         // Delete the offline data.
 |         // Delete the offline data.
 | ||||||
|             return this.assignOfflineProvider.deleteSubmission(assign.id, userId, siteId).then(() => { |         await this.deleteSubmissionData(assign, submission, offlineData, siteId); | ||||||
|                 const promises = []; |  | ||||||
| 
 |  | ||||||
|                 submission.plugins.forEach((plugin) => { |  | ||||||
|                     promises.push(this.submissionDelegate.deletePluginOfflineData(assign, submission, plugin, offlineData, siteId)); |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|                 return Promise.all(promises); |  | ||||||
|             }); |  | ||||||
|         }).then(() => { |  | ||||||
|             if (discardError) { |  | ||||||
|                 // Submission was discarded, add a warning.
 |  | ||||||
|                 const message = this.translate.instant('core.warningofflinedatadeleted', { |  | ||||||
|                     component: this.componentTranslate, |  | ||||||
|                     name: assign.name, |  | ||||||
|                     error: discardError |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|                 if (warnings.indexOf(message) == -1) { |  | ||||||
|                     warnings.push(message); |  | ||||||
|     } |     } | ||||||
|             } | 
 | ||||||
|         }); |     /** | ||||||
|  |      * Delete the submission offline data (not grades). | ||||||
|  |      * | ||||||
|  |      * @param assign Assign. | ||||||
|  |      * @param submission Submission. | ||||||
|  |      * @param offlineData Offline data. | ||||||
|  |      * @param siteId Site ID. | ||||||
|  |      * @return Promise resolved when done. | ||||||
|  |      */ | ||||||
|  |     protected async deleteSubmissionData(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, offlineData: any, | ||||||
|  |             siteId?: string): Promise<void> { | ||||||
|  | 
 | ||||||
|  |         // Delete the offline data.
 | ||||||
|  |         await this.assignOfflineProvider.deleteSubmission(assign.id, offlineData.userid, siteId); | ||||||
|  | 
 | ||||||
|  |         // Delete plugins data.
 | ||||||
|  |         await Promise.all(submission.plugins.map(async (plugin) => { | ||||||
|  |             await this.submissionDelegate.deletePluginOfflineData(assign, submission, plugin, offlineData, siteId); | ||||||
|  |         })); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -381,34 +400,36 @@ 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: AddonModAssignAssign, offlineData: any, warnings: string[], courseId: number, |     protected async syncSubmissionGrade(assign: AddonModAssignAssign, offlineData: any, warnings: string[], courseId: number, | ||||||
|             siteId?: string): Promise<any> { |             siteId?: string): Promise<any> { | ||||||
| 
 | 
 | ||||||
|         const userId = offlineData.userid; |         const userId = offlineData.userid; | ||||||
|         let discardError; |  | ||||||
|         const syncId = this.getGradeSyncId(assign.id, userId); |         const syncId = this.getGradeSyncId(assign.id, userId); | ||||||
| 
 | 
 | ||||||
|         // Check if this grade sync is blocked.
 |         // Check if this grade sync is blocked.
 | ||||||
|         if (this.syncProvider.isBlocked(AddonModAssignProvider.COMPONENT, syncId, siteId)) { |         if (this.syncProvider.isBlocked(AddonModAssignProvider.COMPONENT, syncId, siteId)) { | ||||||
|             this.logger.error(`Cannot sync grade for assign ${assign.id} and user ${userId} because it is blocked.`); |             this.logger.error(`Cannot sync grade for assign ${assign.id} and user ${userId} because it is blocked.`); | ||||||
| 
 | 
 | ||||||
|             return Promise.reject(new Error(this.translate.instant('core.errorsyncblocked', |             throw new Error(this.translate.instant('core.errorsyncblocked', | ||||||
|                     {$a: this.translate.instant('addon.mod_assign.syncblockedusercomponent')}))); |                     {$a: this.translate.instant('addon.mod_assign.syncblockedusercomponent')})); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId).then((status) => { |         const status = await this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId); | ||||||
|  | 
 | ||||||
|         const timemodified = status.feedback && (status.feedback.gradeddate || status.feedback.grade.timemodified); |         const timemodified = status.feedback && (status.feedback.gradeddate || status.feedback.grade.timemodified); | ||||||
| 
 | 
 | ||||||
|         if (timemodified > offlineData.timemodified) { |         if (timemodified > offlineData.timemodified) { | ||||||
|             // The submission grade was modified in Moodle, discard it.
 |             // The submission grade was modified in Moodle, discard it.
 | ||||||
|                 discardError = this.translate.instant('addon.mod_assign.warningsubmissiongrademodified'); |             this.addOfflineDataDeletedWarning(warnings, this.componentTranslate, assign.name, | ||||||
|  |                     this.translate.instant('addon.mod_assign.warningsubmissiongrademodified')); | ||||||
| 
 | 
 | ||||||
|                 return; |             return this.assignOfflineProvider.deleteSubmissionGrade(assign.id, userId, siteId); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // If grade has been modified from gradebook, do not use offline.
 |         // If grade has been modified from gradebook, do not use offline.
 | ||||||
|             return this.gradesHelper.getGradeModuleItems(courseId, assign.cmid, userId, undefined, siteId, true).then((grades) => { |         const grades = await this.gradesHelper.getGradeModuleItems(courseId, assign.cmid, userId, undefined, siteId, true); | ||||||
|                 return this.courseProvider.getModuleBasicGradeInfo(assign.cmid, siteId).then((gradeInfo) => { | 
 | ||||||
|  |         const gradeInfo = await this.courseProvider.getModuleBasicGradeInfo(assign.cmid, siteId); | ||||||
| 
 | 
 | ||||||
|         // Override offline grade and outcomes based on the gradebook data.
 |         // Override offline grade and outcomes based on the gradebook data.
 | ||||||
|         grades.forEach((grade) => { |         grades.forEach((grade) => { | ||||||
| @ -429,14 +450,14 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|                 }); | 
 | ||||||
|             }).then(() => { |         try { | ||||||
|              // Now submit the grade.
 |              // Now submit the grade.
 | ||||||
|                 return this.assignProvider.submitGradingFormOnline(assign.id, userId, offlineData.grade, offlineData.attemptnumber, |             await this.assignProvider.submitGradingFormOnline(assign.id, userId, offlineData.grade, offlineData.attemptnumber, | ||||||
|                     offlineData.addattempt, offlineData.workflowstate, offlineData.applytoall, offlineData.outcomes, |                     offlineData.addattempt, offlineData.workflowstate, offlineData.applytoall, offlineData.outcomes, | ||||||
|                         offlineData.plugindata, siteId).then(() => { |                     offlineData.plugindata, siteId); | ||||||
|                     // Grades sent.
 | 
 | ||||||
|                     // Discard grades drafts.
 |             // Grades sent. Discard grades drafts.
 | ||||||
|             const promises = []; |             const promises = []; | ||||||
|             if (status.feedback && status.feedback.plugins) { |             if (status.feedback && status.feedback.plugins) { | ||||||
|                 status.feedback.plugins.forEach((plugin) => { |                 status.feedback.plugins.forEach((plugin) => { | ||||||
| @ -447,34 +468,20 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { | |||||||
|             // Update cached data.
 |             // Update cached data.
 | ||||||
|             promises.push(this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId)); |             promises.push(this.assignProvider.getSubmissionStatus(assign.id, userId, undefined, false, true, true, siteId)); | ||||||
| 
 | 
 | ||||||
|                     return Promise.all(promises); |             await Promise.all(promises); | ||||||
|                 }).catch((error) => { |         } catch (error) { | ||||||
|                     if (error && this.utils.isWebServiceError(error)) { |             if (!error || !this.utils.isWebServiceError(error)) { | ||||||
|                         // The WebService has thrown an error, this means it cannot be submitted. Discard the offline data.
 |                 // Local error, reject.
 | ||||||
|                         discardError = this.textUtils.getErrorMessageFromError(error); |                 throw error; | ||||||
|                     } else { |  | ||||||
|                         // Couldn't connect to server, reject.
 |  | ||||||
|                     return Promise.reject(error); |  | ||||||
|             } |             } | ||||||
|                 }); |  | ||||||
|             }); |  | ||||||
|         }).then(() => { |  | ||||||
|             // Delete the offline data.
 |  | ||||||
|             return this.assignOfflineProvider.deleteSubmissionGrade(assign.id, userId, siteId); |  | ||||||
|         }).then(() => { |  | ||||||
|             if (discardError) { |  | ||||||
|                 // Submission grade was discarded, add a warning.
 |  | ||||||
|                 const message = this.translate.instant('core.warningofflinedatadeleted', { |  | ||||||
|                     component: this.componentTranslate, |  | ||||||
|                     name: assign.name, |  | ||||||
|                     error: discardError |  | ||||||
|                 }); |  | ||||||
| 
 | 
 | ||||||
|                 if (warnings.indexOf(message) == -1) { |             // A WebService has thrown an error, this means it cannot be submitted. Discard the submission.
 | ||||||
|                     warnings.push(message); |             this.addOfflineDataDeletedWarning(warnings, this.componentTranslate, assign.name, | ||||||
|  |                 this.textUtils.getErrorMessageFromError(error)); | ||||||
|         } |         } | ||||||
|             } | 
 | ||||||
|         }); |         // Delete the offline data.
 | ||||||
|  |         await this.assignOfflineProvider.deleteSubmissionGrade(assign.id, userId, siteId); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -52,6 +52,26 @@ export class CoreSyncBaseProvider { | |||||||
|         this.component = component; |         this.component = component; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Add an offline data deleted warning to a list of warnings. | ||||||
|  |      * | ||||||
|  |      * @param warnings List of warnings. | ||||||
|  |      * @param component Component. | ||||||
|  |      * @param name Instance name. | ||||||
|  |      * @param error Specific error message. | ||||||
|  |      */ | ||||||
|  |     protected addOfflineDataDeletedWarning(warnings: string[], component: string, name: string, error: string): void { | ||||||
|  |         const warning = this.translate.instant('core.warningofflinedatadeleted', { | ||||||
|  |             component: component, | ||||||
|  |             name: name, | ||||||
|  |             error: error, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         if (warnings.indexOf(warning) == -1) { | ||||||
|  |             warnings.push(warning); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Add an ongoing sync to the syncPromises list. On finish the promise will be removed. |      * Add an ongoing sync to the syncPromises list. On finish the promise will be removed. | ||||||
|      * |      * | ||||||
| @ -60,7 +80,7 @@ export class CoreSyncBaseProvider { | |||||||
|      * @param siteId Site ID. If not defined, current site. |      * @param siteId Site ID. If not defined, current site. | ||||||
|      * @return The sync promise. |      * @return The sync promise. | ||||||
|      */ |      */ | ||||||
|     addOngoingSync(id: string | number, promise: Promise<any>, siteId?: string): Promise<any> { |     addOngoingSync<T>(id: string | number, promise: Promise<T>, siteId?: string): Promise<T> { | ||||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); |         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||||
| 
 | 
 | ||||||
|         const uniqueId = this.getUniqueSyncId(id); |         const uniqueId = this.getUniqueSyncId(id); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user