Skip to content

Commit 15d8361

Browse files
Stephan Kruschebensofficial
authored andcommitted
Development: Reduce for-dashboard payload significantly when participation results exist (#6984)
1 parent db2087f commit 15d8361

File tree

9 files changed

+43
-30
lines changed

9 files changed

+43
-30
lines changed

src/main/java/de/tum/in/www1/artemis/service/CourseScoreCalculationService.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,16 @@ public CourseForDashboardDTO getScoresAndParticipationResults(Course course, Gra
230230
Map<ExerciseType, CourseScoresDTO> scoresPerExerciseType = calculateCourseScoresPerExerciseType(course, gradedStudentParticipations, userId, plagiarismCases);
231231

232232
// Get participation results (used in course-statistics.component).
233-
List<Result> participationResults = new ArrayList<>();
233+
List<ParticipationResultDTO> participationResults = new ArrayList<>();
234234
for (StudentParticipation studentParticipation : gradedStudentParticipations) {
235235
if (studentParticipation.getResults() != null && !studentParticipation.getResults().isEmpty()) {
236-
Result participationResult = getResultForParticipation(studentParticipation, studentParticipation.getIndividualDueDate());
237-
participationResult.setParticipation(studentParticipation);
236+
Result result = getResultForParticipation(studentParticipation, studentParticipation.getIndividualDueDate());
237+
var participationResult = new ParticipationResultDTO(result.getScore(), result.isRated(), studentParticipation.getId());
238238
participationResults.add(participationResult);
239+
// this line is an important workaround. It prevents that the whole tree
240+
// "result -> participation -> exercise -> course -> exercises -> studentParticipations -> submissions -> results" is sent again to the client which is useless
241+
// TODO: in the future, we need a better solution to prevent this
242+
studentParticipation.setExercise(null);
239243
}
240244
}
241245

src/main/java/de/tum/in/www1/artemis/web/rest/dto/CourseForDashboardDTO.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.fasterxml.jackson.annotation.JsonInclude;
66

77
import de.tum.in.www1.artemis.domain.Course;
8-
import de.tum.in.www1.artemis.domain.Result;
98

109
/**
1110
* Returned by the for-dashboard resources.
@@ -23,5 +22,5 @@
2322
*/
2423
@JsonInclude(JsonInclude.Include.NON_EMPTY)
2524
public record CourseForDashboardDTO(Course course, CourseScoresDTO totalScores, CourseScoresDTO textScores, CourseScoresDTO programmingScores, CourseScoresDTO modelingScores,
26-
CourseScoresDTO fileUploadScores, CourseScoresDTO quizScores, List<Result> participationResults) {
25+
CourseScoresDTO fileUploadScores, CourseScoresDTO quizScores, List<ParticipationResultDTO> participationResults) {
2726
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package de.tum.in.www1.artemis.web.rest.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
5+
@JsonInclude(JsonInclude.Include.NON_EMPTY)
6+
public record ParticipationResultDTO(Double score, Boolean rated, Long participationId) {
7+
}

src/main/webapp/app/course/course-scores/scores-storage.service.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable } from '@angular/core';
2+
import { ParticipationResultDTO } from 'app/course/manage/course-for-dashboard-dto';
23
import { ScoresPerExerciseType } from 'app/entities/exercise.model';
3-
import { Result } from 'app/entities/result.model';
44
import { CourseScores } from 'app/course/course-scores/course-scores';
55

66
/**
@@ -24,7 +24,7 @@ export class ScoresStorageService {
2424
/**
2525
* This map stores the {@link Result} object for each {@link Participation} of the currently logged-in user. The number is the id of the participation.
2626
*/
27-
private storedParticipationResults: Map<number, Result> = new Map();
27+
private storedParticipationResults: Map<number, ParticipationResultDTO> = new Map();
2828

2929
getStoredTotalScores(courseId: number): CourseScores | undefined {
3030
return this.storedTotalScores.get(courseId);
@@ -42,13 +42,13 @@ export class ScoresStorageService {
4242
this.storedScoresPerExerciseType.set(courseId, scoresPerExerciseType);
4343
}
4444

45-
getStoredParticipationResult(participationId: number): Result | undefined {
45+
getStoredParticipationResult(participationId: number): ParticipationResultDTO | undefined {
4646
return this.storedParticipationResults.get(participationId);
4747
}
4848

49-
setStoredParticipationResults(participationResults?: Result[]): void {
50-
for (const result of participationResults ?? []) {
51-
this.storedParticipationResults.set(result.participation!.id!, result);
49+
setStoredParticipationResults(participationResults?: ParticipationResultDTO[]): void {
50+
for (const participationResult of participationResults ?? []) {
51+
this.storedParticipationResults.set(participationResult.participationId, participationResult);
5252
}
5353
}
5454
}

src/main/webapp/app/course/manage/course-for-dashboard-dto.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Course } from 'app/entities/course.model';
22
import { CourseScores } from 'app/course/course-scores/course-scores';
3-
import { Result } from 'app/entities/result.model';
43

54
export class CourseForDashboardDTO {
65
course: Course;
@@ -13,7 +12,14 @@ export class CourseForDashboardDTO {
1312
fileUploadScores: CourseScores;
1413
quizScores: CourseScores;
1514

16-
participationResults: Result[];
15+
participationResults: ParticipationResultDTO[];
1716

1817
constructor() {}
1918
}
19+
20+
export class ParticipationResultDTO {
21+
score?: number;
22+
rated?: boolean;
23+
participationId: number;
24+
constructor() {}
25+
}

src/main/webapp/app/overview/course-statistics/course-statistics.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import { TranslateService } from '@ngx-translate/core';
55
import { Color, ScaleType } from '@swimlane/ngx-charts';
66
import { CourseScores } from 'app/course/course-scores/course-scores';
77
import { ScoresStorageService } from 'app/course/course-scores/scores-storage.service';
8+
import { ParticipationResultDTO } from 'app/course/manage/course-for-dashboard-dto';
89
import { CourseStorageService } from 'app/course/manage/course-storage.service';
910
import { Course } from 'app/entities/course.model';
1011
import { Exercise, ExerciseType, IncludedInOverallScore, ScoresPerExerciseType } from 'app/entities/exercise.model';
1112
import { GradeDTO } from 'app/entities/grade-step.model';
1213
import { GradeType } from 'app/entities/grading-scale.model';
1314
import { InitializationState } from 'app/entities/participation/participation.model';
1415
import { StudentParticipation } from 'app/entities/participation/student-participation.model';
15-
import { Result } from 'app/entities/result.model';
1616
import { GraphColors } from 'app/entities/statistics.model';
1717
import { GradingSystemService } from 'app/grading-system/grading-system.service';
1818
import { BarControlConfiguration, BarControlConfigurationProvider } from 'app/shared/tab-bar/tab-bar';
@@ -326,7 +326,7 @@ export class CourseStatisticsComponent implements OnInit, OnDestroy, AfterViewIn
326326
} else {
327327
exercise.studentParticipations.forEach((participation: StudentParticipation) => {
328328
if (participation.id && participation.results?.length) {
329-
const participationResult: Result | undefined = this.scoresStorageService.getStoredParticipationResult(participation.id);
329+
const participationResult: ParticipationResultDTO | undefined = this.scoresStorageService.getStoredParticipationResult(participation.id);
330330
if (participationResult?.rated) {
331331
const roundedParticipationScore = roundValueSpecifiedByCourseSettings(participationResult.score!, this.course);
332332
const cappedParticipationScore = Math.min(roundedParticipationScore, 100);

src/test/javascript/spec/component/course/course-management.service.spec.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ import { MockRouter } from '../../helpers/mocks/mock-router';
2121
import { MockSyncStorage } from '../../helpers/mocks/service/mock-sync-storage.service';
2222
import { MockTranslateService } from '../../helpers/mocks/service/mock-translate.service';
2323
import { OnlineCourseConfiguration } from 'app/entities/online-course-configuration.model';
24-
import { CourseForDashboardDTO } from 'app/course/manage/course-for-dashboard-dto';
24+
import { CourseForDashboardDTO, ParticipationResultDTO } from 'app/course/manage/course-for-dashboard-dto';
2525
import { CourseScores } from 'app/course/course-scores/course-scores';
2626
import { ScoresStorageService } from 'app/course/course-scores/scores-storage.service';
2727
import { CourseStorageService } from 'app/course/manage/course-storage.service';
28-
import { Result } from 'app/entities/result.model';
2928

3029
describe('Course Management Service', () => {
3130
let courseManagementService: CourseManagementService;
@@ -48,7 +47,7 @@ describe('Course Management Service', () => {
4847
let courseForDashboard: CourseForDashboardDTO;
4948
let courseScores: CourseScores;
5049
let scoresPerExerciseType: ScoresPerExerciseType;
51-
let participationResult: Result;
50+
let participationResult: ParticipationResultDTO;
5251
let onlineCourseConfiguration: OnlineCourseConfiguration;
5352
let exercises: Exercise[];
5453
let returnedFromService: any;
@@ -96,10 +95,8 @@ describe('Course Management Service', () => {
9695
courseForDashboard.quizScores = courseScores;
9796
courseForDashboard.textScores = courseScores;
9897
courseForDashboard.fileUploadScores = courseScores;
99-
participationResult = new Result();
100-
const participation = new StudentParticipation();
101-
participation.id = 432;
102-
participationResult.participation = participation;
98+
participationResult = new ParticipationResultDTO();
99+
participationResult.participationId = 432;
103100
courseForDashboard.participationResults = [participationResult];
104101

105102
scoresPerExerciseType = new Map<ExerciseType, CourseScores>();

src/test/javascript/spec/component/overview/course-statistics/course-statistics.component.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { BarChartModule, PieChartModule } from '@swimlane/ngx-charts';
77
import { CourseScores } from 'app/course/course-scores/course-scores';
88
import { ScoresStorageService } from 'app/course/course-scores/scores-storage.service';
99
import { DueDateStat } from 'app/course/dashboards/due-date-stat.model';
10+
import { ParticipationResultDTO } from 'app/course/manage/course-for-dashboard-dto';
1011
import { CourseStorageService } from 'app/course/manage/course-storage.service';
1112
import { Course } from 'app/entities/course.model';
1213
import { ExerciseCategory } from 'app/entities/exercise-category.model';
@@ -15,7 +16,6 @@ import { FileUploadExercise } from 'app/entities/file-upload-exercise.model';
1516
import { ModelingExercise } from 'app/entities/modeling-exercise.model';
1617
import { ProgrammingExercise } from 'app/entities/programming-exercise.model';
1718
import { QuizExercise } from 'app/entities/quiz/quiz-exercise.model';
18-
import { Result } from 'app/entities/result.model';
1919
import { TreeviewModule } from 'app/exercises/programming/shared/code-editor/treeview/treeview.module';
2020
import { CourseCompetenciesComponent } from 'app/overview/course-competencies/course-competencies.component';
2121
import { CourseStatisticsComponent, NgxExercise } from 'app/overview/course-statistics/course-statistics.component';
@@ -360,7 +360,7 @@ describe('CourseStatisticsComponent', () => {
360360
const courseToAdd = { ...course };
361361
courseToAdd.exercises = [programmingExercise, quizExercise, ...modelingExercises, fileUploadExercise];
362362
jest.spyOn(courseStorageService, 'getCourse').mockReturnValue(courseToAdd);
363-
const mockParticipationResult: Result = { rated: true, score: 100 };
363+
const mockParticipationResult: ParticipationResultDTO = { rated: true, score: 100, participationId: 1 };
364364
jest.spyOn(scoresStorageService, 'getStoredParticipationResult').mockReturnValue(mockParticipationResult);
365365
fixture.detectChanges();
366366
comp.ngOnInit();
@@ -384,7 +384,7 @@ describe('CourseStatisticsComponent', () => {
384384
const courseToAdd = { ...course };
385385
courseToAdd.exercises = [...modelingExercises];
386386
jest.spyOn(courseStorageService, 'getCourse').mockReturnValue(courseToAdd);
387-
const mockParticipationResult: Result = { rated: true, score: 100 };
387+
const mockParticipationResult: ParticipationResultDTO = { rated: true, score: 100, participationId: 1 };
388388
jest.spyOn(scoresStorageService, 'getStoredParticipationResult').mockReturnValue(mockParticipationResult);
389389
fixture.detectChanges();
390390
comp.ngOnInit();
@@ -480,7 +480,7 @@ describe('CourseStatisticsComponent', () => {
480480
});
481481

482482
it('should filter optional exercises correctly', () => {
483-
const mockParticipationResult: Result = { rated: true, score: 100 };
483+
const mockParticipationResult: ParticipationResultDTO = { rated: true, score: 100, participationId: 1 };
484484
jest.spyOn(scoresStorageService, 'getStoredParticipationResult').mockReturnValue(mockParticipationResult);
485485
comp.toggleNotIncludedInScoreExercises();
486486

src/test/javascript/spec/service/scores-storage.service.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ describe('ScoresStorageService', () => {
1212
participation2.id = 2;
1313

1414
scoresStorageService.setStoredParticipationResults([
15-
{ successful: true, participation: participation1 },
16-
{ successful: false, participation: participation2 },
15+
{ score: 100, participationId: participation1.id },
16+
{ score: 0, participationId: participation2.id },
1717
]);
18-
expect(scoresStorageService.getStoredParticipationResult(1)).toEqual({ successful: true, participation: participation1 });
18+
expect(scoresStorageService.getStoredParticipationResult(1)).toEqual({ score: 100, participationId: participation1.id });
1919
// Should return undefined for an unknown participation id.
2020
expect(scoresStorageService.getStoredParticipationResult(3)).toBeUndefined();
2121
});
@@ -24,7 +24,7 @@ describe('ScoresStorageService', () => {
2424
const scoresStorageService = new ScoresStorageService();
2525
const participation = new StudentParticipation();
2626
participation.id = 234;
27-
scoresStorageService.setStoredParticipationResults([{ successful: true, participation }]);
27+
scoresStorageService.setStoredParticipationResults([{ score: 100, participationId: participation.id }]);
2828
expect(scoresStorageService.getStoredParticipationResult(1)).toBeUndefined();
2929
});
3030
});

0 commit comments

Comments
 (0)