Allows admins to manage grading report templates #14
@ -33,4 +33,9 @@ public interface GradingReportTemplateService {
|
|||||||
NoSuchTemplateException,
|
NoSuchTemplateException,
|
||||||
DuplicateDateException,
|
DuplicateDateException,
|
||||||
TemplateLockedException;
|
TemplateLockedException;
|
||||||
|
|
||||||
|
GradingReportTemplate create(ProjectType projectType, GradingReportTemplateUpdate update)
|
||||||
|
throws
|
||||||
|
ValidDateMustBeInTheFutureException,
|
||||||
|
DuplicateDateException;
|
||||||
}
|
}
|
||||||
|
@ -269,4 +269,25 @@ public class GradingReportServiceImpl implements GradingReportTemplateService, G
|
|||||||
|
|
||||||
return gradingReportTemplateRepo.updateTemplate(templateId, update);
|
return gradingReportTemplateRepo.updateTemplate(templateId, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GradingReportTemplate create(ProjectType projectType, GradingReportTemplateUpdate update)
|
||||||
|
throws ValidDateMustBeInTheFutureException, DuplicateDateException
|
||||||
|
{
|
||||||
|
LocalDate today = LocalDate.now(clock);
|
||||||
|
if (!update.validFrom().isAfter(today)) {
|
||||||
|
throw new ValidDateMustBeInTheFutureException(update.validFrom(), today.plusDays(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
GradingReportTemplate currentTemplate = gradingReportTemplateRepo.getCurrentTemplate(
|
||||||
|
projectType,
|
||||||
|
update.validFrom());
|
||||||
|
if (currentTemplate != null &&
|
||||||
|
Objects.equals(currentTemplate.getValidFrom(), update.validFrom()))
|
||||||
|
{
|
||||||
|
throw new DuplicateDateException(update.validFrom(), projectType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gradingReportTemplateRepo.createTemplate(projectType, update);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,4 +20,6 @@ public interface GradingReportTemplateRepo extends JpaRepository<GradingReportTe
|
|||||||
GradingReportTemplate getTemplateById(long templateId);
|
GradingReportTemplate getTemplateById(long templateId);
|
||||||
|
|
||||||
GradingReportTemplate updateTemplate(long templateId, GradingReportTemplateUpdate update);
|
GradingReportTemplate updateTemplate(long templateId, GradingReportTemplateUpdate update);
|
||||||
|
|
||||||
|
GradingReportTemplate createTemplate(ProjectType projectType, GradingReportTemplateUpdate update);
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,13 @@ public class GradingReportTemplateRepoImpl extends GenericRepo<GradingReportTemp
|
|||||||
@Transactional
|
@Transactional
|
||||||
public GradingReportTemplate updateTemplate(long templateId, GradingReportTemplateUpdate update) {
|
public GradingReportTemplate updateTemplate(long templateId, GradingReportTemplateUpdate update) {
|
||||||
GradingReportTemplate gradingReportTemplate = findOne(templateId);
|
GradingReportTemplate gradingReportTemplate = findOne(templateId);
|
||||||
|
return updateTemplate(gradingReportTemplate, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GradingReportTemplate updateTemplate(
|
||||||
|
GradingReportTemplate gradingReportTemplate,
|
||||||
|
GradingReportTemplateUpdate update)
|
||||||
|
{
|
||||||
gradingReportTemplate.setValidFrom(update.validFrom());
|
gradingReportTemplate.setValidFrom(update.validFrom());
|
||||||
gradingReportTemplate.setNote(update.note());
|
gradingReportTemplate.setNote(update.note());
|
||||||
gradingReportTemplate.setFailingGrade(update.failingGrade());
|
gradingReportTemplate.setFailingGrade(update.failingGrade());
|
||||||
@ -111,6 +118,13 @@ public class GradingReportTemplateRepoImpl extends GenericRepo<GradingReportTemp
|
|||||||
return save(gradingReportTemplate);
|
return save(gradingReportTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public GradingReportTemplate createTemplate(ProjectType projectType, GradingReportTemplateUpdate update) {
|
||||||
|
GradingReportTemplate gradingReportTemplate = new GradingReportTemplate(projectType, update.validFrom());
|
||||||
|
return updateTemplate(gradingReportTemplate, update);
|
||||||
|
}
|
||||||
|
|
||||||
private GradingCriterionPointTemplate toPointTemplate(GradingReportTemplateUpdate.Criteria.Requirement requirement) {
|
private GradingCriterionPointTemplate toPointTemplate(GradingReportTemplateUpdate.Criteria.Requirement requirement) {
|
||||||
return new GradingCriterionPointTemplate.Builder()
|
return new GradingCriterionPointTemplate.Builder()
|
||||||
.point(requirement.points())
|
.point(requirement.points())
|
||||||
|
@ -14,6 +14,7 @@ import org.apache.wicket.util.convert.converter.LocalDateConverter;
|
|||||||
import org.apache.wicket.util.convert.converter.LocalDateTimeConverter;
|
import org.apache.wicket.util.convert.converter.LocalDateTimeConverter;
|
||||||
import se.su.dsv.scipro.activityplan.*;
|
import se.su.dsv.scipro.activityplan.*;
|
||||||
import se.su.dsv.scipro.admin.pages.*;
|
import se.su.dsv.scipro.admin.pages.*;
|
||||||
|
import se.su.dsv.scipro.admin.pages.grading.AdminGradingTemplateCreationPage;
|
||||||
import se.su.dsv.scipro.admin.pages.grading.AdminGradingTemplateEditPage;
|
import se.su.dsv.scipro.admin.pages.grading.AdminGradingTemplateEditPage;
|
||||||
import se.su.dsv.scipro.admin.pages.grading.AdminGradingTemplatePage;
|
import se.su.dsv.scipro.admin.pages.grading.AdminGradingTemplatePage;
|
||||||
import se.su.dsv.scipro.admin.pages.grading.AdminGradingTemplatesOverviewPage;
|
import se.su.dsv.scipro.admin.pages.grading.AdminGradingTemplatesOverviewPage;
|
||||||
@ -288,6 +289,7 @@ public class SciProApplication extends LifecycleManagedWebApplication {
|
|||||||
mountPage("admin/project/grading/template", AdminGradingTemplatesOverviewPage.class);
|
mountPage("admin/project/grading/template", AdminGradingTemplatesOverviewPage.class);
|
||||||
mountPage("admin/project/grading/template/view", AdminGradingTemplatePage.class);
|
mountPage("admin/project/grading/template/view", AdminGradingTemplatePage.class);
|
||||||
mountPage("admin/project/grading/template/edit", AdminGradingTemplateEditPage.class);
|
mountPage("admin/project/grading/template/edit", AdminGradingTemplateEditPage.class);
|
||||||
|
mountPage("admin/project/grading/template/create", AdminGradingTemplateCreationPage.class);
|
||||||
mountPage("admin/edit", AdminEditProjectPage.class);
|
mountPage("admin/edit", AdminEditProjectPage.class);
|
||||||
mountPage("admin/finalseminars", AdminFinalSeminarPage.class);
|
mountPage("admin/finalseminars", AdminFinalSeminarPage.class);
|
||||||
mountPage("admin/finalseminars/exemptions", AdminFinalSeminarExemptionPage.class);
|
mountPage("admin/finalseminars/exemptions", AdminFinalSeminarExemptionPage.class);
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
|
||||||
|
<body>
|
||||||
|
<wicket:extend>
|
||||||
|
<h1>Create a new grading report template</h1>
|
||||||
|
|
||||||
|
<div wicket:id="feedback"></div>
|
||||||
|
|
||||||
|
<form wicket:id="form" class="line-length-limit">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label" wicket:for="project_type">Project type</label>
|
||||||
|
<select wicket:id="project_type" class="form-select">
|
||||||
|
<option value="bachelor">Bachelor</option>
|
||||||
|
<option value="master">Master</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div wicket:id="grading_template_component_panel"></div>
|
||||||
|
|
||||||
|
<div class="position-sticky bottom-0 bg-white p-3 border line-length-limit">
|
||||||
|
<button type="submit" class="btn btn-primary">Create</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</wicket:extend>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,80 @@
|
|||||||
|
package se.su.dsv.scipro.admin.pages.grading;
|
||||||
|
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
import org.apache.wicket.RestartResponseException;
|
||||||
|
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||||
|
import org.apache.wicket.markup.html.form.Form;
|
||||||
|
import org.apache.wicket.markup.html.form.LambdaChoiceRenderer;
|
||||||
|
import org.apache.wicket.markup.html.panel.FeedbackPanel;
|
||||||
|
import org.apache.wicket.model.IModel;
|
||||||
|
import org.apache.wicket.model.Model;
|
||||||
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
|
import se.su.dsv.scipro.admin.pages.AbstractAdminProjectPage;
|
||||||
|
import se.su.dsv.scipro.components.AjaxDropDownChoice;
|
||||||
|
import se.su.dsv.scipro.data.DetachableServiceModel;
|
||||||
|
import se.su.dsv.scipro.grading.GradingReportTemplateService;
|
||||||
|
import se.su.dsv.scipro.grading.GradingReportTemplateUpdate;
|
||||||
|
import se.su.dsv.scipro.report.DuplicateDateException;
|
||||||
|
import se.su.dsv.scipro.report.GradingReportTemplate;
|
||||||
|
import se.su.dsv.scipro.report.ValidDateMustBeInTheFutureException;
|
||||||
|
import se.su.dsv.scipro.system.ProjectType;
|
||||||
|
import se.su.dsv.scipro.system.ProjectTypeService;
|
||||||
|
|
||||||
|
public class AdminGradingTemplateCreationPage extends AbstractAdminProjectPage implements MenuHighlightGradingTemplates {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
GradingReportTemplateService gradingReportTemplateService;
|
||||||
|
@Inject
|
||||||
|
ProjectTypeService projectTypeService;
|
||||||
|
|
||||||
|
private final IModel<ProjectType> projectTypeModel;
|
||||||
|
private EditingGradingTemplate editingGradingTemplateModel;
|
||||||
|
|
||||||
|
public AdminGradingTemplateCreationPage() {
|
||||||
|
projectTypeModel = new DetachableServiceModel<>(projectTypeService);
|
||||||
|
|
||||||
|
add(new FeedbackPanel("feedback"));
|
||||||
|
|
||||||
|
Form<?> form = new Form<>("form") {
|
||||||
|
@Override
|
||||||
|
protected void onSubmit() {
|
||||||
|
super.onSubmit();
|
||||||
|
GradingReportTemplateUpdate update = AdminGradingTemplateEditPage.toUpdate(editingGradingTemplateModel);
|
||||||
|
try {
|
||||||
|
GradingReportTemplate gradingReportTemplate = gradingReportTemplateService.create(
|
||||||
|
projectTypeModel.getObject(),
|
||||||
|
update);
|
||||||
|
getSession().success(getString("template_created", projectTypeModel));
|
||||||
|
PageParameters pageParameters = AdminGradingTemplateEditPage.getPageParameters(gradingReportTemplate);
|
||||||
|
throw new RestartResponseException(AdminGradingTemplateEditPage.class, pageParameters);
|
||||||
|
} catch (ValidDateMustBeInTheFutureException e) {
|
||||||
|
error(getString("valid_from_must_be_in_the_future", () -> e));
|
||||||
|
} catch (DuplicateDateException e) {
|
||||||
|
error(getString("another_template_exists_for_the_given_date_date", () -> e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
form.setOutputMarkupId(true);
|
||||||
|
add(form);
|
||||||
|
|
||||||
|
form.add(new AjaxDropDownChoice<>(
|
||||||
|
"project_type",
|
||||||
|
projectTypeModel,
|
||||||
|
gradingReportTemplateService.getProjectTypes(),
|
||||||
|
new LambdaChoiceRenderer<>(ProjectType::getName, ProjectType::getId)) {
|
||||||
|
@Override
|
||||||
|
public void onNewSelection(AjaxRequestTarget target, ProjectType objectSelected) {
|
||||||
|
target.add(form);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
editingGradingTemplateModel = new EditingGradingTemplate();
|
||||||
|
form.add(new EditingGradingTemplateComponentPanel("grading_template_component_panel", Model.of(editingGradingTemplateModel)) {
|
||||||
|
@Override
|
||||||
|
protected void onConfigure() {
|
||||||
|
super.onConfigure();
|
||||||
|
setVisible(projectTypeModel.getObject() != null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -66,17 +66,17 @@ public class AdminGradingTemplateEditPage extends AbstractAdminProjectPage imple
|
|||||||
add(form);
|
add(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GradingReportTemplateUpdate toUpdate(EditingGradingTemplate editingGradingTemplate) {
|
public static GradingReportTemplateUpdate toUpdate(EditingGradingTemplate editingGradingTemplate) {
|
||||||
List<GradingReportTemplateUpdate.GradeLimit> gradeLimits = editingGradingTemplate
|
List<GradingReportTemplateUpdate.GradeLimit> gradeLimits = editingGradingTemplate
|
||||||
.getGradeLimits()
|
.getGradeLimits()
|
||||||
.getGradeLimits()
|
.getGradeLimits()
|
||||||
.stream()
|
.stream()
|
||||||
.map(this::toGrade)
|
.map(AdminGradingTemplateEditPage::toGrade)
|
||||||
.toList();
|
.toList();
|
||||||
List<GradingReportTemplateUpdate.Criteria> criteria = editingGradingTemplate
|
List<GradingReportTemplateUpdate.Criteria> criteria = editingGradingTemplate
|
||||||
.getCriteria()
|
.getCriteria()
|
||||||
.stream()
|
.stream()
|
||||||
.map(this::toCriteria)
|
.map(AdminGradingTemplateEditPage::toCriteria)
|
||||||
.toList();
|
.toList();
|
||||||
return new GradingReportTemplateUpdate(
|
return new GradingReportTemplateUpdate(
|
||||||
editingGradingTemplate.getValidFrom(),
|
editingGradingTemplate.getValidFrom(),
|
||||||
@ -86,7 +86,7 @@ public class AdminGradingTemplateEditPage extends AbstractAdminProjectPage imple
|
|||||||
criteria);
|
criteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GradingReportTemplateUpdate.Criteria toCriteria(EditingGradingTemplate.Criteria criteria) {
|
private static GradingReportTemplateUpdate.Criteria toCriteria(EditingGradingTemplate.Criteria criteria) {
|
||||||
ArrayList<GradingReportTemplateUpdate.Criteria.Requirement> requirements = new ArrayList<>();
|
ArrayList<GradingReportTemplateUpdate.Criteria.Requirement> requirements = new ArrayList<>();
|
||||||
requirements.add(ZERO_REQUIREMENT);
|
requirements.add(ZERO_REQUIREMENT);
|
||||||
for (int i = 0; i < criteria.getPoints().size(); i++) {
|
for (int i = 0; i < criteria.getPoints().size(); i++) {
|
||||||
@ -117,7 +117,7 @@ public class AdminGradingTemplateEditPage extends AbstractAdminProjectPage imple
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private GradingReportTemplateUpdate.GradeLimit toGrade(GradeLimits.GradeLimit gradeLimit) {
|
private static GradingReportTemplateUpdate.GradeLimit toGrade(GradeLimits.GradeLimit gradeLimit) {
|
||||||
return new GradingReportTemplateUpdate.GradeLimit(
|
return new GradingReportTemplateUpdate.GradeLimit(
|
||||||
gradeLimit.getGrade(),
|
gradeLimit.getGrade(),
|
||||||
gradeLimit.getLowerLimit());
|
gradeLimit.getLowerLimit());
|
||||||
|
@ -32,15 +32,9 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="btn-group mb-3" role="group">
|
<div class="btn-group mb-3" role="group">
|
||||||
<button type="button" class="btn btn-outline-primary">Create new template</button>
|
<wicket:link>
|
||||||
|
<a href="AdminGradingTemplateCreationPage.html" class="btn btn-outline-primary">Create new template</a>
|
||||||
<div class="btn-group" role="group">
|
</wicket:link>
|
||||||
<button type="button" class="btn btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><button class="dropdown-item" href="#">Create new based on another template</button></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3" wicket:id="project_types">
|
<div class="mb-3" wicket:id="project_types">
|
||||||
|
@ -15,6 +15,11 @@ class EditingGradingTemplate implements Serializable {
|
|||||||
private List<Criteria> criteria;
|
private List<Criteria> criteria;
|
||||||
private GradeLimits gradeLimits;
|
private GradeLimits gradeLimits;
|
||||||
|
|
||||||
|
public EditingGradingTemplate() {
|
||||||
|
this.gradeLimits = new GradeLimits();
|
||||||
|
this.criteria = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
EditingGradingTemplate(GradingReportTemplate template) {
|
EditingGradingTemplate(GradingReportTemplate template) {
|
||||||
this.note = template.getNote();
|
this.note = template.getNote();
|
||||||
this.validFrom = template.getValidFrom();
|
this.validFrom = template.getValidFrom();
|
||||||
|
@ -10,6 +10,10 @@ class GradeLimits implements Serializable {
|
|||||||
private List<GradeLimit> gradeLimits;
|
private List<GradeLimit> gradeLimits;
|
||||||
private String failingGrade;
|
private String failingGrade;
|
||||||
|
|
||||||
|
public GradeLimits() {
|
||||||
|
this.gradeLimits = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
GradeLimits(GradingReportTemplate template) {
|
GradeLimits(GradingReportTemplate template) {
|
||||||
this.gradeLimits = new ArrayList<>();
|
this.gradeLimits = new ArrayList<>();
|
||||||
for (var gradeLimit : template.getGradeLimits()) {
|
for (var gradeLimit : template.getGradeLimits()) {
|
||||||
|
@ -2,3 +2,4 @@ template_updated=Template updated
|
|||||||
valid_from_must_be_in_the_future=The templates valid date must be in the future. The given date was ${validFrom} but it must be at least ${earliestAllowedValidFrom}.
|
valid_from_must_be_in_the_future=The templates valid date must be in the future. The given date was ${validFrom} but it must be at least ${earliestAllowedValidFrom}.
|
||||||
another_template_exists_for_the_given_date_date=There is already another ${projectType.name} template that becomes valid at ${validFrom}, please pick another date.
|
another_template_exists_for_the_given_date_date=There is already another ${projectType.name} template that becomes valid at ${validFrom}, please pick another date.
|
||||||
template_is_locked=You can not edit templates that have become current. The template you are trying to edit became current at ${validFrom}.
|
template_is_locked=You can not edit templates that have become current. The template you are trying to edit became current at ${validFrom}.
|
||||||
|
template_created=New template for ${name} created.
|
Loading…
x
Reference in New Issue
Block a user