diff --git a/core/src/main/java/se/su/dsv/scipro/CoreConfig.java b/core/src/main/java/se/su/dsv/scipro/CoreConfig.java index 46a1ef3127..776327b8b7 100644 --- a/core/src/main/java/se/su/dsv/scipro/CoreConfig.java +++ b/core/src/main/java/se/su/dsv/scipro/CoreConfig.java @@ -31,6 +31,7 @@ import se.su.dsv.scipro.finalseminar.AuthorRepository; import se.su.dsv.scipro.finalseminar.FinalSeminarActiveParticipationRepository; import se.su.dsv.scipro.finalseminar.FinalSeminarActiveParticipationServiceImpl; import se.su.dsv.scipro.finalseminar.FinalSeminarCreationSubscribers; +import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionGrading; import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionRepo; import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionServiceImpl; import se.su.dsv.scipro.finalseminar.FinalSeminarRepository; @@ -430,8 +431,11 @@ public class CoreConfig { } @Bean - public FinalSeminarOppositionServiceImpl finalSeminarOppositionService(Provider<EntityManager> em) { - return new FinalSeminarOppositionServiceImpl(em); + public FinalSeminarOppositionServiceImpl finalSeminarOppositionService( + Provider<EntityManager> em, + FinalSeminarOppositionGrading finalSeminarOppositionGrading + ) { + return new FinalSeminarOppositionServiceImpl(em, finalSeminarOppositionGrading); } @Bean diff --git a/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionGrading.java b/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionGrading.java new file mode 100644 index 0000000000..0ac5bba547 --- /dev/null +++ b/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionGrading.java @@ -0,0 +1,7 @@ +package se.su.dsv.scipro.finalseminar; + +import java.util.List; + +public interface FinalSeminarOppositionGrading { + List<OppositionCriterion> oppositionCriteria(FinalSeminarOpposition opposition); +} diff --git a/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionService.java b/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionService.java index 60eeacc1a9..8394531675 100755 --- a/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionService.java +++ b/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionService.java @@ -1,8 +1,11 @@ package se.su.dsv.scipro.finalseminar; +import java.util.List; import se.su.dsv.scipro.system.GenericService; public interface FinalSeminarOppositionService extends GenericService<FinalSeminarOpposition, Long> { @Override void delete(Long aLong); + + List<OppositionCriterion> getCriteriaForOpposition(FinalSeminarOpposition opposition); } diff --git a/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionServiceImpl.java index 27550bb3ac..47bc869a32 100755 --- a/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/finalseminar/FinalSeminarOppositionServiceImpl.java @@ -3,14 +3,26 @@ package se.su.dsv.scipro.finalseminar; import jakarta.inject.Inject; import jakarta.inject.Provider; import jakarta.persistence.EntityManager; +import java.util.List; import se.su.dsv.scipro.system.AbstractServiceImpl; public class FinalSeminarOppositionServiceImpl extends AbstractServiceImpl<FinalSeminarOpposition, Long> implements FinalSeminarOppositionService { + private final FinalSeminarOppositionGrading finalSeminarOppositionGrading; + @Inject - public FinalSeminarOppositionServiceImpl(Provider<EntityManager> em) { + public FinalSeminarOppositionServiceImpl( + Provider<EntityManager> em, + FinalSeminarOppositionGrading finalSeminarOppositionGrading + ) { super(em, FinalSeminarOpposition.class, QFinalSeminarOpposition.finalSeminarOpposition); + this.finalSeminarOppositionGrading = finalSeminarOppositionGrading; + } + + @Override + public List<OppositionCriterion> getCriteriaForOpposition(FinalSeminarOpposition opposition) { + return finalSeminarOppositionGrading.oppositionCriteria(opposition); } } diff --git a/core/src/main/java/se/su/dsv/scipro/finalseminar/OppositionCriterion.java b/core/src/main/java/se/su/dsv/scipro/finalseminar/OppositionCriterion.java new file mode 100644 index 0000000000..9915cf55f1 --- /dev/null +++ b/core/src/main/java/se/su/dsv/scipro/finalseminar/OppositionCriterion.java @@ -0,0 +1,3 @@ +package se.su.dsv.scipro.finalseminar; + +public record OppositionCriterion(int points, String requirement) {} diff --git a/core/src/main/java/se/su/dsv/scipro/report/GradingReportServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/report/GradingReportServiceImpl.java index bc945b6443..f8486cf0fb 100644 --- a/core/src/main/java/se/su/dsv/scipro/report/GradingReportServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/report/GradingReportServiceImpl.java @@ -8,6 +8,8 @@ import java.time.Instant; import java.time.LocalDate; import java.util.*; import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition; +import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionGrading; +import se.su.dsv.scipro.finalseminar.OppositionCriterion; import se.su.dsv.scipro.grading.GradingBasis; import se.su.dsv.scipro.grading.GradingReportTemplateService; import se.su.dsv.scipro.grading.GradingReportTemplateUpdate; @@ -20,7 +22,8 @@ import se.su.dsv.scipro.system.ProjectTypeService; import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.util.Either; -public class GradingReportServiceImpl implements GradingReportTemplateService, GradingReportService { +public class GradingReportServiceImpl + implements GradingReportTemplateService, GradingReportService, FinalSeminarOppositionGrading { private final EventBus eventBus; private final ThesisSubmissionHistoryService thesisSubmissionHistoryService; @@ -289,4 +292,17 @@ public class GradingReportServiceImpl implements GradingReportTemplateService, G return gradingReportTemplateRepo.createTemplate(projectType, update); } + + @Override + @Transactional + public List<OppositionCriterion> oppositionCriteria(FinalSeminarOpposition opposition) { + return getSupervisorGradingReport(opposition.getProject(), opposition.getUser()) + .getIndividualCriteria() + .stream() + .filter(individualCriterion -> individualCriterion.getFlag() == AbstractGradingCriterion.Flag.OPPOSITION) + .map(GradingCriterion::getGradingCriterionPoints) + .flatMap(Collection::stream) + .map(gcp -> new OppositionCriterion(gcp.getPoint(), gcp.getDescription(Language.ENGLISH))) + .toList(); + } } diff --git a/view/src/main/java/se/su/dsv/scipro/finalseminar/SeminarOppositionPanel.html b/view/src/main/java/se/su/dsv/scipro/finalseminar/SeminarOppositionPanel.html index 07e9b23129..117f8a9cd4 100644 --- a/view/src/main/java/se/su/dsv/scipro/finalseminar/SeminarOppositionPanel.html +++ b/view/src/main/java/se/su/dsv/scipro/finalseminar/SeminarOppositionPanel.html @@ -25,7 +25,7 @@ <div class="mb-3"> <label>Points:</label> - <input type="text" class="form-control gradingPoints" wicket:id="points"/> + <select class="form-control gradingPoints" wicket:id="points"></select> </div> <label>Motivation:</label> diff --git a/view/src/main/java/se/su/dsv/scipro/finalseminar/SeminarOppositionPanel.java b/view/src/main/java/se/su/dsv/scipro/finalseminar/SeminarOppositionPanel.java index 6683d90aeb..e9f5ed0c33 100644 --- a/view/src/main/java/se/su/dsv/scipro/finalseminar/SeminarOppositionPanel.java +++ b/view/src/main/java/se/su/dsv/scipro/finalseminar/SeminarOppositionPanel.java @@ -11,10 +11,11 @@ import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink; import org.apache.wicket.feedback.FencedFeedbackPanel; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponent; +import org.apache.wicket.markup.html.form.LambdaChoiceRenderer; import org.apache.wicket.markup.html.form.TextArea; -import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; @@ -23,11 +24,12 @@ import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LambdaModel; +import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; -import org.apache.wicket.validation.validator.RangeValidator; import org.apache.wicket.validation.validator.StringValidator; import se.su.dsv.scipro.components.ListAdapterModel; +import se.su.dsv.scipro.components.StatelessModel; import se.su.dsv.scipro.profile.UserLinkPanel; import se.su.dsv.scipro.report.GradingReportService; import se.su.dsv.scipro.report.OppositionReportService; @@ -229,29 +231,25 @@ public class SeminarOppositionPanel extends Panel { private class FinalSeminarOppositionForm extends Form<FinalSeminarOpposition> { + private IModel<OppositionCriterion> pointsModel = new StatelessModel<>(); + private IModel<String> feedbackModel = new Model<>(); + public FinalSeminarOppositionForm(String id, final IModel<FinalSeminarOpposition> finalSeminarOpposition) { super(id, finalSeminarOpposition); - FormComponent<Integer> pointsField = new TextField<>( + IModel<List<OppositionCriterion>> criteriaModel = LoadableDetachableModel.of(() -> + finalSeminarOppositionService.getCriteriaForOpposition(finalSeminarOpposition.getObject()) + ); + + FormComponent<OppositionCriterion> pointsField = new DropDownChoice<>( POINTS, - LambdaModel.of( - finalSeminarOpposition, - FinalSeminarOpposition::getPoints, - FinalSeminarOpposition::setPoints - ) - ) - .add(RangeValidator.range(MIN_POINTS, MAX_POINTS)) - .setType(Integer.class) - .setRequired(true); + pointsModel, + criteriaModel, + new LambdaChoiceRenderer<>(OppositionCriterion::points) + ); + pointsField.setRequired(true); add(pointsField); - TextArea<String> feedback = new TextArea<>( - GRADING_FEEDBACK, - LambdaModel.of( - finalSeminarOpposition, - FinalSeminarOpposition::getFeedback, - FinalSeminarOpposition::setFeedback - ) - ); + TextArea<String> feedback = new TextArea<>(GRADING_FEEDBACK, feedbackModel); feedback.add(StringValidator.maximumLength(FEEDBACK_MAX_LENGTH)); feedback.setRequired(true); add(feedback);