Allow supervisors to write a note associated with their projects #8
@ -25,4 +25,5 @@ public interface ProjectForumService {
|
||||
// TODO: Get these away from here
|
||||
List<Pair<ProjectThread, ForumPost>> latestPost(Project a, int amount);
|
||||
|
||||
boolean hasUnreadThreads(Project project, User user);
|
||||
}
|
||||
|
@ -95,6 +95,17 @@ public class ProjectForumServiceImpl implements ProjectForumService {
|
||||
return postRepository.latestPost(project, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnreadThreads(Project project, User user) {
|
||||
List<ProjectThread> threads = getThreads(project);
|
||||
for (ProjectThread thread : threads) {
|
||||
if (!basicForumService.isThreadRead(user, thread.getForumThread())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectThread findOne(long threadId) {
|
||||
return projectThreadRepository.findOne(threadId);
|
||||
|
@ -20,6 +20,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ProjectForumServiceImplTest extends ForumModuleTest {
|
||||
|
||||
@ -29,23 +30,24 @@ public class ProjectForumServiceImplTest extends ForumModuleTest {
|
||||
ProjectForumService service;
|
||||
|
||||
private Project project;
|
||||
private User user;
|
||||
private User author;
|
||||
private User supervisor;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
ProjectType projectType = new ProjectType(DegreeType.BACHELOR, "Some project type", "Some description");
|
||||
projectType.addModule(ProjectModule.FORUM);
|
||||
save(projectType);
|
||||
final User supervisor = save(User.builder().firstName("Bob").lastName("The Builder").emailAddress("bob@example.com").build());
|
||||
supervisor = save(User.builder().firstName("Bob").lastName("The Builder").emailAddress("bob@example.com").build());
|
||||
project = Project.builder().title("Some title").projectType(projectType).startDate(LocalDate.now()).headSupervisor(supervisor).build();
|
||||
save(project);
|
||||
user = User.builder().firstName("Stina").lastName("Student").emailAddress("stina@example.com").build();
|
||||
save(user);
|
||||
author = User.builder().firstName("Stina").lastName("Student").emailAddress("stina@example.com").build();
|
||||
save(author);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadThread() {
|
||||
final ProjectThread thread = service.createThread(project, user, "subject", "content", Set.of());
|
||||
final ProjectThread thread = service.createThread(project, author, "subject", "content", Set.of());
|
||||
ProjectThread serviceThread = service.findOne(thread.getId());
|
||||
|
||||
assertEquals(thread, serviceThread);
|
||||
@ -55,17 +57,17 @@ public class ProjectForumServiceImplTest extends ForumModuleTest {
|
||||
public void testCreateThreadWithPostAttachment() throws Exception {
|
||||
final String file = "attachment.txt";
|
||||
try (var is = ProjectForumServiceImplTest.class.getResourceAsStream(file)) {
|
||||
final StreamingUpload upload = new StreamingUpload(file, "text/plain", user, 2, is);
|
||||
final ProjectThread thread = service.createThread(project, user, SUBJECT, CONTENT, Set.of(Attachment.newUpload(upload)));
|
||||
final StreamingUpload upload = new StreamingUpload(file, "text/plain", author, 2, is);
|
||||
final ProjectThread thread = service.createThread(project, author, SUBJECT, CONTENT, Set.of(Attachment.newUpload(upload)));
|
||||
|
||||
assertNewForumThread(thread, project, user, SUBJECT, CONTENT, file);
|
||||
assertNewForumThread(thread, project, author, SUBJECT, CONTENT, file);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPostPageByForumThread() {
|
||||
final ProjectThread thread = service.createThread(project, user, "subject", "content", Set.of());
|
||||
final ForumPost reply = service.createReply(thread, user, "reply", Set.of());
|
||||
final ProjectThread thread = service.createThread(project, author, "subject", "content", Set.of());
|
||||
final ForumPost reply = service.createReply(thread, author, "reply", Set.of());
|
||||
|
||||
|
||||
List<ForumPost> servicePage = service.getPosts(thread);
|
||||
@ -76,8 +78,8 @@ public class ProjectForumServiceImplTest extends ForumModuleTest {
|
||||
|
||||
@Test
|
||||
public void testGetThreadsByProject() {
|
||||
final ProjectThread thread1 = service.createThread(project, user, "subject 1", "content", Set.of());
|
||||
final ProjectThread thread2 = service.createThread(project, user, "subject 2", "content", Set.of());
|
||||
final ProjectThread thread1 = service.createThread(project, author, "subject 1", "content", Set.of());
|
||||
final ProjectThread thread2 = service.createThread(project, author, "subject 2", "content", Set.of());
|
||||
|
||||
List<ProjectThread> serviceThreads = service.getThreads(project);
|
||||
|
||||
@ -86,6 +88,16 @@ public class ProjectForumServiceImplTest extends ForumModuleTest {
|
||||
assertThat(serviceThreads, hasSize(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supervisor_has_unread_forum_threads_after_student_replies() {
|
||||
final ProjectThread thread = service.createThread(project, supervisor, "subject", "content", Set.of());
|
||||
service.createReply(thread, author, "reply", Set.of());
|
||||
|
||||
boolean hasUnreadThreads = service.hasUnreadThreads(project, supervisor);
|
||||
|
||||
assertTrue(hasUnreadThreads);
|
||||
}
|
||||
|
||||
private void assertNewForumThread(
|
||||
ProjectThread thread, Project project, User user, String subject, String content, String attachmentFileName) {
|
||||
assertEquals(project, thread.getProject(), "Thread created for the wrong project");
|
||||
|
@ -20,7 +20,7 @@ public abstract class AbstractReadStatePanel extends Panel {
|
||||
@Override
|
||||
public void onClick(final Optional<AjaxRequestTarget> target) {
|
||||
target.ifPresent(t -> {
|
||||
toggleReadState(t);
|
||||
onFlagClick(t);
|
||||
t.add(icon);
|
||||
});
|
||||
}
|
||||
@ -33,7 +33,7 @@ public abstract class AbstractReadStatePanel extends Panel {
|
||||
}
|
||||
|
||||
protected abstract boolean isRead();
|
||||
protected abstract void toggleReadState(final AjaxRequestTarget target);
|
||||
protected abstract void onFlagClick(final AjaxRequestTarget target);
|
||||
|
||||
public static final String TOGGLE = "toggle";
|
||||
static final String ICON = "icon";
|
||||
|
@ -31,7 +31,7 @@ public class ThreadReadStatePanel extends AbstractReadStatePanel {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleReadState(final AjaxRequestTarget target) {
|
||||
protected void onFlagClick(final AjaxRequestTarget target) {
|
||||
boolean read = isRead();
|
||||
basicForumService.setThreadRead(SciProSession.get().getUser(), model.getObject(), !read);
|
||||
|
||||
|
@ -117,7 +117,7 @@ public class NotificationDataPanel extends Panel {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleReadState(final AjaxRequestTarget target) {
|
||||
protected void onFlagClick(final AjaxRequestTarget target) {
|
||||
Notification notification = rowModel.getObject();
|
||||
notification.setUnread(!notification.isUnread());
|
||||
notificationService.save(notification);
|
||||
|
@ -3,7 +3,9 @@ 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;
|
||||
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
|
||||
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;
|
||||
@ -11,6 +13,7 @@ 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.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;
|
||||
@ -21,6 +24,9 @@ import se.su.dsv.scipro.components.datatables.UserColumn;
|
||||
import se.su.dsv.scipro.dataproviders.FilteredDataProvider;
|
||||
import se.su.dsv.scipro.datatables.project.ProjectStateColumn;
|
||||
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.project.Project;
|
||||
import se.su.dsv.scipro.project.ProjectService;
|
||||
import se.su.dsv.scipro.project.ProjectStatus;
|
||||
@ -54,6 +60,8 @@ public class SupervisorMyProjectsPanel extends Panel {
|
||||
private ProjectService projectService;
|
||||
@Inject
|
||||
private UserProfileService profileService;
|
||||
@Inject
|
||||
private ProjectForumService projectForumService;
|
||||
|
||||
private ExportableDataPanel dataPanel;
|
||||
private ProjectService.Filter filter = new ProjectService.Filter();
|
||||
@ -76,6 +84,7 @@ public class SupervisorMyProjectsPanel extends Panel {
|
||||
private List<IColumn<Project, String>> createColumns() {
|
||||
List<IColumn<Project, String>> columns = new ArrayList<>();
|
||||
columns.add(new ProjectStateColumn(Model.of("State"), "stateOfMind"));
|
||||
columns.add(new ProjectForumStateColumn(Model.of("Forum")));
|
||||
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"));
|
||||
@ -177,4 +186,29 @@ public class SupervisorMyProjectsPanel extends Panel {
|
||||
profileService.save(userProfile);
|
||||
}
|
||||
}
|
||||
|
||||
private class ProjectForumStateColumn extends AbstractColumn<Project, String> {
|
||||
public ProjectForumStateColumn(IModel<String> label) {
|
||||
super(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateItem(Item<ICellPopulator<Project>> item, String id, IModel<Project> projectModel) {
|
||||
item.add(new AbstractReadStatePanel(id) {
|
||||
@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()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user