Skip to content

Commit

Permalink
Merge branch 'develop' into chore/cleanup-service-improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
coolchock committed Nov 30, 2024
2 parents 530914e + 2611d04 commit ced1ea5
Show file tree
Hide file tree
Showing 484 changed files with 13,021 additions and 4,244 deletions.
8 changes: 4 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ Prerequisites:
- [ ] Test 2

### Test Coverage
<!-- Please add the test coverages for all changed files here. You can see this when executing the tests locally (see build.gradle and package.json) or when looking into the corresponding Bamboo build plan. -->
<!-- The line coverage must be above 90% for changes files and you must use extensive and useful assertions for server tests and expect statements for client tests. -->
<!-- Note: Use the table below and confirm in the last column that you have implemented extensive assertions for server tests and expect statements for client tests. -->
<!-- You can use `supporting_script/generate_code_cov_table/generate_code_cov_table.py` to automatically generate one from the corresponding Bamboo build plan artefacts. -->
<!-- Please add the test coverages for all changed files modified in this PR here. You can use `supporting_script/generate_code_cov_table/generate_code_cov_table.py` to automatically generate the coverage table from the corresponding artefacts of your branch (follow the ReadMe for setup details). -->
<!-- Alternatively you can execute the tests locally (see build.gradle and package.json) or look into the corresponding artefacts. -->
<!-- The line coverage must be above 90% for changes files, and you must use extensive and useful assertions for server tests and expect statements for client tests. -->
<!-- Note: Confirm in the last column that you have implemented extensive assertions for server tests and expect statements for client tests. -->
<!-- Remove rows with only trivial changes from the table. -->
<!--
| Class/File | Line Coverage | Confirmation (assert/expect) |
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ Refer to [Using JHipster in production](http://www.jhipster.tech/production) for
The following command can automate the deployment to a server. The example shows the deployment to the main Artemis test server (which runs a virtual machine):

```shell
./artemis-server-cli deploy username@artemistest.ase.in.tum.de -w build/libs/Artemis-7.7.2.war
./artemis-server-cli deploy username@artemistest.ase.in.tum.de -w build/libs/Artemis-7.7.4.war
```

## Architecture
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ plugins {
}

group = "de.tum.cit.aet.artemis"
version = "7.7.2"
version = "7.7.4"
description = "Interactive Learning with Individual Feedback"

java {
Expand Down
Binary file modified docs/user/exams/student/access_exam.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user/exams/student/buttons/exam_hand_in_early.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/exams/student/buttons/save_exercise.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/exams/student/buttons/upload.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user/exams/student/exam_bar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user/exams/student/exam_modeling_exercises.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user/exams/student/exam_navigation_sidebar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user/exams/student/exam_overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user/exams/student/exam_programming_exercises.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user/exams/student/exam_quiz_exercises.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/user/exams/student/exam_text_exercises.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions docs/user/exams/students_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ Welcome Screen

Welcome Screen, waiting for exam start

This video offers a detailed guide on accessing your exams:

.. raw:: html

<iframe src="https://live.rbg.tum.de/w/artemisintro/52546?video_only=1&t=0" allowfullscreen="1" frameborder="0" width="600" height="350">
Watch this video on TUM-Live.
</iframe>

Exam Conduction
^^^^^^^^^^^^^^^
- Once the exam working time starts and you have confirmed your participation, the *Exercise Overview* screen will appear. This screen lists all exercises that are part of your exam with their respective amount of points, title and exercise type. The status column indicates the status of each exercise and whether you have a submission in them or not.
Expand Down Expand Up @@ -132,6 +140,14 @@ Exam Conduction

Exam Navigation Sidebar

- You have two options to save your changes for an exercise:

1. Click the |save_exercise| button to manually save and submit your changes.
2. Select an exercise in the navigation sidebar (either the current one or a different exercise), which will automatically save and submit your changes.

.. warning::
The |save_exercise| button is only available for text, modeling, and quiz exercises. For file upload exercises, you need to manually click the |upload| button, and for programming exercises, you need to manually click the |submit| button to save and submit your changes.

- On the header, you will find the exam bar that includes the remaining time and the |exam_hand_in_early| button. If you click this button, you will be sent to the exam `End Screen`_.
- The *time left* until the end of the exam is also shown next to the button.

Expand Down Expand Up @@ -373,6 +389,14 @@ Summary

Complaining about the Assessment of a Text Exercise

This video offers a detailed guide on participating in your exams:

.. raw:: html

<iframe src="https://live.rbg.tum.de/w/artemisintro/53405?video_only=1&t=0" allowfullscreen="1" frameborder="0" width="600" height="350">
Watch this video on TUM-Live.
</iframe>

Example Solutions
^^^^^^^^^^^^^^^^^
- If the instructor sets the example solution publication date of the exam, the solutions will be available after that date.
Expand Down Expand Up @@ -470,3 +494,5 @@ Grades
.. |exam_no_results_found| image:: student/buttons/exam_no_results_found.png
.. |exam_hand_in_early| image:: student/buttons/exam_hand_in_early.png
.. |saved_exercises| image:: student/buttons/saved_exercises.png
.. |upload| image:: student/buttons/upload.png
.. |save_exercise| image:: student/buttons/save_exercise.png
39 changes: 2 additions & 37 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "artemis",
"version": "7.7.2",
"version": "7.7.4",
"description": "Interactive Learning with Individual Feedback",
"private": true,
"license": "MIT",
Expand Down Expand Up @@ -69,7 +69,6 @@
"papaparse": "5.4.1",
"pdf-lib": "1.17.1",
"pdfjs-dist": "4.8.69",
"posthog-js": "1.187.2",
"rxjs": "7.8.1",
"simple-statistics": "7.8.7",
"smoothscroll-polyfill": "0.4.4",
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/de/tum/cit/aet/artemis/assessment/domain/Result.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,12 @@ public class Result extends DomainObject implements Comparable<Result> {
@JsonView(QuizView.Before.class)
private List<Feedback> feedbacks = new ArrayList<>();

/**
* @deprecated: Will be removed for 8.0, please use submission.participation instead
*/
@ManyToOne
@JsonView(QuizView.Before.class)
@Deprecated(since = "7.7", forRemoval = true)
private Participation participation;

@ManyToOne(fetch = FetchType.LAZY)
Expand Down Expand Up @@ -385,15 +389,31 @@ private boolean feedbackTextHasChanged(String existingText, String newText) {
return !Objects.equals(existingText, newText);
}

/**
* @deprecated: Will be removed for 8.0, please use submission.participation instead
* @return the participation
*/
@Deprecated(since = "7.7", forRemoval = true)
public Participation getParticipation() {
return participation;
}

/**
* @deprecated: Will be removed for 8.0, please use submission.participation instead
* @param participation the participation to set
* @return the result
*/
@Deprecated(since = "7.7", forRemoval = true)
public Result participation(Participation participation) {
this.participation = participation;
return this;
}

/**
* @deprecated: Will be removed for 8.0, please use submission.participation instead
* @param participation the participation to set
*/
@Deprecated(since = "7.7", forRemoval = true)
public void setParticipation(Participation participation) {
this.participation = participation;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import de.tum.cit.aet.artemis.assessment.dto.AssessmentUpdateBaseDTO;
import de.tum.cit.aet.artemis.assessment.repository.ComplaintRepository;
import de.tum.cit.aet.artemis.assessment.repository.FeedbackRepository;
import de.tum.cit.aet.artemis.assessment.repository.LongFeedbackTextRepository;
import de.tum.cit.aet.artemis.assessment.repository.ResultRepository;
import de.tum.cit.aet.artemis.assessment.web.ResultWebsocketService;
import de.tum.cit.aet.artemis.communication.service.notifications.SingleUserNotificationService;
Expand Down Expand Up @@ -68,12 +67,10 @@ public class AssessmentService {

protected final ResultWebsocketService resultWebsocketService;

private final LongFeedbackTextRepository longFeedbackTextRepository;

public AssessmentService(ComplaintResponseService complaintResponseService, ComplaintRepository complaintRepository, FeedbackRepository feedbackRepository,
ResultRepository resultRepository, StudentParticipationRepository studentParticipationRepository, ResultService resultService, SubmissionService submissionService,
SubmissionRepository submissionRepository, ExamDateService examDateService, UserRepository userRepository, Optional<LtiNewResultService> ltiNewResultService,
SingleUserNotificationService singleUserNotificationService, ResultWebsocketService resultWebsocketService, LongFeedbackTextRepository longFeedbackTextRepository) {
SingleUserNotificationService singleUserNotificationService, ResultWebsocketService resultWebsocketService) {
this.complaintResponseService = complaintResponseService;
this.complaintRepository = complaintRepository;
this.feedbackRepository = feedbackRepository;
Expand All @@ -87,7 +84,6 @@ public AssessmentService(ComplaintResponseService complaintResponseService, Comp
this.ltiNewResultService = ltiNewResultService;
this.singleUserNotificationService = singleUserNotificationService;
this.resultWebsocketService = resultWebsocketService;
this.longFeedbackTextRepository = longFeedbackTextRepository;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import de.tum.cit.aet.artemis.assessment.repository.ResultRepository;
import de.tum.cit.aet.artemis.assessment.repository.StudentScoreRepository;
import de.tum.cit.aet.artemis.assessment.repository.TeamScoreRepository;
import de.tum.cit.aet.artemis.atlas.service.competency.CompetencyProgressService;
import de.tum.cit.aet.artemis.atlas.api.CompetencyProgressApi;
import de.tum.cit.aet.artemis.core.domain.User;
import de.tum.cit.aet.artemis.core.repository.UserRepository;
import de.tum.cit.aet.artemis.core.security.SecurityUtils;
Expand Down Expand Up @@ -74,7 +74,7 @@ public class ParticipantScoreScheduleService {

private Optional<Instant> lastScheduledRun = Optional.empty();

private final CompetencyProgressService competencyProgressService;
private final CompetencyProgressApi competencyProgressApi;

private final ParticipantScoreRepository participantScoreRepository;

Expand All @@ -96,11 +96,11 @@ public class ParticipantScoreScheduleService {
*/
private final AtomicBoolean isRunning = new AtomicBoolean(false);

public ParticipantScoreScheduleService(@Qualifier("taskScheduler") TaskScheduler scheduler, CompetencyProgressService competencyProgressService,
public ParticipantScoreScheduleService(@Qualifier("taskScheduler") TaskScheduler scheduler, CompetencyProgressApi competencyProgressApi,
ParticipantScoreRepository participantScoreRepository, StudentScoreRepository studentScoreRepository, TeamScoreRepository teamScoreRepository,
ExerciseRepository exerciseRepository, ResultRepository resultRepository, UserRepository userRepository, TeamRepository teamRepository) {
this.scheduler = scheduler;
this.competencyProgressService = competencyProgressService;
this.competencyProgressApi = competencyProgressApi;
this.participantScoreRepository = participantScoreRepository;
this.studentScoreRepository = studentScoreRepository;
this.teamScoreRepository = teamScoreRepository;
Expand Down Expand Up @@ -336,7 +336,7 @@ private void executeTask(Long exerciseId, Long participantId, Instant resultLast
if (scoreParticipant instanceof Team team && !Hibernate.isInitialized(team.getStudents())) {
scoreParticipant = teamRepository.findWithStudentsByIdElseThrow(team.getId());
}
competencyProgressService.updateProgressByLearningObjectSync(score.getExercise(), scoreParticipant.getParticipants());
competencyProgressApi.updateProgressByLearningObjectSync(score.getExercise(), scoreParticipant.getParticipants());
}
catch (Exception e) {
log.error("Exception while processing participant score for exercise {} and participant {} for participant scores:", exerciseId, participantId, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -692,4 +692,15 @@ public void deleteLongFeedback(List<Feedback> feedbackList, Result result) {
List<Feedback> feedbacks = new ArrayList<>(feedbackList);
result.updateAllFeedbackItems(feedbacks, true);
}

/**
* Retrieves the number of students affected by a specific feedback detail text for a given exercise.
*
* @param exerciseId for which the affected student count is requested.
* @param detailText used to filter affected students.
* @return the total number of distinct students affected by the feedback detail text.
*/
public long getAffectedStudentCountByFeedbackDetailText(long exerciseId, String detailText) {
return studentParticipationRepository.countAffectedStudentsByFeedbackDetailText(exerciseId, detailText);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,18 @@ public ResponseEntity<Page<FeedbackAffectedStudentDTO>> getAffectedStudentsWithF

return ResponseEntity.ok(participation);
}

/**
* GET /exercises/{exerciseId}/feedback-detail/affected-students : Retrieves the count of students affected by a specific feedback detail text.
*
* @param exerciseId The ID of the exercise for which affected students are counted.
* @param detailText The feedback detail text to filter by.
* @return A {@link ResponseEntity} containing the count of affected students.
*/
@GetMapping("exercises/{exerciseId}/feedback-detail/affected-students")
@EnforceAtLeastEditorInExercise
public ResponseEntity<Long> countAffectedStudentsByFeedbackDetailText(@PathVariable long exerciseId, @RequestParam("detailText") String detailText) {
long affectedStudentCount = resultService.getAffectedStudentCountByFeedbackDetailText(exerciseId, detailText);
return ResponseEntity.ok(affectedStudentCount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package de.tum.cit.aet.artemis.atlas.api;

import de.tum.cit.aet.artemis.core.api.AbstractApi;

public abstract class AbstractAtlasApi implements AbstractApi {
}
24 changes: 24 additions & 0 deletions src/main/java/de/tum/cit/aet/artemis/atlas/api/CompetencyApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package de.tum.cit.aet.artemis.atlas.api;

import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Controller;

import de.tum.cit.aet.artemis.atlas.service.competency.CompetencyService;
import de.tum.cit.aet.artemis.lecture.domain.Lecture;

@Controller
@Profile(PROFILE_CORE)
public class CompetencyApi extends AbstractAtlasApi {

private final CompetencyService competencyService;

public CompetencyApi(CompetencyService competencyService) {
this.competencyService = competencyService;
}

public void addCompetencyLinksToExerciseUnits(Lecture lecture) {
competencyService.addCompetencyLinksToExerciseUnits(lecture);
}
}
Loading

0 comments on commit ced1ea5

Please sign in to comment.