mesauth-angular 1.1.8 → 1.1.9

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.
@@ -1055,7 +1055,7 @@ class NotificationPanelComponent {
1055
1055
  </div>
1056
1056
  </div>
1057
1057
  </div>
1058
- `, isInline: true, styles: [":host{--primary-color: #1976d2;--primary-hover: #1565c0;--success-color: #4caf50;--error-color: #f44336;--text-primary: #333;--text-secondary: #666;--text-muted: #999;--bg-primary: white;--bg-secondary: #f5f5f5;--bg-tertiary: #fafafa;--bg-hover: #f5f5f5;--bg-unread: #e3f2fd;--border-color: #e0e0e0;--border-light: #f0f0f0;--shadow: rgba(0, 0, 0, .1)}:host(.theme-dark){--primary-color: #90caf9;--primary-hover: #64b5f6;--success-color: #81c784;--error-color: #ef5350;--text-primary: #e0e0e0;--text-secondary: #b0b0b0;--text-muted: #888;--bg-primary: #1e1e1e;--bg-secondary: #2d2d2d;--bg-tertiary: #252525;--bg-hover: #333;--bg-unread: rgba(144, 202, 249, .1);--border-color: #404040;--border-light: #333;--shadow: rgba(0, 0, 0, .3)}.notification-panel{position:fixed;top:0;right:-350px;width:350px;height:100vh;background:var(--bg-primary);box-shadow:-2px 0 8px var(--shadow);display:flex;flex-direction:column;z-index:1000;transition:right .3s ease}.notification-panel.open{right:0}.panel-header{display:flex;justify-content:space-between;align-items:center;padding:16px;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary)}.panel-header h3{margin:0;font-size:18px;color:var(--text-primary)}.close-btn{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn:hover{color:var(--text-primary)}.tabs{display:flex;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary)}.tab-btn{flex:1;padding:12px 16px;background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:14px;font-weight:500;transition:all .2s;border-bottom:2px solid transparent}.tab-btn:hover{background-color:var(--bg-hover);color:var(--text-primary)}.tab-btn.active{color:var(--primary-color);border-bottom-color:var(--primary-color);background-color:var(--bg-primary)}.notifications-list{flex:1;overflow-y:auto}.notification-item{display:flex;gap:12px;padding:12px 16px;border-bottom:1px solid var(--border-light);cursor:pointer;background-color:var(--bg-tertiary);transition:background-color .2s}.notification-item:hover{background-color:var(--bg-hover)}.notification-item.unread{background-color:var(--bg-unread)}.notification-content{flex:1;min-width:0}.notification-title{font-weight:600;color:var(--text-primary);font-size:14px;margin-bottom:4px}.notification-message{color:var(--text-secondary);font-size:13px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.notification-meta{display:flex;justify-content:space-between;font-size:12px;color:var(--text-muted)}.app-name{font-weight:500;color:var(--primary-color)}.read-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.read-btn:hover{color:var(--success-color)}.delete-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.delete-btn:hover{color:var(--error-color)}.empty-state{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:14px}.panel-footer{padding:12px 16px;border-top:1px solid var(--border-color);background-color:var(--bg-secondary)}.footer-actions{display:flex;gap:8px}.footer-actions .action-btn{flex:1}.action-btn{width:100%;padding:8px;background-color:var(--primary-color);color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:500;transition:background-color .2s}.action-btn:hover{background-color:var(--primary-hover)}.delete-all-btn{background-color:var(--error-color);color:#fff}.delete-all-btn:hover{background-color:#d32f2f}.modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1100}.modal-container{background:var(--bg-primary);border-radius:8px;width:90%;max-width:600px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 4px 20px var(--shadow)}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary);border-radius:8px 8px 0 0}.modal-header h3{margin:0;font-size:18px;color:var(--text-primary)}.modal-meta{display:flex;justify-content:space-between;padding:8px 20px;font-size:12px;color:var(--text-muted);background-color:var(--bg-tertiary);border-bottom:1px solid var(--border-light)}.modal-body{padding:20px;overflow-y:auto;flex:1;color:var(--text-primary);font-size:14px;line-height:1.6}.modal-footer{padding:12px 20px;border-top:1px solid var(--border-color);background-color:var(--bg-secondary);border-radius:0 0 8px 8px;display:flex;justify-content:flex-end}.modal-footer .action-btn{width:auto;padding:8px 24px}@media(max-width:600px){.notification-panel{width:100%;right:-100%}.modal-container{width:95%;max-height:90vh}}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
1058
+ `, isInline: true, styles: [":host{display:block;position:relative;--primary-color: #1976d2;--primary-hover: #1565c0;--success-color: #4caf50;--error-color: #f44336;--text-primary: #333;--text-secondary: #666;--text-muted: #999;--bg-primary: white;--bg-secondary: #f5f5f5;--bg-tertiary: #fafafa;--bg-hover: #f5f5f5;--bg-unread: #e3f2fd;--border-color: #e0e0e0;--border-light: #f0f0f0;--shadow: rgba(0, 0, 0, .1)}:host(.theme-dark){display:block;position:relative;--primary-color: #90caf9;--primary-hover: #64b5f6;--success-color: #81c784;--error-color: #ef5350;--text-primary: #e0e0e0;--text-secondary: #b0b0b0;--text-muted: #888;--bg-primary: #1e1e1e;--bg-secondary: #2d2d2d;--bg-tertiary: #252525;--bg-hover: #333;--bg-unread: rgba(144, 202, 249, .1);--border-color: #404040;--border-light: #333;--shadow: rgba(0, 0, 0, .3)}.notification-panel{position:fixed;top:0;right:-350px;width:350px;height:100vh;background:var(--bg-primary);box-shadow:-2px 0 8px var(--shadow);display:flex;flex-direction:column;z-index:1000;transition:right .3s ease}.notification-panel.open{right:0}.panel-header{display:flex;justify-content:space-between;align-items:center;padding:16px;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary)}.panel-header h3{margin:0;font-size:18px;color:var(--text-primary)}.close-btn{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn:hover{color:var(--text-primary)}.tabs{display:flex;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary)}.tab-btn{flex:1;padding:12px 16px;background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:14px;font-weight:500;transition:all .2s;border-bottom:2px solid transparent}.tab-btn:hover{background-color:var(--bg-hover);color:var(--text-primary)}.tab-btn.active{color:var(--primary-color);border-bottom-color:var(--primary-color);background-color:var(--bg-primary)}.notifications-list{flex:1;overflow-y:auto}.notification-item{display:flex;gap:12px;padding:12px 16px;border-bottom:1px solid var(--border-light);cursor:pointer;background-color:var(--bg-tertiary);transition:background-color .2s}.notification-item:hover{background-color:var(--bg-hover)}.notification-item.unread{background-color:var(--bg-unread)}.notification-content{flex:1;min-width:0}.notification-title{font-weight:600;color:var(--text-primary);font-size:14px;margin-bottom:4px}.notification-message{color:var(--text-secondary);font-size:12px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.notification-meta{display:flex;justify-content:space-between;font-size:12px;color:var(--text-muted)}.app-name{font-weight:500;color:var(--primary-color)}.read-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.read-btn:hover{color:var(--success-color)}.delete-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.delete-btn:hover{color:var(--error-color)}.empty-state{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:14px}.panel-footer{padding:12px 16px;border-top:1px solid var(--border-color);background-color:var(--bg-secondary)}.footer-actions{display:flex;gap:8px}.footer-actions .action-btn{flex:1}.action-btn{width:100%;padding:8px;background-color:var(--primary-color);color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:500;transition:background-color .2s}.action-btn:hover{background-color:var(--primary-hover)}.delete-all-btn{background-color:var(--error-color);color:#fff}.delete-all-btn:hover{background-color:#d32f2f}.modal-overlay{position:fixed;inset:0;width:100vw;height:100vh;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:9999}.modal-container{background:var(--bg-primary);border-radius:8px;width:90%;max-width:600px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 4px 20px var(--shadow)}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary);border-radius:8px 8px 0 0}.modal-header h3{margin:0;font-size:18px;color:var(--text-primary)}.modal-meta{display:flex;justify-content:space-between;padding:8px 20px;font-size:12px;color:var(--text-muted);background-color:var(--bg-tertiary);border-bottom:1px solid var(--border-light)}.modal-body{padding:20px;overflow-y:auto;flex:1;color:var(--text-primary);font-size:14px;line-height:1.6}.modal-footer{padding:12px 20px;border-top:1px solid var(--border-color);background-color:var(--bg-secondary);border-radius:0 0 8px 8px;display:flex;justify-content:flex-end}.modal-footer .action-btn{width:auto;padding:8px 24px}@media(max-width:600px){.notification-panel{width:100%;right:-100%}.modal-container{width:95%;max-height:90vh}}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
1059
1059
  }
1060
1060
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationPanelComponent, decorators: [{
1061
1061
  type: Component,
@@ -1161,7 +1161,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1161
1161
  </div>
1162
1162
  </div>
1163
1163
  </div>
1164
- `, styles: [":host{--primary-color: #1976d2;--primary-hover: #1565c0;--success-color: #4caf50;--error-color: #f44336;--text-primary: #333;--text-secondary: #666;--text-muted: #999;--bg-primary: white;--bg-secondary: #f5f5f5;--bg-tertiary: #fafafa;--bg-hover: #f5f5f5;--bg-unread: #e3f2fd;--border-color: #e0e0e0;--border-light: #f0f0f0;--shadow: rgba(0, 0, 0, .1)}:host(.theme-dark){--primary-color: #90caf9;--primary-hover: #64b5f6;--success-color: #81c784;--error-color: #ef5350;--text-primary: #e0e0e0;--text-secondary: #b0b0b0;--text-muted: #888;--bg-primary: #1e1e1e;--bg-secondary: #2d2d2d;--bg-tertiary: #252525;--bg-hover: #333;--bg-unread: rgba(144, 202, 249, .1);--border-color: #404040;--border-light: #333;--shadow: rgba(0, 0, 0, .3)}.notification-panel{position:fixed;top:0;right:-350px;width:350px;height:100vh;background:var(--bg-primary);box-shadow:-2px 0 8px var(--shadow);display:flex;flex-direction:column;z-index:1000;transition:right .3s ease}.notification-panel.open{right:0}.panel-header{display:flex;justify-content:space-between;align-items:center;padding:16px;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary)}.panel-header h3{margin:0;font-size:18px;color:var(--text-primary)}.close-btn{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn:hover{color:var(--text-primary)}.tabs{display:flex;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary)}.tab-btn{flex:1;padding:12px 16px;background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:14px;font-weight:500;transition:all .2s;border-bottom:2px solid transparent}.tab-btn:hover{background-color:var(--bg-hover);color:var(--text-primary)}.tab-btn.active{color:var(--primary-color);border-bottom-color:var(--primary-color);background-color:var(--bg-primary)}.notifications-list{flex:1;overflow-y:auto}.notification-item{display:flex;gap:12px;padding:12px 16px;border-bottom:1px solid var(--border-light);cursor:pointer;background-color:var(--bg-tertiary);transition:background-color .2s}.notification-item:hover{background-color:var(--bg-hover)}.notification-item.unread{background-color:var(--bg-unread)}.notification-content{flex:1;min-width:0}.notification-title{font-weight:600;color:var(--text-primary);font-size:14px;margin-bottom:4px}.notification-message{color:var(--text-secondary);font-size:13px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.notification-meta{display:flex;justify-content:space-between;font-size:12px;color:var(--text-muted)}.app-name{font-weight:500;color:var(--primary-color)}.read-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.read-btn:hover{color:var(--success-color)}.delete-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.delete-btn:hover{color:var(--error-color)}.empty-state{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:14px}.panel-footer{padding:12px 16px;border-top:1px solid var(--border-color);background-color:var(--bg-secondary)}.footer-actions{display:flex;gap:8px}.footer-actions .action-btn{flex:1}.action-btn{width:100%;padding:8px;background-color:var(--primary-color);color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:500;transition:background-color .2s}.action-btn:hover{background-color:var(--primary-hover)}.delete-all-btn{background-color:var(--error-color);color:#fff}.delete-all-btn:hover{background-color:#d32f2f}.modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:1100}.modal-container{background:var(--bg-primary);border-radius:8px;width:90%;max-width:600px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 4px 20px var(--shadow)}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary);border-radius:8px 8px 0 0}.modal-header h3{margin:0;font-size:18px;color:var(--text-primary)}.modal-meta{display:flex;justify-content:space-between;padding:8px 20px;font-size:12px;color:var(--text-muted);background-color:var(--bg-tertiary);border-bottom:1px solid var(--border-light)}.modal-body{padding:20px;overflow-y:auto;flex:1;color:var(--text-primary);font-size:14px;line-height:1.6}.modal-footer{padding:12px 20px;border-top:1px solid var(--border-color);background-color:var(--bg-secondary);border-radius:0 0 8px 8px;display:flex;justify-content:flex-end}.modal-footer .action-btn{width:auto;padding:8px 24px}@media(max-width:600px){.notification-panel{width:100%;right:-100%}.modal-container{width:95%;max-height:90vh}}\n"] }]
1164
+ `, styles: [":host{display:block;position:relative;--primary-color: #1976d2;--primary-hover: #1565c0;--success-color: #4caf50;--error-color: #f44336;--text-primary: #333;--text-secondary: #666;--text-muted: #999;--bg-primary: white;--bg-secondary: #f5f5f5;--bg-tertiary: #fafafa;--bg-hover: #f5f5f5;--bg-unread: #e3f2fd;--border-color: #e0e0e0;--border-light: #f0f0f0;--shadow: rgba(0, 0, 0, .1)}:host(.theme-dark){display:block;position:relative;--primary-color: #90caf9;--primary-hover: #64b5f6;--success-color: #81c784;--error-color: #ef5350;--text-primary: #e0e0e0;--text-secondary: #b0b0b0;--text-muted: #888;--bg-primary: #1e1e1e;--bg-secondary: #2d2d2d;--bg-tertiary: #252525;--bg-hover: #333;--bg-unread: rgba(144, 202, 249, .1);--border-color: #404040;--border-light: #333;--shadow: rgba(0, 0, 0, .3)}.notification-panel{position:fixed;top:0;right:-350px;width:350px;height:100vh;background:var(--bg-primary);box-shadow:-2px 0 8px var(--shadow);display:flex;flex-direction:column;z-index:1000;transition:right .3s ease}.notification-panel.open{right:0}.panel-header{display:flex;justify-content:space-between;align-items:center;padding:16px;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary)}.panel-header h3{margin:0;font-size:18px;color:var(--text-primary)}.close-btn{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn:hover{color:var(--text-primary)}.tabs{display:flex;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary)}.tab-btn{flex:1;padding:12px 16px;background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:14px;font-weight:500;transition:all .2s;border-bottom:2px solid transparent}.tab-btn:hover{background-color:var(--bg-hover);color:var(--text-primary)}.tab-btn.active{color:var(--primary-color);border-bottom-color:var(--primary-color);background-color:var(--bg-primary)}.notifications-list{flex:1;overflow-y:auto}.notification-item{display:flex;gap:12px;padding:12px 16px;border-bottom:1px solid var(--border-light);cursor:pointer;background-color:var(--bg-tertiary);transition:background-color .2s}.notification-item:hover{background-color:var(--bg-hover)}.notification-item.unread{background-color:var(--bg-unread)}.notification-content{flex:1;min-width:0}.notification-title{font-weight:600;color:var(--text-primary);font-size:14px;margin-bottom:4px}.notification-message{color:var(--text-secondary);font-size:12px;line-height:1.4;margin-bottom:6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.notification-meta{display:flex;justify-content:space-between;font-size:12px;color:var(--text-muted)}.app-name{font-weight:500;color:var(--primary-color)}.read-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.read-btn:hover{color:var(--success-color)}.delete-btn{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:color .2s}.delete-btn:hover{color:var(--error-color)}.empty-state{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:14px}.panel-footer{padding:12px 16px;border-top:1px solid var(--border-color);background-color:var(--bg-secondary)}.footer-actions{display:flex;gap:8px}.footer-actions .action-btn{flex:1}.action-btn{width:100%;padding:8px;background-color:var(--primary-color);color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:500;transition:background-color .2s}.action-btn:hover{background-color:var(--primary-hover)}.delete-all-btn{background-color:var(--error-color);color:#fff}.delete-all-btn:hover{background-color:#d32f2f}.modal-overlay{position:fixed;inset:0;width:100vw;height:100vh;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:9999}.modal-container{background:var(--bg-primary);border-radius:8px;width:90%;max-width:600px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 4px 20px var(--shadow)}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--border-color);background-color:var(--bg-secondary);border-radius:8px 8px 0 0}.modal-header h3{margin:0;font-size:18px;color:var(--text-primary)}.modal-meta{display:flex;justify-content:space-between;padding:8px 20px;font-size:12px;color:var(--text-muted);background-color:var(--bg-tertiary);border-bottom:1px solid var(--border-light)}.modal-body{padding:20px;overflow-y:auto;flex:1;color:var(--text-primary);font-size:14px;line-height:1.6}.modal-footer{padding:12px 20px;border-top:1px solid var(--border-color);background-color:var(--bg-secondary);border-radius:0 0 8px 8px;display:flex;justify-content:flex-end}.modal-footer .action-btn{width:auto;padding:8px 24px}@media(max-width:600px){.notification-panel{width:100%;right:-100%}.modal-container{width:95%;max-height:90vh}}\n"] }]
1165
1165
  }], ctorParameters: () => [{ type: MesAuthService }, { type: ToastService }, { type: ThemeService }], propDecorators: { notificationRead: [{
1166
1166
  type: Output
1167
1167
  }], themeClass: [{
@@ -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/ma-user.component.ts","../../src/notification-badge.component.ts","../../src/mesauth-angular.ts"],"sourcesContent":["import { inject, Injectable, InjectionToken, EnvironmentProviders, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { HubConnection, HubConnectionBuilder, LogLevel } from '@microsoft/signalr';\r\nimport { BehaviorSubject, Subject, Observable } from 'rxjs';\r\nimport { tap, filter, debounceTime } from 'rxjs/operators';\r\nimport { Router, NavigationEnd } from '@angular/router';\r\n\r\nexport interface MesAuthConfig {\r\n apiBaseUrl: string;\r\n withCredentials?: boolean;\r\n userBaseUrl?: string;\r\n}\r\n\r\n/** Injection token for MesAuth configuration */\r\nexport const MES_AUTH_CONFIG = new InjectionToken<MesAuthConfig>('MES_AUTH_CONFIG');\r\n\r\n/**\r\n * Provides MesAuth with configuration.\r\n * This is the recommended way to set up mesauth-angular in standalone apps.\r\n *\r\n * @example\r\n * ```typescript\r\n * // app.config.ts\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideHttpClient(withInterceptors([mesAuthInterceptor])),\r\n * provideMesAuth({\r\n * apiBaseUrl: 'https://auth.example.com',\r\n * userBaseUrl: 'https://app.example.com'\r\n * })\r\n * ]\r\n * };\r\n * ```\r\n */\r\nexport function provideMesAuth(config: MesAuthConfig): EnvironmentProviders {\r\n return makeEnvironmentProviders([\r\n { provide: MES_AUTH_CONFIG, useValue: config },\r\n MesAuthService,\r\n provideAppInitializer(() => {\r\n const mesAuthService = inject(MesAuthService);\r\n const httpClient = inject(HttpClient);\r\n const router = inject(Router);\r\n mesAuthService.init(config, httpClient, router);\r\n })\r\n ]);\r\n}\r\n\r\nexport interface IUser {\r\n userId?: string;\r\n userName?: string;\r\n fullName?: string;\r\n gender?: string;\r\n email?: string;\r\n phoneNumber?: string;\r\n department?: string;\r\n position?: string;\r\n tokenVersion?: string;\r\n permEndpoint?: string;\r\n perms?: Set<string>;\r\n employeeCode?: string;\r\n avatarPath?: string;\r\n loginMethod?: number;\r\n hrFullNameVn?: string;\r\n hrFullNameEn?: string;\r\n hrPosition?: string;\r\n hrJobTitle?: string;\r\n hrGender?: string;\r\n hrMobile?: string;\r\n hrEmail?: string;\r\n hrJoinDate?: string;\r\n hrBirthDate?: string;\r\n hrWorkStatus?: string;\r\n hrDoiTuong?: string;\r\n hrTeamCode?: string;\r\n hrLineCode?: string;\r\n}\r\n\r\nexport enum NotificationType {\r\n Info = 'Info',\r\n Warning = 'Warning',\r\n Error = 'Error',\r\n Success = 'Success'\r\n}\r\n\r\nexport interface NotificationDto {\r\n id: string;\r\n title: string;\r\n message: string;\r\n messageHtml?: string;\r\n url?: string;\r\n type: NotificationType;\r\n isRead: boolean;\r\n createdAt: string;\r\n sourceAppName: string;\r\n sourceAppIconUrl?: string;\r\n}\r\n\r\nexport interface FrontEndRoute {\r\n id: number;\r\n roleId: string;\r\n roleName: string;\r\n routePath: string;\r\n routeName: string;\r\n description?: string;\r\n icon?: string;\r\n cssClass?: string;\r\n parentId?: number | null;\r\n sortOrder: number;\r\n isLabel: boolean;\r\n isActive: boolean;\r\n createdAt: string;\r\n updatedAt?: string;\r\n children: FrontEndRoute[];\r\n}\r\n\r\nexport interface UserFrontEndRoutesGrouped {\r\n appId: string;\r\n appName: string;\r\n feUrl?: string;\r\n routes: FrontEndRoute[];\r\n}\r\n\r\nexport interface FrontEndRouteMaster {\r\n id: number;\r\n appId: string;\r\n routePath: string;\r\n routeName: string;\r\n description?: string;\r\n icon?: string;\r\n cssClass?: string;\r\n parentId?: number | null;\r\n sortOrder: number;\r\n isLabel: boolean;\r\n isActive: boolean;\r\n createdAt: string;\r\n updatedAt?: string;\r\n}\r\n\r\nexport interface CreateFrontEndRouteDto {\r\n routePath: string;\r\n routeName: string;\r\n description?: string;\r\n icon?: string;\r\n cssClass?: string;\r\n parentId?: number | null;\r\n sortOrder?: number;\r\n isLabel?: boolean;\r\n}\r\n\r\nexport interface PagedList<T> {\r\n items: T[];\r\n totalCount: number;\r\n page: number;\r\n pageSize: number;\r\n totalPages: number;\r\n hasNext: boolean;\r\n hasPrevious: boolean;\r\n}\r\n\r\nexport interface RealTimeNotificationDto {\r\n id: string;\r\n title: string;\r\n message: string;\r\n messageHtml?: string;\r\n url?: string;\r\n type: NotificationType;\r\n createdAt: string;\r\n sourceAppName: string;\r\n sourceAppIconUrl?: string;\r\n}\r\n\r\n@Injectable()\r\nexport class MesAuthService {\r\n private hubConnection: HubConnection | null = null;\r\n private _currentUser = new BehaviorSubject<IUser | null>(null);\r\n public currentUser$: Observable<IUser | null> = this._currentUser.asObservable();\r\n private _notifications = new Subject<any>();\r\n public notifications$: Observable<any> = this._notifications.asObservable();\r\n\r\n private apiBase = '';\r\n private config: MesAuthConfig | null = null;\r\n private http!: HttpClient;\r\n private router?: Router;\r\n\r\n constructor() {\r\n // Empty constructor - all dependencies passed to init()\r\n }\r\n\r\n private isProtectedRoute(url: string): boolean {\r\n // Consider routes protected if they don't include auth-related paths\r\n return !url.includes('/login') && !url.includes('/auth') && !url.includes('/signin') && !url.includes('/logout');\r\n }\r\n\r\n init(config: MesAuthConfig, httpClient: HttpClient, router?: Router) {\r\n this.config = config;\r\n this.http = httpClient;\r\n this.router = router;\r\n this.apiBase = config.apiBaseUrl.replace(/\\/$/, '');\r\n\r\n // Listen for route changes - only refresh user data if needed for SPA navigation\r\n // This helps maintain authentication state in single-page applications\r\n if (this.router) {\r\n this.router.events\r\n .pipe(\r\n filter(event => event instanceof NavigationEnd),\r\n debounceTime(1000) // Longer debounce to avoid interfering with login flow\r\n )\r\n .subscribe((event: NavigationEnd) => {\r\n // Only refresh if user is logged in and navigating to protected routes\r\n // Avoid refreshing during login/logout flows\r\n if (this._currentUser.value && this.isProtectedRoute(event.url)) {\r\n // Small delay to ensure any login/logout operations complete\r\n setTimeout(() => {\r\n if (this._currentUser.value) {\r\n this.refreshUser();\r\n }\r\n }, 100);\r\n }\r\n });\r\n }\r\n\r\n this.fetchCurrentUser();\r\n }\r\n\r\n getConfig(): MesAuthConfig | null {\r\n return this.config;\r\n }\r\n\r\n private fetchCurrentUser() {\r\n if (!this.apiBase) return;\r\n const url = `${this.apiBase}/auth/me`;\r\n this.http.get(url, { withCredentials: this.config?.withCredentials ?? true }).subscribe({\r\n next: (u) => {\r\n this._currentUser.next(u);\r\n if (u && this.config) {\r\n this.startConnection(this.config);\r\n // Only fetch notifications after confirming user is logged in\r\n this.fetchInitialNotifications();\r\n }\r\n },\r\n error: (err) => {\r\n // Silently handle auth errors (401/403) - user is not logged in\r\n if (err.status === 401 || err.status === 403) {\r\n this._currentUser.next(null);\r\n }\r\n }\r\n });\r\n }\r\n\r\n private fetchInitialNotifications() {\r\n // Skip if no user is logged in or apiBase not set\r\n if (!this.apiBase || !this._currentUser.value) return;\r\n this.http.get(`${this.apiBase}/notif/me`, { withCredentials: this.config?.withCredentials ?? true }).subscribe({\r\n next: (notifications: any) => {\r\n if (Array.isArray(notifications?.items)) {\r\n notifications.items.forEach((n: any) => this._notifications.next(n));\r\n }\r\n },\r\n error: (err) => {\r\n // Silently handle auth errors (401/403) - user is not logged in\r\n // No need to emit anything\r\n }\r\n });\r\n }\r\n\r\n public getUnreadCount(): Observable<any> {\r\n return this.http.get(`${this.apiBase}/notif/me/unread-count`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public getNotifications(page: number = 1, pageSize: number = 20, includeRead: boolean = false, type?: string): Observable<any> {\r\n let url = `${this.apiBase}/notif/me?page=${page}&pageSize=${pageSize}&includeRead=${includeRead}`;\r\n if (type) {\r\n url += `&type=${type}`;\r\n }\r\n return this.http.get(url, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public markAsRead(notificationId: string): Observable<any> {\r\n return this.http.patch(`${this.apiBase}/notif/${notificationId}/read`, {}, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public markAllAsRead(): Observable<any> {\r\n return this.http.patch(`${this.apiBase}/notif/me/read-all`, {}, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public deleteNotification(notificationId: string): Observable<any> {\r\n return this.http.delete(`${this.apiBase}/notif/${notificationId}`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Get frontend routes assigned to the current user\r\n * Returns routes grouped by application\r\n */\r\n public getFrontEndRoutes(): Observable<UserFrontEndRoutesGrouped[]> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.get<UserFrontEndRoutesGrouped[]>(`${this.apiBase}/fe-routes/me`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Get master routes for a specific application\r\n * @param appId - The application ID\r\n */\r\n public getRouteMasters(appId: string): Observable<FrontEndRouteMaster[]> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.get<FrontEndRouteMaster[]>(`${this.apiBase}/fe-routes/masters/${appId}`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Register/sync frontend routes for an application\r\n * This is typically called on app startup to sync routes from the frontend app\r\n * @param appId - The application ID (passed via X-App-Id header)\r\n * @param routes - Array of route definitions\r\n */\r\n public registerFrontEndRoutes(appId: string, routes: CreateFrontEndRouteDto[]): Observable<any> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n const headers = { 'X-App-Id': appId };\r\n return this.http.post(`${this.apiBase}/fe-routes/register`, routes, {\r\n headers,\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n /**\r\n * Create a new route master\r\n * @param appId - The application ID\r\n * @param route - Route details\r\n */\r\n public createRouteMaster(appId: string, route: CreateFrontEndRouteDto): Observable<FrontEndRouteMaster> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.post<FrontEndRouteMaster>(`${this.apiBase}/fe-routes/masters`, {\r\n appId,\r\n ...route\r\n }, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Update an existing route master\r\n * @param routeId - The route master ID\r\n * @param route - Updated route details\r\n */\r\n public updateRouteMaster(routeId: number, route: Partial<CreateFrontEndRouteDto> & { isActive?: boolean }): Observable<FrontEndRouteMaster> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.put<FrontEndRouteMaster>(`${this.apiBase}/fe-routes/masters/${routeId}`, route, {\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n /**\r\n * Delete a route master\r\n * @param routeId - The route master ID\r\n */\r\n public deleteRouteMaster(routeId: number): Observable<any> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.delete(`${this.apiBase}/fe-routes/masters/${routeId}`, {\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n /**\r\n * Assign a route to a role\r\n * @param routeMasterId - The route master ID\r\n * @param roleId - The role ID (GUID)\r\n */\r\n public assignRouteToRole(routeMasterId: number, roleId: string): Observable<any> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.post(`${this.apiBase}/fe-routes/mappings`, {\r\n routeMasterId,\r\n roleId\r\n }, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Remove a route assignment from a role\r\n * @param mappingId - The mapping ID\r\n */\r\n public removeRouteFromRole(mappingId: number): Observable<any> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.delete(`${this.apiBase}/fe-routes/mappings/${mappingId}`, {\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n /**\r\n * Get route-to-role mappings for a specific role\r\n * @param roleId - The role ID (GUID)\r\n */\r\n public getRouteMappingsByRole(roleId: string): Observable<any[]> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.get<any[]>(`${this.apiBase}/fe-routes/mappings?roleId=${roleId}`, {\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n private startConnection(config: MesAuthConfig) {\r\n if (this.hubConnection) return;\r\n const signalrUrl = config.apiBaseUrl.replace(/\\/$/, '') + '/hub/notification';\r\n const builder = new HubConnectionBuilder()\r\n .withUrl(signalrUrl, { withCredentials: config.withCredentials ?? true })\r\n .withAutomaticReconnect()\r\n .configureLogging(LogLevel.Warning);\r\n\r\n this.hubConnection = builder.build();\r\n\r\n this.hubConnection.on('ReceiveNotification', (n: any) => {\r\n this._notifications.next(n);\r\n });\r\n\r\n this.hubConnection.start().then(() => {}).catch((err) => {});\r\n\r\n this.hubConnection.onclose(() => {});\r\n this.hubConnection.onreconnecting(() => {});\r\n this.hubConnection.onreconnected(() => {});\r\n }\r\n\r\n public stop() {\r\n if (!this.hubConnection) return;\r\n this.hubConnection.stop().catch(() => {});\r\n this.hubConnection = null;\r\n }\r\n\r\n public logout(): Observable<any> {\r\n const url = `${this.apiBase}/auth/logout`;\r\n return this.http.post(url, {}, { withCredentials: this.config?.withCredentials ?? true }).pipe(\r\n tap(() => {\r\n this._currentUser.next(null);\r\n this.stop();\r\n })\r\n );\r\n }\r\n\r\n public get currentUser(): IUser | null {\r\n return this._currentUser.value;\r\n }\r\n\r\n public get isAuthenticated(): boolean {\r\n return this._currentUser.value !== null;\r\n }\r\n\r\n public refreshUser() {\r\n this.fetchCurrentUser();\r\n }\r\n}\r\n","import { inject } from '@angular/core';\r\nimport { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';\r\nimport { throwError } from 'rxjs';\r\nimport { catchError } from 'rxjs/operators';\r\nimport { Router } from '@angular/router';\r\nimport { MesAuthService } from './mes-auth.service';\r\n\r\n// Track if we're currently redirecting to prevent loopback\r\nlet isRedirecting = false;\r\n\r\n/**\r\n * Functional HTTP interceptor for handling 401/403 auth errors.\r\n * Redirects to login page on 401, and to 403 page on 403.\r\n * Includes loopback prevention to avoid infinite redirects.\r\n */\r\nexport const mesAuthInterceptor: HttpInterceptorFn = (req, next) => {\r\n const authService = inject(MesAuthService);\r\n const router = inject(Router);\r\n\r\n return next(req).pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n const status = error.status;\r\n\r\n // Check if we should handle this error and prevent loopback\r\n if ((status === 401 || status === 403) && !isRedirecting) {\r\n const config = authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n\r\n // Use router URL for internal navigation (cleaner URLs)\r\n // Falls back to window.location for full URL if needed\r\n const currentUrl = router.url + (window.location.hash || '');\r\n const returnUrl = encodeURIComponent(currentUrl);\r\n\r\n // Avoid loops if already on auth/unauth pages\r\n const isLoginPage = currentUrl.includes('/login');\r\n const is403Page = currentUrl.includes('/403');\r\n const isAuthPage = currentUrl.includes('/auth');\r\n const isMeAuthPage = req.url.includes('/auth/me'); \r\n\r\n // Check if user is authenticated\r\n const isAuthenticated = authService.isAuthenticated;\r\n\r\n if (status === 401 && !isLoginPage && !isAuthPage && !isAuthenticated && !isMeAuthPage) {\r\n isRedirecting = true;\r\n // Reset flag after a delay to allow future redirects after user returns\r\n setTimeout(() => { isRedirecting = false; }, 5000);\r\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\r\n } else if (status === 403 && !is403Page) {\r\n isRedirecting = true;\r\n setTimeout(() => { isRedirecting = false; }, 5000);\r\n let redirectUrl = `${baseUrl}/403?returnUrl=${returnUrl}`;\r\n if (error.error && error.error.required) {\r\n redirectUrl += `&required=${encodeURIComponent(error.error.required)}`;\r\n }\r\n window.location.href = redirectUrl;\r\n }\r\n }\r\n return throwError(() => error);\r\n })\r\n );\r\n};\r\n","import { NgModule } from '@angular/core';\r\nimport { MesAuthService } from './mes-auth.service';\r\n\r\n@NgModule({\r\n providers: [\r\n MesAuthService\r\n ]\r\n})\r\nexport class MesAuthModule {}\r\n","import { Injectable, OnDestroy } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nexport type Theme = 'light' | 'dark';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ThemeService implements OnDestroy {\r\n private _currentTheme = new BehaviorSubject<Theme>('light');\r\n public currentTheme$: Observable<Theme> = this._currentTheme.asObservable();\r\n private observer: MutationObserver | null = null;\r\n\r\n constructor() {\r\n this.detectTheme();\r\n this.startWatching();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stopWatching();\r\n }\r\n\r\n private detectTheme(): void {\r\n const html = document.documentElement;\r\n const isDark = html.classList.contains('dark') ||\r\n html.getAttribute('data-theme') === 'dark' ||\r\n html.getAttribute('theme') === 'dark' ||\r\n html.getAttribute('data-coreui-theme') === 'dark';\r\n\r\n this._currentTheme.next(isDark ? 'dark' : 'light');\r\n }\r\n\r\n private startWatching(): void {\r\n if (typeof MutationObserver === 'undefined') {\r\n // Fallback for older browsers - check periodically\r\n setInterval(() => this.detectTheme(), 1000);\r\n return;\r\n }\r\n\r\n this.observer = new MutationObserver(() => {\r\n this.detectTheme();\r\n });\r\n\r\n this.observer.observe(document.documentElement, {\r\n attributes: true,\r\n attributeFilter: ['class', 'data-theme', 'theme', 'data-coreui-theme']\r\n });\r\n }\r\n\r\n private stopWatching(): void {\r\n if (this.observer) {\r\n this.observer.disconnect();\r\n this.observer = null;\r\n }\r\n }\r\n\r\n get currentTheme(): Theme {\r\n return this._currentTheme.value;\r\n }\r\n\r\n // Method to manually set theme if needed\r\n setTheme(theme: Theme): void {\r\n this._currentTheme.next(theme);\r\n }\r\n\r\n // Re-detect theme from DOM\r\n refreshTheme(): void {\r\n this.detectTheme();\r\n }\r\n}","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding, HostListener, signal, ChangeDetectorRef } from '@angular/core';\r\nimport { NgIf } from '@angular/common';\r\nimport { Router } from '@angular/router';\r\nimport { MesAuthService, IUser } from './mes-auth.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-user-profile',\r\n standalone: true,\r\n imports: [NgIf],\r\n template: `\r\n <div class=\"user-profile-container\">\r\n <!-- Not logged in -->\r\n <ng-container *ngIf=\"!currentUser()\">\r\n <button class=\"login-btn\" (click)=\"onLogin()\">\r\n Login\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Logged in -->\r\n <ng-container *ngIf=\"currentUser()\">\r\n <div class=\"user-header\">\r\n <button class=\"notification-btn\" (click)=\"onNotificationClick()\" title=\"Notifications\">\r\n <span class=\"icon\">🔔</span>\r\n <span class=\"badge\" *ngIf=\"unreadCount > 0\">{{ unreadCount }}</span>\r\n </button>\r\n\r\n <div class=\"user-menu-wrapper\">\r\n <button class=\"user-menu-btn\" (click)=\"toggleDropdown()\">\r\n <img \r\n *ngIf=\"currentUser().fullName || currentUser().userName\"\r\n [src]=\"getAvatarUrl(currentUser())\" \r\n [alt]=\"currentUser().fullName || currentUser().userName\"\r\n class=\"avatar\"\r\n />\r\n <span *ngIf=\"!(currentUser().fullName || currentUser().userName)\" class=\"avatar-initial\">\r\n {{ getLastNameInitial(currentUser()) }}\r\n </span>\r\n </button>\r\n\r\n <div class=\"mes-dropdown-menu\" *ngIf=\"dropdownOpen\">\r\n <div class=\"mes-dropdown-header\">\r\n {{ currentUser().fullName || currentUser().userName }}\r\n </div>\r\n <button class=\"mes-dropdown-item profile-link\" (click)=\"onViewProfile()\">\r\n View Profile\r\n </button>\r\n <button class=\"mes-dropdown-item logout-item\" (click)=\"onLogout()\">\r\n Logout\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --primary-color: #1976d2;\r\n --primary-hover: #1565c0;\r\n --primary-light: rgba(25, 118, 210, 0.1);\r\n --error-color: #f44336;\r\n --error-light: #ffebee;\r\n --text-primary: #333;\r\n --text-secondary: #666;\r\n --text-muted: #999;\r\n --bg-primary: white;\r\n --bg-secondary: #f5f5f5;\r\n --bg-tertiary: #fafafa;\r\n --bg-hover: #f5f5f5;\r\n --border-color: #e0e0e0;\r\n --border-light: #f0f0f0;\r\n --shadow: rgba(0, 0, 0, 0.15);\r\n --shadow-light: rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n :host(.theme-dark) {\r\n --primary-color: #90caf9;\r\n --primary-hover: #64b5f6;\r\n --primary-light: rgba(144, 202, 249, 0.1);\r\n --error-color: #ef5350;\r\n --error-light: rgba(239, 83, 80, 0.1);\r\n --text-primary: #e0e0e0;\r\n --text-secondary: #b0b0b0;\r\n --text-muted: #888;\r\n --bg-primary: #1e1e1e;\r\n --bg-secondary: #2d2d2d;\r\n --bg-tertiary: #252525;\r\n --bg-hover: #333;\r\n --border-color: #404040;\r\n --border-light: #333;\r\n --shadow: rgba(0, 0, 0, 0.3);\r\n --shadow-light: rgba(0, 0, 0, 0.2);\r\n }\r\n\r\n .user-profile-container {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding: 0 16px;\r\n }\r\n\r\n .login-btn {\r\n padding: 8px 16px;\r\n background-color: var(--primary-color);\r\n color: white;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-weight: 500;\r\n transition: background-color 0.3s;\r\n }\r\n\r\n .login-btn:hover {\r\n background-color: var(--primary-hover);\r\n }\r\n\r\n .user-header {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n\r\n .notification-btn {\r\n position: relative;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n cursor: pointer;\r\n padding: 8px;\r\n transition: opacity 0.2s;\r\n }\r\n\r\n .notification-btn:hover {\r\n opacity: 0.7;\r\n }\r\n\r\n .icon {\r\n display: inline-block;\r\n }\r\n\r\n .badge {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n background-color: var(--error-color);\r\n color: white;\r\n border-radius: 50%;\r\n width: 20px;\r\n height: 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 12px;\r\n font-weight: bold;\r\n }\r\n\r\n .user-menu-wrapper {\r\n position: relative;\r\n }\r\n\r\n .user-menu-btn {\r\n background: none;\r\n border: none;\r\n cursor: pointer;\r\n padding: 4px;\r\n border-radius: 50%;\r\n transition: background-color 0.2s;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n .user-menu-btn:hover {\r\n background-color: var(--primary-light);\r\n }\r\n\r\n .avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n object-fit: cover;\r\n background-color: #e0e0e0;\r\n }\r\n\r\n .avatar-initial {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n background-color: var(--primary-color);\r\n color: white;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-weight: bold;\r\n font-size: 16px;\r\n }\r\n\r\n .mes-dropdown-menu {\r\n position: absolute;\r\n top: calc(100% + 8px);\r\n right: 0;\r\n background: var(--bg-primary);\r\n border: 1px solid var(--border-color);\r\n border-radius: 4px;\r\n box-shadow: 0 2px 8px var(--shadow);\r\n min-width: 200px;\r\n z-index: 1000;\r\n overflow: hidden;\r\n }\r\n\r\n .mes-dropdown-header {\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--border-light);\r\n font-weight: 600;\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n }\r\n\r\n .mes-dropdown-item {\r\n display: block;\r\n width: 100%;\r\n padding: 12px 16px;\r\n border: none;\r\n background: none;\r\n text-align: left;\r\n cursor: pointer;\r\n font-size: 14px;\r\n color: var(--text-primary);\r\n text-decoration: none;\r\n transition: background-color 0.2s;\r\n }\r\n\r\n .mes-dropdown-item:hover {\r\n background-color: var(--bg-hover);\r\n }\r\n\r\n .profile-link {\r\n color: var(--primary-color);\r\n }\r\n\r\n .logout-item {\r\n border-top: 1px solid var(--border-light);\r\n color: var(--error-color);\r\n }\r\n\r\n .logout-item:hover {\r\n background-color: var(--error-light);\r\n }\r\n\r\n .user-info {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n\r\n .user-name {\r\n font-weight: 500;\r\n font-size: 14px;\r\n color: var(--text-primary);\r\n }\r\n\r\n .user-position {\r\n font-size: 12px;\r\n color: var(--text-secondary);\r\n }\r\n\r\n .logout-btn {\r\n background: none;\r\n border: none;\r\n font-size: 20px;\r\n cursor: pointer;\r\n color: var(--text-secondary);\r\n padding: 4px 8px;\r\n transition: color 0.2s;\r\n }\r\n\r\n .logout-btn:hover {\r\n color: var(--primary-color);\r\n }\r\n\r\n @media (max-width: 768px) {\r\n .user-info {\r\n display: none;\r\n }\r\n\r\n .avatar {\r\n width: 32px;\r\n height: 32px;\r\n }\r\n }\r\n `]\r\n})\r\nexport class UserProfileComponent implements OnInit, OnDestroy {\r\n @Output() notificationClick = new EventEmitter<void>();\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n\r\n currentUser = signal<IUser | null>(null);\r\n currentTheme: Theme = 'light';\r\n unreadCount = 0;\r\n dropdownOpen = false;\r\n private hasUser = false;\r\n private destroy$ = new Subject<void>();\r\n\r\n // Signal to force avatar refresh\r\n avatarRefresh = signal<number>(Date.now());\r\n\r\n constructor(private authService: MesAuthService, private router: Router, private themeService: ThemeService, private cdr: ChangeDetectorRef) {}\r\n\r\n ngOnInit() {\r\n this.authService.currentUser$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(user => {\r\n this.currentUser.set(user);\r\n this.hasUser = !!user;\r\n // Force avatar refresh when user changes\r\n this.avatarRefresh.set(Date.now());\r\n if (!this.hasUser) {\r\n this.unreadCount = 0;\r\n } else {\r\n this.loadUnreadCount();\r\n }\r\n this.cdr.markForCheck();\r\n });\r\n\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n\r\n // Listen for new notifications\r\n this.authService.notifications$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(() => {\r\n console.log('Notification received, updating unread count');\r\n if (this.hasUser) {\r\n this.loadUnreadCount();\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n loadUnreadCount() {\r\n if (!this.hasUser) {\r\n this.unreadCount = 0;\r\n return;\r\n }\r\n\r\n this.authService.getUnreadCount().subscribe({\r\n next: (response: any) => {\r\n this.unreadCount = response.unreadCount || 0;\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n getAvatarUrl(user: IUser): string {\r\n // Use the refresh signal to force update\r\n const refresh = this.avatarRefresh();\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.apiBaseUrl || '';\r\n \r\n // If user has avatarPath, use it directly\r\n if (user.avatarPath) {\r\n // If avatarPath is already a full URL, use it as-is\r\n if (user.avatarPath.startsWith('http://') || user.avatarPath.startsWith('https://')) {\r\n return user.avatarPath;\r\n }\r\n // If it's a relative path, construct full URL with refresh timestamp\r\n return `${baseUrl.replace(/\\/$/, '')}${user.avatarPath}?t=${refresh}`;\r\n }\r\n\r\n // Fallback: construct URL using userId\r\n const userId = user.userId;\r\n if (userId && baseUrl) {\r\n return `${baseUrl.replace(/\\/$/, '')}/auth/${userId}/avatar?t=${refresh}`;\r\n }\r\n \r\n // Fallback to UI avatars service if no userId or baseUrl\r\n const displayName = user.userName || user.userId || 'User';\r\n return `https://ui-avatars.com/api/?name=${encodeURIComponent(displayName)}&background=1976d2&color=fff`;\r\n }\r\n\r\n getLastNameInitial(user: IUser): string {\r\n const fullName = user.fullName || user.userName || 'U';\r\n const parts = fullName.split(' ');\r\n const lastPart = parts[parts.length - 1];\r\n return lastPart.charAt(0).toUpperCase();\r\n }\r\n\r\n toggleDropdown() {\r\n this.dropdownOpen = !this.dropdownOpen;\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: Event) {\r\n const target = event.target as HTMLElement;\r\n const clickedInside = target.closest('.user-menu-wrapper');\r\n if (!clickedInside) {\r\n this.dropdownOpen = false;\r\n }\r\n }\r\n\r\n onLogin() {\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n const returnUrl = encodeURIComponent(this.router.url);\r\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\r\n }\r\n\r\n onViewProfile() {\r\n this.router.navigate(['/profile']);\r\n this.dropdownOpen = false;\r\n }\r\n\r\n onLogout() {\r\n this.authService.logout().subscribe({\r\n next: () => {\r\n // Clear current user after successful logout\r\n this.dropdownOpen = false;\r\n \r\n // Navigate to login with return URL\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n const returnUrl = encodeURIComponent(window.location.href);\r\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\r\n },\r\n error: (err) => {\r\n // Still navigate to login even if logout fails\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n window.location.href = `${baseUrl}/login`;\r\n }\r\n });\r\n }\r\n\r\n onNotificationClick() {\r\n this.notificationClick.emit();\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nexport interface Toast {\r\n id: string;\r\n message: string;\r\n title?: string;\r\n type: 'info' | 'success' | 'warning' | 'error';\r\n duration?: number;\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class ToastService {\r\n private toasts$ = new BehaviorSubject<Toast[]>([]);\r\n public toasts: Observable<Toast[]> = this.toasts$.asObservable();\r\n\r\n show(message: string, title?: string, type: 'info' | 'success' | 'warning' | 'error' = 'info', duration: number = 5000) {\r\n const id = Math.random().toString(36).substr(2, 9);\r\n const toast: Toast = {\r\n id,\r\n message,\r\n title,\r\n type,\r\n duration\r\n };\r\n\r\n const currentToasts = this.toasts$.value;\r\n this.toasts$.next([...currentToasts, toast]);\r\n\r\n if (duration > 0) {\r\n setTimeout(() => {\r\n this.remove(id);\r\n }, duration);\r\n }\r\n\r\n return id;\r\n }\r\n\r\n remove(id: string) {\r\n const currentToasts = this.toasts$.value;\r\n this.toasts$.next(currentToasts.filter(t => t.id !== id));\r\n }\r\n\r\n clear() {\r\n this.toasts$.next([]);\r\n }\r\n}\r\n","import { Component, OnInit, OnDestroy, HostBinding } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ToastService, Toast } from './toast.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-toast-container',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n <div class=\"toast-container\">\r\n <div \r\n *ngFor=\"let toast of toasts\"\r\n class=\"toast\"\r\n [class]=\"'toast-' + toast.type\"\r\n [@slideIn]\r\n >\r\n <div class=\"toast-content\">\r\n <div *ngIf=\"toast.title\" class=\"toast-title\">{{ toast.title }}</div>\r\n <div class=\"toast-message\" [innerHTML]=\"toast.message\"></div>\r\n </div>\r\n <button class=\"toast-close\" (click)=\"close(toast.id)\" aria-label=\"Close\">\r\n ✕\r\n </button>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --info-color: #2196f3;\r\n --success-color: #4caf50;\r\n --warning-color: #ff9800;\r\n --error-color: #f44336;\r\n --text-primary: #333;\r\n --bg-primary: white;\r\n --shadow: rgba(0, 0, 0, 0.15);\r\n --text-secondary: #999;\r\n --border-color: rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n :host(.theme-dark) {\r\n --info-color: #64b5f6;\r\n --success-color: #81c784;\r\n --warning-color: #ffb74d;\r\n --error-color: #ef5350;\r\n --text-primary: #e0e0e0;\r\n --bg-primary: #1e1e1e;\r\n --shadow: rgba(0, 0, 0, 0.3);\r\n --text-secondary: #888;\r\n --border-color: rgba(255, 255, 255, 0.1);\r\n }\r\n\r\n .toast-container {\r\n position: fixed;\r\n top: 20px;\r\n right: 20px;\r\n z-index: 9999;\r\n pointer-events: none;\r\n }\r\n\r\n .toast {\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n margin-bottom: 12px;\r\n border-radius: 4px;\r\n background: var(--bg-primary);\r\n border: 1px solid var(--border-color);\r\n box-shadow: 0 4px 12px var(--shadow);\r\n pointer-events: auto;\r\n min-width: 280px;\r\n max-width: 400px;\r\n animation: slideIn 0.3s ease-out;\r\n }\r\n\r\n .toast-content {\r\n flex: 1;\r\n }\r\n\r\n .toast-title {\r\n font-weight: 600;\r\n font-size: 14px;\r\n margin-bottom: 4px;\r\n }\r\n\r\n .toast-message {\r\n font-size: 13px;\r\n line-height: 1.4;\r\n }\r\n\r\n .toast-close {\r\n background: none;\r\n border: none;\r\n cursor: pointer;\r\n font-size: 18px;\r\n color: var(--text-secondary);\r\n padding: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n transition: color 0.2s;\r\n }\r\n\r\n .toast-close:hover {\r\n color: var(--text-primary);\r\n }\r\n\r\n /* Toast types */\r\n .toast-info {\r\n border-left: 4px solid var(--info-color);\r\n }\r\n\r\n .toast-info .toast-title {\r\n color: var(--info-color);\r\n }\r\n\r\n .toast-info .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n .toast-success {\r\n border-left: 4px solid var(--success-color);\r\n }\r\n\r\n .toast-success .toast-title {\r\n color: var(--success-color);\r\n }\r\n\r\n .toast-success .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n .toast-warning {\r\n border-left: 4px solid var(--warning-color);\r\n }\r\n\r\n .toast-warning .toast-title {\r\n color: var(--warning-color);\r\n }\r\n\r\n .toast-warning .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n .toast-error {\r\n border-left: 4px solid var(--error-color);\r\n }\r\n\r\n .toast-error .toast-title {\r\n color: var(--error-color);\r\n }\r\n\r\n .toast-error .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n @keyframes slideIn {\r\n from {\r\n transform: translateX(400px);\r\n opacity: 0;\r\n }\r\n to {\r\n transform: translateX(0);\r\n opacity: 1;\r\n }\r\n }\r\n\r\n @media (max-width: 600px) {\r\n .toast-container {\r\n top: 10px;\r\n right: 10px;\r\n left: 10px;\r\n }\r\n\r\n .toast {\r\n min-width: auto;\r\n max-width: 100%;\r\n }\r\n }\r\n `]\r\n})\r\nexport class ToastContainerComponent implements OnInit, OnDestroy {\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n\r\n toasts: Toast[] = [];\r\n currentTheme: Theme = 'light';\r\n private destroy$ = new Subject<void>();\r\n\r\n constructor(private toastService: ToastService, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.toastService.toasts\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(toasts => {\r\n this.toasts = toasts;\r\n });\r\n\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n close(id: string) {\r\n this.toastService.remove(id);\r\n }\r\n}\r\n","import { Component, OnInit, OnDestroy, HostBinding, Output, EventEmitter } from '@angular/core';\r\nimport { NgIf, NgFor } from '@angular/common';\r\nimport { MesAuthService, NotificationDto, PagedList, RealTimeNotificationDto } from './mes-auth.service';\r\nimport { ToastService } from './toast.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-notification-panel',\r\n standalone: true,\r\n imports: [NgIf, NgFor],\r\n template: `\r\n <div class=\"notification-panel\" [class.open]=\"isOpen\">\r\n <!-- Header -->\r\n <div class=\"panel-header\">\r\n <h3>Notifications</h3>\r\n <button class=\"close-btn\" (click)=\"close()\" title=\"Close\">✕</button>\r\n </div>\r\n\r\n <!-- Tabs -->\r\n <div class=\"tabs\">\r\n <button\r\n class=\"tab-btn\"\r\n [class.active]=\"activeTab === 'unread'\"\r\n (click)=\"switchTab('unread')\"\r\n >\r\n Unread ({{ unreadNotifications.length }})\r\n </button>\r\n <button\r\n class=\"tab-btn\"\r\n [class.active]=\"activeTab === 'read'\"\r\n (click)=\"switchTab('read')\"\r\n >\r\n Read ({{ readNotifications.length }})\r\n </button>\r\n </div>\r\n\r\n <!-- Notifications List -->\r\n <div class=\"notifications-list\">\r\n <ng-container *ngIf=\"currentNotifications.length > 0\">\r\n <div\r\n *ngFor=\"let notification of currentNotifications\"\r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.isRead\"\r\n (click)=\"openDetails(notification)\"\r\n >\r\n <div class=\"notification-content\">\r\n <div class=\"notification-title\">{{ notification.title }}</div>\r\n <div class=\"notification-message\">{{ getNotificationMessage(notification) }}</div>\r\n <div class=\"notification-meta\">\r\n <span class=\"app-name\">{{ notification.sourceAppName }}</span>\r\n <span class=\"time\">{{ formatDate(notification.createdAt) }}</span>\r\n </div>\r\n </div>\r\n <button\r\n class=\"read-btn\"\r\n (click)=\"markAsRead(notification.id, $event)\"\r\n title=\"Mark as read\"\r\n *ngIf=\"!notification.isRead\"\r\n >\r\n ✓\r\n </button>\r\n <button\r\n class=\"delete-btn\"\r\n (click)=\"delete(notification.id, $event)\"\r\n title=\"Delete notification\"\r\n *ngIf=\"notification.isRead\"\r\n >\r\n 🗑\r\n </button>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"currentNotifications.length === 0\">\r\n <div class=\"empty-state\">\r\n No {{ activeTab }} notifications\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Footer Actions -->\r\n <div class=\"panel-footer\" *ngIf=\"currentNotifications.length > 0\">\r\n <div class=\"footer-actions\" *ngIf=\"activeTab === 'unread'\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadNotifications.length > 0\">\r\n Mark all as read\r\n </button>\r\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllUnread()\" *ngIf=\"unreadNotifications.length > 0\">\r\n Delete all\r\n </button>\r\n </div>\r\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllRead()\" *ngIf=\"activeTab === 'read' && readNotifications.length > 0\">\r\n Delete all\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Details Modal -->\r\n <div class=\"modal-overlay\" *ngIf=\"selectedNotification\" (click)=\"closeDetails()\">\r\n <div class=\"modal-container\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-header\">\r\n <h3>{{ selectedNotification.title }}</h3>\r\n <button class=\"close-btn\" (click)=\"closeDetails()\" title=\"Close\">✕</button>\r\n </div>\r\n <div class=\"modal-meta\">\r\n <span class=\"app-name\">{{ selectedNotification.sourceAppName }}</span>\r\n <span class=\"time\">{{ formatDate(selectedNotification.createdAt) }}</span>\r\n </div>\r\n <div class=\"modal-body\" [innerHTML]=\"getHtmlMessage(selectedNotification)\"></div>\r\n <div class=\"modal-footer\">\r\n <button class=\"action-btn\" (click)=\"closeDetails()\">Close</button>\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --primary-color: #1976d2;\r\n --primary-hover: #1565c0;\r\n --success-color: #4caf50;\r\n --error-color: #f44336;\r\n --text-primary: #333;\r\n --text-secondary: #666;\r\n --text-muted: #999;\r\n --bg-primary: white;\r\n --bg-secondary: #f5f5f5;\r\n --bg-tertiary: #fafafa;\r\n --bg-hover: #f5f5f5;\r\n --bg-unread: #e3f2fd;\r\n --border-color: #e0e0e0;\r\n --border-light: #f0f0f0;\r\n --shadow: rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n :host(.theme-dark) {\r\n --primary-color: #90caf9;\r\n --primary-hover: #64b5f6;\r\n --success-color: #81c784;\r\n --error-color: #ef5350;\r\n --text-primary: #e0e0e0;\r\n --text-secondary: #b0b0b0;\r\n --text-muted: #888;\r\n --bg-primary: #1e1e1e;\r\n --bg-secondary: #2d2d2d;\r\n --bg-tertiary: #252525;\r\n --bg-hover: #333;\r\n --bg-unread: rgba(144, 202, 249, 0.1);\r\n --border-color: #404040;\r\n --border-light: #333;\r\n --shadow: rgba(0, 0, 0, 0.3);\r\n }\r\n\r\n .notification-panel {\r\n position: fixed;\r\n top: 0;\r\n right: -350px;\r\n width: 350px;\r\n height: 100vh;\r\n background: var(--bg-primary);\r\n box-shadow: -2px 0 8px var(--shadow);\r\n display: flex;\r\n flex-direction: column;\r\n z-index: 1000;\r\n transition: right 0.3s ease;\r\n }\r\n\r\n .notification-panel.open {\r\n right: 0;\r\n }\r\n\r\n .panel-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 16px;\r\n border-bottom: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n }\r\n\r\n .panel-header h3 {\r\n margin: 0;\r\n font-size: 18px;\r\n color: var(--text-primary);\r\n }\r\n\r\n .close-btn {\r\n background: none;\r\n border: none;\r\n font-size: 20px;\r\n cursor: pointer;\r\n color: var(--text-secondary);\r\n padding: 0;\r\n width: 32px;\r\n height: 32px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: color 0.2s;\r\n }\r\n\r\n .close-btn:hover {\r\n color: var(--text-primary);\r\n }\r\n\r\n .tabs {\r\n display: flex;\r\n border-bottom: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n }\r\n\r\n .tab-btn {\r\n flex: 1;\r\n padding: 12px 16px;\r\n background: none;\r\n border: none;\r\n color: var(--text-secondary);\r\n cursor: pointer;\r\n font-size: 14px;\r\n font-weight: 500;\r\n transition: all 0.2s;\r\n border-bottom: 2px solid transparent;\r\n }\r\n\r\n .tab-btn:hover {\r\n background-color: var(--bg-hover);\r\n color: var(--text-primary);\r\n }\r\n\r\n .tab-btn.active {\r\n color: var(--primary-color);\r\n border-bottom-color: var(--primary-color);\r\n background-color: var(--bg-primary);\r\n }\r\n\r\n .notifications-list {\r\n flex: 1;\r\n overflow-y: auto;\r\n }\r\n\r\n .notification-item {\r\n display: flex;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--border-light);\r\n cursor: pointer;\r\n background-color: var(--bg-tertiary);\r\n transition: background-color 0.2s;\r\n }\r\n\r\n .notification-item:hover {\r\n background-color: var(--bg-hover);\r\n }\r\n\r\n .notification-item.unread {\r\n background-color: var(--bg-unread);\r\n }\r\n\r\n .notification-content {\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .notification-title {\r\n font-weight: 600;\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n margin-bottom: 4px;\r\n }\r\n\r\n .notification-message {\r\n color: var(--text-secondary);\r\n font-size: 13px;\r\n line-height: 1.4;\r\n margin-bottom: 6px;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n }\r\n\r\n .notification-meta {\r\n display: flex;\r\n justify-content: space-between;\r\n font-size: 12px;\r\n color: var(--text-muted);\r\n }\r\n\r\n .app-name {\r\n font-weight: 500;\r\n color: var(--primary-color);\r\n }\r\n\r\n .read-btn {\r\n background: none;\r\n border: none;\r\n color: var(--text-muted);\r\n cursor: pointer;\r\n font-size: 14px;\r\n padding: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n transition: color 0.2s;\r\n }\r\n\r\n .read-btn:hover {\r\n color: var(--success-color);\r\n }\r\n\r\n .delete-btn {\r\n background: none;\r\n border: none;\r\n color: var(--text-muted);\r\n cursor: pointer;\r\n font-size: 14px;\r\n padding: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n transition: color 0.2s;\r\n }\r\n\r\n .delete-btn:hover {\r\n color: var(--error-color);\r\n }\r\n\r\n .empty-state {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n color: var(--text-muted);\r\n font-size: 14px;\r\n }\r\n\r\n .panel-footer {\r\n padding: 12px 16px;\r\n border-top: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n }\r\n\r\n .footer-actions {\r\n display: flex;\r\n gap: 8px;\r\n }\r\n\r\n .footer-actions .action-btn {\r\n flex: 1;\r\n }\r\n\r\n .action-btn {\r\n width: 100%;\r\n padding: 8px;\r\n background-color: var(--primary-color);\r\n color: white;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-weight: 500;\r\n transition: background-color 0.2s;\r\n }\r\n\r\n .action-btn:hover {\r\n background-color: var(--primary-hover);\r\n }\r\n\r\n .delete-all-btn {\r\n background-color: var(--error-color);\r\n color: white;\r\n }\r\n\r\n .delete-all-btn:hover {\r\n background-color: #d32f2f; /* Darker red for hover */\r\n }\r\n\r\n /* Modal Overlay */\r\n .modal-overlay {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 1100;\r\n }\r\n\r\n .modal-container {\r\n background: var(--bg-primary);\r\n border-radius: 8px;\r\n width: 90%;\r\n max-width: 600px;\r\n max-height: 80vh;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 4px 20px var(--shadow);\r\n }\r\n\r\n .modal-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 16px 20px;\r\n border-bottom: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n border-radius: 8px 8px 0 0;\r\n }\r\n\r\n .modal-header h3 {\r\n margin: 0;\r\n font-size: 18px;\r\n color: var(--text-primary);\r\n }\r\n\r\n .modal-meta {\r\n display: flex;\r\n justify-content: space-between;\r\n padding: 8px 20px;\r\n font-size: 12px;\r\n color: var(--text-muted);\r\n background-color: var(--bg-tertiary);\r\n border-bottom: 1px solid var(--border-light);\r\n }\r\n\r\n .modal-body {\r\n padding: 20px;\r\n overflow-y: auto;\r\n flex: 1;\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n line-height: 1.6;\r\n }\r\n\r\n .modal-footer {\r\n padding: 12px 20px;\r\n border-top: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n border-radius: 0 0 8px 8px;\r\n display: flex;\r\n justify-content: flex-end;\r\n }\r\n\r\n .modal-footer .action-btn {\r\n width: auto;\r\n padding: 8px 24px;\r\n }\r\n\r\n @media (max-width: 600px) {\r\n .notification-panel {\r\n width: 100%;\r\n right: -100%;\r\n }\r\n\r\n .modal-container {\r\n width: 95%;\r\n max-height: 90vh;\r\n }\r\n }\r\n `]\r\n})\r\nexport class NotificationPanelComponent implements OnInit, OnDestroy {\r\n @Output() notificationRead = new EventEmitter<void>();\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n\r\n isOpen = false;\r\n notifications: NotificationDto[] = [];\r\n currentTheme: Theme = 'light';\r\n activeTab: 'unread' | 'read' = 'unread'; // Default to unread tab\r\n private destroy$ = new Subject<void>();\r\n\r\n get unreadNotifications(): NotificationDto[] {\r\n return this.notifications.filter(n => !n.isRead);\r\n }\r\n\r\n get readNotifications(): NotificationDto[] {\r\n return this.notifications.filter(n => n.isRead);\r\n }\r\n\r\n get currentNotifications(): NotificationDto[] {\r\n return this.activeTab === 'unread' ? this.unreadNotifications : this.readNotifications;\r\n }\r\n\r\n selectedNotification: NotificationDto | null = null;\r\n\r\n // Returns plain text message for list display\r\n getNotificationMessage(notification: NotificationDto): string {\r\n return notification.message || '';\r\n }\r\n\r\n // Returns HTML message for modal display\r\n getHtmlMessage(notification: NotificationDto): string {\r\n return notification.messageHtml || notification.message || '';\r\n }\r\n\r\n constructor(private authService: MesAuthService, private toastService: ToastService, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n\r\n this.loadNotifications();\r\n\r\n // Listen for new real-time notifications\r\n this.authService.notifications$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe((notification: RealTimeNotificationDto) => {\r\n // Show toast for new notification\r\n this.toastService.show(\r\n notification.messageHtml || notification.message || '',\r\n notification.title,\r\n 'info',\r\n 5000\r\n );\r\n // Reload notifications list\r\n this.loadNotifications();\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n private loadNotifications() {\r\n this.authService.getNotifications(1, 50, true).subscribe({ // includeRead = true to get both read and unread\r\n next: (response: PagedList<NotificationDto>) => {\r\n this.notifications = response.items || [];\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n open() {\r\n this.isOpen = true;\r\n this.activeTab = 'unread'; // Reset to unread tab when opening\r\n }\r\n\r\n close() {\r\n this.isOpen = false;\r\n }\r\n\r\n switchTab(tab: 'unread' | 'read') {\r\n this.activeTab = tab;\r\n }\r\n\r\n openDetails(notification: NotificationDto) {\r\n this.selectedNotification = notification;\r\n // Mark as read when opening details (if not already read)\r\n if (!notification.isRead) {\r\n this.authService.markAsRead(notification.id).subscribe({\r\n next: () => {\r\n notification.isRead = true;\r\n this.notificationRead.emit();\r\n },\r\n error: () => {}\r\n });\r\n }\r\n }\r\n\r\n closeDetails() {\r\n this.selectedNotification = null;\r\n }\r\n\r\n markAsRead(notificationId: string, event?: Event) {\r\n if (event) {\r\n event.stopPropagation();\r\n }\r\n this.authService.markAsRead(notificationId).subscribe({\r\n next: () => {\r\n const notification = this.notifications.find(n => n.id === notificationId);\r\n if (notification) {\r\n notification.isRead = true;\r\n this.notificationRead.emit();\r\n }\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n markAllAsRead() {\r\n this.authService.markAllAsRead().subscribe({\r\n next: () => {\r\n this.notifications.forEach(n => n.isRead = true);\r\n this.notificationRead.emit();\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n deleteAllRead() {\r\n const readNotificationIds = this.notifications\r\n .filter(n => n.isRead)\r\n .map(n => n.id);\r\n\r\n // Delete all read notifications\r\n const deletePromises = readNotificationIds.map(id =>\r\n this.authService.deleteNotification(id).toPromise()\r\n );\r\n\r\n Promise.all(deletePromises).then(() => {\r\n // Remove all read notifications from the local array\r\n this.notifications = this.notifications.filter(n => !n.isRead);\r\n }).catch((err) => {\r\n // If bulk delete fails, reload notifications to get current state\r\n this.loadNotifications();\r\n });\r\n }\r\n\r\n deleteAllUnread() {\r\n const unreadNotificationIds = this.notifications\r\n .filter(n => !n.isRead)\r\n .map(n => n.id);\r\n\r\n // Delete all unread notifications\r\n const deletePromises = unreadNotificationIds.map(id =>\r\n this.authService.deleteNotification(id).toPromise()\r\n );\r\n\r\n Promise.all(deletePromises).then(() => {\r\n // Remove all unread notifications from the local array\r\n this.notifications = this.notifications.filter(n => n.isRead);\r\n }).catch((err) => {\r\n // If bulk delete fails, reload notifications to get current state\r\n this.loadNotifications();\r\n });\r\n }\r\n\r\n delete(notificationId: string, event: Event) {\r\n event.stopPropagation();\r\n this.authService.deleteNotification(notificationId).subscribe({\r\n next: () => {\r\n this.notifications = this.notifications.filter(n => n.id !== notificationId);\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n formatDate(dateString: string): string {\r\n const date = new Date(dateString);\r\n const now = new Date();\r\n const diffMs = now.getTime() - date.getTime();\r\n const diffMins = Math.floor(diffMs / 60000);\r\n const diffHours = Math.floor(diffMs / 3600000);\r\n const diffDays = Math.floor(diffMs / 86400000);\r\n\r\n if (diffMins < 1) return 'Now';\r\n if (diffMins < 60) return `${diffMins}m ago`;\r\n if (diffHours < 24) return `${diffHours}h ago`;\r\n if (diffDays < 7) return `${diffDays}d ago`;\r\n \r\n return date.toLocaleDateString();\r\n }\r\n}\r\n","import { Component, ViewChild, AfterViewInit } from '@angular/core';\r\nimport { ToastContainerComponent } from './toast-container.component';\r\nimport { UserProfileComponent } from './user-profile.component';\r\nimport { NotificationPanelComponent } from './notification-panel.component';\r\n\r\n@Component({\r\n selector: 'ma-user',\r\n standalone: true,\r\n imports: [ToastContainerComponent, UserProfileComponent, NotificationPanelComponent],\r\n template: `\r\n <ma-toast-container></ma-toast-container>\r\n <div class=\"user-header\">\r\n <ma-user-profile (notificationClick)=\"notificationPanel.open()\"></ma-user-profile>\r\n </div>\r\n <ma-notification-panel #notificationPanel (notificationRead)=\"onNotificationRead()\"></ma-notification-panel>\r\n `,\r\n styles: [`\r\n .user-header {\r\n display: flex;\r\n justify-content: flex-end;\r\n }\r\n `]\r\n})\r\nexport class MaUserComponent implements AfterViewInit {\r\n @ViewChild(UserProfileComponent) userProfile?: UserProfileComponent;\r\n\r\n ngAfterViewInit() {\r\n // Ensure proper initialization\r\n if (this.userProfile) {\r\n this.userProfile.loadUnreadCount();\r\n }\r\n }\r\n\r\n onNotificationRead() {\r\n if (this.userProfile) {\r\n this.userProfile.loadUnreadCount();\r\n }\r\n }\r\n}\r\n","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding } from '@angular/core';\r\nimport { NgIf } from '@angular/common';\r\nimport { MesAuthService } from './mes-auth.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-notification-badge',\r\n standalone: true,\r\n imports: [NgIf],\r\n template: `\r\n <button class=\"notification-btn\" (click)=\"onNotificationClick()\" title=\"Notifications\">\r\n <span class=\"icon\">🔔</span>\r\n <span class=\"badge\" *ngIf=\"unreadCount > 0\">{{ unreadCount }}</span>\r\n </button>\r\n `,\r\n styles: [`\r\n :host {\r\n --error-color: #f44336;\r\n }\r\n\r\n :host(.theme-dark) {\r\n --error-color: #ef5350;\r\n }\r\n\r\n .notification-btn {\r\n position: relative;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n cursor: pointer;\r\n padding: 8px;\r\n transition: opacity 0.2s;\r\n }\r\n\r\n .notification-btn:hover {\r\n opacity: 0.7;\r\n }\r\n\r\n .icon {\r\n display: inline-block;\r\n }\r\n\r\n .badge {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n background-color: var(--error-color);\r\n color: white;\r\n border-radius: 50%;\r\n width: 20px;\r\n height: 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 12px;\r\n font-weight: bold;\r\n }\r\n `]\r\n})\r\nexport class NotificationBadgeComponent implements OnInit, OnDestroy {\r\n @Output() notificationClick = new EventEmitter<void>();\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n \r\n unreadCount = 0;\r\n currentTheme: Theme = 'light';\r\n private hasUser = false;\r\n private destroy$ = new Subject<void>();\r\n\r\n constructor(private authService: MesAuthService, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n\r\n this.authService.currentUser$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(user => {\r\n this.hasUser = !!user;\r\n if (!this.hasUser) {\r\n this.unreadCount = 0;\r\n return;\r\n }\r\n this.loadUnreadCount();\r\n });\r\n \r\n // Listen for new notifications\r\n this.authService.notifications$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(() => {\r\n if (this.hasUser) {\r\n this.loadUnreadCount();\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n private loadUnreadCount() {\r\n if (!this.hasUser) {\r\n this.unreadCount = 0;\r\n return;\r\n }\r\n\r\n this.authService.getUnreadCount().subscribe({\r\n next: (response: any) => {\r\n this.unreadCount = response.unreadCount || 0;\r\n },\r\n error: (err) => console.error('Error loading unread count:', err)\r\n });\r\n }\r\n\r\n onNotificationClick() {\r\n this.notificationClick.emit();\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.MesAuthService","i3.ThemeService","i1.ToastService","i2.ThemeService","i2.ToastService"],"mappings":"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"}
1
+ {"version":3,"file":"mesauth-angular.mjs","sources":["../../src/mes-auth.service.ts","../../src/mes-auth.interceptor.ts","../../src/mes-auth.module.ts","../../src/theme.service.ts","../../src/user-profile.component.ts","../../src/toast.service.ts","../../src/toast-container.component.ts","../../src/notification-panel.component.ts","../../src/ma-user.component.ts","../../src/notification-badge.component.ts","../../src/mesauth-angular.ts"],"sourcesContent":["import { inject, Injectable, InjectionToken, EnvironmentProviders, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { HubConnection, HubConnectionBuilder, LogLevel } from '@microsoft/signalr';\r\nimport { BehaviorSubject, Subject, Observable } from 'rxjs';\r\nimport { tap, filter, debounceTime } from 'rxjs/operators';\r\nimport { Router, NavigationEnd } from '@angular/router';\r\n\r\nexport interface MesAuthConfig {\r\n apiBaseUrl: string;\r\n withCredentials?: boolean;\r\n userBaseUrl?: string;\r\n}\r\n\r\n/** Injection token for MesAuth configuration */\r\nexport const MES_AUTH_CONFIG = new InjectionToken<MesAuthConfig>('MES_AUTH_CONFIG');\r\n\r\n/**\r\n * Provides MesAuth with configuration.\r\n * This is the recommended way to set up mesauth-angular in standalone apps.\r\n *\r\n * @example\r\n * ```typescript\r\n * // app.config.ts\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideHttpClient(withInterceptors([mesAuthInterceptor])),\r\n * provideMesAuth({\r\n * apiBaseUrl: 'https://auth.example.com',\r\n * userBaseUrl: 'https://app.example.com'\r\n * })\r\n * ]\r\n * };\r\n * ```\r\n */\r\nexport function provideMesAuth(config: MesAuthConfig): EnvironmentProviders {\r\n return makeEnvironmentProviders([\r\n { provide: MES_AUTH_CONFIG, useValue: config },\r\n MesAuthService,\r\n provideAppInitializer(() => {\r\n const mesAuthService = inject(MesAuthService);\r\n const httpClient = inject(HttpClient);\r\n const router = inject(Router);\r\n mesAuthService.init(config, httpClient, router);\r\n })\r\n ]);\r\n}\r\n\r\nexport interface IUser {\r\n userId?: string;\r\n userName?: string;\r\n fullName?: string;\r\n gender?: string;\r\n email?: string;\r\n phoneNumber?: string;\r\n department?: string;\r\n position?: string;\r\n tokenVersion?: string;\r\n permEndpoint?: string;\r\n perms?: Set<string>;\r\n employeeCode?: string;\r\n avatarPath?: string;\r\n loginMethod?: number;\r\n hrFullNameVn?: string;\r\n hrFullNameEn?: string;\r\n hrPosition?: string;\r\n hrJobTitle?: string;\r\n hrGender?: string;\r\n hrMobile?: string;\r\n hrEmail?: string;\r\n hrJoinDate?: string;\r\n hrBirthDate?: string;\r\n hrWorkStatus?: string;\r\n hrDoiTuong?: string;\r\n hrTeamCode?: string;\r\n hrLineCode?: string;\r\n}\r\n\r\nexport enum NotificationType {\r\n Info = 'Info',\r\n Warning = 'Warning',\r\n Error = 'Error',\r\n Success = 'Success'\r\n}\r\n\r\nexport interface NotificationDto {\r\n id: string;\r\n title: string;\r\n message: string;\r\n messageHtml?: string;\r\n url?: string;\r\n type: NotificationType;\r\n isRead: boolean;\r\n createdAt: string;\r\n sourceAppName: string;\r\n sourceAppIconUrl?: string;\r\n}\r\n\r\nexport interface FrontEndRoute {\r\n id: number;\r\n roleId: string;\r\n roleName: string;\r\n routePath: string;\r\n routeName: string;\r\n description?: string;\r\n icon?: string;\r\n cssClass?: string;\r\n parentId?: number | null;\r\n sortOrder: number;\r\n isLabel: boolean;\r\n isActive: boolean;\r\n createdAt: string;\r\n updatedAt?: string;\r\n children: FrontEndRoute[];\r\n}\r\n\r\nexport interface UserFrontEndRoutesGrouped {\r\n appId: string;\r\n appName: string;\r\n feUrl?: string;\r\n routes: FrontEndRoute[];\r\n}\r\n\r\nexport interface FrontEndRouteMaster {\r\n id: number;\r\n appId: string;\r\n routePath: string;\r\n routeName: string;\r\n description?: string;\r\n icon?: string;\r\n cssClass?: string;\r\n parentId?: number | null;\r\n sortOrder: number;\r\n isLabel: boolean;\r\n isActive: boolean;\r\n createdAt: string;\r\n updatedAt?: string;\r\n}\r\n\r\nexport interface CreateFrontEndRouteDto {\r\n routePath: string;\r\n routeName: string;\r\n description?: string;\r\n icon?: string;\r\n cssClass?: string;\r\n parentId?: number | null;\r\n sortOrder?: number;\r\n isLabel?: boolean;\r\n}\r\n\r\nexport interface PagedList<T> {\r\n items: T[];\r\n totalCount: number;\r\n page: number;\r\n pageSize: number;\r\n totalPages: number;\r\n hasNext: boolean;\r\n hasPrevious: boolean;\r\n}\r\n\r\nexport interface RealTimeNotificationDto {\r\n id: string;\r\n title: string;\r\n message: string;\r\n messageHtml?: string;\r\n url?: string;\r\n type: NotificationType;\r\n createdAt: string;\r\n sourceAppName: string;\r\n sourceAppIconUrl?: string;\r\n}\r\n\r\n@Injectable()\r\nexport class MesAuthService {\r\n private hubConnection: HubConnection | null = null;\r\n private _currentUser = new BehaviorSubject<IUser | null>(null);\r\n public currentUser$: Observable<IUser | null> = this._currentUser.asObservable();\r\n private _notifications = new Subject<any>();\r\n public notifications$: Observable<any> = this._notifications.asObservable();\r\n\r\n private apiBase = '';\r\n private config: MesAuthConfig | null = null;\r\n private http!: HttpClient;\r\n private router?: Router;\r\n\r\n constructor() {\r\n // Empty constructor - all dependencies passed to init()\r\n }\r\n\r\n private isProtectedRoute(url: string): boolean {\r\n // Consider routes protected if they don't include auth-related paths\r\n return !url.includes('/login') && !url.includes('/auth') && !url.includes('/signin') && !url.includes('/logout');\r\n }\r\n\r\n init(config: MesAuthConfig, httpClient: HttpClient, router?: Router) {\r\n this.config = config;\r\n this.http = httpClient;\r\n this.router = router;\r\n this.apiBase = config.apiBaseUrl.replace(/\\/$/, '');\r\n\r\n // Listen for route changes - only refresh user data if needed for SPA navigation\r\n // This helps maintain authentication state in single-page applications\r\n if (this.router) {\r\n this.router.events\r\n .pipe(\r\n filter(event => event instanceof NavigationEnd),\r\n debounceTime(1000) // Longer debounce to avoid interfering with login flow\r\n )\r\n .subscribe((event: NavigationEnd) => {\r\n // Only refresh if user is logged in and navigating to protected routes\r\n // Avoid refreshing during login/logout flows\r\n if (this._currentUser.value && this.isProtectedRoute(event.url)) {\r\n // Small delay to ensure any login/logout operations complete\r\n setTimeout(() => {\r\n if (this._currentUser.value) {\r\n this.refreshUser();\r\n }\r\n }, 100);\r\n }\r\n });\r\n }\r\n\r\n this.fetchCurrentUser();\r\n }\r\n\r\n getConfig(): MesAuthConfig | null {\r\n return this.config;\r\n }\r\n\r\n private fetchCurrentUser() {\r\n if (!this.apiBase) return;\r\n const url = `${this.apiBase}/auth/me`;\r\n this.http.get(url, { withCredentials: this.config?.withCredentials ?? true }).subscribe({\r\n next: (u) => {\r\n this._currentUser.next(u);\r\n if (u && this.config) {\r\n this.startConnection(this.config);\r\n // Only fetch notifications after confirming user is logged in\r\n this.fetchInitialNotifications();\r\n }\r\n },\r\n error: (err) => {\r\n // Silently handle auth errors (401/403) - user is not logged in\r\n if (err.status === 401 || err.status === 403) {\r\n this._currentUser.next(null);\r\n }\r\n }\r\n });\r\n }\r\n\r\n private fetchInitialNotifications() {\r\n // Skip if no user is logged in or apiBase not set\r\n if (!this.apiBase || !this._currentUser.value) return;\r\n this.http.get(`${this.apiBase}/notif/me`, { withCredentials: this.config?.withCredentials ?? true }).subscribe({\r\n next: (notifications: any) => {\r\n if (Array.isArray(notifications?.items)) {\r\n notifications.items.forEach((n: any) => this._notifications.next(n));\r\n }\r\n },\r\n error: (err) => {\r\n // Silently handle auth errors (401/403) - user is not logged in\r\n // No need to emit anything\r\n }\r\n });\r\n }\r\n\r\n public getUnreadCount(): Observable<any> {\r\n return this.http.get(`${this.apiBase}/notif/me/unread-count`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public getNotifications(page: number = 1, pageSize: number = 20, includeRead: boolean = false, type?: string): Observable<any> {\r\n let url = `${this.apiBase}/notif/me?page=${page}&pageSize=${pageSize}&includeRead=${includeRead}`;\r\n if (type) {\r\n url += `&type=${type}`;\r\n }\r\n return this.http.get(url, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public markAsRead(notificationId: string): Observable<any> {\r\n return this.http.patch(`${this.apiBase}/notif/${notificationId}/read`, {}, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public markAllAsRead(): Observable<any> {\r\n return this.http.patch(`${this.apiBase}/notif/me/read-all`, {}, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n public deleteNotification(notificationId: string): Observable<any> {\r\n return this.http.delete(`${this.apiBase}/notif/${notificationId}`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Get frontend routes assigned to the current user\r\n * Returns routes grouped by application\r\n */\r\n public getFrontEndRoutes(): Observable<UserFrontEndRoutesGrouped[]> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.get<UserFrontEndRoutesGrouped[]>(`${this.apiBase}/fe-routes/me`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Get master routes for a specific application\r\n * @param appId - The application ID\r\n */\r\n public getRouteMasters(appId: string): Observable<FrontEndRouteMaster[]> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.get<FrontEndRouteMaster[]>(`${this.apiBase}/fe-routes/masters/${appId}`, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Register/sync frontend routes for an application\r\n * This is typically called on app startup to sync routes from the frontend app\r\n * @param appId - The application ID (passed via X-App-Id header)\r\n * @param routes - Array of route definitions\r\n */\r\n public registerFrontEndRoutes(appId: string, routes: CreateFrontEndRouteDto[]): Observable<any> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n const headers = { 'X-App-Id': appId };\r\n return this.http.post(`${this.apiBase}/fe-routes/register`, routes, {\r\n headers,\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n /**\r\n * Create a new route master\r\n * @param appId - The application ID\r\n * @param route - Route details\r\n */\r\n public createRouteMaster(appId: string, route: CreateFrontEndRouteDto): Observable<FrontEndRouteMaster> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.post<FrontEndRouteMaster>(`${this.apiBase}/fe-routes/masters`, {\r\n appId,\r\n ...route\r\n }, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Update an existing route master\r\n * @param routeId - The route master ID\r\n * @param route - Updated route details\r\n */\r\n public updateRouteMaster(routeId: number, route: Partial<CreateFrontEndRouteDto> & { isActive?: boolean }): Observable<FrontEndRouteMaster> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.put<FrontEndRouteMaster>(`${this.apiBase}/fe-routes/masters/${routeId}`, route, {\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n /**\r\n * Delete a route master\r\n * @param routeId - The route master ID\r\n */\r\n public deleteRouteMaster(routeId: number): Observable<any> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.delete(`${this.apiBase}/fe-routes/masters/${routeId}`, {\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n /**\r\n * Assign a route to a role\r\n * @param routeMasterId - The route master ID\r\n * @param roleId - The role ID (GUID)\r\n */\r\n public assignRouteToRole(routeMasterId: number, roleId: string): Observable<any> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.post(`${this.apiBase}/fe-routes/mappings`, {\r\n routeMasterId,\r\n roleId\r\n }, { withCredentials: this.config?.withCredentials ?? true });\r\n }\r\n\r\n /**\r\n * Remove a route assignment from a role\r\n * @param mappingId - The mapping ID\r\n */\r\n public removeRouteFromRole(mappingId: number): Observable<any> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.delete(`${this.apiBase}/fe-routes/mappings/${mappingId}`, {\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n /**\r\n * Get route-to-role mappings for a specific role\r\n * @param roleId - The role ID (GUID)\r\n */\r\n public getRouteMappingsByRole(roleId: string): Observable<any[]> {\r\n if (!this.apiBase) throw new Error('MesAuth not initialized');\r\n return this.http.get<any[]>(`${this.apiBase}/fe-routes/mappings?roleId=${roleId}`, {\r\n withCredentials: this.config?.withCredentials ?? true\r\n });\r\n }\r\n\r\n private startConnection(config: MesAuthConfig) {\r\n if (this.hubConnection) return;\r\n const signalrUrl = config.apiBaseUrl.replace(/\\/$/, '') + '/hub/notification';\r\n const builder = new HubConnectionBuilder()\r\n .withUrl(signalrUrl, { withCredentials: config.withCredentials ?? true })\r\n .withAutomaticReconnect()\r\n .configureLogging(LogLevel.Warning);\r\n\r\n this.hubConnection = builder.build();\r\n\r\n this.hubConnection.on('ReceiveNotification', (n: any) => {\r\n this._notifications.next(n);\r\n });\r\n\r\n this.hubConnection.start().then(() => {}).catch((err) => {});\r\n\r\n this.hubConnection.onclose(() => {});\r\n this.hubConnection.onreconnecting(() => {});\r\n this.hubConnection.onreconnected(() => {});\r\n }\r\n\r\n public stop() {\r\n if (!this.hubConnection) return;\r\n this.hubConnection.stop().catch(() => {});\r\n this.hubConnection = null;\r\n }\r\n\r\n public logout(): Observable<any> {\r\n const url = `${this.apiBase}/auth/logout`;\r\n return this.http.post(url, {}, { withCredentials: this.config?.withCredentials ?? true }).pipe(\r\n tap(() => {\r\n this._currentUser.next(null);\r\n this.stop();\r\n })\r\n );\r\n }\r\n\r\n public get currentUser(): IUser | null {\r\n return this._currentUser.value;\r\n }\r\n\r\n public get isAuthenticated(): boolean {\r\n return this._currentUser.value !== null;\r\n }\r\n\r\n public refreshUser() {\r\n this.fetchCurrentUser();\r\n }\r\n}\r\n","import { inject } from '@angular/core';\r\nimport { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';\r\nimport { throwError } from 'rxjs';\r\nimport { catchError } from 'rxjs/operators';\r\nimport { Router } from '@angular/router';\r\nimport { MesAuthService } from './mes-auth.service';\r\n\r\n// Track if we're currently redirecting to prevent loopback\r\nlet isRedirecting = false;\r\n\r\n/**\r\n * Functional HTTP interceptor for handling 401/403 auth errors.\r\n * Redirects to login page on 401, and to 403 page on 403.\r\n * Includes loopback prevention to avoid infinite redirects.\r\n */\r\nexport const mesAuthInterceptor: HttpInterceptorFn = (req, next) => {\r\n const authService = inject(MesAuthService);\r\n const router = inject(Router);\r\n\r\n return next(req).pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n const status = error.status;\r\n\r\n // Check if we should handle this error and prevent loopback\r\n if ((status === 401 || status === 403) && !isRedirecting) {\r\n const config = authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n\r\n // Use router URL for internal navigation (cleaner URLs)\r\n // Falls back to window.location for full URL if needed\r\n const currentUrl = router.url + (window.location.hash || '');\r\n const returnUrl = encodeURIComponent(currentUrl);\r\n\r\n // Avoid loops if already on auth/unauth pages\r\n const isLoginPage = currentUrl.includes('/login');\r\n const is403Page = currentUrl.includes('/403');\r\n const isAuthPage = currentUrl.includes('/auth');\r\n const isMeAuthPage = req.url.includes('/auth/me'); \r\n\r\n // Check if user is authenticated\r\n const isAuthenticated = authService.isAuthenticated;\r\n\r\n if (status === 401 && !isLoginPage && !isAuthPage && !isAuthenticated && !isMeAuthPage) {\r\n isRedirecting = true;\r\n // Reset flag after a delay to allow future redirects after user returns\r\n setTimeout(() => { isRedirecting = false; }, 5000);\r\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\r\n } else if (status === 403 && !is403Page) {\r\n isRedirecting = true;\r\n setTimeout(() => { isRedirecting = false; }, 5000);\r\n let redirectUrl = `${baseUrl}/403?returnUrl=${returnUrl}`;\r\n if (error.error && error.error.required) {\r\n redirectUrl += `&required=${encodeURIComponent(error.error.required)}`;\r\n }\r\n window.location.href = redirectUrl;\r\n }\r\n }\r\n return throwError(() => error);\r\n })\r\n );\r\n};\r\n","import { NgModule } from '@angular/core';\r\nimport { MesAuthService } from './mes-auth.service';\r\n\r\n@NgModule({\r\n providers: [\r\n MesAuthService\r\n ]\r\n})\r\nexport class MesAuthModule {}\r\n","import { Injectable, OnDestroy } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nexport type Theme = 'light' | 'dark';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ThemeService implements OnDestroy {\r\n private _currentTheme = new BehaviorSubject<Theme>('light');\r\n public currentTheme$: Observable<Theme> = this._currentTheme.asObservable();\r\n private observer: MutationObserver | null = null;\r\n\r\n constructor() {\r\n this.detectTheme();\r\n this.startWatching();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.stopWatching();\r\n }\r\n\r\n private detectTheme(): void {\r\n const html = document.documentElement;\r\n const isDark = html.classList.contains('dark') ||\r\n html.getAttribute('data-theme') === 'dark' ||\r\n html.getAttribute('theme') === 'dark' ||\r\n html.getAttribute('data-coreui-theme') === 'dark';\r\n\r\n this._currentTheme.next(isDark ? 'dark' : 'light');\r\n }\r\n\r\n private startWatching(): void {\r\n if (typeof MutationObserver === 'undefined') {\r\n // Fallback for older browsers - check periodically\r\n setInterval(() => this.detectTheme(), 1000);\r\n return;\r\n }\r\n\r\n this.observer = new MutationObserver(() => {\r\n this.detectTheme();\r\n });\r\n\r\n this.observer.observe(document.documentElement, {\r\n attributes: true,\r\n attributeFilter: ['class', 'data-theme', 'theme', 'data-coreui-theme']\r\n });\r\n }\r\n\r\n private stopWatching(): void {\r\n if (this.observer) {\r\n this.observer.disconnect();\r\n this.observer = null;\r\n }\r\n }\r\n\r\n get currentTheme(): Theme {\r\n return this._currentTheme.value;\r\n }\r\n\r\n // Method to manually set theme if needed\r\n setTheme(theme: Theme): void {\r\n this._currentTheme.next(theme);\r\n }\r\n\r\n // Re-detect theme from DOM\r\n refreshTheme(): void {\r\n this.detectTheme();\r\n }\r\n}","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding, HostListener, signal, ChangeDetectorRef } from '@angular/core';\r\nimport { NgIf } from '@angular/common';\r\nimport { Router } from '@angular/router';\r\nimport { MesAuthService, IUser } from './mes-auth.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-user-profile',\r\n standalone: true,\r\n imports: [NgIf],\r\n template: `\r\n <div class=\"user-profile-container\">\r\n <!-- Not logged in -->\r\n <ng-container *ngIf=\"!currentUser()\">\r\n <button class=\"login-btn\" (click)=\"onLogin()\">\r\n Login\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Logged in -->\r\n <ng-container *ngIf=\"currentUser()\">\r\n <div class=\"user-header\">\r\n <button class=\"notification-btn\" (click)=\"onNotificationClick()\" title=\"Notifications\">\r\n <span class=\"icon\">🔔</span>\r\n <span class=\"badge\" *ngIf=\"unreadCount > 0\">{{ unreadCount }}</span>\r\n </button>\r\n\r\n <div class=\"user-menu-wrapper\">\r\n <button class=\"user-menu-btn\" (click)=\"toggleDropdown()\">\r\n <img \r\n *ngIf=\"currentUser().fullName || currentUser().userName\"\r\n [src]=\"getAvatarUrl(currentUser())\" \r\n [alt]=\"currentUser().fullName || currentUser().userName\"\r\n class=\"avatar\"\r\n />\r\n <span *ngIf=\"!(currentUser().fullName || currentUser().userName)\" class=\"avatar-initial\">\r\n {{ getLastNameInitial(currentUser()) }}\r\n </span>\r\n </button>\r\n\r\n <div class=\"mes-dropdown-menu\" *ngIf=\"dropdownOpen\">\r\n <div class=\"mes-dropdown-header\">\r\n {{ currentUser().fullName || currentUser().userName }}\r\n </div>\r\n <button class=\"mes-dropdown-item profile-link\" (click)=\"onViewProfile()\">\r\n View Profile\r\n </button>\r\n <button class=\"mes-dropdown-item logout-item\" (click)=\"onLogout()\">\r\n Logout\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --primary-color: #1976d2;\r\n --primary-hover: #1565c0;\r\n --primary-light: rgba(25, 118, 210, 0.1);\r\n --error-color: #f44336;\r\n --error-light: #ffebee;\r\n --text-primary: #333;\r\n --text-secondary: #666;\r\n --text-muted: #999;\r\n --bg-primary: white;\r\n --bg-secondary: #f5f5f5;\r\n --bg-tertiary: #fafafa;\r\n --bg-hover: #f5f5f5;\r\n --border-color: #e0e0e0;\r\n --border-light: #f0f0f0;\r\n --shadow: rgba(0, 0, 0, 0.15);\r\n --shadow-light: rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n :host(.theme-dark) {\r\n --primary-color: #90caf9;\r\n --primary-hover: #64b5f6;\r\n --primary-light: rgba(144, 202, 249, 0.1);\r\n --error-color: #ef5350;\r\n --error-light: rgba(239, 83, 80, 0.1);\r\n --text-primary: #e0e0e0;\r\n --text-secondary: #b0b0b0;\r\n --text-muted: #888;\r\n --bg-primary: #1e1e1e;\r\n --bg-secondary: #2d2d2d;\r\n --bg-tertiary: #252525;\r\n --bg-hover: #333;\r\n --border-color: #404040;\r\n --border-light: #333;\r\n --shadow: rgba(0, 0, 0, 0.3);\r\n --shadow-light: rgba(0, 0, 0, 0.2);\r\n }\r\n\r\n .user-profile-container {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding: 0 16px;\r\n }\r\n\r\n .login-btn {\r\n padding: 8px 16px;\r\n background-color: var(--primary-color);\r\n color: white;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-weight: 500;\r\n transition: background-color 0.3s;\r\n }\r\n\r\n .login-btn:hover {\r\n background-color: var(--primary-hover);\r\n }\r\n\r\n .user-header {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n\r\n .notification-btn {\r\n position: relative;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n cursor: pointer;\r\n padding: 8px;\r\n transition: opacity 0.2s;\r\n }\r\n\r\n .notification-btn:hover {\r\n opacity: 0.7;\r\n }\r\n\r\n .icon {\r\n display: inline-block;\r\n }\r\n\r\n .badge {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n background-color: var(--error-color);\r\n color: white;\r\n border-radius: 50%;\r\n width: 20px;\r\n height: 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 12px;\r\n font-weight: bold;\r\n }\r\n\r\n .user-menu-wrapper {\r\n position: relative;\r\n }\r\n\r\n .user-menu-btn {\r\n background: none;\r\n border: none;\r\n cursor: pointer;\r\n padding: 4px;\r\n border-radius: 50%;\r\n transition: background-color 0.2s;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n .user-menu-btn:hover {\r\n background-color: var(--primary-light);\r\n }\r\n\r\n .avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n object-fit: cover;\r\n background-color: #e0e0e0;\r\n }\r\n\r\n .avatar-initial {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n background-color: var(--primary-color);\r\n color: white;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-weight: bold;\r\n font-size: 16px;\r\n }\r\n\r\n .mes-dropdown-menu {\r\n position: absolute;\r\n top: calc(100% + 8px);\r\n right: 0;\r\n background: var(--bg-primary);\r\n border: 1px solid var(--border-color);\r\n border-radius: 4px;\r\n box-shadow: 0 2px 8px var(--shadow);\r\n min-width: 200px;\r\n z-index: 1000;\r\n overflow: hidden;\r\n }\r\n\r\n .mes-dropdown-header {\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--border-light);\r\n font-weight: 600;\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n }\r\n\r\n .mes-dropdown-item {\r\n display: block;\r\n width: 100%;\r\n padding: 12px 16px;\r\n border: none;\r\n background: none;\r\n text-align: left;\r\n cursor: pointer;\r\n font-size: 14px;\r\n color: var(--text-primary);\r\n text-decoration: none;\r\n transition: background-color 0.2s;\r\n }\r\n\r\n .mes-dropdown-item:hover {\r\n background-color: var(--bg-hover);\r\n }\r\n\r\n .profile-link {\r\n color: var(--primary-color);\r\n }\r\n\r\n .logout-item {\r\n border-top: 1px solid var(--border-light);\r\n color: var(--error-color);\r\n }\r\n\r\n .logout-item:hover {\r\n background-color: var(--error-light);\r\n }\r\n\r\n .user-info {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n\r\n .user-name {\r\n font-weight: 500;\r\n font-size: 14px;\r\n color: var(--text-primary);\r\n }\r\n\r\n .user-position {\r\n font-size: 12px;\r\n color: var(--text-secondary);\r\n }\r\n\r\n .logout-btn {\r\n background: none;\r\n border: none;\r\n font-size: 20px;\r\n cursor: pointer;\r\n color: var(--text-secondary);\r\n padding: 4px 8px;\r\n transition: color 0.2s;\r\n }\r\n\r\n .logout-btn:hover {\r\n color: var(--primary-color);\r\n }\r\n\r\n @media (max-width: 768px) {\r\n .user-info {\r\n display: none;\r\n }\r\n\r\n .avatar {\r\n width: 32px;\r\n height: 32px;\r\n }\r\n }\r\n `]\r\n})\r\nexport class UserProfileComponent implements OnInit, OnDestroy {\r\n @Output() notificationClick = new EventEmitter<void>();\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n\r\n currentUser = signal<IUser | null>(null);\r\n currentTheme: Theme = 'light';\r\n unreadCount = 0;\r\n dropdownOpen = false;\r\n private hasUser = false;\r\n private destroy$ = new Subject<void>();\r\n\r\n // Signal to force avatar refresh\r\n avatarRefresh = signal<number>(Date.now());\r\n\r\n constructor(private authService: MesAuthService, private router: Router, private themeService: ThemeService, private cdr: ChangeDetectorRef) {}\r\n\r\n ngOnInit() {\r\n this.authService.currentUser$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(user => {\r\n this.currentUser.set(user);\r\n this.hasUser = !!user;\r\n // Force avatar refresh when user changes\r\n this.avatarRefresh.set(Date.now());\r\n if (!this.hasUser) {\r\n this.unreadCount = 0;\r\n } else {\r\n this.loadUnreadCount();\r\n }\r\n this.cdr.markForCheck();\r\n });\r\n\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n\r\n // Listen for new notifications\r\n this.authService.notifications$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(() => {\r\n console.log('Notification received, updating unread count');\r\n if (this.hasUser) {\r\n this.loadUnreadCount();\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n loadUnreadCount() {\r\n if (!this.hasUser) {\r\n this.unreadCount = 0;\r\n return;\r\n }\r\n\r\n this.authService.getUnreadCount().subscribe({\r\n next: (response: any) => {\r\n this.unreadCount = response.unreadCount || 0;\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n getAvatarUrl(user: IUser): string {\r\n // Use the refresh signal to force update\r\n const refresh = this.avatarRefresh();\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.apiBaseUrl || '';\r\n \r\n // If user has avatarPath, use it directly\r\n if (user.avatarPath) {\r\n // If avatarPath is already a full URL, use it as-is\r\n if (user.avatarPath.startsWith('http://') || user.avatarPath.startsWith('https://')) {\r\n return user.avatarPath;\r\n }\r\n // If it's a relative path, construct full URL with refresh timestamp\r\n return `${baseUrl.replace(/\\/$/, '')}${user.avatarPath}?t=${refresh}`;\r\n }\r\n\r\n // Fallback: construct URL using userId\r\n const userId = user.userId;\r\n if (userId && baseUrl) {\r\n return `${baseUrl.replace(/\\/$/, '')}/auth/${userId}/avatar?t=${refresh}`;\r\n }\r\n \r\n // Fallback to UI avatars service if no userId or baseUrl\r\n const displayName = user.userName || user.userId || 'User';\r\n return `https://ui-avatars.com/api/?name=${encodeURIComponent(displayName)}&background=1976d2&color=fff`;\r\n }\r\n\r\n getLastNameInitial(user: IUser): string {\r\n const fullName = user.fullName || user.userName || 'U';\r\n const parts = fullName.split(' ');\r\n const lastPart = parts[parts.length - 1];\r\n return lastPart.charAt(0).toUpperCase();\r\n }\r\n\r\n toggleDropdown() {\r\n this.dropdownOpen = !this.dropdownOpen;\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: Event) {\r\n const target = event.target as HTMLElement;\r\n const clickedInside = target.closest('.user-menu-wrapper');\r\n if (!clickedInside) {\r\n this.dropdownOpen = false;\r\n }\r\n }\r\n\r\n onLogin() {\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n const returnUrl = encodeURIComponent(this.router.url);\r\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\r\n }\r\n\r\n onViewProfile() {\r\n this.router.navigate(['/profile']);\r\n this.dropdownOpen = false;\r\n }\r\n\r\n onLogout() {\r\n this.authService.logout().subscribe({\r\n next: () => {\r\n // Clear current user after successful logout\r\n this.dropdownOpen = false;\r\n \r\n // Navigate to login with return URL\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n const returnUrl = encodeURIComponent(window.location.href);\r\n window.location.href = `${baseUrl}/login?returnUrl=${returnUrl}`;\r\n },\r\n error: (err) => {\r\n // Still navigate to login even if logout fails\r\n const config = this.authService.getConfig();\r\n const baseUrl = config?.userBaseUrl || '';\r\n window.location.href = `${baseUrl}/login`;\r\n }\r\n });\r\n }\r\n\r\n onNotificationClick() {\r\n this.notificationClick.emit();\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nexport interface Toast {\r\n id: string;\r\n message: string;\r\n title?: string;\r\n type: 'info' | 'success' | 'warning' | 'error';\r\n duration?: number;\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class ToastService {\r\n private toasts$ = new BehaviorSubject<Toast[]>([]);\r\n public toasts: Observable<Toast[]> = this.toasts$.asObservable();\r\n\r\n show(message: string, title?: string, type: 'info' | 'success' | 'warning' | 'error' = 'info', duration: number = 5000) {\r\n const id = Math.random().toString(36).substr(2, 9);\r\n const toast: Toast = {\r\n id,\r\n message,\r\n title,\r\n type,\r\n duration\r\n };\r\n\r\n const currentToasts = this.toasts$.value;\r\n this.toasts$.next([...currentToasts, toast]);\r\n\r\n if (duration > 0) {\r\n setTimeout(() => {\r\n this.remove(id);\r\n }, duration);\r\n }\r\n\r\n return id;\r\n }\r\n\r\n remove(id: string) {\r\n const currentToasts = this.toasts$.value;\r\n this.toasts$.next(currentToasts.filter(t => t.id !== id));\r\n }\r\n\r\n clear() {\r\n this.toasts$.next([]);\r\n }\r\n}\r\n","import { Component, OnInit, OnDestroy, HostBinding } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ToastService, Toast } from './toast.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-toast-container',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n <div class=\"toast-container\">\r\n <div \r\n *ngFor=\"let toast of toasts\"\r\n class=\"toast\"\r\n [class]=\"'toast-' + toast.type\"\r\n [@slideIn]\r\n >\r\n <div class=\"toast-content\">\r\n <div *ngIf=\"toast.title\" class=\"toast-title\">{{ toast.title }}</div>\r\n <div class=\"toast-message\" [innerHTML]=\"toast.message\"></div>\r\n </div>\r\n <button class=\"toast-close\" (click)=\"close(toast.id)\" aria-label=\"Close\">\r\n ✕\r\n </button>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --info-color: #2196f3;\r\n --success-color: #4caf50;\r\n --warning-color: #ff9800;\r\n --error-color: #f44336;\r\n --text-primary: #333;\r\n --bg-primary: white;\r\n --shadow: rgba(0, 0, 0, 0.15);\r\n --text-secondary: #999;\r\n --border-color: rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n :host(.theme-dark) {\r\n --info-color: #64b5f6;\r\n --success-color: #81c784;\r\n --warning-color: #ffb74d;\r\n --error-color: #ef5350;\r\n --text-primary: #e0e0e0;\r\n --bg-primary: #1e1e1e;\r\n --shadow: rgba(0, 0, 0, 0.3);\r\n --text-secondary: #888;\r\n --border-color: rgba(255, 255, 255, 0.1);\r\n }\r\n\r\n .toast-container {\r\n position: fixed;\r\n top: 20px;\r\n right: 20px;\r\n z-index: 9999;\r\n pointer-events: none;\r\n }\r\n\r\n .toast {\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n margin-bottom: 12px;\r\n border-radius: 4px;\r\n background: var(--bg-primary);\r\n border: 1px solid var(--border-color);\r\n box-shadow: 0 4px 12px var(--shadow);\r\n pointer-events: auto;\r\n min-width: 280px;\r\n max-width: 400px;\r\n animation: slideIn 0.3s ease-out;\r\n }\r\n\r\n .toast-content {\r\n flex: 1;\r\n }\r\n\r\n .toast-title {\r\n font-weight: 600;\r\n font-size: 14px;\r\n margin-bottom: 4px;\r\n }\r\n\r\n .toast-message {\r\n font-size: 13px;\r\n line-height: 1.4;\r\n }\r\n\r\n .toast-close {\r\n background: none;\r\n border: none;\r\n cursor: pointer;\r\n font-size: 18px;\r\n color: var(--text-secondary);\r\n padding: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n transition: color 0.2s;\r\n }\r\n\r\n .toast-close:hover {\r\n color: var(--text-primary);\r\n }\r\n\r\n /* Toast types */\r\n .toast-info {\r\n border-left: 4px solid var(--info-color);\r\n }\r\n\r\n .toast-info .toast-title {\r\n color: var(--info-color);\r\n }\r\n\r\n .toast-info .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n .toast-success {\r\n border-left: 4px solid var(--success-color);\r\n }\r\n\r\n .toast-success .toast-title {\r\n color: var(--success-color);\r\n }\r\n\r\n .toast-success .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n .toast-warning {\r\n border-left: 4px solid var(--warning-color);\r\n }\r\n\r\n .toast-warning .toast-title {\r\n color: var(--warning-color);\r\n }\r\n\r\n .toast-warning .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n .toast-error {\r\n border-left: 4px solid var(--error-color);\r\n }\r\n\r\n .toast-error .toast-title {\r\n color: var(--error-color);\r\n }\r\n\r\n .toast-error .toast-message {\r\n color: var(--text-primary);\r\n }\r\n\r\n @keyframes slideIn {\r\n from {\r\n transform: translateX(400px);\r\n opacity: 0;\r\n }\r\n to {\r\n transform: translateX(0);\r\n opacity: 1;\r\n }\r\n }\r\n\r\n @media (max-width: 600px) {\r\n .toast-container {\r\n top: 10px;\r\n right: 10px;\r\n left: 10px;\r\n }\r\n\r\n .toast {\r\n min-width: auto;\r\n max-width: 100%;\r\n }\r\n }\r\n `]\r\n})\r\nexport class ToastContainerComponent implements OnInit, OnDestroy {\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n\r\n toasts: Toast[] = [];\r\n currentTheme: Theme = 'light';\r\n private destroy$ = new Subject<void>();\r\n\r\n constructor(private toastService: ToastService, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.toastService.toasts\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(toasts => {\r\n this.toasts = toasts;\r\n });\r\n\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n close(id: string) {\r\n this.toastService.remove(id);\r\n }\r\n}\r\n","import { Component, OnInit, OnDestroy, HostBinding, Output, EventEmitter } from '@angular/core';\r\nimport { NgIf, NgFor } from '@angular/common';\r\nimport { MesAuthService, NotificationDto, PagedList, RealTimeNotificationDto } from './mes-auth.service';\r\nimport { ToastService } from './toast.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-notification-panel',\r\n standalone: true,\r\n imports: [NgIf, NgFor],\r\n template: `\r\n <div class=\"notification-panel\" [class.open]=\"isOpen\">\r\n <!-- Header -->\r\n <div class=\"panel-header\">\r\n <h3>Notifications</h3>\r\n <button class=\"close-btn\" (click)=\"close()\" title=\"Close\">✕</button>\r\n </div>\r\n\r\n <!-- Tabs -->\r\n <div class=\"tabs\">\r\n <button\r\n class=\"tab-btn\"\r\n [class.active]=\"activeTab === 'unread'\"\r\n (click)=\"switchTab('unread')\"\r\n >\r\n Unread ({{ unreadNotifications.length }})\r\n </button>\r\n <button\r\n class=\"tab-btn\"\r\n [class.active]=\"activeTab === 'read'\"\r\n (click)=\"switchTab('read')\"\r\n >\r\n Read ({{ readNotifications.length }})\r\n </button>\r\n </div>\r\n\r\n <!-- Notifications List -->\r\n <div class=\"notifications-list\">\r\n <ng-container *ngIf=\"currentNotifications.length > 0\">\r\n <div\r\n *ngFor=\"let notification of currentNotifications\"\r\n class=\"notification-item\"\r\n [class.unread]=\"!notification.isRead\"\r\n (click)=\"openDetails(notification)\"\r\n >\r\n <div class=\"notification-content\">\r\n <div class=\"notification-title\">{{ notification.title }}</div>\r\n <div class=\"notification-message\">{{ getNotificationMessage(notification) }}</div>\r\n <div class=\"notification-meta\">\r\n <span class=\"app-name\">{{ notification.sourceAppName }}</span>\r\n <span class=\"time\">{{ formatDate(notification.createdAt) }}</span>\r\n </div>\r\n </div>\r\n <button\r\n class=\"read-btn\"\r\n (click)=\"markAsRead(notification.id, $event)\"\r\n title=\"Mark as read\"\r\n *ngIf=\"!notification.isRead\"\r\n >\r\n ✓\r\n </button>\r\n <button\r\n class=\"delete-btn\"\r\n (click)=\"delete(notification.id, $event)\"\r\n title=\"Delete notification\"\r\n *ngIf=\"notification.isRead\"\r\n >\r\n 🗑\r\n </button>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"currentNotifications.length === 0\">\r\n <div class=\"empty-state\">\r\n No {{ activeTab }} notifications\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Footer Actions -->\r\n <div class=\"panel-footer\" *ngIf=\"currentNotifications.length > 0\">\r\n <div class=\"footer-actions\" *ngIf=\"activeTab === 'unread'\">\r\n <button class=\"action-btn\" (click)=\"markAllAsRead()\" *ngIf=\"unreadNotifications.length > 0\">\r\n Mark all as read\r\n </button>\r\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllUnread()\" *ngIf=\"unreadNotifications.length > 0\">\r\n Delete all\r\n </button>\r\n </div>\r\n <button class=\"action-btn delete-all-btn\" (click)=\"deleteAllRead()\" *ngIf=\"activeTab === 'read' && readNotifications.length > 0\">\r\n Delete all\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Details Modal -->\r\n <div class=\"modal-overlay\" *ngIf=\"selectedNotification\" (click)=\"closeDetails()\">\r\n <div class=\"modal-container\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-header\">\r\n <h3>{{ selectedNotification.title }}</h3>\r\n <button class=\"close-btn\" (click)=\"closeDetails()\" title=\"Close\">✕</button>\r\n </div>\r\n <div class=\"modal-meta\">\r\n <span class=\"app-name\">{{ selectedNotification.sourceAppName }}</span>\r\n <span class=\"time\">{{ formatDate(selectedNotification.createdAt) }}</span>\r\n </div>\r\n <div class=\"modal-body\" [innerHTML]=\"getHtmlMessage(selectedNotification)\"></div>\r\n <div class=\"modal-footer\">\r\n <button class=\"action-btn\" (click)=\"closeDetails()\">Close</button>\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n position: relative;\r\n --primary-color: #1976d2;\r\n --primary-hover: #1565c0;\r\n --success-color: #4caf50;\r\n --error-color: #f44336;\r\n --text-primary: #333;\r\n --text-secondary: #666;\r\n --text-muted: #999;\r\n --bg-primary: white;\r\n --bg-secondary: #f5f5f5;\r\n --bg-tertiary: #fafafa;\r\n --bg-hover: #f5f5f5;\r\n --bg-unread: #e3f2fd;\r\n --border-color: #e0e0e0;\r\n --border-light: #f0f0f0;\r\n --shadow: rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n :host(.theme-dark) {\r\n display: block;\r\n position: relative;\r\n --primary-color: #90caf9;\r\n --primary-hover: #64b5f6;\r\n --success-color: #81c784;\r\n --error-color: #ef5350;\r\n --text-primary: #e0e0e0;\r\n --text-secondary: #b0b0b0;\r\n --text-muted: #888;\r\n --bg-primary: #1e1e1e;\r\n --bg-secondary: #2d2d2d;\r\n --bg-tertiary: #252525;\r\n --bg-hover: #333;\r\n --bg-unread: rgba(144, 202, 249, 0.1);\r\n --border-color: #404040;\r\n --border-light: #333;\r\n --shadow: rgba(0, 0, 0, 0.3);\r\n }\r\n\r\n .notification-panel {\r\n position: fixed;\r\n top: 0;\r\n right: -350px;\r\n width: 350px;\r\n height: 100vh;\r\n background: var(--bg-primary);\r\n box-shadow: -2px 0 8px var(--shadow);\r\n display: flex;\r\n flex-direction: column;\r\n z-index: 1000;\r\n transition: right 0.3s ease;\r\n }\r\n\r\n .notification-panel.open {\r\n right: 0;\r\n }\r\n\r\n .panel-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 16px;\r\n border-bottom: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n }\r\n\r\n .panel-header h3 {\r\n margin: 0;\r\n font-size: 18px;\r\n color: var(--text-primary);\r\n }\r\n\r\n .close-btn {\r\n background: none;\r\n border: none;\r\n font-size: 20px;\r\n cursor: pointer;\r\n color: var(--text-secondary);\r\n padding: 0;\r\n width: 32px;\r\n height: 32px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: color 0.2s;\r\n }\r\n\r\n .close-btn:hover {\r\n color: var(--text-primary);\r\n }\r\n\r\n .tabs {\r\n display: flex;\r\n border-bottom: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n }\r\n\r\n .tab-btn {\r\n flex: 1;\r\n padding: 12px 16px;\r\n background: none;\r\n border: none;\r\n color: var(--text-secondary);\r\n cursor: pointer;\r\n font-size: 14px;\r\n font-weight: 500;\r\n transition: all 0.2s;\r\n border-bottom: 2px solid transparent;\r\n }\r\n\r\n .tab-btn:hover {\r\n background-color: var(--bg-hover);\r\n color: var(--text-primary);\r\n }\r\n\r\n .tab-btn.active {\r\n color: var(--primary-color);\r\n border-bottom-color: var(--primary-color);\r\n background-color: var(--bg-primary);\r\n }\r\n\r\n .notifications-list {\r\n flex: 1;\r\n overflow-y: auto;\r\n }\r\n\r\n .notification-item {\r\n display: flex;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--border-light);\r\n cursor: pointer;\r\n background-color: var(--bg-tertiary);\r\n transition: background-color 0.2s;\r\n }\r\n\r\n .notification-item:hover {\r\n background-color: var(--bg-hover);\r\n }\r\n\r\n .notification-item.unread {\r\n background-color: var(--bg-unread);\r\n }\r\n\r\n .notification-content {\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .notification-title {\r\n font-weight: 600;\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n margin-bottom: 4px;\r\n }\r\n\r\n .notification-message {\r\n color: var(--text-secondary);\r\n font-size: 12px;\r\n line-height: 1.4;\r\n margin-bottom: 6px;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n }\r\n\r\n .notification-meta {\r\n display: flex;\r\n justify-content: space-between;\r\n font-size: 12px;\r\n color: var(--text-muted);\r\n }\r\n\r\n .app-name {\r\n font-weight: 500;\r\n color: var(--primary-color);\r\n }\r\n\r\n .read-btn {\r\n background: none;\r\n border: none;\r\n color: var(--text-muted);\r\n cursor: pointer;\r\n font-size: 14px;\r\n padding: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n transition: color 0.2s;\r\n }\r\n\r\n .read-btn:hover {\r\n color: var(--success-color);\r\n }\r\n\r\n .delete-btn {\r\n background: none;\r\n border: none;\r\n color: var(--text-muted);\r\n cursor: pointer;\r\n font-size: 14px;\r\n padding: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n transition: color 0.2s;\r\n }\r\n\r\n .delete-btn:hover {\r\n color: var(--error-color);\r\n }\r\n\r\n .empty-state {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n color: var(--text-muted);\r\n font-size: 14px;\r\n }\r\n\r\n .panel-footer {\r\n padding: 12px 16px;\r\n border-top: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n }\r\n\r\n .footer-actions {\r\n display: flex;\r\n gap: 8px;\r\n }\r\n\r\n .footer-actions .action-btn {\r\n flex: 1;\r\n }\r\n\r\n .action-btn {\r\n width: 100%;\r\n padding: 8px;\r\n background-color: var(--primary-color);\r\n color: white;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-weight: 500;\r\n transition: background-color 0.2s;\r\n }\r\n\r\n .action-btn:hover {\r\n background-color: var(--primary-hover);\r\n }\r\n\r\n .delete-all-btn {\r\n background-color: var(--error-color);\r\n color: white;\r\n }\r\n\r\n .delete-all-btn:hover {\r\n background-color: #d32f2f; /* Darker red for hover */\r\n }\r\n\r\n /* Modal Overlay */\r\n .modal-overlay {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n width: 100vw;\r\n height: 100vh;\r\n background-color: rgba(0, 0, 0, 0.5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 9999;\r\n }\r\n\r\n .modal-container {\r\n background: var(--bg-primary);\r\n border-radius: 8px;\r\n width: 90%;\r\n max-width: 600px;\r\n max-height: 80vh;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 4px 20px var(--shadow);\r\n }\r\n\r\n .modal-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 16px 20px;\r\n border-bottom: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n border-radius: 8px 8px 0 0;\r\n }\r\n\r\n .modal-header h3 {\r\n margin: 0;\r\n font-size: 18px;\r\n color: var(--text-primary);\r\n }\r\n\r\n .modal-meta {\r\n display: flex;\r\n justify-content: space-between;\r\n padding: 8px 20px;\r\n font-size: 12px;\r\n color: var(--text-muted);\r\n background-color: var(--bg-tertiary);\r\n border-bottom: 1px solid var(--border-light);\r\n }\r\n\r\n .modal-body {\r\n padding: 20px;\r\n overflow-y: auto;\r\n flex: 1;\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n line-height: 1.6;\r\n }\r\n\r\n .modal-footer {\r\n padding: 12px 20px;\r\n border-top: 1px solid var(--border-color);\r\n background-color: var(--bg-secondary);\r\n border-radius: 0 0 8px 8px;\r\n display: flex;\r\n justify-content: flex-end;\r\n }\r\n\r\n .modal-footer .action-btn {\r\n width: auto;\r\n padding: 8px 24px;\r\n }\r\n\r\n @media (max-width: 600px) {\r\n .notification-panel {\r\n width: 100%;\r\n right: -100%;\r\n }\r\n\r\n .modal-container {\r\n width: 95%;\r\n max-height: 90vh;\r\n }\r\n }\r\n `]\r\n})\r\nexport class NotificationPanelComponent implements OnInit, OnDestroy {\r\n @Output() notificationRead = new EventEmitter<void>();\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n\r\n isOpen = false;\r\n notifications: NotificationDto[] = [];\r\n currentTheme: Theme = 'light';\r\n activeTab: 'unread' | 'read' = 'unread'; // Default to unread tab\r\n private destroy$ = new Subject<void>();\r\n\r\n get unreadNotifications(): NotificationDto[] {\r\n return this.notifications.filter(n => !n.isRead);\r\n }\r\n\r\n get readNotifications(): NotificationDto[] {\r\n return this.notifications.filter(n => n.isRead);\r\n }\r\n\r\n get currentNotifications(): NotificationDto[] {\r\n return this.activeTab === 'unread' ? this.unreadNotifications : this.readNotifications;\r\n }\r\n\r\n selectedNotification: NotificationDto | null = null;\r\n\r\n // Returns plain text message for list display\r\n getNotificationMessage(notification: NotificationDto): string {\r\n return notification.message || '';\r\n }\r\n\r\n // Returns HTML message for modal display\r\n getHtmlMessage(notification: NotificationDto): string {\r\n return notification.messageHtml || notification.message || '';\r\n }\r\n\r\n constructor(private authService: MesAuthService, private toastService: ToastService, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n\r\n this.loadNotifications();\r\n\r\n // Listen for new real-time notifications\r\n this.authService.notifications$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe((notification: RealTimeNotificationDto) => {\r\n // Show toast for new notification\r\n this.toastService.show(\r\n notification.messageHtml || notification.message || '',\r\n notification.title,\r\n 'info',\r\n 5000\r\n );\r\n // Reload notifications list\r\n this.loadNotifications();\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n private loadNotifications() {\r\n this.authService.getNotifications(1, 50, true).subscribe({ // includeRead = true to get both read and unread\r\n next: (response: PagedList<NotificationDto>) => {\r\n this.notifications = response.items || [];\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n open() {\r\n this.isOpen = true;\r\n this.activeTab = 'unread'; // Reset to unread tab when opening\r\n }\r\n\r\n close() {\r\n this.isOpen = false;\r\n }\r\n\r\n switchTab(tab: 'unread' | 'read') {\r\n this.activeTab = tab;\r\n }\r\n\r\n openDetails(notification: NotificationDto) {\r\n this.selectedNotification = notification;\r\n // Mark as read when opening details (if not already read)\r\n if (!notification.isRead) {\r\n this.authService.markAsRead(notification.id).subscribe({\r\n next: () => {\r\n notification.isRead = true;\r\n this.notificationRead.emit();\r\n },\r\n error: () => {}\r\n });\r\n }\r\n }\r\n\r\n closeDetails() {\r\n this.selectedNotification = null;\r\n }\r\n\r\n markAsRead(notificationId: string, event?: Event) {\r\n if (event) {\r\n event.stopPropagation();\r\n }\r\n this.authService.markAsRead(notificationId).subscribe({\r\n next: () => {\r\n const notification = this.notifications.find(n => n.id === notificationId);\r\n if (notification) {\r\n notification.isRead = true;\r\n this.notificationRead.emit();\r\n }\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n markAllAsRead() {\r\n this.authService.markAllAsRead().subscribe({\r\n next: () => {\r\n this.notifications.forEach(n => n.isRead = true);\r\n this.notificationRead.emit();\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n deleteAllRead() {\r\n const readNotificationIds = this.notifications\r\n .filter(n => n.isRead)\r\n .map(n => n.id);\r\n\r\n // Delete all read notifications\r\n const deletePromises = readNotificationIds.map(id =>\r\n this.authService.deleteNotification(id).toPromise()\r\n );\r\n\r\n Promise.all(deletePromises).then(() => {\r\n // Remove all read notifications from the local array\r\n this.notifications = this.notifications.filter(n => !n.isRead);\r\n }).catch((err) => {\r\n // If bulk delete fails, reload notifications to get current state\r\n this.loadNotifications();\r\n });\r\n }\r\n\r\n deleteAllUnread() {\r\n const unreadNotificationIds = this.notifications\r\n .filter(n => !n.isRead)\r\n .map(n => n.id);\r\n\r\n // Delete all unread notifications\r\n const deletePromises = unreadNotificationIds.map(id =>\r\n this.authService.deleteNotification(id).toPromise()\r\n );\r\n\r\n Promise.all(deletePromises).then(() => {\r\n // Remove all unread notifications from the local array\r\n this.notifications = this.notifications.filter(n => n.isRead);\r\n }).catch((err) => {\r\n // If bulk delete fails, reload notifications to get current state\r\n this.loadNotifications();\r\n });\r\n }\r\n\r\n delete(notificationId: string, event: Event) {\r\n event.stopPropagation();\r\n this.authService.deleteNotification(notificationId).subscribe({\r\n next: () => {\r\n this.notifications = this.notifications.filter(n => n.id !== notificationId);\r\n },\r\n error: (err) => {}\r\n });\r\n }\r\n\r\n formatDate(dateString: string): string {\r\n const date = new Date(dateString);\r\n const now = new Date();\r\n const diffMs = now.getTime() - date.getTime();\r\n const diffMins = Math.floor(diffMs / 60000);\r\n const diffHours = Math.floor(diffMs / 3600000);\r\n const diffDays = Math.floor(diffMs / 86400000);\r\n\r\n if (diffMins < 1) return 'Now';\r\n if (diffMins < 60) return `${diffMins}m ago`;\r\n if (diffHours < 24) return `${diffHours}h ago`;\r\n if (diffDays < 7) return `${diffDays}d ago`;\r\n \r\n return date.toLocaleDateString();\r\n }\r\n}\r\n","import { Component, ViewChild, AfterViewInit } from '@angular/core';\r\nimport { ToastContainerComponent } from './toast-container.component';\r\nimport { UserProfileComponent } from './user-profile.component';\r\nimport { NotificationPanelComponent } from './notification-panel.component';\r\n\r\n@Component({\r\n selector: 'ma-user',\r\n standalone: true,\r\n imports: [ToastContainerComponent, UserProfileComponent, NotificationPanelComponent],\r\n template: `\r\n <ma-toast-container></ma-toast-container>\r\n <div class=\"user-header\">\r\n <ma-user-profile (notificationClick)=\"notificationPanel.open()\"></ma-user-profile>\r\n </div>\r\n <ma-notification-panel #notificationPanel (notificationRead)=\"onNotificationRead()\"></ma-notification-panel>\r\n `,\r\n styles: [`\r\n .user-header {\r\n display: flex;\r\n justify-content: flex-end;\r\n }\r\n `]\r\n})\r\nexport class MaUserComponent implements AfterViewInit {\r\n @ViewChild(UserProfileComponent) userProfile?: UserProfileComponent;\r\n\r\n ngAfterViewInit() {\r\n // Ensure proper initialization\r\n if (this.userProfile) {\r\n this.userProfile.loadUnreadCount();\r\n }\r\n }\r\n\r\n onNotificationRead() {\r\n if (this.userProfile) {\r\n this.userProfile.loadUnreadCount();\r\n }\r\n }\r\n}\r\n","import { Component, OnInit, OnDestroy, Output, EventEmitter, HostBinding } from '@angular/core';\r\nimport { NgIf } from '@angular/common';\r\nimport { MesAuthService } from './mes-auth.service';\r\nimport { ThemeService, Theme } from './theme.service';\r\nimport { Subject } from 'rxjs';\r\nimport { takeUntil } from 'rxjs/operators';\r\n\r\n@Component({\r\n selector: 'ma-notification-badge',\r\n standalone: true,\r\n imports: [NgIf],\r\n template: `\r\n <button class=\"notification-btn\" (click)=\"onNotificationClick()\" title=\"Notifications\">\r\n <span class=\"icon\">🔔</span>\r\n <span class=\"badge\" *ngIf=\"unreadCount > 0\">{{ unreadCount }}</span>\r\n </button>\r\n `,\r\n styles: [`\r\n :host {\r\n --error-color: #f44336;\r\n }\r\n\r\n :host(.theme-dark) {\r\n --error-color: #ef5350;\r\n }\r\n\r\n .notification-btn {\r\n position: relative;\r\n background: none;\r\n border: none;\r\n font-size: 24px;\r\n cursor: pointer;\r\n padding: 8px;\r\n transition: opacity 0.2s;\r\n }\r\n\r\n .notification-btn:hover {\r\n opacity: 0.7;\r\n }\r\n\r\n .icon {\r\n display: inline-block;\r\n }\r\n\r\n .badge {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n background-color: var(--error-color);\r\n color: white;\r\n border-radius: 50%;\r\n width: 20px;\r\n height: 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 12px;\r\n font-weight: bold;\r\n }\r\n `]\r\n})\r\nexport class NotificationBadgeComponent implements OnInit, OnDestroy {\r\n @Output() notificationClick = new EventEmitter<void>();\r\n @HostBinding('class') get themeClass(): string {\r\n return `theme-${this.currentTheme}`;\r\n }\r\n \r\n unreadCount = 0;\r\n currentTheme: Theme = 'light';\r\n private hasUser = false;\r\n private destroy$ = new Subject<void>();\r\n\r\n constructor(private authService: MesAuthService, private themeService: ThemeService) {}\r\n\r\n ngOnInit() {\r\n this.themeService.currentTheme$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(theme => {\r\n this.currentTheme = theme;\r\n });\r\n\r\n this.authService.currentUser$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(user => {\r\n this.hasUser = !!user;\r\n if (!this.hasUser) {\r\n this.unreadCount = 0;\r\n return;\r\n }\r\n this.loadUnreadCount();\r\n });\r\n \r\n // Listen for new notifications\r\n this.authService.notifications$\r\n .pipe(takeUntil(this.destroy$))\r\n .subscribe(() => {\r\n if (this.hasUser) {\r\n this.loadUnreadCount();\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.destroy$.next();\r\n this.destroy$.complete();\r\n }\r\n\r\n private loadUnreadCount() {\r\n if (!this.hasUser) {\r\n this.unreadCount = 0;\r\n return;\r\n }\r\n\r\n this.authService.getUnreadCount().subscribe({\r\n next: (response: any) => {\r\n this.unreadCount = response.unreadCount || 0;\r\n },\r\n error: (err) => console.error('Error loading unread count:', err)\r\n });\r\n }\r\n\r\n onNotificationClick() {\r\n this.notificationClick.emit();\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.MesAuthService","i3.ThemeService","i1.ToastService","i2.ThemeService","i2.ToastService"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mesauth-angular",
3
- "version": "1.1.8",
3
+ "version": "1.1.9",
4
4
  "description": "Angular helper library to connect to a backend API and SignalR hub to surface the current logged-in user and incoming notifications with dark/light theme support",
5
5
  "main": "dist/fesm2022/mesauth-angular.mjs",
6
6
  "types": "dist/index.d.ts",