Merge pull request #24557 from drodil/notification_mark_read2

feat: allow setting notification read also from web notifications
This commit is contained in:
Fredrik Adelöw
2024-08-07 13:31:17 +02:00
committed by GitHub
6 changed files with 38 additions and 24 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-notifications': minor
---
By default, set notification as read when opening snackbar or web notification link
-15
View File
@@ -176,20 +176,5 @@ export function useNotificationsApi<T>(
value: T;
};
// @public (undocumented)
export function useTitleCounter(): {
setNotificationCount: (newCount: number) => void;
};
// @public (undocumented)
export function useWebNotifications(enabled: boolean): {
sendWebNotification: (options: {
id: string;
title: string;
description: string;
link?: string;
}) => Notification | null;
};
// (No @packageDocumentation comment for this package)
```
@@ -114,7 +114,9 @@ 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, requestUserPermission } = useWebNotifications(
webNotificationsEnabled,
);
const [refresh, setRefresh] = React.useState(false);
const { setNotificationCount } = useTitleCounter();
@@ -126,6 +128,19 @@ export const NotificationsSidebarItem = (props?: {
component={Link}
to={notification.payload.link ?? notificationsRoute()}
onClick={() => {
if (notification.payload.link) {
notificationsApi
.updateNotifications({
ids: [notification.id],
read: true,
})
.catch(() => {
alertApi.post({
message: 'Failed to mark notification as read',
severity: 'error',
});
});
}
closeSnackbar(snackBarId);
}}
>
@@ -259,6 +274,9 @@ export const NotificationsSidebarItem = (props?: {
)}
<SidebarItem
to={notificationsRoute()}
onClick={() => {
requestUserPermission();
}}
hasNotifications={!error && !!unreadCount}
text={text}
icon={icon}
@@ -25,7 +25,7 @@ const throttledSetTitle = throttle((shownTitle: string) => {
document.title = shownTitle;
}, 100);
/** @public */
/** @internal */
export function useTitleCounter() {
const [title, setTitle] = useState(document.title);
const [count, setCount] = useState(0);
@@ -13,19 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useCallback, useEffect, useState } from 'react';
import { useCallback, 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 */
/** @internal */
export function useWebNotifications(enabled: boolean) {
const [webNotificationPermission, setWebNotificationPermission] =
useState('default');
const notificationsRoute = useRouteRef(rootRouteRef);
const notificationsApi = useApi(notificationsApiRef);
const navigate = useNavigate();
useEffect(() => {
const requestUserPermission = useCallback(() => {
if (
enabled &&
'Notification' in window &&
@@ -57,6 +59,10 @@ export function useWebNotifications(enabled: boolean) {
event.preventDefault();
if (options.link) {
window.open(options.link, '_blank');
notificationsApi.updateNotifications({
ids: [options.id],
read: true,
});
} else {
navigate(notificationsRoute());
}
@@ -65,8 +71,8 @@ export function useWebNotifications(enabled: boolean) {
return notification;
},
[webNotificationPermission, navigate, notificationsRoute],
[webNotificationPermission, notificationsApi, navigate, notificationsRoute],
);
return { sendWebNotification };
return { sendWebNotification, requestUserPermission };
}
+1 -1
View File
@@ -15,5 +15,5 @@
*/
export { notificationsPlugin, NotificationsPage } from './plugin';
export * from './api';
export * from './hooks';
export { useNotificationsApi } from './hooks';
export * from './components';