add in app notification navbar

This commit is contained in:
amentis 2024-01-09 15:52:07 +02:00
parent 1f92872158
commit da657b667b
14 changed files with 141 additions and 12 deletions

View File

@ -32,7 +32,8 @@ public class TenantScopedEntityManager {
public int getBulkSize() {
Session session = this.entityManager.unwrap(Session.class);
return session.getJdbcBatchSize();
if (session.getJdbcBatchSize() != null) return session.getJdbcBatchSize();
return 0;
}
public void setBulkSize(int size) {

View File

@ -118,6 +118,11 @@ export class ConfigurationService extends BaseComponent {
return this._notificationServiceEnabled;
}
private _inAppNotificationsCountInterval: number;
get inAppNotificationsCountInterval(): number {
return this._inAppNotificationsCountInterval || 3200;
}
public loadConfiguration(): Promise<any> {
return new Promise((r, e) => {
// We need to exclude all interceptors here, for the initial configuration request.
@ -178,6 +183,7 @@ export class ConfigurationService extends BaseComponent {
this._notificationServiceEnabled = config.notification_service.enabled;
this._notificationServiceAddress = config.notification_service.address;
}
this._inAppNotificationsCountInterval = config.inAppNotificationsCountInterval;
}
}

View File

@ -57,6 +57,14 @@ export class InAppNotificationService {
catchError((error: any) => throwError(error)));
}
readAll(): Observable<string> {
const url = `${this.apiBase}/read-all`;
return this.http
.post<string>(url, {}).pipe(
catchError((error: any) => throwError(error)));
}
delete(id: Guid): Observable<InAppNotification> {
const url = `${this.apiBase}/${id}`;
return this.http

View File

@ -37,7 +37,6 @@ import { CommonFormattingModule } from '@common/formatting/common-formatting.mod
// ],
exports: [
InAppNotificationListingComponent,
InAppNotificationListingDialogComponent
]
})
export class InAppNotificationModule { }

View File

@ -6,8 +6,12 @@
<span mat-line class="secondary-text">{{ inappNotification.createdAt | date : 'short'}}</span>
<mat-divider inset *ngIf="!last"></mat-divider>
</a>
<mat-list-item *ngIf="authService.hasPermission(authService.permissionEnum.ViewInAppNotificationPage)">
<a (click)="goToNotifications()">{{'APP.NAVIGATION.ALL-INAPP-NOTIFICATIONS'
<mat-list-item class = "mat-list-item-content" *ngIf="authService.hasPermission(authService.permissionEnum.ViewInAppNotificationPage)">
<a (click)="goToNotifications()">{{'NAV-BAR.INAPP-NOTIFICATIONS'
| translate}}</a>
</mat-list-item>
<mat-list-item class = "mat-list-item-content" *ngIf="authService.hasPermission(authService.permissionEnum.ViewInAppNotificationPage)">
<a (click)="readAllNotifications()">{{'NAV-BAR.READ-ALL-INAPP-NOTIFICATIONS'
| translate}}</a>
</mat-list-item>
</mat-nav-list>

View File

@ -8,4 +8,8 @@
.secondary-text {
color: rgba(0, 0, 0, 0.54);
}
.mat-list-item-content {
text-align: center
}
}

View File

@ -85,4 +85,12 @@ export class InAppNotificationListingDialogComponent extends BaseComponent imple
this.router.navigate(['/inapp-notifications']);
this.dialogRef.close();
}
readAllNotifications() {
this.inappNotificationService.readAll()
.pipe(takeUntil(this._destroyed))
.subscribe(
data => {},
);
}
}

View File

@ -22,7 +22,7 @@
</mat-form-field>
<div class="col-md-3 d-flex justify-content-center align-items-center">
<mat-slide-toggle [(ngModel)]="isActive" class="toggle col-auto w-100">
{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FILTER.SHOW-INACTIVE' | translate}}
{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FILTER.IS-ACTIVE' | translate}}
</mat-slide-toggle>
</div>
</div>

View File

@ -60,7 +60,14 @@ export class InAppNotificationListingFiltersComponent extends BaseComponent impl
return this.filter.trackingState ? this.filter.trackingState : null;
}
set trackingState(value: NotificationInAppTracking[]) {
this.filter.trackingState = value && value.length > 0 ? value : null;
// this.filter.trackingState = value && value.length > 0 ? value : null;
if (value[0] == 0){
this.filter.trackingState = [NotificationInAppTracking.Stored];
} else if(value[0] == 1) {
this.filter.trackingState = [NotificationInAppTracking.Delivered];
} else {
this.filter.trackingState = null;
}
this.filterChange.emit(this.filter);
}
}

View File

@ -78,16 +78,16 @@ export class InAppNotificationListingComponent extends BaseListingComponent<InAp
}, {
prop: nameof<InAppNotification>(x => x.subject),
sortable: true,
languageName: 'INAPP-NOTIFICATION-LISTING.FIELDS.SUBJECT'
languageName: 'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.SUBJECT'
}, {
prop: nameof<InAppNotification>(x => x.trackingState),
sortable: true,
languageName: 'INAPP-NOTIFICATION-LISTING.FIELDS.TRACKING-STATE',
languageName: 'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.TRACKING-STATE',
pipe: this.pipeService.getPipe<NotificationInAppTrackingTypePipe>(NotificationInAppTrackingTypePipe)
}, {
prop: nameof<InAppNotification>(x => x.createdAt),
sortable: true,
languageName: 'INAPP-NOTIFICATION-LISTING.FIELDS.CREATED-AT',
languageName: 'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.CREATED-AT',
pipe: this.pipeService.getPipe<DataTableDateTimeFormatPipe>(DataTableDateTimeFormatPipe).withFormat('short')
}]);
}
@ -105,6 +105,7 @@ export class InAppNotificationListingComponent extends BaseListingComponent<InAp
}
protected loadListing() : Observable<QueryResult<InAppNotification>> {
console.log(this.lookup);
return this.inappNotificationService.query(this.lookup);
}

View File

@ -32,6 +32,11 @@
<app-language (languageChange)="getLanguage($event)"></app-language>
</mat-menu>
</div>
<div class="col-auto" *ngIf="isAuthenticated() && authentication.hasPermission(authentication.permissionEnum.ViewInAppNotificationPage)">
<button class="col-auto" mat-icon-button matTooltip="{{'NAV-BAR.INAPP-NOTIFICATIONS' | translate}}" (click)="toggleInAppNotifications()">
<mat-icon [matBadge]="inAppNotificationCount" [matBadgeHidden]="inAppNotificationCount <= 0" matBadgeColor="warn">mail</mat-icon>
</button>
</div>
<!-- <app-search></app-search> -->

View File

@ -1,6 +1,6 @@
import { Location } from '@angular/common';
import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { MatMenuTrigger } from '@angular/material/menu';
import { Router } from '@angular/router';
import { AppRole } from '@app/core/common/enum/app-role';
@ -16,6 +16,10 @@ import { StartNewDmpDialogComponent } from '../dmp/new/start-new-dmp-dialogue/st
import { FaqDialogComponent } from '../faq/dialog/faq-dialog.component';
import { UserDialogComponent } from './user-dialog/user-dialog.component';
import { DATASETS_ROUTES, DMP_ROUTES, GENERAL_ROUTES } from '../sidebar/sidebar.component';
import { InAppNotificationListingDialogComponent } from '../inapp-notification/listing-dialog/inapp-notification-listing-dialog.component';
import { InAppNotificationService } from '@app/core/services/inapp-notification/inapp-notification.service';
import { timer } from 'rxjs';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
@Component({
selector: 'app-navbar',
@ -33,18 +37,22 @@ export class NavbarComponent extends BaseComponent implements OnInit {
currentRoute: string;
selectedLanguage: string;
private user: User;
inAppNotificationDialog: MatDialogRef<InAppNotificationListingDialogComponent> = null;
inAppNotificationCount = 0;
@Output() sidebarToggled: EventEmitter<any> = new EventEmitter();
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;
constructor(location: Location,
private element: ElementRef,
private router: Router,
private authentication: AuthService,
public authentication: AuthService,
private dialog: MatDialog,
private progressIndicationService: ProgressIndicationService,
private languageService: LanguageService,
private matomoService: MatomoService,
private sidenavService: SideNavService,
private inappNotificationService: InAppNotificationService,
private configurationService: ConfigurationService
) {
super();
this.location = location;
@ -75,6 +83,23 @@ export class NavbarComponent extends BaseComponent implements OnInit {
this.progressIndicationService.getProgressIndicationObservable().pipe(takeUntil(this._destroyed)).subscribe(x => {
setTimeout(() => { this.progressIndication = x; });
});
timer(2000, this.configurationService.inAppNotificationsCountInterval * 1000)
.pipe(takeUntil(this._destroyed))
.subscribe(x => {
this.countUnreadInappNotifications();
});
}
private countUnreadInappNotifications() {
if (this.isAuthenticated()) {
this.inappNotificationService.countUnread()
.pipe(takeUntil(this._destroyed))
.subscribe(
data => {
this.inAppNotificationCount = data;
},
);
}
}
public isAuthenticated(): boolean {
@ -273,4 +298,21 @@ export class NavbarComponent extends BaseComponent implements OnInit {
this.router.navigate(['/logout']);
}
toggleInAppNotifications() {
if (this.inAppNotificationDialog != null) {
this.inAppNotificationDialog.close();
} else {
this.countUnreadInappNotifications();
this.inAppNotificationDialog = this.dialog.open(InAppNotificationListingDialogComponent, {
position: {
top: '64px', right: '0px'
}
});
this.inAppNotificationDialog.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
this.countUnreadInappNotifications();
this.inAppNotificationDialog = null;
});
}
}
}

View File

@ -19,6 +19,7 @@
"clientSecret": null,
"grantType": "code"
},
"inAppNotificationsCountInterval": "30",
"notification_service": {
"enabled": true,
"address": "http://localhost:8086/api/"

View File

@ -314,7 +314,9 @@
"DMP": "DMP",
"GRANT": "Grant",
"PUBLISHED": "Published"
}
},
"INAPP-NOTIFICATIONS": "All Notifications",
"READ-ALL-INAPP-NOTIFICATIONS": "Read All"
},
"SIDE-BAR": {
"GENERAL": "GENERAL",
@ -1328,6 +1330,43 @@
}
},
"NOTIFICATION-SERVICE": {
"INAPP-NOTIFICATION-LISTING": {
"FIELDS": {
"SUBJECT": "Subject",
"TRACKING-STATE": "Tracking State",
"CREATED-AT": "Created",
"IS-ACTIVE": "Is Active"
},
"FILTER": {
"MORE-FILTERS": "More filters",
"TRACKING-STATE":"Tracking State",
"IS-ACTIVE": "Is Active",
"CHANNEL": "Channel",
"CANCEL": "Cancel",
"APPLY-FILTERS": "Apply filters"
},
"CONFIRM-DELETE-DIALOG": {
"MESSAGE": "Would you like to delete this Notification Template?",
"CONFIRM-BUTTON": "Yes, delete",
"CANCEL-BUTTON": "No"
},
"ACTIONS": {
"DELETE": "Delete",
"EDIT": "Edit"
},
"SUCCESSFUL-DELETE": "Successful Delete",
"UNSUCCESSFUL-DELETE": "This item could not be deleted."
},
"INAPP-NOTIFICATION-EDITOR": {
"FIELDS": {
},
"ACTIONS": {
"READ": "Read",
"CANCEL": "Cancel",
"DELETE": "Delete"
}
},
"NOTIFICATION-TEMPLATE-EDITOR": {
"NEW": "New Notification Template",
"FIELDS": {
@ -2275,6 +2314,10 @@
"DESCRIPTION-TEMPLATE-INVITATION": "Description Template Invitation",
"CONTACT-SUPPORT": "Contact Support",
"PUBLIC-CONTACT-SUPPORT": "Public Contact Support"
},
"NOTIFICATION-INAPP-TRACKING": {
"STORED": "Stored",
"DELIVERED": "Delivered"
}
},
"ADDRESEARCHERS-EDITOR": {