mesauth-angular 0.2.14 → 0.2.20

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 (32) hide show
  1. package/README.md +139 -61
  2. package/dist/README.md +139 -61
  3. package/dist/{fesm2020 → fesm2022}/mesauth-angular.mjs +702 -662
  4. package/dist/fesm2022/mesauth-angular.mjs.map +1 -0
  5. package/dist/index.d.ts +269 -9
  6. package/package.json +12 -12
  7. package/dist/esm2020/index.mjs +0 -10
  8. package/dist/esm2020/ma-user.component.mjs +0 -32
  9. package/dist/esm2020/mes-auth.interceptor.mjs +0 -29
  10. package/dist/esm2020/mes-auth.module.mjs +0 -23
  11. package/dist/esm2020/mes-auth.service.mjs +0 -146
  12. package/dist/esm2020/mesauth-angular.mjs +0 -5
  13. package/dist/esm2020/notification-badge.component.mjs +0 -71
  14. package/dist/esm2020/notification-panel.component.mjs +0 -333
  15. package/dist/esm2020/theme.service.mjs +0 -63
  16. package/dist/esm2020/toast-container.component.mjs +0 -83
  17. package/dist/esm2020/toast.service.mjs +0 -41
  18. package/dist/esm2020/user-profile.component.mjs +0 -223
  19. package/dist/fesm2015/mesauth-angular.mjs +0 -1012
  20. package/dist/fesm2015/mesauth-angular.mjs.map +0 -1
  21. package/dist/fesm2020/mesauth-angular.mjs.map +0 -1
  22. package/dist/ma-user.component.d.ts +0 -8
  23. package/dist/mes-auth.interceptor.d.ts +0 -13
  24. package/dist/mes-auth.module.d.ts +0 -6
  25. package/dist/mes-auth.service.d.ts +0 -102
  26. package/dist/notification-badge.component.d.ts +0 -20
  27. package/dist/notification-panel.component.d.ts +0 -36
  28. package/dist/package.json +0 -52
  29. package/dist/theme.service.d.ts +0 -19
  30. package/dist/toast-container.component.d.ts +0 -18
  31. package/dist/toast.service.d.ts +0 -18
  32. package/dist/user-profile.component.d.ts +0 -31
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesauth-angular.mjs","sources":["../../src/mes-auth.service.ts","../../src/mes-auth.interceptor.ts","../../src/mes-auth.module.ts","../../src/theme.service.ts","../../src/user-profile.component.ts","../../src/toast.service.ts","../../src/toast-container.component.ts","../../src/notification-panel.component.ts","../../src/ma-user.component.ts","../../src/notification-badge.component.ts","../../src/mesauth-angular.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { HubConnection, HubConnectionBuilder, LogLevel } from '@microsoft/signalr';\r\nimport { BehaviorSubject, Subject, Observable } from 'rxjs';\r\nimport { tap, filter, debounceTime } from 'rxjs/operators';\r\nimport { Router, NavigationEnd } from '@angular/router';\r\n\r\nexport interface MesAuthConfig { \r\n apiBaseUrl: string;\r\n withCredentials?: boolean;\r\n userBaseUrl?: string;\r\n}\r\n\r\nexport interface IUser {\r\n userId?: string;\r\n userName?: string;\r\n fullName?: string;\r\n gender?: string;\r\n email?: string;\r\n phoneNumber?: string;\r\n department?: string;\r\n position?: string;\r\n tokenVersion?: string;\r\n permEndpoint?: string;\r\n perms?: Set<string>;\r\n employeeCode?: string;\r\n hrFullNameVn?: string;\r\n hrFullNameEn?: string;\r\n hrPosition?: string;\r\n hrJobTitle?: string;\r\n hrGender?: string;\r\n hrMobile?: string;\r\n hrEmail?: string;\r\n hrJoinDate?: string;\r\n hrBirthDate?: string;\r\n hrWorkStatus?: string;\r\n hrDoiTuong?: string;\r\n hrTeamCode?: string;\r\n hrLineCode?: string;\r\n}\r\n\r\nexport enum NotificationType {\r\n Info = 'Info',\r\n Warning = 'Warning',\r\n Error = 'Error',\r\n Success = 'Success'\r\n}\r\n\r\nexport interface NotificationDto {\r\n id: string;\r\n title: string;\r\n message: string;\r\n messageHtml?: string;\r\n url?: string;\r\n type: NotificationType;\r\n isRead: boolean;\r\n createdAt: string;\r\n sourceAppName: string;\r\n sourceAppIconUrl?: string;\r\n}\r\n\r\nexport interface FrontEndRoute {\r\n id: number;\r\n appId: string;\r\n roleId: string;\r\n routePath: string;\r\n routeName: string;\r\n description?: string;\r\n isActive: boolean;\r\n createdAt: string;\r\n updatedAt?: string;\r\n feUrl?: string;\r\n}\r\n\r\nexport interface PagedList<T> {\r\n items: T[];\r\n totalCount: number;\r\n page: number;\r\n pageSize: number;\r\n totalPages: number;\r\n hasNext: boolean;\r\n hasPrevious: boolean;\r\n}\r\n\r\nexport interface RealTimeNotificationDto {\r\n id: string;\r\n title: string;\r\n message: string;\r\n messageHtml?: string;\r\n url?: string;\r\n type: NotificationType;\r\n createdAt: string;\r\n sourceAppName: string;\r\n sourceAppIconUrl?: string;\r\n}\r\n\r\n@Injectable()\r\nexport class MesAuthService {\r\n private hubConnection: HubConnection | null = null;\r\n private _currentUser = new BehaviorSubject<IUser | null>(null);\r\n public currentUser$: Observable<IUser | null> = this._currentUser.asObservable();\r\n private _notifications = new Subject<any>();\r\n public notifications$: Observable<any> = this._notifications.asObservable();\r\n\r\n private apiBase = '';\r\n private config: MesAuthConfig | null = null;\r\n private http!: HttpClient;\r\n private router?: Router;\r\n\r\n constructor() {\r\n // Empty constructor - all dependencies passed to init()\r\n }\r\n\r\n private isProtectedRoute(url: string): boolean {\r\n // Consider routes protected if they don't include auth-related paths\r\n return !url.includes('/login') && !url.includes('/auth') && !url.includes('/signin') && !url.includes('/logout');\r\n }\r\n\r\n init(config: MesAuthConfig, httpClient: HttpClient, router?: Router) {\r\n this.config = config;\r\n this.http = httpClient;\r\n this.router = router;\r\n this.apiBase = config.apiBaseUrl.replace(/\\/$/, '');\r\n\r\n // Listen for route changes - only refresh user data if needed for SPA navigation\r\n // This helps maintain authentication state in single-page applications\r\n if (this.router) {\r\n this.router.events\r\n .pipe(\r\n filter(event => event instanceof NavigationEnd),\r\n debounceTime(1000) // Longer debounce to avoid interfering with login flow\r\n )\r\n .subscribe((event: NavigationEnd) => {\r\n // Only refresh if user is logged in and navigating to protected routes\r\n // Avoid refreshing during login/logout flows\r\n if (this._currentUser.value && this.isProtectedRoute(event.url)) {\r\n // Small delay to ensure any login/logout operations complete\r\n setTimeout(() => {\r\n if (this._currentUser.value) {\r\n this.refreshUser();\r\n }\r\n }, 100);\r\n }\r\n });\r\n }\r\n\r\n this.fetchCurrentUser();\r\n this.fetchInitialNotifications();\r\n }\r\n\r\n getConfig(): MesAuthConfig | null {\r\n return this.config;\r\n }\r\n\r\n private fetchCurrentUser() {\r\n if (!this.apiBase) return;\r\n const url = `${this.apiBase}/auth/me`;\r\n this.http.get(url, { withCredentials: this.config?.withCredentials ?? true }).subscribe({\r\n next: (u) => {\r\n this._currentUser.next(u);\r\n if (u && this.config) {\r\n this.startConnection(this.config);\r\n }\r\n },\r\n error: (err) => {\r\n // Silently handle auth errors (401/403) - user is not logged in\r\n if (err.status === 401 || err.status === 403) {\r\n this._currentUser.next(null);\r\n }\r\n }\r\n });\r\n }\r\n\r\n private fetchInitialNotifications() {\r\n if (!this.apiBase) return;\r\n this.http.get(`${this.apiBase}/notif/me`, { withCredentials: this.config?.withCredentials ?? true }).subscribe({\r\n next: (notifications: any) => {\r\n if (Array.isArray(notifications?.items)) {\r\n notifications.items.forEach((n: any) => this._notifications.next(n));\r\n }\r\n },\r\n error: (err) => {\r\n // Silently handle auth errors (401/403) - user is not logged in\r\n // No need to emit anything\r\n }\r\n });\r\n }\r\n\r\n public getUnreadCount(): Observable<any> {\r\n return this.http.get(`${this.apiBase}/notif/me/unread-count`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public getNotifications(page: number = 1, pageSize: number = 20, includeRead: boolean = false, type?: string): Observable<any> {\r\n let url = `${this.apiBase}/notif/me?page=${page}&pageSize=${pageSize}&includeRead=${includeRead}`;\r\n if (type) {\r\n url += `&type=${type}`;\r\n }\r\n return this.http.get(url, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public markAsRead(notificationId: string): Observable<any> {\r\n return this.http.patch(`${this.apiBase}/notif/${notificationId}/read`, {}, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public markAllAsRead(): Observable<any> {\r\n return this.http.patch(`${this.apiBase}/notif/me/read-all`, {}, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public deleteNotification(notificationId: string): Observable<any> {\r\n return this.http.delete(`${this.apiBase}/notif/${notificationId}`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public getFrontEndRoutes(): Observable<FrontEndRoute[]> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.get<FrontEndRoute[]>(`${this.apiBase}/fe-routes/me`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public registerFrontEndRoutes(routes: any[]): Observable<any> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.post(`${this.apiBase}/fe-routes/register`, routes, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n private startConnection(config: MesAuthConfig) {\r\n if (this.hubConnection) return;\r\n const signalrUrl = config.apiBaseUrl.replace(/\\/$/, '') + '/hub/notification';\r\n const builder = new HubConnectionBuilder()\r\n .withUrl(signalrUrl, { withCredentials: config.withCredentials ?? true })\r\n .withAutomaticReconnect()\r\n .configureLogging(LogLevel.Warning);\r\n\r\n this.hubConnection = builder.build();\r\n\r\n this.hubConnection.on('ReceiveNotification', (n: any) => {\r\n this._notifications.next(n);\r\n });\r\n\r\n this.hubConnection.start().then(() => {}).catch((err) => {});\r\n\r\n this.hubConnection.onclose(() => {});\r\n this.hubConnection.onreconnecting(() => {});\r\n this.hubConnection.onreconnected(() => {});\r\n }\r\n\r\n public stop() {\r\n if (!this.hubConnection) return;\r\n this.hubConnection.stop().catch(() => {});\r\n this.hubConnection = null;\r\n }\r\n\r\n public logout(): Observable<any> {\r\n const url = `${this.apiBase}/auth/logout`;\r\n return this.http.post(url, {}, { withCredentials: this.config?.withCredentials ?? true }).pipe(\r\n tap(() => {\r\n this._currentUser.next(null);\r\n this.stop();\r\n })\r\n );\r\n }\r\n\r\n public refreshUser() {\r\n this.fetchCurrentUser();\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';\r\nimport { Observable, throwError } from 'rxjs';\r\nimport { catchError } from 'rxjs/operators';\r\nimport { Router } from '@angular/router';\r\nimport { MesAuthService } from './mes-auth.service';\r\n\r\n@Injectable()\r\nexport class MesAuthInterceptor implements HttpInterceptor {\r\n constructor(private authService: MesAuthService, private router: Router) {}\r\n\r\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n return next.handle(req).pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n if (error.status === 403) {\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n\r\n // Use router URL for internal navigation (cleaner URLs)\r\n // Falls back to window.location for full URL if needed\r\n const currentUrl = this.router.url || window.location.pathname + window.location.search;\r\n const returnUrl = encodeURIComponent(currentUrl);\r\n\r\n window.location.href = `${baseUrl}/403?returnUrl=${returnUrl}`;\r\n }\r\n return throwError(error);\r\n })\r\n );\r\n }\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\r\nimport { MesAuthService } from './mes-auth.service';\r\nimport { MesAuthInterceptor } from './mes-auth.interceptor';\r\n\r\n@NgModule({\r\n providers: [\r\n MesAuthService,\r\n { provide: HTTP_INTERCEPTORS, useClass: MesAuthInterceptor, multi: true }\r\n ]\r\n})\r\nexport class MesAuthModule {}\r\n","import { Injectable, OnDestroy } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nexport type Theme = 'light' | 'dark';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ThemeService implements OnDestroy {\r\n private _currentTheme = new BehaviorSubject<Theme>('light');\r\n public currentTheme$: Observable<Theme> = this._currentTheme.asObservable();\r\n private observer: MutationObserver | null = null;\r\n\r\n constructor() {\r\n this.detectTheme();\r\n this.startWatching();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stopWatching();\r\n }\r\n\r\n private detectTheme(): void {\r\n const html = document.documentElement;\r\n const isDark = html.classList.contains('dark') ||\r\n html.getAttribute('data-theme') === 'dark' ||\r\n html.getAttribute('theme') === 'dark' ||\r\n html.getAttribute('data-coreui-theme') === 'dark';\r\n\r\n this._currentTheme.next(isDark ? 'dark' : 'light');\r\n }\r\n\r\n private startWatching(): void {\r\n if (typeof MutationObserver === 'undefined') {\r\n // Fallback for older browsers - check periodically\r\n setInterval(() => this.detectTheme(), 1000);\r\n return;\r\n }\r\n\r\n this.observer = new MutationObserver(() => {\r\n this.detectTheme();\r\n });\r\n\r\n this.observer.observe(document.documentElement, {\r\n attributes: true,\r\n attributeFilter: ['class', 'data-theme', 'theme', 'data-coreui-theme']\r\n });\r\n }\r\n\r\n private stopWatching(): void {\r\n if (this.observer) {\r\n this.observer.disconnect();\r\n this.observer = null;\r\n }\r\n }\r\n\r\n get currentTheme(): Theme {\r\n return this._currentTheme.value;\r\n }\r\n\r\n // Method to manually set theme if needed\r\n setTheme(theme: Theme): void {\r\n this._currentTheme.next(theme);\r\n }\r\n\r\n // Re-detect theme from DOM\r\n refreshTheme(): void {\r\n this.detectTheme();\r\n }\r\n}","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding, HostListener } from '@angular/core';\r\nimport { NgIf } from '@angular/common';\r\nimport { Router } from '@angular/router';\r\nimport { MesAuthService, IUser } from './mes-auth.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-user-profile',\r\n standalone: true,\r\n imports: [NgIf],\r\n template: `\r\n <div class=\"user-profile-container\">\r\n <!-- Not logged in -->\r\n <ng-container *ngIf=\"!currentUser\">\r\n <button class=\"login-btn\" (click)=\"onLogin()\">\r\n Login\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Logged in -->\r\n <ng-container *ngIf=\"currentUser\">\r\n <div class=\"user-header\">\r\n <button class=\"notification-btn\" (click)=\"onNotificationClick()\" title=\"Notifications\">\r\n <span class=\"icon\">🔔</span>\r\n <span class=\"badge\" *ngIf=\"unreadCount > 0\">{{ unreadCount }}</span>\r\n </button>\r\n\r\n <div class=\"user-menu-wrapper\">\r\n <button class=\"user-menu-btn\" (click)=\"toggleDropdown()\">\r\n <img \r\n *ngIf=\"currentUser.fullName || currentUser.userName\"\r\n [src]=\"getAvatarUrl(currentUser)\" \r\n [alt]=\"currentUser.fullName || currentUser.userName\"\r\n class=\"avatar\"\r\n />\r\n <span *ngIf=\"!(currentUser.fullName || currentUser.userName)\" class=\"avatar-initial\">\r\n {{ getLastNameInitial(currentUser) }}\r\n </span>\r\n </button>\r\n\r\n <div class=\"mes-dropdown-menu\" *ngIf=\"dropdownOpen\">\r\n <div class=\"mes-dropdown-header\">\r\n {{ currentUser.fullName || currentUser.userName }}\r\n </div>\r\n <button class=\"mes-dropdown-item profile-link\" (click)=\"onViewProfile()\">\r\n View Profile\r\n </button>\r\n <button class=\"mes-dropdown-item logout-item\" (click)=\"onLogout()\">\r\n Logout\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --primary-color: #1976d2;\r\n --primary-hover: #1565c0;\r\n --primary-light: rgba(25, 118, 210, 0.1);\r\n --error-color: #f44336;\r\n --error-light: #ffebee;\r\n --text-primary: #333;\r\n --text-secondary: #666;\r\n --text-muted: #999;\r\n --bg-primary: white;\r\n --bg-secondary: #f5f5f5;\r\n --bg-tertiary: #fafafa;\r\n --bg-hover: #f5f5f5;\r\n --border-color: #e0e0e0;\r\n --border-light: #f0f0f0;\r\n --shadow: rgba(0, 0, 0, 0.15);\r\n --shadow-light: rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n :host(.theme-dark) {\r\n --primary-color: #90caf9;\r\n --primary-hover: #64b5f6;\r\n --primary-light: rgba(144, 202, 249, 0.1);\r\n --error-color: #ef5350;\r\n --error-light: rgba(239, 83, 80, 0.1);\r\n --text-primary: #e0e0e0;\r\n --text-secondary: #b0b0b0;\r\n --text-muted: #888;\r\n --bg-primary: #1e1e1e;\r\n --bg-secondary: #2d2d2d;\r\n --bg-tertiary: #252525;\r\n --bg-hover: #333;\r\n --border-color: #404040;\r\n --border-light: #333;\r\n --shadow: rgba(0, 0, 0, 0.3);\r\n --shadow-light: rgba(0, 0, 0, 0.2);\r\n }\r\n\r\n .user-profile-container {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding: 0 16px;\r\n }\r\n\r\n .login-btn {\r\n padding: 8px 16px;\r\n background-color: var(--primary-color);\r\n color: white;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-weight: 500;\r\n transition: background-color 0.3s;\r\n }\r\n\r\n .login-btn:hover {\r\n background-color: var(--primary-hover);\r\n }\r\n\r\n .user-header {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n\r\n .notification-btn {\r\n position: relative;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n cursor: pointer;\r\n padding: 8px;\r\n transition: opacity 0.2s;\r\n }\r\n\r\n .notification-btn:hover {\r\n opacity: 0.7;\r\n }\r\n\r\n .icon {\r\n display: inline-block;\r\n }\r\n\r\n .badge {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n background-color: var(--error-color);\r\n color: white;\r\n border-radius: 50%;\r\n width: 20px;\r\n height: 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 12px;\r\n font-weight: bold;\r\n }\r\n\r\n .user-menu-wrapper {\r\n position: relative;\r\n }\r\n\r\n .user-menu-btn {\r\n background: none;\r\n border: none;\r\n cursor: pointer;\r\n padding: 4px;\r\n border-radius: 50%;\r\n transition: background-color 0.2s;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n .user-menu-btn:hover {\r\n background-color: var(--primary-light);\r\n }\r\n\r\n .avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n object-fit: cover;\r\n background-color: #e0e0e0;\r\n }\r\n\r\n .avatar-initial {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n background-color: var(--primary-color);\r\n color: white;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-weight: bold;\r\n font-size: 16px;\r\n }\r\n\r\n .mes-dropdown-menu {\r\n position: absolute;\r\n top: calc(100% + 8px);\r\n right: 0;\r\n background: var(--bg-primary);\r\n border: 1px solid var(--border-color);\r\n border-radius: 4px;\r\n box-shadow: 0 2px 8px var(--shadow);\r\n min-width: 200px;\r\n z-index: 1000;\r\n overflow: hidden;\r\n }\r\n\r\n .mes-dropdown-header {\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--border-light);\r\n font-weight: 600;\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n }\r\n\r\n .mes-dropdown-item {\r\n display: block;\r\n width: 100%;\r\n padding: 12px 16px;\r\n border: none;\r\n background: none;\r\n text-align: left;\r\n cursor: pointer;\r\n font-size: 14px;\r\n color: var(--text-primary);\r\n text-decoration: none;\r\n transition: background-color 0.2s;\r\n }\r\n\r\n .mes-dropdown-item:hover {\r\n background-color: var(--bg-hover);\r\n }\r\n\r\n .profile-link {\r\n color: var(--primary-color);\r\n }\r\n\r\n .logout-item {\r\n border-top: 1px solid var(--border-light);\r\n color: var(--error-color);\r\n }\r\n\r\n .logout-item:hover {\r\n background-color: var(--error-light);\r\n }\r\n\r\n .user-info {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n\r\n .user-name {\r\n font-weight: 500;\r\n font-size: 14px;\r\n color: var(--text-primary);\r\n }\r\n\r\n .user-position {\r\n font-size: 12px;\r\n color: var(--text-secondary);\r\n }\r\n\r\n .logout-btn {\r\n background: none;\r\n border: none;\r\n font-size: 20px;\r\n cursor: pointer;\r\n color: var(--text-secondary);\r\n padding: 4px 8px;\r\n transition: color 0.2s;\r\n }\r\n\r\n .logout-btn:hover {\r\n color: var(--primary-color);\r\n }\r\n\r\n @media (max-width: 768px) {\r\n .user-info {\r\n display: none;\r\n }\r\n\r\n .avatar {\r\n width: 32px;\r\n height: 32px;\r\n }\r\n }\r\n `]\r\n})\r\nexport class UserProfileComponent implements OnInit, OnDestroy {\r\n @Output() notificationClick = new EventEmitter<void>();\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n\r\n currentUser: IUser | null = null;\r\n currentTheme: Theme = 'light';\r\n unreadCount = 0;\r\n dropdownOpen = false;\r\n private destroy$ = new Subject<void>();\r\n\r\n constructor(private authService: MesAuthService, private router: Router, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.authService.currentUser$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(user => {\r\n this.currentUser = user;\r\n });\r\n\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n\r\n this.loadUnreadCount();\r\n\r\n // Listen for new notifications\r\n this.authService.notifications$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(() => {\r\n console.log('Notification received, updating unread count');\r\n this.loadUnreadCount();\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n loadUnreadCount() {\r\n this.authService.getUnreadCount().subscribe({\r\n next: (response: any) => {\r\n this.unreadCount = response.unreadCount || 0;\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n getAvatarUrl(user: IUser): string {\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.apiBaseUrl || '';\r\n \r\n // Use userId for the avatar endpoint\r\n const userId = user.userId;\r\n if (userId && baseUrl) {\r\n return `${baseUrl.replace(/\\/$/, '')}/auth/${userId}/avatar`;\r\n }\r\n \r\n // Fallback to UI avatars service if no userId or baseUrl\r\n const displayName = user.userName || user.userId || 'User';\r\n return `https://ui-avatars.com/api/?name=${encodeURIComponent(displayName)}&background=1976d2&color=fff`;\r\n }\r\n\r\n getLastNameInitial(user: IUser): string {\r\n const fullName = user.fullName || user.userName || 'U';\r\n const parts = fullName.split(' ');\r\n const lastPart = parts[parts.length - 1];\r\n return lastPart.charAt(0).toUpperCase();\r\n }\r\n\r\n toggleDropdown() {\r\n this.dropdownOpen = !this.dropdownOpen;\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: Event) {\r\n const target = event.target as HTMLElement;\r\n const clickedInside = target.closest('.user-menu-wrapper');\r\n if (!clickedInside) {\r\n this.dropdownOpen = false;\r\n }\r\n }\r\n\r\n onLogin() {\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n const returnUrl = encodeURIComponent(this.router.url);\r\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\r\n }\r\n\r\n onViewProfile() {\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n window.location.href = `${baseUrl}/profile`;\r\n this.dropdownOpen = false;\r\n }\r\n\r\n onLogout() {\r\n this.authService.logout().subscribe({\r\n next: () => {\r\n // Clear current user after successful logout\r\n this.dropdownOpen = false;\r\n \r\n // Navigate to login with return URL\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n const returnUrl = encodeURIComponent(window.location.href);\r\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\r\n },\r\n error: (err) => {\r\n // Still navigate to login even if logout fails\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n window.location.href = `${baseUrl}/login`;\r\n }\r\n });\r\n }\r\n\r\n onNotificationClick() {\r\n this.notificationClick.emit();\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nexport interface Toast {\r\n id: string;\r\n message: string;\r\n title?: string;\r\n type: 'info' | 'success' | 'warning' | 'error';\r\n duration?: number;\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class ToastService {\r\n private toasts$ = new BehaviorSubject<Toast[]>([]);\r\n public toasts: Observable<Toast[]> = this.toasts$.asObservable();\r\n\r\n show(message: string, title?: string, type: 'info' | 'success' | 'warning' | 'error' = 'info', duration: number = 5000) {\r\n const id = Math.random().toString(36).substr(2, 9);\r\n const toast: Toast = {\r\n id,\r\n message,\r\n title,\r\n type,\r\n duration\r\n };\r\n\r\n const currentToasts = this.toasts$.value;\r\n this.toasts$.next([...currentToasts, toast]);\r\n\r\n if (duration > 0) {\r\n setTimeout(() => {\r\n this.remove(id);\r\n }, duration);\r\n }\r\n\r\n return id;\r\n }\r\n\r\n remove(id: string) {\r\n const currentToasts = this.toasts$.value;\r\n this.toasts$.next(currentToasts.filter(t => t.id !== id));\r\n }\r\n\r\n clear() {\r\n this.toasts$.next([]);\r\n }\r\n}\r\n","import { Component, OnInit, OnDestroy, HostBinding } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ToastService, Toast } from './toast.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-toast-container',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n <div class=\"toast-container\">\r\n <div \r\n *ngFor=\"let toast of toasts\"\r\n class=\"toast\"\r\n [class]=\"'toast-' + toast.type\"\r\n [@slideIn]\r\n >\r\n <div class=\"toast-content\">\r\n <div *ngIf=\"toast.title\" class=\"toast-title\">{{ toast.title }}</div>\r\n <div class=\"toast-message\" [innerHTML]=\"toast.message\"></div>\r\n </div>\r\n <button class=\"toast-close\" (click)=\"close(toast.id)\" aria-label=\"Close\">\r\n ✕\r\n </button>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --info-color: #2196f3;\r\n --success-color: #4caf50;\r\n --warning-color: #ff9800;\r\n --error-color: #f44336;\r\n --text-primary: #333;\r\n --bg-primary: white;\r\n --shadow: rgba(0, 0, 0, 0.15);\r\n --text-secondary: #999;\r\n --border-color: rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n :host(.theme-dark) {\r\n --info-color: #64b5f6;\r\n --success-color: #81c784;\r\n --warning-color: #ffb74d;\r\n --error-color: #ef5350;\r\n --text-primary: #e0e0e0;\r\n --bg-primary: #1e1e1e;\r\n --shadow: rgba(0, 0, 0, 0.3);\r\n --text-secondary: #888;\r\n --border-color: rgba(255, 255, 255, 0.1);\r\n }\r\n\r\n .toast-container {\r\n position: fixed;\r\n top: 20px;\r\n right: 20px;\r\n z-index: 9999;\r\n pointer-events: none;\r\n }\r\n\r\n .toast {\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n margin-bottom: 12px;\r\n border-radius: 4px;\r\n background: var(--bg-primary);\r\n border: 1px solid var(--border-color);\r\n box-shadow: 0 4px 12px var(--shadow);\r\n pointer-events: auto;\r\n min-width: 280px;\r\n max-width: 400px;\r\n animation: slideIn 0.3s ease-out;\r\n }\r\n\r\n .toast-content {\r\n flex: 1;\r\n }\r\n\r\n .toast-title {\r\n font-weight: 600;\r\n font-size: 14px;\r\n margin-bottom: 4px;\r\n }\r\n\r\n .toast-message {\r\n font-size: 13px;\r\n line-height: 1.4;\r\n }\r\n\r\n .toast-close {\r\n background: none;\r\n border: none;\r\n cursor: pointer;\r\n font-size: 18px;\r\n color: var(--text-secondary);\r\n padding: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n transition: color 0.2s;\r\n }\r\n\r\n .toast-close:hover {\r\n color: var(--text-primary);\r\n }\r\n\r\n /* Toast types */\r\n .toast-info {\r\n border-left: 4px solid var(--info-color);\r\n }\r\n\r\n .toast-info .toast-title {\r\n color: var(--info-color);\r\n }\r\n\r\n .toast-info .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n .toast-success {\r\n border-left: 4px solid var(--success-color);\r\n }\r\n\r\n .toast-success .toast-title {\r\n color: var(--success-color);\r\n }\r\n\r\n .toast-success .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n .toast-warning {\r\n border-left: 4px solid var(--warning-color);\r\n }\r\n\r\n .toast-warning .toast-title {\r\n color: var(--warning-color);\r\n }\r\n\r\n .toast-warning .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n .toast-error {\r\n border-left: 4px solid var(--error-color);\r\n }\r\n\r\n .toast-error .toast-title {\r\n color: var(--error-color);\r\n }\r\n\r\n .toast-error .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n @keyframes slideIn {\r\n from {\r\n transform: translateX(400px);\r\n opacity: 0;\r\n }\r\n to {\r\n transform: translateX(0);\r\n opacity: 1;\r\n }\r\n }\r\n\r\n @media (max-width: 600px) {\r\n .toast-container {\r\n top: 10px;\r\n right: 10px;\r\n left: 10px;\r\n }\r\n\r\n .toast {\r\n min-width: auto;\r\n max-width: 100%;\r\n }\r\n }\r\n `]\r\n})\r\nexport class ToastContainerComponent implements OnInit, OnDestroy {\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n\r\n toasts: Toast[] = [];\r\n currentTheme: Theme = 'light';\r\n private destroy$ = new Subject<void>();\r\n\r\n constructor(private toastService: ToastService, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.toastService.toasts\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(toasts => {\r\n this.toasts = toasts;\r\n });\r\n\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n close(id: string) {\r\n this.toastService.remove(id);\r\n }\r\n}\r\n","import { Component, OnInit, OnDestroy, HostBinding, Output, EventEmitter } from '@angular/core';\r\nimport { NgIf, NgFor } from '@angular/common';\r\nimport { MesAuthService, NotificationDto, PagedList, RealTimeNotificationDto } from './mes-auth.service';\r\nimport { ToastService } from './toast.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-notification-panel',\r\n standalone: true,\r\n imports: [NgIf, NgFor],\r\n template: `\r\n <div class=\"notification-panel\" [class.open]=\"isOpen\">\r\n <!-- Header -->\r\n <div class=\"panel-header\">\r\n <h3>Notifications</h3>\r\n <button class=\"close-btn\" (click)=\"close()\" title=\"Close\">✕</button>\r\n </div>\r\n\r\n <!-- Tabs -->\r\n <div class=\"tabs\">\r\n <button \r\n class=\"tab-btn\" \r\n [class.active]=\"activeTab === 'unread'\"\r\n (click)=\"switchTab('unread')\"\r\n >\r\n Unread ({{ unreadNotifications.length }})\r\n </button>\r\n <button \r\n class=\"tab-btn\" \r\n [class.active]=\"activeTab === 'read'\"\r\n (click)=\"switchTab('read')\"\r\n >\r\n Read ({{ readNotifications.length }})\r\n </button>\r\n </div>\r\n\r\n <!-- Notifications List -->\r\n <div class=\"notifications-list\">\r\n <ng-container *ngIf=\"currentNotifications.length > 0\">\r\n <div \r\n *ngFor=\"let notification of currentNotifications\"\r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.isRead\"\r\n (click)=\"markAsRead(notification.id)\"\r\n >\r\n <div class=\"notification-content\">\r\n <div class=\"notification-title\">{{ notification.title }}</div>\r\n <div class=\"notification-message\" [innerHTML]=\"getNotificationMessage(notification)\"></div>\r\n <div class=\"notification-meta\">\r\n <span class=\"app-name\">{{ notification.sourceAppName }}</span>\r\n <span class=\"time\">{{ formatDate(notification.createdAt) }}</span>\r\n </div>\r\n </div>\r\n <button \r\n class=\"read-btn\" \r\n (click)=\"markAsRead(notification.id, $event)\"\r\n title=\"Mark as read\"\r\n *ngIf=\"!notification.isRead\"\r\n >\r\n ✓\r\n </button>\r\n <button \r\n class=\"delete-btn\" \r\n (click)=\"delete(notification.id, $event)\"\r\n title=\"Delete notification\"\r\n *ngIf=\"notification.isRead\"\r\n >\r\n ✓\r\n </button>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"currentNotifications.length === 0\">\r\n <div class=\"empty-state\">\r\n No {{ activeTab }} notifications\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Footer Actions -->\r\n <div class=\"panel-footer\" *ngIf=\"currentNotifications.length > 0\">\r\n <div class=\"footer-actions\" *ngIf=\"activeTab === 'unread'\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadNotifications.length > 0\">\r\n Mark all as read\r\n </button>\r\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllUnread()\" *ngIf=\"unreadNotifications.length > 0\">\r\n Delete all\r\n </button>\r\n </div>\r\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllRead()\" *ngIf=\"activeTab === 'read' && readNotifications.length > 0\">\r\n Delete all\r\n </button>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --primary-color: #1976d2;\r\n --primary-hover: #1565c0;\r\n --success-color: #4caf50;\r\n --error-color: #f44336;\r\n --text-primary: #333;\r\n --text-secondary: #666;\r\n --text-muted: #999;\r\n --bg-primary: white;\r\n --bg-secondary: #f5f5f5;\r\n --bg-tertiary: #fafafa;\r\n --bg-hover: #f5f5f5;\r\n --bg-unread: #e3f2fd;\r\n --border-color: #e0e0e0;\r\n --border-light: #f0f0f0;\r\n --shadow: rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n :host(.theme-dark) {\r\n --primary-color: #90caf9;\r\n --primary-hover: #64b5f6;\r\n --success-color: #81c784;\r\n --error-color: #ef5350;\r\n --text-primary: #e0e0e0;\r\n --text-secondary: #b0b0b0;\r\n --text-muted: #888;\r\n --bg-primary: #1e1e1e;\r\n --bg-secondary: #2d2d2d;\r\n --bg-tertiary: #252525;\r\n --bg-hover: #333;\r\n --bg-unread: rgba(144, 202, 249, 0.1);\r\n --border-color: #404040;\r\n --border-light: #333;\r\n --shadow: rgba(0, 0, 0, 0.3);\r\n }\r\n\r\n .notification-panel {\r\n position: fixed;\r\n top: 0;\r\n right: -350px;\r\n width: 350px;\r\n height: 100vh;\r\n background: var(--bg-primary);\r\n box-shadow: -2px 0 8px var(--shadow);\r\n display: flex;\r\n flex-direction: column;\r\n z-index: 1000;\r\n transition: right 0.3s ease;\r\n }\r\n\r\n .notification-panel.open {\r\n right: 0;\r\n }\r\n\r\n .panel-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 16px;\r\n border-bottom: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n }\r\n\r\n .panel-header h3 {\r\n margin: 0;\r\n font-size: 18px;\r\n color: var(--text-primary);\r\n }\r\n\r\n .close-btn {\r\n background: none;\r\n border: none;\r\n font-size: 20px;\r\n cursor: pointer;\r\n color: var(--text-secondary);\r\n padding: 0;\r\n width: 32px;\r\n height: 32px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: color 0.2s;\r\n }\r\n\r\n .close-btn:hover {\r\n color: var(--text-primary);\r\n }\r\n\r\n .tabs {\r\n display: flex;\r\n border-bottom: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n }\r\n\r\n .tab-btn {\r\n flex: 1;\r\n padding: 12px 16px;\r\n background: none;\r\n border: none;\r\n color: var(--text-secondary);\r\n cursor: pointer;\r\n font-size: 14px;\r\n font-weight: 500;\r\n transition: all 0.2s;\r\n border-bottom: 2px solid transparent;\r\n }\r\n\r\n .tab-btn:hover {\r\n background-color: var(--bg-hover);\r\n color: var(--text-primary);\r\n }\r\n\r\n .tab-btn.active {\r\n color: var(--primary-color);\r\n border-bottom-color: var(--primary-color);\r\n background-color: var(--bg-primary);\r\n }\r\n\r\n .notifications-list {\r\n flex: 1;\r\n overflow-y: auto;\r\n }\r\n\r\n .notification-item {\r\n display: flex;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--border-light);\r\n cursor: pointer;\r\n background-color: var(--bg-tertiary);\r\n transition: background-color 0.2s;\r\n }\r\n\r\n .notification-item:hover {\r\n background-color: var(--bg-hover);\r\n }\r\n\r\n .notification-item.unread {\r\n background-color: var(--bg-unread);\r\n }\r\n\r\n .notification-content {\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .notification-title {\r\n font-weight: 600;\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n margin-bottom: 4px;\r\n }\r\n\r\n .notification-message {\r\n color: var(--text-secondary);\r\n font-size: 13px;\r\n line-height: 1.4;\r\n margin-bottom: 6px;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n }\r\n\r\n .notification-meta {\r\n display: flex;\r\n justify-content: space-between;\r\n font-size: 12px;\r\n color: var(--text-muted);\r\n }\r\n\r\n .app-name {\r\n font-weight: 500;\r\n color: var(--primary-color);\r\n }\r\n\r\n .read-btn {\r\n background: none;\r\n border: none;\r\n color: var(--text-muted);\r\n cursor: pointer;\r\n font-size: 14px;\r\n padding: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n transition: color 0.2s;\r\n }\r\n\r\n .read-btn:hover {\r\n color: var(--success-color);\r\n }\r\n\r\n .delete-btn {\r\n background: none;\r\n border: none;\r\n color: var(--text-muted);\r\n cursor: pointer;\r\n font-size: 14px;\r\n padding: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n transition: color 0.2s;\r\n }\r\n\r\n .delete-btn:hover {\r\n color: var(--error-color);\r\n }\r\n\r\n .empty-state {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n color: var(--text-muted);\r\n font-size: 14px;\r\n }\r\n\r\n .panel-footer {\r\n padding: 12px 16px;\r\n border-top: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n }\r\n\r\n .footer-actions {\r\n display: flex;\r\n gap: 8px;\r\n }\r\n\r\n .footer-actions .action-btn {\r\n flex: 1;\r\n }\r\n\r\n .action-btn {\r\n width: 100%;\r\n padding: 8px;\r\n background-color: var(--primary-color);\r\n color: white;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-weight: 500;\r\n transition: background-color 0.2s;\r\n }\r\n\r\n .action-btn:hover {\r\n background-color: var(--primary-hover);\r\n }\r\n\r\n .delete-all-btn {\r\n background-color: var(--error-color);\r\n color: white;\r\n }\r\n\r\n .delete-all-btn:hover {\r\n background-color: #d32f2f; /* Darker red for hover */\r\n }\r\n\r\n @media (max-width: 600px) {\r\n .notification-panel {\r\n width: 100%;\r\n right: -100%;\r\n }\r\n }\r\n `]\r\n})\r\nexport class NotificationPanelComponent implements OnInit, OnDestroy {\r\n @Output() notificationRead = new EventEmitter<void>();\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n\r\n isOpen = false;\r\n notifications: NotificationDto[] = [];\r\n currentTheme: Theme = 'light';\r\n activeTab: 'unread' | 'read' = 'unread'; // Default to unread tab\r\n private destroy$ = new Subject<void>();\r\n\r\n get unreadNotifications(): NotificationDto[] {\r\n return this.notifications.filter(n => !n.isRead);\r\n }\r\n\r\n get readNotifications(): NotificationDto[] {\r\n return this.notifications.filter(n => n.isRead);\r\n }\r\n\r\n get currentNotifications(): NotificationDto[] {\r\n return this.activeTab === 'unread' ? this.unreadNotifications : this.readNotifications;\r\n }\r\n\r\n getNotificationMessage(notification: NotificationDto): string {\r\n return notification.messageHtml || notification.message || '';\r\n }\r\n\r\n constructor(private authService: MesAuthService, private toastService: ToastService, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n\r\n this.loadNotifications();\r\n\r\n // Listen for new real-time notifications\r\n this.authService.notifications$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe((notification: RealTimeNotificationDto) => {\r\n // Show toast for new notification\r\n this.toastService.show(\r\n notification.messageHtml || notification.message || '',\r\n notification.title,\r\n 'info',\r\n 5000\r\n );\r\n // Reload notifications list\r\n this.loadNotifications();\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n private loadNotifications() {\r\n this.authService.getNotifications(1, 50, true).subscribe({ // includeRead = true to get both read and unread\r\n next: (response: PagedList<NotificationDto>) => {\r\n this.notifications = response.items || [];\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n open() {\r\n this.isOpen = true;\r\n this.activeTab = 'unread'; // Reset to unread tab when opening\r\n }\r\n\r\n close() {\r\n this.isOpen = false;\r\n }\r\n\r\n switchTab(tab: 'unread' | 'read') {\r\n this.activeTab = tab;\r\n }\r\n\r\n markAsRead(notificationId: string, event?: Event) {\r\n if (event) {\r\n event.stopPropagation();\r\n }\r\n this.authService.markAsRead(notificationId).subscribe({\r\n next: () => {\r\n const notification = this.notifications.find(n => n.id === notificationId);\r\n if (notification) {\r\n notification.isRead = true;\r\n this.notificationRead.emit();\r\n }\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n markAllAsRead() {\r\n this.authService.markAllAsRead().subscribe({\r\n next: () => {\r\n this.notifications.forEach(n => n.isRead = true);\r\n this.notificationRead.emit();\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n deleteAllRead() {\r\n const readNotificationIds = this.notifications\r\n .filter(n => n.isRead)\r\n .map(n => n.id);\r\n\r\n // Delete all read notifications\r\n const deletePromises = readNotificationIds.map(id =>\r\n this.authService.deleteNotification(id).toPromise()\r\n );\r\n\r\n Promise.all(deletePromises).then(() => {\r\n // Remove all read notifications from the local array\r\n this.notifications = this.notifications.filter(n => !n.isRead);\r\n }).catch((err) => {\r\n // If bulk delete fails, reload notifications to get current state\r\n this.loadNotifications();\r\n });\r\n }\r\n\r\n deleteAllUnread() {\r\n const unreadNotificationIds = this.notifications\r\n .filter(n => !n.isRead)\r\n .map(n => n.id);\r\n\r\n // Delete all unread notifications\r\n const deletePromises = unreadNotificationIds.map(id =>\r\n this.authService.deleteNotification(id).toPromise()\r\n );\r\n\r\n Promise.all(deletePromises).then(() => {\r\n // Remove all unread notifications from the local array\r\n this.notifications = this.notifications.filter(n => n.isRead);\r\n }).catch((err) => {\r\n // If bulk delete fails, reload notifications to get current state\r\n this.loadNotifications();\r\n });\r\n }\r\n\r\n delete(notificationId: string, event: Event) {\r\n event.stopPropagation();\r\n this.authService.deleteNotification(notificationId).subscribe({\r\n next: () => {\r\n this.notifications = this.notifications.filter(n => n.id !== notificationId);\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n formatDate(dateString: string): string {\r\n const date = new Date(dateString);\r\n const now = new Date();\r\n const diffMs = now.getTime() - date.getTime();\r\n const diffMins = Math.floor(diffMs / 60000);\r\n const diffHours = Math.floor(diffMs / 3600000);\r\n const diffDays = Math.floor(diffMs / 86400000);\r\n\r\n if (diffMins < 1) return 'Now';\r\n if (diffMins < 60) return `${diffMins}m ago`;\r\n if (diffHours < 24) return `${diffHours}h ago`;\r\n if (diffDays < 7) return `${diffDays}d ago`;\r\n \r\n return date.toLocaleDateString();\r\n }\r\n}\r\n","import { Component, ViewChild, AfterViewInit } from '@angular/core';\r\nimport { ToastContainerComponent } from './toast-container.component';\r\nimport { UserProfileComponent } from './user-profile.component';\r\nimport { NotificationPanelComponent } from './notification-panel.component';\r\n\r\n@Component({\r\n selector: 'ma-user',\r\n standalone: true,\r\n imports: [ToastContainerComponent, UserProfileComponent, NotificationPanelComponent],\r\n template: `\r\n <ma-toast-container></ma-toast-container>\r\n <div class=\"user-header\">\r\n <ma-user-profile (notificationClick)=\"notificationPanel.open()\"></ma-user-profile>\r\n </div>\r\n <ma-notification-panel #notificationPanel (notificationRead)=\"onNotificationRead()\"></ma-notification-panel>\r\n `,\r\n styles: [`\r\n .user-header {\r\n display: flex;\r\n justify-content: flex-end;\r\n }\r\n `]\r\n})\r\nexport class MaUserComponent implements AfterViewInit {\r\n @ViewChild(UserProfileComponent) userProfile?: UserProfileComponent;\r\n\r\n ngAfterViewInit() {\r\n // Ensure proper initialization\r\n if (this.userProfile) {\r\n this.userProfile.loadUnreadCount();\r\n }\r\n }\r\n\r\n onNotificationRead() {\r\n if (this.userProfile) {\r\n this.userProfile.loadUnreadCount();\r\n }\r\n }\r\n}\r\n","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding } from '@angular/core';\r\nimport { NgIf } from '@angular/common';\r\nimport { MesAuthService } from './mes-auth.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-notification-badge',\r\n standalone: true,\r\n imports: [NgIf],\r\n template: `\r\n <button class=\"notification-btn\" (click)=\"onNotificationClick()\" title=\"Notifications\">\r\n <span class=\"icon\">🔔</span>\r\n <span class=\"badge\" *ngIf=\"unreadCount > 0\">{{ unreadCount }}</span>\r\n </button>\r\n `,\r\n styles: [`\r\n :host {\r\n --error-color: #f44336;\r\n }\r\n\r\n :host(.theme-dark) {\r\n --error-color: #ef5350;\r\n }\r\n\r\n .notification-btn {\r\n position: relative;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n cursor: pointer;\r\n padding: 8px;\r\n transition: opacity 0.2s;\r\n }\r\n\r\n .notification-btn:hover {\r\n opacity: 0.7;\r\n }\r\n\r\n .icon {\r\n display: inline-block;\r\n }\r\n\r\n .badge {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n background-color: var(--error-color);\r\n color: white;\r\n border-radius: 50%;\r\n width: 20px;\r\n height: 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 12px;\r\n font-weight: bold;\r\n }\r\n `]\r\n})\r\nexport class NotificationBadgeComponent implements OnInit, OnDestroy {\r\n @Output() notificationClick = new EventEmitter<void>();\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n \r\n unreadCount = 0;\r\n currentTheme: Theme = 'light';\r\n private destroy$ = new Subject<void>();\r\n\r\n constructor(private authService: MesAuthService, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n\r\n this.loadUnreadCount();\r\n \r\n // Listen for new notifications\r\n this.authService.notifications$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(() => {\r\n this.loadUnreadCount();\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n private loadUnreadCount() {\r\n this.authService.getUnreadCount().subscribe({\r\n next: (response: any) => {\r\n this.unreadCount = response.unreadCount || 0;\r\n },\r\n error: (err) => console.error('Error loading unread count:', err)\r\n });\r\n }\r\n\r\n onNotificationClick() {\r\n this.notificationClick.emit();\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.MesAuthService","i3.ThemeService","i1.ToastService","i2.ThemeService","i2.ToastService"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,269 @@
1
- export * from './mes-auth.service';
2
- export * from './mes-auth.interceptor';
3
- export * from './mes-auth.module';
4
- export * from './user-profile.component';
5
- export * from './ma-user.component';
6
- export * from './notification-badge.component';
7
- export * from './notification-panel.component';
8
- export * from './toast-container.component';
9
- export * from './theme.service';
1
+ import { HttpClient, HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
2
+ import { Observable } from 'rxjs';
3
+ import { Router } from '@angular/router';
4
+ import * as i0 from '@angular/core';
5
+ import { OnDestroy, OnInit, EventEmitter, AfterViewInit } from '@angular/core';
6
+
7
+ interface MesAuthConfig {
8
+ apiBaseUrl: string;
9
+ withCredentials?: boolean;
10
+ userBaseUrl?: string;
11
+ }
12
+ interface IUser {
13
+ userId?: string;
14
+ userName?: string;
15
+ fullName?: string;
16
+ gender?: string;
17
+ email?: string;
18
+ phoneNumber?: string;
19
+ department?: string;
20
+ position?: string;
21
+ tokenVersion?: string;
22
+ permEndpoint?: string;
23
+ perms?: Set<string>;
24
+ employeeCode?: string;
25
+ hrFullNameVn?: string;
26
+ hrFullNameEn?: string;
27
+ hrPosition?: string;
28
+ hrJobTitle?: string;
29
+ hrGender?: string;
30
+ hrMobile?: string;
31
+ hrEmail?: string;
32
+ hrJoinDate?: string;
33
+ hrBirthDate?: string;
34
+ hrWorkStatus?: string;
35
+ hrDoiTuong?: string;
36
+ hrTeamCode?: string;
37
+ hrLineCode?: string;
38
+ }
39
+ declare enum NotificationType {
40
+ Info = "Info",
41
+ Warning = "Warning",
42
+ Error = "Error",
43
+ Success = "Success"
44
+ }
45
+ interface NotificationDto {
46
+ id: string;
47
+ title: string;
48
+ message: string;
49
+ messageHtml?: string;
50
+ url?: string;
51
+ type: NotificationType;
52
+ isRead: boolean;
53
+ createdAt: string;
54
+ sourceAppName: string;
55
+ sourceAppIconUrl?: string;
56
+ }
57
+ interface FrontEndRoute {
58
+ id: number;
59
+ appId: string;
60
+ roleId: string;
61
+ routePath: string;
62
+ routeName: string;
63
+ description?: string;
64
+ isActive: boolean;
65
+ createdAt: string;
66
+ updatedAt?: string;
67
+ feUrl?: string;
68
+ }
69
+ interface PagedList<T> {
70
+ items: T[];
71
+ totalCount: number;
72
+ page: number;
73
+ pageSize: number;
74
+ totalPages: number;
75
+ hasNext: boolean;
76
+ hasPrevious: boolean;
77
+ }
78
+ interface RealTimeNotificationDto {
79
+ id: string;
80
+ title: string;
81
+ message: string;
82
+ messageHtml?: string;
83
+ url?: string;
84
+ type: NotificationType;
85
+ createdAt: string;
86
+ sourceAppName: string;
87
+ sourceAppIconUrl?: string;
88
+ }
89
+ declare class MesAuthService {
90
+ private hubConnection;
91
+ private _currentUser;
92
+ currentUser$: Observable<IUser | null>;
93
+ private _notifications;
94
+ notifications$: Observable<any>;
95
+ private apiBase;
96
+ private config;
97
+ private http;
98
+ private router?;
99
+ constructor();
100
+ private isProtectedRoute;
101
+ init(config: MesAuthConfig, httpClient: HttpClient, router?: Router): void;
102
+ getConfig(): MesAuthConfig | null;
103
+ private fetchCurrentUser;
104
+ private fetchInitialNotifications;
105
+ getUnreadCount(): Observable<any>;
106
+ getNotifications(page?: number, pageSize?: number, includeRead?: boolean, type?: string): Observable<any>;
107
+ markAsRead(notificationId: string): Observable<any>;
108
+ markAllAsRead(): Observable<any>;
109
+ deleteNotification(notificationId: string): Observable<any>;
110
+ getFrontEndRoutes(): Observable<FrontEndRoute[]>;
111
+ registerFrontEndRoutes(routes: any[]): Observable<any>;
112
+ private startConnection;
113
+ stop(): void;
114
+ logout(): Observable<any>;
115
+ refreshUser(): void;
116
+ static ɵfac: i0.ɵɵFactoryDeclaration<MesAuthService, never>;
117
+ static ɵprov: i0.ɵɵInjectableDeclaration<MesAuthService>;
118
+ }
119
+
120
+ declare class MesAuthInterceptor implements HttpInterceptor {
121
+ private authService;
122
+ private router;
123
+ constructor(authService: MesAuthService, router: Router);
124
+ intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
125
+ static ɵfac: i0.ɵɵFactoryDeclaration<MesAuthInterceptor, never>;
126
+ static ɵprov: i0.ɵɵInjectableDeclaration<MesAuthInterceptor>;
127
+ }
128
+
129
+ declare class MesAuthModule {
130
+ static ɵfac: i0.ɵɵFactoryDeclaration<MesAuthModule, never>;
131
+ static ɵmod: i0.ɵɵNgModuleDeclaration<MesAuthModule, never, never, never>;
132
+ static ɵinj: i0.ɵɵInjectorDeclaration<MesAuthModule>;
133
+ }
134
+
135
+ type Theme = 'light' | 'dark';
136
+ declare class ThemeService implements OnDestroy {
137
+ private _currentTheme;
138
+ currentTheme$: Observable<Theme>;
139
+ private observer;
140
+ constructor();
141
+ ngOnDestroy(): void;
142
+ private detectTheme;
143
+ private startWatching;
144
+ private stopWatching;
145
+ get currentTheme(): Theme;
146
+ setTheme(theme: Theme): void;
147
+ refreshTheme(): void;
148
+ static ɵfac: i0.ɵɵFactoryDeclaration<ThemeService, never>;
149
+ static ɵprov: i0.ɵɵInjectableDeclaration<ThemeService>;
150
+ }
151
+
152
+ declare class UserProfileComponent implements OnInit, OnDestroy {
153
+ private authService;
154
+ private router;
155
+ private themeService;
156
+ notificationClick: EventEmitter<void>;
157
+ get themeClass(): string;
158
+ currentUser: IUser | null;
159
+ currentTheme: Theme;
160
+ unreadCount: number;
161
+ dropdownOpen: boolean;
162
+ private destroy$;
163
+ constructor(authService: MesAuthService, router: Router, themeService: ThemeService);
164
+ ngOnInit(): void;
165
+ ngOnDestroy(): void;
166
+ loadUnreadCount(): void;
167
+ getAvatarUrl(user: IUser): string;
168
+ getLastNameInitial(user: IUser): string;
169
+ toggleDropdown(): void;
170
+ onDocumentClick(event: Event): void;
171
+ onLogin(): void;
172
+ onViewProfile(): void;
173
+ onLogout(): void;
174
+ onNotificationClick(): void;
175
+ static ɵfac: i0.ɵɵFactoryDeclaration<UserProfileComponent, never>;
176
+ static ɵcmp: i0.ɵɵComponentDeclaration<UserProfileComponent, "ma-user-profile", never, {}, { "notificationClick": "notificationClick"; }, never, never, true, never>;
177
+ }
178
+
179
+ declare class MaUserComponent implements AfterViewInit {
180
+ userProfile?: UserProfileComponent;
181
+ ngAfterViewInit(): void;
182
+ onNotificationRead(): void;
183
+ static ɵfac: i0.ɵɵFactoryDeclaration<MaUserComponent, never>;
184
+ static ɵcmp: i0.ɵɵComponentDeclaration<MaUserComponent, "ma-user", never, {}, {}, never, never, true, never>;
185
+ }
186
+
187
+ declare class NotificationBadgeComponent implements OnInit, OnDestroy {
188
+ private authService;
189
+ private themeService;
190
+ notificationClick: EventEmitter<void>;
191
+ get themeClass(): string;
192
+ unreadCount: number;
193
+ currentTheme: Theme;
194
+ private destroy$;
195
+ constructor(authService: MesAuthService, themeService: ThemeService);
196
+ ngOnInit(): void;
197
+ ngOnDestroy(): void;
198
+ private loadUnreadCount;
199
+ onNotificationClick(): void;
200
+ static ɵfac: i0.ɵɵFactoryDeclaration<NotificationBadgeComponent, never>;
201
+ static ɵcmp: i0.ɵɵComponentDeclaration<NotificationBadgeComponent, "ma-notification-badge", never, {}, { "notificationClick": "notificationClick"; }, never, never, true, never>;
202
+ }
203
+
204
+ interface Toast {
205
+ id: string;
206
+ message: string;
207
+ title?: string;
208
+ type: 'info' | 'success' | 'warning' | 'error';
209
+ duration?: number;
210
+ }
211
+ declare class ToastService {
212
+ private toasts$;
213
+ toasts: Observable<Toast[]>;
214
+ show(message: string, title?: string, type?: 'info' | 'success' | 'warning' | 'error', duration?: number): string;
215
+ remove(id: string): void;
216
+ clear(): void;
217
+ static ɵfac: i0.ɵɵFactoryDeclaration<ToastService, never>;
218
+ static ɵprov: i0.ɵɵInjectableDeclaration<ToastService>;
219
+ }
220
+
221
+ declare class NotificationPanelComponent implements OnInit, OnDestroy {
222
+ private authService;
223
+ private toastService;
224
+ private themeService;
225
+ notificationRead: EventEmitter<void>;
226
+ get themeClass(): string;
227
+ isOpen: boolean;
228
+ notifications: NotificationDto[];
229
+ currentTheme: Theme;
230
+ activeTab: 'unread' | 'read';
231
+ private destroy$;
232
+ get unreadNotifications(): NotificationDto[];
233
+ get readNotifications(): NotificationDto[];
234
+ get currentNotifications(): NotificationDto[];
235
+ getNotificationMessage(notification: NotificationDto): string;
236
+ constructor(authService: MesAuthService, toastService: ToastService, themeService: ThemeService);
237
+ ngOnInit(): void;
238
+ ngOnDestroy(): void;
239
+ private loadNotifications;
240
+ open(): void;
241
+ close(): void;
242
+ switchTab(tab: 'unread' | 'read'): void;
243
+ markAsRead(notificationId: string, event?: Event): void;
244
+ markAllAsRead(): void;
245
+ deleteAllRead(): void;
246
+ deleteAllUnread(): void;
247
+ delete(notificationId: string, event: Event): void;
248
+ formatDate(dateString: string): string;
249
+ static ɵfac: i0.ɵɵFactoryDeclaration<NotificationPanelComponent, never>;
250
+ static ɵcmp: i0.ɵɵComponentDeclaration<NotificationPanelComponent, "ma-notification-panel", never, {}, { "notificationRead": "notificationRead"; }, never, never, true, never>;
251
+ }
252
+
253
+ declare class ToastContainerComponent implements OnInit, OnDestroy {
254
+ private toastService;
255
+ private themeService;
256
+ get themeClass(): string;
257
+ toasts: Toast[];
258
+ currentTheme: Theme;
259
+ private destroy$;
260
+ constructor(toastService: ToastService, themeService: ThemeService);
261
+ ngOnInit(): void;
262
+ ngOnDestroy(): void;
263
+ close(id: string): void;
264
+ static ɵfac: i0.ɵɵFactoryDeclaration<ToastContainerComponent, never>;
265
+ static ɵcmp: i0.ɵɵComponentDeclaration<ToastContainerComponent, "ma-toast-container", never, {}, {}, never, never, true, never>;
266
+ }
267
+
268
+ export { MaUserComponent, MesAuthInterceptor, MesAuthModule, MesAuthService, NotificationBadgeComponent, NotificationPanelComponent, NotificationType, ThemeService, ToastContainerComponent, ToastService, UserProfileComponent };
269
+ export type { FrontEndRoute, IUser, MesAuthConfig, NotificationDto, PagedList, RealTimeNotificationDto, Theme, Toast };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "mesauth-angular",
3
- "version": "0.2.14",
3
+ "version": "0.2.20",
4
4
  "description": "Angular helper library to connect to a backend API and SignalR hub to surface the current logged-in user and incoming notifications with dark/light theme support",
5
- "main": "dist/fesm2015/mesauth-angular.mjs",
5
+ "main": "dist/fesm2022/mesauth-angular.mjs",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": ["dist"],
8
8
  "scripts": {
@@ -12,9 +12,9 @@
12
12
  "keywords": ["angular","signalr","notifications","auth","mes"],
13
13
  "license": "MIT",
14
14
  "peerDependencies": {
15
- "@angular/core": "^14.0.0",
16
- "@angular/common": "^14.0.0",
17
- "@angular/router": "^14.0.0",
15
+ "@angular/core": "^20.0.0",
16
+ "@angular/common": "^20.0.0",
17
+ "@angular/router": "^20.0.0",
18
18
  "rxjs": "^7"
19
19
  },
20
20
  "dependencies": {
@@ -22,14 +22,14 @@
22
22
  "rxjs": "^7.5.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@angular/compiler-cli": "^14.0.0",
26
- "@angular/compiler": "^14.0.0",
27
- "@angular/core": "^14.0.0",
28
- "@angular/common": "^14.0.0",
29
- "@angular/router": "^14.0.0",
30
- "typescript": "~4.7.0",
25
+ "@angular/compiler-cli": "^20.0.0",
26
+ "@angular/compiler": "^20.0.0",
27
+ "@angular/core": "^20.0.0",
28
+ "@angular/common": "^20.0.0",
29
+ "@angular/router": "^20.0.0",
30
+ "typescript": "~5.8.0",
31
31
  "tslib": "^2.0.0",
32
- "ng-packagr": "^14.0.0"
32
+ "ng-packagr": "^20.0.0"
33
33
  },
34
34
  "angularCompilerOptions": {
35
35
  "enableIvy": true
@@ -1,10 +0,0 @@
1
- export * from './mes-auth.service';
2
- export * from './mes-auth.interceptor';
3
- export * from './mes-auth.module';
4
- export * from './user-profile.component';
5
- export * from './ma-user.component';
6
- export * from './notification-badge.component';
7
- export * from './notification-panel.component';
8
- export * from './toast-container.component';
9
- export * from './theme.service';
10
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsZ0NBQWdDLENBQUM7QUFDL0MsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLDZCQUE2QixDQUFDO0FBQzVDLGNBQWMsaUJBQWlCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL21lcy1hdXRoLnNlcnZpY2UnO1xyXG5leHBvcnQgKiBmcm9tICcuL21lcy1hdXRoLmludGVyY2VwdG9yJztcclxuZXhwb3J0ICogZnJvbSAnLi9tZXMtYXV0aC5tb2R1bGUnO1xyXG5leHBvcnQgKiBmcm9tICcuL3VzZXItcHJvZmlsZS5jb21wb25lbnQnO1xyXG5leHBvcnQgKiBmcm9tICcuL21hLXVzZXIuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9ub3RpZmljYXRpb24tYmFkZ2UuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9ub3RpZmljYXRpb24tcGFuZWwuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi90b2FzdC1jb250YWluZXIuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi90aGVtZS5zZXJ2aWNlJzsiXX0=
@@ -1,32 +0,0 @@
1
- import { Component, ViewChild } from '@angular/core';
2
- import { ToastContainerComponent } from './toast-container.component';
3
- import { UserProfileComponent } from './user-profile.component';
4
- import { NotificationPanelComponent } from './notification-panel.component';
5
- import * as i0 from "@angular/core";
6
- export class MaUserComponent {
7
- onNotificationRead() {
8
- this.userProfile.loadUnreadCount();
9
- }
10
- }
11
- MaUserComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MaUserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12
- MaUserComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MaUserComponent, isStandalone: true, selector: "ma-user", viewQueries: [{ propertyName: "userProfile", first: true, predicate: UserProfileComponent, descendants: true }], ngImport: i0, template: `
13
- <ma-toast-container></ma-toast-container>
14
- <div class="user-header">
15
- <ma-user-profile (notificationClick)="notificationPanel.open()"></ma-user-profile>
16
- </div>
17
- <ma-notification-panel #notificationPanel (notificationRead)="onNotificationRead()"></ma-notification-panel>
18
- `, 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", outputs: ["notificationRead"] }] });
19
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MaUserComponent, decorators: [{
20
- type: Component,
21
- args: [{ selector: 'ma-user', standalone: true, imports: [ToastContainerComponent, UserProfileComponent, NotificationPanelComponent], template: `
22
- <ma-toast-container></ma-toast-container>
23
- <div class="user-header">
24
- <ma-user-profile (notificationClick)="notificationPanel.open()"></ma-user-profile>
25
- </div>
26
- <ma-notification-panel #notificationPanel (notificationRead)="onNotificationRead()"></ma-notification-panel>
27
- `, styles: [".user-header{display:flex;justify-content:flex-end}\n"] }]
28
- }], propDecorators: { userProfile: [{
29
- type: ViewChild,
30
- args: [UserProfileComponent]
31
- }] } });
32
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWEtdXNlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWEtdXNlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7O0FBb0I1RSxNQUFNLE9BQU8sZUFBZTtJQUcxQixrQkFBa0I7UUFDaEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUNyQyxDQUFDOzs0R0FMVSxlQUFlO2dHQUFmLGVBQWUsZ0hBQ2Ysb0JBQW9CLGdEQWZyQjs7Ozs7O0dBTVQsK0hBUFMsdUJBQXVCLCtEQUFFLG9CQUFvQiw0RkFBRSwwQkFBMEI7MkZBZXhFLGVBQWU7a0JBbEIzQixTQUFTOytCQUNFLFNBQVMsY0FDUCxJQUFJLFdBQ1AsQ0FBQyx1QkFBdUIsRUFBRSxvQkFBb0IsRUFBRSwwQkFBMEIsQ0FBQyxZQUMxRTs7Ozs7O0dBTVQ7OEJBU2dDLFdBQVc7c0JBQTNDLFNBQVM7dUJBQUMsb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgVG9hc3RDb250YWluZXJDb21wb25lbnQgfSBmcm9tICcuL3RvYXN0LWNvbnRhaW5lci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBVc2VyUHJvZmlsZUNvbXBvbmVudCB9IGZyb20gJy4vdXNlci1wcm9maWxlLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IE5vdGlmaWNhdGlvblBhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9ub3RpZmljYXRpb24tcGFuZWwuY29tcG9uZW50JztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbWEtdXNlcicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbVG9hc3RDb250YWluZXJDb21wb25lbnQsIFVzZXJQcm9maWxlQ29tcG9uZW50LCBOb3RpZmljYXRpb25QYW5lbENvbXBvbmVudF0sXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxtYS10b2FzdC1jb250YWluZXI+PC9tYS10b2FzdC1jb250YWluZXI+XHJcbiAgICA8ZGl2IGNsYXNzPVwidXNlci1oZWFkZXJcIj5cclxuICAgICAgPG1hLXVzZXItcHJvZmlsZSAobm90aWZpY2F0aW9uQ2xpY2spPVwibm90aWZpY2F0aW9uUGFuZWwub3BlbigpXCI+PC9tYS11c2VyLXByb2ZpbGU+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxtYS1ub3RpZmljYXRpb24tcGFuZWwgI25vdGlmaWNhdGlvblBhbmVsIChub3RpZmljYXRpb25SZWFkKT1cIm9uTm90aWZpY2F0aW9uUmVhZCgpXCI+PC9tYS1ub3RpZmljYXRpb24tcGFuZWw+XHJcbiAgYCxcclxuICBzdHlsZXM6IFtgXHJcbiAgICAudXNlci1oZWFkZXIge1xyXG4gICAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xyXG4gICAgfVxyXG4gIGBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYVVzZXJDb21wb25lbnQge1xyXG4gIEBWaWV3Q2hpbGQoVXNlclByb2ZpbGVDb21wb25lbnQpIHVzZXJQcm9maWxlITogVXNlclByb2ZpbGVDb21wb25lbnQ7XHJcblxyXG4gIG9uTm90aWZpY2F0aW9uUmVhZCgpIHtcclxuICAgIHRoaXMudXNlclByb2ZpbGUubG9hZFVucmVhZENvdW50KCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
@@ -1,29 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { throwError } from 'rxjs';
3
- import { catchError } from 'rxjs/operators';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "./mes-auth.service";
6
- import * as i2 from "@angular/router";
7
- export class MesAuthInterceptor {
8
- constructor(authService, router) {
9
- this.authService = authService;
10
- this.router = router;
11
- }
12
- intercept(req, next) {
13
- return next.handle(req).pipe(catchError((error) => {
14
- if (error.status === 403) {
15
- const config = this.authService.getConfig();
16
- const baseUrl = config?.userBaseUrl || '';
17
- const returnUrl = encodeURIComponent(window.location.href);
18
- window.location.href = `${baseUrl}/403?returnUrl=${returnUrl}`;
19
- }
20
- return throwError(error);
21
- }));
22
- }
23
- }
24
- MesAuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthInterceptor, deps: [{ token: i1.MesAuthService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Injectable });
25
- MesAuthInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthInterceptor });
26
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthInterceptor, decorators: [{
27
- type: Injectable
28
- }], ctorParameters: function () { return [{ type: i1.MesAuthService }, { type: i2.Router }]; } });
29
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzLWF1dGguaW50ZXJjZXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWVzLWF1dGguaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQWMsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQUs1QyxNQUFNLE9BQU8sa0JBQWtCO0lBQzdCLFlBQW9CLFdBQTJCLEVBQVUsTUFBYztRQUFuRCxnQkFBVyxHQUFYLFdBQVcsQ0FBZ0I7UUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQUcsQ0FBQztJQUUzRSxTQUFTLENBQUMsR0FBcUIsRUFBRSxJQUFpQjtRQUNoRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUMxQixVQUFVLENBQUMsQ0FBQyxLQUF3QixFQUFFLEVBQUU7WUFDdEMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRTtnQkFDeEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDNUMsTUFBTSxPQUFPLEdBQUcsTUFBTSxFQUFFLFdBQVcsSUFBSSxFQUFFLENBQUM7Z0JBQzFDLE1BQU0sU0FBUyxHQUFHLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzNELE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLEdBQUcsT0FBTyxrQkFBa0IsU0FBUyxFQUFFLENBQUM7YUFDaEU7WUFDRCxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQzs7K0dBZlUsa0JBQWtCO21IQUFsQixrQkFBa0I7MkZBQWxCLGtCQUFrQjtrQkFEOUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgSHR0cEludGVyY2VwdG9yLCBIdHRwUmVxdWVzdCwgSHR0cEhhbmRsZXIsIEh0dHBFdmVudCwgSHR0cEVycm9yUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIHRocm93RXJyb3IgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgY2F0Y2hFcnJvciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHsgTWVzQXV0aFNlcnZpY2UgfSBmcm9tICcuL21lcy1hdXRoLnNlcnZpY2UnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgTWVzQXV0aEludGVyY2VwdG9yIGltcGxlbWVudHMgSHR0cEludGVyY2VwdG9yIHtcclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGF1dGhTZXJ2aWNlOiBNZXNBdXRoU2VydmljZSwgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcikge31cclxuXHJcbiAgaW50ZXJjZXB0KHJlcTogSHR0cFJlcXVlc3Q8YW55PiwgbmV4dDogSHR0cEhhbmRsZXIpOiBPYnNlcnZhYmxlPEh0dHBFdmVudDxhbnk+PiB7XHJcbiAgICByZXR1cm4gbmV4dC5oYW5kbGUocmVxKS5waXBlKFxyXG4gICAgICBjYXRjaEVycm9yKChlcnJvcjogSHR0cEVycm9yUmVzcG9uc2UpID0+IHtcclxuICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzID09PSA0MDMpIHtcclxuICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuYXV0aFNlcnZpY2UuZ2V0Q29uZmlnKCk7XHJcbiAgICAgICAgICBjb25zdCBiYXNlVXJsID0gY29uZmlnPy51c2VyQmFzZVVybCB8fCAnJztcclxuICAgICAgICAgIGNvbnN0IHJldHVyblVybCA9IGVuY29kZVVSSUNvbXBvbmVudCh3aW5kb3cubG9jYXRpb24uaHJlZik7XHJcbiAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IGAke2Jhc2VVcmx9LzQwMz9yZXR1cm5Vcmw9JHtyZXR1cm5Vcmx9YDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoZXJyb3IpO1xyXG4gICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcbn1cclxuIl19
@@ -1,23 +0,0 @@
1
- import { NgModule } from '@angular/core';
2
- import { HTTP_INTERCEPTORS } from '@angular/common/http';
3
- import { MesAuthService } from './mes-auth.service';
4
- import { MesAuthInterceptor } from './mes-auth.interceptor';
5
- import * as i0 from "@angular/core";
6
- export class MesAuthModule {
7
- }
8
- MesAuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
9
- MesAuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: MesAuthModule });
10
- MesAuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthModule, providers: [
11
- MesAuthService,
12
- { provide: HTTP_INTERCEPTORS, useClass: MesAuthInterceptor, multi: true }
13
- ] });
14
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MesAuthModule, decorators: [{
15
- type: NgModule,
16
- args: [{
17
- providers: [
18
- MesAuthService,
19
- { provide: HTTP_INTERCEPTORS, useClass: MesAuthInterceptor, multi: true }
20
- ]
21
- }]
22
- }] });
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzLWF1dGgubW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21lcy1hdXRoLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7QUFRNUQsTUFBTSxPQUFPLGFBQWE7OzBHQUFiLGFBQWE7MkdBQWIsYUFBYTsyR0FBYixhQUFhLGFBTGI7UUFDVCxjQUFjO1FBQ2QsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLGtCQUFrQixFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUU7S0FDMUU7MkZBRVUsYUFBYTtrQkFOekIsUUFBUTttQkFBQztvQkFDUixTQUFTLEVBQUU7d0JBQ1QsY0FBYzt3QkFDZCxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTtxQkFDMUU7aUJBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBIVFRQX0lOVEVSQ0VQVE9SUyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgTWVzQXV0aFNlcnZpY2UgfSBmcm9tICcuL21lcy1hdXRoLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBNZXNBdXRoSW50ZXJjZXB0b3IgfSBmcm9tICcuL21lcy1hdXRoLmludGVyY2VwdG9yJztcclxuXHJcbkBOZ01vZHVsZSh7XHJcbiAgcHJvdmlkZXJzOiBbXHJcbiAgICBNZXNBdXRoU2VydmljZSxcclxuICAgIHsgcHJvdmlkZTogSFRUUF9JTlRFUkNFUFRPUlMsIHVzZUNsYXNzOiBNZXNBdXRoSW50ZXJjZXB0b3IsIG11bHRpOiB0cnVlIH1cclxuICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNZXNBdXRoTW9kdWxlIHt9XHJcbiJdfQ==