Deadline visible in "Rough draft approval" page ()

Previously deadline was only visible at the Reviewer start page, tab 'Rough draft approvals'.

Now the deadline is also shown when you go to the detail page of a rough draft.

Fixes issue 

Reviewed-on: 
Reviewed-by: Andreas Svanberg <andreass@dsv.su.se>
Co-authored-by: Nico Athanassiadis <nico@dsv.su.se>
Co-committed-by: Nico Athanassiadis <nico@dsv.su.se>
This commit is contained in:
Nico Athanassiadis 2025-02-12 11:07:53 +01:00 committed by Andreas Svanberg
parent 219c312441
commit 304d0431c1
6 changed files with 99 additions and 6 deletions
compose-branch-deploy.yaml
core/src/main/java/se/su/dsv/scipro
view/src
main/java/se/su/dsv/scipro/supervisor/panels
test/java/se/su/dsv/scipro/supervisor/panels
war/src/main/resources

@ -21,6 +21,8 @@ services:
- OAUTH2_RESOURCE_SERVER_ID=scipro_api_client
- OAUTH2_RESOURCE_SERVER_SECRET=scipro_api_secret
- OAUTH2_RESOURCE_SERVER_INTROSPECTION_URI=https://oauth2-${VHOST}/introspect
- OAUTH2_GS_AUTHORIZATION_URI=https://oauth2-gs-${VHOST}
- OAUTH2_GS_CLIENT_REDIRECT_URI=https://${VHOST}/oauth/callback
networks:
- traefik
- internal
@ -64,6 +66,25 @@ services:
- "traefik.http.routers.oauth2-${COMPOSE_PROJECT_NAME}.rule=Host(`oauth2-${VHOST}`)"
- "traefik.http.routers.oauth2-${COMPOSE_PROJECT_NAME}.tls.certresolver=letsencrypt"
oauth2-gs:
build:
context: https://github.com/dsv-su/toker.git
dockerfile: embedded.Dockerfile
restart: unless-stopped
environment:
- CLIENT_ID=scipro_client
- CLIENT_SECRET=scipro_secret
- CLIENT_REDIRECT_URI=https://${VHOST}/oauth/callback
- RESOURCE_SERVER_ID=scipro_api_client
- RESOURCE_SERVER_SECRET=scipro_api_secret
- CLIENT_SCOPES=grade:read grade:write
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.oauth2-gs-${COMPOSE_PROJECT_NAME}.rule=Host(`oauth2-gs-${VHOST}`)"
- "traefik.http.routers.oauth2-gs-${COMPOSE_PROJECT_NAME}.tls.certresolver=letsencrypt"
networks:
traefik:
name: traefik

@ -4,11 +4,15 @@ import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Month;
import java.util.*;
import java.util.function.Function;
import se.su.dsv.scipro.checklist.ChecklistCategory;
import se.su.dsv.scipro.file.FileUpload;
import se.su.dsv.scipro.match.ApplicationPeriod;
import se.su.dsv.scipro.match.Keyword;
import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate;
@ -20,6 +24,8 @@ import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.report.AbstractGradingCriterion;
import se.su.dsv.scipro.report.GradingCriterionPointTemplate;
import se.su.dsv.scipro.report.GradingReportTemplate;
import se.su.dsv.scipro.reviewing.ReviewerAssignmentService;
import se.su.dsv.scipro.reviewing.RoughDraftApprovalService;
import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.system.*;
@ -45,6 +51,12 @@ public class DataInitializer implements Lifecycle {
@Inject
private Provider<EntityManager> em;
@Inject
private RoughDraftApprovalService roughDraftApprovalService;
@Inject
private ReviewerAssignmentService reviewerAssignmentService;
private static final String MAIL = "@example.com";
private static final String ADMIN = "admin";
@ -75,6 +87,7 @@ public class DataInitializer implements Lifecycle {
private ResearchArea researchArea2;
private ProjectType masterClass;
private ProjectType magisterClass;
private Project project2;
@Transactional
@Override
@ -89,12 +102,23 @@ public class DataInitializer implements Lifecycle {
createMilestonesIfNotDone();
createUsers();
createProjects();
createRoughDraftApproval();
}
if (profile.getCurrentProfile() == Profiles.DEV && noAdminUser()) {
createAdmin();
}
}
private void createRoughDraftApproval() {
roughDraftApprovalService.requestApproval(
project2,
new SimpleTextFile(project2.getHeadSupervisor(), "thesis.txt", "text/plain"),
"Please approve"
);
reviewerAssignmentService.assignReviewer(project2, eric_employee);
}
@Override
public void stop() {}
@ -146,10 +170,10 @@ public class DataInitializer implements Lifecycle {
private void createProjects() {
createProject(PROJECT_1, eric_employee, sture_student, stina_student, eve_employee);
createProject(PROJECT_2, eve_employee, sid_student, simon_student, eric_employee);
project2 = createProject(PROJECT_2, eve_employee, sid_student, simon_student, eric_employee);
}
private void createProject(String title, User headSupervisor, User student1, User student2, User reviewer) {
private Project createProject(String title, User headSupervisor, User student1, User student2, User reviewer) {
Project project = Project.builder()
.title(title)
.projectType(bachelorClass)
@ -160,6 +184,7 @@ public class DataInitializer implements Lifecycle {
project.addProjectParticipant(student1);
project.addReviewer(reviewer);
save(project);
return project;
}
private void createUsers() {
@ -1907,4 +1932,42 @@ public class DataInitializer implements Lifecycle {
em.get().persist(entity);
return entity;
}
private static final class SimpleTextFile implements FileUpload {
private final User uploader;
private final String fileName;
private final String content;
private SimpleTextFile(User uploader, String fileName, String content) {
this.uploader = uploader;
this.fileName = fileName;
this.content = content;
}
@Override
public String getFileName() {
return fileName;
}
@Override
public String getContentType() {
return "text/plain";
}
@Override
public User getUploader() {
return uploader;
}
@Override
public long getSize() {
return content.length();
}
@Override
public <T> T handleData(Function<InputStream, T> handler) {
return handler.apply(new ByteArrayInputStream(content.getBytes()));
}
}
}

@ -4,6 +4,7 @@
<wicket:panel>
<strong>Current thesis:</strong> <span wicket:id="currentThesis">[thesis.pdf (2014-08-08)]</span><br>
<strong>Status:</strong> <span wicket:id="currentStatus">[Undecided]</span> <br>
<strong>Deadline:</strong> <span wicket:id="deadline">[Undecided]</span> <br>
<strong>Supervisor comment:</strong> <span wicket:id="currentDecision.comment">[Undecided]</span> <br>
<wicket:enclosure>
<strong>Reason:</strong> <span wicket:id="currentReason">[I need more time]</span><br>

@ -28,6 +28,7 @@ public class FinalSeminarApprovalProcessPanel extends GenericPanel<ReviewerAppro
)
);
add(new EnumLabel<>("currentStatus", process.map(ReviewerApproval::getCurrentStatus)));
add(new DateLabel("deadline", process.map(ReviewerApproval::getCurrentDeadline)));
add(
new MultiLineLabel(
"currentDecision.comment",

@ -10,6 +10,7 @@ import org.apache.wicket.model.LoadableDetachableModel;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import se.su.dsv.scipro.SciProTest;
import se.su.dsv.scipro.components.DateLabel;
import se.su.dsv.scipro.file.FileDescription;
import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.project.Project;
@ -44,6 +45,12 @@ public class FinalSeminarApprovalProcessPanelTest extends SciProTest {
tester.assertModelValue(path(panel, "currentStatus"), finalSeminarApproval.getCurrentStatus());
}
@Test
public void shows_deadline() {
tester.assertComponent(path(panel, "deadline"), DateLabel.class);
tester.assertModelValue(path(panel, "deadline"), finalSeminarApproval.getCurrentDeadline());
}
@Test
public void shows_current_reason_if_a_decision_has_been_made() {
startPanelWithApprovedFinalSeminar();

@ -7,10 +7,10 @@ profile=DEV
# No secrets available for branch deployment to branch.dsv.su.se
# Will have to set up some mock API for this later
service.grading.url=
oauth.uri=
oauth.clientId=
oauth.clientSecret=
oauth.redirectUri=
oauth.uri=${OAUTH2_GS_AUTHORIZATION_URI:http://localhost:59734/authorize}
oauth.clientId=${OAUTH2_CLIENT_ID:scipro}
oauth.clientSecret=${OAUTH2_CLIENT_SECRET:s3cr3t}
oauth.redirectUri=${OAUTH2_GS_CLIENT_REDIRECT_URI}
# No secrets available for branch deployment to branch.dsv.su.se
# Will have to set up some mock API for this later