add user field in notification listing and small changes in other UI listings

This commit is contained in:
amentis 2024-01-12 14:01:59 +02:00
parent a2edcd6a04
commit 9e413d77f2
14 changed files with 149 additions and 42 deletions

View File

@ -35,6 +35,8 @@ public class NotificationQuery extends QueryBase<NotificationEntity> {
private List<NotificationTrackingState> trackingState;
private List<NotificationTrackingProcess> trackingProgress;
private Collection<UUID> userIds;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
public NotificationQuery ids(UUID value) {
@ -172,6 +174,21 @@ public class NotificationQuery extends QueryBase<NotificationEntity> {
return this;
}
public NotificationQuery userIds(UUID value) {
this.userIds = List.of(value);
return this;
}
public NotificationQuery userIds(UUID... value) {
this.userIds = Arrays.asList(value);
return this;
}
public NotificationQuery userIds(Collection<UUID> values) {
this.userIds = values;
return this;
}
public NotificationQuery ordering(Ordering ordering) {
this.setOrder(ordering);
return this;
@ -246,6 +263,10 @@ public class NotificationQuery extends QueryBase<NotificationEntity> {
predicates.add(queryContext.Root.get(NotificationEntity.Field._trackingProcess).in(trackingProgress));
}
if (this.userIds != null) {
predicates.add(queryContext.Root.get(NotificationEntity.Field._userId).in(userIds));
}
if (predicates.size() > 0) {
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
return queryContext.CriteriaBuilder.and(predicatesArray);

View File

@ -24,6 +24,7 @@ public class NotificationLookup extends Lookup {
private Instant createdAfter;
private List<NotificationTrackingState> trackingState;
private List<NotificationTrackingProcess> trackingProcess;
private List<UUID> userIds;
public List<IsActive> getIsActive() {
@ -122,6 +123,14 @@ public class NotificationLookup extends Lookup {
this.trackingProcess = trackingProcess;
}
public List<UUID> getUserIds() {
return userIds;
}
public void setUserIds(List<UUID> userIds) {
this.userIds = userIds;
}
public NotificationQuery enrich(QueryFactory queryFactory) {
NotificationQuery query = queryFactory.query(NotificationQuery.class);
if (this.isActive != null) query.isActive(this.isActive);
@ -136,6 +145,7 @@ public class NotificationLookup extends Lookup {
if (this.type != null) query.type(this.type);
if (this.trackingProcess != null) query.trackingProgress(this.trackingProcess);
if (this.trackingState != null) query.trackingState(this.trackingState);
if (this.userIds != null) query.userIds(this.userIds);
this.enrichCommon(query);

View File

@ -17,6 +17,7 @@ export class NotificationLookup extends Lookup implements NotificationFilter {
contactType: NotificationContactType[];
trackingState: NotificationTrackingState[];
trackingProcess: NotificationTrackingProcess[];
userIds: Guid[];
constructor() {
super();
@ -33,4 +34,5 @@ export interface NotificationFilter {
contactType: NotificationContactType[];
trackingState: NotificationTrackingState[];
trackingProcess: NotificationTrackingProcess[];
userIds: Guid[];
}

View File

@ -39,9 +39,9 @@
<div class="d-flex align-items-center p-3 gap-1-rem">
<div class="row">
<ng-container *ngIf="isColumnSelected('name')">
<ng-container *ngIf="isColumnSelected('code')">
<a class="buttonLinkClass" [routerLink]="'./' + item?.id" class="col-12"
(click)="$event.stopPropagation()">{{item?.name | nullifyValue}}</a>
(click)="$event.stopPropagation()">{{item?.code | nullifyValue}}</a>
<br />
</ng-container>

View File

@ -71,6 +71,14 @@
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('createdAt')">
<span class="col-12">
{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-LISTING.FIELDS.CREATED-AT' | translate}}:
<small>
{{item?.createdAt | dateTimeFormatter : 'short' | nullifyValue}}
</small>
</span>
</ng-container>
<ng-container *ngIf="isColumnSelected('updatedAt')">
<span class="col-12">
{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-LISTING.FIELDS.UPDATED-AT' | translate}}:

View File

@ -20,6 +20,14 @@
{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FILTER.IS-ACTIVE' | translate}}
</mat-slide-toggle>
<div>
<mat-form-field class="col-12">
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FILTER.USERS' | translate}}</mat-label>
<app-multiple-auto-complete [(ngModel)]="internalFilters.userIds" [hidePlaceholder]="true" [separatorKeysCodes]="separatorKeysCodes" [configuration]="userAutoCompleteConfiguration">
</app-multiple-auto-complete>
</mat-form-field>
</div>
<div>
<mat-label>{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FILTER.NOTIFICATION-TYPE' | translate}}
<mat-select multiple [(ngModel)]="internalFilters.type">

View File

@ -1,3 +1,4 @@
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { NotificationContactType } from '@app/core/common/enum/notification-contact-type';
@ -6,8 +7,11 @@ import { NotificationTrackingProcess } from '@app/core/common/enum/notification-
import { NotificationTrackingState } from '@app/core/common/enum/notification-tracking-state';
import { NotificationType } from '@app/core/common/enum/notification-type';
import { NotificationFilter } from '@app/core/query/notification.lookup';
import { UserService } from '@app/core/services/user/user.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { BaseComponent } from '@common/base/base.component';
import { Guid } from '@common/types/guid';
import { nameof } from 'ts-simple-nameof';
@Component({
@ -24,6 +28,9 @@ export class NotificationListingFiltersComponent extends BaseComponent implement
notificationTrackingStateEnumValues = this.enumUtils.getEnumValues<NotificationTrackingState>(NotificationTrackingState);
notificationTrackingProcessEnumValues = this.enumUtils.getEnumValues<NotificationTrackingProcess>(NotificationTrackingProcess);
notificationTypeEnumValues = this.enumUtils.getEnumValues<NotificationType>(NotificationType);
userAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
// * State
internalFilters: NotificationListingFilters = this._getEmptyFilters();
@ -31,9 +38,11 @@ export class NotificationListingFiltersComponent extends BaseComponent implement
protected appliedFilterCount: number = 0;
constructor(
public enumUtils: EnumUtils,
private userService: UserService,
) { super(); }
ngOnInit() {
this.userAutoCompleteConfiguration = this.userService.multipleAutocompleteConfiguration;
}
ngOnChanges(changes: SimpleChanges): void {
@ -55,7 +64,7 @@ export class NotificationListingFiltersComponent extends BaseComponent implement
}
protected applyFilters(): void {
const { isActive, type, notifyState, notifiedWith, contactType, trackingState, trackingProcess } = this.internalFilters ?? {}
const { isActive, type, notifyState, notifiedWith, contactType, trackingState, trackingProcess, userIds } = this.internalFilters ?? {}
this.filterChange.emit({
...this.filter,
isActive: isActive ? [IsActive.Active] : [IsActive.Inactive],
@ -64,7 +73,8 @@ export class NotificationListingFiltersComponent extends BaseComponent implement
notifiedWith,
contactType,
trackingState,
trackingProcess
trackingProcess,
userIds
})
}
@ -74,7 +84,7 @@ export class NotificationListingFiltersComponent extends BaseComponent implement
return this._getEmptyFilters();
}
let { isActive, type, notifyState, notifiedWith, contactType, trackingState, trackingProcess } = inputFilter;
let { isActive, type, notifyState, notifiedWith, contactType, trackingState, trackingProcess, userIds } = inputFilter;
return {
isActive: (isActive ?? [])?.includes(IsActive.Active) || !isActive?.length,
@ -83,7 +93,8 @@ export class NotificationListingFiltersComponent extends BaseComponent implement
notifiedWith: notifiedWith,
contactType: contactType,
trackingState: trackingState,
trackingProcess: trackingProcess
trackingProcess: trackingProcess,
userIds: userIds
}
}
@ -96,7 +107,8 @@ export class NotificationListingFiltersComponent extends BaseComponent implement
notifiedWith: null,
contactType: null,
trackingState: null,
trackingProcess: null
trackingProcess: null,
userIds: null
}
}
@ -121,4 +133,5 @@ interface NotificationListingFilters {
contactType: NotificationContactType[];
trackingState: NotificationTrackingState[];
trackingProcess: NotificationTrackingProcess[];
userIds: Guid[];
}

View File

@ -11,7 +11,7 @@
<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)"
[defaultSort]="lookup.order?.items" [externalSorting]="true"
(pageLoad)="alterPage($event)" (columnSort)="onColumnSort($event)"
(columnsChanged)="onColumnsChanged($event)" [listItemTemplate]="listItemTemplate">
@ -31,43 +31,47 @@
<div class="d-flex align-items-center p-3 gap-1-rem">
<div class="row">
<ng-container *ngIf="isColumnSelected('name')">
<a class="buttonLinkClass" [routerLink]="'./' + item?.id" class="col-12"
(click)="$event.stopPropagation()">{{item?.name | nullifyValue}}</a>
<br />
</ng-container>
<ng-container *ngIf="isColumnSelected('notificationType')">
<ng-container *ngIf="isColumnSelected('type')">
<span class="col-12">
{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.NOTIFICATION-TYPE' | translate}}:
<small>
{{enumUtils.toNotificationTypeString(item.notificationType) | nullifyValue}}
{{enumUtils.toNotificationTypeString(item.type) | nullifyValue}}
</small>
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('kind')">
<ng-container *ngIf="isColumnSelected('contactTypeHint')">
<span class="col-12">
{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.KIND' | translate}}:
{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.CONTACT-TYPE' | translate}}:
<small>
{{enumUtils.toNotificationTemplateKindString(item.kind) | nullifyValue}}
{{enumUtils.toNotificationContactTypeString(item.contactTypeHint) | nullifyValue}}
</small>
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('channel')">
<ng-container *ngIf="isColumnSelected('notifyState')">
<span class="col-12">
{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.CHANNEL' | translate}}:
{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.NOTIFY-STATE' | translate}}:
<small>
{{enumUtils.toNotificationTemplateChannelString(item.channel) | nullifyValue}}
{{enumUtils.toNotificationNotifyStateString(item.notifyState) | nullifyValue}}
</small>
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('updatedAt')">
<ng-container *ngIf="isColumnSelected('notifiedAt')">
<span class="col-12">
{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.UPDATED-AT' | translate}}:
{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.NOTIFIED-AT' | translate}}:
<small>
{{item?.updatedAt | dateTimeFormatter : 'short' | nullifyValue}}
{{item?.notifiedAt | dateTimeFormatter : 'short' | nullifyValue}}
</small>
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('createdAt')">
<span class="col-12">
{{'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.CREATED-AT' | translate}}:
<small>
{{item?.createdAt | dateTimeFormatter : 'short' | nullifyValue}}
</small>
</span>
</ng-container>

View File

@ -50,6 +50,8 @@ export class NotificationListingComponent extends BaseListingComponent<Notificat
nameof<Notification>(x => x.notifyState),
nameof<Notification>(x => x.notifiedWith),
nameof<Notification>(x => x.notifiedAt),
nameof<Notification>(x => x.user.id),
nameof<Notification>(x => x.user.name),
nameof<Notification>(x => x.createdAt),
nameof<Notification>(x => x.updatedAt),
nameof<Notification>(x => x.hash),
@ -125,7 +127,7 @@ export class NotificationListingComponent extends BaseListingComponent<Notificat
prop: nameof<Notification>(x => x.notifiedAt),
sortable: true,
languageName: 'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.NOTIFIED-AT',
// pipe: this.pipeService.getPipe<NotificationContactTypePipe>(NotificationContactTypePipe)
pipe: this.pipeService.getPipe<DataTableDateTimeFormatPipe>(DataTableDateTimeFormatPipe).withFormat('short')
},
{
prop: nameof<Notification>(x => x.trackingState),
@ -133,6 +135,11 @@ export class NotificationListingComponent extends BaseListingComponent<Notificat
languageName: 'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.TRACKING-STATE',
pipe: this.pipeService.getPipe<NotificationTrackingStatePipe>(NotificationTrackingStatePipe)
},
{
prop: nameof<Notification>(x => x.user.name),
sortable: true,
languageName: 'NOTIFICATION-SERVICE.NOTIFICATION-LISTING.FIELDS.USER',
},
{
prop: nameof<Notification>(x => x.trackingProcess),
sortable: true,

View File

@ -1,4 +1,4 @@
<div class="row description-template-type-listing">
<div class="row reference-type-listing">
<div class="col-md-8 offset-md-2">
<div class="row mb-4 mt-3">
@ -49,12 +49,13 @@
</ng-container>
<ng-container *ngIf="isColumnSelected('code')">
<div class="col-auto">
<div class="status-chip"
[ngClass]="{'status-chip-finalized': item.status === descriptionTemplateTypeStatuses.Finalized, 'status-chip-draft' : item.status === descriptionTemplateTypeStatuses.Draft}">
{{enumUtils.toDescriptionTemplateTypeStatusString(item.status) | nullifyValue}}
</div>
</div>
<span class="col-12">
{{'REFERENCE-TYPE-LISTING.FIELDS.CODE' | translate}}:
<small>
{{item?.code | nullifyValue}}
</small>
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('createdAt')">

View File

@ -1,4 +1,4 @@
.description-template-type-listing {
.reference-type-listing {
margin-top: 1.3rem;
margin-left: 1rem;
margin-right: 2rem;

View File

@ -39,12 +39,42 @@
<div class="d-flex align-items-center p-3 gap-1-rem">
<div class="row">
<ng-container *ngIf="isColumnSelected('name')">
<ng-container *ngIf="isColumnSelected('label')">
<a class="buttonLinkClass" [routerLink]="'./' + item?.id" class="col-12"
(click)="$event.stopPropagation()">{{item?.name | nullifyValue}}</a>
(click)="$event.stopPropagation()">{{item?.label | nullifyValue}}</a>
<br />
</ng-container>
<ng-container *ngIf="isColumnSelected('source')">
<span class="col-12">
{{'REFERENCE-LISTING.FIELDS.SOURCE' | translate}}:
<small>
{{item.source}}
</small>
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('sourceType')">
<span class="col-12">
{{'REFERENCE-LISTING.FIELDS.SOURCE-TYPE' | translate}}:
<small>
{{enumUtils.toReferenceTypeSourceTypeString(item.sourceType) | nullifyValue}}
</small>
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('type')">
<span class="col-12">
{{'REFERENCE-LISTING.FIELDS.TYPE' | translate}}:
<small>
{{enumUtils.toReferenceTypeString(item.type) | nullifyValue}}
</small>
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('createdAt')">
<span class="col-12">
{{'REFERENCE-LISTING.FIELDS.CREATED-AT' | translate}}:

View File

@ -45,13 +45,14 @@
<br />
</ng-container>
<ng-container *ngIf="isColumnSelected('status')">
<div class="col-auto">
<div class="status-chip"
[ngClass]="{'status-chip-finalized': item.status === descriptionTemplateTypeStatuses.Finalized, 'status-chip-draft' : item.status === descriptionTemplateTypeStatuses.Draft}">
{{enumUtils.toDescriptionTemplateTypeStatusString(item.status) | nullifyValue}}
</div>
</div>
<ng-container *ngIf="isColumnSelected('code')">
<span class="col-12">
{{'TENANT-LISTING.FIELDS.CODE' | translate}}:
<small>
{{item?.code | nullifyValue}}
</small>
</span>
<br>
</ng-container>
<ng-container *ngIf="isColumnSelected('createdAt')">

View File

@ -1421,6 +1421,7 @@
"TRACKING-PROCESS": "Tracking Process",
"RETRY-COUNT": "Retry Count",
"NOTIFIED-AT": "Notified At",
"USER": "User",
"UPDATED-AT": "Updated",
"CREATED-AT": "Created",
"IS-ACTIVE": "Is Active"
@ -1433,6 +1434,7 @@
"CONTACT-TYPE": "Contact Type",
"TRACKING-STATE": "Tracking State",
"TRACKING-PROCESS": "Tracking Process",
"USERS": "Users",
"CANCEL": "Cancel",
"APPLY-FILTERS": "Apply filters"
},