@memberjunction/ng-notifications 5.11.0 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -49,8 +49,14 @@ export declare class MJNotificationService {
|
|
|
49
49
|
*/
|
|
50
50
|
CreateNotification(title: string, message: string, resourceTypeId: string | null, resourceRecordId: string | null, resourceConfiguration: any | null, displayToUser?: boolean): Promise<MJUserNotificationEntity>;
|
|
51
51
|
/**
|
|
52
|
-
* Refresh
|
|
53
|
-
*
|
|
52
|
+
* Refresh user notifications and re-emit to observables.
|
|
53
|
+
*
|
|
54
|
+
* Uses RefreshItem() to guarantee fresh data from the server. The global
|
|
55
|
+
* CACHE_INVALIDATION listener keeps the engine cache updated for background
|
|
56
|
+
* changes, but when this method is called in response to a PushStatusUpdates
|
|
57
|
+
* message, the cache invalidation event may not have arrived yet (separate
|
|
58
|
+
* WebSocket message, potential race). RefreshItem() eliminates that race by
|
|
59
|
+
* doing a targeted RunView for just notifications.
|
|
54
60
|
*/
|
|
55
61
|
static RefreshUserNotifications(): Promise<void>;
|
|
56
62
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.service.d.ts","sourceRoot":"","sources":["../../src/lib/notifications.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAGzF,OAAO,EAAE,mBAAmB,EAAwB,MAAM,sCAAsC,CAAC;AACjG,OAAO,EAAmB,UAAU,EAAW,MAAM,MAAM,CAAC;;AAE5D;;;GAGG;AACH,qBAGa,qBAAqB;IAYpB,OAAO,CAAC,mBAAmB;IAXvC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAwB;IAChD,OAAO,CAAC,MAAM,CAAC,OAAO,CAAkB;IAExC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAuC;IAChE,OAAO,CAAC,SAAS,CAAiB;IAClC,UAAU,sBAAiC;IAG3C,OAAO,CAAC,MAAM,CAAC,eAAe,CAAuD;IACrF,OAAO,CAAC,MAAM,CAAC,aAAa,CAAkC;gBAE1C,mBAAmB,EAAE,mBAAmB;
|
|
1
|
+
{"version":3,"file":"notifications.service.d.ts","sourceRoot":"","sources":["../../src/lib/notifications.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAGzF,OAAO,EAAE,mBAAmB,EAAwB,MAAM,sCAAsC,CAAC;AACjG,OAAO,EAAmB,UAAU,EAAW,MAAM,MAAM,CAAC;;AAE5D;;;GAGG;AACH,qBAGa,qBAAqB;IAYpB,OAAO,CAAC,mBAAmB;IAXvC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAwB;IAChD,OAAO,CAAC,MAAM,CAAC,OAAO,CAAkB;IAExC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAuC;IAChE,OAAO,CAAC,SAAS,CAAiB;IAClC,UAAU,sBAAiC;IAG3C,OAAO,CAAC,MAAM,CAAC,eAAe,CAAuD;IACrF,OAAO,CAAC,MAAM,CAAC,aAAa,CAAkC;gBAE1C,mBAAmB,EAAE,mBAAmB;IA2ErD,iBAAiB,IAAI,UAAU,CAAC,MAAM,CAAC;IAK9C,WAAkB,QAAQ,IAAI,qBAAqB,CAElD;IAED,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAkC;IACnE,WAAkB,iBAAiB,IAAI,wBAAwB,EAAE,CAEhE;IACD,WAAkB,uBAAuB,IAAI,wBAAwB,EAAE,CAEtE;IACD,WAAkB,2BAA2B,IAAI,MAAM,CAEtD;IAED;;OAEG;IACH,WAAkB,cAAc,IAAI,UAAU,CAAC,wBAAwB,EAAE,CAAC,CAEzE;IAED;;OAEG;IACH,WAAkB,YAAY,IAAI,UAAU,CAAC,MAAM,CAAC,CAEnD;IAED;;OAEG;IACH,IAAW,cAAc,IAAI,UAAU,CAAC,wBAAwB,EAAE,CAAC,CAElE;IAED;;OAEG;IACH,IAAW,YAAY,IAAI,UAAU,CAAC,MAAM,CAAC,CAE5C;IAGD;;;;;;;;OAQG;IACU,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI,EAAE,qBAAqB,EAAE,GAAG,GAAG,IAAI,EAAE,aAAa,GAAE,OAAc,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAyBpO;;;;;;;;;OASG;WACiB,wBAAwB;IAc5C;;;;OAIG;WACW,6BAA6B;IAK3C;;;;;OAKG;IACI,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAkB,EAAE,SAAS,CAAC,EAAE,MAAM;yCAlN9H,qBAAqB;6CAArB,qBAAqB;CAiOjC"}
|
|
@@ -43,6 +43,16 @@ export class MJNotificationService {
|
|
|
43
43
|
case MJEventType.LoggedIn:
|
|
44
44
|
if (MJNotificationService._loaded === false)
|
|
45
45
|
MJNotificationService.RefreshUserNotifications();
|
|
46
|
+
// Subscribe to UserInfoEngine's DataChange$ so that when CACHE_INVALIDATION
|
|
47
|
+
// updates the _UserNotifications array, we immediately sync our BehaviorSubjects.
|
|
48
|
+
// This is the primary mechanism for real-time notification updates — it fires
|
|
49
|
+
// whenever BaseEngine processes a remote-invalidate event for User Notifications.
|
|
50
|
+
UserInfoEngine.Instance.DataChange$.subscribe(event => {
|
|
51
|
+
if (event.config.PropertyName === '_UserNotifications') {
|
|
52
|
+
MJNotificationService._userNotifications = UserInfoEngine.Instance.UserNotifications;
|
|
53
|
+
MJNotificationService.UpdateNotificationObservables();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
46
56
|
// got the login, now subscribe to push status updates here so we can then raise them as events in MJ Global locally
|
|
47
57
|
this.PushStatusUpdates().subscribe((message) => {
|
|
48
58
|
// Handle undefined/null messages gracefully
|
|
@@ -57,16 +67,18 @@ export class MJNotificationService {
|
|
|
57
67
|
args: statusObj,
|
|
58
68
|
component: this
|
|
59
69
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
const type = statusObj.type?.trim().toLowerCase();
|
|
71
|
+
if (type === 'notification' || type === 'usernotifications') {
|
|
72
|
+
// Server sends type:'notification', legacy used 'usernotifications' — support both
|
|
73
|
+
const action = statusObj.action?.trim().toLowerCase()
|
|
74
|
+
|| statusObj.details?.action?.trim().toLowerCase();
|
|
75
|
+
if (action === 'create') {
|
|
76
|
+
this.CreateSimpleNotification(statusObj.title || 'New Notification Available', "success", 3000);
|
|
64
77
|
MJNotificationService.RefreshUserNotifications();
|
|
65
78
|
}
|
|
66
79
|
}
|
|
67
80
|
else {
|
|
68
81
|
// otherwise just post it as a simple notification, except Skip messages, we will let Skip handle those
|
|
69
|
-
const type = statusObj.type?.trim().toLowerCase();
|
|
70
82
|
if (type !== 'askskip' && type !== 'entityobjectstatusmessage' && typeof statusObj.message === 'string') {
|
|
71
83
|
this.CreateSimpleNotification(statusObj.message, "success", 2500);
|
|
72
84
|
}
|
|
@@ -148,15 +160,20 @@ export class MJNotificationService {
|
|
|
148
160
|
return notification;
|
|
149
161
|
}
|
|
150
162
|
/**
|
|
151
|
-
* Refresh
|
|
152
|
-
*
|
|
163
|
+
* Refresh user notifications and re-emit to observables.
|
|
164
|
+
*
|
|
165
|
+
* Uses RefreshItem() to guarantee fresh data from the server. The global
|
|
166
|
+
* CACHE_INVALIDATION listener keeps the engine cache updated for background
|
|
167
|
+
* changes, but when this method is called in response to a PushStatusUpdates
|
|
168
|
+
* message, the cache invalidation event may not have arrived yet (separate
|
|
169
|
+
* WebSocket message, potential race). RefreshItem() eliminates that race by
|
|
170
|
+
* doing a targeted RunView for just notifications.
|
|
153
171
|
*/
|
|
154
172
|
static async RefreshUserNotifications() {
|
|
155
173
|
try {
|
|
156
|
-
// Use UserInfoEngine for centralized, cached access
|
|
157
174
|
const engine = UserInfoEngine.Instance;
|
|
175
|
+
await engine.RefreshItem('_UserNotifications');
|
|
158
176
|
MJNotificationService._userNotifications = engine.UserNotifications;
|
|
159
|
-
// Emit to observables
|
|
160
177
|
MJNotificationService._notifications$.next(engine.UserNotifications);
|
|
161
178
|
MJNotificationService._unreadCount$.next(MJNotificationService.UnreadUserNotificationCount);
|
|
162
179
|
MJNotificationService._loaded = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.service.js","sourceRoot":"","sources":["../../src/lib/notifications.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { ElementRef, Injectable } from '@angular/core';\nimport { LogError, Metadata } from '@memberjunction/core';\nimport { UserInfoEngine, MJUserNotificationEntity } from '@memberjunction/core-entities';\nimport { DisplaySimpleNotificationRequestData, MJEventType, MJGlobal } from '@memberjunction/global';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { NotificationService, NotificationSettings } from \"@progress/kendo-angular-notification\";\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\n\n/**\n * This injectable service is also available as a singleton MJNotificationService.Instance globally within an Angular application/library process space. It is responsible for displaying notifications to the user and also is able to manage the User Notifications entity\n * in the database.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class MJNotificationService {\n private static _instance: MJNotificationService;\n private static _loaded: boolean = false;\n\n private static isLoading$ = new BehaviorSubject<boolean>(false);\n private tabChange = new Subject();\n tabChange$ = this.tabChange.asObservable();\n\n // Observable for notification changes\n private static _notifications$ = new BehaviorSubject<MJUserNotificationEntity[]>([]);\n private static _unreadCount$ = new BehaviorSubject<number>(0);\n\n constructor(private notificationService: NotificationService) {\n if (MJNotificationService._instance) {\n // return existing instance which will short circuit the creation of a new instance\n return MJNotificationService._instance;\n }\n // first time this has been called, so return ourselves since we're in the constructor\n MJNotificationService._instance = this;\n\n MJGlobal.Instance.GetEventListener(true).subscribe( (event) => {\n switch (event.event) {\n case MJEventType.DisplaySimpleNotificationRequest: \n // received the message to display a notification to the user, so do that...\n const messageData: DisplaySimpleNotificationRequestData = <DisplaySimpleNotificationRequestData>event.args;\n this.CreateSimpleNotification(messageData.message,messageData.style, messageData.DisplayDuration);\n break;\n case MJEventType.ComponentEvent:\n if (event.eventCode === \"UserNotificationsUpdated\") {\n // refresh the user notifications\n MJNotificationService.RefreshUserNotifications();\n }\n break;\n case MJEventType.LoggedIn:\n if (MJNotificationService._loaded === false) \n MJNotificationService.RefreshUserNotifications();\n\n // got the login, now subscribe to push status updates here so we can then raise them as events in MJ Global locally\n this.PushStatusUpdates().subscribe( (message: string) => {\n // Handle undefined/null messages gracefully\n if (!message) {\n return;\n }\n\n const statusObj = JSON.parse(message);\n\n // pass along as an event so anyone else who wants to know about the push status update can do stuff\n MJGlobal.Instance.RaiseEvent({\n event: MJEventType.ComponentEvent,\n eventCode: \"PushStatusUpdates\",\n args: statusObj,\n component: this\n })\n\n if (statusObj.type?.trim().toLowerCase() === 'usernotifications') {\n if (statusObj.details && statusObj.details.action?.trim().toLowerCase() === 'create') { \n // we have changes to user notifications, so refresh them\n this.CreateSimpleNotification('New Notification Available', \"success\", 2000)\n MJNotificationService.RefreshUserNotifications();\n }\n }\n else {\n // otherwise just post it as a simple notification, except Skip messages, we will let Skip handle those\n const type = statusObj.type?.trim().toLowerCase();\n if (type !== 'askskip' && type !== 'entityobjectstatusmessage' && typeof statusObj.message === 'string') { \n this.CreateSimpleNotification(statusObj.message, \"success\", 2500);\n }\n }\n });\n break;\n } \n });\n }\n\n public PushStatusUpdates(): Observable<string> {\n const gp: GraphQLDataProvider = <GraphQLDataProvider>Metadata.Provider;\n return gp.PushStatusUpdates();\n }\n\n public static get Instance(): MJNotificationService {\n return MJNotificationService._instance;\n }\n \n private static _userNotifications: MJUserNotificationEntity[] = [];\n public static get UserNotifications(): MJUserNotificationEntity[] {\n return MJNotificationService._userNotifications;\n }\n public static get UnreadUserNotifications(): MJUserNotificationEntity[] {\n return MJNotificationService._userNotifications.filter(n => n.Unread);\n }\n public static get UnreadUserNotificationCount(): number {\n return MJNotificationService.UnreadUserNotifications.length;\n }\n\n /**\n * Observable that emits the full list of user notifications whenever they change\n */\n public static get Notifications$(): Observable<MJUserNotificationEntity[]> {\n return MJNotificationService._notifications$.asObservable();\n }\n\n /**\n * Observable that emits the unread notification count whenever it changes\n */\n public static get UnreadCount$(): Observable<number> {\n return MJNotificationService._unreadCount$.asObservable();\n }\n\n /**\n * Instance method to access Notifications$ observable\n */\n public get notifications$(): Observable<MJUserNotificationEntity[]> {\n return MJNotificationService.Notifications$;\n }\n\n /**\n * Instance method to access UnreadCount$ observable\n */\n public get unreadCount$(): Observable<number> {\n return MJNotificationService.UnreadCount$;\n }\n\n\n /**\n * Creates a user notification in the database and refreshes the UI. Returns the notification object.\n * @param title \n * @param message \n * @param resourceTypeId \n * @param resourceRecordId \n * @param resourceConfiguration Any object, it is converted to a string by JSON.stringify and stored in the database\n * @returns \n */\n public async CreateNotification(title: string, message: string, resourceTypeId: string | null, resourceRecordId: string | null, resourceConfiguration: any | null, displayToUser: boolean = true): Promise<MJUserNotificationEntity> {\n const md = new Metadata();\n const notification = <MJUserNotificationEntity>await md.GetEntityObject('MJ: User Notifications');\n notification.Title = title;\n notification.Message = message;\n if (resourceTypeId)\n notification.ResourceTypeID = resourceTypeId;\n if (resourceRecordId)\n notification.ResourceRecordID = resourceRecordId;\n if (resourceConfiguration)\n notification.ResourceConfiguration = JSON.stringify(resourceConfiguration);\n \n notification.UserID = md.CurrentUser.ID;\n notification.Unread = true;\n const result = await notification.Save();\n if (result) {\n MJNotificationService.RefreshUserNotifications();\n }\n\n if (displayToUser)\n this.CreateSimpleNotification(notification.Message, \"success\", 2500);\n\n return notification;\n }\n\n /**\n * Refresh the User Notifications from the database. This is called automatically when the service is first loaded after login occurs.\n * Uses UserInfoEngine for centralized data access with local caching.\n */\n public static async RefreshUserNotifications() {\n try {\n // Use UserInfoEngine for centralized, cached access\n const engine = UserInfoEngine.Instance;\n MJNotificationService._userNotifications = engine.UserNotifications;\n // Emit to observables\n MJNotificationService._notifications$.next(engine.UserNotifications);\n MJNotificationService._unreadCount$.next(MJNotificationService.UnreadUserNotificationCount);\n MJNotificationService._loaded = true;\n }\n catch (e) {\n LogError(e);\n }\n }\n\n /**\n * Update notification observables from existing in-memory data without doing a database query.\n * This is efficient for cases where notifications have been modified locally (e.g., marking as read)\n * and we just need to notify subscribers of the change.\n */\n public static UpdateNotificationObservables() {\n MJNotificationService._notifications$.next(MJNotificationService._userNotifications);\n MJNotificationService._unreadCount$.next(MJNotificationService.UnreadUserNotificationCount);\n }\n\n /**\n * Creates a message that is not saved to the User Notifications table, but is displayed to the user.\n * @param message - text to display\n * @param style - display styling\n * @param hideAfter - option to auto hide after the specified delay in milliseconds\n */\n public CreateSimpleNotification(message: string, style: \"none\" | \"success\" | \"error\" | \"warning\" | \"info\" = \"success\", hideAfter?: number) {\n const props: NotificationSettings = {\n content: message,\n cssClass: \"button-notification\",\n animation: { type: \"slide\", duration: 400 },\n position: { horizontal: \"center\", vertical: \"top\" },\n type: { style: style, icon: true }\n }\n if (hideAfter)\n props.hideAfter = hideAfter;\n else\n props.closable = true;\n\n this.notificationService.show(props);\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"notifications.service.js","sourceRoot":"","sources":["../../src/lib/notifications.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { ElementRef, Injectable } from '@angular/core';\nimport { LogError, Metadata } from '@memberjunction/core';\nimport { UserInfoEngine, MJUserNotificationEntity } from '@memberjunction/core-entities';\nimport { DisplaySimpleNotificationRequestData, MJEventType, MJGlobal } from '@memberjunction/global';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { NotificationService, NotificationSettings } from \"@progress/kendo-angular-notification\";\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\n\n/**\n * This injectable service is also available as a singleton MJNotificationService.Instance globally within an Angular application/library process space. It is responsible for displaying notifications to the user and also is able to manage the User Notifications entity\n * in the database.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class MJNotificationService {\n private static _instance: MJNotificationService;\n private static _loaded: boolean = false;\n\n private static isLoading$ = new BehaviorSubject<boolean>(false);\n private tabChange = new Subject();\n tabChange$ = this.tabChange.asObservable();\n\n // Observable for notification changes\n private static _notifications$ = new BehaviorSubject<MJUserNotificationEntity[]>([]);\n private static _unreadCount$ = new BehaviorSubject<number>(0);\n\n constructor(private notificationService: NotificationService) {\n if (MJNotificationService._instance) {\n // return existing instance which will short circuit the creation of a new instance\n return MJNotificationService._instance;\n }\n // first time this has been called, so return ourselves since we're in the constructor\n MJNotificationService._instance = this;\n\n MJGlobal.Instance.GetEventListener(true).subscribe( (event) => {\n switch (event.event) {\n case MJEventType.DisplaySimpleNotificationRequest: \n // received the message to display a notification to the user, so do that...\n const messageData: DisplaySimpleNotificationRequestData = <DisplaySimpleNotificationRequestData>event.args;\n this.CreateSimpleNotification(messageData.message,messageData.style, messageData.DisplayDuration);\n break;\n case MJEventType.ComponentEvent:\n if (event.eventCode === \"UserNotificationsUpdated\") {\n // refresh the user notifications\n MJNotificationService.RefreshUserNotifications();\n }\n break;\n case MJEventType.LoggedIn:\n if (MJNotificationService._loaded === false) \n MJNotificationService.RefreshUserNotifications();\n\n // Subscribe to UserInfoEngine's DataChange$ so that when CACHE_INVALIDATION\n // updates the _UserNotifications array, we immediately sync our BehaviorSubjects.\n // This is the primary mechanism for real-time notification updates — it fires\n // whenever BaseEngine processes a remote-invalidate event for User Notifications.\n UserInfoEngine.Instance.DataChange$.subscribe(event => {\n if (event.config.PropertyName === '_UserNotifications') {\n MJNotificationService._userNotifications = UserInfoEngine.Instance.UserNotifications;\n MJNotificationService.UpdateNotificationObservables();\n }\n });\n\n // got the login, now subscribe to push status updates here so we can then raise them as events in MJ Global locally\n this.PushStatusUpdates().subscribe( (message: string) => {\n // Handle undefined/null messages gracefully\n if (!message) {\n return;\n }\n\n const statusObj = JSON.parse(message);\n\n // pass along as an event so anyone else who wants to know about the push status update can do stuff\n MJGlobal.Instance.RaiseEvent({\n event: MJEventType.ComponentEvent,\n eventCode: \"PushStatusUpdates\",\n args: statusObj,\n component: this\n })\n\n const type = statusObj.type?.trim().toLowerCase();\n if (type === 'notification' || type === 'usernotifications') {\n // Server sends type:'notification', legacy used 'usernotifications' — support both\n const action = statusObj.action?.trim().toLowerCase()\n || statusObj.details?.action?.trim().toLowerCase();\n if (action === 'create') {\n this.CreateSimpleNotification(statusObj.title || 'New Notification Available', \"success\", 3000);\n MJNotificationService.RefreshUserNotifications();\n }\n }\n else {\n // otherwise just post it as a simple notification, except Skip messages, we will let Skip handle those\n if (type !== 'askskip' && type !== 'entityobjectstatusmessage' && typeof statusObj.message === 'string') {\n this.CreateSimpleNotification(statusObj.message, \"success\", 2500);\n }\n }\n });\n break;\n } \n });\n }\n\n public PushStatusUpdates(): Observable<string> {\n const gp: GraphQLDataProvider = <GraphQLDataProvider>Metadata.Provider;\n return gp.PushStatusUpdates();\n }\n\n public static get Instance(): MJNotificationService {\n return MJNotificationService._instance;\n }\n \n private static _userNotifications: MJUserNotificationEntity[] = [];\n public static get UserNotifications(): MJUserNotificationEntity[] {\n return MJNotificationService._userNotifications;\n }\n public static get UnreadUserNotifications(): MJUserNotificationEntity[] {\n return MJNotificationService._userNotifications.filter(n => n.Unread);\n }\n public static get UnreadUserNotificationCount(): number {\n return MJNotificationService.UnreadUserNotifications.length;\n }\n\n /**\n * Observable that emits the full list of user notifications whenever they change\n */\n public static get Notifications$(): Observable<MJUserNotificationEntity[]> {\n return MJNotificationService._notifications$.asObservable();\n }\n\n /**\n * Observable that emits the unread notification count whenever it changes\n */\n public static get UnreadCount$(): Observable<number> {\n return MJNotificationService._unreadCount$.asObservable();\n }\n\n /**\n * Instance method to access Notifications$ observable\n */\n public get notifications$(): Observable<MJUserNotificationEntity[]> {\n return MJNotificationService.Notifications$;\n }\n\n /**\n * Instance method to access UnreadCount$ observable\n */\n public get unreadCount$(): Observable<number> {\n return MJNotificationService.UnreadCount$;\n }\n\n\n /**\n * Creates a user notification in the database and refreshes the UI. Returns the notification object.\n * @param title \n * @param message \n * @param resourceTypeId \n * @param resourceRecordId \n * @param resourceConfiguration Any object, it is converted to a string by JSON.stringify and stored in the database\n * @returns \n */\n public async CreateNotification(title: string, message: string, resourceTypeId: string | null, resourceRecordId: string | null, resourceConfiguration: any | null, displayToUser: boolean = true): Promise<MJUserNotificationEntity> {\n const md = new Metadata();\n const notification = <MJUserNotificationEntity>await md.GetEntityObject('MJ: User Notifications');\n notification.Title = title;\n notification.Message = message;\n if (resourceTypeId)\n notification.ResourceTypeID = resourceTypeId;\n if (resourceRecordId)\n notification.ResourceRecordID = resourceRecordId;\n if (resourceConfiguration)\n notification.ResourceConfiguration = JSON.stringify(resourceConfiguration);\n \n notification.UserID = md.CurrentUser.ID;\n notification.Unread = true;\n const result = await notification.Save();\n if (result) {\n MJNotificationService.RefreshUserNotifications();\n }\n\n if (displayToUser)\n this.CreateSimpleNotification(notification.Message, \"success\", 2500);\n\n return notification;\n }\n\n /**\n * Refresh user notifications and re-emit to observables.\n *\n * Uses RefreshItem() to guarantee fresh data from the server. The global\n * CACHE_INVALIDATION listener keeps the engine cache updated for background\n * changes, but when this method is called in response to a PushStatusUpdates\n * message, the cache invalidation event may not have arrived yet (separate\n * WebSocket message, potential race). RefreshItem() eliminates that race by\n * doing a targeted RunView for just notifications.\n */\n public static async RefreshUserNotifications() {\n try {\n const engine = UserInfoEngine.Instance;\n await engine.RefreshItem('_UserNotifications');\n MJNotificationService._userNotifications = engine.UserNotifications;\n MJNotificationService._notifications$.next(engine.UserNotifications);\n MJNotificationService._unreadCount$.next(MJNotificationService.UnreadUserNotificationCount);\n MJNotificationService._loaded = true;\n }\n catch (e) {\n LogError(e);\n }\n }\n\n /**\n * Update notification observables from existing in-memory data without doing a database query.\n * This is efficient for cases where notifications have been modified locally (e.g., marking as read)\n * and we just need to notify subscribers of the change.\n */\n public static UpdateNotificationObservables() {\n MJNotificationService._notifications$.next(MJNotificationService._userNotifications);\n MJNotificationService._unreadCount$.next(MJNotificationService.UnreadUserNotificationCount);\n }\n\n /**\n * Creates a message that is not saved to the User Notifications table, but is displayed to the user.\n * @param message - text to display\n * @param style - display styling\n * @param hideAfter - option to auto hide after the specified delay in milliseconds\n */\n public CreateSimpleNotification(message: string, style: \"none\" | \"success\" | \"error\" | \"warning\" | \"info\" = \"success\", hideAfter?: number) {\n const props: NotificationSettings = {\n content: message,\n cssClass: \"button-notification\",\n animation: { type: \"slide\", duration: 400 },\n position: { horizontal: \"center\", vertical: \"top\" },\n type: { style: style, icon: true }\n }\n if (hideAfter)\n props.hideAfter = hideAfter;\n else\n props.closable = true;\n\n this.notificationService.show(props);\n }\n}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-notifications",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.12.0",
|
|
4
4
|
"description": "MemberJunction: Simple Angular library for displaying user notifications",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"@progress/kendo-angular-notification": "22.0.1"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@memberjunction/core": "5.
|
|
30
|
-
"@memberjunction/core-entities": "5.
|
|
31
|
-
"@memberjunction/global": "5.
|
|
32
|
-
"@memberjunction/graphql-dataprovider": "5.
|
|
29
|
+
"@memberjunction/core": "5.12.0",
|
|
30
|
+
"@memberjunction/core-entities": "5.12.0",
|
|
31
|
+
"@memberjunction/global": "5.12.0",
|
|
32
|
+
"@memberjunction/graphql-dataprovider": "5.12.0",
|
|
33
33
|
"tslib": "^2.8.1",
|
|
34
34
|
"rxjs": "^7.8.2"
|
|
35
35
|
},
|