From b6c1523444b95ef512662b740724ca9a5483cb84 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Mon, 18 Dec 2023 09:00:32 +0200 Subject: [PATCH] feat: add support for notification processors Signed-off-by: Heikki Hellgren --- plugins/notifications-node/api-report.md | 10 ++++ .../src/service/NotificationProcessor.ts | 34 ++++++++++++ .../src/service/NotificationService.ts | 52 +++++++++++++------ .../notifications-node/src/service/index.ts | 1 + .../NotificationsTable/NotificationsTable.tsx | 5 +- 5 files changed, 85 insertions(+), 17 deletions(-) create mode 100644 plugins/notifications-node/src/service/NotificationProcessor.ts diff --git a/plugins/notifications-node/api-report.md b/plugins/notifications-node/api-report.md index 4cfe35233e..7762d41550 100644 --- a/plugins/notifications-node/api-report.md +++ b/plugins/notifications-node/api-report.md @@ -51,6 +51,12 @@ export type NotificationModifyOptions = { ids: string[]; } & NotificationGetOptions; +// @public (undocumented) +export type NotificationProcessor = { + decorate?(notification: Notification_2): Promise; + send?(notification: Notification_2): Promise; +}; + // @public (undocumented) export type NotificationSendOptions = { entityRef: string | string[]; @@ -63,10 +69,13 @@ export type NotificationSendOptions = { // @public (undocumented) export class NotificationService { + // (undocumented) + addProcessor(processor: NotificationProcessor): this; // (undocumented) static create({ database, discovery, + processors, }: NotificationServiceOptions): NotificationService; // (undocumented) getStore(): Promise; @@ -81,6 +90,7 @@ export const notificationService: ServiceRef; export type NotificationServiceOptions = { database: PluginDatabaseManager; discovery: PluginEndpointDiscovery; + processors?: NotificationProcessor[]; }; // @public (undocumented) diff --git a/plugins/notifications-node/src/service/NotificationProcessor.ts b/plugins/notifications-node/src/service/NotificationProcessor.ts new file mode 100644 index 0000000000..57fe648f30 --- /dev/null +++ b/plugins/notifications-node/src/service/NotificationProcessor.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Notification } from '@backstage/plugin-notifications-common'; + +/** @public */ +export type NotificationProcessor = { + /** + * Decorate notification before sending it + * + * @param notification - The notification to decorate + * @returns The same notification or a modified version of it + */ + decorate?(notification: Notification): Promise; + + /** + * Send notification using this processor. + * + * @param notification - The notification to send + */ + send?(notification: Notification): Promise; +}; diff --git a/plugins/notifications-node/src/service/NotificationService.ts b/plugins/notifications-node/src/service/NotificationService.ts index 029df83185..288da01dc4 100644 --- a/plugins/notifications-node/src/service/NotificationService.ts +++ b/plugins/notifications-node/src/service/NotificationService.ts @@ -32,11 +32,13 @@ import { PluginEndpointDiscovery, } from '@backstage/backend-common'; import { DatabaseNotificationsStore } from '../database'; +import { NotificationProcessor } from './NotificationProcessor'; /** @public */ export type NotificationServiceOptions = { database: PluginDatabaseManager; discovery: PluginEndpointDiscovery; + processors?: NotificationProcessor[]; }; /** @public */ @@ -52,21 +54,31 @@ export type NotificationSendOptions = { /** @public */ export class NotificationService { private store: NotificationsStore | null = null; + private readonly processors: NotificationProcessor[]; private constructor( private readonly database: PluginDatabaseManager, private readonly catalog: CatalogApi, - ) {} + processors?: NotificationProcessor[], + ) { + this.processors = processors ?? []; + } static create({ database, discovery, + processors, }: NotificationServiceOptions): NotificationService { const catalogClient = new CatalogClient({ discoveryApi: discovery, }); - return new NotificationService(database, catalogClient); + return new NotificationService(database, catalogClient, processors); + } + + addProcessor(processor: NotificationProcessor) { + this.processors.push(processor); + return this; } async send(options: NotificationSendOptions): Promise { @@ -80,27 +92,35 @@ export class NotificationService { } const store = await this.getStore(); + const baseNotification = { + id: uuid(), + title, + description, + link, + created: new Date(), + icon, + image, + saved: false, + }; for (const user of users) { - const notification = { - id: uuid(), - userRef: user, - title, - description, - link, - created: new Date(), - icon, - image, - saved: false, - }; + let notification: Notification = { ...baseNotification, userRef: user }; + for (const processor of this.processors) { + notification = processor.decorate + ? await processor.decorate(notification) + : notification; + } await store.saveNotification(notification); + for (const processor of this.processors) { + if (processor.send) { + processor.send(notification); + } + } notifications.push(notification); + // TODO: Signal service } - // TODO: Signal service - // TODO: Other senders - return notifications; } diff --git a/plugins/notifications-node/src/service/index.ts b/plugins/notifications-node/src/service/index.ts index 450f4f7dcc..718e9a5567 100644 --- a/plugins/notifications-node/src/service/index.ts +++ b/plugins/notifications-node/src/service/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export * from './NotificationService'; +export * from './NotificationProcessor'; diff --git a/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx b/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx index 68df969db6..acdb2b8b59 100644 --- a/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx +++ b/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx @@ -173,7 +173,10 @@ export const NotificationsTable = (props: { {props.notifications?.map(notification => { return ( - +