Merge branch 'develop' into 3204-reviewer-capacity

This commit is contained in:
Andreas Svanberg 2024-01-22 12:26:17 +01:00
commit 3ad7dd2261
29 changed files with 42 additions and 43 deletions

@ -65,7 +65,7 @@ public class FinalSeminarCreationSubscribers {
}
private boolean onlyFailedOppositions(Author subscriber) {
return finalSeminarService.findUserOpposing(subscriber.getProject(), subscriber.getUser())
return finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(subscriber.getProject().getProjectType(), subscriber.getUser())
.stream()
.noneMatch(FinalSeminarParticipation::isApproved);
}

@ -3,10 +3,7 @@ package se.su.dsv.scipro.finalseminar;
import org.springframework.data.domain.Pageable;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.DegreeType;
import se.su.dsv.scipro.system.FilteredService;
import se.su.dsv.scipro.system.GenericService;
import se.su.dsv.scipro.system.User;
import se.su.dsv.scipro.system.*;
import se.su.dsv.scipro.util.Either;
import java.io.Serializable;
@ -54,7 +51,8 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
FinalSeminar cancel(FinalSeminar finalSeminar);
List<FinalSeminarOpposition> findUserOpposing(Project project, User user);
List<FinalSeminarOpposition> findFinalSeminarOppositionsByOpponentAndProjectType(ProjectType projectType, User user);
List<FinalSeminarActiveParticipation> findUserParticipating(Project project, User user);
boolean isSubscribedToSeminarCreationNotifications(Project project, User user);

@ -17,6 +17,7 @@ import se.su.dsv.scipro.report.OppositionReportService;
import se.su.dsv.scipro.reviewing.RoughDraftApproval;
import se.su.dsv.scipro.reviewing.RoughDraftApprovalService;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User;
import se.su.dsv.scipro.util.Either;
@ -269,9 +270,9 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
@Transactional
public Either<OpposeError, FinalSeminarOpposition> attemptAddOppositionAsSupervisor(User student, FinalSeminar finalSeminar, Project project) {
if (finalSeminar.getActiveParticipants().contains(student)) {
return Either.left(OpposeError.AlreadyParticipant);
return Either.left(OpposeError.ALREADY_PARTICIPANT);
} else if (finalSeminar.getOpponents().contains(student)) {
return Either.left(OpposeError.AlreadyOpponent);
return Either.left(OpposeError.ALREADY_OPPONENT);
} else {
return Either.right(createAndSaveOpposition(student, finalSeminar, project));
}
@ -418,7 +419,7 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
public List<FinalSeminarOpposition> getOppositionsByProjectAuthors(Project project) {
return project.getProjectParticipants()
.stream()
.map(author -> findUserOpposing(project, author))
.map(author -> findFinalSeminarOppositionsByOpponentAndProjectType(project.getProjectType(), author))
.flatMap(List::stream)
.toList();
}
@ -449,8 +450,8 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
}
@Override
public List<FinalSeminarOpposition> findUserOpposing(Project project, User user) {
return finalSeminarOppositionRepository.findByOpposingUserAndType(user, project.getProjectType());
public List<FinalSeminarOpposition> findFinalSeminarOppositionsByOpponentAndProjectType(ProjectType projectType, User user) {
return finalSeminarOppositionRepository.findByOpposingUserAndType(user, projectType);
}
@Override

@ -1,5 +1,5 @@
package se.su.dsv.scipro.finalseminar;
public enum OpposeError {
AlreadyOpponent, AlreadyParticipant
ALREADY_OPPONENT, ALREADY_PARTICIPANT
}

@ -428,7 +428,7 @@ public class ZipReporter implements Reporter {
if (finalSeminar != null) {
children.addAll(finalSeminarReport(finalSeminar));
}
final List<FinalSeminarOpposition> oppositions = finalSeminarService.findUserOpposing(project, user);
final List<FinalSeminarOpposition> oppositions = finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(project.getProjectType(), user);
if (!oppositions.isEmpty()) {
List<FinalSeminar> seminars = oppositions.stream().map(FinalSeminarParticipation::getFinalSeminar).toList();
children.addAll(oppositionsReport("Oppositions", seminars));

@ -51,7 +51,7 @@ public class ActivateCompletedMilestonesOnNewProjects {
}
private void activateOppositionMilestone(Project project, User author) {
List<FinalSeminarOpposition> opposing = finalSeminarService.findUserOpposing(project, author);
List<FinalSeminarOpposition> opposing = finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(project.getProjectType(), author);
for (FinalSeminarOpposition finalSeminarOpposition : opposing) {
if (finalSeminarOpposition.isApproved()) {
confirmMilestoneByEvent(project, author, "OppositionGradingEvent");

@ -74,7 +74,7 @@
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.1.3</version>
<version>5.3.2</version>
</dependency>
<!-- Servlet API, needed for compilation. -->

@ -19,7 +19,7 @@
<div class="mb-3" wicket:id="dateContainer">
<label for="endDate" wicket:for="endDate" class="col-form-label"><wicket:message key="endDate"/></label>
<input id="endDate" type="text" class="form-control" wicket:id="endDate">
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
The application period ends at <strong wicket:id="periodEnd">2021-01-01</strong>
and the course starts at <strong wicket:id="courseStart">2021-01-10</strong>.
</small>

@ -43,7 +43,7 @@
<div class="mb-3 col-md-6 col-12">
<label wicket:for="courseEndDate"><wicket:message key="courseEndDate"/></label>
<input class="form-control" type="text" wicket:id="courseEndDate">
<small class="form-text text-muted">Expected date the thesis should be completed by</small>
<small class="form-text text-body-secondary">Expected date the thesis should be completed by</small>
<div wicket:id="courseEndDateFeedback"></div>
</div>
</div>
@ -51,7 +51,7 @@
<div class="mb-3 col-md-6 col-12">
<label wicket:for="courseStartTime"><wicket:message key="courseStartTime"/></label>
<input class="form-control" wicket:id="courseStartTime">
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
The start time for any activity plan template used and the default time for first meetings.
</small>
<div wicket:id="courseStartTimeFeedback"></div>

@ -3,7 +3,7 @@
<body>
<wicket:extend>
<header class="mb-3">
<nav class="navbar navbar-dark">
<nav class="navbar" data-bs-theme="dark">
<span class="navbar-brand" title="SciPro Projects">SciPro Projects</span>
</nav>
</header>

@ -2,7 +2,7 @@
<html xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:panel>
<nav class="navbar navbar-dark navbar-expand-md">
<nav class="navbar navbar-expand-md" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" wicket:id="homeLink" title="SciPro Projects">SciPro Projects</a>
<button class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#navbarCollapsedContent">

@ -114,7 +114,7 @@ public class AttendingPanel extends GenericPanel<Project> {
return new LoadableDetachableModel<>() {
@Override
protected List<FinalSeminarOpposition> load() {
return finalSeminarService.findUserOpposing(getModelObject(), SciProSession.get().getUser());
return finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(getModelObject().getProjectType(), SciProSession.get().getUser());
}
};
}

@ -46,7 +46,7 @@
<div class="mb-3">
<label for="extraInfo" wicket:for="extraInfo">Extra info</label>
<textarea id="extraInfo" class="form-control" wicket:id="extraInfo"></textarea>
<small class="text-muted">
<small class="text-body-secondary">
If you have any extra info you want to communicate to all the participants of the seminar
you can put it here.
</small>

@ -22,7 +22,7 @@
Subscribe to notifications for newly scheduled seminars
</label>
</div>
<small class="text-muted">
<small class="text-body-secondary">
If you're having trouble finding a seminar to oppose or participate in, you can subscribe to
be notified when one is scheduled. This should help you finish the last remaining tasks in
the project.

@ -261,9 +261,9 @@ public class SeminarCRUDPanel extends GenericPanel<FinalSeminar> {
result.fold(
error -> {
switch (error) {
case AlreadyOpponent ->
case ALREADY_OPPONENT ->
error(potentialOpponent.getFullName() + " that you selected as an opponent is already an opponent");
case AlreadyParticipant ->
case ALREADY_PARTICIPANT ->
error(potentialOpponent.getFullName() + " that you selected as an opponent is already an active participant");
}
return false;

@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:panel>
<small wicket:id="help" class="text-muted mb-1 d-block">
<small wicket:id="help" class="text-body-secondary mb-1 d-block">
After the final seminar has been held and any revisions have been performed, the final version of the thesis
should be uploaded. It can be uploaded by you or the students. Once uploaded you should look over the thesis to
see that all the necessary changes have been made, and if not, reject the version and tell the students they

@ -54,7 +54,7 @@
<div class="mb-3">
<label for="activeProjectIdeaSupportMail">Support mail address for active projects</label>
<input class="form-control" wicket:id="activeProjectIdeaSupportMail" id="activeProjectIdeaSupportMail">
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
It is shown to students who try to submit an idea when they already have an active project.
</small>
</div>

@ -204,7 +204,7 @@ abstract class AbstractExaminationsPanel extends GenericPanel<User> {
if (!examination.hasManyPassingGrades()) {
return NO_REQUIREMENTS;
}
final long completedOppositions = finalSeminarService.findUserOpposing(project, user)
final long completedOppositions = finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(project.getProjectType(), user)
.stream()
.filter(FinalSeminarOpposition::isApproved)
.count();

@ -170,7 +170,7 @@ public class CriteriaPanel extends GenericPanel<SupervisorGradingReport> {
super(id, author);
this.gradingCriterion = gradingCriterion;
final IModel<List<FinalSeminarOpposition>> authorOppositions = LoadableDetachableModel.of(() ->
finalSeminarService.findUserOpposing(CriteriaPanel.this.getModelObject().getProject(), author.getObject()));
finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(CriteriaPanel.this.getModelObject().getProject().getProjectType(), author.getObject()));
modal = new ModalWindowPlus("modal");
modal.setTitle("Opposition feedback");

@ -220,7 +220,7 @@ public class SendToExaminer extends GenericPanel<Project> {
}
private LocalDate getExaminationDate(User author, Project project, FinalThesis finalThesis) {
var oppositions = finalSeminarService.findUserOpposing(project, author);
var oppositions = finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(project.getProjectType(), author);
var participations = finalSeminarService.findUserParticipating(project, author);
Optional<LocalDate> seminarDate = Stream.concat(oppositions.stream(), participations.stream())

@ -54,7 +54,7 @@
<div class="card-body p-2">
<p>
<strong>Conversion from points to grades is done according to the following schema:</strong>
<span class="text-muted">Updated 2017-02-20</span>
<span class="text-body-secondary">Updated 2017-02-20</span>
</p>
<p>[A] 33-31, at least 1 point on components U1-U4, U10-U12, Ö1-Ö4, Ö6, and at least 2 points on U5-U9, U13</p>

@ -9,7 +9,7 @@
<div class="mb-3">
<label class="col-form-label" wicket:for="background">Background</label>
<textarea wicket:id="background" class="form-control" rows="4"></textarea>
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
Describe the background of your topic, preferably both theoretical, empirical and/or practical.
</small>
</div>
@ -17,7 +17,7 @@
<div class="mb-3">
<label class="col-form-label" wicket:for="literature">Literature</label>
<textarea wicket:id="literature" class="form-control" rows="4"></textarea>
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
Describe the connection to your background, for example literature, theory and methodology related to the topic, courses that you have taken that relates to the topic.
</small>
</div>
@ -25,7 +25,7 @@
<div class="mb-3">
<label class="col-form-label" wicket:for="problem">Problem</label>
<textarea wicket:id="problem" class="form-control" rows="4"></textarea>
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
Here you describe the problem you want to address and solve by your work, preferably formulated as a research question.
</small>
</div>
@ -33,7 +33,7 @@
<div class="mb-3">
<label class="col-form-label" wicket:for="method">Method</label>
<textarea wicket:id="method" class="form-control" rows="4"></textarea>
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
The method you plan to use in order to solve the problem and answer the research question.
</small>
</div>
@ -41,7 +41,7 @@
<div class="mb-3">
<label class="col-form-label" wicket:for="interests">My interests</label>
<textarea wicket:id="interests" class="form-control" rows="4"></textarea>
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
Please note that when you propose your own topic, it is not guaranteed that your topic will be approved. In that case, you will be assigned a different topic by your supervisor. Specify which topics of interest you have, relating to the research fields or the courses that you have taken at DSV.
</small>
</div>

@ -26,7 +26,7 @@
<label wicket:for="title">Title</label> <span wicket:id="titleInfo"></span>
<div wicket:id="titleFeedback"></div>
<input wicket:id="title" type="text" class="form-control"/>
<small class="form-text text-muted" wicket:id="titleSmallText">At least 5 characters are needed.</small>
<small class="form-text text-body-secondary" wicket:id="titleSmallText">At least 5 characters are needed.</small>
</div>
<div class="mb-3">

@ -51,7 +51,7 @@
[Publication rights]
</wicket:message>
</legend>
<p class="text-muted">
<p class="text-body-secondary">
<wicket:message key="publishing_consent_explanation"/>
</p>
<div wicket:id="publishingConsentLevel"></div>

@ -6,7 +6,7 @@
<label wicket:for="inputField">Partner: <span wicket:id="partnerInfo"></span></label>
<wicket:enclosure child="inputField">
<select wicket:id="inputField" class="w-100"></select>
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
Don't have a partner?
<wicket:link><a href="../projectpartner/ProjectPartnerPage.html">Find one!</a></wicket:link>
</small>

@ -28,7 +28,7 @@
<div class="mb-3">
<label for="projectExpectedEndDate">Expected end date:</label>
<input wicket:id="expected_end_date" id="projectExpectedEndDate" class="form-control">
<small class="form-text text-muted">
<small class="form-text text-body-secondary">
If the project is not completed by this date it will be considered late.
It has no functional effect and is only for followup purposes.
</small>

@ -4,7 +4,7 @@
<wicket:panel>
<form wicket:id="requestApproval">
<small class="text-muted">
<small class="text-body-secondary">
<wicket:message key="info"/>
</small>
<div wicket:id="feedback"></div>

@ -3,7 +3,7 @@
xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:panel>
<small wicket:id="help" class="text-muted mb-1 d-block">
<small wicket:id="help" class="text-body-secondary mb-1 d-block">
After approving the final thesis, it will be sent for text matching.
Once the text matching is done the report will be made available, and you should read it and determine if
the authors have plagiarised. Submit the text matching report and your analysis of its findings below.

@ -61,7 +61,7 @@ public class AttendingPanelTest extends SciProTest {
List<FinalSeminarOpposition> oppositions = List.of(finalSeminarOpposition);
when(finalSeminarService.findUserOpposing(isA(Project.class), isA(User.class))).thenReturn(oppositions);
when(finalSeminarService.findFinalSeminarOppositionsByOpponentAndProjectType(isA(ProjectType.class), isA(User.class))).thenReturn(oppositions);
startPanel();