diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee-panel.component.scss b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee-panel.component.scss
index 971e0abd55..8db3bb111f 100644
--- a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee-panel.component.scss
+++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee-panel.component.scss
@@ -65,7 +65,6 @@
display: inline-flex;
justify-content: center;
align-items: center;
- align-self: center;
margin-right: 8px;
border-radius: 50%;
background-color: #5cb445;
@@ -73,7 +72,7 @@
height: 28px;
min-width: 28px;
min-height: 28px;
- color: white;
+ color: #fff;
font-size: 13px;
font-weight: 700
}
diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.html b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.html
new file mode 100644
index 0000000000..6e50082e8b
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+ {{ getUserInitials(alarm.assignee) }}
+
+ {{ getUserDisplayName(alarm.assignee) }}
+
+
+ account_circle
+ alarm.unassigned
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss
new file mode 100644
index 0000000000..5736aa8ef1
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss
@@ -0,0 +1,51 @@
+/**
+ * Copyright © 2016-2023 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+:host {
+ .tb-assignee {
+ cursor: pointer;
+
+ .assigned-container {
+ max-width: 233px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+
+ .user-avatar {
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ margin-right: 8px;
+ border-radius: 50%;
+ width: 28px;
+ height: 28px;
+ min-width: 28px;
+ min-height: 28px;
+ color: white;
+ font-size: 13px;
+ font-weight: 700;
+ }
+ }
+ .material-icons.unassigned-icon {
+ width: 28px;
+ height: 28px;
+ font-size: 28px;
+ margin-right: 8px;
+ color: rgba(0, 0, 0, 0.38);
+ overflow: visible;
+ }
+ }
+}
diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts
new file mode 100644
index 0000000000..5d7f29d55b
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts
@@ -0,0 +1,141 @@
+///
+/// Copyright © 2016-2023 The Thingsboard Authors
+///
+/// Licensed under the Apache License, Version 2.0 (the "License");
+/// you may not use this file except in compliance with the License.
+/// You may obtain a copy of the License at
+///
+/// http://www.apache.org/licenses/LICENSE-2.0
+///
+/// Unless required by applicable law or agreed to in writing, software
+/// distributed under the License is distributed on an "AS IS" BASIS,
+/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+/// See the License for the specific language governing permissions and
+/// limitations under the License.
+///
+
+import {
+ Component, EventEmitter, Injector, Input, Output, StaticProvider, ViewContainerRef
+} from '@angular/core';
+import { UtilsService } from '@core/services/utils.service';
+import { AlarmAssignee, AlarmInfo } from '@shared/models/alarm.models';
+import {
+ ALARM_ASSIGNEE_PANEL_DATA, AlarmAssigneePanelComponent,
+ AlarmAssigneePanelData
+} from '@home/components/alarm/alarm-assignee-panel.component';
+import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
+import { ComponentPortal } from '@angular/cdk/portal';
+
+@Component({
+ selector: 'tb-alarm-assignee',
+ templateUrl: './alarm-assignee.component.html',
+ styleUrls: ['./alarm-assignee.component.scss']
+})
+export class AlarmAssigneeComponent {
+ @Input()
+ alarm: AlarmInfo;
+
+ @Output()
+ alarmReassigned = new EventEmitter();
+
+ constructor(private utilsService: UtilsService,
+ private overlay: Overlay,
+ private viewContainerRef: ViewContainerRef) {
+ }
+
+ getUserDisplayName(entity: AlarmAssignee) {
+ 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: 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) {
+ return this.utilsService.stringToHslColor(this.getUserDisplayName(entity), 40, 60);
+ }
+
+ openAlarmAssigneePanel($event: Event, alarm: AlarmInfo) {
+ if ($event) {
+ $event.stopPropagation();
+ }
+ const target = $event.target || $event.srcElement || $event.currentTarget;
+ const config = new OverlayConfig();
+ config.backdropClass = 'cdk-overlay-transparent-backdrop';
+ config.hasBackdrop = true;
+ const connectedPosition: ConnectedPosition = {
+ originX: 'end',
+ originY: 'bottom',
+ overlayX: 'end',
+ overlayY: 'top'
+ };
+ config.positionStrategy = this.overlay.position().flexibleConnectedTo(target as HTMLElement)
+ .withPositions([connectedPosition]);
+ config.minWidth = '260px';
+ const overlayRef = this.overlay.create(config);
+ overlayRef.backdropClick().subscribe(() => {
+ overlayRef.dispose();
+ });
+ const providers: StaticProvider[] = [
+ {
+ provide: ALARM_ASSIGNEE_PANEL_DATA,
+ useValue: {
+ alarmId: alarm.id.id,
+ assigneeId: alarm.assigneeId?.id
+ } as AlarmAssigneePanelData
+ },
+ {
+ provide: OverlayRef,
+ useValue: overlayRef
+ }
+ ];
+ const injector = Injector.create({parent: this.viewContainerRef.injector, providers});
+ overlayRef.attach(new ComponentPortal(AlarmAssigneePanelComponent,
+ this.viewContainerRef, injector)).onDestroy(() => this.alarmReassigned.emit(true));
+ }
+
+}
diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.html
index c8bbbe5537..c1be93431d 100644
--- a/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.html
+++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.html
@@ -56,14 +56,10 @@
alarm.status
-
- alarm.assignee
-
- {{ assigneeInitials }}
-
-
-
+
+
diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.ts b/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.ts
index a8d24bdafa..e86b470566 100644
--- a/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.ts
+++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.ts
@@ -34,7 +34,6 @@ import { tap } from 'rxjs/operators';
import { DatePipe } from '@angular/common';
import { TranslateService } from '@ngx-translate/core';
import { AlarmCommentComponent } from '@home/components/alarm/alarm-comment.component';
-import { UtilsService } from '@core/services/utils.service';
export interface AlarmDetailsDialogData {
alarmId?: string;
@@ -70,8 +69,6 @@ export class AlarmDetailsDialogComponent extends DialogComponent,
protected router: Router,
private datePipe: DatePipe,
@@ -79,8 +76,7 @@ export class AlarmDetailsDialogComponent extends DialogComponent,
- public fb: UntypedFormBuilder,
- private utilsService: UtilsService) {
+ public fb: UntypedFormBuilder) {
super(store, router, dialogRef);
this.allowAcknowledgment = data.allowAcknowledgment;
@@ -91,15 +87,12 @@ export class AlarmDetailsDialogComponent extends DialogComponent 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 {
- displayName = entity.assignee.email;
- }
- return displayName;
- }
-
- getUserInitials(entity: AlarmInfo): string {
- let initials = '';
- 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();
+ onReassign(): void {
+ this.alarmUpdated = true;
+ this.loadAlarm()
+ this.alarmCommentComponent.loadAlarmComments();
}
-
}
diff --git a/ui-ngx/src/app/modules/home/components/shared-home-components.module.ts b/ui-ngx/src/app/modules/home/components/shared-home-components.module.ts
index fbfc297439..865e7cf224 100644
--- a/ui-ngx/src/app/modules/home/components/shared-home-components.module.ts
+++ b/ui-ngx/src/app/modules/home/components/shared-home-components.module.ts
@@ -21,6 +21,7 @@ import { AlarmDetailsDialogComponent } from '@home/components/alarm/alarm-detail
import { SHARED_HOME_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens';
import { AlarmCommentComponent } from '@home/components/alarm/alarm-comment.component';
import { AlarmCommentDialogComponent } from '@home/components/alarm/alarm-comment-dialog.component';
+import { AlarmAssigneeComponent } from '@home/components/alarm/alarm-assignee.component';
@NgModule({
providers: [
@@ -30,7 +31,8 @@ import { AlarmCommentDialogComponent } from '@home/components/alarm/alarm-commen
[
AlarmDetailsDialogComponent,
AlarmCommentComponent,
- AlarmCommentDialogComponent
+ AlarmCommentDialogComponent,
+ AlarmAssigneeComponent
],
imports: [
CommonModule,
@@ -39,7 +41,8 @@ import { AlarmCommentDialogComponent } from '@home/components/alarm/alarm-commen
exports: [
AlarmDetailsDialogComponent,
AlarmCommentComponent,
- AlarmCommentDialogComponent
+ AlarmCommentDialogComponent,
+ AlarmAssigneeComponent
]
})
export class SharedHomeComponentsModule { }