3380 Specify information URL about the review process for supervisors

Administrators want to inform the supervisors how the reviewers are assigned and what dates are important during the thesis writing process.

They can now configure an information URL for each type of project under "Admin / System / Type settings" that is shown to the supervisors as they enter the review process.
This commit is contained in:
Andreas Svanberg 2024-05-27 16:29:23 +02:00
parent da842a9fd2
commit 663b92eb3b
7 changed files with 69 additions and 1 deletions
core/src/main
view/src

@ -59,6 +59,10 @@ public class ProjectTypeSettings extends DomainObject {
@Basic(optional = false)
private int numDaysBeforePeerGetsCancelled = DEFAULT_NUM_DAYS_BEFORE_CANCELLED_PEERS;
@Basic
@Column(name = "review_process_information_url_for_supervisor")
private String reviewProcessInformationUrl;
@Override
public Long getId() {
return this.id;
@ -164,6 +168,14 @@ public class ProjectTypeSettings extends DomainObject {
this.minimumActiveParticipationsToBeGraded = minimumActiveParticipationsToBeGraded;
}
public String getReviewProcessInformationUrl() {
return reviewProcessInformationUrl;
}
public void setReviewProcessInformationUrl(String reviewProcessInformationUrl) {
this.reviewProcessInformationUrl = reviewProcessInformationUrl;
}
@Override
public String toString() {
return "ProjectTypeSettings(id=" + this.getId() + ", projectType=" + this.getProjectType() + ", minAuthors=" + this.getMinAuthors() + ", maxAuthors=" + this.getMaxAuthors() + ", maxFinalSeminarActiveParticipation=" + this.getMaxFinalSeminarActiveParticipation() + ", maxOpponentsOnFinalSeminar=" + this.getMaxOpponentsOnFinalSeminar() + ", minFinalSeminarActiveParticipation=" + this.getMinFinalSeminarActiveParticipation() + ", minOpponentsOnFinalSeminar=" + this.getMinOpponentsOnFinalSeminar() + ", numDaysBetweenPeerReviewsOnSameProject=" + this.getNumDaysBetweenPeerReviewsOnSameProject() + ", numDaysToSubmitPeerReview=" + this.getNumDaysToSubmitPeerReview() + ", numDaysBeforePeerGetsCancelled=" + this.getNumDaysBeforePeerGetsCancelled() + ")";

@ -0,0 +1,2 @@
ALTER TABLE `project_type_settings`
ADD COLUMN `review_process_information_url_for_supervisor` VARCHAR(255) NULL;

@ -46,6 +46,15 @@
</label>
<input class="form-control" type="number" wicket:id="minimum_active_participations_to_be_graded">
</div>
<div class="mb-3">
<label wicket:for="review_process_information_url">
URL with information about the review process
</label>
<input class="form-control" type="url" wicket:id="review_process_information_url">
<small class="text-muted">
This link is display for supervisors when they are in the review process.
</small>
</div>
<input class="btn btn-sm btn-success" wicket:id="createButton" type="submit" value="Save" />
<input class="btn btn-sm btn-danger" wicket:id="deleteButton" type="submit" value="Inactivate" />
</form>

@ -84,6 +84,14 @@ public class AdminProjectTypePanel extends Panel {
maximumAuthors.setRequired(true);
add(maximumAuthors);
TextField<String> reviewProcessInformationUrl = new UrlTextField(
"review_process_information_url",
LambdaModel.of(
settings,
ProjectTypeSettings::getReviewProcessInformationUrl,
ProjectTypeSettings::setReviewProcessInformationUrl));
add(reviewProcessInformationUrl);
Button createButton = new Button("createButton") {
@Override
public void onSubmit() {

@ -10,7 +10,16 @@
<div class="col-12 col-xl-3 col-lg-6">
<div class="card bg-light">
<h4 class="card-header">Rough draft approval</h4>
<div class="card-body" wicket:id="roughDraftApproval"></div>
<div class="card-body">
<wicket:enclosure>
<p>
<a href="https://example.com" wicket:id="review_process_information">
See more information about the review process and any important dates.
</a>
</p>
</wicket:enclosure>
<div wicket:id="roughDraftApproval"></div>
</div>
</div>
</div>
<div class="col-12 col-xl-6 col-lg-6">

@ -3,6 +3,8 @@ package se.su.dsv.scipro.supervisor.pages;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnEventHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightSupervisorMyProjects;
import se.su.dsv.scipro.file.FileService;
@ -18,6 +20,8 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.supervisor.panels.RoughDraftApprovalPanel;
import jakarta.inject.Inject;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.ProjectTypeSettings;
@Authorization(authorizedRoles = Roles.SUPERVISOR)
public class SupervisorInteractWithReviewerPage extends AbstractSupervisorProjectDetailsPage implements MenuHighlightSupervisorMyProjects {
@ -41,6 +45,17 @@ public class SupervisorInteractWithReviewerPage extends AbstractSupervisorProjec
}
});
IModel<String> moreInformationUrl = projectModel
.map(Project::getProjectType)
.map(ProjectType::getProjectTypeSettings)
.map(ProjectTypeSettings::getReviewProcessInformationUrl);
add(new ExternalLink("review_process_information", moreInformationUrl) {
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(moreInformationUrl.getObject() != null);
}
});
ForumThread<Project> reviewerThread = new ReviewerInteractionForumThread(reviewerInteractionService);
add(new RoughDraftApprovalPanel("roughDraftApproval", projectModel));
add(new SubmitForumReplyPanel<>("communication", projectModel, reviewerThread));

@ -55,4 +55,17 @@ public class AdminProjectTypePanelTest extends SciProTest {
assertEquals(17, captor.getValue().getProjectTypeSettings().getMinAuthors());
assertEquals(29, captor.getValue().getProjectTypeSettings().getMaxAuthors());
}
@Test
public void set_review_process_information_url() {
FormTester formTester = tester.newFormTester(path(panel, "projectTypeForm"));
formTester.setValue("name", "bachelor");
formTester.setValue("review_process_information_url", "https://example.com");
formTester.submit("createButton");
ArgumentCaptor<ProjectType> captor = ArgumentCaptor.forClass(ProjectType.class);
verify(projectTypeService).save(captor.capture());
assertEquals("https://example.com", captor.getValue().getProjectTypeSettings().getReviewProcessInformationUrl());
}
}