Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion component/api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<artifactId>social-component</artifactId>
<groupId>io.meeds.social</groupId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
</parent>
<artifactId>social-component-api</artifactId>
<name>Meeds:: PLF:: Social API</name>
Expand Down
2 changes: 1 addition & 1 deletion component/common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<artifactId>social-component</artifactId>
<groupId>io.meeds.social</groupId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
</parent>
<groupId>io.meeds.social</groupId>
<artifactId>social-component-common</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion component/core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<artifactId>social-component</artifactId>
<groupId>io.meeds.social</groupId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
</parent>
<artifactId>social-component-core</artifactId>
<name>Meeds:: PLF:: Social Core Component</name>
Expand Down
2 changes: 1 addition & 1 deletion component/notification/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<artifactId>social-component</artifactId>
<groupId>io.meeds.social</groupId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
</parent>
<artifactId>social-component-notification</artifactId>
<name>Meeds:: PLF:: Social Notification Component</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,31 @@ public Response getNotifications(
return Response.ok(webNotificationsList).build();
}

@DELETE
@RolesAllowed("users")
@Operation(summary = "Hide notifications", description = "Hides a designated list of notifications", method = "DELETE")
@ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Request fullfilled"),
@ApiResponse(responseCode = "400", description = "Invalid query input"),
@ApiResponse(responseCode = "500", description = "Internal server error") })
public Response hideNotifications(
@Parameter(description = "The list of notification ids to hide", required = true)
@QueryParam("id")
List<String> notificationIds) {
String currentUser = ConversationState.getCurrent().getIdentity().getUserId();
if (notificationIds == null || notificationIds.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
for (String notificationId : notificationIds) {
NotificationInfo notification = webNftService.getNotificationInfo(notificationId);
if (notification != null && currentUser.equals(notification.getTo())) {
webNftService.hidePopover(notificationId);
} else {
LOG.warn("User {} is not allowed to hide notification {}", currentUser, notificationId);
}
}
return Response.noContent().build();
}

@DELETE
@Path("{id}")
@RolesAllowed("users")
Expand Down Expand Up @@ -183,6 +208,9 @@ public Response updateNotifications(
@Parameter(description = "The list of plugins to include in list", required = false)
@QueryParam("plugin")
List<String> plugins,
@Parameter(description = "The list of notification ids to update, used by the markAsRead operation", required = false)
@QueryParam("id")
List<String> notificationIds,
@Parameter(description = "notification operation", required = true)
@QueryParam("operation")
String operation) {
Expand All @@ -192,6 +220,18 @@ public Response updateNotifications(
} else if (MARK_ALL_AS_READ_OPERATION.equals(operation)) {
webNftService.markAllRead(plugins, currentUser);
webNftService.resetNumberOnBadge(plugins, currentUser);
} else if (MARK_AS_READ_OPERATION.equals(operation)) {
if (notificationIds == null || notificationIds.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
for (String notificationId : notificationIds) {
NotificationInfo notification = webNftService.getNotificationInfo(notificationId);
if (notification != null && currentUser.equals(notification.getTo())) {
webNftService.markRead(notificationId);
} else {
LOG.warn("User {} is not allowed to mark notification {} as read", currentUser, notificationId);
}
}
} else {
return Response.status(Response.Status.BAD_REQUEST).entity("Unrecognized operation parameter value: " + operation).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Collections;
import java.util.List;

import javax.ws.rs.core.Response;

import org.mockito.Mock;
Expand Down Expand Up @@ -113,6 +118,92 @@ public void testAuthorizedHide() {

}

public void testBatchMarkAsReadAuthorized() {
startSessionAs("john");

webNotificationService = mock(WebNotificationService.class);
NotificationInfo notificationInfo = new NotificationInfo();
notificationInfo.setTo("john");
when(webNotificationService.getNotificationInfo(anyString())).thenReturn(notificationInfo);

WebNotificationRestService webNotificationRestService = newWebNotificationRestService();
Response response = webNotificationRestService.updateNotifications(null, List.of("1", "2"), "markAsRead");

assertEquals(204, response.getStatus());
verify(webNotificationService).markRead("1");
verify(webNotificationService).markRead("2");
}

public void testBatchMarkAsReadSkipsNotOwned() {
startSessionAs("john");

webNotificationService = mock(WebNotificationService.class);
NotificationInfo notificationInfo = new NotificationInfo();
notificationInfo.setTo("mary");
when(webNotificationService.getNotificationInfo(anyString())).thenReturn(notificationInfo);

WebNotificationRestService webNotificationRestService = newWebNotificationRestService();
Response response = webNotificationRestService.updateNotifications(null, List.of("1"), "markAsRead");

assertEquals(204, response.getStatus());
verify(webNotificationService, never()).markRead(anyString());
}

public void testBatchMarkAsReadEmptyIds() {
startSessionAs("john");

webNotificationService = mock(WebNotificationService.class);

WebNotificationRestService webNotificationRestService = newWebNotificationRestService();
Response response = webNotificationRestService.updateNotifications(null, Collections.emptyList(), "markAsRead");

assertEquals(400, response.getStatus());
verify(webNotificationService, never()).markRead(anyString());
}

public void testBatchHideAuthorized() {
startSessionAs("john");

webNotificationService = mock(WebNotificationService.class);
NotificationInfo notificationInfo = new NotificationInfo();
notificationInfo.setTo("john");
when(webNotificationService.getNotificationInfo(anyString())).thenReturn(notificationInfo);

WebNotificationRestService webNotificationRestService = newWebNotificationRestService();
Response response = webNotificationRestService.hideNotifications(List.of("1", "2"));

assertEquals(204, response.getStatus());
verify(webNotificationService).hidePopover("1");
verify(webNotificationService).hidePopover("2");
}

public void testBatchHideSkipsNotOwned() {
startSessionAs("john");

webNotificationService = mock(WebNotificationService.class);
NotificationInfo notificationInfo = new NotificationInfo();
notificationInfo.setTo("mary");
when(webNotificationService.getNotificationInfo(anyString())).thenReturn(notificationInfo);

WebNotificationRestService webNotificationRestService = newWebNotificationRestService();
Response response = webNotificationRestService.hideNotifications(List.of("1"));

assertEquals(204, response.getStatus());
verify(webNotificationService, never()).hidePopover(anyString());
}

public void testBatchHideEmptyIds() {
startSessionAs("john");

webNotificationService = mock(WebNotificationService.class);

WebNotificationRestService webNotificationRestService = newWebNotificationRestService();
Response response = webNotificationRestService.hideNotifications(Collections.<String> emptyList());

assertEquals(400, response.getStatus());
verify(webNotificationService, never()).hidePopover(anyString());
}

private void startSessionAs(String username) {
Identity identity = new Identity(username);
ConversationState state = new ConversationState(identity);
Expand Down
2 changes: 1 addition & 1 deletion component/oauth-auth/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<artifactId>social-component</artifactId>
<groupId>io.meeds.social</groupId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
2 changes: 1 addition & 1 deletion component/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<artifactId>social</artifactId>
<groupId>io.meeds.social</groupId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
</parent>
<artifactId>social-component</artifactId>
<packaging>pom</packaging>
Expand Down
2 changes: 1 addition & 1 deletion component/service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<artifactId>social-component</artifactId>
<groupId>io.meeds.social</groupId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
</parent>
<artifactId>social-component-service</artifactId>
<name>Meeds:: PLF:: Social Service Component</name>
Expand Down
2 changes: 1 addition & 1 deletion component/web/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<artifactId>social-component</artifactId>
<groupId>io.meeds.social</groupId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
</parent>
<groupId>io.meeds.social</groupId>
<artifactId>social-component-web</artifactId>
Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</parent>
<groupId>io.meeds.social</groupId>
<artifactId>social</artifactId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Meeds:: PLF:: Social</name>
<description>Meeds Social - Enterprise Social Networking</description>
Expand All @@ -45,8 +45,8 @@
<!-- **************************************** -->
<!-- Project Dependencies -->
<!-- **************************************** -->
<io.meeds.commons.version>7.3.x-SNAPSHOT</io.meeds.commons.version>
<io.meeds.platform-ui.version>7.3.x-SNAPSHOT</io.meeds.platform-ui.version>
<io.meeds.commons.version>7.3.x-ai-contribution-SNAPSHOT</io.meeds.commons.version>
<io.meeds.platform-ui.version>7.3.x-ai-contribution-SNAPSHOT</io.meeds.platform-ui.version>

<!-- Sonar properties -->
<sonar.organization>meeds-io</sonar.organization>
Expand Down
2 changes: 1 addition & 1 deletion webapp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<groupId>io.meeds.social</groupId>
<artifactId>social</artifactId>
<version>7.3.x-SNAPSHOT</version>
<version>7.3.x-ai-contribution-SNAPSHOT</version>
</parent>
<artifactId>social-webapp</artifactId>
<packaging>war</packaging>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,9 @@ Notification.activity.stopWatching=Stop watching this activity
Notification.openInNewWindow=Open in a new tab
Notification.markRead=Mark as read
Notification.deleteNotification=Delete notification
Notification.select=Select
Notification.label.selectAll=Select all
Notification.label.selectedCount={0} selected
Notification.muteSpaceNotification=Mute notifications from this space
Notification.tooltip.muteSpaceNotification=Mute this space
Notification.tooltip.unmuteSpaceNotification=Unmute this space
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,9 @@ Notification.activity.stopWatching=Arrêter de suivre cette activité
Notification.openInNewWindow=Ouvrir dans un nouvel onglet
Notification.markRead=Marqué comme lu
Notification.deleteNotification=Supprimer la notification
Notification.select=Sélectionner
Notification.label.selectAll=Tout sélectionner
Notification.label.selectedCount={0} sélectionné(s)
Notification.muteSpaceNotification=Désactiver les notifications issues de cet espace
Notification.tooltip.muteSpaceNotification=Mettre en sourdine cet espace
Notification.tooltip.unmuteSpaceNotification=Réactiver les notifications de cet espace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
class="flex-column justify-center">
<v-card
v-if="display"
:class="isMobile && 'overflow-x-auto specific-scrollbar'"
:class="(isMobile || scrollable) && 'overflow-x-auto specific-scrollbar'"
class="d-flex align-center transparent"
min-height="34"
flat>
Expand All @@ -44,6 +44,7 @@
v-if="displayChipsSelection"
:categories="selectedSubcategories"
:selected-id="value"
:scrollable="scrollable"
class="flex-grow-1 flex-shrink-1 text-start"
@select="selectCategory"
@open-more="openMore" />
Expand Down Expand Up @@ -96,6 +97,12 @@ export default {
type: Boolean,
default: false,
},
// Lay the filter's chips out in a horizontally scrollable row (mobile behaviour)
// whatever the viewport width, for use in narrow containers such as side drawers.
scrollable: {
type: Boolean,
default: false,
},
},
data: () => ({
categoryTree: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
-->
<template>
<div
:class="!isMobile && 'specific-scrollbar overflow-x-auto overflow-y-hidden'"
:class="[(!isMobile || scrollable) && 'specific-scrollbar overflow-x-auto overflow-y-hidden', scrollable && 'category-chips-thin-scrollbar']"
class="d-flex align-center position-relative d-inline text-no-wrap">
<component
v-if="initialized"
:is="isMobile ? 'div' : 'card-carousel'"
class="flex-grow-0 flex-shrink-1 overflow-hidden"
:is="(isMobile || scrollable) ? 'div' : 'card-carousel'"
:class="scrollable ? 'flex-grow-0 flex-shrink-0' : 'flex-grow-0 flex-shrink-1 overflow-hidden'"
hide-arrows
dense>
<category-chip
Expand All @@ -43,7 +43,7 @@
@select="openCategory" />
</component>
<v-btn
v-if="!isMobile"
v-if="!isMobile && !scrollable"
ref="moreButton"
:class="{
'invisible' : !hasInvisibleItems,
Expand All @@ -69,6 +69,13 @@ export default {
type: Number,
default: () => 0,
},
// When true, always lay the chips out in a horizontally scrollable row (the
// mobile behaviour) instead of the desktop carousel with a "See all" overflow
// button — useful in narrow containers such as side drawers.
scrollable: {
type: Boolean,
default: false,
},
},
data: () => ({
resizeObserver: null,
Expand Down Expand Up @@ -167,4 +174,21 @@ export default {
},
},
};
</script>
</script>
<style lang="scss">
/* A thin, subtle horizontal scrollbar for the scrollable (mobile-like) chips row,
used in narrow containers such as side drawers. */
.category-chips-thin-scrollbar {
scrollbar-width: thin;
&::-webkit-scrollbar {
height: 3px;
}
&::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.16);
border-radius: 3px;
}
&::-webkit-scrollbar-track {
background: transparent;
}
}
</style>
Loading
Loading