Update supervisor's idea table immediately upon scheduling a first meeting #105

Merged
ansv7779 merged 4 commits from first-meeting-feedback into develop 2025-02-13 09:59:34 +01:00
3 changed files with 44 additions and 18 deletions

View File

@ -14,6 +14,8 @@ import java.util.function.Function;
import se.su.dsv.scipro.checklist.ChecklistCategory; import se.su.dsv.scipro.checklist.ChecklistCategory;
import se.su.dsv.scipro.file.FileUpload; import se.su.dsv.scipro.file.FileUpload;
import se.su.dsv.scipro.match.ApplicationPeriod; 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.match.Keyword;
import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate;
import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate; 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.reviewing.RoughDraftApprovalService;
import se.su.dsv.scipro.security.auth.roles.Roles; import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.system.*; import se.su.dsv.scipro.system.*;
import se.su.dsv.scipro.util.Pair;
public class DataInitializer implements Lifecycle { public class DataInitializer implements Lifecycle {
@ -42,6 +45,9 @@ public class DataInitializer implements Lifecycle {
@Inject @Inject
private PasswordService passwordService; private PasswordService passwordService;
@Inject
private IdeaService ideaService;
@Inject @Inject
private MilestoneActivityTemplateService milestoneActivityTemplateService; private MilestoneActivityTemplateService milestoneActivityTemplateService;
@ -83,6 +89,8 @@ public class DataInitializer implements Lifecycle {
private Set<ResearchArea> researchAreas; private Set<ResearchArea> researchAreas;
private Long researchAreaId = RESEARCH_AREA_ID; private Long researchAreaId = RESEARCH_AREA_ID;
private Set<Language> languages; private Set<Language> languages;
private ApplicationPeriod applicationPeriod;
private Keyword keyword1;
private ResearchArea researchArea1; private ResearchArea researchArea1;
private ResearchArea researchArea2; private ResearchArea researchArea2;
private ProjectType masterClass; private ProjectType masterClass;
@ -101,6 +109,7 @@ public class DataInitializer implements Lifecycle {
createKeywordsIfNotDone(); createKeywordsIfNotDone();
createMilestonesIfNotDone(); createMilestonesIfNotDone();
createUsers(); createUsers();
createMatchedIdea();
createProjects(); createProjects();
createRoughDraftApproval(); createRoughDraftApproval();
} }
@ -127,18 +136,18 @@ public class DataInitializer implements Lifecycle {
} }
private void createApplicationPeriodIfNotDone() { 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.setStartDate(LocalDate.now().minusDays(APPLICATION_PERIOD_START_MINUS_DAYS));
applicationPeriod.setEndDate(LocalDate.now().plusDays(APPLICATION_PERIOD_END_PLUS_DAYS)); applicationPeriod.setEndDate(LocalDate.now().plusDays(APPLICATION_PERIOD_END_PLUS_DAYS));
applicationPeriod.setCourseStartDate(LocalDate.now().plusDays(APPLICATION_PERIOD_COURSE_START_PLUS_DAYS)); applicationPeriod.setCourseStartDate(LocalDate.now().plusDays(APPLICATION_PERIOD_COURSE_START_PLUS_DAYS));
applicationPeriod.setCourseStartTime(LocalTime.of(8, 0)); applicationPeriod.setCourseStartTime(LocalTime.of(8, 0));
applicationPeriod = save(applicationPeriod); applicationPeriod = save(applicationPeriod);
applicationPeriod.setProjectTypes(new HashSet<>(Collections.singletonList(bachelorClass))); applicationPeriod.setProjectTypes(new HashSet<>(Set.of(bachelorClass, masterClass)));
save(applicationPeriod); save(applicationPeriod);
} }
private void createKeywordsIfNotDone() { private void createKeywordsIfNotDone() {
Keyword keyword1 = new Keyword("IT"); keyword1 = new Keyword("IT");
keyword1.addResearchArea(researchArea1); keyword1.addResearchArea(researchArea1);
keyword1.addResearchArea(researchArea2); keyword1.addResearchArea(researchArea2);
save(keyword1); save(keyword1);
@ -273,6 +282,22 @@ public class DataInitializer implements Lifecycle {
return u; 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() { private void createGradingCriterionTemplateIfNotDone() {
save(getBachelorTemplate()); save(getBachelorTemplate());
save(getMasterTemplate()); save(getMasterTemplate());

View File

@ -169,7 +169,11 @@ public class FirstMeetingPanel extends GenericPanel<Idea> {
} }
private void saveAndNotify() { 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.
niat8586 marked this conversation as resolved
Review

Can the first meeting be edited from other users or from other places?

If it can maybe we should enforce a database refresh as per your comment of an alternative method.

If not then this is good in that we don't need to do a database refresh on the view we are in.

Can the first meeting be edited from other users or from other places? If it can maybe we should enforce a database refresh as per your comment of an alternative method. If not then this is good in that we don't need to do a database refresh on the view we are in.
Review

Yes it can be edited from other places (but always by the supervisor). However, I do not see how that is relevant? The issue is the table not updating when using the modal dialog to schedule a meeting.

Do you want the page with the table to update itself based on what happens on a different page if it happened to be open simultaneously?

Yes it can be edited from other places (but always by the supervisor). However, I do not see how that is relevant? The issue is the table not updating when using the modal dialog to schedule a meeting. Do you want the page with the table to update itself based on what happens on a different page if it happened to be open simultaneously?
Review

We discussed yesterday (2025-02-11) in person, and I am happy with the resolution we got to. So we keep it as is.

We discussed yesterday (2025-02-11) in person, and I am happy with the resolution we got to. So we keep it as is.
FirstMeetingPanel.this.getModelObject().setFirstMeeting(saved);
NotificationSource source = new NotificationSource(); NotificationSource source = new NotificationSource();
String date = dateService.format(getModelObject().getFirstMeetingDate(), DateStyle.DATETIME); String date = dateService.format(getModelObject().getFirstMeetingDate(), DateStyle.DATETIME);
String room = getModelObject().getRoom(); String room = getModelObject().getRoom();

View File

@ -337,29 +337,26 @@ public class SupervisorMyIdeasPanel extends Panel {
if (idea.getMatch() == null) { if (idea.getMatch() == null) {
return "-"; return "-";
} }
switch (idea.getMatchStatus()) { return switch (idea.getMatchStatus()) {
case UNMATCHED: case UNMATCHED -> getString("status.unmatched");
return getString("status.unmatched"); case COMPLETED -> getString("status.completed");
case COMPLETED: case INACTIVE -> getString("status.inactive");
return getString("status.completed"); case MATCHED -> {
case INACTIVE:
return getString("status.inactive");
case MATCHED:
if (applicationPeriodService.courseStartHasPassed(idea.getApplicationPeriod())) { if (applicationPeriodService.courseStartHasPassed(idea.getApplicationPeriod())) {
if (idea.isExported()) { if (idea.isExported()) {
if (idea.wasExportSuccessful()) { if (idea.wasExportSuccessful()) {
return getString("status.project.created"); yield getString("status.project.created");
} else { } else {
return getString("status.export.failed"); yield getString("status.export.failed");
} }
} else { } else {
return getString("status.awaiting.project.creation"); yield getString("status.awaiting.project.creation");
} }
} else { } 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 };
} }
}; };
} }