feat: support pagination and searching in notification backend

disabled broadcast notifications for now

Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
Heikki Hellgren
2024-02-01 21:19:45 +02:00
parent 50c7dbde2f
commit b3c3672b64
13 changed files with 124 additions and 56 deletions
@@ -29,6 +29,9 @@ export const notificationsApiRef = createApiRef<NotificationsApi>({
/** @public */
export type GetNotificationsOptions = {
type?: NotificationType;
offset?: number;
limit?: number;
search?: string;
};
/** @public */
@@ -42,6 +42,15 @@ export class NotificationsClient implements NotificationsApi {
if (options?.type) {
queryString.append('type', options.type);
}
if (options?.limit) {
queryString.append('limit', options.limit.toString(10));
}
if (options?.offset) {
queryString.append('offset', options.offset.toString(10));
}
if (options?.search) {
queryString.append('search', options.search);
}
const urlSegment = `notifications?${queryString}`;
@@ -54,7 +54,7 @@ export const NotificationsPage = () => {
const { lastSignal } = useSignal('notifications');
useEffect(() => {
if (lastSignal && lastSignal.action === 'refresh') {
if (lastSignal && lastSignal.action) {
setRefresh(true);
}
}, [lastSignal]);
@@ -68,7 +68,6 @@ export const NotificationsPage = () => {
return <ErrorPanel error={new Error('Failed to load notifications')} />;
}
// TODO: Add signals listener and refresh data on message
return (
<PageWithHeader title="Notifications" themeId="tool">
<Content>
@@ -22,6 +22,7 @@ import { rootRouteRef } from '../../routes';
import { useSignal } from '@backstage/plugin-signals-react';
import { useWebNotifications } from '../../hooks/useWebNotifications';
import { useTitleCounter } from '../../hooks/useTitleCounter';
import { JsonObject } from '@backstage/types';
/** @public */
export const NotificationsSidebarItem = () => {
@@ -31,6 +32,8 @@ export const NotificationsSidebarItem = () => {
const config = useApi(configApiRef);
const [unreadCount, setUnreadCount] = React.useState(0);
const notificationsRoute = useRouteRef(rootRouteRef);
// TODO: Add signal type support to `useSignal` to make it a bit easier to use
// TODO: Do we want to add long polling in case signals are not available
const { lastSignal } = useSignal('notifications');
const { sendWebNotification } = useWebNotifications();
const [refresh, setRefresh] = React.useState(false);
@@ -54,25 +57,36 @@ export const NotificationsSidebarItem = () => {
}, [refresh, retry]);
useEffect(() => {
if (lastSignal && lastSignal.action === 'refresh') {
if (
webNotificationsEnabled &&
'title' in lastSignal &&
'description' in lastSignal &&
'link' in lastSignal
) {
const notification = sendWebNotification({
title: lastSignal.title as string,
description: lastSignal.description as string,
});
if (notification) {
notification.onclick = event => {
event.preventDefault();
notification.close();
window.open(lastSignal.link as string, '_blank');
};
}
const handleWebNotification = (signal: JsonObject) => {
if (!webNotificationsEnabled || !('notification' in signal)) {
return;
}
const notificationData = signal.notification as JsonObject;
if (
!notificationData ||
!('title' in notificationData) ||
!('description' in notificationData) ||
!('title' in notificationData)
) {
return;
}
const notification = sendWebNotification({
title: notificationData.title as string,
description: notificationData.description as string,
});
if (notification) {
notification.onclick = event => {
event.preventDefault();
notification.close();
window.open(notificationData.link as string, '_blank');
};
}
};
if (lastSignal && lastSignal.action) {
handleWebNotification(lastSignal);
setRefresh(true);
}
}, [lastSignal, sendWebNotification, webNotificationsEnabled]);