@@ -64,6 +64,7 @@ import {
6464 ADDON_MOD_ASSIGN_GRADED_EVENT ,
6565 ADDON_MOD_ASSIGN_MANUAL_SYNCED ,
6666 ADDON_MOD_ASSIGN_PAGE_NAME ,
67+ ADDON_MOD_ASSIGN_SUBMISSION_REMOVED_EVENT ,
6768 ADDON_MOD_ASSIGN_SUBMITTED_FOR_GRADING_EVENT ,
6869 ADDON_MOD_ASSIGN_UNLIMITED_ATTEMPTS ,
6970} from '../../constants' ;
@@ -96,8 +97,9 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
9697 isSubmittedForGrading = false ; // Whether the submission has been submitted for grading.
9798 acceptStatement = false ; // Statement accepted (for grading).
9899 feedback ?: AddonModAssignSubmissionFeedbackFormatted ; // The feedback.
99- hasOffline = false ; // Whether there is offline data .
100+ editedOffline = false ; // Whether the submission was added or edited in offline .
100101 submittedOffline = false ; // Whether it was submitted in offline.
102+ removedOffline = false ; // Whether the submission was removed in offline.
101103 fromDate ?: string ; // Readable date when the assign started accepting submissions.
102104 currentAttempt = 0 ; // The current attempt number.
103105 maxAttemptsText : string ; // The text for maximum attempts.
@@ -108,6 +110,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
108110 membersToSubmitBlind : number [ ] = [ ] ; // Team members that need to submit the assignment (blindmarking).
109111 canSubmit = false ; // Whether the user can submit for grading.
110112 canEdit = false ; // Whether the user can edit the submission.
113+ isRemoveAvailable = false ; // Whether WS to remove submission is available.
111114 submissionStatement ?: string ; // The submission statement.
112115 showErrorStatementEdit = false ; // Whether to show an error in edit due to submission statement.
113116 showErrorStatementSubmit = false ; // Whether to show an error in submit due to submission statement.
@@ -406,6 +409,47 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
406409 ) ;
407410 }
408411
412+ /**
413+ * Remove submisson.
414+ */
415+ async remove ( ) : Promise < void > {
416+ if ( ! this . assign || ! this . userSubmission ) {
417+ return ;
418+ }
419+ const message = this . assign ?. timelimit ?
420+ 'addon.mod_assign.removesubmissionconfirmwithtimelimit' :
421+ 'addon.mod_assign.removesubmissionconfirm' ;
422+ try {
423+ await CoreDomUtils . showDeleteConfirm ( message ) ;
424+ } catch {
425+ return ;
426+ }
427+
428+ const modal = await CoreLoadings . show ( 'core.sending' , true ) ;
429+
430+ try {
431+ const sent = await AddonModAssign . removeSubmission ( this . assign , this . userSubmission ) ;
432+
433+ if ( sent ) {
434+ CoreEvents . trigger ( CoreEvents . ACTIVITY_DATA_SENT , { module : 'assign' } ) ;
435+ }
436+
437+ CoreEvents . trigger (
438+ ADDON_MOD_ASSIGN_SUBMISSION_REMOVED_EVENT ,
439+ {
440+ assignmentId : this . assign . id ,
441+ submissionId : this . userSubmission . id ,
442+ userId : this . currentUserId ,
443+ } ,
444+ CoreSites . getCurrentSiteId ( ) ,
445+ ) ;
446+ } catch ( error ) {
447+ CoreDomUtils . showErrorModalDefault ( error , 'Error removing submission.' ) ;
448+ } finally {
449+ modal . dismiss ( ) ;
450+ }
451+ }
452+
409453 /**
410454 * Check if there's data to save (grade).
411455 *
@@ -633,13 +677,14 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
633677 try {
634678 const submission = await AddonModAssignOffline . getSubmission ( this . assign . id , this . submitId ) ;
635679
636- this . hasOffline = submission && submission . plugindata && Object . keys ( submission . plugindata ) . length > 0 ;
637-
638- this . submittedOffline = ! ! submission ?. submitted ;
680+ this . removedOffline = submission && Object . keys ( submission . plugindata ) . length == 0 ;
681+ this . editedOffline = submission && ! this . removedOffline ;
682+ this . submittedOffline = ! ! submission ?. submitted && ! this . removedOffline ;
639683 } catch ( error ) {
640684 // No offline data found.
641- this . hasOffline = false ;
685+ this . editedOffline = false ;
642686 this . submittedOffline = false ;
687+ this . removedOffline = false ;
643688 }
644689 }
645690
@@ -821,14 +866,14 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
821866 return ;
822867 }
823868
824- if ( this . hasOffline || this . submittedOffline ) {
825- // Offline data .
869+ if ( this . editedOffline || this . submittedOffline ) {
870+ // Added, edited or submitted offline .
826871 this . statusTranslated = Translate . instant ( 'core.notsent' ) ;
827872 this . statusColor = CoreIonicColorNames . WARNING ;
828873 } else if ( ! this . assign . teamsubmission ) {
829874
830875 // Single submission.
831- if ( this . userSubmission && this . userSubmission . status != this . statusNew ) {
876+ if ( this . userSubmission && this . userSubmission . status != this . statusNew && ! this . removedOffline ) {
832877 this . statusTranslated = Translate . instant ( 'addon.mod_assign.submissionstatus_' + this . userSubmission . status ) ;
833878 this . statusColor = AddonModAssign . getSubmissionStatusColor ( this . userSubmission . status ) ;
834879 } else {
@@ -844,10 +889,10 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
844889 } else {
845890
846891 // Team submission.
847- if ( ! status . lastattempt ?. submissiongroup && this . assign . preventsubmissionnotingroup ) {
892+ if ( ! status . lastattempt ?. submissiongroup && this . assign . preventsubmissionnotingroup && ! this . removedOffline ) {
848893 this . statusTranslated = Translate . instant ( 'addon.mod_assign.nosubmission' ) ;
849894 this . statusColor = AddonModAssign . getSubmissionStatusColor ( AddonModAssignSubmissionStatusValues . NO_SUBMISSION ) ;
850- } else if ( this . userSubmission && this . userSubmission . status != this . statusNew ) {
895+ } else if ( this . userSubmission && this . userSubmission . status != this . statusNew && ! this . removedOffline ) {
851896 this . statusTranslated = Translate . instant ( 'addon.mod_assign.submissionstatus_' + this . userSubmission . status ) ;
852897 this . statusColor = AddonModAssign . getSubmissionStatusColor ( this . userSubmission . status ) ;
853898 } else {
@@ -907,7 +952,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
907952 this . courseId ,
908953 acceptStatement ,
909954 this . userSubmission . timemodified ,
910- this . hasOffline ,
955+ this . editedOffline ,
911956 ) ;
912957
913958 // Submitted, trigger event.
@@ -1142,11 +1187,12 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
11421187 this . assign . requiresubmissionstatement = 0 ;
11431188 }
11441189
1145- this . canSubmit = ! this . isSubmittedForGrading && ! this . submittedOffline && ( lastAttempt . cansubmit ||
1146- ( this . hasOffline && AddonModAssign . canSubmitOffline ( this . assign , submissionStatus ) ) ) ;
1190+ this . canSubmit = ! this . isSubmittedForGrading && ! this . submittedOffline && ! this . removedOffline &&
1191+ ( lastAttempt . cansubmit || ( this . editedOffline && AddonModAssign . canSubmitOffline ( this . assign , submissionStatus ) ) ) ;
11471192
11481193 this . canEdit = ! this . isSubmittedForGrading && lastAttempt . canedit &&
11491194 ( ! this . submittedOffline || ! this . assign . submissiondrafts ) ;
1195+ this . isRemoveAvailable = AddonModAssign . isRemoveSubmissionAvailable ( ) ;
11501196
11511197 // Get submission statement if needed.
11521198 if ( this . assign . requiresubmissionstatement && this . assign . submissiondrafts && this . submitId == this . currentUserId ) {
0 commit comments