UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

2,677 lines 246 kB
import * as i0 from '@angular/core';
import { Injectable, Pipe, InjectionToken, HostListener, Input, Optional, Component, EventEmitter, ViewChild, Output, ChangeDetectionStrategy, forwardRef, signal, NgModule } from '@angular/core';
import { combineLatest, Subject, BehaviorSubject, fromEvent, firstValueFrom, of, from, forkJoin, EMPTY, Observable, pipe, take, takeUntil as takeUntil$1, map as map$1 } from 'rxjs';
import { filter, map, switchMap, startWith, debounceTime, takeUntil, distinctUntilChanged, catchError, finalize, tap, shareReplay, throttleTime } from 'rxjs/operators';
import * as i3 from '@c8y/ngx-components';
import { Permissions, ViewContext, SupportedApps, IconDirective, ProductExperienceDirective, EmptyStateComponent, LoadingComponent, ListGroupComponent, ForOfDirective, ListItemTimelineComponent, ListItemComponent, ListItemBodyComponent, C8yTranslatePipe, DatePipe, HumanizeAppNamePipe, AssetLinkPipe, TitleComponent, TabsOutletComponent, RequiredInputPlaceholderDirective, CountdownIntervalComponent, DynamicComponentAlertAggregator, DynamicComponentAlert, C8yTranslateDirective, ListItemIconComponent, GuideDocsComponent, GuideHrefDirective, DynamicComponentAlertsComponent, DropdownDirectionDirective, FormGroupComponent, DateTimePickerComponent, MessagesComponent, MessageDirective, ListItemCheckboxComponent, ActionBarItemComponent, HelpComponent, AlarmWithChildrenRealtimeService, RouterTabsResolver, ContextRouteGuard, ContextRouteComponent, hookNavigator, hookRoute, CommonModule, CoreModule, HeaderModule, C8yTranslateModule, DynamicComponentModule, RelativeTimePipe } from '@c8y/ngx-components';
import { sortBy, cloneDeep } from 'lodash-es';
import * as i2 from '@c8y/client';
import { AlarmStatus, Severity, ALARM_STATUS_LABELS, SEVERITY_LABELS } from '@c8y/client';
import { gettext } from '@c8y/ngx-components/gettext';
import * as i1$1 from '@ngx-translate/core';
import { INTERVAL_TITLES, INTERVALS, IntervalPickerComponent } from '@c8y/ngx-components/interval-picker';
import * as i1 from '@angular/router';
import { RouterLink, NavigationEnd, RouterLinkActive, RouterOutlet, RouterModule } from '@angular/router';
import * as i3$1 from '@c8y/ngx-components/global-context';
import { NgClass, NgIf, NgStyle, NgFor, AsyncPipe, LowerCasePipe, JsonPipe, TitleCasePipe } from '@angular/common';
import { PopoverDirective, PopoverModule } from 'ngx-bootstrap/popover';
import * as i1$2 from '@angular/forms';
import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { BsDropdownDirective, BsDropdownToggleDirective, BsDropdownMenuDirective, BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { CdkTrapFocus, A11yModule } from '@angular/cdk/a11y';
import * as i1$4 from 'ngx-bootstrap/tooltip';
import { TooltipDirective, TooltipModule } from 'ngx-bootstrap/tooltip';
import * as i1$3 from '@c8y/ngx-components/alarm-event-selector';
import { AlarmEventSelectorModule } from '@c8y/ngx-components/alarm-event-selector';

/**
 * A service to retrieve custom buttons for the alarm details view.
 */
class AlarmDetailsButtonService {
    constructor(serviceRegistry, pluginsResolver) {
        this.serviceRegistry = serviceRegistry;
        this.pluginsResolver = pluginsResolver;
    }
    get$(alarm, source) {
        const providers$ = this.pluginsResolver.allPluginsLoaded$.pipe(filter(Boolean), map(() => {
            return this.serviceRegistry.get('alarmDetailsButton');
        }));
        return providers$.pipe(switchMap(providers => {
            const observables$ = providers.map(provider => provider.getAlarmDetailsButton$(alarm, source).pipe(startWith(false)));
            return combineLatest(observables$);
        }), map(indicators => {
            return indicators.filter(Boolean);
        }), map(indicators => sortBy(indicators, this.byPriority)));
    }
    byPriority(item) {
        if (item.priority === undefined) {
            return 0;
        }
        return -item.priority;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsButtonService, deps: [{ token: i3.ServiceRegistry }, { token: i3.PluginsResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsButtonService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsButtonService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: () => [{ type: i3.ServiceRegistry }, { type: i3.PluginsResolveService }] });

/**
 * A pipe to provide custom buttons for the alarm details view.
 *
 * Will call `get$()` method of `AlarmDetailsButtonService` to get the custom buttons for the provided alarm.
 */
class AlarmDetailsButtonPipe {
    constructor(alarmDetailsButtonService) {
        this.alarmDetailsButtonService = alarmDetailsButtonService;
    }
    transform(alarm, source) {
        return this.alarmDetailsButtonService.get$(alarm, source);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsButtonPipe, deps: [{ token: AlarmDetailsButtonService }], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsButtonPipe, isStandalone: true, name: "alarmDetailsButton" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsButtonPipe, decorators: [{
            type: Pipe,
            args: [{
                    standalone: true,
                    name: 'alarmDetailsButton',
                    pure: true
                }]
        }], ctorParameters: () => [{ type: AlarmDetailsButtonService }] });

class AlarmDetailsService {
    constructor(permissions) {
        this.permissions = permissions;
        this.STATUS_ATTRIBUTE = 'status';
    }
    /**
     * Retrieves the username of the user who acknowledged an alarm status.
     *
     * This method checks if the provided status is equal to the acknowledged
     * status. If it is not, or if the
     * audit log is empty or the first log item does not contain a user, the
     * method returns a default value ('--').
     *
     * If the status is the acknowledged status and the audit log contains valid
     * records, the method iterates over the audit records in reverse order
     * (starting from the most recent). It finds the first record where the
     * status attribute (defined by this.STATUS_ATTRIBUTE) has been changed to
     * the acknowledged status. The method then returns the username of the user
     * who made this change.
     *
     * If no such change is found in the audit records, it returns the username
     * from the first record of the audit log.
     *
     * There can be multiple audit logs with ACKNOWLEDGED status.
     *
     * @param status - The current status of the alarm.
     * @param auditLog - An array of audit records to process.
     * @returns The username of the user who acknowledged the status
     *           or '--' if the status is not acknowledged or audit log is invalid.
     */
    getAcknowledgedBy(status, auditLog) {
        let acknowledgedBy = '--';
        if (status !== AlarmStatus.ACKNOWLEDGED || !auditLog || !auditLog[0]?.user) {
            return acknowledgedBy;
        }
        acknowledgedBy = auditLog[0].user;
        return auditLog.reduceRight((acc, auditLogItem) => {
            const changes = Array.from(auditLogItem.changes || []);
            const acknowledgedStatusChange = changes.find((change) => change.attribute === this.STATUS_ATTRIBUTE && change.newValue === AlarmStatus.ACKNOWLEDGED);
            return (acknowledgedStatusChange && auditLogItem.user) || acc;
        }, acknowledgedBy);
    }
    /**
     * Calculates the acknowledge time from a list of audit records.
     *
     * This method iterates over the provided audit records in reverse order
     * (starting from the most recent) and finds the first record where a
     * specific status attribute (defined by this.STATUS_ATTRIBUTE) has been
     * acknowledged. It then returns the creation time of that record.
     *
     * If no such record is found, the method returns the creation time of the
     * first audit record. If the audit record list is empty, it returns null.
     *
     * There can be multiple audit logs with ACKNOWLEDGED status.
     *
     * @param auditLog - An array of audit records to process.
     * @returns The creation time of the acknowledged record,
     *           the creation time of the first record if no acknowledged record is found,
     *           or null if the audit log is empty.
     */
    getAcknowledgeTime(auditLog) {
        const initialValue = auditLog.length ? auditLog[0].creationTime : null;
        return auditLog.reduceRight((acc, auditLogItem) => {
            const changes = Array.from(auditLogItem.changes || []);
            const acknowledgedStatusChange = changes.find((change) => change.attribute === this.STATUS_ATTRIBUTE && change.newValue === AlarmStatus.ACKNOWLEDGED);
            return acknowledgedStatusChange ? auditLogItem.creationTime : acc;
        }, initialValue);
    }
    /**
     * Retrieves the end time of an event from an audit log.
     *
     * The method processes the provided audit log to find the first instance
     * (starting from the most recent record) where the status was changed to 'CLEARED'.
     * It iterates over the audit records and
     * checks the changes in each record to find this status change.
     *
     * If a record with the CLEARED status is found, the method returns the creation time
     * of that record. If the entire audit log is processed without finding a CLEARED status,
     * the creation time of the first audit log record is returned.
     *
     * If the audit log is empty or null, the method returns null.
     *
     * There can be only one audit log with CLEARED status.
     *
     * @param auditLog - An array of audit records to process.
     * @returns The creation time of the record with the CLEARED status,
     *          the creation time of the first record if no CLEARED status is found,
     *          or null if the audit log is empty or null.
     */
    getEndTime(auditLog) {
        if (!auditLog || auditLog.length === 0) {
            return null;
        }
        let latestClearedAuditTime = null;
        for (const auditLogItem of auditLog) {
            const changes = Array.from(auditLogItem.changes || []);
            const clearedStatusChange = changes.find(change => change.attribute === this.STATUS_ATTRIBUTE && change.newValue === AlarmStatus.CLEARED);
            if (clearedStatusChange) {
                if (!latestClearedAuditTime || auditLogItem.creationTime > latestClearedAuditTime) {
                    latestClearedAuditTime = auditLogItem.creationTime;
                }
            }
        }
        return latestClearedAuditTime || auditLog[0].creationTime;
    }
    checkIfHasAnyRoleAllowingToCreateSmartRule() {
        const ROLES_ALLOWING_SMART_RULE_CREATION = [
            [
                Permissions.ROLE_INVENTORY_ADMIN,
                Permissions.ROLE_INVENTORY_CREATE,
                Permissions.ROLE_MANAGED_OBJECT_ADMIN,
                Permissions.ROLE_MANAGED_OBJECT_CREATE
            ],
            [Permissions.ROLE_CEP_MANAGEMENT_ADMIN, Permissions.ROLE_SMARTRULE_ADMIN]
        ];
        return (this.permissions.hasAnyRole(ROLES_ALLOWING_SMART_RULE_CREATION[0]) &&
            this.permissions.hasAnyRole(ROLES_ALLOWING_SMART_RULE_CREATION[1]));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsService, deps: [{ token: i3.Permissions }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: i3.Permissions }] });

const ALARMS_MODULE_CONFIG = new InjectionToken('AlarmsModuleConfig');
const ALARM_STATUS_ICON = {
    ALERT_IDLE: 'c8y-alert-idle',
    BELL_SLASH: 'bell-slash',
    BELL: 'bell'
};
/**
 * A lookup table to map alarm statuses to corresponding icons.
 */
const AlarmIconMap = {
    [AlarmStatus.CLEARED]: ALARM_STATUS_ICON.ALERT_IDLE,
    [AlarmStatus.ACKNOWLEDGED]: ALARM_STATUS_ICON.BELL_SLASH,
    [AlarmStatus.ACTIVE]: ALARM_STATUS_ICON.BELL
};
const ALARM_SEVERITY_ICON = {
    CIRCLE: 'circle',
    HIGH_PRIORITY: 'high-priority',
    WARNING: 'warning',
    EXCLAMATION_CIRCLE: 'exclamation-circle'
};
const HELP_ICON = 'help';
/**
 * A lookup table to map alarm severity types to corresponding icons.
 */
const ALARM_SEVERITY_ICON_MAP = {
    [Severity.CRITICAL]: ALARM_SEVERITY_ICON.EXCLAMATION_CIRCLE,
    [Severity.MAJOR]: ALARM_SEVERITY_ICON.WARNING,
    [Severity.MINOR]: ALARM_SEVERITY_ICON.HIGH_PRIORITY,
    [Severity.WARNING]: ALARM_SEVERITY_ICON.CIRCLE
};
/**
 * Extended interval titles with an additional title for the case when no date is selected.
 */
const INTERVAL_TITLES_EXTENDED = {
    ...INTERVAL_TITLES,
    none: gettext('No date filter')
};
const INTERVALS_EXTENDED = [
    {
        id: 'none',
        title: gettext('No date filter')
    },
    ...INTERVALS
];
const DEFAULT_ALARM_COUNTS = { CRITICAL: 0, MAJOR: 0, MINOR: 0, WARNING: 0 };
const DEFAULT_SEVERITY_VALUES = {
    [Severity.CRITICAL]: true,
    [Severity.MAJOR]: true,
    [Severity.MINOR]: true,
    [Severity.WARNING]: true
};
const DEFAULT_STATUS_VALUES = {
    [AlarmStatus.ACTIVE]: true,
    [AlarmStatus.ACKNOWLEDGED]: true,
    [AlarmStatus.CLEARED]: true
};
const ALARMS_PATH = 'alarms';
/**
 * Default properties of a alarm. Used to extract the custom properties from a Alarm object.
 */
const ALARM_DEFAULT_PROPERTIES = [
    'severity',
    'source',
    'type',
    'time',
    'text',
    'id',
    'status',
    'count',
    'name',
    'history',
    'self',
    'creationTime',
    'firstOccurrenceTime',
    'lastUpdated'
];
const THROTTLE_REALTIME_REFRESH = 1_000;
const PRODUCT_EXPERIENCE_ALARMS = {
    EVENTS: {
        ALARMS: 'Alarms'
    },
    COMPONENTS: {
        ALARMS_FILTER: 'alarms-filter',
        ALARMS_INTERVAL_REFRESH: 'alarms-interval-refresh',
        ALARMS: 'alarms',
        ALARMS_TYPE_FILTER: 'alarms-type-filter',
        ALARM_DETAILS: 'alarm-details'
    },
    ACTIONS: {
        APPLY_FILTER: 'applyFilter',
        REMOVE_CHIP_FILTER: 'removeChipFilter',
        APPLY_TYPE_FILTER: 'applyTypeFilter',
        CREATE_SMART_RULE: 'createSmartRule',
        ACKNOWLEDGE_ALARM: 'acknowledgeAlarm',
        REACTIVATE_ALARM: 'reactivateAlarm',
        CLEAR_ALARM: 'clearAlarm',
        RELOAD_AUDIT_LOGS: 'reloadAuditLogs',
        USER_SPEND_TIME_ON_COMPONENT: 'userSpendTimeOnComponent'
    }
};

/**
 * This service is a duplicate of smart-rules-service with slight name change.
 * Duplicating allows to pass 'Verify App tutorial' job.
 * Name renames allows to pass 'Reusable build codex' job.
 * Overall this service is considered as a workaround.
 * In ticket MTM-58985 we will investigate if it's possible to remove this service
 * along with making failing jobs pass.
 */
class Ng1SmartRulesUpgradeService {
}
function SmartRulesUpgradeServiceFactory(injector) {
    return injector.get('smartRulesSvc');
}
const smartRulesUpgradeServiceProvider = {
    provide: Ng1SmartRulesUpgradeService,
    useFactory: SmartRulesUpgradeServiceFactory,
    deps: ['$injector']
};

/**
 * Service for managing and retrieving alarms data within the alarms view.
 *
 * The `AlarmsViewService` provides functionality to interact with alarms,
 * including filtering, counting, and translation-related operations in an alarms view.
 *
 * This service relies on the `AlarmService` for fetching alarm data and the `OptionsService`
 * for configuring alarms view options.
 */
class AlarmsViewService {
    constructor(alarmService, optionsService, dateTimeContextPickerService, router, contextRouteService) {
        this.alarmService = alarmService;
        this.optionsService = optionsService;
        this.dateTimeContextPickerService = dateTimeContextPickerService;
        this.router = router;
        this.contextRouteService = contextRouteService;
        this.ALARM_REFRESH_TYPE_KEY = 'alarmsRefreshType';
        this.DEFAULT_INTERVAL_VALUE = 30_000;
        this.DEFAULT_REFRESH_OPTION_VALUE = 'interval';
        this.DEFAULT_INTERVAL_VALUES = [5_000, 10_000, 15_000, 30_000, 60_000];
        this.REALTIME_UPDATE_ALARMS_MESSAGE = gettext('The list was updated, click to refresh.');
        this.reloadAlarmsList$ = new Subject();
        this.closeDetailsView$ = new Subject();
        if (this.isIntervalRefresh()) {
            this._isIntervalEnabled = new Subject();
            this.isIntervalEnabled$ = this._isIntervalEnabled.asObservable();
        }
    }
    /**
     * Emits a subject to initialize the alarms reloading.
     */
    updateAlarmList(value = null) {
        this.reloadAlarmsList$.next(value);
    }
    /**
     * Retrieves a list of alarms filtered by specified severities and other optional query filters.
     *
     * @param severities an array of severities to filter the alarms.
     * @param showCleared flag indicating whether to show cleared alarms. Defaults to false.
     * @param selectedDates an array of two dates to filter alarms by creation and last update dates.
     * @param filter additional query filters for retrieving alarms.
     *
     * @returns A promise that resolves to a list of alarms satisfying the specified filters.
     */
    retrieveFilteredAlarms(severities, showCleared = false, selectedDates, filter) {
        const severitiesQuery = this.getSeverityQueryParameter(severities);
        const statusesQuery = this.getStatusQueryParameter(showCleared);
        const _filter = {
            pageSize: 50,
            withTotalPages: true,
            ...(severitiesQuery && { severity: severitiesQuery }),
            ...(statusesQuery && { status: statusesQuery }),
            ...(selectedDates && {
                lastUpdatedFrom: selectedDates[0].toISOString(),
                createdTo: selectedDates[1].toISOString()
            }),
            ...filter
        };
        return this.alarmService.list(_filter);
    }
    retrieveAlarmsByDate(dates) {
        return this.alarmService.list({
            lastUpdatedFrom: dates[0].toISOString(),
            createdTo: dates[1].toISOString(),
            pageSize: 50,
            withTotalPages: true
        });
    }
    /**
     * Updates the state to enable or disable intervals.
     * @param value - A boolean value to indicate whether to enable intervals.
     */
    updateIntervalState(value) {
        this._isIntervalEnabled?.next(value);
    }
    /**
     * Fetches the count of alarms filtered by severity and clearance status.
     *
     * @param severity - The severity level to filter by (e.g., CRITICAL, MAJOR, etc.).
     * @param showCleared - Whether or not to include cleared alarms in the count.
     * @param filter - Additional filter criteria for alarms.
     *
     * @returns A promise that resolves to the number of alarms that match the filter criteria.
     *
     */
    async getAlarmsCountBySeverity(severity, showCleared, filter) {
        const statusesQuery = this.getStatusQueryParameter(showCleared);
        const _filter = {
            ...(severity && { severity: severity }),
            ...(statusesQuery && { status: statusesQuery }),
            ...filter
        };
        const { data } = await this.alarmService.count(_filter);
        return data;
    }
    /**
     * Retrieves the current alarms refresh type from the OptionsService
     * and determines whether it is set to "interval".
     *
     * @returns `true` if the alarms refresh type is "interval," otherwise `false`.
     */
    isIntervalRefresh() {
        const value = this.optionsService.get(this.ALARM_REFRESH_TYPE_KEY, 'interval');
        return value === 'interval';
    }
    /**
     * Updates the list of selected severities based on the new severity filter.
     *
     * @param severityUpdates - The object representing the updates to each severity.
     *
     * @returns An array representing the updated selected severities.
     */
    updateSelectedSeverities(severityUpdates) {
        return Object.keys(severityUpdates)
            .filter(key => severityUpdates[key])
            .map(key => key.toUpperCase());
    }
    /**
     * Clears all active alarms of the selected severities.
     *
     * This method clears all active alarms for the given list of severities by making bulk update calls. If no severities are selected, it defaults to using all available severities.
     * It works by sending a series of update requests for each severity and returns a Promise that resolves with an object indicating if all alarms were resolved immediately.
     *
     * @param selectedSeverities An array of severities to be cleared. If not provided, all severities will be cleared.
     * @param sourceId - Identifier for the source associated with the alarms to be cleared.
     *
     * @returns A Promise that resolves with an object with a flag `resolvedImmediately`. The flag is true if all alarms for all selected severities were cleared successfully; otherwise false.
     *
     * **Example**
     * ```typescript
     * const severitiesToClear: SeverityType[] = [Severity.MAJOR, Severity.MINOR];
     *
     * clearAllActiveAlarms(severitiesToClear).then(({ resolvedImmediately }) => {
     *   if (resolvedImmediately) {
     *     console.log('All selected alarms were cleared successfully.');
     *   } else {
     *     console.log('Some alarms could not be cleared.');
     *   }
     * });
     * ```
     *
     * **Note**
     * - The method uses the `alarmService.updateBulk` for each severity to clear the active alarms.
     * - It may fetch the `sourceId` based on the view (if applicable) and include it as a query parameter in the update calls.
     * - The method returns immediately but the returned Promise needs to have a `then` or `catch` method call to handle the result or error respectively.
     * - Uses `Promise.all` to wait for all update requests to complete before resolving the final result.
     */
    async clearAllActiveAlarms(selectedSeverities, sourceId) {
        const severitiesToUpdate = selectedSeverities || Severity;
        const promises = Object.values(severitiesToUpdate).map((severity) => {
            const commonParams = { resolved: false, severity };
            const parameters = sourceId
                ? {
                    ...commonParams,
                    source: sourceId,
                    withSourceAssets: true,
                    withSourceDevices: true
                }
                : commonParams;
            return this.alarmService.updateBulk({ status: AlarmStatus.CLEARED }, parameters);
        });
        const responses = await Promise.all(promises);
        return {
            resolvedImmediately: responses.every(res => res)
        };
    }
    /**
     * Returns the correct link based on the provided context data.
     * @param contextData The context the navigation was triggered from.
     * @param alarm The alarm to navigate to.
     * @returns A link to be used as an url navigation.
     */
    getRouterLink(contextData, alarm) {
        let detailUrl = `/${ALARMS_PATH}`;
        if (alarm) {
            detailUrl = `/${ALARMS_PATH}/${alarm.id}`;
        }
        if (!contextData) {
            return detailUrl;
        }
        switch (contextData.context) {
            case ViewContext.Device:
                return `/device/${contextData.contextData.id}${detailUrl}`;
            case ViewContext.Group:
                return `/group/${contextData.contextData.id}${detailUrl}`;
            case ViewContext.Simulators:
                return `/simulators/${contextData.contextData.id}${detailUrl}`;
            default:
                return detailUrl;
        }
    }
    /**
     * Returns the correct array navigation.
     * @param contextData The context the navigation was triggered from.
     * @param alarm The alarm to navigate to.
     * @returns A link to be used as a router.navigation.
     */
    getRouterNavigationArray(contextData, alarm) {
        return this.getRouterLink(contextData, alarm).split('/').filter(Boolean);
    }
    /**
     * Closes the details view and navigates based on the current route context,
     * preserving existing query parameters.
     */
    async closeDetailsView(activatedRoute) {
        const contextData = this.contextRouteService.getContextData(activatedRoute);
        await this.router.navigate(this.getRouterNavigationArray(contextData), {
            queryParamsHandling: 'merge'
        });
        this.updateIntervalState(true);
    }
    /**
     * Returns the correct from and to dates based on the selected interval
     * @param intervalId the selected interval. E.g. 'none', 'hours', 'custom' ...
     * @returns The calculated date context based on the selected interval.
     */
    getDateTimeContextByInterval(intervalId) {
        return this.dateTimeContextPickerService.getDateTimeContextByInterval(intervalId);
    }
    /**
     * Converts a given number of seconds into a formatted string representing hours, minutes, and seconds.
     *
     * @param totalSeconds - The total number of seconds to convert.
     * @returns A string in the format "HH:MM:SS", where HH is hours, MM is minutes, and SS is seconds.
     */
    convertSecondsToTime(totalSeconds) {
        const hours = Math.floor(totalSeconds / 3600);
        const minutes = Math.floor((totalSeconds % 3600) / 60);
        const seconds = Math.floor(totalSeconds % 60);
        const paddedHours = hours.toString().padStart(2, '0');
        const paddedMinutes = minutes.toString().padStart(2, '0');
        const paddedSeconds = seconds.toString().padStart(2, '0');
        return `${paddedHours}:${paddedMinutes}:${paddedSeconds}`;
    }
    /**
     * Creates a value for query parameter for filtering alarms by severity based on array of selected severities.
     *
     * @param severities - An array of alarm severity types to include in the filter.
     * If the array is empty or undefined, no severity filter will be applied.
     *
     * @returns A comma-separated string of selected alarm severities,
     * or null if no severities are provided.
     */
    getSeverityQueryParameter(severities) {
        if (!severities || severities.length === 0) {
            return;
        }
        if (severities.length === Object.keys(Severity).length) {
            return;
        }
        return severities.join(',');
    }
    /**
     * Creates a value for query parameter for filtering alarms by statuses based on showCleared option.
     *
     * @param showCleared - A flag indicating whether to include cleared statuses.
     * If true, all statuses, including 'CLEARED', will be included; if false, 'CLEARED' will be excluded.
     *
     * @returns A comma-separated string of alarm statuses.
     */
    getStatusQueryParameter(showCleared) {
        const statuses = Object.keys(ALARM_STATUS_LABELS);
        const filteredStatuses = showCleared
            ? statuses
            : statuses.filter(status => status !== 'CLEARED');
        return filteredStatuses.join(',');
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsViewService, deps: [{ token: i2.AlarmService }, { token: i3.OptionsService }, { token: i3$1.DateTimeContextPickerService }, { token: i1.Router }, { token: i3.ContextRouteService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsViewService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsViewService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: i2.AlarmService }, { type: i3.OptionsService }, { type: i3$1.DateTimeContextPickerService }, { type: i1.Router }, { type: i3.ContextRouteService }] });

class AlarmsActivityTrackerService {
    constructor() {
        this.isUserActive$ = new BehaviorSubject(true);
        this.userSecondsSpendOnPage = 0;
        this.INACTIVITY_THRESHOLD_SECONDS = 10;
        this.ONE_SECOND_IN_MILLISECONDS = 1_000;
        this.destroy$ = new Subject();
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    setGainsightInterval() {
        this.gainsightTimerId = setInterval(() => this.userSecondsSpendOnPage++, this.ONE_SECOND_IN_MILLISECONDS);
    }
    clearGainsightInterval() {
        clearInterval(this.gainsightTimerId);
    }
    resetInactivityTimer() {
        this.isUserActive$.next(true);
        clearTimeout(this.gainsightInactivityTimeoutId);
        this.gainsightInactivityTimeoutId = setTimeout(() => {
            this.isUserActive$.next(false); // Pause counting if the user is inactive
        }, this.INACTIVITY_THRESHOLD_SECONDS * this.ONE_SECOND_IN_MILLISECONDS);
    }
    setupEventListenersForGainsight() {
        const events = ['mousemove', 'keydown', 'click'];
        events.forEach(event => {
            fromEvent(window, event)
                .pipe(debounceTime(30), takeUntil(this.destroy$))
                .subscribe(() => this.resetInactivityTimer());
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsActivityTrackerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsActivityTrackerService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsActivityTrackerService, decorators: [{
            type: Injectable
        }] });

/**
 * Pipe for transforming alarm severity types into corresponding icons.
 *
 * @example
 * Usage in an Angular template:
 * {{ 'CRITICAL' | AlarmSeverityToIcon }}
 * Result: 'exclamation-circle'
 */
class AlarmSeverityToIconPipe {
    /**
     * Transforms an alarm severity type into a corresponding icon.
     *
     * @param alarmSeverity - The severity type of the alarm.
     * @returns The corresponding icon for the given alarm severity type.
     */
    transform(alarmSeverity) {
        const alarmSeverityMapped = Severity[alarmSeverity?.toUpperCase()];
        return ALARM_SEVERITY_ICON_MAP[alarmSeverityMapped] || HELP_ICON;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeverityToIconPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeverityToIconPipe, isStandalone: true, name: "AlarmSeverityToIcon" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeverityToIconPipe, decorators: [{
            type: Pipe,
            args: [{
                    name: 'AlarmSeverityToIcon',
                    standalone: true
                }]
        }] });

/**
 * Angular pipe for transforming alarm statuses into corresponding icons.
 *
 * @example
 * Usage in an Angular template:
 * {{ 'ACTIVE' | AlarmStatusToIcon }}
 * Result: 'bell'
 */
class AlarmStatusToIconPipe {
    /**
     * Transforms an alarm status into a corresponding icon.
     *
     * @param alarmStatus - The status of the alarm.
     * @returns - The corresponding icon for the given alarm status.
     */
    transform(alarmStatus) {
        return AlarmIconMap[alarmStatus?.toUpperCase()] || HELP_ICON;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmStatusToIconPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AlarmStatusToIconPipe, isStandalone: true, name: "AlarmStatusToIcon" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmStatusToIconPipe, decorators: [{
            type: Pipe,
            args: [{ name: 'AlarmStatusToIcon' }]
        }] });

/**
 * A pipe for transforming audit record data into localized messages.
 * It specifically addresses changes in the audit records, with an emphasis on status changes.
 */
class AuditChangesMessagePipe {
    constructor(translateService) {
        this.translateService = translateService;
    }
    /**
     * Transforms an IAuditRecord into a localized string message.
     * If the record contains changes, and if the first change is related to the 'status' attribute,
     * it formats a message indicating the status change. Otherwise, it returns a general activity message.
     * Example when there is a status change: "Alarm status changed from ACKNOWLEDGED to ACTIVE".
     * Example when record does not have a status attribute: "Alarm updated".
     *
     * @param record - The audit record to be transformed.
     * @returns The localized message describing the audit record,
     *                   particularly focusing on status changes if applicable.
     */
    transform(record) {
        const firstItem = !!record.changes && Array.from(record.changes)[0];
        if (!firstItem || firstItem.attribute !== 'status') {
            const activityString = gettext(record.activity);
            return this.translateService.instant(activityString);
        }
        const { newValue, previousValue } = firstItem;
        const message = gettext(`Alarm status changed from {{ previousValue }} to {{ newValue }}`);
        return this.translateService.instant(message, {
            previousValue: this.translateService.instant(previousValue),
            newValue: this.translateService.instant(newValue)
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AuditChangesMessagePipe, deps: [{ token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AuditChangesMessagePipe, isStandalone: true, name: "auditChangesMessage" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AuditChangesMessagePipe, decorators: [{
            type: Pipe,
            args: [{ name: 'auditChangesMessage' }]
        }], ctorParameters: () => [{ type: i1$1.TranslateService }] });

class AlarmDetailsComponent {
    constructor(alarmDetailsService, alarmService, alertService, appState, auditService, relativeTime, ng1SmartRulesUpgradeService, translateService, inventoryService, alarmsViewService, colorService, interAppService, gainsightService, alarmsActivityTrackerService) {
        this.alarmDetailsService = alarmDetailsService;
        this.alarmService = alarmService;
        this.alertService = alertService;
        this.appState = appState;
        this.auditService = auditService;
        this.relativeTime = relativeTime;
        this.ng1SmartRulesUpgradeService = ng1SmartRulesUpgradeService;
        this.translateService = translateService;
        this.inventoryService = inventoryService;
        this.alarmsViewService = alarmsViewService;
        this.colorService = colorService;
        this.interAppService = interAppService;
        this.gainsightService = gainsightService;
        this.alarmsActivityTrackerService = alarmsActivityTrackerService;
        this.ACKNOWLEDGED_STATUS_VALUE = AlarmStatus.ACKNOWLEDGED;
        this.ACTIVE_STATUS_VALUE = AlarmStatus.ACTIVE;
        this.CLEARED_STATUS_VALUE = AlarmStatus.CLEARED;
        this.ACKNOWLEDGE_LABEL = gettext('Acknowledge');
        this.REACTIVATE_LABEL = gettext('Reactivate');
        this.SEVERITY_LABELS = SEVERITY_LABELS;
        this.BELL_SLASH_ICON = ALARM_STATUS_ICON.BELL_SLASH;
        this.BELL_ICON = ALARM_STATUS_ICON.BELL;
        this.PRODUCT_EXPERIENCE_ALARMS = PRODUCT_EXPERIENCE_ALARMS;
        this.deviceManagementAppKey = SupportedApps.devicemanagement;
        this.linkTitle = gettext('Open in {{ appName }}');
        this.PAGE_SIZE = 100;
        /**
         * Indicates when alarms status change was started (Acknowledge/Reactivate)
         */
        this.isAlarmStatusChanging = false;
        /**
         * Custom fragments of the selected alarm. If none exist, null is returned.
         */
        this.customFragments = null;
        this.USER_MINIMUM_SPEND_TIME_SECONDS_TO_TRIGGER_EVENT = 1;
        this.destroy$ = new Subject();
    }
    async ngOnInit() {
        this.alarmsActivityTrackerService.setupEventListenersForGainsight();
        this.alarmsActivityTrackerService.resetInactivityTimer();
        this.alarmsActivityTrackerService.isUserActive$
            .pipe(distinctUntilChanged(), takeUntil(this.destroy$))
            .subscribe(isActive => isActive
            ? this.alarmsActivityTrackerService.setGainsightInterval()
            : this.alarmsActivityTrackerService.clearGainsightInterval());
        const isSmartRulesServiceSubscribed = !!(await firstValueFrom(this.interAppService.getApp$(SupportedApps.smartrules)));
        const hasAnyRoleAllowingToCreateSmartRule = this.alarmDetailsService.checkIfHasAnyRoleAllowingToCreateSmartRule();
        this.isCreateSmartRulesButtonAvailable =
            !!this.ng1SmartRulesUpgradeService &&
                isSmartRulesServiceSubscribed &&
                hasAnyRoleAllowingToCreateSmartRule;
        this.userDeviceManagementApp$ = this.interAppService.getApp$(this.deviceManagementAppKey);
        this.showSourceNavigationLink$ = this.interAppService.shouldShowAppLink$(this.deviceManagementAppKey);
        this.typeColor = await this.colorService.generateColor(this.selectedAlarm.type);
    }
    async ngOnChanges(changes) {
        if (changes.selectedAlarm && changes.selectedAlarm.currentValue) {
            await this.reloadAuditLog(true, true);
            await this.updateStatusMessage();
            const { data } = await this.inventoryService.detail(this.selectedAlarm.source.id);
            this.selectedAlarmMO = data;
            this.customFragments = this.getCustomFragments(this.selectedAlarm);
        }
    }
    ngOnDestroy() {
        if (this.alarmsActivityTrackerService.userSecondsSpendOnPage >=
            this.USER_MINIMUM_SPEND_TIME_SECONDS_TO_TRIGGER_EVENT) {
            this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS, {
                component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARM_DETAILS,
                action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.USER_SPEND_TIME_ON_COMPONENT,
                userSpendTime: this.alarmsViewService.convertSecondsToTime(this.alarmsActivityTrackerService.userSecondsSpendOnPage)
            });
        }
        this.alarmsActivityTrackerService.clearGainsightInterval();
        this.destroy$.next();
        this.destroy$.complete();
    }
    visibilityChange() {
        if (document.hidden) {
            this.alarmsActivityTrackerService.clearGainsightInterval();
            return;
        }
        this.alarmsActivityTrackerService.setGainsightInterval();
    }
    createSmartRule() {
        if (!this.isCreateSmartRulesButtonAvailable) {
            return;
        }
        this.ng1SmartRulesUpgradeService.addNewForInputAlarmAndOutputUserWithUI(this.selectedAlarm, this.appState.currentUser.value);
    }
    /**
     * Navigates to a specific alarm source device based on the provided source.
     *
     * @param sourceId - The source id.
     */
    async goToAlarmSource(sourceId) {
        const { data } = await this.alarmService.detail(sourceId);
        await this.interAppService.navigateToApp(this.deviceManagementAppKey, `#/device/${data.source.id}/alarms`);
    }
    /**
     * 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.
     *
     * @param isRevert - 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.
     * @param isSetAuditLogs - A boolean flag to determine if the fetched audit logs should be set in the component state. Defaults to `false`.
     * @returns A promise that resolves to a list of `IAuditRecord` objects.
     */
    async reloadAuditLog(isRevert = true, isSetAuditLogs = false) {
        try {
            this.isLoading = true;
            const auditLogs = await this.getAlarmAuditRecords(isRevert);
            if (isSetAuditLogs) {
                this.setAuditLogs(auditLogs);
            }
            return auditLogs;
        }
        catch (error) {
            this.alertService.addServerFailure(error);
        }
        finally {
            this.isLoading = false;
        }
    }
    async onUpdateDetails(status) {
        try {
            this.isAlarmStatusChanging = true;
            await this.updateAlarmStatus(status);
            await this.reloadAuditLog(true, true);
            await this.updateStatusMessage();
            this.updateLastUpdatedDate(this.auditLog.data[0]);
            if (status === AlarmStatus.CLEARED) {
                this.alarmsViewService.closeDetailsView$.next();
            }
        }
        catch (error) {
            this.alertService.addServerFailure(error);
        }
        finally {
            this.isAlarmStatusChanging = false;
        }
    }
    async detailsButtonAction(button, alarm) {
        const result = button.action(alarm);
        let shouldReload = false;
        if (result instanceof Promise) {
            shouldReload = await result;
        }
        else {
            shouldReload = result;
        }
        if (shouldReload) {
            let alarm;
            if (shouldReload === true) {
                const { data: updatedAlarm } = await this.alarmService.detail(this.selectedAlarm.id);
                alarm = updatedAlarm;
            }
            else {
                alarm = shouldReload;
            }
            this.alarmsViewService.updateAlarmList();
            const previousValue = this.selectedAlarm;
            this.selectedAlarm = alarm;
            this.ngOnChanges({
                selectedAlarm: {
                    currentValue: alarm,
                    previousValue,
                    firstChange: false,
                    isFirstChange: () => false
                }
            });
        }
    }
    async updateAlarmStatus(status) {
        const partiallyUpdatedAlarm = { id: this.selectedAlarm.id, status };
        await this.alarmService.update(partiallyUpdatedAlarm);
        const translatedStatusLabel = this.translateService.instant(ALARM_STATUS_LABELS[status]);
        this.alertService.success(this.translateService.instant(gettext('Alarm status changed to {{ status }}'), {
            status: translatedStatusLabel.toUpperCase()
        }));
        this.selectedAlarm.status = status;
        this.alarmsViewService.updateAlarmList();
    }
    /**
     * Retrieves the audit log and appends the last audit record to it.
     *
     * This method fetches the existing audit log data and makes a deep copy of it. It then
     * retrieves the last audit record and appends it to the copied audit log data. This is
     * useful for scenarios where the most recent audit record needs to be included in the
     * existing audit log data (calculating the CLEARED period).
     *
     * @returns A promise of `IResultList<IAuditRecord>`, which includes the
     *          existing audit log data along with the last audit record appended.
     * @private
     */
    async auditLogWithFirstRecord() {
        const existingData = this.auditLog;
        const copiedExistingData = cloneDeep(existingData);
        const lastAuditRecord = await this.reloadAuditLog(false);
        const lastRecord = lastAuditRecord.data[lastAuditRecord.data.length - 1];
        copiedExistingData.data.push(lastRecord);
        return copiedExistingData;
    }
    setAuditLogs(auditLogs) {
        this.auditLog = auditLogs;
    }
    updateLastUpdatedDate(updatedAuditRecords) {
        if (!updatedAuditRecords) {
            return;
        }
        const { creationTime } = updatedAuditRecords;
        this.selectedAlarm.lastUpdated = creationTime;
    }
    getActiveStatusMessage(time) {
        return this.translateService.instant(gettext('ACTIVE`alarm`: triggered {{alarmTimeFromNow}}'), {
            alarmTimeFromNow: this.relativeTime.transform(new Date(time))
        });
    }
    getAcknowledgedStatusMessage(status, changeLog) {
        if (changeLog.length === 0) {
            return this.translateService.instant(gettext('ACKNOWLEDGED`alarm`'));
        }
        const acknowledgedBy = this.alarmDetailsService.getAcknowledgedBy(status, changeLog);
        const acknowledgeTime = this.alarmDetailsService.getAcknowledgeTime(changeLog);
        if (acknowledgedBy) {
            return this.translateService.instant(gettext('ACKNOWLEDGED`alarm` by: {{ackBy}} {{ackTimeFromNow}}'), {
                ackBy: acknowledgedBy,
                ackTimeFromNow: this.relativeTime.transform(new Date(acknowledgeTime))
            });
        }
        return this.translateService.instant(gettext('ACKNOWLEDGED`alarm` {{ackTimeFromNow}}'), {
            ackTimeFromNow: this.relativeTime.transform(new Date(acknowledgeTime))
        });
    }
    getClearedStatusMessage(auditLog) {
        if (auditLog.length === 0) {
            return this.translateService.instant(gettext('CLEARED`alarm`'));
        }
        const differenceInMs = this.calculateAlarmDuration(auditLog);
        return this.translateService.instant(gettext('CLEARED`alarm`: was active for {{alarmDuration}}'), {
            alarmDuration: this.relativeTime.transform(differenceInMs, true)
        });
    }
    /**
     * Calculates the duration of an alarm based on audit log records.
     *
     * This method computes the duration of an alarm by finding the difference
     * between the start and end times of the alarm. The start time is determined
     * from the last record in the audit log, using the first available time field
     * (`firstOccurrenceTime`, `time`, or `creationTime`). The end time is obtained
     * from the `alarmDetailsService`.
     *
     * @param auditLog - An array of `IAuditRecord` objects representing the audit log records.
     * @returns The duration of the alarm in milliseconds, or `null` if the end time is not available.
     * @private
     */
    calculateAlarmDuration(auditLog) {
        const firstAlarm = auditLog[auditLog.length - 1];
        const startTime = firstAlarm.firstOccurrenceTime || firstAlarm.time || firstAlarm.creationTime;
        const endTime = this.alarmDetailsService.getEndTime(auditLog);
        if (!endTime) {
            return null;
        }
        const startTimeToDate = new Date(startTime);
        const endTimeToDate = new Date(endTime);
        return endTimeToDate.getTime() - startTimeToDate.getTime();
    }
    /**
     * Retrieves a list of audit records for a selected alarm.
     *
     * This method fetches audit records based on the specified properties, including
     * the date, page size, whether to revert, the source alarm ID, and whether to include total pages.
     *
     * @param isRevert - 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).
     * @returns A Promise that resolves to an IResultList of IAuditRecord objects, representing the audit records.
     * @async
     * @private
     */
    async getAlarmAuditRecords(isRevert = true) {
        const properties = {
            dateTo: new Date(Date.now()).toISOString(),
            pageSize: isRevert ? this.PAGE_SIZE : 1,
            revert: isRevert,
            source: this.selectedAlarm.id,
            withTotalPages: true
        };
        return await this.auditService.list(properties);
    }
    async updateStatusMessage() {
        switch (this.selectedAlarm.status) {
            case this.ACTIVE_STATUS_VALUE:
                this.statusMessage = this.getActiveStatusMessage(this.selectedAlarm.time);
                break;
            case this.ACKNOWLEDGED_STATUS_VALUE:
                this.statusMessage = this.getAcknowledgedStatusMessage(this.selectedAlarm.status, this.auditLog.data);
                break;
            case this.CLEARED_STATUS_VALUE:
                if (this.hasReachedOrExceededPageSizeLimit()) {
                    this.extendedAuditLogs = await this.auditLogWithFirstRecord();
                    this.statusMessage = this.getClearedStatusMessage(this.extendedAuditLogs.data);
                    return;
                }
                this.statusMessage = this.getClearedStatusMessage(this.auditLog.data);
                break;
        }
    }
    hasReachedOrExceededPageSizeLimit() {
        return this.auditLog.data.length >= this.PAGE_SIZE;
    }
    getCustomFragments(selectedAlarm) {
        let customProperties = null;
        for (const key in selectedAlarm) {
            if (!ALARM_DEFAULT_PROPERTIES.find(k => k === key)) {
                if (!customProperties) {
                    customProperties = {};
                }
                customProperties[key] = selectedAlarm[key];
            }
        }
        return customProperties;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsComponent, deps: [{ token: AlarmDetailsService }, { token: i2.AlarmService }, { token: i3.AlertService }, { token: i3.AppStateService }, { token: i2.AuditService }, { token: i3.RelativeTimePipe }, { token: Ng1SmartRulesUpgradeService, optional: true }, { token: i1$1.TranslateService }, { token: i2.InventoryService }, { token: AlarmsViewService }, { token: i3.ColorService }, { token: i3.InterAppService }, { token: i3.GainsightService }, { token: AlarmsActivityTrackerService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: AlarmDetailsComponent, isStandalone: true, selector: "c8y-alarm-details", inputs: { selectedAlarm: "selectedAlarm" }, host: { listeners: { "document:visibilitychange": "visibilityChange()" } }, providers: [AlarmsActivityTrackerService], usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex row tight-grid flex-wrap a-i-stretch\">\n  <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n    <div\n      class=\"border-all fit-w d-flex\"\n      data-cy=\"c8y-alarm-details--status-section-wrapper\"\n    >\n      <div\n        class=\"p-8\"\n        data-cy=\"c8y-alarm-details--status-icon\"\n      >\n        <i\n          class=\"icon-24 text-gray-dark m-t-4 c8y-icon\"\n          [c8yIcon]=\"selectedAlarm.status | AlarmStatusToIcon\"\n        ></i>\n      </div>\n      <div class=\"p-t-8 p-b-8 p-r-8\">\n        <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Status' | translate }}</p>\n        <p class=\"small\">{{ statusMessage }}</p>\n      </div>\n    </div>\n  </div>\n  <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n    <div\n      class=\"border-all fit-w d-flex\"\n      data-cy=\"c8y-alarm-details--severity-section-wrapper\"\n    >\n      <div class=\"p-8\">\n        <i\n          class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n          [c8yIcon]=\"selectedAlarm.severity | AlarmSeverityToIcon\"\n          [ngClass]=\"selectedAlarm.severity?.toString() | lowercase\"\n        ></i>\n      </div>\n      <div class=\"p-t-8 p-b-8 p-r-8\">\n        <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Severity' | translate }}</p>\n        <p class=\"small\">{{ SEVERITY_LABELS[selectedAlarm.severity] | translate }}</p>\n      </div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-md-6 d-flex p-b-8\"\n    data-cy=\"c8y-alarm-details--source-wrapper\"\n  >\n    <div class=\"border-all fit-w d-flex\">\n      <div class=\"p-8\">\n        <i\n          class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n          c8yIcon=\"contactless-payment\"\n        ></i>\n      </div>\n      <div class=\"p-t-8 p-b-8 p-r-8\">\n        <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Source' | translate }}</p>\n        <p class=\"small\">\n          <button\n            class=\"btn-link text-muted p-0 m-r-8 text-left\"\n            title=\"{{ selectedAlarm.source.name }}\"\n            type=\"button\"\n            routerLink=\"{{ selectedAlarmMO | assetLink }}\"\n          >\n            <small class=\"icon-flex\">\n              <i c8yIcon=\"exchange\"></i>\n              {{ selectedAlarm.source.name || selectedAlarm.source.id }}\n            </small>\n          </button>\n          <ng-container *ngIf=\"showSourceNavigationLink$ | async\">\n            <button\n              class=\"btn-link p-0 text-left\"\n              title=\"{{\n                linkTitle\n                  | translate\n                    : { appName: userDeviceManagementApp$ | async | humanizeAppName | async }\n              }}\"\n              type=\"button\"\n              (click)=\"goToAlarmSource(selectedAlarm.id)\"\n              data-cy=\"alarm-details-device-management-link\"\n            >\n              {{ userDeviceManagementApp$ | async | humanizeAppName | async }}\n              <i c8yIcon=\"external-link\"></i>\n            </button>\n          </ng-container>\n        </p>\n      </div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-md-6 d-flex p-b-8\"\n    data-cy=\"c8y-alarm-details--severity-type-wrapper\"\n  >\n    <div class=\"border-all fit-w d-flex\">\n      <div class=\"p-8\">\n        <span\n          class=\"circle-icon-wrapper\"\n          [ngStyle]=\"{ 'background-color': typeColor }\"\n        >\n          <i\n            class=\"stroked-icon\"\n            c8yIcon=\"bell\"\n          ></i>\n        </span>\n      </div>\n      <div class=\"p-t-8 p-b-8 p-r-8 min-width-0\">\n        <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Type' | translate }}</p>\n        <p\n          class=\"small text-truncate\"\n          title=\"{{ selectedAlarm.type }}\"\n        >\n          <code>{{ selectedAlarm.type }}</code>\n        </p>\n      </div>\n    </div>\n  </div>\n\n  <div class=\"col-xs-12 col-md-12 p-b-16\">\n    <div class=\"border-all fit-w d-flex\">\n      <div class=\"p-8\">\n        <i\n          class=\"icon-24 text-gray-dark m-t-4\"\n          c8yIcon=\"calendar\"\n          data-cy=\"c8y-alarm-details--last-updated-icon\"\n        ></i>\n      </div>\n      <div class=\"p-t-8 p-b-0 p-r-8 flex-grow\">\n        <div class=\"content-flex-50\">\n          <div\n            class=\"col-4 p-b-8\"\n            *ngIf=\"selectedAlarm.count > 1\"\n            data-cy=\"c8y-alarm-details--number-of-occurrences-wrapper\"\n          >\n            <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Number of occurrences' | translate }}</p>\n            <p>\n              <span\n                class=\"badge badge-info\"\n                data-cy=\"c8y-alarm-details--badge\"\n              >\n                {{ selectedAlarm.count }}\n              </span>\n            </p>\n          </div>\n          <div\n            class=\"col-4 p-b-8\"\n            *ngIf=\"selectedAlarm.count > 1\"\n            data-cy=\"c8y-alarm-details--first-occurrence-wrapper\"\n          >\n            <p class=\"text-label-small m-b-0 m-r-8\">{{ 'First occurrence' | translate }}</p>\n            <p class=\"small\">\n              {{ selectedAlarm.creationTime | c8yDate: 'medium' }}\n\n              <button\n                class=\"btn-help btn-help--sm\"\n                [attr.aria-label]=\"'Help' | translate\"\n                popover=\"{{\n                  'Time in which the alarm was created. The time shown corresponds to the server\\'s time. Device time can be different from server time.'\n                    | translate\n                }}\"\n                placement=\"right\"\n                triggers=\"focus\"\n                container=\"body\"\n                type=\"button\"\n              ></button>\n            </p>\n          </div>\n          <div\n            class=\"col-4 p-b-8\"\n            data-cy=\"c8y-alarm-details--last-updated-wrapper\"\n          >\n            <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Last occurrence' | translate }}</p>\n            <p class=\"small\">\n              {{ selectedAlarm.lastUpdated | c8yDate: 'medium' }}\n\n              <button\n                class=\"btn-help btn-help--sm\"\n                [attr.aria-label]=\"'Help' | translate\"\n                popover=\"{{\n                  '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.'\n                    | translate\n                }}\"\n                placement=\"right\"\n                triggers=\"focus\"\n                container=\"body\"\n                type=\"button\"\n              ></button>\n            </p>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <div\n    class=\"col-xs-12 col-md-12 p-b-16\"\n    data-cy=\"c8y-alarm-details--custom-fragments-wrapper\"\n    *ngIf=\"customFragments\"\n  >\n    <div class=\"border-all fit-w d-flex\">\n      <div class=\"p-8\">\n        <i\n          class=\"icon-24 text-gray-dark m-t-4\"\n          c8yIcon=\"outgoing-data\"\n        ></i>\n      </div>\n      <div\n        class=\"p-t-8 p-b-0 p-r-8 flex-grow\"\n        data-cy=\"alarm-details-custom-data\"\n      >\n        <p class=\"text-label-small m-b-4 m-r-8\">{{ 'Custom data' | translate }}</p>\n        <pre><code>{{ customFragments | json }}</code></pre>\n      </div>\n    </div>\n  </div>\n</div>\n\n<div class=\"d-flex flex-wrap gap-8\">\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"'Reload audit logs' | translate\"\n    type=\"submit\"\n    (click)=\"reloadAuditLog(true, true)\"\n    data-cy=\"c8y-alarms-details--reload-audit-logs\"\n    c8yProductExperience\n    [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n    [actionData]=\"{\n      component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARM_DETAILS,\n      action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.RELOAD_AUDIT_LOGS\n    }\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': isLoading }\"\n    ></i>\n    {{ 'Reload audit logs' | translate }}\n  </button>\n\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"\n      selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n        ? (ACKNOWLEDGE_LABEL | translate)\n        : (REACTIVATE_LABEL | translate)\n    \"\n    type=\"submit\"\n    c8yProductExperience\n    [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n    [actionData]=\"{\n      component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARM_DETAILS,\n      action:\n        selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n          ? PRODUCT_EXPERIENCE_ALARMS.ACTIONS.ACKNOWLEDGE_ALARM\n          : PRODUCT_EXPERIENCE_ALARMS.ACTIONS.REACTIVATE_ALARM\n    }\"\n    (click)=\"\n      onUpdateDetails(\n        selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n          ? ACKNOWLEDGED_STATUS_VALUE\n          : ACTIVE_STATUS_VALUE\n      )\n    \"\n    [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE || isAlarmStatusChanging\"\n  >\n    <i\n      [c8yIcon]=\"selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE ? BELL_SLASH_ICON : BELL_ICON\"\n    ></i>\n    {{\n      selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n        ? (ACKNOWLEDGE_LABEL | translate)\n        : (REACTIVATE_LABEL | translate)\n    }}\n  </button>\n\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"'Create smart rule' | translate\"\n    type=\"submit\"\n    *ngIf=\"isCreateSmartRulesButtonAvailable\"\n    (click)=\"createSmartRule()\"\n    c8yProductExperience\n    [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n    [actionData]=\"{\n      component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARM_DETAILS,\n      action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.CREATE_SMART_RULE\n    }\"\n    data-cy=\"c8y-alarms-details--create-smart-rule\"\n  >\n    <i c8yIcon=\"c8y-icon c8y-icon-smart-rules\"></i>\n    {{ 'Create smart rule' | translate }}\n  </button>\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"'Clear`alarm`' | translate\"\n    type=\"submit\"\n    data-cy=\"c8y-alarm-details--clear-alarm\"\n    (click)=\"onUpdateDetails(CLEARED_STATUS_VALUE)\"\n    [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE\"\n    c8yProductExperience\n    [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n    [actionData]=\"{\n      component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARM_DETAILS,\n      action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.CLEAR_ALARM\n    }\"\n  >\n    <i c8yIcon=\"c8y-alert-idle\"></i>\n    {{ 'Clear`alarm`' | translate }}\n  </button>\n\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"button.title | translate\"\n    type=\"button\"\n    *ngFor=\"let button of selectedAlarm | alarmDetailsButton: selectedAlarmMO | async\"\n    [ngClass]=\"button.additionalButtonClasses\"\n    (click)=\"detailsButtonAction(button, selectedAlarm)\"\n    [disabled]=\"button.disabled\"\n  >\n    <i\n      [c8yIcon]=\"button.icon\"\n      [ngClass]=\"button.additionalIconClasses\"\n    ></i>\n    <span *ngIf=\"button.label\">{{ button.label | translate }}</span>\n  </button>\n</div>\n\n<ng-template #noAuditLogAvailable>\n  <div class=\"p-16\">\n    <c8y-ui-empty-state\n      [icon]=\"'archive'\"\n      [title]=\"'No audit logs found.' | translate\"\n      [horizontal]=\"true\"\n    ></c8y-ui-empty-state>\n  </div>\n</ng-template>\n\n<div class=\"legend form-block\">{{ 'Audit logs' | translate }}</div>\n\n<ng-container *ngIf=\"isLoading || auditLog?.data.length; else noAuditLogAvailable\">\n  <c8y-loading *ngIf=\"isLoading\"></c8y-loading>\n\n  <c8y-list-group\n    data-cy=\"c8y-alarms-details--audit-logs\"\n    *ngIf=\"!isLoading\"\n  >\n    <c8y-li-timeline *c8yFor=\"let log of auditLog; loadMore: 'hidden'\">\n      {{ log.creationTime | c8yDate: 'mediumDate' }}\n      {{ log.creationTime | c8yDate: 'mediumTime' }}\n      <c8y-li>\n        <c8y-li-body>\n          <p class=\"text-truncate-wrap separator-bottom p-b-4\">\n            {{ log | auditChangesMessage }}\n          </p>\n          <div class=\"c8y-list__item__footer\">\n            <span\n              class=\"m-r-16 small\"\n              *ngIf=\"log.user\"\n            >\n              <span class=\"text-label-small\">\n                {{ 'by`user`' | translate }}\n              </span>\n              {{ log.user }}\n            </span>\n            <span class=\"small\">\n              <span class=\"text-label-small\">\n                {{ 'device time' | translate }}\n              </span>\n              {{ log.time | c8yDate: 'medium' }}\n            </span>\n          </div>\n        </c8y-li-body>\n      </c8y-li>\n    </c8y-li-timeline>\n  </c8y-list-group>\n</ng-container>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "component", type: ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: LowerCasePipe, name: "lowercase" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }, { kind: "pipe", type: HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "pipe", type: AssetLinkPipe, name: "assetLink" }, { kind: "pipe", type: AlarmDetailsButtonPipe, name: "alarmDetailsButton" }, { kind: "pipe", type: AlarmSeverityToIconPipe, name: "AlarmSeverityToIcon" }, { kind: "pipe", type: AlarmStatusToIconPipe, name: "AlarmStatusToIcon" }, { kind: "pipe", type: AuditChangesMessagePipe, name: "auditChangesMessage" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmDetailsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarm-details', providers: [AlarmsActivityTrackerService], imports: [
                        IconDirective,
                        NgClass,
                        RouterLink,
                        NgIf,
                        NgStyle,
                        PopoverDirective,
                        ProductExperienceDirective,
                        NgFor,
                        EmptyStateComponent,
                        LoadingComponent,
                        ListGroupComponent,
                        ForOfDirective,
                        ListItemTimelineComponent,
                        ListItemComponent,
                        ListItemBodyComponent,
                        C8yTranslatePipe,
                        AsyncPipe,
                        LowerCasePipe,
                        JsonPipe,
                        DatePipe,
                        HumanizeAppNamePipe,
                        AssetLinkPipe,
                        AlarmDetailsButtonPipe,
                        AlarmSeverityToIconPipe,
                        AlarmStatusToIconPipe,
                        AuditChangesMessagePipe
                    ], template: "<div class=\"d-flex row tight-grid flex-wrap a-i-stretch\">\n  <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n    <div\n      class=\"border-all fit-w d-flex\"\n      data-cy=\"c8y-alarm-details--status-section-wrapper\"\n    >\n      <div\n        class=\"p-8\"\n        data-cy=\"c8y-alarm-details--status-icon\"\n      >\n        <i\n          class=\"icon-24 text-gray-dark m-t-4 c8y-icon\"\n          [c8yIcon]=\"selectedAlarm.status | AlarmStatusToIcon\"\n        ></i>\n      </div>\n      <div class=\"p-t-8 p-b-8 p-r-8\">\n        <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Status' | translate }}</p>\n        <p class=\"small\">{{ statusMessage }}</p>\n      </div>\n    </div>\n  </div>\n  <div class=\"col-xs-12 col-md-6 d-flex p-b-8\">\n    <div\n      class=\"border-all fit-w d-flex\"\n      data-cy=\"c8y-alarm-details--severity-section-wrapper\"\n    >\n      <div class=\"p-8\">\n        <i\n          class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n          [c8yIcon]=\"selectedAlarm.severity | AlarmSeverityToIcon\"\n          [ngClass]=\"selectedAlarm.severity?.toString() | lowercase\"\n        ></i>\n      </div>\n      <div class=\"p-t-8 p-b-8 p-r-8\">\n        <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Severity' | translate }}</p>\n        <p class=\"small\">{{ SEVERITY_LABELS[selectedAlarm.severity] | translate }}</p>\n      </div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-md-6 d-flex p-b-8\"\n    data-cy=\"c8y-alarm-details--source-wrapper\"\n  >\n    <div class=\"border-all fit-w d-flex\">\n      <div class=\"p-8\">\n        <i\n          class=\"icon-24 text-gray-dark m-t-4 stroked-icon status\"\n          c8yIcon=\"contactless-payment\"\n        ></i>\n      </div>\n      <div class=\"p-t-8 p-b-8 p-r-8\">\n        <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Source' | translate }}</p>\n        <p class=\"small\">\n          <button\n            class=\"btn-link text-muted p-0 m-r-8 text-left\"\n            title=\"{{ selectedAlarm.source.name }}\"\n            type=\"button\"\n            routerLink=\"{{ selectedAlarmMO | assetLink }}\"\n          >\n            <small class=\"icon-flex\">\n              <i c8yIcon=\"exchange\"></i>\n              {{ selectedAlarm.source.name || selectedAlarm.source.id }}\n            </small>\n          </button>\n          <ng-container *ngIf=\"showSourceNavigationLink$ | async\">\n            <button\n              class=\"btn-link p-0 text-left\"\n              title=\"{{\n                linkTitle\n                  | translate\n                    : { appName: userDeviceManagementApp$ | async | humanizeAppName | async }\n              }}\"\n              type=\"button\"\n              (click)=\"goToAlarmSource(selectedAlarm.id)\"\n              data-cy=\"alarm-details-device-management-link\"\n            >\n              {{ userDeviceManagementApp$ | async | humanizeAppName | async }}\n              <i c8yIcon=\"external-link\"></i>\n            </button>\n          </ng-container>\n        </p>\n      </div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-md-6 d-flex p-b-8\"\n    data-cy=\"c8y-alarm-details--severity-type-wrapper\"\n  >\n    <div class=\"border-all fit-w d-flex\">\n      <div class=\"p-8\">\n        <span\n          class=\"circle-icon-wrapper\"\n          [ngStyle]=\"{ 'background-color': typeColor }\"\n        >\n          <i\n            class=\"stroked-icon\"\n            c8yIcon=\"bell\"\n          ></i>\n        </span>\n      </div>\n      <div class=\"p-t-8 p-b-8 p-r-8 min-width-0\">\n        <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Type' | translate }}</p>\n        <p\n          class=\"small text-truncate\"\n          title=\"{{ selectedAlarm.type }}\"\n        >\n          <code>{{ selectedAlarm.type }}</code>\n        </p>\n      </div>\n    </div>\n  </div>\n\n  <div class=\"col-xs-12 col-md-12 p-b-16\">\n    <div class=\"border-all fit-w d-flex\">\n      <div class=\"p-8\">\n        <i\n          class=\"icon-24 text-gray-dark m-t-4\"\n          c8yIcon=\"calendar\"\n          data-cy=\"c8y-alarm-details--last-updated-icon\"\n        ></i>\n      </div>\n      <div class=\"p-t-8 p-b-0 p-r-8 flex-grow\">\n        <div class=\"content-flex-50\">\n          <div\n            class=\"col-4 p-b-8\"\n            *ngIf=\"selectedAlarm.count > 1\"\n            data-cy=\"c8y-alarm-details--number-of-occurrences-wrapper\"\n          >\n            <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Number of occurrences' | translate }}</p>\n            <p>\n              <span\n                class=\"badge badge-info\"\n                data-cy=\"c8y-alarm-details--badge\"\n              >\n                {{ selectedAlarm.count }}\n              </span>\n            </p>\n          </div>\n          <div\n            class=\"col-4 p-b-8\"\n            *ngIf=\"selectedAlarm.count > 1\"\n            data-cy=\"c8y-alarm-details--first-occurrence-wrapper\"\n          >\n            <p class=\"text-label-small m-b-0 m-r-8\">{{ 'First occurrence' | translate }}</p>\n            <p class=\"small\">\n              {{ selectedAlarm.creationTime | c8yDate: 'medium' }}\n\n              <button\n                class=\"btn-help btn-help--sm\"\n                [attr.aria-label]=\"'Help' | translate\"\n                popover=\"{{\n                  'Time in which the alarm was created. The time shown corresponds to the server\\'s time. Device time can be different from server time.'\n                    | translate\n                }}\"\n                placement=\"right\"\n                triggers=\"focus\"\n                container=\"body\"\n                type=\"button\"\n              ></button>\n            </p>\n          </div>\n          <div\n            class=\"col-4 p-b-8\"\n            data-cy=\"c8y-alarm-details--last-updated-wrapper\"\n          >\n            <p class=\"text-label-small m-b-0 m-r-8\">{{ 'Last occurrence' | translate }}</p>\n            <p class=\"small\">\n              {{ selectedAlarm.lastUpdated | c8yDate: 'medium' }}\n\n              <button\n                class=\"btn-help btn-help--sm\"\n                [attr.aria-label]=\"'Help' | translate\"\n                popover=\"{{\n                  '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.'\n                    | translate\n                }}\"\n                placement=\"right\"\n                triggers=\"focus\"\n                container=\"body\"\n                type=\"button\"\n              ></button>\n            </p>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <div\n    class=\"col-xs-12 col-md-12 p-b-16\"\n    data-cy=\"c8y-alarm-details--custom-fragments-wrapper\"\n    *ngIf=\"customFragments\"\n  >\n    <div class=\"border-all fit-w d-flex\">\n      <div class=\"p-8\">\n        <i\n          class=\"icon-24 text-gray-dark m-t-4\"\n          c8yIcon=\"outgoing-data\"\n        ></i>\n      </div>\n      <div\n        class=\"p-t-8 p-b-0 p-r-8 flex-grow\"\n        data-cy=\"alarm-details-custom-data\"\n      >\n        <p class=\"text-label-small m-b-4 m-r-8\">{{ 'Custom data' | translate }}</p>\n        <pre><code>{{ customFragments | json }}</code></pre>\n      </div>\n    </div>\n  </div>\n</div>\n\n<div class=\"d-flex flex-wrap gap-8\">\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"'Reload audit logs' | translate\"\n    type=\"submit\"\n    (click)=\"reloadAuditLog(true, true)\"\n    data-cy=\"c8y-alarms-details--reload-audit-logs\"\n    c8yProductExperience\n    [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n    [actionData]=\"{\n      component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARM_DETAILS,\n      action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.RELOAD_AUDIT_LOGS\n    }\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': isLoading }\"\n    ></i>\n    {{ 'Reload audit logs' | translate }}\n  </button>\n\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"\n      selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n        ? (ACKNOWLEDGE_LABEL | translate)\n        : (REACTIVATE_LABEL | translate)\n    \"\n    type=\"submit\"\n    c8yProductExperience\n    [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n    [actionData]=\"{\n      component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARM_DETAILS,\n      action:\n        selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n          ? PRODUCT_EXPERIENCE_ALARMS.ACTIONS.ACKNOWLEDGE_ALARM\n          : PRODUCT_EXPERIENCE_ALARMS.ACTIONS.REACTIVATE_ALARM\n    }\"\n    (click)=\"\n      onUpdateDetails(\n        selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n          ? ACKNOWLEDGED_STATUS_VALUE\n          : ACTIVE_STATUS_VALUE\n      )\n    \"\n    [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE || isAlarmStatusChanging\"\n  >\n    <i\n      [c8yIcon]=\"selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE ? BELL_SLASH_ICON : BELL_ICON\"\n    ></i>\n    {{\n      selectedAlarm.status !== ACKNOWLEDGED_STATUS_VALUE\n        ? (ACKNOWLEDGE_LABEL | translate)\n        : (REACTIVATE_LABEL | translate)\n    }}\n  </button>\n\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"'Create smart rule' | translate\"\n    type=\"submit\"\n    *ngIf=\"isCreateSmartRulesButtonAvailable\"\n    (click)=\"createSmartRule()\"\n    c8yProductExperience\n    [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n    [actionData]=\"{\n      component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARM_DETAILS,\n      action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.CREATE_SMART_RULE\n    }\"\n    data-cy=\"c8y-alarms-details--create-smart-rule\"\n  >\n    <i c8yIcon=\"c8y-icon c8y-icon-smart-rules\"></i>\n    {{ 'Create smart rule' | translate }}\n  </button>\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"'Clear`alarm`' | translate\"\n    type=\"submit\"\n    data-cy=\"c8y-alarm-details--clear-alarm\"\n    (click)=\"onUpdateDetails(CLEARED_STATUS_VALUE)\"\n    [disabled]=\"selectedAlarm.status === CLEARED_STATUS_VALUE\"\n    c8yProductExperience\n    [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n    [actionData]=\"{\n      component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARM_DETAILS,\n      action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.CLEAR_ALARM\n    }\"\n  >\n    <i c8yIcon=\"c8y-alert-idle\"></i>\n    {{ 'Clear`alarm`' | translate }}\n  </button>\n\n  <button\n    class=\"btn btn-default btn-sm\"\n    [title]=\"button.title | translate\"\n    type=\"button\"\n    *ngFor=\"let button of selectedAlarm | alarmDetailsButton: selectedAlarmMO | async\"\n    [ngClass]=\"button.additionalButtonClasses\"\n    (click)=\"detailsButtonAction(button, selectedAlarm)\"\n    [disabled]=\"button.disabled\"\n  >\n    <i\n      [c8yIcon]=\"button.icon\"\n      [ngClass]=\"button.additionalIconClasses\"\n    ></i>\n    <span *ngIf=\"button.label\">{{ button.label | translate }}</span>\n  </button>\n</div>\n\n<ng-template #noAuditLogAvailable>\n  <div class=\"p-16\">\n    <c8y-ui-empty-state\n      [icon]=\"'archive'\"\n      [title]=\"'No audit logs found.' | translate\"\n      [horizontal]=\"true\"\n    ></c8y-ui-empty-state>\n  </div>\n</ng-template>\n\n<div class=\"legend form-block\">{{ 'Audit logs' | translate }}</div>\n\n<ng-container *ngIf=\"isLoading || auditLog?.data.length; else noAuditLogAvailable\">\n  <c8y-loading *ngIf=\"isLoading\"></c8y-loading>\n\n  <c8y-list-group\n    data-cy=\"c8y-alarms-details--audit-logs\"\n    *ngIf=\"!isLoading\"\n  >\n    <c8y-li-timeline *c8yFor=\"let log of auditLog; loadMore: 'hidden'\">\n      {{ log.creationTime | c8yDate: 'mediumDate' }}\n      {{ log.creationTime | c8yDate: 'mediumTime' }}\n      <c8y-li>\n        <c8y-li-body>\n          <p class=\"text-truncate-wrap separator-bottom p-b-4\">\n            {{ log | auditChangesMessage }}\n          </p>\n          <div class=\"c8y-list__item__footer\">\n            <span\n              class=\"m-r-16 small\"\n              *ngIf=\"log.user\"\n            >\n              <span class=\"text-label-small\">\n                {{ 'by`user`' | translate }}\n              </span>\n              {{ log.user }}\n            </span>\n            <span class=\"small\">\n              <span class=\"text-label-small\">\n                {{ 'device time' | translate }}\n              </span>\n              {{ log.time | c8yDate: 'medium' }}\n            </span>\n          </div>\n        </c8y-li-body>\n      </c8y-li>\n    </c8y-li-timeline>\n  </c8y-list-group>\n</ng-container>\n" }]
        }], ctorParameters: () => [{ type: AlarmDetailsService }, { type: i2.AlarmService }, { type: i3.AlertService }, { type: i3.AppStateService }, { type: i2.AuditService }, { type: i3.RelativeTimePipe }, { type: Ng1SmartRulesUpgradeService, decorators: [{
                    type: Optional
                }] }, { type: i1$1.TranslateService }, { type: i2.InventoryService }, { type: AlarmsViewService }, { type: i3.ColorService }, { type: i3.InterAppService }, { type: i3.GainsightService }, { type: AlarmsActivityTrackerService }], propDecorators: { selectedAlarm: [{
                type: Input
            }], visibilityChange: [{
                type: HostListener,
                args: ['document:visibilitychange']
            }] } });

class AlarmEmptyComponent {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmEmptyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: AlarmEmptyComponent, isStandalone: true, selector: "c8y-alarms-empty", ngImport: i0, template: "<div class=\"p-24 hidden-sm\" data-cy=\"c8y-alarms-empty\">\n  <c8y-ui-empty-state\n    [icon]=\"'alarm'\"\n    [title]=\"'No alarm selected' | translate\"\n    [subtitle]=\"'Select an alarm from the list to view its details.' | translate\"\n    [horizontal]=\"true\"\n  ></c8y-ui-empty-state>\n</div>\n", dependencies: [{ kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmEmptyComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarms-empty', imports: [EmptyStateComponent, C8yTranslatePipe], template: "<div class=\"p-24 hidden-sm\" data-cy=\"c8y-alarms-empty\">\n  <c8y-ui-empty-state\n    [icon]=\"'alarm'\"\n    [title]=\"'No alarm selected' | translate\"\n    [subtitle]=\"'Select an alarm from the list to view its details.' | translate\"\n    [horizontal]=\"true\"\n  ></c8y-ui-empty-state>\n</div>\n" }]
        }] });

class AlarmInfoComponent {
    constructor(activatedRoute, router, contextRouteService, alarmsViewService) {
        this.activatedRoute = activatedRoute;
        this.router = router;
        this.contextRouteService = contextRouteService;
        this.alarmsViewService = alarmsViewService;
        this.isContextRoute = false;
        this.TITLE = gettext('Alarms');
    }
    async ngOnInit() {
        const contextData = this.contextRouteService.getContextData(this.activatedRoute);
        this.selectedAlarm$ = of(contextData.contextData);
        this.isContextRoute = this.contextRouteService.isContextRoute(this.router.url, [
            ViewContext.Device,
            ViewContext.Group
        ]);
    }
    back() {
        this.alarmsViewService.closeDetailsView$.next();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmInfoComponent, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: i3.ContextRouteService }, { token: AlarmsViewService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: AlarmInfoComponent, isStandalone: true, selector: "c8y-alarm-info", ngImport: i0, template: "<ng-container *ngIf=\"!isContextRoute\">\n  <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<div\n  class=\"inner-scroll split-view__detail split-view__detail--selected\"\n  *ngIf=\"selectedAlarm$ | async\"\n>\n  <div class=\"sticky-top bg-component\">\n    <div class=\"card-header gap-16 d-block-xs d-block-sm p-l-24 p-r-24 p-t-16 separator\">\n      <button\n        class=\"btn btn-clean text-primary visible-sm visible-xs\"\n        data-cy=\"c8y-alarms-info--back\"\n        [title]=\"'Back' | translate\"\n        (click)=\"back()\"\n      >\n        <i c8yIcon=\"chevron-left\"></i>\n        <span>{{ 'Back' | translate }}</span>\n      </button>\n\n      <div class=\"flex-no-shrink a-s-start\"></div>\n      <div class=\"flex-grow d-col\">\n        <div\n          class=\"text-break-word flex-grow text-16\"\n          data-cy=\"c8y-alarms-info--title\"\n        >\n          {{ (selectedAlarm$ | async)?.text | translate }}\n        </div>\n      </div>\n    </div>\n    <div class=\"p-relative\">\n      <c8y-tabs-outlet\n        outletName=\"alarms\"\n        orientation=\"horizontal\"\n      ></c8y-tabs-outlet>\n    </div>\n    <div class=\"card-block overflow-visible p-l-24 p-r-24\">\n      <c8y-alarm-details [selectedAlarm]=\"selectedAlarm$ | async\"></c8y-alarm-details>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: TabsOutletComponent, selector: "c8y-tabs-outlet,c8y-ui-tabs", inputs: ["tabs", "orientation", "navigatorOpen", "outletName", "context", "openFirstTab", "hasHeader"] }, { kind: "component", type: AlarmDetailsComponent, selector: "c8y-alarm-details", inputs: ["selectedAlarm"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmInfoComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarm-info', imports: [
                        NgIf,
                        TitleComponent,
                        IconDirective,
                        TabsOutletComponent,
                        AlarmDetailsComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<ng-container *ngIf=\"!isContextRoute\">\n  <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<div\n  class=\"inner-scroll split-view__detail split-view__detail--selected\"\n  *ngIf=\"selectedAlarm$ | async\"\n>\n  <div class=\"sticky-top bg-component\">\n    <div class=\"card-header gap-16 d-block-xs d-block-sm p-l-24 p-r-24 p-t-16 separator\">\n      <button\n        class=\"btn btn-clean text-primary visible-sm visible-xs\"\n        data-cy=\"c8y-alarms-info--back\"\n        [title]=\"'Back' | translate\"\n        (click)=\"back()\"\n      >\n        <i c8yIcon=\"chevron-left\"></i>\n        <span>{{ 'Back' | translate }}</span>\n      </button>\n\n      <div class=\"flex-no-shrink a-s-start\"></div>\n      <div class=\"flex-grow d-col\">\n        <div\n          class=\"text-break-word flex-grow text-16\"\n          data-cy=\"c8y-alarms-info--title\"\n        >\n          {{ (selectedAlarm$ | async)?.text | translate }}\n        </div>\n      </div>\n    </div>\n    <div class=\"p-relative\">\n      <c8y-tabs-outlet\n        outletName=\"alarms\"\n        orientation=\"horizontal\"\n      ></c8y-tabs-outlet>\n    </div>\n    <div class=\"card-block overflow-visible p-l-24 p-r-24\">\n      <c8y-alarm-details [selectedAlarm]=\"selectedAlarm$ | async\"></c8y-alarm-details>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: i3.ContextRouteService }, { type: AlarmsViewService }] });

/**
 * A service to retrieve custom indicators for the alarm list view.
 */
class AlarmListIndicatorService {
    constructor(serviceRegistry, pluginsResolver) {
        this.serviceRegistry = serviceRegistry;
        this.pluginsResolver = pluginsResolver;
    }
    get$(alarm) {
        const providers$ = this.pluginsResolver.allPluginsLoaded$.pipe(filter(Boolean), map(() => {
            return this.serviceRegistry.get('alarmListIndicator');
        }));
        return providers$.pipe(switchMap(providers => {
            const observables$ = providers.map(provider => provider.getAlarmListIndicator$(alarm).pipe(startWith(false)));
            return combineLatest(observables$);
        }), map(indicators => {
            return indicators.filter(Boolean);
        }), map(indicators => sortBy(indicators, this.byPriority)));
    }
    byPriority(item) {
        if (item.priority === undefined) {
            return 0;
        }
        return -item.priority;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmListIndicatorService, deps: [{ token: i3.ServiceRegistry }, { token: i3.PluginsResolveService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmListIndicatorService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmListIndicatorService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: () => [{ type: i3.ServiceRegistry }, { type: i3.PluginsResolveService }] });

/**
 * A pipe to provide custom indicators for the alarm list view.
 *
 * Will call `get$()` method of `AlarmListIndicatorService` to get the custom indicators for the provided alarm.
 */
class AlarmListIndicatorPipe {
    constructor(alarmListIndicatorService) {
        this.alarmListIndicatorService = alarmListIndicatorService;
    }
    transform(alarm) {
        return this.alarmListIndicatorService.get$(alarm);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmListIndicatorPipe, deps: [{ token: AlarmListIndicatorService }], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AlarmListIndicatorPipe, isStandalone: true, name: "alarmListIndicator" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmListIndicatorPipe, decorators: [{
            type: Pipe,
            args: [{
                    standalone: true,
                    name: 'alarmListIndicator',
                    pure: true
                }]
        }], ctorParameters: () => [{ type: AlarmListIndicatorService }] });

/**
 * Pipe for transforming an array of alarm severity types into a comma-separated string.
 *
 * @example
 * Usage in a template: {{ ['WARNING', 'CRITICAL'] | AlarmSeveritiesToTitle }}
 * Result: 'Warning, Critical'
 */
class AlarmSeveritiesToTitlePipe {
    constructor(translateService) {
        this.translateService = translateService;
        this.severityOptionsCount = Object.keys(SEVERITY_LABELS).length;
    }
    /**
     * Transforms an array of alarm severity types into a comma-separated string.
     *
     * @param severities - Array of severity types.
     * @returns - Transformed human-readable title string.
     */
    transform(severities) {
        const uniqueSeverities = [...new Set(severities)];
        if (uniqueSeverities.some(severity => !(severity in SEVERITY_LABELS))) {
            return null;
        }
        if (uniqueSeverities.length === this.severityOptionsCount) {
            return this.translateService.instant(gettext('All alarms'));
        }
        const translatedChips = uniqueSeverities.map(severity => this.translateSeverityLabel(severity));
        return translatedChips.join(', ');
    }
    /**
     * Translates and converts a severity type to title case.
     *
     * @private
     * @param chip - Severity type.
     * @returns - Translated and title-cased severity type.
     */
    translateSeverityLabel(chip) {
        return this.translateService.instant(SEVERITY_LABELS[chip]);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeveritiesToTitlePipe, deps: [{ token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeveritiesToTitlePipe, isStandalone: true, name: "AlarmSeveritiesToTitle" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeveritiesToTitlePipe, decorators: [{
            type: Pipe,
            args: [{ name: 'AlarmSeveritiesToTitle' }]
        }], ctorParameters: () => [{ type: i1$1.TranslateService }] });

class AlarmSeverityToIconClassPipe {
    transform(alarmSeverity) {
        let severityClassName = '';
        let iconClassName = '';
        switch (alarmSeverity) {
            case Severity.CRITICAL:
                severityClassName = 'critical';
                iconClassName = 'exclamation-circle';
                break;
            case Severity.MAJOR:
                severityClassName = 'major';
                iconClassName = 'warning';
                break;
            case Severity.MINOR:
                severityClassName = 'minor';
                iconClassName = 'high-priority';
                break;
            case Severity.WARNING:
                severityClassName = 'warning';
                iconClassName = 'circle';
                break;
            default:
                return '';
        }
        return `status icon-lg stroked-icon dlt-c8y-icon-${iconClassName} ${severityClassName}`;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeverityToIconClassPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeverityToIconClassPipe, isStandalone: true, name: "AlarmSeverityToIconClass" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeverityToIconClassPipe, decorators: [{
            type: Pipe,
            args: [{
                    name: 'AlarmSeverityToIconClass',
                    standalone: true
                }]
        }] });

/**
 * Pipe to transform alarm severity to corresponding label.
 */
class AlarmSeverityToLabelPipe {
    constructor(translateService) {
        this.translateService = translateService;
    }
    /**
     * Transforms an alarm severity to its corresponding label.
     * @param alarmSeverity - The alarm severity to transform.
     * @returns The translated label corresponding to the given alarm severity.
     */
    transform(alarmSeverity) {
        const alarmStatusMapped = SEVERITY_LABELS[alarmSeverity?.toUpperCase()];
        return this.translateService.instant(alarmStatusMapped ?? alarmSeverity);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeverityToLabelPipe, deps: [{ token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeverityToLabelPipe, isStandalone: true, name: "AlarmSeverityToLabel" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmSeverityToLabelPipe, decorators: [{
            type: Pipe,
            args: [{ name: 'AlarmSeverityToLabel' }]
        }], ctorParameters: () => [{ type: i1$1.TranslateService }] });

/**
 * Pipe to transform alarm status to corresponding label.
 */
class AlarmStatusToLabelPipe {
    constructor(translateService) {
        this.translateService = translateService;
    }
    /**
     * Transforms an alarm status to its corresponding label.
     * @param alarmStatus - The alarm status to transform.
     * @returns The translated label corresponding to the given alarm status.
     */
    transform(alarmStatus) {
        return this.translateService.instant(ALARM_STATUS_LABELS[alarmStatus?.toUpperCase()]);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmStatusToLabelPipe, deps: [{ token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AlarmStatusToLabelPipe, isStandalone: true, name: "AlarmStatusToLabel" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmStatusToLabelPipe, decorators: [{
            type: Pipe,
            args: [{ name: 'AlarmStatusToLabel' }]
        }], ctorParameters: () => [{ type: i1$1.TranslateService }] });

class AlarmsFilterComponent {
    constructor(formBuilder, alarmsViewService, alertService, router, activatedRoute) {
        this.formBuilder = formBuilder;
        this.alarmsViewService = alarmsViewService;
        this.alertService = alertService;
        this.router = router;
        this.activatedRoute = activatedRoute;
        this.severitiesList = Object.keys(SEVERITY_LABELS);
        /**
         * EventEmitter to notify when filters have been applied.
         * Emits a `AlarmListFormFilters` object representing the filter criteria applied by the user.
         */
        this.onFilterApplied = new EventEmitter();
        this.formGroup = this.formBuilder.group(DEFAULT_SEVERITY_VALUES);
        this.chips = [];
        this.showCleared = false;
        this.alarmCounts = DEFAULT_ALARM_COUNTS;
        this.SEVERITY_LABELS = SEVERITY_LABELS;
        this.PRODUCT_EXPERIENCE_ALARMS = PRODUCT_EXPERIENCE_ALARMS;
        this.isNoneCheckboxSelected$ = new BehaviorSubject(false);
        this.severitiesTouched$ = new BehaviorSubject(false);
        this.currentFormGroupValues = this.formGroup.value;
        this.destroy$ = new Subject();
    }
    ngOnInit() {
        this.activatedRoute.queryParams.pipe(takeUntil(this.destroy$)).subscribe(params => {
            this.showCleared = params.showCleared === 'true';
            this.formGroup.setValue({
                [Severity.CRITICAL]: params[Severity.CRITICAL] === 'true',
                [Severity.MAJOR]: params[Severity.MAJOR] === 'true',
                [Severity.MINOR]: params[Severity.MINOR] === 'true',
                [Severity.WARNING]: params[Severity.WARNING] === 'true'
            });
            if (params.lastUpdatedFrom) {
                this.selectedDates = [new Date(params.lastUpdatedFrom), new Date(params.createdTo)];
            }
            this.applyFilters(true, false);
        });
        this.trackCheckboxStateWithFormChanges();
        this.currentShowClearedValue = this.showCleared;
        this.updateChipsAndDefaultValues();
    }
    ngAfterViewInit() {
        this.filtersDropdown.isOpenChange
            .pipe(takeUntil(this.destroy$), filter(Boolean))
            .subscribe(() => this.updateAlarmsCount());
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    allChanged(selected) {
        this.formGroup.patchValue({
            [Severity.CRITICAL]: selected,
            [Severity.MAJOR]: selected,
            [Severity.MINOR]: selected,
            [Severity.WARNING]: selected
        });
    }
    applyFilters(emit = true, navigate = true) {
        this.updateChipsAndDefaultValues();
        const combinedFormEvent = {
            showCleared: this.showCleared,
            severityOptions: this.formGroup.value,
            selectedDates: this.selectedDates
        };
        if (emit) {
            this.onFilterApplied.emit(combinedFormEvent);
        }
        this.currentFormGroupValues = this.formGroup.value;
        this.currentShowClearedValue = this.showCleared;
        if (navigate) {
            this.router.navigate([], {
                queryParams: {
                    showCleared: combinedFormEvent.showCleared,
                    ...combinedFormEvent.severityOptions,
                    lastUpdatedFrom: combinedFormEvent.selectedDates?.[0]?.toISOString(),
                    createdTo: combinedFormEvent.selectedDates?.[1]?.toISOString()
                },
                queryParamsHandling: 'merge'
            });
        }
    }
    deselectChip(chip) {
        this.formGroup.patchValue({
            ...this.formGroup.value,
            [chip]: false
        });
        this.applyFilters(false);
        this.closeDropdown();
    }
    closeDropdown() {
        if (this.filtersDropdown.isOpen) {
            this.filtersDropdown.isOpen = false;
        }
    }
    resetForm() {
        this.formGroup.reset(this.currentFormGroupValues);
        this.severitiesTouched$.next(false);
        this.showCleared = this.currentShowClearedValue;
    }
    markSeveritiesAsTouched() {
        this.severitiesTouched$.next(true);
    }
    /**
     * Asynchronously fetches and updates the count of alarms for each severity level.
     *
     * @param showCleared - Whether to include cleared alarms in the count.
     * Defaults to the current value of `this.currentShowClearedValue`.
     * @returns A Promise that resolves when all alarm counts have been fetched,
     * or rejects with an error if the operation fails.
     * @throws Will throw an error if any of the alarm count fetching promises reject.
     */
    async updateAlarmsCount(showCleared = this.currentShowClearedValue) {
        this.countLoading = true;
        const alarmFilter = this.contextSourceId
            ? {
                source: this.contextSourceId,
                withSourceAssets: true,
                withSourceDevices: true
            }
            : null;
        const observables = this.severitiesList.reduce((acc, severity) => {
            acc[severity] = from(this.alarmsViewService.getAlarmsCountBySeverity(severity, showCleared, alarmFilter));
            return acc;
        }, {
            CRITICAL: null,
            MAJOR: null,
            MINOR: null,
            WARNING: null
        });
        forkJoin(observables)
            .pipe(catchError(err => {
            this.alarmCounts = {};
            this.alertService.addServerFailure(err);
            return EMPTY;
        }), finalize(() => (this.countLoading = false)))
            .subscribe((alarmCounts) => (this.alarmCounts = alarmCounts));
    }
    createFormValueWithChangesStream() {
        return this.formGroup.valueChanges.pipe(startWith(this.formGroup.value));
    }
    trackCheckboxStateWithFormChanges() {
        const formValue$ = this.createFormValueWithChangesStream();
        this.isEachCheckboxSelected$ = this.createAllSelectedStream(formValue$);
        this.isIndeterminate$ = this.createIndeterminateStream(formValue$);
        this.trackAllCheckboxesDisabled(formValue$);
        this.shouldDisableApplyButton$ = this.createDisableApplyButtonStream();
    }
    createAllSelectedStream(formValue$) {
        return formValue$.pipe(map(severities => Object.values(severities).every(Boolean)));
    }
    createIndeterminateStream(formValue$) {
        return formValue$.pipe(map(severities => Object.values(severities).some(Boolean) && !Object.values(severities).every(Boolean)));
    }
    trackAllCheckboxesDisabled(formValue$) {
        formValue$.pipe(takeUntil(this.destroy$)).subscribe(severities => {
            const areAllDisabled = Object.values(severities).every(value => !value);
            this.isNoneCheckboxSelected$.next(areAllDisabled);
        });
    }
    createDisableApplyButtonStream() {
        return combineLatest([this.isNoneCheckboxSelected$, this.severitiesTouched$]).pipe(map(([allCheckboxesAreDisabled, severitiesTouched]) => allCheckboxesAreDisabled || !severitiesTouched));
    }
    updateChipsAndDefaultValues() {
        const severityFilter = this.formGroup;
        const seveerityValues = severityFilter.value;
        this.chips = Object.keys(seveerityValues).filter(key => seveerityValues[key]);
        const allChipsRemoved = this.chips.length === 0;
        if (allChipsRemoved) {
            const defaultValues = DEFAULT_SEVERITY_VALUES;
            severityFilter.setValue(defaultValues);
            this.chips = Object.keys(defaultValues);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsFilterComponent, deps: [{ token: i1$2.FormBuilder }, { token: AlarmsViewService }, { token: i3.AlertService }, { token: i1.Router }, { token: i1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: AlarmsFilterComponent, isStandalone: true, selector: "c8y-alarms-filter", inputs: { contextSourceId: "contextSourceId" }, outputs: { onFilterApplied: "onFilterApplied" }, viewQueries: [{ propertyName: "filtersDropdown", first: true, predicate: ["filtersDropdown"], descendants: true }], ngImport: i0, template: "<form\n  class=\"d-flex a-i-center\"\n  [formGroup]=\"formGroup\"\n>\n  <div\n    class=\"dropdown\"\n    title=\"{{ 'Filter by severity' | translate }}\"\n    container=\"body\"\n    dropdown\n    #filtersDropdown=\"bs-dropdown\"\n    [cdkTrapFocus]=\"filtersDropdown.isOpen\"\n    [insideClick]=\"true\"\n  >\n    <div class=\"input-group fit-w\">\n      <div\n        class=\"form-control d-flex a-i-center inner-scroll\"\n        style=\"min-width: 104px; padding-top: 0; padding-bottom: 0\"\n      >\n        @if (chips.length !== severitiesList.length) {\n          @for (chip of chips; track chip) {\n            <span\n              class=\"tag tag--info chip\"\n              [attr.data-cy]=\"'c8y-alarms-filter--chip-' + chip\"\n            >\n              <button\n                class=\"btn btn-xs btn-clean text-10\"\n                title=\"{{ 'Remove' | translate }}\"\n                type=\"button\"\n                data-cy=\"c8y-alarms-filter--remove-chip\"\n                c8yProductExperience\n                [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n                [actionData]=\"{\n                  component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARMS_FILTER,\n                  action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.REMOVE_CHIP_FILTER,\n                  filterValues: {\n                    severities: formGroup.value,\n                    showCleared: showCleared\n                  }\n                }\"\n                (click)=\"deselectChip(chip); $event.stopPropagation()\"\n              >\n                <i c8yIcon=\"times\"></i>\n              </button>\n              <i\n                class=\"status stroked-icon icon-12\"\n                [c8yIcon]=\"chip | AlarmSeverityToIcon\"\n                [attr.data-cy]=\"'c8y-alarms-filter--icon-' + chip\"\n                [ngClass]=\"chip | lowercase\"\n              ></i>\n              {{ SEVERITY_LABELS[chip] | translate }}\n            </span>\n          }\n        } @else {\n          <span\n            class=\"text-truncate\"\n            title=\"{{ 'All severities' | translate }}\"\n          >\n            {{ 'All severities' | translate }}\n          </span>\n        }\n      </div>\n      <div class=\"input-group-btn input-group-btn--last\">\n        <button\n          class=\"btn-default btn btn--caret\"\n          title=\"{{ chips | AlarmSeveritiesToTitle }}\"\n          data-cy=\"c8y-alarms-filter\"\n          dropdownToggle\n          (click)=\"resetForm()\"\n        >\n          <i class=\"caret\"></i>\n        </button>\n      </div>\n    </div>\n    <ul\n      class=\"dropdown-menu dropdown-menu-action-bar\"\n      *dropdownMenu\n    >\n      <li class=\"p-l-16 p-r-16 p-t-4 p-b-4 d-flex a-i-center sticky-top separator-bottom\">\n        <label\n          class=\"c8y-checkbox d-flex a-i-center\"\n          [title]=\"'All' | translate\"\n        >\n          <input\n            type=\"checkbox\"\n            data-cy=\"c8y-alarms-filter--all\"\n            [ngModelOptions]=\"{ standalone: true }\"\n            (ngModelChange)=\"allChanged($event)\"\n            [ngModel]=\"isEachCheckboxSelected$ | async\"\n            [indeterminate]=\"isIndeterminate$ | async\"\n            (click)=\"markSeveritiesAsTouched()\"\n          />\n          <span></span>\n          <i\n            class=\"status stroked-icon m-l-8 icon-20\"\n            [c8yIcon]=\"'bell'\"\n          ></i>\n          <span class=\"m-l-8\">{{ 'All' | translate }}</span>\n        </label>\n      </li>\n      @for (severity of severitiesList; track severity) {\n        <li class=\"p-l-16 p-r-16 p-t-4 p-b-4 d-flex a-i-center\">\n          <label\n            class=\"c8y-checkbox d-flex a-i-center\"\n            [title]=\"SEVERITY_LABELS[severity] | translate\"\n          >\n            <input\n              type=\"checkbox\"\n              [attr.data-cy]=\"'c8y-alarms-filter--' + severity\"\n              [formControlName]=\"severity\"\n              [value]=\"severity\"\n              (click)=\"markSeveritiesAsTouched()\"\n            />\n            <span></span>\n            <i\n              class=\"status stroked-icon m-l-8 icon-20\"\n              [c8yIcon]=\"severity | AlarmSeverityToIcon\"\n              [ngClass]=\"severity | lowercase\"\n            ></i>\n            <span class=\"m-l-8\">{{ SEVERITY_LABELS[severity] | translate }}</span>\n          </label>\n          <!-- badge -->\n          @if (alarmCounts[severity] || alarmCounts[severity] === 0) {\n            <div class=\"badge badge-info m-l-auto\">\n              @if (countLoading) {\n                <i\n                  class=\"icon-spin\"\n                  [c8yIcon]=\"'circle-o-notch'\"\n                ></i>\n              }\n              @if (!countLoading) {\n                <span [attr.data-cy]=\"'c8y-alarms-filter--' + severity + '-badge'\">\n                  {{ alarmCounts[severity] < 99 ? alarmCounts[severity] : '99+' }}\n                </span>\n              }\n            </div>\n          }\n        </li>\n      }\n      <li class=\"p-l-16 p-r-16 p-t-4 p-b-4 d-flex a-i-center separator-top\">\n        <label\n          class=\"c8y-switch\"\n          [attr.aria-label]=\"'Show cleared alarms' | translate\"\n          [attr.data-cy]=\"'c8y-alarms-filter--cleared'\"\n        >\n          <input\n            type=\"checkbox\"\n            #showClearedCheckbox\n            [ngModelOptions]=\"{ standalone: true }\"\n            [(ngModel)]=\"showCleared\"\n            (click)=\"markSeveritiesAsTouched(); updateAlarmsCount(showClearedCheckbox.checked)\"\n          />\n          <span></span>\n          <span\n            class=\"text-truncate\"\n            title=\"{{ 'Show cleared alarms' | translate }}\"\n          >\n            {{ 'Show cleared alarms' | translate }}\n          </span>\n        </label>\n      </li>\n      <li class=\"p-16 d-flex sticky-bottom separator-top\">\n        <button\n          class=\"btn btn-primary btn-sm flex-grow\"\n          title=\"{{ 'Apply' | translate }}\"\n          type=\"button\"\n          data-cy=\"c8y-alarms-filter--apply\"\n          c8yProductExperience\n          [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n          [actionData]=\"{\n            component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARMS_FILTER,\n            action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.APPLY_FILTER,\n            filterValues: {\n              severities: formGroup.value,\n              showCleared: showCleared\n            }\n          }\"\n          (click)=\"applyFilters(false); closeDropdown()\"\n          [disabled]=\"shouldDisableApplyButton$ | async\"\n        >\n          {{ 'Apply' | translate }}\n        </button>\n      </li>\n    </ul>\n  </div>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: LowerCasePipe, name: "lowercase" }, { kind: "pipe", type: AlarmSeverityToIconPipe, name: "AlarmSeverityToIcon" }, { kind: "pipe", type: AlarmSeveritiesToTitlePipe, name: "AlarmSeveritiesToTitle" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsFilterComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarms-filter', imports: [
                        FormsModule,
                        ReactiveFormsModule,
                        BsDropdownDirective,
                        CdkTrapFocus,
                        NgIf,
                        NgFor,
                        ProductExperienceDirective,
                        IconDirective,
                        NgClass,
                        BsDropdownToggleDirective,
                        BsDropdownMenuDirective,
                        RequiredInputPlaceholderDirective,
                        C8yTranslatePipe,
                        AsyncPipe,
                        LowerCasePipe,
                        AlarmSeverityToIconPipe,
                        AlarmSeveritiesToTitlePipe
                    ], template: "<form\n  class=\"d-flex a-i-center\"\n  [formGroup]=\"formGroup\"\n>\n  <div\n    class=\"dropdown\"\n    title=\"{{ 'Filter by severity' | translate }}\"\n    container=\"body\"\n    dropdown\n    #filtersDropdown=\"bs-dropdown\"\n    [cdkTrapFocus]=\"filtersDropdown.isOpen\"\n    [insideClick]=\"true\"\n  >\n    <div class=\"input-group fit-w\">\n      <div\n        class=\"form-control d-flex a-i-center inner-scroll\"\n        style=\"min-width: 104px; padding-top: 0; padding-bottom: 0\"\n      >\n        @if (chips.length !== severitiesList.length) {\n          @for (chip of chips; track chip) {\n            <span\n              class=\"tag tag--info chip\"\n              [attr.data-cy]=\"'c8y-alarms-filter--chip-' + chip\"\n            >\n              <button\n                class=\"btn btn-xs btn-clean text-10\"\n                title=\"{{ 'Remove' | translate }}\"\n                type=\"button\"\n                data-cy=\"c8y-alarms-filter--remove-chip\"\n                c8yProductExperience\n                [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n                [actionData]=\"{\n                  component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARMS_FILTER,\n                  action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.REMOVE_CHIP_FILTER,\n                  filterValues: {\n                    severities: formGroup.value,\n                    showCleared: showCleared\n                  }\n                }\"\n                (click)=\"deselectChip(chip); $event.stopPropagation()\"\n              >\n                <i c8yIcon=\"times\"></i>\n              </button>\n              <i\n                class=\"status stroked-icon icon-12\"\n                [c8yIcon]=\"chip | AlarmSeverityToIcon\"\n                [attr.data-cy]=\"'c8y-alarms-filter--icon-' + chip\"\n                [ngClass]=\"chip | lowercase\"\n              ></i>\n              {{ SEVERITY_LABELS[chip] | translate }}\n            </span>\n          }\n        } @else {\n          <span\n            class=\"text-truncate\"\n            title=\"{{ 'All severities' | translate }}\"\n          >\n            {{ 'All severities' | translate }}\n          </span>\n        }\n      </div>\n      <div class=\"input-group-btn input-group-btn--last\">\n        <button\n          class=\"btn-default btn btn--caret\"\n          title=\"{{ chips | AlarmSeveritiesToTitle }}\"\n          data-cy=\"c8y-alarms-filter\"\n          dropdownToggle\n          (click)=\"resetForm()\"\n        >\n          <i class=\"caret\"></i>\n        </button>\n      </div>\n    </div>\n    <ul\n      class=\"dropdown-menu dropdown-menu-action-bar\"\n      *dropdownMenu\n    >\n      <li class=\"p-l-16 p-r-16 p-t-4 p-b-4 d-flex a-i-center sticky-top separator-bottom\">\n        <label\n          class=\"c8y-checkbox d-flex a-i-center\"\n          [title]=\"'All' | translate\"\n        >\n          <input\n            type=\"checkbox\"\n            data-cy=\"c8y-alarms-filter--all\"\n            [ngModelOptions]=\"{ standalone: true }\"\n            (ngModelChange)=\"allChanged($event)\"\n            [ngModel]=\"isEachCheckboxSelected$ | async\"\n            [indeterminate]=\"isIndeterminate$ | async\"\n            (click)=\"markSeveritiesAsTouched()\"\n          />\n          <span></span>\n          <i\n            class=\"status stroked-icon m-l-8 icon-20\"\n            [c8yIcon]=\"'bell'\"\n          ></i>\n          <span class=\"m-l-8\">{{ 'All' | translate }}</span>\n        </label>\n      </li>\n      @for (severity of severitiesList; track severity) {\n        <li class=\"p-l-16 p-r-16 p-t-4 p-b-4 d-flex a-i-center\">\n          <label\n            class=\"c8y-checkbox d-flex a-i-center\"\n            [title]=\"SEVERITY_LABELS[severity] | translate\"\n          >\n            <input\n              type=\"checkbox\"\n              [attr.data-cy]=\"'c8y-alarms-filter--' + severity\"\n              [formControlName]=\"severity\"\n              [value]=\"severity\"\n              (click)=\"markSeveritiesAsTouched()\"\n            />\n            <span></span>\n            <i\n              class=\"status stroked-icon m-l-8 icon-20\"\n              [c8yIcon]=\"severity | AlarmSeverityToIcon\"\n              [ngClass]=\"severity | lowercase\"\n            ></i>\n            <span class=\"m-l-8\">{{ SEVERITY_LABELS[severity] | translate }}</span>\n          </label>\n          <!-- badge -->\n          @if (alarmCounts[severity] || alarmCounts[severity] === 0) {\n            <div class=\"badge badge-info m-l-auto\">\n              @if (countLoading) {\n                <i\n                  class=\"icon-spin\"\n                  [c8yIcon]=\"'circle-o-notch'\"\n                ></i>\n              }\n              @if (!countLoading) {\n                <span [attr.data-cy]=\"'c8y-alarms-filter--' + severity + '-badge'\">\n                  {{ alarmCounts[severity] < 99 ? alarmCounts[severity] : '99+' }}\n                </span>\n              }\n            </div>\n          }\n        </li>\n      }\n      <li class=\"p-l-16 p-r-16 p-t-4 p-b-4 d-flex a-i-center separator-top\">\n        <label\n          class=\"c8y-switch\"\n          [attr.aria-label]=\"'Show cleared alarms' | translate\"\n          [attr.data-cy]=\"'c8y-alarms-filter--cleared'\"\n        >\n          <input\n            type=\"checkbox\"\n            #showClearedCheckbox\n            [ngModelOptions]=\"{ standalone: true }\"\n            [(ngModel)]=\"showCleared\"\n            (click)=\"markSeveritiesAsTouched(); updateAlarmsCount(showClearedCheckbox.checked)\"\n          />\n          <span></span>\n          <span\n            class=\"text-truncate\"\n            title=\"{{ 'Show cleared alarms' | translate }}\"\n          >\n            {{ 'Show cleared alarms' | translate }}\n          </span>\n        </label>\n      </li>\n      <li class=\"p-16 d-flex sticky-bottom separator-top\">\n        <button\n          class=\"btn btn-primary btn-sm flex-grow\"\n          title=\"{{ 'Apply' | translate }}\"\n          type=\"button\"\n          data-cy=\"c8y-alarms-filter--apply\"\n          c8yProductExperience\n          [actionName]=\"PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS\"\n          [actionData]=\"{\n            component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARMS_FILTER,\n            action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.APPLY_FILTER,\n            filterValues: {\n              severities: formGroup.value,\n              showCleared: showCleared\n            }\n          }\"\n          (click)=\"applyFilters(false); closeDropdown()\"\n          [disabled]=\"shouldDisableApplyButton$ | async\"\n        >\n          {{ 'Apply' | translate }}\n        </button>\n      </li>\n    </ul>\n  </div>\n</form>\n" }]
        }], ctorParameters: () => [{ type: i1$2.FormBuilder }, { type: AlarmsViewService }, { type: i3.AlertService }, { type: i1.Router }, { type: i1.ActivatedRoute }], propDecorators: { contextSourceId: [{
                type: Input
            }], onFilterApplied: [{
                type: Output
            }], filtersDropdown: [{
                type: ViewChild,
                args: ['filtersDropdown']
            }] } });

class AlarmsIconComponent {
    constructor() {
        this.iconBackgroundColor = 'none';
        this.isFilterApplied = false;
        this.alarmSeverityLabel = gettext('Severity: {{ alarmSeverity }}');
        this.alarmStatusLabel = gettext('Status: {{ alarmStatus }}');
        this.alarmStatusType = gettext('Type: {{ alarmType }}');
    }
    ngOnInit() {
        this.isFilterApplied = this.typeFilters.length > 0;
        this.iconBackgroundColor =
            this.typeFilters.find(filter => filter.filters.type === this.alarm.type)?.color || 'none';
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: AlarmsIconComponent, isStandalone: true, selector: "c8y-alarms-icon", inputs: { alarm: "alarm", typeFilters: "typeFilters" }, ngImport: i0, template: "<button\n  class=\"btn-clean severity\"\n  [attr.aria-label]=\"\n    alarmSeverityLabel | translate: { alarmSeverity: alarm.severity | AlarmSeverityToLabel }\n  \"\n  [tooltip]=\"\n    alarmSeverityLabel | translate: { alarmSeverity: alarm.severity | AlarmSeverityToLabel }\n  \"\n  placement=\"right\"\n  container=\"body\"\n  type=\"button\"\n  (click)=\"$event.stopPropagation()\"\n  [delay]=\"500\"\n>\n  <i\n    class=\"status stroked-icon\"\n    [c8yIcon]=\"alarm.severity | AlarmSeverityToIcon\"\n    [ngClass]=\"alarm.severity | lowercase\"\n  ></i>\n</button>\n<button\n  class=\"btn-clean status\"\n  [ngStyle]=\"{ 'background-color': iconBackgroundColor }\"\n  [attr.aria-label]=\"\n    alarmStatusLabel | translate: { alarmStatus: alarm.status | AlarmStatusToLabel }\n  \"\n  [tooltip]=\"\n    (alarmStatusLabel | translate: { alarmStatus: alarm.status | AlarmStatusToLabel }) +\n    '\\n' +\n    (alarmStatusType | translate: { alarmType: alarm.type })\n  \"\n  placement=\"right\"\n  container=\"body\"\n  type=\"button\"\n  [ngClass]=\"{ 'circle-icon-wrapper': isFilterApplied }\"\n  data-cy=\"c8y-alarms-icon--status-icon\"\n  (click)=\"$event.stopPropagation()\"\n  [delay]=\"500\"\n>\n  <i\n    [c8yIcon]=\"alarm.status | AlarmStatusToIcon\"\n    [ngClass]=\"{ 'stroked-icon': isFilterApplied }\"\n  ></i>\n</button>\n", dependencies: [{ kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: LowerCasePipe, name: "lowercase" }, { kind: "pipe", type: AlarmSeverityToIconPipe, name: "AlarmSeverityToIcon" }, { kind: "pipe", type: AlarmStatusToIconPipe, name: "AlarmStatusToIcon" }, { kind: "pipe", type: AlarmSeverityToLabelPipe, name: "AlarmSeverityToLabel" }, { kind: "pipe", type: AlarmStatusToLabelPipe, name: "AlarmStatusToLabel" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsIconComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarms-icon', imports: [
                        TooltipDirective,
                        IconDirective,
                        NgClass,
                        NgStyle,
                        C8yTranslatePipe,
                        LowerCasePipe,
                        AlarmSeverityToIconPipe,
                        AlarmStatusToIconPipe,
                        AlarmSeverityToLabelPipe,
                        AlarmStatusToLabelPipe
                    ], template: "<button\n  class=\"btn-clean severity\"\n  [attr.aria-label]=\"\n    alarmSeverityLabel | translate: { alarmSeverity: alarm.severity | AlarmSeverityToLabel }\n  \"\n  [tooltip]=\"\n    alarmSeverityLabel | translate: { alarmSeverity: alarm.severity | AlarmSeverityToLabel }\n  \"\n  placement=\"right\"\n  container=\"body\"\n  type=\"button\"\n  (click)=\"$event.stopPropagation()\"\n  [delay]=\"500\"\n>\n  <i\n    class=\"status stroked-icon\"\n    [c8yIcon]=\"alarm.severity | AlarmSeverityToIcon\"\n    [ngClass]=\"alarm.severity | lowercase\"\n  ></i>\n</button>\n<button\n  class=\"btn-clean status\"\n  [ngStyle]=\"{ 'background-color': iconBackgroundColor }\"\n  [attr.aria-label]=\"\n    alarmStatusLabel | translate: { alarmStatus: alarm.status | AlarmStatusToLabel }\n  \"\n  [tooltip]=\"\n    (alarmStatusLabel | translate: { alarmStatus: alarm.status | AlarmStatusToLabel }) +\n    '\\n' +\n    (alarmStatusType | translate: { alarmType: alarm.type })\n  \"\n  placement=\"right\"\n  container=\"body\"\n  type=\"button\"\n  [ngClass]=\"{ 'circle-icon-wrapper': isFilterApplied }\"\n  data-cy=\"c8y-alarms-icon--status-icon\"\n  (click)=\"$event.stopPropagation()\"\n  [delay]=\"500\"\n>\n  <i\n    [c8yIcon]=\"alarm.status | AlarmStatusToIcon\"\n    [ngClass]=\"{ 'stroked-icon': isFilterApplied }\"\n  ></i>\n</button>\n" }]
        }], propDecorators: { alarm: [{
                type: Input
            }], typeFilters: [{
                type: Input
            }] } });

class AlarmsIntervalRefreshComponent {
    /**
     * * Set the value of `isIntervalEnabled` in response to user interactions with the alarm list scroll.
     *  *
     *  * This input setter allows you to control the `isIntervalEnabled` property, which is used to manage the state
     *  * of a toggle button. When a user scrolls through the alarms list, you can update the `isIntervalEnabled` value
     *  * using this setter.
     *  *
     *  * @param value - A boolean value representing the new state of the `isIntervalEnabled` property.
     *  *   - `true` indicates that the interval is enabled.
     *  *   - `false` indicates that the interval is disabled.
     */
    set isIntervalToggleEnabled(value) {
        const shouldSetInterval = this.isIntervalToggleEnabled || this.doesUserCheckedIntervalToggle;
        const shouldToggleInterval = !this.isDisabled &&
            this.isIntervalToggleEnabled &&
            this.doesUserCheckedIntervalToggle &&
            value;
        const intervalToggleControl = this.toggleIntervalForm.get('intervalToggle');
        /**
         * We check if any interactions to toggle interval button were made.
         * When user interacts with toggle button, we need to ignore assigning value to the form.
         */
        if (intervalToggleControl.dirty && !shouldSetInterval) {
            return;
        }
        /**
         * This condition checks if the interval toggle is enabled and if there has been user interaction,
         * and if the provided value is truthy.
         * If all conditions are met, the interval toggle should not be updated due to unnecessary update of countdown interval component
         */
        if (shouldToggleInterval) {
            return;
        }
        intervalToggleControl.setValue(value);
    }
    /**
     * This getter allows you to access the current state of the `isIntervalEnabled` property, which reflects
     * the state of a toggle button. It retrieves the value from the associated form control, providing the
     * current state of the toggle button.
     */
    get isIntervalToggleEnabled() {
        return !this.isDisabled && this.toggleIntervalForm.get('intervalToggle').value;
    }
    constructor(fb, alarmsViewService) {
        this.fb = fb;
        this.alarmsViewService = alarmsViewService;
        this.refreshIntervalsInMilliseconds = this.alarmsViewService.DEFAULT_INTERVAL_VALUES;
        this.DISABLE_AUTO_REFRESH = gettext('Disable auto refresh');
        this.ENABLE_AUTO_REFRESH = gettext('Enable auto refresh');
        this.SECONDS_UNTIL_REFRESH = gettext('{{ seconds }} s');
        this.isDisabled = false;
        /**
         * Event emitter for notifying when a countdown timer has completed.
         */
        this.onCountdownEnded = new EventEmitter();
        this.toggleIntervalForm = this.initForm();
        this.destroy$ = new Subject();
    }
    ngOnInit() {
        this.listenToRefreshIntervalChange();
    }
    ngAfterViewInit() {
        this.onIntervalToggleChange();
        this.listenOnLoadingChanges();
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    resetCountdown() {
        this.countdownIntervalComponent?.reset();
    }
    trackUserClickOnIntervalToggle(target) {
        this.doesUserCheckedIntervalToggle = target.checked;
    }
    getTooltip() {
        return this.isDisabled
            ? gettext('Disabled')
            : this.isIntervalToggleEnabled
                ? this.DISABLE_AUTO_REFRESH
                : this.ENABLE_AUTO_REFRESH;
    }
    startCountdown() {
        this.countdownIntervalComponent.start();
    }
    onIntervalToggleChange() {
        this.toggleIntervalForm
            .get('intervalToggle')
            .valueChanges.pipe(takeUntil(this.destroy$), filter(Boolean))
            .subscribe(() => setTimeout(() => this.startCountdown()));
    }
    initForm() {
        return this.fb.group({
            intervalToggle: true,
            refreshInterval: this.alarmsViewService.DEFAULT_INTERVAL_VALUE
        });
    }
    listenToRefreshIntervalChange() {
        this.toggleIntervalForm
            .get('refreshInterval')
            .valueChanges.pipe(takeUntil(this.destroy$))
            .subscribe(() => this.resetCountdown());
    }
    listenOnLoadingChanges() {
        this.alarmsListLoading$
            .pipe(tap(() => this.countdownIntervalComponent?.stop()))
            .subscribe(state => {
            !state && this.countdownIntervalComponent?.reset();
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsIntervalRefreshComponent, deps: [{ token: i1$2.FormBuilder }, { token: AlarmsViewService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: AlarmsIntervalRefreshComponent, isStandalone: true, selector: "c8y-alarms-interval-refresh", inputs: { isDisabled: "isDisabled", alarmsListLoading$: "alarmsListLoading$", isIntervalToggleEnabled: "isIntervalToggleEnabled" }, outputs: { onCountdownEnded: "onCountdownEnded" }, viewQueries: [{ propertyName: "countdownIntervalComponent", first: true, predicate: CountdownIntervalComponent, descendants: true }], ngImport: i0, template: "<form\n  class=\"d-flex a-i-center fit-w fit-h\"\n  [formGroup]=\"toggleIntervalForm\"\n>\n  <label class=\"m-b-0 m-r-8 text-normal text-muted flex-no-shrink\">\n    {{ 'Auto refresh' | translate }}\n  </label>\n  <div class=\"input-group\">\n    <label\n      class=\"toggle-countdown\"\n      [class.toggle-countdown-disabled]=\"isDisabled\"\n      [attr.aria-label]=\"getTooltip() | translate\"\n      [tooltip]=\"getTooltip() | translate\"\n      placement=\"bottom\"\n      [adaptivePosition]=\"false\"\n      [delay]=\"500\"\n      data-cy=\"c8y-alarms-interval-refresh--toggle-countdown\"\n    >\n      <input\n        type=\"checkbox\"\n        data-cy=\"c8y-alarms-interval-toggle\"\n        formControlName=\"intervalToggle\"\n        (click)=\"trackUserClickOnIntervalToggle($event.target)\"\n      />\n      <c8y-countdown-interval\n        *ngIf=\"isIntervalToggleEnabled\"\n        [countdownInterval]=\"toggleIntervalForm.value.refreshInterval\"\n        (countdownEnded)=\"onCountdownEnded.emit()\"\n      ></c8y-countdown-interval>\n      <i\n        data-cy=\"c8y-alarms-interval-refresh--pause\"\n        c8yIcon=\"pause\"\n        *ngIf=\"!isIntervalToggleEnabled\"\n      ></i>\n    </label>\n    <div\n      class=\"c8y-select-wrapper\"\n      *ngIf=\"!isDisabled\"\n    >\n      <select\n        class=\"form-control text-12\"\n        [attr.aria-label]=\"'Refresh interval in seconds' | translate\"\n        [tooltip]=\"'Refresh interval in seconds' | translate\"\n        placement=\"bottom\"\n        [adaptivePosition]=\"false\"\n        [delay]=\"500\"\n        [container]=\"'body'\"\n        formControlName=\"refreshInterval\"\n        data-cy=\"c8y-alarms-interval-refresh--selector\"\n      >\n        <option\n          [disabled]=\"isDisabled\"\n          *ngFor=\"let refreshInterval of refreshIntervalsInMilliseconds\"\n          [ngValue]=\"refreshInterval\"\n          [attr.data-cy]=\"'c8y-interval-' + refreshInterval\"\n        >\n          {{ SECONDS_UNTIL_REFRESH | translate: { seconds: refreshInterval / 1000 } }}\n        </option>\n      </select>\n      <span></span>\n    </div>\n    <div class=\"input-group-btn\">\n      <button\n        class=\"btn btn-default\"\n        style=\"border-left: 0\"\n        [attr.aria-label]=\"'Refresh' | translate\"\n        [tooltip]=\"'Refresh' | translate\"\n        placement=\"bottom\"\n        type=\"button\"\n        [adaptivePosition]=\"false\"\n        [delay]=\"500\"\n        [disabled]=\"isDisabled || (alarmsListLoading$ | async)\"\n        (click)=\"onCountdownEnded.emit()\"\n        data-cy=\"c8y-alarms-interval-refresh--btn\"\n      >\n        <i\n          c8yIcon=\"refresh\"\n          [ngClass]=\"{ 'icon-spin': alarmsListLoading$ | async }\"\n        ></i>\n      </button>\n    </div>\n  </div>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CountdownIntervalComponent, selector: "c8y-countdown-interval", inputs: ["countdownInterval", "config"], outputs: ["countdownEnded"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsIntervalRefreshComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarms-interval-refresh', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
                        FormsModule,
                        ReactiveFormsModule,
                        TooltipDirective,
                        RequiredInputPlaceholderDirective,
                        NgIf,
                        CountdownIntervalComponent,
                        IconDirective,
                        NgFor,
                        NgClass,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<form\n  class=\"d-flex a-i-center fit-w fit-h\"\n  [formGroup]=\"toggleIntervalForm\"\n>\n  <label class=\"m-b-0 m-r-8 text-normal text-muted flex-no-shrink\">\n    {{ 'Auto refresh' | translate }}\n  </label>\n  <div class=\"input-group\">\n    <label\n      class=\"toggle-countdown\"\n      [class.toggle-countdown-disabled]=\"isDisabled\"\n      [attr.aria-label]=\"getTooltip() | translate\"\n      [tooltip]=\"getTooltip() | translate\"\n      placement=\"bottom\"\n      [adaptivePosition]=\"false\"\n      [delay]=\"500\"\n      data-cy=\"c8y-alarms-interval-refresh--toggle-countdown\"\n    >\n      <input\n        type=\"checkbox\"\n        data-cy=\"c8y-alarms-interval-toggle\"\n        formControlName=\"intervalToggle\"\n        (click)=\"trackUserClickOnIntervalToggle($event.target)\"\n      />\n      <c8y-countdown-interval\n        *ngIf=\"isIntervalToggleEnabled\"\n        [countdownInterval]=\"toggleIntervalForm.value.refreshInterval\"\n        (countdownEnded)=\"onCountdownEnded.emit()\"\n      ></c8y-countdown-interval>\n      <i\n        data-cy=\"c8y-alarms-interval-refresh--pause\"\n        c8yIcon=\"pause\"\n        *ngIf=\"!isIntervalToggleEnabled\"\n      ></i>\n    </label>\n    <div\n      class=\"c8y-select-wrapper\"\n      *ngIf=\"!isDisabled\"\n    >\n      <select\n        class=\"form-control text-12\"\n        [attr.aria-label]=\"'Refresh interval in seconds' | translate\"\n        [tooltip]=\"'Refresh interval in seconds' | translate\"\n        placement=\"bottom\"\n        [adaptivePosition]=\"false\"\n        [delay]=\"500\"\n        [container]=\"'body'\"\n        formControlName=\"refreshInterval\"\n        data-cy=\"c8y-alarms-interval-refresh--selector\"\n      >\n        <option\n          [disabled]=\"isDisabled\"\n          *ngFor=\"let refreshInterval of refreshIntervalsInMilliseconds\"\n          [ngValue]=\"refreshInterval\"\n          [attr.data-cy]=\"'c8y-interval-' + refreshInterval\"\n        >\n          {{ SECONDS_UNTIL_REFRESH | translate: { seconds: refreshInterval / 1000 } }}\n        </option>\n      </select>\n      <span></span>\n    </div>\n    <div class=\"input-group-btn\">\n      <button\n        class=\"btn btn-default\"\n        style=\"border-left: 0\"\n        [attr.aria-label]=\"'Refresh' | translate\"\n        [tooltip]=\"'Refresh' | translate\"\n        placement=\"bottom\"\n        type=\"button\"\n        [adaptivePosition]=\"false\"\n        [delay]=\"500\"\n        [disabled]=\"isDisabled || (alarmsListLoading$ | async)\"\n        (click)=\"onCountdownEnded.emit()\"\n        data-cy=\"c8y-alarms-interval-refresh--btn\"\n      >\n        <i\n          c8yIcon=\"refresh\"\n          [ngClass]=\"{ 'icon-spin': alarmsListLoading$ | async }\"\n        ></i>\n      </button>\n    </div>\n  </div>\n</form>\n" }]
        }], ctorParameters: () => [{ type: i1$2.FormBuilder }, { type: AlarmsViewService }], propDecorators: { isDisabled: [{
                type: Input
            }], alarmsListLoading$: [{
                type: Input
            }], isIntervalToggleEnabled: [{
                type: Input
            }], onCountdownEnded: [{
                type: Output
            }], countdownIntervalComponent: [{
                type: ViewChild,
                args: [CountdownIntervalComponent]
            }] } });

class AlarmsListComponent {
    constructor(activatedRoute, alarmsViewService, contextRouteService, router) {
        this.activatedRoute = activatedRoute;
        this.alarmsViewService = alarmsViewService;
        this.contextRouteService = contextRouteService;
        this.router = router;
        this.alarmBadgeTooltip = gettext('Number of occurrences`number of occurrences of alarm`. First occurrence {{ alarmFirstOccurrenceTime }} (device time).');
        this.alarmLastOccurrenceLabel = gettext('Last occurrence of this alarm (device time).');
        this.hasPermissions = true;
        /**
         * Input property for the currently applied type filters.
         */
        this.typeFilters = [];
        /**
         * Input property for receiving load more mode.
         */
        this.loadMoreMode = 'hidden';
        /**
         * Defines options, how the alarm list should be navigated if a user
         * clicks on an alarm.
         */
        this.navigationOptions = {
            allowNavigationToAlarmsView: true,
            alwaysNavigateToAllAlarms: false,
            includeClearedQueryParams: false,
            queryParamsHandling: 'merge'
        };
        /**
         * Controls the visibility of the loading bar
         * When set to `false`, the alarm list is displayed. When set to `true`, the opacity of alarms list is changed and a loading bar is shown.
         */
        this.isInitialLoading = false;
        /**
         * Controls the visibility and functionality of some components
         * When set to `true`, means the list is displayed in a split view layout:
         * the list on the first column and the selected record detail on the second column (the cockpit
         * alarms view for example)
         * When set to false, the list is displayed as a standalone component, opening the detail will
         * redirect to the alarms
         */
        this.splitView = false;
        /**
         * Indicates whether the component is in widget preview mode.
         */
        this.isInPreviewMode = false;
        /**
         * Emits an instance of a selected alarm when one is chosen from the list.
         */
        this.onSelectedAlarm = new EventEmitter();
        /**
         * Emits a boolean value indicating the scrolling state: true when the user starts scrolling, and false when the user reaches the top of the list.
         */
        this.onScrollingStateChange = new EventEmitter();
        /**
         * Current alarm or last alarm marked as active by the routerLinkActive directive.
         */
        this.activeAlarm$ = new BehaviorSubject(null);
        this.activeChildParam$ = new Observable();
        this.isScrolling = false;
        /**
         * Determines whether the c8y-loading component should be displayed.
         * The loading component is shown when no alarms are displayed in the view or when the request is initial,
         * as we don't want to see empty space on alarm list during loading.
         */
        this.isEmptyListLoading = true;
        this.alertAggregator = new DynamicComponentAlertAggregator();
        this.mapAlarmLink = pipe(map((alarms) => alarms.map((alarm) => {
            alarm.link = this.getRouterLink(alarm);
            return alarm;
        })));
        this.destroy$ = new Subject();
        this.HIDE_INTERVAL_COUNTDOWN_SCROLL = 50;
        this.verifyIfFiltersMatchingAlarm();
    }
    /**
     * Handles the change of the active route.
     *
     * @param isActive - A boolean indicating whether the route is active or not.
     * @param scrollAnchor - The ListItemComponent used as a scroll anchor.
     * @param alarm - The IAlarm object representing the active alarm.
     */
    activeRouteChanged(isActive, scrollAnchor, alarm) {
        if (isActive) {
            scrollAnchor.element.nativeElement.scrollIntoView({
                behavior: 'smooth',
                block: 'nearest'
            });
            this.activeAlarm$.next(alarm);
        }
    }
    ngOnChanges(changes) {
        if (this.alarms && changes.alarms) {
            this.activeAlarm$.next(null);
            this.isEmptyListLoading = !this.alarms?.data?.length;
        }
        if (changes.hasPermissions?.currentValue === false) {
            this.alertAggregator.addAlerts(new DynamicComponentAlert({
                type: 'system',
                text: gettext("You don't have permission to view alarms.")
            }));
        }
    }
    ngAfterViewInit() {
        if (this.isInPreviewMode) {
            return;
        }
        if (this.alarmsViewService.isIntervalRefresh()) {
            const scrollElement = this.innerScrollWrapper.nativeElement;
            fromEvent(scrollElement, 'scroll')
                .pipe(takeUntil(this.destroy$), debounceTime(300))
                .subscribe((event) => {
                const target = event.target;
                this.isScrolling = this.shouldCountdownIntervalBeHidden(target);
                this.onScrollingStateChange.emit(this.isScrolling);
            });
        }
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    onAlarmOpen(alarm) {
        this.onSelectedAlarm.emit(alarm);
    }
    getRouterLink(alarm) {
        if (this.navigationOptions.alwaysNavigateToAllAlarms) {
            return this.alarmsViewService.getRouterLink(null, alarm);
        }
        const contextData = this.contextRouteService.getContextData(this.activatedRoute);
        return this.alarmsViewService.getRouterLink(contextData, alarm);
    }
    shouldCountdownIntervalBeHidden(target) {
        const scrollTopPixels = target.scrollTop;
        return scrollTopPixels > this.HIDE_INTERVAL_COUNTDOWN_SCROLL;
    }
    verifyIfFiltersMatchingAlarm() {
        this.activeChildParam$ = this.router.events.pipe(filter(e => e instanceof NavigationEnd && this.activatedRoute.children.length > 0), switchMap(() => this.activatedRoute.children[0].params), map(params => params.id), distinctUntilChanged(), shareReplay(), takeUntil(this.destroy$));
        // done to get the first navigation
        this.activeChildParam$.subscribe();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsListComponent, deps: [{ token: i1.ActivatedRoute }, { token: AlarmsViewService }, { token: i3.ContextRouteService }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: AlarmsListComponent, isStandalone: true, selector: "c8y-alarms-list", inputs: { alarms: "alarms", hasPermissions: "hasPermissions", typeFilters: "typeFilters", loadMoreMode: "loadMoreMode", navigationOptions: "navigationOptions", isInitialLoading: "isInitialLoading", splitView: "splitView", isInPreviewMode: "isInPreviewMode" }, outputs: { onSelectedAlarm: "onSelectedAlarm", onScrollingStateChange: "onScrollingStateChange" }, viewQueries: [{ propertyName: "innerScrollWrapper", first: true, predicate: ["scrollWrapper"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n  class=\"inner-scroll\"\n  [ngClass]=\"{ 'split-view__list bg-level-1': splitView, 'bg-component': !splitView }\"\n  data-cy=\"c8y-alarms-list\"\n  #scrollWrapper\n>\n  <div\n    class=\"flex-wrap flex-no-shrink sticky-top m-b-16\"\n    [ngClass]=\"{\n      'separator-bottom card-header p-b-0': splitView,\n      'd-flex fit-w separator-top-bottom widget-bar p-l-16 p-r-16':\n        !splitView && navigationOptions.allowNavigationToAlarmsView\n    }\"\n  >\n    <div\n      class=\"h4 card-title\"\n      *ngIf=\"splitView\"\n    >\n      {{ 'Alarms list' | translate }}\n    </div>\n    <div\n      [ngClass]=\"{ 'fit-w d-flex a-i-center gap-16': !splitView, 'fit-h-20 m-l-auto': splitView }\"\n    >\n      <ng-content></ng-content>\n    </div>\n    <!--  Loading -->\n    <div\n      class=\"fit-w overflow-hidden\"\n      [ngClass]=\"{ 'p-t-16': splitView }\"\n    >\n      <div\n        class=\"loading-bar\"\n        data-cy=\"c8y-alarms-list--loading-bar\"\n        style=\"z-index: 101\"\n        [ngClass]=\"{ active: isInitialLoading && !isEmptyListLoading }\"\n      ></div>\n    </div>\n\n    <div\n      class=\"alert alert-warning\"\n      role=\"alert\"\n      translate\n      *ngIf=\"\n        !isEmptyListLoading &&\n        (activeChildParam$ | async) &&\n        (activeAlarm$ | async)?.id !== (activeChildParam$ | async)\n      \"\n    >\n      The selected alarm is not currently in the list, change your filter.\n    </div>\n  </div>\n  <c8y-list-group\n    class=\"p-r-16 interactive\"\n    [ngStyle]=\"{ opacity: isInitialLoading && !isEmptyListLoading ? 0.2 : 1 }\"\n    style=\"transition: opacity 0.15s linear\"\n    data-cy=\"c8y-alarms-list--group\"\n  >\n    <c8y-li-timeline\n      class=\"pointer\"\n      role=\"button\"\n      data-cy=\"c8y-alarms-list--timeline-repeat\"\n      *c8yFor=\"let alarm of alarms; let i = index; pipe: mapAlarmLink; loadMore: loadMoreMode\"\n      [routerLink]=\"navigationOptions.allowNavigationToAlarmsView ? alarm.link : null\"\n      routerLinkActive=\"active\"\n      [queryParamsHandling]=\"navigationOptions.queryParamsHandling\"\n      (isActiveChange)=\"activeRouteChanged($event, liScrollAnchor, alarm)\"\n      (click)=\"onAlarmOpen(alarm)\"\n      [queryParams]=\"\n        navigationOptions.includeClearedQueryParams\n          ? { showCleared: alarm.status === 'CLEARED' }\n          : {}\n      \"\n    >\n      <span\n        [attr.aria-label]=\"alarmLastOccurrenceLabel | translate\"\n        [tooltip]=\"alarmLastOccurrenceLabel | translate\"\n        placement=\"right\"\n        data-cy=\"c8y-alarms-list--last-occurrence-date\"\n        container=\"body\"\n        [delay]=\"500\"\n      >\n        {{ alarm.time | c8yDate: 'mediumDate' }}\n        {{ alarm.time | c8yDate: 'mediumTime' }}\n      </span>\n      <c8y-li\n        style=\"scroll-margin-top: 56px\"\n        #liScrollAnchor\n      >\n        <c8y-li-icon class=\"a-s-start\">\n          <div class=\"alarm-icons\">\n            <c8y-alarms-icon [typeFilters]=\"typeFilters\" [alarm]=\"alarm\"></c8y-alarms-icon>\n          </div>\n          <button\n            class=\"btn-clean text-center\"\n            data-cy=\"c8y-alarms-list--badge\"\n            [attr.aria-label]=\"\n              alarmBadgeTooltip\n                | translate\n                  : { alarmFirstOccurrenceTime: alarm.firstOccurrenceTime | c8yDate: 'medium' }\n            \"\n            [tooltip]=\"\n              alarmBadgeTooltip\n                | translate\n                  : { alarmFirstOccurrenceTime: alarm.firstOccurrenceTime | c8yDate: 'medium' }\n            \"\n            placement=\"right\"\n            container=\"body\"\n            type=\"button\"\n            *ngIf=\"alarm.firstOccurrenceTime\"\n            (click)=\"$event.stopPropagation()\"\n            [delay]=\"500\"\n          >\n            <span\n              class=\"badge badge-info\"\n              *ngIf=\"alarm.count > 1\"\n            >\n              {{ alarm.count }}\n            </span>\n          </button>\n        </c8y-li-icon>\n        <c8y-li-body class=\"a-s-stretch\">\n          <div class=\"d-flex a-i-start fit-h\">\n            <div class=\"min-width-0 flex-grow\">\n              <p class=\"text-truncate-wrap p-b-4\" data-cy=\"c8y-alarms-list--alarm-text\">\n                {{ alarm.text | translate }}\n              </p>\n              <div class=\"d-flex\">\n                <p\n                  class=\"small text-muted text-truncate flex-grow\"\n                  [title]=\"alarm.source.name\"\n                  data-cy=\"c8y-alarms-list--alarm-source-name\"\n                >\n                  <i [c8yIcon]=\"'exchange'\"></i>\n                  {{ alarm.source.name }}\n                </p>\n                <div class=\"d-flex\">\n                  <div\n                    [title]=\"item.title | translate\"\n                    *ngFor=\"let item of alarm | alarmListIndicator | async\"\n                  >\n                    <i\n                      [class]=\"item.class\"\n                      [c8yIcon]=\"item.icon\"\n                    ></i>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </c8y-li-body>\n      </c8y-li>\n    </c8y-li-timeline>\n    <c8y-loading\n      data-cy=\"c8y-alarms-list--c8y-loading\"\n      *ngIf=\"isInitialLoading && isEmptyListLoading\"></c8y-loading>\n    <div\n      class=\"p-relative p-l-24\"\n      *ngIf=\"isEmptyListLoading && !isInitialLoading\"\n    >\n      <c8y-ui-empty-state\n        [icon]=\"'c8y-alert-idle'\"\n        [title]=\"'No alarms to display.' | translate\"\n        data-cy=\"c8y-alarms-list--empty-state\"\n        *ngIf=\"hasPermissions; else alertsA\"\n      >\n        <p c8y-guide-docs>\n          <small\n            translate\n            ngNonBindable\n          >\n            Find out more in the\n            <a\n              c8y-guide-href=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n            >\n              user documentation\n            </a>\n            .\n          </small>\n        </p>\n      </c8y-ui-empty-state>\n    </div>\n  </c8y-list-group>\n</div>\n\n<ng-template #alertsA>\n  <c8y-dynamic-component-alerts [alerts]=\"alertAggregator\"></c8y-dynamic-component-alerts>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "component", type: ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: AlarmsIconComponent, selector: "c8y-alarms-icon", inputs: ["alarm", "typeFilters"] }, { kind: "component", type: ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "component", type: GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "directive", type: GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: DynamicComponentAlertsComponent, selector: "c8y-dynamic-component-alerts", inputs: ["alerts"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }, { kind: "pipe", type: AlarmListIndicatorPipe, name: "alarmListIndicator" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarms-list', imports: [
                        NgClass,
                        NgIf,
                        C8yTranslateDirective,
                        ListGroupComponent,
                        NgStyle,
                        ForOfDirective,
                        ListItemTimelineComponent,
                        RouterLinkActive,
                        RouterLink,
                        TooltipDirective,
                        ListItemComponent,
                        ListItemIconComponent,
                        AlarmsIconComponent,
                        ListItemBodyComponent,
                        IconDirective,
                        NgFor,
                        LoadingComponent,
                        EmptyStateComponent,
                        GuideDocsComponent,
                        GuideHrefDirective,
                        DynamicComponentAlertsComponent,
                        C8yTranslatePipe,
                        AsyncPipe,
                        DatePipe,
                        AlarmListIndicatorPipe
                    ], template: "<div\n  class=\"inner-scroll\"\n  [ngClass]=\"{ 'split-view__list bg-level-1': splitView, 'bg-component': !splitView }\"\n  data-cy=\"c8y-alarms-list\"\n  #scrollWrapper\n>\n  <div\n    class=\"flex-wrap flex-no-shrink sticky-top m-b-16\"\n    [ngClass]=\"{\n      'separator-bottom card-header p-b-0': splitView,\n      'd-flex fit-w separator-top-bottom widget-bar p-l-16 p-r-16':\n        !splitView && navigationOptions.allowNavigationToAlarmsView\n    }\"\n  >\n    <div\n      class=\"h4 card-title\"\n      *ngIf=\"splitView\"\n    >\n      {{ 'Alarms list' | translate }}\n    </div>\n    <div\n      [ngClass]=\"{ 'fit-w d-flex a-i-center gap-16': !splitView, 'fit-h-20 m-l-auto': splitView }\"\n    >\n      <ng-content></ng-content>\n    </div>\n    <!--  Loading -->\n    <div\n      class=\"fit-w overflow-hidden\"\n      [ngClass]=\"{ 'p-t-16': splitView }\"\n    >\n      <div\n        class=\"loading-bar\"\n        data-cy=\"c8y-alarms-list--loading-bar\"\n        style=\"z-index: 101\"\n        [ngClass]=\"{ active: isInitialLoading && !isEmptyListLoading }\"\n      ></div>\n    </div>\n\n    <div\n      class=\"alert alert-warning\"\n      role=\"alert\"\n      translate\n      *ngIf=\"\n        !isEmptyListLoading &&\n        (activeChildParam$ | async) &&\n        (activeAlarm$ | async)?.id !== (activeChildParam$ | async)\n      \"\n    >\n      The selected alarm is not currently in the list, change your filter.\n    </div>\n  </div>\n  <c8y-list-group\n    class=\"p-r-16 interactive\"\n    [ngStyle]=\"{ opacity: isInitialLoading && !isEmptyListLoading ? 0.2 : 1 }\"\n    style=\"transition: opacity 0.15s linear\"\n    data-cy=\"c8y-alarms-list--group\"\n  >\n    <c8y-li-timeline\n      class=\"pointer\"\n      role=\"button\"\n      data-cy=\"c8y-alarms-list--timeline-repeat\"\n      *c8yFor=\"let alarm of alarms; let i = index; pipe: mapAlarmLink; loadMore: loadMoreMode\"\n      [routerLink]=\"navigationOptions.allowNavigationToAlarmsView ? alarm.link : null\"\n      routerLinkActive=\"active\"\n      [queryParamsHandling]=\"navigationOptions.queryParamsHandling\"\n      (isActiveChange)=\"activeRouteChanged($event, liScrollAnchor, alarm)\"\n      (click)=\"onAlarmOpen(alarm)\"\n      [queryParams]=\"\n        navigationOptions.includeClearedQueryParams\n          ? { showCleared: alarm.status === 'CLEARED' }\n          : {}\n      \"\n    >\n      <span\n        [attr.aria-label]=\"alarmLastOccurrenceLabel | translate\"\n        [tooltip]=\"alarmLastOccurrenceLabel | translate\"\n        placement=\"right\"\n        data-cy=\"c8y-alarms-list--last-occurrence-date\"\n        container=\"body\"\n        [delay]=\"500\"\n      >\n        {{ alarm.time | c8yDate: 'mediumDate' }}\n        {{ alarm.time | c8yDate: 'mediumTime' }}\n      </span>\n      <c8y-li\n        style=\"scroll-margin-top: 56px\"\n        #liScrollAnchor\n      >\n        <c8y-li-icon class=\"a-s-start\">\n          <div class=\"alarm-icons\">\n            <c8y-alarms-icon [typeFilters]=\"typeFilters\" [alarm]=\"alarm\"></c8y-alarms-icon>\n          </div>\n          <button\n            class=\"btn-clean text-center\"\n            data-cy=\"c8y-alarms-list--badge\"\n            [attr.aria-label]=\"\n              alarmBadgeTooltip\n                | translate\n                  : { alarmFirstOccurrenceTime: alarm.firstOccurrenceTime | c8yDate: 'medium' }\n            \"\n            [tooltip]=\"\n              alarmBadgeTooltip\n                | translate\n                  : { alarmFirstOccurrenceTime: alarm.firstOccurrenceTime | c8yDate: 'medium' }\n            \"\n            placement=\"right\"\n            container=\"body\"\n            type=\"button\"\n            *ngIf=\"alarm.firstOccurrenceTime\"\n            (click)=\"$event.stopPropagation()\"\n            [delay]=\"500\"\n          >\n            <span\n              class=\"badge badge-info\"\n              *ngIf=\"alarm.count > 1\"\n            >\n              {{ alarm.count }}\n            </span>\n          </button>\n        </c8y-li-icon>\n        <c8y-li-body class=\"a-s-stretch\">\n          <div class=\"d-flex a-i-start fit-h\">\n            <div class=\"min-width-0 flex-grow\">\n              <p class=\"text-truncate-wrap p-b-4\" data-cy=\"c8y-alarms-list--alarm-text\">\n                {{ alarm.text | translate }}\n              </p>\n              <div class=\"d-flex\">\n                <p\n                  class=\"small text-muted text-truncate flex-grow\"\n                  [title]=\"alarm.source.name\"\n                  data-cy=\"c8y-alarms-list--alarm-source-name\"\n                >\n                  <i [c8yIcon]=\"'exchange'\"></i>\n                  {{ alarm.source.name }}\n                </p>\n                <div class=\"d-flex\">\n                  <div\n                    [title]=\"item.title | translate\"\n                    *ngFor=\"let item of alarm | alarmListIndicator | async\"\n                  >\n                    <i\n                      [class]=\"item.class\"\n                      [c8yIcon]=\"item.icon\"\n                    ></i>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </c8y-li-body>\n      </c8y-li>\n    </c8y-li-timeline>\n    <c8y-loading\n      data-cy=\"c8y-alarms-list--c8y-loading\"\n      *ngIf=\"isInitialLoading && isEmptyListLoading\"></c8y-loading>\n    <div\n      class=\"p-relative p-l-24\"\n      *ngIf=\"isEmptyListLoading && !isInitialLoading\"\n    >\n      <c8y-ui-empty-state\n        [icon]=\"'c8y-alert-idle'\"\n        [title]=\"'No alarms to display.' | translate\"\n        data-cy=\"c8y-alarms-list--empty-state\"\n        *ngIf=\"hasPermissions; else alertsA\"\n      >\n        <p c8y-guide-docs>\n          <small\n            translate\n            ngNonBindable\n          >\n            Find out more in the\n            <a\n              c8y-guide-href=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n            >\n              user documentation\n            </a>\n            .\n          </small>\n        </p>\n      </c8y-ui-empty-state>\n    </div>\n  </c8y-list-group>\n</div>\n\n<ng-template #alertsA>\n  <c8y-dynamic-component-alerts [alerts]=\"alertAggregator\"></c8y-dynamic-component-alerts>\n</ng-template>\n" }]
        }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: AlarmsViewService }, { type: i3.ContextRouteService }, { type: i1.Router }], propDecorators: { alarms: [{
                type: Input
            }], hasPermissions: [{
                type: Input
            }], typeFilters: [{
                type: Input
            }], loadMoreMode: [{
                type: Input
            }], navigationOptions: [{
                type: Input
            }], isInitialLoading: [{
                type: Input
            }], splitView: [{
                type: Input
            }], isInPreviewMode: [{
                type: Input
            }], onSelectedAlarm: [{
                type: Output
            }], onScrollingStateChange: [{
                type: Output
            }], innerScrollWrapper: [{
                type: ViewChild,
                args: ['scrollWrapper']
            }] } });

class AlarmsDateFilterComponent {
    constructor(formBuilder, router, activatedRoute, alarmsViewService) {
        this.formBuilder = formBuilder;
        this.router = router;
        this.activatedRoute = activatedRoute;
        this.alarmsViewService = alarmsViewService;
        this.INTERVALS = INTERVALS_EXTENDED;
        this.INTERVAL_TITLES = INTERVAL_TITLES_EXTENDED;
        this.DATE_FORMAT = 'short';
        this.DEFAULT_INTERVAL = 'none';
        this.updateQueryParams = true;
        this.noFilterLabel = gettext('No date filter');
        this.destroy$ = new Subject();
        this.dateFilterChange = new EventEmitter();
        // eslint-disable-next-line @typescript-eslint/no-empty-function
        this.onTouched = () => { };
    }
    ngOnInit() {
        const context = this.getDefaultContext();
        this.form = this.createForm(context);
        this.date = [
            this.form.value.currentDateContextFromDate,
            this.form.value.currentDateContextToDate
        ];
        this.activatedRoute.queryParams.pipe(take(1), takeUntil$1(this.destroy$)).subscribe(params => {
            this.showCleared = params.showCleared === 'true';
            this.severityOptions = {
                [Severity.CRITICAL]: params.critical === 'true',
                [Severity.MAJOR]: params.major === 'true',
                [Severity.MINOR]: params.minor === 'true',
                [Severity.WARNING]: params.warning === 'true'
            };
            if (params.typeFilters) {
                this.typeFilters = params.typeFilters;
            }
            if (!params.interval) {
                return;
            }
            if (params.interval !== 'custom') {
                this.updateDateTime(params.interval);
            }
            else {
                this.form.patchValue({
                    currentDateContextInterval: params.interval,
                    temporaryUserSelectedFromDate: params.lastUpdatedFrom,
                    temporaryUserSelectedToDate: params.createdTo
                });
                this.date = [params.lastUpdatedFrom, params.createdTo];
            }
        });
        this.subscribeToIntervalChange();
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    applyDateFilter() {
        const combinedFormEvent = {
            showCleared: this.showCleared,
            severityOptions: this.severityOptions,
            typeFilters: this.typeFilters,
            interval: this.form.value.currentDateContextInterval,
            selectedDates: [
                new Date(this.form.value.temporaryUserSelectedFromDate),
                new Date(this.form.value.temporaryUserSelectedToDate)
            ]
        };
        // needed for custom interval
        this.date = [
            this.form.value.temporaryUserSelectedFromDate,
            this.form.value.temporaryUserSelectedToDate
        ];
        this.router.navigate([], {
            relativeTo: this.activatedRoute,
            queryParams: {
                interval: this.form.value.currentDateContextInterval,
                lastUpdatedFrom: combinedFormEvent.selectedDates[0].toISOString(),
                createdTo: combinedFormEvent.selectedDates[1].toISOString()
            },
            queryParamsHandling: 'merge'
        });
        this.dateFilterChange.emit(combinedFormEvent);
    }
    writeValue(value) {
        if (value) {
            this.form.patchValue({
                currentDateContextFromDate: typeof value[0] === 'string' ? value[0] : value[0].toISOString(),
                currentDateContextToDate: typeof value[1] === 'string' ? value[1] : value[1].toISOString()
            });
        }
    }
    registerOnChange(fn) {
        this.onChange = fn;
    }
    registerOnTouched(onTouched) {
        this.onTouched = onTouched;
    }
    updateDateTime(interval) {
        const date = this.alarmsViewService.getDateTimeContextByInterval(interval);
        if (this.dropdown) {
            this.dropdown.isOpen = false;
        }
        this.date = date.map(d => d.toISOString());
        this.form.patchValue({
            temporaryUserSelectedFromDate: date[0].toISOString(),
            temporaryUserSelectedToDate: date[1].toISOString(),
            currentDateContextInterval: interval
        }, { emitEvent: false });
        this.applyDateFilter();
    }
    getDefaultContext() {
        return {
            date: this.alarmsViewService.getDateTimeContextByInterval(this.DEFAULT_INTERVAL),
            interval: this.DEFAULT_INTERVAL
        };
    }
    subscribeToIntervalChange() {
        this.form.controls.currentDateContextInterval.valueChanges
            .pipe(takeUntil$1(this.destroy$))
            .subscribe(interval => {
            if (interval === 'custom') {
                this.form.patchValue({
                    temporaryUserSelectedFromDate: this.form.controls.temporaryUserSelectedFromDate.value === new Date(0).toISOString()
                        ? this.form.controls.currentDateContextToDate.value
                        : this.form.controls.temporaryUserSelectedFromDate.value,
                    currentDateContextInterval: interval
                }, { emitEvent: false });
                return;
            }
            this.updateDateTime(interval);
        });
    }
    createForm(context) {
        return this.formBuilder.group({
            temporaryUserSelectedFromDate: context.date[0].toISOString(),
            temporaryUserSelectedToDate: context.date[1].toISOString(),
            currentDateContextFromDate: context.date[0].toISOString(),
            currentDateContextToDate: context.date[1].toISOString(),
            currentDateContextInterval: context.interval || 'custom'
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsDateFilterComponent, deps: [{ token: i1$2.FormBuilder }, { token: i1.Router }, { token: i1.ActivatedRoute }, { token: AlarmsViewService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: AlarmsDateFilterComponent, isStandalone: true, selector: "c8y-alarms-date-filter", inputs: { DEFAULT_INTERVAL: "DEFAULT_INTERVAL", updateQueryParams: "updateQueryParams", date: "date" }, outputs: { dateFilterChange: "dateFilterChange" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => AlarmsDateFilterComponent),
                multi: true
            }
        ], viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], ngImport: i0, template: "<form\n  class=\"d-flex gap-16 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n  [formGroup]=\"form\"\n>\n  <div\n    class=\"dropdown flex-grow\"\n    c8yDropdownDirection\n    #dropDirection=\"bs-dropdown\"\n    dropdown\n    [insideClick]=\"true\"\n  >\n    <button\n      class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n      attr.aria-label=\"{{\n        (form.value.currentDateContextInterval === 'none'\n          ? noFilterLabel\n          : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n        ) | translate\n      }}\"\n      tooltip=\"{{\n        (form.value.currentDateContextInterval === 'none'\n          ? noFilterLabel\n          : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n        ) | translate\n      }}\"\n      placement=\"top\"\n      container=\"body\"\n      data-cy=\"alarms-date-filter--date-picker-dropdown-button\"\n      [adaptivePosition]=\"false\"\n      [delay]=\"500\"\n      dropdownToggle\n    >\n      <i\n        class=\"m-r-4\"\n        c8yIcon=\"schedule1\"\n      ></i>\n      <div class=\"d-col text-left fit-w\">\n        <span\n          class=\"text-12\"\n          data-cy=\"widget-time-context--selected-interval\"\n        >\n          {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n        </span>\n        <span\n          class=\"text-10 text-muted text-truncate\"\n          data-cy=\"alarms-date-filter--selected-time-range\"\n          *ngIf=\"form.controls.currentDateContextInterval.value !== 'none'\"\n        >\n          {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n        </span>\n      </div>\n      <span class=\"caret m-r-16 m-l-4\"></span>\n    </button>\n\n    <ul\n      class=\"dropdown-menu dropdown-menu--date-range\"\n      *dropdownMenu\n    >\n      <c8y-interval-picker\n        class=\"d-contents\"\n        formControlName=\"currentDateContextInterval\"\n        [INTERVALS]=\"INTERVALS\"\n      ></c8y-interval-picker>\n\n      <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n        <div class=\"p-l-16 p-r-16\">\n          <c8y-form-group\n            class=\"m-b-8\"\n            [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n          >\n            <label\n              [title]=\"'From`date`' | translate\"\n              for=\"temporaryUserSelectedFromDate\"\n              translate\n            >\n              From`date`\n            </label>\n            <c8y-date-time-picker\n              id=\"temporaryUserSelectedFromDate\"\n              [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n              [placeholder]=\"'From`date`' | translate\"\n              [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n              [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n            ></c8y-date-time-picker>\n            <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n              <c8y-message\n                name=\"dateAfterRangeMax\"\n                [text]=\"'This date is after the latest allowed date.' | translate\"\n              ></c8y-message>\n              <c8y-message\n                name=\"invalidDateTime\"\n                [text]=\"'This date is invalid.' | translate\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n\n          <c8y-form-group\n            class=\"m-b-8\"\n            [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n          >\n            <label\n              [title]=\"'To`date`' | translate\"\n              for=\"temporaryUserSelectedToDate\"\n              translate\n            >\n              To`date`\n            </label>\n            <c8y-date-time-picker\n              id=\"temporaryUserSelectedToDate\"\n              [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n              [placeholder]=\"'To`date`' | translate\"\n              [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n              [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n            ></c8y-date-time-picker>\n            <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n              <c8y-message\n                name=\"dateBeforeRangeMin\"\n                [text]=\"'This date is before the earliest allowed date.' | translate\"\n              ></c8y-message>\n              <c8y-message\n                name=\"invalidDateTime\"\n                [text]=\"'This date is invalid.' | translate\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div class=\"p-16 d-flex gap-8 separator-top\">\n          <button\n            class=\"btn btn-primary btn-sm flex-grow\"\n            title=\"{{ 'Apply' | translate }}\"\n            type=\"button\"\n            (click)=\"applyDateFilter(); dropdown.isOpen = false\"\n            [disabled]=\"(form.pristine && form.untouched) || form.invalid\"\n            translate\n          >\n            Apply\n          </button>\n        </div>\n      </ng-container>\n    </ul>\n  </div>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: DropdownDirectionDirective, selector: "[dropdown][c8yBsDropdownDirection],[dropdown][c8yDropdownDirection]" }, { kind: "directive", type: BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "component", type: IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsDateFilterComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarms-date-filter', providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => AlarmsDateFilterComponent),
                            multi: true
                        }
                    ], imports: [
                        FormsModule,
                        ReactiveFormsModule,
                        BsDropdownDirective,
                        DropdownDirectionDirective,
                        BsDropdownToggleDirective,
                        TooltipDirective,
                        IconDirective,
                        NgIf,
                        BsDropdownMenuDirective,
                        IntervalPickerComponent,
                        FormGroupComponent,
                        NgClass,
                        C8yTranslateDirective,
                        DateTimePickerComponent,
                        MessagesComponent,
                        MessageDirective,
                        C8yTranslatePipe,
                        DatePipe
                    ], template: "<form\n  class=\"d-flex gap-16 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n  [formGroup]=\"form\"\n>\n  <div\n    class=\"dropdown flex-grow\"\n    c8yDropdownDirection\n    #dropDirection=\"bs-dropdown\"\n    dropdown\n    [insideClick]=\"true\"\n  >\n    <button\n      class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n      attr.aria-label=\"{{\n        (form.value.currentDateContextInterval === 'none'\n          ? noFilterLabel\n          : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n        ) | translate\n      }}\"\n      tooltip=\"{{\n        (form.value.currentDateContextInterval === 'none'\n          ? noFilterLabel\n          : (date[0] | c8yDate: DATE_FORMAT) + ' \u2014 ' + (date[1] | c8yDate: DATE_FORMAT)\n        ) | translate\n      }}\"\n      placement=\"top\"\n      container=\"body\"\n      data-cy=\"alarms-date-filter--date-picker-dropdown-button\"\n      [adaptivePosition]=\"false\"\n      [delay]=\"500\"\n      dropdownToggle\n    >\n      <i\n        class=\"m-r-4\"\n        c8yIcon=\"schedule1\"\n      ></i>\n      <div class=\"d-col text-left fit-w\">\n        <span\n          class=\"text-12\"\n          data-cy=\"widget-time-context--selected-interval\"\n        >\n          {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n        </span>\n        <span\n          class=\"text-10 text-muted text-truncate\"\n          data-cy=\"alarms-date-filter--selected-time-range\"\n          *ngIf=\"form.controls.currentDateContextInterval.value !== 'none'\"\n        >\n          {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n        </span>\n      </div>\n      <span class=\"caret m-r-16 m-l-4\"></span>\n    </button>\n\n    <ul\n      class=\"dropdown-menu dropdown-menu--date-range\"\n      *dropdownMenu\n    >\n      <c8y-interval-picker\n        class=\"d-contents\"\n        formControlName=\"currentDateContextInterval\"\n        [INTERVALS]=\"INTERVALS\"\n      ></c8y-interval-picker>\n\n      <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n        <div class=\"p-l-16 p-r-16\">\n          <c8y-form-group\n            class=\"m-b-8\"\n            [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n          >\n            <label\n              [title]=\"'From`date`' | translate\"\n              for=\"temporaryUserSelectedFromDate\"\n              translate\n            >\n              From`date`\n            </label>\n            <c8y-date-time-picker\n              id=\"temporaryUserSelectedFromDate\"\n              [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n              [placeholder]=\"'From`date`' | translate\"\n              [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n              [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n            ></c8y-date-time-picker>\n            <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n              <c8y-message\n                name=\"dateAfterRangeMax\"\n                [text]=\"'This date is after the latest allowed date.' | translate\"\n              ></c8y-message>\n              <c8y-message\n                name=\"invalidDateTime\"\n                [text]=\"'This date is invalid.' | translate\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n\n          <c8y-form-group\n            class=\"m-b-8\"\n            [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n          >\n            <label\n              [title]=\"'To`date`' | translate\"\n              for=\"temporaryUserSelectedToDate\"\n              translate\n            >\n              To`date`\n            </label>\n            <c8y-date-time-picker\n              id=\"temporaryUserSelectedToDate\"\n              [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n              [placeholder]=\"'To`date`' | translate\"\n              [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n              [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n            ></c8y-date-time-picker>\n            <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n              <c8y-message\n                name=\"dateBeforeRangeMin\"\n                [text]=\"'This date is before the earliest allowed date.' | translate\"\n              ></c8y-message>\n              <c8y-message\n                name=\"invalidDateTime\"\n                [text]=\"'This date is invalid.' | translate\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div class=\"p-16 d-flex gap-8 separator-top\">\n          <button\n            class=\"btn btn-primary btn-sm flex-grow\"\n            title=\"{{ 'Apply' | translate }}\"\n            type=\"button\"\n            (click)=\"applyDateFilter(); dropdown.isOpen = false\"\n            [disabled]=\"(form.pristine && form.untouched) || form.invalid\"\n            translate\n          >\n            Apply\n          </button>\n        </div>\n      </ng-container>\n    </ul>\n  </div>\n</form>\n" }]
        }], ctorParameters: () => [{ type: i1$2.FormBuilder }, { type: i1.Router }, { type: i1.ActivatedRoute }, { type: AlarmsViewService }], propDecorators: { DEFAULT_INTERVAL: [{
                type: Input
            }], updateQueryParams: [{
                type: Input
            }], date: [{
                type: Input
            }], dateFilterChange: [{
                type: Output
            }], dropdown: [{
                type: ViewChild,
                args: [BsDropdownDirective]
            }] } });

class AlarmsTypeFilterComponent {
    constructor(alarmEventSelectorService, activatedRoute, router, colorService) {
        this.alarmEventSelectorService = alarmEventSelectorService;
        this.activatedRoute = activatedRoute;
        this.router = router;
        this.colorService = colorService;
        this.possibleFilters = [];
        this.activeFilters = [];
        this.onFilterChanged = new EventEmitter();
        this.customAlarmTypes = [];
        this.customAlarmTypeInput = '';
        this.queryParamName = 'typeFilter';
        this.STORAGE_ACCESS_KEY = 'customAlarmTypes';
        this.destroy$ = new Subject();
        this.currentQueryParam = '';
    }
    ngOnInit() {
        this.setQueryParameterObservable();
    }
    async ngOnChanges(changes) {
        if (changes.alarms && changes.alarms.currentValue && this.activeFilters.length === 0) {
            await this.setPossibleFilters();
            this.applyFilterChange();
        }
    }
    setQueryParameterObservable() {
        this.activatedRoute.queryParams
            .pipe(map$1(params => {
            const alarms = this.possibleFilters;
            const possibleFilters = this.setActiveAlarmFiltersFromQueryParameter(alarms, params[this.queryParamName]);
            return possibleFilters;
        }), takeUntil$1(this.destroy$))
            .subscribe((possibleFilters) => {
            this.possibleFilters = possibleFilters;
            this.applyFilterChange();
        });
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    toggleAlarmType(alarmType) {
        alarmType.__active = !alarmType.__active;
    }
    deselect(type) {
        const alarmFilter = this.possibleFilters.find(alarm => alarm.filters.type === type.filters.type);
        alarmFilter.__active = false;
        this.applyFilterChange();
    }
    deselectAll() {
        this.possibleFilters = this.possibleFilters.map(alarm => {
            return {
                ...alarm,
                __active: false
            };
        });
        this.applyFilterChange();
    }
    applyFilterChange() {
        const actives = this.possibleFilters.filter((alarmFilter) => alarmFilter.__active);
        const newQueryParam = this.getQueryParams(actives);
        const hasChanged = newQueryParam !== this.currentQueryParam;
        if (hasChanged) {
            this.activeFilters = actives;
            this.onFilterChanged.emit(this.activeFilters);
            this.router.navigate([], {
                queryParams: {
                    typeFilter: newQueryParam || null
                },
                queryParamsHandling: 'merge'
            });
            this.currentQueryParam = newQueryParam;
        }
    }
    resetFilters() {
        this.possibleFilters.forEach(possibleFilter => {
            possibleFilter.__active = this.activeFilters.some((activeFilter) => activeFilter === possibleFilter);
        });
    }
    removeCustomAlarm(alarmDetails) {
        this.possibleFilters = this.possibleFilters.filter(filter => filter !== alarmDetails);
        this.storeCustomAlarmTypes();
    }
    confirmWithEnter(event) {
        if (event.key === 'Enter') {
            this.addCustomAlarmType();
        }
    }
    async addCustomAlarmType() {
        if (!this.customAlarmTypeInput) {
            return;
        }
        this.possibleFilters.unshift({
            label: this.customAlarmTypeInput,
            color: await this.colorService.generateColor(this.customAlarmTypeInput),
            filters: {
                type: this.customAlarmTypeInput
            },
            timelineType: 'ALARM',
            __active: true,
            __target: null
        });
        this.customAlarmTypeInput = '';
        this.storeCustomAlarmTypes();
    }
    storeCustomAlarmTypes() {
        const customTypes = this.possibleFilters.filter((filter) => !filter.__target);
        window.localStorage.setItem(this.STORAGE_ACCESS_KEY, JSON.stringify(customTypes));
    }
    getCustomAlarmTypeFromStorage() {
        const types = window.localStorage.getItem(this.STORAGE_ACCESS_KEY);
        return types ? JSON.parse(types) : [];
    }
    async setPossibleFilters() {
        const queryParameters = this.activatedRoute.snapshot.queryParamMap.get(this.queryParamName);
        const alarmTypesFromCurrentlyShownAlarms = await this.alarmEventSelectorService.getUniqueAlarmsOnly(this.alarms.data);
        const customAlarmTypesFromLocalStorage = this.getCustomAlarmTypeFromStorage();
        const selectableAlarmTypes = this.setActiveAlarmFiltersFromQueryParameter([...customAlarmTypesFromLocalStorage, ...alarmTypesFromCurrentlyShownAlarms], queryParameters);
        this.possibleFilters = selectableAlarmTypes;
    }
    setActiveAlarmFiltersFromQueryParameter(alarmFilters, filterTypesQuery = '') {
        const types = (filterTypesQuery ?? '').split(',');
        return alarmFilters.map((alarm) => ({
            ...alarm,
            __active: types.includes(alarm.filters.type)
        }));
    }
    getQueryParams(activeFilters) {
        return activeFilters.map(filter => filter.filters.type).join(',');
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsTypeFilterComponent, deps: [{ token: i1$3.AlarmEventSelectorService }, { token: i1.ActivatedRoute }, { token: i1.Router }, { token: i3.ColorService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: AlarmsTypeFilterComponent, isStandalone: true, selector: "c8y-alarms-type-filter", inputs: { alarms: "alarms", possibleFilters: "possibleFilters", activeFilters: "activeFilters" }, outputs: { onFilterChanged: "onFilterChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex a-i-center\">\n  <div\n    class=\"dropdown\"\n    title=\"{{ 'Filter by alarm types' | translate }}\"\n    dropdown\n    #filtersDropdown=\"bs-dropdown\"\n    [cdkTrapFocus]=\"filtersDropdown.isOpen\"\n    (onHidden)=\"resetFilters()\"\n    [insideClick]=\"true\"\n  >\n    <div class=\"input-group fit-w\">\n      <div class=\"form-control d-flex a-i-center inner-scroll\">\n        @if (activeFilters.length > 0) {\n          @for (filter of activeFilters; track $index) {\n            <span\n              class=\"tag tag--info chip\"\n              style=\"max-width: 150px\"\n            >\n              <button\n                class=\"btn btn-xs btn-clean text-10\"\n                title=\"{{ 'Remove' | translate }}\"\n                type=\"button\"\n                (click)=\"$event.stopPropagation(); deselect(filter)\"\n              >\n                <i c8yIcon=\"times\"></i>\n              </button>\n              <span\n                class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n                [ngStyle]=\"{ 'background-color': filter.color }\"\n              >\n                <i\n                  class=\"stroked-icon\"\n                  c8yIcon=\"bell\"\n                ></i>\n              </span>\n              <span\n                class=\"text-truncate text-12 flex-grow\"\n                [title]=\"filter.filters.type\"\n                [attr.aria-label]=\"filter.filters.type\"\n              >\n                {{ filter.filters.type }}\n              </span>\n            </span>\n          }\n        } @else {\n          <span class=\"text-nowrap\">\n            {{ 'All alarm types' | translate }}\n          </span>\n        }\n      </div>\n      <div class=\"input-group-btn input-group-btn--last text-center\">\n        @if (activeFilters.length) {\n          <button\n            class=\"btn-default btn\"\n            [title]=\"'Clear filters' | translate\"\n            (click)=\"deselectAll()\"\n          >\n            <i c8yIcon=\"times\"></i>\n          </button>\n        }\n        <button\n          class=\"btn-default btn btn--caret\"\n          [title]=\"'Alarm types' | translate\"\n          data-cy=\"c8y-alarm-type-filter\"\n          dropdownToggle\n        >\n          <i class=\"caret\"></i>\n        </button>\n      </div>\n    </div>\n    <div\n      class=\"dropdown-menu dropdown-menu-action-bar\"\n      style=\"min-width: 250px\"\n      *dropdownMenu\n    >\n      <div class=\"p-16 bg-level-2\">\n        <div>\n          <p>\n            <i\n              class=\"text-info m-r-4\"\n              [c8yIcon]=\"'info-circle'\"\n            ></i>\n            <strong translate>The list below may not be complete.</strong>\n          </p>\n          <p>\n            <span translate>\n              Recent alarms are displayed below but older ones may not be shown.\n            </span>\n            <span translate>Optionally, you can add a custom alarm.</span>\n          </p>\n        </div>\n      </div>\n      <c8y-list-group>\n        <div class=\"input-group p-t-16 p-b-16 p-r-32 p-l-32 separator-bottom\">\n          <input\n            class=\"form-control\"\n            type=\"text\"\n            [placeholder]=\"'Custom alarm type' | translate\"\n            [(ngModel)]=\"customAlarmTypeInput\"\n            (keydown)=\"confirmWithEnter($event)\"\n          />\n          <div class=\"input-group-btn\">\n            <button\n              class=\"btn-dot text-primary\"\n              [attr.aria-label]=\"'Add custom alarm' | translate\"\n              [tooltip]=\"'Add' | translate\"\n              placement=\"top\"\n              [delay]=\"500\"\n              (click)=\"addCustomAlarmType()\"\n            >\n              <i c8yIcon=\"plus-circle\"></i>\n            </button>\n          </div>\n        </div>\n\n        @for (alarmType of possibleFilters; track $index) {\n          <c8y-li\n            class=\"c8y-list__item__collapse--container-small cdk-drag\"\n            style=\"cursor: pointer\"\n            (click)=\"toggleAlarmType(alarmType)\"\n          >\n            <c8y-li-checkbox\n              class=\"a-s-center m-t-4 p-r-0 p-l-0\"\n              [selected]=\"alarmType.__active\"\n              (click)=\"$event.stopPropagation()\"\n              (change)=\"toggleAlarmType(alarmType); $event.stopPropagation()\"\n            ></c8y-li-checkbox>\n            <div class=\"d-flex a-i-center p-l-4\">\n              <div class=\"c8y-list__item__colorpicker p-t-0 p-b-0 p-l-0\">\n                <div class=\"c8y-colorpicker c8y-colorpicker--alarm\">\n                  <span\n                    class=\"circle-icon-wrapper\"\n                    [ngStyle]=\"{ 'background-color': alarmType.color }\"\n                  >\n                    <i\n                      class=\"stroked-icon\"\n                      [c8yIcon]=\"'bell'\"\n                    ></i>\n                  </span>\n                </div>\n              </div>\n              <span\n                class=\"text-truncate text-12 flex-grow\"\n                [title]=\"alarmType.label\"\n                [attr.aria-label]=\"alarmType.label\"\n              >\n                {{ alarmType.label }}\n              </span>\n              @if (alarmType.__target === null) {\n                <button\n                  class=\"btn-dot btn-dot--danger\"\n                  [attr.aria-label]=\"'Remove' | translate\"\n                  tooltip=\"'Remove' | translate\"\n                  placement=\"top\"\n                  [delay]=\"500\"\n                  (click)=\"removeCustomAlarm(alarmType); $event.stopPropagation()\"\n                >\n                  <i c8yIcon=\"minus-circle\"></i>\n                </button>\n              }\n            </div>\n          </c8y-li>\n        }\n        @if (possibleFilters.length === 0) {\n          <c8y-li>\n            <c8y-ui-empty-state\n              class=\"p-t-8\"\n              icon=\"c8y-alarm\"\n              [title]=\"'No alarm found' | translate\"\n              [subtitle]=\"\n                'There is no alarm to filter. You can still add a custom alarm.' | translate\n              \"\n              [horizontal]=\"true\"\n            ></c8y-ui-empty-state>\n          </c8y-li>\n        }\n        <div class=\"sticky-bottom p-16\">\n          <button\n            class=\"btn btn-block btn-primary\"\n            [disabled]=\"possibleFilters.length === 0\"\n            (click)=\"applyFilterChange(); $event.stopPropagation(); filtersDropdown.hide()\"\n            translate\n          >\n            Apply\n          </button>\n        </div>\n      </c8y-list-group>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "directive", type: BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemCheckboxComponent, selector: "c8y-list-item-checkbox, c8y-li-checkbox", inputs: ["selected", "indeterminate", "disabled", "displayAsSwitch"], outputs: ["onSelect"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsTypeFilterComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarms-type-filter', imports: [
                        BsDropdownDirective,
                        CdkTrapFocus,
                        IconDirective,
                        NgStyle,
                        BsDropdownToggleDirective,
                        BsDropdownMenuDirective,
                        ListGroupComponent,
                        FormsModule,
                        TooltipDirective,
                        ListItemComponent,
                        ListItemCheckboxComponent,
                        EmptyStateComponent,
                        C8yTranslateDirective,
                        C8yTranslatePipe
                    ], template: "<div class=\"d-flex a-i-center\">\n  <div\n    class=\"dropdown\"\n    title=\"{{ 'Filter by alarm types' | translate }}\"\n    dropdown\n    #filtersDropdown=\"bs-dropdown\"\n    [cdkTrapFocus]=\"filtersDropdown.isOpen\"\n    (onHidden)=\"resetFilters()\"\n    [insideClick]=\"true\"\n  >\n    <div class=\"input-group fit-w\">\n      <div class=\"form-control d-flex a-i-center inner-scroll\">\n        @if (activeFilters.length > 0) {\n          @for (filter of activeFilters; track $index) {\n            <span\n              class=\"tag tag--info chip\"\n              style=\"max-width: 150px\"\n            >\n              <button\n                class=\"btn btn-xs btn-clean text-10\"\n                title=\"{{ 'Remove' | translate }}\"\n                type=\"button\"\n                (click)=\"$event.stopPropagation(); deselect(filter)\"\n              >\n                <i c8yIcon=\"times\"></i>\n              </button>\n              <span\n                class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n                [ngStyle]=\"{ 'background-color': filter.color }\"\n              >\n                <i\n                  class=\"stroked-icon\"\n                  c8yIcon=\"bell\"\n                ></i>\n              </span>\n              <span\n                class=\"text-truncate text-12 flex-grow\"\n                [title]=\"filter.filters.type\"\n                [attr.aria-label]=\"filter.filters.type\"\n              >\n                {{ filter.filters.type }}\n              </span>\n            </span>\n          }\n        } @else {\n          <span class=\"text-nowrap\">\n            {{ 'All alarm types' | translate }}\n          </span>\n        }\n      </div>\n      <div class=\"input-group-btn input-group-btn--last text-center\">\n        @if (activeFilters.length) {\n          <button\n            class=\"btn-default btn\"\n            [title]=\"'Clear filters' | translate\"\n            (click)=\"deselectAll()\"\n          >\n            <i c8yIcon=\"times\"></i>\n          </button>\n        }\n        <button\n          class=\"btn-default btn btn--caret\"\n          [title]=\"'Alarm types' | translate\"\n          data-cy=\"c8y-alarm-type-filter\"\n          dropdownToggle\n        >\n          <i class=\"caret\"></i>\n        </button>\n      </div>\n    </div>\n    <div\n      class=\"dropdown-menu dropdown-menu-action-bar\"\n      style=\"min-width: 250px\"\n      *dropdownMenu\n    >\n      <div class=\"p-16 bg-level-2\">\n        <div>\n          <p>\n            <i\n              class=\"text-info m-r-4\"\n              [c8yIcon]=\"'info-circle'\"\n            ></i>\n            <strong translate>The list below may not be complete.</strong>\n          </p>\n          <p>\n            <span translate>\n              Recent alarms are displayed below but older ones may not be shown.\n            </span>\n            <span translate>Optionally, you can add a custom alarm.</span>\n          </p>\n        </div>\n      </div>\n      <c8y-list-group>\n        <div class=\"input-group p-t-16 p-b-16 p-r-32 p-l-32 separator-bottom\">\n          <input\n            class=\"form-control\"\n            type=\"text\"\n            [placeholder]=\"'Custom alarm type' | translate\"\n            [(ngModel)]=\"customAlarmTypeInput\"\n            (keydown)=\"confirmWithEnter($event)\"\n          />\n          <div class=\"input-group-btn\">\n            <button\n              class=\"btn-dot text-primary\"\n              [attr.aria-label]=\"'Add custom alarm' | translate\"\n              [tooltip]=\"'Add' | translate\"\n              placement=\"top\"\n              [delay]=\"500\"\n              (click)=\"addCustomAlarmType()\"\n            >\n              <i c8yIcon=\"plus-circle\"></i>\n            </button>\n          </div>\n        </div>\n\n        @for (alarmType of possibleFilters; track $index) {\n          <c8y-li\n            class=\"c8y-list__item__collapse--container-small cdk-drag\"\n            style=\"cursor: pointer\"\n            (click)=\"toggleAlarmType(alarmType)\"\n          >\n            <c8y-li-checkbox\n              class=\"a-s-center m-t-4 p-r-0 p-l-0\"\n              [selected]=\"alarmType.__active\"\n              (click)=\"$event.stopPropagation()\"\n              (change)=\"toggleAlarmType(alarmType); $event.stopPropagation()\"\n            ></c8y-li-checkbox>\n            <div class=\"d-flex a-i-center p-l-4\">\n              <div class=\"c8y-list__item__colorpicker p-t-0 p-b-0 p-l-0\">\n                <div class=\"c8y-colorpicker c8y-colorpicker--alarm\">\n                  <span\n                    class=\"circle-icon-wrapper\"\n                    [ngStyle]=\"{ 'background-color': alarmType.color }\"\n                  >\n                    <i\n                      class=\"stroked-icon\"\n                      [c8yIcon]=\"'bell'\"\n                    ></i>\n                  </span>\n                </div>\n              </div>\n              <span\n                class=\"text-truncate text-12 flex-grow\"\n                [title]=\"alarmType.label\"\n                [attr.aria-label]=\"alarmType.label\"\n              >\n                {{ alarmType.label }}\n              </span>\n              @if (alarmType.__target === null) {\n                <button\n                  class=\"btn-dot btn-dot--danger\"\n                  [attr.aria-label]=\"'Remove' | translate\"\n                  tooltip=\"'Remove' | translate\"\n                  placement=\"top\"\n                  [delay]=\"500\"\n                  (click)=\"removeCustomAlarm(alarmType); $event.stopPropagation()\"\n                >\n                  <i c8yIcon=\"minus-circle\"></i>\n                </button>\n              }\n            </div>\n          </c8y-li>\n        }\n        @if (possibleFilters.length === 0) {\n          <c8y-li>\n            <c8y-ui-empty-state\n              class=\"p-t-8\"\n              icon=\"c8y-alarm\"\n              [title]=\"'No alarm found' | translate\"\n              [subtitle]=\"\n                'There is no alarm to filter. You can still add a custom alarm.' | translate\n              \"\n              [horizontal]=\"true\"\n            ></c8y-ui-empty-state>\n          </c8y-li>\n        }\n        <div class=\"sticky-bottom p-16\">\n          <button\n            class=\"btn btn-block btn-primary\"\n            [disabled]=\"possibleFilters.length === 0\"\n            (click)=\"applyFilterChange(); $event.stopPropagation(); filtersDropdown.hide()\"\n            translate\n          >\n            Apply\n          </button>\n        </div>\n      </c8y-list-group>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$3.AlarmEventSelectorService }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type: i3.ColorService }], propDecorators: { alarms: [{
                type: Input
            }], possibleFilters: [{
                type: Input
            }], activeFilters: [{
                type: Input
            }], onFilterChanged: [{
                type: Output
            }] } });

class AlarmsComponent {
    constructor(activatedRoute, alarmsViewService, alarmWithChildrenRealtimeService, alertService, contextRouteService, modalService, translateService, router, gainsightService, alarmsActivityTrackerService) {
        this.activatedRoute = activatedRoute;
        this.alarmsViewService = alarmsViewService;
        this.alarmWithChildrenRealtimeService = alarmWithChildrenRealtimeService;
        this.alertService = alertService;
        this.contextRouteService = contextRouteService;
        this.modalService = modalService;
        this.translateService = translateService;
        this.router = router;
        this.gainsightService = gainsightService;
        this.alarmsActivityTrackerService = alarmsActivityTrackerService;
        this.NEW_REALTIME_ALARM_MESSAGE = this.alarmsViewService.REALTIME_UPDATE_ALARMS_MESSAGE;
        this.TITLE = gettext('Alarms');
        this.REFRESH_LABEL = gettext('Refresh');
        this.alarms$ = new BehaviorSubject(null);
        this.isLoading$ = new BehaviorSubject(false);
        this.isRealtimeActive = new BehaviorSubject(false);
        this.shouldShowIntervalToggle$ = new BehaviorSubject(true);
        this.isRealtimeToggleOn = true;
        this.typeFilters = [];
        this.isDisabled = false;
        this.isListScrolled = signal(false, ...(ngDevMode ? [{ debugName: "isListScrolled" }] : []));
        this.destroy$ = new Subject();
        this.selectedSeverities = Object.keys(SEVERITY_LABELS);
        this.severityOptions = DEFAULT_SEVERITY_VALUES;
        this.showCleared = false;
        this.WAIT_TIME_AVOID_MULTIPLE_REQUEST_BY_PARAM_CHANGE = 100;
        this.isIntervalRefresh = this.alarmsViewService.isIntervalRefresh();
        this.initializeContextSourceId();
    }
    ngOnInit() {
        this.alarmsActivityTrackerService.setupEventListenersForGainsight();
        this.alarmsActivityTrackerService.resetInactivityTimer();
        this.alarmsActivityTrackerService.isUserActive$
            .pipe(distinctUntilChanged(), takeUntil(this.destroy$))
            .subscribe(isActive => isActive
            ? this.alarmsActivityTrackerService.setGainsightInterval()
            : this.alarmsActivityTrackerService.clearGainsightInterval());
        const isInDetailView = !!this.activatedRoute.children[0]?.snapshot.params.id;
        if (isInDetailView) {
            this.changeInterval(false);
        }
        if (!this.isIntervalRefresh) {
            this.handleLegacyRealtime();
        }
        this.alarmsViewService.reloadAlarmsList$
            .pipe(debounceTime(this.WAIT_TIME_AVOID_MULTIPLE_REQUEST_BY_PARAM_CHANGE), takeUntil(this.destroy$))
            .subscribe((value) => {
            this.updateAlarms(value);
        });
        if (this.isIntervalRefresh) {
            this.alarmsViewService.isIntervalEnabled$
                .pipe(takeUntil(this.destroy$), filter(() => !this.isListScrolled()))
                .subscribe(value => this.changeInterval(value));
        }
        this.alarmsViewService.closeDetailsView$.subscribe(async () => await this.alarmsViewService.closeDetailsView(this.activatedRoute));
    }
    ngOnDestroy() {
        this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS, {
            component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARMS,
            action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.USER_SPEND_TIME_ON_COMPONENT,
            userSpendTime: this.alarmsViewService.convertSecondsToTime(this.alarmsActivityTrackerService.userSecondsSpendOnPage)
        });
        this.alarmsActivityTrackerService.clearGainsightInterval();
        this.destroy$.next();
        this.destroy$.complete();
    }
    visibilityChange() {
        if (document.hidden) {
            this.alarmsActivityTrackerService.clearGainsightInterval();
            return;
        }
        this.alarmsActivityTrackerService.setGainsightInterval();
    }
    applyTypeFilters(typeFilters) {
        this.typeFilters = typeFilters;
        setTimeout(() => this.alarmsViewService.updateAlarmList(typeFilters.length > 0 ? 'gainsightTypeFilters' : null));
        this.isRealtimeActive.next(false);
    }
    applyFormFilters({ severityOptions, showCleared, selectedDates }) {
        this.severityOptions = severityOptions;
        this.showCleared = showCleared;
        this.selectedDates = selectedDates;
        this.selectedSeverities = this.alarmsViewService.updateSelectedSeverities(this.severityOptions);
        this.alarmsViewService.updateAlarmList();
        this.isRealtimeActive.next(false);
    }
    async applyDateFilter(selectedDates) {
        this.alarms$.next(await this.alarmsViewService.retrieveAlarmsByDate(selectedDates));
        this.isRealtimeActive.next(false);
    }
    async clearAll() {
        try {
            const translatedBody = this.translateService.instant(gettext('Do you really want to clear all alarms of selected severities?'));
            await this.modalService.confirm(gettext('Confirm clearing alarms?'), translatedBody, 'danger', {
                ok: gettext('Confirm'),
                cancel: gettext('Cancel')
            });
        }
        catch {
            // modal canceled
            return;
        }
        await this.clearAlarms();
        this.alarmsViewService.closeDetailsView$.next();
    }
    refresh() {
        this.updateAlarms(null);
        this.isRealtimeActive.next(false);
    }
    changeInterval(value = true) {
        this.shouldShowIntervalToggle$.next(value);
    }
    toggleRealtimeState() {
        this.isRealtimeToggleOn = !this.isRealtimeToggleOn;
    }
    handleLegacyRealtime() {
        this.realtimeIconTitle = this.translateService.instant(gettext('Realtime active'));
        this.subscribeToRealtimeUpdates();
    }
    async clearAlarms() {
        try {
            const result = await this.alarmsViewService.clearAllActiveAlarms(this.selectedSeverities, this.contextSourceId);
            if (result.resolvedImmediately) {
                this.alertService.success(this.translateService.instant(gettext('Alarms cleared.')));
                this.refresh();
            }
            else {
                this.alertService.success(this.translateService.instant(gettext('Alarms are being cleared in background.')));
            }
        }
        catch (error) {
            this.alertService.addServerFailure(error);
        }
    }
    async getAlarms() {
        try {
            this.isLoading$.next(true);
            const additionalFilter = {};
            if (this.contextSourceId) {
                (additionalFilter.source = this.contextSourceId),
                    (additionalFilter.withSourceAssets = true),
                    (additionalFilter.withSourceDevices = true);
            }
            if (this.typeFilters.length > 0) {
                additionalFilter.type = this.typeFilters.map(({ filters }) => filters.type).join(',');
            }
            return await this.alarmsViewService.retrieveFilteredAlarms(this.selectedSeverities, this.showCleared, this.selectedDates, additionalFilter);
        }
        catch (error) {
            if (error?.res?.status === 403) {
                this.isDisabled = true;
                return;
            }
            this.alertService.addServerFailure(error);
        }
        finally {
            this.isLoading$.next(false);
        }
    }
    async updateAlarms(value) {
        const alarms = await this.getAlarms();
        this.alarms$.next(alarms);
        if (value === 'gainsightTypeFilters') {
            this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ALARMS.EVENTS.ALARMS, {
                component: PRODUCT_EXPERIENCE_ALARMS.COMPONENTS.ALARMS_TYPE_FILTER,
                action: PRODUCT_EXPERIENCE_ALARMS.ACTIONS.APPLY_TYPE_FILTER,
                alarmsCount: alarms.data.length
            });
        }
    }
    subscribeToRealtimeUpdates() {
        this.alarmWithChildrenRealtimeService
            .onAll$(this.contextSourceId)
            .pipe(takeUntil(this.destroy$), throttleTime(THROTTLE_REALTIME_REFRESH, undefined, { trailing: true }))
            .subscribe(() => {
            if (this.isRealtimeToggleOn) {
                this.refresh();
            }
            else {
                this.isRealtimeActive.next(true);
            }
        });
    }
    initializeContextSourceId() {
        const routeContext = this.contextRouteService.getContextData(this.activatedRoute);
        if (!routeContext) {
            return;
        }
        const { context, contextData } = routeContext;
        if ([ViewContext.Device, ViewContext.Group, ViewContext.Service, ViewContext.Simulators].includes(context)) {
            this.contextSourceId = contextData?.id;
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsComponent, deps: [{ token: i1.ActivatedRoute }, { token: AlarmsViewService }, { token: i3.AlarmWithChildrenRealtimeService }, { token: i3.AlertService }, { token: i3.ContextRouteService }, { token: i3.ModalService }, { token: i1$1.TranslateService }, { token: i1.Router }, { token: i3.GainsightService }, { token: AlarmsActivityTrackerService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: AlarmsComponent, isStandalone: true, selector: "c8y-alarms", host: { listeners: { "document:visibilitychange": "visibilityChange()" } }, providers: [AlarmWithChildrenRealtimeService, AlarmsActivityTrackerService], viewQueries: [{ propertyName: "alarmIntervalRefreshComponent", first: true, predicate: AlarmsIntervalRefreshComponent, descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"(activatedRoute.data | async)?.title\">\n  <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form min-width-fit\"\n>\n  <c8y-alarms-filter\n    class=\"d-block fit-w\"\n    [contextSourceId]=\"contextSourceId\"\n    (onFilterApplied)=\"applyFormFilters($event)\"\n  ></c8y-alarms-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form min-width-fit\"\n>\n  <c8y-alarms-date-filter (dateFilterChange)=\"applyFormFilters($event)\"></c8y-alarms-date-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form\"\n>\n  <c8y-alarms-type-filter\n    class=\"d-block fit-w\"\n    [alarms]=\"alarms$ | async\"\n    (onFilterChanged)=\"applyTypeFilters($event)\"\n  ></c8y-alarms-type-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'right'\"\n  [priority]=\"0\"\n>\n  <button\n    class=\"btn btn-link\"\n    [title]=\"'Clear all alarms' | translate\"\n    type=\"button\"\n    (click)=\"clearAll()\"\n    data-cy=\"c8y-alarms-view--clear-all-button\"\n  >\n    <i c8yIcon=\"c8y-alert-idle\"></i>\n    {{ 'Clear all`alarms`' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<!--Realtime button-->\n<ng-template #realtimeRefresh>\n  <div class=\"input-group-btn\">\n    <button\n      class=\"btn btn-default btn-sm\"\n      [attr.aria-label]=\"'Refresh' | translate\"\n      [tooltip]=\"\n        (isRealtimeActive | async)\n          ? (NEW_REALTIME_ALARM_MESSAGE | translate)\n          : (REFRESH_LABEL | translate)\n      \"\n      placement=\"left\"\n      container=\"body\"\n      type=\"button\"\n      [adaptivePosition]=\"false\"\n      [delay]=\"500\"\n      [disabled]=\"isLoading$ | async\"\n      (click)=\"refresh()\"\n    >\n      <span\n        class=\"tag tag--info m-r-8\"\n        *ngIf=\"isRealtimeActive | async\"\n      >\n        {{ 'New alarms' | translate }}\n      </span>\n      <i\n        c8yIcon=\"refresh\"\n        [ngClass]=\"{ 'icon-spin': isLoading$ | async }\"\n      ></i>\n    </button>\n    <button\n      class=\"c8y-realtime btn btn-default btn-sm\"\n      [attr.aria-label]=\"realtimeIconTitle\"\n      [tooltip]=\"realtimeIconTitle\"\n      placement=\"bottom\"\n      type=\"button\"\n      data-cy=\"c8y-alarms--realtime-button\"\n      [container]=\"'body'\"\n      (click)=\"toggleRealtimeState()\"\n    >\n      <span\n        class=\"c8y-pulse m-0\"\n        [ngClass]=\"{\n          active: isRealtimeToggleOn,\n          inactive: !isRealtimeToggleOn\n        }\"\n      ></span>\n    </button>\n  </div>\n</ng-template>\n\n<c8y-help\n  src=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n></c8y-help>\n\n<div class=\"card content-fullpage split-view--5-7 grid__row--1\">\n  <c8y-alarms-list\n    class=\"d-contents\"\n    [isInitialLoading]=\"isLoading$ | async\"\n    [alarms]=\"alarms$ | async\"\n    [typeFilters]=\"typeFilters\"\n    (onScrollingStateChange)=\"changeInterval(!$event); isListScrolled.set($event)\"\n    (onSelectedAlarm)=\"changeInterval(false)\"\n    [splitView]=\"true\"\n    [hasPermissions]=\"!isDisabled\"\n  >\n    <ng-container *ngIf=\"isIntervalRefresh; else realtimeRefresh\">\n      <c8y-alarms-interval-refresh\n        [alarmsListLoading$]=\"isLoading$\"\n        [isIntervalToggleEnabled]=\"shouldShowIntervalToggle$ | async\"\n        (onCountdownEnded)=\"refresh()\"\n        [isDisabled]=\"isDisabled\"\n      ></c8y-alarms-interval-refresh>\n    </ng-container>\n  </c8y-alarms-list>\n\n  <router-outlet class=\"d-contents\"></router-outlet>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: AlarmsFilterComponent, selector: "c8y-alarms-filter", inputs: ["contextSourceId"], outputs: ["onFilterApplied"] }, { kind: "component", type: AlarmsDateFilterComponent, selector: "c8y-alarms-date-filter", inputs: ["DEFAULT_INTERVAL", "updateQueryParams", "date"], outputs: ["dateFilterChange"] }, { kind: "component", type: AlarmsTypeFilterComponent, selector: "c8y-alarms-type-filter", inputs: ["alarms", "possibleFilters", "activeFilters"], outputs: ["onFilterChanged"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }, { kind: "component", type: AlarmsListComponent, selector: "c8y-alarms-list", inputs: ["alarms", "hasPermissions", "typeFilters", "loadMoreMode", "navigationOptions", "isInitialLoading", "splitView", "isInPreviewMode"], outputs: ["onSelectedAlarm", "onScrollingStateChange"] }, { kind: "component", type: AlarmsIntervalRefreshComponent, selector: "c8y-alarms-interval-refresh", inputs: ["isDisabled", "alarmsListLoading$", "isIntervalToggleEnabled"], outputs: ["onCountdownEnded"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-alarms', providers: [AlarmWithChildrenRealtimeService, AlarmsActivityTrackerService], imports: [
                        NgIf,
                        TitleComponent,
                        ActionBarItemComponent,
                        AlarmsFilterComponent,
                        AlarmsDateFilterComponent,
                        AlarmsTypeFilterComponent,
                        IconDirective,
                        TooltipDirective,
                        NgClass,
                        HelpComponent,
                        AlarmsListComponent,
                        AlarmsIntervalRefreshComponent,
                        RouterOutlet,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<ng-container *ngIf=\"(activatedRoute.data | async)?.title\">\n  <c8y-title>{{ TITLE | translate }}</c8y-title>\n</ng-container>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form min-width-fit\"\n>\n  <c8y-alarms-filter\n    class=\"d-block fit-w\"\n    [contextSourceId]=\"contextSourceId\"\n    (onFilterApplied)=\"applyFormFilters($event)\"\n  ></c8y-alarms-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form min-width-fit\"\n>\n  <c8y-alarms-date-filter (dateFilterChange)=\"applyFormFilters($event)\"></c8y-alarms-date-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form\"\n>\n  <c8y-alarms-type-filter\n    class=\"d-block fit-w\"\n    [alarms]=\"alarms$ | async\"\n    (onFilterChanged)=\"applyTypeFilters($event)\"\n  ></c8y-alarms-type-filter>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'right'\"\n  [priority]=\"0\"\n>\n  <button\n    class=\"btn btn-link\"\n    [title]=\"'Clear all alarms' | translate\"\n    type=\"button\"\n    (click)=\"clearAll()\"\n    data-cy=\"c8y-alarms-view--clear-all-button\"\n  >\n    <i c8yIcon=\"c8y-alert-idle\"></i>\n    {{ 'Clear all`alarms`' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<!--Realtime button-->\n<ng-template #realtimeRefresh>\n  <div class=\"input-group-btn\">\n    <button\n      class=\"btn btn-default btn-sm\"\n      [attr.aria-label]=\"'Refresh' | translate\"\n      [tooltip]=\"\n        (isRealtimeActive | async)\n          ? (NEW_REALTIME_ALARM_MESSAGE | translate)\n          : (REFRESH_LABEL | translate)\n      \"\n      placement=\"left\"\n      container=\"body\"\n      type=\"button\"\n      [adaptivePosition]=\"false\"\n      [delay]=\"500\"\n      [disabled]=\"isLoading$ | async\"\n      (click)=\"refresh()\"\n    >\n      <span\n        class=\"tag tag--info m-r-8\"\n        *ngIf=\"isRealtimeActive | async\"\n      >\n        {{ 'New alarms' | translate }}\n      </span>\n      <i\n        c8yIcon=\"refresh\"\n        [ngClass]=\"{ 'icon-spin': isLoading$ | async }\"\n      ></i>\n    </button>\n    <button\n      class=\"c8y-realtime btn btn-default btn-sm\"\n      [attr.aria-label]=\"realtimeIconTitle\"\n      [tooltip]=\"realtimeIconTitle\"\n      placement=\"bottom\"\n      type=\"button\"\n      data-cy=\"c8y-alarms--realtime-button\"\n      [container]=\"'body'\"\n      (click)=\"toggleRealtimeState()\"\n    >\n      <span\n        class=\"c8y-pulse m-0\"\n        [ngClass]=\"{\n          active: isRealtimeToggleOn,\n          inactive: !isRealtimeToggleOn\n        }\"\n      ></span>\n    </button>\n  </div>\n</ng-template>\n\n<c8y-help\n  src=\"/docs/device-management-application/monitoring-and-controlling-devices/#working-with-alarms\"\n></c8y-help>\n\n<div class=\"card content-fullpage split-view--5-7 grid__row--1\">\n  <c8y-alarms-list\n    class=\"d-contents\"\n    [isInitialLoading]=\"isLoading$ | async\"\n    [alarms]=\"alarms$ | async\"\n    [typeFilters]=\"typeFilters\"\n    (onScrollingStateChange)=\"changeInterval(!$event); isListScrolled.set($event)\"\n    (onSelectedAlarm)=\"changeInterval(false)\"\n    [splitView]=\"true\"\n    [hasPermissions]=\"!isDisabled\"\n  >\n    <ng-container *ngIf=\"isIntervalRefresh; else realtimeRefresh\">\n      <c8y-alarms-interval-refresh\n        [alarmsListLoading$]=\"isLoading$\"\n        [isIntervalToggleEnabled]=\"shouldShowIntervalToggle$ | async\"\n        (onCountdownEnded)=\"refresh()\"\n        [isDisabled]=\"isDisabled\"\n      ></c8y-alarms-interval-refresh>\n    </ng-container>\n  </c8y-alarms-list>\n\n  <router-outlet class=\"d-contents\"></router-outlet>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: AlarmsViewService }, { type: i3.AlarmWithChildrenRealtimeService }, { type: i3.AlertService }, { type: i3.ContextRouteService }, { type: i3.ModalService }, { type: i1$1.TranslateService }, { type: i1.Router }, { type: i3.GainsightService }, { type: AlarmsActivityTrackerService }], propDecorators: { alarmIntervalRefreshComponent: [{
                type: ViewChild,
                args: [AlarmsIntervalRefreshComponent]
            }], visibilityChange: [{
                type: HostListener,
                args: ['document:visibilitychange']
            }] } });

function getViewContextRoutes(contexts) {
    return contexts.map(context => ({
        context,
        path: 'details',
        icon: 'bell',
        label: gettext('Details'),
        component: AlarmInfoComponent,
        tabsOutlet: 'alarms'
    }));
}
function getChildrenForViewContext(context) {
    return [
        {
            path: '',
            component: AlarmEmptyComponent,
            label: gettext('Alarms')
        },
        {
            path: ':id',
            rootContext: context,
            component: ContextRouteComponent,
            canActivate: [ContextRouteGuard],
            data: { context, contextData: {} },
            resolve: {
                tabs: RouterTabsResolver
            }
        }
    ];
}

const defaultAlarmsConfig = {
    hybrid: true
};
class AlarmsModule {
    static config(config = {}) {
        const alarmsConfig = { ...defaultAlarmsConfig, ...config };
        return {
            ngModule: AlarmsModule,
            providers: [
                ...(alarmsConfig.hybrid ? [smartRulesUpgradeServiceProvider] : []),
                hookNavigator(alarmsConfig.rootNavigatorNode),
                hookRoute(alarmsConfig.route),
                {
                    provide: ALARMS_MODULE_CONFIG,
                    useValue: alarmsConfig
                }
            ]
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: AlarmsModule, imports: [A11yModule,
            BsDropdownModule,
            CommonModule,
            CoreModule,
            HeaderModule,
            PopoverModule, i1$4.TooltipModule, C8yTranslateModule,
            RouterModule,
            AlarmEventSelectorModule,
            RouterModule,
            AlarmListIndicatorPipe,
            AlarmDetailsButtonPipe,
            AlarmSeverityToIconPipe,
            DynamicComponentModule,
            IntervalPickerComponent,
            AlarmDetailsComponent,
            AlarmInfoComponent,
            AlarmsComponent,
            AlarmSeveritiesToTitlePipe,
            AlarmsFilterComponent,
            AlarmsIconComponent,
            AlarmsIntervalRefreshComponent,
            AlarmsListComponent,
            AlarmStatusToIconPipe,
            AuditChangesMessagePipe,
            AlarmSeverityToLabelPipe,
            AlarmStatusToLabelPipe,
            AlarmEmptyComponent,
            AlarmsDateFilterComponent,
            AlarmsTypeFilterComponent], exports: [AlarmsComponent, AlarmsListComponent, AlarmsFilterComponent, AlarmsDateFilterComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsModule, providers: [
            TitleCasePipe,
            RelativeTimePipe,
            {
                provide: ALARMS_MODULE_CONFIG,
                useValue: defaultAlarmsConfig
            }
        ], imports: [A11yModule,
            BsDropdownModule,
            CommonModule,
            CoreModule,
            HeaderModule,
            PopoverModule,
            TooltipModule.forRoot(),
            C8yTranslateModule,
            RouterModule,
            AlarmEventSelectorModule,
            RouterModule,
            DynamicComponentModule,
            IntervalPickerComponent,
            AlarmDetailsComponent,
            AlarmInfoComponent,
            AlarmsComponent,
            AlarmsFilterComponent,
            AlarmsIntervalRefreshComponent,
            AlarmsListComponent,
            AlarmEmptyComponent,
            AlarmsDateFilterComponent,
            AlarmsTypeFilterComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AlarmsModule, decorators: [{
            type: NgModule,
            args: [{
                    exports: [AlarmsComponent, AlarmsListComponent, AlarmsFilterComponent, AlarmsDateFilterComponent],
                    providers: [
                        TitleCasePipe,
                        RelativeTimePipe,
                        {
                            provide: ALARMS_MODULE_CONFIG,
                            useValue: defaultAlarmsConfig
                        }
                    ],
                    imports: [
                        A11yModule,
                        BsDropdownModule,
                        CommonModule,
                        CoreModule,
                        HeaderModule,
                        PopoverModule,
                        TooltipModule.forRoot(),
                        C8yTranslateModule,
                        RouterModule,
                        AlarmEventSelectorModule,
                        RouterModule,
                        AlarmListIndicatorPipe,
                        AlarmDetailsButtonPipe,
                        AlarmSeverityToIconPipe,
                        DynamicComponentModule,
                        IntervalPickerComponent,
                        AlarmDetailsComponent,
                        AlarmInfoComponent,
                        AlarmsComponent,
                        AlarmSeveritiesToTitlePipe,
                        AlarmsFilterComponent,
                        AlarmsIconComponent,
                        AlarmsIntervalRefreshComponent,
                        AlarmsListComponent,
                        AlarmStatusToIconPipe,
                        AuditChangesMessagePipe,
                        AlarmSeverityToLabelPipe,
                        AlarmStatusToLabelPipe,
                        AlarmEmptyComponent,
                        AlarmsDateFilterComponent,
                        AlarmsTypeFilterComponent
                    ]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { ALARMS_MODULE_CONFIG, ALARMS_PATH, ALARM_DEFAULT_PROPERTIES, ALARM_SEVERITY_ICON, ALARM_SEVERITY_ICON_MAP, ALARM_STATUS_ICON, AlarmDetailsButtonPipe, AlarmDetailsButtonService, AlarmDetailsComponent, AlarmDetailsService, AlarmEmptyComponent, AlarmIconMap, AlarmInfoComponent, AlarmListIndicatorPipe, AlarmListIndicatorService, AlarmSeveritiesToTitlePipe, AlarmSeverityToIconClassPipe, AlarmSeverityToIconPipe, AlarmSeverityToLabelPipe, AlarmStatusToIconPipe, AlarmStatusToLabelPipe, AlarmsActivityTrackerService, AlarmsComponent, AlarmsDateFilterComponent, AlarmsFilterComponent, AlarmsIconComponent, AlarmsIntervalRefreshComponent, AlarmsListComponent, AlarmsModule, AlarmsTypeFilterComponent, AlarmsViewService, AuditChangesMessagePipe, DEFAULT_ALARM_COUNTS, DEFAULT_SEVERITY_VALUES, DEFAULT_STATUS_VALUES, HELP_ICON, INTERVALS_EXTENDED, INTERVAL_TITLES_EXTENDED, Ng1SmartRulesUpgradeService, PRODUCT_EXPERIENCE_ALARMS, SmartRulesUpgradeServiceFactory, THROTTLE_REALTIME_REFRESH, getChildrenForViewContext, getViewContextRoutes, smartRulesUpgradeServiceProvider };
//# sourceMappingURL=c8y-ngx-components-alarms.mjs.map