Allows admins to manage grading report templates #14

Merged
niat8586 merged 41 commits from 3482-new-grading-criteria into develop 2024-10-30 10:05:23 +01:00
8 changed files with 167 additions and 4 deletions
Showing only changes of commit 7a1b3d4744 - Show all commits

View File

@ -3,10 +3,21 @@ package se.su.dsv.scipro.grading;
import se.su.dsv.scipro.report.GradingReportTemplate;
import se.su.dsv.scipro.system.ProjectType;
import java.time.LocalDate;
import java.util.List;
public interface GradingReportTemplateService {
List<ProjectType> getProjectTypes();
GradingReportTemplate getCurrentTemplate(ProjectType projectType);
Review

Shouldn't we be able to delete faulty or unwanted templates? Maybe we should introduce that in the future?

Shouldn't we be able to delete faulty or unwanted templates? Maybe we should introduce that in the future?
GradingReportTemplate getTemplate(long templateId);
/**
* Returns the end date of this grading report template.
* End date is specified as the date before another template takes over.
*
* @return the end date of this grading report template, possibly {@code null}
*/
LocalDate getEndDate(GradingReportTemplate gradingReportTemplate);
}

View File

@ -212,4 +212,19 @@ public class GradingReportServiceImpl implements GradingReportTemplateService, G
public GradingReportTemplate getCurrentTemplate(ProjectType projectType) {
return gradingReportTemplateRepo.getCurrentTemplate(projectType, LocalDate.now(clock));
}
@Override
public GradingReportTemplate getTemplate(long templateId) {
return gradingReportTemplateRepo.findOne(templateId);
}
@Override
public LocalDate getEndDate(GradingReportTemplate gradingReportTemplate) {
GradingReportTemplate next = gradingReportTemplateRepo.getNextTemplate(gradingReportTemplate);
if (next == null) {
return null;
} else {
return next.getValidFrom().minusDays(1);
}
}
}

View File

@ -84,6 +84,14 @@ public class GradingReportTemplate extends DomainObject {
this.validFrom = validFrom;
}
public ProjectType getProjectType() {
return projectType;
}
public void setProjectType(ProjectType projectType) {
this.projectType = projectType;
}
@Override
public boolean equals(final Object o) {
if (o == this) return true;

View File

@ -10,4 +10,6 @@ public interface GradingReportTemplateRepo extends JpaRepository<GradingReportTe
GradingReportTemplate getTemplate(Project project);
GradingReportTemplate getCurrentTemplate(ProjectType projectType, LocalDate now);
GradingReportTemplate getNextTemplate(GradingReportTemplate gradingReportTemplate);
}

View File

@ -34,4 +34,16 @@ public class GradingReportTemplateRepoImpl extends GenericRepo<GradingReportTemp
.and(template.validFrom.loe(now)));
return findOne(template.projectType.eq(projectType).and(template.validFrom.eq(validFrom)));
}
@Override
public GradingReportTemplate getNextTemplate(GradingReportTemplate gradingReportTemplate) {
QGradingReportTemplate template = QGradingReportTemplate.gradingReportTemplate;
// find the latest template that is valid for the project
JPQLQuery<LocalDate> validFrom = JPAExpressions
.select(template.validFrom.min())
.from(template)
.where(template.projectType.eq(gradingReportTemplate.getProjectType())
.and(template.validFrom.gt(gradingReportTemplate.getValidFrom())));
return findOne(template.projectType.eq(gradingReportTemplate.getProjectType()).and(template.validFrom.eq(validFrom)));
}
}

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<head>
<title>View a specific grading report template</title>
<wicket:remove>
<link rel="stylesheet" type="text/css" href="../../../../../../../../webapp/css/scipro_m.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</wicket:remove>
</head>
<body>
<wicket:extend>
<div class="line-length-limit" wicket:id="details">
<h1>
Grading report template for
<wicket:container wicket:id="project_type"/>
<small>
(<span wicket:id="valid_period"></span>)
</small>
</h1>
<h2>Criteria</h2>
<ol class="list-unstyled">
<li wicket:id="criteria" class="mb-3">
<h3 wicket:id="title"></h3>
<ol class="list-unstyled">
<li wicket:id="points">
<span wicket:id="point"></span> - <span wicket:id="description"></span>
</li>
</ol>
</li>
</ol>
</div>
</wicket:extend>
</body>
</html>

View File

@ -1,19 +1,96 @@
package se.su.dsv.scipro.admin.pages.grading;
import jakarta.inject.Inject;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.markup.html.GenericWebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import se.su.dsv.scipro.admin.pages.AbstractAdminProjectPage;
import se.su.dsv.scipro.grading.GradingReportTemplateService;
import se.su.dsv.scipro.report.GradingCriterionPointTemplate;
import se.su.dsv.scipro.report.GradingCriterionTemplate;
import se.su.dsv.scipro.report.GradingReportTemplate;
import se.su.dsv.scipro.system.ProjectType;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class AdminGradingTemplatePage extends AbstractAdminProjectPage implements MenuHighlightGradingTemplates {
private static final String TEMPLATE_ID_PARAMETER = "id";
public AdminGradingTemplatePage(PageParameters parameters) {
long templateId = parameters.get(TEMPLATE_ID_PARAMETER).toLong();
}
@Inject
private GradingReportTemplateService gradingReportTemplateService;
public static PageParameters getPageParameters(GradingReportTemplate gradingReportTemplate) {
PageParameters pageParameters = new PageParameters();
pageParameters.add(TEMPLATE_ID_PARAMETER, gradingReportTemplate.getId());
return pageParameters;
}
public AdminGradingTemplatePage(PageParameters parameters) {
long templateId = parameters.get(TEMPLATE_ID_PARAMETER).toLong();
IModel<GradingReportTemplate> template = LoadableDetachableModel.of(() ->
gradingReportTemplateService.getTemplate(templateId));
if (template.getObject() == null) {
throw new RestartResponseException(AdminGradingTemplatesOverviewPage.class);
}
add(new TemplateDetailsPanel("details", template));
}
private class TemplateDetailsPanel extends GenericWebMarkupContainer<GradingReportTemplate> {
public TemplateDetailsPanel(String id, IModel<GradingReportTemplate> model) {
super(id, model);
add(new Label("project_type", model.map(GradingReportTemplate::getProjectType).map(ProjectType::getName)));
IModel<String> validPeriod = () -> {
GradingReportTemplate template = model.getObject();
LocalDate validFrom = template.getValidFrom();
LocalDate endDate = gradingReportTemplateService.getEndDate(template);
if (endDate == null) {
return "from " + validFrom + " and onwards";
} else {
return "from " + validFrom + " to " + endDate;
}
};
add(new Label("valid_period", validPeriod));
add(new ListView<>("criteria", model.map(this::getCriteria)) {
@Override
protected void populateItem(ListItem<GradingCriterionTemplate> item) {
item.add(new Label("title", item.getModel().map(GradingCriterionTemplate::getTitle)));
item.add(new ListView<>(
"points",
item.getModel().map(GradingCriterionTemplate::getGradingCriterionPointTemplates))
{
@Override
protected void populateItem(ListItem<GradingCriterionPointTemplate> item) {
item.add(new Label("point", item.getModel().map(GradingCriterionPointTemplate::getPoint)));
item.add(new Label(
"description",
item.getModel().map(GradingCriterionPointTemplate::getDescription)));
}
});
}
});
}
private List<GradingCriterionTemplate> getCriteria(GradingReportTemplate gradingReportTemplate) {
ArrayList<GradingCriterionTemplate> criteria = new ArrayList<>();
gradingReportTemplate.getCriteria().forEach(criteria::add);
criteria.sort(Comparator.comparing(GradingCriterionTemplate::getSortOrder));
return Collections.unmodifiableList(criteria);
}
}
}

View File

@ -597,4 +597,7 @@ th.wicket_orderUp, th.sorting_asc {
.bg-su-primary {
background-color: #002f5f;
}
}
.line-length-limit {
max-width: 80em;
}