File

alarms/alarm-details.component.ts

Implements

OnInit OnChanges OnDestroy

Metadata

Index

Properties
Methods
Inputs
HostListeners

Constructor

constructor(alarmDetailsService: AlarmDetailsService, alarmService: AlarmService, alertService: AlertService, appState: AppStateService, auditService: AuditService, relativeTime: RelativeTimePipe, ng1SmartRulesUpgradeService: Ng1SmartRulesUpgradeService, translateService: TranslateService, inventoryService: InventoryService, alarmsViewService: AlarmsViewService, colorService: ColorService, interAppService: InterAppService, gainsightService: GainsightService, alarmsActivityTrackerService: AlarmsActivityTrackerService)
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
interAppService InterAppService No
gainsightService GainsightService No
alarmsActivityTrackerService AlarmsActivityTrackerService No

Inputs

hiddenActions
Type : literal type

Configure which individual actions to hide in the alarm details view. Only applies when showActions=true. Set a property to true to hide that action.

Example :
<!-- Hide specific actions -->
<c8y-alarm-details [hiddenActions]="{ createSmartRule: true }">
hiddenSections
Type : literal type

Configure which individual sections to hide in the alarm details view. Only applies when showSections=true. Set a property to true to hide that section.

Example :
<!-- Hide specific sections -->
<c8y-alarm-details [hiddenSections]="{ source: true, type: true, auditLogs: true }">
selectedAlarm
Type : IAlarm
showActions
Type : boolean
Default value : true

Master switch to show/hide ALL action buttons (default: true). When false, all actions are hidden regardless of hiddenActions. When true, use hiddenActions for granular control of individual actions.

Priority: showActions takes precedence over hiddenActions.

showExternalNavigation
Type : boolean
Default value : true

Whether to show external navigation links (default: true)

showSections
Type : boolean
Default value : true

Master switch to show/hide ALL alarm details sections (default: true). When false, all sections are hidden regardless of hiddenSections. When true, use hiddenSections for granular control of individual sections.

Priority: showSections takes precedence over hiddenSections.

HostListeners

document:visibilitychange
document:visibilitychange()

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>
ngOnDestroy
ngOnDestroy()
Returns : 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: unknown, isSetAuditLogs: unknown)

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 Type Optional Default value Description
isRevert unknown 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 unknown 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.

visibilityChange
visibilityChange()
Decorators :
@HostListener('document:visibilitychange')
Returns : void

Properties

Readonly ACKNOWLEDGE_LABEL
Type : unknown
Default value : gettext('Acknowledge')
Readonly ACKNOWLEDGED_STATUS_VALUE
Type : unknown
Default value : AlarmStatus.ACKNOWLEDGED
Readonly ACTIVE_STATUS_VALUE
Type : unknown
Default value : AlarmStatus.ACTIVE
alarmActions
Type : SplitViewAction[]
Default value : []

Cached alarm actions to prevent constant re-rendering

alarmInfoSections
Type : IconPanelSection[]
Default value : []

Cached alarm info sections to prevent constant re-rendering

auditLog
Type : IResultList<IAuditRecord>

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

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

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

deviceManagementAppKey
Type : SupportedAppKey
Default value : SupportedApps.devicemanagement
isAlarmStatusChanging
Type : unknown
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
Readonly linkTitle
Type : unknown
Default value : gettext('Open in {{ appName }}')
Readonly PRODUCT_EXPERIENCE_ALARMS
Type : unknown
Default value : PRODUCT_EXPERIENCE_ALARMS
Readonly REACTIVATE_LABEL
Type : unknown
Default value : gettext('Reactivate')
selectedAlarmMO
Type : IManagedObject
Readonly SEVERITY_LABELS
Type : unknown
Default value : SEVERITY_LABELS
showSourceNavigationLink$
Type : Observable<boolean>

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 : Observable<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

@if (selectedAlarm) {
  <div
    class="card-header p-24 m-b-16 bg-component separator-bottom sticky-top"
    style="margin: 0 -24px"
  >
    <h4
      class="m-0"
      data-cy="c8y-alarm-details-title"
    >
      {{ selectedAlarm.text | translate }}
    </h4>
  </div>
}

<c8y-icon-panel [sections]="alarmInfoSections">
  @if (showSections && !hiddenSections?.source) {
    <div
      class="col-xs-12 col-md-6 d-flex p-b-8"
      data-cy="c8y-alarm-details--source-wrapper"
    >
      <div class="border-all fit-w d-flex">
        <div class="p-8">
          <i
            class="icon-24 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 text-left"
              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>
            @if (showSourceNavigationLink$ | async) {
              <button
                class="btn-link p-0 text-left"
                title="{{
                  linkTitle
                    | translate
                      : { appName: userDeviceManagementApp$ | async | humanizeAppName | async }
                }}"
                type="button"
                (click)="goToAlarmSource(selectedAlarm?.id)"
                data-cy="alarm-details-device-management-link"
              >
                {{ userDeviceManagementApp$ | async | humanizeAppName | async }}
                <i c8yIcon="external-link"></i>
              </button>
            }
          </p>
        </div>
      </div>
    </div>
  }

  @if (showSections && !hiddenSections?.type) {
    <div
      class="col-xs-12 col-md-6 d-flex p-b-8"
      data-cy="c8y-alarm-details--severity-type-wrapper"
    >
      <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"
          data-cy="c8y-alarm-details--last-updated-icon"
        ></i>
      </div>
      <div class="p-t-8 p-b-0 p-r-8 flex-grow">
        <div class="content-flex-50">
          @if (selectedAlarm?.count > 1 && showSections && !hiddenSections?.occurrenceCount) {
            <div
              class="col-4 p-b-8"
              data-cy="c8y-alarm-details--number-of-occurrences-wrapper"
            >
              <p class="text-label-small m-b-0 m-r-8">
                {{ 'Number of occurrences' | translate }}
              </p>
              <p>
                <span
                  class="badge badge-info"
                  data-cy="c8y-alarm-details--badge"
                >
                  {{ selectedAlarm?.count }}
                </span>
              </p>
            </div>
          }
          @if (selectedAlarm?.count > 1 && showSections && !hiddenSections?.firstOccurrence) {
            <div
              class="col-4 p-b-8"
              data-cy="c8y-alarm-details--first-occurrence-wrapper"
            >
              <p class="text-label-small m-b-0 m-r-8">{{ 'First occurrence' | translate }}</p>
              <p class="small">
                {{ selectedAlarm?.creationTime | c8yDate: 'medium' }}
                <button
                  class="btn-help btn-help--sm"
                  [attr.aria-label]="'Help' | translate"
                  popover="{{
                    'Time in which the alarm was created. The time shown corresponds to the server\'s time. Device time can be different from server time.'
                      | translate
                  }}"
                  placement="right"
                  triggers="focus"
                  container="body"
                  type="button"
                ></button>
              </p>
            </div>
          }
          @if (showSections && !hiddenSections?.lastOccurrence) {
            <div
              class="col-4 p-b-8"
              data-cy="c8y-alarm-details--last-updated-wrapper"
            >
              <p class="text-label-small m-b-0 m-r-8">{{ 'Last occurrence' | translate }}</p>
              <p class="small">
                {{ selectedAlarm?.lastUpdated | c8yDate: 'medium' }}
                <button
                  class="btn-help btn-help--sm"
                  [attr.aria-label]="'Help' | translate"
                  popover="{{
                    'Time in which the alarm was last updated. The time shown corresponds to the server\'s time. Device time can be different from server time.'
                      | translate
                  }}"
                  placement="right"
                  triggers="focus"
                  container="body"
                  type="button"
                ></button>
              </p>
            </div>
          }
        </div>
      </div>
    </div>
  </div>

  @if (customFragments && showSections && !hiddenSections?.customData) {
    <div
      class="col-xs-12 col-md-12 p-b-16"
      data-cy="c8y-alarm-details--custom-fragments-wrapper"
    >
      <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>
  }
</c8y-icon-panel>

@if (showActions) {
  <c8y-sv-details-actions [actions]="alarmActions">
    @for (button of selectedAlarm | alarmDetailsButton: selectedAlarmMO | async; track $index) {
      <button
        class="btn btn-default btn-sm no-swing"
        [title]="button.title | translate"
        type="button"
        [ngClass]="button.additionalButtonClasses"
        (click)="detailsButtonAction(button, selectedAlarm!)"
        [disabled]="button.disabled"
      >
        <i
          [c8yIcon]="button.icon"
          [ngClass]="button.additionalIconClasses"
        ></i>
        @if (button.label) {
          <span>{{ button.label | translate }}</span>
        }
      </button>
    }
  </c8y-sv-details-actions>
}

@if (showSections && !hiddenSections?.auditLogs) {
  <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>
    <div class="legend form-block">{{ 'Audit logs' | translate }}</div>

    @if (isLoading || auditLog?.data.length) {
      @if (isLoading) {
        <c8y-loading></c8y-loading>
      }

      @if (!isLoading) {
        <c8y-list-group data-cy="c8y-alarms-details--audit-logs">
          <c8y-li-timeline *c8yFor="let log of auditLog; loadMore: 'hidden'">
            {{ log.creationTime | c8yDate: 'mediumDate' }}
            {{ log.creationTime | c8yDate: '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">
                  @if (log.user) {
                    <span class="m-r-16 small">
                      <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>
      }
    } @else {
      <ng-container [ngTemplateOutlet]="noAuditLogAvailable"></ng-container>
    }
  </div>
}

results matching ""

    No results matching ""