feat: notifications in the app and, optionally, by e-mail
Derived from events and kept per person: whoever a ticket is assigned to, whoever reports or works on it when it moves, fails QA or gets a comment, and whoever joins a project. Never about what you did yourself, once per event. They arrive live through a subscription to a bell in the header, and are copied by e-mail to whoever turns it on when SMTP_URL is set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
37
libs/web/tracker/application/src/lib/events/inbox.events.ts
Normal file
37
libs/web/tracker/application/src/lib/events/inbox.events.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { type } from '@ngrx/signals';
|
||||
import { eventGroup } from '@ngrx/signals/events';
|
||||
import {
|
||||
Notification,
|
||||
NotificationSettings,
|
||||
} from '@task-stream/web/tracker/domain';
|
||||
|
||||
/* Notifications are "the inbox" here, so as not to clash with `Notifications` (the toasts port). */
|
||||
|
||||
export const inboxPageEvents = eventGroup({
|
||||
source: 'Inbox',
|
||||
events: {
|
||||
/** Signed in: load, and follow new ones. */
|
||||
opened: type<void>(),
|
||||
/** Signed out: forget everything. */
|
||||
closed: type<void>(),
|
||||
markReadRequested: type<{ ids?: string[] }>(),
|
||||
emailToggled: type<boolean>(),
|
||||
},
|
||||
});
|
||||
|
||||
export const inboxApiEvents = eventGroup({
|
||||
source: 'Inbox API',
|
||||
events: {
|
||||
loaded: type<{ items: Notification[]; unread: number }>(),
|
||||
settingsLoaded: type<NotificationSettings>(),
|
||||
markedRead: type<{ ids?: string[]; at: string }>(),
|
||||
failed: type<string>(),
|
||||
},
|
||||
});
|
||||
|
||||
export const inboxRealtimeEvents = eventGroup({
|
||||
source: 'Inbox Realtime',
|
||||
events: {
|
||||
arrived: type<Notification>(),
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user