From 15703a7c0147388871ff84a3e3a5205c6f957172 Mon Sep 17 00:00:00 2001 From: rusikv Date: Mon, 6 Nov 2023 16:56:21 +0200 Subject: [PATCH 1/2] UI: improved usability of bulk operations in alarm widget table --- .../alarm/alarms-table-widget.component.ts | 83 +++++++++++-------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts index 034c131769..098f9a0939 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts @@ -888,12 +888,22 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, $event.stopPropagation(); } if (this.alarmsDatasource.selection.hasValue()) { - const alarmIds = this.alarmsDatasource.selection.selected.filter( - (alarmId) => alarmId !== NULL_UUID + const unacknowledgedAlarms = this.alarmsDatasource.selection.selected.filter( + (alarm) => alarm.id.id !== NULL_UUID && (alarm.status === AlarmStatus.CLEARED_UNACK || + alarm.status === AlarmStatus.ACTIVE_UNACK) ); - if (alarmIds.length) { - const title = this.translate.instant('alarm.aknowledge-alarms-title', {count: alarmIds.length}); - const content = this.translate.instant('alarm.aknowledge-alarms-text', {count: alarmIds.length}); + let title = ''; + let content = ''; + if (!unacknowledgedAlarms.length) { + title = this.translate.instant('alarm.selected-alarms', {count: unacknowledgedAlarms.length}); + content = this.translate.instant('alarm.selected-alarms-are-acknowledged'); + this.dialogService.alert( + title, + content + ).subscribe(); + } else { + title = this.translate.instant('alarm.aknowledge-alarms-title', {count: unacknowledgedAlarms.length}); + content = this.translate.instant('alarm.aknowledge-alarms-text', {count: unacknowledgedAlarms.length}); this.dialogService.confirm( title, content, @@ -901,16 +911,14 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, this.translate.instant('action.yes') ).subscribe((res) => { if (res) { - if (res) { - const tasks: Observable[] = []; - for (const alarmId of alarmIds) { - tasks.push(this.alarmService.ackAlarm(alarmId)); - } - forkJoin(tasks).subscribe(() => { - this.alarmsDatasource.clearSelection(); - this.subscription.update(); - }); + const tasks: Observable[] = []; + for (const alarm of unacknowledgedAlarms) { + tasks.push(this.alarmService.ackAlarm(alarm.id.id)); } + forkJoin(tasks).subscribe(() => { + this.alarmsDatasource.clearSelection(); + this.subscription.update(); + }); } }); } @@ -944,12 +952,22 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, $event.stopPropagation(); } if (this.alarmsDatasource.selection.hasValue()) { - const alarmIds = this.alarmsDatasource.selection.selected.filter( - (alarmId) => alarmId !== NULL_UUID + const activeAlarms = this.alarmsDatasource.selection.selected.filter( + (alarm) => alarm.id.id !== NULL_UUID && (alarm.status === AlarmStatus.ACTIVE_ACK || + alarm.status === AlarmStatus.ACTIVE_UNACK) ); - if (alarmIds.length) { - const title = this.translate.instant('alarm.clear-alarms-title', {count: alarmIds.length}); - const content = this.translate.instant('alarm.clear-alarms-text', {count: alarmIds.length}); + let title = ''; + let content = ''; + if (!activeAlarms.length) { + title = this.translate.instant('alarm.selected-alarms', {count: activeAlarms.length}); + content = this.translate.instant('alarm.selected-alarms-are-cleared'); + this.dialogService.alert( + title, + content + ).subscribe(); + } else { + title = this.translate.instant('alarm.clear-alarms-title', {count: activeAlarms.length}); + content = this.translate.instant('alarm.clear-alarms-text', {count: activeAlarms.length}); this.dialogService.confirm( title, content, @@ -957,16 +975,14 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, this.translate.instant('action.yes') ).subscribe((res) => { if (res) { - if (res) { - const tasks: Observable[] = []; - for (const alarmId of alarmIds) { - tasks.push(this.alarmService.clearAlarm(alarmId)); - } - forkJoin(tasks).subscribe(() => { - this.alarmsDatasource.clearSelection(); - this.subscription.update(); - }); + const tasks: Observable[] = []; + for (const alarm of activeAlarms) { + tasks.push(this.alarmService.clearAlarm(alarm.id.id)); } + forkJoin(tasks).subscribe(() => { + this.alarmsDatasource.clearSelection(); + this.subscription.update(); + }); } }); } @@ -1124,7 +1140,8 @@ class AlarmsDatasource implements DataSource { private alarmsSubject = new BehaviorSubject([]); private pageDataSubject = new BehaviorSubject>(emptyPageData()); - public selection = new SelectionModel(true, [], false); + public selection = new SelectionModel(true, [], false, + (alarm1: AlarmDataInfo, alarm2: AlarmDataInfo) => alarm1.id.id === alarm2.id.id); private selectionModeChanged = new EventEmitter(); @@ -1202,7 +1219,7 @@ class AlarmsDatasource implements DataSource { } if (this.selection.hasValue()) { const alarmIds = alarms.map((alarm) => alarm.id.id); - const toRemove = this.selection.selected.filter(alarmId => alarmIds.indexOf(alarmId) === -1); + const toRemove = this.selection.selected.filter(alarm => alarmIds.indexOf(alarm.id.id) === -1); this.selection.deselect(...toRemove); if (this.selection.isEmpty()) { isEmptySelection = true; @@ -1276,14 +1293,14 @@ class AlarmsDatasource implements DataSource { toggleSelection(alarm: AlarmDataInfo) { const hasValue = this.selection.hasValue(); - this.selection.toggle(alarm.id.id); + this.selection.toggle(alarm); if (hasValue !== this.selection.hasValue()) { this.onSelectionModeChanged(this.selection.hasValue()); } } isSelected(alarm: AlarmDataInfo): boolean { - return this.selection.isSelected(alarm.id.id); + return this.selection.isSelected(alarm); } clearSelection() { @@ -1304,7 +1321,7 @@ class AlarmsDatasource implements DataSource { } } else { alarms.forEach(row => { - this.selection.select(row.id.id); + this.selection.select(row); }); if (numSelected === 0) { this.onSelectionModeChanged(true); From 19fe327cabc52c3fbb7ab18df281e89068459f07 Mon Sep 17 00:00:00 2001 From: rusikv Date: Tue, 7 Nov 2023 12:13:04 +0200 Subject: [PATCH 2/2] UI: added acknowldged and cleared properties to alarm ts model --- .../modules/home/components/alarm/alarm-table-config.ts | 8 ++------ .../widget/lib/alarm/alarms-table-widget.component.ts | 6 ++---- ui-ngx/src/app/shared/models/alarm.models.ts | 4 ++++ 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-table-config.ts b/ui-ngx/src/app/modules/home/components/alarm/alarm-table-config.ts index 15e3fb1952..865a1b8c8b 100644 --- a/ui-ngx/src/app/modules/home/components/alarm/alarm-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-table-config.ts @@ -319,9 +319,7 @@ export class AlarmTableConfig extends EntityTableConfig if ($event) { $event.stopPropagation(); } - const unacknowledgedAlarms = alarms.filter(alarm => { - return alarm.status === AlarmStatus.CLEARED_UNACK || alarm.status === AlarmStatus.ACTIVE_UNACK; - }) + const unacknowledgedAlarms = alarms.filter(alarm => !alarm.acknowledged); let title = ''; let content = ''; if (!unacknowledgedAlarms.length) { @@ -356,9 +354,7 @@ export class AlarmTableConfig extends EntityTableConfig if ($event) { $event.stopPropagation(); } - const activeAlarms = alarms.filter(alarm => { - return alarm.status === AlarmStatus.ACTIVE_ACK || alarm.status === AlarmStatus.ACTIVE_UNACK; - }) + const activeAlarms = alarms.filter(alarm => !alarm.cleared); let title = ''; let content = ''; if (!activeAlarms.length) { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts index 098f9a0939..b5907f2bf2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/alarm/alarms-table-widget.component.ts @@ -889,8 +889,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, } if (this.alarmsDatasource.selection.hasValue()) { const unacknowledgedAlarms = this.alarmsDatasource.selection.selected.filter( - (alarm) => alarm.id.id !== NULL_UUID && (alarm.status === AlarmStatus.CLEARED_UNACK || - alarm.status === AlarmStatus.ACTIVE_UNACK) + alarm => alarm.id.id !== NULL_UUID && !alarm.acknowledged ); let title = ''; let content = ''; @@ -953,8 +952,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, } if (this.alarmsDatasource.selection.hasValue()) { const activeAlarms = this.alarmsDatasource.selection.selected.filter( - (alarm) => alarm.id.id !== NULL_UUID && (alarm.status === AlarmStatus.ACTIVE_ACK || - alarm.status === AlarmStatus.ACTIVE_UNACK) + alarm => alarm.id.id !== NULL_UUID && !alarm.cleared ); let title = ''; let content = ''; diff --git a/ui-ngx/src/app/shared/models/alarm.models.ts b/ui-ngx/src/app/shared/models/alarm.models.ts index 49f780beeb..71d64f2df1 100644 --- a/ui-ngx/src/app/shared/models/alarm.models.ts +++ b/ui-ngx/src/app/shared/models/alarm.models.ts @@ -102,6 +102,8 @@ export interface Alarm extends BaseData { originator: EntityId; severity: AlarmSeverity; status: AlarmStatus; + acknowledged: boolean; + cleared: boolean; startTs: number; endTs: number; ackTs: number; @@ -181,6 +183,8 @@ export const simulatedAlarm: AlarmInfo = { type: 'TEMPERATURE', severity: AlarmSeverity.MAJOR, status: AlarmStatus.ACTIVE_UNACK, + acknowledged: false, + cleared: false, details: { message: 'Temperature is high!' },