Merge branch 'develop' into 1584-abstract-keywords
This commit is contained in:
commit
0105f6a490
core/src
main
java/se/su/dsv/scipro/finalseminar
resources/db/migration
test/java/se/su/dsv/scipro
view/src/main
java/se/su/dsv/scipro
admin/pages
finalseminar
FinalSeminarDetailsParameters.javaFinalSeminarDetailsParametersPanel.htmlFinalSeminarDetailsParametersPanel.javaProjectOppositionPage.java
profile
statistics
resources
@ -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,
|
||||
|
@ -3,7 +3,10 @@ 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.*;
|
||||
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.util.Either;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -58,6 +61,7 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
|
||||
private Boolean onlyActiveOrCompletedProjects;
|
||||
private User headSupervisor;
|
||||
private DegreeType degreeType;
|
||||
private Boolean onlyNonManualParticipants;
|
||||
|
||||
public Date getFromDate() {
|
||||
return this.fromDate;
|
||||
@ -123,6 +127,14 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
|
||||
this.degreeType = degreeType;
|
||||
}
|
||||
|
||||
public Boolean getOnlyNonManualParticipants() {
|
||||
return onlyNonManualParticipants;
|
||||
}
|
||||
|
||||
public void setOnlyNonManualParticipants(Boolean onlyNonManualParticipants) {
|
||||
this.onlyNonManualParticipants = onlyNonManualParticipants;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) return true;
|
||||
@ -136,7 +148,8 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
|
||||
&& Objects.equals(this.getOnlyActiveProjects(), other.getOnlyActiveProjects())
|
||||
&& Objects.equals(this.getOnlyActiveOrCompletedProjects(), other.getOnlyActiveOrCompletedProjects())
|
||||
&& Objects.equals(this.getHeadSupervisor(), other.getHeadSupervisor())
|
||||
&& Objects.equals(this.getDegreeType(), other.getDegreeType());
|
||||
&& Objects.equals(this.getDegreeType(), other.getDegreeType())
|
||||
&& Objects.equals(this.onlyNonManualParticipants, other.onlyNonManualParticipants);
|
||||
}
|
||||
|
||||
protected boolean canEqual(final Object other) {
|
||||
@ -153,12 +166,22 @@ public interface FinalSeminarService extends GenericService<FinalSeminar, Long>,
|
||||
this.getOnlyActiveProjects(),
|
||||
this.getOnlyActiveOrCompletedProjects(),
|
||||
this.getHeadSupervisor(),
|
||||
this.getDegreeType());
|
||||
this.getDegreeType(),
|
||||
this.getOnlyNonManualParticipants());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FinalSeminarService.Filter(fromDate=" + this.getFromDate() + ", toDate=" + this.getToDate() + ", lazyDeleted=" + this.getLazyDeleted() + ", exempted=" + this.getExempted() + ", onlyActiveProjects=" + this.getOnlyActiveProjects() + ", onlyActiveOrCompletedProjects=" + this.getOnlyActiveOrCompletedProjects() + ", headSupervisor=" + this.getHeadSupervisor() + ", degreeType=" + this.getDegreeType() + ")";
|
||||
return "FinalSeminarService.Filter(" +
|
||||
"fromDate=" + this.getFromDate()
|
||||
+ ", toDate=" + this.getToDate()
|
||||
+ ", lazyDeleted=" + this.getLazyDeleted()
|
||||
+ ", exempted=" + this.getExempted()
|
||||
+ ", onlyActiveProjects=" + this.getOnlyActiveProjects()
|
||||
+ ", onlyActiveOrCompletedProjects=" + this.getOnlyActiveOrCompletedProjects()
|
||||
+ ", headSupervisor=" + this.getHeadSupervisor()
|
||||
+ ", degreeType=" + this.getDegreeType()
|
||||
+ ", onlyNonManualParticipants=" + this.getOnlyNonManualParticipants() + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +154,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());
|
||||
@ -342,6 +343,9 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
|
||||
if (params.getOnlyActiveOrCompletedProjects() != null) {
|
||||
bb.and(onlyActiveOrCompletedProjectsFilter());
|
||||
}
|
||||
if (params.getOnlyNonManualParticipants() != null){
|
||||
bb.and(onlyNonManualParticipantsFilter());
|
||||
}
|
||||
if (params.getDegreeType() != null) {
|
||||
bb.and(QFinalSeminar.finalSeminar.project.projectType.degreeType.eq(params.getDegreeType()));
|
||||
}
|
||||
@ -360,6 +364,10 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
|
||||
return QFinalSeminar.finalSeminar.project.projectStatus.eq(ProjectStatus.ACTIVE);
|
||||
}
|
||||
|
||||
private BooleanExpression onlyNonManualParticipantsFilter() {
|
||||
return QFinalSeminar.finalSeminar.manualParticipants.isFalse();
|
||||
}
|
||||
|
||||
private BooleanExpression onlyActiveOrCompletedProjectsFilter() {
|
||||
return QFinalSeminar.finalSeminar.project.projectStatus.in(ProjectStatus.ACTIVE, ProjectStatus.COMPLETED);
|
||||
}
|
||||
|
1
core/src/main/resources/db/migration/V376__added_manual_participants_flag_to_final_Seminar.sql
Normal file
1
core/src/main/resources/db/migration/V376__added_manual_participants_flag_to_final_Seminar.sql
Normal file
@ -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,
|
||||
|
@ -55,6 +55,7 @@ public class ProjectOppositionPage extends AbstractProjectDetailsPage implements
|
||||
filter.setLazyDeleted(Boolean.FALSE);
|
||||
filter.setDegreeType(getActiveProject().getProjectType().getDegreeType());
|
||||
filter.setOnlyActiveProjects(Boolean.TRUE);
|
||||
filter.setOnlyNonManualParticipants(Boolean.TRUE);
|
||||
|
||||
add(new FeedbackPanel("feedback"));
|
||||
|
||||
|
@ -74,7 +74,10 @@ public class DaisyPicture extends ResourceReference {
|
||||
|
||||
final int userId = attributes.getParameters().get(USER_ID).toInt(0);
|
||||
final boolean alwaysShow = projectRelations.contains(userId) || seminarRelations.contains(userId);
|
||||
Integer requesterDaisyId = session.getUser().getIdentifier();
|
||||
Integer requesterDaisyId = null;
|
||||
if(session.getUser() != null){
|
||||
requesterDaisyId = session.getUser().getIdentifier();
|
||||
}
|
||||
final PhotoResult photo = daisyAPI.getPhoto(userId, requesterDaisyId == null ? -1 : requesterDaisyId, alwaysShow);
|
||||
return photo.fold(this::noPhoto, this::noPhoto, this::showPhoto);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class SupervisorApplicationPeriodStatisticsPanel extends GenericPanel<Use
|
||||
upcomingPeriods().stream()
|
||||
.flatMap(period -> period.getProjectTypes().stream()
|
||||
.map(projectType -> {
|
||||
final Target target = targetService.findOne(period, supervisorModel.getObject(), projectType);
|
||||
final Target target = targetService.findOne(period, getModelObject(), projectType);
|
||||
return new PeriodTypeTarget(period, projectType, target);
|
||||
}))
|
||||
.filter(ptt -> ptt.getTarget().getTarget() > 0)
|
||||
|
@ -28,7 +28,7 @@ public class SupervisorStatisticsPanel extends Panel {
|
||||
ideaPanel = new SupervisorIdeaStatisticsPanel(IDEAS_PANEL);
|
||||
ideaPanel.setOutputMarkupPlaceholderTag(true);
|
||||
add(ideaPanel);
|
||||
periodStatisticsPanel = new SupervisorApplicationPeriodStatisticsPanel("periods", new Model<>()) {
|
||||
periodStatisticsPanel = new SupervisorApplicationPeriodStatisticsPanel("periods", new DetachableServiceModel<>(userService)) {
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
@ -47,7 +47,7 @@ public class SupervisorStatisticsPanel extends Panel {
|
||||
protected void action(AjaxRequestTarget pTarget, User newSelection) {
|
||||
projectPanel.updateSupervisor(newSelection);
|
||||
ideaPanel.updateSupervisor(newSelection);
|
||||
periodStatisticsPanel.setModel(getModel());
|
||||
periodStatisticsPanel.setModelObject(getModelObject());
|
||||
pTarget.add(projectPanel);
|
||||
pTarget.add(ideaPanel);
|
||||
pTarget.add(periodStatisticsPanel);
|
||||
|
@ -55,7 +55,7 @@
|
||||
<band height="50">
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement style="titleStyle" x="0" y="0" width="495" height="30" uuid="b0bf7adc-8731-42ed-8e5d-8ab64653ba32"/>
|
||||
<textFieldExpression><![CDATA[($F{swedish} ? "Handledarens underlag till examinator för betygssättning av " : "Supervisor's grading basis to the examiner for grading of ") + $F{authorName}]]></textFieldExpression>
|
||||
<textFieldExpression><![CDATA[($F{swedish} ? "Handledarens underlag till examinator för betygsättning av " : "Supervisor's grading basis to the examiner for grading of ") + $F{authorName}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</title>
|
||||
|
Loading…
x
Reference in New Issue
Block a user