From b58a8a2d8b5e105686fe09d4f33b26c9445a94bf Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Mon, 25 Nov 2024 15:20:28 +0100 Subject: [PATCH 01/16] 3470: Show tooltip if there are unread messages * AbstractReadStatePanel is expanded with option to show tooltip. --- .../forum/panels/AbstractReadStatePanel.java | 24 ++++++++++++++++--- .../AbstractReadStatePanel.utf8.properties | 1 + .../panels/SupervisorMyProjectsPanel.java | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.utf8.properties diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java index 25eea67afa..f6344d1afc 100644 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java @@ -11,10 +11,24 @@ import java.util.Optional; public abstract class AbstractReadStatePanel extends Panel { + public static final String TOGGLE = "toggle"; + static final String ICON = "icon"; + + public enum ShowReadStateTooltip { + ENABLED, + DISABLED + } + private final Component icon; + private final ShowReadStateTooltip showReadStateTooltip; public AbstractReadStatePanel(final String id) { + this(id, ShowReadStateTooltip.DISABLED); + } + + public AbstractReadStatePanel(final String id, final ShowReadStateTooltip showReadStateTooltip) { super(id); + this.showReadStateTooltip = showReadStateTooltip; AjaxFallbackLink link = new AjaxFallbackLink<>(TOGGLE) { @Override @@ -35,11 +49,11 @@ public abstract class AbstractReadStatePanel extends Panel { protected abstract boolean isRead(); protected abstract void onFlagClick(final AjaxRequestTarget target); - public static final String TOGGLE = "toggle"; - static final String ICON = "icon"; + public ShowReadStateTooltip getShowReadStateTooltip() { + return showReadStateTooltip; + } private class UpdatingImage extends WebComponent { - public UpdatingImage(String id) { super(id); } @@ -49,6 +63,10 @@ public abstract class AbstractReadStatePanel extends Panel { super.onComponentTag(tag); String state = isRead() ? "read" : "unread"; tag.append("class", state, " "); + + if (getShowReadStateTooltip() == ShowReadStateTooltip.ENABLED && !isRead()) { + tag.put("title", getString("unread.msg")); + } } } } diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.utf8.properties b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.utf8.properties new file mode 100644 index 0000000000..e86f4d6e50 --- /dev/null +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.utf8.properties @@ -0,0 +1 @@ +unread.msg=There are unread messages. \ No newline at end of file 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 e3cab053eb..823db59cde 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 @@ -194,7 +194,7 @@ public class SupervisorMyProjectsPanel extends Panel { @Override public void populateItem(Item> item, String id, IModel projectModel) { - item.add(new AbstractReadStatePanel(id) { + item.add(new AbstractReadStatePanel(id, AbstractReadStatePanel.ShowReadStateTooltip.ENABLED) { @Override protected boolean isRead() { return !projectForumService.hasUnreadThreads( -- 2.39.5 From 499aaaa402a1ad21d7b98026f0497b743762b91e Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Mon, 2 Dec 2024 14:40:43 +0100 Subject: [PATCH 02/16] 3470: Enhance ProjectForumStateColumn of SupervisorMyProjectPanel * it contains 2 components, one with flag, one with number of messages. * since table cell can only contain one component, Wicket Fragment is used. --- .../panels/SupervisorMyProjectsPanel.html | 6 +++ .../panels/SupervisorMyProjectsPanel.java | 49 ++++++++++++++++--- 2 files changed, 49 insertions(+), 6 deletions(-) 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 73ab571f7f..b50ec6da63 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 @@ -41,6 +41,12 @@
+ + + + + + \ No newline at end of file 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 823db59cde..9e1860c856 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,5 +1,6 @@ package se.su.dsv.scipro.supervisor.panels; +import jakarta.inject.Inject; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; @@ -12,13 +13,18 @@ import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvid import org.apache.wicket.markup.html.form.EnumChoiceRenderer; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.LambdaChoiceRenderer; +import org.apache.wicket.markup.html.panel.Fragment; 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.AjaxCheckBoxMultipleChoice; +import se.su.dsv.scipro.components.BootstrapRadioChoice; +import se.su.dsv.scipro.components.ExportableDataPanel; +import se.su.dsv.scipro.components.ListAdapterModel; +import se.su.dsv.scipro.components.TemporalColumn; import se.su.dsv.scipro.components.datatables.MultipleUsersColumn; import se.su.dsv.scipro.components.datatables.UserColumn; import se.su.dsv.scipro.dataproviders.FilteredDataProvider; @@ -27,6 +33,7 @@ import se.su.dsv.scipro.datatables.project.ProjectTitleColumn; import se.su.dsv.scipro.forum.ProjectForumService; import se.su.dsv.scipro.forum.pages.threaded.SupervisorThreadedForumPage; import se.su.dsv.scipro.forum.panels.AbstractReadStatePanel; +import se.su.dsv.scipro.forum.panels.NumberOfMessagesPanel; import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.ProjectService; import se.su.dsv.scipro.project.ProjectStatus; @@ -39,7 +46,6 @@ import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectTypeService; import se.su.dsv.scipro.system.User; -import jakarta.inject.Inject; import java.util.ArrayList; import java.util.List; @@ -194,21 +200,52 @@ public class SupervisorMyProjectsPanel extends Panel { @Override public void populateItem(Item> item, String id, IModel projectModel) { + /* item.add(new AbstractReadStatePanel(id, AbstractReadStatePanel.ShowReadStateTooltip.ENABLED) { @Override protected boolean isRead() { - return !projectForumService.hasUnreadThreads( - projectModel.getObject(), + return !projectForumService.hasUnreadThreads(projectModel.getObject(), SciProSession.get().getUser()); } @Override protected void onFlagClick(AjaxRequestTarget target) { - setResponsePage( - SupervisorThreadedForumPage.class, + setResponsePage(SupervisorThreadedForumPage.class, SupervisorThreadedForumPage.getPageParameters(projectModel.getObject())); } }); + + */ + + + //WebMarkupContainer container = new WebMarkupContainer(id); + //container.setOutputMarkupId(true); +/* + container + */ + //container.add(new NumberOfMessagesPanel("counter")); + + //item.add(container); + // todo: reconsider name of this id, needs to be improved. + + Fragment fragment = new Fragment(id, "parentMarkupId", SupervisorMyProjectsPanel.this); + + fragment.add(new AbstractReadStatePanel("flag", AbstractReadStatePanel.ShowReadStateTooltip.ENABLED) { + @Override + protected boolean isRead() { + return !projectForumService.hasUnreadThreads(projectModel.getObject(), + SciProSession.get().getUser()); + } + + @Override + protected void onFlagClick(AjaxRequestTarget target) { + setResponsePage(SupervisorThreadedForumPage.class, + SupervisorThreadedForumPage.getPageParameters(projectModel.getObject())); + } + }); + fragment.add(new NumberOfMessagesPanel("counter")); + + item.add(fragment); } } } -- 2.39.5 From 2eb7f1bf1488a083501b609fd9808e0c9d86441b Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Mon, 2 Dec 2024 14:43:27 +0100 Subject: [PATCH 03/16] 3470: Write a-element in one line to avoid white spaces: * since this component is put in a table cell, and when there are more than one component in the cell, the white spaces breaks the visual with additional underscore like character. --- .../se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.html b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.html index 7e4d838121..0fb10bd9e4 100644 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.html +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.html @@ -6,9 +6,7 @@ - - - + \ No newline at end of file -- 2.39.5 From 0d612d44eef7792f910246ffb847c5bf1829584b Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Mon, 2 Dec 2024 14:46:03 +0100 Subject: [PATCH 04/16] 3470: Move variable 'icon' from class level to method level: This reduces the visibility of the variable icon, which usually is a good thing. The 'icon' is never accessed anywhere else. --- .../forum/panels/AbstractReadStatePanel.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java index f6344d1afc..13df58ff05 100644 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java @@ -19,7 +19,6 @@ public abstract class AbstractReadStatePanel extends Panel { DISABLED } - private final Component icon; private final ShowReadStateTooltip showReadStateTooltip; public AbstractReadStatePanel(final String id) { @@ -30,6 +29,9 @@ public abstract class AbstractReadStatePanel extends Panel { super(id); this.showReadStateTooltip = showReadStateTooltip; + Component icon = new UpdatingImage(ICON); + icon.setOutputMarkupId(true); + AjaxFallbackLink link = new AjaxFallbackLink<>(TOGGLE) { @Override public void onClick(final Optional target) { @@ -39,20 +41,14 @@ public abstract class AbstractReadStatePanel extends Panel { }); } }; - add(link); - - icon = new UpdatingImage(ICON); - icon.setOutputMarkupId(true); link.add(icon); + + add(link); } protected abstract boolean isRead(); protected abstract void onFlagClick(final AjaxRequestTarget target); - public ShowReadStateTooltip getShowReadStateTooltip() { - return showReadStateTooltip; - } - private class UpdatingImage extends WebComponent { public UpdatingImage(String id) { super(id); @@ -64,7 +60,7 @@ public abstract class AbstractReadStatePanel extends Panel { String state = isRead() ? "read" : "unread"; tag.append("class", state, " "); - if (getShowReadStateTooltip() == ShowReadStateTooltip.ENABLED && !isRead()) { + if (showReadStateTooltip == ShowReadStateTooltip.ENABLED && !isRead()) { tag.put("title", getString("unread.msg")); } } -- 2.39.5 From 552aaade6ed169deb270b6347fd40b31b98aea86 Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Mon, 2 Dec 2024 14:47:46 +0100 Subject: [PATCH 05/16] 3470: Write a method to get unread messages count as POC --- .../su/dsv/scipro/forum/ProjectForumServiceImpl.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java index 1825a16197..878d2c2050 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java @@ -106,6 +106,17 @@ public class ProjectForumServiceImpl implements ProjectForumService { return false; } + public int getUnreadThreadsCount(Project project, User user) { + List threads = getThreads(project); + int count = 0; + for (ProjectThread thread : threads) { + if (!basicForumService.isThreadRead(user, thread.getForumThread())) { + count++; + } + } + return count; + } + @Override public ProjectThread findOne(long threadId) { return projectThreadRepository.findOne(threadId); -- 2.39.5 From 74b2396376e7c2eb1555cc482813d287adc0df3d Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Mon, 2 Dec 2024 14:49:40 +0100 Subject: [PATCH 06/16] 3470: Add new panel to show unread message count (as POC so far) --- .../scipro/forum/panels/NumberOfMessagesPanel.html | 11 +++++++++++ .../scipro/forum/panels/NumberOfMessagesPanel.java | 13 +++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.html create mode 100644 view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.html b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.html new file mode 100644 index 0000000000..5184048389 --- /dev/null +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.html @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java new file mode 100644 index 0000000000..b7a5900689 --- /dev/null +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java @@ -0,0 +1,13 @@ +package se.su.dsv.scipro.forum.panels; + +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.panel.Panel; + +public class NumberOfMessagesPanel extends Panel { + + public NumberOfMessagesPanel(final String id) { + super(id); + + add(new Label("msgCount", " (0)")); + } +} -- 2.39.5 From 0525f8956023099cade6a5fd30921b76bc160fed Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Tue, 17 Dec 2024 09:45:14 +0100 Subject: [PATCH 07/16] 3470: Add logic to retrieve actual message counts --- .../dsv/scipro/forum/ProjectForumService.java | 2 ++ .../scipro/forum/ProjectForumServiceImpl.java | 1 + .../forum/panels/NumberOfMessagesPanel.java | 22 +++++++++++++++++-- .../panels/SupervisorMyProjectsPanel.java | 22 ++++++++++++------- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java index d3b1c35773..018e4736fa 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java @@ -26,4 +26,6 @@ public interface ProjectForumService { List> latestPost(Project a, int amount); boolean hasUnreadThreads(Project project, User user); + + int getUnreadThreadsCount(Project project, User user); } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java index 878d2c2050..2743d0cc3d 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java @@ -106,6 +106,7 @@ public class ProjectForumServiceImpl implements ProjectForumService { return false; } + @Override public int getUnreadThreadsCount(Project project, User user) { List threads = getThreads(project); int count = 0; diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java index b7a5900689..932b62f302 100644 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java @@ -1,13 +1,31 @@ package se.su.dsv.scipro.forum.panels; +import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.Model; -public class NumberOfMessagesPanel extends Panel { +public abstract class NumberOfMessagesPanel extends Panel { + + private Model model = Model.of(""); public NumberOfMessagesPanel(final String id) { super(id); - add(new Label("msgCount", " (0)")); + add(new Label("msgCount", model)); + } + + @Override + protected void onComponentTag(ComponentTag tag) { + super.onComponentTag(tag); + + int count = getMessageCount(); + + if (count > 0) { + model.setObject("(" + count + ")"); + } + } + + public abstract int getMessageCount(); } 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 9e1860c856..53ff74a577 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 @@ -214,27 +214,27 @@ public class SupervisorMyProjectsPanel extends Panel { SupervisorThreadedForumPage.getPageParameters(projectModel.getObject())); } }); - */ - - //WebMarkupContainer container = new WebMarkupContainer(id); - //container.setOutputMarkupId(true); + // WebMarkupContainer container = new WebMarkupContainer(id); + // container.setOutputMarkupId(true); /* container */ //container.add(new NumberOfMessagesPanel("counter")); //item.add(container); - // todo: reconsider name of this id, needs to be improved. + //boolean hasUnreadThreads = projectForumService.hasUnreadThreads(projectModel.getObject(), SciProSession.get().getUser()); + int msgCount = projectForumService.getUnreadThreadsCount(projectModel.getObject(), SciProSession.get().getUser()); + + // todo: reconsider name of this id, needs to be improved. Fragment fragment = new Fragment(id, "parentMarkupId", SupervisorMyProjectsPanel.this); fragment.add(new AbstractReadStatePanel("flag", AbstractReadStatePanel.ShowReadStateTooltip.ENABLED) { @Override protected boolean isRead() { - return !projectForumService.hasUnreadThreads(projectModel.getObject(), - SciProSession.get().getUser()); + return msgCount == 0; } @Override @@ -243,7 +243,13 @@ public class SupervisorMyProjectsPanel extends Panel { SupervisorThreadedForumPage.getPageParameters(projectModel.getObject())); } }); - fragment.add(new NumberOfMessagesPanel("counter")); + + fragment.add(new NumberOfMessagesPanel("counter") { + @Override + public int getMessageCount() { + return msgCount; + } + }); item.add(fragment); } -- 2.39.5 From 3e71bc1c9e557446678fe143f266d4ab03b60d23 Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Wed, 18 Dec 2024 08:58:41 +0100 Subject: [PATCH 08/16] 3470: Use JPA native query to reduce number of calls to database --- .../dsv/scipro/forum/ProjectForumService.java | 2 +- .../scipro/forum/ProjectForumServiceImpl.java | 6 ++++- .../scipro/forum/ProjectThreadRepository.java | 3 +++ .../forum/ProjectThreadRepositoryImpl.java | 24 +++++++++++++++++++ .../forum/panels/NumberOfMessagesPanel.java | 4 ++-- .../panels/SupervisorMyProjectsPanel.java | 4 ++-- 6 files changed, 37 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java index 018e4736fa..6220776cec 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java @@ -27,5 +27,5 @@ public interface ProjectForumService { boolean hasUnreadThreads(Project project, User user); - int getUnreadThreadsCount(Project project, User user); + long getUnreadThreadsCount(Project project, User user); } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java index 2743d0cc3d..467b092b70 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java @@ -107,7 +107,9 @@ public class ProjectForumServiceImpl implements ProjectForumService { } @Override - public int getUnreadThreadsCount(Project project, User user) { + public long getUnreadThreadsCount(Project project, User user) { + return projectThreadRepository.getUnreadThreadsCount(project, user); + /* List threads = getThreads(project); int count = 0; for (ProjectThread thread : threads) { @@ -116,6 +118,8 @@ public class ProjectForumServiceImpl implements ProjectForumService { } } return count; + + */ } @Override diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java index cbe28506a1..189ffed09b 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java @@ -5,6 +5,7 @@ import se.su.dsv.scipro.system.JpaRepository; import se.su.dsv.scipro.system.QueryDslPredicateExecutor; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.project.Project; +import se.su.dsv.scipro.system.User; import java.util.List; @@ -13,4 +14,6 @@ public interface ProjectThreadRepository extends JpaRepository findByProject(Project project); + long getUnreadThreadsCount(Project project, User user); + } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java index b278d1d214..26286262e6 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java @@ -1,5 +1,6 @@ package se.su.dsv.scipro.forum; +import jakarta.persistence.Query; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.forum.dataobjects.QProjectThread; import se.su.dsv.scipro.project.Project; @@ -8,6 +9,8 @@ import se.su.dsv.scipro.system.GenericRepo; import jakarta.inject.Inject; import jakarta.inject.Provider; import jakarta.persistence.EntityManager; +import se.su.dsv.scipro.system.User; + import java.util.List; public class ProjectThreadRepositoryImpl extends GenericRepo implements ProjectThreadRepository { @@ -21,4 +24,25 @@ public class ProjectThreadRepositoryImpl extends GenericRepo 0) { model.setObject("(" + count + ")"); } } - public abstract int getMessageCount(); + public abstract long getMessageCount(); } 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 53ff74a577..3ac0eb01e8 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 @@ -226,7 +226,7 @@ public class SupervisorMyProjectsPanel extends Panel { //item.add(container); //boolean hasUnreadThreads = projectForumService.hasUnreadThreads(projectModel.getObject(), SciProSession.get().getUser()); - int msgCount = projectForumService.getUnreadThreadsCount(projectModel.getObject(), SciProSession.get().getUser()); + long msgCount = projectForumService.getUnreadThreadsCount(projectModel.getObject(), SciProSession.get().getUser()); // todo: reconsider name of this id, needs to be improved. Fragment fragment = new Fragment(id, "parentMarkupId", SupervisorMyProjectsPanel.this); @@ -246,7 +246,7 @@ public class SupervisorMyProjectsPanel extends Panel { fragment.add(new NumberOfMessagesPanel("counter") { @Override - public int getMessageCount() { + public long getMessageCount() { return msgCount; } }); -- 2.39.5 From b20b1239a0b6aba0f847c3bed228b2145c9491c9 Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Wed, 18 Dec 2024 13:23:58 +0100 Subject: [PATCH 09/16] 3470: Refactor how message counting works: 1. Now we retrieve at first all threads, then use another database call to get count of threads which have unread posts. It makes possible to reuse the logic of unread-post-counting somewhere else. 2. We use QueryDSL instead of native SQL, also left join from thread table instead of exists(). --- .../dsv/scipro/forum/BasicForumService.java | 1 + .../scipro/forum/BasicForumServiceImpl.java | 5 +++ .../dsv/scipro/forum/ForumPostRepository.java | 3 ++ .../scipro/forum/ForumPostRepositoryImpl.java | 19 +++++++++++ .../scipro/forum/ProjectForumServiceImpl.java | 15 +++------ .../scipro/forum/ProjectThreadRepository.java | 7 ++-- .../forum/ProjectThreadRepositoryImpl.java | 33 +++---------------- 7 files changed, 38 insertions(+), 45 deletions(-) diff --git a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java index a6cff8bdae..b1001c6a3b 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java @@ -23,4 +23,5 @@ public interface BasicForumService extends Serializable { ForumThread createThread(String subject); + long countUnreadThreads(List forumThreadList, User user); } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumServiceImpl.java index 0dae3383bb..6877c784ae 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumServiceImpl.java @@ -88,6 +88,11 @@ public class BasicForumServiceImpl implements BasicForumService { return threadRepository.save(forumThread); } + @Override + public long countUnreadThreads(List forumThreadList, User user) { + return postRepository.countUnreadThreads(forumThreadList, user); + } + private ForumPostReadState getReadState(final User user, final ForumPost post) { ForumPostReadState state = readStateRepository.find(user, post); if (state == null) { diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepository.java b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepository.java index 92e3afb1c8..8e965c015b 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepository.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepository.java @@ -7,6 +7,7 @@ import se.su.dsv.scipro.forum.dataobjects.ForumPost; import se.su.dsv.scipro.forum.dataobjects.ForumThread; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.project.Project; +import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.util.Pair; import java.util.List; @@ -17,4 +18,6 @@ public interface ForumPostRepository extends JpaRepository, Que List findByThread(ForumThread forumThread); List> latestPost(Project project, int amount); + + long countUnreadThreads(List forumThreadList, User user); } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java index e4536e7582..e806c717d6 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java @@ -1,15 +1,19 @@ package se.su.dsv.scipro.forum; +import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQuery; import jakarta.persistence.EntityManager; +import jakarta.persistence.Query; import se.su.dsv.scipro.forum.dataobjects.ForumPost; import se.su.dsv.scipro.forum.dataobjects.ForumThread; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.forum.dataobjects.QForumPost; +import se.su.dsv.scipro.forum.dataobjects.QForumPostReadState; import se.su.dsv.scipro.forum.dataobjects.QForumThread; import se.su.dsv.scipro.forum.dataobjects.QProjectThread; import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.system.GenericRepo; +import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.util.Pair; import jakarta.inject.Inject; @@ -46,4 +50,19 @@ public class ForumPostRepositoryImpl extends GenericRepo implem tuple.get(QForumPost.forumPost))) .toList(); } + + @Override + public long countUnreadThreads(List forumThreadList, User user) { + return new JPAQuery<>(em()) + .select(QForumThread.forumThread.id.countDistinct()) + .from(QForumThread.forumThread) + .leftJoin(QForumThread.forumThread.posts, QForumPost.forumPost) + .where(QForumPost.forumPost.notIn( + JPAExpressions.select(QForumPostReadState.forumPostReadState.id.post) + .from(QForumPostReadState.forumPostReadState) + .where(QForumPostReadState.forumPostReadState.read.isTrue(), + QForumPostReadState.forumPostReadState.id.user.eq(user)) + ), QForumThread.forumThread.in(forumThreadList) + ).fetchOne(); + } } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java index 467b092b70..305943b062 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java @@ -108,18 +108,11 @@ public class ProjectForumServiceImpl implements ProjectForumService { @Override public long getUnreadThreadsCount(Project project, User user) { - return projectThreadRepository.getUnreadThreadsCount(project, user); - /* List threads = getThreads(project); - int count = 0; - for (ProjectThread thread : threads) { - if (!basicForumService.isThreadRead(user, thread.getForumThread())) { - count++; - } - } - return count; - - */ + List list = threads.stream() + .map(ProjectThread::getForumThread) + .toList(); + return basicForumService.countUnreadThreads(list, user); } @Override diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java index 189ffed09b..83720860fe 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java @@ -1,11 +1,10 @@ package se.su.dsv.scipro.forum; import jakarta.transaction.Transactional; -import se.su.dsv.scipro.system.JpaRepository; -import se.su.dsv.scipro.system.QueryDslPredicateExecutor; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.project.Project; -import se.su.dsv.scipro.system.User; +import se.su.dsv.scipro.system.JpaRepository; +import se.su.dsv.scipro.system.QueryDslPredicateExecutor; import java.util.List; @@ -14,6 +13,4 @@ public interface ProjectThreadRepository extends JpaRepository findByProject(Project project); - long getUnreadThreadsCount(Project project, User user); - } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java index 26286262e6..cf5988cfde 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java @@ -1,15 +1,12 @@ package se.su.dsv.scipro.forum; -import jakarta.persistence.Query; -import se.su.dsv.scipro.forum.dataobjects.ProjectThread; -import se.su.dsv.scipro.forum.dataobjects.QProjectThread; -import se.su.dsv.scipro.project.Project; -import se.su.dsv.scipro.system.GenericRepo; - import jakarta.inject.Inject; import jakarta.inject.Provider; import jakarta.persistence.EntityManager; -import se.su.dsv.scipro.system.User; +import se.su.dsv.scipro.forum.dataobjects.ProjectThread; +import se.su.dsv.scipro.forum.dataobjects.QProjectThread; +import se.su.dsv.scipro.project.Project; +import se.su.dsv.scipro.system.GenericRepo; import java.util.List; @@ -23,26 +20,4 @@ public class ProjectThreadRepositoryImpl extends GenericRepo findByProject(Project project) { return findAll(QProjectThread.projectThread.project.eq(project)); } - - @Override - public long getUnreadThreadsCount(Project project, User user) { - StringBuilder sql = new StringBuilder() - .append("select count(distinct(thread_id)) result ") - .append(" from (select fp.thread_id as thread_id, fp.id as post_id, ") - .append(" exists (select `read` ") - .append(" from forum_post_read_state fprs ") - .append(" where fprs.forum_post_id = fp.id and ") - .append(" fprs.user_id = :uid and ") - .append(" fprs.read = 1) as post_read ") - .append(" from project_thread pt, forum_post fp ") - .append(" where pt.thread_id = fp.thread_id and ") - .append(" pt.project_id = :pid) tbl_ex ") - .append(" where post_read = 0"); - Query query = em().createNativeQuery(sql.toString()); - query.setParameter("uid", user.getId()) - .setParameter("pid", project.getId()); - - return (Long)query.getSingleResult(); - } - } -- 2.39.5 From c8930ec5fe43e9cd06e623519dbdbe485b6044af Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Wed, 18 Dec 2024 13:34:33 +0100 Subject: [PATCH 10/16] 3470: Optimize import --- .../se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java index e806c717d6..8fcaa9ef17 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java @@ -2,8 +2,9 @@ package se.su.dsv.scipro.forum; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQuery; +import jakarta.inject.Inject; +import jakarta.inject.Provider; import jakarta.persistence.EntityManager; -import jakarta.persistence.Query; import se.su.dsv.scipro.forum.dataobjects.ForumPost; import se.su.dsv.scipro.forum.dataobjects.ForumThread; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; @@ -16,9 +17,7 @@ import se.su.dsv.scipro.system.GenericRepo; import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.util.Pair; -import jakarta.inject.Inject; -import jakarta.inject.Provider; -import java.util.*; +import java.util.List; import static com.querydsl.core.types.dsl.Expressions.allOf; -- 2.39.5 From 379b5c34fcfefd7c832554af602c66e60cb1df02 Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Wed, 18 Dec 2024 15:15:22 +0100 Subject: [PATCH 11/16] 3470: Use Wicket behavior (less intrusive) to modify AbstractReadStatePanel --- .../forum/panels/AbstractReadStatePanel.java | 16 ------ .../AbstractReadStatePanel.utf8.properties | 1 - .../panels/SupervisorMyProjectsPanel.html | 5 +- .../panels/SupervisorMyProjectsPanel.java | 49 +++++++------------ .../SupervisorMyProjectsPanel.utf8.properties | 2 + 5 files changed, 21 insertions(+), 52 deletions(-) delete mode 100644 view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.utf8.properties diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java index 13df58ff05..223dc04531 100644 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java @@ -14,20 +14,8 @@ public abstract class AbstractReadStatePanel extends Panel { public static final String TOGGLE = "toggle"; static final String ICON = "icon"; - public enum ShowReadStateTooltip { - ENABLED, - DISABLED - } - - private final ShowReadStateTooltip showReadStateTooltip; - public AbstractReadStatePanel(final String id) { - this(id, ShowReadStateTooltip.DISABLED); - } - - public AbstractReadStatePanel(final String id, final ShowReadStateTooltip showReadStateTooltip) { super(id); - this.showReadStateTooltip = showReadStateTooltip; Component icon = new UpdatingImage(ICON); icon.setOutputMarkupId(true); @@ -59,10 +47,6 @@ public abstract class AbstractReadStatePanel extends Panel { super.onComponentTag(tag); String state = isRead() ? "read" : "unread"; tag.append("class", state, " "); - - if (showReadStateTooltip == ShowReadStateTooltip.ENABLED && !isRead()) { - tag.put("title", getString("unread.msg")); - } } } } diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.utf8.properties b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.utf8.properties deleted file mode 100644 index e86f4d6e50..0000000000 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.utf8.properties +++ /dev/null @@ -1 +0,0 @@ -unread.msg=There are unread messages. \ No newline at end of file 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 b50ec6da63..da97aaf553 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 @@ -42,9 +42,8 @@
- - - + + 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 3ac0eb01e8..5d9cf5ca90 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 @@ -4,6 +4,7 @@ import jakarta.inject.Inject; 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.AttributeModifier; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder; import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; @@ -200,12 +201,19 @@ public class SupervisorMyProjectsPanel extends Panel { @Override public void populateItem(Item> item, String id, IModel projectModel) { - /* - item.add(new AbstractReadStatePanel(id, AbstractReadStatePanel.ShowReadStateTooltip.ENABLED) { + // Since table cell only can contain one item, we use Wicket Fragment here. It will contains two components, + // one for flag, one for unread messages counter. + + Fragment fragment = new Fragment(id, "readStateColumnMarkupId", SupervisorMyProjectsPanel.this); + + long msgCount = projectForumService.getUnreadThreadsCount(projectModel.getObject(), + SciProSession.get().getUser()); + boolean isRead = msgCount == 0; + + AbstractReadStatePanel readStatePanel = new AbstractReadStatePanel("flag") { @Override protected boolean isRead() { - return !projectForumService.hasUnreadThreads(projectModel.getObject(), - SciProSession.get().getUser()); + return isRead; } @Override @@ -213,36 +221,13 @@ public class SupervisorMyProjectsPanel extends Panel { setResponsePage(SupervisorThreadedForumPage.class, SupervisorThreadedForumPage.getPageParameters(projectModel.getObject())); } - }); - */ + }; - // WebMarkupContainer container = new WebMarkupContainer(id); - // container.setOutputMarkupId(true); -/* - container - */ - //container.add(new NumberOfMessagesPanel("counter")); + if (!isRead) { + readStatePanel.add(new AttributeModifier("title", getString("unread.msg"))); + } - //item.add(container); - - //boolean hasUnreadThreads = projectForumService.hasUnreadThreads(projectModel.getObject(), SciProSession.get().getUser()); - long msgCount = projectForumService.getUnreadThreadsCount(projectModel.getObject(), SciProSession.get().getUser()); - - // todo: reconsider name of this id, needs to be improved. - Fragment fragment = new Fragment(id, "parentMarkupId", SupervisorMyProjectsPanel.this); - - fragment.add(new AbstractReadStatePanel("flag", AbstractReadStatePanel.ShowReadStateTooltip.ENABLED) { - @Override - protected boolean isRead() { - return msgCount == 0; - } - - @Override - protected void onFlagClick(AjaxRequestTarget target) { - setResponsePage(SupervisorThreadedForumPage.class, - SupervisorThreadedForumPage.getPageParameters(projectModel.getObject())); - } - }); + fragment.add(readStatePanel); fragment.add(new NumberOfMessagesPanel("counter") { @Override 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 17f454ad8c..e279982933 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 @@ -12,3 +12,5 @@ ProjectStatus.COMPLETED= Completed SupervisorProjectNoteDisplay.COMPACT=Compact SupervisorProjectNoteDisplay.FULL=Full + +unread.msg=There are unread messages. \ No newline at end of file -- 2.39.5 From 08f40959fd6ccc338f8171e758ce3027b636930d Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Wed, 18 Dec 2024 15:31:17 +0100 Subject: [PATCH 12/16] 3470: Reformat code with prettier --- .../dsv/scipro/forum/BasicForumService.java | 4 +- .../dsv/scipro/forum/ForumPostRepository.java | 8 +- .../scipro/forum/ForumPostRepositoryImpl.java | 57 +++--- .../scipro/forum/ProjectForumServiceImpl.java | 4 +- .../scipro/forum/ProjectThreadRepository.java | 8 +- .../forum/ProjectThreadRepositoryImpl.java | 4 +- .../forum/panels/AbstractReadStatePanel.java | 6 +- .../forum/panels/NumberOfMessagesPanel.java | 2 - .../panels/SupervisorMyProjectsPanel.java | 178 ++++++++++++------ 9 files changed, 164 insertions(+), 107 deletions(-) diff --git a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java index b1001c6a3b..ee581f015f 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java @@ -5,10 +5,10 @@ import se.su.dsv.scipro.forum.dataobjects.ForumThread; import se.su.dsv.scipro.system.User; import java.io.Serializable; -import java.util.*; +import java.util.List; +import java.util.Set; public interface BasicForumService extends Serializable { - ForumPost createReply(ForumThread forumThread, User poster, String content, Set attachments); boolean setRead(User user, ForumPost post, boolean read); diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepository.java b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepository.java index 8e965c015b..e5d975add4 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepository.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepository.java @@ -1,20 +1,18 @@ package se.su.dsv.scipro.forum; import jakarta.transaction.Transactional; -import se.su.dsv.scipro.system.JpaRepository; -import se.su.dsv.scipro.system.QueryDslPredicateExecutor; +import java.util.List; import se.su.dsv.scipro.forum.dataobjects.ForumPost; import se.su.dsv.scipro.forum.dataobjects.ForumThread; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.project.Project; +import se.su.dsv.scipro.system.JpaRepository; +import se.su.dsv.scipro.system.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.util.Pair; -import java.util.List; - @Transactional public interface ForumPostRepository extends JpaRepository, QueryDslPredicateExecutor { - List findByThread(ForumThread forumThread); List> latestPost(Project project, int amount); diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java index 8fcaa9ef17..f43a0147bb 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ForumPostRepositoryImpl.java @@ -1,10 +1,13 @@ package se.su.dsv.scipro.forum; +import static com.querydsl.core.types.dsl.Expressions.allOf; + import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQuery; import jakarta.inject.Inject; import jakarta.inject.Provider; import jakarta.persistence.EntityManager; +import java.util.List; import se.su.dsv.scipro.forum.dataobjects.ForumPost; import se.su.dsv.scipro.forum.dataobjects.ForumThread; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; @@ -17,11 +20,8 @@ import se.su.dsv.scipro.system.GenericRepo; import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.util.Pair; -import java.util.List; - -import static com.querydsl.core.types.dsl.Expressions.allOf; - public class ForumPostRepositoryImpl extends GenericRepo implements ForumPostRepository { + @Inject public ForumPostRepositoryImpl(Provider em) { super(em, ForumPost.class, QForumPost.forumPost); @@ -35,33 +35,36 @@ public class ForumPostRepositoryImpl extends GenericRepo implem @Override public List> latestPost(Project project, int amount) { return new JPAQuery<>(em()) - .select(QProjectThread.projectThread, QForumPost.forumPost) - .from(QProjectThread.projectThread) - .innerJoin(QProjectThread.projectThread.forumThread) - .innerJoin(QForumThread.forumThread.posts, QForumPost.forumPost) - .where(QProjectThread.projectThread.project.eq(project)) - .orderBy(QForumPost.forumPost.dateCreated.desc()) - .limit(amount) - .fetch() - .stream() - .map(tuple -> new Pair<>( - tuple.get(QProjectThread.projectThread), - tuple.get(QForumPost.forumPost))) - .toList(); + .select(QProjectThread.projectThread, QForumPost.forumPost) + .from(QProjectThread.projectThread) + .innerJoin(QProjectThread.projectThread.forumThread) + .innerJoin(QForumThread.forumThread.posts, QForumPost.forumPost) + .where(QProjectThread.projectThread.project.eq(project)) + .orderBy(QForumPost.forumPost.dateCreated.desc()) + .limit(amount) + .fetch() + .stream() + .map(tuple -> new Pair<>(tuple.get(QProjectThread.projectThread), tuple.get(QForumPost.forumPost))) + .toList(); } @Override public long countUnreadThreads(List forumThreadList, User user) { return new JPAQuery<>(em()) - .select(QForumThread.forumThread.id.countDistinct()) - .from(QForumThread.forumThread) - .leftJoin(QForumThread.forumThread.posts, QForumPost.forumPost) - .where(QForumPost.forumPost.notIn( - JPAExpressions.select(QForumPostReadState.forumPostReadState.id.post) - .from(QForumPostReadState.forumPostReadState) - .where(QForumPostReadState.forumPostReadState.read.isTrue(), - QForumPostReadState.forumPostReadState.id.user.eq(user)) - ), QForumThread.forumThread.in(forumThreadList) - ).fetchOne(); + .select(QForumThread.forumThread.id.countDistinct()) + .from(QForumThread.forumThread) + .leftJoin(QForumThread.forumThread.posts, QForumPost.forumPost) + .where( + QForumPost.forumPost.notIn( + JPAExpressions.select(QForumPostReadState.forumPostReadState.id.post) + .from(QForumPostReadState.forumPostReadState) + .where( + QForumPostReadState.forumPostReadState.read.isTrue(), + QForumPostReadState.forumPostReadState.id.user.eq(user) + ) + ), + QForumThread.forumThread.in(forumThreadList) + ) + .fetchOne(); } } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java index c85552ed79..e2c0d252b4 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java @@ -127,9 +127,7 @@ public class ProjectForumServiceImpl implements ProjectForumService { @Override public long getUnreadThreadsCount(Project project, User user) { List threads = getThreads(project); - List list = threads.stream() - .map(ProjectThread::getForumThread) - .toList(); + List list = threads.stream().map(ProjectThread::getForumThread).toList(); return basicForumService.countUnreadThreads(list, user); } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java index 83720860fe..d0d4f27f60 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepository.java @@ -1,16 +1,14 @@ package se.su.dsv.scipro.forum; import jakarta.transaction.Transactional; +import java.util.List; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.system.JpaRepository; import se.su.dsv.scipro.system.QueryDslPredicateExecutor; -import java.util.List; - @Transactional -public interface ProjectThreadRepository extends JpaRepository, QueryDslPredicateExecutor { - +public interface ProjectThreadRepository + extends JpaRepository, QueryDslPredicateExecutor { List findByProject(Project project); - } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java index cf5988cfde..f42cbdbe41 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectThreadRepositoryImpl.java @@ -3,14 +3,14 @@ package se.su.dsv.scipro.forum; import jakarta.inject.Inject; import jakarta.inject.Provider; import jakarta.persistence.EntityManager; +import java.util.List; import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.forum.dataobjects.QProjectThread; import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.system.GenericRepo; -import java.util.List; - public class ProjectThreadRepositoryImpl extends GenericRepo implements ProjectThreadRepository { + @Inject public ProjectThreadRepositoryImpl(Provider em) { super(em, ProjectThread.class, QProjectThread.projectThread); diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java index 223dc04531..54072c9532 100644 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/AbstractReadStatePanel.java @@ -1,5 +1,6 @@ package se.su.dsv.scipro.forum.panels; +import java.util.Optional; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxFallbackLink; @@ -7,8 +8,6 @@ import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.html.WebComponent; import org.apache.wicket.markup.html.panel.Panel; -import java.util.Optional; - public abstract class AbstractReadStatePanel extends Panel { public static final String TOGGLE = "toggle"; @@ -16,7 +15,6 @@ public abstract class AbstractReadStatePanel extends Panel { public AbstractReadStatePanel(final String id) { super(id); - Component icon = new UpdatingImage(ICON); icon.setOutputMarkupId(true); @@ -35,9 +33,11 @@ public abstract class AbstractReadStatePanel extends Panel { } protected abstract boolean isRead(); + protected abstract void onFlagClick(final AjaxRequestTarget target); private class UpdatingImage extends WebComponent { + public UpdatingImage(String id) { super(id); } diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java index 115aad83f2..86a9ca96b2 100644 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java +++ b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java @@ -11,9 +11,7 @@ public abstract class NumberOfMessagesPanel extends Panel { public NumberOfMessagesPanel(final String id) { super(id); - add(new Label("msgCount", model)); - } @Override 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 5d9cf5ca90..4de431f9e6 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,10 +1,14 @@ package se.su.dsv.scipro.supervisor.panels; +import static java.util.Arrays.asList; + import jakarta.inject.Inject; +import java.util.ArrayList; +import java.util.List; +import org.apache.wicket.AttributeModifier; 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.AttributeModifier; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder; import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; @@ -47,11 +51,6 @@ import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectTypeService; import se.su.dsv.scipro.system.User; -import java.util.ArrayList; -import java.util.List; - -import static java.util.Arrays.asList; - public class SupervisorMyProjectsPanel extends Panel { public static final String FILTER_FORM = "filterForm"; @@ -63,10 +62,13 @@ public class SupervisorMyProjectsPanel extends Panel { @Inject private ProjectTypeService projectTypeService; + @Inject private ProjectService projectService; + @Inject private UserProfileService profileService; + @Inject private ProjectForumService projectForumService; @@ -82,7 +84,10 @@ public class SupervisorMyProjectsPanel extends Panel { } private void dataViewSetup() { - SortableDataProvider provider = new FilteredDataProvider<>(projectService, Model.of(this.filter)); + SortableDataProvider provider = new FilteredDataProvider<>( + projectService, + Model.of(this.filter) + ); provider.setSort("dateCreated", SortOrder.DESCENDING); dataPanel = new ExportableDataPanel<>(DATA_PANEL, createColumns(), provider); add(dataPanel); @@ -95,14 +100,24 @@ public class SupervisorMyProjectsPanel extends Panel { columns.add(new TemporalColumn<>(Model.of("Started"), "startDate", Project::getStartDate)); columns.add(new LambdaColumn<>(Model.of("Type"), "projectType.name", Project::getProjectTypeName)); columns.add(new ProjectTitleColumn(Model.of("Title"), "title")); - columns.add(new MultipleUsersColumn<>(Model.of("Authors")) { - @Override - public ListAdapterModel getUsers(final IModel rowModel) { - return new ListAdapterModel<>(rowModel.map(Project::getProjectParticipants)); + columns.add( + new MultipleUsersColumn<>(Model.of("Authors")) { + @Override + public ListAdapterModel getUsers(final IModel rowModel) { + 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)); + ); + 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; } @@ -139,47 +154,87 @@ public class SupervisorMyProjectsPanel extends Panel { public FilterForm(String id, IModel filterParams) { super(id, filterParams); - - add(new AjaxCheckBox(SUPERVISOR, LambdaModel.of(filterParams, ProjectService.Filter::isFilterSupervisor, ProjectService.Filter::setFilterSupervisor)) { - @Override - protected void onUpdate(AjaxRequestTarget target) { - target.add(dataPanel); - updateProfileWithCurrentFilter(); + add( + new AjaxCheckBox( + SUPERVISOR, + LambdaModel.of( + filterParams, + ProjectService.Filter::isFilterSupervisor, + ProjectService.Filter::setFilterSupervisor + ) + ) { + @Override + protected void onUpdate(AjaxRequestTarget target) { + target.add(dataPanel); + updateProfileWithCurrentFilter(); + } } - }); - add(new AjaxCheckBoxMultipleChoice<>(ROLE_FILTER, LambdaModel.of(filterParams, ProjectService.Filter::getRoles, ProjectService.Filter::setRoles), List.of(ProjectTeamMemberRoles.CO_SUPERVISOR), new EnumChoiceRenderer<>(this)) { - @Override - public void onUpdate(AjaxRequestTarget target) { - target.add(dataPanel); - updateProfileWithCurrentFilter(); + ); + add( + new AjaxCheckBoxMultipleChoice<>( + ROLE_FILTER, + LambdaModel.of(filterParams, ProjectService.Filter::getRoles, ProjectService.Filter::setRoles), + List.of(ProjectTeamMemberRoles.CO_SUPERVISOR), + new EnumChoiceRenderer<>(this) + ) { + @Override + public void onUpdate(AjaxRequestTarget target) { + target.add(dataPanel); + updateProfileWithCurrentFilter(); + } } - }); - add(new AjaxCheckBoxMultipleChoice<>(STATUS_FILTER, LambdaModel.of(filterParams, ProjectService.Filter::getStatuses, ProjectService.Filter::setStatuses), asList(ProjectStatus.values()), new EnumChoiceRenderer<>(this)) { - @Override - public void onUpdate(AjaxRequestTarget target) { - target.add(dataPanel); - updateProfileWithCurrentFilter(); + ); + add( + new AjaxCheckBoxMultipleChoice<>( + STATUS_FILTER, + LambdaModel.of( + filterParams, + ProjectService.Filter::getStatuses, + ProjectService.Filter::setStatuses + ), + asList(ProjectStatus.values()), + new EnumChoiceRenderer<>(this) + ) { + @Override + public void onUpdate(AjaxRequestTarget target) { + target.add(dataPanel); + updateProfileWithCurrentFilter(); + } } - }); - add(new AjaxCheckBoxMultipleChoice<>(TYPE_FILTER, LambdaModel.of(filterParams, ProjectService.Filter::getProjectTypes, ProjectService.Filter::setProjectTypes), projectTypeService.findBySupervisorProjects(SciProSession.get().getUser()), new LambdaChoiceRenderer<>(ProjectType::getName, ProjectType::getId)) { - @Override - public void onUpdate(AjaxRequestTarget target) { - target.add(dataPanel); - updateProfileWithCurrentFilter(); + ); + add( + new AjaxCheckBoxMultipleChoice<>( + TYPE_FILTER, + LambdaModel.of( + filterParams, + ProjectService.Filter::getProjectTypes, + ProjectService.Filter::setProjectTypes + ), + projectTypeService.findBySupervisorProjects(SciProSession.get().getUser()), + new LambdaChoiceRenderer<>(ProjectType::getName, ProjectType::getId) + ) { + @Override + public void onUpdate(AjaxRequestTarget target) { + target.add(dataPanel); + updateProfileWithCurrentFilter(); + } } - }); + ); BootstrapRadioChoice 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(); + "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); } @@ -195,6 +250,7 @@ public class SupervisorMyProjectsPanel extends Panel { } private class ProjectForumStateColumn extends AbstractColumn { + public ProjectForumStateColumn(IModel label) { super(label); } @@ -206,8 +262,10 @@ public class SupervisorMyProjectsPanel extends Panel { Fragment fragment = new Fragment(id, "readStateColumnMarkupId", SupervisorMyProjectsPanel.this); - long msgCount = projectForumService.getUnreadThreadsCount(projectModel.getObject(), - SciProSession.get().getUser()); + long msgCount = projectForumService.getUnreadThreadsCount( + projectModel.getObject(), + SciProSession.get().getUser() + ); boolean isRead = msgCount == 0; AbstractReadStatePanel readStatePanel = new AbstractReadStatePanel("flag") { @@ -218,8 +276,10 @@ public class SupervisorMyProjectsPanel extends Panel { @Override protected void onFlagClick(AjaxRequestTarget target) { - setResponsePage(SupervisorThreadedForumPage.class, - SupervisorThreadedForumPage.getPageParameters(projectModel.getObject())); + setResponsePage( + SupervisorThreadedForumPage.class, + SupervisorThreadedForumPage.getPageParameters(projectModel.getObject()) + ); } }; @@ -229,12 +289,14 @@ public class SupervisorMyProjectsPanel extends Panel { fragment.add(readStatePanel); - fragment.add(new NumberOfMessagesPanel("counter") { - @Override - public long getMessageCount() { - return msgCount; + fragment.add( + new NumberOfMessagesPanel("counter") { + @Override + public long getMessageCount() { + return msgCount; + } } - }); + ); item.add(fragment); } -- 2.39.5 From 1f2670b5016eb2831dcba360c8f4558824219581 Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Wed, 18 Dec 2024 15:38:29 +0100 Subject: [PATCH 13/16] 3470: Reformat code with prettier for BasicForumService --- .../java/se/su/dsv/scipro/forum/BasicForumService.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java index ee581f015f..6a680ad26f 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/BasicForumService.java @@ -1,12 +1,11 @@ package se.su.dsv.scipro.forum; -import se.su.dsv.scipro.forum.dataobjects.ForumPost; -import se.su.dsv.scipro.forum.dataobjects.ForumThread; -import se.su.dsv.scipro.system.User; - import java.io.Serializable; import java.util.List; import java.util.Set; +import se.su.dsv.scipro.forum.dataobjects.ForumPost; +import se.su.dsv.scipro.forum.dataobjects.ForumThread; +import se.su.dsv.scipro.system.User; public interface BasicForumService extends Serializable { ForumPost createReply(ForumThread forumThread, User poster, String content, Set attachments); -- 2.39.5 From 4a9232dab02f37c5be1fa2aac9c85833cda05eea Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Thu, 19 Dec 2024 11:58:21 +0100 Subject: [PATCH 14/16] 3492: Move counter to a Label instead of Panel, which simplifies a lot. --- .../forum/panels/NumberOfMessagesPanel.html | 11 ------- .../forum/panels/NumberOfMessagesPanel.java | 29 ------------------- .../panels/SupervisorMyProjectsPanel.html | 4 ++- .../panels/SupervisorMyProjectsPanel.java | 18 +++++++----- 4 files changed, 13 insertions(+), 49 deletions(-) delete mode 100644 view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.html delete mode 100644 view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.html b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.html deleted file mode 100644 index 5184048389..0000000000 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java b/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java deleted file mode 100644 index 86a9ca96b2..0000000000 --- a/view/src/main/java/se/su/dsv/scipro/forum/panels/NumberOfMessagesPanel.java +++ /dev/null @@ -1,29 +0,0 @@ -package se.su.dsv.scipro.forum.panels; - -import org.apache.wicket.markup.ComponentTag; -import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.panel.Panel; -import org.apache.wicket.model.Model; - -public abstract class NumberOfMessagesPanel extends Panel { - - private Model model = Model.of(""); - - public NumberOfMessagesPanel(final String id) { - super(id); - add(new Label("msgCount", model)); - } - - @Override - protected void onComponentTag(ComponentTag tag) { - super.onComponentTag(tag); - - long count = getMessageCount(); - - if (count > 0) { - model.setObject("(" + count + ")"); - } - } - - public abstract long getMessageCount(); -} 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 da97aaf553..d171f8e3ba 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 @@ -44,7 +44,9 @@ - + + () + 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 4de431f9e6..423967edff 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 @@ -15,6 +15,7 @@ import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColu import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.LambdaColumn; import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider; +import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.EnumChoiceRenderer; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.LambdaChoiceRenderer; @@ -257,7 +258,7 @@ public class SupervisorMyProjectsPanel extends Panel { @Override public void populateItem(Item> item, String id, IModel projectModel) { - // Since table cell only can contain one item, we use Wicket Fragment here. It will contains two components, + // Since table cell only can contain one item, we use Wicket Fragment here. It will contain two components, // one for flag, one for unread messages counter. Fragment fragment = new Fragment(id, "readStateColumnMarkupId", SupervisorMyProjectsPanel.this); @@ -289,14 +290,15 @@ public class SupervisorMyProjectsPanel extends Panel { fragment.add(readStatePanel); - fragment.add( - new NumberOfMessagesPanel("counter") { - @Override - public long getMessageCount() { - return msgCount; - } + Label counterLabel = new Label("counter", msgCount) { + @Override + protected void onConfigure() { + super.onConfigure(); + setVisible(msgCount > 0); } - ); + }; + + fragment.add(counterLabel); item.add(fragment); } -- 2.39.5 From d5bc04e90c477cc1a5a481f4246cd93974f040bf Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Thu, 19 Dec 2024 12:14:06 +0100 Subject: [PATCH 15/16] 3492: Remove unused method hasUreadThreads in ProjectForumService --- .../su/dsv/scipro/forum/ProjectForumService.java | 2 -- .../scipro/forum/ProjectForumServiceImpl.java | 16 ++++------------ .../forum/ProjectForumServiceImplTest.java | 4 ++-- .../panels/SupervisorMyProjectsPanel.java | 1 - 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java index 2217d9d345..a6ac11ebcd 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumService.java @@ -23,7 +23,5 @@ public interface ProjectForumService { // TODO: Get these away from here List> latestPost(Project a, int amount); - boolean hasUnreadThreads(Project project, User user); - long getUnreadThreadsCount(Project project, User user); } diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java index e2c0d252b4..4d72557225 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java @@ -3,7 +3,10 @@ package se.su.dsv.scipro.forum; import com.google.common.eventbus.EventBus; import jakarta.inject.Inject; import jakarta.transaction.Transactional; -import java.util.*; + +import java.util.List; +import java.util.Set; + import se.su.dsv.scipro.file.FileSource; import se.su.dsv.scipro.file.ProjectFileService; import se.su.dsv.scipro.forum.dataobjects.ForumPost; @@ -113,17 +116,6 @@ public class ProjectForumServiceImpl implements ProjectForumService { return postRepository.latestPost(project, amount); } - @Override - public boolean hasUnreadThreads(Project project, User user) { - List threads = getThreads(project); - for (ProjectThread thread : threads) { - if (!basicForumService.isThreadRead(user, thread.getForumThread())) { - return true; - } - } - return false; - } - @Override public long getUnreadThreadsCount(Project project, User user) { List threads = getThreads(project); diff --git a/core/src/test/java/se/su/dsv/scipro/forum/ProjectForumServiceImplTest.java b/core/src/test/java/se/su/dsv/scipro/forum/ProjectForumServiceImplTest.java index 3f6a99dba8..321bc5b940 100644 --- a/core/src/test/java/se/su/dsv/scipro/forum/ProjectForumServiceImplTest.java +++ b/core/src/test/java/se/su/dsv/scipro/forum/ProjectForumServiceImplTest.java @@ -105,9 +105,9 @@ public class ProjectForumServiceImplTest extends ForumModuleTest { final ProjectThread thread = service.createThread(project, supervisor, "subject", "content", Set.of()); service.createReply(thread, author, "reply", Set.of()); - boolean hasUnreadThreads = service.hasUnreadThreads(project, supervisor); + long count = service.getUnreadThreadsCount(project, supervisor); - assertTrue(hasUnreadThreads); + assertEquals(1, count); } private void assertNewForumThread( 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 423967edff..cb76132906 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 @@ -39,7 +39,6 @@ import se.su.dsv.scipro.datatables.project.ProjectTitleColumn; import se.su.dsv.scipro.forum.ProjectForumService; import se.su.dsv.scipro.forum.pages.threaded.SupervisorThreadedForumPage; import se.su.dsv.scipro.forum.panels.AbstractReadStatePanel; -import se.su.dsv.scipro.forum.panels.NumberOfMessagesPanel; import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.ProjectService; import se.su.dsv.scipro.project.ProjectStatus; -- 2.39.5 From 844ef399144079fdbe54424738e3bc78c6b73e5a Mon Sep 17 00:00:00 2001 From: Tom Zhao Date: Thu, 19 Dec 2024 12:18:35 +0100 Subject: [PATCH 16/16] 3492: Reformat code --- .../java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java index 4d72557225..0c6b65227f 100644 --- a/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/forum/ProjectForumServiceImpl.java @@ -3,10 +3,8 @@ package se.su.dsv.scipro.forum; import com.google.common.eventbus.EventBus; import jakarta.inject.Inject; import jakarta.transaction.Transactional; - import java.util.List; import java.util.Set; - import se.su.dsv.scipro.file.FileSource; import se.su.dsv.scipro.file.ProjectFileService; import se.su.dsv.scipro.forum.dataobjects.ForumPost; -- 2.39.5