Skip to content

Commit

Permalink
Allow to work on complaints (ls1intum#1307)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpbernius authored Apr 21, 2020
1 parent c89c6bf commit 4f53b25
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import de.tum.in.www1.artemis.repository.TextSubmissionRepository;
import de.tum.in.www1.artemis.service.*;
import de.tum.in.www1.artemis.web.rest.dto.TextAssessmentDTO;
import de.tum.in.www1.artemis.web.rest.dto.TextAssessmentUpdateDTO;
import de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException;
import de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException;
import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException;
Expand Down Expand Up @@ -108,11 +109,7 @@ public ResponseEntity<Result> saveTextAssessment(@PathVariable Long exerciseId,
return forbidden("assessment", "assessmentSaveNotAllowed", "The user is not allowed to override the assessment");
}

if (textAssessment.getTextBlocks() != null) {
textAssessment.getTextBlocks().forEach(tb -> tb.setSubmission(optionalTextSubmission.get()));
textBlockRepository.saveAll(textAssessment.getTextBlocks());
}

saveTextBlocks(textAssessment.getTextBlocks(), optionalTextSubmission.get());
Result result = textAssessmentService.saveAssessment(resultId, textAssessment.getFeedbacks(), textExercise);

if (result.getParticipation() != null && result.getParticipation() instanceof StudentParticipation
Expand Down Expand Up @@ -148,10 +145,7 @@ public ResponseEntity<Result> submitTextAssessment(@PathVariable Long exerciseId
return forbidden("assessment", "assessmentSaveNotAllowed", "The user is not allowed to override the assessment");
}

if (textAssessment.getTextBlocks() != null) {
textAssessment.getTextBlocks().forEach(tb -> tb.setSubmission(optionalTextSubmission.get()));
textBlockRepository.saveAll(textAssessment.getTextBlocks());
}
saveTextBlocks(textAssessment.getTextBlocks(), optionalTextSubmission.get());
Result result = textAssessmentService.submitAssessment(resultId, textExercise, textAssessment.getFeedbacks());
StudentParticipation studentParticipation = (StudentParticipation) result.getParticipation();
if (studentParticipation.getExercise().getAssessmentDueDate() == null || studentParticipation.getExercise().getAssessmentDueDate().isBefore(ZonedDateTime.now())) {
Expand All @@ -176,18 +170,17 @@ public ResponseEntity<Result> submitTextAssessment(@PathVariable Long exerciseId
@ResponseStatus(HttpStatus.OK)
@PutMapping("/text-submissions/{submissionId}/assessment-after-complaint")
@PreAuthorize("hasAnyRole('TA', 'INSTRUCTOR', 'ADMIN')")
public ResponseEntity<Result> updateTextAssessmentAfterComplaint(@PathVariable Long submissionId, @RequestBody AssessmentUpdate assessmentUpdate) {
public ResponseEntity<Result> updateTextAssessmentAfterComplaint(@PathVariable Long submissionId, @RequestBody TextAssessmentUpdateDTO assessmentUpdate) {
log.debug("REST request to update the assessment of submission {} after complaint.", submissionId);
User user = userService.getUserWithGroupsAndAuthorities();
TextSubmission textSubmission = textSubmissionService.findOneWithEagerResultAndFeedback(submissionId);
StudentParticipation studentParticipation = (StudentParticipation) textSubmission.getParticipation();
long exerciseId = studentParticipation.getExercise().getId();
TextExercise textExercise = textExerciseService.findOne(exerciseId);
checkAuthorization(textExercise, user);
saveTextBlocks(assessmentUpdate.getTextBlocks(), textSubmission);
Result result = textAssessmentService.updateAssessmentAfterComplaint(textSubmission.getResult(), textExercise, assessmentUpdate);

// TODO: in case of automatic assessment, we might want to update the assessment engine

if (result.getParticipation() != null && result.getParticipation() instanceof StudentParticipation && !authCheckService.isAtLeastInstructorForExercise(textExercise)) {
((StudentParticipation) result.getParticipation()).setParticipant(null);
}
Expand Down Expand Up @@ -394,4 +387,18 @@ private void checkTextExerciseForRequest(@Nullable TextExercise textExercise, Us
validateExercise(textExercise);
checkAuthorization(textExercise, user);
}

/**
* Save TextBlocks received from Client (if present). We need to reference them to the submission first.
* @param textBlocks received from Client
* @param textSubmission to associate blocks with
*/
private void saveTextBlocks(List<TextBlock> textBlocks, TextSubmission textSubmission) {
if (textBlocks != null) {
textBlocks.forEach(tb -> {
tb.setSubmission(textSubmission);
});
textBlockRepository.saveAll(textBlocks);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package de.tum.in.www1.artemis.web.rest.dto;

import java.util.List;

import de.tum.in.www1.artemis.domain.AssessmentUpdate;
import de.tum.in.www1.artemis.domain.TextBlock;

public class TextAssessmentUpdateDTO extends AssessmentUpdate {

private List<TextBlock> textBlocks;

public List<TextBlock> getTextBlocks() {
return textBlocks;
}

public void setTextBlocks(List<TextBlock> textBlocks) {
this.textBlocks = textBlocks;
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
<div class="assessment-container">
<jhi-assessment-header
[hideBackButton]="hideBackButton"
(navigateBack)="navigateBack.emit()"
[isLoading]="isLoading"
[busy]="busy"
[isAssessor]="isAssessor"
[isAtLeastInstructor]="isAtLeastInstructor"
[canOverride]="canOverride"
[assessmentsAreValid]="assessmentsAreValid"
[result]="result"
(save)="save.emit()"
(submit)="submit.emit()"
(cancel)="cancel.emit()"
(nextSubmission)="nextSubmission.emit()"
[hasConflict]="conflicts && conflicts.length >= 0"
(resolveConflict)="resolveConflict.emit()"
[hasComplaint]="!!complaint"
></jhi-assessment-header>
<jhi-assessment-header
[hideBackButton]="hideBackButton"
(navigateBack)="navigateBack.emit()"
[isLoading]="isLoading"
[busy]="busy"
[isAssessor]="isAssessor"
[isAtLeastInstructor]="isAtLeastInstructor"
[canOverride]="canOverride"
[assessmentsAreValid]="assessmentsAreValid"
[result]="result"
(save)="save.emit()"
(submit)="submit.emit()"
(cancel)="cancel.emit()"
(nextSubmission)="nextSubmission.emit()"
[hasConflict]="conflicts && conflicts.length >= 0"
(resolveConflict)="resolveConflict.emit()"
[hasComplaint]="!!complaint"
></jhi-assessment-header>

<jhi-assessment-complaint-alert [complaint]="complaint"></jhi-assessment-complaint-alert>
<jhi-assessment-complaint-alert [complaint]="complaint"></jhi-assessment-complaint-alert>

<ng-content></ng-content>
</div>
<ng-content></ng-content>

<div class="mt-3" *ngIf="complaint">
<jhi-complaints-for-tutor-form
[complaint]="complaint"
[isAllowedToRespond]="complaint.complaintType === ComplaintType.COMPLAINT ? !isAssessor : isAssessor"
(updateAssessmentAfterComplaint)="updateAssessmentAfterComplaint.emit($event)"
>
</jhi-complaints-for-tutor-form>
</div>
<jhi-complaints-for-tutor-form
class="row mt-4"
*ngIf="complaint"
[zeroIndent]="false"
[complaint]="complaint"
[isAllowedToRespond]="complaint.complaintType === ComplaintType.COMPLAINT ? !isAssessor : isAssessor"
(updateAssessmentAfterComplaint)="updateAssessmentAfterComplaint.emit($event)"
></jhi-complaints-for-tutor-form>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Component, EventEmitter, Input, Output, HostBinding } from '@angular/core';
import { Result } from 'app/entities/result.model';
import { ComplaintResponse } from 'app/entities/complaint-response.model';
import { Complaint, ComplaintType } from 'app/entities/complaint.model';
Expand All @@ -16,6 +16,8 @@ import { Conflict } from 'app/exercises/modeling/assess/modeling-assessment-edit
styleUrls: ['./assessment-layout.component.scss'],
})
export class AssessmentLayoutComponent {
@HostBinding('class.assessment-container') readonly assessmentContainerClass = true;

@Input() hideBackButton = false;
@Output() navigateBack = new EventEmitter<void>();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<h3>{{ complaint.complaintType === ComplaintType.MORE_FEEDBACK ? ('artemisApp.moreFeedback.review' | translate) : ('artemisApp.complaint.review' | translate) }}</h3>
<div class="col-12 px-0 mt-2">
<div class="col-12 mt-2" [class.px-0]="zeroIndent">
<div class="alert alert-info" *ngIf="handled">
{{
complaint.complaintType === ComplaintType.MORE_FEEDBACK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Complaint, ComplaintType } from 'app/entities/complaint.model';
providers: [],
})
export class ComplaintsForTutorComponent implements OnInit {
@Input() zeroIndent = true;
@Input() complaint: Complaint;
@Input() isAllowedToRespond: boolean; // indicates if the tutor is allowed to respond (i.e. that he is not the assessor)
// Indicates that the assessment should be updated after a complaint. Includes the corresponding complaint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
(submit)="submit()"
(cancel)="cancel()"
(nextSubmission)="nextSubmission()"
(updateAssessmentAfterComplaint)="updateAssessmentAfterComplaint()"
(updateAssessmentAfterComplaint)="updateAssessmentAfterComplaint($event)"
>
<ng-container *ngIf="submission; then assessment; else noSubmission"></ng-container>
</jhi-assessment-layout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { StudentParticipation } from 'app/entities/participation/student-partici
import { TextSubmission } from 'app/entities/text-submission.model';
import { TextExercise } from 'app/entities/text-exercise.model';
import { Result } from 'app/entities/result.model';
import { Complaint } from 'app/entities/complaint.model';
import { Complaint, ComplaintType } from 'app/entities/complaint.model';
import { ComplaintResponse } from 'app/entities/complaint-response.model';
import { ComplaintService } from 'app/complaints/complaint.service';
import { TextAssessmentsService } from 'app/exercises/text/assess/text-assessments.service';
import { TextBlockRef } from 'app/entities/text-block-ref.model';
Expand Down Expand Up @@ -168,7 +169,29 @@ export class TextSubmissionAssessmentComponent implements OnInit {
this.router.navigate(['course-management', this.exercise?.course?.id, 'text-exercises', this.exercise?.id, 'submissions-new', 'new', 'assessment']);
}

updateAssessmentAfterComplaint(): void {}
/**
* Sends the current (updated) assessment to the server to update the original assessment after a complaint was accepted.
* The corresponding complaint response is sent along with the updated assessment to prevent additional requests.
*
* @param complaintResponse the response to the complaint that is sent to the server along with the assessment update
*/
updateAssessmentAfterComplaint(complaintResponse: ComplaintResponse): void {
this.validateFeedback();
if (!this.assessmentsAreValid) {
this.jhiAlertService.error('artemisApp.textAssessment.error.invalidAssessments');
return;
}

this.assessmentsService.updateAssessmentAfterComplaint(this.assessments, this.textBlocks, complaintResponse, this.submission?.id!).subscribe(
(response) => this.handleSaveOrSubmitSuccessWithAlert(response, 'artemisApp.textAssessment.updateAfterComplaintSuccessful'),
(error: HttpErrorResponse) => {
console.error(error);
this.jhiAlertService.clear();
this.jhiAlertService.error('artemisApp.textAssessment.updateAfterComplaintFailed');
this.busy = false;
},
);
}

private computeTotalScore() {
const credits = this.assessments.map((feedback) => feedback.credits);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ export class TextAssessmentComponent implements OnInit, OnDestroy, AfterViewInit
return;
}

this.assessmentsService.updateAssessmentAfterComplaint(this.assessments, complaintResponse, this.submission.id).subscribe(
this.assessmentsService.updateAssessmentAfterComplaint(this.assessments, [], complaintResponse, this.submission.id).subscribe(
(response) => {
this.result = response.body!;
this.updateParticipationWithResult();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,16 @@ export class TextAssessmentsService {
.map((res: EntityResponseType) => TextAssessmentsService.convertResponse(res));
}

public updateAssessmentAfterComplaint(feedbacks: Feedback[], complaintResponse: ComplaintResponse, submissionId: number): Observable<EntityResponseType> {
public updateAssessmentAfterComplaint(
feedbacks: Feedback[],
textBlocks: TextBlock[],
complaintResponse: ComplaintResponse,
submissionId: number,
): Observable<EntityResponseType> {
const url = `${this.resourceUrl}/text-submissions/${submissionId}/assessment-after-complaint`;
const assessmentUpdate = {
feedbacks,
textBlocks,
complaintResponse,
};
return this.http
Expand Down

0 comments on commit 4f53b25

Please sign in to comment.