add in app notification navbar
This commit is contained in:
parent
1f92872158
commit
da657b667b
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -37,7 +37,6 @@ import { CommonFormattingModule } from '@common/formatting/common-formatting.mod
|
|||
// ],
|
||||
exports: [
|
||||
InAppNotificationListingComponent,
|
||||
InAppNotificationListingDialogComponent
|
||||
]
|
||||
})
|
||||
export class InAppNotificationModule { }
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -8,4 +8,8 @@
|
|||
.secondary-text {
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.mat-list-item-content {
|
||||
text-align: center
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 => {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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> -->
|
||||
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"clientSecret": null,
|
||||
"grantType": "code"
|
||||
},
|
||||
"inAppNotificationsCountInterval": "30",
|
||||
"notification_service": {
|
||||
"enabled": true,
|
||||
"address": "http://localhost:8086/api/"
|
||||
|
|
|
@ -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": {
|
||||
|
|
Loading…
Reference in New Issue