File

alarms/alarm-details.component.ts

Implements

OnChanges

Metadata

Index

Properties
Methods
Inputs

Constructor

constructor(alarmDetailsService: AlarmDetailsService, alarmService: AlarmService, alertService: AlertService, appState: AppStateService, auditService: AuditService, relativeTime: RelativeTimePipe, ng1SmartRulesUpgradeService: Ng1SmartRulesUpgradeService, translateService: TranslateService, inventoryService: InventoryService, alarmsViewService: AlarmsViewService, colorService: ColorService)
Parameters :
Name Type Optional
alarmDetailsService AlarmDetailsService No
alarmService AlarmService No
alertService AlertService No
appState AppStateService No
auditService AuditService No
relativeTime RelativeTimePipe No
ng1SmartRulesUpgradeService Ng1SmartRulesUpgradeService No
translateService TranslateService No
inventoryService InventoryService No
alarmsViewService AlarmsViewService No
colorService ColorService No

Inputs

hasAnyRoleAllowingToCreateSmartRule
Type : boolean
isSmartRulesServiceSubscribed
Type : boolean
selectedAlarm
Type : IAlarm

Methods

createSmartRule
createSmartRule()
Returns : void
Async detailsButtonAction
detailsButtonAction(button: AlarmDetailsButton, alarm: IAlarm)
Parameters :
Name Type Optional
button AlarmDetailsButton No
alarm IAlarm No
Returns : Promise<void>
Async goToAlarmSource
goToAlarmSource(sourceId: string | number)

Navigates to a specific alarm source device based on the provided source.

Parameters :
Name Type Optional Description
sourceId string | number No
  • The source id.
Returns : Promise<void>
Async ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges No
Returns : Promise<void>
Async ngOnInit
ngOnInit()
Returns : Promise<void>
Async onUpdateDetails
onUpdateDetails(status: AlarmStatusType)
Parameters :
Name Type Optional
status AlarmStatusType No
Returns : Promise<void>
Async reloadAuditLog
reloadAuditLog(isRevert, isSetAuditLogs)

Reloads audit log data asynchronously.

This method fetches audit records using getAlarmAuditRecords and optionally updates the audit logs state in the component based on the isSetAuditLogs flag. It handles the loading state and potential errors during the fetch operation.

Example :
              or only record, that chronologically will be the oldest one (false). Defaults to true.
              If set to false, it will set PAGE_SIZE to 1 and trigger a logic
              concatenating a most recent record with the very first one to
              calculate the alarm duration (change to CLEARED status).
              It's passed to the `getAlarmAuditRecords` method.
Parameters :
Name Optional Default value Description
isRevert No true
  • A boolean flag indicating whether to retrieve a 100 (see PAGE_SIZE) records (true) or only record, that chronologically will be the oldest one (false). Defaults to true. If set to false, it will set PAGE_SIZE to 1 and trigger a logic concatenating a most recent record with the very first one to calculate the alarm duration (change to CLEARED status). It's passed to the getAlarmAuditRecords method.
isSetAuditLogs No false
  • A boolean flag to determine if the fetched audit logs should be set in the component state. Defaults to false.
Returns : Promise<IResultList<IAuditRecord>>

A promise that resolves to a list of IAuditRecord objects.

Properties

Readonly ACKNOWLEDGE_LABEL
Default value : gettext('Acknowledge')
Readonly ACKNOWLEDGED_STATUS_VALUE
Default value : AlarmStatus.ACKNOWLEDGED
Readonly ACTIVE_STATUS_VALUE
Default value : AlarmStatus.ACTIVE
auditLog
Type : IResultList<IAuditRecord>

Property contains a 100 (see PAGE_SIZE) of most recent audit logs records.

Readonly BELL_ICON
Default value : ALARM_STATUS_ICON.BELL
Readonly BELL_SLASH_ICON
Default value : ALARM_STATUS_ICON.BELL_SLASH
Readonly CLEARED_STATUS_VALUE
Default value : AlarmStatus.CLEARED
customFragments
Type : CustomFragment
Default value : null

Custom fragments of the selected alarm. If none exist, null is returned.

isAlarmStatusChanging
Default value : false

Indicates when alarms status change was started (Acknowledge/Reactivate)

isCreateSmartRulesButtonAvailable
Type : boolean

Prevents the pipeline from failing for a tutorial application because it's a pure Angular application and doesn't support any AngularJS services.

isLoading
Type : boolean
lastUpdated
Type : string

Represents a value for a 'Last updated' section in details.

Readonly linkTitle
Default value : gettext('Open in {{ appName }}')
Readonly REACTIVATE_LABEL
Default value : gettext('Reactivate')
selectedAlarmMO
Type : IManagedObject
Readonly SEVERITY_LABELS
Default value : SEVERITY_LABELS
showSourceNavigationLink
Default value : false

Manages the visibility of the navigation link. If set to true, the link is visible, otherwise, it remains hidden.

statusMessage
Type : string

Represents a value for a 'Status' section in details.

typeColor
Type : string

The color of the alarm type.

userDeviceManagementApp
Type : IApplication

Represents a Device Management application used by the user. Determines the accurate name and context path required for navigating to alarms of the current device

<div class="d-flex row tight-grid flex-wrap a-i-stretch">
  <div class="col-xs-12 col-md-6 d-flex p-b-8">
    <div class="border-all fit-w d-flex">
      <div class="p-8">
        <i
          class="icon-24 text-gray-dark m-t-4 c8y-icon"
          [c8yIcon]="selectedAlarm.status | AlarmStatusToIcon"
        ></i>
      </div>
      <div class="p-t-8 p-b-8 p-r-8">
        <p class="text-label-small m-b-0 m-r-8">{{ 'Status' | translate }}</p>
        <p class="small">{{ statusMessage }}</p>
      </div>
    </div>
  </div>
  <div class="col-xs-12 col-md-6 d-flex p-b-8">
    <div class="border-all fit-w d-flex">
      <div class="p-8">
        <i
          class="icon-24 text-gray-dark m-t-4 stroked-icon status"
          [c8yIcon]="selectedAlarm.severity | AlarmSeverityToIcon"
          [ngClass]="selectedAlarm.severity?.toString() | lowercase"
        ></i>
      </div>
      <div class="p-t-8 p-b-8 p-r-8">
        <p class="text-label-small m-b-0 m-r-8">{{ 'Severity' | translate }}</p>
        <p class="small">{{ SEVERITY_LABELS[selectedAlarm.severity] | translate }}</p>
      </div>
    </div>
  </div>
  <div class="col-xs-12 col-md-6 d-flex p-b-8">
    <div class="border-all fit-w d-flex">
      <div class="p-8">
        <i
          class="icon-24 text-gray-dark m-t-4 stroked-icon status"
          c8yIcon="contactless-payment"
        ></i>
      </div>
      <div class="p-t-8 p-b-8 p-r-8">
        <p class="text-label-small m-b-0 m-r-8">{{ 'Source' | translate }}</p>
        <p class="small">
          <button
            class="btn-link text-muted p-0 m-r-8"
            title="{{ selectedAlarm.source.name }}"
            type="button"
            routerLink="{{ selectedAlarmMO | assetLink }}"
          >
            <small class="icon-flex">
              <i c8yIcon="exchange"></i>
              {{ selectedAlarm.source.name || selectedAlarm.source.id }}
            </small>
          </button>
          <ng-container *ngIf="showSourceNavigationLink">
            <button
              class="btn-link p-0"
              title="{{
                linkTitle
                  | translate: { appName: userDeviceManagementApp | humanizeAppName | async }
              }}"
              type="button"
              (click)="goToAlarmSource(selectedAlarm.id)"
              data-cy="alarm-details-device-management-link"
            >
              {{ userDeviceManagementApp | humanizeAppName | async }}
              <i c8yIcon="external-link"></i>
            </button>
          </ng-container>
        </p>
      </div>
    </div>
  </div>
  <div class="col-xs-12 col-md-6 d-flex p-b-8">
    <div class="border-all fit-w d-flex">
      <div class="p-8">
        <span
          class="circle-icon-wrapper"
          [ngStyle]="{ 'background-color': typeColor }"
        >
          <i
            class="stroked-icon"
            c8yIcon="bell"
          ></i>
        </span>
      </div>
      <div class="p-t-8 p-b-8 p-r-8 min-width-0">
        <p class="text-label-small m-b-0 m-r-8">{{ 'Type' | translate }}</p>
        <p
          class="small text-truncate"
          title="{{ selectedAlarm.type }}"
        >
          <code>{{ selectedAlarm.type }}</code>
        </p>
      </div>
    </div>
  </div>

  <div class="col-xs-12 col-md-12 p-b-16">
    <div class="border-all fit-w d-flex">
      <div class="p-8">
        <i
          class="icon-24 text-gray-dark m-t-4"
          c8yIcon="calendar"
        ></i>
      </div>
      <div class="p-t-8 p-b-0 p-r-8 flex-grow">
        <div class="content-flex-50">
          <div class="col-4 p-b-8">
            <p class="text-label-small m-b-0 m-r-8">{{ 'Last updated' | translate }}</p>
            <p class="small">
              {{ lastUpdated | c8yDate: 'medium' }}
            </p>
          </div>
          <div
            class="col-4 p-b-8"
            *ngIf="selectedAlarm.count > 1"
          >
            <p class="text-label-small m-b-0 m-r-8">{{ 'Number of occurrences' | translate }}</p>
            <p>
              <span class="badge badge-info">{{ selectedAlarm.count }}</span>
            </p>
          </div>
          <div
            class="col-4 p-b-8"
            *ngIf="selectedAlarm.count > 1"
          >
            <p class="text-label-small m-b-0 m-r-8">{{ 'First occurrence' | translate }}</p>
            <p class="small">
              {{ selectedAlarm.creationTime | c8yDate: 'medium' }}
            </p>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div
    class="col-xs-12 col-md-12 p-b-16"
    *ngIf="customFragments"
  >
    <div class="border-all fit-w d-flex">
      <div class="p-8">
        <i
          class="icon-24 text-gray-dark m-t-4"
          c8yIcon="outgoing-data"
        ></i>
      </div>
      <div
        class="p-t-8 p-b-0 p-r-8 flex-grow"
        data-cy="alarm-details-custom-data"
      >
        <p class="text-label-small m-b-4 m-r-8">{{ 'Custom data' | translate }}</p>
        <pre><code>{{ customFragments | json }}</code></pre>
      </div>
    </div>
  </div>
</div>

<div class="d-flex flex-wrap gap-8">
  <button
    class="btn btn-default btn-sm"
    [title]="'Reload audit logs' | translate"
    type="submit"
    (click)="reloadAuditLog(true, true)"
  >
    <i
      c8yIcon="refresh"
      [ngClass]="{ 'icon-spin': isLoading }"
    ></i>
    {{ 'Reload audit logs' | translate }}
  </button>

  <button
    class="btn btn-default btn-sm"
    [title]="
      selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE
        ? (ACKNOWLEDGE_LABEL | translate)
        : (REACTIVATE_LABEL | translate)
    "
    type="submit"
    (click)="
      onUpdateDetails(
        selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE
          ? ACKNOWLEDGED_STATUS_VALUE
          : ACTIVE_STATUS_VALUE
      )
    "
    [disabled]="selectedAlarm.status === CLEARED_STATUS_VALUE || isAlarmStatusChanging"
  >
    <i
      [c8yIcon]="selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE ? BELL_SLASH_ICON : BELL_ICON"
    ></i>
    {{
      selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE
        ? (ACKNOWLEDGE_LABEL | translate)
        : (REACTIVATE_LABEL | translate)
    }}
  </button>

  <button
    class="btn btn-default btn-sm"
    [title]="'Create smart rule' | translate"
    type="submit"
    *ngIf="isCreateSmartRulesButtonAvailable"
    (click)="createSmartRule()"
  >
    <i c8yIcon="c8y-icon c8y-icon-smart-rules"></i>
    {{ 'Create smart rule' | translate }}
  </button>
  <button
    class="btn btn-default btn-sm"
    [title]="'Clear`alarm`' | translate"
    type="submit"
    (click)="onUpdateDetails(CLEARED_STATUS_VALUE)"
    [disabled]="selectedAlarm.status === CLEARED_STATUS_VALUE"
  >
    <i c8yIcon="c8y-alert-idle"></i>
    {{ 'Clear`alarm`' | translate }}
  </button>

  <button
    *ngFor="let button of selectedAlarm | alarmDetailsButton: selectedAlarmMO | async"
    class="btn btn-default btn-sm"
    [ngClass]="button.additionalButtonClasses"
    [title]="button.title | translate"
    type="button"
    (click)="detailsButtonAction(button, selectedAlarm)"
    [disabled]="button.disabled"
  >
    <i [ngClass]="button.additionalIconClasses" [c8yIcon]="button.icon"></i>
    <span *ngIf="button.label">{{ button.label | translate }}</span>
  </button>
</div>

<ng-template #noAuditLogAvailable>
  <div class="p-16">
    <c8y-ui-empty-state
      [icon]="'archive'"
      [title]="'No audit logs found.' | translate"
      [horizontal]="true"
    ></c8y-ui-empty-state>
  </div>
</ng-template>

<div class="legend form-block">{{ 'Audit logs' | translate }}</div>

<ng-container *ngIf="isLoading || auditLog?.data.length; else noAuditLogAvailable">
  <c8y-loading *ngIf="isLoading"></c8y-loading>

  <c8y-list-group
    data-cy="c8y-alarms-details--audit-logs"
    *ngIf="!isLoading"
  >
    <c8y-li-timeline *c8yFor="let log of auditLog; loadMore: 'hidden'">
      {{ log.creationTime | date: 'mediumDate' }}
      {{ log.creationTime | date: 'mediumTime' }}
      <c8y-li>
        <c8y-li-body>
          <p class="text-truncate-wrap separator-bottom p-b-4">
            {{ log | auditChangesMessage }}
          </p>
          <div class="c8y-list__item__footer">
            <span
              class="m-r-16 small"
              *ngIf="log.user"
            >
              <span class="text-label-small">
                {{ 'by`user`' | translate }}
              </span>
              {{ log.user }}
            </span>
            <span class="small">
              <span class="text-label-small">
                {{ 'device time' | translate }}
              </span>
              {{ log.time | c8yDate: 'medium' }}
            </span>
          </div>
        </c8y-li-body>
      </c8y-li>
    </c8y-li-timeline>
  </c8y-list-group>
</ng-container>

results matching ""

    No results matching ""