@memberjunction/ng-notifications 6.1.4 → 6.2.0-edge.1
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.
|
@@ -63,7 +63,11 @@ export declare class MJNotificationService {
|
|
|
63
63
|
set Provider(value: IMetadataProvider | null);
|
|
64
64
|
private static isLoading$;
|
|
65
65
|
private tabChange;
|
|
66
|
-
|
|
66
|
+
TabChange$: Observable<unknown>;
|
|
67
|
+
/** @deprecated Use {@link TabChange$}. */
|
|
68
|
+
get tabChange$(): Observable<unknown>;
|
|
69
|
+
/** @deprecated Use {@link TabChange$}. */
|
|
70
|
+
set tabChange$(value: Observable<unknown>);
|
|
67
71
|
/**
|
|
68
72
|
* Observable stream of the current user's notifications, derived from
|
|
69
73
|
* UserInfoEngine.UserNotifications$. Emits immediately on subscribe (shareReplay
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.service.d.ts","sourceRoot":"","sources":["../../src/lib/notifications.service.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"notifications.service.d.ts","sourceRoot":"","sources":["../../src/lib/notifications.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,15 @@ export class MJNotificationService {
|
|
|
17
17
|
}
|
|
18
18
|
static isLoading$ = new BehaviorSubject(false);
|
|
19
19
|
tabChange = new Subject();
|
|
20
|
-
|
|
20
|
+
TabChange$ = this.tabChange.asObservable();
|
|
21
|
+
/** @deprecated Use {@link TabChange$}. */
|
|
22
|
+
get tabChange$() {
|
|
23
|
+
return this.TabChange$;
|
|
24
|
+
}
|
|
25
|
+
/** @deprecated Use {@link TabChange$}. */
|
|
26
|
+
set tabChange$(value) {
|
|
27
|
+
this.TabChange$ = value;
|
|
28
|
+
}
|
|
21
29
|
/**
|
|
22
30
|
* Observable stream of the current user's notifications, derived from
|
|
23
31
|
* UserInfoEngine.UserNotifications$. Emits immediately on subscribe (shareReplay
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.service.js","sourceRoot":"","sources":["../../src/lib/notifications.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAqB,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EAAE,cAAc,EAA4B,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAAwC,WAAW,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE3H,OAAO,EAAE,eAAe,EAAc,OAAO,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;;AA4DlD,MAAM,OAAO,qBAAqB;IACxB,MAAM,CAAU,eAAe,GAAG,qCAAqC,CAAC;IACxE,MAAM,CAAC,OAAO,GAAY,KAAK,CAAC;IAEhC,SAAS,GAA6B,IAAI,CAAC;IACnD,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC;IAC7C,CAAC;IACD,IAAW,QAAQ,CAAC,KAA+B;QACjD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAEO,MAAM,CAAC,UAAU,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC,CAAC;IACxD,SAAS,GAAG,IAAI,OAAO,EAAE,CAAC;IAClC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;IAE3C;;;;;;OAMG;IACI,MAAM,CAAU,cAAc,GACnC,cAAc,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAC7C,GAAG,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EACpD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAChD,CAAC;IAEJ;;;OAGG;IACI,MAAM,CAAU,YAAY,GACjC,qBAAqB,CAAC,cAAc,CAAC,IAAI,CACvC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAChD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAChD,CAAC;IAEJ;;;;;OAKG;IACI,mBAAmB,CAAmD;IAE7E;;;;;OAKG;IACI,0BAA0B,GAA2E,IAAI,CAAC;IAEjH;;;;OAIG;IACc,cAAc,GAAG,IAAI,GAAG,EAAsG,CAAC;IAChJ,6FAA6F;IAC5E,iBAAiB,GAAG,IAAI,GAAG,EAAyC,CAAC;IAEtF;QACE,MAAM,CAAC,GAAG,oBAAoB,EAAG,CAAC;QAClC,IAAI,CAAC,CAAC,qBAAqB,CAAC,eAAe,CAAC,EAAE,CAAC;YAC7C,OAAO,CAAC,CAAC,qBAAqB,CAAC,eAAe,CAA0B,CAAC;QAC3E,CAAC;QACD,CAAC,CAAC,qBAAqB,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC;QAEhD,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAE,CAAC,KAAK,EAAE,EAAE;YAC5D,QAAQ,KAAK,CAAC,KAAK,EAAE,CAAC;gBACpB,KAAK,WAAW,CAAC,gCAAgC;oBAC/C,4EAA4E;oBAC5E,MAAM,WAAW,GAA+E,KAAK,CAAC,IAAI,CAAC;oBAC3G,IAAI,CAAC,wBAAwB,CAAC,WAAW,CAAC,OAAO,EAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC;oBAClG,MAAM;gBACR,KAAK,WAAW,CAAC,cAAc;oBAC7B,IAAI,KAAK,CAAC,SAAS,KAAK,0BAA0B,EAAE,CAAC;wBACnD,iCAAiC;wBACjC,qBAAqB,CAAC,wBAAwB,EAAE,CAAC;oBACnD,CAAC;oBACD,MAAM;gBACR,KAAK,WAAW,CAAC,QAAQ;oBACvB,IAAI,qBAAqB,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;wBAC5C,uEAAuE;wBACvE,+EAA+E;wBAC/E,yEAAyE;wBACzE,yEAAyE;wBACzE,8DAA8D;wBAC9D,cAAc,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;4BAC1C,qBAAqB,CAAC,wBAAwB,EAAE,CAAC;wBACnD,CAAC,CAAC,CAAC;oBACL,CAAC;oBAED,mFAAmF;oBACnF,gFAAgF;oBAChF,8CAA8C;oBAE9C,oHAAoH;oBACpH,IAAI,CAAC,iBAAiB,EAAE,CAAC,SAAS,CAAE,CAAC,OAAe,EAAE,EAAE;wBACtD,4CAA4C;wBAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;4BACb,OAAO;wBACT,CAAC;wBAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBAEtC,oGAAoG;wBACpG,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;4BAC3B,KAAK,EAAE,WAAW,CAAC,cAAc;4BACjC,SAAS,EAAE,mBAAmB;4BAC9B,IAAI,EAAE,SAAS;4BACf,SAAS,EAAE,IAAI;yBAChB,CAAC,CAAA;wBAEF,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;wBAClD,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;4BAC5D,mFAAmF;4BACnF,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE;mCACtC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;4BAC/D,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gCACxB,0DAA0D;gCAC1D,sEAAsE;gCACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC;gCAChE,IAAI,CAAC,QAAQ,EAAE,CAAC;oCACd,IAAI,SAAS,CAAC,cAAc,EAAE,CAAC;wCAC7B,4EAA4E;wCAC5E,6EAA6E;wCAC7E,IAAI,CAAC,sBAAsB,CAAC;4CAC1B,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,UAAU;4CACpC,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,IAAI;4CAClC,SAAS,EAAE,IAAI;4CACf,SAAS,EAAE,oBAAoB,SAAS,CAAC,cAAc,EAAE;4CACzD,OAAO,EAAE,IAAI;4CACb,OAAO,EAAE,EAAE,cAAc,EAAE,SAAS,CAAC,cAAc,EAAE;yCACtD,CAAC,CAAC;oCACL,CAAC;yCAAM,CAAC;wCACN,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,KAAK,IAAI,4BAA4B,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;oCAClG,CAAC;gCACH,CAAC;gCACD,mEAAmE;gCACnE,qBAAqB,CAAC,wBAAwB,EAAE,CAAC;4BACnD,CAAC;wBACH,CAAC;6BACI,CAAC;4BACJ,wGAAwG;4BACxG,qGAAqG;4BACrG,oGAAoG;4BACpG,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,2BAA2B,IAAI,IAAI,KAAK,4BAA4B,IAAI,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gCACjJ,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;4BACpE,CAAC;wBACH,CAAC;oBACH,CAAC,CAAC,CAAC;oBACH,MAAM;YACV,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,iBAAiB;QACtB,MAAM,EAAE,GAAsD,IAAI,CAAC,QAAQ,CAAC;QAC5E,OAAO,EAAE,CAAC,iBAAiB,EAAE,CAAC;IAChC,CAAC;IAEM,MAAM,KAAK,QAAQ;QACxB,OAAO,oBAAoB,EAAG,CAAC,qBAAqB,CAAC,eAAe,CAA0B,CAAC;IACjG,CAAC;IAED;;;OAGG;IACI,MAAM,KAAK,iBAAiB;QACjC,OAAO,cAAc,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACnD,CAAC;IAED;;OAEG;IACI,MAAM,KAAK,uBAAuB;QACvC,OAAO,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CAAC;IACrD,CAAC;IAED;;OAEG;IACI,MAAM,KAAK,2BAA2B;QAC3C,OAAO,cAAc,CAAC,QAAQ,CAAC,uBAAuB,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,IAAW,cAAc;QACvB,OAAO,qBAAqB,CAAC,cAAc,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,IAAW,YAAY;QACrB,OAAO,qBAAqB,CAAC,YAAY,CAAC;IAC5C,CAAC;IAGD;;;;;;;;OAQG;IACI,KAAK,CAAC,kBAAkB,CAAC,KAAa,EAAE,OAAe,EAAE,cAA6B,EAAE,gBAA+B,EAAE,qBAAiC,EAAE,gBAAyB,IAAI;QAC9L,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzB,MAAM,YAAY,GAA6B,MAAM,EAAE,CAAC,eAAe,CAAC,wBAAwB,CAAC,CAAC;QAClG,YAAY,CAAC,KAAK,GAAG,KAAK,CAAC;QAC3B,YAAY,CAAC,OAAO,GAAG,OAAO,CAAC;QAC/B,IAAI,cAAc;YAChB,YAAY,CAAC,cAAc,GAAG,cAAc,CAAC;QAC/C,IAAI,gBAAgB;YAClB,YAAY,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACnD,IAAI,qBAAqB;YACvB,YAAY,CAAC,qBAAqB,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAE7E,YAAY,CAAC,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;QACxC,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,MAAM,EAAE,CAAC;YACT,qBAAqB,CAAC,wBAAwB,EAAE,CAAC;QACrD,CAAC;QAED,IAAI,aAAa;YACb,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAEzE,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;;;;;;;;;;OAWG;IACI,MAAM,CAAC,KAAK,CAAC,wBAAwB;QAC1C,IAAI,CAAC;YACH,MAAM,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;YAChE,qBAAqB,CAAC,OAAO,GAAG,IAAI,CAAC;QACvC,CAAC;QACD,OAAO,CAAC,EAAE,CAAC;YACT,QAAQ,CAAC,CAAC,CAAC,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,6BAA6B;QACzC,2BAA2B;IAC7B,CAAC;IAED;;;;;;OAMG;IACI,wBAAwB,CAC7B,OAAe,EACf,QAA2D,SAAS,EACpE,SAAkB;QAElB,MAAM,WAAW,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACjF,MAAM,kBAAkB,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;QAC7E,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACI,sBAAsB,CAAC,OAAkC;QAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;QAC9B,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,EAAE,CAAC;oBAC7F,gFAAgF;oBAChF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBAC/B,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChD,IAAI,OAAO,EAAE,CAAC;gBACZ,sDAAsD;gBACtD,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACrC,CAAC;YACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,8EAA8E;gBAC9E,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE;oBAC9C,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACnC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gBAC9B,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3B,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAEO,aAAa,CAAC,OAAkC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC9C,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5C,KAAK,CAAC,SAAS,GAAG,yBAAyB,CAAC;QAC5C,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACrC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG;;;;;;;0EAOgD,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE;KAC9G,CAAC;QACF,wFAAwF;QACxF,wFAAwF;QACxF,4FAA4F;QAC5F,8CAA8C;QAC9C,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YAClB,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,KAAK,EAAE,CAAC;gBAC3D,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC,CAAC;QACF,qEAAqE;QACrE,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACpC,IAAK,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACzD,OAAO,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,qEAAqE;QACrE,IAAI,KAAK,GAAyC,IAAI,CAAC;QACvD,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QAClC,MAAM,GAAG,GAAG,GAAG,EAAE;YACf,IAAI,KAAK,EAAE,CAAC;gBACV,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YACD,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5D,CAAC,CAAC;QACF,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;YACxC,IAAI,KAAK,EAAE,CAAC;gBACV,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;QACH,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;YACxC,IAAI,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC;gBACxB,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACpC,CAAC;QACH,CAAC,CAAC,CAAC;QACH,GAAG,EAAE,CAAC;QACN,IAAI,GAAG,EAAE,CAAC;YACR,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE;gBAC3B,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;gBACnB,MAAM,EAAE,CAAC,aAAa,EAAE,EAAE;oBACxB,SAAS,GAAG,aAAa,CAAC;oBAC1B,GAAG,EAAE,CAAC;gBACR,CAAC;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,4FAA4F;IACpF,gBAAgB,CAAC,OAAkC;QACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7F,OAAO,QAAQ,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED,qGAAqG;IAC7F,aAAa,CAAC,KAAkB,EAAE,OAAkC,EAAE,QAAuB;QACnG,yFAAyF;QACzF,0EAA0E;QAC1E,MAAM,KAAK,GAAG,QAAQ;YACpB,CAAC,CAAC,aAAa,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,0HAA0H;YACvK,CAAC,CAAC,qRAAqR,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,IAAI,mBAAmB,CAAC,eAAe,CAAC;QACvW,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO;YAC5B,CAAC,CAAC,+DAA+D,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ;YACzG,CAAC,CAAC,EAAE,CAAC;QACP,KAAK,CAAC,SAAS,GAAG;QACd,KAAK;;0FAE6E,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC;UAC9G,MAAM;;;KAGX,CAAC;IACJ,CAAC;IAED,qFAAqF;IAC7E,SAAS,CAAC,QAAoB;QACpC,IAAI,OAAO,qBAAqB,KAAK,UAAU,EAAE,CAAC;YAChD,qBAAqB,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,KAAkB;QACrC,IAAI,CAAC,KAAK,CAAC,WAAW;YAAE,OAAO;QAC/B,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,iEAAiE,CAAC;QAC1F,KAAK,CAAC,gBAAgB,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,gGAAgG;IACxF,oBAAoB;QAC1B,IAAI,QAAQ,CAAC,cAAc,CAAC,oBAAoB,CAAC;YAAE,OAAO;QAC1D,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAChD,OAAO,CAAC,EAAE,GAAG,oBAAoB,CAAC;QAClC,OAAO,CAAC,WAAW,GAAG;;;;;;;;;KASrB,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAEO,eAAe,CAAC,KAAa;QACnC,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1G,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,IAAI,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC1C,SAAS,CAAC,EAAE,GAAG,oBAAoB,CAAC;YACpC,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG;;;;;;;;;;;OAWzB,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,OAAe,EAAE,KAAa,EAAE,SAAiB;QACjE,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAE9C,MAAM,YAAY,GAA2B;YAC3C,OAAO,EAAE,mCAAmC;YAC5C,KAAK,EAAI,iCAAiC;YAC1C,OAAO,EAAE,mCAAmC;YAC5C,IAAI,EAAK,gCAAgC;YACzC,IAAI,EAAK,kCAAkC;SAC5C,CAAC;QACF,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;QAEhE,MAAM,OAAO,GAA2B;YACtC,OAAO,EAAE,gVAAgV;YACzV,KAAK,EAAI,4UAA4U;YACrV,OAAO,EAAE,wVAAwV;YACjW,IAAI,EAAK,yUAAyU;YAClV,IAAI,EAAK,sUAAsU;SAChV,CAAC;QACF,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5C,KAAK,CAAC,SAAS,GAAG,2BAA2B,KAAK,EAAE,CAAC;QACrD,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG;;;;;;;;;+BASK,WAAW;;;;;;;;;;;;KAYrC,CAAC;QAEF,KAAK,CAAC,SAAS,GAAG;QACd,QAAQ;oIACoH,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;;;;KAIvJ,CAAC;QAEF,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAoB,iBAAiB,CAAC,CAAC;QAC3E,MAAM,WAAW,GAAG,GAAG,EAAE;YACvB,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,iEAAiE,CAAC;YAC1F,KAAK,CAAC,gBAAgB,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/E,CAAC,CAAC;QAEF,QAAQ,EAAE,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACjD,QAAQ,EAAE,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;YAC5C,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,iCAAiC,CAAC;YACzD,QAAQ,CAAC,KAAK,CAAC,eAAe,GAAG,sCAAsC,CAAC;QAC1E,CAAC,CAAC,CAAC;QACH,QAAQ,EAAE,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;YAC5C,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,+BAA+B,CAAC;YACvD,QAAQ,CAAC,KAAK,CAAC,eAAe,GAAG,aAAa,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAE7B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAE5B,qCAAqC;QACrC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,IAAI,KAAK,GAAyC,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAErF,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;gBACxC,IAAI,KAAK,EAAE,CAAC;oBACV,YAAY,CAAC,KAAK,CAAC,CAAC;oBACpB,KAAK,GAAG,IAAI,CAAC;gBACf,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;gBACxC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,IAAY;QAC7B,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1C,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC;QACvB,OAAO,GAAG,CAAC,SAAS,CAAC;IACvB,CAAC;+GAplBU,qBAAqB;gEAArB,qBAAqB,WAArB,qBAAqB,mBAFpB,MAAM;;iFAEP,qBAAqB;cAHjC,UAAU;eAAC;gBACV,UAAU,EAAE,MAAM;aACnB","sourcesContent":["import { Injectable } from '@angular/core';\nimport { IMetadataProvider, LogError, Metadata, StartupManager } from '@memberjunction/core';\nimport { UserInfoEngine, MJUserNotificationEntity } from '@memberjunction/core-entities';\nimport { DisplaySimpleNotificationRequestData, MJEventType, MJGlobal, GetGlobalObjectStore } from '@memberjunction/global';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport { map, shareReplay } from 'rxjs/operators';\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/**\n * Multi-provider note: callers under a non-default provider should set\n * `service.Provider = component.ProviderToUse` before invoking any methods.\n */\n/** What a rich toast knows about the thing it announces — handed to {@link MJNotificationService.CompletionImageUrlResolver}. */\nexport interface MJNotificationContext {\n conversationId?: string | null;\n agentId?: string | null;\n agentName?: string | null;\n}\n\n/** A toast with an image (or icon), a bold title and a line of detail — see {@link MJNotificationService.CreateRichNotification}. */\nexport interface MJRichNotificationOptions {\n /** Bold first line, e.g. \"Sage finished\". */\n title: string;\n /** Second line, e.g. \"in General Discussion\". */\n message?: string | null;\n /** Image at the left — an agent's avatar. Wins over `iconClass`. */\n imageUrl?: string | null;\n /** Font Awesome class used when there is no image, e.g. \"fa-solid fa-robot\". */\n iconClass?: string | null;\n /** Auto-hide in ms; omit for a sticky toast with a close button. */\n hideAfter?: number;\n /**\n * Toasts sharing a key within `dedupeWindowMs` collapse into ONE. A toast already on screen\n * wins — a later call with the same key only keeps it up longer, so the wording never\n * changes under the reader's eyes. A toast still waiting on `deferMs` is replaced by the\n * later call and shown at once. An agent run's completion is announced twice — by the\n * server's Agent Completion notification and by the client that ran it — and the reader\n * should hear it once, in one wording.\n */\n dedupeKey?: string;\n /**\n * Default 3 000 — wide enough to fold the two announcements of one completion (the deferred\n * server notification and the client's, tens of ms apart), narrow enough that a different\n * agent finishing seconds later in the same conversation is announced on its own.\n */\n dedupeWindowMs?: number;\n /**\n * Hold the toast this long before showing it, giving a better-worded announcement with the\n * same `dedupeKey` the chance to take its place. The server's completion notification uses\n * this: the client that ran the agent announces the same completion a few ms later with the\n * agent's name and the conversation's, and that is the one to show.\n */\n deferMs?: number;\n /** Runs when the toast body is clicked, e.g. open the conversation. */\n onClick?: () => void;\n /** Handed to {@link MJNotificationService.CompletionImageUrlResolver}, whose answer wins over `imageUrl`. */\n context?: MJNotificationContext;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class MJNotificationService {\n private static readonly _globalStoreKey = '___SINGLETON__MJNotificationService';\n private static _loaded: boolean = false;\n\n private _provider: IMetadataProvider | null = null;\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n private static isLoading$ = new BehaviorSubject<boolean>(false);\n private tabChange = new Subject();\n tabChange$ = this.tabChange.asObservable();\n\n /**\n * Observable stream of the current user's notifications, derived from\n * UserInfoEngine.UserNotifications$. Emits immediately on subscribe (shareReplay\n * buffers the latest value) and re-emits whenever the engine's notifications\n * cache is mutated — by save, delete, remote-invalidate, or refresh. Each\n * emission re-runs the engine's per-user filter+sort.\n */\n public static readonly Notifications$: Observable<MJUserNotificationEntity[]> =\n UserInfoEngine.Instance.UserNotifications$.pipe(\n map(() => UserInfoEngine.Instance.UserNotifications),\n shareReplay({ bufferSize: 1, refCount: false })\n );\n\n /**\n * Observable stream of the current user's unread notification count, derived\n * from Notifications$. Same emission lifecycle as Notifications$.\n */\n public static readonly UnreadCount$: Observable<number> =\n MJNotificationService.Notifications$.pipe(\n map((arr) => arr.filter((n) => n.Unread).length),\n shareReplay({ bufferSize: 1, refCount: false })\n );\n\n /**\n * Optional callback that consuming apps can set to suppress toast notifications\n * for specific events (e.g., when the user is actively viewing the conversation\n * that triggered the notification). Return true to suppress the toast.\n * The notification DB record is still created and the badge count still updates.\n */\n public ShouldSuppressToast?: (statusObj: Record<string, unknown>) => boolean;\n\n /**\n * Host hook: the image for agent-completion toasts. A white-label host brands the\n * assistant itself — the avatar on its chat bubbles — and that is the face the toast\n * should wear, whichever path announced the completion. Return null/undefined to fall back\n * to the agent's own LogoURL / IconClass.\n */\n public CompletionImageUrlResolver: ((context: MJNotificationContext) => string | null | undefined) | null = null;\n\n /**\n * Rich toasts on screen by dedupe key, so a repeat announcement extends rather than stacks.\n * An entry lives exactly as long as its toast: it is dropped the moment dismissal starts, so\n * a same-key call during the slide-out renders a fresh toast instead of extending a dying one.\n */\n private readonly liveRichToasts = new Map<string, { element: HTMLElement; shownAt: number; extend: (hideAfter: number | undefined) => void }>();\n /** Rich toasts held back by `deferMs`, by dedupe key — a same-key call takes their place. */\n private readonly pendingRichToasts = new Map<string, ReturnType<typeof setTimeout>>();\n\n constructor() {\n const g = GetGlobalObjectStore()!;\n if (g[MJNotificationService._globalStoreKey]) {\n return g[MJNotificationService._globalStoreKey] as MJNotificationService;\n }\n g[MJNotificationService._globalStoreKey] = 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 // Wait for StartupManager to complete before refreshing notifications.\n // UserInfoEngine (which backs RefreshUserNotifications) is @RegisterForStartup\n // and its _metadataConfigs are only populated during Config() which runs\n // as part of StartupManager.Startup(). Calling RefreshItem() before that\n // completes would silently find no config and return nothing.\n StartupManager.Instance.Startup().then(() => {\n MJNotificationService.RefreshUserNotifications();\n });\n }\n\n // Notifications$ / UnreadCount$ are derived from UserInfoEngine.UserNotifications$\n // at static-init time, so they auto-update whenever the engine's cache mutates.\n // No per-login subscription wiring is needed.\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 // Check if the consuming app wants to suppress this toast\n // (e.g., user is actively viewing the conversation that triggered it)\n const suppress = this.ShouldSuppressToast?.(statusObj) ?? false;\n if (!suppress) {\n if (statusObj.conversationId) {\n // An agent finished in a conversation. The client that ran it announces the\n // same completion from message-input; the shared key folds the two into one.\n this.CreateRichNotification({\n title: statusObj.title || 'Finished',\n message: statusObj.message || null,\n hideAfter: 5000,\n dedupeKey: `agent-completion:${statusObj.conversationId}`,\n deferMs: 1500,\n context: { conversationId: statusObj.conversationId }\n });\n } else {\n this.CreateSimpleNotification(statusObj.title || 'New Notification Available', \"success\", 3000);\n }\n }\n // Always refresh the notification list (badge count, unread state)\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 // 'realtimedelegationprogress' carries a per-step message that the voice session consumes + narrates\n // itself — it must NOT raise a toast (otherwise a live voice call spams a toast per progress step).\n if (type !== 'askskip' && type !== 'entityobjectstatusmessage' && type !== 'realtimedelegationprogress' && 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><unknown>this.Provider;\n return gp.PushStatusUpdates();\n }\n\n public static get Instance(): MJNotificationService {\n return GetGlobalObjectStore()![MJNotificationService._globalStoreKey] as MJNotificationService;\n }\n \n /**\n * The current user's notifications, delegated to UserInfoEngine which owns the\n * cache. Applies the per-user filter and newest-first sort on each access.\n */\n public static get UserNotifications(): MJUserNotificationEntity[] {\n return UserInfoEngine.Instance.UserNotifications;\n }\n\n /**\n * The current user's unread notifications, delegated to UserInfoEngine.\n */\n public static get UnreadUserNotifications(): MJUserNotificationEntity[] {\n return UserInfoEngine.Instance.UnreadNotifications;\n }\n\n /**\n * The current user's unread notification count, delegated to UserInfoEngine.\n */\n public static get UnreadUserNotificationCount(): number {\n return UserInfoEngine.Instance.UnreadNotificationCount;\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 = this.Provider;\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 from the server. Delegates to UserInfoEngine.RefreshItem,\n * whose successful reload mutates the engine's notifications cache and triggers an\n * emission on Notifications$/UnreadCount$ via the BaseEngine observable plumbing —\n * subscribers are updated automatically with no manual re-emit required here.\n *\n * Uses RefreshItem() rather than relying solely on the global CACHE_INVALIDATION\n * listener: when this method is called in response to a PushStatusUpdates message,\n * the cache-invalidation event may not have arrived yet (separate WebSocket message,\n * potential race). RefreshItem() eliminates that race by doing a targeted RunView\n * for just notifications.\n */\n public static async RefreshUserNotifications() {\n try {\n await UserInfoEngine.Instance.RefreshItem('_UserNotifications');\n MJNotificationService._loaded = true;\n }\n catch (e) {\n LogError(e);\n }\n }\n\n /**\n * @deprecated Kept as a no-op for backward compatibility. Observable emissions are now\n * driven by UserInfoEngine.UserNotifications$, which auto-emits on save/delete/\n * remote-invalidate/refresh. External callers no longer need to manually push updates.\n */\n public static UpdateNotificationObservables() {\n // No-op — see JSDoc above.\n }\n\n /**\n * Creates a message that is not saved to the User Notifications table, but is displayed to the user.\n * Uses a lightweight DOM-based toast notification styled with MemberJunction design tokens.\n * @param message - text to display\n * @param style - display styling ('none' | 'success' | 'error' | 'warning' | 'info')\n * @param hideAfter - option to auto hide after the specified delay in milliseconds (defaults to 3500-5000ms based on style; pass 0 to disable auto-hide)\n */\n public CreateSimpleNotification(\n message: string,\n style: \"none\" | \"success\" | \"error\" | \"warning\" | \"info\" = \"success\",\n hideAfter?: number\n ): void {\n const defaultHide = style === 'error' ? 5000 : style === 'warning' ? 4500 : 3500;\n const effectiveHideAfter = hideAfter !== undefined ? hideAfter : defaultHide;\n this.showToast(message, style, effectiveHideAfter);\n }\n\n /**\n * Shows a rich toast: an image or icon, a bold title and a line of detail, on the surface\n * tokens (so a white-label brand ramp themes it) with the brand colour as its accent.\n * See {@link MJRichNotificationOptions} for de-duplication.\n */\n public CreateRichNotification(options: MJRichNotificationOptions): void {\n const key = options.dedupeKey;\n if (key) {\n const live = this.liveRichToasts.get(key);\n if (live) {\n if (live.element.isConnected && Date.now() - live.shownAt < (options.dedupeWindowMs ?? 3000)) {\n // Already announced — keep what the reader is looking at, just a little longer.\n live.extend(options.hideAfter);\n return;\n }\n this.liveRichToasts.delete(key);\n }\n const pending = this.pendingRichToasts.get(key);\n if (pending) {\n // A held-back announcement is superseded by this one.\n clearTimeout(pending);\n this.pendingRichToasts.delete(key);\n }\n if (options.deferMs) {\n // Deferred (or deferred again): the wait starts over with the latest wording.\n this.pendingRichToasts.set(key, setTimeout(() => {\n this.pendingRichToasts.delete(key);\n this.showRichToast(options);\n }, options.deferMs));\n return;\n }\n } else if (options.deferMs) {\n setTimeout(() => this.showRichToast(options), options.deferMs);\n return;\n }\n this.showRichToast(options);\n }\n\n private showRichToast(options: MJRichNotificationOptions): void {\n const imageUrl = this.resolveRichImage(options);\n const key = options.dedupeKey;\n const container = this.ensureToastContainer();\n this.ensureToastKeyframes();\n const toast = document.createElement('div');\n toast.className = 'mj-toast mj-toast--rich';\n toast.setAttribute('role', 'status');\n toast.style.cssText = `\n pointer-events: auto; display: flex; align-items: center; gap: var(--mj-space-3);\n min-width: 280px; max-width: 420px; padding: var(--mj-space-3) var(--mj-space-4);\n background: var(--mj-bg-surface-card); color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-default); border-left: 4px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-lg); box-shadow: var(--mj-shadow-lg);\n font-family: var(--mj-font-family); font-size: var(--mj-text-sm);\n animation: mj-toast-slide-in 0.28s cubic-bezier(0.16, 1, 0.3, 1); ${options.onClick ? 'cursor: pointer;' : ''}\n `;\n // The live region enters the DOM empty and is filled on the NEXT frame, not in the same\n // task: a region that is already populated when the accessibility tree first sees it is\n // not announced. Everything else about the toast — registry entry, timers, click handling —\n // is wired now, so nothing waits on the fill.\n container.appendChild(toast);\n this.nextFrame(() => {\n if (toast.isConnected) {\n this.fillRichToast(toast, options, imageUrl);\n }\n });\n\n const dismiss = () => {\n if (key && this.liveRichToasts.get(key)?.element === toast) {\n this.liveRichToasts.delete(key);\n }\n this.dismissToast(toast);\n };\n // Delegated, because the close button does not exist until the fill.\n toast.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).closest('.mj-toast-close')) {\n dismiss();\n return;\n }\n if (options.onClick) {\n options.onClick();\n dismiss();\n }\n });\n\n // Auto-hide with hover-pause, the same contract as the simple toast.\n let timer: ReturnType<typeof setTimeout> | null = null;\n let hideAfter = options.hideAfter;\n const arm = () => {\n if (timer) {\n clearTimeout(timer);\n }\n timer = hideAfter ? setTimeout(dismiss, hideAfter) : null;\n };\n toast.addEventListener('mouseenter', () => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n });\n toast.addEventListener('mouseleave', () => {\n if (hideAfter && !timer) {\n timer = setTimeout(dismiss, 2000);\n }\n });\n arm();\n if (key) {\n this.liveRichToasts.set(key, {\n element: toast,\n shownAt: Date.now(),\n extend: (nextHideAfter) => {\n hideAfter = nextHideAfter;\n arm();\n }\n });\n }\n }\n\n /** Host resolver first (it knows how the assistant is branded), then the caller's image. */\n private resolveRichImage(options: MJRichNotificationOptions): string | null {\n const fromHost = options.context ? this.CompletionImageUrlResolver?.(options.context) : null;\n return fromHost || options.imageUrl || null;\n }\n\n /** Writes a rich toast's content. Written once per toast — a de-duplicated repeat never re-fills. */\n private fillRichToast(toast: HTMLElement, options: MJRichNotificationOptions, imageUrl: string | null): void {\n // The icon chip uses the house tint — the brand colour mixed to 14% under itself — which\n // holds contrast in both themes; a solid brand-light background does not.\n const media = imageUrl\n ? `<img src=\"${this.escapeAttribute(imageUrl)}\" alt=\"\" style=\"width:40px;height:40px;border-radius:50%;object-fit:cover;flex:none;background:var(--mj-bg-surface);\" />`\n : `<span aria-hidden=\"true\" style=\"width:40px;height:40px;border-radius:50%;flex:none;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);color:var(--mj-brand-primary);font-size:18px;\"><i class=\"${this.escapeAttribute(options.iconClass || 'fa-solid fa-robot')}\"></i></span>`;\n const detail = options.message\n ? `<div style=\"color:var(--mj-text-secondary);margin-top:2px;\">${this.escapeHtml(options.message)}</div>`\n : '';\n toast.innerHTML = `\n ${media}\n <div style=\"flex:1;min-width:0;\">\n <div style=\"font-weight:var(--mj-font-semibold);font-size:var(--mj-text-base);\">${this.escapeHtml(options.title)}</div>\n ${detail}\n </div>\n <button type=\"button\" class=\"mj-toast-close\" aria-label=\"Dismiss\" style=\"background:transparent;border:none;padding:4px 6px;border-radius:4px;color:var(--mj-text-muted);cursor:pointer;flex:none;\"><i class=\"fa-solid fa-xmark\"></i></button>\n `;\n }\n\n /** Next paint, or the next task where no frame scheduler exists (tests, workers). */\n private nextFrame(callback: () => void): void {\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => callback());\n } else {\n setTimeout(callback, 0);\n }\n }\n\n private dismissToast(toast: HTMLElement): void {\n if (!toast.isConnected) return;\n toast.style.animation = 'mj-toast-slide-out 0.25s cubic-bezier(0.16, 1, 0.3, 1) forwards';\n toast.addEventListener('animationend', () => toast.remove(), { once: true });\n }\n\n /** One writer for the toast keyframes — the simple and rich toasts share the same animation. */\n private ensureToastKeyframes(): void {\n if (document.getElementById('mj-toast-keyframes')) return;\n const styleEl = document.createElement('style');\n styleEl.id = 'mj-toast-keyframes';\n styleEl.textContent = `\n @keyframes mj-toast-slide-in {\n from { opacity: 0; transform: translateY(-12px) scale(0.96); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n @keyframes mj-toast-slide-out {\n from { opacity: 1; transform: translateY(0) scale(1); }\n to { opacity: 0; transform: translateY(-12px) scale(0.96); }\n }\n `;\n document.head.appendChild(styleEl);\n }\n\n private escapeAttribute(value: string): string {\n return value.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>');\n }\n\n /**\n * Ensures the toast container element exists in the DOM.\n */\n private ensureToastContainer(): HTMLElement {\n let container = document.getElementById('mj-toast-container');\n if (!container) {\n container = document.createElement('div');\n container.id = 'mj-toast-container';\n container.style.cssText = `\n position: fixed;\n top: 24px;\n right: 24px;\n z-index: 100000;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 10px;\n pointer-events: none;\n max-width: calc(100vw - 48px);\n `;\n document.body.appendChild(container);\n }\n return container;\n }\n\n /**\n * Shows a modern card toast notification using DOM elements and MJ design tokens.\n */\n private showToast(message: string, style: string, hideAfter: number): void {\n const container = this.ensureToastContainer();\n\n const statusColors: Record<string, string> = {\n success: 'var(--mj-status-success, #10b981)',\n error: 'var(--mj-status-error, #ef4444)',\n warning: 'var(--mj-status-warning, #f59e0b)',\n info: 'var(--mj-status-info, #3b82f6)',\n none: 'var(--mj-brand-primary, #6366f1)',\n };\n const accentColor = statusColors[style] || statusColors['none'];\n\n const iconMap: Record<string, string> = {\n success: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-status-success, #10b981) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-status-success, #10b981); flex-shrink: 0;\"><i class=\"fa-solid fa-circle-check\" style=\"font-size: 15px;\"></i></div>`,\n error: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-status-error, #ef4444) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-status-error, #ef4444); flex-shrink: 0;\"><i class=\"fa-solid fa-circle-xmark\" style=\"font-size: 15px;\"></i></div>`,\n warning: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-status-warning, #f59e0b) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-status-warning, #f59e0b); flex-shrink: 0;\"><i class=\"fa-solid fa-triangle-exclamation\" style=\"font-size: 14px;\"></i></div>`,\n info: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-status-info, #3b82f6) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-status-info, #3b82f6); flex-shrink: 0;\"><i class=\"fa-solid fa-circle-info\" style=\"font-size: 15px;\"></i></div>`,\n none: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-brand-primary, #6366f1) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-brand-primary, #6366f1); flex-shrink: 0;\"><i class=\"fa-solid fa-bell\" style=\"font-size: 14px;\"></i></div>`,\n };\n const iconHtml = iconMap[style] || iconMap['none'];\n\n const toast = document.createElement('div');\n toast.className = `mj-toast-item mj-toast--${style}`;\n toast.style.cssText = `\n pointer-events: auto;\n min-width: 300px;\n max-width: 460px;\n padding: 12px 16px;\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface, #ffffff);\n color: var(--mj-text-primary, #1e293b);\n border: 1px solid var(--mj-border-subtle, rgba(0, 0, 0, 0.08));\n border-left: 4px solid ${accentColor};\n box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.12), 0 8px 10px -6px rgba(0, 0, 0, 0.08);\n display: flex;\n align-items: center;\n gap: 12px;\n font-family: inherit;\n font-size: 0.88rem;\n line-height: 1.4;\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n animation: mj-toast-slide-in 0.28s cubic-bezier(0.16, 1, 0.3, 1);\n transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n `;\n\n toast.innerHTML = `\n ${iconHtml}\n <div style=\"flex: 1; font-weight: 500; font-size: 0.84rem; color: var(--mj-text-primary, #1e293b); word-break: break-word;\">${this.escapeHtml(message)}</div>\n <button type=\"button\" class=\"mj-toast-close\" style=\"background: transparent; border: none; padding: 4px 6px; border-radius: 4px; color: var(--mj-text-muted, #94a3b8); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 13px; line-height: 1; transition: color 0.15s ease;\" aria-label=\"Close\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n `;\n\n const closeBtn = toast.querySelector<HTMLButtonElement>('.mj-toast-close');\n const removeToast = () => {\n toast.style.animation = 'mj-toast-slide-out 0.25s cubic-bezier(0.16, 1, 0.3, 1) forwards';\n toast.addEventListener('animationend', () => toast.remove(), { once: true });\n };\n\n closeBtn?.addEventListener('click', removeToast);\n closeBtn?.addEventListener('mouseenter', () => {\n closeBtn.style.color = 'var(--mj-text-primary, #1e293b)';\n closeBtn.style.backgroundColor = 'var(--mj-bg-surface-sunken, #f1f5f9)';\n });\n closeBtn?.addEventListener('mouseleave', () => {\n closeBtn.style.color = 'var(--mj-text-muted, #94a3b8)';\n closeBtn.style.backgroundColor = 'transparent';\n });\n\n container.appendChild(toast);\n\n this.ensureToastKeyframes();\n\n // Auto-hide with hover-pause support\n if (hideAfter > 0) {\n let timer: ReturnType<typeof setTimeout> | null = setTimeout(removeToast, hideAfter);\n\n toast.addEventListener('mouseenter', () => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n });\n\n toast.addEventListener('mouseleave', () => {\n if (!timer) {\n timer = setTimeout(removeToast, 2000);\n }\n });\n }\n }\n\n /**\n * Escapes HTML entities to prevent XSS in toast messages.\n */\n private escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"notifications.service.js","sourceRoot":"","sources":["../../src/lib/notifications.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { IMetadataProvider, LogError, Metadata, StartupManager } from '@memberjunction/core';\nimport { UserInfoEngine, MJUserNotificationEntity } from '@memberjunction/core-entities';\nimport { DisplaySimpleNotificationRequestData, MJEventType, MJGlobal, GetGlobalObjectStore } from '@memberjunction/global';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport { map, shareReplay } from 'rxjs/operators';\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/**\n * Multi-provider note: callers under a non-default provider should set\n * `service.Provider = component.ProviderToUse` before invoking any methods.\n */\n/** What a rich toast knows about the thing it announces — handed to {@link MJNotificationService.CompletionImageUrlResolver}. */\nexport interface MJNotificationContext {\n conversationId?: string | null;\n agentId?: string | null;\n agentName?: string | null;\n}\n\n/** A toast with an image (or icon), a bold title and a line of detail — see {@link MJNotificationService.CreateRichNotification}. */\nexport interface MJRichNotificationOptions {\n /** Bold first line, e.g. \"Sage finished\". */\n title: string;\n /** Second line, e.g. \"in General Discussion\". */\n message?: string | null;\n /** Image at the left — an agent's avatar. Wins over `iconClass`. */\n imageUrl?: string | null;\n /** Font Awesome class used when there is no image, e.g. \"fa-solid fa-robot\". */\n iconClass?: string | null;\n /** Auto-hide in ms; omit for a sticky toast with a close button. */\n hideAfter?: number;\n /**\n * Toasts sharing a key within `dedupeWindowMs` collapse into ONE. A toast already on screen\n * wins — a later call with the same key only keeps it up longer, so the wording never\n * changes under the reader's eyes. A toast still waiting on `deferMs` is replaced by the\n * later call and shown at once. An agent run's completion is announced twice — by the\n * server's Agent Completion notification and by the client that ran it — and the reader\n * should hear it once, in one wording.\n */\n dedupeKey?: string;\n /**\n * Default 3 000 — wide enough to fold the two announcements of one completion (the deferred\n * server notification and the client's, tens of ms apart), narrow enough that a different\n * agent finishing seconds later in the same conversation is announced on its own.\n */\n dedupeWindowMs?: number;\n /**\n * Hold the toast this long before showing it, giving a better-worded announcement with the\n * same `dedupeKey` the chance to take its place. The server's completion notification uses\n * this: the client that ran the agent announces the same completion a few ms later with the\n * agent's name and the conversation's, and that is the one to show.\n */\n deferMs?: number;\n /** Runs when the toast body is clicked, e.g. open the conversation. */\n onClick?: () => void;\n /** Handed to {@link MJNotificationService.CompletionImageUrlResolver}, whose answer wins over `imageUrl`. */\n context?: MJNotificationContext;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class MJNotificationService {\n private static readonly _globalStoreKey = '___SINGLETON__MJNotificationService';\n private static _loaded: boolean = false;\n\n private _provider: IMetadataProvider | null = null;\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n private static isLoading$ = new BehaviorSubject<boolean>(false);\n private tabChange = new Subject();\n TabChange$ = this.tabChange.asObservable();\n\n /** @deprecated Use {@link TabChange$}. */\n get tabChange$() {\n return this.TabChange$;\n }\n /** @deprecated Use {@link TabChange$}. */\n set tabChange$(value) {\n this.TabChange$ = value;\n }\n\n /**\n * Observable stream of the current user's notifications, derived from\n * UserInfoEngine.UserNotifications$. Emits immediately on subscribe (shareReplay\n * buffers the latest value) and re-emits whenever the engine's notifications\n * cache is mutated — by save, delete, remote-invalidate, or refresh. Each\n * emission re-runs the engine's per-user filter+sort.\n */\n public static readonly Notifications$: Observable<MJUserNotificationEntity[]> =\n UserInfoEngine.Instance.UserNotifications$.pipe(\n map(() => UserInfoEngine.Instance.UserNotifications),\n shareReplay({ bufferSize: 1, refCount: false })\n );\n\n /**\n * Observable stream of the current user's unread notification count, derived\n * from Notifications$. Same emission lifecycle as Notifications$.\n */\n public static readonly UnreadCount$: Observable<number> =\n MJNotificationService.Notifications$.pipe(\n map((arr) => arr.filter((n) => n.Unread).length),\n shareReplay({ bufferSize: 1, refCount: false })\n );\n\n /**\n * Optional callback that consuming apps can set to suppress toast notifications\n * for specific events (e.g., when the user is actively viewing the conversation\n * that triggered the notification). Return true to suppress the toast.\n * The notification DB record is still created and the badge count still updates.\n */\n public ShouldSuppressToast?: (statusObj: Record<string, unknown>) => boolean;\n\n /**\n * Host hook: the image for agent-completion toasts. A white-label host brands the\n * assistant itself — the avatar on its chat bubbles — and that is the face the toast\n * should wear, whichever path announced the completion. Return null/undefined to fall back\n * to the agent's own LogoURL / IconClass.\n */\n public CompletionImageUrlResolver: ((context: MJNotificationContext) => string | null | undefined) | null = null;\n\n /**\n * Rich toasts on screen by dedupe key, so a repeat announcement extends rather than stacks.\n * An entry lives exactly as long as its toast: it is dropped the moment dismissal starts, so\n * a same-key call during the slide-out renders a fresh toast instead of extending a dying one.\n */\n private readonly liveRichToasts = new Map<string, { element: HTMLElement; shownAt: number; extend: (hideAfter: number | undefined) => void }>();\n /** Rich toasts held back by `deferMs`, by dedupe key — a same-key call takes their place. */\n private readonly pendingRichToasts = new Map<string, ReturnType<typeof setTimeout>>();\n\n constructor() {\n const g = GetGlobalObjectStore()!;\n if (g[MJNotificationService._globalStoreKey]) {\n return g[MJNotificationService._globalStoreKey] as MJNotificationService;\n }\n g[MJNotificationService._globalStoreKey] = 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 // Wait for StartupManager to complete before refreshing notifications.\n // UserInfoEngine (which backs RefreshUserNotifications) is @RegisterForStartup\n // and its _metadataConfigs are only populated during Config() which runs\n // as part of StartupManager.Startup(). Calling RefreshItem() before that\n // completes would silently find no config and return nothing.\n StartupManager.Instance.Startup().then(() => {\n MJNotificationService.RefreshUserNotifications();\n });\n }\n\n // Notifications$ / UnreadCount$ are derived from UserInfoEngine.UserNotifications$\n // at static-init time, so they auto-update whenever the engine's cache mutates.\n // No per-login subscription wiring is needed.\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 // Check if the consuming app wants to suppress this toast\n // (e.g., user is actively viewing the conversation that triggered it)\n const suppress = this.ShouldSuppressToast?.(statusObj) ?? false;\n if (!suppress) {\n if (statusObj.conversationId) {\n // An agent finished in a conversation. The client that ran it announces the\n // same completion from message-input; the shared key folds the two into one.\n this.CreateRichNotification({\n title: statusObj.title || 'Finished',\n message: statusObj.message || null,\n hideAfter: 5000,\n dedupeKey: `agent-completion:${statusObj.conversationId}`,\n deferMs: 1500,\n context: { conversationId: statusObj.conversationId }\n });\n } else {\n this.CreateSimpleNotification(statusObj.title || 'New Notification Available', \"success\", 3000);\n }\n }\n // Always refresh the notification list (badge count, unread state)\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 // 'realtimedelegationprogress' carries a per-step message that the voice session consumes + narrates\n // itself — it must NOT raise a toast (otherwise a live voice call spams a toast per progress step).\n if (type !== 'askskip' && type !== 'entityobjectstatusmessage' && type !== 'realtimedelegationprogress' && 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><unknown>this.Provider;\n return gp.PushStatusUpdates();\n }\n\n public static get Instance(): MJNotificationService {\n return GetGlobalObjectStore()![MJNotificationService._globalStoreKey] as MJNotificationService;\n }\n \n /**\n * The current user's notifications, delegated to UserInfoEngine which owns the\n * cache. Applies the per-user filter and newest-first sort on each access.\n */\n public static get UserNotifications(): MJUserNotificationEntity[] {\n return UserInfoEngine.Instance.UserNotifications;\n }\n\n /**\n * The current user's unread notifications, delegated to UserInfoEngine.\n */\n public static get UnreadUserNotifications(): MJUserNotificationEntity[] {\n return UserInfoEngine.Instance.UnreadNotifications;\n }\n\n /**\n * The current user's unread notification count, delegated to UserInfoEngine.\n */\n public static get UnreadUserNotificationCount(): number {\n return UserInfoEngine.Instance.UnreadNotificationCount;\n }\n\n /**\n * Instance method to access Notifications$ observable\n */\n public get notifications$(): Observable<MJUserNotificationEntity[]> { // case-violation-ok-legacy-back-compat: the PascalCase name is already taken in this scope\n return MJNotificationService.Notifications$;\n }\n\n /**\n * Instance method to access UnreadCount$ observable\n */\n public get unreadCount$(): Observable<number> { // case-violation-ok-legacy-back-compat: the PascalCase name is already taken in this scope\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 = this.Provider;\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 from the server. Delegates to UserInfoEngine.RefreshItem,\n * whose successful reload mutates the engine's notifications cache and triggers an\n * emission on Notifications$/UnreadCount$ via the BaseEngine observable plumbing —\n * subscribers are updated automatically with no manual re-emit required here.\n *\n * Uses RefreshItem() rather than relying solely on the global CACHE_INVALIDATION\n * listener: when this method is called in response to a PushStatusUpdates message,\n * the cache-invalidation event may not have arrived yet (separate WebSocket message,\n * potential race). RefreshItem() eliminates that race by doing a targeted RunView\n * for just notifications.\n */\n public static async RefreshUserNotifications() {\n try {\n await UserInfoEngine.Instance.RefreshItem('_UserNotifications');\n MJNotificationService._loaded = true;\n }\n catch (e) {\n LogError(e);\n }\n }\n\n /**\n * @deprecated Kept as a no-op for backward compatibility. Observable emissions are now\n * driven by UserInfoEngine.UserNotifications$, which auto-emits on save/delete/\n * remote-invalidate/refresh. External callers no longer need to manually push updates.\n */\n public static UpdateNotificationObservables() {\n // No-op — see JSDoc above.\n }\n\n /**\n * Creates a message that is not saved to the User Notifications table, but is displayed to the user.\n * Uses a lightweight DOM-based toast notification styled with MemberJunction design tokens.\n * @param message - text to display\n * @param style - display styling ('none' | 'success' | 'error' | 'warning' | 'info')\n * @param hideAfter - option to auto hide after the specified delay in milliseconds (defaults to 3500-5000ms based on style; pass 0 to disable auto-hide)\n */\n public CreateSimpleNotification(\n message: string,\n style: \"none\" | \"success\" | \"error\" | \"warning\" | \"info\" = \"success\",\n hideAfter?: number\n ): void {\n const defaultHide = style === 'error' ? 5000 : style === 'warning' ? 4500 : 3500;\n const effectiveHideAfter = hideAfter !== undefined ? hideAfter : defaultHide;\n this.showToast(message, style, effectiveHideAfter);\n }\n\n /**\n * Shows a rich toast: an image or icon, a bold title and a line of detail, on the surface\n * tokens (so a white-label brand ramp themes it) with the brand colour as its accent.\n * See {@link MJRichNotificationOptions} for de-duplication.\n */\n public CreateRichNotification(options: MJRichNotificationOptions): void {\n const key = options.dedupeKey;\n if (key) {\n const live = this.liveRichToasts.get(key);\n if (live) {\n if (live.element.isConnected && Date.now() - live.shownAt < (options.dedupeWindowMs ?? 3000)) {\n // Already announced — keep what the reader is looking at, just a little longer.\n live.extend(options.hideAfter);\n return;\n }\n this.liveRichToasts.delete(key);\n }\n const pending = this.pendingRichToasts.get(key);\n if (pending) {\n // A held-back announcement is superseded by this one.\n clearTimeout(pending);\n this.pendingRichToasts.delete(key);\n }\n if (options.deferMs) {\n // Deferred (or deferred again): the wait starts over with the latest wording.\n this.pendingRichToasts.set(key, setTimeout(() => {\n this.pendingRichToasts.delete(key);\n this.showRichToast(options);\n }, options.deferMs));\n return;\n }\n } else if (options.deferMs) {\n setTimeout(() => this.showRichToast(options), options.deferMs);\n return;\n }\n this.showRichToast(options);\n }\n\n private showRichToast(options: MJRichNotificationOptions): void {\n const imageUrl = this.resolveRichImage(options);\n const key = options.dedupeKey;\n const container = this.ensureToastContainer();\n this.ensureToastKeyframes();\n const toast = document.createElement('div');\n toast.className = 'mj-toast mj-toast--rich';\n toast.setAttribute('role', 'status');\n toast.style.cssText = `\n pointer-events: auto; display: flex; align-items: center; gap: var(--mj-space-3);\n min-width: 280px; max-width: 420px; padding: var(--mj-space-3) var(--mj-space-4);\n background: var(--mj-bg-surface-card); color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-default); border-left: 4px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-lg); box-shadow: var(--mj-shadow-lg);\n font-family: var(--mj-font-family); font-size: var(--mj-text-sm);\n animation: mj-toast-slide-in 0.28s cubic-bezier(0.16, 1, 0.3, 1); ${options.onClick ? 'cursor: pointer;' : ''}\n `;\n // The live region enters the DOM empty and is filled on the NEXT frame, not in the same\n // task: a region that is already populated when the accessibility tree first sees it is\n // not announced. Everything else about the toast — registry entry, timers, click handling —\n // is wired now, so nothing waits on the fill.\n container.appendChild(toast);\n this.nextFrame(() => {\n if (toast.isConnected) {\n this.fillRichToast(toast, options, imageUrl);\n }\n });\n\n const dismiss = () => {\n if (key && this.liveRichToasts.get(key)?.element === toast) {\n this.liveRichToasts.delete(key);\n }\n this.dismissToast(toast);\n };\n // Delegated, because the close button does not exist until the fill.\n toast.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).closest('.mj-toast-close')) {\n dismiss();\n return;\n }\n if (options.onClick) {\n options.onClick();\n dismiss();\n }\n });\n\n // Auto-hide with hover-pause, the same contract as the simple toast.\n let timer: ReturnType<typeof setTimeout> | null = null;\n let hideAfter = options.hideAfter;\n const arm = () => {\n if (timer) {\n clearTimeout(timer);\n }\n timer = hideAfter ? setTimeout(dismiss, hideAfter) : null;\n };\n toast.addEventListener('mouseenter', () => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n });\n toast.addEventListener('mouseleave', () => {\n if (hideAfter && !timer) {\n timer = setTimeout(dismiss, 2000);\n }\n });\n arm();\n if (key) {\n this.liveRichToasts.set(key, {\n element: toast,\n shownAt: Date.now(),\n extend: (nextHideAfter) => {\n hideAfter = nextHideAfter;\n arm();\n }\n });\n }\n }\n\n /** Host resolver first (it knows how the assistant is branded), then the caller's image. */\n private resolveRichImage(options: MJRichNotificationOptions): string | null {\n const fromHost = options.context ? this.CompletionImageUrlResolver?.(options.context) : null;\n return fromHost || options.imageUrl || null;\n }\n\n /** Writes a rich toast's content. Written once per toast — a de-duplicated repeat never re-fills. */\n private fillRichToast(toast: HTMLElement, options: MJRichNotificationOptions, imageUrl: string | null): void {\n // The icon chip uses the house tint — the brand colour mixed to 14% under itself — which\n // holds contrast in both themes; a solid brand-light background does not.\n const media = imageUrl\n ? `<img src=\"${this.escapeAttribute(imageUrl)}\" alt=\"\" style=\"width:40px;height:40px;border-radius:50%;object-fit:cover;flex:none;background:var(--mj-bg-surface);\" />`\n : `<span aria-hidden=\"true\" style=\"width:40px;height:40px;border-radius:50%;flex:none;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);color:var(--mj-brand-primary);font-size:18px;\"><i class=\"${this.escapeAttribute(options.iconClass || 'fa-solid fa-robot')}\"></i></span>`;\n const detail = options.message\n ? `<div style=\"color:var(--mj-text-secondary);margin-top:2px;\">${this.escapeHtml(options.message)}</div>`\n : '';\n toast.innerHTML = `\n ${media}\n <div style=\"flex:1;min-width:0;\">\n <div style=\"font-weight:var(--mj-font-semibold);font-size:var(--mj-text-base);\">${this.escapeHtml(options.title)}</div>\n ${detail}\n </div>\n <button type=\"button\" class=\"mj-toast-close\" aria-label=\"Dismiss\" style=\"background:transparent;border:none;padding:4px 6px;border-radius:4px;color:var(--mj-text-muted);cursor:pointer;flex:none;\"><i class=\"fa-solid fa-xmark\"></i></button>\n `;\n }\n\n /** Next paint, or the next task where no frame scheduler exists (tests, workers). */\n private nextFrame(callback: () => void): void {\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => callback());\n } else {\n setTimeout(callback, 0);\n }\n }\n\n private dismissToast(toast: HTMLElement): void {\n if (!toast.isConnected) return;\n toast.style.animation = 'mj-toast-slide-out 0.25s cubic-bezier(0.16, 1, 0.3, 1) forwards';\n toast.addEventListener('animationend', () => toast.remove(), { once: true });\n }\n\n /** One writer for the toast keyframes — the simple and rich toasts share the same animation. */\n private ensureToastKeyframes(): void {\n if (document.getElementById('mj-toast-keyframes')) return;\n const styleEl = document.createElement('style');\n styleEl.id = 'mj-toast-keyframes';\n styleEl.textContent = `\n @keyframes mj-toast-slide-in {\n from { opacity: 0; transform: translateY(-12px) scale(0.96); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n @keyframes mj-toast-slide-out {\n from { opacity: 1; transform: translateY(0) scale(1); }\n to { opacity: 0; transform: translateY(-12px) scale(0.96); }\n }\n `;\n document.head.appendChild(styleEl);\n }\n\n private escapeAttribute(value: string): string {\n return value.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>');\n }\n\n /**\n * Ensures the toast container element exists in the DOM.\n */\n private ensureToastContainer(): HTMLElement {\n let container = document.getElementById('mj-toast-container');\n if (!container) {\n container = document.createElement('div');\n container.id = 'mj-toast-container';\n container.style.cssText = `\n position: fixed;\n top: 24px;\n right: 24px;\n z-index: 100000;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 10px;\n pointer-events: none;\n max-width: calc(100vw - 48px);\n `;\n document.body.appendChild(container);\n }\n return container;\n }\n\n /**\n * Shows a modern card toast notification using DOM elements and MJ design tokens.\n */\n private showToast(message: string, style: string, hideAfter: number): void {\n const container = this.ensureToastContainer();\n\n const statusColors: Record<string, string> = {\n success: 'var(--mj-status-success, #10b981)',\n error: 'var(--mj-status-error, #ef4444)',\n warning: 'var(--mj-status-warning, #f59e0b)',\n info: 'var(--mj-status-info, #3b82f6)',\n none: 'var(--mj-brand-primary, #6366f1)',\n };\n const accentColor = statusColors[style] || statusColors['none'];\n\n const iconMap: Record<string, string> = {\n success: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-status-success, #10b981) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-status-success, #10b981); flex-shrink: 0;\"><i class=\"fa-solid fa-circle-check\" style=\"font-size: 15px;\"></i></div>`,\n error: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-status-error, #ef4444) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-status-error, #ef4444); flex-shrink: 0;\"><i class=\"fa-solid fa-circle-xmark\" style=\"font-size: 15px;\"></i></div>`,\n warning: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-status-warning, #f59e0b) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-status-warning, #f59e0b); flex-shrink: 0;\"><i class=\"fa-solid fa-triangle-exclamation\" style=\"font-size: 14px;\"></i></div>`,\n info: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-status-info, #3b82f6) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-status-info, #3b82f6); flex-shrink: 0;\"><i class=\"fa-solid fa-circle-info\" style=\"font-size: 15px;\"></i></div>`,\n none: `<div style=\"width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, var(--mj-brand-primary, #6366f1) 14%, transparent); display: flex; align-items: center; justify-content: center; color: var(--mj-brand-primary, #6366f1); flex-shrink: 0;\"><i class=\"fa-solid fa-bell\" style=\"font-size: 14px;\"></i></div>`,\n };\n const iconHtml = iconMap[style] || iconMap['none'];\n\n const toast = document.createElement('div');\n toast.className = `mj-toast-item mj-toast--${style}`;\n toast.style.cssText = `\n pointer-events: auto;\n min-width: 300px;\n max-width: 460px;\n padding: 12px 16px;\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface, #ffffff);\n color: var(--mj-text-primary, #1e293b);\n border: 1px solid var(--mj-border-subtle, rgba(0, 0, 0, 0.08));\n border-left: 4px solid ${accentColor};\n box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.12), 0 8px 10px -6px rgba(0, 0, 0, 0.08);\n display: flex;\n align-items: center;\n gap: 12px;\n font-family: inherit;\n font-size: 0.88rem;\n line-height: 1.4;\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n animation: mj-toast-slide-in 0.28s cubic-bezier(0.16, 1, 0.3, 1);\n transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n `;\n\n toast.innerHTML = `\n ${iconHtml}\n <div style=\"flex: 1; font-weight: 500; font-size: 0.84rem; color: var(--mj-text-primary, #1e293b); word-break: break-word;\">${this.escapeHtml(message)}</div>\n <button type=\"button\" class=\"mj-toast-close\" style=\"background: transparent; border: none; padding: 4px 6px; border-radius: 4px; color: var(--mj-text-muted, #94a3b8); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 13px; line-height: 1; transition: color 0.15s ease;\" aria-label=\"Close\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n `;\n\n const closeBtn = toast.querySelector<HTMLButtonElement>('.mj-toast-close');\n const removeToast = () => {\n toast.style.animation = 'mj-toast-slide-out 0.25s cubic-bezier(0.16, 1, 0.3, 1) forwards';\n toast.addEventListener('animationend', () => toast.remove(), { once: true });\n };\n\n closeBtn?.addEventListener('click', removeToast);\n closeBtn?.addEventListener('mouseenter', () => {\n closeBtn.style.color = 'var(--mj-text-primary, #1e293b)';\n closeBtn.style.backgroundColor = 'var(--mj-bg-surface-sunken, #f1f5f9)';\n });\n closeBtn?.addEventListener('mouseleave', () => {\n closeBtn.style.color = 'var(--mj-text-muted, #94a3b8)';\n closeBtn.style.backgroundColor = 'transparent';\n });\n\n container.appendChild(toast);\n\n this.ensureToastKeyframes();\n\n // Auto-hide with hover-pause support\n if (hideAfter > 0) {\n let timer: ReturnType<typeof setTimeout> | null = setTimeout(removeToast, hideAfter);\n\n toast.addEventListener('mouseenter', () => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n });\n\n toast.addEventListener('mouseleave', () => {\n if (!timer) {\n timer = setTimeout(removeToast, 2000);\n }\n });\n }\n }\n\n /**\n * Escapes HTML entities to prevent XSS in toast messages.\n */\n private escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-notifications",
|
|
3
|
-
"version": "6.1
|
|
3
|
+
"version": "6.2.0-edge.1",
|
|
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",
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
"@angular/core": "^21.2.22"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@memberjunction/core": "6.1
|
|
24
|
-
"@memberjunction/ng-base-types": "6.1
|
|
25
|
-
"@memberjunction/core-entities": "6.1
|
|
26
|
-
"@memberjunction/global": "6.1
|
|
27
|
-
"@memberjunction/graphql-dataprovider": "6.1
|
|
23
|
+
"@memberjunction/core": "6.2.0-edge.1",
|
|
24
|
+
"@memberjunction/ng-base-types": "6.2.0-edge.1",
|
|
25
|
+
"@memberjunction/core-entities": "6.2.0-edge.1",
|
|
26
|
+
"@memberjunction/global": "6.2.0-edge.1",
|
|
27
|
+
"@memberjunction/graphql-dataprovider": "6.2.0-edge.1",
|
|
28
28
|
"tslib": "^2.8.1",
|
|
29
29
|
"rxjs": "^7.8.2"
|
|
30
30
|
},
|