Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
nikos dimitrakas 2023-09-22 22:13:42 +02:00
commit b6df7ec299
15 changed files with 64 additions and 17 deletions

@ -21,4 +21,8 @@ class AbstractOppositionEvent {
public FinalSeminar getFinalSeminar() {
return opposition.getFinalSeminar();
}
public FinalSeminarOpposition getOpposition() {
return opposition;
}
}

@ -53,6 +53,9 @@ public class FinalSeminar extends LazyDeletableDomainObject {
@Column(name = "extra_info")
private String extraInfo;
@Basic
private Boolean manualParticipants = false;
@OneToMany(mappedBy = FINAL_SEMINAR, orphanRemoval = true, cascade = CascadeType.ALL)
private Set<FinalSeminarActiveParticipation> activeParticipations = new HashSet<>();
@ -96,6 +99,14 @@ public class FinalSeminar extends LazyDeletableDomainObject {
this.project = project;
}
public Boolean getManualParticipants() {
return manualParticipants;
}
public void setManualParticipants(Boolean manualParticipants) {
this.manualParticipants = manualParticipants;
}
public void setStartDate(Date startDate) {
this.startDate = (Date) startDate.clone();
}

@ -4,6 +4,7 @@ import se.su.dsv.scipro.system.Language;
public record FinalSeminarDetails(
String location,
Boolean manualParticipants,
int maxParticipants,
int maxOpponents,
Language presentationLanguage,

@ -157,6 +157,7 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
public FinalSeminar updateDetails(FinalSeminar finalSeminar, FinalSeminarDetails finalSeminarDetails) {
finalSeminar.setRoom(finalSeminarDetails.location());
finalSeminar.setExtraInfo(finalSeminarDetails.extraInfo());
finalSeminar.setManualParticipants(finalSeminarDetails.manualParticipants());
finalSeminar.setMaxOpponents(finalSeminarDetails.maxOpponents());
finalSeminar.setMaxParticipants(finalSeminarDetails.maxParticipants());
finalSeminar.setPresentationLanguage(finalSeminarDetails.presentationLanguage());

@ -108,6 +108,7 @@ public class Notifications {
Set<Member> recipients = Set.of(recipient);
NotificationSource source = new NotificationSource();
source.setMessage(event.getFinalSeminar().getProjectTitle());
source.setAdditionalMessage(event.getOpposition().getFeedback());
notificationController.notifyCustomProject(event.getProject(), ProjectEvent.Event.OPPOSITION_FAILED, source, recipients);
}

@ -78,7 +78,7 @@ PROJECT.FIRST_MEETING.title = First meeting booked for {0}
PROJECT.FIRST_MEETING.body = Date: {0}\n\nDescription:\n{2}
PROJECT.OPPOSITION_FAILED.title = Your opposition on {1} did not meet the minimum requirements.
PROJECT.OPPOSITION_FAILED.body = Your opposition did not meet the minimum requirements set, and you will have to \
oppose on a different final seminar to pass this step.
oppose on a different final seminar to pass this step.\n\nFeedback from the seminar supervisor: {2}
PROJECT.PARTICIPATION_APPROVED.title = Active participation on {1} has been approved.
PROJECT.PARTICIPATION_APPROVED.body = Your active participation on {0} has been approved, but you still have to complete \
{2} more active participation to meet the minimum requirements for your thesis project.

@ -0,0 +1 @@
ALTER TABLE final_seminar ADD COLUMN manualParticipants BOOLEAN NOT NULL DEFAULT FALSE;

@ -155,7 +155,7 @@ public class FinalSeminarSchedulingTest extends IntegrationTest {
}
private static FinalSeminarDetails detailsAt() {
return new FinalSeminarDetails("Zoom", 5, 5, Language.SWEDISH, Language.ENGLISH, null);
return new FinalSeminarDetails("Zoom", false, 5, 5, Language.SWEDISH, Language.ENGLISH, null);
}
private void approveRoughDraftApproval(Project project) {

@ -103,7 +103,7 @@ public class ReflectionServiceTest extends IntegrationTest {
private LocalDate scheduleSeminar() {
project.setFinalSeminarRuleExempted(true); // to bypass rough draft approval
FinalSeminarDetails details = new FinalSeminarDetails("Zoom", 1, 1, Language.SWEDISH, Language.ENGLISH, "zoom id 123");
FinalSeminarDetails details = new FinalSeminarDetails("Zoom", false, 1, 1, Language.SWEDISH, Language.ENGLISH, "zoom id 123");
LocalDate seminarDate = finalSeminarService.getEarliestSeminarDate();
Either<SchedulingError, FinalSeminar> schedule = finalSeminarService.schedule(project, seminarDate.atStartOfDay(), details);
assertTrue(schedule.isRight(), "Failed to schedule seminar: " + schedule);

@ -50,7 +50,6 @@ public class SystemMaintenancePage extends AbstractAdminSystemPage {
runningContainer.setOutputMarkupId(true);
scheduledContainer.setOutputMarkupId(true);
runningContainer.add(new AjaxSelfUpdatingTimerBehavior(Duration.ofSeconds(REFRESH_TIMER)) {
@Override
@ -126,7 +125,7 @@ public class SystemMaintenancePage extends AbstractAdminSystemPage {
private static class SystemNoticeForm extends Form<Void> {
private IModel<String> noticeModel = Model.of(getApplication().getMetaData(SystemNoticePanel.SYSTEM_NOTICE));
private final IModel<String> noticeModel = Model.of(getApplication().getMetaData(SystemNoticePanel.SYSTEM_NOTICE));
public SystemNoticeForm(String id) {
super(id);
@ -135,7 +134,11 @@ public class SystemMaintenancePage extends AbstractAdminSystemPage {
@Override
protected void onSubmit() {
getApplication().setMetaData(SystemNoticePanel.SYSTEM_NOTICE, noticeModel.getObject());
if (noticeModel.getObject() == null) {
getApplication().setMetaData(SystemNoticePanel.SYSTEM_NOTICE, "");
} else {
getApplication().setMetaData(SystemNoticePanel.SYSTEM_NOTICE, noticeModel.getObject());
}
}
}
}

@ -6,6 +6,7 @@ import java.io.Serializable;
public class FinalSeminarDetailsParameters implements Serializable {
private String room;
private Boolean manualParticipants;
private int maxParticipants;
private int maxOpponents;
private Language presentationLanguage;
@ -15,6 +16,7 @@ public class FinalSeminarDetailsParameters implements Serializable {
static FinalSeminarDetailsParameters from(FinalSeminar finalSeminar) {
FinalSeminarDetailsParameters finalSeminarDetailsParameters = new FinalSeminarDetailsParameters();
finalSeminarDetailsParameters.setRoom(finalSeminar.getRoom());
finalSeminarDetailsParameters.setManualParticipants(finalSeminar.getManualParticipants());
finalSeminarDetailsParameters.setMaxOpponents(finalSeminar.getMaxOpponents());
finalSeminarDetailsParameters.setMaxParticipants(finalSeminar.getMaxParticipants());
finalSeminarDetailsParameters.setPresentationLanguage(finalSeminar.getPresentationLanguage());
@ -24,13 +26,21 @@ public class FinalSeminarDetailsParameters implements Serializable {
}
FinalSeminarDetails asDetails() {
return new FinalSeminarDetails(room, maxParticipants, maxOpponents, presentationLanguage, reportLanguage, extraInfo);
return new FinalSeminarDetails(room, manualParticipants, maxParticipants, maxOpponents, presentationLanguage, reportLanguage, extraInfo);
}
public String getRoom() {
return room;
}
public Boolean getManualParticipants() {
return manualParticipants;
}
public void setManualParticipants(Boolean manualParticipants) {
this.manualParticipants = manualParticipants;
}
public void setRoom(String room) {
this.room = room;
}

@ -25,8 +25,15 @@
<select id="reportLanguage" class="form-select mb-3" wicket:id="reportLanguage"></select>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" wicket:id="manualParticipants"/>
<label class="form-check-label" wicket:for="manualParticipants">
Supervisor manually chooses opponents and active participants
</label>
</div>
<div class="mb-3">
<label for="maxOpponents" wicket:for="maxOpponents" class="col-form-label">Max oppositions</label>
<label for="maxOpponents" wicket:for="maxOpponents" class="col-form-label">Max opponents</label>
<input id="maxOpponents" wicket:id="maxOpponents" class="form-control"/>
</div>

@ -1,9 +1,6 @@
package se.su.dsv.scipro.finalseminar;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.EnumChoiceRenderer;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.*;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.panel.GenericPanel;
import org.apache.wicket.model.IModel;
@ -48,6 +45,11 @@ public class FinalSeminarDetailsParametersPanel extends GenericPanel<FinalSemina
}
});
add(new CheckBox("manualParticipants",
LambdaModel.of(model,
FinalSeminarDetailsParameters::getManualParticipants,
FinalSeminarDetailsParameters::setManualParticipants)).setOutputMarkupId(true));
RequiredTextField<Integer> maxParticipants = new RequiredTextField<>("maxParticipants",
LambdaModel.of(model,
FinalSeminarDetailsParameters::getMaxParticipants,

@ -46,18 +46,23 @@
</div>
<wicket:enclosure>
<fieldset class="mb-3">
<legend>
<wicket:message key="publishing_consent"/>
<legend class="required">
<wicket:message key="publishing_consent_label">
[Publication rights]
</wicket:message>
</legend>
<p class="text-muted">
<wicket:message key="publishing_consent_explanation"/>
</p>
<div wicket:id="publishingConsentLevel"></div>
</fieldset>
</wicket:enclosure>
<div wicket:id="publication_metadata">
<p>
<h4>
<wicket:message key="publication_metadata_why">
Please provide the following metadata.
</wicket:message>
</p>
</h4>
<wicket:container class="mb-3" wicket:id="publication_metadata_components"/>
</div>
<button type="submit" class="btn btn-success btn-sm"><wicket:message key="submit">[Submit]</wicket:message></button>

@ -2,7 +2,8 @@ reflection_submitted=Reflection submitted
explain=You've had your final seminar, and it is now time to finish the last few steps in the thesis process.
reflection=Reflection
submit=Submit
publishing_consent=Giving consent to publish does not mean the thesis <em>will</em> be published, only that it <em>may</em> be published.
publishing_consent_label=Publication rights
publishing_consent_explanation=Giving consent to publish does not mean the thesis <em>will</em> be published, only that it <em>may</em> be published.
publishingConsentLevel.Required=You must decide how your thesis may be published.
current_final_thesis=Final thesis
publication_metadata_why=Please provide the following metadata.