feat: allow setting notification read from web/snackbar

when opening link from snackbar or web notification, the notification
can be automatically set as read like in the notifications page

Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
Heikki Hellgren
2024-04-30 11:49:36 +03:00
parent ee9e1737b3
commit 0410fc9ce6
4 changed files with 51 additions and 6 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-notifications': patch
---
Allow setting notification as read when opening snackbar or web notification link
+5 -1
View File
@@ -103,6 +103,7 @@ export const NotificationsSidebarItem: (props?: {
titleCounterEnabled?: boolean;
snackbarEnabled?: boolean;
snackbarAutoHideDuration?: number | null;
markAsReadOnLinkOpen?: boolean;
className?: string;
icon?: IconComponent;
text?: string;
@@ -182,7 +183,10 @@ export function useTitleCounter(): {
};
// @public (undocumented)
export function useWebNotifications(enabled: boolean): {
export function useWebNotifications(
enabled: boolean,
markAsReadOnLinkOpen: boolean,
): {
sendWebNotification: (options: {
id: string;
title: string;
@@ -84,6 +84,7 @@ export const NotificationsSidebarItem = (props?: {
titleCounterEnabled?: boolean;
snackbarEnabled?: boolean;
snackbarAutoHideDuration?: number | null;
markAsReadOnLinkOpen?: boolean;
className?: string;
icon?: IconComponent;
text?: string;
@@ -95,6 +96,7 @@ export const NotificationsSidebarItem = (props?: {
titleCounterEnabled = true,
snackbarEnabled = true,
snackbarAutoHideDuration = 10000,
markAsReadOnLinkOpen = false,
icon = NotificationsIcon,
text = 'Notifications',
...restProps
@@ -103,6 +105,7 @@ export const NotificationsSidebarItem = (props?: {
titleCounterEnabled: true,
snackbarEnabled: true,
snackbarAutoHideDuration: 10000,
markAsReadOnLinkOpen: false,
};
const { loading, error, value, retry } = useNotificationsApi(api =>
@@ -114,7 +117,10 @@ export const NotificationsSidebarItem = (props?: {
const notificationsRoute = useRouteRef(rootRouteRef);
// TODO: Do we want to add long polling in case signals are not available
const { lastSignal } = useSignal<NotificationSignal>('notifications');
const { sendWebNotification } = useWebNotifications(webNotificationsEnabled);
const { sendWebNotification } = useWebNotifications(
webNotificationsEnabled,
markAsReadOnLinkOpen,
);
const [refresh, setRefresh] = React.useState(false);
const { setNotificationCount } = useTitleCounter();
@@ -126,6 +132,19 @@ export const NotificationsSidebarItem = (props?: {
component={Link}
to={notification.payload.link ?? notificationsRoute()}
onClick={() => {
if (markAsReadOnLinkOpen) {
notificationsApi
.updateNotifications({
ids: [notification.id],
read: true,
})
.catch(() => {
alertApi.post({
message: 'Failed to mark notification as read',
severity: 'error',
});
});
}
closeSnackbar(snackBarId);
}}
>
@@ -156,7 +175,7 @@ export const NotificationsSidebarItem = (props?: {
return { action };
},
[notificationsRoute, notificationsApi, alertApi],
[notificationsRoute, markAsReadOnLinkOpen, notificationsApi, alertApi],
);
useEffect(() => {
@@ -15,14 +15,19 @@
*/
import { useCallback, useEffect, useState } from 'react';
import { rootRouteRef } from '../routes';
import { useRouteRef } from '@backstage/core-plugin-api';
import { useApi, useRouteRef } from '@backstage/core-plugin-api';
import { useNavigate } from 'react-router-dom';
import { notificationsApiRef } from '../api';
/** @public */
export function useWebNotifications(enabled: boolean) {
export function useWebNotifications(
enabled: boolean,
markAsReadOnLinkOpen: boolean,
) {
const [webNotificationPermission, setWebNotificationPermission] =
useState('default');
const notificationsRoute = useRouteRef(rootRouteRef);
const notificationsApi = useApi(notificationsApiRef);
const navigate = useNavigate();
useEffect(() => {
@@ -57,6 +62,12 @@ export function useWebNotifications(enabled: boolean) {
event.preventDefault();
if (options.link) {
window.open(options.link, '_blank');
if (markAsReadOnLinkOpen) {
notificationsApi.updateNotifications({
ids: [options.id],
read: true,
});
}
} else {
navigate(notificationsRoute());
}
@@ -65,7 +76,13 @@ export function useWebNotifications(enabled: boolean) {
return notification;
},
[webNotificationPermission, navigate, notificationsRoute],
[
webNotificationPermission,
markAsReadOnLinkOpen,
notificationsApi,
navigate,
notificationsRoute,
],
);
return { sendWebNotification };