mesauth-angular 0.1.10 → 0.1.11

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 (37) hide show
  1. package/dist/README.md +265 -0
  2. package/dist/esm2020/index.mjs +9 -0
  3. package/dist/esm2020/ma-user.component.mjs +26 -0
  4. package/dist/esm2020/mes-auth.interceptor.mjs +29 -0
  5. package/dist/esm2020/mes-auth.module.mjs +23 -0
  6. package/dist/esm2020/mes-auth.service.mjs +103 -0
  7. package/dist/esm2020/mesauth-angular.mjs +5 -0
  8. package/dist/esm2020/notification-badge.component.mjs +57 -0
  9. package/dist/esm2020/notification-panel.component.mjs +196 -0
  10. package/dist/esm2020/toast-container.component.mjs +60 -0
  11. package/dist/esm2020/toast.service.mjs +41 -0
  12. package/dist/esm2020/user-profile.component.mjs +197 -0
  13. package/dist/fesm2015/mesauth-angular.mjs +701 -0
  14. package/dist/fesm2015/mesauth-angular.mjs.map +1 -0
  15. package/dist/fesm2020/mesauth-angular.mjs +700 -0
  16. package/dist/fesm2020/mesauth-angular.mjs.map +1 -0
  17. package/dist/ma-user.component.d.ts +3 -0
  18. package/dist/mes-auth.interceptor.d.ts +3 -0
  19. package/dist/mes-auth.module.d.ts +4 -0
  20. package/dist/mes-auth.service.d.ts +5 -1
  21. package/dist/notification-badge.component.d.ts +3 -0
  22. package/dist/notification-panel.component.d.ts +3 -0
  23. package/dist/package.json +52 -0
  24. package/dist/toast-container.component.d.ts +3 -0
  25. package/dist/toast.service.d.ts +3 -0
  26. package/dist/user-profile.component.d.ts +3 -0
  27. package/package.json +15 -9
  28. package/dist/index.js +0 -8
  29. package/dist/ma-user.component.js +0 -33
  30. package/dist/mes-auth.interceptor.js +0 -36
  31. package/dist/mes-auth.module.js +0 -33
  32. package/dist/mes-auth.service.js +0 -107
  33. package/dist/notification-badge.component.js +0 -100
  34. package/dist/notification-panel.component.js +0 -327
  35. package/dist/toast-container.component.js +0 -185
  36. package/dist/toast.service.js +0 -43
  37. package/dist/user-profile.component.js +0 -363
@@ -0,0 +1,701 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, NgModule, EventEmitter, Component, Output } from '@angular/core';
3
+ import { HubConnectionBuilder, LogLevel } from '@microsoft/signalr';
4
+ import { BehaviorSubject, Subject, throwError } from 'rxjs';
5
+ import * as i1 from '@angular/common/http';
6
+ import { HTTP_INTERCEPTORS } from '@angular/common/http';
7
+ import { catchError, takeUntil } from 'rxjs/operators';
8
+ import * as i2 from '@angular/router';
9
+ import * as i2$1 from '@angular/common';
10
+ import { NgIf, CommonModule, NgFor } from '@angular/common';
11
+
12
+ var NotificationType;
13
+ (function (NotificationType) {
14
+ NotificationType["Info"] = "Info";
15
+ NotificationType["Warning"] = "Warning";
16
+ NotificationType["Error"] = "Error";
17
+ NotificationType["Success"] = "Success";
18
+ })(NotificationType || (NotificationType = {}));
19
+ class MesAuthService {
20
+ constructor(http) {
21
+ this.http = http;
22
+ this.hubConnection = null;
23
+ this._currentUser = new BehaviorSubject(null);
24
+ this.currentUser$ = this._currentUser.asObservable();
25
+ this._notifications = new Subject();
26
+ this.notifications$ = this._notifications.asObservable();
27
+ this.apiBase = '';
28
+ this.config = null;
29
+ }
30
+ init(config) {
31
+ this.config = config;
32
+ this.apiBase = config.apiBaseUrl.replace(/\/$/, '');
33
+ this.fetchCurrentUser();
34
+ this.fetchInitialNotifications();
35
+ this.startConnection(config);
36
+ }
37
+ getConfig() {
38
+ return this.config;
39
+ }
40
+ fetchCurrentUser() {
41
+ if (!this.apiBase)
42
+ return;
43
+ this.http.get(`${this.apiBase}/auth/me`).subscribe({
44
+ next: (u) => this._currentUser.next(u),
45
+ error: (err) => console.error('fetchCurrentUser error', err)
46
+ });
47
+ }
48
+ fetchInitialNotifications() {
49
+ if (!this.apiBase)
50
+ return;
51
+ this.http.get(`${this.apiBase}/notif/me`).subscribe({
52
+ next: (notifications) => {
53
+ if (Array.isArray(notifications === null || notifications === void 0 ? void 0 : notifications.items)) {
54
+ notifications.items.forEach((n) => this._notifications.next(n));
55
+ }
56
+ },
57
+ error: (err) => console.error('fetchInitialNotifications error', err)
58
+ });
59
+ }
60
+ getUnreadCount() {
61
+ return this.http.get(`${this.apiBase}/notif/me/unread-count`);
62
+ }
63
+ getNotifications(page = 1, pageSize = 20, includeRead = false, type) {
64
+ let url = `${this.apiBase}/notif/me?page=${page}&pageSize=${pageSize}&includeRead=${includeRead}`;
65
+ if (type) {
66
+ url += `&type=${type}`;
67
+ }
68
+ return this.http.get(url);
69
+ }
70
+ markAsRead(notificationId) {
71
+ return this.http.patch(`${this.apiBase}/notif/${notificationId}/read`, {});
72
+ }
73
+ markAllAsRead() {
74
+ return this.http.patch(`${this.apiBase}/notif/me/read-all`, {});
75
+ }
76
+ deleteNotification(notificationId) {
77
+ return this.http.delete(`${this.apiBase}/notif/${notificationId}`);
78
+ }
79
+ startConnection(config) {
80
+ var _a;
81
+ if (this.hubConnection)
82
+ return;
83
+ const signalrUrl = config.apiBaseUrl.replace(/\/$/, '') + '/hub/notification';
84
+ const builder = new HubConnectionBuilder()
85
+ .withUrl(signalrUrl, { withCredentials: (_a = config.withCredentials) !== null && _a !== void 0 ? _a : true })
86
+ .withAutomaticReconnect()
87
+ .configureLogging(LogLevel.Warning);
88
+ this.hubConnection = builder.build();
89
+ this.hubConnection.on('ReceiveNotification', (n) => this._notifications.next(n));
90
+ this.hubConnection.start().catch((err) => console.error('SignalR start error', err));
91
+ }
92
+ stop() {
93
+ if (!this.hubConnection)
94
+ return;
95
+ this.hubConnection.stop().catch(() => { });
96
+ this.hubConnection = null;
97
+ }
98
+ logout() {
99
+ return this.http.post(`${this.apiBase}/auth/logout`, {});
100
+ }
101
+ refreshUser() {
102
+ this.fetchCurrentUser();
103
+ }
104
+ }
105
+ MesAuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
106
+ MesAuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthService });
107
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthService, decorators: [{
108
+ type: Injectable
109
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
110
+
111
+ class MesAuthInterceptor {
112
+ constructor(authService, router) {
113
+ this.authService = authService;
114
+ this.router = router;
115
+ }
116
+ intercept(req, next) {
117
+ return next.handle(req).pipe(catchError((error) => {
118
+ if (error.status === 403) {
119
+ const config = this.authService.getConfig();
120
+ const baseUrl = (config === null || config === void 0 ? void 0 : config.userBaseUrl) || '';
121
+ const returnUrl = encodeURIComponent(window.location.href);
122
+ window.location.href = `${baseUrl}/403?returnUrl=${returnUrl}`;
123
+ }
124
+ return throwError(error);
125
+ }));
126
+ }
127
+ }
128
+ MesAuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthInterceptor, deps: [{ token: MesAuthService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Injectable });
129
+ MesAuthInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthInterceptor });
130
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthInterceptor, decorators: [{
131
+ type: Injectable
132
+ }], ctorParameters: function () { return [{ type: MesAuthService }, { type: i2.Router }]; } });
133
+
134
+ class MesAuthModule {
135
+ }
136
+ MesAuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
137
+ MesAuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: MesAuthModule });
138
+ MesAuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthModule, providers: [
139
+ MesAuthService,
140
+ { provide: HTTP_INTERCEPTORS, useClass: MesAuthInterceptor, multi: true }
141
+ ] });
142
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthModule, decorators: [{
143
+ type: NgModule,
144
+ args: [{
145
+ providers: [
146
+ MesAuthService,
147
+ { provide: HTTP_INTERCEPTORS, useClass: MesAuthInterceptor, multi: true }
148
+ ]
149
+ }]
150
+ }] });
151
+
152
+ class UserProfileComponent {
153
+ constructor(authService, router) {
154
+ this.authService = authService;
155
+ this.router = router;
156
+ this.notificationClick = new EventEmitter();
157
+ this.currentUser = null;
158
+ this.unreadCount = 0;
159
+ this.dropdownOpen = false;
160
+ this.destroy$ = new Subject();
161
+ }
162
+ ngOnInit() {
163
+ console.log('UserProfileComponent: Service injected?', !!this.authService);
164
+ this.authService.currentUser$
165
+ .pipe(takeUntil(this.destroy$))
166
+ .subscribe(user => {
167
+ console.log('UserProfileComponent: currentUser', user);
168
+ this.currentUser = user;
169
+ });
170
+ this.loadUnreadCount();
171
+ // Listen for new notifications
172
+ this.authService.notifications$
173
+ .pipe(takeUntil(this.destroy$))
174
+ .subscribe(() => {
175
+ this.loadUnreadCount();
176
+ });
177
+ }
178
+ ngOnDestroy() {
179
+ this.destroy$.next();
180
+ this.destroy$.complete();
181
+ }
182
+ loadUnreadCount() {
183
+ this.authService.getUnreadCount().subscribe({
184
+ next: (response) => {
185
+ this.unreadCount = response.unreadCount || 0;
186
+ },
187
+ error: (err) => console.error('Error loading unread count:', err)
188
+ });
189
+ }
190
+ getAvatarUrl(user) {
191
+ const config = this.authService.getConfig();
192
+ const baseUrl = (config === null || config === void 0 ? void 0 : config.avatarUrl) || 'https://ui-avatars.com/api/';
193
+ // Use userName first, fallback to userId, final fallback to 'User'
194
+ const displayName = user.userName || user.userId || 'User';
195
+ return `${baseUrl}?name=${encodeURIComponent(displayName)}&background=1976d2&color=fff`;
196
+ }
197
+ getLastNameInitial(user) {
198
+ const fullName = user.fullName || user.userName || 'U';
199
+ const parts = fullName.split(' ');
200
+ const lastPart = parts[parts.length - 1];
201
+ return lastPart.charAt(0).toUpperCase();
202
+ }
203
+ toggleDropdown() {
204
+ this.dropdownOpen = !this.dropdownOpen;
205
+ }
206
+ onLogin() {
207
+ const config = this.authService.getConfig();
208
+ const baseUrl = (config === null || config === void 0 ? void 0 : config.userBaseUrl) || '';
209
+ const returnUrl = encodeURIComponent(this.router.url);
210
+ window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;
211
+ }
212
+ onViewProfile() {
213
+ const config = this.authService.getConfig();
214
+ const baseUrl = (config === null || config === void 0 ? void 0 : config.userBaseUrl) || '';
215
+ window.location.href = `${baseUrl}/profile`;
216
+ this.dropdownOpen = false;
217
+ }
218
+ onLogout() {
219
+ this.authService.logout().subscribe({
220
+ next: () => {
221
+ // Clear current user after successful logout
222
+ this.currentUser = null;
223
+ this.dropdownOpen = false;
224
+ // Navigate to login with return URL
225
+ const config = this.authService.getConfig();
226
+ const baseUrl = (config === null || config === void 0 ? void 0 : config.userBaseUrl) || '';
227
+ const returnUrl = encodeURIComponent(window.location.href);
228
+ window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;
229
+ },
230
+ error: (err) => {
231
+ console.error('Logout error:', err);
232
+ // Still navigate to login even if logout fails
233
+ const config = this.authService.getConfig();
234
+ const baseUrl = (config === null || config === void 0 ? void 0 : config.userBaseUrl) || '';
235
+ window.location.href = `${baseUrl}/login`;
236
+ }
237
+ });
238
+ }
239
+ onNotificationClick() {
240
+ this.notificationClick.emit();
241
+ }
242
+ }
243
+ UserProfileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: UserProfileComponent, deps: [{ token: MesAuthService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
244
+ UserProfileComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: UserProfileComponent, isStandalone: true, selector: "ma-user-profile", outputs: { notificationClick: "notificationClick" }, ngImport: i0, template: `
245
+ <div class="user-profile-container">
246
+ <!-- Not logged in -->
247
+ <ng-container *ngIf="!currentUser">
248
+ <button class="login-btn" (click)="onLogin()">
249
+ Login
250
+ </button>
251
+ </ng-container>
252
+
253
+ <!-- Logged in -->
254
+ <ng-container *ngIf="currentUser">
255
+ <div class="user-header">
256
+ <button class="notification-btn" (click)="onNotificationClick()" title="Notifications">
257
+ <span class="icon">🔔</span>
258
+ <span class="badge" *ngIf="unreadCount > 0">{{ unreadCount }}</span>
259
+ </button>
260
+
261
+ <div class="user-menu-wrapper">
262
+ <button class="user-menu-btn" (click)="toggleDropdown()">
263
+ <img
264
+ *ngIf="currentUser.fullName || currentUser.userName"
265
+ [src]="getAvatarUrl(currentUser)"
266
+ [alt]="currentUser.fullName || currentUser.userName"
267
+ class="avatar"
268
+ />
269
+ <span *ngIf="!(currentUser.fullName || currentUser.userName)" class="avatar-initial">
270
+ {{ getLastNameInitial(currentUser) }}
271
+ </span>
272
+ </button>
273
+
274
+ <div class="dropdown-menu" *ngIf="dropdownOpen">
275
+ <div class="dropdown-header">
276
+ {{ currentUser.fullName || currentUser.userName }}
277
+ </div>
278
+ <button class="dropdown-item profile-link" (click)="onViewProfile()">
279
+ View Profile
280
+ </button>
281
+ <button class="dropdown-item logout-item" (click)="onLogout()">
282
+ Logout
283
+ </button>
284
+ </div>
285
+ </div>
286
+ </div>
287
+ </ng-container>
288
+ </div>
289
+ `, isInline: true, styles: [".user-profile-container{display:flex;align-items:center;gap:16px;padding:0 16px}.login-btn{padding:8px 16px;background-color:#1976d2;color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:500;transition:background-color .3s}.login-btn:hover{background-color:#1565c0}.user-header{display:flex;align-items:center;gap:16px}.notification-btn{position:relative;background:none;border:none;font-size:24px;cursor:pointer;padding:8px;transition:opacity .2s}.notification-btn:hover{opacity:.7}.icon{display:inline-block}.badge{position:absolute;top:0;right:0;background-color:#f44336;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700}.user-menu-wrapper{position:relative}.user-menu-btn{background:none;border:none;cursor:pointer;padding:4px;border-radius:50%;transition:background-color .2s;display:flex;align-items:center;justify-content:center}.user-menu-btn:hover{background-color:#1976d21a}.avatar{width:40px;height:40px;border-radius:50%;object-fit:cover;background-color:#e0e0e0}.avatar-initial{width:40px;height:40px;border-radius:50%;background-color:#1976d2;color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:16px}.dropdown-menu{position:absolute;top:calc(100% + 8px);right:0;background:white;border:1px solid #e0e0e0;border-radius:4px;box-shadow:0 2px 8px #00000026;min-width:200px;z-index:1000;overflow:hidden}.dropdown-header{padding:12px 16px;border-bottom:1px solid #f0f0f0;font-weight:600;color:#333;font-size:14px}.dropdown-item{display:block;width:100%;padding:12px 16px;border:none;background:none;text-align:left;cursor:pointer;font-size:14px;color:#333;text-decoration:none;transition:background-color .2s}.dropdown-item:hover{background-color:#f5f5f5}.profile-link{color:#1976d2}.logout-item{border-top:1px solid #f0f0f0;color:#f44336}.logout-item:hover{background-color:#ffebee}.user-info{display:flex;flex-direction:column;gap:2px}.user-name{font-weight:500;font-size:14px;color:#333}.user-position{font-size:12px;color:#666}.logout-btn{background:none;border:none;font-size:20px;cursor:pointer;color:#666;padding:4px 8px;transition:color .2s}.logout-btn:hover{color:#1976d2}@media (max-width: 768px){.user-info{display:none}.avatar{width:32px;height:32px}}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
290
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: UserProfileComponent, decorators: [{
291
+ type: Component,
292
+ args: [{ selector: 'ma-user-profile', standalone: true, imports: [NgIf], template: `
293
+ <div class="user-profile-container">
294
+ <!-- Not logged in -->
295
+ <ng-container *ngIf="!currentUser">
296
+ <button class="login-btn" (click)="onLogin()">
297
+ Login
298
+ </button>
299
+ </ng-container>
300
+
301
+ <!-- Logged in -->
302
+ <ng-container *ngIf="currentUser">
303
+ <div class="user-header">
304
+ <button class="notification-btn" (click)="onNotificationClick()" title="Notifications">
305
+ <span class="icon">🔔</span>
306
+ <span class="badge" *ngIf="unreadCount > 0">{{ unreadCount }}</span>
307
+ </button>
308
+
309
+ <div class="user-menu-wrapper">
310
+ <button class="user-menu-btn" (click)="toggleDropdown()">
311
+ <img
312
+ *ngIf="currentUser.fullName || currentUser.userName"
313
+ [src]="getAvatarUrl(currentUser)"
314
+ [alt]="currentUser.fullName || currentUser.userName"
315
+ class="avatar"
316
+ />
317
+ <span *ngIf="!(currentUser.fullName || currentUser.userName)" class="avatar-initial">
318
+ {{ getLastNameInitial(currentUser) }}
319
+ </span>
320
+ </button>
321
+
322
+ <div class="dropdown-menu" *ngIf="dropdownOpen">
323
+ <div class="dropdown-header">
324
+ {{ currentUser.fullName || currentUser.userName }}
325
+ </div>
326
+ <button class="dropdown-item profile-link" (click)="onViewProfile()">
327
+ View Profile
328
+ </button>
329
+ <button class="dropdown-item logout-item" (click)="onLogout()">
330
+ Logout
331
+ </button>
332
+ </div>
333
+ </div>
334
+ </div>
335
+ </ng-container>
336
+ </div>
337
+ `, styles: [".user-profile-container{display:flex;align-items:center;gap:16px;padding:0 16px}.login-btn{padding:8px 16px;background-color:#1976d2;color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:500;transition:background-color .3s}.login-btn:hover{background-color:#1565c0}.user-header{display:flex;align-items:center;gap:16px}.notification-btn{position:relative;background:none;border:none;font-size:24px;cursor:pointer;padding:8px;transition:opacity .2s}.notification-btn:hover{opacity:.7}.icon{display:inline-block}.badge{position:absolute;top:0;right:0;background-color:#f44336;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700}.user-menu-wrapper{position:relative}.user-menu-btn{background:none;border:none;cursor:pointer;padding:4px;border-radius:50%;transition:background-color .2s;display:flex;align-items:center;justify-content:center}.user-menu-btn:hover{background-color:#1976d21a}.avatar{width:40px;height:40px;border-radius:50%;object-fit:cover;background-color:#e0e0e0}.avatar-initial{width:40px;height:40px;border-radius:50%;background-color:#1976d2;color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:16px}.dropdown-menu{position:absolute;top:calc(100% + 8px);right:0;background:white;border:1px solid #e0e0e0;border-radius:4px;box-shadow:0 2px 8px #00000026;min-width:200px;z-index:1000;overflow:hidden}.dropdown-header{padding:12px 16px;border-bottom:1px solid #f0f0f0;font-weight:600;color:#333;font-size:14px}.dropdown-item{display:block;width:100%;padding:12px 16px;border:none;background:none;text-align:left;cursor:pointer;font-size:14px;color:#333;text-decoration:none;transition:background-color .2s}.dropdown-item:hover{background-color:#f5f5f5}.profile-link{color:#1976d2}.logout-item{border-top:1px solid #f0f0f0;color:#f44336}.logout-item:hover{background-color:#ffebee}.user-info{display:flex;flex-direction:column;gap:2px}.user-name{font-weight:500;font-size:14px;color:#333}.user-position{font-size:12px;color:#666}.logout-btn{background:none;border:none;font-size:20px;cursor:pointer;color:#666;padding:4px 8px;transition:color .2s}.logout-btn:hover{color:#1976d2}@media (max-width: 768px){.user-info{display:none}.avatar{width:32px;height:32px}}\n"] }]
338
+ }], ctorParameters: function () { return [{ type: MesAuthService }, { type: i2.Router }]; }, propDecorators: { notificationClick: [{
339
+ type: Output
340
+ }] } });
341
+
342
+ class ToastService {
343
+ constructor() {
344
+ this.toasts$ = new BehaviorSubject([]);
345
+ this.toasts = this.toasts$.asObservable();
346
+ }
347
+ show(message, title, type = 'info', duration = 5000) {
348
+ const id = Math.random().toString(36).substr(2, 9);
349
+ const toast = {
350
+ id,
351
+ message,
352
+ title,
353
+ type,
354
+ duration
355
+ };
356
+ const currentToasts = this.toasts$.value;
357
+ this.toasts$.next([...currentToasts, toast]);
358
+ if (duration > 0) {
359
+ setTimeout(() => {
360
+ this.remove(id);
361
+ }, duration);
362
+ }
363
+ return id;
364
+ }
365
+ remove(id) {
366
+ const currentToasts = this.toasts$.value;
367
+ this.toasts$.next(currentToasts.filter(t => t.id !== id));
368
+ }
369
+ clear() {
370
+ this.toasts$.next([]);
371
+ }
372
+ }
373
+ ToastService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
374
+ ToastService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ToastService, providedIn: 'root' });
375
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ToastService, decorators: [{
376
+ type: Injectable,
377
+ args: [{ providedIn: 'root' }]
378
+ }] });
379
+
380
+ class ToastContainerComponent {
381
+ constructor(toastService) {
382
+ this.toastService = toastService;
383
+ this.toasts = [];
384
+ }
385
+ ngOnInit() {
386
+ this.toastService.toasts.subscribe(toasts => {
387
+ this.toasts = toasts;
388
+ });
389
+ }
390
+ close(id) {
391
+ this.toastService.remove(id);
392
+ }
393
+ }
394
+ ToastContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ToastContainerComponent, deps: [{ token: ToastService }], target: i0.ɵɵFactoryTarget.Component });
395
+ ToastContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ToastContainerComponent, isStandalone: true, selector: "ma-toast-container", ngImport: i0, template: `
396
+ <div class="toast-container">
397
+ <div
398
+ *ngFor="let toast of toasts"
399
+ class="toast"
400
+ [class]="'toast-' + toast.type"
401
+ [@slideIn]
402
+ >
403
+ <div class="toast-content">
404
+ <div *ngIf="toast.title" class="toast-title">{{ toast.title }}</div>
405
+ <div class="toast-message">{{ toast.message }}</div>
406
+ </div>
407
+ <button class="toast-close" (click)="close(toast.id)" aria-label="Close">
408
+
409
+ </button>
410
+ </div>
411
+ </div>
412
+ `, isInline: true, styles: [".toast-container{position:fixed;top:20px;right:20px;z-index:9999;pointer-events:none}.toast{display:flex;align-items:flex-start;gap:12px;padding:12px 16px;margin-bottom:12px;border-radius:4px;background-color:#fff;box-shadow:0 4px 12px #00000026;pointer-events:auto;min-width:300px;max-width:500px;animation:slideIn .3s ease-out}.toast-content{flex:1}.toast-title{font-weight:600;font-size:14px;margin-bottom:4px}.toast-message{font-size:13px;line-height:1.4}.toast-close{background:none;border:none;cursor:pointer;font-size:18px;color:#999;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.toast-close:hover{color:#333}.toast-info{border-left:4px solid #2196f3}.toast-info .toast-title{color:#2196f3}.toast-info .toast-message{color:#333}.toast-success{border-left:4px solid #4caf50}.toast-success .toast-title{color:#4caf50}.toast-success .toast-message{color:#333}.toast-warning{border-left:4px solid #ff9800}.toast-warning .toast-title{color:#ff9800}.toast-warning .toast-message{color:#333}.toast-error{border-left:4px solid #f44336}.toast-error .toast-title{color:#f44336}.toast-error .toast-message{color:#333}@keyframes slideIn{0%{transform:translate(400px);opacity:0}to{transform:translate(0);opacity:1}}@media (max-width: 600px){.toast-container{top:10px;right:10px;left:10px}.toast{min-width:auto;max-width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
413
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ToastContainerComponent, decorators: [{
414
+ type: Component,
415
+ args: [{ selector: 'ma-toast-container', standalone: true, imports: [CommonModule], template: `
416
+ <div class="toast-container">
417
+ <div
418
+ *ngFor="let toast of toasts"
419
+ class="toast"
420
+ [class]="'toast-' + toast.type"
421
+ [@slideIn]
422
+ >
423
+ <div class="toast-content">
424
+ <div *ngIf="toast.title" class="toast-title">{{ toast.title }}</div>
425
+ <div class="toast-message">{{ toast.message }}</div>
426
+ </div>
427
+ <button class="toast-close" (click)="close(toast.id)" aria-label="Close">
428
+
429
+ </button>
430
+ </div>
431
+ </div>
432
+ `, styles: [".toast-container{position:fixed;top:20px;right:20px;z-index:9999;pointer-events:none}.toast{display:flex;align-items:flex-start;gap:12px;padding:12px 16px;margin-bottom:12px;border-radius:4px;background-color:#fff;box-shadow:0 4px 12px #00000026;pointer-events:auto;min-width:300px;max-width:500px;animation:slideIn .3s ease-out}.toast-content{flex:1}.toast-title{font-weight:600;font-size:14px;margin-bottom:4px}.toast-message{font-size:13px;line-height:1.4}.toast-close{background:none;border:none;cursor:pointer;font-size:18px;color:#999;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.toast-close:hover{color:#333}.toast-info{border-left:4px solid #2196f3}.toast-info .toast-title{color:#2196f3}.toast-info .toast-message{color:#333}.toast-success{border-left:4px solid #4caf50}.toast-success .toast-title{color:#4caf50}.toast-success .toast-message{color:#333}.toast-warning{border-left:4px solid #ff9800}.toast-warning .toast-title{color:#ff9800}.toast-warning .toast-message{color:#333}.toast-error{border-left:4px solid #f44336}.toast-error .toast-title{color:#f44336}.toast-error .toast-message{color:#333}@keyframes slideIn{0%{transform:translate(400px);opacity:0}to{transform:translate(0);opacity:1}}@media (max-width: 600px){.toast-container{top:10px;right:10px;left:10px}.toast{min-width:auto;max-width:100%}}\n"] }]
433
+ }], ctorParameters: function () { return [{ type: ToastService }]; } });
434
+
435
+ class NotificationPanelComponent {
436
+ constructor(authService, toastService) {
437
+ this.authService = authService;
438
+ this.toastService = toastService;
439
+ this.isOpen = false;
440
+ this.notifications = [];
441
+ this.destroy$ = new Subject();
442
+ }
443
+ ngOnInit() {
444
+ this.loadNotifications();
445
+ // Listen for new real-time notifications
446
+ this.authService.notifications$
447
+ .pipe(takeUntil(this.destroy$))
448
+ .subscribe((notification) => {
449
+ // Show toast for new notification
450
+ this.toastService.show(notification.message, notification.title, 'info', 5000);
451
+ // Reload notifications list
452
+ this.loadNotifications();
453
+ });
454
+ }
455
+ ngOnDestroy() {
456
+ this.destroy$.next();
457
+ this.destroy$.complete();
458
+ }
459
+ loadNotifications() {
460
+ this.authService.getNotifications(1, 50, false).subscribe({
461
+ next: (response) => {
462
+ this.notifications = response.items || [];
463
+ },
464
+ error: (err) => console.error('Error loading notifications:', err)
465
+ });
466
+ }
467
+ open() {
468
+ this.isOpen = true;
469
+ }
470
+ close() {
471
+ this.isOpen = false;
472
+ }
473
+ markAsRead(notificationId) {
474
+ this.authService.markAsRead(notificationId).subscribe({
475
+ next: () => {
476
+ const notification = this.notifications.find(n => n.id === notificationId);
477
+ if (notification) {
478
+ notification.isRead = true;
479
+ }
480
+ },
481
+ error: (err) => console.error('Error marking as read:', err)
482
+ });
483
+ }
484
+ markAllAsRead() {
485
+ this.authService.markAllAsRead().subscribe({
486
+ next: () => {
487
+ this.notifications.forEach(n => n.isRead = true);
488
+ },
489
+ error: (err) => console.error('Error marking all as read:', err)
490
+ });
491
+ }
492
+ delete(notificationId, event) {
493
+ event.stopPropagation();
494
+ this.authService.deleteNotification(notificationId).subscribe({
495
+ next: () => {
496
+ this.notifications = this.notifications.filter(n => n.id !== notificationId);
497
+ },
498
+ error: (err) => console.error('Error deleting notification:', err)
499
+ });
500
+ }
501
+ formatDate(dateString) {
502
+ const date = new Date(dateString);
503
+ const now = new Date();
504
+ const diffMs = now.getTime() - date.getTime();
505
+ const diffMins = Math.floor(diffMs / 60000);
506
+ const diffHours = Math.floor(diffMs / 3600000);
507
+ const diffDays = Math.floor(diffMs / 86400000);
508
+ if (diffMins < 1)
509
+ return 'Now';
510
+ if (diffMins < 60)
511
+ return `${diffMins}m ago`;
512
+ if (diffHours < 24)
513
+ return `${diffHours}h ago`;
514
+ if (diffDays < 7)
515
+ return `${diffDays}d ago`;
516
+ return date.toLocaleDateString();
517
+ }
518
+ }
519
+ NotificationPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationPanelComponent, deps: [{ token: MesAuthService }, { token: ToastService }], target: i0.ɵɵFactoryTarget.Component });
520
+ NotificationPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NotificationPanelComponent, isStandalone: true, selector: "ma-notification-panel", ngImport: i0, template: `
521
+ <div class="notification-panel" [class.open]="isOpen">
522
+ <!-- Header -->
523
+ <div class="panel-header">
524
+ <h3>Notifications</h3>
525
+ <button class="close-btn" (click)="close()" title="Close">✕</button>
526
+ </div>
527
+
528
+ <!-- Notifications List -->
529
+ <div class="notifications-list">
530
+ <ng-container *ngIf="notifications.length > 0">
531
+ <div
532
+ *ngFor="let notification of notifications"
533
+ class="notification-item"
534
+ [class.unread]="!notification.isRead"
535
+ (click)="markAsRead(notification.id)"
536
+ >
537
+ <div class="notification-content">
538
+ <div class="notification-title">{{ notification.title }}</div>
539
+ <div class="notification-message">{{ notification.message }}</div>
540
+ <div class="notification-meta">
541
+ <span class="app-name">{{ notification.sourceAppName }}</span>
542
+ <span class="time">{{ formatDate(notification.createdAt) }}</span>
543
+ </div>
544
+ </div>
545
+ <button
546
+ class="delete-btn"
547
+ (click)="delete(notification.id, $event)"
548
+ title="Delete"
549
+ >
550
+
551
+ </button>
552
+ </div>
553
+ </ng-container>
554
+
555
+ <ng-container *ngIf="notifications.length === 0">
556
+ <div class="empty-state">
557
+ No notifications
558
+ </div>
559
+ </ng-container>
560
+ </div>
561
+
562
+ <!-- Footer Actions -->
563
+ <div class="panel-footer" *ngIf="notifications.length > 0">
564
+ <button class="action-btn" (click)="markAllAsRead()">
565
+ Mark all as read
566
+ </button>
567
+ </div>
568
+ </div>
569
+ `, isInline: true, styles: [".notification-panel{position:fixed;top:0;right:-350px;width:350px;height:100vh;background:white;box-shadow:-2px 0 8px #0000001a;display:flex;flex-direction:column;z-index:1000;transition:right .3s ease}.notification-panel.open{right:0}.panel-header{display:flex;justify-content:space-between;align-items:center;padding:16px;border-bottom:1px solid #e0e0e0;background-color:#f5f5f5}.panel-header h3{margin:0;font-size:18px;color:#333}.close-btn{background:none;border:none;font-size:20px;cursor:pointer;color:#666;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn:hover{color:#333}.notifications-list{flex:1;overflow-y:auto}.notification-item{display:flex;gap:12px;padding:12px 16px;border-bottom:1px solid #f0f0f0;cursor:pointer;background-color:#fafafa;transition:background-color .2s}.notification-item:hover{background-color:#f5f5f5}.notification-item.unread{background-color:#e3f2fd}.notification-content{flex:1;min-width:0}.notification-title{font-weight:600;color:#333;font-size:14px;margin-bottom:4px}.notification-message{color:#666;font-size:13px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.notification-meta{display:flex;justify-content:space-between;font-size:12px;color:#999}.app-name{font-weight:500;color:#1976d2}.delete-btn{background:none;border:none;color:#999;cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.delete-btn:hover{color:#f44336}.empty-state{display:flex;align-items:center;justify-content:center;height:100%;color:#999;font-size:14px}.panel-footer{padding:12px 16px;border-top:1px solid #e0e0e0;background-color:#f5f5f5}.action-btn{width:100%;padding:8px;background-color:#1976d2;color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:500;transition:background-color .2s}.action-btn:hover{background-color:#1565c0}@media (max-width: 600px){.notification-panel{width:100%;right:-100%}}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
570
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationPanelComponent, decorators: [{
571
+ type: Component,
572
+ args: [{ selector: 'ma-notification-panel', standalone: true, imports: [NgIf, NgFor], template: `
573
+ <div class="notification-panel" [class.open]="isOpen">
574
+ <!-- Header -->
575
+ <div class="panel-header">
576
+ <h3>Notifications</h3>
577
+ <button class="close-btn" (click)="close()" title="Close">✕</button>
578
+ </div>
579
+
580
+ <!-- Notifications List -->
581
+ <div class="notifications-list">
582
+ <ng-container *ngIf="notifications.length > 0">
583
+ <div
584
+ *ngFor="let notification of notifications"
585
+ class="notification-item"
586
+ [class.unread]="!notification.isRead"
587
+ (click)="markAsRead(notification.id)"
588
+ >
589
+ <div class="notification-content">
590
+ <div class="notification-title">{{ notification.title }}</div>
591
+ <div class="notification-message">{{ notification.message }}</div>
592
+ <div class="notification-meta">
593
+ <span class="app-name">{{ notification.sourceAppName }}</span>
594
+ <span class="time">{{ formatDate(notification.createdAt) }}</span>
595
+ </div>
596
+ </div>
597
+ <button
598
+ class="delete-btn"
599
+ (click)="delete(notification.id, $event)"
600
+ title="Delete"
601
+ >
602
+
603
+ </button>
604
+ </div>
605
+ </ng-container>
606
+
607
+ <ng-container *ngIf="notifications.length === 0">
608
+ <div class="empty-state">
609
+ No notifications
610
+ </div>
611
+ </ng-container>
612
+ </div>
613
+
614
+ <!-- Footer Actions -->
615
+ <div class="panel-footer" *ngIf="notifications.length > 0">
616
+ <button class="action-btn" (click)="markAllAsRead()">
617
+ Mark all as read
618
+ </button>
619
+ </div>
620
+ </div>
621
+ `, styles: [".notification-panel{position:fixed;top:0;right:-350px;width:350px;height:100vh;background:white;box-shadow:-2px 0 8px #0000001a;display:flex;flex-direction:column;z-index:1000;transition:right .3s ease}.notification-panel.open{right:0}.panel-header{display:flex;justify-content:space-between;align-items:center;padding:16px;border-bottom:1px solid #e0e0e0;background-color:#f5f5f5}.panel-header h3{margin:0;font-size:18px;color:#333}.close-btn{background:none;border:none;font-size:20px;cursor:pointer;color:#666;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn:hover{color:#333}.notifications-list{flex:1;overflow-y:auto}.notification-item{display:flex;gap:12px;padding:12px 16px;border-bottom:1px solid #f0f0f0;cursor:pointer;background-color:#fafafa;transition:background-color .2s}.notification-item:hover{background-color:#f5f5f5}.notification-item.unread{background-color:#e3f2fd}.notification-content{flex:1;min-width:0}.notification-title{font-weight:600;color:#333;font-size:14px;margin-bottom:4px}.notification-message{color:#666;font-size:13px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.notification-meta{display:flex;justify-content:space-between;font-size:12px;color:#999}.app-name{font-weight:500;color:#1976d2}.delete-btn{background:none;border:none;color:#999;cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.delete-btn:hover{color:#f44336}.empty-state{display:flex;align-items:center;justify-content:center;height:100%;color:#999;font-size:14px}.panel-footer{padding:12px 16px;border-top:1px solid #e0e0e0;background-color:#f5f5f5}.action-btn{width:100%;padding:8px;background-color:#1976d2;color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:500;transition:background-color .2s}.action-btn:hover{background-color:#1565c0}@media (max-width: 600px){.notification-panel{width:100%;right:-100%}}\n"] }]
622
+ }], ctorParameters: function () { return [{ type: MesAuthService }, { type: ToastService }]; } });
623
+
624
+ class MaUserComponent {
625
+ }
626
+ MaUserComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MaUserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
627
+ MaUserComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MaUserComponent, isStandalone: true, selector: "ma-user", ngImport: i0, template: `
628
+ <ma-toast-container></ma-toast-container>
629
+ <div class="user-header">
630
+ <ma-user-profile (notificationClick)="notificationPanel.open()"></ma-user-profile>
631
+ </div>
632
+ <ma-notification-panel #notificationPanel></ma-notification-panel>
633
+ `, isInline: true, styles: [".user-header{display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "component", type: ToastContainerComponent, selector: "ma-toast-container" }, { kind: "component", type: UserProfileComponent, selector: "ma-user-profile", outputs: ["notificationClick"] }, { kind: "component", type: NotificationPanelComponent, selector: "ma-notification-panel" }] });
634
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MaUserComponent, decorators: [{
635
+ type: Component,
636
+ args: [{ selector: 'ma-user', standalone: true, imports: [ToastContainerComponent, UserProfileComponent, NotificationPanelComponent], template: `
637
+ <ma-toast-container></ma-toast-container>
638
+ <div class="user-header">
639
+ <ma-user-profile (notificationClick)="notificationPanel.open()"></ma-user-profile>
640
+ </div>
641
+ <ma-notification-panel #notificationPanel></ma-notification-panel>
642
+ `, styles: [".user-header{display:flex;justify-content:flex-end}\n"] }]
643
+ }] });
644
+
645
+ class NotificationBadgeComponent {
646
+ constructor(authService) {
647
+ this.authService = authService;
648
+ this.notificationClick = new EventEmitter();
649
+ this.unreadCount = 0;
650
+ this.destroy$ = new Subject();
651
+ }
652
+ ngOnInit() {
653
+ this.loadUnreadCount();
654
+ // Listen for new notifications
655
+ this.authService.notifications$
656
+ .pipe(takeUntil(this.destroy$))
657
+ .subscribe(() => {
658
+ this.loadUnreadCount();
659
+ });
660
+ }
661
+ ngOnDestroy() {
662
+ this.destroy$.next();
663
+ this.destroy$.complete();
664
+ }
665
+ loadUnreadCount() {
666
+ this.authService.getUnreadCount().subscribe({
667
+ next: (response) => {
668
+ this.unreadCount = response.unreadCount || 0;
669
+ },
670
+ error: (err) => console.error('Error loading unread count:', err)
671
+ });
672
+ }
673
+ onNotificationClick() {
674
+ this.notificationClick.emit();
675
+ }
676
+ }
677
+ NotificationBadgeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationBadgeComponent, deps: [{ token: MesAuthService }], target: i0.ɵɵFactoryTarget.Component });
678
+ NotificationBadgeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NotificationBadgeComponent, isStandalone: true, selector: "ma-notification-badge", outputs: { notificationClick: "notificationClick" }, ngImport: i0, template: `
679
+ <button class="notification-btn" (click)="onNotificationClick()" title="Notifications">
680
+ <span class="icon">🔔</span>
681
+ <span class="badge" *ngIf="unreadCount > 0">{{ unreadCount }}</span>
682
+ </button>
683
+ `, isInline: true, styles: [".notification-btn{position:relative;background:none;border:none;font-size:24px;cursor:pointer;padding:8px;transition:opacity .2s}.notification-btn:hover{opacity:.7}.icon{display:inline-block}.badge{position:absolute;top:0;right:0;background-color:#f44336;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
684
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationBadgeComponent, decorators: [{
685
+ type: Component,
686
+ args: [{ selector: 'ma-notification-badge', standalone: true, imports: [NgIf], template: `
687
+ <button class="notification-btn" (click)="onNotificationClick()" title="Notifications">
688
+ <span class="icon">🔔</span>
689
+ <span class="badge" *ngIf="unreadCount > 0">{{ unreadCount }}</span>
690
+ </button>
691
+ `, styles: [".notification-btn{position:relative;background:none;border:none;font-size:24px;cursor:pointer;padding:8px;transition:opacity .2s}.notification-btn:hover{opacity:.7}.icon{display:inline-block}.badge{position:absolute;top:0;right:0;background-color:#f44336;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700}\n"] }]
692
+ }], ctorParameters: function () { return [{ type: MesAuthService }]; }, propDecorators: { notificationClick: [{
693
+ type: Output
694
+ }] } });
695
+
696
+ /**
697
+ * Generated bundle index. Do not edit.
698
+ */
699
+
700
+ export { MaUserComponent, MesAuthInterceptor, MesAuthModule, MesAuthService, NotificationBadgeComponent, NotificationPanelComponent, NotificationType, ToastContainerComponent, UserProfileComponent };
701
+ //# sourceMappingURL=mesauth-angular.mjs.map