From cbbd98b597cbb4de9bad77c01d83a54a65720dcd Mon Sep 17 00:00:00 2001 From: Andreas Svanberg <andreass@dsv.su.se> Date: Thu, 6 Feb 2025 14:10:30 +0100 Subject: [PATCH 1/5] Upgrade Wicket version (#102) Is a drop in replacement according to https://wicket.apache.org/news/2025/01/24/wicket-10.4.0-released.html#upgrading-from-earlier-versions Fixes #100 Reviewed-on: https://gitea.dsv.su.se/DMC/scipro/pulls/102 Reviewed-by: Nico Athanassiadis <nico@dsv.su.se> Co-authored-by: Andreas Svanberg <andreass@dsv.su.se> Co-committed-by: Andreas Svanberg <andreass@dsv.su.se> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3e5972cbae..42018f99dc 100755 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ <!-- Dependency versions --> <slf4j.version>2.0.7</slf4j.version> <log4j2.version>2.20.0</log4j2.version> - <wicket.version>10.1.0</wicket.version> + <wicket.version>10.4.0</wicket.version> <!-- See https://hibernate.org/orm/releases/ for which version Hibernate implements --> <jakarta.persistence-api.version>3.1.0</jakarta.persistence-api.version> From 219c312441eeeba79df4b7295d9fd63542b65cd1 Mon Sep 17 00:00:00 2001 From: Andreas Svanberg <andreass@dsv.su.se> Date: Fri, 7 Feb 2025 07:50:02 +0100 Subject: [PATCH 2/5] Fix localizer warning on the finishing up tab for each author (#101) Fixes #48 The `getReflectionText` method was calling `getString` when no reflection has been submitted. This is not a relevant case for the editing form since it can not be accessed when there is no reflection. Inlined the method call and removed the non-submitted case, the default will be an empty string. ## How to test 1. Log in as a supervisor 2. Open a project that has a Daisy connection (`identifier`is non-null on the `Project`) 3. Go to the "Finishing up" tab 4. Go to the tab for the author with no reflection submitted 5. See that no warning is logged Co-authored-by: Nico Athanassiadis <nico@dsv.su.se> Reviewed-on: https://gitea.dsv.su.se/DMC/scipro/pulls/101 Reviewed-by: Nico Athanassiadis <nico@dsv.su.se> Co-authored-by: Andreas Svanberg <andreass@dsv.su.se> Co-committed-by: Andreas Svanberg <andreass@dsv.su.se> --- .../su/dsv/scipro/grading/ReflectionModalBodyPanel.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/view/src/main/java/se/su/dsv/scipro/grading/ReflectionModalBodyPanel.java b/view/src/main/java/se/su/dsv/scipro/grading/ReflectionModalBodyPanel.java index 986d509685..a7e48a1f1c 100644 --- a/view/src/main/java/se/su/dsv/scipro/grading/ReflectionModalBodyPanel.java +++ b/view/src/main/java/se/su/dsv/scipro/grading/ReflectionModalBodyPanel.java @@ -178,7 +178,13 @@ class ReflectionModalBodyPanel extends Panel { public SupervisorEditReflectionForm(String id, IModel<Reflection> reflectionModel) { super(id, reflectionModel); - IModel<String> reflectionTextModel = new Model<>(getReflectionText(reflectionModel.getObject())); + IModel<String> reflectionTextModel = new Model<>(); + Reflection reflection = reflectionModel.getObject(); + if (reflection instanceof Reflection.Submitted submitted) { + reflectionTextModel.setObject(submitted.reflection()); + } else if (reflection instanceof Reflection.ImprovementsNeeded improvementsNeeded) { + reflectionTextModel.setObject(improvementsNeeded.oldReflection()); + } TextArea<String> reflectionTextArea = new TextArea<>("reflection", reflectionTextModel); reflectionTextArea.setRequired(true); From 304d0431c14f2b4808716122958c998cdb7dce68 Mon Sep 17 00:00:00 2001 From: Nico Athanassiadis <nico@dsv.su.se> Date: Wed, 12 Feb 2025 11:07:53 +0100 Subject: [PATCH 3/5] Deadline visible in "Rough draft approval" page (#106) 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 #99 Reviewed-on: https://gitea.dsv.su.se/DMC/scipro/pulls/106 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> --- compose-branch-deploy.yaml | 21 ++++++ .../se/su/dsv/scipro/DataInitializer.java | 67 ++++++++++++++++++- .../FinalSeminarApprovalProcessPanel.html | 1 + .../FinalSeminarApprovalProcessPanel.java | 1 + .../FinalSeminarApprovalProcessPanelTest.java | 7 ++ .../resources/application-branch.properties | 8 +-- 6 files changed, 99 insertions(+), 6 deletions(-) diff --git a/compose-branch-deploy.yaml b/compose-branch-deploy.yaml index aba04bbb51..05ba4bd181 100644 --- a/compose-branch-deploy.yaml +++ b/compose-branch-deploy.yaml @@ -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 diff --git a/core/src/main/java/se/su/dsv/scipro/DataInitializer.java b/core/src/main/java/se/su/dsv/scipro/DataInitializer.java index 85a1f413a7..380176606b 100644 --- a/core/src/main/java/se/su/dsv/scipro/DataInitializer.java +++ b/core/src/main/java/se/su/dsv/scipro/DataInitializer.java @@ -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())); + } + } } diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanel.html b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanel.html index dfbda44988..b67dc4bcbb 100644 --- a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanel.html +++ b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanel.html @@ -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> diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanel.java b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanel.java index 00ba26aa74..6781c946d9 100644 --- a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanel.java +++ b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanel.java @@ -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", diff --git a/view/src/test/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanelTest.java b/view/src/test/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanelTest.java index 35269ebf7a..753f2db147 100644 --- a/view/src/test/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanelTest.java +++ b/view/src/test/java/se/su/dsv/scipro/supervisor/panels/FinalSeminarApprovalProcessPanelTest.java @@ -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(); diff --git a/war/src/main/resources/application-branch.properties b/war/src/main/resources/application-branch.properties index 0d6cb9b213..47d660c18a 100644 --- a/war/src/main/resources/application-branch.properties +++ b/war/src/main/resources/application-branch.properties @@ -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 From 08e1b785ca439a27a68eb925470debbdff41a06a Mon Sep 17 00:00:00 2001 From: Andreas Svanberg <andreass@dsv.su.se> Date: Wed, 12 Feb 2025 13:28:14 +0100 Subject: [PATCH 4/5] Fix Docker build due to missing json-smart version (#107) Co-authored-by: Andreas Svanberg <andreass@dsv.su.se> Co-committed-by: Andreas Svanberg <andreass@dsv.su.se> --- Dockerfile | 7 ------- war/pom.xml | 41 ----------------------------------------- 2 files changed, 48 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9212410a58..ac53fd07f3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,12 +13,6 @@ COPY view/pom.xml view/pom.xml COPY war/pom.xml war/pom.xml COPY daisy-integration/pom.xml daisy-integration/pom.xml -# Download dependencies in a separate layer to allow caching for future builds -RUN ./mvnw dependency:go-offline \ - --batch-mode \ - --define includeScope=compile \ - --activate-profiles docker-dependencies - COPY api/src/ api/src/ COPY core/src/ core/src/ COPY view/src/ view/src/ @@ -26,7 +20,6 @@ COPY war/src/ war/src/ COPY daisy-integration/src/ daisy-integration/src/ RUN ./mvnw package \ - --offline \ --define skipTests \ --activate-profiles branch,DEV \ --define skip.npm \ diff --git a/war/pom.xml b/war/pom.xml index 19e7317b23..c1dd889587 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -140,46 +140,5 @@ <spring.profile.active>branch</spring.profile.active> </properties> </profile> - <profile> - <id>docker-dependencies</id> - <!-- - Some dependencies are not discovered by default when running dependency:go-offline. - They are added here manually to allow Docker build layers to be cached properly. - --> - <dependencies> - <dependency> - <groupId>org.jboss.logging</groupId> - <artifactId>jboss-logging</artifactId> - </dependency> - <dependency> - <groupId>com.fasterxml</groupId> - <artifactId>classmate</artifactId> - </dependency> - <dependency> - <groupId>net.bytebuddy</groupId> - <artifactId>byte-buddy-agent</artifactId> - </dependency> - <dependency> - <groupId>com.querydsl</groupId> - <artifactId>querydsl-apt</artifactId> - <version>${querydsl.version}</version> - <classifier>jakarta</classifier> - </dependency> - <dependency> - <groupId>org.assertj</groupId> - <artifactId>assertj-core</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>net.minidev</groupId> - <artifactId>json-smart</artifactId> - </dependency> - <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest-core</artifactId> - <scope>test</scope> - </dependency> - </dependencies> - </profile> </profiles> </project> From b9f7dd5a49aeebd64a5f44b66ac0775901550476 Mon Sep 17 00:00:00 2001 From: Andreas Svanberg <andreass@dsv.su.se> Date: Thu, 13 Feb 2025 09:59:33 +0100 Subject: [PATCH 5/5] Update supervisor's idea table immediately upon scheduling a first meeting (#105) Before, after scheduling a first meeting, they had to refresh the entire page to show the information in the table. Fixes #82 Reviewed-on: https://gitea.dsv.su.se/DMC/scipro/pulls/105 Reviewed-by: Nico Athanassiadis <nico@dsv.su.se> --- .../se/su/dsv/scipro/DataInitializer.java | 31 +++++++++++++++++-- .../firstmeeting/FirstMeetingPanel.java | 6 +++- .../scipro/match/SupervisorMyIdeasPanel.java | 25 +++++++-------- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/se/su/dsv/scipro/DataInitializer.java b/core/src/main/java/se/su/dsv/scipro/DataInitializer.java index 380176606b..7807205f64 100644 --- a/core/src/main/java/se/su/dsv/scipro/DataInitializer.java +++ b/core/src/main/java/se/su/dsv/scipro/DataInitializer.java @@ -14,6 +14,8 @@ 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.Idea; +import se.su.dsv.scipro.match.IdeaService; import se.su.dsv.scipro.match.Keyword; import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate; @@ -28,6 +30,7 @@ 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.*; +import se.su.dsv.scipro.util.Pair; public class DataInitializer implements Lifecycle { @@ -42,6 +45,9 @@ public class DataInitializer implements Lifecycle { @Inject private PasswordService passwordService; + @Inject + private IdeaService ideaService; + @Inject private MilestoneActivityTemplateService milestoneActivityTemplateService; @@ -83,6 +89,8 @@ public class DataInitializer implements Lifecycle { private Set<ResearchArea> researchAreas; private Long researchAreaId = RESEARCH_AREA_ID; private Set<Language> languages; + private ApplicationPeriod applicationPeriod; + private Keyword keyword1; private ResearchArea researchArea1; private ResearchArea researchArea2; private ProjectType masterClass; @@ -101,6 +109,7 @@ public class DataInitializer implements Lifecycle { createKeywordsIfNotDone(); createMilestonesIfNotDone(); createUsers(); + createMatchedIdea(); createProjects(); createRoughDraftApproval(); } @@ -127,18 +136,18 @@ public class DataInitializer implements Lifecycle { } private void createApplicationPeriodIfNotDone() { - ApplicationPeriod applicationPeriod = new ApplicationPeriod("HT 2014"); + applicationPeriod = new ApplicationPeriod("HT 2014"); applicationPeriod.setStartDate(LocalDate.now().minusDays(APPLICATION_PERIOD_START_MINUS_DAYS)); applicationPeriod.setEndDate(LocalDate.now().plusDays(APPLICATION_PERIOD_END_PLUS_DAYS)); applicationPeriod.setCourseStartDate(LocalDate.now().plusDays(APPLICATION_PERIOD_COURSE_START_PLUS_DAYS)); applicationPeriod.setCourseStartTime(LocalTime.of(8, 0)); applicationPeriod = save(applicationPeriod); - applicationPeriod.setProjectTypes(new HashSet<>(Collections.singletonList(bachelorClass))); + applicationPeriod.setProjectTypes(new HashSet<>(Set.of(bachelorClass, masterClass))); save(applicationPeriod); } private void createKeywordsIfNotDone() { - Keyword keyword1 = new Keyword("IT"); + keyword1 = new Keyword("IT"); keyword1.addResearchArea(researchArea1); keyword1.addResearchArea(researchArea2); save(keyword1); @@ -273,6 +282,22 @@ public class DataInitializer implements Lifecycle { return u; } + private void createMatchedIdea() { + Idea idea = new Idea(); + idea.setApplicationPeriod(applicationPeriod); + idea.setType(Idea.Type.SUPERVISOR); + idea.setProjectType(masterClass); + idea.setTitle("Idea without first meeting"); + idea.setDescription("Explore the deep sea"); + idea.setPrerequisites("Diving experience"); + idea.setResearchArea(researchArea1); + idea.setPublished(true); + Idea saved = ideaService.saveSupervisorIdea(idea, eve_employee, new ArrayList<>(Set.of(keyword1)), true); + Pair<Boolean, String> validated = ideaService.validateAdminAddAuthors(saved, Set.of(sid_student)); + assert validated.getHead(); + ideaService.setAuthors(saved, Set.of(sid_student), eve_employee); + } + private void createGradingCriterionTemplateIfNotDone() { save(getBachelorTemplate()); save(getMasterTemplate()); diff --git a/view/src/main/java/se/su/dsv/scipro/firstmeeting/FirstMeetingPanel.java b/view/src/main/java/se/su/dsv/scipro/firstmeeting/FirstMeetingPanel.java index c7b62f64cd..3158294d42 100644 --- a/view/src/main/java/se/su/dsv/scipro/firstmeeting/FirstMeetingPanel.java +++ b/view/src/main/java/se/su/dsv/scipro/firstmeeting/FirstMeetingPanel.java @@ -169,7 +169,11 @@ public class FirstMeetingPanel extends GenericPanel<Idea> { } private void saveAndNotify() { - firstMeetingRepository.save(getModelObject()); + FirstMeeting saved = firstMeetingRepository.save(getModelObject()); + // After saving the first meeting we have to populate it on the already loaded idea to + // make sure that other places that want to render the first meeting get the correct data. + // An alternative would be to detach the idea model to force a database refresh. + FirstMeetingPanel.this.getModelObject().setFirstMeeting(saved); NotificationSource source = new NotificationSource(); String date = dateService.format(getModelObject().getFirstMeetingDate(), DateStyle.DATETIME); String room = getModelObject().getRoom(); diff --git a/view/src/main/java/se/su/dsv/scipro/match/SupervisorMyIdeasPanel.java b/view/src/main/java/se/su/dsv/scipro/match/SupervisorMyIdeasPanel.java index cd59b023bf..f59bd4ac49 100755 --- a/view/src/main/java/se/su/dsv/scipro/match/SupervisorMyIdeasPanel.java +++ b/view/src/main/java/se/su/dsv/scipro/match/SupervisorMyIdeasPanel.java @@ -337,29 +337,26 @@ public class SupervisorMyIdeasPanel extends Panel { if (idea.getMatch() == null) { return "-"; } - switch (idea.getMatchStatus()) { - case UNMATCHED: - return getString("status.unmatched"); - case COMPLETED: - return getString("status.completed"); - case INACTIVE: - return getString("status.inactive"); - case MATCHED: + return switch (idea.getMatchStatus()) { + case UNMATCHED -> getString("status.unmatched"); + case COMPLETED -> getString("status.completed"); + case INACTIVE -> getString("status.inactive"); + case MATCHED -> { if (applicationPeriodService.courseStartHasPassed(idea.getApplicationPeriod())) { if (idea.isExported()) { if (idea.wasExportSuccessful()) { - return getString("status.project.created"); + yield getString("status.project.created"); } else { - return getString("status.export.failed"); + yield getString("status.export.failed"); } } else { - return getString("status.awaiting.project.creation"); + yield getString("status.awaiting.project.creation"); } } else { - return getString("status.awaiting.course.start", Model.of(idea.getApplicationPeriod())); + yield getString("status.awaiting.course.start", Model.of(idea.getApplicationPeriod())); } - } - return "-"; // can't happen + } + }; } }; }