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:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-notifications': patch
|
||||
---
|
||||
|
||||
Allow setting notification as read when opening snackbar or web notification link
|
||||
@@ -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;
|
||||
|
||||
+21
-2
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user