UI: fixed alarm tables and alarm details breaking if deleted user was assigned or left comments
This commit is contained in:
parent
9039607780
commit
7df466d0db
@ -31,6 +31,7 @@ import {
|
|||||||
hashCode,
|
hashCode,
|
||||||
isDefined,
|
isDefined,
|
||||||
isDefinedAndNotNull,
|
isDefinedAndNotNull,
|
||||||
|
isNotEmptyStr,
|
||||||
isString,
|
isString,
|
||||||
isUndefined,
|
isUndefined,
|
||||||
objToBase64,
|
objToBase64,
|
||||||
@ -41,7 +42,13 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
import { customTranslationsPrefix, i18nPrefix } from '@app/shared/models/constants';
|
import { customTranslationsPrefix, i18nPrefix } from '@app/shared/models/constants';
|
||||||
import { DataKey, Datasource, DatasourceType, KeyInfo } from '@shared/models/widget.models';
|
import { DataKey, Datasource, DatasourceType, KeyInfo } from '@shared/models/widget.models';
|
||||||
import { DataKeyType } from '@app/shared/models/telemetry/telemetry.models';
|
import { DataKeyType } from '@app/shared/models/telemetry/telemetry.models';
|
||||||
import { alarmFields, alarmSeverityTranslations, alarmStatusTranslations } from '@shared/models/alarm.models';
|
import {
|
||||||
|
AlarmAssignee,
|
||||||
|
AlarmCommentInfo,
|
||||||
|
alarmFields,
|
||||||
|
alarmSeverityTranslations,
|
||||||
|
alarmStatusTranslations
|
||||||
|
} from '@shared/models/alarm.models';
|
||||||
import { materialColors } from '@app/shared/models/material.models';
|
import { materialColors } from '@app/shared/models/material.models';
|
||||||
import { WidgetInfo } from '@home/models/widget-component.models';
|
import { WidgetInfo } from '@home/models/widget-component.models';
|
||||||
import jsonSchemaDefaults from 'json-schema-defaults';
|
import jsonSchemaDefaults from 'json-schema-defaults';
|
||||||
@ -374,6 +381,39 @@ export class UtilsService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getUserDisplayName(alarmAssignee: AlarmAssignee | AlarmCommentInfo) {
|
||||||
|
let displayName = '';
|
||||||
|
if (isNotEmptyStr(alarmAssignee.firstName) || isNotEmptyStr(alarmAssignee.lastName)) {
|
||||||
|
if (alarmAssignee.firstName) {
|
||||||
|
displayName += alarmAssignee.firstName;
|
||||||
|
}
|
||||||
|
if (alarmAssignee.lastName) {
|
||||||
|
if (displayName.length > 0) {
|
||||||
|
displayName += ' ';
|
||||||
|
}
|
||||||
|
displayName += alarmAssignee.lastName;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
displayName = alarmAssignee.email;
|
||||||
|
}
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserInitials(alarmAssignee: AlarmAssignee): string {
|
||||||
|
let initials = '';
|
||||||
|
if (isNotEmptyStr(alarmAssignee.firstName) || isNotEmptyStr(alarmAssignee.lastName)) {
|
||||||
|
if (alarmAssignee.firstName) {
|
||||||
|
initials += alarmAssignee.firstName.charAt(0);
|
||||||
|
}
|
||||||
|
if (alarmAssignee.lastName) {
|
||||||
|
initials += alarmAssignee.lastName.charAt(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initials += alarmAssignee.email.charAt(0);
|
||||||
|
}
|
||||||
|
return initials.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
public stringToHslColor(str: string, saturationPercentage: number, lightnessPercentage: number): string {
|
public stringToHslColor(str: string, saturationPercentage: number, lightnessPercentage: number): string {
|
||||||
if (str && str.length) {
|
if (str && str.length) {
|
||||||
const hue = hashCode(str) % 360;
|
const hue = hashCode(str) % 360;
|
||||||
|
|||||||
@ -110,9 +110,7 @@ export class AlarmAssigneePanelComponent implements OnInit, AfterViewInit, OnDe
|
|||||||
this.filteredUsers = this.selectUserFormGroup.get('user').valueChanges
|
this.filteredUsers = this.selectUserFormGroup.get('user').valueChanges
|
||||||
.pipe(
|
.pipe(
|
||||||
debounceTime(150),
|
debounceTime(150),
|
||||||
map(value => {
|
map(value => value ? (typeof value === 'string' ? value : '') : ''),
|
||||||
return value ? (typeof value === 'string' ? value : '') : ''
|
|
||||||
}),
|
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
switchMap(name => this.fetchUsers(name)),
|
switchMap(name => this.fetchUsers(name)),
|
||||||
share(),
|
share(),
|
||||||
@ -123,7 +121,7 @@ export class AlarmAssigneePanelComponent implements OnInit, AfterViewInit, OnDe
|
|||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.userInput.nativeElement.focus();
|
this.userInput.nativeElement.focus();
|
||||||
}, 0)
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
@ -149,7 +147,7 @@ export class AlarmAssigneePanelComponent implements OnInit, AfterViewInit, OnDe
|
|||||||
this.alarmService.assignAlarm(this.alarmId, user.id.id, {ignoreLoading: true}).subscribe(
|
this.alarmService.assignAlarm(this.alarmId, user.id.id, {ignoreLoading: true}).subscribe(
|
||||||
() => {
|
() => {
|
||||||
this.reassigned = true;
|
this.reassigned = true;
|
||||||
this.overlayRef.dispose()
|
this.overlayRef.dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +155,7 @@ export class AlarmAssigneePanelComponent implements OnInit, AfterViewInit, OnDe
|
|||||||
this.alarmService.unassignAlarm(this.alarmId, {ignoreLoading: true}).subscribe(
|
this.alarmService.unassignAlarm(this.alarmId, {ignoreLoading: true}).subscribe(
|
||||||
() => {
|
() => {
|
||||||
this.reassigned = true;
|
this.reassigned = true;
|
||||||
this.overlayRef.dispose()
|
this.overlayRef.dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,9 +168,7 @@ export class AlarmAssigneePanelComponent implements OnInit, AfterViewInit, OnDe
|
|||||||
return this.userService.getUsersForAssign(this.alarmId, pageLink, {ignoreLoading: true})
|
return this.userService.getUsersForAssign(this.alarmId, pageLink, {ignoreLoading: true})
|
||||||
.pipe(
|
.pipe(
|
||||||
catchError(() => of(emptyPageData<UserEmailInfo>())),
|
catchError(() => of(emptyPageData<UserEmailInfo>())),
|
||||||
map(pageData => {
|
map(pageData => pageData.data)
|
||||||
return pageData.data;
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,42 +187,11 @@ export class AlarmAssigneePanelComponent implements OnInit, AfterViewInit, OnDe
|
|||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserDisplayName(entity: User) {
|
getUserInitials(entity: UserEmailInfo): string {
|
||||||
let displayName = '';
|
return this.utilsService.getUserInitials(entity);
|
||||||
if ((entity.firstName && entity.firstName.length > 0) ||
|
|
||||||
(entity.lastName && entity.lastName.length > 0)) {
|
|
||||||
if (entity.firstName) {
|
|
||||||
displayName += entity.firstName;
|
|
||||||
}
|
|
||||||
if (entity.lastName) {
|
|
||||||
if (displayName.length > 0) {
|
|
||||||
displayName += ' ';
|
|
||||||
}
|
|
||||||
displayName += entity.lastName;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayName = entity.email;
|
|
||||||
}
|
|
||||||
return displayName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserInitials(entity: User): string {
|
getFullName(entity: UserEmailInfo): string {
|
||||||
let initials = '';
|
|
||||||
if (entity.firstName && entity.firstName.length ||
|
|
||||||
entity.lastName && entity.lastName.length) {
|
|
||||||
if (entity.firstName) {
|
|
||||||
initials += entity.firstName.charAt(0);
|
|
||||||
}
|
|
||||||
if (entity.lastName) {
|
|
||||||
initials += entity.lastName.charAt(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
initials += entity.email.charAt(0);
|
|
||||||
}
|
|
||||||
return initials.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
getFullName(entity: User): string {
|
|
||||||
let fullName = '';
|
let fullName = '';
|
||||||
if ((entity.firstName && entity.firstName.length > 0) ||
|
if ((entity.firstName && entity.firstName.length > 0) ||
|
||||||
(entity.lastName && entity.lastName.length > 0)) {
|
(entity.lastName && entity.lastName.length > 0)) {
|
||||||
@ -243,8 +208,8 @@ export class AlarmAssigneePanelComponent implements OnInit, AfterViewInit, OnDe
|
|||||||
return fullName;
|
return fullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAvatarBgColor(entity: User) {
|
getAvatarBgColor(entity: UserEmailInfo) {
|
||||||
return this.utilsService.stringToHslColor(this.getUserDisplayName(entity), 40, 60);
|
return this.utilsService.stringToHslColor(this.utilsService.getUserDisplayName(entity), 40, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -165,39 +165,8 @@ export class AlarmAssigneeSelectPanelComponent implements OnInit, AfterViewInit
|
|||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserDisplayName(entity: UserEmailInfo) {
|
|
||||||
let displayName = '';
|
|
||||||
if ((entity.firstName && entity.firstName.length > 0) ||
|
|
||||||
(entity.lastName && entity.lastName.length > 0)) {
|
|
||||||
if (entity.firstName) {
|
|
||||||
displayName += entity.firstName;
|
|
||||||
}
|
|
||||||
if (entity.lastName) {
|
|
||||||
if (displayName.length > 0) {
|
|
||||||
displayName += ' ';
|
|
||||||
}
|
|
||||||
displayName += entity.lastName;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayName = entity.email;
|
|
||||||
}
|
|
||||||
return displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserInitials(entity: UserEmailInfo): string {
|
getUserInitials(entity: UserEmailInfo): string {
|
||||||
let initials = '';
|
return this.utilsService.getUserInitials(entity);
|
||||||
if (entity.firstName && entity.firstName.length ||
|
|
||||||
entity.lastName && entity.lastName.length) {
|
|
||||||
if (entity.firstName) {
|
|
||||||
initials += entity.firstName.charAt(0);
|
|
||||||
}
|
|
||||||
if (entity.lastName) {
|
|
||||||
initials += entity.lastName.charAt(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
initials += entity.email.charAt(0);
|
|
||||||
}
|
|
||||||
return initials.toUpperCase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getFullName(entity: UserEmailInfo): string {
|
getFullName(entity: UserEmailInfo): string {
|
||||||
@ -218,7 +187,7 @@ export class AlarmAssigneeSelectPanelComponent implements OnInit, AfterViewInit
|
|||||||
}
|
}
|
||||||
|
|
||||||
getAvatarBgColor(entity: UserEmailInfo) {
|
getAvatarBgColor(entity: UserEmailInfo) {
|
||||||
return this.utilsService.stringToHslColor(this.getUserDisplayName(entity), 40, 60);
|
return this.utilsService.stringToHslColor(this.utilsService.getUserDisplayName(entity), 40, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,10 +20,12 @@
|
|||||||
subscriptSizing="dynamic">
|
subscriptSizing="dynamic">
|
||||||
<mat-label translate>alarm.assignee</mat-label>
|
<mat-label translate>alarm.assignee</mat-label>
|
||||||
<input matInput readonly [value]="getAssignee()">
|
<input matInput readonly [value]="getAssignee()">
|
||||||
<span *ngIf="alarm?.assigneeId" matPrefix class="user-avatar"
|
<span *ngIf="userAssigned; else unassigned" matPrefix class="user-avatar"
|
||||||
[style.backgroundColor]="getAvatarBgColor(alarm.assignee)">
|
[style.background-color]="getAvatarBgColor(alarm.assignee)">
|
||||||
{{ getUserInitials(alarm.assignee) }}
|
{{ getUserInitials(alarm.assignee) }}
|
||||||
</span>
|
</span>
|
||||||
<mat-icon *ngIf="!alarm?.assigneeId" matPrefix class="unassigned-icon">account_circle</mat-icon>
|
<ng-template #unassigned>
|
||||||
|
<mat-icon matPrefix class="material-icons unassigned-icon">{{ alarm?.assigneeId ? 'no_accounts' : 'account_circle' }}</mat-icon>
|
||||||
|
</ng-template>
|
||||||
<mat-icon matSuffix>arrow_drop_down</mat-icon>
|
<mat-icon matSuffix>arrow_drop_down</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import {
|
|||||||
import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
|
import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
|
||||||
import { ComponentPortal } from '@angular/cdk/portal';
|
import { ComponentPortal } from '@angular/cdk/portal';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { isNotEmptyStr } from '@core/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-alarm-assignee',
|
selector: 'tb-alarm-assignee',
|
||||||
@ -41,6 +42,8 @@ export class AlarmAssigneeComponent {
|
|||||||
@Output()
|
@Output()
|
||||||
alarmReassigned = new EventEmitter<boolean>();
|
alarmReassigned = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
userAssigned: boolean;
|
||||||
|
|
||||||
constructor(private utilsService: UtilsService,
|
constructor(private utilsService: UtilsService,
|
||||||
private overlay: Overlay,
|
private overlay: Overlay,
|
||||||
private viewContainerRef: ViewContainerRef,
|
private viewContainerRef: ViewContainerRef,
|
||||||
@ -49,68 +52,22 @@ export class AlarmAssigneeComponent {
|
|||||||
|
|
||||||
getAssignee() {
|
getAssignee() {
|
||||||
if (this.alarm) {
|
if (this.alarm) {
|
||||||
if (this.alarm.assignee) {
|
this.userAssigned = this.alarm.assigneeId && ((isNotEmptyStr(this.alarm.assignee?.firstName) ||
|
||||||
return this.getUserDisplayName(this.alarm.assignee);
|
isNotEmptyStr(this.alarm.assignee?.lastName)) || isNotEmptyStr(this.alarm.assignee?.email));
|
||||||
|
if (this.userAssigned) {
|
||||||
|
return this.utilsService.getUserDisplayName(this.alarm.assignee);
|
||||||
} else {
|
} else {
|
||||||
return this.translateService.instant('alarm.unassigned');
|
return this.translateService.instant(this.alarm.assigneeId ? 'alarm.user-deleted' : 'alarm.unassigned');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserDisplayName(entity: AlarmAssignee) {
|
getUserInitials(alarmAssignee: AlarmAssignee): string {
|
||||||
let displayName = '';
|
return this.utilsService.getUserInitials(alarmAssignee);
|
||||||
if ((entity.firstName && entity.firstName.length > 0) ||
|
|
||||||
(entity.lastName && entity.lastName.length > 0)) {
|
|
||||||
if (entity.firstName) {
|
|
||||||
displayName += entity.firstName;
|
|
||||||
}
|
|
||||||
if (entity.lastName) {
|
|
||||||
if (displayName.length > 0) {
|
|
||||||
displayName += ' ';
|
|
||||||
}
|
|
||||||
displayName += entity.lastName;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayName = entity.email;
|
|
||||||
}
|
|
||||||
return displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserInitials(entity: AlarmAssignee): string {
|
|
||||||
let initials = '';
|
|
||||||
if (entity.firstName && entity.firstName.length ||
|
|
||||||
entity.lastName && entity.lastName.length) {
|
|
||||||
if (entity.firstName) {
|
|
||||||
initials += entity.firstName.charAt(0);
|
|
||||||
}
|
|
||||||
if (entity.lastName) {
|
|
||||||
initials += entity.lastName.charAt(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
initials += entity.email.charAt(0);
|
|
||||||
}
|
|
||||||
return initials.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
getFullName(entity: AlarmAssignee): string {
|
|
||||||
let fullName = '';
|
|
||||||
if ((entity.firstName && entity.firstName.length > 0) ||
|
|
||||||
(entity.lastName && entity.lastName.length > 0)) {
|
|
||||||
if (entity.firstName) {
|
|
||||||
fullName += entity.firstName;
|
|
||||||
}
|
|
||||||
if (entity.lastName) {
|
|
||||||
if (fullName.length > 0) {
|
|
||||||
fullName += ' ';
|
|
||||||
}
|
|
||||||
fullName += entity.lastName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fullName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getAvatarBgColor(entity: AlarmAssignee) {
|
getAvatarBgColor(entity: AlarmAssignee) {
|
||||||
return this.utilsService.stringToHslColor(this.getUserDisplayName(entity), 40, 60);
|
return this.utilsService.stringToHslColor(this.utilsService.getUserDisplayName(entity), 40, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
openAlarmAssigneePanel($event: Event, alarm: AlarmInfo) {
|
openAlarmAssigneePanel($event: Event, alarm: AlarmInfo) {
|
||||||
|
|||||||
@ -69,10 +69,14 @@
|
|||||||
*ngIf="!displayDataElement.edit; else commentEditing"
|
*ngIf="!displayDataElement.edit; else commentEditing"
|
||||||
(mouseenter)="onCommentMouseEnter(displayDataElement.commentId, i)"
|
(mouseenter)="onCommentMouseEnter(displayDataElement.commentId, i)"
|
||||||
(mouseleave)="onCommentMouseLeave(i)">
|
(mouseleave)="onCommentMouseLeave(i)">
|
||||||
<div class="user-avatar" fxLayout="row" fxLayoutAlign="center center" fxFlexAlign="start" fxHide.xs
|
<div *ngIf="displayDataElement.userExists; else userDeleted" class="user-avatar"
|
||||||
|
fxLayout="row" fxLayoutAlign="center center" fxFlexAlign="start" fxHide.xs
|
||||||
[style.background-color]="displayDataElement.avatarBgColor">
|
[style.background-color]="displayDataElement.avatarBgColor">
|
||||||
{{ getUserInitials(displayDataElement.displayName) }}
|
{{ getUserInitials(displayDataElement.displayName) }}
|
||||||
</div>
|
</div>
|
||||||
|
<ng-template #userDeleted>
|
||||||
|
<mat-icon matPrefix class="mat-icon tb-mat-30" fxHide.xs>no_accounts</mat-icon>
|
||||||
|
</ng-template>
|
||||||
<div fxFlex fxLayout="column" fxLayoutGap="5px">
|
<div fxFlex fxLayout="column" fxLayoutGap="5px">
|
||||||
<div fxLayout="row" fxLayoutGap="8px" fxLayoutAlign="start center">
|
<div fxLayout="row" fxLayoutGap="8px" fxLayoutAlign="start center">
|
||||||
<span class="user-name">{{ displayDataElement.displayName }}</span>
|
<span class="user-name">{{ displayDataElement.displayName }}</span>
|
||||||
|
|||||||
@ -86,7 +86,7 @@ $border: 1px solid mat.get-color-from-palette($tb-primary);
|
|||||||
background-color: $primary-color;
|
background-color: $primary-color;
|
||||||
border: $border;
|
border: $border;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-radius: 8px 8px 0px 0px;
|
border-radius: 8px 8px 0 0;
|
||||||
|
|
||||||
&.activity-only {
|
&.activity-only {
|
||||||
border: none;
|
border: none;
|
||||||
@ -94,7 +94,7 @@ $border: 1px solid mat.get-color-from-palette($tb-primary);
|
|||||||
|
|
||||||
&.asc {
|
&.asc {
|
||||||
border-bottom: $border;
|
border-bottom: $border;
|
||||||
box-shadow: 0px 4px 10px rgba(23, 33, 90, 0.08);
|
box-shadow: 0 4px 10px rgba(23, 33, 90, 0.08);
|
||||||
|
|
||||||
&.activity-only {
|
&.activity-only {
|
||||||
border: none;
|
border: none;
|
||||||
@ -116,7 +116,7 @@ $border: 1px solid mat.get-color-from-palette($tb-primary);
|
|||||||
.comments-container {
|
.comments-container {
|
||||||
border: $border;
|
border: $border;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
border-radius: 0px 0px 8px 8px;
|
border-radius: 0 0 8px 8px;
|
||||||
|
|
||||||
&.activity-only {
|
&.activity-only {
|
||||||
border: none;
|
border: none;
|
||||||
@ -134,6 +134,11 @@ $border: 1px solid mat.get-color-from-palette($tb-primary);
|
|||||||
&:hover {
|
&:hover {
|
||||||
background-color: $primary-color;
|
background-color: $primary-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mat-icon {
|
||||||
|
align-self: start;
|
||||||
|
color: rgba(0, 0, 0, 0.38);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-avatar {
|
.user-avatar {
|
||||||
|
|||||||
@ -21,31 +21,33 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
import { AlarmCommentService } from '@core/http/alarm-comment.service';
|
import { AlarmCommentService } from '@core/http/alarm-comment.service';
|
||||||
import { AbstractControl, FormBuilder, FormGroup } from '@angular/forms';
|
import { AbstractControl, FormBuilder, FormGroup } from '@angular/forms';
|
||||||
import { DialogService } from '@core/services/dialog.service';
|
import { DialogService } from '@core/services/dialog.service';
|
||||||
import { AuthUser, User } from '@shared/models/user.model';
|
import { AuthUser } from '@shared/models/user.model';
|
||||||
import { getCurrentAuthUser, selectUserDetails } from '@core/auth/auth.selectors';
|
import { getCurrentAuthUser, selectUserDetails } from '@core/auth/auth.selectors';
|
||||||
import { Direction, SortOrder } from '@shared/models/page/sort-order';
|
import { Direction, SortOrder } from '@shared/models/page/sort-order';
|
||||||
import { MAX_SAFE_PAGE_SIZE, PageLink } from '@shared/models/page/page-link';
|
import { MAX_SAFE_PAGE_SIZE, PageLink } from '@shared/models/page/page-link';
|
||||||
import { DateAgoPipe } from '@shared/pipe/date-ago.pipe';
|
import { DateAgoPipe } from '@shared/pipe/date-ago.pipe';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { AlarmComment, AlarmCommentInfo, AlarmCommentType } from '@shared/models/alarm.models';
|
import { AlarmComment, AlarmCommentType } from '@shared/models/alarm.models';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { EntityType } from '@shared/models/entity-type.models';
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
import { DatePipe } from '@angular/common';
|
import { DatePipe } from '@angular/common';
|
||||||
import { ImportExportService } from '@shared/import-export/import-export.service';
|
import { ImportExportService } from '@shared/import-export/import-export.service';
|
||||||
|
import { isNotEmptyStr } from '@core/utils';
|
||||||
|
|
||||||
interface AlarmCommentsDisplayData {
|
interface AlarmCommentsDisplayData {
|
||||||
commentId?: string,
|
commentId?: string;
|
||||||
displayName?: string,
|
displayName?: string;
|
||||||
createdTime: string,
|
createdTime: string;
|
||||||
createdDateAgo?: string,
|
createdDateAgo?: string;
|
||||||
edit?: boolean,
|
edit?: boolean;
|
||||||
isEdited?: boolean,
|
isEdited?: boolean;
|
||||||
editedTime?: string;
|
editedTime?: string;
|
||||||
editedDateAgo?: string,
|
editedDateAgo?: string;
|
||||||
showActions?: boolean,
|
showActions?: boolean;
|
||||||
commentText?: string,
|
commentText?: string;
|
||||||
isSystemComment?: boolean,
|
isSystemComment?: boolean;
|
||||||
avatarBgColor?: string
|
avatarBgColor?: string;
|
||||||
|
userExists?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -58,7 +60,7 @@ export class AlarmCommentComponent implements OnInit {
|
|||||||
alarmId: string;
|
alarmId: string;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
alarmActivityOnly: boolean = false;
|
alarmActivityOnly = false;
|
||||||
|
|
||||||
authUser: AuthUser;
|
authUser: AuthUser;
|
||||||
|
|
||||||
@ -73,11 +75,11 @@ export class AlarmCommentComponent implements OnInit {
|
|||||||
direction: Direction.DESC
|
direction: Direction.DESC
|
||||||
};
|
};
|
||||||
|
|
||||||
editMode: boolean = false;
|
editMode = false;
|
||||||
|
|
||||||
userDisplayName$ = this.store.pipe(
|
userDisplayName$ = this.store.pipe(
|
||||||
select(selectUserDetails),
|
select(selectUserDetails),
|
||||||
map((user) => this.getUserDisplayName(user))
|
map((user) => this.utilsService.getUserDisplayName(user))
|
||||||
);
|
);
|
||||||
|
|
||||||
currentUserDisplayName: string;
|
currentUserDisplayName: string;
|
||||||
@ -115,15 +117,18 @@ export class AlarmCommentComponent implements OnInit {
|
|||||||
(pagedData) => {
|
(pagedData) => {
|
||||||
this.alarmComments = pagedData.data;
|
this.alarmComments = pagedData.data;
|
||||||
this.displayData.length = 0;
|
this.displayData.length = 0;
|
||||||
for (let alarmComment of pagedData.data) {
|
for (const alarmComment of pagedData.data) {
|
||||||
let displayDataElement = {} as AlarmCommentsDisplayData;
|
const displayDataElement = {} as AlarmCommentsDisplayData;
|
||||||
displayDataElement.createdTime = this.datePipe.transform(alarmComment.createdTime, 'yyyy-MM-dd HH:mm:ss');
|
displayDataElement.createdTime = this.datePipe.transform(alarmComment.createdTime, 'yyyy-MM-dd HH:mm:ss');
|
||||||
displayDataElement.createdDateAgo = this.dateAgoPipe.transform(alarmComment.createdTime);
|
displayDataElement.createdDateAgo = this.dateAgoPipe.transform(alarmComment.createdTime);
|
||||||
displayDataElement.commentText = alarmComment.comment.text;
|
displayDataElement.commentText = alarmComment.comment.text;
|
||||||
displayDataElement.isSystemComment = alarmComment.type === AlarmCommentType.SYSTEM;
|
displayDataElement.isSystemComment = alarmComment.type === AlarmCommentType.SYSTEM;
|
||||||
if (alarmComment.type === AlarmCommentType.OTHER) {
|
if (alarmComment.type === AlarmCommentType.OTHER) {
|
||||||
displayDataElement.commentId = alarmComment.id.id;
|
displayDataElement.commentId = alarmComment.id.id;
|
||||||
displayDataElement.displayName = this.getUserDisplayName(alarmComment);
|
displayDataElement.userExists = isNotEmptyStr(alarmComment.firstName) || isNotEmptyStr(alarmComment.lastName) ||
|
||||||
|
isNotEmptyStr(alarmComment.email);
|
||||||
|
displayDataElement.displayName = displayDataElement.userExists ? this.utilsService.getUserDisplayName(alarmComment) :
|
||||||
|
this.translate.instant('alarm.user-deleted');
|
||||||
displayDataElement.edit = false;
|
displayDataElement.edit = false;
|
||||||
displayDataElement.isEdited = alarmComment.comment.edited;
|
displayDataElement.isEdited = alarmComment.comment.edited;
|
||||||
displayDataElement.editedTime = this.datePipe.transform(alarmComment.comment.editedOn, 'yyyy-MM-dd HH:mm:ss');
|
displayDataElement.editedTime = this.datePipe.transform(alarmComment.comment.editedOn, 'yyyy-MM-dd HH:mm:ss');
|
||||||
@ -136,17 +141,17 @@ export class AlarmCommentComponent implements OnInit {
|
|||||||
this.displayData.push(displayDataElement);
|
this.displayData.push(displayDataElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeSortDirection() {
|
changeSortDirection() {
|
||||||
let currentDirection = this.alarmCommentSortOrder.direction;
|
const currentDirection = this.alarmCommentSortOrder.direction;
|
||||||
this.alarmCommentSortOrder.direction = currentDirection === Direction.DESC ? Direction.ASC : Direction.DESC;
|
this.alarmCommentSortOrder.direction = currentDirection === Direction.DESC ? Direction.ASC : Direction.DESC;
|
||||||
this.loadAlarmComments();
|
this.loadAlarmComments();
|
||||||
}
|
}
|
||||||
|
|
||||||
exportAlarmActivity() {
|
exportAlarmActivity() {
|
||||||
let fileName = this.translate.instant('alarm.alarm') + '_' + this.translate.instant('alarm-activity.activity');
|
const fileName = this.translate.instant('alarm.alarm') + '_' + this.translate.instant('alarm-activity.activity');
|
||||||
this.importExportService.exportCsv(this.getDataForExport(), fileName.toLowerCase());
|
this.importExportService.exportCsv(this.getDataForExport(), fileName.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +167,7 @@ export class AlarmCommentComponent implements OnInit {
|
|||||||
comment: {
|
comment: {
|
||||||
text: commentInputValue
|
text: commentInputValue
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
this.doSave(comment);
|
this.doSave(comment);
|
||||||
this.clearCommentInput();
|
this.clearCommentInput();
|
||||||
}
|
}
|
||||||
@ -185,7 +190,7 @@ export class AlarmCommentComponent implements OnInit {
|
|||||||
() => {
|
() => {
|
||||||
this.loadAlarmComments();
|
this.loadAlarmComments();
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
editComment(commentId: string): void {
|
editComment(commentId: string): void {
|
||||||
@ -217,18 +222,18 @@ export class AlarmCommentComponent implements OnInit {
|
|||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
this.loadAlarmComments();
|
this.loadAlarmComments();
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getSortDirectionIcon() {
|
getSortDirectionIcon() {
|
||||||
return this.alarmCommentSortOrder.direction === Direction.DESC ? 'mdi:sort-descending' : 'mdi:sort-ascending'
|
return this.alarmCommentSortOrder.direction === Direction.DESC ? 'mdi:sort-descending' : 'mdi:sort-ascending';
|
||||||
}
|
}
|
||||||
|
|
||||||
getSortDirectionTooltipText() {
|
getSortDirectionTooltipText() {
|
||||||
let text = this.alarmCommentSortOrder.direction === Direction.DESC ? 'alarm-activity.newest-first' :
|
const text = this.alarmCommentSortOrder.direction === Direction.DESC ? 'alarm-activity.newest-first' :
|
||||||
'alarm-activity.oldest-first';
|
'alarm-activity.oldest-first';
|
||||||
return this.translate.instant(text);
|
return this.translate.instant(text);
|
||||||
}
|
}
|
||||||
@ -264,25 +269,6 @@ export class AlarmCommentComponent implements OnInit {
|
|||||||
return this.utilsService.stringToHslColor(userDisplayName, 40, 60);
|
return this.utilsService.stringToHslColor(userDisplayName, 40, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getUserDisplayName(alarmCommentInfo: AlarmCommentInfo | User): string {
|
|
||||||
let name = '';
|
|
||||||
if ((alarmCommentInfo.firstName && alarmCommentInfo.firstName.length > 0) ||
|
|
||||||
(alarmCommentInfo.lastName && alarmCommentInfo.lastName.length > 0)) {
|
|
||||||
if (alarmCommentInfo.firstName) {
|
|
||||||
name += alarmCommentInfo.firstName;
|
|
||||||
}
|
|
||||||
if (alarmCommentInfo.lastName) {
|
|
||||||
if (name.length > 0) {
|
|
||||||
name += ' ';
|
|
||||||
}
|
|
||||||
name += alarmCommentInfo.lastName;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
name = alarmCommentInfo.email;
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAlarmCommentFormControl(): AbstractControl {
|
getAlarmCommentFormControl(): AbstractControl {
|
||||||
return this.alarmCommentFormGroup.get('alarmComment');
|
return this.alarmCommentFormGroup.get('alarmComment');
|
||||||
}
|
}
|
||||||
@ -308,16 +294,16 @@ export class AlarmCommentComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getDataForExport() {
|
private getDataForExport() {
|
||||||
let dataToExport = [];
|
const dataToExport = [];
|
||||||
for (let row of this.displayData) {
|
for (const row of this.displayData) {
|
||||||
let exportRow = {
|
const exportRow = {
|
||||||
[this.translate.instant('alarm-activity.author')]: row.isSystemComment ?
|
[this.translate.instant('alarm-activity.author')]: row.isSystemComment ?
|
||||||
this.translate.instant('alarm-activity.system') : row.displayName,
|
this.translate.instant('alarm-activity.system') : row.displayName,
|
||||||
[this.translate.instant('alarm-activity.created-date')]: row.createdTime,
|
[this.translate.instant('alarm-activity.created-date')]: row.createdTime,
|
||||||
[this.translate.instant('alarm-activity.edited-date')]: row.editedTime,
|
[this.translate.instant('alarm-activity.edited-date')]: row.editedTime,
|
||||||
[this.translate.instant('alarm-activity.text')]: row.commentText
|
[this.translate.instant('alarm-activity.text')]: row.commentText
|
||||||
}
|
};
|
||||||
dataToExport.push(exportRow)
|
dataToExport.push(exportRow);
|
||||||
}
|
}
|
||||||
return dataToExport;
|
return dataToExport;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,13 +31,13 @@ import { forkJoin, Observable } from 'rxjs';
|
|||||||
import { PageData } from '@shared/models/page/page-data';
|
import { PageData } from '@shared/models/page/page-data';
|
||||||
import { EntityId } from '@shared/models/id/entity-id';
|
import { EntityId } from '@shared/models/id/entity-id';
|
||||||
import {
|
import {
|
||||||
|
AlarmAssignee,
|
||||||
AlarmInfo,
|
AlarmInfo,
|
||||||
AlarmQueryV2,
|
AlarmQueryV2,
|
||||||
AlarmSearchStatus,
|
AlarmSearchStatus,
|
||||||
alarmSeverityColors,
|
alarmSeverityColors,
|
||||||
alarmSeverityTranslations,
|
alarmSeverityTranslations,
|
||||||
AlarmsMode,
|
AlarmsMode,
|
||||||
AlarmStatus,
|
|
||||||
alarmStatusTranslations
|
alarmStatusTranslations
|
||||||
} from '@app/shared/models/alarm.models';
|
} from '@app/shared/models/alarm.models';
|
||||||
import { AlarmService } from '@app/core/http/alarm.service';
|
import { AlarmService } from '@app/core/http/alarm.service';
|
||||||
@ -60,7 +60,7 @@ import {
|
|||||||
AlarmAssigneePanelData
|
AlarmAssigneePanelData
|
||||||
} from '@home/components/alarm/alarm-assignee-panel.component';
|
} from '@home/components/alarm/alarm-assignee-panel.component';
|
||||||
import { ComponentPortal } from '@angular/cdk/portal';
|
import { ComponentPortal } from '@angular/cdk/portal';
|
||||||
import { getEntityDetailsPageURL, isDefinedAndNotNull } from '@core/utils';
|
import { getEntityDetailsPageURL, isDefinedAndNotNull, isNotEmptyStr } from '@core/utils';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { AlarmFilterConfig } from '@shared/models/query/query.models';
|
import { AlarmFilterConfig } from '@shared/models/query/query.models';
|
||||||
import { EntityService } from '@core/http/entity.service';
|
import { EntityService } from '@core/http/entity.service';
|
||||||
@ -129,22 +129,15 @@ export class AlarmTableConfig extends EntityTableConfig<AlarmInfo, TimePageLink>
|
|||||||
})));
|
})));
|
||||||
this.columns.push(
|
this.columns.push(
|
||||||
new EntityTableColumn<AlarmInfo>('assignee', 'alarm.assignee', '240px',
|
new EntityTableColumn<AlarmInfo>('assignee', 'alarm.assignee', '240px',
|
||||||
(entity) => {
|
(entity) => this.getAssigneeTemplate(entity), () => ({}), false, () => ({}), () => undefined, false,
|
||||||
return this.getAssigneeTemplate(entity)
|
|
||||||
},
|
|
||||||
() => ({}),
|
|
||||||
false,
|
|
||||||
() => ({}),
|
|
||||||
(entity) => undefined,
|
|
||||||
false,
|
|
||||||
{
|
{
|
||||||
icon: 'keyboard_arrow_down',
|
icon: 'keyboard_arrow_down',
|
||||||
type: CellActionDescriptorType.DEFAULT,
|
type: CellActionDescriptorType.DEFAULT,
|
||||||
isEnabled: (entity) => true,
|
isEnabled: () => true,
|
||||||
name: this.translate.instant('alarm.assign'),
|
name: this.translate.instant('alarm.assign'),
|
||||||
onAction: ($event, entity) => this.openAlarmAssigneePanel($event, entity)
|
onAction: ($event, entity) => this.openAlarmAssigneePanel($event, entity)
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
this.columns.push(
|
this.columns.push(
|
||||||
new EntityTableColumn<AlarmInfo>('status', 'alarm.status', '25%',
|
new EntityTableColumn<AlarmInfo>('status', 'alarm.status', '25%',
|
||||||
(entity) => this.translate.instant(alarmStatusTranslations.get(entity.status))));
|
(entity) => this.translate.instant(alarmStatusTranslations.get(entity.status))));
|
||||||
@ -177,7 +170,7 @@ export class AlarmTableConfig extends EntityTableConfig<AlarmInfo, TimePageLink>
|
|||||||
isEnabled: true,
|
isEnabled: true,
|
||||||
onAction: ($event, entities) => this.deleteAlarms($event, entities)
|
onAction: ($event, entities) => this.deleteAlarms($event, entities)
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchAlarms(pageLink: TimePageLink): Observable<PageData<AlarmInfo>> {
|
fetchAlarms(pageLink: TimePageLink): Observable<PageData<AlarmInfo>> {
|
||||||
@ -216,61 +209,32 @@ export class AlarmTableConfig extends EntityTableConfig<AlarmInfo, TimePageLink>
|
|||||||
}
|
}
|
||||||
|
|
||||||
getAssigneeTemplate(entity: AlarmInfo): string {
|
getAssigneeTemplate(entity: AlarmInfo): string {
|
||||||
return `
|
const hasAssigneeId = isDefinedAndNotNull(entity.assigneeId);
|
||||||
<span class="assignee-cell">
|
let templateContent: string;
|
||||||
${isDefinedAndNotNull(entity.assigneeId) ?
|
|
||||||
`<span class="assigned-container">
|
if (hasAssigneeId && ((isNotEmptyStr(entity.assignee?.firstName) || isNotEmptyStr(entity.assignee?.lastName)) ||
|
||||||
<span class="user-avatar" style="background-color: ${this.getAvatarBgColor(entity)}">
|
isNotEmptyStr(entity.assignee?.email))) {
|
||||||
${this.getUserInitials(entity)}
|
templateContent = `
|
||||||
|
<span class="assigned-container">
|
||||||
|
<span class="user-avatar" style="background-color: ${this.getAvatarBgColor(entity.assignee)}">
|
||||||
|
${this.utilsService.getUserInitials(entity.assignee)}
|
||||||
</span>
|
</span>
|
||||||
<span class="user-display-name">${this.getUserDisplayName(entity)}</span>
|
<span class="user-display-name">${this.utilsService.getUserDisplayName(entity.assignee)}</span>
|
||||||
</span>`
|
</span>`;
|
||||||
:
|
|
||||||
`<span class="unassigned-container">
|
|
||||||
<mat-icon class="material-icons unassigned-icon">account_circle</mat-icon>
|
|
||||||
<span>${this.translate.instant('alarm.unassigned')}</span>
|
|
||||||
</span>`
|
|
||||||
}
|
|
||||||
</span>`
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserDisplayName(entity: AlarmInfo) {
|
|
||||||
let displayName = '';
|
|
||||||
if ((entity.assignee.firstName && entity.assignee.firstName.length > 0) ||
|
|
||||||
(entity.assignee.lastName && entity.assignee.lastName.length > 0)) {
|
|
||||||
if (entity.assignee.firstName) {
|
|
||||||
displayName += entity.assignee.firstName;
|
|
||||||
}
|
|
||||||
if (entity.assignee.lastName) {
|
|
||||||
if (displayName.length > 0) {
|
|
||||||
displayName += ' ';
|
|
||||||
}
|
|
||||||
displayName += entity.assignee.lastName;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
displayName = entity.assignee.email;
|
templateContent = `
|
||||||
|
<span class="unassigned-container">
|
||||||
|
<mat-icon class="material-icons unassigned-icon">
|
||||||
|
${hasAssigneeId ? 'no_accounts' : 'account_circle'}
|
||||||
|
</mat-icon>
|
||||||
|
<span>${this.translate.instant(hasAssigneeId ? 'alarm.user-deleted' : 'alarm.unassigned')}</span>
|
||||||
|
</span>`;
|
||||||
}
|
}
|
||||||
return displayName;
|
return `<span class="assignee-cell">${templateContent}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserInitials(entity: AlarmInfo): string {
|
getAvatarBgColor(alarmAssignee: AlarmAssignee) {
|
||||||
let initials = '';
|
return this.utilsService.stringToHslColor(this.utilsService.getUserDisplayName(alarmAssignee), 40, 60);
|
||||||
if (entity.assignee.firstName && entity.assignee.firstName.length ||
|
|
||||||
entity.assignee.lastName && entity.assignee.lastName.length) {
|
|
||||||
if (entity.assignee.firstName) {
|
|
||||||
initials += entity.assignee.firstName.charAt(0);
|
|
||||||
}
|
|
||||||
if (entity.assignee.lastName) {
|
|
||||||
initials += entity.assignee.lastName.charAt(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
initials += entity.assignee.email.charAt(0);
|
|
||||||
}
|
|
||||||
return initials.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
getAvatarBgColor(entity: AlarmInfo) {
|
|
||||||
return this.utilsService.stringToHslColor(this.getUserDisplayName(entity), 40, 60);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openAlarmAssigneePanel($event: Event, entity: AlarmInfo) {
|
openAlarmAssigneePanel($event: Event, entity: AlarmInfo) {
|
||||||
@ -312,7 +276,7 @@ export class AlarmTableConfig extends EntityTableConfig<AlarmInfo, TimePageLink>
|
|||||||
this.viewContainerRef, injector));
|
this.viewContainerRef, injector));
|
||||||
componentRef.onDestroy(() => {
|
componentRef.onDestroy(() => {
|
||||||
if (componentRef.instance.reassigned) {
|
if (componentRef.instance.reassigned) {
|
||||||
this.updateData()
|
this.updateData();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -88,24 +88,24 @@
|
|||||||
<span [innerHTML]="cellContent(alarm, column, row)"></span>
|
<span [innerHTML]="cellContent(alarm, column, row)"></span>
|
||||||
<ng-container *ngIf="column.entityKey.key === 'assignee'">
|
<ng-container *ngIf="column.entityKey.key === 'assignee'">
|
||||||
<span class="assignee-cell" fxLayout="row" fxLayoutAlign="start center">
|
<span class="assignee-cell" fxLayout="row" fxLayoutAlign="start center">
|
||||||
<span *ngIf="alarm.assigneeId" class="assigned-container">
|
<span *ngIf="alarm.assigneeId && checkAssigneeHasName(alarm.assignee); else unassigned"
|
||||||
<span class="user-avatar" [style.backgroundColor]="getAvatarBgColor(alarm)">
|
class="assigned-container">
|
||||||
{{ getUserInitials(alarm) }}
|
<span class="user-avatar" [style.backgroundColor]="getAvatarBgColor(alarm.assignee)">
|
||||||
|
{{ getUserInitials(alarm.assignee) }}
|
||||||
</span>
|
</span>
|
||||||
<span [matTooltip]="getUserDisplayName(alarm)"
|
<span [matTooltip]="getUserDisplayName(alarm.assignee)" matTooltipPosition="above">
|
||||||
matTooltipPosition="above">
|
{{ getUserDisplayName(alarm.assignee) }}
|
||||||
{{ getUserDisplayName(alarm) }}
|
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span *ngIf="!alarm.assigneeId" class="unassigned-container">
|
<ng-template #unassigned>
|
||||||
<mat-icon class="material-icons unassigned-icon">account_circle</mat-icon>
|
<span class="unassigned-container">
|
||||||
<span matTooltip="{{ 'alarm.unassigned' | translate }}"
|
<mat-icon class="material-icons unassigned-icon">{{ alarm.assigneeId ? 'no_accounts' : 'account_circle' }}</mat-icon>
|
||||||
matTooltipPosition="above"
|
<span matTooltip="{{ (alarm.assigneeId ? 'alarm.user-deleted' : 'alarm.unassigned') | translate }}"
|
||||||
style="vertical-align: middle"
|
matTooltipPosition="above" style="vertical-align: middle">
|
||||||
translate>
|
{{ (alarm.assigneeId ? 'alarm.user-deleted' : 'alarm.unassigned') | translate }}
|
||||||
alarm.unassigned
|
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
</ng-template>
|
||||||
<button *ngIf="allowAssign"
|
<button *ngIf="allowAssign"
|
||||||
mat-icon-button [disabled]="isLoading$ | async"
|
mat-icon-button [disabled]="isLoading$ | async"
|
||||||
matTooltip="{{ 'alarm.assign' | translate }}"
|
matTooltip="{{ 'alarm.assign' | translate }}"
|
||||||
|
|||||||
@ -37,7 +37,16 @@ import { DataKey, WidgetActionDescriptor, WidgetConfig } from '@shared/models/wi
|
|||||||
import { IWidgetSubscription } from '@core/api/widget-api.models';
|
import { IWidgetSubscription } from '@core/api/widget-api.models';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { deepClone, hashCode, isDefined, isDefinedAndNotNull, isNumber, isObject, isUndefined } from '@core/utils';
|
import {
|
||||||
|
deepClone,
|
||||||
|
hashCode,
|
||||||
|
isDefined,
|
||||||
|
isDefinedAndNotNull,
|
||||||
|
isNotEmptyStr,
|
||||||
|
isNumber,
|
||||||
|
isObject,
|
||||||
|
isUndefined
|
||||||
|
} from '@core/utils';
|
||||||
import cssjs from '@core/css/css';
|
import cssjs from '@core/css/css';
|
||||||
import { sortItems } from '@shared/models/page/page-link';
|
import { sortItems } from '@shared/models/page/page-link';
|
||||||
import { Direction } from '@shared/models/page/sort-order';
|
import { Direction } from '@shared/models/page/sort-order';
|
||||||
@ -83,7 +92,14 @@ import {
|
|||||||
DisplayColumnsPanelComponent,
|
DisplayColumnsPanelComponent,
|
||||||
DisplayColumnsPanelData
|
DisplayColumnsPanelData
|
||||||
} from '@home/components/widget/lib/display-columns-panel.component';
|
} from '@home/components/widget/lib/display-columns-panel.component';
|
||||||
import { AlarmDataInfo, alarmFields, AlarmInfo, alarmSeverityColors, AlarmStatus } from '@shared/models/alarm.models';
|
import {
|
||||||
|
AlarmAssignee,
|
||||||
|
AlarmDataInfo,
|
||||||
|
alarmFields,
|
||||||
|
AlarmInfo,
|
||||||
|
alarmSeverityColors,
|
||||||
|
AlarmStatus
|
||||||
|
} from '@shared/models/alarm.models';
|
||||||
import { DatePipe } from '@angular/common';
|
import { DatePipe } from '@angular/common';
|
||||||
import {
|
import {
|
||||||
AlarmDetailsDialogComponent,
|
AlarmDetailsDialogComponent,
|
||||||
@ -1097,43 +1113,21 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
|
|||||||
this.rowStyleCache.length = 0;
|
this.rowStyleCache.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserDisplayName(entity: AlarmInfo) {
|
checkAssigneeHasName(alarmAssignee: AlarmAssignee): boolean {
|
||||||
let displayName = '';
|
return (isNotEmptyStr(alarmAssignee?.firstName) || isNotEmptyStr(alarmAssignee?.lastName)) ||
|
||||||
if ((entity.assignee.firstName && entity.assignee.firstName.length > 0) ||
|
isNotEmptyStr(alarmAssignee?.email);
|
||||||
(entity.assignee.lastName && entity.assignee.lastName.length > 0)) {
|
|
||||||
if (entity.assignee.firstName) {
|
|
||||||
displayName += entity.assignee.firstName;
|
|
||||||
}
|
|
||||||
if (entity.assignee.lastName) {
|
|
||||||
if (displayName.length > 0) {
|
|
||||||
displayName += ' ';
|
|
||||||
}
|
|
||||||
displayName += entity.assignee.lastName;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayName = entity.assignee.email;
|
|
||||||
}
|
|
||||||
return displayName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserInitials(entity: AlarmInfo): string {
|
getUserDisplayName(alarmAssignee: AlarmAssignee) {
|
||||||
let initials = '';
|
return this.utils.getUserDisplayName(alarmAssignee);
|
||||||
if (entity.assignee.firstName && entity.assignee.firstName.length ||
|
|
||||||
entity.assignee.lastName && entity.assignee.lastName.length) {
|
|
||||||
if (entity.assignee.firstName) {
|
|
||||||
initials += entity.assignee.firstName.charAt(0);
|
|
||||||
}
|
|
||||||
if (entity.assignee.lastName) {
|
|
||||||
initials += entity.assignee.lastName.charAt(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
initials += entity.assignee.email.charAt(0);
|
|
||||||
}
|
|
||||||
return initials.toUpperCase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getAvatarBgColor(entity: AlarmInfo) {
|
getUserInitials(alarmAssignee: AlarmAssignee): string {
|
||||||
return this.utils.stringToHslColor(this.getUserDisplayName(entity), 40, 60);
|
return this.utils.getUserInitials(alarmAssignee);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAvatarBgColor(alarmAssignee: AlarmAssignee) {
|
||||||
|
return this.utils.stringToHslColor(this.getUserDisplayName(alarmAssignee), 40, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
openAlarmAssigneePanel($event: Event, entity: AlarmInfo) {
|
openAlarmAssigneePanel($event: Event, entity: AlarmInfo) {
|
||||||
|
|||||||
@ -127,7 +127,7 @@ export interface AlarmComment extends BaseData<AlarmCommentId> {
|
|||||||
text: string;
|
text: string;
|
||||||
edited?: boolean;
|
edited?: boolean;
|
||||||
editedOn?: number;
|
editedOn?: number;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AlarmCommentInfo extends AlarmComment {
|
export interface AlarmCommentInfo extends AlarmComment {
|
||||||
@ -173,9 +173,9 @@ export const simulatedAlarm: AlarmInfo = {
|
|||||||
originatorName: 'Simulated',
|
originatorName: 'Simulated',
|
||||||
originatorLabel: 'Simulated',
|
originatorLabel: 'Simulated',
|
||||||
assignee: {
|
assignee: {
|
||||||
firstName: "",
|
firstName: '',
|
||||||
lastName: "",
|
lastName: '',
|
||||||
email: "test@example.com",
|
email: 'test@example.com',
|
||||||
},
|
},
|
||||||
originator: {
|
originator: {
|
||||||
entityType: EntityType.DEVICE,
|
entityType: EntityType.DEVICE,
|
||||||
|
|||||||
@ -594,6 +594,7 @@
|
|||||||
"assignee-last-name": "Assignee last name",
|
"assignee-last-name": "Assignee last name",
|
||||||
"assignee-email": "Assignee email",
|
"assignee-email": "Assignee email",
|
||||||
"unassigned": "Unassigned",
|
"unassigned": "Unassigned",
|
||||||
|
"user-deleted": "User deleted",
|
||||||
"assignee-not-set": "All",
|
"assignee-not-set": "All",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"alarm-details": "Alarm details",
|
"alarm-details": "Alarm details",
|
||||||
|
|||||||
@ -912,6 +912,9 @@ mat-icon {
|
|||||||
&.tb-mat-28 {
|
&.tb-mat-28 {
|
||||||
@include tb-mat-icon-size(28);
|
@include tb-mat-icon-size(28);
|
||||||
}
|
}
|
||||||
|
&.tb-mat-30 {
|
||||||
|
@include tb-mat-icon-size(30);
|
||||||
|
}
|
||||||
&.tb-mat-32 {
|
&.tb-mat-32 {
|
||||||
@include tb-mat-icon-size(32);
|
@include tb-mat-icon-size(32);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user