mesauth-angular 1.7.1 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/mesauth-angular.mjs +230 -1265
- package/fesm2022/mesauth-angular.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mesauth-angular.d.ts +113 -5
|
@@ -1 +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/approval.service.ts","../../src/approval.models.ts","../../src/ma-approval-panel.component.ts","../../src/ma-user.component.ts","../../src/notification-badge.component.ts","../../src/ma-arv-container.component.ts","../../src/x-ma-perm.pipe.ts","../../src/x-ma-resource.ts","../../src/mesauth-angular.ts"],"sourcesContent":["import { inject, Injectable, InjectionToken, EnvironmentProviders, makeEnvironmentProviders, provideAppInitializer, NgZone } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { HubConnection, HubConnectionBuilder, LogLevel } from '@microsoft/signalr';\nimport { BehaviorSubject, Subject, Observable, of, EMPTY } from 'rxjs';\nimport { tap, catchError } from 'rxjs/operators';\nimport { Router } from '@angular/router';\n\nexport interface MesAuthConfig {\n apiBaseUrl: string;\n withCredentials?: boolean;\n userBaseUrl?: string;\n}\n\n/** Injection token for MesAuth configuration */\nexport const MES_AUTH_CONFIG = new InjectionToken<MesAuthConfig>('MES_AUTH_CONFIG');\n\n/**\n * Provides MesAuth with configuration.\n * This is the recommended way to set up mesauth-angular in standalone apps.\n *\n * @example\n * ```typescript\n * // app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([mesAuthInterceptor])),\n * provideMesAuth({\n * apiBaseUrl: 'https://auth.example.com',\n * userBaseUrl: 'https://app.example.com'\n * })\n * ]\n * };\n * ```\n */\nexport function provideMesAuth(config: MesAuthConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: MES_AUTH_CONFIG, useValue: config },\n MesAuthService,\n provideAppInitializer(() => {\n const mesAuthService = inject(MesAuthService);\n const httpClient = inject(HttpClient);\n const router = inject(Router);\n const ngZone = inject(NgZone);\n mesAuthService.init(config, httpClient, router, ngZone);\n })\n ]);\n}\n\nexport interface IUser {\n userId?: string;\n userName?: string;\n fullName?: string;\n gender?: string;\n email?: string;\n phoneNumber?: string;\n department?: string;\n position?: string;\n tokenVersion?: string;\n permEndpoint?: string;\n perms?: Set<string>;\n employeeCode?: string;\n avatarPath?: string;\n loginMethod?: number;\n hrFullNameVn?: string;\n hrFullNameEn?: string;\n hrPosition?: string;\n hrJobTitle?: string;\n hrGender?: string;\n hrMobile?: string;\n hrEmail?: string;\n hrJoinDate?: string;\n hrBirthDate?: string;\n hrWorkStatus?: string;\n hrDoiTuong?: string;\n hrTeamCode?: string;\n hrLineCode?: string;\n}\n\nexport enum NotificationType {\n Info = 'Info',\n Warning = 'Warning',\n Error = 'Error',\n Success = 'Success'\n}\n\nexport interface NotificationDto {\n id: string;\n title: string;\n message: string;\n messageHtml?: string;\n url?: string;\n type: NotificationType;\n isRead: boolean;\n createdAt: string;\n sourceAppName: string;\n sourceAppIconUrl?: string;\n}\n\nexport interface FrontEndRoute {\n id: number;\n roleId: string;\n roleName: string;\n routePath: string;\n routeName: string;\n description?: string;\n icon?: string;\n cssClass?: string;\n parentId?: number | null;\n sortOrder: number;\n isLabel: boolean;\n isActive: boolean;\n createdAt: string;\n updatedAt?: string;\n children: FrontEndRoute[];\n}\n\nexport interface UserFrontEndRoutesGrouped {\n appId: string;\n appName: string;\n feUrl?: string;\n routes: FrontEndRoute[];\n}\n\nexport interface PagedList<T> {\n items: T[];\n totalCount: number;\n page: number;\n pageSize: number;\n totalPages: number;\n hasNext: boolean;\n hasPrevious: boolean;\n}\n\nexport interface RealTimeNotificationDto {\n id: string;\n title: string;\n message: string;\n messageHtml?: string;\n url?: string;\n type: NotificationType;\n createdAt: string;\n sourceAppName: string;\n sourceAppIconUrl?: string;\n}\n\n@Injectable()\nexport class MesAuthService {\n private hubConnection: HubConnection | null = null;\n private _currentUser = new BehaviorSubject<IUser | null>(null);\n public currentUser$: Observable<IUser | null> = this._currentUser.asObservable();\n private _notifications = new Subject<any>();\n public notifications$: Observable<any> = this._notifications.asObservable();\n private _approvalEvents = new Subject<any>();\n public approvalEvents$: Observable<any> = this._approvalEvents.asObservable();\n\n private apiBase = '';\n private config: MesAuthConfig | null = null;\n private http!: HttpClient;\n private router?: Router;\n private ngZone: NgZone | null = null;\n\n constructor() {\n // Empty constructor - all dependencies passed to init()\n }\n\n init(config: MesAuthConfig, httpClient: HttpClient, router?: Router, ngZone?: NgZone) {\n this.config = config;\n this.http = httpClient;\n this.router = router;\n this.ngZone = ngZone ?? null;\n this.apiBase = config.apiBaseUrl.replace(/\\/$/, '');\n\n // Fetch user once on init. Route changes do NOT re-fetch the user.\n // Auth state is maintained via cookies; 401 errors are handled by HTTP interceptors.\n // SignalR handles real-time notification delivery without polling.\n this.fetchCurrentUser().subscribe();\n }\n\n getConfig(): MesAuthConfig | null {\n return this.config;\n }\n\n private fetchCurrentUser(): Observable<any> {\n if (!this.apiBase) return EMPTY;\n const url = `${this.apiBase}/auth/me`;\n return this.http.get(url, { withCredentials: this.config?.withCredentials ?? true }).pipe(\n tap((u) => {\n this._currentUser.next(u);\n if (u && this.config) {\n this.startConnection(this.config);\n }\n }),\n catchError((err) => {\n // Silently handle auth errors (401/403) - user is not logged in\n if (err.status === 401 || err.status === 403) {\n this._currentUser.next(null);\n }\n return of(null);\n })\n );\n }\n\n public getUnreadCount(): Observable<any> {\n return this.http.get(`${this.apiBase}/notif/me/unread-count`, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n public getNotifications(page: number = 1, pageSize: number = 20, includeRead: boolean = false, type?: string): Observable<any> {\n let url = `${this.apiBase}/notif/me?page=${page}&pageSize=${pageSize}&includeRead=${includeRead}`;\n if (type) {\n url += `&type=${type}`;\n }\n return this.http.get(url, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n public markAsRead(notificationId: string): Observable<any> {\n return this.http.patch(`${this.apiBase}/notif/${notificationId}/read`, {}, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n public markAllAsRead(): Observable<any> {\n return this.http.patch(`${this.apiBase}/notif/me/read-all`, {}, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n public deleteNotification(notificationId: string): Observable<any> {\n return this.http.delete(`${this.apiBase}/notif/${notificationId}`, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n /**\n * Get frontend routes assigned to the current user\n * Returns routes grouped by application\n */\n public getFrontEndRoutes(): Observable<UserFrontEndRoutesGrouped[]> {\n if (!this.apiBase) throw new Error('MesAuth not initialized');\n return this.http.get<UserFrontEndRoutesGrouped[]>(`${this.apiBase}/fe-routes/me`, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n private startConnection(config: MesAuthConfig) {\n if (this.hubConnection) return;\n const signalrUrl = config.apiBaseUrl.replace(/\\/$/, '') + '/hub/notification';\n const builder = new HubConnectionBuilder()\n .withUrl(signalrUrl, { withCredentials: config.withCredentials ?? true })\n .withAutomaticReconnect()\n .configureLogging(LogLevel.Warning);\n\n this.hubConnection = builder.build();\n\n this.hubConnection.on('ReceiveNotification', (n: any) => {\n if (this.ngZone) {\n this.ngZone.run(() => this._notifications.next(n));\n } else {\n this._notifications.next(n);\n }\n });\n\n this.hubConnection.on('ApprovalCompleted', (e: any) => {\n if (this.ngZone) {\n this.ngZone.run(() => this._approvalEvents.next({ type: 'ApprovalCompleted', ...e }));\n } else {\n this._approvalEvents.next({ type: 'ApprovalCompleted', ...e });\n }\n });\n\n this.hubConnection.on('ApprovalStepChanged', (e: any) => {\n if (this.ngZone) {\n this.ngZone.run(() => this._approvalEvents.next({ type: 'ApprovalStepChanged', ...e }));\n } else {\n this._approvalEvents.next({ type: 'ApprovalStepChanged', ...e });\n }\n });\n\n this.hubConnection.start().then(() => {}).catch((err) => {});\n\n this.hubConnection.onclose(() => {});\n this.hubConnection.onreconnecting(() => {});\n this.hubConnection.onreconnected(() => {});\n }\n\n public stop() {\n if (!this.hubConnection) return;\n this.hubConnection.stop().catch(() => {});\n this.hubConnection = null;\n }\n\n public logout(): Observable<any> {\n const url = `${this.apiBase}/auth/logout`;\n return this.http.post(url, {}, { withCredentials: this.config?.withCredentials ?? true }).pipe(\n tap(() => {\n this._currentUser.next(null);\n this.stop();\n })\n );\n }\n\n public get currentUser(): IUser | null {\n return this._currentUser.value;\n }\n\n public get isAuthenticated(): boolean {\n return this._currentUser.value !== null;\n }\n\n /**\n * Refreshes the current user from the server.\n * Returns an Observable that completes when the user data is loaded.\n * Callers can subscribe to wait for completion before proceeding (e.g., navigating after login).\n */\n public refreshUser(): Observable<any> {\n return this.fetchCurrentUser();\n }\n}\n","import { inject } from '@angular/core';\nimport { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';\nimport { throwError, timer } from 'rxjs';\nimport { catchError, switchMap } from 'rxjs/operators';\nimport { Router } from '@angular/router';\nimport { MesAuthService } from './mes-auth.service';\n\n// Track if we're currently redirecting to prevent loopback\nlet isRedirecting = false;\n\ninterface PermissionHeader {\n resource: string;\n allowedActions: string[];\n}\n/**\n * Functional HTTP interceptor for handling 401/403 auth errors.\n * Redirects to login page on 401, and to 403 page on 403.\n * Includes loopback prevention to avoid infinite redirects.\n */\nexport const mesAuthInterceptor: HttpInterceptorFn = (req, next) => {\n const authService = inject(MesAuthService);\n const router = inject(Router);\n\n return next(req).pipe(\n catchError((error: HttpErrorResponse) => {\n const status = error.status;\n\n // Check if we should handle this error and prevent loopback\n if ((status === 401 || status === 403) && !isRedirecting) {\n const config = authService.getConfig();\n const baseUrl = config?.userBaseUrl || '';\n\n const currentUrl = router.url + (window.location.hash || '');\n const returnUrl = encodeURIComponent(currentUrl);\n\n // Avoid loops if already on auth/unauth pages\n const isLoginPage = currentUrl.includes('/login');\n const is403Page = currentUrl.includes('/403');\n const isAuthPage = currentUrl.includes('/auth');\n // Public pages that should never trigger a 401 redirect (e.g., register, password reset)\n const isPublicPage = currentUrl.includes('/register')\n || currentUrl.includes('/forgot-password')\n || currentUrl.includes('/reset-password');\n // Skip redirect for the initial /auth/me check (app startup when not logged in)\n const isMeAuthPage = req.url.includes('/auth/me');\n\n if (status === 401 && !isLoginPage && !isAuthPage && !isMeAuthPage && !isPublicPage) {\n // Wait 1.5s for the concurrent refresh's Set-Cookie to be processed, then retry once.\n // If retry also gets 401, redirect to login.\n return timer(1500).pipe(\n switchMap(() => next(req)),\n catchError((retryError: HttpErrorResponse) => {\n if (retryError.status === 401) {\n isRedirecting = true;\n setTimeout(() => { isRedirecting = false; }, 5000);\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\n }\n return throwError(() => retryError);\n })\n );\n } else if (status === 403 && !is403Page) {\n isRedirecting = true;\n setTimeout(() => { isRedirecting = false; }, 5000);\n let redirectUrl = `${baseUrl}/403?returnUrl=${returnUrl}`;\n if (error.error && error.error.required) {\n redirectUrl += `&required=${encodeURIComponent(error.error.required)}`;\n }\n window.location.href = redirectUrl;\n }\n }\n return throwError(() => error);\n })\n );\n};\n\n\nfunction appendPermissions(body: unknown, allowedActions: string[]): unknown {\n if (body === null || body === undefined) {\n return { 'x-ma-perms': allowedActions };\n }\n\n if (Array.isArray(body)) {\n return { data: body, 'x-ma-perms': allowedActions };\n }\n\n if (typeof body === 'object') {\n return { ...(body as object), 'x-ma-perms': allowedActions };\n }\n\n // Primitive (string, number, boolean)\n return { data: body, 'x-ma-perms': allowedActions };\n}","import { NgModule } from '@angular/core';\nimport { MesAuthService } from './mes-auth.service';\n\n@NgModule({\n providers: [\n MesAuthService\n ]\n})\nexport class MesAuthModule {}\n","import { Injectable, OnDestroy } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\nexport type Theme = 'light' | 'dark';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ThemeService implements OnDestroy {\n private _currentTheme = new BehaviorSubject<Theme>('light');\n public currentTheme$: Observable<Theme> = this._currentTheme.asObservable();\n private observer: MutationObserver | null = null;\n\n constructor() {\n this.detectTheme();\n this.startWatching();\n }\n\n ngOnDestroy(): void {\n this.stopWatching();\n }\n\n private detectTheme(): void {\n const html = document.documentElement;\n const isDark = html.classList.contains('dark') ||\n html.getAttribute('data-theme') === 'dark' ||\n html.getAttribute('theme') === 'dark' ||\n html.getAttribute('data-coreui-theme') === 'dark';\n\n this._currentTheme.next(isDark ? 'dark' : 'light');\n }\n\n private startWatching(): void {\n if (typeof MutationObserver === 'undefined') {\n // Fallback for older browsers - check periodically\n setInterval(() => this.detectTheme(), 1000);\n return;\n }\n\n this.observer = new MutationObserver(() => {\n this.detectTheme();\n });\n\n this.observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class', 'data-theme', 'theme', 'data-coreui-theme']\n });\n }\n\n private stopWatching(): void {\n if (this.observer) {\n this.observer.disconnect();\n this.observer = null;\n }\n }\n\n get currentTheme(): Theme {\n return this._currentTheme.value;\n }\n\n // Method to manually set theme if needed\n setTheme(theme: Theme): void {\n this._currentTheme.next(theme);\n }\n\n // Re-detect theme from DOM\n refreshTheme(): void {\n this.detectTheme();\n }\n}","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding, HostListener, signal, ChangeDetectorRef } from '@angular/core';\nimport { NgIf } from '@angular/common';\nimport { Router } from '@angular/router';\nimport { HttpClient } from '@angular/common/http';\nimport { MesAuthService, IUser } from './mes-auth.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n selector: 'ma-user-profile',\n standalone: true,\n imports: [NgIf],\n template: `\n <div class=\"user-profile-container\">\n <!-- Not logged in -->\n <ng-container *ngIf=\"!currentUser()\">\n <button class=\"login-btn\" (click)=\"onLogin()\">Login</button>\n </ng-container>\n\n <!-- Logged in -->\n <ng-container *ngIf=\"currentUser()\">\n <div class=\"user-header\">\n <!-- Notification Bell -->\n <button class=\"notification-btn\" [class.has-unread]=\"unreadCount > 0\" (click)=\"onNotificationClick()\" title=\"Notifications\" aria-label=\"Notifications\">\n <svg class=\"bell-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/>\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n <span class=\"badge\" *ngIf=\"unreadCount > 0\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\n </button>\n\n <!-- Approval Button -->\n <button class=\"notification-btn\" [class.has-unread]=\"pendingApprovalCount > 0\" (click)=\"onApprovalClick()\" title=\"Approvals\" aria-label=\"Approvals\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M9 11l3 3L22 4\"/>\n <path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"/>\n </svg>\n <span class=\"badge\" *ngIf=\"pendingApprovalCount > 0\">{{ pendingApprovalCount > 99 ? '99+' : pendingApprovalCount }}</span>\n </button>\n\n <!-- User Avatar + Dropdown -->\n <div class=\"user-menu-wrapper\">\n <button class=\"user-menu-btn\" (click)=\"toggleDropdown()\" [attr.aria-label]=\"'User menu for ' + (currentUser().fullName || currentUser().userName)\" aria-haspopup=\"true\" [attr.aria-expanded]=\"dropdownOpen\">\n <div class=\"avatar-ring\" [class.active]=\"dropdownOpen\">\n <img\n *ngIf=\"currentUser().fullName || currentUser().userName\"\n [src]=\"getAvatarUrl(currentUser())\"\n [alt]=\"currentUser().fullName || currentUser().userName\"\n class=\"avatar\"\n />\n <span *ngIf=\"!(currentUser().fullName || currentUser().userName)\" class=\"avatar-initial\">\n {{ getLastNameInitial(currentUser()) }}\n </span>\n </div>\n </button>\n\n <div class=\"mes-dropdown-menu\" *ngIf=\"dropdownOpen\">\n <!-- User info header -->\n <div class=\"mes-dropdown-header\">\n <div class=\"dropdown-avatar-wrap\">\n <img\n *ngIf=\"currentUser().fullName || currentUser().userName\"\n [src]=\"getAvatarUrl(currentUser())\"\n [alt]=\"currentUser().fullName || currentUser().userName\"\n class=\"dropdown-avatar\"\n />\n <span *ngIf=\"!(currentUser().fullName || currentUser().userName)\" class=\"dropdown-avatar-initial\">\n {{ getLastNameInitial(currentUser()) }}\n </span>\n </div>\n <div class=\"dropdown-user-info\">\n <span class=\"dropdown-user-name\">{{ currentUser().fullName || currentUser().userName }}</span>\n <span class=\"dropdown-user-sub\" *ngIf=\"currentUser().position || currentUser().department\">\n {{ currentUser().position || currentUser().department }}\n </span>\n </div>\n </div>\n\n <div class=\"mes-dropdown-divider\"></div>\n\n <button class=\"mes-dropdown-item profile-link\" (click)=\"onViewProfile()\">\n <svg class=\"item-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"/><circle cx=\"12\" cy=\"7\" r=\"4\"/>\n </svg>\n View Profile\n </button>\n\n <div class=\"mes-dropdown-divider\"></div>\n\n <button class=\"mes-dropdown-item logout-item\" (click)=\"onLogout()\">\n <svg class=\"item-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\"/><polyline points=\"16 17 21 12 16 7\"/><line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"/>\n </svg>\n Logout\n </button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n `,\n styles: [`\n :host {\n --primary-color: #1976d2;\n --primary-hover: #1565c0;\n --primary-light: rgba(25, 118, 210, 0.12);\n --primary-glow: rgba(25, 118, 210, 0.3);\n --error-color: #f44336;\n --error-light: rgba(244, 67, 54, 0.1);\n --text-primary: #212121;\n --text-secondary: #616161;\n --text-muted: #9e9e9e;\n --bg-primary: #ffffff;\n --bg-secondary: #f8f9fa;\n --bg-hover: #f0f4ff;\n --border-color: #e0e0e0;\n --shadow: rgba(0, 0, 0, 0.12);\n --shadow-lg: rgba(0, 0, 0, 0.18);\n }\n\n :host(.theme-dark) {\n --primary-color: #90caf9;\n --primary-hover: #64b5f6;\n --primary-light: rgba(144, 202, 249, 0.12);\n --primary-glow: rgba(144, 202, 249, 0.25);\n --error-color: #ef5350;\n --error-light: rgba(239, 83, 80, 0.12);\n --text-primary: #e0e0e0;\n --text-secondary: #b0b0b0;\n --text-muted: #757575;\n --bg-primary: #1e1e2e;\n --bg-secondary: #27273a;\n --bg-hover: #2a2d4a;\n --border-color: #383850;\n --shadow: rgba(0, 0, 0, 0.35);\n --shadow-lg: rgba(0, 0, 0, 0.5);\n }\n\n .user-profile-container {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .login-btn {\n padding: 7px 18px;\n background-color: var(--primary-color);\n color: white;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n font-weight: 500;\n font-size: 13px;\n letter-spacing: 0.2px;\n transition: background-color 0.2s, transform 0.15s;\n }\n\n .login-btn:hover {\n background-color: var(--primary-hover);\n transform: translateY(-1px);\n }\n\n .user-header {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n /* ── Bell button ── */\n .notification-btn {\n position: relative;\n background: none;\n border: none;\n cursor: pointer;\n padding: 8px;\n border-radius: 10px;\n color: var(--text-secondary);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: color 0.2s, background-color 0.2s;\n }\n\n .notification-btn:hover {\n background-color: var(--primary-light);\n color: var(--primary-color);\n }\n\n .notification-btn.has-unread {\n color: var(--primary-color);\n }\n\n .bell-icon {\n display: block;\n transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n .notification-btn:hover .bell-icon {\n transform: rotate(-20deg) scale(1.15);\n }\n\n .badge {\n position: absolute;\n top: 2px;\n right: 2px;\n background-color: var(--error-color);\n color: white;\n border-radius: 10px;\n min-width: 17px;\n height: 17px;\n padding: 0 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n font-weight: 700;\n line-height: 1;\n box-shadow: 0 0 0 2px var(--bg-primary);\n animation: badge-pop 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n @keyframes badge-pop {\n from { transform: scale(0); }\n to { transform: scale(1); }\n }\n\n /* ── Avatar ── */\n .user-menu-wrapper {\n position: relative;\n }\n\n .user-menu-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 2px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s;\n }\n\n .user-menu-btn:hover {\n transform: scale(1.06);\n }\n\n .avatar-ring {\n border-radius: 50%;\n padding: 2px;\n border: 2px solid transparent;\n transition: border-color 0.25s, box-shadow 0.25s;\n }\n\n .avatar-ring.active,\n .user-menu-btn:hover .avatar-ring {\n border-color: var(--primary-color);\n box-shadow: 0 0 0 3px var(--primary-glow);\n }\n\n .avatar {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n object-fit: cover;\n display: block;\n }\n\n .avatar-initial {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: linear-gradient(135deg, var(--primary-color), var(--primary-hover));\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 15px;\n }\n\n /* ── Dropdown ── */\n .mes-dropdown-menu {\n position: absolute;\n top: calc(100% + 10px);\n right: 0;\n background: var(--bg-primary);\n border: 1px solid var(--border-color);\n border-radius: 14px;\n box-shadow: 0 8px 32px var(--shadow-lg), 0 2px 8px var(--shadow);\n min-width: 220px;\n z-index: 1000;\n overflow: hidden;\n animation: dropdown-in 0.16s cubic-bezier(0.16, 1, 0.3, 1);\n }\n\n @keyframes dropdown-in {\n from { opacity: 0; transform: translateY(-8px) scale(0.96); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n\n .mes-dropdown-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: var(--bg-secondary);\n }\n\n .dropdown-avatar-wrap {\n flex-shrink: 0;\n }\n\n .dropdown-avatar {\n width: 46px;\n height: 46px;\n border-radius: 50%;\n object-fit: cover;\n border: 2px solid var(--primary-color);\n display: block;\n }\n\n .dropdown-avatar-initial {\n width: 46px;\n height: 46px;\n border-radius: 50%;\n background: linear-gradient(135deg, var(--primary-color), var(--primary-hover));\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 18px;\n border: 2px solid var(--primary-color);\n }\n\n .dropdown-user-info {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n }\n\n .dropdown-user-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .dropdown-user-sub {\n font-size: 11px;\n color: var(--primary-color);\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .mes-dropdown-divider {\n height: 1px;\n background: var(--border-color);\n }\n\n .mes-dropdown-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 11px 16px;\n border: none;\n background: none;\n text-align: left;\n cursor: pointer;\n font-size: 13.5px;\n font-weight: 500;\n transition: background-color 0.15s;\n }\n\n .item-icon {\n flex-shrink: 0;\n opacity: 0.8;\n }\n\n .profile-link {\n color: var(--primary-color);\n }\n\n .profile-link:hover {\n background-color: var(--primary-light);\n }\n\n .logout-item {\n color: var(--error-color);\n }\n\n .logout-item:hover {\n background-color: var(--error-light);\n }\n\n @media (max-width: 768px) {\n .avatar, .avatar-initial { width: 32px; height: 32px; font-size: 13px; }\n }\n `]\n})\nexport class UserProfileComponent implements OnInit, OnDestroy {\n @Output() notificationClick = new EventEmitter<void>();\n @Output() approvalClick = new EventEmitter<void>();\n @HostBinding('class') get themeClass(): string {\n return `theme-${this.currentTheme}`;\n }\n\n currentUser = signal<IUser | null>(null);\n currentTheme: Theme = 'light';\n unreadCount = 0;\n pendingApprovalCount = 0;\n dropdownOpen = false;\n private hasUser = false;\n private destroy$ = new Subject<void>();\n\n // Signal to force avatar refresh\n avatarRefresh = signal<number>(Date.now());\n\n constructor(private authService: MesAuthService, private router: Router, private themeService: ThemeService, private cdr: ChangeDetectorRef, private http: HttpClient) {}\n\n ngOnInit() {\n this.authService.currentUser$\n .pipe(takeUntil(this.destroy$))\n .subscribe(user => {\n this.currentUser.set(user);\n this.hasUser = !!user;\n // Force avatar refresh when user changes\n this.avatarRefresh.set(Date.now());\n if (!this.hasUser) {\n this.unreadCount = 0;\n this.pendingApprovalCount = 0;\n } else {\n this.loadUnreadCount();\n this.loadPendingApprovalCount();\n }\n this.cdr.markForCheck();\n });\n\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(theme => {\n this.currentTheme = theme;\n });\n\n // Listen for approval events (SignalR) to refresh pending count\n this.authService.approvalEvents$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n if (this.hasUser) this.loadPendingApprovalCount();\n });\n\n // Listen for new real-time notifications (SignalR only)\n this.authService.notifications$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n if (this.hasUser) {\n this.loadUnreadCount();\n }\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n loadUnreadCount() {\n if (!this.hasUser) {\n this.unreadCount = 0;\n return;\n }\n\n this.authService.getUnreadCount().subscribe({\n next: (response: any) => {\n this.unreadCount = response.unreadCount || 0;\n },\n error: (err) => {}\n });\n }\n\n loadPendingApprovalCount() {\n if (!this.hasUser) { this.pendingApprovalCount = 0; return; }\n const config = this.authService.getConfig();\n if (!config) return;\n const url = `${config.apiBaseUrl.replace(/\\/$/, '')}/approval/dashboard`;\n this.http.get(url, { withCredentials: config.withCredentials ?? true }).subscribe({\n next: (r: any) => { this.pendingApprovalCount = r?.pendingCount ?? 0; },\n error: () => {}\n });\n }\n\n onApprovalClick() {\n this.approvalClick.emit();\n }\n\n getAvatarUrl(user: IUser): string {\n // Use the refresh signal to force update\n const refresh = this.avatarRefresh();\n const config = this.authService.getConfig();\n const baseUrl = config?.apiBaseUrl || '';\n \n // If user has avatarPath, use it directly\n if (user.avatarPath) {\n // If avatarPath is already a full URL, use it as-is\n if (user.avatarPath.startsWith('http://') || user.avatarPath.startsWith('https://')) {\n return user.avatarPath;\n }\n // If it's a relative path, construct full URL with refresh timestamp\n return `${baseUrl.replace(/\\/$/, '')}${user.avatarPath}?t=${refresh}`;\n }\n\n // Fallback: construct URL using userId\n const userId = user.userId;\n if (userId && baseUrl) {\n return `${baseUrl.replace(/\\/$/, '')}/auth/${userId}/avatar?t=${refresh}`;\n }\n \n // Fallback to UI avatars service if no userId or baseUrl\n const displayName = user.userName || user.userId || 'User';\n return `https://ui-avatars.com/api/?name=${encodeURIComponent(displayName)}&background=1976d2&color=fff`;\n }\n\n getLastNameInitial(user: IUser): string {\n const fullName = user.fullName || user.userName || 'U';\n const parts = fullName.split(' ');\n const lastPart = parts[parts.length - 1];\n return lastPart.charAt(0).toUpperCase();\n }\n\n toggleDropdown() {\n this.dropdownOpen = !this.dropdownOpen;\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: Event) {\n const target = event.target as HTMLElement;\n const clickedInside = target.closest('.user-menu-wrapper');\n if (!clickedInside) {\n this.dropdownOpen = false;\n }\n }\n\n onLogin() {\n const config = this.authService.getConfig();\n const baseUrl = config?.userBaseUrl || '';\n const returnUrl = encodeURIComponent(this.router.url);\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\n }\n\n onViewProfile() {\n this.router.navigate(['/profile']);\n this.dropdownOpen = false;\n }\n\n onLogout() {\n this.authService.logout().subscribe({\n next: () => {\n // Clear current user after successful logout\n this.dropdownOpen = false;\n \n // Navigate to login with return URL\n const config = this.authService.getConfig();\n const baseUrl = config?.userBaseUrl || '';\n const returnUrl = encodeURIComponent(window.location.href);\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\n },\n error: (err) => {\n // Still navigate to login even if logout fails\n const config = this.authService.getConfig();\n const baseUrl = config?.userBaseUrl || '';\n window.location.href = `${baseUrl}/login`;\n }\n });\n }\n\n onNotificationClick() {\n this.notificationClick.emit();\n }\n}\n\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\nexport interface Toast {\n id: string;\n message: string;\n title?: string;\n type: 'info' | 'success' | 'warning' | 'error';\n duration?: number;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ToastService {\n private toasts$ = new BehaviorSubject<Toast[]>([]);\n public toasts: Observable<Toast[]> = this.toasts$.asObservable();\n\n show(message: string, title?: string, type: 'info' | 'success' | 'warning' | 'error' = 'info', duration: number = 5000) {\n const id = Math.random().toString(36).substr(2, 9);\n const toast: Toast = {\n id,\n message,\n title,\n type,\n duration\n };\n\n const currentToasts = this.toasts$.value;\n this.toasts$.next([...currentToasts, toast]);\n\n if (duration > 0) {\n setTimeout(() => {\n this.remove(id);\n }, duration);\n }\n\n return id;\n }\n\n remove(id: string) {\n const currentToasts = this.toasts$.value;\n this.toasts$.next(currentToasts.filter(t => t.id !== id));\n }\n\n clear() {\n this.toasts$.next([]);\n }\n}\n","import { Component, OnInit, OnDestroy, HostBinding } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ToastService, Toast } from './toast.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n selector: 'ma-toast-container',\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"toast-container\">\n <div *ngFor=\"let toast of toasts\" class=\"toast toast-{{ toast.type }}\">\n\n <!-- Type icon -->\n <div class=\"toast-icon\">\n <svg *ngIf=\"toast.type === 'info'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n <svg *ngIf=\"toast.type === 'success'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/><polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n <svg *ngIf=\"toast.type === 'warning'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/>\n </svg>\n <svg *ngIf=\"toast.type === 'error'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/>\n </svg>\n </div>\n\n <!-- Content -->\n <div class=\"toast-content\">\n <div *ngIf=\"toast.title\" class=\"toast-title\">{{ toast.title }}</div>\n <div class=\"toast-message\" [innerHTML]=\"toast.message\"></div>\n </div>\n\n <!-- Close -->\n <button class=\"toast-close\" (click)=\"close(toast.id)\" aria-label=\"Close\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n\n <!-- Auto-dismiss progress bar — hidden when duration <= 0 (persistent toast) -->\n <div class=\"toast-progress\" *ngIf=\"toast.duration == null || toast.duration > 0\" [style.animation-duration]=\"(toast.duration ?? 5000) + 'ms'\"></div>\n </div>\n </div>\n `,\n styles: [`\n :host {\n --info-color: #2196f3;\n --info-bg: rgba(33, 150, 243, 0.1);\n --success-color: #43a047;\n --success-bg: rgba(67, 160, 71, 0.1);\n --warning-color: #f57c00;\n --warning-bg: rgba(245, 124, 0, 0.1);\n --error-color: #e53935;\n --error-bg: rgba(229, 57, 53, 0.1);\n --text-primary: #212121;\n --text-secondary: #757575;\n --bg-primary: #ffffff;\n --border-color: rgba(0, 0, 0, 0.08);\n --shadow: rgba(0, 0, 0, 0.1);\n --shadow-lg: rgba(0, 0, 0, 0.18);\n }\n\n :host(.theme-dark) {\n --info-color: #64b5f6;\n --info-bg: rgba(100, 181, 246, 0.12);\n --success-color: #66bb6a;\n --success-bg: rgba(102, 187, 106, 0.12);\n --warning-color: #ffb74d;\n --warning-bg: rgba(255, 183, 77, 0.12);\n --error-color: #ef5350;\n --error-bg: rgba(239, 83, 80, 0.12);\n --text-primary: #e0e0e0;\n --text-secondary: #9e9e9e;\n --bg-primary: #1e1e2e;\n --border-color: rgba(255, 255, 255, 0.08);\n --shadow: rgba(0, 0, 0, 0.35);\n --shadow-lg: rgba(0, 0, 0, 0.5);\n }\n\n .toast-container {\n position: fixed;\n top: 20px;\n right: 20px;\n z-index: 9999;\n pointer-events: none;\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .toast {\n position: relative;\n display: flex;\n align-items: flex-start;\n gap: 11px;\n padding: 13px 13px 16px 16px;\n border-radius: 12px;\n background: var(--bg-primary);\n border: 1px solid var(--border-color);\n box-shadow: 0 8px 28px var(--shadow-lg), 0 2px 8px var(--shadow);\n pointer-events: auto;\n min-width: 300px;\n max-width: 420px;\n overflow: hidden;\n animation: toast-in 0.35s cubic-bezier(0.16, 1, 0.3, 1);\n }\n\n @keyframes toast-in {\n from { opacity: 0; transform: translateX(36px) scale(0.96); }\n to { opacity: 1; transform: translateX(0) scale(1); }\n }\n\n /* Left accent bar via ::before */\n .toast::before {\n content: '';\n position: absolute;\n left: 0; top: 0; bottom: 0;\n width: 4px;\n border-radius: 12px 0 0 12px;\n }\n\n .toast-info::before { background: var(--info-color); }\n .toast-success::before { background: var(--success-color); }\n .toast-warning::before { background: var(--warning-color); }\n .toast-error::before { background: var(--error-color); }\n\n /* Type icon bubble */\n .toast-icon {\n flex-shrink: 0;\n width: 34px;\n height: 34px;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 2px;\n }\n\n .toast-info .toast-icon { color: var(--info-color); background: var(--info-bg); }\n .toast-success .toast-icon { color: var(--success-color); background: var(--success-bg); }\n .toast-warning .toast-icon { color: var(--warning-color); background: var(--warning-bg); }\n .toast-error .toast-icon { color: var(--error-color); background: var(--error-bg); }\n\n .toast-content {\n flex: 1;\n min-width: 0;\n padding-top: 1px;\n }\n\n .toast-title {\n font-weight: 700;\n font-size: 13.5px;\n margin-bottom: 3px;\n line-height: 1.3;\n }\n\n .toast-info .toast-title { color: var(--info-color); }\n .toast-success .toast-title { color: var(--success-color); }\n .toast-warning .toast-title { color: var(--warning-color); }\n .toast-error .toast-title { color: var(--error-color); }\n\n .toast-message {\n font-size: 12.5px;\n line-height: 1.45;\n color: var(--text-secondary);\n }\n\n .toast-close {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--text-secondary);\n width: 26px;\n height: 26px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n padding: 0;\n transition: color 0.15s, background-color 0.15s;\n }\n\n .toast-close:hover {\n color: var(--text-primary);\n background: var(--border-color);\n }\n\n /* Auto-dismiss progress bar */\n .toast-progress {\n position: absolute;\n bottom: 0;\n left: 4px;\n right: 0;\n height: 3px;\n border-radius: 0 0 12px 0;\n animation: toast-progress linear forwards;\n opacity: 0.7;\n }\n\n .toast-info .toast-progress { background: var(--info-color); }\n .toast-success .toast-progress { background: var(--success-color); }\n .toast-warning .toast-progress { background: var(--warning-color); }\n .toast-error .toast-progress { background: var(--error-color); }\n\n @keyframes toast-progress {\n from { width: calc(100% - 4px); }\n to { width: 0; }\n }\n\n @media (max-width: 600px) {\n .toast-container { top: 10px; right: 10px; left: 10px; }\n .toast { min-width: auto; max-width: 100%; }\n }\n `]\n})\nexport class ToastContainerComponent implements OnInit, OnDestroy {\n @HostBinding('class') get themeClass(): string {\n return `theme-${this.currentTheme}`;\n }\n\n toasts: Toast[] = [];\n currentTheme: Theme = 'light';\n private destroy$ = new Subject<void>();\n\n constructor(private toastService: ToastService, private themeService: ThemeService) {}\n\n ngOnInit() {\n this.toastService.toasts\n .pipe(takeUntil(this.destroy$))\n .subscribe(toasts => {\n this.toasts = toasts;\n });\n\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(theme => {\n this.currentTheme = theme;\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n close(id: string) {\n this.toastService.remove(id);\n }\n}\n","import { Component, OnInit, OnDestroy, HostBinding, Output, EventEmitter, inject } from '@angular/core';\nimport { NgIf, NgFor } from '@angular/common';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { MesAuthService, NotificationDto, PagedList, RealTimeNotificationDto } from './mes-auth.service';\nimport { ToastService } from './toast.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n selector: 'ma-notification-panel',\n standalone: true,\n imports: [NgIf, NgFor],\n template: `\n <div class=\"notification-panel\" [class.open]=\"isOpen\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/>\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n <h3>Notifications</h3>\n </div>\n <button class=\"close-btn\" (click)=\"close()\" title=\"Close\" aria-label=\"Close notifications\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs\">\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'unread'\" (click)=\"switchTab('unread')\">\n Unread\n <span class=\"tab-badge\" *ngIf=\"unreadNotifications.length > 0\">{{ unreadNotifications.length }}</span>\n </button>\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'read'\" (click)=\"switchTab('read')\">\n Read\n <span class=\"tab-badge read-badge\" *ngIf=\"readNotifications.length > 0\">{{ readNotifications.length }}</span>\n </button>\n </div>\n\n <!-- Notifications List -->\n <div class=\"notifications-list\">\n <ng-container *ngIf=\"currentNotifications.length > 0\">\n <div\n *ngFor=\"let notification of currentNotifications\"\n class=\"notification-item\"\n [class.unread]=\"!notification.isRead\"\n (click)=\"openDetails(notification)\"\n >\n @let t = typeOf(notification);\n <div class=\"notif-accent\"\n [class.type-info]=\"t === 'Info'\"\n [class.type-success]=\"t === 'Success'\"\n [class.type-warning]=\"t === 'Warning'\"\n [class.type-error]=\"t === 'Error'\"></div>\n <div class=\"notif-type-icon\"\n [class.type-info]=\"t === 'Info'\"\n [class.type-success]=\"t === 'Success'\"\n [class.type-warning]=\"t === 'Warning'\"\n [class.type-error]=\"t === 'Error'\">\n <svg *ngIf=\"t === 'Info'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n <svg *ngIf=\"t === 'Success'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\"/>\n </svg>\n <svg *ngIf=\"t === 'Warning'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/>\n </svg>\n <svg *ngIf=\"t === 'Error'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/>\n </svg>\n </div>\n <div class=\"notification-content\">\n <div class=\"notification-title\">{{ notification.title }}</div>\n <div class=\"notification-message\">{{ getNotificationMessage(notification) }}</div>\n <div class=\"notification-meta\">\n <span class=\"app-name\">{{ notification.sourceAppName }}</span>\n <span class=\"time\">{{ dateLabels.get(notification.id) }}</span>\n </div>\n </div>\n <button class=\"icon-btn read-btn\" (click)=\"markAsRead(notification.id, $event)\" title=\"Mark as read\" aria-label=\"Mark as read\" *ngIf=\"!notification.isRead\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\"/>\n </svg>\n </button>\n <button class=\"icon-btn delete-btn\" (click)=\"delete(notification.id, $event)\" title=\"Delete\" aria-label=\"Delete notification\" *ngIf=\"notification.isRead\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6\"/><path d=\"M10 11v6\"/><path d=\"M14 11v6\"/><path d=\"M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/>\n </svg>\n </button>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"currentNotifications.length === 0\">\n <div class=\"empty-state\">\n <svg class=\"empty-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"44\" height=\"44\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/>\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n <p>No {{ activeTab }} notifications</p>\n </div>\n </ng-container>\n </div>\n\n <!-- Footer Actions -->\n <div class=\"panel-footer\" *ngIf=\"currentNotifications.length > 0\">\n <div class=\"footer-actions\" *ngIf=\"activeTab === 'unread'\">\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadNotifications.length > 0\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n Mark all read\n </button>\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllUnread()\" *ngIf=\"unreadNotifications.length > 0\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6\"/></svg>\n Delete all\n </button>\n </div>\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllRead()\" *ngIf=\"activeTab === 'read' && readNotifications.length > 0\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6\"/></svg>\n Delete all\n </button>\n </div>\n </div>\n\n <!-- Details Modal -->\n <div class=\"modal-overlay\" *ngIf=\"selectedNotification\" (click)=\"closeDetails()\">\n <div class=\"modal-container\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\"\n [class.modal-type-info]=\"typeOf(selectedNotification) === 'Info'\"\n [class.modal-type-success]=\"typeOf(selectedNotification) === 'Success'\"\n [class.modal-type-warning]=\"typeOf(selectedNotification) === 'Warning'\"\n [class.modal-type-error]=\"typeOf(selectedNotification) === 'Error'\">\n <div class=\"modal-header-left\">\n <div class=\"modal-type-icon\">\n <svg *ngIf=\"typeOf(selectedNotification) === 'Info'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n <svg *ngIf=\"typeOf(selectedNotification) === 'Success'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/><polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n <svg *ngIf=\"typeOf(selectedNotification) === 'Warning'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/>\n </svg>\n <svg *ngIf=\"typeOf(selectedNotification) === 'Error'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/>\n </svg>\n </div>\n <h3>{{ selectedNotification.title }}</h3>\n </div>\n <button class=\"close-btn\" (click)=\"closeDetails()\" title=\"Close\" aria-label=\"Close notification detail\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n <div class=\"modal-meta\">\n <span class=\"app-name\">{{ selectedNotification.sourceAppName }}</span>\n <span class=\"time\">{{ selectedNotificationDate }}</span>\n </div>\n <div class=\"modal-body\" [innerHTML]=\"selectedNotificationHtml\"></div>\n <div class=\"modal-footer\">\n <button class=\"action-btn see-details-btn\" *ngIf=\"selectedNotification.url?.trim()\" (click)=\"openUrl()\">See Details</button>\n <button class=\"action-btn\" (click)=\"closeDetails()\">Close</button>\n </div>\n </div>\n </div>\n `,\n styleUrls: ['./panel-shared.css', './notification-panel.component.css'],\n})\nexport class NotificationPanelComponent implements OnInit, OnDestroy {\n @Output() notificationRead = new EventEmitter<void>();\n @HostBinding('class') get themeClass(): string {\n return `theme-${this.currentTheme}`;\n }\n\n isOpen = false;\n notifications: NotificationDto[] = [];\n currentTheme: Theme = 'light';\n activeTab: 'unread' | 'read' = 'unread'; // Default to unread tab\n private destroy$ = new Subject<void>();\n\n // Cached filtered lists — updated explicitly to avoid re-filtering on every CD cycle\n private _unreadNotifications: NotificationDto[] = [];\n private _readNotifications: NotificationDto[] = [];\n\n // Stable time-ago strings keyed by notification id — refreshed every 30s\n dateLabels: Map<string, string> = new Map();\n private dateTimer: ReturnType<typeof setInterval> | null = null;\n\n get unreadNotifications(): NotificationDto[] {\n return this._unreadNotifications;\n }\n\n get readNotifications(): NotificationDto[] {\n return this._readNotifications;\n }\n\n get currentNotifications(): NotificationDto[] {\n return this.activeTab === 'unread' ? this._unreadNotifications : this._readNotifications;\n }\n\n selectedNotification: NotificationDto | null = null;\n selectedNotificationHtml: SafeHtml | null = null;\n selectedNotificationDate: string = '';\n\n // Returns plain text message for list display\n getNotificationMessage(notification: NotificationDto): string {\n return notification.message || '';\n }\n\n // Normalize type to string — API may return integer or string\n // Backend enum: Info=0, Success=1, Warning=2, Error=3\n typeOf(notification: { type: any }): 'Info' | 'Success' | 'Warning' | 'Error' {\n const t = notification.type;\n if (t === 0 || t === 'Info') return 'Info';\n if (t === 1 || t === 'Success') return 'Success';\n if (t === 2 || t === 'Warning') return 'Warning';\n if (t === 3 || t === 'Error') return 'Error';\n return 'Info';\n }\n\n private toastType(type: any): 'info' | 'warning' | 'error' | 'success' {\n const t = this.typeOf({ type });\n return t.toLowerCase() as 'info' | 'warning' | 'error' | 'success';\n }\n\n private readonly sanitizer = inject(DomSanitizer);\n\n constructor(private authService: MesAuthService, private toastService: ToastService, private themeService: ThemeService) {}\n\n ngOnInit() {\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(theme => {\n this.currentTheme = theme;\n });\n\n this.loadNotifications();\n\n // Refresh time-ago labels every 30s to avoid NG0100 from live new Date() in template\n this.dateTimer = setInterval(() => this.refreshDateLabels(), 30000);\n\n // Listen for new real-time notifications\n this.authService.notifications$\n .pipe(takeUntil(this.destroy$))\n .subscribe((notification: RealTimeNotificationDto) => {\n // Show toast for new notification\n this.toastService.show(\n notification.messageHtml || notification.message || '',\n notification.title,\n this.toastType(notification.type),\n 5000\n );\n // Reload notifications list\n this.loadNotifications();\n });\n }\n\n ngOnDestroy() {\n if (this.dateTimer !== null) {\n clearInterval(this.dateTimer);\n this.dateTimer = null;\n }\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private loadNotifications() {\n this.authService.getNotifications(1, 50, true).subscribe({ // includeRead = true to get both read and unread\n next: (response: PagedList<NotificationDto>) => {\n this.notifications = response.items || [];\n this.onNotificationsChanged();\n },\n error: (err) => {}\n });\n }\n\n open() {\n this.isOpen = true;\n this.activeTab = 'unread'; // Reset to unread tab when opening\n }\n\n close() {\n this.isOpen = false;\n }\n\n switchTab(tab: 'unread' | 'read') {\n this.activeTab = tab;\n }\n\n openDetails(notification: NotificationDto) {\n this.selectedNotification = notification;\n // Cache computed values to avoid re-rendering on every change detection cycle\n const html = notification.messageHtml || notification.message || '';\n this.selectedNotificationHtml = this.sanitizer.bypassSecurityTrustHtml(html);\n this.selectedNotificationDate = this.formatDate(notification.createdAt);\n // Mark as read when opening details (if not already read)\n if (!notification.isRead) {\n this.authService.markAsRead(notification.id).subscribe({\n next: () => {\n notification.isRead = true;\n this.notificationRead.emit();\n this.onNotificationsChanged();\n },\n error: () => {}\n });\n }\n }\n\n closeDetails() {\n this.selectedNotification = null;\n this.selectedNotificationHtml = null;\n this.selectedNotificationDate = '';\n }\n\n openUrl() {\n const url = this.selectedNotification?.url?.trim();\n if (url) {\n window.open(url, '_blank', 'noopener,noreferrer');\n }\n }\n\n markAsRead(notificationId: string, event?: Event) {\n if (event) {\n event.stopPropagation();\n }\n this.authService.markAsRead(notificationId).subscribe({\n next: () => {\n const notification = this.notifications.find(n => n.id === notificationId);\n if (notification) {\n notification.isRead = true;\n this.notificationRead.emit();\n this.onNotificationsChanged();\n }\n },\n error: (err) => {}\n });\n }\n\n markAllAsRead() {\n this.authService.markAllAsRead().subscribe({\n next: () => {\n this.notifications.forEach(n => n.isRead = true);\n this.notificationRead.emit();\n this.onNotificationsChanged();\n },\n error: (err) => {}\n });\n }\n\n deleteAllRead() {\n const readNotificationIds = this.notifications\n .filter(n => n.isRead)\n .map(n => n.id);\n\n // Delete all read notifications\n const deletePromises = readNotificationIds.map(id =>\n this.authService.deleteNotification(id).toPromise()\n );\n\n Promise.all(deletePromises).then(() => {\n // Remove all read notifications from the local array\n this.notifications = this.notifications.filter(n => !n.isRead);\n this.onNotificationsChanged();\n }).catch((err) => {\n // If bulk delete fails, reload notifications to get current state\n this.loadNotifications();\n });\n }\n\n deleteAllUnread() {\n const unreadNotificationIds = this.notifications\n .filter(n => !n.isRead)\n .map(n => n.id);\n\n // Delete all unread notifications\n const deletePromises = unreadNotificationIds.map(id =>\n this.authService.deleteNotification(id).toPromise()\n );\n\n Promise.all(deletePromises).then(() => {\n // Remove all unread notifications from the local array\n this.notifications = this.notifications.filter(n => n.isRead);\n this.notificationRead.emit();\n this.onNotificationsChanged();\n }).catch((err) => {\n // If bulk delete fails, reload notifications to get current state\n this.loadNotifications();\n });\n }\n\n delete(notificationId: string, event: Event) {\n event.stopPropagation();\n const wasUnread = this.notifications.find(n => n.id === notificationId && !n.isRead) !== undefined;\n this.authService.deleteNotification(notificationId).subscribe({\n next: () => {\n this.notifications = this.notifications.filter(n => n.id !== notificationId);\n if (wasUnread) {\n this.notificationRead.emit();\n }\n this.onNotificationsChanged();\n },\n error: (err) => {}\n });\n }\n\n formatDate(dateString: string): string {\n return this.computeTimeAgo(dateString, new Date());\n }\n\n // Pure computation — takes now as param so it never calls new Date() internally\n private computeTimeAgo(dateString: string, now: Date): string {\n const normalizedDateString = this.parseUtcDate(dateString);\n const date = new Date(normalizedDateString);\n\n if (isNaN(date.getTime())) {\n return 'Invalid date';\n }\n\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString();\n }\n\n // Rebuild dateLabels map using a single shared now — prevents mid-loop clock drift\n private refreshDateLabels(): void {\n const now = new Date();\n for (const n of this.notifications) {\n this.dateLabels.set(n.id, this.computeTimeAgo(n.createdAt, now));\n }\n }\n\n // Re-run filter once and store results in stable arrays\n private recomputeFilteredLists(): void {\n this._unreadNotifications = this.notifications.filter(n => !n.isRead);\n this._readNotifications = this.notifications.filter(n => n.isRead);\n }\n\n // Single call-site after every notification mutation\n private onNotificationsChanged(): void {\n this.recomputeFilteredLists();\n this.refreshDateLabels();\n }\n\n // Parse date string from server (stored in UTC but without 'Z' suffix or 'T' separator)\n private parseUtcDate(dateStr: string): string {\n // Handle date strings that might be missing the 'T' separator\n // Convert formats like \"2023-12-01 12:30:45\" to \"2023-12-01T12:30:45\"\n let normalized = dateStr.includes('T') ? dateStr : dateStr.replace(' ', 'T');\n\n // If no timezone indicator, assume UTC by appending 'Z'\n if (!normalized.endsWith('Z') && !normalized.includes('+') && !normalized.includes('-', 10)) {\n normalized += 'Z';\n }\n\n return normalized;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { Observable } from 'rxjs';\nimport { MesAuthConfig, PagedList } from './mes-auth.service';\nimport {\n ApprovalDocumentDto,\n ApprovalDocumentSummaryDto,\n ApprovalDocumentStatus,\n ApprovalDashboardDto,\n ApprovalHistoryDto,\n ApprovalTemplateSummaryDto,\n ApprovalTemplateDto,\n RolePreviewUserDto,\n CreateApprovalRequest,\n CreateApprovalResponseDto,\n CreateApprovalTemplateRequest,\n UpdateApprovalTemplateRequest,\n ApproveRejectRequest,\n DelegateRequest\n} from './approval.models';\n\n@Injectable()\nexport class MaApprovalService {\n private apiBase = '';\n private http!: HttpClient;\n private config: MesAuthConfig | null = null;\n\n constructor() {}\n\n init(config: MesAuthConfig, httpClient: HttpClient) {\n this.config = config;\n this.http = httpClient;\n this.apiBase = config.apiBaseUrl.replace(/\\/$/, '');\n }\n\n private get opts() {\n return { withCredentials: this.config?.withCredentials ?? true };\n }\n\n // ====================== Dashboard ======================\n\n getDashboard(): Observable<ApprovalDashboardDto> {\n return this.http.get<ApprovalDashboardDto>(`${this.apiBase}/approval/dashboard`, this.opts);\n }\n\n // ====================== Pending & My Requests ======================\n\n getPendingApprovals(page = 1, pageSize = 20): Observable<PagedList<ApprovalDocumentSummaryDto>> {\n return this.http.get<PagedList<ApprovalDocumentSummaryDto>>(\n `${this.apiBase}/approval/pending?page=${page}&pageSize=${pageSize}`,\n this.opts\n );\n }\n\n getMyRequests(page = 1, pageSize = 20, status?: ApprovalDocumentStatus): Observable<PagedList<ApprovalDocumentSummaryDto>> {\n let url = `${this.apiBase}/approval/my-requests?page=${page}&pageSize=${pageSize}`;\n if (status !== undefined) url += `&status=${status}`;\n return this.http.get<PagedList<ApprovalDocumentSummaryDto>>(url, this.opts);\n }\n\n // ====================== Document ======================\n\n getDocument(id: string): Observable<ApprovalDocumentDto> {\n return this.http.get<ApprovalDocumentDto>(`${this.apiBase}/approval/documents/${id}`, this.opts);\n }\n\n getDocumentHistory(id: string): Observable<ApprovalHistoryDto[]> {\n return this.http.get<ApprovalHistoryDto[]>(`${this.apiBase}/approval/documents/${id}/history`, this.opts);\n }\n\n getDocumentContentUrl(id: string): string {\n return `${this.apiBase}/approval/documents/${id}/content`;\n }\n\n getDocumentThumbnailUrl(id: string): string {\n return `${this.apiBase}/approval/documents/${id}/thumbnail`;\n }\n\n // ====================== Actions ======================\n\n approve(documentId: string, comment?: string): Observable<void> {\n const body: ApproveRejectRequest = { comment };\n return this.http.post<void>(`${this.apiBase}/approval/documents/${documentId}/approve`, body, this.opts);\n }\n\n reject(documentId: string, comment: string): Observable<void> {\n const body: ApproveRejectRequest = { comment };\n return this.http.post<void>(`${this.apiBase}/approval/documents/${documentId}/reject`, body, this.opts);\n }\n\n delegate(documentId: string, toUserId: string, reason?: string): Observable<void> {\n const body: DelegateRequest = { toUserId, reason };\n return this.http.post<void>(`${this.apiBase}/approval/documents/${documentId}/delegate`, body, this.opts);\n }\n\n cancel(documentId: string, reason?: string): Observable<void> {\n let url = `${this.apiBase}/approval/documents/${documentId}`;\n if (reason) url += `?reason=${encodeURIComponent(reason)}`;\n return this.http.delete<void>(url, this.opts);\n }\n\n // ====================== Templates ======================\n\n getTemplates(appId?: string): Observable<ApprovalTemplateSummaryDto[]> {\n let url = `${this.apiBase}/approval/templates`;\n if (appId) url += `?appId=${encodeURIComponent(appId)}`;\n return this.http.get<ApprovalTemplateSummaryDto[]>(url, this.opts);\n }\n\n getTemplate(id: number): Observable<ApprovalTemplateDto> {\n return this.http.get<ApprovalTemplateDto>(`${this.apiBase}/approval/templates/${id}`, this.opts);\n }\n\n createTemplate(request: CreateApprovalTemplateRequest): Observable<ApprovalTemplateDto> {\n return this.http.post<ApprovalTemplateDto>(`${this.apiBase}/approval/templates`, request, this.opts);\n }\n\n updateTemplate(id: number, request: UpdateApprovalTemplateRequest): Observable<ApprovalTemplateDto> {\n return this.http.put<ApprovalTemplateDto>(`${this.apiBase}/approval/templates/${id}`, request, this.opts);\n }\n\n deleteTemplate(id: number): Observable<void> {\n return this.http.delete<void>(`${this.apiBase}/approval/templates/${id}`, this.opts);\n }\n\n previewRole(orgCode: string, level: string): Observable<RolePreviewUserDto[]> {\n return this.http.get<RolePreviewUserDto[]>(\n `${this.apiBase}/approval/roles/preview?orgCode=${encodeURIComponent(orgCode)}&level=${encodeURIComponent(level)}`,\n this.opts\n );\n }\n\n // ====================== Create (used by ma-arv-container) ======================\n\n createApproval(request: CreateApprovalRequest): Observable<CreateApprovalResponseDto> {\n return this.http.post<CreateApprovalResponseDto>(`${this.apiBase}/approval/documents`, request, this.opts);\n }\n}\n","// ====================== Enums ======================\n\nexport enum ApprovalStepMode {\n Sequential = 0,\n Parallel = 1\n}\n\nexport enum ApprovalDocumentStatus {\n Draft = 0,\n Pending = 1,\n Approved = 2,\n Rejected = 3,\n Cancelled = 4,\n Expired = 5\n}\n\nexport enum ApprovalStepStatus {\n Waiting = 0,\n Active = 1,\n Approved = 2,\n Rejected = 3,\n Delegated = 4,\n Expired = 5,\n Skipped = 6\n}\n\nexport enum ApprovalActionType {\n Created = 0,\n Submitted = 1,\n Approved = 2,\n Rejected = 3,\n Delegated = 4,\n Cancelled = 5,\n Commented = 6,\n Expired = 7,\n StepAdvanced = 8\n}\n\n// ====================== DTOs ======================\n\nexport interface ApprovalDocumentSummaryDto {\n id: string;\n title: string;\n description?: string;\n thumbnailPath?: string;\n sourceAppId: string;\n referenceId: string;\n requestedByUserName: string;\n status: ApprovalDocumentStatus;\n currentStepOrder: number;\n totalSteps: number;\n currentStepName?: string;\n createdAt: string;\n completedAt?: string;\n}\n\nexport interface ApprovalStepDto {\n id: number;\n stepOrder: number;\n stepName: string;\n mode: ApprovalStepMode;\n assignedUserId: string;\n assignedUserName: string;\n delegatedToUserId?: string;\n delegatedToUserName?: string;\n status: ApprovalStepStatus;\n comment?: string;\n decidedAt?: string;\n deadlineAt?: string;\n}\n\nexport interface ApprovalReferenceDto {\n userId: string;\n userName: string;\n addedAt: string;\n}\n\nexport interface ApprovalDocumentDto {\n id: string;\n title: string;\n description?: string;\n contentPath: string;\n thumbnailPath?: string;\n sourceAppId: string;\n referenceId: string;\n templateId?: number;\n requestedByUserId: string;\n requestedByUserName: string;\n status: ApprovalDocumentStatus;\n currentStepOrder: number;\n callbackUrl?: string;\n createdAt: string;\n updatedAt: string;\n completedAt?: string;\n deadlineAt?: string;\n steps: ApprovalStepDto[];\n references: ApprovalReferenceDto[];\n}\n\nexport interface ApprovalHistoryDto {\n id: number;\n documentId: string;\n stepId?: number;\n action: ApprovalActionType;\n actorUserId: string;\n actorUserName: string;\n comment?: string;\n details?: string;\n timestamp: string;\n}\n\nexport interface ApprovalTemplateSummaryDto {\n id: number;\n name: string;\n description?: string;\n sourceAppId: string;\n stepCount: number;\n referenceCount: number;\n isActive: boolean;\n createdAt: string;\n}\n\nexport interface StepRoleDto {\n orgCode: string;\n positionLevel: string;\n orgName?: string;\n}\n\nexport interface RolePreviewUserDto {\n userId: string;\n fullName?: string;\n position?: string;\n department?: string;\n employeeCode?: string;\n}\n\nexport interface ApprovalTemplateStepDto {\n id: number;\n stepOrder: number;\n stepName: string;\n mode: ApprovalStepMode;\n deadlineHours?: number;\n assigneeUserIds: string[];\n roles: StepRoleDto[];\n}\n\nexport interface ApprovalTemplateDto {\n id: number;\n name: string;\n description?: string;\n sourceAppId: string;\n createdByUserId: string;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n steps: ApprovalTemplateStepDto[];\n referenceUserIds: string[];\n}\n\nexport interface ApprovalDashboardDto {\n pendingCount: number;\n approvedTodayCount: number;\n rejectedTodayCount: number;\n recentActivity: ApprovalDocumentSummaryDto[];\n}\n\nexport interface CreateApprovalResponseDto {\n documentId: string;\n message: string;\n}\n\n// ====================== Requests ======================\n\nexport interface ApprovalStepRequest {\n stepOrder: number;\n stepName: string;\n mode?: ApprovalStepMode;\n approverUserIds: string[];\n deadlineHours?: number;\n}\n\nexport interface CreateApprovalRequest {\n title: string;\n description?: string;\n contentHtml: string;\n thumbnailBase64?: string;\n referenceId: string;\n templateId?: number;\n requestedByUserId?: string;\n callbackUrl?: string;\n deadlineHours?: number;\n steps?: ApprovalStepRequest[];\n referenceUserIds?: string[];\n}\n\nexport interface ApproveRejectRequest {\n comment?: string;\n}\n\nexport interface DelegateRequest {\n toUserId: string;\n reason?: string;\n}\n\nexport interface CreateApprovalTemplateRequest {\n name: string;\n description?: string;\n sourceAppId: string;\n steps: ApprovalStepRequest[];\n referenceUserIds?: string[];\n}\n\nexport interface UpdateApprovalTemplateRequest {\n name: string;\n description?: string;\n steps: ApprovalStepRequest[];\n referenceUserIds?: string[];\n}\n\n// ====================== Submit Result ======================\n\nexport interface ApprovalSubmitResult {\n documentId: string;\n message: string;\n}\n","import {\n Component, Output, EventEmitter, OnInit, OnDestroy, inject, HostListener\n} from '@angular/core';\nimport { NgIf, NgFor, DatePipe } from '@angular/common';\nimport { Router } from '@angular/router';\nimport { MesAuthService, MesAuthConfig } from './mes-auth.service';\nimport { MaApprovalService } from './approval.service';\nimport { ApprovalDocumentSummaryDto, ApprovalDocumentStatus } from './approval.models';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { HttpClient } from '@angular/common/http';\n\ntype PanelTab = 'processing' | 'approved' | 'rejected';\n\n@Component({\n selector: 'ma-approval-panel',\n standalone: true,\n imports: [NgIf, NgFor, DatePipe],\n template: `\n <div class=\"approval-backdrop\" [class.open]=\"isOpen\" (click)=\"close()\"></div>\n <div class=\"approval-panel\" [class.open]=\"isOpen\">\n\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M9 11l3 3L22 4\"/>\n <path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"/>\n </svg>\n <h3>Approvals</h3>\n </div>\n <button class=\"close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs\">\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'processing'\" (click)=\"switchTab('processing')\">\n Processing\n <span class=\"tab-badge\" *ngIf=\"processingItems.length > 0\">{{ processingItems.length }}</span>\n </button>\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'approved'\" (click)=\"switchTab('approved')\">\n Approved\n </button>\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'rejected'\" (click)=\"switchTab('rejected')\">\n Rejected\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Loading -->\n <div class=\"loading-state\" *ngIf=\"loading\">\n <div class=\"spinner\"></div>\n <span>Loading...</span>\n </div>\n\n <!-- Processing tab -->\n <ng-container *ngIf=\"!loading && activeTab === 'processing'\">\n <div class=\"empty-state\" *ngIf=\"processingItems.length === 0\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" opacity=\"0.4\"><path d=\"M9 11l3 3L22 4\"/><path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"/></svg>\n <p>No pending approvals</p>\n </div>\n <div class=\"approval-item\" *ngFor=\"let item of processingItems\" (click)=\"navigateToDetail(item.id)\">\n <div class=\"item-title\">{{ item.title }}</div>\n <div class=\"item-meta\">\n <span class=\"item-requester\">By {{ item.requestedByUserName }}</span>\n <span class=\"item-step\" *ngIf=\"item.currentStepName\">· {{ item.currentStepName }}</span>\n </div>\n <div class=\"item-footer\">\n <span class=\"item-time\">{{ item.createdAt | date:'shortDate' }}</span>\n <span class=\"item-link\">View →</span>\n </div>\n </div>\n </ng-container>\n\n <!-- Approved tab -->\n <ng-container *ngIf=\"!loading && activeTab === 'approved'\">\n <div class=\"empty-state\" *ngIf=\"approvedItems.length === 0\">\n <p>No approved documents</p>\n </div>\n <div class=\"approval-item approved\" *ngFor=\"let item of approvedItems\" (click)=\"navigateToDetail(item.id)\">\n <div class=\"item-title\">{{ item.title }}</div>\n <div class=\"item-meta\">\n <span class=\"item-requester\">By {{ item.requestedByUserName }}</span>\n </div>\n <div class=\"item-footer\">\n <span class=\"status-badge approved-badge\">Approved</span>\n <span class=\"item-time\">{{ item.completedAt | date:'shortDate' }}</span>\n <span class=\"item-link\">View →</span>\n </div>\n </div>\n <div class=\"show-more\" *ngIf=\"approvedItems.length >= 10\" (click)=\"showMore('approved')\">\n Show more →\n </div>\n </ng-container>\n\n <!-- Rejected tab -->\n <ng-container *ngIf=\"!loading && activeTab === 'rejected'\">\n <div class=\"empty-state\" *ngIf=\"rejectedItems.length === 0\">\n <p>No rejected documents</p>\n </div>\n <div class=\"approval-item rejected\" *ngFor=\"let item of rejectedItems\" (click)=\"navigateToDetail(item.id)\">\n <div class=\"item-title\">{{ item.title }}</div>\n <div class=\"item-meta\">\n <span class=\"item-requester\">By {{ item.requestedByUserName }}</span>\n </div>\n <div class=\"item-footer\">\n <span class=\"status-badge rejected-badge\">Rejected</span>\n <span class=\"item-time\">{{ item.completedAt | date:'shortDate' }}</span>\n <span class=\"item-link\">View →</span>\n </div>\n </div>\n <div class=\"show-more\" *ngIf=\"rejectedItems.length >= 10\" (click)=\"showMore('rejected')\">\n Show more →\n </div>\n </ng-container>\n </div>\n </div>\n `,\n styleUrls: ['./panel-shared.css', './ma-approval-panel.component.css']\n})\nexport class MaApprovalPanelComponent implements OnInit, OnDestroy {\n @Output() approvalActioned = new EventEmitter<void>();\n\n isOpen = false;\n loading = false;\n activeTab: PanelTab = 'processing';\n\n processingItems: ApprovalDocumentSummaryDto[] = [];\n approvedItems: ApprovalDocumentSummaryDto[] = [];\n rejectedItems: ApprovalDocumentSummaryDto[] = [];\n\n private destroy$ = new Subject<void>();\n private mesAuth = inject(MesAuthService);\n private http = inject(HttpClient);\n private router = inject(Router);\n private approvalSvc: MaApprovalService | null = null;\n\n ngOnInit() {\n const config = this.mesAuth.getConfig();\n if (config) {\n this.approvalSvc = new MaApprovalService();\n this.approvalSvc.init(config, this.http);\n }\n\n this.mesAuth.approvalEvents$.pipe(takeUntil(this.destroy$)).subscribe(() => {\n if (this.isOpen) this.loadCurrentTab();\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n open() {\n this.isOpen = true;\n this.loadAllTabs();\n }\n\n close() {\n this.isOpen = false;\n }\n\n toggle() {\n if (this.isOpen) this.close();\n else this.open();\n }\n\n switchTab(tab: PanelTab) {\n this.activeTab = tab;\n this.loadCurrentTab();\n }\n\n private loadAllTabs() {\n this.loading = true;\n if (!this.approvalSvc) { this.loading = false; return; }\n\n let pending = 3;\n const done = () => { if (--pending === 0) this.loading = false; };\n\n this.approvalSvc.getPendingApprovals(1, 100).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => { this.processingItems = r.items; done(); },\n error: () => done()\n });\n\n this.approvalSvc.getMyRequests(1, 10, ApprovalDocumentStatus.Approved).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => { this.approvedItems = r.items; done(); },\n error: () => done()\n });\n\n this.approvalSvc.getMyRequests(1, 10, ApprovalDocumentStatus.Rejected).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => { this.rejectedItems = r.items; done(); },\n error: () => done()\n });\n }\n\n private loadCurrentTab() {\n if (!this.approvalSvc) return;\n\n if (this.activeTab === 'processing') {\n this.approvalSvc.getPendingApprovals(1, 100).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => this.processingItems = r.items,\n error: () => {}\n });\n } else if (this.activeTab === 'approved') {\n this.approvalSvc.getMyRequests(1, 10, ApprovalDocumentStatus.Approved).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => this.approvedItems = r.items,\n error: () => {}\n });\n } else {\n this.approvalSvc.getMyRequests(1, 10, ApprovalDocumentStatus.Rejected).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => this.rejectedItems = r.items,\n error: () => {}\n });\n }\n }\n\n navigateToDetail(id: string) {\n this.close();\n this.router.navigate(['/auth/approval/detail', id]);\n this.approvalActioned.emit();\n }\n\n showMore(status: 'approved' | 'rejected') {\n this.close();\n this.router.navigate(['/auth/approval/my-requests'], { queryParams: { status } });\n }\n}\n","import { Component, ViewChild, AfterViewInit } from '@angular/core';\nimport { ToastContainerComponent } from './toast-container.component';\nimport { UserProfileComponent } from './user-profile.component';\nimport { NotificationPanelComponent } from './notification-panel.component';\nimport { MaApprovalPanelComponent } from './ma-approval-panel.component';\n\n@Component({\n selector: 'ma-user',\n standalone: true,\n imports: [ToastContainerComponent, UserProfileComponent, NotificationPanelComponent, MaApprovalPanelComponent],\n template: `\n <ma-toast-container></ma-toast-container>\n <div class=\"user-header\">\n <ma-user-profile\n (notificationClick)=\"notificationPanel.open()\"\n (approvalClick)=\"approvalPanel.open()\">\n </ma-user-profile>\n </div>\n <ma-notification-panel #notificationPanel (notificationRead)=\"onNotificationRead()\"></ma-notification-panel>\n <ma-approval-panel #approvalPanel (approvalActioned)=\"onApprovalActioned()\"></ma-approval-panel>\n `,\n styles: [`\n .user-header {\n display: flex;\n justify-content: flex-end;\n }\n `]\n})\nexport class MaUserComponent implements AfterViewInit {\n @ViewChild(UserProfileComponent) userProfile?: UserProfileComponent;\n @ViewChild(MaApprovalPanelComponent) approvalPanel!: MaApprovalPanelComponent;\n\n ngAfterViewInit() {\n if (this.userProfile) {\n this.userProfile.loadUnreadCount();\n this.userProfile.loadPendingApprovalCount();\n }\n }\n\n onNotificationRead() {\n if (this.userProfile) {\n this.userProfile.loadUnreadCount();\n }\n }\n\n onApprovalActioned() {\n if (this.userProfile) {\n this.userProfile.loadPendingApprovalCount();\n }\n }\n}\n","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding } from '@angular/core';\nimport { NgIf } from '@angular/common';\nimport { MesAuthService } from './mes-auth.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n selector: 'ma-notification-badge',\n standalone: true,\n imports: [NgIf],\n template: `\n <button class=\"notification-btn\" (click)=\"onNotificationClick()\" title=\"Notifications\">\n <span class=\"icon\">🔔</span>\n <span class=\"badge\" *ngIf=\"unreadCount > 0\">{{ unreadCount }}</span>\n </button>\n `,\n styles: [`\n :host {\n --error-color: #f44336;\n }\n\n :host(.theme-dark) {\n --error-color: #ef5350;\n }\n\n .notification-btn {\n position: relative;\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n padding: 8px;\n transition: opacity 0.2s;\n }\n\n .notification-btn:hover {\n opacity: 0.7;\n }\n\n .icon {\n display: inline-block;\n }\n\n .badge {\n position: absolute;\n top: 0;\n right: 0;\n background-color: var(--error-color);\n color: white;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: bold;\n }\n `]\n})\nexport class NotificationBadgeComponent implements OnInit, OnDestroy {\n @Output() notificationClick = new EventEmitter<void>();\n @HostBinding('class') get themeClass(): string {\n return `theme-${this.currentTheme}`;\n }\n \n unreadCount = 0;\n currentTheme: Theme = 'light';\n private hasUser = false;\n private destroy$ = new Subject<void>();\n\n constructor(private authService: MesAuthService, private themeService: ThemeService) {}\n\n ngOnInit() {\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(theme => {\n this.currentTheme = theme;\n });\n\n this.authService.currentUser$\n .pipe(takeUntil(this.destroy$))\n .subscribe(user => {\n this.hasUser = !!user;\n if (!this.hasUser) {\n this.unreadCount = 0;\n return;\n }\n this.loadUnreadCount();\n });\n \n // Listen for new notifications\n this.authService.notifications$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n if (this.hasUser) {\n this.loadUnreadCount();\n }\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private loadUnreadCount() {\n if (!this.hasUser) {\n this.unreadCount = 0;\n return;\n }\n\n this.authService.getUnreadCount().subscribe({\n next: (response: any) => {\n this.unreadCount = response.unreadCount || 0;\n },\n error: (err) => console.error('Error loading unread count:', err)\n });\n }\n\n onNotificationClick() {\n this.notificationClick.emit();\n }\n}\n","import {\n Component, Input, Output, EventEmitter, OnInit, OnDestroy,\n ElementRef, ViewChild, HostBinding\n} from '@angular/core';\nimport { NgIf, NgFor } from '@angular/common';\nimport { MesAuthService, MesAuthConfig } from './mes-auth.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { MaApprovalService } from './approval.service';\nimport {\n ApprovalTemplateSummaryDto,\n ApprovalTemplateDto,\n ApprovalTemplateStepDto,\n RolePreviewUserDto,\n ApprovalStepRequest,\n ApprovalStepMode,\n CreateApprovalRequest,\n ApprovalSubmitResult\n} from './approval.models';\nimport { Subject, forkJoin, of } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { HttpClient } from '@angular/common/http';\nimport { inject } from '@angular/core';\n\n@Component({\n selector: 'ma-arv-container',\n standalone: true, \n template: `\n <div class=\"arv-container\">\n <!-- Content Area -->\n <div class=\"arv-content-body\" #contentBody>\n <ng-content></ng-content>\n </div>\n\n <!-- Approval Footer -->\n <div class=\"arv-footer\">\n @if (!isSubmitted) {\n <div class=\"arv-footer-inner\">\n\n <!-- Routing mode -->\n <div class=\"arv-routing\">\n <div class=\"arv-routing-header\">\n <h4 class=\"arv-section-title\">Approval Routing</h4>\n <!-- Show routing toggle only when templateId is NOT locked to a single template -->\n @if (!templateId || (templateIds && templateIds.length > 0)) {\n <div class=\"arv-routing-mode\">\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"template\" [checked]=\"routingMode === 'template'\" (change)=\"routingMode = 'template'\"> Use Template\n </label>\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"adhoc\" [checked]=\"routingMode === 'adhoc'\" (change)=\"routingMode = 'adhoc'\"> Custom Steps\n </label>\n </div>\n }\n </div>\n\n <!-- Locked template: only when templateId set and no multi-choice -->\n @if (templateId && (!templateIds || templateIds.length <= 1) && routingMode === 'template') {\n <div class=\"arv-template-select\">\n @if (loadingTemplate) {\n <div class=\"arv-template-loading\">Loading template...</div>\n }\n @if (selectedTemplate && !loadingTemplate) {\n <div class=\"arv-locked-template\">\n <span class=\"arv-locked-label\">Template</span>\n <span class=\"arv-locked-name\">{{ selectedTemplate.name }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Template selector: shown when no templateId, OR when templateIds has multiple choices -->\n @if ((!templateId || (templateIds && templateIds.length > 1)) && routingMode === 'template') {\n <div class=\"arv-template-select\">\n <label class=\"arv-label\">Select Template</label>\n <select class=\"arv-select\" (change)=\"onTemplateChange($event)\">\n <option value=\"\">-- Select a template --</option>\n @for (t of templates; track t.id) {\n <option [value]=\"t.id\" [selected]=\"t.id === selectedTemplateId\">{{ t.name }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Step pickers (shared for both locked and free template) -->\n @if (routingMode === 'template') {\n <div class=\"arv-template-select\">\n @if (!loadingTemplate && selectedTemplate) {\n <div class=\"arv-template-steps\">\n @for (s of selectedTemplate.steps; track s.stepOrder; let i = $index) {\n <div class=\"arv-step-card\">\n <div class=\"arv-step-card-header\">\n <span class=\"arv-step-preview-num\">Step {{ s.stepOrder }}</span>\n <span class=\"arv-step-preview-name\">{{ s.stepName }}</span>\n @if (s.roles && s.roles.length > 0) {\n <span class=\"arv-step-role-badge\">\n {{ s.roles[0].positionLevel }}{{ s.roles[0].orgName ? ' · ' + s.roles[0].orgName : '' }}\n </span>\n }\n </div>\n <!-- Selectable step: show approver picker -->\n @if (stepCandidates[i]?.length > 1 || stepLoadingCandidates[i]) {\n <div class=\"arv-step-picker\">\n @if (stepLoadingCandidates[i]) {\n <div class=\"arv-template-loading\">Loading candidates...</div>\n }\n @if (!stepLoadingCandidates[i]) {\n <select class=\"arv-select arv-select-sm\" (change)=\"onStepUserChange(i, $event)\">\n <option value=\"\">-- Select approver --</option>\n @for (u of stepCandidates[i]; track u.userId) {\n <option [value]=\"u.userId\" [selected]=\"u.userId === stepSelectedUsers[i]\">\n {{ u.fullName || u.userId }}{{ u.department ? ' · ' + u.department : '' }}{{ u.position ? ' (' + u.position + ')' : '' }}\n </option>\n }\n </select>\n }\n </div>\n }\n <!-- Single fixed-user step: show who is assigned -->\n @if (!stepLoadingCandidates[i] && stepCandidates[i]?.length === 1) {\n <div class=\"arv-step-fixed\">\n {{ stepCandidates[i][0].fullName || stepCandidates[i][0].userId }}{{ stepCandidates[i][0].department ? ' · ' + stepCandidates[i][0].department : '' }}{{ stepCandidates[i][0].position ? ' (' + stepCandidates[i][0].position + ')' : '' }}\n </div>\n }\n </div>\n }\n @if (selectedTemplate.referenceUserIds.length > 0) {\n <div class=\"arv-step-preview arv-step-preview-cc\">\n <span class=\"arv-step-preview-num\">CC</span>\n <span class=\"arv-step-preview-name\">{{ selectedTemplate.referenceUserIds.length }} reference user(s) from template</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Ad-hoc steps -->\n @if (routingMode === 'adhoc') {\n <div class=\"arv-steps\">\n @for (step of adHocSteps; track step.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-header\">\n <span class=\"arv-step-num\">Step {{ i + 1 }}</span>\n <input class=\"arv-input\" [value]=\"step.stepName\" (input)=\"step.stepName = $any($event.target).value\" placeholder=\"Step name\" />\n <button class=\"arv-btn-icon arv-btn-danger\" (click)=\"removeStep(i)\" title=\"Remove step\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>\n </button>\n </div>\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @for (uid of step.approverUserIds; track uid; let j = $index) {\n <span class=\"arv-tag\">\n {{ userLabelMap[uid] || uid }}\n <button class=\"arv-tag-remove\" (click)=\"removeApprover(i, j)\">x</button>\n </span>\n }\n </div>\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"userSearchQuery[i] || ''\"\n (input)=\"onUserSearchInput(i, $any($event.target).value)\"\n placeholder=\"Search approver...\" />\n @if (userSearchResults[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of userSearchResults[i]; track u.id) {\n <div class=\"arv-search-item\" (click)=\"addApprover(i, u.id)\">\n {{ u.fullName || u.userName }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n <button class=\"arv-btn arv-btn-outline\" (click)=\"addStep()\">+ Add Step</button>\n </div>\n }\n </div>\n\n <!-- Reference / CC users -->\n <div class=\"arv-references\">\n <h4 class=\"arv-section-title\">CC / Reference</h4>\n <p class=\"arv-hint\">These users will be notified when the approval completes, but won't be asked to approve.</p>\n <div class=\"arv-approver-tags\">\n @for (uid of referenceUserIds; track uid; let j = $index) {\n <span class=\"arv-tag\">\n {{ userLabelMap[uid] || uid }}\n <button class=\"arv-tag-remove\" (click)=\"removeReference(j)\">x</button>\n </span>\n }\n </div>\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"refSearchQuery\"\n (input)=\"onRefSearchInput($any($event.target).value)\"\n placeholder=\"Search CC user...\" />\n @if (refSearchResults?.length) {\n <div class=\"arv-search-results\">\n @for (u of refSearchResults; track u.id) {\n <div class=\"arv-search-item\" (click)=\"addReference(u.id)\">\n {{ u.fullName || u.userName }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"arv-actions\">\n <button class=\"arv-btn arv-btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"arv-btn arv-btn-primary\" [disabled]=\"submitting\" (click)=\"submit()\">\n @if (submitting) {\n <span class=\"arv-spinner\"></span>\n }\n {{ submitting ? 'Submitting...' : 'Submit for Approval' }}\n </button>\n </div>\n\n @if (errorMessage) {\n <div class=\"arv-error\">{{ errorMessage }}</div>\n }\n </div>\n }\n </div>\n\n <!-- Success state -->\n @if (isSubmitted) {\n <div class=\"arv-success\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#66bb6a\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n <p>Submitted for approval successfully.</p>\n </div>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n --arv-primary: #90caf9;\n --arv-primary-hover: #64b5f6;\n --arv-success: #66bb6a;\n --arv-danger: #ef5350;\n --arv-text: #e0e0e0;\n --arv-text-muted: #9e9e9e;\n --arv-bg: #1e1e2e;\n --arv-bg2: #27273a;\n --arv-border: #383850;\n --arv-radius: 8px;\n }\n :host(.theme-light) {\n --arv-primary: #1565c0;\n --arv-primary-hover: #0d47a1;\n --arv-success: #2e7d32;\n --arv-danger: #c62828;\n --arv-text: #212121;\n --arv-text-muted: #616161;\n --arv-bg: #ffffff;\n --arv-bg2: #f5f5f5;\n --arv-border: #e0e0e0;\n }\n\n .arv-container { display: flex; flex-direction: column; height: 100%; }\n .arv-content-body { flex: 1; overflow: auto; }\n .arv-footer { border-top: 1px solid var(--arv-border); background: var(--arv-bg2); }\n .arv-footer-inner { padding: 16px; display: flex; flex-direction: column; gap: 14px; }\n\n .arv-section-title { margin: 0 0 8px; font-size: 13px; font-weight: 700; color: var(--arv-primary); text-transform: uppercase; letter-spacing: 0.5px; }\n .arv-routing-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; }\n .arv-routing-mode { display: flex; gap: 12px; }\n .arv-radio { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--arv-text); cursor: pointer; }\n\n .arv-label { font-size: 12px; color: var(--arv-text-muted); display: block; margin-bottom: 4px; }\n .arv-select { width: 100%; padding: 8px 10px; border: 1px solid var(--arv-border); border-radius: var(--arv-radius); background: var(--arv-bg); color: var(--arv-text); font-size: 13px; }\n .arv-input { padding: 7px 10px; border: 1px solid var(--arv-border); border-radius: var(--arv-radius); background: var(--arv-bg); color: var(--arv-text); font-size: 13px; }\n .arv-input-sm { width: 100%; margin-top: 4px; }\n\n .arv-steps { display: flex; flex-direction: column; gap: 10px; }\n .arv-step { background: var(--arv-bg); border: 1px solid var(--arv-border); border-radius: var(--arv-radius); padding: 10px; }\n .arv-step-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }\n .arv-step-num { font-size: 12px; font-weight: 700; color: var(--arv-primary); min-width: 44px; }\n\n .arv-approver-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }\n .arv-tag { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; background: rgba(144,202,249,0.12); border: 1px solid rgba(144,202,249,0.3); border-radius: 12px; font-size: 12px; color: var(--arv-primary); }\n .arv-tag-remove { background: none; border: none; cursor: pointer; color: var(--arv-text-muted); font-size: 11px; padding: 0 2px; line-height: 1; }\n .arv-tag-remove:hover { color: var(--arv-danger); }\n\n .arv-user-search { position: relative; }\n .arv-search-results { position: absolute; left: 0; right: 0; z-index: 100; background: var(--arv-bg2); border: 1px solid var(--arv-border); border-radius: var(--arv-radius); max-height: 150px; overflow-y: auto; }\n .arv-search-item { padding: 8px 12px; cursor: pointer; font-size: 13px; color: var(--arv-text); }\n .arv-search-item:hover { background: var(--arv-bg); }\n\n .arv-hint { font-size: 12px; color: var(--arv-text-muted); margin: 0 0 8px; }\n\n .arv-btn-icon { background: none; border: none; cursor: pointer; padding: 2px; border-radius: 4px; display: inline-flex; align-items: center; justify-content: center; }\n .arv-btn-danger { color: var(--arv-danger); }\n .arv-btn-danger:hover { background: rgba(239,83,80,0.1); }\n\n .arv-actions { display: flex; justify-content: flex-end; gap: 10px; }\n .arv-btn { padding: 9px 18px; border-radius: var(--arv-radius); font-size: 13px; font-weight: 600; cursor: pointer; border: none; transition: background 0.15s; }\n .arv-btn-primary { background: var(--arv-primary); color: #fff; }\n .arv-btn-primary:hover:not(:disabled) { background: var(--arv-primary-hover); }\n .arv-btn-primary:disabled { opacity: 0.6; cursor: not-allowed; }\n .arv-btn-secondary { background: transparent; border: 1px solid var(--arv-border); color: var(--arv-text-muted); }\n .arv-btn-secondary:hover { color: var(--arv-text); border-color: var(--arv-text-muted); }\n .arv-btn-outline { background: transparent; border: 1px dashed var(--arv-border); color: var(--arv-text-muted); font-size: 12px; padding: 6px 12px; }\n .arv-btn-outline:hover { border-color: var(--arv-primary); color: var(--arv-primary); }\n\n .arv-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-top-color: #fff; border-radius: 50%; animation: arv-spin 0.6s linear infinite; margin-right: 6px; }\n @keyframes arv-spin { to { transform: rotate(360deg); } }\n\n .arv-error { padding: 8px 12px; background: rgba(239,83,80,0.1); border: 1px solid rgba(239,83,80,0.3); border-radius: var(--arv-radius); font-size: 13px; color: var(--arv-danger); }\n\n .arv-success { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 32px; gap: 12px; text-align: center; }\n .arv-success p { color: var(--arv-success); font-size: 15px; font-weight: 600; margin: 0; }\n\n .arv-references { border-top: 1px solid var(--arv-border); padding-top: 12px; }\n\n .arv-template-loading { font-size: 12px; color: var(--arv-text-muted); margin-top: 8px; padding: 4px 0; }\n .arv-template-steps { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }\n\n .arv-step-card { background: var(--arv-bg); border: 1px solid var(--arv-border); border-radius: var(--arv-radius); overflow: hidden; }\n .arv-step-card-header { display: flex; align-items: center; gap: 8px; padding: 7px 10px; background: rgba(0,0,0,0.03); border-bottom: 1px solid var(--arv-border); flex-wrap: wrap; }\n .arv-step-preview { display: flex; align-items: center; gap: 8px; padding: 5px 8px; background: var(--arv-bg); border: 1px solid var(--arv-border); border-radius: 4px; font-size: 12px; }\n .arv-step-preview-num { font-weight: 700; color: var(--arv-primary); min-width: 44px; flex-shrink: 0; font-size: 12px; }\n .arv-step-preview-name { flex: 1; color: var(--arv-text); font-size: 12px; font-weight: 600; }\n .arv-step-role-badge { font-size: 11px; color: var(--arv-text-muted); background: rgba(144,202,249,0.1); border: 1px solid rgba(144,202,249,0.25); border-radius: 10px; padding: 1px 7px; }\n .arv-step-preview-cc .arv-step-preview-num { color: var(--arv-text-muted); }\n\n .arv-locked-template { display: flex; align-items: center; gap: 8px; padding: 7px 10px; background: var(--arv-bg); border: 1px solid var(--arv-border); border-radius: var(--arv-radius); margin-top: 6px; }\n .arv-locked-label { font-size: 11px; color: var(--arv-text-muted); text-transform: uppercase; letter-spacing: 0.5px; flex-shrink: 0; }\n .arv-locked-name { font-size: 13px; font-weight: 600; color: var(--arv-text); }\n\n .arv-step-picker { padding: 8px 10px; }\n .arv-select-sm { font-size: 12px; padding: 6px 8px; }\n .arv-step-fixed { padding: 6px 10px; font-size: 12px; color: var(--arv-text-muted); }\n `]\n})\nexport class MaArvContainerComponent implements OnInit, OnDestroy {\n @Input() title = '';\n @Input() description?: string;\n @Input() referenceId = '';\n @Input() templateId?: number;\n @Input() templateIds?: number[];\n @Input() callbackUrl?: string;\n @Input() deadlineHours?: number;\n\n @Output() approvalSubmitted = new EventEmitter<ApprovalSubmitResult>();\n @Output() approvalSubmitting = new EventEmitter<void>();\n @Output() cancelled = new EventEmitter<void>();\n\n @ViewChild('contentBody', { static: true }) contentBody!: ElementRef<HTMLElement>;\n\n routingMode: 'template' | 'adhoc' = 'template';\n templates: ApprovalTemplateSummaryDto[] = [];\n selectedTemplateId: number | null = null;\n selectedTemplate: ApprovalTemplateDto | null = null;\n loadingTemplate = false;\n\n // Per-step role candidates and selected user\n stepCandidates: RolePreviewUserDto[][] = [];\n stepLoadingCandidates: boolean[] = [];\n stepSelectedUsers: string[] = [];\n adHocSteps: ApprovalStepRequest[] = [];\n\n referenceUserIds: string[] = [];\n refSearchQuery = '';\n refSearchResults: any[] = [];\n\n userSearchQuery: string[] = [];\n userSearchResults: any[][] = [];\n\n submitting = false;\n isSubmitted = false;\n errorMessage = '';\n userLabelMap: Record<string, string> = {};\n\n @HostBinding('class') get themeClass(): string { return `theme-${this.currentTheme}`; }\n currentTheme: Theme = 'light';\n\n private destroy$ = new Subject<void>();\n private mesAuth = inject(MesAuthService);\n private themeService = inject(ThemeService);\n private approvalSvc: MaApprovalService | null = null;\n private http = inject(HttpClient);\n\n ngOnInit() {\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(t => this.currentTheme = t);\n\n const config = this.mesAuth.getConfig();\n if (config) {\n this.approvalSvc = new MaApprovalService();\n this.approvalSvc.init(config, this.http);\n this.loadTemplates();\n }\n this.addStep();\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private loadTemplates() {\n this.approvalSvc!.getTemplates().pipe(takeUntil(this.destroy$)).subscribe({\n next: (t) => {\n \n if (this.templateIds && this.templateIds.length > 0) \n t = t.filter(temp => this.templateIds!.includes(temp.id)); \n\n this.templates = t;\n if (this.templateId != null && this.selectedTemplateId == null) {\n this.selectedTemplateId = this.templateId;\n this.loadTemplateDetail(this.templateId);\n }\n },\n error: () => {}\n });\n }\n\n private loadTemplateDetail(id: number) {\n this.loadingTemplate = true;\n this.selectedTemplate = null;\n this.stepCandidates = [];\n this.stepLoadingCandidates = [];\n this.stepSelectedUsers = [];\n this.approvalSvc!.getTemplate(id).pipe(takeUntil(this.destroy$)).subscribe({\n next: (t) => {\n this.selectedTemplate = t;\n this.loadingTemplate = false;\n this.loadStepCandidates(t.steps);\n },\n error: () => { this.loadingTemplate = false; }\n });\n }\n\n private loadStepCandidates(steps: ApprovalTemplateStepDto[]) {\n this.stepCandidates = steps.map(() => []);\n this.stepLoadingCandidates = steps.map(() => false);\n this.stepSelectedUsers = steps.map(() => '');\n\n const config = this.mesAuth.getConfig();\n\n steps.forEach((step, i) => {\n if (step.roles && step.roles.length > 0) {\n // Role-based: fetch candidates via role preview\n this.stepLoadingCandidates[i] = true;\n const calls = step.roles.map(r => this.approvalSvc!.previewRole(r.orgCode, r.positionLevel));\n forkJoin(calls.length > 0 ? calls : [of([] as RolePreviewUserDto[])])\n .pipe(takeUntil(this.destroy$))\n .subscribe({\n next: results => {\n const merged = new Map<string, RolePreviewUserDto>();\n results.forEach(list => list.forEach(u => merged.set(u.userId, u)));\n this.stepCandidates[i] = Array.from(merged.values());\n // Single candidate — pre-select automatically\n if (this.stepCandidates[i].length === 1) {\n this.stepSelectedUsers[i] = this.stepCandidates[i][0].userId;\n }\n this.stepLoadingCandidates[i] = false;\n },\n error: () => { this.stepLoadingCandidates[i] = false; }\n });\n } else if (step.assigneeUserIds && step.assigneeUserIds.length > 0 && config) {\n // Search-selected employees: resolve IDs to display names\n this.stepLoadingCandidates[i] = true;\n const base = config.apiBaseUrl.replace(/\\/$/, '');\n const opts = { withCredentials: config.withCredentials ?? true };\n const calls = step.assigneeUserIds.map(uid =>\n this.http.get<any>(`${base}/urs/users/${encodeURIComponent(uid)}`, opts)\n );\n forkJoin(calls)\n .pipe(takeUntil(this.destroy$))\n .subscribe({\n next: results => {\n this.stepCandidates[i] = results.map((u: any) => ({\n userId: u.id || u.Id,\n fullName: u.fullName || u.FullName || u.userName || u.UserName,\n department: u.department || u.Department,\n position: u.position || u.Position\n } as RolePreviewUserDto));\n // Single assignee — pre-select automatically\n if (this.stepCandidates[i].length === 1) {\n this.stepSelectedUsers[i] = this.stepCandidates[i][0].userId;\n }\n this.stepLoadingCandidates[i] = false;\n },\n error: () => { this.stepLoadingCandidates[i] = false; }\n });\n }\n });\n }\n\n onStepUserChange(stepIndex: number, event: Event) {\n this.stepSelectedUsers[stepIndex] = (event.target as HTMLSelectElement).value;\n }\n\n onTemplateChange(event: Event) {\n const val = (event.target as HTMLSelectElement).value;\n this.selectedTemplateId = val ? parseInt(val, 10) : null;\n this.selectedTemplate = null;\n if (this.selectedTemplateId) {\n this.loadTemplateDetail(this.selectedTemplateId);\n }\n }\n\n addStep() {\n const order = this.adHocSteps.length + 1;\n this.adHocSteps.push({ stepOrder: order, stepName: `Step ${order}`, approverUserIds: [] });\n this.userSearchQuery.push('');\n this.userSearchResults.push([]);\n }\n\n removeStep(i: number) {\n this.adHocSteps.splice(i, 1);\n this.userSearchQuery.splice(i, 1);\n this.userSearchResults.splice(i, 1);\n this.adHocSteps.forEach((s, idx) => s.stepOrder = idx + 1);\n }\n\n addApprover(stepIndex: number, userId: string) {\n if (!this.adHocSteps[stepIndex].approverUserIds.includes(userId)) {\n this.adHocSteps[stepIndex].approverUserIds.push(userId);\n }\n this.storeLabelFromResults(userId, this.userSearchResults[stepIndex]);\n this.userSearchQuery[stepIndex] = '';\n this.userSearchResults[stepIndex] = [];\n }\n\n removeApprover(stepIndex: number, approverIndex: number) {\n this.adHocSteps[stepIndex].approverUserIds.splice(approverIndex, 1);\n }\n\n addReference(userId: string) {\n if (!this.referenceUserIds.includes(userId)) {\n this.referenceUserIds.push(userId);\n }\n this.storeLabelFromResults(userId, this.refSearchResults);\n this.refSearchQuery = '';\n this.refSearchResults = [];\n }\n\n private storeLabelFromResults(userId: string, results: any[]) {\n const user = results.find((u: any) => u.id === userId);\n if (user) {\n const parts = [user.department, user.position, user.fullName].filter(Boolean);\n this.userLabelMap[userId] = parts.length > 0 ? parts.join(' - ') : (user.userName || userId);\n }\n }\n\n removeReference(j: number) {\n this.referenceUserIds.splice(j, 1);\n }\n\n onUserSearchInput(stepIndex: number, query: string) {\n this.userSearchQuery[stepIndex] = query;\n if (!query || query.length < 2) { this.userSearchResults[stepIndex] = []; return; }\n this.searchUsers(query).then(r => this.userSearchResults[stepIndex] = r);\n }\n\n onRefSearchInput(query: string) {\n this.refSearchQuery = query;\n if (!query || query.length < 2) { this.refSearchResults = []; return; }\n this.searchUsers(query).then(r => this.refSearchResults = r);\n }\n\n private searchUsers(query: string): Promise<any[]> {\n const config = this.mesAuth.getConfig();\n if (!config) return Promise.resolve([]);\n const url = `${config.apiBaseUrl.replace(/\\/$/, '')}/urs/users?search=${encodeURIComponent(query)}&page=1&pageSize=20`;\n return this.http.get<any>(url, { withCredentials: config.withCredentials ?? true })\n .toPromise()\n .then((r: any) => {\n const items = r?.data || r?.Data || r?.items || r || [];\n // Normalize PascalCase to camelCase for template binding\n return (Array.isArray(items) ? items : []).map((u: any) => ({\n id: u.id || u.Id,\n userName: u.userName || u.UserName,\n fullName: u.fullName || u.FullName,\n email: u.email || u.Email,\n department: u.department || u.Department,\n position: u.position || u.Position\n }));\n })\n .catch(() => []);\n }\n\n async submit() {\n if (this.submitting) return;\n this.errorMessage = '';\n\n if (!this.approvalSvc) { this.errorMessage = 'Approval service not initialized. Ensure provideMesAuth() is configured.'; return; }\n if (!this.referenceId) { this.errorMessage = 'ReferenceId is required.'; return; }\n if (!this.title) { this.errorMessage = 'Title is required.'; return; }\n\n if (this.routingMode === 'template' && !this.selectedTemplateId && !this.templateId) {\n this.errorMessage = 'Please select a template or switch to Custom Steps.'; return;\n }\n if (this.routingMode === 'adhoc' && this.adHocSteps.length === 0) {\n this.errorMessage = 'Please add at least one approval step.'; return;\n }\n // Validate selectable steps (role-based or multi-assignee) have a selected approver\n if (this.routingMode === 'template' && this.selectedTemplate) {\n for (let i = 0; i < this.selectedTemplate.steps.length; i++) {\n const step = this.selectedTemplate.steps[i];\n const isSelectable = (this.stepCandidates[i]?.length ?? 0) > 1;\n if (isSelectable && !this.stepSelectedUsers[i]) {\n this.errorMessage = `Please select an approver for step \"${step.stepName}\".`; return;\n }\n }\n }\n\n // Emit before capture so parent can hide edit controls (inputs, buttons)\n // then wait one tick for Angular CD to update the DOM before snapshotting\n this.approvalSubmitting.emit();\n await new Promise(resolve => setTimeout(resolve));\n\n this.submitting = true;\n\n try {\n const contentHtml = await this.captureContent();\n const thumbnailBase64 = await this.captureThumbnail().catch(() => undefined);\n\n const request: CreateApprovalRequest = {\n title: this.title,\n description: this.description,\n contentHtml,\n thumbnailBase64,\n referenceId: this.referenceId,\n callbackUrl: this.callbackUrl,\n deadlineHours: this.deadlineHours,\n referenceUserIds: this.referenceUserIds.length > 0 ? this.referenceUserIds : undefined\n };\n\n if (this.routingMode === 'template') {\n request.templateId = this.selectedTemplateId ?? this.templateId;\n // If template has role-based steps with selected approvers, pass explicit steps\n if (this.selectedTemplate) {\n const hasSelectableSteps = this.selectedTemplate.steps.some(\n (s, i) => (this.stepCandidates[i]?.length ?? 0) > 0\n );\n if (hasSelectableSteps) {\n request.steps = this.selectedTemplate.steps.map((s, i) => ({\n stepOrder: s.stepOrder,\n stepName: s.stepName,\n mode: s.mode,\n approverUserIds: this.stepSelectedUsers[i]\n ? [this.stepSelectedUsers[i]]\n : (this.stepCandidates[i] && this.stepCandidates[i].length > 0\n ? this.stepCandidates[i].map(u => u.userId)\n : s.assigneeUserIds)\n }));\n }\n }\n } else {\n request.steps = this.adHocSteps.map((s, i) => ({\n stepOrder: i + 1,\n stepName: s.stepName,\n mode: ApprovalStepMode.Sequential,\n approverUserIds: s.approverUserIds\n }));\n }\n\n this.approvalSvc!.createApproval(request).pipe(takeUntil(this.destroy$)).subscribe({\n next: (result) => {\n this.isSubmitted = true;\n this.submitting = false;\n this.approvalSubmitted.emit({ documentId: result.documentId, message: result.message });\n },\n error: (err) => {\n this.submitting = false;\n this.errorMessage = err?.error?.message || 'Failed to submit approval. Please try again.';\n }\n });\n } catch (err: any) {\n this.submitting = false;\n this.errorMessage = err?.message || 'Failed to capture content.';\n }\n }\n\n onCancel() {\n this.cancelled.emit();\n }\n\n // ====================== Content Capture ======================\n\n async captureContent(): Promise<string> {\n const host = this.contentBody.nativeElement;\n\n // Step 1: Build canvas -> img map from the live DOM\n const canvasMap = new Map<Element, HTMLImageElement>();\n host.querySelectorAll('canvas').forEach((canvas) => {\n try {\n const img = document.createElement('img');\n img.src = (canvas as HTMLCanvasElement).toDataURL('image/png');\n img.style.width = canvas.offsetWidth + 'px';\n img.style.height = canvas.offsetHeight + 'px';\n canvasMap.set(canvas, img);\n } catch {}\n });\n\n // Step 2: Deep clone\n const clone = host.cloneNode(true) as HTMLElement;\n\n // Step 3: Replace canvas nodes in clone with img snapshots\n const originalCanvases = Array.from(host.querySelectorAll('canvas'));\n clone.querySelectorAll('canvas').forEach((cloneCanvas, idx) => {\n const img = canvasMap.get(originalCanvases[idx]);\n if (img) cloneCanvas.replaceWith(img.cloneNode(true));\n });\n\n // Step 4: Inline all <img> sources as base64 data URIs for content integrity\n const imgElements = Array.from(clone.querySelectorAll('img')) as HTMLImageElement[];\n await Promise.all(imgElements.map(async (img) => {\n const src = img.getAttribute('src');\n if (!src || src.startsWith('data:')) return;\n try {\n const resp = await fetch(src, { mode: 'cors', credentials: 'same-origin' });\n if (!resp.ok) return;\n const blob = await resp.blob();\n const dataUri = await new Promise<string>((resolve) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.readAsDataURL(blob);\n });\n img.setAttribute('src', dataUri);\n } catch { /* keep original src if fetch fails */ }\n }));\n\n // Step 5: Inline only essential layout styles (skip colors, widths, cursors)\n const liveElements = Array.from(host.querySelectorAll('*'));\n const cloneElements = Array.from(clone.querySelectorAll('*'));\n const styleProps = this.getStyleProperties();\n\n liveElements.forEach((liveEl, i) => {\n const cloneEl = cloneElements[i] as HTMLElement;\n if (!cloneEl || typeof cloneEl.setAttribute !== 'function') return;\n try {\n const computed = window.getComputedStyle(liveEl as Element);\n const styles: string[] = [];\n styleProps.forEach(prop => {\n const val = computed.getPropertyValue(prop);\n if (val && val !== '' && val !== 'initial' && val !== 'normal' && val !== 'none' && val !== 'auto') {\n styles.push(`${prop}:${val}`);\n }\n });\n if (styles.length) cloneEl.setAttribute('style', styles.join(';'));\n } catch {}\n });\n\n // Step 6: Strip scripts, Angular attributes, style/link tags, and form elements\n clone.querySelectorAll('script, link, style').forEach(el => el.remove());\n clone.querySelectorAll('*').forEach(el => {\n // Remove Angular-specific attributes\n Array.from(el.attributes).forEach(attr => {\n if (attr.name.startsWith('_ngcontent-') ||\n attr.name.startsWith('_nghost-') ||\n attr.name.startsWith('ng-reflect-') ||\n attr.name.startsWith('ng-version') ||\n attr.name.startsWith('on') ||\n attr.name === 'cformcontrol' ||\n attr.name === 'clabel') {\n el.removeAttribute(attr.name);\n }\n });\n // Remove class attribute (framework-specific classes add no value)\n el.removeAttribute('class');\n });\n\n // Step 7: Wrap in a clean, print-friendly HTML document\n return `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <style>\n *, *::before, *::after { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n margin: 0; padding: 24px;\n color: #212121; background: #fff;\n font-size: 14px; line-height: 1.6;\n max-width: 210mm;\n }\n h1, h2, h3, h4, h5, h6 { color: #1565c0; margin: 0 0 12px; }\n p { margin: 0 0 8px; }\n img { max-width: 100%; }\n table { border-collapse: collapse; width: 100%; }\n td, th { padding: 8px 12px; border: 1px solid #ddd; text-align: left; vertical-align: top; }\n input, textarea, select { \n border: 1px solid #ccc; border-radius: 4px; padding: 6px 10px;\n font-size: 14px; width: 100%; background: #fafafa; color: #333;\n }\n label { font-weight: 500; display: block; margin-bottom: 4px; color: #333; }\n div { max-width: 100%; }\n </style>\n</head>\n<body>\n${clone.outerHTML}\n</body>\n</html>`;\n }\n\n private async captureThumbnail(): Promise<string | undefined> {\n const html2canvas = (window as any)['html2canvas'];\n if (!html2canvas) return undefined;\n\n const canvas: HTMLCanvasElement = await html2canvas(this.contentBody.nativeElement, {\n scale: 1, useCORS: true, logging: false, width: 600, height: 400\n });\n return canvas.toDataURL('image/png').split(',')[1];\n }\n\n private getStyleProperties(): string[] {\n // Only capture essential layout/typography — NOT colors, widths, or cursor styles\n // Colors and backgrounds are handled by the clean document stylesheet instead\n return [\n 'font-size', 'font-weight', 'font-style', 'line-height', 'text-align', 'text-decoration',\n 'border', 'border-top', 'border-right', 'border-bottom', 'border-left',\n 'border-width', 'border-style', 'border-radius',\n 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left',\n 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left',\n 'display', 'flex-direction', 'flex-wrap', 'justify-content', 'align-items', 'gap',\n 'vertical-align', 'table-layout', 'border-collapse', 'border-spacing',\n 'text-transform', 'letter-spacing', 'white-space', 'word-break'\n ];\n }\n}\n","import { HttpResponse } from '@angular/common/http';\nimport { map } from 'rxjs/operators';\nimport { OperatorFunction } from 'rxjs';\n\nexport interface PermissionHeader {\n resource: string;\n allowedActions: string[];\n}\n// ─── Utility: extract allowedActions from x-ma-perm header ───\n \nexport const ALL_ACTIONS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'WEBSOCKET'] as const;\n\nexport function extractXMaPerm(response: HttpResponse<unknown>): string[] {\n const raw = response.headers.get('x-ma-perm');\n if (!raw) return [];\n \n try {\n const parsed = JSON.parse(raw) as PermissionHeader;\n const actions = parsed?.allowedActions ?? [];\n // Wildcard means all actions are allowed\n if (actions.includes('*')) return [...ALL_ACTIONS];\n return actions;\n } catch {\n return [];\n }\n}\n \n// ─── RxJS operator: pipe it on any HttpClient call ───\n \nexport function withXMaPerm<T>(): OperatorFunction<\n HttpResponse<T>,\n { data: T; allowedActions: string[] }\n> {\n return map((response: HttpResponse<T>) => ({\n data: response.body as T,\n allowedActions: extractXMaPerm(response),\n }));\n}","import { inject } from '@angular/core';\nimport { rxResource } from '@angular/core/rxjs-interop';\nimport { HttpClient, HttpParams } from '@angular/common/http';\nimport { withXMaPerm } from './x-ma-perm.pipe';\n\nexport interface RequestConfig {\n url: string;\n params?: HttpParams | Record<string, string | string[]>;\n}\n\nexport function xMaResource<T>(request: () => RequestConfig) {\n const http = inject(HttpClient);\n\n return rxResource({\n params: () => request(),\n stream: ({ params: { url, params } }) =>\n http\n .get<T>(url, { observe: 'response', params })\n .pipe(withXMaPerm()),\n });\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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"}
|
|
1
|
+
{"version":3,"file":"mesauth-angular.mjs","sources":["../../src/ma-ui-config.service.ts","../../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/user-profile.component.html","../../src/toast.service.ts","../../src/toast-container.component.ts","../../src/toast-container.component.html","../../src/notification-panel.component.ts","../../src/notification-panel.component.html","../../src/approval.service.ts","../../src/approval.models.ts","../../src/ma-approval-panel.component.ts","../../src/ma-approval-panel.component.html","../../src/ma-user.component.ts","../../src/ma-user.component.html","../../src/notification-badge.component.ts","../../src/notification-badge.component.html","../../src/ma-arv-container.component.ts","../../src/ma-arv-container.component.html","../../src/x-ma-perm.pipe.ts","../../src/x-ma-resource.ts","../../src/ma-icon.component.ts","../../src/ma-theme.directive.ts","../../src/index.ts","../../src/mesauth-angular.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { catchError, of } from 'rxjs';\n\nexport interface MaUiManifest {\n /** Version of the package that created this manifest. */\n version: string;\n /** Latest published package version — library logs a warning if installed version is older. */\n latestPackageVersion?: string;\n /** Set true to show an upgrade banner inside components. */\n updateRequired?: boolean;\n /** URL override for the theme CSS (defaults to themes/default.css relative to assetsUrl). */\n themeUrl?: string;\n /** URL override for the SVG icon sprite. */\n iconSpriteUrl?: string;\n /** UI string overrides — keys match component label identifiers. */\n labels?: Record<string, string>;\n /** Feature flags read by components at runtime. */\n features?: Record<string, boolean>;\n}\n\n/** Current installed package version — keep in sync with package.json. */\nconst PACKAGE_VERSION = '1.8.1';\n\n/**\n * Provides server-driven UI configuration loaded from the hosted manifest.\n * Components read `labels()` and `features()` signals instead of hardcoded strings.\n * Update manifest.json on the server to change labels or toggle features without\n * republishing the npm package.\n */\n@Injectable({ providedIn: 'root' })\nexport class MaUiConfigService {\n private _labels = signal<Record<string, string>>({});\n private _features = signal<Record<string, boolean>>({\n showApprovalPanel: true,\n showNotificationPanel: true\n });\n private _updateRequired = signal(false);\n\n /** Reactive map of UI string overrides from the server manifest. */\n readonly labels = this._labels.asReadonly();\n /** Reactive map of feature flags from the server manifest. */\n readonly features = this._features.asReadonly();\n /** True when the server signals that a package upgrade is needed. */\n readonly updateRequired = this._updateRequired.asReadonly();\n\n /**\n * Returns a label by key, falling back to `defaultValue` when the server\n * manifest has not provided an override.\n */\n label(key: string, defaultValue: string): string {\n return this._labels()[key] ?? defaultValue;\n }\n\n /**\n * Returns a feature flag by key, falling back to `defaultValue`.\n */\n feature(key: string, defaultValue = true): boolean {\n const val = this._features()[key];\n return val !== undefined ? val : defaultValue;\n }\n\n /**\n * Called by MesAuthService.init() — fetches the manifest and applies any\n * label/feature overrides. Failures are silently ignored so the library\n * works without a manifest endpoint.\n */\n loadManifest(assetsUrl: string, http: HttpClient): void {\n http.get<MaUiManifest>(`${assetsUrl}/manifest.json`).pipe(\n catchError(() => of(null))\n ).subscribe(manifest => {\n if (!manifest) return;\n\n if (manifest.labels) this._labels.set(manifest.labels);\n if (manifest.features) this._features.update(f => ({ ...f, ...manifest.features }));\n if (manifest.updateRequired) this._updateRequired.set(true);\n\n // Version-check: warn dev team when a newer package is available\n const latest = manifest.latestPackageVersion;\n if (latest && latest !== PACKAGE_VERSION) {\n console.warn(\n `[mesauth-angular] A newer version (${latest}) is available. ` +\n `Installed: ${PACKAGE_VERSION}. Please update the package.`\n );\n }\n });\n }\n}\n","import { inject, Injectable, InjectionToken, EnvironmentProviders, makeEnvironmentProviders, provideAppInitializer, NgZone } from '@angular/core';\nimport { MaUiConfigService } from './ma-ui-config.service';\nimport { HttpClient } from '@angular/common/http';\nimport { HubConnection, HubConnectionBuilder, LogLevel } from '@microsoft/signalr';\nimport { BehaviorSubject, Subject, Observable, of, EMPTY } from 'rxjs';\nimport { tap, catchError } from 'rxjs/operators';\nimport { Router } from '@angular/router';\n\nexport interface MesAuthConfig {\n apiBaseUrl: string;\n withCredentials?: boolean;\n userBaseUrl?: string;\n /**\n * Base URL for hosted UI assets (CSS themes, icons, manifest).\n * Defaults to `{apiBaseUrl}/mesauth-angular/v1` when omitted.\n * Allows updating themes, icons, and labels without republishing the npm package.\n */\n uiAssetsUrl?: string;\n}\n\n/** Injection token for MesAuth configuration */\nexport const MES_AUTH_CONFIG = new InjectionToken<MesAuthConfig>('MES_AUTH_CONFIG');\n\n/**\n * Provides MesAuth with configuration.\n * This is the recommended way to set up mesauth-angular in standalone apps.\n *\n * @example\n * ```typescript\n * // app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideHttpClient(withInterceptors([mesAuthInterceptor])),\n * provideMesAuth({\n * apiBaseUrl: 'https://auth.example.com',\n * userBaseUrl: 'https://app.example.com'\n * })\n * ]\n * };\n * ```\n */\nexport function provideMesAuth(config: MesAuthConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: MES_AUTH_CONFIG, useValue: config },\n MesAuthService,\n provideAppInitializer(() => {\n const mesAuthService = inject(MesAuthService);\n const httpClient = inject(HttpClient);\n const router = inject(Router);\n const ngZone = inject(NgZone);\n mesAuthService.init(config, httpClient, router, ngZone);\n })\n ]);\n}\n\nexport interface IUser {\n userId?: string;\n userName?: string;\n fullName?: string;\n gender?: string;\n email?: string;\n phoneNumber?: string;\n department?: string;\n position?: string;\n tokenVersion?: string;\n permEndpoint?: string;\n perms?: Set<string>;\n employeeCode?: string;\n avatarPath?: string;\n loginMethod?: number;\n hrFullNameVn?: string;\n hrFullNameEn?: string;\n hrPosition?: string;\n hrJobTitle?: string;\n hrGender?: string;\n hrMobile?: string;\n hrEmail?: string;\n hrJoinDate?: string;\n hrBirthDate?: string;\n hrWorkStatus?: string;\n hrDoiTuong?: string;\n hrTeamCode?: string;\n hrLineCode?: string;\n}\n\nexport enum NotificationType {\n Info = 'Info',\n Warning = 'Warning',\n Error = 'Error',\n Success = 'Success'\n}\n\nexport interface NotificationDto {\n id: string;\n title: string;\n message: string;\n messageHtml?: string;\n url?: string;\n type: NotificationType;\n isRead: boolean;\n createdAt: string;\n sourceAppName: string;\n sourceAppIconUrl?: string;\n}\n\nexport interface FrontEndRoute {\n id: number;\n roleId: string;\n roleName: string;\n routePath: string;\n routeName: string;\n description?: string;\n icon?: string;\n cssClass?: string;\n parentId?: number | null;\n sortOrder: number;\n isLabel: boolean;\n isActive: boolean;\n createdAt: string;\n updatedAt?: string;\n children: FrontEndRoute[];\n}\n\nexport interface UserFrontEndRoutesGrouped {\n appId: string;\n appName: string;\n feUrl?: string;\n routes: FrontEndRoute[];\n}\n\nexport interface PagedList<T> {\n items: T[];\n totalCount: number;\n page: number;\n pageSize: number;\n totalPages: number;\n hasNext: boolean;\n hasPrevious: boolean;\n}\n\nexport interface RealTimeNotificationDto {\n id: string;\n title: string;\n message: string;\n messageHtml?: string;\n url?: string;\n type: NotificationType;\n createdAt: string;\n sourceAppName: string;\n sourceAppIconUrl?: string;\n}\n\n@Injectable()\nexport class MesAuthService {\n private hubConnection: HubConnection | null = null;\n private _currentUser = new BehaviorSubject<IUser | null>(null);\n public currentUser$: Observable<IUser | null> = this._currentUser.asObservable();\n private _notifications = new Subject<any>();\n public notifications$: Observable<any> = this._notifications.asObservable();\n private _approvalEvents = new Subject<any>();\n public approvalEvents$: Observable<any> = this._approvalEvents.asObservable();\n\n private apiBase = '';\n private config: MesAuthConfig | null = null;\n private http!: HttpClient;\n private router?: Router;\n private ngZone: NgZone | null = null;\n\n constructor() {\n // Empty constructor - all dependencies passed to init()\n }\n\n init(config: MesAuthConfig, httpClient: HttpClient, router?: Router, ngZone?: NgZone) {\n this.config = config;\n this.http = httpClient;\n this.router = router;\n this.ngZone = ngZone ?? null;\n this.apiBase = config.apiBaseUrl.replace(/\\/$/, '');\n\n // Inject server-hosted theme CSS and manifest so visual/config changes\n // don't require a package republish.\n const assetsUrl = config.uiAssetsUrl || `${this.apiBase}/mesauth-angular/v1`;\n this.injectThemeStylesheet(assetsUrl);\n inject(MaUiConfigService).loadManifest(assetsUrl, httpClient);\n\n // Fetch user once on init. Route changes do NOT re-fetch the user.\n // Auth state is maintained via cookies; 401 errors are handled by HTTP interceptors.\n // SignalR handles real-time notification delivery without polling.\n this.fetchCurrentUser().subscribe();\n }\n\n private injectThemeStylesheet(assetsUrl: string) {\n const id = 'ma-theme-css';\n if (typeof document === 'undefined' || document.getElementById(id)) return;\n const link = document.createElement('link');\n link.id = id;\n link.rel = 'stylesheet';\n link.href = `${assetsUrl}/themes/default.css`;\n document.head.appendChild(link);\n }\n\n getConfig(): MesAuthConfig | null {\n return this.config;\n }\n\n private fetchCurrentUser(): Observable<any> {\n if (!this.apiBase) return EMPTY;\n const url = `${this.apiBase}/auth/me`;\n return this.http.get(url, { withCredentials: this.config?.withCredentials ?? true }).pipe(\n tap((u) => {\n this._currentUser.next(u);\n if (u && this.config) {\n this.startConnection(this.config);\n }\n }),\n catchError((err) => {\n // Silently handle auth errors (401/403) - user is not logged in\n if (err.status === 401 || err.status === 403) {\n this._currentUser.next(null);\n }\n return of(null);\n })\n );\n }\n\n public getUnreadCount(): Observable<any> {\n return this.http.get(`${this.apiBase}/notif/me/unread-count`, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n public getNotifications(page: number = 1, pageSize: number = 20, includeRead: boolean = false, type?: string): Observable<any> {\n let url = `${this.apiBase}/notif/me?page=${page}&pageSize=${pageSize}&includeRead=${includeRead}`;\n if (type) {\n url += `&type=${type}`;\n }\n return this.http.get(url, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n public markAsRead(notificationId: string): Observable<any> {\n return this.http.patch(`${this.apiBase}/notif/${notificationId}/read`, {}, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n public markAllAsRead(): Observable<any> {\n return this.http.patch(`${this.apiBase}/notif/me/read-all`, {}, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n public deleteNotification(notificationId: string): Observable<any> {\n return this.http.delete(`${this.apiBase}/notif/${notificationId}`, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n /**\n * Get frontend routes assigned to the current user\n * Returns routes grouped by application\n */\n public getFrontEndRoutes(): Observable<UserFrontEndRoutesGrouped[]> {\n if (!this.apiBase) throw new Error('MesAuth not initialized');\n return this.http.get<UserFrontEndRoutesGrouped[]>(`${this.apiBase}/fe-routes/me`, { withCredentials: this.config?.withCredentials ?? true });\n }\n\n private startConnection(config: MesAuthConfig) {\n if (this.hubConnection) return;\n const signalrUrl = config.apiBaseUrl.replace(/\\/$/, '') + '/hub/notification';\n const builder = new HubConnectionBuilder()\n .withUrl(signalrUrl, { withCredentials: config.withCredentials ?? true })\n .withAutomaticReconnect()\n .configureLogging(LogLevel.Warning);\n\n this.hubConnection = builder.build();\n\n this.hubConnection.on('ReceiveNotification', (n: any) => {\n if (this.ngZone) {\n this.ngZone.run(() => this._notifications.next(n));\n } else {\n this._notifications.next(n);\n }\n });\n\n this.hubConnection.on('ApprovalCompleted', (e: any) => {\n if (this.ngZone) {\n this.ngZone.run(() => this._approvalEvents.next({ type: 'ApprovalCompleted', ...e }));\n } else {\n this._approvalEvents.next({ type: 'ApprovalCompleted', ...e });\n }\n });\n\n this.hubConnection.on('ApprovalStepChanged', (e: any) => {\n if (this.ngZone) {\n this.ngZone.run(() => this._approvalEvents.next({ type: 'ApprovalStepChanged', ...e }));\n } else {\n this._approvalEvents.next({ type: 'ApprovalStepChanged', ...e });\n }\n });\n\n this.hubConnection.start().then(() => {}).catch((err) => {});\n\n this.hubConnection.onclose(() => {});\n this.hubConnection.onreconnecting(() => {});\n this.hubConnection.onreconnected(() => {});\n }\n\n public stop() {\n if (!this.hubConnection) return;\n this.hubConnection.stop().catch(() => {});\n this.hubConnection = null;\n }\n\n public logout(): Observable<any> {\n const url = `${this.apiBase}/auth/logout`;\n return this.http.post(url, {}, { withCredentials: this.config?.withCredentials ?? true }).pipe(\n tap(() => {\n this._currentUser.next(null);\n this.stop();\n })\n );\n }\n\n public get currentUser(): IUser | null {\n return this._currentUser.value;\n }\n\n public get isAuthenticated(): boolean {\n return this._currentUser.value !== null;\n }\n\n /**\n * Refreshes the current user from the server.\n * Returns an Observable that completes when the user data is loaded.\n * Callers can subscribe to wait for completion before proceeding (e.g., navigating after login).\n */\n public refreshUser(): Observable<any> {\n return this.fetchCurrentUser();\n }\n}\n","import { inject } from '@angular/core';\nimport { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';\nimport { throwError, timer } from 'rxjs';\nimport { catchError, switchMap } from 'rxjs/operators';\nimport { Router } from '@angular/router';\nimport { MesAuthService } from './mes-auth.service';\n\n// Track if we're currently redirecting to prevent loopback\nlet isRedirecting = false;\n\ninterface PermissionHeader {\n resource: string;\n allowedActions: string[];\n}\n/**\n * Functional HTTP interceptor for handling 401/403 auth errors.\n * Redirects to login page on 401, and to 403 page on 403.\n * Includes loopback prevention to avoid infinite redirects.\n */\nexport const mesAuthInterceptor: HttpInterceptorFn = (req, next) => {\n const authService = inject(MesAuthService);\n const router = inject(Router);\n\n return next(req).pipe(\n catchError((error: HttpErrorResponse) => {\n const status = error.status;\n\n // Check if we should handle this error and prevent loopback\n if ((status === 401 || status === 403) && !isRedirecting) {\n const config = authService.getConfig();\n const baseUrl = config?.userBaseUrl || '';\n\n const currentUrl = router.url + (window.location.hash || '');\n const returnUrl = encodeURIComponent(currentUrl);\n\n // Avoid loops if already on auth/unauth pages\n const isLoginPage = currentUrl.includes('/login');\n const is403Page = currentUrl.includes('/403');\n const isAuthPage = currentUrl.includes('/auth');\n // Public pages that should never trigger a 401 redirect (e.g., register, password reset)\n const isPublicPage = currentUrl.includes('/register')\n || currentUrl.includes('/forgot-password')\n || currentUrl.includes('/reset-password');\n // Skip redirect for the initial /auth/me check (app startup when not logged in)\n const isMeAuthPage = req.url.includes('/auth/me');\n\n if (status === 401 && !isLoginPage && !isAuthPage && !isMeAuthPage && !isPublicPage) {\n // Wait 1.5s for the concurrent refresh's Set-Cookie to be processed, then retry once.\n // If retry also gets 401, redirect to login.\n return timer(1500).pipe(\n switchMap(() => next(req)),\n catchError((retryError: HttpErrorResponse) => {\n if (retryError.status === 401) {\n isRedirecting = true;\n setTimeout(() => { isRedirecting = false; }, 5000);\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\n }\n return throwError(() => retryError);\n })\n );\n } else if (status === 403 && !is403Page) {\n isRedirecting = true;\n setTimeout(() => { isRedirecting = false; }, 5000);\n let redirectUrl = `${baseUrl}/403?returnUrl=${returnUrl}`;\n if (error.error && error.error.required) {\n redirectUrl += `&required=${encodeURIComponent(error.error.required)}`;\n }\n window.location.href = redirectUrl;\n }\n }\n return throwError(() => error);\n })\n );\n};\n\n\nfunction appendPermissions(body: unknown, allowedActions: string[]): unknown {\n if (body === null || body === undefined) {\n return { 'x-ma-perms': allowedActions };\n }\n\n if (Array.isArray(body)) {\n return { data: body, 'x-ma-perms': allowedActions };\n }\n\n if (typeof body === 'object') {\n return { ...(body as object), 'x-ma-perms': allowedActions };\n }\n\n // Primitive (string, number, boolean)\n return { data: body, 'x-ma-perms': allowedActions };\n}","import { NgModule } from '@angular/core';\nimport { MesAuthService } from './mes-auth.service';\n\n@NgModule({\n providers: [\n MesAuthService\n ]\n})\nexport class MesAuthModule {}\n","import { Injectable, OnDestroy } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\nexport type Theme = 'light' | 'dark';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ThemeService implements OnDestroy {\n private _currentTheme = new BehaviorSubject<Theme>('light');\n public currentTheme$: Observable<Theme> = this._currentTheme.asObservable();\n private observer: MutationObserver | null = null;\n\n constructor() {\n this.detectTheme();\n this.startWatching();\n }\n\n ngOnDestroy(): void {\n this.stopWatching();\n }\n\n private detectTheme(): void {\n const html = document.documentElement;\n const isDark = html.classList.contains('dark') ||\n html.getAttribute('data-theme') === 'dark' ||\n html.getAttribute('theme') === 'dark' ||\n html.getAttribute('data-coreui-theme') === 'dark';\n\n this._currentTheme.next(isDark ? 'dark' : 'light');\n }\n\n private startWatching(): void {\n if (typeof MutationObserver === 'undefined') {\n // Fallback for older browsers - check periodically\n setInterval(() => this.detectTheme(), 1000);\n return;\n }\n\n this.observer = new MutationObserver(() => {\n this.detectTheme();\n });\n\n this.observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class', 'data-theme', 'theme', 'data-coreui-theme']\n });\n }\n\n private stopWatching(): void {\n if (this.observer) {\n this.observer.disconnect();\n this.observer = null;\n }\n }\n\n get currentTheme(): Theme {\n return this._currentTheme.value;\n }\n\n // Method to manually set theme if needed\n setTheme(theme: Theme): void {\n this._currentTheme.next(theme);\n }\n\n // Re-detect theme from DOM\n refreshTheme(): void {\n this.detectTheme();\n }\n}","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding, HostListener, signal, ChangeDetectorRef } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { HttpClient } from '@angular/common/http';\nimport { MesAuthService, IUser } from './mes-auth.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n selector: 'ma-user-profile',\n standalone: true,\n imports: [],\n templateUrl: './user-profile.component.html',\n styleUrl: './user-profile.component.css'\n})\nexport class UserProfileComponent implements OnInit, OnDestroy {\n @Output() notificationClick = new EventEmitter<void>();\n @Output() approvalClick = new EventEmitter<void>();\n @HostBinding('class') get themeClass(): string {\n return `theme-${this.currentTheme}`;\n }\n\n currentUser = signal<IUser | null>(null);\n currentTheme: Theme = 'light';\n unreadCount = 0;\n pendingApprovalCount = 0;\n dropdownOpen = false;\n private hasUser = false;\n private destroy$ = new Subject<void>();\n\n // Signal to force avatar refresh\n avatarRefresh = signal<number>(Date.now());\n\n constructor(private authService: MesAuthService, private router: Router, private themeService: ThemeService, private cdr: ChangeDetectorRef, private http: HttpClient) {}\n\n ngOnInit() {\n this.authService.currentUser$\n .pipe(takeUntil(this.destroy$))\n .subscribe(user => {\n this.currentUser.set(user);\n this.hasUser = !!user;\n // Force avatar refresh when user changes\n this.avatarRefresh.set(Date.now());\n if (!this.hasUser) {\n this.unreadCount = 0;\n this.pendingApprovalCount = 0;\n } else {\n this.loadUnreadCount();\n this.loadPendingApprovalCount();\n }\n this.cdr.markForCheck();\n });\n\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(theme => {\n this.currentTheme = theme;\n });\n\n // Listen for approval events (SignalR) to refresh pending count\n this.authService.approvalEvents$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n if (this.hasUser) this.loadPendingApprovalCount();\n });\n\n // Listen for new real-time notifications (SignalR only)\n this.authService.notifications$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n if (this.hasUser) {\n this.loadUnreadCount();\n }\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n loadUnreadCount() {\n if (!this.hasUser) {\n this.unreadCount = 0;\n return;\n }\n\n this.authService.getUnreadCount().subscribe({\n next: (response: any) => {\n this.unreadCount = response.unreadCount || 0;\n },\n error: (err) => {}\n });\n }\n\n loadPendingApprovalCount() {\n if (!this.hasUser) { this.pendingApprovalCount = 0; return; }\n const config = this.authService.getConfig();\n if (!config) return;\n const url = `${config.apiBaseUrl.replace(/\\/$/, '')}/approval/dashboard`;\n this.http.get(url, { withCredentials: config.withCredentials ?? true }).subscribe({\n next: (r: any) => { this.pendingApprovalCount = r?.pendingCount ?? 0; },\n error: () => {}\n });\n }\n\n onApprovalClick() {\n this.approvalClick.emit();\n }\n\n getAvatarUrl(user: IUser): string {\n // Use the refresh signal to force update\n const refresh = this.avatarRefresh();\n const config = this.authService.getConfig();\n const baseUrl = config?.apiBaseUrl || '';\n\n // If user has avatarPath, use it directly\n if (user.avatarPath) {\n // If avatarPath is already a full URL, use it as-is\n if (user.avatarPath.startsWith('http://') || user.avatarPath.startsWith('https://')) {\n return user.avatarPath;\n }\n // If it's a relative path, construct full URL with refresh timestamp\n return `${baseUrl.replace(/\\/$/, '')}${user.avatarPath}?t=${refresh}`;\n }\n\n // Fallback: construct URL using userId\n const userId = user.userId;\n if (userId && baseUrl) {\n return `${baseUrl.replace(/\\/$/, '')}/auth/${userId}/avatar?t=${refresh}`;\n }\n\n // Fallback to UI avatars service if no userId or baseUrl\n const displayName = user.userName || user.userId || 'User';\n return `https://ui-avatars.com/api/?name=${encodeURIComponent(displayName)}&background=1976d2&color=fff`;\n }\n\n getLastNameInitial(user: IUser): string {\n const fullName = user.fullName || user.userName || 'U';\n const parts = fullName.split(' ');\n const lastPart = parts[parts.length - 1];\n return lastPart.charAt(0).toUpperCase();\n }\n\n toggleDropdown() {\n this.dropdownOpen = !this.dropdownOpen;\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: Event) {\n const target = event.target as HTMLElement;\n const clickedInside = target.closest('.user-menu-wrapper');\n if (!clickedInside) {\n this.dropdownOpen = false;\n }\n }\n\n onLogin() {\n const config = this.authService.getConfig();\n const baseUrl = config?.userBaseUrl || '';\n const returnUrl = encodeURIComponent(this.router.url);\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\n }\n\n onViewProfile() {\n this.router.navigate(['/profile']);\n this.dropdownOpen = false;\n }\n\n onLogout() {\n this.authService.logout().subscribe({\n next: () => {\n // Clear current user after successful logout\n this.dropdownOpen = false;\n\n // Navigate to login with return URL\n const config = this.authService.getConfig();\n const baseUrl = config?.userBaseUrl || '';\n const returnUrl = encodeURIComponent(window.location.href);\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\n },\n error: (err) => {\n // Still navigate to login even if logout fails\n const config = this.authService.getConfig();\n const baseUrl = config?.userBaseUrl || '';\n window.location.href = `${baseUrl}/login`;\n }\n });\n }\n\n onNotificationClick() {\n this.notificationClick.emit();\n }\n}\n","<div class=\"user-profile-container\">\n @if (!currentUser()) {\n <!-- Not logged in -->\n <button class=\"login-btn\" (click)=\"onLogin()\">Login</button>\n } @else {\n <!-- Logged in -->\n <div class=\"user-header\">\n <!-- Notification Bell -->\n <button class=\"notification-btn\" [class.has-unread]=\"unreadCount > 0\" (click)=\"onNotificationClick()\" title=\"Notifications\" aria-label=\"Notifications\">\n <svg class=\"bell-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/>\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n @if (unreadCount > 0) {\n <span class=\"badge\">{{ unreadCount > 99 ? '99+' : unreadCount }}</span>\n }\n </button>\n\n <!-- Approval Button -->\n <button class=\"notification-btn\" [class.has-unread]=\"pendingApprovalCount > 0\" (click)=\"onApprovalClick()\" title=\"Approvals\" aria-label=\"Approvals\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M9 11l3 3L22 4\"/>\n <path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"/>\n </svg>\n @if (pendingApprovalCount > 0) {\n <span class=\"badge\">{{ pendingApprovalCount > 99 ? '99+' : pendingApprovalCount }}</span>\n }\n </button>\n\n <!-- User Avatar + Dropdown -->\n <div class=\"user-menu-wrapper\">\n <button class=\"user-menu-btn\" (click)=\"toggleDropdown()\" [attr.aria-label]=\"'User menu for ' + (currentUser().fullName || currentUser().userName)\" aria-haspopup=\"true\" [attr.aria-expanded]=\"dropdownOpen\">\n <div class=\"avatar-ring\" [class.active]=\"dropdownOpen\">\n @if (currentUser().fullName || currentUser().userName) {\n <img\n [src]=\"getAvatarUrl(currentUser())\"\n [alt]=\"currentUser().fullName || currentUser().userName\"\n class=\"avatar\"\n />\n } @else {\n <span class=\"avatar-initial\">{{ getLastNameInitial(currentUser()) }}</span>\n }\n </div>\n </button>\n\n @if (dropdownOpen) {\n <div class=\"mes-dropdown-menu\">\n <!-- User info header -->\n <div class=\"mes-dropdown-header\">\n <div class=\"dropdown-avatar-wrap\">\n @if (currentUser().fullName || currentUser().userName) {\n <img\n [src]=\"getAvatarUrl(currentUser())\"\n [alt]=\"currentUser().fullName || currentUser().userName\"\n class=\"dropdown-avatar\"\n />\n } @else {\n <span class=\"dropdown-avatar-initial\">{{ getLastNameInitial(currentUser()) }}</span>\n }\n </div>\n <div class=\"dropdown-user-info\">\n <span class=\"dropdown-user-name\">{{ currentUser().fullName || currentUser().userName }}</span>\n @if (currentUser().position || currentUser().department) {\n <span class=\"dropdown-user-sub\">{{ currentUser().position || currentUser().department }}</span>\n }\n </div>\n </div>\n\n <div class=\"mes-dropdown-divider\"></div>\n\n <button class=\"mes-dropdown-item profile-link\" (click)=\"onViewProfile()\">\n <svg class=\"item-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"/><circle cx=\"12\" cy=\"7\" r=\"4\"/>\n </svg>\n View Profile\n </button>\n\n <div class=\"mes-dropdown-divider\"></div>\n\n <button class=\"mes-dropdown-item logout-item\" (click)=\"onLogout()\">\n <svg class=\"item-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\"/><polyline points=\"16 17 21 12 16 7\"/><line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"/>\n </svg>\n Logout\n </button>\n </div>\n }\n </div>\n </div>\n }\n</div>\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\nexport interface Toast {\n id: string;\n message: string;\n title?: string;\n type: 'info' | 'success' | 'warning' | 'error';\n duration?: number;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ToastService {\n private toasts$ = new BehaviorSubject<Toast[]>([]);\n public toasts: Observable<Toast[]> = this.toasts$.asObservable();\n\n show(message: string, title?: string, type: 'info' | 'success' | 'warning' | 'error' = 'info', duration: number = 5000) {\n const id = Math.random().toString(36).substr(2, 9);\n const toast: Toast = {\n id,\n message,\n title,\n type,\n duration\n };\n\n const currentToasts = this.toasts$.value;\n this.toasts$.next([...currentToasts, toast]);\n\n if (duration > 0) {\n setTimeout(() => {\n this.remove(id);\n }, duration);\n }\n\n return id;\n }\n\n remove(id: string) {\n const currentToasts = this.toasts$.value;\n this.toasts$.next(currentToasts.filter(t => t.id !== id));\n }\n\n clear() {\n this.toasts$.next([]);\n }\n}\n","import { Component, OnInit, OnDestroy, HostBinding } from '@angular/core';\nimport { ToastService, Toast } from './toast.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n selector: 'ma-toast-container',\n standalone: true,\n imports: [],\n templateUrl: './toast-container.component.html',\n styleUrl: './toast-container.component.css'\n})\nexport class ToastContainerComponent implements OnInit, OnDestroy {\n @HostBinding('class') get themeClass(): string {\n return `theme-${this.currentTheme}`;\n }\n\n toasts: Toast[] = [];\n currentTheme: Theme = 'light';\n private destroy$ = new Subject<void>();\n\n constructor(private toastService: ToastService, private themeService: ThemeService) {}\n\n ngOnInit() {\n this.toastService.toasts\n .pipe(takeUntil(this.destroy$))\n .subscribe(toasts => {\n this.toasts = toasts;\n });\n\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(theme => {\n this.currentTheme = theme;\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n close(id: string) {\n this.toastService.remove(id);\n }\n}\n","<div class=\"toast-container\">\n @for (toast of toasts; track toast.id) {\n <div class=\"toast toast-{{ toast.type }}\">\n\n <!-- Type icon -->\n <div class=\"toast-icon\">\n @if (toast.type === 'info') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n }\n @if (toast.type === 'success') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/><polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n }\n @if (toast.type === 'warning') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/>\n </svg>\n }\n @if (toast.type === 'error') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/>\n </svg>\n }\n </div>\n\n <!-- Content -->\n <div class=\"toast-content\">\n @if (toast.title) {\n <div class=\"toast-title\">{{ toast.title }}</div>\n }\n <div class=\"toast-message\" [innerHTML]=\"toast.message\"></div>\n </div>\n\n <!-- Close -->\n <button class=\"toast-close\" (click)=\"close(toast.id)\" aria-label=\"Close\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n\n <!-- Auto-dismiss progress bar — hidden when duration <= 0 (persistent toast) -->\n @if (toast.duration == null || toast.duration > 0) {\n <div class=\"toast-progress\" [style.animation-duration]=\"(toast.duration ?? 5000) + 'ms'\"></div>\n }\n </div>\n }\n</div>\n","import { Component, OnInit, OnDestroy, HostBinding, Output, EventEmitter, inject } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { MesAuthService, NotificationDto, PagedList, RealTimeNotificationDto } from './mes-auth.service';\nimport { ToastService } from './toast.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n selector: 'ma-notification-panel',\n standalone: true,\n imports: [],\n templateUrl: './notification-panel.component.html',\n styleUrls: ['./panel-shared.css', './notification-panel.component.css'],\n})\nexport class NotificationPanelComponent implements OnInit, OnDestroy {\n @Output() notificationRead = new EventEmitter<void>();\n @HostBinding('class') get themeClass(): string {\n return `theme-${this.currentTheme}`;\n }\n\n isOpen = false;\n notifications: NotificationDto[] = [];\n currentTheme: Theme = 'light';\n activeTab: 'unread' | 'read' = 'unread'; // Default to unread tab\n private destroy$ = new Subject<void>();\n\n // Cached filtered lists — updated explicitly to avoid re-filtering on every CD cycle\n private _unreadNotifications: NotificationDto[] = [];\n private _readNotifications: NotificationDto[] = [];\n\n // Stable time-ago strings keyed by notification id — refreshed every 30s\n dateLabels: Map<string, string> = new Map();\n private dateTimer: ReturnType<typeof setInterval> | null = null;\n\n get unreadNotifications(): NotificationDto[] {\n return this._unreadNotifications;\n }\n\n get readNotifications(): NotificationDto[] {\n return this._readNotifications;\n }\n\n get currentNotifications(): NotificationDto[] {\n return this.activeTab === 'unread' ? this._unreadNotifications : this._readNotifications;\n }\n\n selectedNotification: NotificationDto | null = null;\n selectedNotificationHtml: SafeHtml | null = null;\n selectedNotificationDate: string = '';\n\n // Returns plain text message for list display\n getNotificationMessage(notification: NotificationDto): string {\n return notification.message || '';\n }\n\n // Normalize type to string — API may return integer or string\n // Backend enum: Info=0, Success=1, Warning=2, Error=3\n typeOf(notification: { type: any }): 'Info' | 'Success' | 'Warning' | 'Error' {\n const t = notification.type;\n if (t === 0 || t === 'Info') return 'Info';\n if (t === 1 || t === 'Success') return 'Success';\n if (t === 2 || t === 'Warning') return 'Warning';\n if (t === 3 || t === 'Error') return 'Error';\n return 'Info';\n }\n\n private toastType(type: any): 'info' | 'warning' | 'error' | 'success' {\n const t = this.typeOf({ type });\n return t.toLowerCase() as 'info' | 'warning' | 'error' | 'success';\n }\n\n private readonly sanitizer = inject(DomSanitizer);\n\n constructor(private authService: MesAuthService, private toastService: ToastService, private themeService: ThemeService) {}\n\n ngOnInit() {\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(theme => {\n this.currentTheme = theme;\n });\n\n this.loadNotifications();\n\n // Refresh time-ago labels every 30s to avoid NG0100 from live new Date() in template\n this.dateTimer = setInterval(() => this.refreshDateLabels(), 30000);\n\n // Listen for new real-time notifications\n this.authService.notifications$\n .pipe(takeUntil(this.destroy$))\n .subscribe((notification: RealTimeNotificationDto) => {\n // Show toast for new notification\n this.toastService.show(\n notification.messageHtml || notification.message || '',\n notification.title,\n this.toastType(notification.type),\n 5000\n );\n // Reload notifications list\n this.loadNotifications();\n });\n }\n\n ngOnDestroy() {\n if (this.dateTimer !== null) {\n clearInterval(this.dateTimer);\n this.dateTimer = null;\n }\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private loadNotifications() {\n this.authService.getNotifications(1, 50, true).subscribe({ // includeRead = true to get both read and unread\n next: (response: PagedList<NotificationDto>) => {\n this.notifications = response.items || [];\n this.onNotificationsChanged();\n },\n error: (err) => {}\n });\n }\n\n open() {\n this.isOpen = true;\n this.activeTab = 'unread'; // Reset to unread tab when opening\n }\n\n close() {\n this.isOpen = false;\n }\n\n switchTab(tab: 'unread' | 'read') {\n this.activeTab = tab;\n }\n\n openDetails(notification: NotificationDto) {\n this.selectedNotification = notification;\n // Cache computed values to avoid re-rendering on every change detection cycle\n const html = notification.messageHtml || notification.message || '';\n this.selectedNotificationHtml = this.sanitizer.bypassSecurityTrustHtml(html);\n this.selectedNotificationDate = this.formatDate(notification.createdAt);\n // Mark as read when opening details (if not already read)\n if (!notification.isRead) {\n this.authService.markAsRead(notification.id).subscribe({\n next: () => {\n notification.isRead = true;\n this.notificationRead.emit();\n this.onNotificationsChanged();\n },\n error: () => {}\n });\n }\n }\n\n closeDetails() {\n this.selectedNotification = null;\n this.selectedNotificationHtml = null;\n this.selectedNotificationDate = '';\n }\n\n openUrl() {\n const url = this.selectedNotification?.url?.trim();\n if (url) {\n window.open(url, '_blank', 'noopener,noreferrer');\n }\n }\n\n markAsRead(notificationId: string, event?: Event) {\n if (event) {\n event.stopPropagation();\n }\n this.authService.markAsRead(notificationId).subscribe({\n next: () => {\n const notification = this.notifications.find(n => n.id === notificationId);\n if (notification) {\n notification.isRead = true;\n this.notificationRead.emit();\n this.onNotificationsChanged();\n }\n },\n error: (err) => {}\n });\n }\n\n markAllAsRead() {\n this.authService.markAllAsRead().subscribe({\n next: () => {\n this.notifications.forEach(n => n.isRead = true);\n this.notificationRead.emit();\n this.onNotificationsChanged();\n },\n error: (err) => {}\n });\n }\n\n deleteAllRead() {\n const readNotificationIds = this.notifications\n .filter(n => n.isRead)\n .map(n => n.id);\n\n const deletePromises = readNotificationIds.map(id =>\n this.authService.deleteNotification(id).toPromise()\n );\n\n Promise.all(deletePromises).then(() => {\n this.notifications = this.notifications.filter(n => !n.isRead);\n this.onNotificationsChanged();\n }).catch((err) => {\n this.loadNotifications();\n });\n }\n\n deleteAllUnread() {\n const unreadNotificationIds = this.notifications\n .filter(n => !n.isRead)\n .map(n => n.id);\n\n const deletePromises = unreadNotificationIds.map(id =>\n this.authService.deleteNotification(id).toPromise()\n );\n\n Promise.all(deletePromises).then(() => {\n this.notifications = this.notifications.filter(n => n.isRead);\n this.notificationRead.emit();\n this.onNotificationsChanged();\n }).catch((err) => {\n this.loadNotifications();\n });\n }\n\n delete(notificationId: string, event: Event) {\n event.stopPropagation();\n const wasUnread = this.notifications.find(n => n.id === notificationId && !n.isRead) !== undefined;\n this.authService.deleteNotification(notificationId).subscribe({\n next: () => {\n this.notifications = this.notifications.filter(n => n.id !== notificationId);\n if (wasUnread) {\n this.notificationRead.emit();\n }\n this.onNotificationsChanged();\n },\n error: (err) => {}\n });\n }\n\n formatDate(dateString: string): string {\n return this.computeTimeAgo(dateString, new Date());\n }\n\n // Pure computation — takes now as param so it never calls new Date() internally\n private computeTimeAgo(dateString: string, now: Date): string {\n const normalizedDateString = this.parseUtcDate(dateString);\n const date = new Date(normalizedDateString);\n\n if (isNaN(date.getTime())) {\n return 'Invalid date';\n }\n\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString();\n }\n\n // Rebuild dateLabels map using a single shared now — prevents mid-loop clock drift\n private refreshDateLabels(): void {\n const now = new Date();\n for (const n of this.notifications) {\n this.dateLabels.set(n.id, this.computeTimeAgo(n.createdAt, now));\n }\n }\n\n // Re-run filter once and store results in stable arrays\n private recomputeFilteredLists(): void {\n this._unreadNotifications = this.notifications.filter(n => !n.isRead);\n this._readNotifications = this.notifications.filter(n => n.isRead);\n }\n\n // Single call-site after every notification mutation\n private onNotificationsChanged(): void {\n this.recomputeFilteredLists();\n this.refreshDateLabels();\n }\n\n // Parse date string from server (stored in UTC but without 'Z' suffix or 'T' separator)\n private parseUtcDate(dateStr: string): string {\n let normalized = dateStr.includes('T') ? dateStr : dateStr.replace(' ', 'T');\n\n // If no timezone indicator, assume UTC by appending 'Z'\n if (!normalized.endsWith('Z') && !normalized.includes('+') && !normalized.includes('-', 10)) {\n normalized += 'Z';\n }\n\n return normalized;\n }\n}\n","<div class=\"notification-panel\" [class.open]=\"isOpen\">\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/>\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n <h3>Notifications</h3>\n </div>\n <button class=\"close-btn\" (click)=\"close()\" title=\"Close\" aria-label=\"Close notifications\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs\">\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'unread'\" (click)=\"switchTab('unread')\">\n Unread\n @if (unreadNotifications.length > 0) {\n <span class=\"tab-badge\">{{ unreadNotifications.length }}</span>\n }\n </button>\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'read'\" (click)=\"switchTab('read')\">\n Read\n @if (readNotifications.length > 0) {\n <span class=\"tab-badge read-badge\">{{ readNotifications.length }}</span>\n }\n </button>\n </div>\n\n <!-- Notifications List -->\n <div class=\"notifications-list\">\n @if (currentNotifications.length > 0) {\n @for (notification of currentNotifications; track notification.id) {\n <div\n class=\"notification-item\"\n [class.unread]=\"!notification.isRead\"\n (click)=\"openDetails(notification)\"\n >\n @let t = typeOf(notification);\n <div class=\"notif-accent\"\n [class.type-info]=\"t === 'Info'\"\n [class.type-success]=\"t === 'Success'\"\n [class.type-warning]=\"t === 'Warning'\"\n [class.type-error]=\"t === 'Error'\"></div>\n <div class=\"notif-type-icon\"\n [class.type-info]=\"t === 'Info'\"\n [class.type-success]=\"t === 'Success'\"\n [class.type-warning]=\"t === 'Warning'\"\n [class.type-error]=\"t === 'Error'\">\n @if (t === 'Info') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n }\n @if (t === 'Success') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\"/>\n </svg>\n }\n @if (t === 'Warning') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/>\n </svg>\n }\n @if (t === 'Error') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/>\n </svg>\n }\n </div>\n <div class=\"notification-content\">\n <div class=\"notification-title\">{{ notification.title }}</div>\n <div class=\"notification-message\">{{ getNotificationMessage(notification) }}</div>\n <div class=\"notification-meta\">\n <span class=\"app-name\">{{ notification.sourceAppName }}</span>\n <span class=\"time\">{{ dateLabels.get(notification.id) }}</span>\n </div>\n </div>\n @if (!notification.isRead) {\n <button class=\"icon-btn read-btn\" (click)=\"markAsRead(notification.id, $event)\" title=\"Mark as read\" aria-label=\"Mark as read\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\"/>\n </svg>\n </button>\n }\n @if (notification.isRead) {\n <button class=\"icon-btn delete-btn\" (click)=\"delete(notification.id, $event)\" title=\"Delete\" aria-label=\"Delete notification\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6\"/><path d=\"M10 11v6\"/><path d=\"M14 11v6\"/><path d=\"M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/>\n </svg>\n </button>\n }\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <svg class=\"empty-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"44\" height=\"44\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/>\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n <p>No {{ activeTab }} notifications</p>\n </div>\n }\n </div>\n\n <!-- Footer Actions -->\n @if (currentNotifications.length > 0) {\n <div class=\"panel-footer\">\n @if (activeTab === 'unread') {\n <div class=\"footer-actions\">\n @if (unreadNotifications.length > 0) {\n <button class=\"action-btn\" (click)=\"markAllAsRead()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n Mark all read\n </button>\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllUnread()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6\"/></svg>\n Delete all\n </button>\n }\n </div>\n }\n @if (activeTab === 'read' && readNotifications.length > 0) {\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllRead()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6\"/></svg>\n Delete all\n </button>\n }\n </div>\n }\n</div>\n\n<!-- Details Modal -->\n@if (selectedNotification) {\n <div class=\"modal-overlay\" (click)=\"closeDetails()\">\n <div class=\"modal-container\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\"\n [class.modal-type-info]=\"typeOf(selectedNotification) === 'Info'\"\n [class.modal-type-success]=\"typeOf(selectedNotification) === 'Success'\"\n [class.modal-type-warning]=\"typeOf(selectedNotification) === 'Warning'\"\n [class.modal-type-error]=\"typeOf(selectedNotification) === 'Error'\">\n <div class=\"modal-header-left\">\n <div class=\"modal-type-icon\">\n @if (typeOf(selectedNotification) === 'Info') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>\n </svg>\n }\n @if (typeOf(selectedNotification) === 'Success') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/><polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n }\n @if (typeOf(selectedNotification) === 'Warning') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/>\n </svg>\n }\n @if (typeOf(selectedNotification) === 'Error') {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/>\n </svg>\n }\n </div>\n <h3>{{ selectedNotification.title }}</h3>\n </div>\n <button class=\"close-btn\" (click)=\"closeDetails()\" title=\"Close\" aria-label=\"Close notification detail\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n <div class=\"modal-meta\">\n <span class=\"app-name\">{{ selectedNotification.sourceAppName }}</span>\n <span class=\"time\">{{ selectedNotificationDate }}</span>\n </div>\n <div class=\"modal-body\" [innerHTML]=\"selectedNotificationHtml\"></div>\n <div class=\"modal-footer\">\n @if (selectedNotification.url?.trim()) {\n <button class=\"action-btn see-details-btn\" (click)=\"openUrl()\">See Details</button>\n }\n <button class=\"action-btn\" (click)=\"closeDetails()\">Close</button>\n </div>\n </div>\n </div>\n}\n","import { Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { Observable } from 'rxjs';\nimport { MesAuthConfig, PagedList } from './mes-auth.service';\nimport {\n ApprovalDocumentDto,\n ApprovalDocumentSummaryDto,\n ApprovalDocumentStatus,\n ApprovalDashboardDto,\n ApprovalHistoryDto,\n ApprovalTemplateSummaryDto,\n ApprovalTemplateDto,\n RolePreviewUserDto,\n CreateApprovalRequest,\n CreateApprovalResponseDto,\n CreateApprovalTemplateRequest,\n UpdateApprovalTemplateRequest,\n ApproveRejectRequest,\n DelegateRequest\n} from './approval.models';\n\n@Injectable()\nexport class MaApprovalService {\n private apiBase = '';\n private http!: HttpClient;\n private config: MesAuthConfig | null = null;\n\n constructor() {}\n\n init(config: MesAuthConfig, httpClient: HttpClient) {\n this.config = config;\n this.http = httpClient;\n this.apiBase = config.apiBaseUrl.replace(/\\/$/, '');\n }\n\n private get opts() {\n return { withCredentials: this.config?.withCredentials ?? true };\n }\n\n // ====================== Dashboard ======================\n\n getDashboard(): Observable<ApprovalDashboardDto> {\n return this.http.get<ApprovalDashboardDto>(`${this.apiBase}/approval/dashboard`, this.opts);\n }\n\n // ====================== Pending & My Requests ======================\n\n getPendingApprovals(page = 1, pageSize = 20): Observable<PagedList<ApprovalDocumentSummaryDto>> {\n return this.http.get<PagedList<ApprovalDocumentSummaryDto>>(\n `${this.apiBase}/approval/pending?page=${page}&pageSize=${pageSize}`,\n this.opts\n );\n }\n\n getMyRequests(page = 1, pageSize = 20, status?: ApprovalDocumentStatus): Observable<PagedList<ApprovalDocumentSummaryDto>> {\n let url = `${this.apiBase}/approval/my-requests?page=${page}&pageSize=${pageSize}`;\n if (status !== undefined) url += `&status=${status}`;\n return this.http.get<PagedList<ApprovalDocumentSummaryDto>>(url, this.opts);\n }\n\n // ====================== Document ======================\n\n getDocument(id: string): Observable<ApprovalDocumentDto> {\n return this.http.get<ApprovalDocumentDto>(`${this.apiBase}/approval/documents/${id}`, this.opts);\n }\n\n getDocumentHistory(id: string): Observable<ApprovalHistoryDto[]> {\n return this.http.get<ApprovalHistoryDto[]>(`${this.apiBase}/approval/documents/${id}/history`, this.opts);\n }\n\n getDocumentContentUrl(id: string): string {\n return `${this.apiBase}/approval/documents/${id}/content`;\n }\n\n getDocumentThumbnailUrl(id: string): string {\n return `${this.apiBase}/approval/documents/${id}/thumbnail`;\n }\n\n // ====================== Actions ======================\n\n approve(documentId: string, comment?: string): Observable<void> {\n const body: ApproveRejectRequest = { comment };\n return this.http.post<void>(`${this.apiBase}/approval/documents/${documentId}/approve`, body, this.opts);\n }\n\n reject(documentId: string, comment: string): Observable<void> {\n const body: ApproveRejectRequest = { comment };\n return this.http.post<void>(`${this.apiBase}/approval/documents/${documentId}/reject`, body, this.opts);\n }\n\n delegate(documentId: string, toUserId: string, reason?: string): Observable<void> {\n const body: DelegateRequest = { toUserId, reason };\n return this.http.post<void>(`${this.apiBase}/approval/documents/${documentId}/delegate`, body, this.opts);\n }\n\n cancel(documentId: string, reason?: string): Observable<void> {\n let url = `${this.apiBase}/approval/documents/${documentId}`;\n if (reason) url += `?reason=${encodeURIComponent(reason)}`;\n return this.http.delete<void>(url, this.opts);\n }\n\n // ====================== Templates ======================\n\n getTemplates(appId?: string): Observable<ApprovalTemplateSummaryDto[]> {\n let url = `${this.apiBase}/approval/templates`;\n if (appId) url += `?appId=${encodeURIComponent(appId)}`;\n return this.http.get<ApprovalTemplateSummaryDto[]>(url, this.opts);\n }\n\n getTemplate(id: number): Observable<ApprovalTemplateDto> {\n return this.http.get<ApprovalTemplateDto>(`${this.apiBase}/approval/templates/${id}`, this.opts);\n }\n\n createTemplate(request: CreateApprovalTemplateRequest): Observable<ApprovalTemplateDto> {\n return this.http.post<ApprovalTemplateDto>(`${this.apiBase}/approval/templates`, request, this.opts);\n }\n\n updateTemplate(id: number, request: UpdateApprovalTemplateRequest): Observable<ApprovalTemplateDto> {\n return this.http.put<ApprovalTemplateDto>(`${this.apiBase}/approval/templates/${id}`, request, this.opts);\n }\n\n deleteTemplate(id: number): Observable<void> {\n return this.http.delete<void>(`${this.apiBase}/approval/templates/${id}`, this.opts);\n }\n\n previewRole(orgCode: string, level: string): Observable<RolePreviewUserDto[]> {\n return this.http.get<RolePreviewUserDto[]>(\n `${this.apiBase}/approval/roles/preview?orgCode=${encodeURIComponent(orgCode)}&level=${encodeURIComponent(level)}`,\n this.opts\n );\n }\n\n // ====================== Create (used by ma-arv-container) ======================\n\n createApproval(request: CreateApprovalRequest): Observable<CreateApprovalResponseDto> {\n return this.http.post<CreateApprovalResponseDto>(`${this.apiBase}/approval/documents`, request, this.opts);\n }\n}\n","// ====================== Enums ======================\n\nexport enum ApprovalStepMode {\n Sequential = 0,\n Parallel = 1\n}\n\nexport enum ApprovalDocumentStatus {\n Draft = 0,\n Pending = 1,\n Approved = 2,\n Rejected = 3,\n Cancelled = 4,\n Expired = 5\n}\n\nexport enum ApprovalStepStatus {\n Waiting = 0,\n Active = 1,\n Approved = 2,\n Rejected = 3,\n Delegated = 4,\n Expired = 5,\n Skipped = 6\n}\n\nexport enum ApprovalActionType {\n Created = 0,\n Submitted = 1,\n Approved = 2,\n Rejected = 3,\n Delegated = 4,\n Cancelled = 5,\n Commented = 6,\n Expired = 7,\n StepAdvanced = 8\n}\n\n// ====================== DTOs ======================\n\nexport interface ApprovalDocumentSummaryDto {\n id: string;\n title: string;\n description?: string;\n thumbnailPath?: string;\n sourceAppId: string;\n referenceId: string;\n requestedByUserName: string;\n status: ApprovalDocumentStatus;\n currentStepOrder: number;\n totalSteps: number;\n currentStepName?: string;\n createdAt: string;\n completedAt?: string;\n}\n\nexport interface ApprovalStepDto {\n id: number;\n stepOrder: number;\n stepName: string;\n mode: ApprovalStepMode;\n assignedUserId: string;\n assignedUserName: string;\n delegatedToUserId?: string;\n delegatedToUserName?: string;\n status: ApprovalStepStatus;\n comment?: string;\n decidedAt?: string;\n deadlineAt?: string;\n}\n\nexport interface ApprovalReferenceDto {\n userId: string;\n userName: string;\n addedAt: string;\n}\n\nexport interface ApprovalDocumentDto {\n id: string;\n title: string;\n description?: string;\n contentPath: string;\n thumbnailPath?: string;\n sourceAppId: string;\n referenceId: string;\n templateId?: number;\n requestedByUserId: string;\n requestedByUserName: string;\n status: ApprovalDocumentStatus;\n currentStepOrder: number;\n callbackUrl?: string;\n createdAt: string;\n updatedAt: string;\n completedAt?: string;\n deadlineAt?: string;\n steps: ApprovalStepDto[];\n references: ApprovalReferenceDto[];\n}\n\nexport interface ApprovalHistoryDto {\n id: number;\n documentId: string;\n stepId?: number;\n action: ApprovalActionType;\n actorUserId: string;\n actorUserName: string;\n comment?: string;\n details?: string;\n timestamp: string;\n}\n\nexport interface ApprovalTemplateSummaryDto {\n id: number;\n name: string;\n description?: string;\n sourceAppId: string;\n stepCount: number;\n referenceCount: number;\n isActive: boolean;\n createdAt: string;\n}\n\nexport interface StepRoleDto {\n orgCode: string;\n positionLevel: string;\n orgName?: string;\n}\n\nexport interface RolePreviewUserDto {\n userId: string;\n fullName?: string;\n position?: string;\n department?: string;\n employeeCode?: string;\n}\n\nexport interface ApprovalTemplateStepDto {\n id: number;\n stepOrder: number;\n stepName: string;\n mode: ApprovalStepMode;\n deadlineHours?: number;\n assigneeUserIds: string[];\n roles: StepRoleDto[];\n}\n\nexport interface ApprovalTemplateDto {\n id: number;\n name: string;\n description?: string;\n sourceAppId: string;\n createdByUserId: string;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n steps: ApprovalTemplateStepDto[];\n referenceUserIds: string[];\n}\n\nexport interface ApprovalDashboardDto {\n pendingCount: number;\n approvedTodayCount: number;\n rejectedTodayCount: number;\n recentActivity: ApprovalDocumentSummaryDto[];\n}\n\nexport interface CreateApprovalResponseDto {\n documentId: string;\n message: string;\n}\n\n// ====================== Requests ======================\n\nexport interface ApprovalStepRequest {\n stepOrder: number;\n stepName: string;\n mode?: ApprovalStepMode;\n approverUserIds: string[];\n deadlineHours?: number;\n}\n\nexport interface CreateApprovalRequest {\n title: string;\n description?: string;\n contentHtml: string;\n thumbnailBase64?: string;\n referenceId: string;\n templateId?: number;\n requestedByUserId?: string;\n callbackUrl?: string;\n deadlineHours?: number;\n steps?: ApprovalStepRequest[];\n referenceUserIds?: string[];\n}\n\nexport interface ApproveRejectRequest {\n comment?: string;\n}\n\nexport interface DelegateRequest {\n toUserId: string;\n reason?: string;\n}\n\nexport interface CreateApprovalTemplateRequest {\n name: string;\n description?: string;\n sourceAppId: string;\n steps: ApprovalStepRequest[];\n referenceUserIds?: string[];\n}\n\nexport interface UpdateApprovalTemplateRequest {\n name: string;\n description?: string;\n steps: ApprovalStepRequest[];\n referenceUserIds?: string[];\n}\n\n// ====================== Submit Result ======================\n\nexport interface ApprovalSubmitResult {\n documentId: string;\n message: string;\n}\n","import {\n Component, Output, EventEmitter, OnInit, OnDestroy, inject, HostListener\n} from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { Router } from '@angular/router';\nimport { MesAuthService, MesAuthConfig } from './mes-auth.service';\nimport { MaApprovalService } from './approval.service';\nimport { ApprovalDocumentSummaryDto, ApprovalDocumentStatus } from './approval.models';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { HttpClient } from '@angular/common/http';\n\ntype PanelTab = 'processing' | 'approved' | 'rejected';\n\n@Component({\n selector: 'ma-approval-panel',\n standalone: true,\n imports: [DatePipe],\n templateUrl: './ma-approval-panel.component.html',\n styleUrls: ['./panel-shared.css', './ma-approval-panel.component.css']\n})\nexport class MaApprovalPanelComponent implements OnInit, OnDestroy {\n @Output() approvalActioned = new EventEmitter<void>();\n\n isOpen = false;\n loading = false;\n activeTab: PanelTab = 'processing';\n\n processingItems: ApprovalDocumentSummaryDto[] = [];\n approvedItems: ApprovalDocumentSummaryDto[] = [];\n rejectedItems: ApprovalDocumentSummaryDto[] = [];\n\n private destroy$ = new Subject<void>();\n private mesAuth = inject(MesAuthService);\n private http = inject(HttpClient);\n private router = inject(Router);\n private approvalSvc: MaApprovalService | null = null;\n\n ngOnInit() {\n const config = this.mesAuth.getConfig();\n if (config) {\n this.approvalSvc = new MaApprovalService();\n this.approvalSvc.init(config, this.http);\n }\n\n this.mesAuth.approvalEvents$.pipe(takeUntil(this.destroy$)).subscribe(() => {\n if (this.isOpen) this.loadCurrentTab();\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n open() {\n this.isOpen = true;\n this.loadAllTabs();\n }\n\n close() {\n this.isOpen = false;\n }\n\n toggle() {\n if (this.isOpen) this.close();\n else this.open();\n }\n\n switchTab(tab: PanelTab) {\n this.activeTab = tab;\n this.loadCurrentTab();\n }\n\n private loadAllTabs() {\n this.loading = true;\n if (!this.approvalSvc) { this.loading = false; return; }\n\n let pending = 3;\n const done = () => { if (--pending === 0) this.loading = false; };\n\n this.approvalSvc.getPendingApprovals(1, 100).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => { this.processingItems = r.items; done(); },\n error: () => done()\n });\n\n this.approvalSvc.getMyRequests(1, 10, ApprovalDocumentStatus.Approved).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => { this.approvedItems = r.items; done(); },\n error: () => done()\n });\n\n this.approvalSvc.getMyRequests(1, 10, ApprovalDocumentStatus.Rejected).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => { this.rejectedItems = r.items; done(); },\n error: () => done()\n });\n }\n\n private loadCurrentTab() {\n if (!this.approvalSvc) return;\n\n if (this.activeTab === 'processing') {\n this.approvalSvc.getPendingApprovals(1, 100).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => this.processingItems = r.items,\n error: () => {}\n });\n } else if (this.activeTab === 'approved') {\n this.approvalSvc.getMyRequests(1, 10, ApprovalDocumentStatus.Approved).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => this.approvedItems = r.items,\n error: () => {}\n });\n } else {\n this.approvalSvc.getMyRequests(1, 10, ApprovalDocumentStatus.Rejected).pipe(takeUntil(this.destroy$)).subscribe({\n next: r => this.rejectedItems = r.items,\n error: () => {}\n });\n }\n }\n\n navigateToDetail(id: string) {\n this.close();\n this.router.navigate(['/auth/approval/detail', id]);\n this.approvalActioned.emit();\n }\n\n showMore(status: 'approved' | 'rejected') {\n this.close();\n this.router.navigate(['/auth/approval/my-requests'], { queryParams: { status } });\n }\n}\n","<div class=\"approval-backdrop\" [class.open]=\"isOpen\" (click)=\"close()\"></div>\n<div class=\"approval-panel\" [class.open]=\"isOpen\">\n\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M9 11l3 3L22 4\"/>\n <path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"/>\n </svg>\n <h3>Approvals</h3>\n </div>\n <button class=\"close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs\">\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'processing'\" (click)=\"switchTab('processing')\">\n Processing\n @if (processingItems.length > 0) {\n <span class=\"tab-badge\">{{ processingItems.length }}</span>\n }\n </button>\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'approved'\" (click)=\"switchTab('approved')\">\n Approved\n </button>\n <button class=\"tab-btn\" [class.active]=\"activeTab === 'rejected'\" (click)=\"switchTab('rejected')\">\n Rejected\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"panel-content\">\n <!-- Loading -->\n @if (loading) {\n <div class=\"loading-state\">\n <div class=\"spinner\"></div>\n <span>Loading...</span>\n </div>\n }\n\n <!-- Processing tab -->\n @if (!loading && activeTab === 'processing') {\n @if (processingItems.length === 0) {\n <div class=\"empty-state\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" opacity=\"0.4\"><path d=\"M9 11l3 3L22 4\"/><path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"/></svg>\n <p>No pending approvals</p>\n </div>\n }\n @for (item of processingItems; track item.id) {\n <div class=\"approval-item\" (click)=\"navigateToDetail(item.id)\">\n <div class=\"item-title\">{{ item.title }}</div>\n <div class=\"item-meta\">\n <span class=\"item-requester\">By {{ item.requestedByUserName }}</span>\n @if (item.currentStepName) {\n <span class=\"item-step\">· {{ item.currentStepName }}</span>\n }\n </div>\n <div class=\"item-footer\">\n <span class=\"item-time\">{{ item.createdAt | date:'shortDate' }}</span>\n <span class=\"item-link\">View →</span>\n </div>\n </div>\n }\n }\n\n <!-- Approved tab -->\n @if (!loading && activeTab === 'approved') {\n @if (approvedItems.length === 0) {\n <div class=\"empty-state\">\n <p>No approved documents</p>\n </div>\n }\n @for (item of approvedItems; track item.id) {\n <div class=\"approval-item approved\" (click)=\"navigateToDetail(item.id)\">\n <div class=\"item-title\">{{ item.title }}</div>\n <div class=\"item-meta\">\n <span class=\"item-requester\">By {{ item.requestedByUserName }}</span>\n </div>\n <div class=\"item-footer\">\n <span class=\"status-badge approved-badge\">Approved</span>\n <span class=\"item-time\">{{ item.completedAt | date:'shortDate' }}</span>\n <span class=\"item-link\">View →</span>\n </div>\n </div>\n }\n @if (approvedItems.length >= 10) {\n <div class=\"show-more\" (click)=\"showMore('approved')\">Show more →</div>\n }\n }\n\n <!-- Rejected tab -->\n @if (!loading && activeTab === 'rejected') {\n @if (rejectedItems.length === 0) {\n <div class=\"empty-state\">\n <p>No rejected documents</p>\n </div>\n }\n @for (item of rejectedItems; track item.id) {\n <div class=\"approval-item rejected\" (click)=\"navigateToDetail(item.id)\">\n <div class=\"item-title\">{{ item.title }}</div>\n <div class=\"item-meta\">\n <span class=\"item-requester\">By {{ item.requestedByUserName }}</span>\n </div>\n <div class=\"item-footer\">\n <span class=\"status-badge rejected-badge\">Rejected</span>\n <span class=\"item-time\">{{ item.completedAt | date:'shortDate' }}</span>\n <span class=\"item-link\">View →</span>\n </div>\n </div>\n }\n @if (rejectedItems.length >= 10) {\n <div class=\"show-more\" (click)=\"showMore('rejected')\">Show more →</div>\n }\n }\n </div>\n</div>\n","import { Component, ViewChild, AfterViewInit } from '@angular/core';\nimport { ToastContainerComponent } from './toast-container.component';\nimport { UserProfileComponent } from './user-profile.component';\nimport { NotificationPanelComponent } from './notification-panel.component';\nimport { MaApprovalPanelComponent } from './ma-approval-panel.component';\n\n@Component({\n selector: 'ma-user',\n standalone: true,\n imports: [ToastContainerComponent, UserProfileComponent, NotificationPanelComponent, MaApprovalPanelComponent],\n templateUrl: './ma-user.component.html',\n styleUrl: './ma-user.component.css'\n})\nexport class MaUserComponent implements AfterViewInit {\n @ViewChild(UserProfileComponent) userProfile?: UserProfileComponent;\n @ViewChild(MaApprovalPanelComponent) approvalPanel!: MaApprovalPanelComponent;\n\n ngAfterViewInit() {\n if (this.userProfile) {\n this.userProfile.loadUnreadCount();\n this.userProfile.loadPendingApprovalCount();\n }\n }\n\n onNotificationRead() {\n if (this.userProfile) {\n this.userProfile.loadUnreadCount();\n }\n }\n\n onApprovalActioned() {\n if (this.userProfile) {\n this.userProfile.loadPendingApprovalCount();\n }\n }\n}\n","<ma-toast-container></ma-toast-container>\n<div class=\"user-header\">\n <ma-user-profile\n (notificationClick)=\"notificationPanel.open()\"\n (approvalClick)=\"approvalPanel.open()\">\n </ma-user-profile>\n</div>\n<ma-notification-panel #notificationPanel (notificationRead)=\"onNotificationRead()\"></ma-notification-panel>\n<ma-approval-panel #approvalPanel (approvalActioned)=\"onApprovalActioned()\"></ma-approval-panel>\n","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding } from '@angular/core';\nimport { MesAuthService } from './mes-auth.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n selector: 'ma-notification-badge',\n standalone: true,\n imports: [],\n templateUrl: './notification-badge.component.html',\n styleUrl: './notification-badge.component.css'\n})\nexport class NotificationBadgeComponent implements OnInit, OnDestroy {\n @Output() notificationClick = new EventEmitter<void>();\n @HostBinding('class') get themeClass(): string {\n return `theme-${this.currentTheme}`;\n }\n \n unreadCount = 0;\n currentTheme: Theme = 'light';\n private hasUser = false;\n private destroy$ = new Subject<void>();\n\n constructor(private authService: MesAuthService, private themeService: ThemeService) {}\n\n ngOnInit() {\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(theme => {\n this.currentTheme = theme;\n });\n\n this.authService.currentUser$\n .pipe(takeUntil(this.destroy$))\n .subscribe(user => {\n this.hasUser = !!user;\n if (!this.hasUser) {\n this.unreadCount = 0;\n return;\n }\n this.loadUnreadCount();\n });\n \n // Listen for new notifications\n this.authService.notifications$\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n if (this.hasUser) {\n this.loadUnreadCount();\n }\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private loadUnreadCount() {\n if (!this.hasUser) {\n this.unreadCount = 0;\n return;\n }\n\n this.authService.getUnreadCount().subscribe({\n next: (response: any) => {\n this.unreadCount = response.unreadCount || 0;\n },\n error: (err) => console.error('Error loading unread count:', err)\n });\n }\n\n onNotificationClick() {\n this.notificationClick.emit();\n }\n}\n","<button class=\"notification-btn\" (click)=\"onNotificationClick()\" title=\"Notifications\">\n <span class=\"icon\">🔔</span>\n @if (unreadCount > 0) {\n <span class=\"badge\">{{ unreadCount }}</span>\n }\n</button>\n","import {\n Component, Input, Output, EventEmitter, OnInit, OnDestroy,\n ElementRef, ViewChild, HostBinding\n} from '@angular/core';\nimport { MesAuthService, MesAuthConfig } from './mes-auth.service';\nimport { ThemeService, Theme } from './theme.service';\nimport { MaApprovalService } from './approval.service';\nimport {\n ApprovalTemplateSummaryDto,\n ApprovalTemplateDto,\n ApprovalTemplateStepDto,\n RolePreviewUserDto,\n ApprovalStepRequest,\n ApprovalStepMode,\n CreateApprovalRequest,\n ApprovalSubmitResult\n} from './approval.models';\nimport { Subject, forkJoin, of } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { HttpClient } from '@angular/common/http';\nimport { inject } from '@angular/core';\n\n@Component({\n selector: 'ma-arv-container',\n standalone: true,\n imports: [],\n templateUrl: './ma-arv-container.component.html',\n styleUrl: './ma-arv-container.component.css'\n})\nexport class MaArvContainerComponent implements OnInit, OnDestroy {\n @Input() title = '';\n @Input() description?: string;\n @Input() referenceId = ''; \n @Input() templateIds?: number[];\n @Input() callbackUrl?: string;\n @Input() deadlineHours?: number;\n\n @Output() approvalSubmitted = new EventEmitter<ApprovalSubmitResult>();\n @Output() approvalSubmitting = new EventEmitter<void>();\n @Output() cancelled = new EventEmitter<void>();\n\n @ViewChild('contentBody', { static: true }) contentBody!: ElementRef<HTMLElement>;\n\n routingMode: 'template' | 'adhoc' = 'template';\n templates: ApprovalTemplateSummaryDto[] = [];\n selectedTemplateId: number | null = null;\n selectedTemplate: ApprovalTemplateDto | null = null;\n loadingTemplate = false;\n\n // Per-step role candidates and selected user\n stepCandidates: RolePreviewUserDto[][] = [];\n stepLoadingCandidates: boolean[] = [];\n stepSelectedUsers: string[] = [];\n adHocSteps: ApprovalStepRequest[] = [];\n\n referenceUserIds: string[] = [];\n refSearchQuery = '';\n refSearchResults: any[] = [];\n\n userSearchQuery: string[] = [];\n userSearchResults: any[][] = [];\n\n submitting = false;\n isSubmitted = false;\n errorMessage = '';\n userLabelMap: Record<string, string> = {};\n\n @HostBinding('class') get themeClass(): string { return `theme-${this.currentTheme}`; }\n currentTheme: Theme = 'light';\n\n private destroy$ = new Subject<void>();\n private mesAuth = inject(MesAuthService);\n private themeService = inject(ThemeService);\n private approvalSvc: MaApprovalService | null = null;\n private http = inject(HttpClient);\n\n ngOnInit() {\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe(t => this.currentTheme = t);\n\n const config = this.mesAuth.getConfig();\n if (config) {\n this.approvalSvc = new MaApprovalService();\n this.approvalSvc.init(config, this.http);\n this.loadTemplates();\n }\n this.addStep();\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private loadTemplates() {\n this.approvalSvc!.getTemplates().pipe(takeUntil(this.destroy$)).subscribe({\n next: (t) => {\n\n if (this.templateIds && this.templateIds.length > 0)\n t = t.filter(temp => this.templateIds!.includes(temp.id));\n\n this.templates = t;\n if (this.templateIds && this.templateIds.length > 0) {\n this.selectedTemplateId = this.templateIds[0];\n this.loadTemplateDetail(this.selectedTemplateId);\n }\n },\n error: () => {}\n });\n }\n\n private loadTemplateDetail(id: number) {\n this.loadingTemplate = true;\n this.selectedTemplate = null;\n this.stepCandidates = [];\n this.stepLoadingCandidates = [];\n this.stepSelectedUsers = [];\n this.approvalSvc!.getTemplate(id).pipe(takeUntil(this.destroy$)).subscribe({\n next: (t) => {\n this.selectedTemplate = t;\n this.loadingTemplate = false;\n this.loadStepCandidates(t.steps);\n },\n error: () => { this.loadingTemplate = false; }\n });\n }\n\n private loadStepCandidates(steps: ApprovalTemplateStepDto[]) {\n this.stepCandidates = steps.map(() => []);\n this.stepLoadingCandidates = steps.map(() => false);\n this.stepSelectedUsers = steps.map(() => '');\n\n const config = this.mesAuth.getConfig();\n\n steps.forEach((step, i) => {\n if (step.roles && step.roles.length > 0) {\n // Role-based: fetch candidates via role preview\n this.stepLoadingCandidates[i] = true;\n const calls = step.roles.map(r => this.approvalSvc!.previewRole(r.orgCode, r.positionLevel));\n forkJoin(calls.length > 0 ? calls : [of([] as RolePreviewUserDto[])])\n .pipe(takeUntil(this.destroy$))\n .subscribe({\n next: results => {\n const merged = new Map<string, RolePreviewUserDto>();\n results.forEach(list => list.forEach(u => merged.set(u.userId, u)));\n this.stepCandidates[i] = Array.from(merged.values());\n // Single candidate — pre-select automatically\n if (this.stepCandidates[i].length === 1) {\n this.stepSelectedUsers[i] = this.stepCandidates[i][0].userId;\n }\n this.stepLoadingCandidates[i] = false;\n },\n error: () => { this.stepLoadingCandidates[i] = false; }\n });\n } else if (step.assigneeUserIds && step.assigneeUserIds.length > 0 && config) {\n // Search-selected employees: resolve IDs to display names\n this.stepLoadingCandidates[i] = true;\n const base = config.apiBaseUrl.replace(/\\/$/, '');\n const opts = { withCredentials: config.withCredentials ?? true };\n const calls = step.assigneeUserIds.map(uid =>\n this.http.get<any>(`${base}/urs/users/${encodeURIComponent(uid)}`, opts)\n );\n forkJoin(calls)\n .pipe(takeUntil(this.destroy$))\n .subscribe({\n next: results => {\n this.stepCandidates[i] = results.map((u: any) => ({\n userId: u.id || u.Id,\n fullName: u.fullName || u.FullName || u.userName || u.UserName,\n department: u.department || u.Department,\n position: u.position || u.Position\n } as RolePreviewUserDto));\n // Single assignee — pre-select automatically\n if (this.stepCandidates[i].length === 1) {\n this.stepSelectedUsers[i] = this.stepCandidates[i][0].userId;\n }\n this.stepLoadingCandidates[i] = false;\n },\n error: () => { this.stepLoadingCandidates[i] = false; }\n });\n }\n });\n }\n\n onStepUserChange(stepIndex: number, event: Event) {\n this.stepSelectedUsers[stepIndex] = (event.target as HTMLSelectElement).value;\n }\n\n onTemplateChange(event: Event) {\n const val = (event.target as HTMLSelectElement).value;\n this.selectedTemplateId = val ? parseInt(val, 10) : null;\n this.selectedTemplate = null;\n if (this.selectedTemplateId) {\n this.loadTemplateDetail(this.selectedTemplateId);\n }\n }\n\n addStep() {\n const order = this.adHocSteps.length + 1;\n this.adHocSteps.push({ stepOrder: order, stepName: `Step ${order}`, approverUserIds: [] });\n this.userSearchQuery.push('');\n this.userSearchResults.push([]);\n }\n\n removeStep(i: number) {\n this.adHocSteps.splice(i, 1);\n this.userSearchQuery.splice(i, 1);\n this.userSearchResults.splice(i, 1);\n this.adHocSteps.forEach((s, idx) => s.stepOrder = idx + 1);\n }\n\n addApprover(stepIndex: number, userId: string) {\n if (!this.adHocSteps[stepIndex].approverUserIds.includes(userId)) {\n this.adHocSteps[stepIndex].approverUserIds.push(userId);\n }\n this.storeLabelFromResults(userId, this.userSearchResults[stepIndex]);\n this.userSearchQuery[stepIndex] = '';\n this.userSearchResults[stepIndex] = [];\n }\n\n removeApprover(stepIndex: number, approverIndex: number) {\n this.adHocSteps[stepIndex].approverUserIds.splice(approverIndex, 1);\n }\n\n addReference(userId: string) {\n if (!this.referenceUserIds.includes(userId)) {\n this.referenceUserIds.push(userId);\n }\n this.storeLabelFromResults(userId, this.refSearchResults);\n this.refSearchQuery = '';\n this.refSearchResults = [];\n }\n\n private storeLabelFromResults(userId: string, results: any[]) {\n const user = results.find((u: any) => u.id === userId);\n if (user) {\n const parts = [user.department, user.position, user.fullName].filter(Boolean);\n this.userLabelMap[userId] = parts.length > 0 ? parts.join(' - ') : (user.userName || userId);\n }\n }\n\n removeReference(j: number) {\n this.referenceUserIds.splice(j, 1);\n }\n\n onUserSearchInput(stepIndex: number, query: string) {\n this.userSearchQuery[stepIndex] = query;\n if (!query || query.length < 2) { this.userSearchResults[stepIndex] = []; return; }\n this.searchUsers(query).then(r => this.userSearchResults[stepIndex] = r);\n }\n\n onRefSearchInput(query: string) {\n this.refSearchQuery = query;\n if (!query || query.length < 2) { this.refSearchResults = []; return; }\n this.searchUsers(query).then(r => this.refSearchResults = r);\n }\n\n private searchUsers(query: string): Promise<any[]> {\n const config = this.mesAuth.getConfig();\n if (!config) return Promise.resolve([]);\n const url = `${config.apiBaseUrl.replace(/\\/$/, '')}/urs/users?search=${encodeURIComponent(query)}&page=1&pageSize=20`;\n return this.http.get<any>(url, { withCredentials: config.withCredentials ?? true })\n .toPromise()\n .then((r: any) => {\n const items = r?.data || r?.Data || r?.items || r || [];\n return (Array.isArray(items) ? items : []).map((u: any) => ({\n id: u.id || u.Id,\n userName: u.userName || u.UserName,\n fullName: u.fullName || u.FullName,\n email: u.email || u.Email,\n department: u.department || u.Department,\n position: u.position || u.Position\n }));\n })\n .catch(() => []);\n }\n\n async submit() {\n if (this.submitting) return;\n this.errorMessage = '';\n\n if (!this.approvalSvc) { this.errorMessage = 'Approval service not initialized. Ensure provideMesAuth() is configured.'; return; }\n if (!this.referenceId) { this.errorMessage = 'ReferenceId is required.'; return; }\n if (!this.title) { this.errorMessage = 'Title is required.'; return; }\n\n if (this.routingMode === 'template' && !this.selectedTemplateId) {\n this.errorMessage = 'Please select a template or switch to Custom Steps.'; return;\n }\n if (this.routingMode === 'adhoc' && this.adHocSteps.length === 0) {\n this.errorMessage = 'Please add at least one approval step.'; return;\n }\n // Validate selectable steps (role-based or multi-assignee) have a selected approver\n if (this.routingMode === 'template' && this.selectedTemplate) {\n for (let i = 0; i < this.selectedTemplate.steps.length; i++) {\n const step = this.selectedTemplate.steps[i];\n const isSelectable = (this.stepCandidates[i]?.length ?? 0) > 1;\n if (isSelectable && !this.stepSelectedUsers[i]) {\n this.errorMessage = `Please select an approver for step \"${step.stepName}\".`; return;\n }\n }\n }\n\n // Emit before capture so parent can hide edit controls (inputs, buttons)\n // then wait one tick for Angular CD to update the DOM before snapshotting\n this.approvalSubmitting.emit();\n await new Promise(resolve => setTimeout(resolve));\n\n this.submitting = true;\n\n try {\n const contentHtml = await this.captureContent();\n const thumbnailBase64 = await this.captureThumbnail().catch(() => undefined);\n\n const request: CreateApprovalRequest = {\n title: this.title,\n description: this.description,\n contentHtml,\n thumbnailBase64,\n referenceId: this.referenceId,\n callbackUrl: this.callbackUrl,\n deadlineHours: this.deadlineHours,\n referenceUserIds: this.referenceUserIds.length > 0 ? this.referenceUserIds : undefined\n };\n\n if (this.routingMode === 'template') {\n request.templateId = this.selectedTemplateId ?? this.templateIds?.[0];\n // If template has role-based steps with selected approvers, pass explicit steps\n if (this.selectedTemplate) {\n const hasSelectableSteps = this.selectedTemplate.steps.some(\n (s, i) => (this.stepCandidates[i]?.length ?? 0) > 0\n );\n if (hasSelectableSteps) {\n request.steps = this.selectedTemplate.steps.map((s, i) => ({\n stepOrder: s.stepOrder,\n stepName: s.stepName,\n mode: s.mode,\n approverUserIds: this.stepSelectedUsers[i]\n ? [this.stepSelectedUsers[i]]\n : (this.stepCandidates[i] && this.stepCandidates[i].length > 0\n ? this.stepCandidates[i].map(u => u.userId)\n : s.assigneeUserIds)\n }));\n }\n }\n } else {\n request.steps = this.adHocSteps.map((s, i) => ({\n stepOrder: i + 1,\n stepName: s.stepName,\n mode: ApprovalStepMode.Sequential,\n approverUserIds: s.approverUserIds\n }));\n }\n\n this.approvalSvc!.createApproval(request).pipe(takeUntil(this.destroy$)).subscribe({\n next: (result) => {\n this.isSubmitted = true;\n this.submitting = false;\n this.approvalSubmitted.emit({ documentId: result.documentId, message: result.message });\n },\n error: (err) => {\n this.submitting = false;\n this.errorMessage = err?.error?.message || 'Failed to submit approval. Please try again.';\n }\n });\n } catch (err: any) {\n this.submitting = false;\n this.errorMessage = err?.message || 'Failed to capture content.';\n }\n }\n\n onCancel() {\n this.cancelled.emit();\n }\n\n // ====================== Content Capture ======================\n\n async captureContent(): Promise<string> {\n const host = this.contentBody.nativeElement;\n\n // Step 1: Build canvas -> img map from the live DOM\n const canvasMap = new Map<Element, HTMLImageElement>();\n host.querySelectorAll('canvas').forEach((canvas) => {\n try {\n const img = document.createElement('img');\n img.src = (canvas as HTMLCanvasElement).toDataURL('image/png');\n img.style.width = canvas.offsetWidth + 'px';\n img.style.height = canvas.offsetHeight + 'px';\n canvasMap.set(canvas, img);\n } catch {}\n });\n\n // Step 2: Deep clone\n const clone = host.cloneNode(true) as HTMLElement;\n\n // Step 3: Replace canvas nodes in clone with img snapshots\n const originalCanvases = Array.from(host.querySelectorAll('canvas'));\n clone.querySelectorAll('canvas').forEach((cloneCanvas, idx) => {\n const img = canvasMap.get(originalCanvases[idx]);\n if (img) cloneCanvas.replaceWith(img.cloneNode(true));\n });\n\n // Step 4: Inline all <img> sources as base64 data URIs for content integrity\n const imgElements = Array.from(clone.querySelectorAll('img')) as HTMLImageElement[];\n await Promise.all(imgElements.map(async (img) => {\n const src = img.getAttribute('src');\n if (!src || src.startsWith('data:')) return;\n try {\n const resp = await fetch(src, { mode: 'cors', credentials: 'same-origin' });\n if (!resp.ok) return;\n const blob = await resp.blob();\n const dataUri = await new Promise<string>((resolve) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.readAsDataURL(blob);\n });\n img.setAttribute('src', dataUri);\n } catch { /* keep original src if fetch fails */ }\n }));\n\n // Step 5: Inline only essential layout styles (skip colors, widths, cursors)\n const liveElements = Array.from(host.querySelectorAll('*'));\n const cloneElements = Array.from(clone.querySelectorAll('*'));\n const styleProps = this.getStyleProperties();\n\n liveElements.forEach((liveEl, i) => {\n const cloneEl = cloneElements[i] as HTMLElement;\n if (!cloneEl || typeof cloneEl.setAttribute !== 'function') return;\n try {\n const computed = window.getComputedStyle(liveEl as Element);\n const styles: string[] = [];\n styleProps.forEach(prop => {\n const val = computed.getPropertyValue(prop);\n if (val && val !== '' && val !== 'initial' && val !== 'normal' && val !== 'none' && val !== 'auto') {\n styles.push(`${prop}:${val}`);\n }\n });\n if (styles.length) cloneEl.setAttribute('style', styles.join(';'));\n } catch {}\n });\n\n // Step 6: Strip scripts, Angular attributes, style/link tags, and form elements\n clone.querySelectorAll('script, link, style').forEach(el => el.remove());\n clone.querySelectorAll('*').forEach(el => {\n Array.from(el.attributes).forEach(attr => {\n if (attr.name.startsWith('_ngcontent-') ||\n attr.name.startsWith('_nghost-') ||\n attr.name.startsWith('ng-reflect-') ||\n attr.name.startsWith('ng-version') ||\n attr.name.startsWith('on') ||\n attr.name === 'cformcontrol' ||\n attr.name === 'clabel') {\n el.removeAttribute(attr.name);\n }\n });\n el.removeAttribute('class');\n });\n\n // Step 7: Wrap in a clean, print-friendly HTML document\n return `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <style>\n *, *::before, *::after { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n margin: 0; padding: 24px;\n color: #212121; background: #fff;\n font-size: 14px; line-height: 1.6;\n max-width: 210mm;\n }\n h1, h2, h3, h4, h5, h6 { color: #1565c0; margin: 0 0 12px; }\n p { margin: 0 0 8px; }\n img { max-width: 100%; }\n table { border-collapse: collapse; width: 100%; }\n td, th { padding: 8px 12px; border: 1px solid #ddd; text-align: left; vertical-align: top; }\n input, textarea, select {\n border: 1px solid #ccc; border-radius: 4px; padding: 6px 10px;\n font-size: 14px; width: 100%; background: #fafafa; color: #333;\n }\n label { font-weight: 500; display: block; margin-bottom: 4px; color: #333; }\n div { max-width: 100%; }\n </style>\n</head>\n<body>\n${clone.outerHTML}\n</body>\n</html>`;\n }\n\n private async captureThumbnail(): Promise<string | undefined> {\n const html2canvas = (window as any)['html2canvas'];\n if (!html2canvas) return undefined;\n\n const canvas: HTMLCanvasElement = await html2canvas(this.contentBody.nativeElement, {\n scale: 1, useCORS: true, logging: false, width: 600, height: 400\n });\n return canvas.toDataURL('image/png').split(',')[1];\n }\n\n private getStyleProperties(): string[] {\n return [\n 'font-size', 'font-weight', 'font-style', 'line-height', 'text-align', 'text-decoration',\n 'border', 'border-top', 'border-right', 'border-bottom', 'border-left',\n 'border-width', 'border-style', 'border-radius',\n 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left',\n 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left',\n 'display', 'flex-direction', 'flex-wrap', 'justify-content', 'align-items', 'gap',\n 'vertical-align', 'table-layout', 'border-collapse', 'border-spacing',\n 'text-transform', 'letter-spacing', 'white-space', 'word-break'\n ];\n }\n}\n","<div class=\"arv-container\">\n <!-- Content Area -->\n <div class=\"arv-content-body\" #contentBody>\n <ng-content></ng-content>\n </div>\n\n <!-- Approval Footer -->\n <div class=\"arv-footer\">\n @if (!isSubmitted) {\n <div class=\"arv-footer-inner\">\n\n <!-- Routing mode -->\n <div class=\"arv-routing\">\n <div class=\"arv-routing-header\">\n <h4 class=\"arv-section-title\">Approval Routing</h4>\n <!-- Show routing toggle only when templateId is NOT locked to a single template -->\n @if (!templateIds || templateIds.length <= 0) {\n <div class=\"arv-routing-mode\">\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"template\" [checked]=\"routingMode === 'template'\" (change)=\"routingMode = 'template'\"> Use Template\n </label>\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"adhoc\" [checked]=\"routingMode === 'adhoc'\" (change)=\"routingMode = 'adhoc'\"> Custom Steps\n </label>\n </div>\n }\n </div>\n\n <!-- Locked template: only when templateId set and no multi-choice -->\n @if (templateIds && templateIds.length === 1 && routingMode === 'template') {\n <div class=\"arv-template-select\">\n @if (loadingTemplate) {\n <div class=\"arv-template-loading\">Loading template...</div>\n }\n @if (selectedTemplate && !loadingTemplate) {\n <div class=\"arv-locked-template\">\n <span class=\"arv-locked-label\">Template</span>\n <span class=\"arv-locked-name\">{{ selectedTemplate.name }}</span>\n </div>\n }\n </div>\n }\n <!-- Template selector: shown when no templateId, OR when templateIds has multiple choices -->\n @else {\n <div class=\"arv-template-select\">\n <label class=\"arv-label\">Select Template</label>\n <select class=\"arv-select\" (change)=\"onTemplateChange($event)\">\n <option value=\"\">-- Select a template --</option>\n @for (t of templates; track t.id) {\n <option [value]=\"t.id\" [selected]=\"t.id === selectedTemplateId\">{{ t.name }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Step pickers (shared for both locked and free template) -->\n @if (routingMode === 'template') {\n <div class=\"arv-template-select\">\n @if (!loadingTemplate && selectedTemplate) {\n <div class=\"arv-template-steps\">\n @for (s of selectedTemplate.steps; track s.stepOrder; let i = $index) {\n <div class=\"arv-step-card\">\n <div class=\"arv-step-card-header\">\n <span class=\"arv-step-preview-num\">Step {{ s.stepOrder }}</span>\n <span class=\"arv-step-preview-name\">{{ s.stepName }}</span>\n @if (s.roles && s.roles.length > 0) {\n <span class=\"arv-step-role-badge\">\n {{ s.roles[0].positionLevel }}{{ s.roles[0].orgName ? ' · ' + s.roles[0].orgName : '' }}\n </span>\n }\n </div>\n <!-- Selectable step: show approver picker -->\n @if (stepCandidates[i]?.length > 1 || stepLoadingCandidates[i]) {\n <div class=\"arv-step-picker\">\n @if (stepLoadingCandidates[i]) {\n <div class=\"arv-template-loading\">Loading candidates...</div>\n }\n @if (!stepLoadingCandidates[i]) {\n <select class=\"arv-select arv-select-sm\" (change)=\"onStepUserChange(i, $event)\">\n <option value=\"\">-- Select approver --</option>\n @for (u of stepCandidates[i]; track u.userId) {\n <option [value]=\"u.userId\" [selected]=\"u.userId === stepSelectedUsers[i]\">\n {{ u.fullName || u.userId }}{{ u.department ? ' · ' + u.department : '' }}{{ u.position ? ' (' + u.position + ')' : '' }}\n </option>\n }\n </select>\n }\n </div>\n }\n <!-- Single fixed-user step: show who is assigned -->\n @if (!stepLoadingCandidates[i] && stepCandidates[i]?.length === 1) {\n <div class=\"arv-step-fixed\">\n {{ stepCandidates[i][0].fullName || stepCandidates[i][0].userId }}{{ stepCandidates[i][0].department ? ' · ' + stepCandidates[i][0].department : '' }}{{ stepCandidates[i][0].position ? ' (' + stepCandidates[i][0].position + ')' : '' }}\n </div>\n }\n </div>\n }\n @if (selectedTemplate.referenceUserIds.length > 0) {\n <div class=\"arv-step-preview arv-step-preview-cc\">\n <span class=\"arv-step-preview-num\">CC</span>\n <span class=\"arv-step-preview-name\">{{ selectedTemplate.referenceUserIds.length }} reference user(s) from template</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Ad-hoc steps -->\n @if (routingMode === 'adhoc') {\n <div class=\"arv-steps\">\n @for (step of adHocSteps; track step.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-header\">\n <span class=\"arv-step-num\">Step {{ i + 1 }}</span>\n <input class=\"arv-input\" [value]=\"step.stepName\" (input)=\"step.stepName = $any($event.target).value\" placeholder=\"Step name\" />\n <button class=\"arv-btn-icon arv-btn-danger\" (click)=\"removeStep(i)\" title=\"Remove step\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>\n </button>\n </div>\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @for (uid of step.approverUserIds; track uid; let j = $index) {\n <span class=\"arv-tag\">\n {{ userLabelMap[uid] || uid }}\n <button class=\"arv-tag-remove\" (click)=\"removeApprover(i, j)\">x</button>\n </span>\n }\n </div>\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"userSearchQuery[i] || ''\"\n (input)=\"onUserSearchInput(i, $any($event.target).value)\"\n placeholder=\"Search approver...\" />\n @if (userSearchResults[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of userSearchResults[i]; track u.id) {\n <div class=\"arv-search-item\" (click)=\"addApprover(i, u.id)\">\n {{ u.fullName || u.userName }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n <button class=\"arv-btn arv-btn-outline\" (click)=\"addStep()\">+ Add Step</button>\n </div>\n }\n </div>\n\n <!-- Reference / CC users -->\n <div class=\"arv-references\">\n <h4 class=\"arv-section-title\">CC / Reference</h4>\n <p class=\"arv-hint\">These users will be notified when the approval completes, but won't be asked to approve.</p>\n <div class=\"arv-approver-tags\">\n @for (uid of referenceUserIds; track uid; let j = $index) {\n <span class=\"arv-tag\">\n {{ userLabelMap[uid] || uid }}\n <button class=\"arv-tag-remove\" (click)=\"removeReference(j)\">x</button>\n </span>\n }\n </div>\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"refSearchQuery\"\n (input)=\"onRefSearchInput($any($event.target).value)\"\n placeholder=\"Search CC user...\" />\n @if (refSearchResults?.length) {\n <div class=\"arv-search-results\">\n @for (u of refSearchResults; track u.id) {\n <div class=\"arv-search-item\" (click)=\"addReference(u.id)\">\n {{ u.fullName || u.userName }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"arv-actions\">\n <button class=\"arv-btn arv-btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"arv-btn arv-btn-primary\" [disabled]=\"submitting\" (click)=\"submit()\">\n @if (submitting) {\n <span class=\"arv-spinner\"></span>\n }\n {{ submitting ? 'Submitting...' : 'Submit for Approval' }}\n </button>\n </div>\n\n @if (errorMessage) {\n <div class=\"arv-error\">{{ errorMessage }}</div>\n }\n </div>\n }\n </div>\n\n <!-- Success state -->\n @if (isSubmitted) {\n <div class=\"arv-success\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#66bb6a\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n <p>Submitted for approval successfully.</p>\n </div>\n }\n</div>\n","import { HttpResponse } from '@angular/common/http';\nimport { map } from 'rxjs/operators';\nimport { OperatorFunction } from 'rxjs';\n\nexport interface PermissionHeader {\n resource: string;\n allowedActions: string[];\n}\n// ─── Utility: extract allowedActions from x-ma-perm header ───\n \nexport const ALL_ACTIONS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'WEBSOCKET'] as const;\n\nexport function extractXMaPerm(response: HttpResponse<unknown>): string[] {\n const raw = response.headers.get('x-ma-perm');\n if (!raw) return [];\n \n try {\n const parsed = JSON.parse(raw) as PermissionHeader;\n const actions = parsed?.allowedActions ?? [];\n // Wildcard means all actions are allowed\n if (actions.includes('*')) return [...ALL_ACTIONS];\n return actions;\n } catch {\n return [];\n }\n}\n \n// ─── RxJS operator: pipe it on any HttpClient call ───\n \nexport function withXMaPerm<T>(): OperatorFunction<\n HttpResponse<T>,\n { data: T; allowedActions: string[] }\n> {\n return map((response: HttpResponse<T>) => ({\n data: response.body as T,\n allowedActions: extractXMaPerm(response),\n }));\n}","import { inject } from '@angular/core';\nimport { rxResource } from '@angular/core/rxjs-interop';\nimport { HttpClient, HttpParams } from '@angular/common/http';\nimport { withXMaPerm } from './x-ma-perm.pipe';\n\nexport interface RequestConfig {\n url: string;\n params?: HttpParams | Record<string, string | string[]>;\n}\n\nexport function xMaResource<T>(request: () => RequestConfig) {\n const http = inject(HttpClient);\n\n return rxResource({\n params: () => request(),\n stream: ({ params: { url, params } }) =>\n http\n .get<T>(url, { observe: 'response', params })\n .pipe(withXMaPerm()),\n });\n}","import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { inject } from '@angular/core';\n\n/**\n * MaIconComponent\n * Renders an SVG icon from the server-hosted sprite.\n * The sprite URL is derived from the stylesheet link injected by MesAuthService,\n * so changing the sprite on the server updates icons without a package rebuild.\n *\n * Selector: <ma-icon name=\"bell\" [size]=\"20\" />\n *\n * When the sprite is not available, falls back to inline SVG definitions\n * for the icons used internally by the library (bell, check, close, etc.).\n *\n * This component is intentionally lightweight — it is the single place where\n * icon SVG is defined, replacing the repeated inline <svg> blocks that were\n * scattered across every component template.\n */\n@Component({\n selector: 'ma-icon',\n standalone: true,\n template: `<span class=\"ma-icon\" [style.width.px]=\"size\" [style.height.px]=\"size\" [innerHTML]=\"svgContent\"></span>`,\n styles: [`\n :host { display: inline-flex; align-items: center; justify-content: center; }\n .ma-icon { display: flex; align-items: center; justify-content: center; }\n .ma-icon svg { display: block; }\n `]\n})\nexport class MaIconComponent implements OnChanges {\n @Input() name = '';\n @Input() size = 18;\n @Input() stroke = 'currentColor';\n @Input() strokeWidth = 2;\n\n svgContent: SafeHtml = '';\n\n private sanitizer = inject(DomSanitizer);\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes['name'] || changes['size'] || changes['stroke'] || changes['strokeWidth']) {\n this.svgContent = this.sanitizer.bypassSecurityTrustHtml(this.buildSvg());\n }\n }\n\n private buildSvg(): string {\n const w = this.size;\n const h = this.size;\n const s = this.stroke;\n const sw = this.strokeWidth;\n const base = `xmlns=\"http://www.w3.org/2000/svg\" width=\"${w}\" height=\"${h}\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${s}\" stroke-width=\"${sw}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"`;\n\n switch (this.name) {\n case 'bell':\n return `<svg ${base}><path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/></svg>`;\n case 'check':\n return `<svg ${base}><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n case 'check-circle':\n return `<svg ${base}><path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/><polyline points=\"22 4 12 14.01 9 11.01\"/></svg>`;\n case 'close':\n return `<svg ${base}><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`;\n case 'alert-triangle':\n return `<svg ${base}><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></svg>`;\n case 'x-circle':\n return `<svg ${base}><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/></svg>`;\n case 'clipboard-check':\n return `<svg ${base}><path d=\"M9 11l3 3L22 4\"/><path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"/></svg>`;\n case 'trash':\n return `<svg ${base}><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6\"/><path d=\"M10 11v6\"/><path d=\"M14 11v6\"/><path d=\"M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2\"/></svg>`;\n case 'user':\n return `<svg ${base}><path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"/><circle cx=\"12\" cy=\"7\" r=\"4\"/></svg>`;\n case 'log-out':\n return `<svg ${base}><path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\"/><polyline points=\"16 17 21 12 16 7\"/><line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"/></svg>`;\n default:\n return `<svg ${base}><circle cx=\"12\" cy=\"12\" r=\"10\"/></svg>`;\n }\n }\n}\n","import { Directive, HostBinding, OnInit, OnDestroy } from '@angular/core';\nimport { ThemeService, Theme } from './theme.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { inject } from '@angular/core';\n\n/**\n * MaThemeDirective\n * Apply `maTheme` to any element or component that needs automatic theme-class binding.\n * Adds `theme-light` or `theme-dark` to the host element's class list and keeps it\n * in sync with ThemeService, replacing the duplicated @HostBinding + subscription\n * pattern that was repeated in every component.\n *\n * Usage:\n * <div maTheme> ... </div>\n *\n * Or as a hostDirective in a component:\n * @Component({ hostDirectives: [MaThemeDirective], ... })\n */\n@Directive({\n selector: '[maTheme]',\n standalone: true\n})\nexport class MaThemeDirective implements OnInit, OnDestroy {\n @HostBinding('class') themeClass = 'theme-light';\n\n private themeService = inject(ThemeService);\n private destroy$ = new Subject<void>();\n\n ngOnInit() {\n this.themeService.currentTheme$\n .pipe(takeUntil(this.destroy$))\n .subscribe((theme: Theme) => {\n this.themeClass = `theme-${theme}`;\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","// mesauth-angular — primary entry point (backward compatible)\n// Re-exports everything so existing imports from 'mesauth-angular' continue to work.\n// Prefer importing from 'mesauth-angular/core' or 'mesauth-angular/ui' for\n// better tree-shaking and to express which layer you depend on.\n\nexport * from './mes-auth.service';\nexport * from './mes-auth.interceptor';\nexport * from './mes-auth.module';\nexport * from './user-profile.component';\nexport * from './ma-user.component';\nexport * from './notification-badge.component';\nexport * from './notification-panel.component';\nexport * from './toast-container.component';\nexport * from './toast.service';\nexport * from './theme.service';\nexport * from './approval.models';\nexport * from './approval.service';\nexport * from './ma-arv-container.component';\nexport * from './ma-approval-panel.component';\nexport * from './x-ma-perm.pipe';\nexport * from './x-ma-resource';\nexport * from './ma-ui-config.service';\nexport * from './ma-icon.component';\nexport * from './ma-theme.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["catchError","i1.MesAuthService","i3.ThemeService","i1.ToastService","i2.ThemeService","i2.ToastService"],"mappings":"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"}
|