diff --git a/core/src/main/java/modules/CoreModule.java b/core/src/main/java/modules/CoreModule.java index cb2c500685..075c6e9ed8 100644 --- a/core/src/main/java/modules/CoreModule.java +++ b/core/src/main/java/modules/CoreModule.java @@ -48,6 +48,7 @@ import se.su.dsv.scipro.notifications.settings.service.ReceiverConfigurationServ import se.su.dsv.scipro.notifications.settings.service.ReceiverConfigurationServiceImpl; import se.su.dsv.scipro.peer.*; import se.su.dsv.scipro.plagiarism.*; +import se.su.dsv.scipro.project.ProjectNoteService; import se.su.dsv.scipro.project.ProjectPeopleStatisticsService; import se.su.dsv.scipro.project.ProjectPeopleStatisticsServiceImpl; import se.su.dsv.scipro.project.ProjectService; @@ -139,6 +140,7 @@ public class CoreModule extends AbstractModule { bind(FirstMeetingService.class).to(FirstMeetingServiceImpl.class); bind(FinalSeminarCreationSubscribers.class).asEagerSingleton(); bind(ProjectPartnerRepository.class).to(ProjectPartnerRepositoryImpl.class); + bind(ProjectNoteService.class).to(ProjectServiceImpl.class); install(new PlagiarismModule()); install(new NotificationModule()); diff --git a/core/src/main/java/se/su/dsv/scipro/project/Project.java b/core/src/main/java/se/su/dsv/scipro/project/Project.java index 92c82a9014..9429d2cbfc 100755 --- a/core/src/main/java/se/su/dsv/scipro/project/Project.java +++ b/core/src/main/java/se/su/dsv/scipro/project/Project.java @@ -85,6 +85,13 @@ public class Project extends DomainObject { @Enumerated(EnumType.STRING) private Language language; + @ElementCollection(fetch = FetchType.LAZY) + @CollectionTable(name = "project_user_note", joinColumns = @JoinColumn(name = "project_id")) + @Column(name = "note") + @SuppressWarnings("JpaDataSourceORMInspection") // false warning from IntelliJ for the @MapKeyJoinColumn + @MapKeyJoinColumn(name = "user_id") + private Map<User, String> userNotes = new HashMap<>(); + @PrePersist @PreUpdate void cleanTitle() { @@ -94,6 +101,14 @@ public class Project extends DomainObject { title = title.trim(); } + public Map<User, String> getUserNotes() { + return userNotes; + } + + public void setUserNotes(Map<User, String> userNotes) { + this.userNotes = userNotes; + } + public boolean isFinalSeminarRuleExempted() { return finalSeminarRuleExempted; } diff --git a/core/src/main/java/se/su/dsv/scipro/project/ProjectNoteService.java b/core/src/main/java/se/su/dsv/scipro/project/ProjectNoteService.java new file mode 100644 index 0000000000..7ff1657d63 --- /dev/null +++ b/core/src/main/java/se/su/dsv/scipro/project/ProjectNoteService.java @@ -0,0 +1,9 @@ +package se.su.dsv.scipro.project; + +import se.su.dsv.scipro.system.User; + +public interface ProjectNoteService { + String getUserNote(Project project, User user); + + void setUserNote(Project project, User user, String note); +} diff --git a/core/src/main/java/se/su/dsv/scipro/project/ProjectRepo.java b/core/src/main/java/se/su/dsv/scipro/project/ProjectRepo.java index 69dcda672d..f27da7b94a 100755 --- a/core/src/main/java/se/su/dsv/scipro/project/ProjectRepo.java +++ b/core/src/main/java/se/su/dsv/scipro/project/ProjectRepo.java @@ -11,4 +11,8 @@ import java.util.List; @Transactional public interface ProjectRepo extends JpaRepository<Project, Long>, QueryDslPredicateExecutor<Project> { List<User> findMultipleAuthors(Collection<Project> projects); + + String getUserNoteForProject(Project project, User user); + + void setUserNoteForProject(Project project, User user, String note); } \ No newline at end of file diff --git a/core/src/main/java/se/su/dsv/scipro/project/ProjectRepoImpl.java b/core/src/main/java/se/su/dsv/scipro/project/ProjectRepoImpl.java index 627af554ec..f8dfb462bd 100644 --- a/core/src/main/java/se/su/dsv/scipro/project/ProjectRepoImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/project/ProjectRepoImpl.java @@ -1,5 +1,6 @@ package se.su.dsv.scipro.project; +import com.google.inject.persist.Transactional; import se.su.dsv.scipro.system.GenericRepo; import se.su.dsv.scipro.system.User; @@ -30,4 +31,16 @@ public class ProjectRepoImpl extends GenericRepo<Project, Long> implements Proje query.setParameter("projects", projects); return query.getResultList(); } + + @Override + public String getUserNoteForProject(Project project, User user) { + return project.getUserNotes().get(user); + } + + @Override + @Transactional + public void setUserNoteForProject(Project project, User user, String note) { + project.getUserNotes().put(user, note); + save(project); + } } diff --git a/core/src/main/java/se/su/dsv/scipro/project/ProjectServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/project/ProjectServiceImpl.java index c2f8e83098..2ba2a6a436 100755 --- a/core/src/main/java/se/su/dsv/scipro/project/ProjectServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/project/ProjectServiceImpl.java @@ -22,7 +22,7 @@ import java.time.Duration; import java.time.Instant; import java.util.*; -public class ProjectServiceImpl extends AbstractServiceImpl<Project, Long> implements ProjectService { +public class ProjectServiceImpl extends AbstractServiceImpl<Project, Long> implements ProjectService, ProjectNoteService { public static final int MIN_TITLE_LENGTH = 3; private final ProjectRepo projectRepo; @@ -175,6 +175,16 @@ public class ProjectServiceImpl extends AbstractServiceImpl<Project, Long> imple return completed; } + @Override + public String getUserNote(Project project, User user) { + return projectRepo.getUserNoteForProject(project, user); + } + + @Override + public void setUserNote(Project project, User user, String note) { + projectRepo.setUserNoteForProject(project, user, note); + } + @Override public List<Project> findAll(Filter filter, Pageable pageable) { return findAll(toPredicate(filter), pageable); diff --git a/core/src/main/java/se/su/dsv/scipro/settings/dataobjects/SupervisorProjectNoteDisplay.java b/core/src/main/java/se/su/dsv/scipro/settings/dataobjects/SupervisorProjectNoteDisplay.java new file mode 100644 index 0000000000..1a6c45d452 --- /dev/null +++ b/core/src/main/java/se/su/dsv/scipro/settings/dataobjects/SupervisorProjectNoteDisplay.java @@ -0,0 +1,5 @@ +package se.su.dsv.scipro.settings.dataobjects; + +public enum SupervisorProjectNoteDisplay { + COMPACT, FULL +} diff --git a/core/src/main/java/se/su/dsv/scipro/settings/dataobjects/UserProfile.java b/core/src/main/java/se/su/dsv/scipro/settings/dataobjects/UserProfile.java index 8cf7d44e31..ac863a2afa 100644 --- a/core/src/main/java/se/su/dsv/scipro/settings/dataobjects/UserProfile.java +++ b/core/src/main/java/se/su/dsv/scipro/settings/dataobjects/UserProfile.java @@ -58,6 +58,11 @@ public class UserProfile extends DomainObject { @Enumerated(EnumType.STRING) private Roles selectedRole; + @Basic + @Enumerated(EnumType.STRING) + @Column(name = "supervisor_project_note_display") + private SupervisorProjectNoteDisplay supervisorProjectNoteDisplay = SupervisorProjectNoteDisplay.COMPACT; + @Override public Long getId() { return this.id; @@ -147,6 +152,14 @@ public class UserProfile extends DomainObject { this.selectedRole = selectedRole; } + public SupervisorProjectNoteDisplay getSupervisorProjectNoteDisplay() { + return supervisorProjectNoteDisplay; + } + + public void setSupervisorProjectNoteDisplay(SupervisorProjectNoteDisplay supervisorProjectNoteDisplay) { + this.supervisorProjectNoteDisplay = supervisorProjectNoteDisplay; + } + @Override public String toString() { return "UserProfile(id=" + this.getId() + ", user=" + this.getUser() + ", skypeId=" + this.getSkypeId() + ", phoneNumber=" + this.getPhoneNumber() + ", otherInfo=" + this.getOtherInfo() + ", mailCompilation=" + this.isMailCompilation() + ", defaultProjectStatusFilter=" + this.getDefaultProjectStatusFilter() + ", defaultProjectTeamMemberRolesFilter=" + this.getDefaultProjectTeamMemberRolesFilter() + ", defaultSupervisorFilter=" + this.isDefaultSupervisorFilter() + ", defaultProjectTypeFilter=" + this.getDefaultProjectTypeFilter() + ", selectedRole=" + this.getSelectedRole() + ")"; diff --git a/core/src/main/resources/db/migration/V388__user_notes_for_projects.sql b/core/src/main/resources/db/migration/V388__user_notes_for_projects.sql new file mode 100644 index 0000000000..334caad59b --- /dev/null +++ b/core/src/main/resources/db/migration/V388__user_notes_for_projects.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS `project_user_note` ( + `project_id` bigint NOT NULL, + `user_id` bigint NOT NULL, + `note` text NULL, + PRIMARY KEY (`project_id`, `user_id`), + CONSTRAINT `FK_project_user_note_project` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `FK_project_user_note_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +); + +ALTER TABLE `user_profile` + ADD COLUMN `supervisor_project_note_display` VARCHAR(15) NOT NULL DEFAULT 'COMPACT'; diff --git a/view/src/main/java/se/su/dsv/scipro/components/MaxLengthLabel.java b/view/src/main/java/se/su/dsv/scipro/components/MaxLengthLabel.java new file mode 100644 index 0000000000..edfdd48ab9 --- /dev/null +++ b/view/src/main/java/se/su/dsv/scipro/components/MaxLengthLabel.java @@ -0,0 +1,37 @@ +package se.su.dsv.scipro.components; + +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.model.IModel; +import org.apache.wicket.util.convert.IConverter; + +import java.util.Locale; + +public class MaxLengthLabel extends Label { + private final IModel<Integer> maxLengthModel; + + public MaxLengthLabel(String id, IModel<String> dataModel, IModel<Integer> maxLength) { + super(id, dataModel); + this.maxLengthModel = maxLength; + } + + @Override + protected IConverter<?> createConverter(Class<?> type) { + return new MaxLengthConverter(); + } + + private class MaxLengthConverter implements IConverter<String> { + @Override + public String convertToObject(String s, Locale locale) { + return s; + } + + @Override + public String convertToString(String o, Locale locale) { + Integer maxLength = maxLengthModel.getObject(); + if (o.length() > maxLength) { + return o.substring(0, maxLength) + "..."; + } + return o; + } + } +} diff --git a/view/src/main/java/se/su/dsv/scipro/components/ModalWindowPlus.java b/view/src/main/java/se/su/dsv/scipro/components/ModalWindowPlus.java index 9faa92158d..0eca546462 100644 --- a/view/src/main/java/se/su/dsv/scipro/components/ModalWindowPlus.java +++ b/view/src/main/java/se/su/dsv/scipro/components/ModalWindowPlus.java @@ -1,6 +1,7 @@ package se.su.dsv.scipro.components; import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxEventBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.ComponentTag; @@ -9,6 +10,7 @@ import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; +import org.danekja.java.util.function.serializable.SerializableConsumer; import java.util.function.Function; @@ -83,4 +85,13 @@ public class ModalWindowPlus extends Panel { component.setOutputMarkupPlaceholderTag(true); replace(component); } + + public void onClose(SerializableConsumer<AjaxRequestTarget> onClose) { + add(new AjaxEventBehavior("hidden.bs.modal") { + @Override + protected void onEvent(AjaxRequestTarget target) { + onClose.accept(target); + } + }); + } } diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn$ViewAndEditNoteCellPanel.html b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn$ViewAndEditNoteCellPanel.html new file mode 100644 index 0000000000..7a5e924096 --- /dev/null +++ b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn$ViewAndEditNoteCellPanel.html @@ -0,0 +1,11 @@ +<?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:panel> + <div wicket:id="edit_note_modal"></div> + <span wicket:id="shortened_note"></span> + <wicket:container wicket:id="full_note"></wicket:container> + <a wicket:id="view_note"><wicket:message key="note.view.edit"/></a> +</wicket:panel> +</body> +</html> \ No newline at end of file diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn$ViewAndEditNoteCellPanel.utf8.properties b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn$ViewAndEditNoteCellPanel.utf8.properties new file mode 100644 index 0000000000..5f31ea7d1c --- /dev/null +++ b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn$ViewAndEditNoteCellPanel.utf8.properties @@ -0,0 +1,2 @@ +note.modal.title=View/edit note for ${title} +note.view.edit=View/edit note diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn$ViewAndEditNoteForm.html b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn$ViewAndEditNoteForm.html new file mode 100644 index 0000000000..bf546f6a76 --- /dev/null +++ b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn$ViewAndEditNoteForm.html @@ -0,0 +1,15 @@ +<?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:panel> + <form wicket:id="form"> + <div wicket:id="feedback"></div> + <div class="mb-3"> + <label wicket:for="note" class="sr-only">Note</label> + <textarea wicket:id="note" rows="20" class="form-control"></textarea> + </div> + <button wicket:id="save" type="submit" class="btn btn-primary">Save</button> + </form> +</wicket:panel> +</body> +</html> \ No newline at end of file diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn.java b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn.java new file mode 100644 index 0000000000..b35962f891 --- /dev/null +++ b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/ProjectNoteColumn.java @@ -0,0 +1,129 @@ +package se.su.dsv.scipro.supervisor.panels; + +import jakarta.inject.Inject; +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.extensions.markup.html.repeater.data.grid.ICellPopulator; +import org.apache.wicket.extensions.markup.html.repeater.data.table.export.AbstractExportableColumn; +import org.apache.wicket.feedback.FencedFeedbackPanel; +import org.apache.wicket.injection.Injector; +import org.apache.wicket.markup.html.basic.MultiLineLabel; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.form.TextArea; +import org.apache.wicket.markup.html.panel.GenericPanel; +import org.apache.wicket.markup.repeater.Item; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.StringResourceModel; +import se.su.dsv.scipro.components.LargeModalWindow; +import se.su.dsv.scipro.components.MaxLengthLabel; +import se.su.dsv.scipro.components.ModalWindowPlus; +import se.su.dsv.scipro.project.Project; +import se.su.dsv.scipro.project.ProjectNoteService; +import se.su.dsv.scipro.settings.dataobjects.SupervisorProjectNoteDisplay; +import se.su.dsv.scipro.system.User; + +import java.time.LocalTime; +import java.time.temporal.ChronoUnit; + +public class ProjectNoteColumn extends AbstractExportableColumn<Project, String> { + @Inject + private ProjectNoteService projectNoteService; + + private final IModel<User> user; + private final IModel<SupervisorProjectNoteDisplay> supervisorProjectNoteDisplayModel; + + public ProjectNoteColumn(IModel<String> displayModel, IModel<User> user, + IModel<SupervisorProjectNoteDisplay> supervisorProjectNoteDisplayModel) { + super(displayModel); + Injector.get().inject(this); + this.supervisorProjectNoteDisplayModel = supervisorProjectNoteDisplayModel; + this.user = user; + } + + @Override + public IModel<String> getDataModel(IModel<Project> rowModel) { + return LoadableDetachableModel.of(() -> projectNoteService.getUserNote( + rowModel.getObject(), + user.getObject())); + } + + @Override + public void populateItem( + Item<ICellPopulator<Project>> cellItem, + String componentId, + IModel<Project> rowModel) + { + cellItem.add(new ViewAndEditNoteCellPanel(componentId, rowModel)); + } + + private class ViewAndEditNoteCellPanel extends GenericPanel<Project> { + public ViewAndEditNoteCellPanel(String id, IModel<Project> model) { + super(id, model); + + ModalWindowPlus modal = new LargeModalWindow("edit_note_modal"); + modal.setTitle(new StringResourceModel("note.modal.title", this, model)); + modal.setContent(componentId -> new ViewAndEditNoteForm(componentId, model)); + add(modal); + + setOutputMarkupId(true); + modal.onClose(target -> target.add(this)); + + add(new MaxLengthLabel("shortened_note", getDataModel(model), Model.of(100)) { + @Override + protected void onConfigure() { + super.onConfigure(); + setVisibilityAllowed(supervisorProjectNoteDisplayModel.getObject() == SupervisorProjectNoteDisplay.COMPACT); + } + }); + add(new MultiLineLabel("full_note", getDataModel(model)) { + @Override + protected void onConfigure() { + super.onConfigure(); + setVisibilityAllowed(supervisorProjectNoteDisplayModel.getObject() == SupervisorProjectNoteDisplay.FULL); + } + }); + + AjaxLink<Object> noteLink = new AjaxLink<>("view_note") { + @Override + public void onClick(AjaxRequestTarget target) { + modal.show(target); + } + }; + add(noteLink); + } + } + + private class ViewAndEditNoteForm extends GenericPanel<Project> { + public ViewAndEditNoteForm(String id, IModel<Project> project) { + super(id, project); + + IModel<String> note = getDataModel(project); + + Form<Project> form = new Form<>("form", project) { + @Override + protected void onSubmit() { + projectNoteService.setUserNote( + project.getObject(), + user.getObject(), + note.getObject() + ); + success("Note saved at " + LocalTime.now().truncatedTo(ChronoUnit.SECONDS)); + } + }; + add(form); + + form.add(new FencedFeedbackPanel("feedback", form)); + + form.add(new TextArea<>("note", note)); + form.add(new AjaxSubmitLink("save") { + @Override + protected void onAfterSubmit(AjaxRequestTarget target) { + target.add(form); + } + }); + } + } +} diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.html b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.html index 9b68bf8d79..73ab571f7f 100755 --- a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.html +++ b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.html @@ -31,6 +31,10 @@ </strong> <div wicket:id="projectTypes"></div> </div> + <fieldset class="col-6 col-md-3 col-lg-2"> + <legend>Note</legend> + <div wicket:id="note_display"></div> + </fieldset> </div> </form> </div> diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.java b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.java index e13137a359..e3cab053eb 100755 --- a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.java +++ b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.java @@ -1,6 +1,7 @@ package se.su.dsv.scipro.supervisor.panels; import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder; @@ -15,6 +16,7 @@ import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LambdaModel; +import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.model.Model; import se.su.dsv.scipro.components.*; import se.su.dsv.scipro.components.datatables.MultipleUsersColumn; @@ -30,6 +32,7 @@ import se.su.dsv.scipro.project.ProjectService; import se.su.dsv.scipro.project.ProjectStatus; import se.su.dsv.scipro.project.ProjectTeamMemberRoles; import se.su.dsv.scipro.session.SciProSession; +import se.su.dsv.scipro.settings.dataobjects.SupervisorProjectNoteDisplay; import se.su.dsv.scipro.settings.dataobjects.UserProfile; import se.su.dsv.scipro.springdata.services.UserProfileService; import se.su.dsv.scipro.system.ProjectType; @@ -62,6 +65,7 @@ public class SupervisorMyProjectsPanel extends Panel { private ExportableDataPanel dataPanel; private ProjectService.Filter filter = new ProjectService.Filter(); + private IModel<SupervisorProjectNoteDisplay> supervisorProjectNoteDisplayModel = new Model<>(); public SupervisorMyProjectsPanel(String id) { super(id); @@ -90,6 +94,7 @@ public class SupervisorMyProjectsPanel extends Panel { return new ListAdapterModel<>(rowModel.map(Project::getProjectParticipants)); } }); + columns.add(new ProjectNoteColumn(Model.of("Note"), LoadableDetachableModel.of(this::currentUser), supervisorProjectNoteDisplayModel)); columns.add(new UserColumn<>(Model.of("Head supervisor"), "headSupervisor.fullName", Project::getHeadSupervisor)); return columns; } @@ -112,6 +117,7 @@ public class SupervisorMyProjectsPanel extends Panel { filter.setRoles(userProfile.getDefaultProjectTeamMemberRolesFilter()); filter.setFilterSupervisor(userProfile.isDefaultSupervisorFilter()); filter.setProjectTypes(userProfile.getDefaultProjectTypeFilter()); + supervisorProjectNoteDisplayModel.setObject(userProfile.getSupervisorProjectNoteDisplay()); } private User currentUser() { @@ -155,6 +161,19 @@ public class SupervisorMyProjectsPanel extends Panel { updateProfileWithCurrentFilter(); } }); + BootstrapRadioChoice<SupervisorProjectNoteDisplay> noteDisplay = new BootstrapRadioChoice<>( + "note_display", + supervisorProjectNoteDisplayModel, + List.of(SupervisorProjectNoteDisplay.values()), + new EnumChoiceRenderer<>(this)); + noteDisplay.add(new AjaxFormChoiceComponentUpdatingBehavior() { + @Override + public void onUpdate(AjaxRequestTarget target) { + target.add(dataPanel); + updateProfileWithCurrentFilter(); + } + }); + add(noteDisplay); } private void updateProfileWithCurrentFilter() { @@ -163,6 +182,7 @@ public class SupervisorMyProjectsPanel extends Panel { userProfile.setDefaultProjectTeamMemberRolesFilter(filter.getRoles()); userProfile.setDefaultSupervisorFilter(filter.isFilterSupervisor()); userProfile.setDefaultProjectTypeFilter(filter.getProjectTypes()); + userProfile.setSupervisorProjectNoteDisplay(supervisorProjectNoteDisplayModel.getObject()); profileService.save(userProfile); } } diff --git a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.utf8.properties b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.utf8.properties index 8c2d03baf2..17f454ad8c 100644 --- a/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.utf8.properties +++ b/view/src/main/java/se/su/dsv/scipro/supervisor/panels/SupervisorMyProjectsPanel.utf8.properties @@ -9,3 +9,6 @@ ProjectTeamMemberRoles.CO_SUPERVISOR= Co-Supervisor ProjectStatus.ACTIVE= Active ProjectStatus.INACTIVE= Inactive ProjectStatus.COMPLETED= Completed + +SupervisorProjectNoteDisplay.COMPACT=Compact +SupervisorProjectNoteDisplay.FULL=Full diff --git a/view/src/test/java/se/su/dsv/scipro/SciProTest.java b/view/src/test/java/se/su/dsv/scipro/SciProTest.java index 9a400e0086..ee39fc8b41 100755 --- a/view/src/test/java/se/su/dsv/scipro/SciProTest.java +++ b/view/src/test/java/se/su/dsv/scipro/SciProTest.java @@ -87,6 +87,7 @@ import se.su.dsv.scipro.peer.PerformReviewService; import se.su.dsv.scipro.plagiarism.PlagiarismControl; import se.su.dsv.scipro.plagiarism.urkund.UrkundService; import se.su.dsv.scipro.profiles.CurrentProfile; +import se.su.dsv.scipro.project.ProjectNoteService; import se.su.dsv.scipro.project.ProjectPeopleStatisticsService; import se.su.dsv.scipro.project.ProjectService; import se.su.dsv.scipro.project.pages.ProjectStartPage; @@ -355,6 +356,8 @@ public abstract class SciProTest { protected ExaminerTimelineService examinerTimelineService; @Mock protected NationalSubjectCategoryService nationalSubjectCategoryService; + @Mock + protected ProjectNoteService projectNoteService; protected WicketTester tester;