Skip to content

Commit

Permalink
Add convenience methods to Notifier (#76, #77)
Browse files Browse the repository at this point in the history
Co-authored-by: Antonia van Eek <[email protected]>
  • Loading branch information
mbeckem and antoniave authored Nov 19, 2024
1 parent e3802fb commit e4ba048
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 4 deletions.
13 changes: 13 additions & 0 deletions .changeset/many-snails-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@open-pioneer/notifier": minor
---

Introduce new convenience methods on the `NotificationService` in addition to the existing `notify()` method:

```js
const notifier = ...; // injected
notifier.success(/* ... */)
notifier.info(/* ... */)
notifier.warning(/* ... */)
notifier.error(/* ... */)
```
92 changes: 89 additions & 3 deletions src/packages/notifier/NotificationServiceImpl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import { NotificationServiceImpl, Notification } from "./NotificationServiceImpl

it("dispatches events to the notification handler", async () => {
const service = await createService(NotificationServiceImpl, {});

const events: unknown[] = [];

const handlerResource = service.registerHandler({
showNotification(notification: Notification) {
events.push({ type: "notification", notification: notification });
Expand Down Expand Up @@ -51,11 +49,99 @@ it("dispatches events to the notification handler", async () => {
expect(events).toHaveLength(0);
});

it("dispatches events to a later registered notification handler", async () => {
it("dispatches events with convenience methods with object parameter", async () => {
const service = await createService(NotificationServiceImpl, {});
const events: unknown[] = [];
service.registerHandler({
showNotification(notification: Notification) {
events.push(notification);
},
closeAll() {}
});

service.success({ title: "test1" });
service.info({ title: "test2" });
service.warning({ title: "test3" });
service.error({ title: "test4" });

expect(events).toMatchInlineSnapshot(`
[
{
"displayDuration": undefined,
"level": "success",
"message": undefined,
"title": "test1",
},
{
"displayDuration": undefined,
"level": "info",
"message": undefined,
"title": "test2",
},
{
"displayDuration": undefined,
"level": "warning",
"message": undefined,
"title": "test3",
},
{
"displayDuration": undefined,
"level": "error",
"message": undefined,
"title": "test4",
},
]
`);
});

it("dispatches events with convenience methods with string parameter", async () => {
const service = await createService(NotificationServiceImpl, {});
const events: unknown[] = [];
service.registerHandler({
showNotification(notification: Notification) {
events.push(notification);
},
closeAll() {}
});

service.success("test1");
service.info("test2");
service.warning("test3");
service.error("test4");

expect(events).toMatchInlineSnapshot(`
[
{
"displayDuration": undefined,
"level": "success",
"message": "test1",
"title": undefined,
},
{
"displayDuration": undefined,
"level": "info",
"message": "test2",
"title": undefined,
},
{
"displayDuration": undefined,
"level": "warning",
"message": "test3",
"title": undefined,
},
{
"displayDuration": undefined,
"level": "error",
"message": "test4",
"title": undefined,
},
]
`);
});

it("dispatches events to a later registered notification handler", async () => {
const service = await createService(NotificationServiceImpl, {});
const events: unknown[] = [];
service.notify({ title: "test" });
service.closeAll();
service.notify({ title: "test2" });
Expand Down
30 changes: 29 additions & 1 deletion src/packages/notifier/NotificationServiceImpl.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)
// SPDX-License-Identifier: Apache-2.0
import type { NotificationLevel, NotificationOptions, NotificationService } from "./api";
import type {
NotificationLevel,
NotificationOptions,
NotificationService,
SimpleNotificationOptions
} from "./api";
import { Resource, createLogger } from "@open-pioneer/core";
import type { ReactNode } from "react";
const LOG = createLogger("notifier:NotificationService");
Expand Down Expand Up @@ -62,6 +67,29 @@ export class NotificationServiceImpl implements InternalNotificationAPI {
});
}

success(options: SimpleNotificationOptions): void {
this.#sendSimpleNotification("success", options);
}

info(options: SimpleNotificationOptions): void {
this.#sendSimpleNotification("info", options);
}

warning(options: SimpleNotificationOptions): void {
this.#sendSimpleNotification("warning", options);
}

error(options: SimpleNotificationOptions): void {
this.#sendSimpleNotification("error", options);
}

#sendSimpleNotification(level: NotificationLevel, options: SimpleNotificationOptions): void {
if (typeof options === "string") {
options = { message: options };
}
this.notify({ ...options, level });
}

closeAll(): void {
this.#dispatchHandlerMethod("closeAll");
}
Expand Down
21 changes: 21 additions & 0 deletions src/packages/notifier/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ export interface NotificationOptions {
displayDuration?: number | undefined;
}

/**
* Options used when emitting a new notification via {@link NotificationService}
* using convenience methods like `warning` and `error`.
*
* Options can either be an object that is the same as {@link NotificationOptions}, but without the `level` property
* or a string, which will be used as the `message` of the Notification.
*/
export type SimpleNotificationOptions = Omit<NotificationOptions, "level"> | string;

/**
* The `NotificationService` allows any part of the application to emit
* notifications to the user.
Expand All @@ -48,6 +57,18 @@ export interface NotificationService extends DeclaredService<"notifier.Notificat
*/
notify(options: NotificationOptions): void;

/** Emits a success notification. Same as {@link notify} with `type: "success"`. */
success(options: SimpleNotificationOptions): void;

/** Emits an info notification. Same as {@link notify} with `type: "info"`. */
info(options: SimpleNotificationOptions): void;

/** Emits a warning notification. Same as {@link notify} with `type: "warning"`. */
warning(options: SimpleNotificationOptions): void;

/** Emits an error notification. Same as {@link notify} with `type: "error"`. */
error(options: SimpleNotificationOptions): void;

/** Closes all active notifications. */
closeAll(): void;
}

0 comments on commit e4ba048

Please sign in to comment.