change in app notification listing
This commit is contained in:
parent
d0157fa0e5
commit
c7ea2ce2db
|
@ -283,11 +283,11 @@ const appRoutes: Routes = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'inapp-notifications',
|
path: 'mine-notifications',
|
||||||
loadChildren: () => import('./ui/inapp-notification/inapp-notification.module').then(m => m.InAppNotificationModule),
|
loadChildren: () => import('./ui/inapp-notification/mine-inapp-notification.module').then(m => m.MineInAppNotificationModule),
|
||||||
data: {
|
data: {
|
||||||
authContext: {
|
authContext: {
|
||||||
permissions: [AppPermission.ViewInAppNotificationPage]
|
permissions: [AppPermission.ViewMineInAppNotificationPage]
|
||||||
},
|
},
|
||||||
...BreadcrumbService.generateRouteDataConfiguration({
|
...BreadcrumbService.generateRouteDataConfiguration({
|
||||||
title: 'BREADCRUMBS.INAPP-NOTIFICATIONS'
|
title: 'BREADCRUMBS.INAPP-NOTIFICATIONS'
|
||||||
|
|
|
@ -34,7 +34,7 @@ export enum AppPermission {
|
||||||
ViewTenantPage = 'ViewTenantPage',
|
ViewTenantPage = 'ViewTenantPage',
|
||||||
ViewLanguagePage = "ViewLanguagePage",
|
ViewLanguagePage = "ViewLanguagePage",
|
||||||
ViewNotificationTemplatePage = "ViewNotificationTemplatePage",
|
ViewNotificationTemplatePage = "ViewNotificationTemplatePage",
|
||||||
ViewInAppNotificationPage = "ViewInAppNotificationPage",
|
ViewMineInAppNotificationPage = "ViewMineInAppNotificationPage",
|
||||||
|
|
||||||
//ReferenceType
|
//ReferenceType
|
||||||
BrowseReferenceType = "BrowseReferenceType",
|
BrowseReferenceType = "BrowseReferenceType",
|
||||||
|
|
|
@ -57,11 +57,11 @@ export class InAppNotificationService {
|
||||||
catchError((error: any) => throwError(error)));
|
catchError((error: any) => throwError(error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
readAll(): Observable<string> {
|
readAll(): Observable<boolean> {
|
||||||
const url = `${this.apiBase}/read-all`;
|
const url = `${this.apiBase}/read-all`;
|
||||||
|
|
||||||
return this.http
|
return this.http
|
||||||
.post<string>(url, {}).pipe(
|
.post<boolean>(url, {}).pipe(
|
||||||
catchError((error: any) => throwError(error)));
|
catchError((error: any) => throwError(error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
</mat-card>
|
</mat-card>
|
||||||
<div *ngIf="!isFromDialog" class="row editor-actions">
|
<div *ngIf="!isFromDialog" class="row editor-actions">
|
||||||
<div class="col"></div>
|
<div class="col"></div>
|
||||||
<div class="col-auto" *ngIf="!isDeleted && !isRead"><button mat-raised-button color="primary" (click)="markAsRead()" type="submit">{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-EDITOR.ACTIONS.READ' | translate}}</button></div>
|
|
||||||
<div class="col-auto" *ngIf="!this.isDeleted && !isNew"><button mat-raised-button color="primary" type="button" (click)="delete()">{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-EDITOR.ACTIONS.DELETE' | translate}}</button></div>
|
<div class="col-auto" *ngIf="!this.isDeleted && !isNew"><button mat-raised-button color="primary" type="button" (click)="delete()">{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-EDITOR.ACTIONS.DELETE' | translate}}</button></div>
|
||||||
<div class="col-auto"><button mat-raised-button color="primary" (click)="cancel()" type="button">{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-EDITOR.ACTIONS.CANCEL' | translate}}</button></div>
|
<div class="col-auto"><button mat-raised-button color="primary" (click)="cancel()" type="button">{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-EDITOR.ACTIONS.CANCEL' | translate}}</button></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -71,6 +71,8 @@ export class InAppNotificationEditorComponent extends BaseComponent implements O
|
||||||
this.inappNotification = data;
|
this.inappNotification = data;
|
||||||
this.isDeleted = this.inappNotification.isActive === IsActive.Inactive;
|
this.isDeleted = this.inappNotification.isActive === IsActive.Inactive;
|
||||||
this.isRead = this.inappNotification.trackingState === NotificationInAppTracking.Delivered;
|
this.isRead = this.inappNotification.trackingState === NotificationInAppTracking.Delivered;
|
||||||
|
|
||||||
|
if(!this.isDeleted && !this.isRead) this.markAsRead()
|
||||||
},
|
},
|
||||||
error => this.onCallbackError(error)
|
error => this.onCallbackError(error)
|
||||||
);
|
);
|
||||||
|
@ -115,12 +117,12 @@ export class InAppNotificationEditorComponent extends BaseComponent implements O
|
||||||
}
|
}
|
||||||
|
|
||||||
public cancel(): void {
|
public cancel(): void {
|
||||||
this.router.navigate(['/inapp-notifications']);
|
this.router.navigate(['/mine-notifications']);
|
||||||
}
|
}
|
||||||
|
|
||||||
onCallbackSuccess(data?: any): void {
|
onCallbackSuccess(data?: any): void {
|
||||||
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
||||||
this.router.navigate(['/inapp-notifications']);
|
this.router.navigate(['/mine-notifications']);
|
||||||
}
|
}
|
||||||
|
|
||||||
onCallbackError(errorResponse: HttpErrorResponse) {
|
onCallbackError(errorResponse: HttpErrorResponse) {
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
<span mat-line class="secondary-text">{{ inappNotification.createdAt | date : 'short'}}</span>
|
<span mat-line class="secondary-text">{{ inappNotification.createdAt | date : 'short'}}</span>
|
||||||
<mat-divider inset *ngIf="!last"></mat-divider>
|
<mat-divider inset *ngIf="!last"></mat-divider>
|
||||||
</a>
|
</a>
|
||||||
<mat-list-item class = "mat-list-item-content" *ngIf="authService.hasPermission(authService.permissionEnum.ViewInAppNotificationPage)">
|
<mat-list-item class = "mat-list-item-content" *ngIf="authService.hasPermission(authService.permissionEnum.ViewMineInAppNotificationPage)">
|
||||||
<a (click)="goToNotifications()">{{'NAV-BAR.INAPP-NOTIFICATIONS'
|
<a (click)="goToNotifications()">{{'NAV-BAR.INAPP-NOTIFICATIONS'
|
||||||
| translate}}</a>
|
| translate}}</a>
|
||||||
</mat-list-item>
|
</mat-list-item>
|
||||||
<mat-list-item class = "mat-list-item-content" *ngIf="authService.hasPermission(authService.permissionEnum.ViewInAppNotificationPage)">
|
<mat-list-item class = "mat-list-item-content" *ngIf="authService.hasPermission(authService.permissionEnum.ViewMineInAppNotificationPage)">
|
||||||
<a (click)="readAllNotifications()">{{'NAV-BAR.READ-ALL-INAPP-NOTIFICATIONS'
|
<a (click)="readAllNotifications()">{{'NAV-BAR.READ-ALL-INAPP-NOTIFICATIONS'
|
||||||
| translate}}</a>
|
| translate}}</a>
|
||||||
</mat-list-item>
|
</mat-list-item>
|
|
@ -14,16 +14,16 @@ import { takeUntil } from 'rxjs/operators';
|
||||||
import { nameof } from 'ts-simple-nameof';
|
import { nameof } from 'ts-simple-nameof';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-inapp-notification-listing-dialog',
|
selector: 'app-mine-inapp-notification-listing-dialog',
|
||||||
templateUrl: './inapp-notification-listing-dialog.component.html',
|
templateUrl: './mine-inapp-notification-listing-dialog.component.html',
|
||||||
styleUrls: ['./inapp-notification-listing-dialog.component.scss']
|
styleUrls: ['./mine-inapp-notification-listing-dialog.component.scss']
|
||||||
})
|
})
|
||||||
export class InAppNotificationListingDialogComponent extends BaseComponent implements OnInit {
|
export class MineInAppNotificationListingDialogComponent extends BaseComponent implements OnInit {
|
||||||
public inappNotifications = new Array<InAppNotification>();
|
public inappNotifications = new Array<InAppNotification>();
|
||||||
public notificationInAppTrackingEnum = NotificationInAppTracking;
|
public notificationInAppTrackingEnum = NotificationInAppTracking;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<InAppNotificationListingDialogComponent>,
|
public dialogRef: MatDialogRef<MineInAppNotificationListingDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public dialogData: any,
|
@Inject(MAT_DIALOG_DATA) public dialogData: any,
|
||||||
private inappNotificationService: InAppNotificationService,
|
private inappNotificationService: InAppNotificationService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
|
@ -68,21 +68,21 @@ export class InAppNotificationListingDialogComponent extends BaseComponent imple
|
||||||
.subscribe(
|
.subscribe(
|
||||||
data => {
|
data => {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
this.router.navigate(['/inapp-notifications/dialog/' + item.id]);
|
this.router.navigate(['/mine-notifications/dialog/' + item.id]);
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
this.router.navigate(['/inapp-notifications/dialog/' + item.id]);
|
this.router.navigate(['/mine-notifications/dialog/' + item.id]);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
this.router.navigate(['/inapp-notifications/dialog/' + item.id]);
|
this.router.navigate(['/mine-notifications/dialog/' + item.id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
goToNotifications() {
|
goToNotifications() {
|
||||||
this.router.navigate(['/inapp-notifications']);
|
this.router.navigate(['/mine-notifications']);
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
<div class="inapp-notification-listing-filters">
|
|
||||||
<mat-expansion-panel class="expansion-panel" [(expanded)]="panelExpanded" [disabled]="true">
|
|
||||||
<mat-expansion-panel-header collapsedHeight="auto" expandedHeight="auto">
|
|
||||||
<div class="row w-100">
|
|
||||||
<app-text-filter class="col-auto" [(value)]="filter.like" (valueChange)="onFilterChange()"></app-text-filter>
|
|
||||||
<div class="filter-actions col-auto ml-auto">
|
|
||||||
<button mat-button color="primary" (click)="panelExpanded = !panelExpanded" [disableRipple]="true">
|
|
||||||
{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FILTER.MORE-FILTERS' | translate}}
|
|
||||||
<mat-icon *ngIf="panelExpanded">keyboard_arrow_up</mat-icon>
|
|
||||||
<mat-icon *ngIf="!panelExpanded">keyboard_arrow_down</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-expansion-panel-header>
|
|
||||||
<div class="row">
|
|
||||||
<mat-form-field class="col-md-3">
|
|
||||||
<mat-label>{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FILTER.TRACKING-STATE' | translate}}</mat-label>
|
|
||||||
<mat-select [(ngModel)]="trackingState">
|
|
||||||
<mat-option *ngIf="trackingState !== null"></mat-option>
|
|
||||||
<mat-option *ngFor="let trackingState of trackingStates" [value]="trackingState">{{enumUtils.toNotificationInAppTrackingString(trackingState)}}</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</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.IS-ACTIVE' | translate}}
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-expansion-panel>
|
|
||||||
</div>
|
|
|
@ -1,22 +0,0 @@
|
||||||
.inapp-notification-listing-filters {
|
|
||||||
margin: 1em 0;
|
|
||||||
|
|
||||||
.filter-actions {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle {
|
|
||||||
font-weight: 400;
|
|
||||||
height: 49px;
|
|
||||||
min-height: 53.59px;
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 0.4em;
|
|
||||||
border: 1px solid #e0e0e0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .mat-form-field-wrapper {
|
|
||||||
padding-bottom: 0;
|
|
||||||
margin: 1em 0 !important;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges, OnChanges } from '@angular/core';
|
|
||||||
import { BaseComponent } from '@common/base/base.component';
|
|
||||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
|
||||||
import { NotificationInAppTracking } from '@app/core/common/enum/notification-inapp-tracking.enum';
|
|
||||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
|
||||||
import { InAppNotificationFilter } from '@app/core/query/inapp-notification.lookup';
|
|
||||||
@Component({
|
|
||||||
selector: 'app-inapp-notification-listing-filters',
|
|
||||||
templateUrl: './inapp-notification-listing-filters.component.html',
|
|
||||||
styleUrls: ['./inapp-notification-listing-filters.component.scss']
|
|
||||||
})
|
|
||||||
export class InAppNotificationListingFiltersComponent extends BaseComponent implements OnInit, OnChanges {
|
|
||||||
|
|
||||||
@Input() filter: InAppNotificationFilter;
|
|
||||||
@Output() filterChange = new EventEmitter<InAppNotificationFilter>();
|
|
||||||
panelExpanded = false;
|
|
||||||
trackingStates: NotificationInAppTracking[] = this.enumUtils.getEnumValues(NotificationInAppTracking);
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public enumUtils: EnumUtils
|
|
||||||
) { super(); }
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.panelExpanded = !this.areHiddenFieldsEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
|
||||||
if (changes['filter']) { this.panelExpanded = !this.areHiddenFieldsEmpty(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
onFilterChange() {
|
|
||||||
this.filterChange.emit(this.filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private areHiddenFieldsEmpty(): boolean {
|
|
||||||
return (!this.filter.isActive || this.filter.isActive.length === 0 || (this.filter.isActive.length === 1 && this.filter.isActive[0] === IsActive.Active));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Filter getters / setters
|
|
||||||
// Implement here any custom logic regarding how these fields are applied to the lookup.
|
|
||||||
//
|
|
||||||
get like(): string {
|
|
||||||
return this.filter.like;
|
|
||||||
}
|
|
||||||
set like(value: string) {
|
|
||||||
this.filter.like = value;
|
|
||||||
this.filterChange.emit(this.filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
get isActive(): boolean {
|
|
||||||
return this.filter.isActive ? this.filter.isActive.includes(IsActive.Inactive) : true;
|
|
||||||
}
|
|
||||||
set isActive(value: boolean) {
|
|
||||||
this.filter.isActive = value ? [IsActive.Active, IsActive.Inactive] : [IsActive.Active];
|
|
||||||
this.filterChange.emit(this.filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
get trackingState(): NotificationInAppTracking[] {
|
|
||||||
return this.filter.trackingState ? this.filter.trackingState : null;
|
|
||||||
}
|
|
||||||
set trackingState(value: NotificationInAppTracking[]) {
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<div class="d-flex align-items-center gap-1-rem">
|
||||||
|
|
||||||
|
<button mat-flat-button [matMenuTriggerFor]="filterMenu" #filterMenuTrigger="matMenuTrigger" (click)="updateFilters()" class="filter-button">
|
||||||
|
<mat-icon aria-hidden="false" [matBadgeHidden]="!appliedFilterCount" [matBadge]="appliedFilterCount" matBadgeColor="warn" matBadgeSize="small">filter_alt</mat-icon>
|
||||||
|
{{'COMMONS.LISTING-COMPONENT.SEARCH-FILTER-BTN' | translate}}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
<mat-menu #filterMenu>
|
||||||
|
<div class="p-3" (click)="$event?.stopPropagation?.()">
|
||||||
|
<div class="search-listing-filters-container">
|
||||||
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
|
<h4>{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FILTER.TITLE' | translate}}</h4>
|
||||||
|
<button color="accent" mat-button (click)="clearFilters()">
|
||||||
|
{{'COMMONS.LISTING-COMPONENT.CLEAR-ALL-FILTERS' | translate}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<mat-label>{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FILTER.TRACKING-STATE' | translate}}
|
||||||
|
<mat-select multiple [(ngModel)]="internalFilters.trackingState">
|
||||||
|
<mat-option *ngFor="let state of notificationInAppTrackingEnumValues" [value]="state">{{enumUtils.toNotificationInAppTrackingString(state)}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-end align-items-center mt-4 gap-1-rem">
|
||||||
|
<button mat-stroked-button color="primary" (click)="filterMenuTrigger?.closeMenu()">
|
||||||
|
{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FILTER.CANCEL' | translate}}
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button color="primary" (click)="filterMenuTrigger.closeMenu(); applyFilters();">
|
||||||
|
{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FILTER.APPLY-FILTERS' | translate}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mat-menu>
|
||||||
|
|
||||||
|
<app-expandable-search-field [(value)]=internalFilters.like (valueChange)="onSearchTermChange($event)" />
|
||||||
|
</div>
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
::ng-deep.mat-mdc-menu-panel {
|
||||||
|
max-width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host::ng-deep.mat-mdc-menu-content:not(:empty) {
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.filter-button{
|
||||||
|
padding-top: .6rem;
|
||||||
|
padding-bottom: .6rem;
|
||||||
|
// .mat-icon{
|
||||||
|
// font-size: 1.5em;
|
||||||
|
// width: 1.2em;
|
||||||
|
// height: 1.2em;
|
||||||
|
// }
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges, OnChanges } from '@angular/core';
|
||||||
|
import { BaseComponent } from '@common/base/base.component';
|
||||||
|
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||||
|
import { NotificationInAppTracking } from '@app/core/common/enum/notification-inapp-tracking.enum';
|
||||||
|
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||||
|
import { InAppNotificationFilter } from '@app/core/query/inapp-notification.lookup';
|
||||||
|
import { nameof } from 'ts-simple-nameof';
|
||||||
|
@Component({
|
||||||
|
selector: 'app-mine-inapp-notification-listing-filters',
|
||||||
|
templateUrl: './mine-inapp-notification-listing-filters.component.html',
|
||||||
|
styleUrls: ['./mine-inapp-notification-listing-filters.component.scss']
|
||||||
|
})
|
||||||
|
export class MineInAppNotificationListingFiltersComponent extends BaseComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
|
@Input() readonly filter: InAppNotificationFilter;
|
||||||
|
@Output() filterChange = new EventEmitter<InAppNotificationFilter>();
|
||||||
|
|
||||||
|
notificationInAppTrackingEnumValues = this.enumUtils.getEnumValues<NotificationInAppTracking>(NotificationInAppTracking);
|
||||||
|
|
||||||
|
// * State
|
||||||
|
internalFilters: InAppNotificationListingFilters = this._getEmptyFilters();
|
||||||
|
|
||||||
|
protected appliedFilterCount: number = 0;
|
||||||
|
constructor(
|
||||||
|
public enumUtils: EnumUtils,
|
||||||
|
) { super(); }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
|
const filterChange = changes[nameof<MineInAppNotificationListingFiltersComponent>(x => x.filter)]?.currentValue as InAppNotificationFilter;
|
||||||
|
if (filterChange) {
|
||||||
|
this.updateFilters()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onSearchTermChange(searchTerm: string): void {
|
||||||
|
this.applyFilters()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected updateFilters(): void {
|
||||||
|
this.internalFilters = this._parseToInternalFilters(this.filter);
|
||||||
|
this.appliedFilterCount = this._computeAppliedFilters(this.internalFilters);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected applyFilters(): void {
|
||||||
|
const { like, trackingState } = this.internalFilters ?? {}
|
||||||
|
this.filterChange.emit({
|
||||||
|
...this.filter,
|
||||||
|
like,
|
||||||
|
trackingState
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private _parseToInternalFilters(inputFilter: InAppNotificationFilter): InAppNotificationListingFilters {
|
||||||
|
if (!inputFilter) {
|
||||||
|
return this._getEmptyFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
let { like, trackingState } = inputFilter;
|
||||||
|
|
||||||
|
return {
|
||||||
|
like: like,
|
||||||
|
trackingState: trackingState
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getEmptyFilters(): InAppNotificationListingFilters {
|
||||||
|
return {
|
||||||
|
like: null,
|
||||||
|
trackingState: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _computeAppliedFilters(filters: InAppNotificationListingFilters): number {
|
||||||
|
let count = 0;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearFilters() {
|
||||||
|
this.internalFilters = this._getEmptyFilters();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface InAppNotificationListingFilters {
|
||||||
|
like: string;
|
||||||
|
trackingState: NotificationInAppTracking[];
|
||||||
|
}
|
|
@ -1,52 +0,0 @@
|
||||||
import { Serializable } from '@common/types/json/serializable';
|
|
||||||
import { Lookup } from '@common/model/lookup';
|
|
||||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
|
||||||
import { InAppNotification } from '@app/core/model/inapp-notification/inapp-notification.model';
|
|
||||||
import { InAppNotificationLookup } from '@app/core/query/inapp-notification.lookup';
|
|
||||||
import { UserSettingsInformation, UserSettingsLookupBuilder } from '@app/core/model/user-settings/user-settings.model';
|
|
||||||
import { nameof } from 'ts-simple-nameof';
|
|
||||||
|
|
||||||
export class InAppNotificationListingUserSettings implements Serializable<InAppNotificationListingUserSettings>, UserSettingsLookupBuilder<InAppNotificationLookup> {
|
|
||||||
|
|
||||||
private like: string;
|
|
||||||
private isActive: IsActive[] = [IsActive.Active];
|
|
||||||
private order: Lookup.Ordering = { items: [nameof<InAppNotification>(x => x.createdAt)] };
|
|
||||||
private project: Lookup.FieldDirectives = {
|
|
||||||
fields: [
|
|
||||||
nameof<InAppNotification>(x => x.id),
|
|
||||||
nameof<InAppNotification>(x => x.subject),
|
|
||||||
nameof<InAppNotification>(x => x.trackingState),
|
|
||||||
nameof<InAppNotification>(x => x.createdAt)
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
static getUserSettingsInformation(): UserSettingsInformation<InAppNotificationListingUserSettings> {
|
|
||||||
return {
|
|
||||||
key: 'InAppNotificationListingUserSettings',
|
|
||||||
type: InAppNotificationListingUserSettings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public fromJSONObject(item: any): InAppNotificationListingUserSettings {
|
|
||||||
this.like = item.like;
|
|
||||||
this.isActive = item.isActive;
|
|
||||||
this.order = item.order;
|
|
||||||
this.project = item.project;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public update(lookup: InAppNotificationLookup) {
|
|
||||||
this.like = lookup.like;
|
|
||||||
this.isActive = lookup.isActive;
|
|
||||||
this.order = lookup.order;
|
|
||||||
this.project = lookup.project;
|
|
||||||
}
|
|
||||||
|
|
||||||
public apply(lookup: InAppNotificationLookup): InAppNotificationLookup {
|
|
||||||
lookup.like = this.like;
|
|
||||||
lookup.isActive = this.isActive;
|
|
||||||
lookup.order = this.order;
|
|
||||||
lookup.project = this.project;
|
|
||||||
return lookup;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
<div class="row inapp-notification-listing">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="row page-title">
|
|
||||||
<div class="col-auto pl-5 pr-0 align-self-center">
|
|
||||||
<i class="fa fa-2x fa-envelope-open-o accent-color"></i>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="col-auto ml-auto mt-3 align-self-center">
|
|
||||||
<button mat-raised-button color="accent" *ngIf="authService.hasAnyPermission([authService.permissionEnum.EditDocument, authService.permissionEnum.DeferredAffiliation])" [routerLink]=" ['./new'] ">
|
|
||||||
<mat-icon class="mb-1 mr-2">add</mat-icon>{{'COMMONS.ACTIONS.NEW' | translate}}
|
|
||||||
</button>
|
|
||||||
</div> -->
|
|
||||||
<div class="col-auto p-0 user-settings-selector">
|
|
||||||
<app-user-settings-selector [key]="userSettingsKey" [lookup]="lookup" (onSettingSelected)="changeSetting($event)" [autoSelectUserSettings]="autoSelectUserSettings"></app-user-settings-selector>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row toggle-row">
|
|
||||||
<div class="col-auto align-self-center view-mode-toggle-container">
|
|
||||||
<button mat-icon-button class="preview-btn" [ngClass]="{'preview-btn-active': isPreviewList}" (click)="togglePreviewMode(true)" matTooltip="{{'APP.DOCUMENT-LISTING.PREVIEW.LIST' | translate}}">
|
|
||||||
<mat-icon>view_module</mat-icon>
|
|
||||||
</button>
|
|
||||||
<button mat-icon-button class="preview-btn" [ngClass]="{'preview-btn-active': !isPreviewList}" (click)="togglePreviewMode(false)" matTooltip="{{'APP.DOCUMENT-LISTING.PREVIEW.TABLE' | translate}}">
|
|
||||||
<mat-icon>table_chart</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12 filter-row">
|
|
||||||
<app-inapp-notification-listing-filters [(filter)]="lookup" (filterChange)="filterChanged($event)"></app-inapp-notification-listing-filters>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12 col-center-align">
|
|
||||||
<app-hybrid-listing [rows]="gridRows" [columns]="gridColumns" [visibleColumns]="visibleColumns" [count]="totalElements" [offset]="currentPageNumber" [limit]="lookup.page.size" [defaultSort]="lookup.order?.items" [externalSorting]="true" (rowActivated)="onRowActivated($event)" (pageLoad)="onPageLoad($event)" (columnSort)="onColumnSort($event)" (columnsChanged)="onColumnsChanged($event)">
|
|
||||||
</app-hybrid-listing>
|
|
||||||
|
|
||||||
<ng-template #readColumnTemplate ngx-datatable-cell-template let-row="row">
|
|
||||||
<mat-icon *ngIf="row.trackingState === notificationInAppTrackingEnum.Delivered" mat-list-icon>drafts</mat-icon>
|
|
||||||
<mat-icon *ngIf="row.trackingState === notificationInAppTrackingEnum.Stored" mat-list-icon>mail</mat-icon>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,28 +0,0 @@
|
||||||
.inapp-notification-listing {
|
|
||||||
// padding-top: 1em;
|
|
||||||
|
|
||||||
.toggle-row {
|
|
||||||
min-height: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-btn {
|
|
||||||
color: rgb(193, 202, 211);
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-btn-active {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.view-mode-toggle-container {
|
|
||||||
padding-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mat-fab-bottom-right {
|
|
||||||
top: auto !important;
|
|
||||||
right: 20px !important;
|
|
||||||
bottom: 10px !important;
|
|
||||||
left: auto !important;
|
|
||||||
position: fixed !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
import { Component, OnInit, TemplateRef, ViewChild, EventEmitter, Output, Input } from '@angular/core';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
|
||||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
|
||||||
import { BaseListingComponent } from '@common/base/base-listing-component';
|
|
||||||
import { PipeService } from '@common/formatting/pipe.service';
|
|
||||||
import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe';
|
|
||||||
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
|
||||||
import { ColumnsChangedEvent, PageLoadEvent } from '@common/modules/hybrid-listing/hybrid-listing.component';
|
|
||||||
import { UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
|
||||||
import { InAppNotification } from '@app/core/model/inapp-notification/inapp-notification.model';
|
|
||||||
import { InAppNotificationLookup } from '@app/core/query/inapp-notification.lookup';
|
|
||||||
import { InAppNotificationService } from '@app/core/services/inapp-notification/inapp-notification.service';
|
|
||||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
|
||||||
import { nameof } from 'ts-simple-nameof';
|
|
||||||
import { NotificationInAppTrackingTypePipe } from '@common/formatting/pipes/notification-inapp-tracking-type.pipe';
|
|
||||||
import { NotificationInAppTracking } from '@app/core/common/enum/notification-inapp-tracking.enum';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { QueryResult } from '@common/model/query-result';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-inapp-notification-listing',
|
|
||||||
templateUrl: './inapp-notification-listing.component.html',
|
|
||||||
styleUrls: ['./inapp-notification-listing.component.scss']
|
|
||||||
})
|
|
||||||
export class InAppNotificationListingComponent extends BaseListingComponent<InAppNotification, InAppNotificationLookup> implements OnInit {
|
|
||||||
@ViewChild('readColumnTemplate', { static: true }) readColumnTemplate: TemplateRef<any>;
|
|
||||||
@Input() isPreviewList;
|
|
||||||
@Output() previewModeChange = new EventEmitter<boolean>();
|
|
||||||
|
|
||||||
userSettingsKey = { key: 'InAppNotificationListingUserSettings' };
|
|
||||||
public notificationInAppTrackingEnum = NotificationInAppTracking;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
protected router: Router,
|
|
||||||
protected route: ActivatedRoute,
|
|
||||||
protected uiNotificationService: UiNotificationService,
|
|
||||||
protected httpErrorHandlingService: HttpErrorHandlingService,
|
|
||||||
protected queryParamsService: QueryParamsService,
|
|
||||||
private inappNotificationService: InAppNotificationService,
|
|
||||||
public authService: AuthService,
|
|
||||||
private pipeService: PipeService,
|
|
||||||
) {
|
|
||||||
super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService);
|
|
||||||
// Lookup setup
|
|
||||||
// Default lookup values are defined in the user settings class.
|
|
||||||
this.lookup = this.initializeLookup();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
super.ngOnInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected initializeLookup(): InAppNotificationLookup {
|
|
||||||
const lookup = new InAppNotificationLookup();
|
|
||||||
lookup.metadata = { countAll: true };
|
|
||||||
lookup.page = { offset: 10, size: 10 };
|
|
||||||
|
|
||||||
lookup.isActive = [IsActive.Active];
|
|
||||||
lookup.order = { items: [nameof<InAppNotification>(x => x.updatedAt)] };
|
|
||||||
lookup.project = {
|
|
||||||
fields: [
|
|
||||||
nameof<InAppNotification>(x => x.id),
|
|
||||||
nameof<InAppNotification>(x => x.subject),
|
|
||||||
nameof<InAppNotification>(x => x.trackingState),
|
|
||||||
nameof<InAppNotification>(x => x.createdAt)
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
return lookup;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected setupColumns() {
|
|
||||||
this.gridColumns.push(...[{
|
|
||||||
cellTemplate: this.readColumnTemplate,
|
|
||||||
alwaysShown: true
|
|
||||||
}, {
|
|
||||||
prop: nameof<InAppNotification>(x => x.subject),
|
|
||||||
sortable: true,
|
|
||||||
languageName: 'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.SUBJECT'
|
|
||||||
}, {
|
|
||||||
prop: nameof<InAppNotification>(x => x.trackingState),
|
|
||||||
sortable: true,
|
|
||||||
languageName: 'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.TRACKING-STATE',
|
|
||||||
pipe: this.pipeService.getPipe<NotificationInAppTrackingTypePipe>(NotificationInAppTrackingTypePipe)
|
|
||||||
}, {
|
|
||||||
prop: nameof<InAppNotification>(x => x.createdAt),
|
|
||||||
sortable: true,
|
|
||||||
languageName: 'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.CREATED-AT',
|
|
||||||
pipe: this.pipeService.getPipe<DataTableDateTimeFormatPipe>(DataTableDateTimeFormatPipe).withFormat('short')
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
|
|
||||||
onColumnsChanged(event: ColumnsChangedEvent) {
|
|
||||||
// Here are defined the projection fields that always requested from the api.
|
|
||||||
this.lookup.project = {
|
|
||||||
fields: [
|
|
||||||
nameof<InAppNotification>(x => x.id),
|
|
||||||
nameof<InAppNotification>(x => x.trackingState),
|
|
||||||
...event.properties.filter(x => x).map(x => x.toString())
|
|
||||||
]
|
|
||||||
};
|
|
||||||
this.onPageLoad({ offset: 0 } as PageLoadEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected loadListing() : Observable<QueryResult<InAppNotification>> {
|
|
||||||
console.log(this.lookup);
|
|
||||||
return this.inappNotificationService.query(this.lookup);
|
|
||||||
}
|
|
||||||
|
|
||||||
togglePreviewMode(value: boolean) {
|
|
||||||
this.isPreviewList = value;
|
|
||||||
this.previewModeChange.emit(value);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
<div class="row inapp-notification-listing">
|
||||||
|
<div class="col-md-8 offset-md-2">
|
||||||
|
|
||||||
|
<div class="row mb-4 mt-3">
|
||||||
|
<div class="col">
|
||||||
|
<h4>{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.TITLE' | translate}}</h4>
|
||||||
|
<app-navigation-breadcrumb />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<app-hybrid-listing [rows]="gridRows" [columns]="gridColumns" [visibleColumns]="visibleColumns"
|
||||||
|
[count]="totalElements" [offset]="currentPageNumber" [limit]="lookup.page.size"
|
||||||
|
[defaultSort]="lookup.order?.items" [externalSorting]="true" (rowActivated)="onRowActivated($event)"
|
||||||
|
(pageLoad)="alterPage($event)" (columnSort)="onColumnSort($event)"
|
||||||
|
(columnsChanged)="onColumnsChanged($event)" [listItemTemplate]="listItemTemplate">
|
||||||
|
|
||||||
|
<app-mine-inapp-notification-listing-filters hybrid-listing-filters [(filter)]="lookup"
|
||||||
|
(filterChange)="filterChanged($event)" />
|
||||||
|
|
||||||
|
<app-user-settings-picker [key]="userSettingsKey" [userPreference]="lookup"
|
||||||
|
(onSettingSelected)="changeSetting($event)" [autoSelectUserSettings]="autoSelectUserSettings"
|
||||||
|
user-preference-settings />
|
||||||
|
</app-hybrid-listing>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template #listItemTemplate let-item="item" let-isColumnSelected="isColumnSelected">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="d-flex align-items-center p-3 gap-1-rem">
|
||||||
|
<div class="row">
|
||||||
|
<ng-container *ngIf="isColumnSelected('trackingState')">
|
||||||
|
<a class="buttonLinkClass" [routerLink]="'./' + item?.id" class="col-12"
|
||||||
|
(click)="$event.stopPropagation()">{{item?.trackingState | nullifyValue}}</a>
|
||||||
|
<br />
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="isColumnSelected('createdAt')">
|
||||||
|
<span class="col-12">
|
||||||
|
{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.CREATED-AT' | translate}}:
|
||||||
|
<small>
|
||||||
|
{{item?.createdAt | dateTimeFormatter : 'short' | nullifyValue}}
|
||||||
|
</small>
|
||||||
|
</span>
|
||||||
|
<br>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #actions let-row="row" let-item>
|
||||||
|
<div class="row" (click)="$event.stopPropagation()">
|
||||||
|
<div class="col-auto">
|
||||||
|
<button mat-icon-button [matMenuTriggerFor]="actionsMenu">
|
||||||
|
<mat-icon>more_horiz</mat-icon>
|
||||||
|
</button>
|
||||||
|
<mat-menu #actionsMenu="matMenu">
|
||||||
|
<button mat-menu-item (click)="deleteType(row.id)">
|
||||||
|
<mat-icon>delete</mat-icon>
|
||||||
|
{{'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.ACTIONS.DELETE' | translate}}
|
||||||
|
</button>
|
||||||
|
</mat-menu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
|
@ -0,0 +1,61 @@
|
||||||
|
.inapp-notification-listing {
|
||||||
|
margin-top: 1.3rem;
|
||||||
|
margin-left: 1rem;
|
||||||
|
margin-right: 2rem;
|
||||||
|
|
||||||
|
.mat-header-row{
|
||||||
|
background: #f3f5f8;
|
||||||
|
}
|
||||||
|
.mat-card {
|
||||||
|
margin: 16px 0;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-row {
|
||||||
|
cursor: pointer;
|
||||||
|
min-height: 4.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-row:hover {
|
||||||
|
background-color: #eef5f6;
|
||||||
|
}
|
||||||
|
.mat-fab-bottom-right {
|
||||||
|
float: right;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.create-btn {
|
||||||
|
border-radius: 30px;
|
||||||
|
background-color: var(--secondary-color);
|
||||||
|
padding-left: 2em;
|
||||||
|
padding-right: 2em;
|
||||||
|
// color: #000;
|
||||||
|
|
||||||
|
.button-text{
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlt-btn {
|
||||||
|
color: rgba(0, 0, 0, 0.54);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-chip{
|
||||||
|
|
||||||
|
border-radius: 20px;
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-right: 1em;
|
||||||
|
padding-top: 0.2em;
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-chip-finalized{
|
||||||
|
color: #568b5a;
|
||||||
|
background: #9dd1a1 0% 0% no-repeat padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-chip-draft{
|
||||||
|
color: #00c4ff;
|
||||||
|
background: #d3f5ff 0% 0% no-repeat padding-box;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
import { Component, OnInit, TemplateRef, ViewChild, EventEmitter, Output, Input } from '@angular/core';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||||
|
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||||
|
import { BaseListingComponent } from '@common/base/base-listing-component';
|
||||||
|
import { PipeService } from '@common/formatting/pipe.service';
|
||||||
|
import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe';
|
||||||
|
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||||
|
import { ColumnDefinition, ColumnsChangedEvent, HybridListingComponent, PageLoadEvent } from '@common/modules/hybrid-listing/hybrid-listing.component';
|
||||||
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||||
|
import { InAppNotification } from '@app/core/model/inapp-notification/inapp-notification.model';
|
||||||
|
import { InAppNotificationLookup } from '@app/core/query/inapp-notification.lookup';
|
||||||
|
import { InAppNotificationService } from '@app/core/services/inapp-notification/inapp-notification.service';
|
||||||
|
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||||
|
import { nameof } from 'ts-simple-nameof';
|
||||||
|
import { NotificationInAppTrackingTypePipe } from '@common/formatting/pipes/notification-inapp-tracking-type.pipe';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { QueryResult } from '@common/model/query-result';
|
||||||
|
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { Guid } from '@common/types/guid';
|
||||||
|
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-mine-inapp-notification-listing',
|
||||||
|
templateUrl: './mine-inapp-notification-listing.component.html',
|
||||||
|
styleUrls: ['./mine-inapp-notification-listing.component.scss']
|
||||||
|
})
|
||||||
|
export class MineInAppNotificationListingComponent extends BaseListingComponent<InAppNotification, InAppNotificationLookup> implements OnInit {
|
||||||
|
publish = false;
|
||||||
|
userSettingsKey = { key: 'InAppNotificationListingUserSettings' };
|
||||||
|
propertiesAvailableForOrder: ColumnDefinition[];
|
||||||
|
|
||||||
|
@ViewChild('actions', { static: true }) actions?: TemplateRef<any>;
|
||||||
|
@ViewChild(HybridListingComponent, { static: true }) hybridListingComponent: HybridListingComponent;
|
||||||
|
|
||||||
|
private readonly lookupFields: string[] = [
|
||||||
|
nameof<InAppNotification>(x => x.id),
|
||||||
|
nameof<InAppNotification>(x => x.subject),
|
||||||
|
nameof<InAppNotification>(x => x.trackingState),
|
||||||
|
nameof<InAppNotification>(x => x.createdAt),
|
||||||
|
nameof<InAppNotification>(x => x.isActive)
|
||||||
|
];
|
||||||
|
|
||||||
|
rowIdentity = x => x.id;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected router: Router,
|
||||||
|
protected route: ActivatedRoute,
|
||||||
|
protected uiNotificationService: UiNotificationService,
|
||||||
|
protected httpErrorHandlingService: HttpErrorHandlingService,
|
||||||
|
protected queryParamsService: QueryParamsService,
|
||||||
|
private inAppNotificationService: InAppNotificationService,
|
||||||
|
public authService: AuthService,
|
||||||
|
private pipeService: PipeService,
|
||||||
|
public enumUtils: EnumUtils,
|
||||||
|
private language: TranslateService,
|
||||||
|
private dialog: MatDialog
|
||||||
|
) {
|
||||||
|
super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService);
|
||||||
|
// Lookup setup
|
||||||
|
// Default lookup values are defined in the user settings class.
|
||||||
|
this.lookup = this.initializeLookup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
super.ngOnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected initializeLookup(): InAppNotificationLookup {
|
||||||
|
const lookup = new InAppNotificationLookup();
|
||||||
|
lookup.metadata = { countAll: true };
|
||||||
|
lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE };
|
||||||
|
lookup.isActive = [IsActive.Active];
|
||||||
|
lookup.order = { items: [this.toDescSortField(nameof<InAppNotification>(x => x.createdAt))] };
|
||||||
|
this.updateOrderUiFields(lookup.order);
|
||||||
|
|
||||||
|
lookup.project = {
|
||||||
|
fields: this.lookupFields
|
||||||
|
};
|
||||||
|
|
||||||
|
return lookup;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected setupColumns() {
|
||||||
|
this.gridColumns.push(...[{
|
||||||
|
prop: nameof<InAppNotification>(x => x.subject),
|
||||||
|
sortable: true,
|
||||||
|
languageName: 'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.SUBJECT'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: nameof<InAppNotification>(x => x.trackingState),
|
||||||
|
sortable: true,
|
||||||
|
languageName: 'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.TRACKING-STATE',
|
||||||
|
pipe: this.pipeService.getPipe<NotificationInAppTrackingTypePipe>(NotificationInAppTrackingTypePipe)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: nameof<InAppNotification>(x => x.createdAt),
|
||||||
|
sortable: true,
|
||||||
|
languageName: 'NOTIFICATION-SERVICE.INAPP-NOTIFICATION-LISTING.FIELDS.CREATED-AT',
|
||||||
|
pipe: this.pipeService.getPipe<DataTableDateTimeFormatPipe>(DataTableDateTimeFormatPipe).withFormat('short')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
alwaysShown: true,
|
||||||
|
cellTemplate: this.actions,
|
||||||
|
maxWidth: 120
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
this.propertiesAvailableForOrder = this.gridColumns.filter(x => x.sortable);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Listing Component functions
|
||||||
|
//
|
||||||
|
onColumnsChanged(event: ColumnsChangedEvent) {
|
||||||
|
super.onColumnsChanged(event);
|
||||||
|
this.onColumnsChangedInternal(event.properties.map(x => x.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private onColumnsChangedInternal(columns: string[]) {
|
||||||
|
// Here are defined the projection fields that always requested from the api.
|
||||||
|
const fields = new Set(this.lookupFields);
|
||||||
|
this.gridColumns.map(x => x.prop)
|
||||||
|
.filter(x => !columns?.includes(x as string))
|
||||||
|
.forEach(item => {
|
||||||
|
fields.delete(item as string)
|
||||||
|
});
|
||||||
|
this.lookup.project = { fields: [...fields] };
|
||||||
|
this.onPageLoad({ offset: 0 } as PageLoadEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected loadListing(): Observable<QueryResult<InAppNotification>> {
|
||||||
|
return this.inAppNotificationService.query(this.lookup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteType(id: Guid) {
|
||||||
|
if (id) {
|
||||||
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||||
|
data: {
|
||||||
|
isDeleteConfirmation: true,
|
||||||
|
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
||||||
|
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
||||||
|
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||||
|
if (result) {
|
||||||
|
this.inAppNotificationService.delete(id).pipe(takeUntil(this._destroyed))
|
||||||
|
.subscribe(
|
||||||
|
complete => this.onCallbackSuccess(),
|
||||||
|
error => this.onCallbackError(error)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onCallbackSuccess(): void {
|
||||||
|
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success);
|
||||||
|
this.ngOnInit();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
import { AuthGuard } from '@app/core/auth-guard.service';
|
import { AuthGuard } from '@app/core/auth-guard.service';
|
||||||
import { InAppNotificationListingComponent } from './listing/inapp-notification-listing.component';
|
import { MineInAppNotificationListingComponent } from './listing/mine-inapp-notification-listing.component';
|
||||||
import { InAppNotificationEditorComponent } from './editor/inapp-notification-editor.component';
|
import { InAppNotificationEditorComponent } from './editor/inapp-notification-editor.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: InAppNotificationListingComponent,
|
component: MineInAppNotificationListingComponent,
|
||||||
data: {
|
data: {
|
||||||
},
|
},
|
||||||
canActivate: [AuthGuard]
|
canActivate: [AuthGuard]
|
||||||
|
@ -32,4 +32,4 @@ const routes: Routes = [
|
||||||
imports: [RouterModule.forChild(routes)],
|
imports: [RouterModule.forChild(routes)],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule]
|
||||||
})
|
})
|
||||||
export class InAppNotificationRoutingModule { }
|
export class MineInAppNotificationRoutingModule { }
|
|
@ -4,15 +4,12 @@ import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/co
|
||||||
import { TextFilterModule } from '@common/modules/text-filter/text-filter.module';
|
import { TextFilterModule } from '@common/modules/text-filter/text-filter.module';
|
||||||
import { UserSettingsModule } from '@common/modules/user-settings/user-settings.module';
|
import { UserSettingsModule } from '@common/modules/user-settings/user-settings.module';
|
||||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||||
import { InAppNotificationRoutingModule } from './inapp-notification-routing.module';
|
import { MineInAppNotificationRoutingModule } from './mine-inapp-notification-routing.module';
|
||||||
import { InAppNotificationListingComponent } from './listing/inapp-notification-listing.component';
|
import { MineInAppNotificationListingComponent } from './listing/mine-inapp-notification-listing.component';
|
||||||
import { HybridListingModule } from '@common/modules/hybrid-listing/hybrid-listing.module';
|
import { HybridListingModule } from '@common/modules/hybrid-listing/hybrid-listing.module';
|
||||||
import { InAppNotificationEditorComponent } from './editor/inapp-notification-editor.component';
|
import { InAppNotificationEditorComponent } from './editor/inapp-notification-editor.component';
|
||||||
import { InAppNotificationListingFiltersComponent } from './listing/filters/inapp-notification-listing-filters.component';
|
import { MineInAppNotificationListingFiltersComponent } from './listing/filters/mine-inapp-notification-listing-filters.component';
|
||||||
import { InAppNotificationListingDialogComponent } from './listing-dialog/inapp-notification-listing-dialog.component';
|
import { MineInAppNotificationListingDialogComponent } from './listing-dialog/mine-inapp-notification-listing-dialog.component';
|
||||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
|
||||||
import { NotificationInAppTrackingTypePipe } from '@common/formatting/pipes/notification-inapp-tracking-type.pipe';
|
|
||||||
import { DatePipe } from '@angular/common';
|
|
||||||
import { CommonFormattingModule } from '@common/formatting/common-formatting.module';
|
import { CommonFormattingModule } from '@common/formatting/common-formatting.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -22,21 +19,18 @@ import { CommonFormattingModule } from '@common/formatting/common-formatting.mod
|
||||||
ConfirmationDialogModule,
|
ConfirmationDialogModule,
|
||||||
HybridListingModule,
|
HybridListingModule,
|
||||||
TextFilterModule,
|
TextFilterModule,
|
||||||
InAppNotificationRoutingModule,
|
MineInAppNotificationRoutingModule,
|
||||||
UserSettingsModule,
|
UserSettingsModule,
|
||||||
CommonFormattingModule
|
CommonFormattingModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
InAppNotificationListingComponent,
|
MineInAppNotificationListingComponent,
|
||||||
InAppNotificationEditorComponent,
|
InAppNotificationEditorComponent,
|
||||||
InAppNotificationListingFiltersComponent,
|
MineInAppNotificationListingFiltersComponent,
|
||||||
InAppNotificationListingDialogComponent
|
MineInAppNotificationListingDialogComponent
|
||||||
],
|
],
|
||||||
// entryComponents: [
|
|
||||||
// InAppNotificationListingDialogComponent
|
|
||||||
// ],
|
|
||||||
exports: [
|
exports: [
|
||||||
InAppNotificationListingComponent,
|
MineInAppNotificationListingComponent,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class InAppNotificationModule { }
|
export class MineInAppNotificationModule { }
|
|
@ -32,7 +32,7 @@
|
||||||
<app-language (languageChange)="getLanguage($event)"></app-language>
|
<app-language (languageChange)="getLanguage($event)"></app-language>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto" *ngIf="isAuthenticated() && authentication.hasPermission(authentication.permissionEnum.ViewInAppNotificationPage)">
|
<div class="col-auto" *ngIf="isAuthenticated() && authentication.hasPermission(authentication.permissionEnum.ViewMineInAppNotificationPage)">
|
||||||
<button class="col-auto" mat-icon-button matTooltip="{{'NAV-BAR.INAPP-NOTIFICATIONS' | translate}}" (click)="toggleInAppNotifications()">
|
<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>
|
<mat-icon [matBadge]="inAppNotificationCount" [matBadgeHidden]="inAppNotificationCount <= 0" matBadgeColor="warn">mail</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { StartNewDmpDialogComponent } from '../dmp/new/start-new-dmp-dialogue/st
|
||||||
import { FaqDialogComponent } from '../faq/dialog/faq-dialog.component';
|
import { FaqDialogComponent } from '../faq/dialog/faq-dialog.component';
|
||||||
import { UserDialogComponent } from './user-dialog/user-dialog.component';
|
import { UserDialogComponent } from './user-dialog/user-dialog.component';
|
||||||
import { DATASETS_ROUTES, DMP_ROUTES, GENERAL_ROUTES } from '../sidebar/sidebar.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 { MineInAppNotificationListingDialogComponent } from '../inapp-notification/listing-dialog/mine-inapp-notification-listing-dialog.component';
|
||||||
import { InAppNotificationService } from '@app/core/services/inapp-notification/inapp-notification.service';
|
import { InAppNotificationService } from '@app/core/services/inapp-notification/inapp-notification.service';
|
||||||
import { timer } from 'rxjs';
|
import { timer } from 'rxjs';
|
||||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||||
|
@ -37,7 +37,7 @@ export class NavbarComponent extends BaseComponent implements OnInit {
|
||||||
currentRoute: string;
|
currentRoute: string;
|
||||||
selectedLanguage: string;
|
selectedLanguage: string;
|
||||||
private user: User;
|
private user: User;
|
||||||
inAppNotificationDialog: MatDialogRef<InAppNotificationListingDialogComponent> = null;
|
inAppNotificationDialog: MatDialogRef<MineInAppNotificationListingDialogComponent> = null;
|
||||||
inAppNotificationCount = 0;
|
inAppNotificationCount = 0;
|
||||||
@Output() sidebarToggled: EventEmitter<any> = new EventEmitter();
|
@Output() sidebarToggled: EventEmitter<any> = new EventEmitter();
|
||||||
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;
|
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;
|
||||||
|
@ -303,7 +303,7 @@ export class NavbarComponent extends BaseComponent implements OnInit {
|
||||||
this.inAppNotificationDialog.close();
|
this.inAppNotificationDialog.close();
|
||||||
} else {
|
} else {
|
||||||
this.countUnreadInappNotifications();
|
this.countUnreadInappNotifications();
|
||||||
this.inAppNotificationDialog = this.dialog.open(InAppNotificationListingDialogComponent, {
|
this.inAppNotificationDialog = this.dialog.open(MineInAppNotificationListingDialogComponent, {
|
||||||
position: {
|
position: {
|
||||||
top: '64px', right: '0px'
|
top: '64px', right: '0px'
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,7 +254,8 @@
|
||||||
"LANGUAGES": "Languages",
|
"LANGUAGES": "Languages",
|
||||||
"NEW-LANGUAGE": "New",
|
"NEW-LANGUAGE": "New",
|
||||||
"EDIT-LANGUAGE": "Edit",
|
"EDIT-LANGUAGE": "Edit",
|
||||||
"NOTIFICATION-TEMPLATES": "Notification Templates"
|
"NOTIFICATION-TEMPLATES": "Notification Templates",
|
||||||
|
"INAPP-NOTIFICATIONS":"Notifications"
|
||||||
},
|
},
|
||||||
"COOKIE": {
|
"COOKIE": {
|
||||||
"MESSAGE": "This website uses cookies to enhance the user experience.",
|
"MESSAGE": "This website uses cookies to enhance the user experience.",
|
||||||
|
@ -1331,17 +1332,16 @@
|
||||||
},
|
},
|
||||||
"NOTIFICATION-SERVICE": {
|
"NOTIFICATION-SERVICE": {
|
||||||
"INAPP-NOTIFICATION-LISTING": {
|
"INAPP-NOTIFICATION-LISTING": {
|
||||||
|
"TITLE": "Notifications",
|
||||||
"FIELDS": {
|
"FIELDS": {
|
||||||
"SUBJECT": "Subject",
|
"SUBJECT": "Subject",
|
||||||
"TRACKING-STATE": "Tracking State",
|
"TRACKING-STATE": "State",
|
||||||
"CREATED-AT": "Created",
|
"CREATED-AT": "Created"
|
||||||
"IS-ACTIVE": "Is Active"
|
|
||||||
},
|
},
|
||||||
"FILTER": {
|
"FILTER": {
|
||||||
"MORE-FILTERS": "More filters",
|
"TITLE": "Filters",
|
||||||
"TRACKING-STATE":"Tracking State",
|
"TRACKING-STATE":"State",
|
||||||
"IS-ACTIVE": "Is Active",
|
"IS-ACTIVE": "Is Active",
|
||||||
"CHANNEL": "Channel",
|
|
||||||
"CANCEL": "Cancel",
|
"CANCEL": "Cancel",
|
||||||
"APPLY-FILTERS": "Apply filters"
|
"APPLY-FILTERS": "Apply filters"
|
||||||
},
|
},
|
||||||
|
@ -1362,7 +1362,6 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"READ": "Read",
|
|
||||||
"CANCEL": "Cancel",
|
"CANCEL": "Cancel",
|
||||||
"DELETE": "Delete"
|
"DELETE": "Delete"
|
||||||
}
|
}
|
||||||
|
@ -2316,8 +2315,8 @@
|
||||||
"PUBLIC-CONTACT-SUPPORT": "Public Contact Support"
|
"PUBLIC-CONTACT-SUPPORT": "Public Contact Support"
|
||||||
},
|
},
|
||||||
"NOTIFICATION-INAPP-TRACKING": {
|
"NOTIFICATION-INAPP-TRACKING": {
|
||||||
"STORED": "Stored",
|
"STORED": "Unread",
|
||||||
"DELIVERED": "Delivered"
|
"DELIVERED": "Read"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ADDRESEARCHERS-EDITOR": {
|
"ADDRESEARCHERS-EDITOR": {
|
||||||
|
|
Loading…
Reference in New Issue