@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
889 lines • 94 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, forwardRef, Component, Input, EventEmitter, Output, Pipe, Optional, ContentChild, NgModule } from '@angular/core';
import * as i1 from '@angular/forms';
import { FormControl, Validators, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
import { take, takeUntil, map, startWith, tap, switchMap, shareReplay, distinctUntilChanged, debounceTime } from 'rxjs/operators';
import * as i3 from '@angular/common';
import * as i2 from '@c8y/ngx-components';
import { gettext, ViewContext, EmptyStateComponent, CommonModule, CoreModule } from '@c8y/ngx-components';
import * as i8 from '@angular/cdk/drag-drop';
import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
import * as i6$1 from '@c8y/ngx-components/context-dashboard';
import * as i1$2 from 'ngx-bootstrap/modal';
import { Subject, BehaviorSubject, combineLatest } from 'rxjs';
import * as i1$1 from '@c8y/client';
import { uniqBy } from 'lodash-es';
import * as i5 from '@c8y/ngx-components/assets-navigator';
import { AssetSelectorModule } from '@c8y/ngx-components/assets-navigator';
import * as i6 from 'ngx-bootstrap/collapse';
import { CollapseModule } from 'ngx-bootstrap/collapse';
import * as i4 from 'ngx-bootstrap/popover';
import { PopoverModule } from 'ngx-bootstrap/popover';
import * as i4$1 from '@angular/router';
import { RouterModule } from '@angular/router';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
class AlarmEventAttributesFormService {
duplicateTypeValidator(selectedItems) {
return (control) => {
if (!control.value || !selectedItems?.length) {
return null;
}
const isDuplicate = selectedItems.some(item => item.filters?.type?.toLowerCase() === control.value.toLowerCase());
return isDuplicate ? { duplicateType: true } : null;
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventAttributesFormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventAttributesFormService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventAttributesFormService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}] });
class AlarmEventAttributesFormComponent {
constructor(formBuilder, alarmEventAttributesFormService) {
this.formBuilder = formBuilder;
this.alarmEventAttributesFormService = alarmEventAttributesFormService;
this.omitProperties = {};
this.selectedItems = [];
this.datapoints = [];
}
ngOnInit() {
this.formGroup = this.formBuilder.group({
filters: this.formBuilder.group({
type: new FormControl('', [
Validators.required,
this.alarmEventAttributesFormService.duplicateTypeValidator(this.selectedItems)
])
}),
timelineType: new FormControl(''),
selectedDatapoint: new FormControl(null)
});
if (!this.omitProperties.label) {
this.formGroup.addControl('label', new FormControl('', Validators.required));
}
if (this.datapoints?.length > 0) {
this.filterKpis();
}
}
validate(_control) {
return this.formGroup?.valid ? null : { formInvalid: {} };
}
writeValue(obj) {
this.formGroup.patchValue(obj);
}
registerOnChange(fn) {
this.formGroup.valueChanges.subscribe(fn);
}
registerOnTouched(fn) {
this.formGroup.valueChanges.pipe(take(1)).subscribe(fn);
}
setDisabledState(isDisabled) {
isDisabled ? this.formGroup.disable() : this.formGroup.enable();
}
changeDatapointSelection(event) {
const selectElement = event.target;
const selectedIndex = selectElement.selectedIndex;
const selectedDatapoint = this.datapoints[selectedIndex];
const trimmedDatapoint = {
target: selectedDatapoint.__target.id,
fragment: selectedDatapoint.fragment,
series: selectedDatapoint.series
};
this.formGroup.patchValue({ selectedDatapoint: trimmedDatapoint });
}
trackByFn(_index, item) {
return `${item.fragment}-${item.series}-${item.__target?.id}`;
}
filterKpis() {
if (this.target && this.target.id) {
this.datapoints = this.datapoints.filter(dp => dp.__target?.id === this.target.id);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventAttributesFormComponent, deps: [{ token: i1.FormBuilder }, { token: AlarmEventAttributesFormService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AlarmEventAttributesFormComponent, selector: "c8y-alarm-event-attributes-form", inputs: { timelineType: "timelineType", omitProperties: "omitProperties", selectedItems: "selectedItems", target: "target", datapoints: "datapoints" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AlarmEventAttributesFormComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AlarmEventAttributesFormComponent),
multi: true
}
], ngImport: i0, template: "<div [formGroup]=\"formGroup\">\n <c8y-form-group\n class=\"form-group-sm\"\n *ngIf=\"formGroup.controls.label\"\n >\n <label class=\"m-0\">{{ 'Label' | translate }}</label>\n <input\n class=\"form-control flex-grow\"\n name=\"label\"\n formControlName=\"label\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate\n : {\n example: timelineType === 'ALARM' ? 'Alarm unavailable' : 'Location update'\n }\n \"\n />\n </c8y-form-group>\n\n <div formGroupName=\"filters\">\n <c8y-form-group class=\"form-group-sm\">\n <label class=\"m-0\">{{ 'Type' | translate }}</label>\n <input\n class=\"form-control flex-grow\"\n name=\"type\"\n formControlName=\"type\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate\n : {\n example:\n timelineType === 'ALARM' ? 'c8y_UnavailabilityAlarm' : 'c8y_LocationUpdate'\n }\n \"\n />\n <c8y-messages>\n <c8y-message\n name=\"duplicateType\"\n [text]=\"'Type already used.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <c8y-form-group\n class=\"form-group-sm\"\n *ngIf=\"datapoints?.length > 0\"\n >\n <label>{{ 'Select data point' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control input-sm\"\n (change)=\"changeDatapointSelection($event)\"\n >\n <option\n title=\"{{ 'Widget configuration' | translate }}\"\n *ngFor=\"let datapoint of datapoints; trackBy: trackByFn\"\n [ngValue]=\"{\n target: datapoint.__target.id,\n fragment: datapoint.fragment,\n series: datapoint.series\n }\"\n [selected]=\"\n datapoint.__target.id === formGroup.value.selectedDatapoint?.target &&\n datapoint.fragment === formGroup.value.selectedDatapoint?.fragment &&\n datapoint.series === formGroup.value.selectedDatapoint?.series\n \"\n >\n {{ datapoint?.label }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i2.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventAttributesFormComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-alarm-event-attributes-form', providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AlarmEventAttributesFormComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AlarmEventAttributesFormComponent),
multi: true
}
], template: "<div [formGroup]=\"formGroup\">\n <c8y-form-group\n class=\"form-group-sm\"\n *ngIf=\"formGroup.controls.label\"\n >\n <label class=\"m-0\">{{ 'Label' | translate }}</label>\n <input\n class=\"form-control flex-grow\"\n name=\"label\"\n formControlName=\"label\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate\n : {\n example: timelineType === 'ALARM' ? 'Alarm unavailable' : 'Location update'\n }\n \"\n />\n </c8y-form-group>\n\n <div formGroupName=\"filters\">\n <c8y-form-group class=\"form-group-sm\">\n <label class=\"m-0\">{{ 'Type' | translate }}</label>\n <input\n class=\"form-control flex-grow\"\n name=\"type\"\n formControlName=\"type\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate\n : {\n example:\n timelineType === 'ALARM' ? 'c8y_UnavailabilityAlarm' : 'c8y_LocationUpdate'\n }\n \"\n />\n <c8y-messages>\n <c8y-message\n name=\"duplicateType\"\n [text]=\"'Type already used.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <c8y-form-group\n class=\"form-group-sm\"\n *ngIf=\"datapoints?.length > 0\"\n >\n <label>{{ 'Select data point' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control input-sm\"\n (change)=\"changeDatapointSelection($event)\"\n >\n <option\n title=\"{{ 'Widget configuration' | translate }}\"\n *ngFor=\"let datapoint of datapoints; trackBy: trackByFn\"\n [ngValue]=\"{\n target: datapoint.__target.id,\n fragment: datapoint.fragment,\n series: datapoint.series\n }\"\n [selected]=\"\n datapoint.__target.id === formGroup.value.selectedDatapoint?.target &&\n datapoint.fragment === formGroup.value.selectedDatapoint?.fragment &&\n datapoint.series === formGroup.value.selectedDatapoint?.series\n \"\n >\n {{ datapoint?.label }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: AlarmEventAttributesFormService }], propDecorators: { timelineType: [{
type: Input
}], omitProperties: [{
type: Input
}], selectedItems: [{
type: Input
}], target: [{
type: Input
}], datapoints: [{
type: Input
}] } });
const EVENT_TEXTS = {
listTitle: gettext('Events'),
emptyStateIcon: 'c8y-events',
emptyStateTitle: gettext('No events to display.'),
emptyStateSubtitle: gettext('Add your first event.'),
addButtonLabel: gettext('Add event'),
addCustomItemButtonLabel: gettext('Add custom event'),
selectorTitle: gettext('Events selector'),
availableItemsTitle: gettext('Available events'),
assetWithNoItemsEmptyStateSubtitle: gettext('Select an asset with events from the list.'),
largeNumberOfItemsInfo: gettext('Due to the large number, only a subset of events are displayed. Use search to narrow down the number of results.'),
selectedItemsTitle: gettext('Selected events'),
noSelectedItemsTitle: gettext('No events selected.'),
recentItemsWarningTitle: gettext('The list below may not be complete.'),
recentItemsWarningText: gettext('Recent events are displayed below. Past events might not be shown.'),
addCustomText: gettext('Optionally you can add a custom event.')
};
const ALARM_TEXTS = {
listTitle: gettext('Alarms'),
emptyStateIcon: 'c8y-alarm',
emptyStateTitle: gettext('No alarms to display.'),
emptyStateSubtitle: gettext('Add your first alarm.'),
addButtonLabel: gettext('Add alarm'),
addCustomItemButtonLabel: gettext('Add custom alarm'),
selectorTitle: gettext('Alarms selector'),
availableItemsTitle: gettext('Available alarms'),
assetWithNoItemsEmptyStateSubtitle: gettext('Select an asset with alarms from the list.'),
largeNumberOfItemsInfo: gettext('Due to the large number, only a subset of alarms are displayed. Use search to narrow down the number of results.'),
selectedItemsTitle: gettext('Selected alarms'),
noSelectedItemsTitle: gettext('No alarms selected.'),
recentItemsWarningTitle: gettext('The list below may not be complete.'),
recentItemsWarningText: gettext('Recent alarms are displayed below. Past alarms might not be shown.'),
addCustomText: gettext('Optionally you can add a custom alarm.')
};
class AlarmEventSelectorService {
constructor(alarmService, eventsService, color) {
this.alarmService = alarmService;
this.eventsService = eventsService;
this.color = color;
this.timelineTypeTextsMap = new Map([
['ALARM', ALARM_TEXTS],
['EVENT', EVENT_TEXTS]
]);
}
/**
* This method returns the texts for the timeline type.
* @param timelineType The timeline type.
* @returns The texts for the timeline type.
*/
timelineTypeTexts(timelineType) {
return this.timelineTypeTextsMap.get(timelineType);
}
/**
* This method returns all alarms or events of the platform based on the timeline type
* @param timelineType The timeline type.
* @returns The alarms or events of the asset.
*/
async getItems(timelineType) {
const filters = {
pageSize: 1000
};
return timelineType === 'ALARM'
? await this.getAlarmsOfAsset(filters)
: await this.getEventsOfAsset(filters);
}
/**
* This method returns the items of the asset based on the timeline type.
* @param parentReference The parent reference.
* @param timelineType The timeline type.
* @returns The alarms or events of the asset.
*/
async getAlarmsOrEvents(parentReference, timelineType) {
const filters = { source: parentReference.id, pageSize: 1000 };
return timelineType === 'ALARM'
? await this.getAlarmsOfAsset(filters)
: await this.getEventsOfAsset(filters);
}
async getUniqueAlarmsOnly(data) {
return Promise.all(uniqBy(data, 'type').map(async (alarm) => this.createItem('ALARM', alarm)));
}
async getUniqueEventsOnly(data) {
return Promise.all(uniqBy(data, 'type').map(async (event) => this.createItem('EVENT', event)));
}
async createItem(timelineType, item) {
const color = await this.color.generateColor(item.type);
if (item.source && !item.source.name) {
item.source.name = `Device ${item.source.id}`;
}
return {
timelineType,
color,
label: item.type,
filters: {
type: item.type
},
__target: item.source
};
}
async getAlarmsOfAsset(filters) {
const res = await this.alarmService.list({
...filters,
withSourceAssets: !!filters.source,
withSourceDevices: !!filters.source,
pageSize: 1000
});
const alarms = await this.getUniqueAlarmsOnly(res.data);
return alarms;
}
async getEventsOfAsset(filters) {
const res = await this.eventsService.list(filters);
const events = this.getUniqueEventsOnly(res.data);
return events;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorService, deps: [{ token: i1$1.AlarmService }, { token: i1$1.EventService }, { token: i2.ColorService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i1$1.AlarmService }, { type: i1$1.EventService }, { type: i2.ColorService }] });
class AlarmEventSelectorListItemComponent {
constructor(formBuilder) {
this.formBuilder = formBuilder;
this.showAddRemoveButton = true;
this.isSelected = false;
this.optionToRemove = false;
this.showActiveToggle = false;
this.allowItemEdit = false;
this.hideSource = false;
this.displayAsSwitch = false;
this.omitProperties = {};
this.added = new EventEmitter();
this.removed = new EventEmitter();
this.destroy$ = new Subject();
this.formGroup = this.formBuilder.group({
details: [],
color: [],
__active: [],
__target: []
});
this.valid$ = this.formGroup.statusChanges.pipe(takeUntil(this.destroy$), map(val => val === 'VALID'));
}
ngOnInit() {
this.colorPickerTitle = this.allowItemEdit ? gettext('Change color') : '';
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
toggleActive() {
this.formGroup.controls.__active.setValue(!this.formGroup.value.__active);
}
validate(_control) {
return this.formGroup?.valid ? null : { formInvalid: {} };
}
writeValue(obj) {
this.formGroup.patchValue({ ...obj, details: obj });
}
registerOnChange(fn) {
this.formGroup.valueChanges
.pipe(map(tmp => this.transformFormValue(tmp)), takeUntil(this.destroy$))
.subscribe(fn);
}
registerOnTouched(fn) {
this.formGroup.valueChanges.pipe(take(1)).subscribe(fn);
}
setDisabledState(isDisabled) {
isDisabled ? this.formGroup.disable() : this.formGroup.enable();
}
addOrRemoveItem() {
const value = this.transformFormValue(this.formGroup.value);
if (this.isSelected) {
this.removed.emit(value);
}
else {
this.added.emit(value);
}
}
remove() {
this.removed.emit(this.transformFormValue(this.formGroup.value));
}
transformFormValue(formValue) {
const obj = Object.assign({}, formValue.details || {}, formValue);
delete obj.details;
return obj;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorListItemComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AlarmEventSelectorListItemComponent, selector: "c8y-alarm-event-selector-list-item", inputs: { timelineType: "timelineType", datapoints: "datapoints", highlightText: "highlightText", showAddRemoveButton: "showAddRemoveButton", isSelected: "isSelected", optionToRemove: "optionToRemove", showActiveToggle: "showActiveToggle", allowItemEdit: "allowItemEdit", hideSource: "hideSource", displayAsSwitch: "displayAsSwitch", omitProperties: "omitProperties" }, outputs: { added: "added", removed: "removed" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AlarmEventSelectorListItemComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AlarmEventSelectorListItemComponent),
multi: true
}
], ngImport: i0, template: "<c8y-li\n class=\"c8y-list__item__collapse--container-small\"\n [formGroup]=\"formGroup\"\n #li\n>\n <c8y-li-drag-handle><ng-content select=\"c8y-li-drag-handle\"></ng-content></c8y-li-drag-handle>\n <c8y-li-icon\n class=\"a-s-center p-r-4\"\n *ngIf=\"showAddRemoveButton\"\n >\n <button\n class=\"btn btn-clean text-primary\"\n [title]=\"'Remove' | translate\"\n *ngIf=\"isSelected\"\n (click)=\"addOrRemoveItem()\"\n >\n <i\n class=\"text-danger\"\n c8yIcon=\"minus-circle\"\n ></i>\n </button>\n <button\n class=\"btn btn-clean text-primary\"\n [title]=\"'Select' | translate\"\n *ngIf=\"!isSelected\"\n (click)=\"addOrRemoveItem()\"\n [disabled]=\"(valid$ | async) === false\"\n >\n <i\n class=\"text-primary\"\n c8yIcon=\"plus-circle\"\n ></i>\n </button>\n </c8y-li-icon>\n\n <c8y-li-checkbox\n class=\"a-s-center m-t-4 p-r-0\"\n *ngIf=\"showActiveToggle\"\n [displayAsSwitch]=\"displayAsSwitch\"\n formControlName=\"__active\"\n (click)=\"$event.stopPropagation()\"\n ></c8y-li-checkbox>\n\n <div class=\"d-flex a-i-center p-l-0\">\n <div\n class=\"c8y-list__item__colorpicker p-t-0 p-b-0 p-l-4\"\n [title]=\"colorPickerTitle | translate\"\n >\n <div\n class=\"c8y-colorpicker\"\n [ngClass]=\"{\n 'c8y-colorpicker--alarm': timelineType === 'ALARM',\n 'c8y-colorpicker--event': timelineType === 'EVENT'\n }\"\n >\n <input\n [ngStyle]=\"{ 'pointer-events': allowItemEdit && !omitProperties.color ? 'auto' : 'none' }\"\n type=\"color\"\n formControlName=\"color\"\n (click)=\"$event.stopPropagation()\"\n />\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--medium\"\n [ngStyle]=\"{ 'background-color': formGroup.value.color }\"\n >\n <i\n class=\"stroked-icon\"\n [c8yIcon]=\"timelineType === 'EVENT' ? 'c8y-events' : 'bell'\"\n ></i>\n </span>\n </div>\n </div>\n <button\n class=\"btn-clean text-truncate\"\n [title]=\"formGroup.value.details?.label\"\n (click)=\"\n allowItemEdit\n ? (li.collapsed = !li.collapsed)\n : showActiveToggle\n ? toggleActive()\n : addOrRemoveItem()\n \"\n >\n <span class=\"text-truncate\">\n <c8y-highlight\n [text]=\"\n omitProperties.label\n ? formGroup.value.details?.filters?.type\n : formGroup.value.details?.label\n \"\n [pattern]=\"highlightText\"\n [shouldTrimPattern]=\"true\"\n ></c8y-highlight>\n </span>\n <small\n class=\"text-truncate text-muted icon-flex\"\n *ngIf=\"formGroup.value.__target && !hideSource\"\n >\n <i c8yIcon=\"exchange\"></i>\n <span class=\"text-truncate\">{{ formGroup.value.__target.name }}</span>\n </small>\n </button>\n\n <button\n class=\"btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Invalid entries' | translate }}\"\n [popover]=\"'Some entries are invalid. Check the required input fields.' | translate\"\n container=\"body\"\n *ngIf=\"(valid$ | async) === false && li.collapsed\"\n [outsideClick]=\"true\"\n >\n <i c8yIcon=\"exclamation-circle\"></i>\n </button>\n </div>\n\n <c8y-li-action\n [icon]=\"'minus-circle'\"\n *ngIf=\"optionToRemove\"\n [label]=\"'Remove from list' | translate\"\n (click)=\"remove()\"\n ></c8y-li-action>\n <c8y-li-collapse *ngIf=\"allowItemEdit\">\n <div class=\"data-point-details\">\n <c8y-alarm-event-attributes-form\n formControlName=\"details\"\n [timelineType]=\"timelineType\"\n [omitProperties]=\"omitProperties\"\n [datapoints]=\"datapoints\"\n [target]=\"formGroup.value.__target\"\n ></c8y-alarm-event-attributes-form>\n </div>\n </c8y-li-collapse>\n</c8y-li>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: i2.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i2.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i2.ListItemActionComponent, selector: "c8y-list-item-action, c8y-li-action", inputs: ["label", "icon", "disabled"], outputs: ["click"] }, { kind: "component", type: i2.ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "component", type: i2.ListItemCheckboxComponent, selector: "c8y-list-item-checkbox, c8y-li-checkbox", inputs: ["selected", "indeterminate", "disabled", "displayAsSwitch"], outputs: ["onSelect"] }, { kind: "component", type: i2.ListItemDragHandleComponent, selector: "c8y-list-item-drag-handle, c8y-li-drag-handle" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i4.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: AlarmEventAttributesFormComponent, selector: "c8y-alarm-event-attributes-form", inputs: ["timelineType", "omitProperties", "selectedItems", "target", "datapoints"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorListItemComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-alarm-event-selector-list-item', providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AlarmEventSelectorListItemComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AlarmEventSelectorListItemComponent),
multi: true
}
], template: "<c8y-li\n class=\"c8y-list__item__collapse--container-small\"\n [formGroup]=\"formGroup\"\n #li\n>\n <c8y-li-drag-handle><ng-content select=\"c8y-li-drag-handle\"></ng-content></c8y-li-drag-handle>\n <c8y-li-icon\n class=\"a-s-center p-r-4\"\n *ngIf=\"showAddRemoveButton\"\n >\n <button\n class=\"btn btn-clean text-primary\"\n [title]=\"'Remove' | translate\"\n *ngIf=\"isSelected\"\n (click)=\"addOrRemoveItem()\"\n >\n <i\n class=\"text-danger\"\n c8yIcon=\"minus-circle\"\n ></i>\n </button>\n <button\n class=\"btn btn-clean text-primary\"\n [title]=\"'Select' | translate\"\n *ngIf=\"!isSelected\"\n (click)=\"addOrRemoveItem()\"\n [disabled]=\"(valid$ | async) === false\"\n >\n <i\n class=\"text-primary\"\n c8yIcon=\"plus-circle\"\n ></i>\n </button>\n </c8y-li-icon>\n\n <c8y-li-checkbox\n class=\"a-s-center m-t-4 p-r-0\"\n *ngIf=\"showActiveToggle\"\n [displayAsSwitch]=\"displayAsSwitch\"\n formControlName=\"__active\"\n (click)=\"$event.stopPropagation()\"\n ></c8y-li-checkbox>\n\n <div class=\"d-flex a-i-center p-l-0\">\n <div\n class=\"c8y-list__item__colorpicker p-t-0 p-b-0 p-l-4\"\n [title]=\"colorPickerTitle | translate\"\n >\n <div\n class=\"c8y-colorpicker\"\n [ngClass]=\"{\n 'c8y-colorpicker--alarm': timelineType === 'ALARM',\n 'c8y-colorpicker--event': timelineType === 'EVENT'\n }\"\n >\n <input\n [ngStyle]=\"{ 'pointer-events': allowItemEdit && !omitProperties.color ? 'auto' : 'none' }\"\n type=\"color\"\n formControlName=\"color\"\n (click)=\"$event.stopPropagation()\"\n />\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--medium\"\n [ngStyle]=\"{ 'background-color': formGroup.value.color }\"\n >\n <i\n class=\"stroked-icon\"\n [c8yIcon]=\"timelineType === 'EVENT' ? 'c8y-events' : 'bell'\"\n ></i>\n </span>\n </div>\n </div>\n <button\n class=\"btn-clean text-truncate\"\n [title]=\"formGroup.value.details?.label\"\n (click)=\"\n allowItemEdit\n ? (li.collapsed = !li.collapsed)\n : showActiveToggle\n ? toggleActive()\n : addOrRemoveItem()\n \"\n >\n <span class=\"text-truncate\">\n <c8y-highlight\n [text]=\"\n omitProperties.label\n ? formGroup.value.details?.filters?.type\n : formGroup.value.details?.label\n \"\n [pattern]=\"highlightText\"\n [shouldTrimPattern]=\"true\"\n ></c8y-highlight>\n </span>\n <small\n class=\"text-truncate text-muted icon-flex\"\n *ngIf=\"formGroup.value.__target && !hideSource\"\n >\n <i c8yIcon=\"exchange\"></i>\n <span class=\"text-truncate\">{{ formGroup.value.__target.name }}</span>\n </small>\n </button>\n\n <button\n class=\"btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Invalid entries' | translate }}\"\n [popover]=\"'Some entries are invalid. Check the required input fields.' | translate\"\n container=\"body\"\n *ngIf=\"(valid$ | async) === false && li.collapsed\"\n [outsideClick]=\"true\"\n >\n <i c8yIcon=\"exclamation-circle\"></i>\n </button>\n </div>\n\n <c8y-li-action\n [icon]=\"'minus-circle'\"\n *ngIf=\"optionToRemove\"\n [label]=\"'Remove from list' | translate\"\n (click)=\"remove()\"\n ></c8y-li-action>\n <c8y-li-collapse *ngIf=\"allowItemEdit\">\n <div class=\"data-point-details\">\n <c8y-alarm-event-attributes-form\n formControlName=\"details\"\n [timelineType]=\"timelineType\"\n [omitProperties]=\"omitProperties\"\n [datapoints]=\"datapoints\"\n [target]=\"formGroup.value.__target\"\n ></c8y-alarm-event-attributes-form>\n </div>\n </c8y-li-collapse>\n</c8y-li>\n" }]
}], ctorParameters: () => [{ type: i1.FormBuilder }], propDecorators: { timelineType: [{
type: Input
}], datapoints: [{
type: Input
}], highlightText: [{
type: Input
}], showAddRemoveButton: [{
type: Input
}], isSelected: [{
type: Input
}], optionToRemove: [{
type: Input
}], showActiveToggle: [{
type: Input
}], allowItemEdit: [{
type: Input
}], hideSource: [{
type: Input
}], displayAsSwitch: [{
type: Input
}], omitProperties: [{
type: Input
}], added: [{
type: Output
}], removed: [{
type: Output
}] } });
class CustomAlarmEventFormComponent {
constructor(formBuilder) {
this.formBuilder = formBuilder;
this.omitProperties = {};
this.selectedItems = [];
this.added = new EventEmitter();
this.cancel = new EventEmitter();
this.destroy$ = new Subject();
this.formGroup = this.formBuilder.group({
details: [],
color: [],
__active: [],
__target: []
});
this.valid$ = this.formGroup.statusChanges.pipe(takeUntil(this.destroy$), map(val => val === 'VALID'), startWith(false));
}
ngOnInit() {
this.formGroup.patchValue({
color: this.defaultColor,
__target: this.target,
details: { timelineType: this.timelineType }
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
add() {
if (this.formGroup.valid) {
const formValue = this.transformFormValue(this.formGroup.value);
this.added.emit(formValue);
}
}
transformFormValue(formValue) {
const obj = Object.assign({}, formValue.details || {}, formValue);
delete obj.details;
return obj;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CustomAlarmEventFormComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CustomAlarmEventFormComponent, selector: "c8y-custom-alarm-event-form", inputs: { timelineType: "timelineType", target: "target", omitProperties: "omitProperties", selectedItems: "selectedItems", defaultColor: "defaultColor" }, outputs: { added: "added", cancel: "cancel" }, ngImport: i0, template: "<form [formGroup]=\"formGroup\" class=\"p-16\">\n <div\n *ngIf=\"!omitProperties.color\"\n class=\"form-group d-flex a-i-center gap-8\"\n [title]=\"'Change color' | translate\"\n >\n <label class=\"m-0\">{{ 'Color' | translate }}</label>\n <div class=\"c8y-colorpicker\"\n [ngClass]=\"{\n 'c8y-colorpicker--event': timelineType === 'EVENT',\n 'c8y-colorpicker--alarm': timelineType !== 'EVENT'\n }\"\n >\n <input\n type=\"color\"\n formControlName=\"color\"\n (click)=\"$event.stopPropagation()\"\n />\n <span [style.background-color]=\"formGroup.value.color\">\n <i [c8yIcon]=\"timelineType === 'EVENT' ? 'c8y-events' : 'bell'\"></i>\n </span>\n </div>\n </div>\n\n <c8y-alarm-event-attributes-form\n formControlName=\"details\"\n [timelineType]=\"timelineType\"\n [omitProperties]=\"omitProperties\"\n [selectedItems]=\"selectedItems\"\n ></c8y-alarm-event-attributes-form>\n\n <div class=\"d-flex p-t-16\">\n <button class=\"btn btn-default btn-sm\" (click)=\"cancel.emit()\">\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary btn-sm\"\n [disabled]=\"(valid$ | async) === false\"\n (click)=\"add()\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Select' | translate }}\n </button>\n </div>\n</form>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: AlarmEventAttributesFormComponent, selector: "c8y-alarm-event-attributes-form", inputs: ["timelineType", "omitProperties", "selectedItems", "target", "datapoints"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CustomAlarmEventFormComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-custom-alarm-event-form', template: "<form [formGroup]=\"formGroup\" class=\"p-16\">\n <div\n *ngIf=\"!omitProperties.color\"\n class=\"form-group d-flex a-i-center gap-8\"\n [title]=\"'Change color' | translate\"\n >\n <label class=\"m-0\">{{ 'Color' | translate }}</label>\n <div class=\"c8y-colorpicker\"\n [ngClass]=\"{\n 'c8y-colorpicker--event': timelineType === 'EVENT',\n 'c8y-colorpicker--alarm': timelineType !== 'EVENT'\n }\"\n >\n <input\n type=\"color\"\n formControlName=\"color\"\n (click)=\"$event.stopPropagation()\"\n />\n <span [style.background-color]=\"formGroup.value.color\">\n <i [c8yIcon]=\"timelineType === 'EVENT' ? 'c8y-events' : 'bell'\"></i>\n </span>\n </div>\n </div>\n\n <c8y-alarm-event-attributes-form\n formControlName=\"details\"\n [timelineType]=\"timelineType\"\n [omitProperties]=\"omitProperties\"\n [selectedItems]=\"selectedItems\"\n ></c8y-alarm-event-attributes-form>\n\n <div class=\"d-flex p-t-16\">\n <button class=\"btn btn-default btn-sm\" (click)=\"cancel.emit()\">\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary btn-sm\"\n [disabled]=\"(valid$ | async) === false\"\n (click)=\"add()\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Select' | translate }}\n </button>\n </div>\n</form>\n" }]
}], ctorParameters: () => [{ type: i1.FormBuilder }], propDecorators: { timelineType: [{
type: Input
}], target: [{
type: Input
}], omitProperties: [{
type: Input
}], selectedItems: [{
type: Input
}], defaultColor: [{
type: Input
}], added: [{
type: Output
}], cancel: [{
type: Output
}] } });
class IncludesAlarmOrEventPipe {
transform(itemList, item) {
if (!Array.isArray(itemList) || !item) {
return false;
}
return itemList.some(tmp => tmp.label === item.label &&
tmp.filters.type === item.filters.type &&
tmp.__target?.id === item.__target?.id);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IncludesAlarmOrEventPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: IncludesAlarmOrEventPipe, name: "includesAlarmOrEvent" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: IncludesAlarmOrEventPipe, decorators: [{
type: Pipe,
args: [{
name: 'includesAlarmOrEvent'
}]
}] });
class AlarmEventSelectorComponent {
constructor(alarmEventSelectorService) {
this.alarmEventSelectorService = alarmEventSelectorService;
this.timelineType = 'ALARM';
this.allowChangingContext = true;
this.selectedItems = new Array();
this.allowSearch = true;
this.groupsSelectable = true;
this.hideSource = false;
this.omitProperties = {};
this.selectionChange = new EventEmitter();
this.filterString = '';
this.maxNumberOfItems = 50;
this.loadingItems$ = new BehaviorSubject(false);
this.assetSelection = new BehaviorSubject({});
this.isExpanded = false;
this.defaultColor = getComputedStyle(document.documentElement).getPropertyValue('--brand-primary') ||
getComputedStyle(document.documentElement).getPropertyValue('--c8y-brand-primary') ||
'#1776BF';
this.filterString$ = new BehaviorSubject('');
}
ngOnInit() {
this.timelineTypeTexts = this.alarmEventSelectorService.timelineTypeTexts(this.timelineType);
this.setupObservables();
if (this.contextAsset) {
this.selectAsset(this.contextAsset);
}
}
itemAdded(item) {
item.__active = true;
this.selectedItems = [...this.selectedItems, item];
this.emitCurrentSelection();
}
itemRemoved(alarm) {
this.selectedItems = this.selectedItems.filter(tmp => tmp.label !== alarm.label ||
tmp.filters.type !== alarm.filters.type ||
tmp.__target?.id !== alarm.__target?.id);
this.emitCurrentSelection();
}
assetSelectionChanged(evt) {
if (evt.items) {
return this.selectAsset(evt.items.length ? evt.items[0] : evt.items);
}
// reset selection
this.assetSelection.next(null);
}
trackByFn(_index, item) {
return `${item.filters.type}-${item.__target?.id}`;
}
filterStringChanged(newValue = '') {
this.filterString$.next(newValue);
this.filterString = newValue;
}
setLoadingState(state) {
queueMicrotask(() => this.loadingItems$.next(state));
}
setupObservables() {
this.items$ = this.assetSelection.pipe(tap(() => this.setLoadingState(true)), switchMap((asset) => asset?.id
? this.alarmEventSelectorService.getAlarmsOrEvents(asset, this.timelineType)
: this.alarmEventSelectorService.getItems(this.timelineType)), tap(() => this.setLoadingState(false)), map(items => {
if (this.omitProperties.color) {
items.forEach(i => (i.color = this.defaultColor));
}
return items;
}), shareReplay(1));
this.filterStringChanges$ = this.filterString$.pipe(distinctUntilChanged(), debounceTime(500), shareReplay(1));
this.filteredItems$ = combineLatest([this.filterStringChanges$, this.items$]).pipe(map(([filterString, items]) => {
if (!filterString) {
return items;
}
const lowerCaseFilterString = filterString.toLowerCase();
return items.filter(item => this.includesFilterString(item, lowerCaseFilterString));
}), map(filtered => filtered.slice(0, this.maxNumberOfItems)));
}
selectAsset(asset) {
this.assetSelection.next(asset);
this.filterStringChanged();
}
emitCurrentSelection() {
this.selectionChange.emit(this.selectedItems);
}
includesFilterString(alarm, lowerCaseFilterString) {
const label = alarm.label?.toLowerCase();
if (label && label.includes(lowerCaseFilterString)) {
return true;
}
const type = alarm.filters.type?.toLowerCase();
if (type && type.includes(lowerCaseFilterString)) {
return true;
}
return false;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorComponent, deps: [{ token: AlarmEventSelectorService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AlarmEventSelectorComponent, selector: "c8y-alarm-event-selector", inputs: { timelineType: "timelineType", contextAsset: "contextAsset", allowChangingContext: "allowChangingContext", selectedItems: "selectedItems", allowSearch: "allowSearch", groupsSelectable: "groupsSelectable", hideSource: "hideSource", omitProperties: "omitProperties" }, outputs: { selectionChange: "selectionChange" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => AlarmEventSelectorComponent)
}
], ngImport: i0, template: "<div\n class=\"d-grid grid__row--1 fit-h\"\n [ngClass]=\"{\n 'grid__col--3-6-3--md': allowChangingContext,\n 'grid__col--8-4--md': !allowChangingContext\n }\"\n>\n <div\n class=\"d-flex d-col p-relative bg-level-1\"\n *ngIf=\"allowChangingContext\"\n >\n <c8y-asset-selector-miller\n class=\"d-contents\"\n [(ngModel)]=\"contextAsset\"\n [asset]=\"contextAsset\"\n (onSelected)=\"assetSelectionChanged($event)\"\n [container]=\"''\"\n [config]=\"{\n view: 'miller',\n groupsSelectable: groupsSelectable,\n columnHeaders: true,\n showChildDevices: true,\n showUnassignedDevices: true,\n singleColumn: true,\n search: allowSearch,\n showFilter: true\n }\"\n ></c8y-asset-selector-miller>\n </div>\n <!-- center column -->\n <div class=\"inner-scroll bg-component\" data-cy=\"c8y-alarm-event-selector--inner-column\">\n <ng-template #noDeviceEmptyState>\n <div class=\"p-16\">\n <c8y-ui-empty-state\n [icon]=\"timelineTypeTexts.emptyStateIcon\"\n [title]=\"timelineTypeTexts.emptyStateTitle | translate\"\n [subtitle]=\"timelineTypeTexts.assetWithNoItemsEmptyStateSubtitle | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n </ng-template>\n\n <ng-template #loadingData>\n <div class=\"p-16 text-center\">\n <c8y-loading></c8y-loading>\n </div>\n </ng-template>\n\n <div\n class=\"bg-inherit\"\n *ngIf=\"assetSelection | async as asset; else noDeviceEmptyState\"\n >\n <div class=\"p-l-16 p-r-16 p-t-8 p-b-8 sticky-top bg-inherit separator-bottom\">\n <p\n class=\"text-medium text-truncate\"\n [title]=\"timelineTypeTexts.availableItemsTitle | translate\"\n >\n {{ timelineTypeTexts.availableItemsTitle | translate }}\n </p>\n <div class=\"d-flex\">\n <div\n class=\"input-group input-group-search m-t-4\"\n id=\"search\"\n *ngIf=\"!(loadingItems$ | async)\"\n >\n <input\n class=\"form-control\"\n placeholder=\"Filter\u2026\"\n type=\"search\"\n [ngModel]=\"filterString\"\n (ngModelChange)=\"filterStringChanged($event)\"\n />\n <span class=\"input-group-addon\">\n <i\n c8yIcon=\"search\"\n *ngIf=\"!filterString; else clearFilterString\"\n ></i>\n <ng-template #clearFilterString>\n <i\n class=\"text-muted\"\n c8yIcon=\"times\"\n *ngIf=\"filterString\"\n (click)=\"filterStringChanged()\"\n ></i>\n </ng-template>\n </span>\n </div>\n </div>\n </div>\n\n <ng-container *ngIf=\"filteredItems$ | async as filteredItems; else loadingData\">\n <ng-container *ngIf=\"!(loadingItems$ | async); else loadingData\">\n <ng-container *ngIf=\"items$ | async as items\">\n <div class=\"p-16 bg-level-2 separator-bottom\">\n <div>\n <p>\n <i\n class=\"text-info m-r-4\"\n c8yIcon=\"info-circle\"\n ></i>\n <strong>{{ timelineTypeTexts.recentItemsWarningTitle | translate }}</strong>\n </p>\n <p>\n {{ timelineTypeTexts.recentItemsWarningText | translate }}\n {{ timelineTypeTexts.addCustomText | translate }}\n </p>\n </div>\n <div class=\"p-t-16\">\n <button\n class=\"btn btn-default btn-sm\"\n aria-controls=\"collapseCustomItemForm\"\n [attr.aria-expanded]=\"isExpanded\"\n (click)=\"isExpanded = !isExpanded\"\n >\n {{ timelineTypeTexts.addCustomItemButtonLabel | translate }}\n </button>\n <div\n class=\"collapse\"\n id=\"collapseCustomItemForm\"\n [collapse]=\"!isExpanded\"\n [isAnimated]=\"true\"\n >\n <div [style.min-height]=\"'230px'\">\n <c8y-custom-alarm-event-form\n class=\"d-block\"\n *ngIf=\"isExpanded\"\n [timelineType]=\"timelineType\"\n [target]=\"assetSelection | async\"\n [omitProperties]=\"omitProperties\"\n [defaultColor]=\"defaultColor\"\n (added)=\"itemAdded($event); isExpanded = false\"\n (cancel)=\"isExpanded = false\"\n [selectedItems]=\"selectedItems\"\n ></c8y-custom-alarm-event-form>\n </div>\n </div>\n </div>\n </div>\n\n <div\n class=\"p-16\"\n *ngIf=\"!filteredItems.length\"\n >\n <c8y-ui-empty-state\n [icon]=\"timelineTypeTexts.emptyStateIcon\"\n [title]=\"timelineTypeTexts.emptyStateTitle | translate\"\n [subtitle]=\"\n items.length\n ? ('Try another filter term.' | translate)\n : (timelineTypeTexts.assetWithNoItemsEmptyStateSubtitle | translate)\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n\n <c8y-list-group>\n <c8y-list-item\n class=\"sticky-top\"\n style=\"top: 72px\"\n *ngIf=\"items.length > maxNumberOfItems && filteredItems.length >= maxNumberOfItems\"\n >\n <div class=\"alert alert-warning m-b-0\">\n {{ timelineTypeTexts.largeNumberOfItemsInfo | translate }}\n </div>\n </c8y-list-item>\n <c8y-alarm-event-selector-list-item\n class=\"d-contents\"\n [ngModel]=\"item\"\n [isSelected]=\"selectedItems | includesAlarmOrEvent: item\"\n (added)=\"itemAdded($event)\"\n (removed)=\"itemRemoved($event)\"\n [highlightText]=\"filterStringChanges$ | async\"\n [timelineType]=\"timelineType\"\n [hideSource]=\"hideSource\"\n *ngFor=\"let item of filteredItems; trackBy: trackByFn\"\n ></c8y-alarm-event-selector-list-item>\n </c8y-list-group>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- last column -->\n <div class=\"inner-scroll bg-level-1\">\n <p\n class=\"text-medium m-b-4 p-l-16 p-r-16 p-t-8 p-b-8 separator-bottom sticky-top text-truncate\"\n [title]=\"timelineTypeTexts.selectedItemsTitle | translate\"\n >\n {{ timelineTypeTexts.selectedItemsTitle | translate }}\n </p>\n <div class=\"d-flex flex-wrap gap-8 p-l-16 p-r-16 p-b-16\">\n <c8y-ui-empty-state\n [icon]=\"timelineTypeTexts.emptyStateIcon\"\n [title]=\"timelineTypeTexts.noSelectedItemsTitle | translate\"\n *ngIf=\"!selectedItems || !selectedItems.length\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n\n <div\n [ngClass]=\"{\n 'c8y-alarm-pill': timelineType === 'ALARM',\n 'c8y-event-pill': timelineType === 'EVENT'\n }\"\n *ngFor=\"let selectedItem of selectedItems\"\n >\n <button\n [title]=\"'Remove' | translate\"\n type=\"button\"\n [ngClass]=\"{\n 'c8y-alarm-pill__btn': timelineType === 'ALARM',\n 'c8y-event-pill__btn': timelineType === 'EVENT'\n }\"\n (click)=\"itemRemoved(selectedItem)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"remove\"\n ></i>\n </button>\n <div\n class=\"c8y-datapoint-pill__label\"\n [title]=\"selectedItem.label || selectedItem.filters.type\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"selectedItem.color || defaultColor\"\n >\n <i\n class=\"stroked-icon\"\n [c8yIcon]=\"timelineType === 'ALARM' ? 'bell' : 'c8y-events'\"\n ></i>\n </span>\n <span class=\"text-truncate\">\n <span class=\"text-truncate\">{{ selectedItem.label || selectedItem.filters.type }}</span>\n <small\n class=\"text-muted text-10\"\n *ngIf=\"!hideSource && selectedItem?.__target?.name\"\n >\n {{ selectedItem?.__target?.name }}\n </small>\n </span>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i2.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i5.MillerViewComponent, selector: "c8y-asset-selector-miller", inputs: ["config", "asset", "selectedDevice", "rootNode", "container"], outputs: ["onSelected", "onClearSelected"] }, { kind: "directive", type: i6.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "component", type: AlarmEventSelectorListItemComponent, selector: "c8y-alarm-event-selector-list-item", inputs: ["timelineType", "datapoints", "highlightText", "showAddRemoveButton", "isSelected", "optionToRemove", "showActiveToggle", "allowItemEdit", "hideSource", "displayAsSwitch", "omitProperties"], outputs: ["added", "removed"] }, { kind: "component", type: CustomAlarmEventFormComponent, selector: "c8y-custom-alarm-event-form", inputs: ["timelineType", "target", "omitProperties", "selectedItems", "defaultColor"], outputs: ["added", "cancel"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: IncludesAlarmOrEventPipe, name: "includesAlarmOrEvent" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-alarm-event-selector', providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => AlarmEventSelectorComponent)
}
], template: "<div\n class=\"d-grid grid__row--1 fit-h\"\n [ngClass]=\"{\n 'grid__col--3-6-3--md': allowChangingContext,\n 'grid__col--8-4--md': !allowChangingContext\n }\"\n>\n <div\n class=\"d-flex d-col p-relative bg-level-1\"\n *ngIf=\"allowChangingContext\"\n >\n <c8y-asset-selector-miller\n class=\"d-contents\"\n [(ngModel)]=\"contextAsset\"\n [asset]=\"contextAsset\"\n (onSelected)=\"assetSelectionChanged($event)\"\n [container]=\"''\"\n [config]=\"{\n view: 'miller',\n groupsSelectable: groupsSelectable,\n columnHeaders: true,\n showChildDevices: true,\n showUnassignedDevices: true,\n singleColumn: true,\n search: allowSearch,\n showFilter: true\n }\"\n ></c8y-asset-selector-miller>\n </div>\n <!-- center column -->\n <div class=\"inner-scroll bg-component\" data-cy=\"c8y-alarm-event-selector--inner-column\">\n <ng-template #noDeviceEmptyState>\n <div class=\"p-16\">\n <c8y-ui-empty-state\n [icon]=\"timelineTypeTexts.emptyStateIcon\"\n [title]=\"timelineTypeTexts.emptyStateTitle | translate\"\n [subtitle]=\"timelineTypeTexts.assetWithNoItemsEmptyStateSubtitle | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n </ng-template>\n\n <ng-template #loadingData>\n <div class=\"p-16 text-center\">\n <c8y-loading></c8y-loading>\n </div>\n </ng-template>\n\n <div\n class=\"bg-inherit\"\n *ngIf=\"assetSelection | async as asset; else noDeviceEmptyState\"\n >\n <div class=\"p-l-16 p-r-16 p-t-8 p-b-8 sticky-top bg-inherit separator-bottom\">\n <p\n class=\"text-medium text-truncate\"\n [title]=\"timelineTypeTexts.availableItemsTitle | translate\"\n >\n {{ timelineTypeTexts.availableItemsTitle | translate }}\n </p>\n <div class=\"d-flex\">\n <div\n class=\"input-group input-group-search m-t-4\"\n id=\"search\"\n *ngIf=\"!(loadingItems$ | async)\"\n >\n <input\n class=\"form-control\"\n placeholder=\"Filter\u2026\"\n type=\"search\"\n [ngModel]=\"filterString\"\n (ngModelChange)=\"filterStringChanged($event)\"\n />\n <span class=\"input-group-addon\">\n <i\n c8yIcon=\"search\"\n *ngIf=\"!filterString; else clearFilterString\"\n ></i>\n <ng-template #clearFilterString>\n <i\n class=\"text-muted\"\n c8yIcon=\"times\"\n *ngIf=\"filterString\"\n (click)=\"filterStringChanged()\"\n ></i>\n </ng-template>\n </span>\n </div>\n </div>\n </div>\n\n <ng-container *ngIf=\"filteredItems$ | async as filteredItems; else loadingData\">\n <ng-container *ngIf=\"!(loadingItems$ | async); else loadingData\">\n <ng-container *ngIf=\"items$ | async as items\">\n <div class=\"p-16 bg-level-2 separator-bottom\">\n <div>\n <p>\n <i\n class=\"text-info m-r-4\"\n c8yIcon=\"info-circle\"\n ></i>\n <strong>{{ timelineTypeTexts.recentItemsWarningTitle | translate }}</strong>\n </p>\n <p>\n {{ timelineTypeTexts.recentItemsWarningText | translate }}\n {{ timelineTypeTexts.addCustomText | translate }}\n </p>\n </div>\n <div class=\"p-t-16\">\n <button\n class=\"btn btn-default btn-sm\"\n aria-controls=\"collapseCustomItemForm\"\n [attr.aria-expanded]=\"isExpanded\"\n (click)=\"isExpanded = !isExpanded\"\n >\n {{ timelineTypeTexts.addCustomItemButtonLabel | translate }}\n </button>\n <div\n class=\"collapse\"\n id=\"collapseCustomItemForm\"\n [collapse]=\"!isExpanded\"\n [isAnimated]=\"true\"\n >\n <div [style.min-height]=\"'230px'\">\n <c8y-custom-alarm-event-form\n class=\"d-block\"\n *ngIf=\"isExpanded\"\n [timelineType]=\"timelineType\"\n [target]=\"assetSelection | async\"\n [omitProperties]=\"omitProperties\"\n [defaultColor]=\"defaultColor\"\n (added)=\"itemAdded($event); isExpanded = false\"\n (cancel)=\"isExpanded = false\"\n [selectedItems]=\"selectedItems\"\n ></c8y-custom-alarm-event-form>\n </div>\n </div>\n </div>\n </div>\n\n <div\n class=\"p-16\"\n *ngIf=\"!filteredItems.length\"\n >\n <c8y-ui-empty-state\n [icon]=\"timelineTypeTexts.emptyStateIcon\"\n [title]=\"timelineTypeTexts.emptyStateTitle | translate\"\n [subtitle]=\"\n items.length\n ? ('Try another filter term.' | translate)\n : (timelineTypeTexts.assetWithNoItemsEmptyStateSubtitle | translate)\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n\n <c8y-list-group>\n <c8y-list-item\n class=\"sticky-top\"\n style=\"top: 72px\"\n *ngIf=\"items.length > maxNumberOfItems && filteredItems.length >= maxNumberOfItems\"\n >\n <div class=\"alert alert-warning m-b-0\">\n {{ timelineTypeTexts.largeNumberOfItemsInfo | translate }}\n </div>\n </c8y-list-item>\n <c8y-alarm-event-selector-list-item\n class=\"d-contents\"\n [ngModel]=\"item\"\n [isSelected]=\"selectedItems | includesAlarmOrEvent: item\"\n (added)=\"itemAdded($event)\"\n (removed)=\"itemRemoved($event)\"\n [highlightText]=\"filterStringChanges$ | async\"\n [timelineType]=\"timelineType\"\n [hideSource]=\"hideSource\"\n *ngFor=\"let item of filteredItems; trackBy: trackByFn\"\n ></c8y-alarm-event-selector-list-item>\n </c8y-list-group>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- last column -->\n <div class=\"inner-scroll bg-level-1\">\n <p\n class=\"text-medium m-b-4 p-l-16 p-r-16 p-t-8 p-b-8 separator-bottom sticky-top text-truncate\"\n [title]=\"timelineTypeTexts.selectedItemsTitle | translate\"\n >\n {{ timelineTypeTexts.selectedItemsTitle | translate }}\n </p>\n <div class=\"d-flex flex-wrap gap-8 p-l-16 p-r-16 p-b-16\">\n <c8y-ui-empty-state\n [icon]=\"timelineTypeTexts.emptyStateIcon\"\n [title]=\"timelineTypeTexts.noSelectedItemsTitle | translate\"\n *ngIf=\"!selectedItems || !selectedItems.length\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n\n <div\n [ngClass]=\"{\n 'c8y-alarm-pill': timelineType === 'ALARM',\n 'c8y-event-pill': timelineType === 'EVENT'\n }\"\n *ngFor=\"let selectedItem of selectedItems\"\n >\n <button\n [title]=\"'Remove' | translate\"\n type=\"button\"\n [ngClass]=\"{\n 'c8y-alarm-pill__btn': timelineType === 'ALARM',\n 'c8y-event-pill__btn': timelineType === 'EVENT'\n }\"\n (click)=\"itemRemoved(selectedItem)\"\n >\n <i\n class=\"icon-14\"\n c8yIcon=\"remove\"\n ></i>\n </button>\n <div\n class=\"c8y-datapoint-pill__label\"\n [title]=\"selectedItem.label || selectedItem.filters.type\"\n >\n <span\n class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n [style.background-color]=\"selectedItem.color || defaultColor\"\n >\n <i\n class=\"stroked-icon\"\n [c8yIcon]=\"timelineType === 'ALARM' ? 'bell' : 'c8y-events'\"\n ></i>\n </span>\n <span class=\"text-truncate\">\n <span class=\"text-truncate\">{{ selectedItem.label || selectedItem.filters.type }}</span>\n <small\n class=\"text-muted text-10\"\n *ngIf=\"!hideSource && selectedItem?.__target?.name\"\n >\n {{ selectedItem?.__target?.name }}\n </small>\n </span>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: AlarmEventSelectorService }], propDecorators: { timelineType: [{
type: Input
}], contextAsset: [{
type: Input
}], allowChangingContext: [{
type: Input
}], selectedItems: [{
type: Input
}], allowSearch: [{
type: Input
}], groupsSelectable: [{
type: Input
}], hideSource: [{
type: Input
}], omitProperties: [{
type: Input
}], selectionChange: [{
type: Output
}] } });
class AlarmEventSelectorModalComponent {
constructor(bsModal) {
this.bsModal = bsModal;
this.selectType = 'ALARM';
this.allowChangingContext = true;
this.allowSearch = true;
this.selectedItems = new Array();
this.groupsSelectable = true;
this.hideSource = false;
this.omitProperties = {};
this.result = new Promise((resolve, reject) => {
this.save = resolve;
this.cancel = reject;
});
}
saveChanges() {
this.bsModal.hide();
this.save(this.selectedItems);
}
close() {
this.bsModal.hide();
this.cancel();
}
selectionChange(selection) {
this.selectedItems = selection;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorModalComponent, deps: [{ token: i1$2.BsModalRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AlarmEventSelectorModalComponent, selector: "c8y-alarm-event-selector-modal", ngImport: i0, template: "<div class=\"modal-header separator\">\n <h4 class=\"text-medium\">{{ title | translate }}</h4>\n</div>\n<div class=\"modal-inner-scroll modal-inner-scroll--fixed\">\n <c8y-alarm-event-selector\n [selectedItems]=\"selectedItems\"\n [contextAsset]=\"contextAsset\"\n [timelineType]=\"selectType\"\n [groupsSelectable]=\"groupsSelectable\"\n [hideSource]=\"hideSource\"\n [allowChangingContext]=\"allowChangingContext\"\n [omitProperties]=\"omitProperties\"\n (selectionChange)=\"selectionChange($event)\"\n ></c8y-alarm-event-selector>\n</div>\n<div class=\"modal-footer\">\n <button\n type=\"button\"\n [title]=\"'Cancel' | translate\"\n class=\"btn btn-default\"\n (click)=\"close()\"\n translate\n >\n Cancel\n </button>\n <button\n [title]=\"saveButtonLabel | translate\"\n class=\"btn btn-primary\"\n [disabled]=\"!this.selectedItems?.length\"\n (click)=\"saveChanges()\"\n >\n {{ saveButtonLabel | translate }}\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: AlarmEventSelectorComponent, selector: "c8y-alarm-event-selector", inputs: ["timelineType", "contextAsset", "allowChangingContext", "selectedItems", "allowSearch", "groupsSelectable", "hideSource", "omitProperties"], outputs: ["selectionChange"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorModalComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-alarm-event-selector-modal', template: "<div class=\"modal-header separator\">\n <h4 class=\"text-medium\">{{ title | translate }}</h4>\n</div>\n<div class=\"modal-inner-scroll modal-inner-scroll--fixed\">\n <c8y-alarm-event-selector\n [selectedItems]=\"selectedItems\"\n [contextAsset]=\"contextAsset\"\n [timelineType]=\"selectType\"\n [groupsSelectable]=\"groupsSelectable\"\n [hideSource]=\"hideSource\"\n [allowChangingContext]=\"allowChangingContext\"\n [omitProperties]=\"omitProperties\"\n (selectionChange)=\"selectionChange($event)\"\n ></c8y-alarm-event-selector>\n</div>\n<div class=\"modal-footer\">\n <button\n type=\"button\"\n [title]=\"'Cancel' | translate\"\n class=\"btn btn-default\"\n (click)=\"close()\"\n translate\n >\n Cancel\n </button>\n <button\n [title]=\"saveButtonLabel | translate\"\n class=\"btn btn-primary\"\n [disabled]=\"!this.selectedItems?.length\"\n (click)=\"saveChanges()\"\n >\n {{ saveButtonLabel | translate }}\n </button>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1$2.BsModalRef }] });
/**
* Service to open the alarm event selector modal.
*/
class AlarmEventSelectorModalService {
constructor(modal) {
this.modal = modal;
}
/**
* Opents the alarm or event selector modal.
* @param initialState Initial state of the modal.
* @returns Promise that resolves with the selected alarms or events.
*/
selectItems(initialState = {}) {
const modal = this.modal.show(AlarmEventSelectorModalComponent, {
ignoreBackdropClick: true,
keyboard: false,
initialState,
class: 'modal-lg'
});
const content = modal.content;
return content.result;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorModalService, deps: [{ token: i1$2.BsModalService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorModalService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorModalService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i1$2.BsModalService }] });
class AlarmEventSelectionListComponent {
constructor(alarmEventModalService, alarmEventSelectService, formBuilder, activatedRoute, contextRouteService, widgetComponent) {
this.alarmEventModalService = alarmEventModalService;
this.alarmEventSelectService = alarmEventSelectService;
this.formBuilder = formBuilder;
this.activatedRoute = activatedRoute;
this.contextRouteService = contextRouteService;
this.widgetComponent = widgetComponent;
this.timelineType = 'ALARM';
this.canRemove = true;
this.canEdit = true;
this.canDragAndDrop = true;
this.hideSource = false;
this.inline = false; // TODO: @janhommes we should rename this to `isDropdownContained` or similar to make it more clear
this.activeToggleAsSwitch = true;
this.omitProperties = { color: false, label: false };
this.datapoints = [];
/**
* The configuration for the alarms-events selector modal.
*/
this.config = {};
this.destroy$ = new Subject();
this.formArray = this.formBuilder.array([]);
}
ngOnInit() {
this.timelineTypeTexts = this.alarmEventSelectService.timelineTypeTexts(this.timelineType);
this.title ??= this.timelineTypeTexts.listTitle;
this.addButtonLabel ??= this.timelineTypeTexts.addButtonLabel;
this.contextSourceId = this.initializeContextSourceId();
const context = this.widgetComponent?.context;
if (context?.id) {
const { name, id, c8y_IsDevice } = context;
this.config.contextAsset = { name, id, c8y_IsDevice };
}
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
registerOnTouched(fn) {
this.formArray.valueChanges.pipe(take(1)).subscribe(fn);
}
validate(_control) {
return this.formArray.valid ? null : { formInvalid: {} };
}
writeValue(val) {
this.formArray.clear();
if (val?.length) {
val.forEach(val => {
const formgroup = this.formBuilder.group({ details: [] });
formgroup.patchValue({ details: val });
this.formArray.push(formgroup);
});
}
}
registerOnChange(fn) {
this.formArray.valueChanges
.pipe(debounceTime(100), // debounce to avoid emitting of this.formArray.clear()
map(res => this.transformValue(res)), takeUntil(this.destroy$))
.subscribe(fn);
}
add() {
const allowChangingContext = !this.widgetComponent?.isDeviceTypeDashboard && this.config?.allowChangingContext !== false;
this.alarmEventModalService
.selectItems({
allowChangingContext,
selectType: this.timelineType,
selectedItems: this.transformValue(this.formArray.value),
allowSearch: !this.config?.contextAsset,
title: this.timelineTypeTexts.selectorTitle,
saveButtonLabel: this.timelineTypeTexts.addButtonLabel,
omitProperties: this.omitProperties,
contextAsset: this.config?.contextAsset
? this.config.contextAsset
: this.contextSourceId
? { id: this.contextSourceId }
: null,
...(this.config || {})
})
.then(result => {
this.writeValue(result);
}, () => {
// nothing to do, modal was closed
});
}
onItemRemoved(index) {
this.formArray.removeAt(index);
}
drop(event) {
const currentSorting = this.formArray.value;
moveItemInArray(currentSorting, event.previousIndex, event.currentIndex);
this.formArray.setValue(currentSorting);
}
transformValue(formArrayValue) {
if (!formArrayValue) {
return [];
}
return formArrayValue.map(tmp => Object.assign({}, ...Object.values(tmp)));
}
initializeContextSourceId() {
const routeContext = this.contextRouteService.getContextData(this.activatedRoute);
if (!routeContext) {
return;
}
const { context, contextData } = routeContext;
if ([ViewContext.Device, ViewContext.Group].includes(context)) {
return contextData?.id;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectionListComponent, deps: [{ token: AlarmEventSelectorModalService }, { token: AlarmEventSelectorService }, { token: i1.FormBuilder }, { token: i4$1.ActivatedRoute, optional: true }, { token: i2.ContextRouteService, optional: true }, { token: i6$1.WidgetConfigComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AlarmEventSelectionListComponent, selector: "c8y-alarm-event-selection-list", inputs: { timelineType: "timelineType", canRemove: "canRemove", canEdit: "canEdit", canDragAndDrop: "canDragAndDrop", title: "title", addButtonLabel: "addButtonLabel", hideSource: "hideSource", inline: "inline", activeToggleAsSwitch: "activeToggleAsSwitch", omitProperties: "omitProperties", datapoints: "datapoints", config: "config" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => AlarmEventSelectionListComponent)
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AlarmEventSelectionListComponent),
multi: true
}
], queries: [{ propertyName: "emptyState", first: true, predicate: EmptyStateComponent, descendants: true }], ngImport: i0, template: "<div\n class=\"card-header separator-top-bottom sticky-top bg-inherit\"\n *ngIf=\"!inline\"\n>\n <span class=\"card-title h4\">{{ title | translate }}</span>\n</div>\n\n<c8y-list-group\n class=\"flex-grow ff-scroll-fix cdk-droplist\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"formArray.controls?.length < 2\"\n>\n <div\n class=\"p-t-8\"\n *ngIf=\"!formArray.controls?.length\"\n >\n <ng-content select=\"c8y-ui-empty-state\"></ng-content>\n <c8y-ui-empty-state\n class=\"p-t-8\"\n [icon]=\"timelineTypeTexts.emptyStateIcon\"\n [title]=\"timelineTypeTexts.emptyStateTitle | translate\"\n [subtitle]=\"timelineTypeTexts.emptyStateSubtitle | translate\"\n *ngIf=\"!emptyState\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n <div\n *ngFor=\"let itemForm of formArray.controls; let index = index\"\n [formGroup]=\"itemForm\"\n >\n <c8y-alarm-event-selector-list-item\n class=\"d-block\"\n cdkDrag\n [cdkDragDisabled]=\"!canDragAndDrop\"\n formControlName=\"details\"\n [showAddRemoveButton]=\"false\"\n [datapoints]=\"datapoints\"\n [optionToRemove]=\"canRemove\"\n [showActiveToggle]=\"true\"\n [timelineType]=\"timelineType\"\n [allowItemEdit]=\"canEdit\"\n [hideSource]=\"hideSource\"\n [displayAsSwitch]=\"activeToggleAsSwitch\"\n [omitProperties]=\"omitProperties\"\n (removed)=\"onItemRemoved(index)\"\n >\n <c8y-li-drag-handle\n title=\"{{ 'Click and drag to reorder' | translate }}\"\n cdkDragHandle\n *ngIf=\"canDragAndDrop\"\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n </c8y-alarm-event-selector-list-item>\n </div>\n</c8y-list-group>\n\n<div class=\"card-footer bg-inherit\">\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"addButtonLabel | translate\"\n type=\"button\"\n [ngClass]=\"{ 'btn-block': inline }\"\n (click)=\"add()\"\n >\n <i\n c8yIcon=\"plus-circle\"\n *ngIf=\"canDragAndDrop\"\n ></i>\n {{ addButtonLabel | translate }}\n </button>\n</div>\n", dependencies: [{ kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i2.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i2.ListItemDragHandleComponent, selector: "c8y-list-item-drag-handle, c8y-li-drag-handle" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i8.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i8.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i8.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: AlarmEventSelectorListItemComponent, selector: "c8y-alarm-event-selector-list-item", inputs: ["timelineType", "datapoints", "highlightText", "showAddRemoveButton", "isSelected", "optionToRemove", "showActiveToggle", "allowItemEdit", "hideSource", "displayAsSwitch", "omitProperties"], outputs: ["added", "removed"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectionListComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-alarm-event-selection-list', providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => AlarmEventSelectionListComponent)
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => AlarmEventSelectionListComponent),
multi: true
}
], template: "<div\n class=\"card-header separator-top-bottom sticky-top bg-inherit\"\n *ngIf=\"!inline\"\n>\n <span class=\"card-title h4\">{{ title | translate }}</span>\n</div>\n\n<c8y-list-group\n class=\"flex-grow ff-scroll-fix cdk-droplist\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"formArray.controls?.length < 2\"\n>\n <div\n class=\"p-t-8\"\n *ngIf=\"!formArray.controls?.length\"\n >\n <ng-content select=\"c8y-ui-empty-state\"></ng-content>\n <c8y-ui-empty-state\n class=\"p-t-8\"\n [icon]=\"timelineTypeTexts.emptyStateIcon\"\n [title]=\"timelineTypeTexts.emptyStateTitle | translate\"\n [subtitle]=\"timelineTypeTexts.emptyStateSubtitle | translate\"\n *ngIf=\"!emptyState\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n <div\n *ngFor=\"let itemForm of formArray.controls; let index = index\"\n [formGroup]=\"itemForm\"\n >\n <c8y-alarm-event-selector-list-item\n class=\"d-block\"\n cdkDrag\n [cdkDragDisabled]=\"!canDragAndDrop\"\n formControlName=\"details\"\n [showAddRemoveButton]=\"false\"\n [datapoints]=\"datapoints\"\n [optionToRemove]=\"canRemove\"\n [showActiveToggle]=\"true\"\n [timelineType]=\"timelineType\"\n [allowItemEdit]=\"canEdit\"\n [hideSource]=\"hideSource\"\n [displayAsSwitch]=\"activeToggleAsSwitch\"\n [omitProperties]=\"omitProperties\"\n (removed)=\"onItemRemoved(index)\"\n >\n <c8y-li-drag-handle\n title=\"{{ 'Click and drag to reorder' | translate }}\"\n cdkDragHandle\n *ngIf=\"canDragAndDrop\"\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n </c8y-alarm-event-selector-list-item>\n </div>\n</c8y-list-group>\n\n<div class=\"card-footer bg-inherit\">\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"addButtonLabel | translate\"\n type=\"button\"\n [ngClass]=\"{ 'btn-block': inline }\"\n (click)=\"add()\"\n >\n <i\n c8yIcon=\"plus-circle\"\n *ngIf=\"canDragAndDrop\"\n ></i>\n {{ addButtonLabel | translate }}\n </button>\n</div>\n" }]
}], ctorParameters: () => [{ type: AlarmEventSelectorModalService }, { type: AlarmEventSelectorService }, { type: i1.FormBuilder }, { type: i4$1.ActivatedRoute, decorators: [{
type: Optional
}] }, { type: i2.ContextRouteService, decorators: [{
type: Optional
}] }, { type: i6$1.WidgetConfigComponent, decorators: [{
type: Optional
}] }], propDecorators: { timelineType: [{
type: Input
}], canRemove: [{
type: Input
}], canEdit: [{
type: Input
}], canDragAndDrop: [{
type: Input
}], title: [{
type: Input
}], addButtonLabel: [{
type: Input
}], hideSource: [{
type: Input
}], inline: [{
type: Input
}], activeToggleAsSwitch: [{
type: Input
}], omitProperties: [{
type: Input
}], datapoints: [{
type: Input
}], emptyState: [{
type: ContentChild,
args: [EmptyStateComponent]
}], config: [{
type: Input
}] } });
class AlarmEventSelectorModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorModule, declarations: [AlarmEventSelectionListComponent,
AlarmEventSelectorListItemComponent,
AlarmEventAttributesFormComponent,
AlarmEventSelectorModalComponent,
AlarmEventSelectorComponent,
IncludesAlarmOrEventPipe,
CustomAlarmEventFormComponent], imports: [CommonModule,
CoreModule,
DragDropModule,
PopoverModule,
TooltipModule,
AssetSelectorModule,
CollapseModule, i4$1.RouterModule], exports: [AlarmEventSelectionListComponent, AlarmEventSelectorComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorModule, imports: [CommonModule,
CoreModule,
DragDropModule,
PopoverModule,
TooltipModule,
AssetSelectorModule,
CollapseModule,
RouterModule.forChild([])] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmEventSelectorModule, decorators: [{
type: NgModule,
args: [{
imports: [
CommonModule,
CoreModule,
DragDropModule,
PopoverModule,
TooltipModule,
AssetSelectorModule,
CollapseModule,
RouterModule.forChild([])
],
declarations: [
AlarmEventSelectionListComponent,
AlarmEventSelectorListItemComponent,
AlarmEventAttributesFormComponent,
AlarmEventSelectorModalComponent,
AlarmEventSelectorComponent,
IncludesAlarmOrEventPipe,
CustomAlarmEventFormComponent
],
exports: [AlarmEventSelectionListComponent, AlarmEventSelectorComponent]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { ALARM_TEXTS, AlarmEventAttributesFormComponent, AlarmEventSelectionListComponent, AlarmEventSelectorComponent, AlarmEventSelectorListItemComponent, AlarmEventSelectorModalComponent, AlarmEventSelectorModalService, AlarmEventSelectorModule, AlarmEventSelectorService, CustomAlarmEventFormComponent, EVENT_TEXTS, IncludesAlarmOrEventPipe };
//# sourceMappingURL=c8y-ngx-components-alarm-event-selector.mjs.map