@memberjunction/ng-explorer-core 5.43.0 → 5.45.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.
Files changed (63) hide show
  1. package/dist/generated/lazy-feature-config.d.ts +1 -1
  2. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  3. package/dist/generated/lazy-feature-config.js +15 -3
  4. package/dist/generated/lazy-feature-config.js.map +1 -1
  5. package/dist/lib/about/about-dialog.component.d.ts +0 -1
  6. package/dist/lib/about/about-dialog.component.d.ts.map +1 -1
  7. package/dist/lib/about/about-dialog.component.js +217 -218
  8. package/dist/lib/about/about-dialog.component.js.map +1 -1
  9. package/dist/lib/command-palette/command-palette.component.js +8 -14
  10. package/dist/lib/command-palette/command-palette.component.js.map +1 -1
  11. package/dist/lib/conversation-feedback/conversation-feedback.js +66 -73
  12. package/dist/lib/conversation-feedback/conversation-feedback.js.map +1 -1
  13. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +35 -45
  14. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
  15. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +6 -4
  16. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  17. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +33 -17
  18. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  19. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  20. package/dist/lib/resource-wrappers/dashboard-resource.component.js +9 -8
  21. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  22. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
  23. package/dist/lib/resource-wrappers/search-results-resource.component.js +35 -43
  24. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  25. package/dist/lib/shell/components/header/app-switcher.component.d.ts +6 -1
  26. package/dist/lib/shell/components/header/app-switcher.component.d.ts.map +1 -1
  27. package/dist/lib/shell/components/header/app-switcher.component.js +6 -3
  28. package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
  29. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +10 -2
  30. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
  31. package/dist/lib/shell/components/tabs/component-cache-manager.js +19 -1
  32. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
  33. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +1 -0
  34. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  35. package/dist/lib/shell/components/tabs/tab-container.component.js +3 -2
  36. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  37. package/dist/lib/shell/shell.module.d.ts +1 -1
  38. package/dist/lib/shell/shell.module.d.ts.map +1 -1
  39. package/dist/lib/shell/shell.module.js +4 -1
  40. package/dist/lib/shell/shell.module.js.map +1 -1
  41. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +5 -7
  42. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
  43. package/dist/lib/single-dashboard/single-dashboard.component.js +17 -27
  44. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  45. package/dist/lib/single-list-detail/single-list-detail.component.d.ts +6 -2
  46. package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
  47. package/dist/lib/single-list-detail/single-list-detail.component.js +48 -57
  48. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  49. package/dist/lib/single-search-result/single-search-result.component.js +17 -22
  50. package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
  51. package/dist/lib/user-notifications/user-notifications.component.d.ts +65 -9
  52. package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
  53. package/dist/lib/user-notifications/user-notifications.component.js +441 -261
  54. package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
  55. package/dist/module.d.ts +33 -32
  56. package/dist/module.d.ts.map +1 -1
  57. package/dist/module.js +18 -7
  58. package/dist/module.js.map +1 -1
  59. package/package.json +49 -47
  60. package/dist/lib/__tests__/explorer-core.test.d.ts +0 -2
  61. package/dist/lib/__tests__/explorer-core.test.d.ts.map +0 -1
  62. package/dist/lib/__tests__/explorer-core.test.js +0 -229
  63. package/dist/lib/__tests__/explorer-core.test.js.map +0 -1
@@ -1,87 +1,102 @@
1
- import { Component, ViewChild } from '@angular/core';
1
+ import { Component, ChangeDetectorRef, inject } from '@angular/core';
2
2
  import { SharedService } from '@memberjunction/ng-shared';
3
3
  import { MJUserNotificationEntity, UserInfoEngine } from '@memberjunction/core-entities';
4
- import { TransactionVariable, CompositeKey } from '@memberjunction/core';
4
+ import { CompositeKey } from '@memberjunction/core';
5
5
  import { SafeJSONParse, UUIDsEqual } from '@memberjunction/global';
6
6
  import { MJNotificationService } from '@memberjunction/ng-notifications';
7
7
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
8
8
  import * as i0 from "@angular/core";
9
9
  import * as i1 from "@memberjunction/ng-shared";
10
10
  import * as i2 from "@memberjunction/ng-base-application";
11
- import * as i3 from "@angular/forms";
12
- import * as i4 from "@angular/common";
13
- const _c0 = ["allRadio"];
14
- const _c1 = ["unreadRadio"];
15
- const _c2 = ["readRadio"];
11
+ import * as i3 from "@memberjunction/ng-markdown";
12
+ import * as i4 from "@angular/forms";
13
+ import * as i5 from "@memberjunction/ng-ui-components";
14
+ import * as i6 from "@angular/common";
16
15
  const _forTrack0 = ($index, $item) => $item.ID;
17
- function UserNotificationsComponent_Conditional_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
18
- const _r1 = i0.ɵɵgetCurrentView();
16
+ const _forTrack1 = ($index, $item) => $item.Key;
17
+ const _forTrack2 = ($index, $item) => $item.N.ID;
18
+ function UserNotificationsComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
19
+ i0.ɵɵelementStart(0, "span", 7);
20
+ i0.ɵɵtext(1);
21
+ i0.ɵɵelementEnd();
22
+ } if (rf & 2) {
23
+ const ctx_r0 = i0.ɵɵnextContext();
24
+ i0.ɵɵadvance();
25
+ i0.ɵɵtextInterpolate1("", ctx_r0.UnreadNotifications.length, " unread");
26
+ } }
27
+ function UserNotificationsComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
28
+ i0.ɵɵelementStart(0, "span", 7);
29
+ i0.ɵɵtext(1, "All caught up");
30
+ i0.ɵɵelementEnd();
31
+ } }
32
+ function UserNotificationsComponent_Conditional_11_Conditional_1_Template(rf, ctx) { if (rf & 1) {
33
+ const _r2 = i0.ɵɵgetCurrentView();
19
34
  i0.ɵɵelementStart(0, "button", 16);
20
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_8_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.markAllAsRead()); });
35
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_11_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.markAllAsRead()); });
21
36
  i0.ɵɵelement(1, "i", 17);
22
37
  i0.ɵɵelementStart(2, "span", 18);
23
38
  i0.ɵɵtext(3, "Mark All Read");
24
39
  i0.ɵɵelementEnd()();
25
40
  } }
26
- function UserNotificationsComponent_Conditional_8_Conditional_2_Template(rf, ctx) { if (rf & 1) {
41
+ function UserNotificationsComponent_Conditional_11_Conditional_2_Template(rf, ctx) { if (rf & 1) {
27
42
  const _r3 = i0.ɵɵgetCurrentView();
28
43
  i0.ɵɵelementStart(0, "button", 19);
29
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_8_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.markAllAsUnread()); });
44
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_11_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.markAllAsUnread()); });
30
45
  i0.ɵɵelement(1, "i", 20);
31
46
  i0.ɵɵelementStart(2, "span", 18);
32
47
  i0.ɵɵtext(3, "Mark All Unread");
33
48
  i0.ɵɵelementEnd()();
34
49
  } }
35
- function UserNotificationsComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
36
- i0.ɵɵelementStart(0, "div", 9);
37
- i0.ɵɵconditionalCreate(1, UserNotificationsComponent_Conditional_8_Conditional_1_Template, 4, 0, "button", 14);
38
- i0.ɵɵconditionalCreate(2, UserNotificationsComponent_Conditional_8_Conditional_2_Template, 4, 0, "button", 15);
50
+ function UserNotificationsComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
51
+ i0.ɵɵelementStart(0, "div", 8);
52
+ i0.ɵɵconditionalCreate(1, UserNotificationsComponent_Conditional_11_Conditional_1_Template, 4, 0, "button", 14);
53
+ i0.ɵɵconditionalCreate(2, UserNotificationsComponent_Conditional_11_Conditional_2_Template, 4, 0, "button", 15);
39
54
  i0.ɵɵelementEnd();
40
55
  } if (rf & 2) {
41
- const ctx_r1 = i0.ɵɵnextContext();
56
+ const ctx_r0 = i0.ɵɵnextContext();
42
57
  i0.ɵɵadvance();
43
- i0.ɵɵconditional(ctx_r1.UnreadNotifications.length > 0 ? 1 : -1);
58
+ i0.ɵɵconditional(ctx_r0.UnreadNotifications.length > 0 ? 1 : -1);
44
59
  i0.ɵɵadvance();
45
- i0.ɵɵconditional(ctx_r1.ReadNotifications.length > 0 ? 2 : -1);
60
+ i0.ɵɵconditional(ctx_r0.ReadNotifications.length > 0 ? 2 : -1);
46
61
  } }
47
- function UserNotificationsComponent_Conditional_9_Conditional_13_Template(rf, ctx) { if (rf & 1) {
62
+ function UserNotificationsComponent_Conditional_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
48
63
  const _r5 = i0.ɵɵgetCurrentView();
49
- i0.ɵɵelementStart(0, "button", 38);
50
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_9_Conditional_13_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectReadOption("Unread")); });
51
- i0.ɵɵelementStart(1, "span", 26);
64
+ i0.ɵɵelementStart(0, "button", 35);
65
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_12_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.selectReadOption("Unread")); });
66
+ i0.ɵɵelementStart(1, "span", 25);
52
67
  i0.ɵɵtext(2, "Unread");
53
68
  i0.ɵɵelementEnd();
54
- i0.ɵɵelementStart(3, "span", 27);
69
+ i0.ɵɵelementStart(3, "span", 26);
55
70
  i0.ɵɵtext(4);
56
71
  i0.ɵɵelementEnd()();
57
72
  } if (rf & 2) {
58
- const ctx_r1 = i0.ɵɵnextContext(2);
59
- i0.ɵɵclassProp("active", ctx_r1.radioSelected === "Unread")("has-unread", ctx_r1.UnreadNotifications.length > 0);
60
- i0.ɵɵattribute("aria-pressed", ctx_r1.radioSelected === "Unread");
73
+ const ctx_r0 = i0.ɵɵnextContext(2);
74
+ i0.ɵɵclassProp("active", ctx_r0.radioSelected === "Unread")("has-unread", ctx_r0.UnreadNotifications.length > 0);
75
+ i0.ɵɵattribute("aria-pressed", ctx_r0.radioSelected === "Unread");
61
76
  i0.ɵɵadvance(3);
62
- i0.ɵɵclassProp("unread-count", ctx_r1.UnreadNotifications.length > 0);
77
+ i0.ɵɵclassProp("unread-count", ctx_r0.UnreadNotifications.length > 0);
63
78
  i0.ɵɵadvance();
64
- i0.ɵɵtextInterpolate1(" ", ctx_r1.UnreadNotifications.length, " ");
79
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.UnreadNotifications.length, " ");
65
80
  } }
66
- function UserNotificationsComponent_Conditional_9_Conditional_16_Template(rf, ctx) { if (rf & 1) {
81
+ function UserNotificationsComponent_Conditional_12_Conditional_10_Template(rf, ctx) { if (rf & 1) {
67
82
  const _r6 = i0.ɵɵgetCurrentView();
68
- i0.ɵɵelementStart(0, "button", 39);
69
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_9_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectReadOption("Read")); });
70
- i0.ɵɵelementStart(1, "span", 26);
83
+ i0.ɵɵelementStart(0, "button", 36);
84
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_12_Conditional_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.selectReadOption("Read")); });
85
+ i0.ɵɵelementStart(1, "span", 25);
71
86
  i0.ɵɵtext(2, "Read");
72
87
  i0.ɵɵelementEnd();
73
- i0.ɵɵelementStart(3, "span", 27);
88
+ i0.ɵɵelementStart(3, "span", 26);
74
89
  i0.ɵɵtext(4);
75
90
  i0.ɵɵelementEnd()();
76
91
  } if (rf & 2) {
77
- const ctx_r1 = i0.ɵɵnextContext(2);
78
- i0.ɵɵclassProp("active", ctx_r1.radioSelected === "Read");
79
- i0.ɵɵattribute("aria-pressed", ctx_r1.radioSelected === "Read");
92
+ const ctx_r0 = i0.ɵɵnextContext(2);
93
+ i0.ɵɵclassProp("active", ctx_r0.radioSelected === "Read");
94
+ i0.ɵɵattribute("aria-pressed", ctx_r0.radioSelected === "Read");
80
95
  i0.ɵɵadvance(4);
81
- i0.ɵɵtextInterpolate(ctx_r1.ReadNotifications.length);
96
+ i0.ɵɵtextInterpolate(ctx_r0.ReadNotifications.length);
82
97
  } }
83
- function UserNotificationsComponent_Conditional_9_Conditional_17_For_5_Template(rf, ctx) { if (rf & 1) {
84
- i0.ɵɵelementStart(0, "option", 41);
98
+ function UserNotificationsComponent_Conditional_12_Conditional_11_For_5_Template(rf, ctx) { if (rf & 1) {
99
+ i0.ɵɵelementStart(0, "option", 38);
85
100
  i0.ɵɵtext(1);
86
101
  i0.ɵɵelementEnd();
87
102
  } if (rf & 2) {
@@ -90,205 +105,281 @@ function UserNotificationsComponent_Conditional_9_Conditional_17_For_5_Template(
90
105
  i0.ɵɵadvance();
91
106
  i0.ɵɵtextInterpolate(type_r8.Name);
92
107
  } }
93
- function UserNotificationsComponent_Conditional_9_Conditional_17_Template(rf, ctx) { if (rf & 1) {
108
+ function UserNotificationsComponent_Conditional_12_Conditional_11_Template(rf, ctx) { if (rf & 1) {
94
109
  const _r7 = i0.ɵɵgetCurrentView();
95
- i0.ɵɵelementStart(0, "div", 32)(1, "select", 40);
96
- i0.ɵɵtwoWayListener("ngModelChange", function UserNotificationsComponent_Conditional_9_Conditional_17_Template_select_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.selectedTypeFilter, $event) || (ctx_r1.selectedTypeFilter = $event); return i0.ɵɵresetView($event); });
97
- i0.ɵɵlistener("change", function UserNotificationsComponent_Conditional_9_Conditional_17_Template_select_change_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onTypeFilterChange(ctx_r1.selectedTypeFilter)); });
98
- i0.ɵɵelementStart(2, "option", 41);
110
+ i0.ɵɵelementStart(0, "div", 29)(1, "select", 37);
111
+ i0.ɵɵtwoWayListener("ngModelChange", function UserNotificationsComponent_Conditional_12_Conditional_11_Template_select_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r0.selectedTypeFilter, $event) || (ctx_r0.selectedTypeFilter = $event); return i0.ɵɵresetView($event); });
112
+ i0.ɵɵlistener("change", function UserNotificationsComponent_Conditional_12_Conditional_11_Template_select_change_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onTypeFilterChange(ctx_r0.selectedTypeFilter)); });
113
+ i0.ɵɵelementStart(2, "option", 38);
99
114
  i0.ɵɵtext(3, "All Types");
100
115
  i0.ɵɵelementEnd();
101
- i0.ɵɵrepeaterCreate(4, UserNotificationsComponent_Conditional_9_Conditional_17_For_5_Template, 2, 2, "option", 41, _forTrack0);
116
+ i0.ɵɵrepeaterCreate(4, UserNotificationsComponent_Conditional_12_Conditional_11_For_5_Template, 2, 2, "option", 38, _forTrack0);
102
117
  i0.ɵɵelementEnd()();
103
118
  } if (rf & 2) {
104
- const ctx_r1 = i0.ɵɵnextContext(2);
119
+ const ctx_r0 = i0.ɵɵnextContext(2);
105
120
  i0.ɵɵadvance();
106
- i0.ɵɵtwoWayProperty("ngModel", ctx_r1.selectedTypeFilter);
121
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.selectedTypeFilter);
107
122
  i0.ɵɵadvance();
108
123
  i0.ɵɵproperty("value", null);
109
124
  i0.ɵɵadvance(2);
110
- i0.ɵɵrepeater(ctx_r1.notificationTypes);
125
+ i0.ɵɵrepeater(ctx_r0.notificationTypes);
111
126
  } }
112
- function UserNotificationsComponent_Conditional_9_Conditional_22_Template(rf, ctx) { if (rf & 1) {
113
- i0.ɵɵelementStart(0, "div", 37)(1, "span", 42);
114
- i0.ɵɵelement(2, "i", 43);
127
+ function UserNotificationsComponent_Conditional_12_Conditional_16_Template(rf, ctx) { if (rf & 1) {
128
+ i0.ɵɵelementStart(0, "div", 34)(1, "span", 39);
129
+ i0.ɵɵelement(2, "i", 40);
115
130
  i0.ɵɵtext(3);
116
131
  i0.ɵɵelementEnd()();
117
132
  } if (rf & 2) {
118
- const ctx_r1 = i0.ɵɵnextContext(2);
133
+ const ctx_r0 = i0.ɵɵnextContext(2);
119
134
  i0.ɵɵadvance(3);
120
- i0.ɵɵtextInterpolate2(" Showing ", ctx_r1.NotificationsToShow.length, " of ", ctx_r1.AllNotifications.length, " ");
135
+ i0.ɵɵtextInterpolate2(" Showing ", ctx_r0.NotificationsToShow.length, " of ", ctx_r0.AllNotifications.length, " ");
121
136
  } }
122
- function UserNotificationsComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
137
+ function UserNotificationsComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
123
138
  const _r4 = i0.ɵɵgetCurrentView();
124
- i0.ɵɵelementStart(0, "div", 10)(1, "div", 21)(2, "div", 22)(3, "div", 23)(4, "input", 24, 0);
125
- i0.ɵɵlistener("change", function UserNotificationsComponent_Conditional_9_Template_input_change_4_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onReadRadioChanged($event)); });
139
+ i0.ɵɵelementStart(0, "div", 9)(1, "div", 21)(2, "div", 22)(3, "div", 23)(4, "button", 24);
140
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_12_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.selectReadOption("All")); });
141
+ i0.ɵɵelementStart(5, "span", 25);
142
+ i0.ɵɵtext(6, "All");
126
143
  i0.ɵɵelementEnd();
127
- i0.ɵɵelementStart(6, "button", 25);
128
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_9_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.selectReadOption("All")); });
129
144
  i0.ɵɵelementStart(7, "span", 26);
130
- i0.ɵɵtext(8, "All");
131
- i0.ɵɵelementEnd();
132
- i0.ɵɵelementStart(9, "span", 27);
133
- i0.ɵɵtext(10);
145
+ i0.ɵɵtext(8);
134
146
  i0.ɵɵelementEnd()();
135
- i0.ɵɵelementStart(11, "input", 28, 1);
136
- i0.ɵɵlistener("change", function UserNotificationsComponent_Conditional_9_Template_input_change_11_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onReadRadioChanged($event)); });
147
+ i0.ɵɵconditionalCreate(9, UserNotificationsComponent_Conditional_12_Conditional_9_Template, 5, 8, "button", 27);
148
+ i0.ɵɵconditionalCreate(10, UserNotificationsComponent_Conditional_12_Conditional_10_Template, 5, 4, "button", 28);
137
149
  i0.ɵɵelementEnd();
138
- i0.ɵɵconditionalCreate(13, UserNotificationsComponent_Conditional_9_Conditional_13_Template, 5, 8, "button", 29);
139
- i0.ɵɵelementStart(14, "input", 30, 2);
140
- i0.ɵɵlistener("change", function UserNotificationsComponent_Conditional_9_Template_input_change_14_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onReadRadioChanged($event)); });
141
- i0.ɵɵelementEnd();
142
- i0.ɵɵconditionalCreate(16, UserNotificationsComponent_Conditional_9_Conditional_16_Template, 5, 4, "button", 31);
143
- i0.ɵɵelementEnd();
144
- i0.ɵɵconditionalCreate(17, UserNotificationsComponent_Conditional_9_Conditional_17_Template, 6, 2, "div", 32);
150
+ i0.ɵɵconditionalCreate(11, UserNotificationsComponent_Conditional_12_Conditional_11_Template, 6, 2, "div", 29);
145
151
  i0.ɵɵelementEnd()();
146
- i0.ɵɵelementStart(18, "div", 33)(19, "div", 34);
147
- i0.ɵɵelement(20, "i", 35);
148
- i0.ɵɵelementStart(21, "input", 36);
149
- i0.ɵɵlistener("input", function UserNotificationsComponent_Conditional_9_Template_input_input_21_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onFilterChanged($event.target.value)); });
152
+ i0.ɵɵelementStart(12, "div", 30)(13, "div", 31);
153
+ i0.ɵɵelement(14, "i", 32);
154
+ i0.ɵɵelementStart(15, "input", 33);
155
+ i0.ɵɵlistener("input", function UserNotificationsComponent_Conditional_12_Template_input_input_15_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onFilterChanged($event.target.value)); });
150
156
  i0.ɵɵelementEnd()()();
151
- i0.ɵɵconditionalCreate(22, UserNotificationsComponent_Conditional_9_Conditional_22_Template, 4, 2, "div", 37);
157
+ i0.ɵɵconditionalCreate(16, UserNotificationsComponent_Conditional_12_Conditional_16_Template, 4, 2, "div", 34);
152
158
  i0.ɵɵelementEnd();
153
159
  } if (rf & 2) {
154
- const ctx_r1 = i0.ɵɵnextContext();
155
- i0.ɵɵadvance(6);
156
- i0.ɵɵclassProp("active", ctx_r1.radioSelected === "All");
157
- i0.ɵɵattribute("aria-pressed", ctx_r1.radioSelected === "All");
160
+ const ctx_r0 = i0.ɵɵnextContext();
158
161
  i0.ɵɵadvance(4);
159
- i0.ɵɵtextInterpolate(ctx_r1.AllNotifications.length);
160
- i0.ɵɵadvance(3);
161
- i0.ɵɵconditional(ctx_r1.UnreadNotifications.length > 0 || ctx_r1.ReadNotifications.length === 0 ? 13 : -1);
162
- i0.ɵɵadvance(3);
163
- i0.ɵɵconditional(ctx_r1.ReadNotifications.length > 0 || ctx_r1.UnreadNotifications.length === 0 ? 16 : -1);
162
+ i0.ɵɵclassProp("active", ctx_r0.radioSelected === "All");
163
+ i0.ɵɵattribute("aria-pressed", ctx_r0.radioSelected === "All");
164
+ i0.ɵɵadvance(4);
165
+ i0.ɵɵtextInterpolate(ctx_r0.AllNotifications.length);
166
+ i0.ɵɵadvance();
167
+ i0.ɵɵconditional(ctx_r0.UnreadNotifications.length > 0 || ctx_r0.ReadNotifications.length === 0 ? 9 : -1);
164
168
  i0.ɵɵadvance();
165
- i0.ɵɵconditional(ctx_r1.notificationTypes.length > 0 ? 17 : -1);
169
+ i0.ɵɵconditional(ctx_r0.ReadNotifications.length > 0 || ctx_r0.UnreadNotifications.length === 0 ? 10 : -1);
170
+ i0.ɵɵadvance();
171
+ i0.ɵɵconditional(ctx_r0.notificationTypes.length > 0 ? 11 : -1);
166
172
  i0.ɵɵadvance(4);
167
- i0.ɵɵproperty("value", ctx_r1.currentFilter);
173
+ i0.ɵɵproperty("value", ctx_r0.currentFilter);
168
174
  i0.ɵɵadvance();
169
- i0.ɵɵconditional(ctx_r1.NotificationsToShow.length !== ctx_r1.AllNotifications.length ? 22 : -1);
175
+ i0.ɵɵconditional(ctx_r0.NotificationsToShow.length !== ctx_r0.AllNotifications.length ? 16 : -1);
170
176
  } }
171
- function UserNotificationsComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
172
- i0.ɵɵelementStart(0, "div", 12)(1, "div", 44);
173
- i0.ɵɵelement(2, "i", 45);
177
+ function UserNotificationsComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
178
+ i0.ɵɵelement(0, "mj-empty-state", 11);
179
+ } }
180
+ function UserNotificationsComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
181
+ i0.ɵɵelement(0, "mj-empty-state", 12);
182
+ } }
183
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_10_Template(rf, ctx) { if (rf & 1) {
184
+ i0.ɵɵtext(0);
185
+ } if (rf & 2) {
186
+ const vm_r10 = i0.ɵɵnextContext().$implicit;
187
+ i0.ɵɵtextInterpolate1(" ", vm_r10.Relative, " ");
188
+ } }
189
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_11_Template(rf, ctx) { if (rf & 1) {
190
+ i0.ɵɵelementStart(0, "time");
191
+ i0.ɵɵtext(1);
192
+ i0.ɵɵpipe(2, "date");
174
193
  i0.ɵɵelementEnd();
175
- i0.ɵɵelementStart(3, "h3");
176
- i0.ɵɵtext(4, "No Notifications");
194
+ } if (rf & 2) {
195
+ const vm_r10 = i0.ɵɵnextContext().$implicit;
196
+ i0.ɵɵattribute("datetime", vm_r10.N.__mj_CreatedAt);
197
+ i0.ɵɵadvance();
198
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(2, 2, vm_r10.N.__mj_CreatedAt, "MMM d, h:mm a"));
199
+ } }
200
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_15_Template(rf, ctx) { if (rf & 1) {
201
+ i0.ɵɵelementStart(0, "span", 52);
202
+ i0.ɵɵelement(1, "i", 59);
203
+ i0.ɵɵtext(2, " Open ");
177
204
  i0.ɵɵelementEnd();
178
- i0.ɵɵelementStart(5, "p");
179
- i0.ɵɵtext(6, "You're all caught up! New notifications will appear here.");
180
- i0.ɵɵelementEnd()();
181
205
  } }
182
- function UserNotificationsComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
183
- i0.ɵɵelementStart(0, "div", 12)(1, "div", 44);
184
- i0.ɵɵelement(2, "i", 46);
206
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_16_Template(rf, ctx) { if (rf & 1) {
207
+ i0.ɵɵelementStart(0, "p", 53);
208
+ i0.ɵɵtext(1);
185
209
  i0.ɵɵelementEnd();
186
- i0.ɵɵelementStart(3, "h3");
187
- i0.ɵɵtext(4, "No Matching Notifications");
210
+ } if (rf & 2) {
211
+ const vm_r10 = i0.ɵɵnextContext().$implicit;
212
+ i0.ɵɵadvance();
213
+ i0.ɵɵtextInterpolate(vm_r10.Preview);
214
+ } }
215
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Case_1_Template(rf, ctx) { if (rf & 1) {
216
+ i0.ɵɵelement(0, "div", 61);
217
+ } if (rf & 2) {
218
+ const vm_r10 = i0.ɵɵnextContext(2).$implicit;
219
+ i0.ɵɵproperty("innerHTML", vm_r10.Body, i0.ɵɵsanitizeHtml);
220
+ } }
221
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Case_2_Template(rf, ctx) { if (rf & 1) {
222
+ i0.ɵɵelement(0, "mj-markdown", 62);
223
+ } if (rf & 2) {
224
+ const vm_r10 = i0.ɵɵnextContext(2).$implicit;
225
+ i0.ɵɵproperty("data", vm_r10.Body)("enableMermaid", false);
226
+ } }
227
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Case_3_Template(rf, ctx) { if (rf & 1) {
228
+ i0.ɵɵelementStart(0, "p", 63);
229
+ i0.ɵɵtext(1);
188
230
  i0.ɵɵelementEnd();
189
- i0.ɵɵelementStart(5, "p");
190
- i0.ɵɵtext(6, "Try adjusting your filters to see more notifications.");
191
- i0.ɵɵelementEnd()();
231
+ } if (rf & 2) {
232
+ const vm_r10 = i0.ɵɵnextContext(2).$implicit;
233
+ i0.ɵɵadvance();
234
+ i0.ɵɵtextInterpolate(vm_r10.N.Message);
192
235
  } }
193
- function UserNotificationsComponent_Conditional_13_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
236
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Template(rf, ctx) { if (rf & 1) {
194
237
  const _r11 = i0.ɵɵgetCurrentView();
195
- i0.ɵɵelementStart(0, "button", 62);
196
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_13_For_2_Conditional_19_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r11); const notification_r10 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.markAsRead(notification_r10, true, null)); });
197
- i0.ɵɵelement(1, "i", 63);
198
- i0.ɵɵelementStart(2, "span", 64);
238
+ i0.ɵɵelementStart(0, "div", 60);
239
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
240
+ i0.ɵɵconditionalCreate(1, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Case_1_Template, 1, 1, "div", 61)(2, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Case_2_Template, 1, 2, "mj-markdown", 62)(3, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Case_3_Template, 2, 1, "p", 63);
241
+ i0.ɵɵelementEnd();
242
+ } if (rf & 2) {
243
+ let tmp_22_0;
244
+ const vm_r10 = i0.ɵɵnextContext().$implicit;
245
+ i0.ɵɵadvance();
246
+ i0.ɵɵconditional((tmp_22_0 = vm_r10.Kind) === "html" ? 1 : tmp_22_0 === "markdown" ? 2 : 3);
247
+ } }
248
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_18_Template(rf, ctx) { if (rf & 1) {
249
+ const _r12 = i0.ɵɵgetCurrentView();
250
+ i0.ɵɵelementStart(0, "button", 64);
251
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_18_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r12); const vm_r10 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.ToggleExpanded(vm_r10, $event)); });
252
+ i0.ɵɵelement(1, "i", 65);
253
+ i0.ɵɵtext(2);
254
+ i0.ɵɵelementEnd();
255
+ } if (rf & 2) {
256
+ const vm_r10 = i0.ɵɵnextContext().$implicit;
257
+ const ctx_r0 = i0.ɵɵnextContext(3);
258
+ i0.ɵɵattribute("aria-expanded", ctx_r0.IsExpanded(vm_r10));
259
+ i0.ɵɵadvance();
260
+ i0.ɵɵclassProp("fa-chevron-down", !ctx_r0.IsExpanded(vm_r10))("fa-chevron-up", ctx_r0.IsExpanded(vm_r10));
261
+ i0.ɵɵadvance();
262
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.IsExpanded(vm_r10) ? "Show less" : "Show more", " ");
263
+ } }
264
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_20_Template(rf, ctx) { if (rf & 1) {
265
+ const _r13 = i0.ɵɵgetCurrentView();
266
+ i0.ɵɵelementStart(0, "button", 66);
267
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_20_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const vm_r10 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.markAsRead(vm_r10.N, true, null)); });
268
+ i0.ɵɵelement(1, "i", 67);
269
+ i0.ɵɵelementStart(2, "span", 68);
199
270
  i0.ɵɵtext(3, "Read");
200
271
  i0.ɵɵelementEnd()();
201
272
  } if (rf & 2) {
202
- const notification_r10 = i0.ɵɵnextContext().$implicit;
203
- i0.ɵɵattribute("aria-label", "Mark " + notification_r10.Title + " as read");
273
+ const vm_r10 = i0.ɵɵnextContext().$implicit;
274
+ i0.ɵɵattribute("aria-label", "Mark " + vm_r10.N.Title + " as read");
204
275
  } }
205
- function UserNotificationsComponent_Conditional_13_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
206
- const _r12 = i0.ɵɵgetCurrentView();
207
- i0.ɵɵelementStart(0, "button", 65);
208
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_13_For_2_Conditional_20_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r12); const notification_r10 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.markAsRead(notification_r10, false, null)); });
276
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_21_Template(rf, ctx) { if (rf & 1) {
277
+ const _r14 = i0.ɵɵgetCurrentView();
278
+ i0.ɵɵelementStart(0, "button", 69);
279
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_21_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const vm_r10 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.markAsRead(vm_r10.N, false, null)); });
209
280
  i0.ɵɵelement(1, "i", 20);
210
- i0.ɵɵelementStart(2, "span", 64);
281
+ i0.ɵɵelementStart(2, "span", 68);
211
282
  i0.ɵɵtext(3, "Unread");
212
283
  i0.ɵɵelementEnd()();
213
284
  } if (rf & 2) {
214
- const notification_r10 = i0.ɵɵnextContext().$implicit;
215
- i0.ɵɵattribute("aria-label", "Mark " + notification_r10.Title + " as unread");
285
+ const vm_r10 = i0.ɵɵnextContext().$implicit;
286
+ i0.ɵɵattribute("aria-label", "Mark " + vm_r10.N.Title + " as unread");
216
287
  } }
217
- function UserNotificationsComponent_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
288
+ function UserNotificationsComponent_Conditional_16_For_2_For_3_Template(rf, ctx) { if (rf & 1) {
218
289
  const _r9 = i0.ɵɵgetCurrentView();
219
- i0.ɵɵelementStart(0, "article", 48);
220
- i0.ɵɵelement(1, "div", 49);
221
- i0.ɵɵelementStart(2, "div", 50);
290
+ i0.ɵɵelementStart(0, "article", 43);
291
+ i0.ɵɵelement(1, "div", 44);
292
+ i0.ɵɵelementStart(2, "div", 45);
222
293
  i0.ɵɵelement(3, "i");
223
294
  i0.ɵɵelementEnd();
224
- i0.ɵɵelementStart(4, "div", 51);
225
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_13_For_2_Template_div_click_4_listener() { const notification_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.notificationClicked(notification_r10)); });
226
- i0.ɵɵelementStart(5, "div", 52)(6, "h3", 53);
295
+ i0.ɵɵelementStart(4, "div", 46);
296
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Template_div_click_4_listener() { const vm_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.notificationClicked(vm_r10.N)); });
297
+ i0.ɵɵelementStart(5, "div", 47)(6, "h3", 48);
227
298
  i0.ɵɵtext(7);
228
299
  i0.ɵɵelementEnd();
229
- i0.ɵɵelementStart(8, "span", 54);
230
- i0.ɵɵelement(9, "i", 55);
231
- i0.ɵɵelementStart(10, "time");
232
- i0.ɵɵtext(11);
233
- i0.ɵɵpipe(12, "date");
234
- i0.ɵɵelementEnd()()();
235
- i0.ɵɵelementStart(13, "div", 56)(14, "span", 57);
236
- i0.ɵɵtext(15);
237
- i0.ɵɵelementEnd()();
238
- i0.ɵɵelementStart(16, "p", 58);
239
- i0.ɵɵtext(17);
300
+ i0.ɵɵelementStart(8, "span", 49);
301
+ i0.ɵɵpipe(9, "date");
302
+ i0.ɵɵconditionalCreate(10, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_10_Template, 1, 1)(11, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_11_Template, 3, 5, "time");
240
303
  i0.ɵɵelementEnd()();
241
- i0.ɵɵelementStart(18, "div", 59);
242
- i0.ɵɵconditionalCreate(19, UserNotificationsComponent_Conditional_13_For_2_Conditional_19_Template, 4, 1, "button", 60)(20, UserNotificationsComponent_Conditional_13_For_2_Conditional_20_Template, 4, 1, "button", 61);
304
+ i0.ɵɵelementStart(12, "div", 50)(13, "span", 51);
305
+ i0.ɵɵtext(14);
306
+ i0.ɵɵelementEnd();
307
+ i0.ɵɵconditionalCreate(15, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_15_Template, 3, 0, "span", 52);
308
+ i0.ɵɵelementEnd();
309
+ i0.ɵɵconditionalCreate(16, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_16_Template, 2, 1, "p", 53)(17, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Template, 4, 1, "div", 54);
310
+ i0.ɵɵconditionalCreate(18, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_18_Template, 3, 6, "button", 55);
311
+ i0.ɵɵelementEnd();
312
+ i0.ɵɵelementStart(19, "div", 56);
313
+ i0.ɵɵconditionalCreate(20, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_20_Template, 4, 1, "button", 57)(21, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_21_Template, 4, 1, "button", 58);
243
314
  i0.ɵɵelementEnd()();
244
315
  } if (rf & 2) {
245
- const notification_r10 = ctx.$implicit;
246
- const ctx_r1 = i0.ɵɵnextContext(2);
247
- i0.ɵɵclassProp("unread", notification_r10.Unread)("clickable", ctx_r1.isNotificationClickable(notification_r10));
248
- i0.ɵɵattribute("aria-label", notification_r10.Title);
249
- i0.ɵɵadvance(2);
250
- i0.ɵɵstyleProp("background-color", ctx_r1.getTypeColor(notification_r10) + "15");
251
- i0.ɵɵadvance();
252
- i0.ɵɵclassMap("fa-solid " + ctx_r1.getTypeIcon(notification_r10));
253
- i0.ɵɵstyleProp("color", ctx_r1.getTypeColor(notification_r10));
316
+ const vm_r10 = ctx.$implicit;
317
+ const ctx_r0 = i0.ɵɵnextContext(3);
318
+ i0.ɵɵclassProp("unread", vm_r10.N.Unread)("expanded", ctx_r0.IsExpanded(vm_r10))("clickable", vm_r10.Clickable);
319
+ i0.ɵɵattribute("aria-label", vm_r10.N.Title);
254
320
  i0.ɵɵadvance(3);
255
- i0.ɵɵclassProp("card-title-unread", notification_r10.Unread);
256
- i0.ɵɵadvance();
257
- i0.ɵɵtextInterpolate1(" ", notification_r10.Title, " ");
321
+ i0.ɵɵclassMap("fa-solid " + ctx_r0.getTypeIcon(vm_r10.N));
322
+ i0.ɵɵstyleProp("color", ctx_r0.getTypeColor(vm_r10.N));
258
323
  i0.ɵɵadvance(3);
259
- i0.ɵɵattribute("datetime", notification_r10.__mj_CreatedAt);
324
+ i0.ɵɵclassProp("card-title-unread", vm_r10.N.Unread);
260
325
  i0.ɵɵadvance();
261
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(12, 23, notification_r10.__mj_CreatedAt, "MMM d, h:mm a"), " ");
262
- i0.ɵɵadvance(3);
263
- i0.ɵɵstyleProp("background-color", ctx_r1.getTypeColor(notification_r10) + "15")("color", ctx_r1.getTypeColor(notification_r10));
326
+ i0.ɵɵtextInterpolate1(" ", vm_r10.N.Title, " ");
264
327
  i0.ɵɵadvance();
265
- i0.ɵɵtextInterpolate1(" ", ctx_r1.getTypeName(notification_r10), " ");
328
+ i0.ɵɵproperty("title", i0.ɵɵpipeBind2(9, 21, vm_r10.N.__mj_CreatedAt, "medium") ?? "");
266
329
  i0.ɵɵadvance(2);
267
- i0.ɵɵtextInterpolate(notification_r10.Message);
330
+ i0.ɵɵconditional(vm_r10.Relative ? 10 : 11);
331
+ i0.ɵɵadvance(4);
332
+ i0.ɵɵtextInterpolate(ctx_r0.getTypeName(vm_r10.N));
333
+ i0.ɵɵadvance();
334
+ i0.ɵɵconditional(vm_r10.Clickable ? 15 : -1);
335
+ i0.ɵɵadvance();
336
+ i0.ɵɵconditional(!ctx_r0.IsExpanded(vm_r10) ? 16 : 17);
337
+ i0.ɵɵadvance(2);
338
+ i0.ɵɵconditional(vm_r10.Expandable ? 18 : -1);
268
339
  i0.ɵɵadvance(2);
269
- i0.ɵɵconditional(notification_r10.Unread ? 19 : 20);
340
+ i0.ɵɵconditional(vm_r10.N.Unread ? 20 : 21);
341
+ } }
342
+ function UserNotificationsComponent_Conditional_16_For_2_Template(rf, ctx) { if (rf & 1) {
343
+ i0.ɵɵelementStart(0, "div", 41);
344
+ i0.ɵɵtext(1);
345
+ i0.ɵɵelementEnd();
346
+ i0.ɵɵrepeaterCreate(2, UserNotificationsComponent_Conditional_16_For_2_For_3_Template, 22, 24, "article", 42, _forTrack2);
347
+ } if (rf & 2) {
348
+ const group_r15 = ctx.$implicit;
349
+ i0.ɵɵadvance();
350
+ i0.ɵɵtextInterpolate(group_r15.Label);
351
+ i0.ɵɵadvance();
352
+ i0.ɵɵrepeater(group_r15.Items);
270
353
  } }
271
- function UserNotificationsComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
354
+ function UserNotificationsComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
272
355
  i0.ɵɵelementStart(0, "div", 13);
273
- i0.ɵɵrepeaterCreate(1, UserNotificationsComponent_Conditional_13_For_2_Template, 21, 26, "article", 47, _forTrack0);
356
+ i0.ɵɵrepeaterCreate(1, UserNotificationsComponent_Conditional_16_For_2_Template, 4, 1, null, null, _forTrack1);
274
357
  i0.ɵɵelementEnd();
275
358
  } if (rf & 2) {
276
- const ctx_r1 = i0.ɵɵnextContext();
359
+ const ctx_r0 = i0.ɵɵnextContext();
277
360
  i0.ɵɵadvance();
278
- i0.ɵɵrepeater(ctx_r1.NotificationsToShow);
361
+ i0.ɵɵrepeater(ctx_r0.Groups);
279
362
  } }
363
+ /** Collapsed-preview cap (characters of plain text). */
364
+ const PREVIEW_MAX_CHARS = 240;
365
+ /** How often the snapshot relative-time labels refresh. */
366
+ const RELATIVE_REFRESH_MS = 60_000;
280
367
  export class UserNotificationsComponent extends BaseAngularComponent {
281
368
  sharedService;
282
369
  navigationService;
283
370
  appManager;
284
- allRadio;
285
- unreadRadio;
286
- readRadio;
371
+ cdr = inject(ChangeDetectorRef);
287
372
  radioSelected = 'All';
288
373
  currentFilter = '';
289
374
  notificationTypes = [];
290
375
  selectedTypeFilter = null;
291
376
  loadingTypes = true;
377
+ /** IDs of cards currently expanded to their full rendered content. */
378
+ Expanded = new Set();
379
+ groups = [];
380
+ groupsKey = '';
381
+ vmCache = new Map();
382
+ relativeTimer = null;
292
383
  constructor(sharedService, navigationService, appManager) {
293
384
  super();
294
385
  this.sharedService = sharedService;
@@ -297,10 +388,23 @@ export class UserNotificationsComponent extends BaseAngularComponent {
297
388
  }
298
389
  async ngOnInit() {
299
390
  this.loadNotificationTypes();
391
+ // Refresh the snapshot relative-time labels between change-detection passes.
392
+ this.relativeTimer = setInterval(() => {
393
+ for (const vm of this.vmCache.values()) {
394
+ vm.Relative = this.relativeTime(vm.N.__mj_CreatedAt);
395
+ }
396
+ this.groupsKey = ''; // day buckets can shift at midnight
397
+ this.cdr.markForCheck();
398
+ }, RELATIVE_REFRESH_MS);
300
399
  }
301
400
  ngAfterViewInit() {
302
401
  this.sharedService.InvokeManualResize(); // make sure the notifications component is sized correctly
303
402
  }
403
+ ngOnDestroy() {
404
+ if (this.relativeTimer != null) {
405
+ clearInterval(this.relativeTimer);
406
+ }
407
+ }
304
408
  loadNotificationTypes() {
305
409
  // Get notification types from UserInfoEngine cache, sorted client-side
306
410
  // UserInfoEngine is auto-configured via @RegisterForStartup()
@@ -314,6 +418,9 @@ export class UserNotificationsComponent extends BaseAngularComponent {
314
418
  });
315
419
  this.loadingTypes = false;
316
420
  }
421
+ // ========================================================================
422
+ // Data shaping (filter → view models → day groups)
423
+ // ========================================================================
317
424
  get NotificationsToShow() {
318
425
  let temp = [];
319
426
  switch (this.radioSelected) {
@@ -339,6 +446,153 @@ export class UserNotificationsComponent extends BaseAngularComponent {
339
446
  }
340
447
  return temp;
341
448
  }
449
+ /**
450
+ * The filtered notifications as render-ready day groups. Memoized on a composite
451
+ * key of the inputs so the getter stays cheap across change-detection passes and
452
+ * the (time-sensitive) VM snapshots never rebuild mid-pass.
453
+ */
454
+ get Groups() {
455
+ const list = this.NotificationsToShow;
456
+ const unread = list.filter(n => n.Unread).length;
457
+ const key = `${list.length}|${unread}|${this.radioSelected}|${this.selectedTypeFilter}|${this.currentFilter}|${list[0]?.ID ?? ''}|${list[list.length - 1]?.ID ?? ''}`;
458
+ if (key !== this.groupsKey) {
459
+ this.groups = this.buildGroups(list);
460
+ this.groupsKey = key;
461
+ }
462
+ return this.groups;
463
+ }
464
+ buildGroups(list) {
465
+ const groups = [];
466
+ let current = null;
467
+ for (const n of list) {
468
+ const label = this.dayLabel(n.__mj_CreatedAt);
469
+ if (!current || current.Label !== label) {
470
+ current = { Key: `${label}-${n.ID}`, Label: label, Items: [] };
471
+ groups.push(current);
472
+ }
473
+ current.Items.push(this.vmFor(n));
474
+ }
475
+ return groups;
476
+ }
477
+ vmFor(n) {
478
+ const cached = this.vmCache.get(n.ID);
479
+ if (cached) {
480
+ cached.N = n;
481
+ cached.Clickable = this.isNotificationClickable(n);
482
+ return cached;
483
+ }
484
+ const { kind, body, preview, expandable } = this.classifyMessage(n.Message ?? '');
485
+ const vm = {
486
+ N: n,
487
+ Kind: kind,
488
+ Body: body,
489
+ Preview: preview,
490
+ Expandable: expandable,
491
+ Relative: this.relativeTime(n.__mj_CreatedAt),
492
+ Clickable: this.isNotificationClickable(n),
493
+ };
494
+ this.vmCache.set(n.ID, vm);
495
+ return vm;
496
+ }
497
+ /**
498
+ * Classifies a notification Message for rendering:
499
+ * - Full HTML documents (e.g. templated email bodies) and HTML fragments →
500
+ * parsed with DOMParser, chrome elements (style/script/link/meta/title) removed,
501
+ * and the body markup kept for a SANITIZED [innerHTML] binding (Angular's
502
+ * default sanitizer strips scripts/event handlers on bind).
503
+ * - Markdown-looking text → rendered through mj-markdown when expanded.
504
+ * - Everything else → plain text.
505
+ */
506
+ classifyMessage(message) {
507
+ const trimmed = (message ?? '').trim();
508
+ const looksHtml = /^<!doctype\s|^<html[\s>]/i.test(trimmed) || /<\/?[a-z][^>]*>/i.test(trimmed);
509
+ if (looksHtml) {
510
+ const doc = new DOMParser().parseFromString(trimmed, 'text/html');
511
+ for (const el of Array.from(doc.querySelectorAll('style, script, link, meta, title'))) {
512
+ el.remove();
513
+ }
514
+ const body = doc.body?.innerHTML?.trim() ?? '';
515
+ const text = this.collapseWhitespace(doc.body?.textContent ?? '');
516
+ return { kind: 'html', body, preview: this.excerpt(text), expandable: true };
517
+ }
518
+ const looksMarkdown = /(^|\n)#{1,6}\s|\*\*[^*]+\*\*|(^|\n)\s*[-*]\s+|\[[^\]]+\]\([^)]+\)|```/m.test(trimmed);
519
+ const text = this.collapseWhitespace(trimmed);
520
+ if (looksMarkdown) {
521
+ return { kind: 'markdown', body: trimmed, preview: this.excerpt(this.stripMarkdown(text)), expandable: true };
522
+ }
523
+ return { kind: 'text', body: '', preview: text, expandable: text.length > PREVIEW_MAX_CHARS };
524
+ }
525
+ collapseWhitespace(value) {
526
+ return value.replace(/\s+/g, ' ').trim();
527
+ }
528
+ excerpt(text) {
529
+ return text.length > PREVIEW_MAX_CHARS ? `${text.substring(0, PREVIEW_MAX_CHARS - 1)}…` : text;
530
+ }
531
+ /** Light de-noising of markdown syntax for the plain-text preview. */
532
+ stripMarkdown(text) {
533
+ return text
534
+ .replace(/```[\s\S]*?```/g, ' ')
535
+ .replace(/[#*_`>]+/g, '')
536
+ .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
537
+ .replace(/\s+/g, ' ')
538
+ .trim();
539
+ }
540
+ /** Compact "just now / 5m ago / 3h ago / 2d ago" label. NEVER call from templates (NG0100) — snapshot only. */
541
+ relativeTime(value) {
542
+ if (!value) {
543
+ return '';
544
+ }
545
+ const ms = Date.now() - new Date(value).getTime();
546
+ const minutes = Math.floor(ms / 60_000);
547
+ if (minutes < 1)
548
+ return 'just now';
549
+ if (minutes < 60)
550
+ return `${minutes}m ago`;
551
+ const hours = Math.floor(minutes / 60);
552
+ if (hours < 24)
553
+ return `${hours}h ago`;
554
+ const days = Math.floor(hours / 24);
555
+ return days < 7 ? `${days}d ago` : '';
556
+ }
557
+ dayLabel(value) {
558
+ if (!value) {
559
+ return 'Earlier';
560
+ }
561
+ const d = new Date(value);
562
+ const now = new Date();
563
+ const startOfDay = (x) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();
564
+ const diffDays = Math.round((startOfDay(now) - startOfDay(d)) / 86_400_000);
565
+ if (diffDays <= 0)
566
+ return 'Today';
567
+ if (diffDays === 1)
568
+ return 'Yesterday';
569
+ if (diffDays < 7)
570
+ return 'This Week';
571
+ return 'Earlier';
572
+ }
573
+ // ========================================================================
574
+ // Expand / collapse
575
+ // ========================================================================
576
+ IsExpanded(vm) {
577
+ return this.Expanded.has(vm.N.ID);
578
+ }
579
+ ToggleExpanded(vm, event) {
580
+ event.stopPropagation();
581
+ if (this.Expanded.has(vm.N.ID)) {
582
+ this.Expanded.delete(vm.N.ID);
583
+ }
584
+ else {
585
+ this.Expanded.add(vm.N.ID);
586
+ // Reading the full content is reading — mark it as such.
587
+ if (vm.N.Unread) {
588
+ void this.markAsRead(vm.N, true, null);
589
+ }
590
+ }
591
+ this.cdr.markForCheck();
592
+ }
593
+ // ========================================================================
594
+ // Clickability + navigation (unchanged behavior)
595
+ // ========================================================================
342
596
  isNotificationClickable(notification) {
343
597
  // Check for special types navigated via NavigationService (not a URL)
344
598
  if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {
@@ -416,41 +670,10 @@ export class UserNotificationsComponent extends BaseAngularComponent {
416
670
  }
417
671
  selectReadOption(option) {
418
672
  this.radioSelected = option;
419
- // now update the radio button group in the UI
420
- switch (option) {
421
- case 'All':
422
- this.allRadio.nativeElement.checked = true;
423
- break;
424
- case 'Unread':
425
- this.unreadRadio.nativeElement.checked = true;
426
- break;
427
- case 'Read':
428
- this.readRadio.nativeElement.checked = true;
429
- break;
430
- }
431
- }
432
- onReadRadioChanged(event) {
433
- if (event.target instanceof HTMLInputElement) {
434
- this.radioSelected = event.target.value;
435
- }
436
673
  }
437
674
  onFilterChanged(value) {
438
675
  this.currentFilter = value;
439
676
  }
440
- getItemTitleClass(notification) {
441
- if (notification.Unread) {
442
- return 'notification-title notification-title-unread';
443
- }
444
- return 'notification-title';
445
- }
446
- getItemWrapperClass(notification) {
447
- let classInfo = 'notification-wrap';
448
- if (this.isNotificationClickable(notification))
449
- classInfo += ' notification-wrap-clickable';
450
- if (notification.Unread)
451
- classInfo += ' notification-wrap-unread';
452
- return classInfo;
453
- }
454
677
  async markAsRead(notification, bRead, transGroup) {
455
678
  if (notification) {
456
679
  const notificationId = notification.ID;
@@ -487,37 +710,6 @@ export class UserNotificationsComponent extends BaseAngularComponent {
487
710
  }
488
711
  async markAllAsRead() {
489
712
  await this.markAll(true);
490
- // test harness for creating Conversations and Conversation Details record in a single transaction using variables
491
- await this.TestTransactionGroupVariables();
492
- }
493
- async TestTransactionGroupVariables() {
494
- const md = this.ProviderToUse;
495
- const transGroup = await md.CreateTransactionGroup();
496
- const conversation = await md.GetEntityObject('MJ: Conversations');
497
- conversation.UserID = md.CurrentUser.ID;
498
- conversation.Description = 'Test Conversation';
499
- conversation.TransactionGroup = transGroup;
500
- if (!await conversation.Save()) {
501
- this.sharedService.CreateSimpleNotification('Unable to create conversation', 'error', 5000);
502
- }
503
- const tvDefine = new TransactionVariable('NewConvoID', conversation, 'ID', 'Define');
504
- transGroup.AddVariable(tvDefine);
505
- const conversationDetail = await md.GetEntityObject('MJ: Conversation Details');
506
- conversationDetail.Message = 'Test Message';
507
- conversationDetail.Role = 'User';
508
- conversationDetail.ConversationID = 'x'; // fake UUID must be non-null to pass validation, this will be replaced by the variable, since we're part of a TG, not a real save, so doesn't validate it as a true fkey
509
- conversationDetail.TransactionGroup = transGroup;
510
- if (!await conversationDetail.Save()) {
511
- this.sharedService.CreateSimpleNotification('Unable to create conversation detail', 'error', 500);
512
- }
513
- const tvUse = new TransactionVariable('NewConvoID', conversationDetail, 'ConversationID', 'Use');
514
- transGroup.AddVariable(tvUse);
515
- if (await transGroup.Submit()) {
516
- this.sharedService.CreateSimpleNotification('Transaction Group with Variables worked', 'success', 5000);
517
- }
518
- else {
519
- this.sharedService.CreateSimpleNotification('Transaction Group with Variables failed', 'error', 5000);
520
- }
521
713
  }
522
714
  async markAllAsUnread() {
523
715
  await this.markAll(false);
@@ -684,7 +876,7 @@ export class UserNotificationsComponent extends BaseAngularComponent {
684
876
  }
685
877
  getTypeColor(notification) {
686
878
  const type = this.getNotificationType(notification.NotificationTypeID);
687
- return type?.Color || '#999';
879
+ return type?.Color || 'var(--mj-text-muted)';
688
880
  }
689
881
  getTypeName(notification) {
690
882
  const type = this.getNotificationType(notification.NotificationTypeID);
@@ -694,48 +886,36 @@ export class UserNotificationsComponent extends BaseAngularComponent {
694
886
  this.selectedTypeFilter = typeId;
695
887
  }
696
888
  static ɵfac = function UserNotificationsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserNotificationsComponent)(i0.ɵɵdirectiveInject(i1.SharedService), i0.ɵɵdirectiveInject(i1.NavigationService), i0.ɵɵdirectiveInject(i2.ApplicationManager)); };
697
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserNotificationsComponent, selectors: [["app-user-notifications"]], viewQuery: function UserNotificationsComponent_Query(rf, ctx) { if (rf & 1) {
698
- i0.ɵɵviewQuery(_c0, 5)(_c1, 5)(_c2, 5);
699
- } if (rf & 2) {
700
- let _t;
701
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.allRadio = _t.first);
702
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.unreadRadio = _t.first);
703
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.readRadio = _t.first);
704
- } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 14, vars: 3, consts: [["allRadio", ""], ["unreadRadio", ""], ["readRadio", ""], [1, "notifications-container"], [1, "notifications-header"], [1, "header-top"], [1, "header-title"], [1, "title-icon"], [1, "fa-solid", "fa-bell"], [1, "header-actions"], [1, "filters-section"], [1, "notifications-content"], [1, "empty-state"], [1, "notifications-list"], ["type", "button", "aria-label", "Mark all notifications as read", 1, "action-btn", "action-btn-ghost"], ["type", "button", "aria-label", "Mark all notifications as unread", 1, "action-btn", "action-btn-secondary"], ["type", "button", "aria-label", "Mark all notifications as read", 1, "action-btn", "action-btn-ghost", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-double"], [1, "btn-text"], ["type", "button", "aria-label", "Mark all notifications as unread", 1, "action-btn", "action-btn-secondary", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-envelope"], [1, "filters-slider"], [1, "slider-content"], ["role", "group", "aria-label", "Filter notifications by read status", 1, "header-stats"], ["type", "radio", "name", "UnreadStatus", "value", "All", "checked", "", "id", "filter-all", 1, "hidden-radio", 3, "change"], ["type", "button", "aria-label", "Show all notifications", 1, "stat-pill", 3, "click"], [1, "stat-label"], [1, "stat-count"], ["type", "radio", "name", "UnreadStatus", "value", "Unread", "id", "filter-unread", 1, "hidden-radio", 3, "change"], ["type", "button", "aria-label", "Show unread notifications", 1, "stat-pill", 3, "active", "has-unread"], ["type", "radio", "name", "UnreadStatus", "value", "Read", "id", "filter-read", 1, "hidden-radio", 3, "change"], ["type", "button", "aria-label", "Show read notifications", 1, "stat-pill", 3, "active"], [1, "filter-item", "type-filter-slider"], [1, "search-section"], [1, "search-container"], ["aria-hidden", "true", 1, "fa-solid", "fa-magnifying-glass", "search-icon"], ["type", "text", "placeholder", "Search notifications...", "aria-label", "Search notifications", 1, "search-input", 3, "input", "value"], [1, "filter-info"], ["type", "button", "aria-label", "Show unread notifications", 1, "stat-pill", 3, "click"], ["type", "button", "aria-label", "Show read notifications", 1, "stat-pill", 3, "click"], ["aria-label", "Filter by notification type", 1, "type-select", 3, "ngModelChange", "change", "ngModel"], [3, "value"], [1, "filter-badge"], ["aria-hidden", "true", 1, "fa-solid", "fa-filter"], [1, "empty-icon"], [1, "fa-solid", "fa-bell-slash"], [1, "fa-solid", "fa-filter-circle-xmark"], ["role", "article", 1, "notification-card", 3, "unread", "clickable"], ["role", "article", 1, "notification-card"], ["aria-hidden", "true", 1, "card-indicator"], ["aria-hidden", "true", 1, "card-icon"], [1, "card-content", 3, "click"], [1, "card-header"], [1, "card-title"], [1, "card-time"], ["aria-hidden", "true", 1, "fa-regular", "fa-clock"], [1, "card-meta"], [1, "card-type"], [1, "card-message"], [1, "card-actions"], ["type", "button", "title", "Mark as Read", 1, "card-action-btn"], ["type", "button", "title", "Mark as Unread", 1, "card-action-btn"], ["type", "button", "title", "Mark as Read", 1, "card-action-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-check"], [1, "action-text"], ["type", "button", "title", "Mark as Unread", 1, "card-action-btn", 3, "click"]], template: function UserNotificationsComponent_Template(rf, ctx) { if (rf & 1) {
705
- i0.ɵɵelementStart(0, "div", 3)(1, "div", 4)(2, "div", 5)(3, "div", 6)(4, "div", 7);
706
- i0.ɵɵelement(5, "i", 8);
889
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserNotificationsComponent, selectors: [["app-user-notifications"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 17, vars: 4, consts: [[1, "notifications-container"], [1, "notifications-header"], [1, "header-top"], [1, "header-title"], [1, "title-icon"], [1, "fa-solid", "fa-bell"], [1, "title-text"], [1, "title-subtitle"], [1, "header-actions"], [1, "filters-section"], [1, "notifications-content"], ["Variant", "success", "Icon", "fa-solid fa-bell-slash", "Title", "No Notifications", "Message", "You're all caught up! New notifications will appear here."], ["Variant", "no-results", "Icon", "fa-solid fa-filter-circle-xmark", "Title", "No Matching Notifications", "Message", "Try adjusting your filters to see more notifications."], [1, "notifications-list"], ["type", "button", "aria-label", "Mark all notifications as read", 1, "action-btn", "action-btn-ghost"], ["type", "button", "aria-label", "Mark all notifications as unread", 1, "action-btn", "action-btn-secondary"], ["type", "button", "aria-label", "Mark all notifications as read", 1, "action-btn", "action-btn-ghost", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-double"], [1, "btn-text"], ["type", "button", "aria-label", "Mark all notifications as unread", 1, "action-btn", "action-btn-secondary", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-envelope"], [1, "filters-slider"], [1, "slider-content"], ["role", "group", "aria-label", "Filter notifications by read status", 1, "header-stats"], ["type", "button", "aria-label", "Show all notifications", 1, "stat-pill", 3, "click"], [1, "stat-label"], [1, "stat-count"], ["type", "button", "aria-label", "Show unread notifications", 1, "stat-pill", 3, "active", "has-unread"], ["type", "button", "aria-label", "Show read notifications", 1, "stat-pill", 3, "active"], [1, "filter-item", "type-filter-slider"], [1, "search-section"], [1, "search-container"], ["aria-hidden", "true", 1, "fa-solid", "fa-magnifying-glass", "search-icon"], ["type", "text", "placeholder", "Search notifications...", "aria-label", "Search notifications", 1, "search-input", 3, "input", "value"], [1, "filter-info"], ["type", "button", "aria-label", "Show unread notifications", 1, "stat-pill", 3, "click"], ["type", "button", "aria-label", "Show read notifications", 1, "stat-pill", 3, "click"], ["aria-label", "Filter by notification type", 1, "type-select", 3, "ngModelChange", "change", "ngModel"], [3, "value"], [1, "filter-badge"], ["aria-hidden", "true", 1, "fa-solid", "fa-filter"], [1, "group-label"], ["role", "article", 1, "notification-card", 3, "unread", "expanded", "clickable"], ["role", "article", 1, "notification-card"], ["aria-hidden", "true", 1, "card-indicator"], ["aria-hidden", "true", 1, "card-icon"], [1, "card-content", 3, "click"], [1, "card-header"], [1, "card-title"], [1, "card-time", 3, "title"], [1, "card-meta"], [1, "card-type"], [1, "card-open-hint"], [1, "card-message"], [1, "card-rich"], ["type", "button", 1, "card-expand-btn"], [1, "card-actions"], ["type", "button", "title", "Mark as Read", 1, "card-action-btn"], ["type", "button", "title", "Mark as Unread", 1, "card-action-btn"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "card-rich", 3, "click"], [1, "card-rich-html", 3, "innerHTML"], [1, "card-rich-md", 3, "data", "enableMermaid"], [1, "card-message", "card-message-full"], ["type", "button", 1, "card-expand-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid"], ["type", "button", "title", "Mark as Read", 1, "card-action-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-check"], [1, "action-text"], ["type", "button", "title", "Mark as Unread", 1, "card-action-btn", 3, "click"]], template: function UserNotificationsComponent_Template(rf, ctx) { if (rf & 1) {
890
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3)(4, "div", 4);
891
+ i0.ɵɵelement(5, "i", 5);
892
+ i0.ɵɵelementEnd();
893
+ i0.ɵɵelementStart(6, "div", 6)(7, "h1");
894
+ i0.ɵɵtext(8, "Notifications");
707
895
  i0.ɵɵelementEnd();
708
- i0.ɵɵelementStart(6, "h1");
709
- i0.ɵɵtext(7, "Notifications");
896
+ i0.ɵɵconditionalCreate(9, UserNotificationsComponent_Conditional_9_Template, 2, 1, "span", 7)(10, UserNotificationsComponent_Conditional_10_Template, 2, 0, "span", 7);
710
897
  i0.ɵɵelementEnd()();
711
- i0.ɵɵconditionalCreate(8, UserNotificationsComponent_Conditional_8_Template, 3, 2, "div", 9);
898
+ i0.ɵɵconditionalCreate(11, UserNotificationsComponent_Conditional_11_Template, 3, 2, "div", 8);
712
899
  i0.ɵɵelementEnd();
713
- i0.ɵɵconditionalCreate(9, UserNotificationsComponent_Conditional_9_Template, 23, 9, "div", 10);
900
+ i0.ɵɵconditionalCreate(12, UserNotificationsComponent_Conditional_12_Template, 17, 9, "div", 9);
714
901
  i0.ɵɵelementEnd();
715
- i0.ɵɵelementStart(10, "div", 11);
716
- i0.ɵɵconditionalCreate(11, UserNotificationsComponent_Conditional_11_Template, 7, 0, "div", 12)(12, UserNotificationsComponent_Conditional_12_Template, 7, 0, "div", 12)(13, UserNotificationsComponent_Conditional_13_Template, 3, 0, "div", 13);
902
+ i0.ɵɵelementStart(13, "div", 10);
903
+ i0.ɵɵconditionalCreate(14, UserNotificationsComponent_Conditional_14_Template, 1, 0, "mj-empty-state", 11)(15, UserNotificationsComponent_Conditional_15_Template, 1, 0, "mj-empty-state", 12)(16, UserNotificationsComponent_Conditional_16_Template, 3, 0, "div", 13);
717
904
  i0.ɵɵelementEnd()();
718
905
  } if (rf & 2) {
719
- i0.ɵɵadvance(8);
720
- i0.ɵɵconditional(ctx.AllNotifications.length > 0 ? 8 : -1);
906
+ i0.ɵɵadvance(9);
907
+ i0.ɵɵconditional(ctx.UnreadNotifications.length > 0 ? 9 : ctx.AllNotifications.length > 0 ? 10 : -1);
908
+ i0.ɵɵadvance(2);
909
+ i0.ɵɵconditional(ctx.AllNotifications.length > 0 ? 11 : -1);
721
910
  i0.ɵɵadvance();
722
- i0.ɵɵconditional(ctx.AllNotifications.length > 0 ? 9 : -1);
911
+ i0.ɵɵconditional(ctx.AllNotifications.length > 0 ? 12 : -1);
723
912
  i0.ɵɵadvance(2);
724
- i0.ɵɵconditional(ctx.NotificationsToShow.length === 0 && ctx.AllNotifications.length === 0 ? 11 : ctx.NotificationsToShow.length === 0 ? 12 : 13);
725
- } }, dependencies: [i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.DatePipe], styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n\n\n\n\n\n.notifications-container[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n}\n\n\n\n\n\n\n.notifications-header[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 0;\n flex-shrink: 0;\n}\n\n\n\n.header-top[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 24px 24px 16px;\n gap: 16px;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.title-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n background: var(--mj-brand-primary);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.title-icon[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n.title-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n color: white;\n}\n\n.header-title[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n letter-spacing: -0.02em;\n}\n\n\n\n\n\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border-radius: 9999px; \n\n font-size: 14px;\n font-weight: 600;\n border: 2px solid var(--mj-brand-primary);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n font-family: inherit;\n}\n\n.action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n transition: transform 0.2s ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n transform: scale(1.1);\n}\n\n\n\n.action-btn-ghost[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.action-btn-ghost[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: white;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n}\n\n.action-btn-ghost[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n\n\n.action-btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.action-btn-secondary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: white;\n border-color: var(--mj-brand-primary);\n}\n\n.action-btn-secondary[_ngcontent-%COMP%]:active {\n transform: scale(0.98);\n}\n\n\n\n\n\n\n.filters-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.filters-slider[_ngcontent-%COMP%] {\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.filters-slider[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.slider-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n min-width: min-content;\n}\n\n\n\n\n\n\n.header-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n}\n\n.hidden-radio[_ngcontent-%COMP%] {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n}\n\n.stat-pill[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border-radius: 9999px; \n\n border: 2px solid var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n min-height: 44px;\n}\n\n.stat-pill[_ngcontent-%COMP%]:hover:not(.active) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n transform: translateY(-1px);\n}\n\n\n\n.stat-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: white;\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n transform: translateY(-1px);\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n}\n\n.stat-count[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 700;\n padding: 4px 10px;\n border-radius: 9999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n min-width: 28px;\n text-align: center;\n transition: all 0.2s ease;\n}\n\n.stat-pill.active[_ngcontent-%COMP%] .stat-count[_ngcontent-%COMP%] {\n background: rgba(255, 255, 255, 0.25);\n color: white;\n}\n\n.stat-count.unread-count[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 700;\n}\n\n.stat-pill.has-unread[_ngcontent-%COMP%]:not(.active) {\n border-color: var(--mj-brand-primary);\n}\n\n\n\n\n\n\n.type-filter-slider[_ngcontent-%COMP%] {\n flex-shrink: 0;\n min-width: 180px;\n}\n\n\n\n\n\n\n.search-section[_ngcontent-%COMP%] {\n padding: 0 24px 16px;\n}\n\n\n\n\n\n\n.filter-info[_ngcontent-%COMP%] {\n padding: 0 24px 16px;\n display: flex;\n justify-content: center;\n}\n\n\n\n.type-select[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 16px;\n border: 2px solid var(--mj-brand-primary);\n border-radius: 9999px; \n\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%230076B6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 16px center;\n padding-right: 42px;\n}\n\n.type-select[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background-color: var(--mj-bg-surface-card);\n}\n\n.type-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-container[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n max-width: 100%;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 16px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 14px;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 16px 10px 44px;\n border: 2px solid var(--mj-brand-primary);\n border-radius: 9999px; \n\n font-size: 14px;\n font-weight: 500;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n}\n\n.search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-card);\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.search-container[_ngcontent-%COMP%]:focus-within .search-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 9999px; \n\n font-size: 13px;\n font-weight: 600;\n border: 1px solid var(--mj-brand-primary);\n}\n\n.filter-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n\n\n\n.notifications-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch; \n\n}\n\n\n\n.notifications-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 8px;\n}\n\n.notifications-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n}\n\n.notifications-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.notifications-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 80px 32px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 96px;\n height: 96px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 40px;\n color: var(--mj-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 15px;\n color: var(--mj-text-secondary);\n margin: 0;\n max-width: 320px;\n line-height: 1.5;\n}\n\n\n\n\n\n\n.notifications-list[_ngcontent-%COMP%] {\n background: transparent;\n}\n\n\n\n\n\n\n.notification-card[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 4px 56px 1fr auto;\n gap: 14px;\n align-items: start;\n padding: 16px 20px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n position: relative;\n}\n\n.notification-card[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.notification-card[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.notification-card.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.notification-card.clickable[_ngcontent-%COMP%]:active {\n background: var(--mj-bg-surface-sunken);\n transform: scale(0.995);\n}\n\n\n\n.notification-card.unread[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.notification-card.unread[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-card));\n}\n\n\n\n.card-indicator[_ngcontent-%COMP%] {\n width: 4px;\n height: 100%;\n min-height: 64px;\n border-radius: 2px;\n background: transparent;\n transition: all 0.2s ease;\n align-self: stretch;\n}\n\n.notification-card.unread[_ngcontent-%COMP%] .card-indicator[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 8px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n\n\n.card-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: transform 0.2s ease;\n}\n\n.notification-card[_ngcontent-%COMP%]:hover .card-icon[_ngcontent-%COMP%] {\n transform: scale(1.05);\n}\n\n.card-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n\n\n.card-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 6px;\n}\n\n.card-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-primary);\n margin: 0;\n line-height: 1.4;\n word-wrap: break-word;\n}\n\n.card-title-unread[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.notification-card.clickable[_ngcontent-%COMP%] .card-title[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.notification-card.clickable[_ngcontent-%COMP%]:hover .card-title[_ngcontent-%COMP%] {\n text-decoration: underline;\n}\n\n.card-time[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.card-time[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.card-meta[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n}\n\n.card-type[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 12px;\n border-radius: 9999px; \n\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n\n\n.card-message[_ngcontent-%COMP%] {\n font-size: 15px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n margin: 0;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n\n\n.card-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding-top: 6px;\n}\n\n.card-action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border-radius: 9999px; \n\n font-size: 13px;\n font-weight: 600;\n border: 2px solid var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n font-family: inherit;\n}\n\n.card-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: white;\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.card-action-btn[_ngcontent-%COMP%]:active {\n transform: translateY(0) scale(0.98);\n}\n\n.card-action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_slideInUp {\n from {\n opacity: 0;\n transform: translateY(12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.notification-card[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_slideInUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n\n\n\nbutton[_ngcontent-%COMP%]:focus-visible, \ninput[_ngcontent-%COMP%]:focus-visible, \nselect[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n\n\n\n\n\n\n\n@media (max-width: 768px) {\n .notifications-container[_ngcontent-%COMP%] {\n border-radius: 0;\n box-shadow: none;\n }\n\n .header-top[_ngcontent-%COMP%] {\n padding: 20px 20px 14px;\n }\n\n .title-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n }\n\n .title-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .header-title[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n }\n\n \n\n .slider-content[_ngcontent-%COMP%] {\n padding: 14px 20px;\n gap: 10px;\n }\n\n .stat-pill[_ngcontent-%COMP%] {\n padding: 8px 16px;\n flex-shrink: 0;\n }\n\n .type-filter-slider[_ngcontent-%COMP%] {\n min-width: 160px;\n }\n\n .search-section[_ngcontent-%COMP%] {\n padding: 0 20px 14px;\n }\n\n .filter-info[_ngcontent-%COMP%] {\n padding: 0 20px 14px;\n }\n\n .notification-card[_ngcontent-%COMP%] {\n grid-template-columns: 4px 52px 1fr;\n gap: 12px;\n padding: 14px 16px;\n }\n\n .card-actions[_ngcontent-%COMP%] {\n grid-column: 2 / -1;\n padding-top: 10px;\n }\n\n .card-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n }\n\n .card-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 22px;\n }\n}\n\n\n\n@media (max-width: 480px) {\n .header-top[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n gap: 12px;\n padding: 16px 16px 12px;\n }\n\n .header-title[_ngcontent-%COMP%] {\n justify-content: flex-start;\n }\n\n .title-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n }\n\n .title-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .header-title[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 1.375rem;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n gap: 8px;\n }\n\n .action-btn[_ngcontent-%COMP%] {\n flex: 1;\n justify-content: center;\n padding: 10px 16px;\n font-size: 13px;\n }\n\n .btn-text[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n .slider-content[_ngcontent-%COMP%] {\n padding: 12px 16px;\n gap: 8px;\n }\n\n .header-stats[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .stat-pill[_ngcontent-%COMP%] {\n padding: 8px 14px;\n min-height: 40px;\n flex-shrink: 0;\n }\n\n .stat-label[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .stat-count[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 3px 8px;\n min-width: 24px;\n }\n\n .type-filter-slider[_ngcontent-%COMP%] {\n min-width: 140px;\n }\n\n .type-select[_ngcontent-%COMP%], \n .search-input[_ngcontent-%COMP%] {\n font-size: 16px; \n\n }\n\n .search-section[_ngcontent-%COMP%] {\n padding: 0 16px 12px;\n }\n\n .filter-info[_ngcontent-%COMP%] {\n padding: 0 16px 12px;\n }\n\n .notification-card[_ngcontent-%COMP%] {\n grid-template-columns: 3px 48px 1fr;\n gap: 10px;\n padding: 12px 12px;\n }\n\n .card-indicator[_ngcontent-%COMP%] {\n width: 3px;\n min-height: 56px;\n }\n\n .card-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n }\n\n .card-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .card-title[_ngcontent-%COMP%] {\n font-size: 15px;\n }\n\n .card-time[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .card-message[_ngcontent-%COMP%] {\n font-size: 14px;\n -webkit-line-clamp: 2;\n }\n\n .card-type[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 10px;\n }\n\n .card-actions[_ngcontent-%COMP%] {\n padding-top: 8px;\n gap: 6px;\n }\n\n .action-text[_ngcontent-%COMP%] {\n display: none;\n }\n\n .card-action-btn[_ngcontent-%COMP%] {\n padding: 8px 12px;\n min-width: 40px;\n justify-content: center;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 60px 20px;\n }\n\n .empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n }\n\n .empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n }\n\n .empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n}\n\n\n\n@media (min-width: 390px) and (max-width: 480px) {\n .btn-text[_ngcontent-%COMP%] {\n display: inline;\n }\n\n .action-btn[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n}\n\n\n\n@media (prefers-color-scheme: dark) {\n \n\n}"] });
913
+ i0.ɵɵconditional(ctx.NotificationsToShow.length === 0 && ctx.AllNotifications.length === 0 ? 14 : ctx.NotificationsToShow.length === 0 ? 15 : 16);
914
+ } }, dependencies: [i3.MarkdownComponent, i4.NgSelectOption, i4.ɵNgSelectMultipleOption, i4.SelectControlValueAccessor, i4.NgControlStatus, i4.NgModel, i5.MJEmptyStateComponent, i6.DatePipe], styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.notifications-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-page);\n}\n\n\n\n\n.notifications-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 20px 24px 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.header-top[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 14px;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.title-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: var(--mj-radius-lg, 12px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.title-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.title-text[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.title-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s, border-color 0.15s;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.action-btn-ghost[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.action-btn-ghost[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n\n.filters-section[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n}\n\n.filters-slider[_ngcontent-%COMP%] {\n min-width: 0;\n}\n\n.slider-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.header-stats[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: 4px;\n padding: 3px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n}\n\n.stat-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border: none;\n border-radius: var(--mj-radius-full, 999px);\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.stat-pill[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.stat-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.stat-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-text-muted) 14%, transparent);\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n}\n\n.stat-count.unread-count[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.type-select[_ngcontent-%COMP%] {\n padding: 7px 10px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.search-section[_ngcontent-%COMP%] {\n flex: 1 1 220px;\n min-width: 180px;\n}\n\n.search-container[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px 8px 32px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n\n.filter-info[_ngcontent-%COMP%] {\n flex-basis: 100%;\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n font-size: 11px;\n font-weight: 600;\n}\n\n\n\n\n.notifications-content[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n padding: 16px 24px 32px 24px;\n}\n\n.notifications-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n max-width: 960px;\n margin: 0 auto;\n}\n\n.group-label[_ngcontent-%COMP%] {\n position: sticky;\n top: -16px;\n z-index: 1;\n padding: 10px 2px 4px 2px;\n background: var(--mj-bg-page);\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n}\n\n.group-label[_ngcontent-%COMP%]:not(:first-child) {\n margin-top: 8px;\n}\n\n\n\n\n.notification-card[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg, 12px);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;\n overflow: hidden;\n}\n\n.notification-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.notification-card.unread[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n}\n\n.card-indicator[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n border-radius: 0 2px 2px 0;\n}\n\n.notification-card.unread[_ngcontent-%COMP%] .card-indicator[_ngcontent-%COMP%] {\n display: block;\n}\n\n.card-icon[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md, 10px);\n background: var(--mj-bg-surface-sunken);\n font-size: 14px;\n}\n\n.card-content[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.notification-card.clickable[_ngcontent-%COMP%] .card-content[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n}\n\n.card-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow-wrap: anywhere;\n}\n\n.card-title-unread[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.card-time[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.card-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 3px 0 6px 0;\n}\n\n.card-type[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n.card-open-hint[_ngcontent-%COMP%] {\n display: none;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n}\n\n.notification-card.clickable[_ngcontent-%COMP%]:hover .card-open-hint[_ngcontent-%COMP%] {\n display: inline-flex;\n}\n\n.card-message[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n\n.card-message-full[_ngcontent-%COMP%] {\n display: block;\n -webkit-line-clamp: unset;\n white-space: pre-wrap;\n}\n\n\n\n\n.card-rich[_ngcontent-%COMP%] {\n margin-top: 4px;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface-card);\n cursor: default;\n}\n\n\n\n.card-rich-html[_ngcontent-%COMP%] {\n font-size: 13px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n overflow-x: auto;\n}\n\n.card-rich-html[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n max-width: 100%;\n height: auto;\n}\n\n.card-rich-html[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n max-width: 100%;\n border-collapse: collapse;\n}\n\n.card-rich-html[_ngcontent-%COMP%] td[_ngcontent-%COMP%], \n.card-rich-html[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 4px 8px;\n border: 1px solid var(--mj-border-subtle);\n}\n\n.card-rich-html[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n}\n\n.card-rich-html[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], \n.card-rich-html[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], \n.card-rich-html[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0.4em 0 0.3em 0;\n font-size: 1.05em;\n}\n\n.card-rich-md[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n}\n\n.card-expand-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n padding: 4px 10px;\n border: none;\n border-radius: var(--mj-radius-full, 999px);\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 700;\n cursor: pointer;\n}\n\n.card-expand-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n\n\n\n.card-actions[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n align-items: flex-start;\n}\n\n.card-action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: 1px solid transparent;\n border-radius: var(--mj-radius-md, 8px);\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.card-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n\n\n\n@media (max-width: 720px) {\n .notifications-header[_ngcontent-%COMP%] {\n padding: 14px 14px 10px 14px;\n }\n\n .notifications-content[_ngcontent-%COMP%] {\n padding: 12px 12px 24px 12px;\n }\n\n .btn-text[_ngcontent-%COMP%], \n .action-text[_ngcontent-%COMP%] {\n display: none;\n }\n\n .card-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 2px;\n }\n\n .card-time[_ngcontent-%COMP%] {\n order: -1;\n }\n}"] });
726
915
  }
727
916
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(UserNotificationsComponent, [{
728
917
  type: Component,
729
- args: [{ standalone: false, selector: 'app-user-notifications', template: "<div class=\"notifications-container\">\n <!-- Header Section -->\n <div class=\"notifications-header\">\n <div class=\"header-top\">\n <div class=\"header-title\">\n <div class=\"title-icon\">\n <i class=\"fa-solid fa-bell\"></i>\n </div>\n <h1>Notifications</h1>\n </div>\n\n @if (AllNotifications.length > 0) {\n <div class=\"header-actions\">\n @if (UnreadNotifications.length > 0) {\n <button class=\"action-btn action-btn-ghost\"\n type=\"button\"\n (click)=\"markAllAsRead()\"\n aria-label=\"Mark all notifications as read\">\n <i class=\"fa-solid fa-check-double\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Read</span>\n </button>\n }\n @if (ReadNotifications.length > 0) {\n <button class=\"action-btn action-btn-secondary\"\n type=\"button\"\n (click)=\"markAllAsUnread()\"\n aria-label=\"Mark all notifications as unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Unread</span>\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Filters Section -->\n @if (AllNotifications.length > 0) {\n <div class=\"filters-section\">\n <!-- Horizontal Slider for Filters (Mobile) -->\n <div class=\"filters-slider\">\n <div class=\"slider-content\">\n <!-- Stats Pills (Filter Tabs) -->\n <div class=\"header-stats\" role=\"group\" aria-label=\"Filter notifications by read status\">\n <input #allRadio type=\"radio\" name=\"UnreadStatus\" value=\"All\"\n (change)=\"onReadRadioChanged($event)\" checked class=\"hidden-radio\"\n id=\"filter-all\" />\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'All'\"\n (click)=\"selectReadOption('All')\"\n [attr.aria-pressed]=\"radioSelected === 'All'\"\n aria-label=\"Show all notifications\">\n <span class=\"stat-label\">All</span>\n <span class=\"stat-count\">{{AllNotifications.length}}</span>\n </button>\n\n <input #unreadRadio type=\"radio\" name=\"UnreadStatus\" value=\"Unread\"\n (change)=\"onReadRadioChanged($event)\" class=\"hidden-radio\"\n id=\"filter-unread\" />\n @if (UnreadNotifications.length > 0 || ReadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Unread'\"\n [class.has-unread]=\"UnreadNotifications.length > 0\"\n (click)=\"selectReadOption('Unread')\"\n [attr.aria-pressed]=\"radioSelected === 'Unread'\"\n aria-label=\"Show unread notifications\">\n <span class=\"stat-label\">Unread</span>\n <span class=\"stat-count\" [class.unread-count]=\"UnreadNotifications.length > 0\">\n {{UnreadNotifications.length}}\n </span>\n </button>\n }\n\n <input #readRadio type=\"radio\" name=\"UnreadStatus\" value=\"Read\"\n (change)=\"onReadRadioChanged($event)\" class=\"hidden-radio\"\n id=\"filter-read\" />\n @if (ReadNotifications.length > 0 || UnreadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Read'\"\n (click)=\"selectReadOption('Read')\"\n [attr.aria-pressed]=\"radioSelected === 'Read'\"\n aria-label=\"Show read notifications\">\n <span class=\"stat-label\">Read</span>\n <span class=\"stat-count\">{{ReadNotifications.length}}</span>\n </button>\n }\n </div>\n\n <!-- Native Type Filter Dropdown (in slider on mobile) -->\n @if (notificationTypes.length > 0) {\n <div class=\"filter-item type-filter-slider\">\n <select class=\"type-select\"\n [(ngModel)]=\"selectedTypeFilter\"\n (change)=\"onTypeFilterChange(selectedTypeFilter)\"\n aria-label=\"Filter by notification type\">\n <option [value]=\"null\">All Types</option>\n @for (type of notificationTypes; track type.ID) {\n <option [value]=\"type.ID\">{{type.Name}}</option>\n }\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Search Filter (separate, full-width on mobile) -->\n <div class=\"search-section\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\" aria-hidden=\"true\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search notifications...\"\n [value]=\"currentFilter\"\n (input)=\"onFilterChanged($any($event.target).value)\"\n aria-label=\"Search notifications\" />\n </div>\n </div>\n\n <!-- Filter Info Badge -->\n @if (NotificationsToShow.length !== AllNotifications.length) {\n <div class=\"filter-info\">\n <span class=\"filter-badge\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n Showing {{NotificationsToShow.length}} of {{AllNotifications.length}}\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Notifications Content -->\n <div class=\"notifications-content\">\n @if (NotificationsToShow.length === 0 && AllNotifications.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-bell-slash\"></i>\n </div>\n <h3>No Notifications</h3>\n <p>You're all caught up! New notifications will appear here.</p>\n </div>\n } @else if (NotificationsToShow.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i>\n </div>\n <h3>No Matching Notifications</h3>\n <p>Try adjusting your filters to see more notifications.</p>\n </div>\n } @else {\n <!-- Notifications List -->\n <div class=\"notifications-list\">\n @for (notification of NotificationsToShow; track notification.ID) {\n <article class=\"notification-card\"\n [class.unread]=\"notification.Unread\"\n [class.clickable]=\"isNotificationClickable(notification)\"\n role=\"article\"\n [attr.aria-label]=\"notification.Title\">\n\n <!-- Unread Indicator Bar -->\n <div class=\"card-indicator\" aria-hidden=\"true\"></div>\n\n <!-- Type Icon -->\n <div class=\"card-icon\"\n [style.background-color]=\"getTypeColor(notification) + '15'\"\n aria-hidden=\"true\">\n <i [class]=\"'fa-solid ' + getTypeIcon(notification)\"\n [style.color]=\"getTypeColor(notification)\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"card-content\" (click)=\"notificationClicked(notification)\">\n <div class=\"card-header\">\n <h3 class=\"card-title\" [class.card-title-unread]=\"notification.Unread\">\n {{notification.Title}}\n </h3>\n <span class=\"card-time\">\n <i class=\"fa-regular fa-clock\" aria-hidden=\"true\"></i>\n <time [attr.datetime]=\"notification.__mj_CreatedAt\">\n {{notification.__mj_CreatedAt | date:'MMM d, h:mm a'}}\n </time>\n </span>\n </div>\n\n <div class=\"card-meta\">\n <span class=\"card-type\"\n [style.background-color]=\"getTypeColor(notification) + '15'\"\n [style.color]=\"getTypeColor(notification)\">\n {{getTypeName(notification)}}\n </span>\n </div>\n\n <p class=\"card-message\">{{notification.Message}}</p>\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\">\n @if (notification.Unread) {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(notification, true, null)\"\n [attr.aria-label]=\"'Mark ' + notification.Title + ' as read'\"\n title=\"Mark as Read\">\n <i class=\"fa-solid fa-check\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Read</span>\n </button>\n } @else {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(notification, false, null)\"\n [attr.aria-label]=\"'Mark ' + notification.Title + ' as unread'\"\n title=\"Mark as Unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Unread</span>\n </button>\n }\n </div>\n </article>\n }\n </div>\n }\n </div>\n</div>\n", styles: ["/* ===================================\n USER NOTIFICATIONS - MD3 DESIGN\n iPhone-inspired UX with Circular Buttons\n =================================== */\n\n:host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* ===================================\n CONTAINER\n =================================== */\n\n.notifications-container {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n}\n\n/* ===================================\n HEADER SECTION\n =================================== */\n\n.notifications-header {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 0;\n flex-shrink: 0;\n}\n\n/* Header Top Row */\n.header-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 24px 24px 16px;\n gap: 16px;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.title-icon {\n width: 48px;\n height: 48px;\n background: var(--mj-brand-primary);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.title-icon:hover {\n transform: scale(1.05);\n}\n\n.title-icon i {\n font-size: 22px;\n color: white;\n}\n\n.header-title h1 {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n letter-spacing: -0.02em;\n}\n\n/* ===================================\n HEADER ACTIONS - Circular Buttons\n =================================== */\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.action-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border-radius: 9999px; /* Circular design */\n font-size: 14px;\n font-weight: 600;\n border: 2px solid var(--mj-brand-primary);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n font-family: inherit;\n}\n\n.action-btn i {\n font-size: 16px;\n transition: transform 0.2s ease;\n}\n\n.action-btn:hover i {\n transform: scale(1.1);\n}\n\n/* Ghost Button - White Background (Mark All Read) */\n.action-btn-ghost {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.action-btn-ghost:hover {\n background: var(--mj-brand-primary);\n color: white;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-md);\n}\n\n.action-btn-ghost:active {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n/* Secondary Button */\n.action-btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.action-btn-secondary:hover {\n background: var(--mj-brand-primary);\n color: white;\n border-color: var(--mj-brand-primary);\n}\n\n.action-btn-secondary:active {\n transform: scale(0.98);\n}\n\n/* ===================================\n FILTERS SECTION\n =================================== */\n\n.filters-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n}\n\n.filters-slider {\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.filters-slider::-webkit-scrollbar {\n display: none;\n}\n\n.slider-content {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n min-width: min-content;\n}\n\n/* ===================================\n STATS PILLS (Filter Tabs) - Circular with mj-blue Active\n =================================== */\n\n.header-stats {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-shrink: 0;\n}\n\n.hidden-radio {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n}\n\n.stat-pill {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border-radius: 9999px; /* Circular design */\n border: 2px solid var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n min-height: 44px;\n}\n\n.stat-pill:hover:not(.active) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n transform: translateY(-1px);\n}\n\n/* Active State - MJ Blue */\n.stat-pill.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: white;\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n transform: translateY(-1px);\n}\n\n.stat-label {\n font-size: 14px;\n font-weight: 600;\n}\n\n.stat-count {\n font-size: 13px;\n font-weight: 700;\n padding: 4px 10px;\n border-radius: 9999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n min-width: 28px;\n text-align: center;\n transition: all 0.2s ease;\n}\n\n.stat-pill.active .stat-count {\n background: rgba(255, 255, 255, 0.25);\n color: white;\n}\n\n.stat-count.unread-count {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 700;\n}\n\n.stat-pill.has-unread:not(.active) {\n border-color: var(--mj-brand-primary);\n}\n\n/* ===================================\n TYPE FILTER IN SLIDER\n =================================== */\n\n.type-filter-slider {\n flex-shrink: 0;\n min-width: 180px;\n}\n\n/* ===================================\n SEARCH SECTION\n =================================== */\n\n.search-section {\n padding: 0 24px 16px;\n}\n\n/* ===================================\n FILTER INFO\n =================================== */\n\n.filter-info {\n padding: 0 24px 16px;\n display: flex;\n justify-content: center;\n}\n\n/* Native Select Dropdown Styling */\n.type-select {\n width: 100%;\n padding: 10px 16px;\n border: 2px solid var(--mj-brand-primary);\n border-radius: 9999px; /* Circular design */\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%230076B6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 16px center;\n padding-right: 42px;\n}\n\n.type-select:hover {\n border-color: var(--mj-brand-primary);\n background-color: var(--mj-bg-surface-card);\n}\n\n.type-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-container {\n position: relative;\n width: 100%;\n max-width: 100%;\n}\n\n.search-icon {\n position: absolute;\n left: 16px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 14px;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n.search-input {\n width: 100%;\n padding: 10px 16px 10px 44px;\n border: 2px solid var(--mj-brand-primary);\n border-radius: 9999px; /* Circular design */\n font-size: 14px;\n font-weight: 500;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n}\n\n.search-input::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.search-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-card);\n}\n\n.search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.search-container:focus-within .search-icon {\n color: var(--mj-brand-primary);\n}\n\n.filter-badge {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 9999px; /* Circular design */\n font-size: 13px;\n font-weight: 600;\n border: 1px solid var(--mj-brand-primary);\n}\n\n.filter-badge i {\n font-size: 12px;\n}\n\n/* ===================================\n NOTIFICATIONS CONTENT\n =================================== */\n\n.notifications-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch; /* iPhone smooth scrolling */\n}\n\n/* Custom Scrollbar */\n.notifications-content::-webkit-scrollbar {\n width: 8px;\n}\n\n.notifications-content::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n}\n\n.notifications-content::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.notifications-content::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n/* ===================================\n EMPTY STATE\n =================================== */\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 80px 32px;\n text-align: center;\n}\n\n.empty-icon {\n width: 96px;\n height: 96px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon i {\n font-size: 40px;\n color: var(--mj-text-muted);\n}\n\n.empty-state h3 {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 8px;\n}\n\n.empty-state p {\n font-size: 15px;\n color: var(--mj-text-secondary);\n margin: 0;\n max-width: 320px;\n line-height: 1.5;\n}\n\n/* ===================================\n NOTIFICATIONS LIST\n =================================== */\n\n.notifications-list {\n background: transparent;\n}\n\n/* ===================================\n NOTIFICATION CARD - iPhone UX Style\n =================================== */\n\n.notification-card {\n display: grid;\n grid-template-columns: 4px 56px 1fr auto;\n gap: 14px;\n align-items: start;\n padding: 16px 20px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n position: relative;\n}\n\n.notification-card:last-child {\n border-bottom: none;\n}\n\n.notification-card:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.notification-card.clickable {\n cursor: pointer;\n}\n\n.notification-card.clickable:active {\n background: var(--mj-bg-surface-sunken);\n transform: scale(0.995);\n}\n\n/* Unread State with Blue Highlight */\n.notification-card.unread {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.notification-card.unread:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-card));\n}\n\n/* Card Indicator - Blue Bar for Unread */\n.card-indicator {\n width: 4px;\n height: 100%;\n min-height: 64px;\n border-radius: 2px;\n background: transparent;\n transition: all 0.2s ease;\n align-self: stretch;\n}\n\n.notification-card.unread .card-indicator {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 8px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n/* Card Icon - Larger and More Prominent */\n.card-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: transform 0.2s ease;\n}\n\n.notification-card:hover .card-icon {\n transform: scale(1.05);\n}\n\n.card-icon i {\n font-size: 24px;\n}\n\n/* Card Content */\n.card-content {\n flex: 1;\n min-width: 0;\n}\n\n.card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 6px;\n}\n\n.card-title {\n font-size: 16px;\n font-weight: 500;\n color: var(--mj-text-primary);\n margin: 0;\n line-height: 1.4;\n word-wrap: break-word;\n}\n\n.card-title-unread {\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.notification-card.clickable .card-title {\n color: var(--mj-brand-primary);\n}\n\n.notification-card.clickable:hover .card-title {\n text-decoration: underline;\n}\n\n.card-time {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.card-time i {\n font-size: 12px;\n}\n\n/* Card Meta */\n.card-meta {\n margin-bottom: 8px;\n}\n\n.card-type {\n display: inline-flex;\n align-items: center;\n padding: 4px 12px;\n border-radius: 9999px; /* Circular design */\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n/* Card Message */\n.card-message {\n font-size: 15px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n margin: 0;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Card Actions - Circular Buttons */\n.card-actions {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding-top: 6px;\n}\n\n.card-action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border-radius: 9999px; /* Circular design */\n font-size: 13px;\n font-weight: 600;\n border: 2px solid var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n font-family: inherit;\n}\n\n.card-action-btn:hover {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: white;\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.card-action-btn:active {\n transform: translateY(0) scale(0.98);\n}\n\n.card-action-btn i {\n font-size: 13px;\n}\n\n/* ===================================\n ANIMATIONS\n =================================== */\n\n@keyframes slideInUp {\n from {\n opacity: 0;\n transform: translateY(12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.notification-card {\n animation: slideInUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* ===================================\n ACCESSIBILITY\n =================================== */\n\nbutton:focus-visible,\ninput:focus-visible,\nselect:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Reduced Motion */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n/* ===================================\n RESPONSIVE DESIGN - iPhone UX\n =================================== */\n\n/* iPad and smaller */\n@media (max-width: 768px) {\n .notifications-container {\n border-radius: 0;\n box-shadow: none;\n }\n\n .header-top {\n padding: 20px 20px 14px;\n }\n\n .title-icon {\n width: 44px;\n height: 44px;\n }\n\n .title-icon i {\n font-size: 20px;\n }\n\n .header-title h1 {\n font-size: 1.5rem;\n }\n\n /* Horizontal Slider on Mobile */\n .slider-content {\n padding: 14px 20px;\n gap: 10px;\n }\n\n .stat-pill {\n padding: 8px 16px;\n flex-shrink: 0;\n }\n\n .type-filter-slider {\n min-width: 160px;\n }\n\n .search-section {\n padding: 0 20px 14px;\n }\n\n .filter-info {\n padding: 0 20px 14px;\n }\n\n .notification-card {\n grid-template-columns: 4px 52px 1fr;\n gap: 12px;\n padding: 14px 16px;\n }\n\n .card-actions {\n grid-column: 2 / -1;\n padding-top: 10px;\n }\n\n .card-icon {\n width: 52px;\n height: 52px;\n }\n\n .card-icon i {\n font-size: 22px;\n }\n}\n\n/* iPhone SE and smaller */\n@media (max-width: 480px) {\n .header-top {\n flex-direction: column;\n align-items: stretch;\n gap: 12px;\n padding: 16px 16px 12px;\n }\n\n .header-title {\n justify-content: flex-start;\n }\n\n .title-icon {\n width: 40px;\n height: 40px;\n }\n\n .title-icon i {\n font-size: 18px;\n }\n\n .header-title h1 {\n font-size: 1.375rem;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n gap: 8px;\n }\n\n .action-btn {\n flex: 1;\n justify-content: center;\n padding: 10px 16px;\n font-size: 13px;\n }\n\n .btn-text {\n display: none;\n }\n\n /* Horizontal Slider - iPhone */\n .slider-content {\n padding: 12px 16px;\n gap: 8px;\n }\n\n .header-stats {\n gap: 8px;\n }\n\n .stat-pill {\n padding: 8px 14px;\n min-height: 40px;\n flex-shrink: 0;\n }\n\n .stat-label {\n font-size: 13px;\n }\n\n .stat-count {\n font-size: 12px;\n padding: 3px 8px;\n min-width: 24px;\n }\n\n .type-filter-slider {\n min-width: 140px;\n }\n\n .type-select,\n .search-input {\n font-size: 16px; /* Prevent iOS zoom on focus */\n }\n\n .search-section {\n padding: 0 16px 12px;\n }\n\n .filter-info {\n padding: 0 16px 12px;\n }\n\n .notification-card {\n grid-template-columns: 3px 48px 1fr;\n gap: 10px;\n padding: 12px 12px;\n }\n\n .card-indicator {\n width: 3px;\n min-height: 56px;\n }\n\n .card-icon {\n width: 48px;\n height: 48px;\n border-radius: 12px;\n }\n\n .card-icon i {\n font-size: 20px;\n }\n\n .card-title {\n font-size: 15px;\n }\n\n .card-time {\n font-size: 12px;\n }\n\n .card-message {\n font-size: 14px;\n -webkit-line-clamp: 2;\n }\n\n .card-type {\n font-size: 11px;\n padding: 3px 10px;\n }\n\n .card-actions {\n padding-top: 8px;\n gap: 6px;\n }\n\n .action-text {\n display: none;\n }\n\n .card-action-btn {\n padding: 8px 12px;\n min-width: 40px;\n justify-content: center;\n }\n\n .empty-state {\n padding: 60px 20px;\n }\n\n .empty-icon {\n width: 80px;\n height: 80px;\n }\n\n .empty-icon i {\n font-size: 32px;\n }\n\n .empty-state h3 {\n font-size: 18px;\n }\n\n .empty-state p {\n font-size: 14px;\n }\n}\n\n/* iPhone 12/13/14 Pro Max and similar */\n@media (min-width: 390px) and (max-width: 480px) {\n .btn-text {\n display: inline;\n }\n\n .action-btn {\n font-size: 14px;\n }\n}\n\n/* Dark mode support (if needed in future) */\n@media (prefers-color-scheme: dark) {\n /* Dark mode styles would go here */\n}\n"] }]
730
- }], () => [{ type: i1.SharedService }, { type: i1.NavigationService }, { type: i2.ApplicationManager }], { allRadio: [{
731
- type: ViewChild,
732
- args: ['allRadio']
733
- }], unreadRadio: [{
734
- type: ViewChild,
735
- args: ['unreadRadio']
736
- }], readRadio: [{
737
- type: ViewChild,
738
- args: ['readRadio']
739
- }] }); })();
740
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserNotificationsComponent, { className: "UserNotificationsComponent", filePath: "src/lib/user-notifications/user-notifications.component.ts", lineNumber: 56 }); })();
918
+ args: [{ standalone: false, selector: 'app-user-notifications', template: "<div class=\"notifications-container\">\n <!-- Header Section -->\n <div class=\"notifications-header\">\n <div class=\"header-top\">\n <div class=\"header-title\">\n <div class=\"title-icon\">\n <i class=\"fa-solid fa-bell\"></i>\n </div>\n <div class=\"title-text\">\n <h1>Notifications</h1>\n @if (UnreadNotifications.length > 0) {\n <span class=\"title-subtitle\">{{UnreadNotifications.length}} unread</span>\n } @else if (AllNotifications.length > 0) {\n <span class=\"title-subtitle\">All caught up</span>\n }\n </div>\n </div>\n\n @if (AllNotifications.length > 0) {\n <div class=\"header-actions\">\n @if (UnreadNotifications.length > 0) {\n <button class=\"action-btn action-btn-ghost\"\n type=\"button\"\n (click)=\"markAllAsRead()\"\n aria-label=\"Mark all notifications as read\">\n <i class=\"fa-solid fa-check-double\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Read</span>\n </button>\n }\n @if (ReadNotifications.length > 0) {\n <button class=\"action-btn action-btn-secondary\"\n type=\"button\"\n (click)=\"markAllAsUnread()\"\n aria-label=\"Mark all notifications as unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Unread</span>\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Filters Section -->\n @if (AllNotifications.length > 0) {\n <div class=\"filters-section\">\n <div class=\"filters-slider\">\n <div class=\"slider-content\">\n <!-- Read-status pills -->\n <div class=\"header-stats\" role=\"group\" aria-label=\"Filter notifications by read status\">\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'All'\"\n (click)=\"selectReadOption('All')\"\n [attr.aria-pressed]=\"radioSelected === 'All'\"\n aria-label=\"Show all notifications\">\n <span class=\"stat-label\">All</span>\n <span class=\"stat-count\">{{AllNotifications.length}}</span>\n </button>\n\n @if (UnreadNotifications.length > 0 || ReadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Unread'\"\n [class.has-unread]=\"UnreadNotifications.length > 0\"\n (click)=\"selectReadOption('Unread')\"\n [attr.aria-pressed]=\"radioSelected === 'Unread'\"\n aria-label=\"Show unread notifications\">\n <span class=\"stat-label\">Unread</span>\n <span class=\"stat-count\" [class.unread-count]=\"UnreadNotifications.length > 0\">\n {{UnreadNotifications.length}}\n </span>\n </button>\n }\n\n @if (ReadNotifications.length > 0 || UnreadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Read'\"\n (click)=\"selectReadOption('Read')\"\n [attr.aria-pressed]=\"radioSelected === 'Read'\"\n aria-label=\"Show read notifications\">\n <span class=\"stat-label\">Read</span>\n <span class=\"stat-count\">{{ReadNotifications.length}}</span>\n </button>\n }\n </div>\n\n <!-- Type filter -->\n @if (notificationTypes.length > 0) {\n <div class=\"filter-item type-filter-slider\">\n <select class=\"type-select\"\n [(ngModel)]=\"selectedTypeFilter\"\n (change)=\"onTypeFilterChange(selectedTypeFilter)\"\n aria-label=\"Filter by notification type\">\n <option [value]=\"null\">All Types</option>\n @for (type of notificationTypes; track type.ID) {\n <option [value]=\"type.ID\">{{type.Name}}</option>\n }\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"search-section\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\" aria-hidden=\"true\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search notifications...\"\n [value]=\"currentFilter\"\n (input)=\"onFilterChanged($any($event.target).value)\"\n aria-label=\"Search notifications\" />\n </div>\n </div>\n\n @if (NotificationsToShow.length !== AllNotifications.length) {\n <div class=\"filter-info\">\n <span class=\"filter-badge\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n Showing {{NotificationsToShow.length}} of {{AllNotifications.length}}\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Notifications Content -->\n <div class=\"notifications-content\">\n @if (NotificationsToShow.length === 0 && AllNotifications.length === 0) {\n <mj-empty-state\n Variant=\"success\"\n Icon=\"fa-solid fa-bell-slash\"\n Title=\"No Notifications\"\n Message=\"You're all caught up! New notifications will appear here.\" />\n } @else if (NotificationsToShow.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-filter-circle-xmark\"\n Title=\"No Matching Notifications\"\n Message=\"Try adjusting your filters to see more notifications.\" />\n } @else {\n <!-- Day-grouped notification list -->\n <div class=\"notifications-list\">\n @for (group of Groups; track group.Key) {\n <div class=\"group-label\">{{group.Label}}</div>\n\n @for (vm of group.Items; track vm.N.ID) {\n <article class=\"notification-card\"\n [class.unread]=\"vm.N.Unread\"\n [class.expanded]=\"IsExpanded(vm)\"\n [class.clickable]=\"vm.Clickable\"\n role=\"article\"\n [attr.aria-label]=\"vm.N.Title\">\n\n <!-- Unread Indicator Bar -->\n <div class=\"card-indicator\" aria-hidden=\"true\"></div>\n\n <!-- Type Icon -->\n <div class=\"card-icon\" aria-hidden=\"true\">\n <i [class]=\"'fa-solid ' + getTypeIcon(vm.N)\"\n [style.color]=\"getTypeColor(vm.N)\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"card-content\" (click)=\"notificationClicked(vm.N)\">\n <div class=\"card-header\">\n <h3 class=\"card-title\" [class.card-title-unread]=\"vm.N.Unread\">\n {{vm.N.Title}}\n </h3>\n <span class=\"card-time\" [title]=\"(vm.N.__mj_CreatedAt | date:'medium') ?? ''\">\n @if (vm.Relative) {\n {{vm.Relative}}\n } @else {\n <time [attr.datetime]=\"vm.N.__mj_CreatedAt\">{{vm.N.__mj_CreatedAt | date:'MMM d, h:mm a'}}</time>\n }\n </span>\n </div>\n\n <div class=\"card-meta\">\n <span class=\"card-type\">{{getTypeName(vm.N)}}</span>\n @if (vm.Clickable) {\n <span class=\"card-open-hint\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\" aria-hidden=\"true\"></i> Open\n </span>\n }\n </div>\n\n @if (!IsExpanded(vm)) {\n <p class=\"card-message\">{{vm.Preview}}</p>\n } @else {\n <div class=\"card-rich\" (click)=\"$event.stopPropagation()\">\n @switch (vm.Kind) {\n @case ('html') {\n <!-- Angular sanitizes on [innerHTML] bind; chrome tags were stripped at classification -->\n <div class=\"card-rich-html\" [innerHTML]=\"vm.Body\"></div>\n }\n @case ('markdown') {\n <mj-markdown class=\"card-rich-md\" [data]=\"vm.Body\" [enableMermaid]=\"false\"></mj-markdown>\n }\n @default {\n <p class=\"card-message card-message-full\">{{vm.N.Message}}</p>\n }\n }\n </div>\n }\n\n @if (vm.Expandable) {\n <button class=\"card-expand-btn\" type=\"button\"\n (click)=\"ToggleExpanded(vm, $event)\"\n [attr.aria-expanded]=\"IsExpanded(vm)\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsExpanded(vm)\" [class.fa-chevron-up]=\"IsExpanded(vm)\" aria-hidden=\"true\"></i>\n {{ IsExpanded(vm) ? 'Show less' : 'Show more' }}\n </button>\n }\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\">\n @if (vm.N.Unread) {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(vm.N, true, null)\"\n [attr.aria-label]=\"'Mark ' + vm.N.Title + ' as read'\"\n title=\"Mark as Read\">\n <i class=\"fa-solid fa-check\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Read</span>\n </button>\n } @else {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(vm.N, false, null)\"\n [attr.aria-label]=\"'Mark ' + vm.N.Title + ' as unread'\"\n title=\"Mark as Unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Unread</span>\n </button>\n }\n </div>\n </article>\n }\n }\n </div>\n }\n </div>\n</div>\n", styles: ["/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n User Notifications \u2014 day-grouped cards with rich (HTML/Markdown) content,\n expand/collapse, and token-driven theming (light + dark for free).\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n:host {\n display: block;\n height: 100%;\n}\n\n.notifications-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-page);\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.notifications-header {\n flex-shrink: 0;\n padding: 20px 24px 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.header-top {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 14px;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.title-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: var(--mj-radius-lg, 12px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.title-text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.title-text h1 {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.title-subtitle {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.action-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s, border-color 0.15s;\n}\n\n.action-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.action-btn-ghost {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.action-btn-ghost:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500 Filters \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.filters-section {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n}\n\n.filters-slider {\n min-width: 0;\n}\n\n.slider-content {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.header-stats {\n display: inline-flex;\n gap: 4px;\n padding: 3px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n}\n\n.stat-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border: none;\n border-radius: var(--mj-radius-full, 999px);\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.stat-pill:hover {\n color: var(--mj-text-primary);\n}\n\n.stat-pill.active {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.stat-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-text-muted) 14%, transparent);\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n}\n\n.stat-count.unread-count {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.type-select {\n padding: 7px 10px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.search-section {\n flex: 1 1 220px;\n min-width: 180px;\n}\n\n.search-container {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-icon {\n position: absolute;\n left: 12px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n}\n\n.search-input {\n width: 100%;\n padding: 8px 12px 8px 32px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.search-input:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n\n.filter-info {\n flex-basis: 100%;\n}\n\n.filter-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n font-size: 11px;\n font-weight: 600;\n}\n\n/* \u2500\u2500 Content / list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.notifications-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n padding: 16px 24px 32px 24px;\n}\n\n.notifications-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n max-width: 960px;\n margin: 0 auto;\n}\n\n.group-label {\n position: sticky;\n top: -16px;\n z-index: 1;\n padding: 10px 2px 4px 2px;\n background: var(--mj-bg-page);\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n}\n\n.group-label:not(:first-child) {\n margin-top: 8px;\n}\n\n/* \u2500\u2500 Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.notification-card {\n position: relative;\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg, 12px);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;\n overflow: hidden;\n}\n\n.notification-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.notification-card.unread {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n}\n\n.card-indicator {\n display: none;\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n border-radius: 0 2px 2px 0;\n}\n\n.notification-card.unread .card-indicator {\n display: block;\n}\n\n.card-icon {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md, 10px);\n background: var(--mj-bg-surface-sunken);\n font-size: 14px;\n}\n\n.card-content {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.notification-card.clickable .card-content {\n cursor: pointer;\n}\n\n.card-header {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n}\n\n.card-title {\n margin: 0;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow-wrap: anywhere;\n}\n\n.card-title-unread {\n font-weight: 700;\n}\n\n.card-time {\n flex-shrink: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.card-meta {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 3px 0 6px 0;\n}\n\n.card-type {\n display: inline-flex;\n padding: 2px 8px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n.card-open-hint {\n display: none;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n}\n\n.notification-card.clickable:hover .card-open-hint {\n display: inline-flex;\n}\n\n.card-message {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n\n.card-message-full {\n display: block;\n -webkit-line-clamp: unset;\n white-space: pre-wrap;\n}\n\n/* \u2500\u2500 Rich (expanded) content \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.card-rich {\n margin-top: 4px;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface-card);\n cursor: default;\n}\n\n/* Sanitized foreign markup: keep it inside the card no matter what it brought along */\n.card-rich-html {\n font-size: 13px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n overflow-x: auto;\n}\n\n.card-rich-html img {\n max-width: 100%;\n height: auto;\n}\n\n.card-rich-html table {\n max-width: 100%;\n border-collapse: collapse;\n}\n\n.card-rich-html td,\n.card-rich-html th {\n padding: 4px 8px;\n border: 1px solid var(--mj-border-subtle);\n}\n\n.card-rich-html a {\n color: var(--mj-text-link);\n}\n\n.card-rich-html h1,\n.card-rich-html h2,\n.card-rich-html h3 {\n margin: 0.4em 0 0.3em 0;\n font-size: 1.05em;\n}\n\n.card-rich-md {\n display: block;\n font-size: 13px;\n}\n\n.card-expand-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n padding: 4px 10px;\n border: none;\n border-radius: var(--mj-radius-full, 999px);\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 700;\n cursor: pointer;\n}\n\n.card-expand-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n/* \u2500\u2500 Card actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.card-actions {\n flex-shrink: 0;\n display: flex;\n align-items: flex-start;\n}\n\n.card-action-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: 1px solid transparent;\n border-radius: var(--mj-radius-md, 8px);\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.card-action-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n@media (max-width: 720px) {\n .notifications-header {\n padding: 14px 14px 10px 14px;\n }\n\n .notifications-content {\n padding: 12px 12px 24px 12px;\n }\n\n .btn-text,\n .action-text {\n display: none;\n }\n\n .card-header {\n flex-direction: column;\n gap: 2px;\n }\n\n .card-time {\n order: -1;\n }\n}\n"] }]
919
+ }], () => [{ type: i1.SharedService }, { type: i1.NavigationService }, { type: i2.ApplicationManager }], null); })();
920
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserNotificationsComponent, { className: "UserNotificationsComponent", filePath: "src/lib/user-notifications/user-notifications.component.ts", lineNumber: 93 }); })();
741
921
  //# sourceMappingURL=user-notifications.component.js.map