@memberjunction/ng-explorer-settings 3.1.1 → 3.3.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 (60) hide show
  1. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +15 -1
  2. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts.map +1 -1
  3. package/dist/lib/application-management/application-dialog/application-dialog.component.js +329 -190
  4. package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
  5. package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
  6. package/dist/lib/application-management/application-management.component.js +265 -184
  7. package/dist/lib/application-management/application-management.component.js.map +1 -1
  8. package/dist/lib/entity-permissions/entity-permissions.component.d.ts +1 -0
  9. package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
  10. package/dist/lib/entity-permissions/entity-permissions.component.js +369 -192
  11. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  12. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts.map +1 -1
  13. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +160 -143
  14. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
  15. package/dist/lib/module.d.ts +17 -21
  16. package/dist/lib/module.d.ts.map +1 -1
  17. package/dist/lib/module.js +20 -39
  18. package/dist/lib/module.js.map +1 -1
  19. package/dist/lib/notification-preferences/notification-preferences.component.d.ts +113 -0
  20. package/dist/lib/notification-preferences/notification-preferences.component.d.ts.map +1 -0
  21. package/dist/lib/notification-preferences/notification-preferences.component.js +382 -0
  22. package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -0
  23. package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts.map +1 -1
  24. package/dist/lib/role-management/role-dialog/role-dialog.component.js +93 -89
  25. package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
  26. package/dist/lib/role-management/role-management.component.d.ts +1 -0
  27. package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
  28. package/dist/lib/role-management/role-management.component.js +275 -158
  29. package/dist/lib/role-management/role-management.component.js.map +1 -1
  30. package/dist/lib/settings/settings.component.d.ts +54 -1
  31. package/dist/lib/settings/settings.component.d.ts.map +1 -1
  32. package/dist/lib/settings/settings.component.js +528 -172
  33. package/dist/lib/settings/settings.component.js.map +1 -1
  34. package/dist/lib/shared/settings-card.component.d.ts.map +1 -1
  35. package/dist/lib/shared/settings-card.component.js +21 -18
  36. package/dist/lib/shared/settings-card.component.js.map +1 -1
  37. package/dist/lib/sql-logging/sql-logging.component.d.ts +70 -10
  38. package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -1
  39. package/dist/lib/sql-logging/sql-logging.component.js +547 -205
  40. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  41. package/dist/lib/user-app-config/user-app-config.component.d.ts +21 -3
  42. package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -1
  43. package/dist/lib/user-app-config/user-app-config.component.js +202 -147
  44. package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
  45. package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
  46. package/dist/lib/user-management/user-dialog/user-dialog.component.js +120 -116
  47. package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
  48. package/dist/lib/user-management/user-management.component.d.ts +32 -2
  49. package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
  50. package/dist/lib/user-management/user-management.component.js +822 -297
  51. package/dist/lib/user-management/user-management.component.js.map +1 -1
  52. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +31 -2
  53. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts.map +1 -1
  54. package/dist/lib/user-profile-settings/user-profile-settings.component.js +213 -80
  55. package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
  56. package/dist/public-api.d.ts +1 -0
  57. package/dist/public-api.d.ts.map +1 -1
  58. package/dist/public-api.js +1 -0
  59. package/dist/public-api.js.map +1 -1
  60. package/package.json +21 -20
@@ -0,0 +1,382 @@
1
+ import { Component } from '@angular/core';
2
+ import { Metadata } from '@memberjunction/core';
3
+ import { UserInfoEngine } from '@memberjunction/core-entities';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@memberjunction/ng-shared";
6
+ import * as i2 from "@angular/forms";
7
+ import * as i3 from "@memberjunction/ng-shared-generic";
8
+ const _forTrack0 = ($index, $item) => $item.type.ID;
9
+ function NotificationPreferencesComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
10
+ i0.ɵɵelement(0, "mj-loading", 1);
11
+ } }
12
+ function NotificationPreferencesComponent_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
13
+ i0.ɵɵelementStart(0, "div", 3);
14
+ i0.ɵɵelement(1, "i", 6);
15
+ i0.ɵɵelementStart(2, "p");
16
+ i0.ɵɵtext(3, "No notification types configured yet.");
17
+ i0.ɵɵelementEnd()();
18
+ } }
19
+ function NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Conditional_29_Template(rf, ctx) { if (rf & 1) {
20
+ i0.ɵɵelementStart(0, "div", 22);
21
+ i0.ɵɵelement(1, "i", 24);
22
+ i0.ɵɵelementStart(2, "span");
23
+ i0.ɵɵtext(3, "This notification type's delivery channels cannot be customized.");
24
+ i0.ɵɵelementEnd()();
25
+ } }
26
+ function NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Conditional_30_Template(rf, ctx) { if (rf & 1) {
27
+ i0.ɵɵelementStart(0, "div", 23);
28
+ i0.ɵɵelement(1, "i", 25);
29
+ i0.ɵɵelementStart(2, "span", 26);
30
+ i0.ɵɵtext(3);
31
+ i0.ɵɵelementEnd()();
32
+ } if (rf & 2) {
33
+ const vm_r2 = i0.ɵɵnextContext().$implicit;
34
+ const ctx_r2 = i0.ɵɵnextContext(3);
35
+ i0.ɵɵadvance(3);
36
+ i0.ɵɵtextInterpolate1(" Auto-marks as read after ", ctx_r2.getTypeAutoExpireDays(vm_r2.type), " day(s) ");
37
+ } }
38
+ function NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
39
+ const _r1 = i0.ɵɵgetCurrentView();
40
+ i0.ɵɵelementStart(0, "article", 8)(1, "div", 9)(2, "div", 10);
41
+ i0.ɵɵelement(3, "i");
42
+ i0.ɵɵelementEnd();
43
+ i0.ɵɵelementStart(4, "div", 11)(5, "h4");
44
+ i0.ɵɵtext(6);
45
+ i0.ɵɵelementEnd();
46
+ i0.ɵɵelementStart(7, "p", 12);
47
+ i0.ɵɵtext(8);
48
+ i0.ɵɵelementEnd()()();
49
+ i0.ɵɵelementStart(9, "div", 13)(10, "div", 14)(11, "label", 15);
50
+ i0.ɵɵtext(12, "Delivery Channels");
51
+ i0.ɵɵelementEnd();
52
+ i0.ɵɵelementStart(13, "div", 16)(14, "label", 17)(15, "input", 18);
53
+ i0.ɵɵtwoWayListener("ngModelChange", function NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Template_input_ngModelChange_15_listener($event) { const vm_r2 = i0.ɵɵrestoreView(_r1).$implicit; i0.ɵɵtwoWayBindingSet(vm_r2.inAppEnabled, $event) || (vm_r2.inAppEnabled = $event); return i0.ɵɵresetView($event); });
54
+ i0.ɵɵlistener("change", function NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Template_input_change_15_listener() { const vm_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onChannelChange(vm_r2)); });
55
+ i0.ɵɵelementEnd();
56
+ i0.ɵɵelement(16, "i", 19);
57
+ i0.ɵɵelementStart(17, "span");
58
+ i0.ɵɵtext(18, "In-App");
59
+ i0.ɵɵelementEnd()();
60
+ i0.ɵɵelementStart(19, "label", 17)(20, "input", 18);
61
+ i0.ɵɵtwoWayListener("ngModelChange", function NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Template_input_ngModelChange_20_listener($event) { const vm_r2 = i0.ɵɵrestoreView(_r1).$implicit; i0.ɵɵtwoWayBindingSet(vm_r2.emailEnabled, $event) || (vm_r2.emailEnabled = $event); return i0.ɵɵresetView($event); });
62
+ i0.ɵɵlistener("change", function NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Template_input_change_20_listener() { const vm_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onChannelChange(vm_r2)); });
63
+ i0.ɵɵelementEnd();
64
+ i0.ɵɵelement(21, "i", 20);
65
+ i0.ɵɵelementStart(22, "span");
66
+ i0.ɵɵtext(23, "Email");
67
+ i0.ɵɵelementEnd()();
68
+ i0.ɵɵelementStart(24, "label", 17)(25, "input", 18);
69
+ i0.ɵɵtwoWayListener("ngModelChange", function NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Template_input_ngModelChange_25_listener($event) { const vm_r2 = i0.ɵɵrestoreView(_r1).$implicit; i0.ɵɵtwoWayBindingSet(vm_r2.smsEnabled, $event) || (vm_r2.smsEnabled = $event); return i0.ɵɵresetView($event); });
70
+ i0.ɵɵlistener("change", function NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Template_input_change_25_listener() { const vm_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onChannelChange(vm_r2)); });
71
+ i0.ɵɵelementEnd();
72
+ i0.ɵɵelement(26, "i", 21);
73
+ i0.ɵɵelementStart(27, "span");
74
+ i0.ɵɵtext(28, "SMS");
75
+ i0.ɵɵelementEnd()()();
76
+ i0.ɵɵtemplate(29, NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Conditional_29_Template, 4, 0, "div", 22);
77
+ i0.ɵɵelementEnd();
78
+ i0.ɵɵtemplate(30, NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Conditional_30_Template, 4, 1, "div", 23);
79
+ i0.ɵɵelementEnd()();
80
+ } if (rf & 2) {
81
+ const vm_r2 = ctx.$implicit;
82
+ const ctx_r2 = i0.ɵɵnextContext(3);
83
+ i0.ɵɵclassProp("changed", vm_r2.changed);
84
+ i0.ɵɵattribute("aria-label", "Notification settings for " + vm_r2.type.Name);
85
+ i0.ɵɵadvance();
86
+ i0.ɵɵstyleProp("border-left-color", ctx_r2.getTypeColor(vm_r2.type));
87
+ i0.ɵɵadvance();
88
+ i0.ɵɵstyleProp("background-color", ctx_r2.getTypeColor(vm_r2.type) + "20");
89
+ i0.ɵɵadvance();
90
+ i0.ɵɵclassMap("fa-solid " + ctx_r2.getTypeIcon(vm_r2.type));
91
+ i0.ɵɵstyleProp("color", ctx_r2.getTypeColor(vm_r2.type));
92
+ i0.ɵɵattribute("aria-hidden", true);
93
+ i0.ɵɵadvance(3);
94
+ i0.ɵɵtextInterpolate(vm_r2.type.Name);
95
+ i0.ɵɵadvance(2);
96
+ i0.ɵɵtextInterpolate(vm_r2.type.Description);
97
+ i0.ɵɵadvance(3);
98
+ i0.ɵɵattribute("id", "delivery-label-" + vm_r2.type.ID);
99
+ i0.ɵɵadvance(2);
100
+ i0.ɵɵattribute("aria-labelledby", "delivery-label-" + vm_r2.type.ID);
101
+ i0.ɵɵadvance(2);
102
+ i0.ɵɵtwoWayProperty("ngModel", vm_r2.inAppEnabled);
103
+ i0.ɵɵproperty("disabled", !ctx_r2.getAllowUserPreference(vm_r2.type));
104
+ i0.ɵɵattribute("aria-label", "Enable in-app notifications for " + vm_r2.type.Name);
105
+ i0.ɵɵadvance(5);
106
+ i0.ɵɵtwoWayProperty("ngModel", vm_r2.emailEnabled);
107
+ i0.ɵɵproperty("disabled", !ctx_r2.getAllowUserPreference(vm_r2.type));
108
+ i0.ɵɵattribute("aria-label", "Enable email notifications for " + vm_r2.type.Name);
109
+ i0.ɵɵadvance(5);
110
+ i0.ɵɵtwoWayProperty("ngModel", vm_r2.smsEnabled);
111
+ i0.ɵɵproperty("disabled", !ctx_r2.getAllowUserPreference(vm_r2.type));
112
+ i0.ɵɵattribute("aria-label", "Enable SMS notifications for " + vm_r2.type.Name);
113
+ i0.ɵɵadvance(4);
114
+ i0.ɵɵconditional(!ctx_r2.getAllowUserPreference(vm_r2.type) ? 29 : -1);
115
+ i0.ɵɵadvance();
116
+ i0.ɵɵconditional(ctx_r2.getTypeAutoExpireDays(vm_r2.type) ? 30 : -1);
117
+ } }
118
+ function NotificationPreferencesComponent_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
119
+ i0.ɵɵelementStart(0, "div", 4);
120
+ i0.ɵɵrepeaterCreate(1, NotificationPreferencesComponent_Conditional_2_Conditional_2_For_2_Template, 31, 27, "article", 7, _forTrack0);
121
+ i0.ɵɵelementEnd();
122
+ } if (rf & 2) {
123
+ const ctx_r2 = i0.ɵɵnextContext(2);
124
+ i0.ɵɵadvance();
125
+ i0.ɵɵrepeater(ctx_r2.viewModels);
126
+ } }
127
+ function NotificationPreferencesComponent_Conditional_2_Conditional_3_Conditional_4_Template(rf, ctx) { if (rf & 1) {
128
+ i0.ɵɵelement(0, "i", 29);
129
+ } }
130
+ function NotificationPreferencesComponent_Conditional_2_Conditional_3_Conditional_5_Template(rf, ctx) { if (rf & 1) {
131
+ i0.ɵɵelement(0, "i", 30);
132
+ } }
133
+ function NotificationPreferencesComponent_Conditional_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
134
+ const _r4 = i0.ɵɵgetCurrentView();
135
+ i0.ɵɵelementStart(0, "div", 5)(1, "button", 27);
136
+ i0.ɵɵlistener("click", function NotificationPreferencesComponent_Conditional_2_Conditional_3_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.cancel()); });
137
+ i0.ɵɵtext(2, " Cancel ");
138
+ i0.ɵɵelementEnd();
139
+ i0.ɵɵelementStart(3, "button", 28);
140
+ i0.ɵɵlistener("click", function NotificationPreferencesComponent_Conditional_2_Conditional_3_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.save()); });
141
+ i0.ɵɵtemplate(4, NotificationPreferencesComponent_Conditional_2_Conditional_3_Conditional_4_Template, 1, 0, "i", 29)(5, NotificationPreferencesComponent_Conditional_2_Conditional_3_Conditional_5_Template, 1, 0, "i", 30);
142
+ i0.ɵɵelementStart(6, "span");
143
+ i0.ɵɵtext(7);
144
+ i0.ɵɵelementEnd()()();
145
+ } if (rf & 2) {
146
+ const ctx_r2 = i0.ɵɵnextContext(2);
147
+ i0.ɵɵadvance();
148
+ i0.ɵɵproperty("disabled", ctx_r2.saving);
149
+ i0.ɵɵattribute("aria-busy", ctx_r2.saving);
150
+ i0.ɵɵadvance(2);
151
+ i0.ɵɵproperty("disabled", ctx_r2.saving);
152
+ i0.ɵɵattribute("aria-busy", ctx_r2.saving);
153
+ i0.ɵɵadvance();
154
+ i0.ɵɵconditional(ctx_r2.saving ? 4 : 5);
155
+ i0.ɵɵadvance(3);
156
+ i0.ɵɵtextInterpolate(ctx_r2.saving ? "Saving..." : "Save Preferences");
157
+ } }
158
+ function NotificationPreferencesComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
159
+ i0.ɵɵelementStart(0, "div", 2);
160
+ i0.ɵɵtemplate(1, NotificationPreferencesComponent_Conditional_2_Conditional_1_Template, 4, 0, "div", 3)(2, NotificationPreferencesComponent_Conditional_2_Conditional_2_Template, 3, 0, "div", 4)(3, NotificationPreferencesComponent_Conditional_2_Conditional_3_Template, 8, 6, "div", 5);
161
+ i0.ɵɵelementEnd();
162
+ } if (rf & 2) {
163
+ const ctx_r2 = i0.ɵɵnextContext();
164
+ i0.ɵɵadvance();
165
+ i0.ɵɵconditional(ctx_r2.viewModels.length === 0 ? 1 : 2);
166
+ i0.ɵɵadvance(2);
167
+ i0.ɵɵconditional(ctx_r2.hasChanges ? 3 : -1);
168
+ } }
169
+ /**
170
+ * Component for managing user notification preferences.
171
+ *
172
+ * Displays notification types with configurable delivery channels (in-app, email, SMS).
173
+ * Users can customize which channels they want to receive notifications through,
174
+ * unless the notification type restricts user customization.
175
+ *
176
+ * Uses Material Design 3 (MD3) styling principles for consistent, accessible UI.
177
+ *
178
+ * Data flow:
179
+ * - Loads notification types from UserInfoEngine (global cache)
180
+ * - Loads user preferences from UserInfoEngine (per-user cache)
181
+ * - Saves preferences using transaction groups for batch updates
182
+ */
183
+ export class NotificationPreferencesComponent {
184
+ sharedService;
185
+ loading = true;
186
+ saving = false;
187
+ viewModels = [];
188
+ hasChanges = false;
189
+ constructor(sharedService) {
190
+ this.sharedService = sharedService;
191
+ }
192
+ /**
193
+ * Angular lifecycle hook - initializes the component by loading notification preferences.
194
+ */
195
+ async ngOnInit() {
196
+ await this.loadData();
197
+ }
198
+ /**
199
+ * Loads notification types and user preferences from UserInfoEngine.
200
+ * Builds view models by merging type defaults with user preferences.
201
+ * Sorts types by Priority (ascending), then Name (alphabetical).
202
+ * @private
203
+ */
204
+ async loadData() {
205
+ try {
206
+ this.loading = true;
207
+ // UserInfoEngine is auto-configured via @RegisterForStartup()
208
+ // NotificationEngine (server-side) loads notification types into global cache
209
+ // UserInfoEngine provides a getter to access them from both client and server
210
+ // Get notification types from UserInfoEngine, sorted client-side
211
+ const types = [...UserInfoEngine.Instance.NotificationTypes].sort((a, b) => {
212
+ const priorityA = a.Priority ?? 999;
213
+ const priorityB = b.Priority ?? 999;
214
+ if (priorityA !== priorityB) {
215
+ return priorityA - priorityB;
216
+ }
217
+ return a.Name.localeCompare(b.Name);
218
+ });
219
+ // Get preferences from UserInfoEngine (entity objects - can be mutated)
220
+ const prefs = UserInfoEngine.Instance.NotificationPreferences;
221
+ // Build view models from cached data
222
+ this.viewModels = types.map((type) => {
223
+ const existingPref = prefs.find((p) => p.NotificationTypeID === type.ID);
224
+ // Get channel values: user preference > type default
225
+ const inAppEnabled = existingPref?.InAppEnabled ?? type.DefaultInApp ?? true;
226
+ const emailEnabled = existingPref?.EmailEnabled ?? type.DefaultEmail ?? false;
227
+ const smsEnabled = existingPref?.SMSEnabled ?? type.DefaultSMS ?? false;
228
+ return {
229
+ type,
230
+ preference: existingPref || null,
231
+ inAppEnabled,
232
+ emailEnabled,
233
+ smsEnabled,
234
+ changed: false,
235
+ originalInAppEnabled: inAppEnabled,
236
+ originalEmailEnabled: emailEnabled,
237
+ originalSmsEnabled: smsEnabled,
238
+ };
239
+ });
240
+ this.loading = false;
241
+ }
242
+ catch (error) {
243
+ this.loading = false;
244
+ const message = error instanceof Error ? error.message : 'Unknown error';
245
+ this.sharedService.CreateSimpleNotification(`Failed to load notification preferences: ${message}`, 'error', 3000);
246
+ }
247
+ }
248
+ /**
249
+ * Called when a user toggles any delivery channel checkbox.
250
+ * Updates the view model's changed flag by comparing current state to original values.
251
+ * Sets the global hasChanges flag to show/hide the save/cancel buttons.
252
+ * @param vm The view model for the notification type being modified
253
+ */
254
+ onChannelChange(vm) {
255
+ vm.changed = vm.inAppEnabled !== vm.originalInAppEnabled || vm.emailEnabled !== vm.originalEmailEnabled || vm.smsEnabled !== vm.originalSmsEnabled;
256
+ this.hasChanges = this.viewModels.some((v) => v.changed);
257
+ }
258
+ /**
259
+ * Saves all changed notification preferences using a transaction group for batch updates.
260
+ * Creates new preference records for types that don't have existing preferences.
261
+ * Updates the Enabled field based on whether any channel is enabled.
262
+ * Shows success/error notification on completion.
263
+ * @returns Promise that resolves when save is complete
264
+ */
265
+ async save() {
266
+ try {
267
+ this.saving = true;
268
+ const md = new Metadata();
269
+ const currentUser = md.CurrentUser;
270
+ const transGroup = await md.CreateTransactionGroup();
271
+ // Queue all saves in transaction group - no need to await individual saves
272
+ // Transaction group queues them and submits all in one batch
273
+ for (const vm of this.viewModels.filter((v) => v.changed)) {
274
+ let pref = vm.preference;
275
+ if (!pref) {
276
+ // Create new preference record
277
+ pref = await md.GetEntityObject('MJ: User Notification Preferences');
278
+ pref.UserID = currentUser.ID;
279
+ pref.NotificationTypeID = vm.type.ID;
280
+ vm.preference = pref;
281
+ }
282
+ // Set Enabled based on whether any channel is enabled
283
+ pref.Enabled = vm.inAppEnabled || vm.emailEnabled || vm.smsEnabled;
284
+ // Set the boolean channel fields
285
+ pref.InAppEnabled = vm.inAppEnabled;
286
+ pref.EmailEnabled = vm.emailEnabled;
287
+ pref.SMSEnabled = vm.smsEnabled;
288
+ pref.TransactionGroup = transGroup;
289
+ // Don't await - Save() with transaction group queues immediately
290
+ pref.Save();
291
+ }
292
+ // Submit transaction group - this is where the actual network call happens
293
+ const success = await transGroup.Submit();
294
+ if (success) {
295
+ // Cache refresh happens automatically in UserNotificationPreferenceEntityExtended.Save()
296
+ // Update original values
297
+ this.viewModels.forEach((vm) => {
298
+ vm.originalInAppEnabled = vm.inAppEnabled;
299
+ vm.originalEmailEnabled = vm.emailEnabled;
300
+ vm.originalSmsEnabled = vm.smsEnabled;
301
+ vm.changed = false;
302
+ });
303
+ this.hasChanges = false;
304
+ this.sharedService.CreateSimpleNotification('Notification preferences saved successfully', 'success', 2500);
305
+ }
306
+ else {
307
+ throw new Error('Failed to save preferences');
308
+ }
309
+ this.saving = false;
310
+ }
311
+ catch (error) {
312
+ this.saving = false;
313
+ const message = error instanceof Error ? error.message : 'Unknown error';
314
+ this.sharedService.CreateSimpleNotification(`Failed to save preferences: ${message}`, 'error', 3000);
315
+ }
316
+ }
317
+ /**
318
+ * Cancels all unsaved changes and reverts to original values.
319
+ * Resets the changed flag on all view models and hides the action buttons.
320
+ */
321
+ cancel() {
322
+ // Revert changes
323
+ this.viewModels.forEach((vm) => {
324
+ vm.inAppEnabled = vm.originalInAppEnabled;
325
+ vm.emailEnabled = vm.originalEmailEnabled;
326
+ vm.smsEnabled = vm.originalSmsEnabled;
327
+ vm.changed = false;
328
+ });
329
+ this.hasChanges = false;
330
+ }
331
+ /**
332
+ * Gets the Font Awesome icon class for a notification type.
333
+ * Used for MD3 dynamic icon styling in the card header.
334
+ * @param type The notification type entity
335
+ * @returns Font Awesome icon class (e.g., 'fa-bell'), defaults to 'fa-bell' if not specified
336
+ */
337
+ getTypeIcon(type) {
338
+ return type.Icon || 'fa-bell';
339
+ }
340
+ /**
341
+ * Gets the color hex code for a notification type.
342
+ * Used for MD3 dynamic color styling (icon background, border accent).
343
+ * @param type The notification type entity
344
+ * @returns Hex color code (e.g., '#0076B6'), defaults to '#999' if not specified
345
+ */
346
+ getTypeColor(type) {
347
+ return type.Color || '#999';
348
+ }
349
+ /**
350
+ * Gets the auto-expire duration in days for a notification type.
351
+ * Displayed in the metadata row to inform users about automatic read marking.
352
+ * @param type The notification type entity
353
+ * @returns Number of days until auto-expire, or null if not configured
354
+ */
355
+ getTypeAutoExpireDays(type) {
356
+ return type.AutoExpireDays || null;
357
+ }
358
+ /**
359
+ * Checks if users are allowed to customize preferences for this notification type.
360
+ * When false, the delivery channel checkboxes are disabled and an info message is shown.
361
+ * @param type The notification type entity
362
+ * @returns True if user customization is allowed (default), false otherwise
363
+ */
364
+ getAllowUserPreference(type) {
365
+ return type.AllowUserPreference !== false;
366
+ }
367
+ static ɵfac = function NotificationPreferencesComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || NotificationPreferencesComponent)(i0.ɵɵdirectiveInject(i1.SharedService)); };
368
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: NotificationPreferencesComponent, selectors: [["mj-notification-preferences"]], decls: 3, vars: 1, consts: [[1, "notification-preferences-container"], ["text", "Loading notification preferences..."], [1, "content"], [1, "empty-state"], [1, "notification-types-grid"], ["role", "group", "aria-label", "Save or cancel changes", 1, "actions"], [1, "fa-solid", "fa-bell-slash"], ["role", "region", 1, "notification-type-card", 3, "changed"], ["role", "region", 1, "notification-type-card"], [1, "card-header"], [1, "icon-wrapper"], [1, "header-text"], [1, "type-description"], [1, "card-body"], [1, "preference-row"], [1, "delivery-label"], ["role", "group", 1, "delivery-checkboxes"], [1, "channel-checkbox"], ["type", "checkbox", 3, "ngModelChange", "change", "ngModel", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-bell"], ["aria-hidden", "true", 1, "fa-solid", "fa-envelope"], ["aria-hidden", "true", 1, "fa-solid", "fa-mobile"], ["role", "alert", "aria-live", "polite", 1, "info-message"], [1, "metadata-row"], ["aria-hidden", "true", 1, "fa-solid", "fa-info-circle"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock"], [1, "metadata-text"], ["type", "button", 1, "btn", "btn-secondary", 3, "click", "disabled"], ["type", "button", 1, "btn", "btn-primary", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["aria-hidden", "true", 1, "fa-solid", "fa-save"]], template: function NotificationPreferencesComponent_Template(rf, ctx) { if (rf & 1) {
369
+ i0.ɵɵelementStart(0, "div", 0);
370
+ i0.ɵɵtemplate(1, NotificationPreferencesComponent_Conditional_1_Template, 1, 0, "mj-loading", 1)(2, NotificationPreferencesComponent_Conditional_2_Template, 4, 2, "div", 2);
371
+ i0.ɵɵelementEnd();
372
+ } if (rf & 2) {
373
+ i0.ɵɵadvance();
374
+ i0.ɵɵconditional(ctx.loading ? 1 : 2);
375
+ } }, dependencies: [i2.CheckboxControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.LoadingComponent], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n \n\n --md-primary: #0076B6;\n --md-on-primary: #FFFFFF;\n --md-primary-container: #AAE7FD;\n --md-on-primary-container: #001F2A;\n\n \n\n --md-secondary: #F5A623;\n --md-on-secondary: #FFFFFF;\n --md-secondary-container: #FFECD6;\n --md-on-secondary-container: #2D1600;\n\n \n\n --md-tertiary: #4CAF50;\n --md-on-tertiary: #FFFFFF;\n --md-tertiary-container: #C8E6C9;\n --md-on-tertiary-container: #002204;\n\n \n\n --md-error: #D32F2F;\n --md-on-error: #FFFFFF;\n --md-error-container: #FFCDD2;\n --md-on-error-container: #410002;\n\n \n\n --md-warning: #FFC107;\n --md-on-warning: #2D1600;\n --md-warning-container: #FFF3CD;\n --md-on-warning-container: #856404;\n\n \n\n --md-surface: #FAFCFF;\n --md-surface-container-lowest: #FFFFFF;\n --md-surface-container-low: #F3F5F9;\n --md-surface-container: #EDF0F4;\n --md-surface-container-high: #E7EAEE;\n --md-surface-container-highest: #E1E3E8;\n --md-on-surface: #191C20;\n --md-on-surface-variant: #43474E;\n --md-outline: #74777F;\n --md-outline-variant: #C4C6D0;\n\n \n\n --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n --md-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n --md-elevation-3: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n --md-elevation-4: 0 6px 12px rgba(0, 0, 0, 0.1), 0 12px 24px rgba(0, 0, 0, 0.08);\n --md-elevation-5: 0 8px 16px rgba(0, 0, 0, 0.12), 0 16px 32px rgba(0, 0, 0, 0.1);\n\n \n\n --md-corner-extra-small: 4px;\n --md-corner-small: 8px;\n --md-corner-medium: 12px;\n --md-corner-large: 16px;\n --md-corner-extra-large: 28px;\n --md-corner-full: 9999px;\n\n \n\n display: block;\n width: 100%;\n}\n\n\n\n\n\n.notification-preferences-container[_ngcontent-%COMP%] {\n padding: 1.5rem;\n max-width: 1200px;\n margin: 0 auto;\n background: var(--md-surface);\n}\n\n\n\n\n\n.content[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 3rem 1.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 1.5rem;\n display: block;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n\n\n\n\n.notification-types-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 1.25rem;\n margin-bottom: 1.5rem;\n}\n\n\n\n\n\n.notification-type-card[_ngcontent-%COMP%] {\n background: var(--md-surface-container-lowest);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n border-left: 4px solid var(--md-outline-variant);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--md-elevation-1);\n}\n\n.notification-type-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n.notification-type-card.changed[_ngcontent-%COMP%] {\n border-left-color: var(--md-primary) !important;\n border-color: var(--md-primary);\n box-shadow: var(--md-elevation-3);\n background: var(--md-primary-container);\n}\n\n\n\n\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n padding: 1.25rem;\n border-bottom: 1px solid var(--md-outline-variant);\n align-items: flex-start;\n}\n\n.icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--md-corner-small);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: transform 0.2s;\n}\n\n.notification-type-card[_ngcontent-%COMP%]:hover .icon-wrapper[_ngcontent-%COMP%] {\n transform: scale(1.05);\n}\n\n.icon-wrapper[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n}\n\n.header-text[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.header-text[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 0.375rem 0;\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n.type-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n line-height: 1.4;\n}\n\n\n\n\n\n.card-body[_ngcontent-%COMP%] {\n padding: 1.25rem;\n}\n\n.preference-row[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n}\n\n.preference-row[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.delivery-label[_ngcontent-%COMP%] {\n display: block;\n font-weight: 600;\n margin-bottom: 0.75rem;\n font-size: 0.875rem;\n color: var(--md-on-surface);\n letter-spacing: 0.01em;\n}\n\n\n\n\n\n.delivery-checkboxes[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.75rem 1rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n background: var(--md-surface);\n min-height: 44px;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--md-primary);\n margin: 0;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%]:disabled {\n cursor: not-allowed;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n transition: color 0.2s;\n}\n\n.channel-checkbox[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--md-on-surface);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:hover:not(:has(input:disabled)) {\n border-color: var(--md-primary);\n background: var(--md-primary-container);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:hover:not(:has(input:disabled)) i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:has(input:checked) {\n border-color: var(--md-primary);\n background: var(--md-primary-container);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:has(input:checked) i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:has(input:disabled) {\n opacity: 0.5;\n cursor: not-allowed;\n background: var(--md-surface-container-low);\n}\n\n.channel-checkbox[_ngcontent-%COMP%]:focus-within {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n.info-message[_ngcontent-%COMP%] {\n margin-top: 0.75rem;\n padding: 0.75rem;\n background: var(--md-warning-container);\n border-left: 3px solid var(--md-warning);\n border-radius: var(--md-corner-small);\n font-size: 0.8125rem;\n display: flex;\n gap: 0.75rem;\n align-items: flex-start;\n line-height: 1.4;\n color: var(--md-on-warning-container);\n}\n\n.info-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-on-warning-container);\n font-size: 1rem;\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n\n\n\n\n.metadata-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.625rem;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--md-on-surface-variant);\n padding-top: 0.75rem;\n margin-top: 0.75rem;\n border-top: 1px solid var(--md-outline-variant);\n}\n\n.metadata-row[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-on-surface-variant);\n font-size: 0.875rem;\n flex-shrink: 0;\n}\n\n.metadata-text[_ngcontent-%COMP%] {\n line-height: 1.4;\n}\n\n\n\n\n\n.actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.25rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n margin-top: 1.5rem;\n}\n\n\n\n\n\n.btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n border: none;\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\n transform: scale(0.98);\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n.btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--md-on-surface-variant);\n border: none;\n}\n\n.btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.btn-ghost[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #005A8C;\n transform: scale(0.98);\n}\n\n.btn-danger[_ngcontent-%COMP%] {\n background: var(--md-error);\n color: var(--md-on-error);\n box-shadow: var(--md-elevation-1);\n}\n\n.btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #E57373;\n box-shadow: var(--md-elevation-2);\n}\n\n.btn-danger[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #EF9A9A;\n transform: scale(0.98);\n}\n\n.btn-sm[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n\n\n\n\n.badge-system[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\n}\n\n.badge-custom[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n\n\n\n\nbutton[_ngcontent-%COMP%]:focus-visible, \ninput[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\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@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .notification-preferences-container[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n\n .card-header[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .card-body[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .delivery-checkboxes[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .channel-checkbox[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .actions[_ngcontent-%COMP%] {\n flex-direction: column;\n padding: 1rem;\n }\n\n .actions[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) and (max-width: 767px) {\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n@media (min-width: 768px) {\n .notification-preferences-container[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));\n }\n}\n\n@media (min-width: 1024px) {\n .notification-types-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(450px, 1fr));\n gap: 1.5rem;\n }\n}"] });
376
+ }
377
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NotificationPreferencesComponent, [{
378
+ type: Component,
379
+ args: [{ selector: 'mj-notification-preferences', template: "<div class=\"notification-preferences-container\">\n @if (loading) {\n <mj-loading text=\"Loading notification preferences...\"></mj-loading>\n } @else {\n <div class=\"content\">\n @if (viewModels.length === 0) {\n <!-- Empty state -->\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-bell-slash\"></i>\n <p>No notification types configured yet.</p>\n </div>\n } @else {\n <!-- Notification type cards -->\n <div class=\"notification-types-grid\">\n @for (vm of viewModels; track vm.type.ID) {\n <article class=\"notification-type-card\"\n [class.changed]=\"vm.changed\"\n role=\"region\"\n [attr.aria-label]=\"'Notification settings for ' + vm.type.Name\">\n\n <div class=\"card-header\" [style.border-left-color]=\"getTypeColor(vm.type)\">\n <div class=\"icon-wrapper\" [style.background-color]=\"getTypeColor(vm.type) + '20'\">\n <i [class]=\"'fa-solid ' + getTypeIcon(vm.type)\" [style.color]=\"getTypeColor(vm.type)\" [attr.aria-hidden]=\"true\"></i>\n </div>\n <div class=\"header-text\">\n <h4>{{ vm.type.Name }}</h4>\n <p class=\"type-description\">{{ vm.type.Description }}</p>\n </div>\n </div>\n\n <div class=\"card-body\">\n <!-- Delivery channel checkboxes -->\n <div class=\"preference-row\">\n <label class=\"delivery-label\" [attr.id]=\"'delivery-label-' + vm.type.ID\">Delivery Channels</label>\n\n <div class=\"delivery-checkboxes\" role=\"group\" [attr.aria-labelledby]=\"'delivery-label-' + vm.type.ID\">\n <label class=\"channel-checkbox\">\n <input type=\"checkbox\"\n [(ngModel)]=\"vm.inAppEnabled\"\n (change)=\"onChannelChange(vm)\"\n [disabled]=\"!getAllowUserPreference(vm.type)\"\n [attr.aria-label]=\"'Enable in-app notifications for ' + vm.type.Name\">\n <i class=\"fa-solid fa-bell\" aria-hidden=\"true\"></i>\n <span>In-App</span>\n </label>\n\n <label class=\"channel-checkbox\">\n <input type=\"checkbox\"\n [(ngModel)]=\"vm.emailEnabled\"\n (change)=\"onChannelChange(vm)\"\n [disabled]=\"!getAllowUserPreference(vm.type)\"\n [attr.aria-label]=\"'Enable email notifications for ' + vm.type.Name\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span>Email</span>\n </label>\n\n <label class=\"channel-checkbox\">\n <input type=\"checkbox\"\n [(ngModel)]=\"vm.smsEnabled\"\n (change)=\"onChannelChange(vm)\"\n [disabled]=\"!getAllowUserPreference(vm.type)\"\n [attr.aria-label]=\"'Enable SMS notifications for ' + vm.type.Name\">\n <i class=\"fa-solid fa-mobile\" aria-hidden=\"true\"></i>\n <span>SMS</span>\n </label>\n </div>\n\n @if (!getAllowUserPreference(vm.type)) {\n <div class=\"info-message\" role=\"alert\" aria-live=\"polite\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n <span>This notification type's delivery channels cannot be customized.</span>\n </div>\n }\n </div>\n\n <!-- Auto-expire info -->\n @if (getTypeAutoExpireDays(vm.type)) {\n <div class=\"metadata-row\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n <span class=\"metadata-text\">\n Auto-marks as read after {{ getTypeAutoExpireDays(vm.type) }} day(s)\n </span>\n </div>\n }\n </div>\n </article>\n }\n </div>\n }\n\n <!-- Action buttons -->\n @if (hasChanges) {\n <div class=\"actions\" role=\"group\" aria-label=\"Save or cancel changes\">\n <button class=\"btn btn-secondary\"\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"saving\"\n [attr.aria-busy]=\"saving\">\n Cancel\n </button>\n <button class=\"btn btn-primary\"\n type=\"button\"\n (click)=\"save()\"\n [disabled]=\"saving\"\n [attr.aria-busy]=\"saving\">\n @if (saving) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-save\" aria-hidden=\"true\"></i>\n }\n <span>{{ saving ? 'Saving...' : 'Save Preferences' }}</span>\n </button>\n </div>\n }\n </div>\n }\n</div>\n", styles: ["/* =============================================================================\n Notification Preferences Component - Material Design 3\n Following MD3 Design System Guidelines\n ============================================================================= */\n\n/* MD3 Color Tokens */\n:host {\n /* Primary - Deep Blue */\n --md-primary: #0076B6;\n --md-on-primary: #FFFFFF;\n --md-primary-container: #AAE7FD;\n --md-on-primary-container: #001F2A;\n\n /* Secondary - Light Orange */\n --md-secondary: #F5A623;\n --md-on-secondary: #FFFFFF;\n --md-secondary-container: #FFECD6;\n --md-on-secondary-container: #2D1600;\n\n /* Tertiary - Light Green */\n --md-tertiary: #4CAF50;\n --md-on-tertiary: #FFFFFF;\n --md-tertiary-container: #C8E6C9;\n --md-on-tertiary-container: #002204;\n\n /* Error - Red */\n --md-error: #D32F2F;\n --md-on-error: #FFFFFF;\n --md-error-container: #FFCDD2;\n --md-on-error-container: #410002;\n\n /* Warning - Amber */\n --md-warning: #FFC107;\n --md-on-warning: #2D1600;\n --md-warning-container: #FFF3CD;\n --md-on-warning-container: #856404;\n\n /* Surface Colors */\n --md-surface: #FAFCFF;\n --md-surface-container-lowest: #FFFFFF;\n --md-surface-container-low: #F3F5F9;\n --md-surface-container: #EDF0F4;\n --md-surface-container-high: #E7EAEE;\n --md-surface-container-highest: #E1E3E8;\n --md-on-surface: #191C20;\n --md-on-surface-variant: #43474E;\n --md-outline: #74777F;\n --md-outline-variant: #C4C6D0;\n\n /* Elevation (Box Shadows) */\n --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n --md-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n --md-elevation-3: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n --md-elevation-4: 0 6px 12px rgba(0, 0, 0, 0.1), 0 12px 24px rgba(0, 0, 0, 0.08);\n --md-elevation-5: 0 8px 16px rgba(0, 0, 0, 0.12), 0 16px 32px rgba(0, 0, 0, 0.1);\n\n /* Corner Radii */\n --md-corner-extra-small: 4px;\n --md-corner-small: 8px;\n --md-corner-medium: 12px;\n --md-corner-large: 16px;\n --md-corner-extra-large: 28px;\n --md-corner-full: 9999px;\n\n /* Host element configuration */\n display: block;\n width: 100%;\n}\n\n/* -----------------------------------------------------------------------------\n Container & Layout\n ----------------------------------------------------------------------------- */\n.notification-preferences-container {\n padding: 1.5rem;\n max-width: 1200px;\n margin: 0 auto;\n background: var(--md-surface);\n}\n\n/* -----------------------------------------------------------------------------\n Loading State\n ----------------------------------------------------------------------------- */\n.content {\n animation: fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* -----------------------------------------------------------------------------\n Empty State\n ----------------------------------------------------------------------------- */\n.empty-state {\n text-align: center;\n padding: 3rem 1.5rem;\n}\n\n.empty-state i {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 1.5rem;\n display: block;\n}\n\n.empty-state p {\n font-size: 1.125rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Notification Types Grid\n ----------------------------------------------------------------------------- */\n.notification-types-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 1.25rem;\n margin-bottom: 1.5rem;\n}\n\n/* -----------------------------------------------------------------------------\n Notification Type Card\n ----------------------------------------------------------------------------- */\n.notification-type-card {\n background: var(--md-surface-container-lowest);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-medium);\n border-left: 4px solid var(--md-outline-variant);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--md-elevation-1);\n}\n\n.notification-type-card:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n.notification-type-card.changed {\n border-left-color: var(--md-primary) !important;\n border-color: var(--md-primary);\n box-shadow: var(--md-elevation-3);\n background: var(--md-primary-container);\n}\n\n/* -----------------------------------------------------------------------------\n Card Header\n ----------------------------------------------------------------------------- */\n.card-header {\n display: flex;\n gap: 1rem;\n padding: 1.25rem;\n border-bottom: 1px solid var(--md-outline-variant);\n align-items: flex-start;\n}\n\n.icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: var(--md-corner-small);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: transform 0.2s;\n}\n\n.notification-type-card:hover .icon-wrapper {\n transform: scale(1.05);\n}\n\n.icon-wrapper i {\n font-size: 1.5rem;\n}\n\n.header-text {\n flex: 1;\n min-width: 0;\n}\n\n.header-text h4 {\n margin: 0 0 0.375rem 0;\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n.type-description {\n margin: 0;\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n line-height: 1.4;\n}\n\n/* -----------------------------------------------------------------------------\n Card Body\n ----------------------------------------------------------------------------- */\n.card-body {\n padding: 1.25rem;\n}\n\n.preference-row {\n margin-bottom: 1rem;\n}\n\n.preference-row:last-child {\n margin-bottom: 0;\n}\n\n.delivery-label {\n display: block;\n font-weight: 600;\n margin-bottom: 0.75rem;\n font-size: 0.875rem;\n color: var(--md-on-surface);\n letter-spacing: 0.01em;\n}\n\n/* -----------------------------------------------------------------------------\n Delivery Channel Checkboxes\n ----------------------------------------------------------------------------- */\n.delivery-checkboxes {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.channel-checkbox {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.75rem 1rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n background: var(--md-surface);\n min-height: 44px;\n}\n\n.channel-checkbox input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--md-primary);\n margin: 0;\n}\n\n.channel-checkbox input[type=\"checkbox\"]:disabled {\n cursor: not-allowed;\n}\n\n.channel-checkbox i {\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n transition: color 0.2s;\n}\n\n.channel-checkbox span {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--md-on-surface);\n}\n\n.channel-checkbox:hover:not(:has(input:disabled)) {\n border-color: var(--md-primary);\n background: var(--md-primary-container);\n}\n\n.channel-checkbox:hover:not(:has(input:disabled)) i {\n color: var(--md-primary);\n}\n\n.channel-checkbox:has(input:checked) {\n border-color: var(--md-primary);\n background: var(--md-primary-container);\n}\n\n.channel-checkbox:has(input:checked) i {\n color: var(--md-primary);\n}\n\n.channel-checkbox:has(input:disabled) {\n opacity: 0.5;\n cursor: not-allowed;\n background: var(--md-surface-container-low);\n}\n\n.channel-checkbox:focus-within {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Info Message\n ----------------------------------------------------------------------------- */\n.info-message {\n margin-top: 0.75rem;\n padding: 0.75rem;\n background: var(--md-warning-container);\n border-left: 3px solid var(--md-warning);\n border-radius: var(--md-corner-small);\n font-size: 0.8125rem;\n display: flex;\n gap: 0.75rem;\n align-items: flex-start;\n line-height: 1.4;\n color: var(--md-on-warning-container);\n}\n\n.info-message i {\n color: var(--md-on-warning-container);\n font-size: 1rem;\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Metadata Row\n ----------------------------------------------------------------------------- */\n.metadata-row {\n display: flex;\n gap: 0.625rem;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--md-on-surface-variant);\n padding-top: 0.75rem;\n margin-top: 0.75rem;\n border-top: 1px solid var(--md-outline-variant);\n}\n\n.metadata-row i {\n color: var(--md-on-surface-variant);\n font-size: 0.875rem;\n flex-shrink: 0;\n}\n\n.metadata-text {\n line-height: 1.4;\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons Section\n ----------------------------------------------------------------------------- */\n.actions {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.25rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n margin-top: 1.5rem;\n}\n\n/* -----------------------------------------------------------------------------\n Button System - MD3 Patterns\n ----------------------------------------------------------------------------- */\n.btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n border: none;\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.btn:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.btn i {\n font-size: 1rem;\n}\n\n.btn-secondary {\n background: var(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.btn-secondary:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\n transform: scale(0.98);\n}\n\n.btn-primary {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.btn-primary:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n.btn-ghost {\n background: transparent;\n color: var(--md-on-surface-variant);\n border: none;\n}\n\n.btn-ghost:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.btn-ghost:active:not(:disabled) {\n background: #005A8C;\n transform: scale(0.98);\n}\n\n.btn-danger {\n background: var(--md-error);\n color: var(--md-on-error);\n box-shadow: var(--md-elevation-1);\n}\n\n.btn-danger:hover:not(:disabled) {\n background: #E57373;\n box-shadow: var(--md-elevation-2);\n}\n\n.btn-danger:active:not(:disabled) {\n background: #EF9A9A;\n transform: scale(0.98);\n}\n\n.btn-sm {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n/* -----------------------------------------------------------------------------\n Badge System - MD3 Patterns\n ----------------------------------------------------------------------------- */\n.badge-system {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\n}\n\n.badge-custom {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\nbutton:focus-visible,\ninput:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Reduced Motion\n ----------------------------------------------------------------------------- */\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 Animations\n ----------------------------------------------------------------------------- */\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* -----------------------------------------------------------------------------\n Responsive Design - Mobile First\n ----------------------------------------------------------------------------- */\n@media (max-width: 639px) {\n .notification-preferences-container {\n padding: 1rem;\n }\n\n .notification-types-grid {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n\n .card-header {\n padding: 1rem;\n }\n\n .card-body {\n padding: 1rem;\n }\n\n .delivery-checkboxes {\n flex-direction: column;\n }\n\n .channel-checkbox {\n width: 100%;\n }\n\n .actions {\n flex-direction: column;\n padding: 1rem;\n }\n\n .actions .btn {\n width: 100%;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) and (max-width: 767px) {\n .notification-types-grid {\n grid-template-columns: 1fr;\n }\n}\n\n@media (min-width: 768px) {\n .notification-preferences-container {\n padding: 2rem;\n }\n\n .notification-types-grid {\n grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));\n }\n}\n\n@media (min-width: 1024px) {\n .notification-types-grid {\n grid-template-columns: repeat(auto-fill, minmax(450px, 1fr));\n gap: 1.5rem;\n }\n}\n"] }]
380
+ }], () => [{ type: i1.SharedService }], null); })();
381
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(NotificationPreferencesComponent, { className: "NotificationPreferencesComponent", filePath: "src/lib/notification-preferences/notification-preferences.component.ts", lineNumber: 50 }); })();
382
+ //# sourceMappingURL=notification-preferences.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-preferences.component.js","sourceRoot":"","sources":["../../../src/lib/notification-preferences/notification-preferences.component.ts","../../../src/lib/notification-preferences/notification-preferences.component.html"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"role-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/role-management/role-dialog/role-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAA2C,MAAM,eAAe,CAAC;AAE7J,OAAO,EAAiD,SAAS,EAAc,MAAM,gBAAgB,CAAC;AAEtG,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;;AAG3D,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,qBAMa,mBAAoB,YAAW,MAAM,EAAE,SAAS,EAAE,SAAS;IAC7D,IAAI,EAAE,cAAc,GAAG,IAAI,CAAQ;IACnC,OAAO,UAAS;IACf,MAAM,iCAAwC;IAExD,OAAO,CAAC,EAAE,CAAuB;IACjC,OAAO,CAAC,QAAQ,CAAkB;IAE3B,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,UAAS;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;;IAUnC,QAAQ,IAAI,IAAI;IAIhB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAWzC,WAAW,IAAI,IAAI;IAInB,OAAO,CAAC,SAAS;IAUjB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAMvC,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,IAAW,YAAY,IAAI,OAAO,CAIjC;IAED,OAAO,CAAC,YAAY;IAgBP,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgD/B,QAAQ,IAAI,IAAI;IAIvB,OAAO,CAAC,oBAAoB;yCAzIjB,mBAAmB;2CAAnB,mBAAmB;CA+I/B"}
1
+ {"version":3,"file":"role-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/role-management/role-dialog/role-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAA2C,MAAM,eAAe,CAAC;AAE7J,OAAO,EAAiD,SAAS,EAAc,MAAM,gBAAgB,CAAC;AAEtG,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;;AAE3D,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,qBAMa,mBAAoB,YAAW,MAAM,EAAE,SAAS,EAAE,SAAS;IAC7D,IAAI,EAAE,cAAc,GAAG,IAAI,CAAQ;IACnC,OAAO,UAAS;IACf,MAAM,iCAAwC;IAExD,OAAO,CAAC,EAAE,CAAuB;IACjC,OAAO,CAAC,QAAQ,CAAkB;IAE3B,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,UAAS;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;;IAUnC,QAAQ,IAAI,IAAI;IAIhB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAWzC,WAAW,IAAI,IAAI;IAInB,OAAO,CAAC,SAAS;IAUjB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAMvC,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,IAAW,YAAY,IAAI,OAAO,CAIjC;IAED,OAAO,CAAC,YAAY;IAgBP,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgD/B,QAAQ,IAAI,IAAI;IAIvB,OAAO,CAAC,oBAAoB;yCAzIjB,mBAAmB;2CAAnB,mBAAmB;CA+I/B"}