Merge pull request #9569 from rusikv/enhancement/alarm-table-widget
Improved usability of bulk operations in alarm widget table
This commit is contained in:
		
						commit
						c7d992155e
					
				@ -319,9 +319,7 @@ export class AlarmTableConfig extends EntityTableConfig<AlarmInfo, TimePageLink>
 | 
			
		||||
    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<AlarmInfo, TimePageLink>
 | 
			
		||||
    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) {
 | 
			
		||||
 | 
			
		||||
@ -896,12 +896,21 @@ 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.acknowledged
 | 
			
		||||
      );
 | 
			
		||||
      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,
 | 
			
		||||
@ -909,16 +918,14 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
 | 
			
		||||
          this.translate.instant('action.yes')
 | 
			
		||||
        ).subscribe((res) => {
 | 
			
		||||
          if (res) {
 | 
			
		||||
            if (res) {
 | 
			
		||||
              const tasks: Observable<AlarmInfo>[] = [];
 | 
			
		||||
              for (const alarmId of alarmIds) {
 | 
			
		||||
                tasks.push(this.alarmService.ackAlarm(alarmId));
 | 
			
		||||
              }
 | 
			
		||||
              forkJoin(tasks).subscribe(() => {
 | 
			
		||||
                this.alarmsDatasource.clearSelection();
 | 
			
		||||
                this.subscription.update();
 | 
			
		||||
              });
 | 
			
		||||
            const tasks: Observable<AlarmInfo>[] = [];
 | 
			
		||||
            for (const alarm of unacknowledgedAlarms) {
 | 
			
		||||
              tasks.push(this.alarmService.ackAlarm(alarm.id.id));
 | 
			
		||||
            }
 | 
			
		||||
            forkJoin(tasks).subscribe(() => {
 | 
			
		||||
              this.alarmsDatasource.clearSelection();
 | 
			
		||||
              this.subscription.update();
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
@ -952,12 +959,21 @@ 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.cleared
 | 
			
		||||
      );
 | 
			
		||||
      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,
 | 
			
		||||
@ -965,16 +981,14 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
 | 
			
		||||
          this.translate.instant('action.yes')
 | 
			
		||||
        ).subscribe((res) => {
 | 
			
		||||
          if (res) {
 | 
			
		||||
            if (res) {
 | 
			
		||||
              const tasks: Observable<AlarmInfo>[] = [];
 | 
			
		||||
              for (const alarmId of alarmIds) {
 | 
			
		||||
                tasks.push(this.alarmService.clearAlarm(alarmId));
 | 
			
		||||
              }
 | 
			
		||||
              forkJoin(tasks).subscribe(() => {
 | 
			
		||||
                this.alarmsDatasource.clearSelection();
 | 
			
		||||
                this.subscription.update();
 | 
			
		||||
              });
 | 
			
		||||
            const tasks: Observable<AlarmInfo>[] = [];
 | 
			
		||||
            for (const alarm of activeAlarms) {
 | 
			
		||||
              tasks.push(this.alarmService.clearAlarm(alarm.id.id));
 | 
			
		||||
            }
 | 
			
		||||
            forkJoin(tasks).subscribe(() => {
 | 
			
		||||
              this.alarmsDatasource.clearSelection();
 | 
			
		||||
              this.subscription.update();
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
@ -1132,7 +1146,8 @@ class AlarmsDatasource implements DataSource<AlarmDataInfo> {
 | 
			
		||||
  private alarmsSubject = new BehaviorSubject<AlarmDataInfo[]>([]);
 | 
			
		||||
  private pageDataSubject = new BehaviorSubject<PageData<AlarmDataInfo>>(emptyPageData<AlarmDataInfo>());
 | 
			
		||||
 | 
			
		||||
  public selection = new SelectionModel<string>(true, [], false);
 | 
			
		||||
  public selection = new SelectionModel<AlarmDataInfo>(true, [], false,
 | 
			
		||||
    (alarm1: AlarmDataInfo, alarm2: AlarmDataInfo) => alarm1.id.id === alarm2.id.id);
 | 
			
		||||
 | 
			
		||||
  private selectionModeChanged = new EventEmitter<boolean>();
 | 
			
		||||
 | 
			
		||||
@ -1210,7 +1225,7 @@ class AlarmsDatasource implements DataSource<AlarmDataInfo> {
 | 
			
		||||
    }
 | 
			
		||||
    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;
 | 
			
		||||
@ -1284,14 +1299,14 @@ class AlarmsDatasource implements DataSource<AlarmDataInfo> {
 | 
			
		||||
 | 
			
		||||
  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() {
 | 
			
		||||
@ -1312,7 +1327,7 @@ class AlarmsDatasource implements DataSource<AlarmDataInfo> {
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          alarms.forEach(row => {
 | 
			
		||||
            this.selection.select(row.id.id);
 | 
			
		||||
            this.selection.select(row);
 | 
			
		||||
          });
 | 
			
		||||
          if (numSelected === 0) {
 | 
			
		||||
            this.onSelectionModeChanged(true);
 | 
			
		||||
 | 
			
		||||
@ -102,6 +102,8 @@ export interface Alarm extends BaseData<AlarmId> {
 | 
			
		||||
  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!'
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user