mesauth-angular 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -2
- package/dist/README.md +17 -2
- package/dist/esm2020/ma-user.component.mjs +13 -7
- package/dist/esm2020/notification-panel.component.mjs +88 -28
- package/dist/esm2020/user-profile.component.mjs +1 -1
- package/dist/fesm2015/mesauth-angular.mjs +98 -32
- package/dist/fesm2015/mesauth-angular.mjs.map +1 -1
- package/dist/fesm2020/mesauth-angular.mjs +98 -32
- package/dist/fesm2020/mesauth-angular.mjs.map +1 -1
- package/dist/ma-user.component.d.ts +3 -0
- package/dist/notification-panel.component.d.ts +9 -3
- package/dist/package.json +1 -1
- package/dist/user-profile.component.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, NgModule, EventEmitter, Component, Output, HostBinding, HostListener } from '@angular/core';
|
|
2
|
+
import { Injectable, NgModule, EventEmitter, Component, Output, HostBinding, HostListener, ViewChild } from '@angular/core';
|
|
3
3
|
import { HubConnectionBuilder, LogLevel } from '@microsoft/signalr';
|
|
4
4
|
import { BehaviorSubject, Subject, throwError } from 'rxjs';
|
|
5
5
|
import { tap, catchError, takeUntil } from 'rxjs/operators';
|
|
@@ -553,14 +553,25 @@ class NotificationPanelComponent {
|
|
|
553
553
|
this.authService = authService;
|
|
554
554
|
this.toastService = toastService;
|
|
555
555
|
this.themeService = themeService;
|
|
556
|
+
this.notificationRead = new EventEmitter();
|
|
556
557
|
this.isOpen = false;
|
|
557
558
|
this.notifications = [];
|
|
558
559
|
this.currentTheme = 'light';
|
|
560
|
+
this.activeTab = 'unread'; // Default to unread tab
|
|
559
561
|
this.destroy$ = new Subject();
|
|
560
562
|
}
|
|
561
563
|
get themeClass() {
|
|
562
564
|
return `theme-${this.currentTheme}`;
|
|
563
565
|
}
|
|
566
|
+
get unreadNotifications() {
|
|
567
|
+
return this.notifications.filter(n => !n.isRead);
|
|
568
|
+
}
|
|
569
|
+
get readNotifications() {
|
|
570
|
+
return this.notifications.filter(n => n.isRead);
|
|
571
|
+
}
|
|
572
|
+
get currentNotifications() {
|
|
573
|
+
return this.activeTab === 'unread' ? this.unreadNotifications : this.readNotifications;
|
|
574
|
+
}
|
|
564
575
|
ngOnInit() {
|
|
565
576
|
this.themeService.currentTheme$
|
|
566
577
|
.pipe(takeUntil(this.destroy$))
|
|
@@ -583,7 +594,7 @@ class NotificationPanelComponent {
|
|
|
583
594
|
this.destroy$.complete();
|
|
584
595
|
}
|
|
585
596
|
loadNotifications() {
|
|
586
|
-
this.authService.getNotifications(1, 50,
|
|
597
|
+
this.authService.getNotifications(1, 50, true).subscribe({
|
|
587
598
|
next: (response) => {
|
|
588
599
|
this.notifications = response.items || [];
|
|
589
600
|
},
|
|
@@ -592,16 +603,24 @@ class NotificationPanelComponent {
|
|
|
592
603
|
}
|
|
593
604
|
open() {
|
|
594
605
|
this.isOpen = true;
|
|
606
|
+
this.activeTab = 'unread'; // Reset to unread tab when opening
|
|
595
607
|
}
|
|
596
608
|
close() {
|
|
597
609
|
this.isOpen = false;
|
|
598
610
|
}
|
|
599
|
-
|
|
611
|
+
switchTab(tab) {
|
|
612
|
+
this.activeTab = tab;
|
|
613
|
+
}
|
|
614
|
+
markAsRead(notificationId, event) {
|
|
615
|
+
if (event) {
|
|
616
|
+
event.stopPropagation();
|
|
617
|
+
}
|
|
600
618
|
this.authService.markAsRead(notificationId).subscribe({
|
|
601
619
|
next: () => {
|
|
602
620
|
const notification = this.notifications.find(n => n.id === notificationId);
|
|
603
621
|
if (notification) {
|
|
604
622
|
notification.isRead = true;
|
|
623
|
+
this.notificationRead.emit();
|
|
605
624
|
}
|
|
606
625
|
},
|
|
607
626
|
error: (err) => { }
|
|
@@ -611,6 +630,7 @@ class NotificationPanelComponent {
|
|
|
611
630
|
this.authService.markAllAsRead().subscribe({
|
|
612
631
|
next: () => {
|
|
613
632
|
this.notifications.forEach(n => n.isRead = true);
|
|
633
|
+
this.notificationRead.emit();
|
|
614
634
|
},
|
|
615
635
|
error: (err) => { }
|
|
616
636
|
});
|
|
@@ -643,7 +663,7 @@ class NotificationPanelComponent {
|
|
|
643
663
|
}
|
|
644
664
|
}
|
|
645
665
|
NotificationPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationPanelComponent, deps: [{ token: MesAuthService }, { token: ToastService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
646
|
-
NotificationPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NotificationPanelComponent, isStandalone: true, selector: "ma-notification-panel", host: { properties: { "class": "this.themeClass" } }, ngImport: i0, template: `
|
|
666
|
+
NotificationPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NotificationPanelComponent, isStandalone: true, selector: "ma-notification-panel", outputs: { notificationRead: "notificationRead" }, host: { properties: { "class": "this.themeClass" } }, ngImport: i0, template: `
|
|
647
667
|
<div class="notification-panel" [class.open]="isOpen">
|
|
648
668
|
<!-- Header -->
|
|
649
669
|
<div class="panel-header">
|
|
@@ -651,11 +671,29 @@ NotificationPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0
|
|
|
651
671
|
<button class="close-btn" (click)="close()" title="Close">✕</button>
|
|
652
672
|
</div>
|
|
653
673
|
|
|
674
|
+
<!-- Tabs -->
|
|
675
|
+
<div class="tabs">
|
|
676
|
+
<button
|
|
677
|
+
class="tab-btn"
|
|
678
|
+
[class.active]="activeTab === 'unread'"
|
|
679
|
+
(click)="switchTab('unread')"
|
|
680
|
+
>
|
|
681
|
+
Unread ({{ unreadNotifications.length }})
|
|
682
|
+
</button>
|
|
683
|
+
<button
|
|
684
|
+
class="tab-btn"
|
|
685
|
+
[class.active]="activeTab === 'read'"
|
|
686
|
+
(click)="switchTab('read')"
|
|
687
|
+
>
|
|
688
|
+
Read ({{ readNotifications.length }})
|
|
689
|
+
</button>
|
|
690
|
+
</div>
|
|
691
|
+
|
|
654
692
|
<!-- Notifications List -->
|
|
655
693
|
<div class="notifications-list">
|
|
656
|
-
<ng-container *ngIf="
|
|
694
|
+
<ng-container *ngIf="currentNotifications.length > 0">
|
|
657
695
|
<div
|
|
658
|
-
*ngFor="let notification of
|
|
696
|
+
*ngFor="let notification of currentNotifications"
|
|
659
697
|
class="notification-item"
|
|
660
698
|
[class.unread]="!notification.isRead"
|
|
661
699
|
(click)="markAsRead(notification.id)"
|
|
@@ -669,30 +707,31 @@ NotificationPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0
|
|
|
669
707
|
</div>
|
|
670
708
|
</div>
|
|
671
709
|
<button
|
|
672
|
-
class="
|
|
673
|
-
(click)="
|
|
674
|
-
title="
|
|
710
|
+
class="read-btn"
|
|
711
|
+
(click)="markAsRead(notification.id, $event)"
|
|
712
|
+
title="Mark as read"
|
|
713
|
+
*ngIf="!notification.isRead"
|
|
675
714
|
>
|
|
676
|
-
|
|
715
|
+
✓
|
|
677
716
|
</button>
|
|
678
717
|
</div>
|
|
679
718
|
</ng-container>
|
|
680
719
|
|
|
681
|
-
<ng-container *ngIf="
|
|
720
|
+
<ng-container *ngIf="currentNotifications.length === 0">
|
|
682
721
|
<div class="empty-state">
|
|
683
|
-
No notifications
|
|
722
|
+
No {{ activeTab }} notifications
|
|
684
723
|
</div>
|
|
685
724
|
</ng-container>
|
|
686
725
|
</div>
|
|
687
726
|
|
|
688
727
|
<!-- Footer Actions -->
|
|
689
|
-
<div class="panel-footer" *ngIf="
|
|
690
|
-
<button class="action-btn" (click)="markAllAsRead()">
|
|
728
|
+
<div class="panel-footer" *ngIf="currentNotifications.length > 0">
|
|
729
|
+
<button class="action-btn" (click)="markAllAsRead()" *ngIf="activeTab === 'unread' && unreadNotifications.length > 0">
|
|
691
730
|
Mark all as read
|
|
692
731
|
</button>
|
|
693
732
|
</div>
|
|
694
733
|
</div>
|
|
695
|
-
`, isInline: true, styles: [":host{--primary-color: #1976d2;--primary-hover: #1565c0;--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;--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)}.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)}.
|
|
734
|
+
`, 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)}.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)}.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)}@media (max-width: 600px){.notification-panel{width:100%;right:-100%}}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
696
735
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationPanelComponent, decorators: [{
|
|
697
736
|
type: Component,
|
|
698
737
|
args: [{ selector: 'ma-notification-panel', standalone: true, imports: [NgIf, NgFor], template: `
|
|
@@ -703,11 +742,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
703
742
|
<button class="close-btn" (click)="close()" title="Close">✕</button>
|
|
704
743
|
</div>
|
|
705
744
|
|
|
745
|
+
<!-- Tabs -->
|
|
746
|
+
<div class="tabs">
|
|
747
|
+
<button
|
|
748
|
+
class="tab-btn"
|
|
749
|
+
[class.active]="activeTab === 'unread'"
|
|
750
|
+
(click)="switchTab('unread')"
|
|
751
|
+
>
|
|
752
|
+
Unread ({{ unreadNotifications.length }})
|
|
753
|
+
</button>
|
|
754
|
+
<button
|
|
755
|
+
class="tab-btn"
|
|
756
|
+
[class.active]="activeTab === 'read'"
|
|
757
|
+
(click)="switchTab('read')"
|
|
758
|
+
>
|
|
759
|
+
Read ({{ readNotifications.length }})
|
|
760
|
+
</button>
|
|
761
|
+
</div>
|
|
762
|
+
|
|
706
763
|
<!-- Notifications List -->
|
|
707
764
|
<div class="notifications-list">
|
|
708
|
-
<ng-container *ngIf="
|
|
765
|
+
<ng-container *ngIf="currentNotifications.length > 0">
|
|
709
766
|
<div
|
|
710
|
-
*ngFor="let notification of
|
|
767
|
+
*ngFor="let notification of currentNotifications"
|
|
711
768
|
class="notification-item"
|
|
712
769
|
[class.unread]="!notification.isRead"
|
|
713
770
|
(click)="markAsRead(notification.id)"
|
|
@@ -721,45 +778,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
721
778
|
</div>
|
|
722
779
|
</div>
|
|
723
780
|
<button
|
|
724
|
-
class="
|
|
725
|
-
(click)="
|
|
726
|
-
title="
|
|
781
|
+
class="read-btn"
|
|
782
|
+
(click)="markAsRead(notification.id, $event)"
|
|
783
|
+
title="Mark as read"
|
|
784
|
+
*ngIf="!notification.isRead"
|
|
727
785
|
>
|
|
728
|
-
|
|
786
|
+
✓
|
|
729
787
|
</button>
|
|
730
788
|
</div>
|
|
731
789
|
</ng-container>
|
|
732
790
|
|
|
733
|
-
<ng-container *ngIf="
|
|
791
|
+
<ng-container *ngIf="currentNotifications.length === 0">
|
|
734
792
|
<div class="empty-state">
|
|
735
|
-
No notifications
|
|
793
|
+
No {{ activeTab }} notifications
|
|
736
794
|
</div>
|
|
737
795
|
</ng-container>
|
|
738
796
|
</div>
|
|
739
797
|
|
|
740
798
|
<!-- Footer Actions -->
|
|
741
|
-
<div class="panel-footer" *ngIf="
|
|
742
|
-
<button class="action-btn" (click)="markAllAsRead()">
|
|
799
|
+
<div class="panel-footer" *ngIf="currentNotifications.length > 0">
|
|
800
|
+
<button class="action-btn" (click)="markAllAsRead()" *ngIf="activeTab === 'unread' && unreadNotifications.length > 0">
|
|
743
801
|
Mark all as read
|
|
744
802
|
</button>
|
|
745
803
|
</div>
|
|
746
804
|
</div>
|
|
747
|
-
`, styles: [":host{--primary-color: #1976d2;--primary-hover: #1565c0;--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;--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)}.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)}.
|
|
748
|
-
}], ctorParameters: function () { return [{ type: MesAuthService }, { type: ToastService }, { type: ThemeService }]; }, propDecorators: {
|
|
805
|
+
`, 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)}.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)}.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)}@media (max-width: 600px){.notification-panel{width:100%;right:-100%}}\n"] }]
|
|
806
|
+
}], ctorParameters: function () { return [{ type: MesAuthService }, { type: ToastService }, { type: ThemeService }]; }, propDecorators: { notificationRead: [{
|
|
807
|
+
type: Output
|
|
808
|
+
}], themeClass: [{
|
|
749
809
|
type: HostBinding,
|
|
750
810
|
args: ['class']
|
|
751
811
|
}] } });
|
|
752
812
|
|
|
753
813
|
class MaUserComponent {
|
|
814
|
+
onNotificationRead() {
|
|
815
|
+
this.userProfile.loadUnreadCount();
|
|
816
|
+
}
|
|
754
817
|
}
|
|
755
818
|
MaUserComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MaUserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
756
|
-
MaUserComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MaUserComponent, isStandalone: true, selector: "ma-user", ngImport: i0, template: `
|
|
819
|
+
MaUserComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MaUserComponent, isStandalone: true, selector: "ma-user", viewQueries: [{ propertyName: "userProfile", first: true, predicate: UserProfileComponent, descendants: true }], ngImport: i0, template: `
|
|
757
820
|
<ma-toast-container></ma-toast-container>
|
|
758
821
|
<div class="user-header">
|
|
759
822
|
<ma-user-profile (notificationClick)="notificationPanel.open()"></ma-user-profile>
|
|
760
823
|
</div>
|
|
761
|
-
<ma-notification-panel #notificationPanel></ma-notification-panel>
|
|
762
|
-
`, isInline: true, styles: [".user-header{display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "component", type: ToastContainerComponent, selector: "ma-toast-container" }, { kind: "component", type: UserProfileComponent, selector: "ma-user-profile", outputs: ["notificationClick"] }, { kind: "component", type: NotificationPanelComponent, selector: "ma-notification-panel" }] });
|
|
824
|
+
<ma-notification-panel #notificationPanel (notificationRead)="onNotificationRead()"></ma-notification-panel>
|
|
825
|
+
`, isInline: true, styles: [".user-header{display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "component", type: ToastContainerComponent, selector: "ma-toast-container" }, { kind: "component", type: UserProfileComponent, selector: "ma-user-profile", outputs: ["notificationClick"] }, { kind: "component", type: NotificationPanelComponent, selector: "ma-notification-panel", outputs: ["notificationRead"] }] });
|
|
763
826
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MaUserComponent, decorators: [{
|
|
764
827
|
type: Component,
|
|
765
828
|
args: [{ selector: 'ma-user', standalone: true, imports: [ToastContainerComponent, UserProfileComponent, NotificationPanelComponent], template: `
|
|
@@ -767,9 +830,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
767
830
|
<div class="user-header">
|
|
768
831
|
<ma-user-profile (notificationClick)="notificationPanel.open()"></ma-user-profile>
|
|
769
832
|
</div>
|
|
770
|
-
<ma-notification-panel #notificationPanel></ma-notification-panel>
|
|
833
|
+
<ma-notification-panel #notificationPanel (notificationRead)="onNotificationRead()"></ma-notification-panel>
|
|
771
834
|
`, styles: [".user-header{display:flex;justify-content:flex-end}\n"] }]
|
|
772
|
-
}]
|
|
835
|
+
}], propDecorators: { userProfile: [{
|
|
836
|
+
type: ViewChild,
|
|
837
|
+
args: [UserProfileComponent]
|
|
838
|
+
}] } });
|
|
773
839
|
|
|
774
840
|
class NotificationBadgeComponent {
|
|
775
841
|
constructor(authService, themeService) {
|