Allows admins to manage grading report templates #14
@ -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.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;
|
||||||
import se.su.dsv.scipro.admin.pages.settings.*;
|
import se.su.dsv.scipro.admin.pages.settings.*;
|
||||||
@ -286,6 +287,7 @@ public class SciProApplication extends LifecycleManagedWebApplication {
|
|||||||
mountPage("admin/project/reviewer/capacity", AdminReviewerCapacityManagementPage.class);
|
mountPage("admin/project/reviewer/capacity", AdminReviewerCapacityManagementPage.class);
|
||||||
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/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,13 @@
|
|||||||
|
<?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>
|
||||||
|
<form wicket:id="form">
|
||||||
|
<div wicket:id="editing" class="mb-3"></div>
|
||||||
|
<div class="position-sticky bottom-0 bg-white p-3 border line-length-limit">
|
||||||
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</wicket:extend>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,13 +1,38 @@
|
|||||||
package se.su.dsv.scipro.admin.pages.grading;
|
package se.su.dsv.scipro.admin.pages.grading;
|
||||||
|
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
import org.apache.wicket.markup.html.form.Form;
|
||||||
|
import org.apache.wicket.model.Model;
|
||||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||||
import se.su.dsv.scipro.admin.pages.AbstractAdminProjectPage;
|
import se.su.dsv.scipro.admin.pages.AbstractAdminProjectPage;
|
||||||
|
import se.su.dsv.scipro.grading.GradingReportTemplateService;
|
||||||
import se.su.dsv.scipro.report.GradingReportTemplate;
|
import se.su.dsv.scipro.report.GradingReportTemplate;
|
||||||
|
|
||||||
public class AdminGradingTemplateEditPage extends AbstractAdminProjectPage implements MenuHighlightGradingTemplates {
|
public class AdminGradingTemplateEditPage extends AbstractAdminProjectPage implements MenuHighlightGradingTemplates {
|
||||||
private static final String GRADING_REPORT_TEMPLATE_ID_PARAMETER = "id";
|
private static final String GRADING_REPORT_TEMPLATE_ID_PARAMETER = "id";
|
||||||
|
|
||||||
public AdminGradingTemplateEditPage() {
|
@Inject
|
||||||
|
GradingReportTemplateService gradingReportTemplateService;
|
||||||
|
|
||||||
|
private EditingGradingTemplate editingGradingTemplate;
|
||||||
|
|
||||||
|
public AdminGradingTemplateEditPage(PageParameters pageParameters) {
|
||||||
|
long id = pageParameters.get(GRADING_REPORT_TEMPLATE_ID_PARAMETER).toLong();
|
||||||
|
|
||||||
|
GradingReportTemplate template = gradingReportTemplateService.getTemplate(id);
|
||||||
|
|
||||||
|
editingGradingTemplate = new EditingGradingTemplate(template);
|
||||||
|
|
||||||
|
Form<EditingGradingTemplate> form = new Form<>("form") {
|
||||||
|
@Override
|
||||||
|
protected void onSubmit() {
|
||||||
|
super.onSubmit();
|
||||||
|
System.out.println(editingGradingTemplate);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
form.add(new EditingGradingTemplateComponentPanel("editing", Model.of(editingGradingTemplate)));
|
||||||
|
add(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PageParameters getPageParameters(GradingReportTemplate gradingReportTemplate) {
|
public static PageParameters getPageParameters(GradingReportTemplate gradingReportTemplate) {
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
package se.su.dsv.scipro.admin.pages.grading;
|
||||||
|
|
||||||
|
import se.su.dsv.scipro.report.GradingCriterionPointTemplate;
|
||||||
|
import se.su.dsv.scipro.report.GradingCriterionTemplate;
|
||||||
|
import se.su.dsv.scipro.report.GradingReportTemplate;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class EditingGradingTemplate implements Serializable {
|
||||||
|
private String note;
|
||||||
|
private List<Criteria> criteria;
|
||||||
|
|
||||||
|
EditingGradingTemplate(GradingReportTemplate template) {
|
||||||
|
this.note = "";
|
||||||
|
this.criteria = new ArrayList<>();
|
||||||
|
for (var criteria : template.getCriteria()) {
|
||||||
|
Criteria editingCriteria = new Criteria(criteria);
|
||||||
|
this.criteria.add(editingCriteria);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNote() {
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNote(String note) {
|
||||||
|
this.note = note;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Criteria> getCriteria() {
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Criteria implements Serializable {
|
||||||
|
private String titleSv;
|
||||||
|
private String titleEn;
|
||||||
|
private List<Point> points;
|
||||||
|
|
||||||
|
Criteria(GradingCriterionTemplate criteria) {
|
||||||
|
this.titleSv = criteria.getTitle();
|
||||||
|
this.titleEn = criteria.getTitleEn();
|
||||||
|
this.points = new ArrayList<>();
|
||||||
|
for (var point : criteria.getGradingCriterionPointTemplates()) {
|
||||||
|
if (point.getPoint() == 0) continue;;
|
||||||
|
Point editingPoint = new Point(point);
|
||||||
|
this.points.add(editingPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitleSv() {
|
||||||
|
return titleSv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitleSv(String titleSv) {
|
||||||
|
this.titleSv = titleSv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitleEn() {
|
||||||
|
return titleEn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitleEn(String titleEn) {
|
||||||
|
this.titleEn = titleEn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Point> getPoints() {
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoints(List<Point> points) {
|
||||||
|
this.points = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Point implements Serializable {
|
||||||
|
private String requirementEn;
|
||||||
|
private String requirementSv;
|
||||||
|
|
||||||
|
Point() {
|
||||||
|
this.requirementEn = "";
|
||||||
|
this.requirementSv = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Point(GradingCriterionPointTemplate point) {
|
||||||
|
this.requirementEn = point.getDescriptionEn();
|
||||||
|
this.requirementSv = point.getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequirementEn() {
|
||||||
|
return requirementEn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequirementEn(String requirement) {
|
||||||
|
this.requirementEn = requirement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequirementSv() {
|
||||||
|
return requirementSv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequirementSv(String requirementSv) {
|
||||||
|
this.requirementSv = requirementSv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
|
||||||
|
<head>
|
||||||
|
<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:panel>
|
||||||
|
<div class="mb-3 line-length-limit">
|
||||||
|
<label class="form-label" wicket:for="note">
|
||||||
|
Note
|
||||||
|
</label>
|
||||||
|
<textarea class="form-control" wicket:id="note" rows="3"></textarea>
|
||||||
|
<small class="text-muted">
|
||||||
|
This note can be used to describe the template, for example, what changes have been made from the previous version.
|
||||||
|
It is purely an aid for administrators if necessary.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 line-length-limit card" wicket:id="criteria">
|
||||||
|
<div class="card-header text-bg-info text-white">
|
||||||
|
<h3 class="text-white mb-0">Criteria 1</h3>
|
||||||
|
</div>
|
||||||
|
<div wicket:id="criteria" class="card-body">
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label class="form-label" wicket:for="title_en">
|
||||||
|
Title (english)
|
||||||
|
</label>
|
||||||
|
<input class="form-control" wicket:id="title_en" type="text">
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<label class="form-label" wicket:for="title_sv">
|
||||||
|
Title (swedish)
|
||||||
|
</label>
|
||||||
|
<input class="form-control" wicket:id="title_sv" type="text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>Points</legend>
|
||||||
|
|
||||||
|
<ol class="list-unstyled">
|
||||||
|
<li wicket:id="points">
|
||||||
|
<fieldset wicket:id="point" class="card mb-3">
|
||||||
|
<legend class="card-header hstack justify-content-between">
|
||||||
|
<span wicket:id="point"></span>
|
||||||
|
<button class="btn btn-sm btn-outline-danger" wicket:id="remove">Remove</button>
|
||||||
|
</legend>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label wicket:for="requirement_en">
|
||||||
|
Requirement (english)
|
||||||
|
</label>
|
||||||
|
<textarea rows="4" class="form-control" wicket:id="requirement_en"></textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label wicket:for="requirement_sv">
|
||||||
|
Requirement (swedish)
|
||||||
|
</label>
|
||||||
|
<textarea rows="4" class="form-control" wicket:id="requirement_sv"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="row align-items-center" wicket:id="new_point_form">
|
||||||
|
<label class="col-auto">
|
||||||
|
<wicket:container wicket:id="new_point"/>
|
||||||
|
</label>
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn btn-sm btn-outline-success" wicket:id="add_new_point">Add</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</wicket:panel>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,109 @@
|
|||||||
|
package se.su.dsv.scipro.admin.pages.grading;
|
||||||
|
|
||||||
|
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||||
|
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||||
|
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
|
||||||
|
import org.apache.wicket.markup.html.GenericWebMarkupContainer;
|
||||||
|
import org.apache.wicket.markup.html.basic.Label;
|
||||||
|
import org.apache.wicket.markup.html.form.Form;
|
||||||
|
import org.apache.wicket.markup.html.form.TextArea;
|
||||||
|
import org.apache.wicket.markup.html.form.TextField;
|
||||||
|
import org.apache.wicket.markup.html.list.ListItem;
|
||||||
|
import org.apache.wicket.markup.html.list.ListView;
|
||||||
|
import org.apache.wicket.markup.html.panel.GenericPanel;
|
||||||
|
import org.apache.wicket.model.IModel;
|
||||||
|
import org.apache.wicket.model.LambdaModel;
|
||||||
|
import org.apache.wicket.model.Model;
|
||||||
|
|
||||||
|
class EditingGradingTemplateComponentPanel extends GenericPanel<EditingGradingTemplate> {
|
||||||
|
EditingGradingTemplateComponentPanel(
|
||||||
|
String id,
|
||||||
|
IModel<EditingGradingTemplate> editingGradingTemplateModel)
|
||||||
|
{
|
||||||
|
super(id, editingGradingTemplateModel);
|
||||||
|
|
||||||
|
add(new TextArea<>("note", LambdaModel.of(
|
||||||
|
editingGradingTemplateModel,
|
||||||
|
EditingGradingTemplate::getNote,
|
||||||
|
EditingGradingTemplate::setNote)));
|
||||||
|
|
||||||
|
add(new ListView<>("criteria", editingGradingTemplateModel.map(EditingGradingTemplate::getCriteria)) {
|
||||||
|
{
|
||||||
|
setReuseItems(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void populateItem(ListItem<EditingGradingTemplate.Criteria> item) {
|
||||||
|
item.add(new CriteriaEditingPanel("criteria", item.getModel()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class CriteriaEditingPanel extends GenericWebMarkupContainer<EditingGradingTemplate.Criteria> {
|
||||||
|
CriteriaEditingPanel(String id, IModel<EditingGradingTemplate.Criteria> model) {
|
||||||
|
super(id, model);
|
||||||
|
|
||||||
|
setOutputMarkupId(true);
|
||||||
|
|
||||||
|
add(new TextField<>("title_sv", LambdaModel.of(
|
||||||
|
model,
|
||||||
|
EditingGradingTemplate.Criteria::getTitleSv,
|
||||||
|
EditingGradingTemplate.Criteria::setTitleSv)));
|
||||||
|
add(new TextField<>("title_en", LambdaModel.of(
|
||||||
|
model,
|
||||||
|
EditingGradingTemplate.Criteria::getTitleEn,
|
||||||
|
EditingGradingTemplate.Criteria::setTitleEn)));
|
||||||
|
|
||||||
|
add(new ListView<>("points", model.map(EditingGradingTemplate.Criteria::getPoints)) {
|
||||||
|
@Override
|
||||||
|
protected void populateItem(ListItem<EditingGradingTemplate.Criteria.Point> item) {
|
||||||
|
item.add(new PointEditingPanel("point", item.getModel()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Form<Object> newPointForm = new Form<>("new_point_form");
|
||||||
|
add(newPointForm);
|
||||||
|
|
||||||
|
newPointForm.add(new Label("new_point", model
|
||||||
|
.map(criteria -> criteria.getPoints().size())
|
||||||
|
.map(size -> "Requirement for " + size + " points")));
|
||||||
|
|
||||||
|
newPointForm.add(new AjaxSubmitLink("add_new_point", newPointForm) {
|
||||||
|
@Override
|
||||||
|
public void onSubmit(AjaxRequestTarget target) {
|
||||||
|
EditingGradingTemplate.Criteria criteria = model.getObject();
|
||||||
|
EditingGradingTemplate.Criteria.Point newPoint = criteria.new Point();
|
||||||
|
criteria.getPoints().add(newPoint);
|
||||||
|
target.add(CriteriaEditingPanel.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PointEditingPanel extends GenericWebMarkupContainer<EditingGradingTemplate.Criteria.Point> {
|
||||||
|
public PointEditingPanel(String id, IModel<EditingGradingTemplate.Criteria.Point> model) {
|
||||||
|
super(id, model);
|
||||||
|
|
||||||
|
add(new Label("point", "Requirement for 1 point"));
|
||||||
|
|
||||||
|
add(new TextArea<>("requirement_en", LambdaModel.of(
|
||||||
|
model,
|
||||||
|
EditingGradingTemplate.Criteria.Point::getRequirementEn,
|
||||||
|
EditingGradingTemplate.Criteria.Point::setRequirementEn)));
|
||||||
|
|
||||||
|
add(new TextArea<>("requirement_sv", LambdaModel.of(
|
||||||
|
model,
|
||||||
|
EditingGradingTemplate.Criteria.Point::getRequirementSv,
|
||||||
|
EditingGradingTemplate.Criteria.Point::setRequirementSv)));
|
||||||
|
|
||||||
|
add(new AjaxLink<>("remove") {
|
||||||
|
@Override
|
||||||
|
public void onClick(AjaxRequestTarget target) {
|
||||||
|
EditingGradingTemplate.Criteria criteria = CriteriaEditingPanel.this.getModelObject();
|
||||||
|
criteria.getPoints().remove(model.getObject());
|
||||||
|
target.add(CriteriaEditingPanel.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user